+6
-3
changelog
+6
-3
changelog
···
105
106
v0.2.6:
107
- Fixed photos not being loaded if they're too low resolution
108
-
- Added close to tray toggle
109
- Fixed "Open in folder" not selecting files on linux
110
-
- Remove all sync stuff
111
- Fixed scroll to top button not animating out
112
- Fixed scroll to top button being ontop of filters menu
113
- Fixed photo ordering
114
- Fixed automatic updates
115
- Fixed broken legacy named photos
116
-
- Fixed photos being loaded with the wrong resolution
···
105
106
v0.2.6:
107
- Fixed photos not being loaded if they're too low resolution
108
- Fixed "Open in folder" not selecting files on linux
109
- Fixed scroll to top button not animating out
110
- Fixed scroll to top button being ontop of filters menu
111
- Fixed photo ordering
112
- Fixed automatic updates
113
- Fixed broken legacy named photos
114
+
- Fixed photos being loaded with the wrong resolution
115
+
116
+
- Added support for multilayer photos
117
+
- Added close to tray toggle
118
+
119
+
- Remove all sync stuff
+2
-2
src/Components/Managers/PhotoListRenderingManager.tsx
+2
-2
src/Components/Managers/PhotoListRenderingManager.tsx
···
124
let photo = (el as PhotoListPhoto).Photo;
125
126
// === DEBUG ===
127
-
ctx.strokeStyle = '#f00';
128
-
ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height);
129
130
if(!photo.loaded)
131
// If the photo is not loaded, start a new task and load it in that task
···
124
let photo = (el as PhotoListPhoto).Photo;
125
126
// === DEBUG ===
127
+
// ctx.strokeStyle = '#f00';
128
+
// ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height);
129
130
if(!photo.loaded)
131
// If the photo is not loaded, start a new task and load it in that task
+3
src/Components/Managers/PhotoManager.tsx
+3
src/Components/Managers/PhotoManager.tsx
···
108
109
let photo = this.Photos.find(x => x.path === data.path);
110
if(!photo)return console.error('Cannot find photo.', data);
111
+
// NOTE: this is triggered by multilayer photo layers loading their metadata
112
+
// we don't need to store metadata of those photos as they inherit this
113
+
// data from the main photo.
114
115
this._lastLoaded = photo.index;
116
-1
src/Components/PhotoList.tsx
-1
src/Components/PhotoList.tsx
+85
-3
src/Components/PhotoViewer.tsx
+85
-3
src/Components/PhotoViewer.tsx
···
1
import { For, Show, createEffect, onCleanup, onMount } from "solid-js";
2
import { invoke } from '@tauri-apps/api/core';
3
import { WorldCache } from "./Structs/WorldCache";
4
-
import { animate, JSAnimation, utils } from "animejs";
5
6
let PhotoViewer = () => {
7
let viewer: HTMLElement;
···
23
let allowedToOpenTray = false;
24
25
let authorProfileButton: HTMLDivElement;
26
27
let switchPhotoWithKey = ( e: KeyboardEvent ) => {
28
switch(e.key){
···
84
}
85
86
let copyImage = () => {
87
-
invoke('copy_image', { path: window.PhotoViewerManager.CurrentPhoto()!.path })
88
.then(() => {
89
utils.set('.copy-notif', { translateX: '-50%', translateY: '-100px' });
90
animate('.copy-notif', {
···
136
onMount(() => {
137
utils.set(photoControls, { translateX: '-50%' });
138
utils.set(photoTrayCloseBtn, { translateX: '-50%', opacity: 0, scale: '0.75', bottom: '10px' });
139
140
window.addEventListener('keyup', switchPhotoWithKey);
141
···
153
viewerContextMenu.style.display = 'none';
154
}
155
})
156
});
157
158
viewerContextMenuButtons[0].onclick = async () => {
···
367
)
368
}
369
370
let toggleLayerManager = () => {
371
-
372
}
373
374
// TODO: Make layers selectable
375
376
return (
377
<div class="photo-viewer" ref={( el ) => viewer = el}>
378
<div class="photo-context-menu" ref={( el ) => viewerContextMenu = el}>
379
<div ref={( el ) => viewerContextMenuButtons.push(el)}>Open file location</div>
380
<div ref={( el ) => viewerContextMenuButtons.push(el)}>Copy image</div>
···
1
import { For, Show, createEffect, onCleanup, onMount } from "solid-js";
2
import { invoke } from '@tauri-apps/api/core';
3
import { WorldCache } from "./Structs/WorldCache";
4
+
import { animate, createSpring, JSAnimation, utils } from "animejs";
5
6
let PhotoViewer = () => {
7
let viewer: HTMLElement;
···
23
let allowedToOpenTray = false;
24
25
let authorProfileButton: HTMLDivElement;
26
+
27
+
let photoLayerManager!: HTMLDivElement;
28
29
let switchPhotoWithKey = ( e: KeyboardEvent ) => {
30
switch(e.key){
···
86
}
87
88
let copyImage = () => {
89
+
let path;
90
+
let photo = window.PhotoViewerManager.CurrentPhoto()!;
91
+
92
+
switch(layerManagerViewing){
93
+
case LayerManagerView.DEFAULT:
94
+
path = photo.path;
95
+
break;
96
+
case LayerManagerView.ENVIRONMENT:
97
+
path = photo.environmentLayer!.path;
98
+
break;
99
+
case LayerManagerView.PLAYER:
100
+
path = photo.playerLayer!.path;
101
+
break;
102
+
}
103
+
104
+
invoke('copy_image', { path })
105
.then(() => {
106
utils.set('.copy-notif', { translateX: '-50%', translateY: '-100px' });
107
animate('.copy-notif', {
···
153
onMount(() => {
154
utils.set(photoControls, { translateX: '-50%' });
155
utils.set(photoTrayCloseBtn, { translateX: '-50%', opacity: 0, scale: '0.75', bottom: '10px' });
156
+
utils.set(photoLayerManager, { translateY: '20px', opacity: 0, display: 'none' });
157
158
window.addEventListener('keyup', switchPhotoWithKey);
159
···
171
viewerContextMenu.style.display = 'none';
172
}
173
})
174
+
});
175
+
176
+
window.CloseAllPopups.push(() => {
177
+
layerManagerOpen = false;
178
+
if(layerManagerAnimation)layerManagerAnimation.cancel();
179
+
180
+
layerManagerAnimation = animate(photoLayerManager, { translateY: '20px', opacity: 0, duration: 100, onComplete: () => utils.set(photoLayerManager, { display: 'none' }) });
181
});
182
183
viewerContextMenuButtons[0].onclick = async () => {
···
392
)
393
}
394
395
+
enum LayerManagerView{
396
+
DEFAULT,
397
+
PLAYER,
398
+
ENVIRONMENT
399
+
}
400
+
401
+
let layerManagerOpen = false;
402
+
let layerManagerAnimation: null | JSAnimation = null;
403
+
let layerManagerViewing = LayerManagerView.DEFAULT;
404
+
405
let toggleLayerManager = () => {
406
+
if(layerManagerOpen){
407
+
// Close
408
+
layerManagerOpen = false;
409
+
if(layerManagerAnimation)layerManagerAnimation.cancel();
410
+
411
+
layerManagerAnimation = animate(photoLayerManager, { translateY: '20px', opacity: 0, duration: 100, onComplete: () => utils.set(photoLayerManager, { display: 'none' }) });
412
+
} else{
413
+
// Open
414
+
layerManagerOpen = true;
415
+
if(layerManagerAnimation)layerManagerAnimation.cancel();
416
+
417
+
utils.set(photoLayerManager, { display: 'block' });
418
+
layerManagerAnimation = animate(photoLayerManager, { translateY: '0px', opacity: 1, duration: 100 });
419
+
}
420
}
421
422
// TODO: Make layers selectable
423
424
return (
425
<div class="photo-viewer" ref={( el ) => viewer = el}>
426
+
<div class="photo-layer-manager" ref={photoLayerManager}>
427
+
<Show when={window.PhotoViewerManager.CurrentPhoto()?.playerLayer}>
428
+
<div class="photo-layer-manager-layer" onClick={() => {
429
+
let photo = window.PhotoViewerManager.CurrentPhoto()?.playerLayer;
430
+
if(!photo)return;
431
+
432
+
layerManagerViewing = LayerManagerView.PLAYER;
433
+
434
+
imageViewer.src = (window.OS === "windows" ? "http://photo.localhost/" : 'photo://localhost/') + photo.path.split('\\').join('/') + "?full";
435
+
imageViewer.crossOrigin = 'anonymous';
436
+
}}>Player Layer</div>
437
+
</Show>
438
+
<Show when={window.PhotoViewerManager.CurrentPhoto()?.environmentLayer}>
439
+
<div class="photo-layer-manager-layer" onClick={() => {
440
+
let photo = window.PhotoViewerManager.CurrentPhoto()?.environmentLayer;
441
+
if(!photo)return;
442
+
443
+
layerManagerViewing = LayerManagerView.ENVIRONMENT;
444
+
445
+
imageViewer.src = (window.OS === "windows" ? "http://photo.localhost/" : 'photo://localhost/') + photo.path.split('\\').join('/') + "?full";
446
+
imageViewer.crossOrigin = 'anonymous';
447
+
}}>Environment Layer</div>
448
+
</Show>
449
+
<div class="photo-layer-manager-layer" onClick={() => {
450
+
let photo = window.PhotoViewerManager.CurrentPhoto();
451
+
if(!photo)return;
452
+
453
+
layerManagerViewing = LayerManagerView.DEFAULT;
454
+
455
+
imageViewer.src = (window.OS === "windows" ? "http://photo.localhost/" : 'photo://localhost/') + photo.path.split('\\').join('/') + "?full";
456
+
imageViewer.crossOrigin = 'anonymous';
457
+
}}>Default Layer</div>
458
+
</div>
459
+
460
<div class="photo-context-menu" ref={( el ) => viewerContextMenu = el}>
461
<div ref={( el ) => viewerContextMenuButtons.push(el)}>Open file location</div>
462
<div ref={( el ) => viewerContextMenuButtons.push(el)}>Copy image</div>
+1
-1
src/css/tray.css
+1
-1
src/css/tray.css
+26
-3
src/css/viewer.css
+26
-3
src/css/viewer.css
···
38
left: 0;
39
padding: 10px;
40
border-radius: 5px;
41
-
background: #555a;
42
color: #aaa;
43
box-shadow: #0005 0 0 10px;
44
opacity: 0;
···
80
-webkit-user-select: none;
81
cursor: pointer;
82
z-index: 7;
83
-
box-shadow: #0008 0 0 10px;
84
}
85
86
.viewer-close{
···
157
left: 50%;
158
color: white;
159
transform: translateX(-50%) translateY(-100px);
160
-
background: #8885;
161
padding: 10px 40px;
162
backdrop-filter: blur(10px);
163
-webkit-backdrop-filter: blur(10px);
···
166
z-index: 12;
167
opacity: 0;
168
pointer-events: none;
169
}
···
38
left: 0;
39
padding: 10px;
40
border-radius: 5px;
41
+
background: rgba(43, 43, 43, 0.76);
42
color: #aaa;
43
box-shadow: #0005 0 0 10px;
44
opacity: 0;
···
80
-webkit-user-select: none;
81
cursor: pointer;
82
z-index: 7;
83
+
background: rgba(43, 43, 43, 0.76);
84
}
85
86
.viewer-close{
···
157
left: 50%;
158
color: white;
159
transform: translateX(-50%) translateY(-100px);
160
+
background: rgba(43, 43, 43, 0.76);
161
padding: 10px 40px;
162
backdrop-filter: blur(10px);
163
-webkit-backdrop-filter: blur(10px);
···
166
z-index: 12;
167
opacity: 0;
168
pointer-events: none;
169
+
}
170
+
171
+
.photo-layer-manager{
172
+
background: rgba(43, 43, 43, 0.76);
173
+
color: #fff;
174
+
padding: 10px;
175
+
backdrop-filter: blur(10px);
176
+
position: fixed;
177
+
bottom: 10px;
178
+
left: 10px;
179
+
border-radius: 10px;
180
+
}
181
+
182
+
.photo-layer-manager-layer{
183
+
cursor: pointer;
184
+
-webkit-user-select: none;
185
+
user-select: none;
186
+
padding: 5px 20px;
187
+
transition: 0.1s;
188
+
}
189
+
190
+
.photo-layer-manager-layer:hover{
191
+
color: #bbb;
192
}