Skip to content

Commit a8a934f

Browse files
committed
feat: add confirmation dialog for file extension changes
- Introduced a dialog to confirm if users want to proceed with changing the file extension. - Added handling for dialog visibility to prevent recursion. (Since it looks like use must press escape to stop rename???) Signed-off-by: nfebe <[email protected]>
1 parent c74ba56 commit a8a934f

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

apps/files/src/store/renaming.ts

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,77 @@ import type { RenamingStore } from '../types'
88
import axios, { isAxiosError } from '@nextcloud/axios'
99
import { emit, subscribe } from '@nextcloud/event-bus'
1010
import { NodeStatus } from '@nextcloud/files'
11+
import { DialogBuilder } from '@nextcloud/dialogs'
1112
import { t } from '@nextcloud/l10n'
12-
import { basename, dirname } from 'path'
13+
import { basename, dirname, extname } from 'path'
1314
import { defineStore } from 'pinia'
1415
import logger from '../logger'
1516
import Vue from 'vue'
17+
import IconCancel from '@mdi/svg/svg/cancel.svg?raw'
18+
import IconCheck from '@mdi/svg/svg/check.svg?raw'
19+
20+
let isDialogVisible = false
21+
22+
const showWarningDialog = (oldExtension: string, newExtension: string): Promise<boolean> => {
23+
if (isDialogVisible) {
24+
return Promise.resolve(false)
25+
}
26+
27+
isDialogVisible = true
28+
29+
let message
30+
31+
if (!oldExtension && newExtension) {
32+
message = t(
33+
'files',
34+
'Adding the file extension "{new}" may render the file unreadable.',
35+
{ new: newExtension },
36+
)
37+
} else if (!newExtension) {
38+
message = t(
39+
'files',
40+
'Removing the file extension "{old}" may render the file unreadable.',
41+
{ old: oldExtension },
42+
)
43+
} else {
44+
message = t(
45+
'files',
46+
'Changing the file extension from "{old}" to "{new}" may render the file unreadable.',
47+
{ old: oldExtension, new: newExtension },
48+
)
49+
}
50+
51+
return new Promise((resolve) => {
52+
const dialog = new DialogBuilder()
53+
.setName(t('files', 'Change file extension'))
54+
.setText(message)
55+
.setButtons([
56+
{
57+
label: t('files', 'Keep {oldextension}', { oldextension: oldExtension }),
58+
icon: IconCancel,
59+
type: 'secondary',
60+
callback: () => {
61+
isDialogVisible = false
62+
resolve(false)
63+
},
64+
},
65+
{
66+
label: newExtension.length ? t('files', 'Use {newextension}', { newextension: newExtension }) : t('files', 'Remove extension'),
67+
icon: IconCheck,
68+
type: 'primary',
69+
callback: () => {
70+
isDialogVisible = false
71+
resolve(true)
72+
},
73+
},
74+
])
75+
.build()
76+
77+
dialog.show().then(() => {
78+
dialog.hide()
79+
})
80+
})
81+
}
1682

1783
export const useRenamingStore = function(...args) {
1884
const store = defineStore('renaming', {
@@ -36,6 +102,17 @@ export const useRenamingStore = function(...args) {
36102
const newName = this.newName.trim?.() || ''
37103
const oldName = this.renamingNode.basename
38104
const oldEncodedSource = this.renamingNode.encodedSource
105+
106+
// Check for extension change
107+
const oldExtension = extname(oldName)
108+
const newExtension = extname(newName)
109+
if (oldExtension !== newExtension) {
110+
const proceed = await showWarningDialog(oldExtension, newExtension)
111+
if (!proceed) {
112+
return false
113+
}
114+
}
115+
39116
if (oldName === newName) {
40117
return false
41118
}

0 commit comments

Comments
 (0)