Skip to content

Commit

Permalink
move should be working for both photo and albums
Browse files Browse the repository at this point in the history
  • Loading branch information
ildyria committed Sep 18, 2024
1 parent 72923bd commit 708f8e3
Show file tree
Hide file tree
Showing 13 changed files with 380 additions and 69 deletions.
62 changes: 62 additions & 0 deletions resources/js/components/forms/album/AlbumDeleteDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<Dialog v-model:visible="visible" pt:root:class="border-none" modal :dismissable-mask="true">
<template #container="{ closeCallback }">
<div>
<p class="p-9 text-center text-muted-color max-w-xl text-wrap">{{ confirmation }}</p>
<div class="flex">
<Button severity="secondary" class="w-full border-none rounded-none rounded-bl-xl font-bold" @click="closeCallback">
{{ $t("lychee.CANCEL") }}
</Button>
<Button severity="danger" class="w-full border-none rounded-none rounded-br-xl font-bold" @click="execute">{{
$t("lychee.DELETE")
}}</Button>
</div>
</div>
</template>
</Dialog>
</template>

<script setup lang="ts">
import { computed } from "vue";
import Button from "primevue/button";
import AlbumService from "@/services/album-service";
import { trans } from "laravel-vue-i18n";
import { sprintf } from "sprintf-js";
import Dialog from "primevue/dialog";
const props = defineProps<{
parentId: string | undefined;
album?: App.Http.Resources.Models.ThumbAlbumResource;
albumIds: string[];
}>();
const visible = defineModel<boolean>("visible", { default: false });
const emit = defineEmits<{
(e: "deleted"): void;
}>();
const confirmation = computed(() => {
if (props.album) {
return sprintf(trans("lychee.DELETE_ALBUM_CONFIRMATION"), props.album.title);
}
return sprintf(trans("lychee.DELETE_ALBUMS_CONFIRMATION"), props.albumIds.length);
});
function execute() {
let albumDeletedIds = [];
if (props.album) {
albumDeletedIds.push(props.album.id);
} else {
albumDeletedIds = props.albumIds as string[];
}
AlbumService.delete(albumDeletedIds).then(() => {
if (props.parentId === undefined) {
AlbumService.clearAlbums();
} else {
AlbumService.clearCache(props.parentId);
}
emit("deleted");
});
}
</script>
102 changes: 102 additions & 0 deletions resources/js/components/forms/album/AlbumMoveDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<template>
<Dialog v-model:visible="visible" pt:root:class="border-none" modal :dismissable-mask="true">
<template #container="{ closeCallback }">
<div v-if="titleMovedTo !== undefined">
<p class="p-9 text-center text-muted-color">{{ confirmation }}</p>
<div class="flex">
<Button severity="secondary" class="font-bold w-full border-none rounded-none rounded-bl-xl" @click="close">
{{ $t("lychee.CANCEL") }}
</Button>
<Button severity="contrast" class="font-bold w-full border-none rounded-none rounded-br-xl" @click="execute">
{{ $t("lychee.MOVE") }}
</Button>
</div>
</div>
<div v-else>
<div class="p-9">
<span v-if="props.album" class="font-bold">
{{ sprintf("Move %s to:", props.album.title) }}
</span>
<span v-else class="font-bold">
{{ sprintf("Move %d albums to:", props.albumIds?.length) }}
</span>
<SearchTargetAlbum :album-id="parentId" @selected="selected" />
</div>
<Button class="w-full font-bold rounded-none rounded-bl-xl rounded-br-xl border-none" severity="secondary" @click="closeCallback">
{{ $t("lychee.CANCEL") }}
</Button>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { computed, ref } from "vue";
import Button from "primevue/button";
import { trans } from "laravel-vue-i18n";
import { sprintf } from "sprintf-js";
import SearchTargetAlbum from "@/components/forms/album/SearchTargetAlbum.vue";
import AlbumService from "@/services/album-service";
import { useToast } from "primevue/usetoast";
import Dialog from "primevue/dialog";

const props = defineProps<{
parentId: string | undefined;
album?: App.Http.Resources.Models.ThumbAlbumResource;
albumIds: string[];
}>();

const visible = defineModel<boolean>("visible", { default: false });

const emit = defineEmits<{
(e: "moved"): void;
}>();

