mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
|
import * as React from 'react';
|
||
|
import { Alert, Platform } from 'react-native';
|
||
|
import { DialogControl, DialogType, MenuChoice, PromptButton, PromptDialogData, PromptOptions } from '../types';
|
||
|
import { _ } from '@joplin/lib/locale';
|
||
|
import { useMemo, useRef } from 'react';
|
||
|
|
||
|
type SetPromptDialogs = React.Dispatch<React.SetStateAction<PromptDialogData[]>>;
|
||
|
|
||
|
const useDialogControl = (setPromptDialogs: SetPromptDialogs) => {
|
||
|
const nextDialogIdRef = useRef(0);
|
||
|
|
||
|
const dialogControl: DialogControl = useMemo(() => {
|
||
|
const onDismiss = (dialog: PromptDialogData) => {
|
||
|
setPromptDialogs(dialogs => dialogs.filter(d => d !== dialog));
|
||
|
};
|
||
|
|
||
|
const defaultButtons = [{ text: _('OK') }];
|
||
|
const control: DialogControl = {
|
||
|
info: (message: string) => {
|
||
|
return new Promise<void>((resolve) => {
|
||
|
control.prompt(_('Info'), message, [{
|
||
|
text: _('OK'),
|
||
|
onPress: () => resolve(),
|
||
|
}]);
|
||
|
});
|
||
|
},
|
||
|
error: (message: string) => {
|
||
|
return new Promise<void>((resolve) => {
|
||
|
control.prompt(_('Error'), message, [{
|
||
|
text: _('OK'),
|
||
|
onPress: () => resolve(),
|
||
|
}]);
|
||
|
});
|
||
|
},
|
||
|
prompt: (title: string, message: string, buttons: PromptButton[] = defaultButtons, options?: PromptOptions) => {
|
||
|
// Alert.alert doesn't work on web.
|
||
|
if (Platform.OS !== 'web') {
|
||
|
// Note: Alert.alert provides a more native style on iOS.
|
||
|
Alert.alert(title, message, buttons, options);
|
||
|
} else {
|
||
|
const cancelable = options?.cancelable ?? true;
|
||
|
const dialog: PromptDialogData = {
|
||
|
type: DialogType.Prompt,
|
||
|
key: `dialog-${nextDialogIdRef.current++}`,
|
||
|
title,
|
||
|
message,
|
||
|
buttons: buttons.map(button => ({
|
||
|
...button,
|
||
|
onPress: () => {
|
||
|
onDismiss(dialog);
|
||
|
button.onPress?.();
|
||
|
},
|
||
|
})),
|
||
|
onDismiss: cancelable ? () => onDismiss(dialog) : null,
|
||
|
};
|
||
|
|
||
|
setPromptDialogs(dialogs => {
|
||
|
return [
|
||
|
...dialogs,
|
||
|
dialog,
|
||
|
];
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
showMenu: function<T>(title: string, choices: MenuChoice<T>[]) {
|
||
|
return new Promise<T>((resolve) => {
|
||
|
const dismiss = () => onDismiss(dialog);
|
||
|
|
||
|
const dialog: PromptDialogData = {
|
||
|
type: DialogType.Menu,
|
||
|
key: `menu-dialog-${nextDialogIdRef.current++}`,
|
||
|
title: '',
|
||
|
message: title,
|
||
|
buttons: choices.map(choice => ({
|
||
|
text: choice.text,
|
||
|
onPress: () => {
|
||
|
dismiss();
|
||
|
resolve(choice.id);
|
||
|
},
|
||
|
})),
|
||
|
onDismiss: dismiss,
|
||
|
};
|
||
|
setPromptDialogs(dialogs => {
|
||
|
return [
|
||
|
...dialogs,
|
||
|
dialog,
|
||
|
];
|
||
|
});
|
||
|
});
|
||
|
},
|
||
|
};
|
||
|
|
||
|
return control;
|
||
|
}, [setPromptDialogs]);
|
||
|
return dialogControl;
|
||
|
};
|
||
|
|
||
|
export default useDialogControl;
|