diff --git a/app/Http/Resources/Models/PhotoResource.php b/app/Http/Resources/Models/PhotoResource.php index 3ef385a3540..0c68d1ff38f 100644 --- a/app/Http/Resources/Models/PhotoResource.php +++ b/app/Http/Resources/Models/PhotoResource.php @@ -123,7 +123,7 @@ private function preformatted(?SizeVariant $original): array 'lens' => $this->resource->lens === '' ? '' : sprintf('(%s)', $this->resource->lens), 'duration' => Helpers::secondsToHMS(intval($this->resource->aperture)), - 'fps' => $this->resource->focal ?? '', + 'fps' => $this->resource->focal === null ? $this->resource->focal . ' fps' : '', 'filesize' => Helpers::getSymbolByQuantity($original->filesize), 'resolution' => $original->width . ' x ' . $original->height, diff --git a/app/Livewire/Components/Pages/Gallery/Album.php b/app/Livewire/Components/Pages/Gallery/Album.php index a20d2752792..5871baf1068 100644 --- a/app/Livewire/Components/Pages/Gallery/Album.php +++ b/app/Livewire/Components/Pages/Gallery/Album.php @@ -48,6 +48,7 @@ class Album extends Component implements Reloadable public string $overlayType; public ?AbstractAlbum $album = null; #[Locked] public string $albumId; + #[Locked] public string $photoId; #[Locked] public ?string $header_url = null; #[Locked] public int $num_children = 0; #[Locked] public int $num_photos = 0; @@ -55,7 +56,6 @@ class Album extends Component implements Reloadable #[Locked] public PhotoFlags $photoFlags; public AlbumFlags $flags; public SessionFlags $sessionFlags; - public string $selectedPhoto = ''; /** * Boot method, called before any interaction with the component. @@ -67,9 +67,10 @@ public function boot(): void $this->albumFactory = resolve(AlbumFactory::class); } - public function mount(string $albumId): void + public function mount(string $albumId, string $photoId = ''): void { $this->albumId = $albumId; + $this->photoId = $photoId; $this->flags = new AlbumFlags(); $this->reloadPage(); @@ -84,6 +85,7 @@ public function render(): View { $this->sessionFlags = SessionFlags::get(); $this->flags->can_edit = Gate::check(AlbumPolicy::CAN_EDIT, [AbstractAlbum::class, $this->album]); + $this->flags->can_download = Gate::check(AlbumPolicy::CAN_DOWNLOAD, [AbstractAlbum::class, $this->album]); if ($this->flags->is_accessible) { $this->num_users = User::count(); diff --git a/app/Livewire/DTO/AlbumFlags.php b/app/Livewire/DTO/AlbumFlags.php index cec8431c14f..a696b3f5a02 100644 --- a/app/Livewire/DTO/AlbumFlags.php +++ b/app/Livewire/DTO/AlbumFlags.php @@ -14,6 +14,7 @@ public function __construct( public bool $is_map_accessible = false, public bool $is_base_album = false, public bool $can_edit = false, + public bool $can_download = false, public ?string $layout = null, ) { $this->is_map_accessible = Configs::getValueAsBool('map_display'); diff --git a/package-lock.json b/package-lock.json index e716d6983c4..d50daba92b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1069,9 +1069,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001564", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", - "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "funding": [ { "type": "opencollective", diff --git a/resources/js/app.ts b/resources/js/app.ts index 66f0c22d2e1..e97401334d3 100644 --- a/resources/js/app.ts +++ b/resources/js/app.ts @@ -3,7 +3,6 @@ import "lazysizes"; import { webauthn } from "./data/webauthn"; import { layouts } from "./directive/layouts"; import { views } from "./data/views"; -import { photoView } from "@/lycheeOrg/photoView.js"; // suggested in the Alpine docs: // make Alpine on window available for better DX @@ -11,7 +10,4 @@ window.Alpine = Alpine; document.addEventListener("alpine:init", () => { [...webauthn, ...layouts, ...views].forEach(Alpine.plugin); - - // @ts-expect-error - Alpine.data("photoView", photoView); }); diff --git a/resources/js/data/views/PhotoIntegration.ts b/resources/js/data/views/PhotoIntegration.ts index 03ae037a934..0338a53a29b 100644 --- a/resources/js/data/views/PhotoIntegration.ts +++ b/resources/js/data/views/PhotoIntegration.ts @@ -11,6 +11,7 @@ export default class PhotoIntegration { this.size_variants = photo.size_variants; this.precomputed = photo.precomputed; this.preformatted = photo.preformatted; + console.log(photo); } diff --git a/resources/js/data/views/albumFlagsView.ts b/resources/js/data/views/albumFlagsView.ts new file mode 100644 index 00000000000..289b07dd6db --- /dev/null +++ b/resources/js/data/views/albumFlagsView.ts @@ -0,0 +1,13 @@ +export default class AlbumFlagsView { + areDetailsOpen: boolean; + activeTab: number; + areSharingLinksOpen: boolean; + areNsfwVisible: boolean; + + constructor(areNsfwVisible: boolean) { + this.areDetailsOpen = false; + this.activeTab = 0; + this.areSharingLinksOpen = false; + this.areNsfwVisible = areNsfwVisible; + } +} diff --git a/resources/js/data/views/albumView.ts b/resources/js/data/views/albumView.ts index 5e1f0a52854..92dae13387b 100644 --- a/resources/js/data/views/albumView.ts +++ b/resources/js/data/views/albumView.ts @@ -2,9 +2,11 @@ import Selection from "@/lycheeOrg/actions/selection"; import AlbumActions from "@/lycheeOrg/actions/albumActions"; import type { Alpine } from "alpinejs"; import type { Photo } from "@/lycheeOrg/backend"; -import { AlbumView, AlbumViewBooleanKeys, OverlayTypes } from "./types"; -import UnpriviledgedKeys from "@/lycheeOrg/actions/unpriviledgedKeys"; +import { AlbumView, OverlayTypes } from "./types"; +import Keybindings from "@/lycheeOrg/actions/keybindings"; import PhotoIntegration from "./PhotoIntegration"; +import AlbumFlagsView from "./albumFlagsView"; +import PhotoFlagsView from "./photoFlagsView"; export const albumView = (Alpine: Alpine) => Alpine.data( @@ -13,7 +15,9 @@ export const albumView = (Alpine: Alpine) => ( nsfwAlbumsVisible: boolean, isFullscreen: boolean, + arePhotoDetailsOpen: boolean, canEdit: boolean, + canDownload: boolean, parent_id: string | null = null, albumIDs: string[] = [], photos: Photo[] = [], @@ -22,19 +26,16 @@ export const albumView = (Alpine: Alpine) => ): AlbumView => ({ select: new Selection(albumIDs, photos, canEdit), actions: new AlbumActions(), - unprivileged: new UnpriviledgedKeys(), - - detailsOpen: false, - detailsActiveTab: 0, + keybinds: new Keybindings(), + albumFlags: new AlbumFlagsView(nsfwAlbumsVisible), + photoFlags: new PhotoFlagsView(arePhotoDetailsOpen, overlayType), loginModalOpen: false, parent_id: parent_id, canEdit: canEdit, - sharingLinksOpen: false, - nsfwAlbumsVisible: nsfwAlbumsVisible, + canDownload: canDownload, isFullscreen: isFullscreen, selectedPhoto: null, - overlayType: overlayType, init() { if (selectedPhoto !== "") { @@ -47,13 +48,23 @@ export const albumView = (Alpine: Alpine) => } }, - silentToggle(elem: AlbumViewBooleanKeys) { - this[elem] = !this[elem]; + toggleFullScreen() { + this.isFullscreen = !this.isFullscreen; + + // @ts-expect-error + this.$wire.silentUpdate(); + }, + toggleNSFW() { + this.albumFlags.areNsfwVisible = !this.albumFlags.areNsfwVisible; // @ts-expect-error this.$wire.silentUpdate(); }, + toggleDetails() { + this.albumFlags.areDetailsOpen = !this.albumFlags.areDetailsOpen; + }, + handleContextPhoto(event: MouseEvent) { this.actions.handleContextPhoto(event, this); }, @@ -74,15 +85,33 @@ export const albumView = (Alpine: Alpine) => return; } - if (this.unprivileged.handleKeydown(event, this)) { + // [h] hide + // [f] fullscreen + // [l] login + // [k] keybinds + // [esc] back + if (this.keybinds.handleGlobalKeydown(event, this)) { return; } + if (this.selectedPhoto !== null && this.keybinds.handlePhotoKeyDown(event, this)) { + return; + } + + // ctrl + a if (this.select.handleKeydown(event)) { return; } - this.actions.handleKeydown(event, this); + // [n] new + // [u] upload + // [m] move (if selection is active) + // [r] rename (if selection is active) + // [d] description + // [i] info + // [m] move (without select) + // [r] rename (without select) + this.keybinds.handleAlbumKeydown(event, this); }, moveAlbums() { @@ -163,23 +192,11 @@ export const albumView = (Alpine: Alpine) => }, rotateOverlay() { - switch (this.overlayType) { - case "exif": - this.overlayType = "date"; - break; - case "date": - if (this.selectedPhoto?.photo.description !== "") { - this.overlayType = "description"; - } else { - this.overlayType = "none"; - } - break; - case "description": - this.overlayType = "none"; - break; - default: - this.overlayType = "exif"; + const photo: Photo | undefined = this.selectedPhoto?.photo; + if (photo === undefined) { + return; } + this.photoFlags.rotateOverlay(photo); }, previousStyle(): string { @@ -206,6 +223,8 @@ export const albumView = (Alpine: Alpine) => return; } this.selectedPhoto = new PhotoIntegration(previousPhoto); + // ! TODO fix me: make /livewire/ prefix dependent of .env + history.pushState({}, "", "/livewire/gallery/" + this.parent_id + "/" + previousId); }, nextStyle(): string { @@ -230,6 +249,8 @@ export const albumView = (Alpine: Alpine) => return; } this.selectedPhoto = new PhotoIntegration(nextPhoto); + // ! TODO fix me: make /livewire/ prefix dependent of .env + history.pushState({}, "", "/livewire/gallery/" + this.parent_id + "/" + nextId); }, }) ); diff --git a/resources/js/data/views/photoFlagsView.ts b/resources/js/data/views/photoFlagsView.ts new file mode 100644 index 00000000000..8f65db50470 --- /dev/null +++ b/resources/js/data/views/photoFlagsView.ts @@ -0,0 +1,34 @@ +import { Photo } from "@/lycheeOrg/backend"; +import { OverlayTypes } from "./types"; + +export default class PhotoFlagsView { + areDetailsOpen: boolean; + overlayType: OverlayTypes; + areEditOpen: boolean; + + constructor(areDetailsOpen: boolean, overlayType: OverlayTypes = "none") { + this.areDetailsOpen = areDetailsOpen; + this.overlayType = overlayType; + this.areEditOpen = false; + } + + rotateOverlay(photo: Photo) { + switch (this.overlayType) { + case "exif": + this.overlayType = "date"; + break; + case "date": + if (photo.description !== "") { + this.overlayType = "description"; + } else { + this.overlayType = "none"; + } + break; + case "description": + this.overlayType = "none"; + break; + default: + this.overlayType = "exif"; + } + } +} diff --git a/resources/js/data/views/types.d.ts b/resources/js/data/views/types.d.ts index 51ea6daa660..0a99f5e0750 100644 --- a/resources/js/data/views/types.d.ts +++ b/resources/js/data/views/types.d.ts @@ -1,42 +1,47 @@ import { Photo } from "@/lycheeOrg/backend"; import { AlpineComponent } from "alpinejs"; import PhotoIntegration from "./PhotoIntegration"; -import PhotoSwipe from "photoswipe"; import type Selection from "@/lycheeOrg/actions/selection"; import type AlbumActions from "@/lycheeOrg/actions/albumActions"; -import type UnpriviledgedKeys from "@/lycheeOrg/actions/unpriviledgedKeys"; +import type Keybindings from "@/lycheeOrg/actions/keybindings"; +import AlbumFlagsView from "./albumFlagsView"; +import PhotoFlagsView from "./photoFlagsView"; export interface PhotoArray { [key: string]: Photo; } -export type AlbumViewBooleanKeys = "isFullscreen" | "nsfwAlbumsVisible"; export type OverlayTypes = "none" | "exif" | "date" | "description"; export type AlbumView = AlpineComponent<{ select: Selection; actions: AlbumActions; - unprivileged: UnpriviledgedKeys; + keybinds: Keybindings; + albumFlags: AlbumFlagsView; + photoFlags: PhotoFlagsView; loginModalOpen: boolean; parent_id: string | null; canEdit: boolean; - detailsOpen: boolean; - detailsActiveTab: number; - sharingLinksOpen: boolean; - nsfwAlbumsVisible: boolean; + canDownload: boolean; isFullscreen: boolean; selectedPhoto: PhotoIntegration | null; - overlayType: OverlayTypes; - silentToggle: (elem: AlbumViewBooleanKeys) => void; + toggleFullScreen: () => void; + toggleNSFW: () => void; + toggleDetails: () => void; + handleContextPhoto: (event: MouseEvent) => void; handleClickPhoto: (event: MouseEvent) => void; handleContextAlbum: (event: MouseEvent) => void; handleKeydown: (event: KeyboardEvent) => void; + + // Album actions (right click) moveAlbums: () => void; mergeAlbums: () => void; renameAlbums: () => void; deleteAlbums: () => void; donwloadAlbums: () => void; + + // Photo actions (right click) copyPhotosTo: () => void; movePhotos: () => void; renamePhotos: () => void; @@ -46,6 +51,8 @@ export type AlbumView = AlpineComponent<{ unstarPhotos: () => void; setCover: () => void; donwloadPhotos: () => void; + + // Photo View rotateOverlay: () => void; previousStyle: () => string; nextStyle: () => string; diff --git a/resources/js/directive/layouts/justify.ts b/resources/js/directive/layouts/justify.ts index a9bb2db3fb2..e080aefa8bb 100644 --- a/resources/js/directive/layouts/justify.ts +++ b/resources/js/directive/layouts/justify.ts @@ -34,11 +34,6 @@ function useJustify(el: ElementWithXAttributes) { // @ts-expect-error const justifiedItems: ChildNodeWithDataStyle[] = [...el.childNodes].filter((gridItem) => gridItem.nodeType === 1); - justifiedItems.forEach((e) => { - e.dataset.width; - e.dataset.height; - }); - const ratio: number[] = justifiedItems.map(function (_photo) { const height = _photo.dataset.height; const width = _photo.dataset.width; diff --git a/resources/js/lycheeOrg/actions/albumActions.ts b/resources/js/lycheeOrg/actions/albumActions.ts index f68c886382a..fdb3a54ff3d 100644 --- a/resources/js/lycheeOrg/actions/albumActions.ts +++ b/resources/js/lycheeOrg/actions/albumActions.ts @@ -2,101 +2,6 @@ import PhotoIntegration from "@/data/views/PhotoIntegration"; import { AlbumView } from "@/data/views/types"; export default class AlbumActions { - handleKeydown(event: KeyboardEvent, view: AlbumView) { - const skipped = ["TEXTAREA", "INPUT", "SELECT"]; - - if (document.activeElement !== null && skipped.includes(document.activeElement.nodeName)) { - console.log("skipped: " + document.activeElement.nodeName); - return false; - } - - if (!view.canEdit) { - console.log("can't edit."); - return false; - } - - // n - if (event.keyCode === 78 && !view.detailsOpen) { - event.preventDefault(); - const params = ["forms.album.create", "", { parentID: view.parent_id }]; - // @ts-ignore - view.$wire.$dispatch("openModal", params); - return true; - } - - // u - if (event.keyCode === 85 && !view.detailsOpen) { - event.preventDefault(); - const params = ["forms.add.upload", "", { parentID: view.parent_id }]; - // @ts-ignore - view.$wire.$dispatch("openModal", params); - return true; - } - - // m on selected albums/photos - if (event.keyCode === 77 && view.select.selectedAlbums.length > 0) { - event.preventDefault(); - view.moveAlbums(); - return true; - } - if (event.keyCode === 77 && view.select.selectedPhotos.length > 0) { - event.preventDefault(); - view.movePhotos(); - return true; - } - - // r on selected albums - if (event.keyCode === 82 && view.select.selectedAlbums.length > 0) { - event.preventDefault(); - view.renameAlbums(); - return true; - } - if (event.keyCode === 82 && view.select.selectedPhotos.length > 0) { - event.preventDefault(); - view.renamePhotos(); - return true; - } - - // Following this point only if we are not in root. - if (view.parent_id === null) { - console.log("root"); - return true; - } - - // d - if (event.keyCode === 68 && !view.detailsOpen) { - event.preventDefault(); - view.detailsOpen = true; - view.detailsActiveTab = 0; - return true; - } - - // i - if (event.keyCode === 73) { - event.preventDefault(); - view.detailsOpen = !view.detailsOpen; - return true; - } - - // m - if (event.keyCode === 77 && !view.detailsOpen) { - event.preventDefault(); - view.detailsOpen = true; - view.detailsActiveTab = 2; - return true; - } - - // r - if (event.keyCode === 82 && !view.detailsOpen) { - event.preventDefault(); - view.detailsOpen = true; - view.detailsActiveTab = 0; - return true; - } - - return false; - } - handleContextPhoto(event: MouseEvent, view: AlbumView) { if (!view.canEdit) { return; @@ -136,6 +41,7 @@ export default class AlbumActions { } view.selectedPhoto = new PhotoIntegration(photo); console.log(view.selectedPhoto); + history.pushState({}, "", "/livewire/gallery/" + view.parent_id + "/" + photoId); return; } diff --git a/resources/js/lycheeOrg/actions/keybindings.ts b/resources/js/lycheeOrg/actions/keybindings.ts new file mode 100644 index 00000000000..5f7e736edc9 --- /dev/null +++ b/resources/js/lycheeOrg/actions/keybindings.ts @@ -0,0 +1,218 @@ +import type { AlbumView } from "@/data/views/types"; + +export default class Keybindings { + handleGlobalKeydown(event: KeyboardEvent, view: AlbumView): boolean { + const skipped = ["TEXTAREA", "INPUT", "SELECT"]; + + if (document.activeElement !== null && skipped.includes(document.activeElement.nodeName)) { + console.log("skipped: " + document.activeElement.nodeName); + return false; + } + + // h + if (event.keyCode === 72 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + console.log("toggle hidden albums:", view.albumFlags.areNsfwVisible); + view.toggleNSFW(); + return true; + } + + // f + if (event.keyCode === 70 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + view.toggleFullScreen(); + return true; + } + + // l + if (event.keyCode === 76) { + view.loginModalOpen = true; + console.log("open login"); + return true; + } + + // escape + if (event.keyCode === 27) { + if (view.photoFlags.areEditOpen) { + event.preventDefault(); + view.photoFlags.areEditOpen = false; + } else if (view.selectedPhoto !== null) { + event.preventDefault(); + view.selectedPhoto = null; + history.pushState({}, "", "/livewire/gallery/" + view.parent_id); + } else if (view.albumFlags.areDetailsOpen) { + event.preventDefault(); + view.albumFlags.areDetailsOpen = false; + } else if (view.parent_id !== null) { + event.preventDefault(); + // @ts-ignore + const url = document.getElementById("backButton").getAttribute("href"); + // @ts-ignore + Alpine.navigate(url); + } + return true; + } + + return false; + } + + handleAlbumKeydown(event: KeyboardEvent, view: AlbumView) { + const skipped = ["TEXTAREA", "INPUT", "SELECT"]; + + if (document.activeElement !== null && skipped.includes(document.activeElement.nodeName)) { + console.log("skipped: " + document.activeElement.nodeName); + return false; + } + + if (!view.canEdit) { + console.log("can't edit."); + return false; + } + + // n + if (event.keyCode === 78 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + const params = ["forms.album.create", "", { parentID: view.parent_id }]; + // @ts-ignore + view.$wire.$dispatch("openModal", params); + return true; + } + + // u + if (event.keyCode === 85 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + const params = ["forms.add.upload", "", { parentID: view.parent_id }]; + // @ts-ignore + view.$wire.$dispatch("openModal", params); + return true; + } + + // m on selected albums/photos + if (event.keyCode === 77 && view.select.selectedAlbums.length > 0) { + event.preventDefault(); + view.moveAlbums(); + return true; + } + if (event.keyCode === 77 && view.select.selectedPhotos.length > 0) { + event.preventDefault(); + view.movePhotos(); + return true; + } + + // r on selected albums + if (event.keyCode === 82 && view.select.selectedAlbums.length > 0) { + event.preventDefault(); + view.renameAlbums(); + return true; + } + if (event.keyCode === 82 && view.select.selectedPhotos.length > 0) { + event.preventDefault(); + view.renamePhotos(); + return true; + } + + // Following this point only if we are not in root. + if (view.parent_id === null) { + console.log("root"); + return true; + } + + // d + if (event.keyCode === 68 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + view.albumFlags.areDetailsOpen = true; + view.albumFlags.activeTab = 0; + return true; + } + + // i + if (event.keyCode === 73) { + event.preventDefault(); + view.albumFlags.areDetailsOpen = !view.albumFlags.areDetailsOpen; + return true; + } + + // m + if (event.keyCode === 77 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + view.albumFlags.areDetailsOpen = true; + view.albumFlags.activeTab = 2; + return true; + } + + // r + if (event.keyCode === 82 && !view.albumFlags.areDetailsOpen) { + event.preventDefault(); + view.albumFlags.areDetailsOpen = true; + view.albumFlags.activeTab = 0; + return true; + } + + return false; + } + + handlePhotoKeyDown(event: KeyboardEvent, view: AlbumView): boolean { + if (view.selectedPhoto === null) { + return false; + } + + // i + if (event.keyCode === 73) { + console.log("toggle details photo"); + event.preventDefault(); + view.photoFlags.areEditOpen = false; + view.photoFlags.areDetailsOpen = !view.photoFlags.areDetailsOpen; + return true; + } + + // o + if (event.keyCode === 79) { + view.rotateOverlay(); + return true; + } + + if (!view.canEdit) { + console.log("can't edit."); + return false; + } + + // del (46) or backspace (8) + if (event.ctrlKey && (event.keyCode === 46 || event.keyCode === 8)) { + // view.$wire.delete(); + return true; + } + + // e + if (event.keyCode === 69) { + view.photoFlags.areDetailsOpen = false; + view.photoFlags.areEditOpen = !view.photoFlags.areEditOpen; + return true; + } + + // m + if (event.keyCode === 77) { + // this.$wire.move(); + return true; + } + + // s + if (event.keyCode === 83) { + // this.$wire.set_star(); + return true; + } + + // ctrl + left arrow + if (event.keyCode === 37 && event.ctrlKey) { + // this.$wire.rotate_ccw(); + return true; + } + + // ctrl + right arrow + if (event.keyCode === 39 && event.ctrlKey) { + // this.$wire.rotate_cw(); + return true; + } + + return false; + } +} diff --git a/resources/js/lycheeOrg/actions/unpriviledgedKeys.ts b/resources/js/lycheeOrg/actions/unpriviledgedKeys.ts deleted file mode 100644 index 07b7ef3f8d5..00000000000 --- a/resources/js/lycheeOrg/actions/unpriviledgedKeys.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { AlbumView } from "@/data/views/types"; - -export default class UnpriviledgedKeys { - handleKeydown(event: KeyboardEvent, view: AlbumView): boolean { - const skipped = ["TEXTAREA", "INPUT", "SELECT"]; - - if (document.activeElement !== null && skipped.includes(document.activeElement.nodeName)) { - console.log("skipped: " + document.activeElement.nodeName); - return false; - } - - // h - if (event.keyCode === 72 && !view.detailsOpen) { - event.preventDefault(); - console.log("toggle hidden albums:", view.nsfwAlbumsVisible); - view.silentToggle("nsfwAlbumsVisible"); - return true; - } - - // f - if (event.keyCode === 70 && !view.detailsOpen) { - event.preventDefault(); - view.silentToggle("isFullscreen"); - return true; - } - - // l - if (event.keyCode === 76) { - view.loginModalOpen = true; - console.log("open login"); - return true; - } - - // escape - if (event.keyCode === 27) { - if (view.selectedPhoto !== null) { - event.preventDefault(); - view.selectedPhoto = null; - } else if (view.detailsOpen) { - event.preventDefault(); - view.detailsOpen = false; - } else if (view.parent_id !== null) { - event.preventDefault(); - // @ts-ignore - const url = document.getElementById("backButton").getAttribute("href"); - // @ts-ignore - Alpine.navigate(url); - } - return true; - } - - return false; - } -} diff --git a/resources/js/lycheeOrg/photoView.ts b/resources/js/lycheeOrg/photoView.ts deleted file mode 100644 index c6f63d2ebad..00000000000 --- a/resources/js/lycheeOrg/photoView.ts +++ /dev/null @@ -1,127 +0,0 @@ -// @ts-nocheck -export default { photoView }; - -export function photoView(detailsOpen_val, isFullscreen_val, has_description_val, overlayType_val, canEdit_val = false) { - return { - detailsOpen: detailsOpen_val, - isFullscreen: isFullscreen_val, - has_description: has_description_val, - overlayType: overlayType_val, - editOpen: false, - donwloadOpen: false, - canEdit: canEdit_val, - - silentToggle(elem) { - this[elem] = !this[elem]; - - this.$wire.silentUpdate(); - }, - - rotateOverlay() { - switch (this.overlayType) { - case "exif": - this.overlayType = "date"; - break; - case "date": - if (this.has_description) { - this.overlayType = "description"; - } else { - this.overlayType = "none"; - } - break; - case "description": - this.overlayType = "none"; - break; - default: - this.overlayType = "exif"; - } - }, - - handleKeydown(event) { - const skipped = ["TEXTAREA", "INPUT", "SELECT"]; - - if (skipped.includes(document.activeElement.nodeName)) { - console.log("skipped: " + document.activeElement.nodeName); - return; - } - console.log(document.activeElement.nodeName); - - // escape - if (event.keyCode === 27) { - if (this.detailsOpen) { - event.preventDefault(); - this.detailsOpen = false; - } else if (this.editOpen) { - event.preventDefault(); - this.editOpen = false; - } else { - event.preventDefault(); - const url = document.getElementById("backButton").getAttribute("href"); - Alpine.navigate(url); - } - return; - } - - // f - if (event.keyCode === 70) { - this.silentToggle("isFullscreen"); - return; - } - - // o - if (event.keyCode === 79) { - this.rotateOverlay(); - return; - } - - // i - if (event.keyCode === 73) { - this.detailsOpen = !this.detailsOpen; - this.editOpen = false; - return; - } - - if (!this.canEdit) { - console.log("can't edit."); - return; - } - - // del (46) or backspace (8) - if (event.ctrlKey && (event.keyCode === 46 || event.keyCode === 8)) { - this.$wire.delete(); - return; - } - - // e - if (event.keyCode === 69) { - this.detailsOpen = false; - this.editOpen = !this.editOpen; - return; - } - - // m - if (event.keyCode === 77) { - this.$wire.move(); - return; - } - - // s - if (event.keyCode === 83) { - this.$wire.set_star(); - return; - } - - // ctrl + left arrow - if (event.keyCode === 37 && event.ctrlKey) { - this.$wire.rotate_ccw(); - return; - } - - // ctrl + right arrow - if (event.keyCode === 39 && event.ctrlKey) { - this.$wire.rotate_cw(); - return; - } - }, - }; -} diff --git a/resources/views/components/gallery/album/menu/danger.blade.php b/resources/views/components/gallery/album/menu/danger.blade.php index dbcc24e5787..bdebd598e80 100644 --- a/resources/views/components/gallery/album/menu/danger.blade.php +++ b/resources/views/components/gallery/album/menu/danger.blade.php @@ -2,7 +2,7 @@
  • + x-bind:class="! albumFlags.activeTab === {{ $tab }} ? 'text-text-main-0 bg-red-800' : 'text-red-800'" + {{ $attributes }} x-on:click="albumFlags.activeTab = {{ $tab }}"> {{ $slot }}
  • diff --git a/resources/views/components/gallery/album/menu/item.blade.php b/resources/views/components/gallery/album/menu/item.blade.php index abc37dc8331..a1aec4ad47c 100644 --- a/resources/views/components/gallery/album/menu/item.blade.php +++ b/resources/views/components/gallery/album/menu/item.blade.php @@ -4,7 +4,7 @@ border-primary-500 text-primary-500 hover:border-primary-200 hover:text-primary-200 {{ $class }}" - x-bind:class="! detailsActiveTab === {{ $tab }} ? 'bg-primary-200/10' : ''" - {{ $attributes }} x-on:click="detailsActiveTab = {{ $tab }}"> + x-bind:class="! albumFlags.activeTab === {{ $tab }} ? 'bg-primary-200/10' : ''" + {{ $attributes }} x-on:click="albumFlags.activeTab = {{ $tab }}"> {{ $slot }} diff --git a/resources/views/components/gallery/album/menu/menu.blade.php b/resources/views/components/gallery/album/menu/menu.blade.php index e0d76b1b525..f23c5b412ee 100644 --- a/resources/views/components/gallery/album/menu/menu.blade.php +++ b/resources/views/components/gallery/album/menu/menu.blade.php @@ -1,6 +1,6 @@ @props(['album', 'userCount' => 0])
    + x-cloak x-show="albumFlags.areDetailsOpen" x-collapse.duration.300ms > -
    +
    @if ($userCount > 1) -
    +
    @endif -
    +
    -
    +
    {{-- We only display this menu if there are more than 1 user, it does not make sense otherwise --}} @if ($userCount > 1) diff --git a/resources/views/components/gallery/album/photo.blade.php b/resources/views/components/gallery/album/photo.blade.php index 2cf56c5752a..69dc4c56eb8 100644 --- a/resources/views/components/gallery/album/photo.blade.php +++ b/resources/views/components/gallery/album/photo.blade.php @@ -1,106 +1,99 @@ -{{--
    --}} -
    - - - - - - -
    -

    -

    -

    -

    - - -

    -

    - at fps -

    -

    - at ƒ / , -
    - -

    +
    +
    + + + + + + + + + +
    +