Skip to content

Commit

Permalink
feat: add Delete button to context menu
Browse files Browse the repository at this point in the history
Split from: jellyfin#1951
  • Loading branch information
noaione committed Apr 23, 2023
1 parent 6fdc59f commit e8e0b75
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 2 deletions.
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@
"vue": "html"
},
"volar.autoCompleteRefs": true,
"volar.vueserver.fullCompletionList": true
"volar.vueserver.fullCompletionList": true,
"[vue]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
86 changes: 86 additions & 0 deletions frontend/src/components/Dialogs/ConfirmDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<v-dialog
class="confirm-dialog"
content-class="confirm-dialog"
:model-value="dialog"
:fullscreen="$vuetify.display.mobile"
@update:model-value="close">
<v-card height="100%" class="d-flex width-90">
<v-card-title class="text-center font-weight-light mt-4">
{{ title }}
</v-card-title>
<v-card-subtitle v-if="subtitle" class="pb-3 text-center">
{{ subtitle }}
</v-card-subtitle>

<v-divider />

<v-card-text class="text-center font-weight-normal px-4">
{{ text }}
</v-card-text>

<v-divider />

<v-card-actions class="d-flex flex-row align-center justify-center mb-4">
<v-btn variant="flat" width="8em" color="secondary" @click="close">
{{ t('cancel') }}
</v-btn>

<v-btn
variant="flat"
width="8em"
:color="confirmColor ?? 'error'"
@click="closeAndConfirm">
{{ confirmText }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n';
defineProps<{
dialog: boolean;
title: string;
text: string;
confirmText: string;
subtitle?: string;
confirmColor?: string;
}>();
const emit = defineEmits<{
(e: 'update:dialog', isOpen: boolean): void;
(e: 'onConfirm'): void;
}>();
const { t } = useI18n();
/**
* Close the dialog
*/
function close(): void {
emit('update:dialog', false);
}
/**
* Close the dialog and send confirmation event
*/
function closeAndConfirm(): void {
close();
emit('onConfirm');
}
</script>

<style lang="scss" scoped>
.confirm-dialog {
max-width: 100vw;
}
@media screen and (min-width: 600px) {
.confirm-dialog {
max-width: 70vw;
}
}
</style>
43 changes: 42 additions & 1 deletion frontend/src/components/Item/ItemMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@
v-if="item.Id"
v-model:dialog="metadataDialog"
:item-id="item.Id" />
<confirm-dialog
v-if="item.Id"
v-model:dialog="deleteDialog"
:title="t('deleteItem')"
:text="t('deleteItemDescription')"
:confirm-text="t('delete')"
@on-confirm="onDeleteConfirmed" />
</template>

<script setup lang="ts">
Expand All @@ -47,14 +54,16 @@ import { getItemRefreshApi } from '@jellyfin/sdk/lib/utils/api/item-refresh-api'
import IMdiPlaySpeed from 'virtual:icons/mdi/play-speed';
import IMdiArrowExpandUp from 'virtual:icons/mdi/arrow-expand-up';
import IMdiArrowExpandDown from 'virtual:icons/mdi/arrow-expand-down';
import IMdiDelete from 'virtual:icons/mdi/delete';
import IMdiDisc from 'virtual:icons/mdi/disc';
import IMdiPlaylistMinus from 'virtual:icons/mdi/playlist-minus';
import IMdiPlaylistPlus from 'virtual:icons/mdi/playlist-plus';
import IMdiPencilOutline from 'virtual:icons/mdi/pencil-outline';
import IMdiShuffle from 'virtual:icons/mdi/shuffle';
import IMdiReplay from 'virtual:icons/mdi/replay';
import IMdiRefresh from 'virtual:icons/mdi/refresh';
import { useRemote, useSnackbar } from '@/composables';
import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api';
import { useRemote, useRouter, useSnackbar } from '@/composables';
import { canInstantMix, canResume } from '@/utils/items';
import { TaskType } from '@/store/taskManager';
import { playbackManagerStore, taskManagerStore } from '@/store';
Expand All @@ -68,6 +77,7 @@ type MenuOption = {
const { t } = useI18n();
const remote = useRemote();
const router = useRouter();
const menuProps = withDefaults(
defineProps<{
Expand All @@ -90,6 +100,7 @@ const show = ref(false);
const positionX = ref<number | undefined>(undefined);
const positionY = ref<number | undefined>(undefined);
const metadataDialog = ref(false);
const deleteDialog = ref(false);
const playbackManager = playbackManagerStore();
const taskManager = taskManagerStore();
const isItemRefreshing = computed(
Expand Down Expand Up @@ -276,6 +287,16 @@ function getLibraryOptions(): MenuOption[] {
});
}
if (menuProps.item.CanDelete) {
libraryOptions.push({
title: t('deleteItem'),
icon: IMdiDelete,
action: (): void => {
deleteDialog.value = true;
}
});
}
return libraryOptions;
}
Expand All @@ -302,6 +323,26 @@ function onActivatorClick(): void {
positionY.value = undefined;
}
/**
* Handle deletion of the item
*/
async function onDeleteConfirmed(): Promise<void> {
if (!menuProps.item.Id) {
useSnackbar(t('failedToDeleteItem'), 'error');
return;
}
try {
await remote.sdk.newUserApi(getLibraryApi).deleteItem({
itemId: menuProps.item.Id
});
router.replace('/');
} catch {
useSnackbar(t('failedToDeleteItem'), 'error');
}
}
onMounted(() => {
const parentHtml = parent?.subTree.el;
Expand Down
1 change: 1 addition & 0 deletions frontend/types/global/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ declare module '@vue/runtime-core' {
CastButton: typeof import('./../../src/components/Layout/AppBar/Buttons/CastButton.vue')['default']
CollectionTabs: typeof import('./../../src/components/Item/CollectionTabs.vue')['default']
CommitLink: typeof import('./../../src/components/Layout/Navigation/CommitLink.vue')['default']
ConfirmDialog: typeof import('./../../src/components/Dialogs/ConfirmDialog.vue')['default']
DateInput: typeof import('./../../src/components/Item/Metadata/DateInput.vue')['default']
DraggableQueue: typeof import('./../../src/components/Playback/DraggableQueue.vue')['default']
FilterButton: typeof import('./../../src/components/Buttons/FilterButton.vue')['default']
Expand Down

0 comments on commit e8e0b75

Please sign in to comment.