const toast = useToast();
const titleMovedTo = ref(undefined as string | undefined);
const destination_id = ref(undefined as string | undefined | null);
const confirmation = computed(() => {
if (props.album) {
return sprintf(trans("lychee.ALBUM_MOVE"), props.album.title, titleMovedTo.value);
}
return sprintf(trans("lychee.ALBUMS_MOVE"), titleMovedTo.value);
});

function selected(target: App.Http.Resources.Models.TargetAlbumResource) {
titleMovedTo.value = target.original;
destination_id.value = target.id;
}

function close() {
titleMovedTo.value = undefined;
destination_id.value = undefined;
visible.value = false;
}

function execute() {
if (destination_id.value === undefined) {
return;
}
let albumMovedIds = [];
if (props.album) {
albumMovedIds.push(props.album.id);
} else {
albumMovedIds = props.albumIds as string[];
}

AlbumService.move(destination_id.value, albumMovedIds).then(() => {
AlbumService.clearCache(destination_id.value);
toast.add({
severity: "success",
summary: "Album(s) moved to " + titleMovedTo.value,
life: 3000,
});
AlbumService.clearCache(destination_id.value);
if (props.parentId === undefined) {
AlbumService.clearAlbums();
} else {
AlbumService.clearCache(props.parentId);
}
emit("moved");
});
}
</script>
4 changes: 3 additions & 1 deletion resources/js/components/forms/photo/DialogPhotoDelete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<Button severity="secondary" class="w-full border-none rounded-none rounded-bl-xl font-bold" @click="closeCallback">
{{ $t("lychee.CANCEL") }}
</Button>
<!-- class="text-danger-600 font-bold hover:text-white hover:bg-danger-700 w-full bg-transparent border-none" -->
<Button severity="danger" class="w-full border-none rounded-none rounded-br-xl font-bold" @click="execute">{{
$t("lychee.DELETE")
}}</Button>
Expand All @@ -24,11 +23,13 @@ import { sprintf } from "sprintf-js";
import { computed } from "vue";
import Button from "primevue/button";
import { trans } from "laravel-vue-i18n";
import AlbumService from "@/services/album-service";
const toast = useToast();
const props = defineProps<{
photo?: App.Http.Resources.Models.PhotoResource;
photoIds?: string[];
albumId: string;
}>();
const visible = defineModel<boolean>("visible", { default: false });
Expand Down Expand Up @@ -56,6 +57,7 @@ function execute() {
summary: "Photo deleted",
life: 3000,
});
AlbumService.clearCache(props.albumId);
emit("deleted");
// Todo emit that we moved things.
});
Expand Down
5 changes: 5 additions & 0 deletions resources/js/components/forms/photo/DialogPhotoMove.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { computed, ref } from "vue";
import SearchTargetAlbum from "../album/SearchTargetAlbum.vue";
import Button from "primevue/button";
import Dialog from "primevue/dialog";
import AlbumService from "@/services/album-service";

const props = defineProps<{
photo?: App.Http.Resources.Models.PhotoResource;
Expand Down Expand Up @@ -87,6 +88,10 @@ function execute() {
summary: "Photo moved",
life: 3000,
});
// Clear the cache for the current album and the destination album
AlbumService.clearCache(props.albumId);
AlbumService.clearCache(destination_id.value);

emit("moved");
// Todo emit that we moved things.
});
Expand Down
60 changes: 60 additions & 0 deletions resources/js/composables/album/albumsRefresher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import AlbumService from "@/services/album-service";
import { AuthStore } from "@/stores/Auth";
import { LycheeStateStore } from "@/stores/LycheeState";
import { computed, ref, Ref } from "vue";

