mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-04-21 06:59:17 -04:00
added device info to "Libraries" in settings
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { Trash } from '@phosphor-icons/react';
|
||||
import { humanizeSize } from '@sd/client';
|
||||
import { Button, Card, Tooltip } from '@sd/ui';
|
||||
import { Icon } from '~/components';
|
||||
import { useLocale } from '~/hooks';
|
||||
|
||||
interface DeviceItemProps {
|
||||
pub_id: Key | null | undefined;
|
||||
name: string;
|
||||
os: string;
|
||||
storage_size: number;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
// unsure where to put pub_id/if this information is important for a user?
|
||||
export default (props: DeviceItemProps) => {
|
||||
const { t } = useLocale();
|
||||
|
||||
return (
|
||||
<Card className="flex items-center space-x-3 p-2">
|
||||
<Icon
|
||||
name={props.os == 'MacOS' || props.os == 'iOS' ? 'SilverBox' : 'Laptop'}
|
||||
alt="Device icon"
|
||||
size={24}
|
||||
className="mr-2"
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<h4 className="text-sm font-semibold">{props.name}</h4>
|
||||
<p className="text-xs text-ink-dull">
|
||||
{props.os}, {`${t('added')}`} {new Date(props.created_at).toLocaleDateString()}
|
||||
</p>
|
||||
<p className="text-xs text-ink-dull"></p>
|
||||
</div>
|
||||
<div className="text-xs text-ink-dull">{`${humanizeSize(props.storage_size)}`}</div>
|
||||
<Button
|
||||
className="!p-1"
|
||||
variant="gray"
|
||||
onClick={() => {
|
||||
// Handle device-specific actions like delete, edit, etc.
|
||||
}}
|
||||
>
|
||||
<Tooltip label={t('Delete device')}>
|
||||
<Trash className="size-4" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Pencil, Trash } from '@phosphor-icons/react';
|
||||
import { LibraryConfigWrapped } from '@sd/client';
|
||||
import { CaretDown, CaretRight, Pencil, Trash } from '@phosphor-icons/react';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { Key, useState } from 'react';
|
||||
import { LibraryConfigWrapped, useBridgeQuery } from '@sd/client';
|
||||
import { Button, ButtonLink, Card, dialogManager, Tooltip } from '@sd/ui';
|
||||
import { Icon } from '~/components';
|
||||
import { useLocale } from '~/hooks';
|
||||
|
||||
import DeleteDialog from './DeleteDialog';
|
||||
import DeviceItem from './DeviceItem';
|
||||
|
||||
interface Props {
|
||||
library: LibraryConfigWrapped;
|
||||
@@ -13,51 +16,115 @@ interface Props {
|
||||
|
||||
export default (props: Props) => {
|
||||
const { t } = useLocale();
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
const cloudDevicesList = useBridgeQuery(['cloud.devices.list'], {
|
||||
suspense: true,
|
||||
retry: false
|
||||
});
|
||||
|
||||
const toggleExpansion = () => {
|
||||
setIsExpanded((prev) => !prev);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="items-center">
|
||||
{/* <DotsSixVertical weight="bold" className="mt-[15px] mr-3 opacity-30" /> */}
|
||||
<Icon name="Database" alt="Database icon" size={30} className="mr-3" />
|
||||
<div className="my-0.5 flex-1">
|
||||
<h3 className="font-semibold">
|
||||
{props.library.config.name}
|
||||
{props.current && (
|
||||
<span className="ml-2 rounded bg-accent px-1.5 py-[2px] text-xs font-medium text-white">
|
||||
{t('current')}
|
||||
</span>
|
||||
)}
|
||||
</h3>
|
||||
<p className="mt-0.5 text-xs text-ink-dull">{props.library.uuid}</p>
|
||||
</div>
|
||||
<div className="flex flex-row items-center space-x-2">
|
||||
{/* <Button className="!p-1.5" variant="gray">
|
||||
<Tooltip label="TODO">
|
||||
<Database className="h-4 w-4" />
|
||||
</Tooltip>
|
||||
</Button> */}
|
||||
<ButtonLink
|
||||
className="!p-1.5"
|
||||
to={`/${props.library.uuid}/settings/library/general`}
|
||||
variant="gray"
|
||||
>
|
||||
<Tooltip label={t('edit_library')}>
|
||||
<Pencil className="size-4" />
|
||||
</Tooltip>
|
||||
</ButtonLink>
|
||||
<Button
|
||||
className="!p-1.5"
|
||||
variant="gray"
|
||||
onClick={() => {
|
||||
dialogManager.create((dp) => (
|
||||
<DeleteDialog {...dp} libraryUuid={props.library.uuid} />
|
||||
));
|
||||
}}
|
||||
>
|
||||
<Tooltip label={t('delete_library')}>
|
||||
<Trash className="size-4" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
<div>
|
||||
<Card className="items-center justify-between">
|
||||
<div className="flex cursor-pointer items-center">
|
||||
<Icon name="Database" alt="Database icon" size={30} className="mr-3" />
|
||||
<div className="my-0.5 flex-1">
|
||||
<h3 className="font-semibold">
|
||||
{props.library.config.name}
|
||||
{props.current && (
|
||||
<span className="ml-2 rounded bg-accent px-1.5 py-[2px] text-xs font-medium text-white">
|
||||
{t('current')}
|
||||
</span>
|
||||
)}
|
||||
</h3>
|
||||
<p className="mt-0.5 text-xs text-ink-dull">{props.library.uuid}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center space-x-2">
|
||||
<ButtonLink
|
||||
className="!p-1.5"
|
||||
to={`/${props.library.uuid}/settings/library/general`}
|
||||
variant="gray"
|
||||
>
|
||||
<Tooltip label={t('edit_library')}>
|
||||
<Pencil className="size-4" />
|
||||
</Tooltip>
|
||||
</ButtonLink>
|
||||
<Button
|
||||
className="!p-1.5"
|
||||
variant="gray"
|
||||
onClick={() => {
|
||||
dialogManager.create((dp) => (
|
||||
<DeleteDialog {...dp} libraryUuid={props.library.uuid} />
|
||||
));
|
||||
}}
|
||||
>
|
||||
<Tooltip label={t('delete_library')}>
|
||||
<Trash className="size-4" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
<Button onClick={toggleExpansion} className="!p-1.5" variant="gray">
|
||||
<Tooltip label={t('toggle devices')}>
|
||||
<motion.div
|
||||
animate={{ rotate: isExpanded ? 90 : 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<CaretRight size={16} className="ml-auto" />
|
||||
</motion.div>
|
||||
</Tooltip>
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<AnimatePresence>
|
||||
{isExpanded && (
|
||||
<motion.div
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: 'auto', opacity: 1 }}
|
||||
exit={{ height: 0, opacity: 0 }}
|
||||
className="relative mt-2 flex origin-top flex-col gap-1 pl-8"
|
||||
>
|
||||
<div className="absolute inset-y-0 left-6 mb-7 w-[2px] rounded-t-full bg-[#5E5F69] "></div>
|
||||
|
||||
{cloudDevicesList.data?.map(
|
||||
(
|
||||
device: {
|
||||
pub_id: Key | null | undefined;
|
||||
name: string;
|
||||
os: string;
|
||||
storage_size: number;
|
||||
created_at: string;
|
||||
},
|
||||
index: number
|
||||
) => (
|
||||
<div key={device.pub_id} className="relative flex items-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: index * 0.03 }}
|
||||
className="relative flex w-full items-center"
|
||||
>
|
||||
<div className="absolute left-[-0.5em] right-6 h-[2px] w-11 rounded-r-full bg-[#5E5F69]"></div>
|
||||
<div className="flex-1 pl-12">
|
||||
<DeviceItem
|
||||
pub_id={device.pub_id}
|
||||
name={device.name}
|
||||
os={device.os}
|
||||
storage_size={device.storage_size}
|
||||
created_at={device.created_at}
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"Add Device Description": "Scan the QR code or authenticate your device UUID to add a device.",
|
||||
"Connect": "Connect",
|
||||
"Connecting": "Connecting",
|
||||
"Delete device": "Remove this device from library",
|
||||
"about": "About",
|
||||
"about_vision_text": "Many of us have multiple cloud accounts, drives that aren’t backed up and data at risk of loss. We depend on cloud services like Google Photos and iCloud, but are locked in with limited capacity and almost zero interoperability between services and operating systems. Photo albums shouldn’t be stuck in a device ecosystem, or harvested for advertising data. They should be OS agnostic, permanent and personally owned. Data we create is our legacy, that will long outlive us—open source technology is the only way to ensure we retain absolute control over the data that defines our lives, at unlimited scale.",
|
||||
"about_vision_title": "Vision",
|
||||
@@ -8,7 +12,6 @@
|
||||
"account": "Account",
|
||||
"actions": "Actions",
|
||||
"add": "Add",
|
||||
"Add Device Description": "Scan the QR code or authenticate your device UUID to add a device.",
|
||||
"add_device": "Add Device",
|
||||
"add_file_extension_rule": "Add a file extension to the current rule",
|
||||
"add_filter": "Add Filter",
|
||||
@@ -19,6 +22,7 @@
|
||||
"add_location_tooltip": "Add path as an indexed location",
|
||||
"add_locations": "Add Locations",
|
||||
"add_tag": "Add Tag",
|
||||
"added": "added to library on",
|
||||
"added_location": "Added Location {{name}}",
|
||||
"adding_location": "Adding Location {{name}}",
|
||||
"advanced": "Advanced",
|
||||
@@ -102,14 +106,12 @@
|
||||
"config_other": "Configs",
|
||||
"configure_location": "Configure Location",
|
||||
"confirm": "Confirm",
|
||||
"Connect": "Connect",
|
||||
"connect_cloud": "Connect a cloud",
|
||||
"connect_cloud_description": "Connect your cloud accounts to Spacedrive.",
|
||||
"connect_device": "Connect a device",
|
||||
"connect_device_description": "Spacedrive works best on all your devices.",
|
||||
"connect_library_to_cloud": "Connect library to Spacedrive Cloud",
|
||||
"connected": "Connected",
|
||||
"Connecting": "Connecting",
|
||||
"connecting_library_to_cloud": "Connecting library to Spacedrive Cloud...",
|
||||
"contacts": "Contacts",
|
||||
"contacts_description": "Manage your contacts in Spacedrive.",
|
||||
@@ -169,7 +171,7 @@
|
||||
"delete_forever": "Delete Forever",
|
||||
"delete_info": "This will not delete the actual folder on disk. Preview media will be deleted.",
|
||||
"delete_library": "Delete Library",
|
||||
"delete_library_description": "This is permanent, your files will not be deleted, only the Spacedrive library.",
|
||||
"delete_library_description": "This is permanent! Original files will not be deleted, only the Spacedrive library.",
|
||||
"delete_location": "Delete Location",
|
||||
"delete_location_description": "Deleting a location will also remove all files associated with it from the Spacedrive database, the files themselves will not be deleted.",
|
||||
"delete_object": "Delete object",
|
||||
@@ -226,7 +228,7 @@
|
||||
"encrypt": "Encrypt",
|
||||
"encrypt_library": "Encrypt Library",
|
||||
"encrypt_library_coming_soon": "Library encryption coming soon",
|
||||
"encrypt_library_description": "Enable encryption for this library, this will only encrypt the Spacedrive database, not the files themselves.",
|
||||
"encrypt_library_description": "Enable encryption for this library. This will only encrypt the Spacedrive database, not the files themselves.",
|
||||
"encrypted": "Encrypted",
|
||||
"encrypted_one": "Encrypted",
|
||||
"encrypted_other": "Encrypted",
|
||||
@@ -323,8 +325,8 @@
|
||||
"general_settings": "General Settings",
|
||||
"general_settings_description": "General settings related to this client.",
|
||||
"general_shortcut_description": "General usage shortcuts",
|
||||
"generate_checksums": "Generate Checksums",
|
||||
"generatePreviewMedia_label": "Generate preview media for this Location",
|
||||
"generate_checksums": "Generate Checksums",
|
||||
"gitignore": "Git Ignore",
|
||||
"glob_description": "Glob (e.g., **/.git)",
|
||||
"go_back": "Go Back",
|
||||
@@ -712,10 +714,10 @@
|
||||
"switch_to_next_tab": "Switch to next tab",
|
||||
"switch_to_previous_tab": "Switch to previous tab",
|
||||
"sync": "Sync",
|
||||
"syncPreviewMedia_label": "Sync preview media for this Location with your devices",
|
||||
"sync_description": "Manage how Spacedrive syncs.",
|
||||
"sync_with_library": "Sync with Library",
|
||||
"sync_with_library_description": "If enabled, your keybinds will be synced with library, otherwise they will apply only to this client.",
|
||||
"syncPreviewMedia_label": "Sync preview media for this Location with your devices",
|
||||
"system": "System",
|
||||
"tag": "Tag",
|
||||
"tag_one": "Tag",
|
||||
@@ -744,6 +746,7 @@
|
||||
"thumbnailer_cpu_usage": "Thumbnailer CPU usage",
|
||||
"thumbnailer_cpu_usage_description": "Limit how much CPU the thumbnailer can use for background processing.",
|
||||
"to": "to",
|
||||
"toggle devices": "Toggle Library Devices",
|
||||
"toggle_all": "Toggle All",
|
||||
"toggle_command_palette": "Toggle command palette",
|
||||
"toggle_hidden_files": "Toggle hidden files",
|
||||
@@ -803,4 +806,4 @@
|
||||
"zoom": "Zoom",
|
||||
"zoom_in": "Zoom In",
|
||||
"zoom_out": "Zoom Out"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user