+6
-3
changelog
+6
-3
changelog
···
105
105
106
106
v0.2.6:
107
107
- Fixed photos not being loaded if they're too low resolution
108
-
- Added close to tray toggle
109
108
- Fixed "Open in folder" not selecting files on linux
110
-
- Remove all sync stuff
111
109
- Fixed scroll to top button not animating out
112
110
- Fixed scroll to top button being ontop of filters menu
113
111
- Fixed photo ordering
114
112
- Fixed automatic updates
115
113
- Fixed broken legacy named photos
116
-
- Fixed photos being loaded with the wrong resolution
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
124
let photo = (el as PhotoListPhoto).Photo;
125
125
126
126
// === DEBUG ===
127
-
ctx.strokeStyle = '#f00';
128
-
ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height);
127
+
// ctx.strokeStyle = '#f00';
128
+
// ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height);
129
129
130
130
if(!photo.loaded)
131
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
108
109
109
let photo = this.Photos.find(x => x.path === data.path);
110
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.
111
114
112
115
this._lastLoaded = photo.index;
113
116
-1
src/Components/PhotoList.tsx
-1
src/Components/PhotoList.tsx
+85
-3
src/Components/PhotoViewer.tsx
+85
-3
src/Components/PhotoViewer.tsx
···
1
1
import { For, Show, createEffect, onCleanup, onMount } from "solid-js";
2
2
import { invoke } from '@tauri-apps/api/core';
3
3
import { WorldCache } from "./Structs/WorldCache";
4
-
import { animate, JSAnimation, utils } from "animejs";
4
+
import { animate, createSpring, JSAnimation, utils } from "animejs";
5
5
6
6
let PhotoViewer = () => {
7
7
let viewer: HTMLElement;
···
23
23
let allowedToOpenTray = false;
24
24
25
25
let authorProfileButton: HTMLDivElement;
26
+
27
+
let photoLayerManager!: HTMLDivElement;
26
28
27
29
let switchPhotoWithKey = ( e: KeyboardEvent ) => {
28
30
switch(e.key){
···
84
86
}
85
87
86
88
let copyImage = () => {
87
-
invoke('copy_image', { path: window.PhotoViewerManager.CurrentPhoto()!.path })
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 })
88
105
.then(() => {
89
106
utils.set('.copy-notif', { translateX: '-50%', translateY: '-100px' });
90
107
animate('.copy-notif', {
···
136
153
onMount(() => {
137
154
utils.set(photoControls, { translateX: '-50%' });
138
155
utils.set(photoTrayCloseBtn, { translateX: '-50%', opacity: 0, scale: '0.75', bottom: '10px' });
156
+
utils.set(photoLayerManager, { translateY: '20px', opacity: 0, display: 'none' });
139
157
140
158
window.addEventListener('keyup', switchPhotoWithKey);
141
159
···
153
171
viewerContextMenu.style.display = 'none';
154
172
}
155
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' }) });
156
181
});
157
182
158
183
viewerContextMenuButtons[0].onclick = async () => {
···
367
392
)
368
393
}
369
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
+
370
405
let toggleLayerManager = () => {
371
-
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
+
}
372
420
}
373
421
374
422
// TODO: Make layers selectable
375
423
376
424
return (
377
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
+
378
460
<div class="photo-context-menu" ref={( el ) => viewerContextMenu = el}>
379
461
<div ref={( el ) => viewerContextMenuButtons.push(el)}>Open file location</div>
380
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
38
left: 0;
39
39
padding: 10px;
40
40
border-radius: 5px;
41
-
background: #555a;
41
+
background: rgba(43, 43, 43, 0.76);
42
42
color: #aaa;
43
43
box-shadow: #0005 0 0 10px;
44
44
opacity: 0;
···
80
80
-webkit-user-select: none;
81
81
cursor: pointer;
82
82
z-index: 7;
83
-
box-shadow: #0008 0 0 10px;
83
+
background: rgba(43, 43, 43, 0.76);
84
84
}
85
85
86
86
.viewer-close{
···
157
157
left: 50%;
158
158
color: white;
159
159
transform: translateX(-50%) translateY(-100px);
160
-
background: #8885;
160
+
background: rgba(43, 43, 43, 0.76);
161
161
padding: 10px 40px;
162
162
backdrop-filter: blur(10px);
163
163
-webkit-backdrop-filter: blur(10px);
···
166
166
z-index: 12;
167
167
opacity: 0;
168
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;
169
192
}