diff --git a/changelog b/changelog index 069a4cc..b6427a1 100644 --- a/changelog +++ b/changelog @@ -105,12 +105,15 @@ v0.2.5: v0.2.6: - Fixed photos not being loaded if they're too low resolution - - Added close to tray toggle - Fixed "Open in folder" not selecting files on linux - - Remove all sync stuff - Fixed scroll to top button not animating out - Fixed scroll to top button being ontop of filters menu - Fixed photo ordering - Fixed automatic updates - Fixed broken legacy named photos - - Fixed photos being loaded with the wrong resolution \ No newline at end of file + - Fixed photos being loaded with the wrong resolution + + - Added support for multilayer photos + - Added close to tray toggle + + - Remove all sync stuff \ No newline at end of file diff --git a/src/Components/Managers/PhotoListRenderingManager.tsx b/src/Components/Managers/PhotoListRenderingManager.tsx index 21cdd00..db3f7a6 100644 --- a/src/Components/Managers/PhotoListRenderingManager.tsx +++ b/src/Components/Managers/PhotoListRenderingManager.tsx @@ -124,8 +124,8 @@ export class PhotoListRenderingManager{ let photo = (el as PhotoListPhoto).Photo; // === DEBUG === - ctx.strokeStyle = '#f00'; - ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height); + // ctx.strokeStyle = '#f00'; + // ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height); if(!photo.loaded) // If the photo is not loaded, start a new task and load it in that task diff --git a/src/Components/Managers/PhotoManager.tsx b/src/Components/Managers/PhotoManager.tsx index 586cfdd..8e2f47f 100644 --- a/src/Components/Managers/PhotoManager.tsx +++ b/src/Components/Managers/PhotoManager.tsx @@ -108,6 +108,9 @@ export class PhotoManager{ let photo = this.Photos.find(x => x.path === data.path); if(!photo)return console.error('Cannot find photo.', data); + // NOTE: this is triggered by multilayer photo layers loading their metadata + // we don't need to store metadata of those photos as they inherit this + // data from the main photo. this._lastLoaded = photo.index; diff --git a/src/Components/PhotoList.tsx b/src/Components/PhotoList.tsx index b9ffe7b..a01021c 100644 --- a/src/Components/PhotoList.tsx +++ b/src/Components/PhotoList.tsx @@ -154,7 +154,6 @@ let PhotoList = () => { }) window.PhotoListRenderingManager.SetCanvas(photoContainer!); - render(); }); diff --git a/src/Components/PhotoViewer.tsx b/src/Components/PhotoViewer.tsx index b38d0b0..2faa227 100644 --- a/src/Components/PhotoViewer.tsx +++ b/src/Components/PhotoViewer.tsx @@ -1,7 +1,7 @@ import { For, Show, createEffect, onCleanup, onMount } from "solid-js"; import { invoke } from '@tauri-apps/api/core'; import { WorldCache } from "./Structs/WorldCache"; -import { animate, JSAnimation, utils } from "animejs"; +import { animate, createSpring, JSAnimation, utils } from "animejs"; let PhotoViewer = () => { let viewer: HTMLElement; @@ -24,6 +24,8 @@ let PhotoViewer = () => { let authorProfileButton: HTMLDivElement; + let photoLayerManager!: HTMLDivElement; + let switchPhotoWithKey = ( e: KeyboardEvent ) => { switch(e.key){ case 'Escape': @@ -84,7 +86,22 @@ let PhotoViewer = () => { } let copyImage = () => { - invoke('copy_image', { path: window.PhotoViewerManager.CurrentPhoto()!.path }) + let path; + let photo = window.PhotoViewerManager.CurrentPhoto()!; + + switch(layerManagerViewing){ + case LayerManagerView.DEFAULT: + path = photo.path; + break; + case LayerManagerView.ENVIRONMENT: + path = photo.environmentLayer!.path; + break; + case LayerManagerView.PLAYER: + path = photo.playerLayer!.path; + break; + } + + invoke('copy_image', { path }) .then(() => { utils.set('.copy-notif', { translateX: '-50%', translateY: '-100px' }); animate('.copy-notif', { @@ -136,6 +153,7 @@ let PhotoViewer = () => { onMount(() => { utils.set(photoControls, { translateX: '-50%' }); utils.set(photoTrayCloseBtn, { translateX: '-50%', opacity: 0, scale: '0.75', bottom: '10px' }); + utils.set(photoLayerManager, { translateY: '20px', opacity: 0, display: 'none' }); window.addEventListener('keyup', switchPhotoWithKey); @@ -155,6 +173,13 @@ let PhotoViewer = () => { }) }); + window.CloseAllPopups.push(() => { + layerManagerOpen = false; + if(layerManagerAnimation)layerManagerAnimation.cancel(); + + layerManagerAnimation = animate(photoLayerManager, { translateY: '20px', opacity: 0, duration: 100, onComplete: () => utils.set(photoLayerManager, { display: 'none' }) }); + }); + viewerContextMenuButtons[0].onclick = async () => { window.CloseAllPopups.forEach(p => p()); // Context Menu -> Open file location @@ -367,14 +392,71 @@ let PhotoViewer = () => { ) } + enum LayerManagerView{ + DEFAULT, + PLAYER, + ENVIRONMENT + } + + let layerManagerOpen = false; + let layerManagerAnimation: null | JSAnimation = null; + let layerManagerViewing = LayerManagerView.DEFAULT; + let toggleLayerManager = () => { - + if(layerManagerOpen){ + // Close + layerManagerOpen = false; + if(layerManagerAnimation)layerManagerAnimation.cancel(); + + layerManagerAnimation = animate(photoLayerManager, { translateY: '20px', opacity: 0, duration: 100, onComplete: () => utils.set(photoLayerManager, { display: 'none' }) }); + } else{ + // Open + layerManagerOpen = true; + if(layerManagerAnimation)layerManagerAnimation.cancel(); + + utils.set(photoLayerManager, { display: 'block' }); + layerManagerAnimation = animate(photoLayerManager, { translateY: '0px', opacity: 1, duration: 100 }); + } } // TODO: Make layers selectable return (
viewer = el}> +
+ +
{ + let photo = window.PhotoViewerManager.CurrentPhoto()?.playerLayer; + if(!photo)return; + + layerManagerViewing = LayerManagerView.PLAYER; + + imageViewer.src = (window.OS === "windows" ? "http://photo.localhost/" : 'photo://localhost/') + photo.path.split('\\').join('/') + "?full"; + imageViewer.crossOrigin = 'anonymous'; + }}>Player Layer
+
+ +
{ + let photo = window.PhotoViewerManager.CurrentPhoto()?.environmentLayer; + if(!photo)return; + + layerManagerViewing = LayerManagerView.ENVIRONMENT; + + imageViewer.src = (window.OS === "windows" ? "http://photo.localhost/" : 'photo://localhost/') + photo.path.split('\\').join('/') + "?full"; + imageViewer.crossOrigin = 'anonymous'; + }}>Environment Layer
+
+
{ + let photo = window.PhotoViewerManager.CurrentPhoto(); + if(!photo)return; + + layerManagerViewing = LayerManagerView.DEFAULT; + + imageViewer.src = (window.OS === "windows" ? "http://photo.localhost/" : 'photo://localhost/') + photo.path.split('\\').join('/') + "?full"; + imageViewer.crossOrigin = 'anonymous'; + }}>Default Layer
+
+
viewerContextMenu = el}>
viewerContextMenuButtons.push(el)}>Open file location
viewerContextMenuButtons.push(el)}>Copy image
diff --git a/src/css/tray.css b/src/css/tray.css index 4fa0df6..b5278d8 100644 --- a/src/css/tray.css +++ b/src/css/tray.css @@ -17,7 +17,7 @@ left: 50%; transform: translate(-50%); color: white; - background: #8885; + background: rgba(43, 43, 43, 0.76); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); box-shadow: #0008 0 0 10px; diff --git a/src/css/viewer.css b/src/css/viewer.css index 2efd5cd..38df7be 100644 --- a/src/css/viewer.css +++ b/src/css/viewer.css @@ -38,7 +38,7 @@ left: 0; padding: 10px; border-radius: 5px; - background: #555a; + background: rgba(43, 43, 43, 0.76); color: #aaa; box-shadow: #0005 0 0 10px; opacity: 0; @@ -80,7 +80,7 @@ -webkit-user-select: none; cursor: pointer; z-index: 7; - box-shadow: #0008 0 0 10px; + background: rgba(43, 43, 43, 0.76); } .viewer-close{ @@ -157,7 +157,7 @@ left: 50%; color: white; transform: translateX(-50%) translateY(-100px); - background: #8885; + background: rgba(43, 43, 43, 0.76); padding: 10px 40px; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); @@ -166,4 +166,27 @@ z-index: 12; opacity: 0; pointer-events: none; +} + +.photo-layer-manager{ + background: rgba(43, 43, 43, 0.76); + color: #fff; + padding: 10px; + backdrop-filter: blur(10px); + position: fixed; + bottom: 10px; + left: 10px; + border-radius: 10px; +} + +.photo-layer-manager-layer{ + cursor: pointer; + -webkit-user-select: none; + user-select: none; + padding: 5px 20px; + transition: 0.1s; +} + +.photo-layer-manager-layer:hover{ + color: #bbb; } \ No newline at end of file