export function useAlbumsRefresher(auth: AuthStore, lycheeStore: LycheeStateStore, isLoginOpen: Ref<boolean>) {
const user = ref(undefined) as Ref<undefined | App.Http.Resources.Models.UserResource>;
const isKeybindingsHelpOpen = ref(false);
const smartAlbums = ref([]) as Ref<App.Http.Resources.Models.ThumbAlbumResource[]>;
const albums = ref([]) as Ref<App.Http.Resources.Models.ThumbAlbumResource[]>;
const sharedAlbums = ref([]) as Ref<App.Http.Resources.Models.ThumbAlbumResource[]>;
const rootConfig = ref(undefined) as Ref<undefined | App.Http.Resources.GalleryConfigs.RootConfig>;
const rootRights = ref(undefined) as Ref<undefined | App.Http.Resources.Rights.RootAlbumRightsResource>;
const selectableAlbums = computed(() => albums.value.concat(sharedAlbums.value));

function refresh() {
auth.getUser().then((data) => {
user.value = data;

// display popup if logged in and set..
if (user.value.id && lycheeStore.show_keybinding_help_popup) {
isKeybindingsHelpOpen.value = true;
}
});

AlbumService.getAll()
.then((data) => {
smartAlbums.value = (data.data.smart_albums as App.Http.Resources.Models.ThumbAlbumResource[]) ?? [];
albums.value = data.data.albums as App.Http.Resources.Models.ThumbAlbumResource[];
smartAlbums.value = smartAlbums.value.concat(data.data.tag_albums as App.Http.Resources.Models.ThumbAlbumResource[]);
sharedAlbums.value = (data.data.shared_albums as App.Http.Resources.Models.ThumbAlbumResource[]) ?? [];
rootConfig.value = data.data.config;
rootRights.value = data.data.rights;

if (albums.value.length === 0 && smartAlbums.value.length === 0 && sharedAlbums.value.length === 0) {
isLoginOpen.value = true;
}
})
.catch((error) => {
// We are required to login :)
if (error.response.status === 401) {
isLoginOpen.value = true;
} else {
console.error(error);
}
});
}

return {
user,
isKeybindingsHelpOpen,
smartAlbums,
albums,
sharedAlbums,
rootConfig,
rootRights,
selectableAlbums,
refresh,
};
}
3 changes: 0 additions & 3 deletions resources/js/composables/contextMenus/contextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ export function useContextMenu(selectors: Selectors, photoCallbacks: PhotoCallba
if (selectors.selectedAlbums.value.length > 0) {
return albumsMenu();
}

//! Should not happen.
console.log("No menu available??");
return [];
});

Expand Down
14 changes: 14 additions & 0 deletions resources/js/composables/modalsTriggers/deleteAlbumOpen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ref } from "vue";

export function useDeleteAlbumOpen() {
const isDeleteAlbumVisible = ref(false);

function toggleDeleteAlbum() {
isDeleteAlbumVisible.value = !isDeleteAlbumVisible.value;
}

return {
isDeleteAlbumVisible,
toggleDeleteAlbum,
};
}
14 changes: 14 additions & 0 deletions resources/js/composables/modalsTriggers/moveAlbumOpen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ref } from "vue";

export function useMoveAlbumOpen() {
const isMoveAlbumVisible = ref(false);

function toggleMoveAlbum() {
isMoveAlbumVisible.value = !isMoveAlbumVisible.value;
}

return {
isMoveAlbumVisible,
toggleMoveAlbum,
};
}
14 changes: 8 additions & 6 deletions resources/js/composables/selections/selections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { computed, ComputedRef, Ref, ref } from "vue";

export function useSelection(
config: Ref<App.Http.Resources.GalleryConfigs.AlbumConfig | null>,
album: ComputedRef<
| App.Http.Resources.Models.AlbumResource
| App.Http.Resources.Models.TagAlbumResource
| App.Http.Resources.Models.SmartAlbumResource
| undefined
>,
album:
| ComputedRef<
| App.Http.Resources.Models.AlbumResource
| App.Http.Resources.Models.TagAlbumResource
| App.Http.Resources.Models.SmartAlbumResource
| undefined
>
| undefined,
photos: Ref<{ [key: number]: App.Http.Resources.Models.PhotoResource }>,
albums: ComputedRef<{ [key: number]: App.Http.Resources.Models.ThumbAlbumResource }>,
) {
Expand Down
5 changes: 5 additions & 0 deletions resources/js/services/album-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ const AlbumService = {
}
},

clearAlbums(): void {
const axiosWithCache = axios as unknown as AxiosCacheInstance;
axiosWithCache.storage.remove("albums");
},

getAll(): Promise<AxiosResponse<App.Http.Resources.Collections.RootAlbumResource>> {
const requester = axios as unknown as AxiosCacheInstance;
return requester.get(`${Constants.API_URL}Albums`, { data: {}, id: "albums" });
Expand Down
Loading

0 comments on commit 708f8e3

Please sign in to comment.