dialog: add fragment

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/888/head
Varun Patil 2023-10-24 12:26:12 -07:00
parent 0a7914d9b9
commit 8588a7d190
3 changed files with 71 additions and 47 deletions

View File

@ -1,4 +1,8 @@
import { translate as t, translatePlural as n } from '@nextcloud/l10n';
import { FilePickerType, getFilePickerBuilder } from '@nextcloud/dialogs';
import { showError } from '@nextcloud/dialogs';
import { bus } from './event-bus';
import { fragment } from './fragment';
// https://github.com/nextcloud/server/blob/4b7ec0a0c18d4e2007565dc28ee214814940161e/core/src/OC/dialogs.js
const oc_dialogs = (<any>OC).dialogs;
@ -20,6 +24,12 @@ type ConfirmOptions = {
modal?: boolean;
};
// Register fragment navigation
bus.on('memories:fragment:pop:dialog', () => {
const selectors = ['button.oc-dialog-close', '[role="dialog"]:last-of-type button.modal-container__close'].join(', ');
(document.querySelector(selectors) as HTMLElement)?.click?.();
});
export function confirmDestructive(options: ConfirmOptions): Promise<boolean> {
const opts: ConfirmOptions = Object.assign(
{
@ -55,7 +65,10 @@ export function confirmDestructive(options: ConfirmOptions): Promise<boolean> {
// Watch changes to body
observer.observe(document.body, { childList: true });
return new Promise((resolve) => oc_dialogs.confirmDestructive(opts.message, opts.title, opts, resolve));
return fragment.wrap(
new Promise((resolve) => oc_dialogs.confirmDestructive(opts.message, opts.title, opts, resolve)),
fragment.types.dialog,
);
}
type PromptOptions = {
@ -84,6 +97,50 @@ export async function prompt(opts: PromptOptions): Promise<string | null> {
});
}
/**
* Choose a folder using the NC file picker
*
* @param title Title of the file picker
* @param initial Initial path
* @param type Type of the file picker
*
* @returns The path of the chosen folder
*/
export async function chooseNcFolder(
title: string,
initial: string = '/',
type: FilePickerType = FilePickerType.Choose,
) {
const picker = getFilePickerBuilder(title)
.setMultiSelect(false)
.setModal(true)
.setType(type)
.addMimeTypeFilter('httpd/unix-directory')
.allowDirectories()
.startAt(initial)
.build();
// Choose a folder
const promise = fragment.wrap(picker.pick(), fragment.types.dialog);
let folder = (await promise) || '/';
// Remove double slashes
folder = folder.replace(/\/+/g, '/');
// Look for any trailing or leading whitespace
if (folder.trim() !== folder) {
showError(
t(
'memories',
'The folder name "{folder}" has a leading or trailing whitespace. This may lead to errors and should be corrected.',
{ folder },
),
);
}
return folder;
}
/** Bespoke confirmation dialogs for re-use */
export const dialogs = {
moveToTrash: (count: number) =>

View File

@ -8,6 +8,7 @@ enum FragmentType {
sidebar = 'i',
editor = 'e',
settings = 'ss',
dialog = 'd',
}
/** Names of fragments */
@ -160,6 +161,18 @@ export const fragment = {
else await this.pop(type);
},
/**
* Wrap a promise as a route fragment.
*/
async wrap<T>(promise: Promise<T>, type: FragmentType, ...args: string[]): Promise<T> {
await this.push(type, ...args);
try {
return await promise;
} finally {
await this.pop(type);
}
},
get viewer() {
return this.get(FragmentType.viewer);
},

View File

@ -1,7 +1,4 @@
import { FilePickerType, getFilePickerBuilder } from '@nextcloud/dialogs';
import { getCurrentUser } from '@nextcloud/auth';
import { showError } from '@nextcloud/dialogs';
import { translate as t } from '@nextcloud/l10n';
import { API } from '../API';
import { constants as c } from './const';
@ -190,49 +187,6 @@ export function setupLivePhotoHooks(video: HTMLVideoElement) {
};
}
/**
* Choose a folder using the NC file picker
*
* @param title Title of the file picker
* @param initial Initial path
* @param type Type of the file picker
*
* @returns The path of the chosen folder
*/
export async function chooseNcFolder(
title: string,
initial: string = '/',
type: FilePickerType = FilePickerType.Choose,
) {
const picker = getFilePickerBuilder(title)
.setMultiSelect(false)
.setModal(true)
.setType(type)
.addMimeTypeFilter('httpd/unix-directory')
.allowDirectories()
.startAt(initial)
.build();
// Choose a folder
let folder = (await picker.pick()) || '/';
// Remove double slashes
folder = folder.replace(/\/+/g, '/');
// Look for any trailing or leading whitespace
if (folder.trim() !== folder) {
showError(
t(
'memories',
'The folder name "{folder}" has a leading or trailing whitespace. This may lead to errors and should be corrected.',
{ folder },
),
);
}
return folder;
}
/**
* Check if the provided Axios Error is a network error.
*/