mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 14:33:34 +00:00
Eng 142 fix interface hot reload (#252)
* fix interface hot reloading * AppPropsContext exsiting in App.tsx was the issue :D * type export fix
This commit is contained in:
parent
c0184ec9f0
commit
6978928db9
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -5,6 +5,7 @@
|
||||||
"consts",
|
"consts",
|
||||||
"countup",
|
"countup",
|
||||||
"creationdate",
|
"creationdate",
|
||||||
|
"fontsource",
|
||||||
"ipfs",
|
"ipfs",
|
||||||
"Keepsafe",
|
"Keepsafe",
|
||||||
"pathctx",
|
"pathctx",
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
"quicktime",
|
"quicktime",
|
||||||
"repr",
|
"repr",
|
||||||
"Roadmap",
|
"Roadmap",
|
||||||
|
"subpackage",
|
||||||
"svgr",
|
"svgr",
|
||||||
"tailwindcss",
|
"tailwindcss",
|
||||||
"titlebar",
|
"titlebar",
|
||||||
|
|
|
@ -65,7 +65,6 @@ function App() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SpacedriveInterface
|
<SpacedriveInterface
|
||||||
useMemoryRouter
|
|
||||||
transport={new Transport()}
|
transport={new Transport()}
|
||||||
platform={platform}
|
platform={platform}
|
||||||
convertFileSrc={function (url: string): string {
|
convertFileSrc={function (url: string): string {
|
||||||
|
|
|
@ -10,7 +10,6 @@ export default defineConfig({
|
||||||
port: 8001
|
port: 8001
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
//@ts-ignore
|
|
||||||
react({
|
react({
|
||||||
jsxRuntime: 'classic'
|
jsxRuntime: 'classic'
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -72,7 +72,6 @@ function App() {
|
||||||
{/* <header className="App-header"></header> */}
|
{/* <header className="App-header"></header> */}
|
||||||
<SpacedriveInterface
|
<SpacedriveInterface
|
||||||
demoMode
|
demoMode
|
||||||
useMemoryRouter={true}
|
|
||||||
transport={new Transport()}
|
transport={new Transport()}
|
||||||
platform={'browser'}
|
platform={'browser'}
|
||||||
convertFileSrc={function (url: string): string {
|
convertFileSrc={function (url: string): string {
|
||||||
|
|
|
@ -1,213 +1,27 @@
|
||||||
import '@fontsource/inter/variable.css';
|
import '@fontsource/inter/variable.css';
|
||||||
import { BaseTransport, ClientProvider, setTransport } from '@sd/client';
|
import { BaseTransport, ClientProvider, setTransport } from '@sd/client';
|
||||||
import { Button } from '@sd/ui';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import React, { useContext, useEffect } from 'react';
|
|
||||||
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
|
|
||||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||||
import {
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
Location,
|
|
||||||
MemoryRouter,
|
|
||||||
Outlet,
|
|
||||||
Route,
|
|
||||||
Routes,
|
|
||||||
useLocation,
|
|
||||||
useNavigate
|
|
||||||
} from 'react-router-dom';
|
|
||||||
|
|
||||||
import { Sidebar } from './components/file/Sidebar';
|
import { AppProps, AppPropsContext } from './AppPropsContext';
|
||||||
import { Modal } from './components/layout/Modal';
|
import { AppRouter } from './AppRouter';
|
||||||
import SlideUp from './components/transitions/SlideUp';
|
import { ErrorFallback } from './ErrorFallback';
|
||||||
import { useCoreEvents } from './hooks/useCoreEvents';
|
import { useCoreEvents } from './hooks/useCoreEvents';
|
||||||
import { ContentScreen } from './screens/Content';
|
|
||||||
import { DebugScreen } from './screens/Debug';
|
|
||||||
import { ExplorerScreen } from './screens/Explorer';
|
|
||||||
import { OverviewScreen } from './screens/Overview';
|
|
||||||
import { PhotosScreen } from './screens/Photos';
|
|
||||||
import { RedirectPage } from './screens/Redirect';
|
|
||||||
import { SettingsScreen } from './screens/Settings';
|
|
||||||
import { TagScreen } from './screens/Tag';
|
|
||||||
import AppearanceSettings from './screens/settings/AppearanceSettings';
|
|
||||||
import ContactsSettings from './screens/settings/ContactsSettings';
|
|
||||||
import ExperimentalSettings from './screens/settings/ExperimentalSettings';
|
|
||||||
import GeneralSettings from './screens/settings/GeneralSettings';
|
|
||||||
import KeysSettings from './screens/settings/KeysSetting';
|
|
||||||
import LibrarySettings from './screens/settings/LibrarySettings';
|
|
||||||
import LocationSettings from './screens/settings/LocationSettings';
|
|
||||||
import SecuritySettings from './screens/settings/SecuritySettings';
|
|
||||||
import SharingSettings from './screens/settings/SharingSettings';
|
|
||||||
import SyncSettings from './screens/settings/SyncSettings';
|
|
||||||
import TagsSettings from './screens/settings/TagsSettings';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
export const AppPropsContext = React.createContext<AppProps | null>(null);
|
function RouterContainer() {
|
||||||
|
|
||||||
export type Platform = 'browser' | 'macOS' | 'windows' | 'linux';
|
|
||||||
|
|
||||||
export interface AppProps {
|
|
||||||
transport: BaseTransport;
|
|
||||||
platform: Platform;
|
|
||||||
convertFileSrc: (url: string) => string;
|
|
||||||
openDialog: (options: { directory?: boolean }) => Promise<string | string[] | null>;
|
|
||||||
onClose?: () => void;
|
|
||||||
onMinimize?: () => void;
|
|
||||||
onFullscreen?: () => void;
|
|
||||||
onOpen?: (path: string) => void;
|
|
||||||
isFocused?: boolean;
|
|
||||||
useMemoryRouter: boolean;
|
|
||||||
demoMode?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
function AppLayout() {
|
|
||||||
const appProps = useContext(AppPropsContext);
|
|
||||||
|
|
||||||
const isWindowRounded = appProps?.platform === 'macOS';
|
|
||||||
const hasWindowBorder = appProps?.platform !== 'browser' && appProps?.platform !== 'windows';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onContextMenu={(e) => {
|
|
||||||
// TODO: allow this on some UI text at least
|
|
||||||
// disable default browser context menu
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}}
|
|
||||||
className={clsx(
|
|
||||||
'flex flex-row h-screen overflow-hidden text-gray-900 select-none dark:text-white',
|
|
||||||
isWindowRounded && 'rounded-xl',
|
|
||||||
hasWindowBorder && 'border border-gray-200 dark:border-gray-500'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Sidebar />
|
|
||||||
<div className="flex flex-col w-full min-h-full">
|
|
||||||
{/* <TopBar /> */}
|
|
||||||
|
|
||||||
<div className="relative flex w-full min-h-full bg-white dark:bg-gray-650">
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function SettingsRoutes({ modal = false }) {
|
|
||||||
return (
|
|
||||||
<SlideUp>
|
|
||||||
<Routes>
|
|
||||||
<Route
|
|
||||||
path={modal ? '/settings' : '/'}
|
|
||||||
element={modal ? <Modal children={<SettingsScreen />} /> : <SettingsScreen />}
|
|
||||||
>
|
|
||||||
<Route index element={<GeneralSettings />} />
|
|
||||||
|
|
||||||
<Route path="appearance" element={<AppearanceSettings />} />
|
|
||||||
<Route path="contacts" element={<ContactsSettings />} />
|
|
||||||
<Route path="experimental" element={<ExperimentalSettings />} />
|
|
||||||
<Route path="general" element={<GeneralSettings />} />
|
|
||||||
<Route path="keys" element={<KeysSettings />} />
|
|
||||||
<Route path="library" element={<LibrarySettings />} />
|
|
||||||
<Route path="security" element={<SecuritySettings />} />
|
|
||||||
<Route path="locations" element={<LocationSettings />} />
|
|
||||||
<Route path="sharing" element={<SharingSettings />} />
|
|
||||||
<Route path="sync" element={<SyncSettings />} />
|
|
||||||
<Route path="tags" element={<TagsSettings />} />
|
|
||||||
</Route>
|
|
||||||
</Routes>
|
|
||||||
</SlideUp>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Router() {
|
|
||||||
let location = useLocation();
|
|
||||||
let state = location.state as { backgroundLocation?: Location };
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log({ url: location.pathname });
|
|
||||||
}, [state]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Routes location={state?.backgroundLocation || location}>
|
|
||||||
<Route path="/" element={<AppLayout />}>
|
|
||||||
<Route index element={<RedirectPage to="/overview" />} />
|
|
||||||
<Route path="overview" element={<OverviewScreen />} />
|
|
||||||
<Route path="content" element={<ContentScreen />} />
|
|
||||||
<Route path="photos" element={<PhotosScreen />} />
|
|
||||||
<Route path="debug" element={<DebugScreen />} />
|
|
||||||
<Route path="settings/*" element={<SettingsRoutes />} />
|
|
||||||
<Route path="explorer/:id" element={<ExplorerScreen />} />
|
|
||||||
<Route path="tag/:id" element={<TagScreen />} />
|
|
||||||
<Route path="*" element={<NotFound />} />
|
|
||||||
</Route>
|
|
||||||
</Routes>
|
|
||||||
{state?.backgroundLocation && <SettingsRoutes modal />}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
data-tauri-drag-region
|
|
||||||
role="alert"
|
|
||||||
className="flex flex-col items-center justify-center w-screen h-screen p-4 border border-gray-200 rounded-lg dark:border-gray-650 bg-gray-50 dark:bg-gray-650 dark:text-white"
|
|
||||||
>
|
|
||||||
<p className="m-3 text-sm font-bold text-gray-400">APP CRASHED</p>
|
|
||||||
<h1 className="text-2xl font-bold">We're past the event horizon...</h1>
|
|
||||||
<pre className="m-2">Error: {error.message}</pre>
|
|
||||||
<div className="flex flex-row space-x-2">
|
|
||||||
<Button variant="primary" className="mt-2" onClick={resetErrorBoundary}>
|
|
||||||
Reload
|
|
||||||
</Button>
|
|
||||||
<Button className="mt-2" onClick={resetErrorBoundary}>
|
|
||||||
Send report
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function NotFound() {
|
|
||||||
const navigate = useNavigate();
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
data-tauri-drag-region
|
|
||||||
role="alert"
|
|
||||||
className="flex flex-col items-center justify-center w-full h-full p-4 rounded-lg dark:text-white"
|
|
||||||
>
|
|
||||||
<p className="m-3 mt-20 text-sm font-semibold text-gray-500 uppercase">Error: 404</p>
|
|
||||||
<h1 className="text-4xl font-bold">You chose nothingness.</h1>
|
|
||||||
<div className="flex flex-row space-x-2">
|
|
||||||
<Button variant="primary" className="mt-4" onClick={() => navigate(-1)}>
|
|
||||||
Go Back
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MemoryRouterContainer() {
|
|
||||||
useCoreEvents();
|
useCoreEvents();
|
||||||
return (
|
return (
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<Router />
|
<AppRouter />
|
||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function BrowserRouterContainer() {
|
|
||||||
useCoreEvents();
|
|
||||||
return (
|
|
||||||
<MemoryRouter>
|
|
||||||
<Router />
|
|
||||||
</MemoryRouter>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function bindCoreEvent() {}
|
|
||||||
|
|
||||||
export default function App(props: AppProps) {
|
export default function App(props: AppProps) {
|
||||||
// TODO: This is a hack and a better solution should probably be found.
|
// TODO: This is a hack and a better solution should probably be found.
|
||||||
// This exists so that the queryClient can be accessed within the subpackage '@sd/client'.
|
// This exists so that the queryClient can be accessed within the subpackage '@sd/client'.
|
||||||
|
@ -218,13 +32,11 @@ export default function App(props: AppProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* @ts-ignore */}
|
|
||||||
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => {}}>
|
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => {}}>
|
||||||
{/* @ts-ignore */}
|
|
||||||
<QueryClientProvider client={queryClient} contextSharing={false}>
|
<QueryClientProvider client={queryClient} contextSharing={false}>
|
||||||
<AppPropsContext.Provider value={Object.assign({ isFocused: true }, props)}>
|
<AppPropsContext.Provider value={Object.assign({ isFocused: true }, props)}>
|
||||||
<ClientProvider>
|
<ClientProvider>
|
||||||
{props.useMemoryRouter ? <MemoryRouterContainer /> : <BrowserRouterContainer />}
|
<RouterContainer />
|
||||||
</ClientProvider>
|
</ClientProvider>
|
||||||
</AppPropsContext.Provider>
|
</AppPropsContext.Provider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
|
|
35
packages/interface/src/AppLayout.tsx
Normal file
35
packages/interface/src/AppLayout.tsx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { AppPropsContext } from './AppPropsContext';
|
||||||
|
import { Sidebar } from './components/file/Sidebar';
|
||||||
|
|
||||||
|
export function AppLayout() {
|
||||||
|
const appProps = useContext(AppPropsContext);
|
||||||
|
|
||||||
|
const isWindowRounded = appProps?.platform === 'macOS';
|
||||||
|
const hasWindowBorder = appProps?.platform !== 'browser' && appProps?.platform !== 'windows';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onContextMenu={(e) => {
|
||||||
|
// TODO: allow this on some UI text at least / disable default browser context menu
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
className={clsx(
|
||||||
|
'flex flex-row h-screen overflow-hidden text-gray-900 select-none dark:text-white',
|
||||||
|
isWindowRounded && 'rounded-xl',
|
||||||
|
hasWindowBorder && 'border border-gray-200 dark:border-gray-500'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Sidebar />
|
||||||
|
<div className="flex flex-col w-full min-h-full">
|
||||||
|
<div className="relative flex w-full min-h-full bg-white dark:bg-gray-650">
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
19
packages/interface/src/AppPropsContext.tsx
Normal file
19
packages/interface/src/AppPropsContext.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { BaseTransport } from '@sd/client';
|
||||||
|
import { createContext } from 'react';
|
||||||
|
|
||||||
|
export const AppPropsContext = createContext<AppProps | null>(null);
|
||||||
|
|
||||||
|
export type Platform = 'browser' | 'macOS' | 'windows' | 'linux';
|
||||||
|
|
||||||
|
export interface AppProps {
|
||||||
|
transport: BaseTransport;
|
||||||
|
platform: Platform;
|
||||||
|
convertFileSrc: (url: string) => string;
|
||||||
|
openDialog: (options: { directory?: boolean }) => Promise<string | string[] | null>;
|
||||||
|
onClose?: () => void;
|
||||||
|
onMinimize?: () => void;
|
||||||
|
onFullscreen?: () => void;
|
||||||
|
onOpen?: (path: string) => void;
|
||||||
|
isFocused?: boolean;
|
||||||
|
demoMode?: boolean;
|
||||||
|
}
|
64
packages/interface/src/AppRouter.tsx
Normal file
64
packages/interface/src/AppRouter.tsx
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { Route, Routes, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { AppLayout } from './AppLayout';
|
||||||
|
import { NotFound } from './NotFound';
|
||||||
|
import { ContentScreen } from './screens/Content';
|
||||||
|
import { DebugScreen } from './screens/Debug';
|
||||||
|
import { ExplorerScreen } from './screens/Explorer';
|
||||||
|
import { OverviewScreen } from './screens/Overview';
|
||||||
|
import { PhotosScreen } from './screens/Photos';
|
||||||
|
import { RedirectPage } from './screens/Redirect';
|
||||||
|
import { SettingsScreen } from './screens/Settings';
|
||||||
|
import { TagScreen } from './screens/Tag';
|
||||||
|
import AppearanceSettings from './screens/settings/AppearanceSettings';
|
||||||
|
import ContactsSettings from './screens/settings/ContactsSettings';
|
||||||
|
import ExperimentalSettings from './screens/settings/ExperimentalSettings';
|
||||||
|
import GeneralSettings from './screens/settings/GeneralSettings';
|
||||||
|
import KeysSettings from './screens/settings/KeysSetting';
|
||||||
|
import LibrarySettings from './screens/settings/LibrarySettings';
|
||||||
|
import LocationSettings from './screens/settings/LocationSettings';
|
||||||
|
import SecuritySettings from './screens/settings/SecuritySettings';
|
||||||
|
import SharingSettings from './screens/settings/SharingSettings';
|
||||||
|
import SyncSettings from './screens/settings/SyncSettings';
|
||||||
|
import TagsSettings from './screens/settings/TagsSettings';
|
||||||
|
|
||||||
|
export function AppRouter() {
|
||||||
|
let location = useLocation();
|
||||||
|
let state = location.state as { backgroundLocation?: Location };
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log({ url: location.pathname });
|
||||||
|
}, [state]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Routes location={state?.backgroundLocation || location}>
|
||||||
|
<Route path="/" element={<AppLayout />}>
|
||||||
|
<Route index element={<RedirectPage to="/overview" />} />
|
||||||
|
<Route path="overview" element={<OverviewScreen />} />
|
||||||
|
<Route path="content" element={<ContentScreen />} />
|
||||||
|
<Route path="photos" element={<PhotosScreen />} />
|
||||||
|
<Route path="debug" element={<DebugScreen />} />
|
||||||
|
<Route path={'settings'} element={<SettingsScreen />}>
|
||||||
|
<Route index element={<GeneralSettings />} />
|
||||||
|
<Route path="appearance" element={<AppearanceSettings />} />
|
||||||
|
<Route path="contacts" element={<ContactsSettings />} />
|
||||||
|
<Route path="experimental" element={<ExperimentalSettings />} />
|
||||||
|
<Route path="general" element={<GeneralSettings />} />
|
||||||
|
<Route path="keys" element={<KeysSettings />} />
|
||||||
|
<Route path="library" element={<LibrarySettings />} />
|
||||||
|
<Route path="security" element={<SecuritySettings />} />
|
||||||
|
<Route path="locations" element={<LocationSettings />} />
|
||||||
|
<Route path="sharing" element={<SharingSettings />} />
|
||||||
|
<Route path="sync" element={<SyncSettings />} />
|
||||||
|
<Route path="tags" element={<TagsSettings />} />
|
||||||
|
</Route>
|
||||||
|
<Route path="explorer/:id" element={<ExplorerScreen />} />
|
||||||
|
<Route path="tag/:id" element={<TagScreen />} />
|
||||||
|
<Route path="*" element={<NotFound />} />
|
||||||
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
25
packages/interface/src/ErrorFallback.tsx
Normal file
25
packages/interface/src/ErrorFallback.tsx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { Button } from '@sd/ui';
|
||||||
|
import React from 'react';
|
||||||
|
import { FallbackProps } from 'react-error-boundary';
|
||||||
|
|
||||||
|
export function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
role="alert"
|
||||||
|
className="flex flex-col items-center justify-center w-screen h-screen p-4 border border-gray-200 rounded-lg dark:border-gray-650 bg-gray-50 dark:bg-gray-650 dark:text-white"
|
||||||
|
>
|
||||||
|
<p className="m-3 text-sm font-bold text-gray-400">APP CRASHED</p>
|
||||||
|
<h1 className="text-2xl font-bold">We're past the event horizon...</h1>
|
||||||
|
<pre className="m-2">Error: {error.message}</pre>
|
||||||
|
<div className="flex flex-row space-x-2">
|
||||||
|
<Button variant="primary" className="mt-2" onClick={resetErrorBoundary}>
|
||||||
|
Reload
|
||||||
|
</Button>
|
||||||
|
<Button className="mt-2" onClick={resetErrorBoundary}>
|
||||||
|
Send report
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
22
packages/interface/src/NotFound.tsx
Normal file
22
packages/interface/src/NotFound.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { Button } from '@sd/ui';
|
||||||
|
import React from 'react';
|
||||||
|
import { useNavigate } from 'react-router';
|
||||||
|
|
||||||
|
export function NotFound() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
role="alert"
|
||||||
|
className="flex flex-col items-center justify-center w-full h-full p-4 rounded-lg dark:text-white"
|
||||||
|
>
|
||||||
|
<p className="m-3 mt-20 text-sm font-semibold text-gray-500 uppercase">Error: 404</p>
|
||||||
|
<h1 className="text-4xl font-bold">You chose nothingness.</h1>
|
||||||
|
<div className="flex flex-row space-x-2">
|
||||||
|
<Button variant="primary" className="mt-4" onClick={() => navigate(-1)}>
|
||||||
|
Go Back
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ export function Device(props: DeviceProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full bg-gray-50 dark:bg-gray-600 border rounded-md border-gray-100 dark:border-gray-550">
|
<div className="w-full border border-gray-100 rounded-md bg-gray-50 dark:bg-gray-600 dark:border-gray-550">
|
||||||
<div className="flex flex-row items-center px-4 pt-2 pb-2">
|
<div className="flex flex-row items-center px-4 pt-2 pb-2">
|
||||||
<DotsSixVertical weight="bold" className="mr-3 opacity-30" />
|
<DotsSixVertical weight="bold" className="mr-3 opacity-30" />
|
||||||
{props.type === 'phone' && <DeviceMobileCamera weight="fill" size={20} className="mr-2" />}
|
{props.type === 'phone' && <DeviceMobileCamera weight="fill" size={20} className="mr-2" />}
|
||||||
|
@ -44,7 +44,7 @@ export function Device(props: DeviceProps) {
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-grow" />
|
<div className="flex flex-grow" />
|
||||||
{props.runningJob && (
|
{props.runningJob && (
|
||||||
<div className="flex flex-row ml-5 bg-opacity-50 rounded-md bg-gray-300 dark:bg-gray-550">
|
<div className="flex flex-row ml-5 bg-gray-300 bg-opacity-50 rounded-md dark:bg-gray-550">
|
||||||
<Rings
|
<Rings
|
||||||
stroke="#2599FF"
|
stroke="#2599FF"
|
||||||
strokeOpacity={4}
|
strokeOpacity={4}
|
||||||
|
|
|
@ -2,38 +2,15 @@ import { DotsVerticalIcon } from '@heroicons/react/solid';
|
||||||
import { useBridgeQuery } from '@sd/client';
|
import { useBridgeQuery } from '@sd/client';
|
||||||
import { FilePath } from '@sd/core';
|
import { FilePath } from '@sd/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import byteSize from 'pretty-bytes';
|
|
||||||
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { Virtuoso, VirtuosoHandle } from 'react-virtuoso';
|
import { Virtuoso, VirtuosoHandle } from 'react-virtuoso';
|
||||||
import { useKey, useWindowSize } from 'rooks';
|
import { useKey, useWindowSize } from 'rooks';
|
||||||
import create from 'zustand';
|
|
||||||
|
|
||||||
import { AppPropsContext } from '../../App';
|
import { AppPropsContext } from '../../AppPropsContext';
|
||||||
|
import { useExplorerState } from '../../hooks/useExplorerState';
|
||||||
import FileThumb from './FileThumb';
|
import FileThumb from './FileThumb';
|
||||||
|
|
||||||
type ExplorerState = {
|
|
||||||
selectedRowIndex: number;
|
|
||||||
setSelectedRowIndex: (index: number) => void;
|
|
||||||
locationId: number;
|
|
||||||
setLocationId: (index: number) => void;
|
|
||||||
newThumbnails: Record<string, boolean>;
|
|
||||||
addNewThumbnail: (cas_id: string) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useExplorerState = create<ExplorerState>((set) => ({
|
|
||||||
selectedRowIndex: 1,
|
|
||||||
setSelectedRowIndex: (index) => set((state) => ({ ...state, selectedRowIndex: index })),
|
|
||||||
locationId: -1,
|
|
||||||
setLocationId: (id: number) => set((state) => ({ ...state, locationId: id })),
|
|
||||||
newThumbnails: {},
|
|
||||||
addNewThumbnail: (cas_id: string) =>
|
|
||||||
set((state) => ({
|
|
||||||
...state,
|
|
||||||
newThumbnails: { ...state.newThumbnails, [cas_id]: true }
|
|
||||||
}))
|
|
||||||
}));
|
|
||||||
|
|
||||||
interface IColumn {
|
interface IColumn {
|
||||||
column: string;
|
column: string;
|
||||||
key: string;
|
key: string;
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { FilePath } from '@sd/core';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
|
||||||
import { AppPropsContext } from '../../App';
|
import { AppPropsContext } from '../../AppPropsContext';
|
||||||
import icons from '../../assets/icons';
|
import icons from '../../assets/icons';
|
||||||
import { Folder } from '../icons/Folder';
|
import { Folder } from '../icons/Folder';
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export default function FileThumb(props: {
|
||||||
const { data: client } = useBridgeQuery('NodeGetState');
|
const { data: client } = useBridgeQuery('NodeGetState');
|
||||||
|
|
||||||
if (props.file.is_dir) {
|
if (props.file.is_dir) {
|
||||||
return <Folder className="max-w-[20px]" />;
|
return <Folder size={100} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client?.data_path && (props.file.file?.has_thumbnail || props.hasThumbnailOverride)) {
|
if (client?.data_path && (props.file.file?.has_thumbnail || props.hasThumbnailOverride)) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Transition } from '@headlessui/react';
|
import { Transition } from '@headlessui/react';
|
||||||
import { ShareIcon } from '@heroicons/react/solid';
|
import { ShareIcon } from '@heroicons/react/solid';
|
||||||
import { FilePath } from '@sd/core';
|
import { FilePath, LocationResource } from '@sd/core';
|
||||||
import { Button, TextArea } from '@sd/ui';
|
import { Button, TextArea } from '@sd/ui';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Heart, Link } from 'phosphor-react';
|
import { Heart, Link } from 'phosphor-react';
|
||||||
|
@ -16,7 +16,7 @@ interface MetaItemProps {
|
||||||
|
|
||||||
const MetaItem = (props: MetaItemProps) => {
|
const MetaItem = (props: MetaItemProps) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col px-3 py-1 meta-item">
|
<div data-tip={props.value} className="flex flex-col px-3 py-1 meta-item">
|
||||||
<h5 className="text-xs font-bold">{props.title}</h5>
|
<h5 className="text-xs font-bold">{props.title}</h5>
|
||||||
{typeof props.value === 'string' ? (
|
{typeof props.value === 'string' ? (
|
||||||
<p className="text-xs text-gray-600 break-all truncate dark:text-gray-300">{props.value}</p>
|
<p className="text-xs text-gray-600 break-all truncate dark:text-gray-300">{props.value}</p>
|
||||||
|
@ -29,12 +29,15 @@ const MetaItem = (props: MetaItemProps) => {
|
||||||
|
|
||||||
const Divider = () => <div className="w-full my-1 h-[1px] bg-gray-100 dark:bg-gray-550" />;
|
const Divider = () => <div className="w-full my-1 h-[1px] bg-gray-100 dark:bg-gray-550" />;
|
||||||
|
|
||||||
export const Inspector = (props: { selectedFile?: FilePath; locationId: number }) => {
|
export const Inspector = (props: {
|
||||||
// const { selectedRowIndex } = useExplorerState();
|
locationId: number;
|
||||||
// const isOpen = !!props.selectedFile;
|
location?: LocationResource;
|
||||||
|
selectedFile?: FilePath;
|
||||||
|
}) => {
|
||||||
const file_path = props.selectedFile;
|
const file_path = props.selectedFile;
|
||||||
|
|
||||||
|
let full_path = `${props.location?.path}/${file_path?.materialized_path}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition
|
<Transition
|
||||||
show={true}
|
show={true}
|
||||||
|
@ -45,9 +48,9 @@ export const Inspector = (props: { selectedFile?: FilePath; locationId: number }
|
||||||
leaveFrom="translate-x-0"
|
leaveFrom="translate-x-0"
|
||||||
leaveTo="translate-x-64"
|
leaveTo="translate-x-64"
|
||||||
>
|
>
|
||||||
<div className="top-0 right-0 h-full m-2 border border-gray-100 rounded-lg w-60 dark:border-gray-850 ">
|
<div className="top-0 right-0 m-2 border border-gray-100 w-60 dark:border-gray-850 custom-scroll page-scroll">
|
||||||
{!!file_path && (
|
{!!file_path && (
|
||||||
<div className="flex flex-col h-full overflow-hidden bg-white rounded-lg select-text dark:bg-gray-600 bg-opacity-70">
|
<div className="flex flex-col overflow-x-hidden bg-white rounded-lg select-text dark:bg-gray-600 bg-opacity-70">
|
||||||
<div className="flex items-center justify-center w-full h-64 overflow-hidden rounded-t-lg bg-gray-50 dark:bg-gray-900">
|
<div className="flex items-center justify-center w-full h-64 overflow-hidden rounded-t-lg bg-gray-50 dark:bg-gray-900">
|
||||||
<FileThumb
|
<FileThumb
|
||||||
hasThumbnailOverride={false}
|
hasThumbnailOverride={false}
|
||||||
|
@ -72,7 +75,7 @@ export const Inspector = (props: { selectedFile?: FilePath; locationId: number }
|
||||||
<MetaItem title="Unique Content ID" value={file_path.file.cas_id as string} />
|
<MetaItem title="Unique Content ID" value={file_path.file.cas_id as string} />
|
||||||
)}
|
)}
|
||||||
<Divider />
|
<Divider />
|
||||||
<MetaItem title="Uri" value={file_path?.materialized_path as string} />
|
<MetaItem title="Uri" value={full_path} />
|
||||||
<Divider />
|
<Divider />
|
||||||
<MetaItem
|
<MetaItem
|
||||||
title="Date Created"
|
title="Date Created"
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { CirclesFour, Code, Planet } from 'phosphor-react';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { NavLink, NavLinkProps } from 'react-router-dom';
|
import { NavLink, NavLinkProps } from 'react-router-dom';
|
||||||
|
|
||||||
import { AppPropsContext } from '../../App';
|
import { AppPropsContext } from '../../AppPropsContext';
|
||||||
import { useNodeStore } from '../device/Stores';
|
import { useNodeStore } from '../device/Stores';
|
||||||
import { Folder } from '../icons/Folder';
|
import { Folder } from '../icons/Folder';
|
||||||
import RunningJobsWidget from '../jobs/RunningJobsWidget';
|
import RunningJobsWidget from '../jobs/RunningJobsWidget';
|
||||||
|
@ -244,10 +244,7 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
|
||||||
<Button
|
<Button
|
||||||
noPadding
|
noPadding
|
||||||
variant={isActive ? 'default' : 'default'}
|
variant={isActive ? 'default' : 'default'}
|
||||||
className={clsx(
|
className={clsx('px-[4px] mb-1')}
|
||||||
'px-[4px] mb-1'
|
|
||||||
// isActive && '!bg-gray-550'
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<CogIcon className="w-5 h-5" />
|
<CogIcon className="w-5 h-5" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
import React, { DetailedHTMLProps, HTMLAttributes } from 'react';
|
import React, { DetailedHTMLProps, HTMLAttributes } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useExplorerState } from '../file/FileList';
|
import { useExplorerState } from '../../hooks/useExplorerState';
|
||||||
import { Shortcut } from '../primitive/Shortcut';
|
import { Shortcut } from '../primitive/Shortcut';
|
||||||
import { DefaultProps } from '../primitive/types';
|
import { DefaultProps } from '../primitive/types';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useContext, useEffect } from 'react';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
|
|
||||||
import { AppPropsContext } from '../App';
|
import { AppPropsContext } from '../App';
|
||||||
import { useExplorerState } from '../components/file/FileList';
|
import { useExplorerState } from './useExplorerState';
|
||||||
|
|
||||||
export function useCoreEvents() {
|
export function useCoreEvents() {
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
|
|
23
packages/interface/src/hooks/useExplorerState.ts
Normal file
23
packages/interface/src/hooks/useExplorerState.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import create from 'zustand';
|
||||||
|
|
||||||
|
type ExplorerState = {
|
||||||
|
selectedRowIndex: number;
|
||||||
|
setSelectedRowIndex: (index: number) => void;
|
||||||
|
locationId: number;
|
||||||
|
setLocationId: (index: number) => void;
|
||||||
|
newThumbnails: Record<string, boolean>;
|
||||||
|
addNewThumbnail: (cas_id: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useExplorerState = create<ExplorerState>((set) => ({
|
||||||
|
selectedRowIndex: 1,
|
||||||
|
setSelectedRowIndex: (index) => set((state) => ({ ...state, selectedRowIndex: index })),
|
||||||
|
locationId: -1,
|
||||||
|
setLocationId: (id: number) => set((state) => ({ ...state, locationId: id })),
|
||||||
|
newThumbnails: {},
|
||||||
|
addNewThumbnail: (cas_id: string) =>
|
||||||
|
set((state) => ({
|
||||||
|
...state,
|
||||||
|
newThumbnails: { ...state.newThumbnails, [cas_id]: true }
|
||||||
|
}))
|
||||||
|
}));
|
|
@ -1,5 +1,5 @@
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import { AppProps, Platform } from './App';
|
import { AppProps, Platform } from './AppPropsContext';
|
||||||
|
|
||||||
export type { AppProps, Platform };
|
export type { AppProps, Platform };
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// import { useBridgeCommand, useBridgeQuery } from '@sd/client';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export const ContentScreen: React.FC<{}> = (props) => {
|
export const ContentScreen: React.FC<{}> = (props) => {
|
||||||
|
|
|
@ -2,45 +2,36 @@ import { useBridgeCommand, useBridgeQuery } from '@sd/client';
|
||||||
import { Button } from '@sd/ui';
|
import { Button } from '@sd/ui';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
|
||||||
import { AppPropsContext } from '../App';
|
import { AppPropsContext } from '../AppPropsContext';
|
||||||
import CodeBlock from '../components/primitive/Codeblock';
|
import CodeBlock from '../components/primitive/Codeblock';
|
||||||
|
|
||||||
export const DebugScreen: React.FC<{}> = (props) => {
|
export const DebugScreen: React.FC<{}> = (props) => {
|
||||||
const appPropsContext = useContext(AppPropsContext);
|
const appPropsContext = useContext(AppPropsContext);
|
||||||
const { data: client } = useBridgeQuery('NodeGetState');
|
const { data: client } = useBridgeQuery('NodeGetState');
|
||||||
const { data: jobs } = useBridgeQuery('JobGetRunning');
|
const { data: jobs } = useBridgeQuery('JobGetRunning');
|
||||||
const { data: jobHistory } = useBridgeQuery('JobGetHistory');
|
const { data: jobHistory } = useBridgeQuery('JobGetHistory');
|
||||||
// const { mutate: purgeDB } = useBridgeCommand('PurgeDatabase', {
|
// const { mutate: purgeDB } = useBridgeCommand('PurgeDatabase', {
|
||||||
// onMutate: () => {
|
// onMutate: () => {
|
||||||
// alert('Database purged');
|
// alert('Database purged');
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
const { mutate: identifyFiles } = useBridgeCommand('IdentifyUniqueFiles');
|
const { mutate: identifyFiles } = useBridgeCommand('IdentifyUniqueFiles');
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full h-screen p-5 custom-scroll page-scroll">
|
<div className="flex flex-col w-full h-screen p-5 custom-scroll page-scroll">
|
||||||
<div className="flex flex-col space-y-5 pb-7">
|
<div className="flex flex-col space-y-5 pb-7">
|
||||||
<h1 className="text-lg font-bold ">Developer Debugger</h1>
|
<h1 className="text-lg font-bold ">Developer Debugger</h1>
|
||||||
<div className="flex flex-row pb-4 space-x-2">
|
<div className="flex flex-row pb-4 space-x-2">
|
||||||
<Button
|
|
||||||
className="w-40"
|
|
||||||
variant="gray"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
if (client && appPropsContext?.onOpen) {
|
|
||||||
appPropsContext.onOpen(client.data_path);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Open data folder
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="w-40"
|
className="w-40"
|
||||||
variant="gray"
|
variant="gray"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => identifyFiles(undefined)}
|
onClick={() => {
|
||||||
|
if (client && appPropsContext?.onOpen) {
|
||||||
|
appPropsContext.onOpen(client.data_path);
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Identify unique files
|
Open data folder
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<h1 className="text-sm font-bold ">Running Jobs</h1>
|
<h1 className="text-sm font-bold ">Running Jobs</h1>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { useBridgeQuery } from '@sd/client';
|
import { useBridgeQuery } from '@sd/client';
|
||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { FileList, useExplorerState } from '../components/file/FileList';
|
import { FileList } from '../components/file/FileList';
|
||||||
import { Inspector } from '../components/file/Inspector';
|
import { Inspector } from '../components/file/Inspector';
|
||||||
import { TopBar } from '../components/layout/TopBar';
|
import { TopBar } from '../components/layout/TopBar';
|
||||||
|
import { useExplorerState } from '../hooks/useExplorerState';
|
||||||
|
|
||||||
export const ExplorerScreen: React.FC<{}> = () => {
|
export const ExplorerScreen: React.FC<{}> = () => {
|
||||||
let [searchParams] = useSearchParams();
|
let [searchParams] = useSearchParams();
|
||||||
|
@ -13,22 +14,20 @@ export const ExplorerScreen: React.FC<{}> = () => {
|
||||||
let { id } = useParams();
|
let { id } = useParams();
|
||||||
let location_id = Number(id);
|
let location_id = Number(id);
|
||||||
|
|
||||||
let [limit, setLimit] = React.useState(100);
|
const [limit, setLimit] = React.useState(100);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log({ location_id, path, limit });
|
|
||||||
}, [location_id, path]);
|
|
||||||
|
|
||||||
const { selectedRowIndex } = useExplorerState();
|
const { selectedRowIndex } = useExplorerState();
|
||||||
|
|
||||||
|
// Current Location
|
||||||
|
const { data: currentLocation } = useBridgeQuery('SysGetLocation', { id: location_id });
|
||||||
|
|
||||||
|
// Current Directory
|
||||||
const { data: currentDir } = useBridgeQuery(
|
const { data: currentDir } = useBridgeQuery(
|
||||||
'LibGetExplorerDir',
|
'LibGetExplorerDir',
|
||||||
{ location_id: location_id!, path, limit },
|
{ location_id: location_id!, path, limit },
|
||||||
{ enabled: !!location_id }
|
{ enabled: !!location_id }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log({ currentDir });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full h-full">
|
<div className="flex flex-col w-full h-full">
|
||||||
<TopBar />
|
<TopBar />
|
||||||
|
@ -36,6 +35,7 @@ export const ExplorerScreen: React.FC<{}> = () => {
|
||||||
<FileList location_id={location_id} path={path} limit={limit} />
|
<FileList location_id={location_id} path={path} limit={limit} />
|
||||||
{currentDir?.contents && (
|
{currentDir?.contents && (
|
||||||
<Inspector
|
<Inspector
|
||||||
|
location={currentLocation}
|
||||||
selectedFile={currentDir.contents[selectedRowIndex]}
|
selectedFile={currentDir.contents[selectedRowIndex]}
|
||||||
locationId={location_id}
|
locationId={location_id}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Skeleton from 'react-loading-skeleton';
|
||||||
import 'react-loading-skeleton/dist/skeleton.css';
|
import 'react-loading-skeleton/dist/skeleton.css';
|
||||||
import create from 'zustand';
|
import create from 'zustand';
|
||||||
|
|
||||||
import { AppPropsContext } from '../App';
|
import { AppPropsContext } from '../AppPropsContext';
|
||||||
import { Device } from '../components/device/Device';
|
import { Device } from '../components/device/Device';
|
||||||
import Dialog from '../components/layout/Dialog';
|
import Dialog from '../components/layout/Dialog';
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
// import { dummyIFile, FileList } from '../components/file/FileList';
|
|
||||||
import {
|
import {
|
||||||
CloudIcon,
|
CloudIcon,
|
||||||
CogIcon,
|
CogIcon,
|
||||||
KeyIcon,
|
KeyIcon,
|
||||||
LockClosedIcon,
|
LockClosedIcon,
|
||||||
PhotographIcon,
|
|
||||||
TagIcon,
|
TagIcon,
|
||||||
TerminalIcon,
|
TerminalIcon,
|
||||||
UsersIcon
|
UsersIcon
|
||||||
} from '@heroicons/react/outline';
|
} from '@heroicons/react/outline';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { Book, Database, HardDrive, PaintBrush } from 'phosphor-react';
|
import { Database, HardDrive, PaintBrush } from 'phosphor-react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
import { SidebarLink } from '../components/file/Sidebar';
|
import { SidebarLink } from '../components/file/Sidebar';
|
||||||
|
|
||||||
//@ts-ignore
|
|
||||||
// import { Spline } from 'react-spline';
|
|
||||||
// import WINDOWS_SCENE from '../assets/spline/scene.json';
|
|
||||||
|
|
||||||
const Icon = ({ component: Icon, ...props }: any) => (
|
const Icon = ({ component: Icon, ...props }: any) => (
|
||||||
<Icon weight="bold" {...props} className={clsx('w-4 h-4 mr-2', props.className)} />
|
<Icon weight="bold" {...props} className={clsx('w-4 h-4 mr-2', props.className)} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,10 +9,7 @@ export const TagScreen: React.FC<{}> = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full p-5">
|
<div className="w-full p-5">
|
||||||
<p className="px-5 py-3 mb-3 text-sm text-gray-400 rounded-md bg-gray-50 dark:text-gray-400 dark:bg-gray-600">
|
<h1>{id}</h1>
|
||||||
<b>Note: </b>This is a pre-alpha build of Spacedrive, many features are yet to be
|
|
||||||
functional.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,32 +15,6 @@ export default function GeneralSettings() {
|
||||||
title="General Settings"
|
title="General Settings"
|
||||||
description="Basic settings related to this client."
|
description="Basic settings related to this client."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* <InputContainer
|
|
||||||
title="Test scan directory"
|
|
||||||
description="This will create a job to scan the directory you specify to the database."
|
|
||||||
>
|
|
||||||
<div className="flex flex-row">
|
|
||||||
<Input
|
|
||||||
value={tempWatchDir}
|
|
||||||
className="flex-grow"
|
|
||||||
onChange={(e) => setTempWatchDir(e.target.value)}
|
|
||||||
placeholder="/users/jamie/Desktop"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
className="ml-2"
|
|
||||||
variant="primary"
|
|
||||||
onClick={() =>
|
|
||||||
createLocation({
|
|
||||||
path: tempWatchDir
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Scan Now
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</InputContainer> */}
|
|
||||||
|
|
||||||
<InputContainer title="Volumes" description="A list of volumes running on this device.">
|
<InputContainer title="Volumes" description="A list of volumes running on this device.">
|
||||||
<div className="flex flex-row space-x-2">
|
<div className="flex flex-row space-x-2">
|
||||||
<div className="flex flex-grow">
|
<div className="flex flex-grow">
|
||||||
|
|
Loading…
Reference in a new issue