mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-21 15:07:54 -04:00
* WIP * Some minor fixes for light theme - Fix `useIsDark` not reading the initial theme value (only reacting to theme changes) - Fix `Inspector` always showing a dark image when no item was selected - Fix `Thumb` video extension using black text on light theme * Improve form error messages - Fix `addLocationDialog` not registering the path input - Remove `@hookform/error-message` * Fix Dialog not respecting max-width - Fix ErrorMessage animation jumping * A lot of misc fixes - Implement an `useExplorerItemData` (cleaner fix for thumbnail flicker) - Fix broken image showing for `Thumb` due a rece condition when props are updated - Implement an `ExternalObject` component that hacks an alternative for `onLoad` and `onError` events for <object> - Fix `Overview` broken layout when `Inspector` is open and window is small - Improve `IndexerRuleEditor` UX in `AddLocationDialog` - Improve the way `IndexerRuleEditor` handles rules deletion - Fix `IndexerRuleEditor` closing the the new rule form even when the rule creation fails - Add an editable prop to `IndexerRuleEditor` to disable all editable functions - Fix `getIcon` fallbacking to Document instead of the dark version of an icon if it exists - Add some missing colors to white theme * Format * Fix Backup restore key dialog not resetting after error * Feedback * Format * Normalize imports * Fix ColorPicker export * Fix Thumb video ext not showing in MediaView with show square thumbnails - Fix AddLocationDialog Error resetting when changing IndexRules
124 lines
3.0 KiB
TypeScript
124 lines
3.0 KiB
TypeScript
import { Eye, EyeSlash } from 'phosphor-react';
|
|
import { useState } from 'react';
|
|
import { useLibraryMutation } from '@sd/client';
|
|
import { Button, Dialog, UseDialogProps, forms, useDialog } from '@sd/ui';
|
|
import { showAlertDialog } from '~/components';
|
|
import { usePlatform } from '~/util/Platform';
|
|
|
|
const { Input, useZodForm, z } = forms;
|
|
|
|
const schema = z.object({
|
|
masterPassword: z.string(),
|
|
secretKey: z.string(),
|
|
filePath: z.string()
|
|
});
|
|
|
|
export default (props: UseDialogProps) => {
|
|
const platform = usePlatform();
|
|
|
|
const restoreKeystoreMutation = useLibraryMutation('keys.restoreKeystore', {
|
|
onSuccess: (total) => {
|
|
showAlertDialog({
|
|
title: 'Import Successful',
|
|
value: `${total} ${total !== 1 ? 'keys were imported.' : 'key was imported.'}`
|
|
});
|
|
},
|
|
onError: () => {
|
|
showAlertDialog({
|
|
title: 'Import Error',
|
|
value: 'There was an error while restoring your backup.'
|
|
});
|
|
}
|
|
});
|
|
|
|
const [show, setShow] = useState({
|
|
masterPassword: false,
|
|
secretKey: false
|
|
});
|
|
|
|
const MPCurrentEyeIcon = show.masterPassword ? EyeSlash : Eye;
|
|
const SKCurrentEyeIcon = show.secretKey ? EyeSlash : Eye;
|
|
|
|
const form = useZodForm({
|
|
schema
|
|
});
|
|
|
|
return (
|
|
<Dialog
|
|
form={form}
|
|
onSubmit={(data) =>
|
|
data.filePath !== ''
|
|
? restoreKeystoreMutation
|
|
.mutateAsync({
|
|
password: data.masterPassword,
|
|
secret_key: data.secretKey,
|
|
path: data.filePath
|
|
})
|
|
.finally(() => form.reset())
|
|
: null
|
|
}
|
|
dialog={useDialog(props)}
|
|
title="Restore Keys"
|
|
description="Restore keys from a backup."
|
|
loading={restoreKeystoreMutation.isLoading}
|
|
ctaLabel="Restore"
|
|
>
|
|
<Input
|
|
placeholder="Master Password"
|
|
type={show.masterPassword ? 'text' : 'password'}
|
|
className="mb-2 mt-3"
|
|
right={
|
|
<Button
|
|
onClick={() =>
|
|
setShow((old) => ({ ...old, masterPassword: !old.masterPassword }))
|
|
}
|
|
size="icon"
|
|
type="button"
|
|
>
|
|
<MPCurrentEyeIcon className="h-4 w-4" />
|
|
</Button>
|
|
}
|
|
{...form.register('masterPassword', { required: true })}
|
|
/>
|
|
|
|
<Input
|
|
placeholder="Secret Key"
|
|
type={show.secretKey ? 'text' : 'password'}
|
|
className="mb-3"
|
|
right={
|
|
<Button
|
|
onClick={() => setShow((old) => ({ ...old, secretKey: !old.secretKey }))}
|
|
size="icon"
|
|
>
|
|
<SKCurrentEyeIcon className="h-4 w-4" />
|
|
</Button>
|
|
}
|
|
{...form.register('secretKey')}
|
|
/>
|
|
|
|
<div className="relative mb-2 flex grow">
|
|
<Button
|
|
size="sm"
|
|
variant={form.watch('filePath') !== '' ? 'accent' : 'gray'}
|
|
type="button"
|
|
onClick={() => {
|
|
if (!platform.openFilePickerDialog) {
|
|
// TODO: Support opening locations on web
|
|
showAlertDialog({
|
|
title: 'Error',
|
|
value: "System dialogs aren't supported on this platform."
|
|
});
|
|
return;
|
|
}
|
|
platform.openFilePickerDialog().then((result) => {
|
|
if (result) form.setValue('filePath', result as string);
|
|
});
|
|
}}
|
|
>
|
|
Select File
|
|
</Button>
|
|
</div>
|
|
</Dialog>
|
|
);
|
|
};
|