Files
spacedrive/interface/app/Spacedrop.tsx
Vítor Vasconcellos 0d3805339e [ENG-591] - Fix some funky behaviors (#827)
* 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
2023-05-20 03:11:10 +00:00

129 lines
3.0 KiB
TypeScript

import { useEffect, useState } from 'react';
import { PeerMetadata, useBridgeMutation, useBridgeSubscription } from '@sd/client';
import {
Dialog,
Select,
SelectOption,
UseDialogProps,
dialogManager,
forms,
useDialog
} from '@sd/ui';
import { getSpacedropState, subscribeSpacedropState } from '../hooks/useSpacedropState';
const { Input, useZodForm, z } = forms;
export function SpacedropUI() {
useEffect(() =>
subscribeSpacedropState(() => {
dialogManager.create((dp) => <SpacedropDialog {...dp} />);
})
);
useBridgeSubscription(['p2p.events'], {
onData(data) {
if (data.type === 'SpacedropRequest') {
dialogManager.create((dp) => (
<SpacedropRequestDialog
dropId={data.id}
name={data.name}
peerId={data.peer_id}
{...dp}
/>
));
}
}
});
return null;
}
function SpacedropDialog(props: UseDialogProps) {
const [[discoveredPeers], setDiscoveredPeer] = useState([new Map<string, PeerMetadata>()]);
const form = useZodForm({
// We aren't using this but it's required for the Dialog :(
schema: z.object({
target_peer: z.string()
})
});
useBridgeSubscription(['p2p.events'], {
onData(data) {
if (data.type === 'DiscoveredPeer') {
setDiscoveredPeer([discoveredPeers.set(data.peer_id, data.metadata)]);
}
}
});
const doSpacedrop = useBridgeMutation('p2p.spacedrop');
return (
<Dialog
form={form}
dialog={useDialog(props)}
title="Spacedrop a File"
loading={doSpacedrop.isLoading}
ctaLabel="Send"
closeLabel="Cancel"
onSubmit={(data) =>
doSpacedrop.mutateAsync({
file_path: getSpacedropState().droppedFiles,
peer_id: data.target_peer
})
}
>
<div className="space-y-2 py-2">
<Select
onChange={(e) => form.setValue('target_peer', e)}
value={form.watch('target_peer')}
>
{[...discoveredPeers.entries()].map(([peerId, metadata], index) => (
<SelectOption default={index === 0} key={peerId} value={peerId}>
{metadata.name}
</SelectOption>
))}
</Select>
</div>
</Dialog>
);
}
function SpacedropRequestDialog(
props: { dropId: string; name: string; peerId: string } & UseDialogProps
) {
const form = useZodForm({
// We aren't using this but it's required for the Dialog :(
schema: z.object({
file_path: z.string()
})
});
const acceptSpacedrop = useBridgeMutation('p2p.acceptSpacedrop');
// TODO: Automatically close this after 60 seconds cause the Spacedrop would have expired
return (
<Dialog
form={form}
dialog={useDialog(props)}
title="Received Spacedrop"
loading={acceptSpacedrop.isLoading}
ctaLabel="Send"
closeLabel="Cancel"
onSubmit={(data) => acceptSpacedrop.mutateAsync([props.dropId, data.file_path])}
onCancelled={() => acceptSpacedrop.mutate([props.dropId, null])}
>
<div className="space-y-2 py-2">
<p>File Name: {props.name}</p>
<p>Peer Id: {props.peerId}</p>
<Input
size="sm"
placeholder="/Users/oscar/Desktop/demo.txt"
className="w-full"
{...form.register('file_path')}
/>
</div>
</Dialog>
);
}