diff --git a/packages/frontend/src/pages/settings/import-export.vue b/packages/frontend/src/pages/settings/import-export.vue
index e000c608fe..1f23b6c9d6 100644
--- a/packages/frontend/src/pages/settings/import-export.vue
+++ b/packages/frontend/src/pages/settings/import-export.vue
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
{{ i18n.ts.import }}
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ i18n.ts.import }}
+ {{ i18n.ts.import }}
@@ -33,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
@@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
@@ -57,7 +57,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._exportOrImport.excludeInactiveUsers }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
@@ -66,7 +66,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._exportOrImport.withReplies }}
- {{ i18n.ts.import }}
+ {{ i18n.ts.import }}
@@ -76,12 +76,12 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
{{ i18n.ts.import }}
- {{ i18n.ts.import }}
+ {{ i18n.ts.import }}
@@ -91,12 +91,12 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
{{ i18n.ts.import }}
- {{ i18n.ts.import }}
+ {{ i18n.ts.import }}
@@ -106,12 +106,12 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
{{ i18n.ts.import }}
- {{ i18n.ts.import }}
+ {{ i18n.ts.import }}
@@ -121,12 +121,12 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.export }}
- {{ i18n.ts.export }}
+ {{ i18n.ts.export }}
{{ i18n.ts.import }}
- {{ i18n.ts.import }}
+ {{ i18n.ts.import }}
@@ -152,6 +152,7 @@ const excludeMutingUsers = ref(false);
const excludeInactiveUsers = ref(false);
const noteType = ref(null);
const withReplies = ref(defaultStore.state.defaultWithReplies);
+const disableButtons = ref(false);
const onExportSuccess = () => {
os.alert({
@@ -174,76 +175,110 @@ const onError = (ev) => {
});
};
+// HACK: purely theatrical lockout delay when the file picker is opened, because we actually can't tell
+// if it was canceled, and file upload can take a while. this is stupid and gets in the user's way if
+// they accidentally cancel out, but it's better than them spamming the import button 50 times
+const tempDisable = () => {
+ disableButtons.value = true;
+ return setTimeout(() => { disableButtons.value = false; }, 10000);
+};
+
const exportNotes = () => {
- misskeyApi('i/export-notes', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-notes', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportFavorites = () => {
- misskeyApi('i/export-favorites', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-favorites', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportClips = () => {
- misskeyApi('i/export-clips', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-clips', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportFollowing = () => {
+ disableButtons.value = true;
misskeyApi('i/export-following', {
excludeMuting: excludeMutingUsers.value,
excludeInactive: excludeInactiveUsers.value,
})
- .then(onExportSuccess).catch(onError);
+ .then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportBlocking = () => {
- misskeyApi('i/export-blocking', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-blocking', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportUserLists = () => {
- misskeyApi('i/export-user-lists', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-user-lists', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportMuting = () => {
- misskeyApi('i/export-mute', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-mute', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const exportAntennas = () => {
- misskeyApi('i/export-antennas', {}).then(onExportSuccess).catch(onError);
+ disableButtons.value = true;
+ misskeyApi('i/export-antennas', {}).then(onExportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const importFollowing = async (ev) => {
+ const timer = tempDisable();
const file = await selectFile(ev.currentTarget ?? ev.target);
+ clearTimeout(timer);
+ disableButtons.value = true;
misskeyApi('i/import-following', {
fileId: file.id,
withReplies: withReplies.value,
- }).then(onImportSuccess).catch(onError);
+ }).then(onImportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const importNotes = async (ev) => {
+ const timer = tempDisable();
const file = await selectFile(ev.currentTarget ?? ev.target);
+ clearTimeout(timer);
+ disableButtons.value = true;
misskeyApi('i/import-notes', {
fileId: file.id,
type: noteType.value,
- }).then(onImportSuccess).catch(onError);
+ }).then(onImportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const importUserLists = async (ev) => {
+ const timer = tempDisable();
const file = await selectFile(ev.currentTarget ?? ev.target);
- misskeyApi('i/import-user-lists', { fileId: file.id }).then(onImportSuccess).catch(onError);
+ clearTimeout(timer);
+ disableButtons.value = true;
+ misskeyApi('i/import-user-lists', { fileId: file.id }).then(onImportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const importMuting = async (ev) => {
+ const timer = tempDisable();
const file = await selectFile(ev.currentTarget ?? ev.target);
- misskeyApi('i/import-muting', { fileId: file.id }).then(onImportSuccess).catch(onError);
+ clearTimeout(timer);
+ disableButtons.value = true;
+ misskeyApi('i/import-muting', { fileId: file.id }).then(onImportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const importBlocking = async (ev) => {
+ const timer = tempDisable();
const file = await selectFile(ev.currentTarget ?? ev.target);
- misskeyApi('i/import-blocking', { fileId: file.id }).then(onImportSuccess).catch(onError);
+ clearTimeout(timer);
+ disableButtons.value = true;
+ misskeyApi('i/import-blocking', { fileId: file.id }).then(onImportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const importAntennas = async (ev) => {
+ const timer = tempDisable();
const file = await selectFile(ev.currentTarget ?? ev.target);
- misskeyApi('i/import-antennas', { fileId: file.id }).then(onImportSuccess).catch(onError);
+ clearTimeout(timer);
+ disableButtons.value = true;
+ misskeyApi('i/import-antennas', { fileId: file.id }).then(onImportSuccess).catch(onError).finally(() => { disableButtons.value = false; });
};
const headerActions = computed(() => []);