- tcp listener WIP

- better settings
This commit is contained in:
Jamie 2022-02-24 16:18:41 -08:00
parent d065937c35
commit 764b052c3f
55 changed files with 5043 additions and 553 deletions

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EslintConfiguration">
<option name="fix-on-save" value="true" />
</component>
</project>

6
.idea/prettier.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myRunOnSave" value="true" />
</component>
</project>

View file

@ -2,9 +2,12 @@
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/apps/desktop/src-tauri/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<excludeFolder url="file://$MODULE_DIR$/packages/core/target" />
<excludeFolder url="file://$MODULE_DIR$/apps/desktop/src-tauri/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

255
.idea/workspace.xml Normal file
View file

@ -0,0 +1,255 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/packages/core/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/apps/desktop/src-tauri/Cargo.toml" />
</component>
<component name="ChangeListManager">
<list default="true" id="e9f4d63e-e014-4f5b-9bf1-6c3b1fae8f30" name="Changes" comment="settings via react router">
<change afterPath="$PROJECT_DIR$/apps/desktop/src/components/layout/Dialog.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Listbox.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/apps/desktop/src/components/transitions/SlideUp.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/apps/desktop/src/screens/settings/LocationSettings.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/apps/desktop/src/screens/settings/SecuritySettings.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/packages/core/lib/p2p/listener.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/packages/core/lib/p2p/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/spacedrive.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/spacedrive.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src-tauri/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src-tauri/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src-tauri/src/commands.rs" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src-tauri/src/commands.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src-tauri/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src-tauri/src/main.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/App.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/App.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/file/FileItem.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/file/FileItem.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/file/Sidebar.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/file/Sidebar.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/layout/Modal.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/layout/Modal.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/layout/TopBar.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/layout/TopBar.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Button.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Button.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Dropdown.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Dropdown.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Input.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Input.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/primitive/InputContainer.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/primitive/InputContainer.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Toggle.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/components/primitive/Toggle.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/screens/Explorer.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/screens/Explorer.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/screens/Overview.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/screens/Overview.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/screens/Settings.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/screens/Settings.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/desktop/src/screens/settings/General.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/apps/desktop/src/screens/settings/GeneralSettings.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/db/entity/location_paths.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/db/entity/locations.rs" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/db/entity/locations.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/db/entity/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/db/entity/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/db/migrations/primary/V1__initial.sql" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/db/migrations/primary/V1__initial.sql" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/file/client.rs" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/file/client.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/file/indexer.rs" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/file/indexer.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/file/locations.rs" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/file/locations.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/packages/core/lib/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/packages/core/lib/main.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/yarn.lock" beforeDir="false" afterPath="$PROJECT_DIR$/yarn.lock" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="TypeScript JSX File" />
<option value="Rust File" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GitSEFilterConfiguration">
<file-type-list>
<filtered-out-file-type name="LOCAL_BRANCH" />
<filtered-out-file-type name="REMOTE_BRANCH" />
<filtered-out-file-type name="TAG" />
<filtered-out-file-type name="COMMIT_BY_MESSAGE" />
</file-type-list>
</component>
<component name="GitToolBoxStore">
<option name="projectConfigVersion" value="4" />
</component>
<component name="GotoFileConfiguration">
<file-type-list>
<filtered-out-file-type name="ActionScript" />
<filtered-out-file-type name="Angular2Html" />
<filtered-out-file-type name="Angular2Svg" />
<filtered-out-file-type name="AUTO_DETECTED" />
<filtered-out-file-type name="CoffeeScript" />
<filtered-out-file-type name="Cucumber" />
<filtered-out-file-type name="DTD" />
<filtered-out-file-type name="ECMAScript 6" />
<filtered-out-file-type name="EditorConfig" />
<filtered-out-file-type name="EJS" />
<filtered-out-file-type name="Flow" />
<filtered-out-file-type name="Haml" />
<filtered-out-file-type name="HgIgnore file" />
<filtered-out-file-type name="Handlebars/Mustache" />
<filtered-out-file-type name="HTML" />
<filtered-out-file-type name="HTTP Request" />
<filtered-out-file-type name="IDEA_MODULE" />
<filtered-out-file-type name="IDEA_PROJECT" />
<filtered-out-file-type name="IDEA_WORKSPACE" />
<filtered-out-file-type name="IgnoreLang file" />
<filtered-out-file-type name="Jade" />
<filtered-out-file-type name="Jest Snapshot" />
<filtered-out-file-type name="JQL" />
<filtered-out-file-type name="JSHint" />
<filtered-out-file-type name="Less" />
<filtered-out-file-type name="PLAIN_TEXT" />
<filtered-out-file-type name="PATCH" />
<filtered-out-file-type name="Literate CoffeeScript" />
<filtered-out-file-type name="Cookie storage file" />
<filtered-out-file-type name="CSS" />
<filtered-out-file-type name="Dictionary" />
<filtered-out-file-type name="GitExclude file" />
<filtered-out-file-type name="GitIgnore file" />
<filtered-out-file-type name="IntegrationPerformanceTest" />
<filtered-out-file-type name="JSON-lines" />
<filtered-out-file-type name="JSON5" />
<filtered-out-file-type name="JSX Harmony" />
<filtered-out-file-type name="RegExp" />
<filtered-out-file-type name="RNG Compact" />
<filtered-out-file-type name="Shell Script" />
<filtered-out-file-type name="SourceMap" />
<filtered-out-file-type name="Spacebars" />
<filtered-out-file-type name="Stylus" />
<filtered-out-file-type name="textmate" />
<filtered-out-file-type name="Vue.js" />
<filtered-out-file-type name="XHTML" />
<filtered-out-file-type name="XPath" />
<filtered-out-file-type name="XPath2" />
<filtered-out-file-type name="yarn.lock" />
<filtered-out-file-type name="Angular Metadata JSON" />
<filtered-out-file-type name="ARCHIVE" />
<filtered-out-file-type name="CVP" />
<filtered-out-file-type name="dependency diagram" />
<filtered-out-file-type name="Image" />
<filtered-out-file-type name="Native" />
<filtered-out-file-type name="UML" />
<filtered-out-file-type name="UNKNOWN" />
<filtered-out-file-type name="Directory" />
</file-type-list>
</component>
<component name="JsBowerSettings">
<bower-package value="" />
<bower.json value="" />
</component>
<component name="MacroExpansionManager">
<option name="directoryName" value="v1czs84n" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="OptimizeOnSaveOptions">
<option name="myRunOnSave" value="true" />
</component>
<component name="ProjectId" id="24eJYnz3rTDPNpb2oOoxp5Ri3GO" />
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState">
<option name="autoscrollFromSource" value="true" />
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="ASKED_ADD_EXTERNAL_FILES" value="true" />
<property name="ASKED_SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.standard" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.standard" value="" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="nodejs_package_manager_path" value="yarn" />
<property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
<property name="prettierjs.PrettierConfiguration.Package" value="$PROJECT_DIR$/node_modules/prettier" />
<property name="settings.editor.selected.configurable" value="language.rust.cargo.check" />
<property name="ts.external.directory.path" value="$PROJECT_DIR$/node_modules/typescript/lib" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/apps/desktop/src/screens/settings" />
</key>
</component>
<component name="RustProjectSettings">
<option name="macroExpansionEngine" value="OLD" />
<option name="runExternalLinterOnTheFly" value="true" />
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
<option name="version" value="2" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="e9f4d63e-e014-4f5b-9bf1-6c3b1fae8f30" name="Changes" comment="" />
<created>1643985169569</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1643985169569</updated>
<workItem from="1643985171248" duration="1282000" />
<workItem from="1644447242960" duration="284000" />
<workItem from="1644608558680" duration="18817000" />
<workItem from="1644942978637" duration="7500000" />
<workItem from="1645404043913" duration="32248000" />
<workItem from="1645491633303" duration="23348000" />
<workItem from="1645523382970" duration="40541000" />
<workItem from="1645675072647" duration="1008000" />
<workItem from="1645676102200" duration="7490000" />
<workItem from="1645688411634" duration="7274000" />
</task>
<task id="LOCAL-00001" summary="just a bunch 'o stuff">
<created>1645422057851</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1645422057851</updated>
</task>
<task id="LOCAL-00002" summary="settings">
<created>1645489326191</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1645489326191</updated>
</task>
<option name="localTasksCounter" value="3" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
<option name="exactExcludedFiles">
<list>
<option value="$PROJECT_DIR$/apps/desktop/src/index.d.ts" />
</list>
</option>
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="just a bunch 'o stuff" />
<MESSAGE value="settings" />
<MESSAGE value="settings via react router" />
<option name="LAST_COMMIT_MESSAGE" value="settings via react router" />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />
<select />
</component>
</project>

View file

@ -31,6 +31,7 @@
"@apollo/client": "^3.4.7",
"@headlessui/react": "^1.4.0",
"@heroicons/react": "^1.0.4",
"@radix-ui/react-dialog": "^0.1.5",
"@tauri-apps/api": "^1.0.0-beta.5",
"@types/pretty-bytes": "^5.2.0",
"@types/react-table": "^7.7.6",
@ -50,7 +51,8 @@
"react-error-boundary": "^3.1.3",
"react-hotkeys-hook": "^3.4.4",
"react-portal": "^4.2.1",
"react-router-dom": "^5.2.0",
"react-router": "6.2.1",
"react-router-dom": "6.2.1",
"react-spline": "^1.2.1",
"react-transition-group": "^4.4.2",
"react-virtuoso": "^2.2.6",

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
use anyhow::Result;
use sdcorelib::{
core_send_stream,
CoreConfig,
db::connection::db_instance,
file::{icon, indexer, retrieve, retrieve::Directory, watcher::watch_dir},
get_core_config, native, CoreConfig,
file::{icon, indexer, locations, retrieve, retrieve::Directory, watcher::watch_dir}, get_core_config, native,
};
use swift_rs::types::SRObjectArray;
@ -55,3 +55,10 @@ pub async fn start_watcher(path: &str) -> Result<(), String> {
Ok(())
}
#[tauri::command]
pub async fn create_location(path: &str) -> Result<(), String> {
let _location = locations::create_location(path);
Ok(())
}

View file

@ -1,10 +1,11 @@
mod commands;
mod menu;
use sdcorelib;
use tauri::api::path;
use tauri::Manager;
use tauri_plugin_shadows::Shadows;
mod commands;
mod menu;
fn main() {
tauri::Builder::default()
.setup(|app| {
@ -13,9 +14,6 @@ fn main() {
let app = app.handle();
let window = app.get_window("main").unwrap();
// window.set_shadow(true);
tauri::async_runtime::spawn(async move {
while let Some(event) = core_receiver.recv().await {
app.emit_all("core_event", &event).unwrap();
@ -27,6 +25,7 @@ fn main() {
.on_menu_event(|event| menu::handle_menu_event(event))
.invoke_handler(tauri::generate_handler![
commands::scan_dir,
commands::create_location,
commands::get_files,
commands::get_config,
commands::get_mounts,

View file

@ -1,5 +1,13 @@
import React, {useContext, useEffect, useState} from 'react';
import { Route, BrowserRouter as Router, Switch, Redirect } from 'react-router-dom';
import React, { useEffect } from 'react';
import {
BrowserRouter,
Location,
Outlet,
Route,
Routes,
useLocation,
useNavigate
} from 'react-router-dom';
import { Sidebar } from './components/file/Sidebar';
import { TopBar } from './components/layout/TopBar';
import { SettingsScreen } from './screens/Settings';
@ -8,14 +16,101 @@ import { invoke } from '@tauri-apps/api';
import { DebugGlobalStore } from './Debug';
import { useCoreEvents } from './hooks/useCoreEvents';
import { AppState, useAppState } from './store/global';
import { Button } from 'ui';
import { Button } from './components/primitive';
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
import { useLocationStore, Location } from './store/locations';
import { useLocationStore } from './store/locations';
import { OverviewScreen } from './screens/Overview';
import { SpacesScreen } from './screens/Spaces';
import {createModal, Modal} from "./components/layout/Modal";
import { Modal } from './components/layout/Modal';
import GeneralSettings from './screens/settings/GeneralSettings';
import SlideUp from './components/transitions/SlideUp';
import SecuritySettings from './screens/settings/SecuritySettings';
import LocationSettings from './screens/settings/LocationSettings';
export const SettingsModal = createModal('settings');
function AppLayout() {
return (
<div className="flex flex-row h-screen overflow-hidden text-gray-900 bg-white border border-gray-200 select-none rounded-xl dark:border-gray-500 dark:text-white dark:bg-gray-650">
<Sidebar />
<div className="flex flex-col w-full min-h-full">
<TopBar />
<div className="relative flex w-full">
<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="general" element={<GeneralSettings />} />
<Route path="security" element={<SecuritySettings />} />
<Route path="appearance" element={<></>} />
<Route path="locations" element={<LocationSettings />} />
<Route path="media" element={<></>} />
<Route path="keys" element={<></>} />
<Route path="tags" element={<></>} />
</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={<OverviewScreen />} />
<Route path="overview" element={<OverviewScreen />} />
<Route path="spaces" element={<SpacesScreen />} />
<Route path="settings/*" element={<SettingsRoutes />} />
<Route path="explorer" element={<ExplorerScreen />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
{state?.backgroundLocation && <SettingsRoutes modal />}
</>
);
}
export default function App() {
useCoreEvents();
useEffect(() => {
invoke<AppState>('get_config').then((state) => useAppState.getState().update(state));
invoke<Location[]>('get_mounts').then((locations) =>
useLocationStore.getState().setLocations(locations)
);
}, []);
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}
// reset the state of your app so the error doesn't happen again
onReset={() => {}}
>
<DebugGlobalStore />
<BrowserRouter>
<Router />
</BrowserRouter>
</ErrorBoundary>
);
}
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
return (
@ -39,54 +134,25 @@ function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
);
}
export default function App() {
useCoreEvents();
useEffect(() => {
invoke<AppState>('get_config').then((state) => useAppState.getState().update(state));
invoke<Location[]>('get_mounts').then((locations) =>
useLocationStore.getState().setLocations(locations)
);
}, []);
// useHotkeys('command+q', () => {
// process.exit();
// });
function NotFound() {
const navigate = useNavigate();
return (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// reset the state of your app so the error doesn't happen again
}}
<div
data-tauri-drag-region
role="alert"
className="flex flex-col w-full h-full items-center justify-center p-4 border border-gray-200 rounded-lg dark:border-gray-650 bg-gray-50 dark:bg-gray-650 dark:text-white"
>
<Router>
<div className="flex flex-row h-screen overflow-hidden text-gray-900 bg-white border border-gray-200 select-none rounded-xl dark:border-gray-500 dark:text-white dark:bg-gray-650">
<Modal {...SettingsModal}>
<SettingsScreen />
</Modal>
<DebugGlobalStore />
<Sidebar />
<div className="flex flex-col w-full min-h-full">
<TopBar />
<div className="relative flex w-full">
<Switch>
<Route path="/overview">
<OverviewScreen />
</Route>
<Route path="/spaces">
<SpacesScreen />
</Route>
<Route path="/explorer">
<ExplorerScreen />
</Route>
</Switch>
</div>
</div>
</div>
</Router>
</ErrorBoundary>
<p className="m-3 text-sm font-bold text-gray-400">Error: 404</p>
<h1 className="text-2xl font-bold">Not found bozo.</h1>
<div className="flex flex-row space-x-2">
<Button variant="primary" className="mt-2" onClick={() => navigate(-1)}>
Go Back
</Button>
</div>
</div>
);
}
// useHotkeys('command+q', () => {
// process.exit();
// });

View file

@ -38,7 +38,7 @@ export default function FileItem(props: Props) {
<div className="relative w-full h-full active:translate-y-[1px]">
<img
className="bottom-0 p-3 pt-[19px] margin-auto z-90 pointer-events-none"
src="svg/folder.svg"
src="/svg/folder.svg"
/>
</div>
) : (
@ -71,7 +71,7 @@ export default function FileItem(props: Props) {
className="mt-2 pointer-events-none margin-auto"
width={40}
height={40}
src={`icons/${props.iconName}.svg`}
src={`/icons/${props.iconName}.svg`}
/>
<span className="mt-1 text-xs font-bold text-center uppercase cursor-default text-gray-450">
{props.format}

View file

@ -13,15 +13,18 @@ import { DefaultProps } from '../primitive/types';
interface SidebarProps extends DefaultProps {}
export const SidebarLink = (props: NavLinkProps) => (
<NavLink
{...props}
className={clsx(
'max-w mb-[2px] text-gray-550 dark:text-gray-150 rounded px-2 py-1 flex flex-row flex-grow items-center hover:bg-gray-100 dark:hover:bg-gray-600 text-sm',
props.className
<NavLink {...props}>
{({ isActive }) => (
<span
className={clsx(
'max-w mb-[2px] text-gray-550 dark:text-gray-150 rounded px-2 py-1 flex flex-row flex-grow items-center hover:bg-gray-100 dark:hover:bg-gray-600 text-sm',
{ '!bg-primary !text-white hover:bg-primary dark:hover:bg-primary': isActive },
props.className
)}
>
{props.children}
</span>
)}
activeClassName="!bg-primary !text-white hover:bg-primary dark:hover:bg-primary"
>
{props.children}
</NavLink>
);
@ -33,18 +36,26 @@ const Heading: React.FC<{}> = ({ children }) => (
<div className="mt-5 mb-1 ml-1 text-xs font-semibold text-gray-300">{children}</div>
);
export function MacOSTrafficLights() {
return (
<div data-tauri-drag-region className="mt-2 mb-1 -ml-1 ">
<TrafficLights
onClose={appWindow.close}
onFullscreen={appWindow.maximize}
onMinimize={appWindow.minimize}
className="p-1.5 z-50 absolute"
/>
</div>
);
}
export const Sidebar: React.FC<SidebarProps> = (props) => {
const locations = useLocations();
console.log({ locations });
return (
<div className="flex flex-col flex-wrap flex-shrink-0 min-h-full px-3 py-1 border-r border-gray-100 w-46 bg-gray-50 dark:bg-gray-850 dark:border-gray-600">
<div data-tauri-drag-region className="mt-2 mb-1 -ml-1 ">
<TrafficLights
onClose={appWindow.close}
onFullscreen={appWindow.maximize}
onMinimize={appWindow.minimize}
className="p-1.5 z-50 absolute"
/>
</div>
<div className="flex flex-col flex-wrap flex-shrink-0 min-h-full px-3 pb-1 border-r border-gray-100 w-46 bg-gray-50 dark:bg-gray-850 dark:border-gray-600">
<MacOSTrafficLights />
<div className="mt-6" />
<Dropdown
buttonProps={{
@ -77,12 +88,12 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
<Icon component={Planet} />
Overview
</SidebarLink>
<SidebarLink to="/spaces">
<SidebarLink to="spaces">
<Icon component={CirclesFour} />
Spaces
</SidebarLink>
<SidebarLink to="/settings">
<SidebarLink to="media">
<Icon component={MonitorPlay} />
Media
</SidebarLink>
@ -92,7 +103,7 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
{locations.map((location, index) => {
return (
<div key={index} className="flex flex-row items-center">
<SidebarLink className="relative group" to={`/explorer/${location.name}`}>
<SidebarLink className="relative group" to={`/app/explorer/${location.name}`}>
<Icon component={ServerIcon} />
{location.name}
<div className="flex-grow" />
@ -110,6 +121,16 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
);
})}
</div>
<div className="flex-grow" />
<div className="mb-2">
<NavLink to="/settings/general">
{({ isActive }) => (
<Button variant={isActive ? 'default' : 'default'} className="px-[4px]">
<CogIcon className="w-5 h-5" />
</Button>
)}
</NavLink>
</div>
</div>
);
};

View file

@ -0,0 +1,26 @@
// import { Button } from '../primitive';
// import React from 'react';
// import * as DialogPrimitive from '@radix-ui/react-dialog';
//
// export default function DialogButton<{ children: React.ReactNode }>(props) {
// return (
// <DialogPrimitive.Root>
// <DialogPrimitive.Trigger asChild>
// <Button variant="primary">Add Location</Button>
// </DialogPrimitive.Trigger>
// <DialogPrimitive.Portal className="">
// <DialogPrimitive.Overlay className="bg-black bg-opacity-50 absolute top-0 left-0 h-screen w-screen" />
// <DialogPrimitive.Content className="absolute p-8 rounded-md margin-auto bg-gray-700 text-white">
// <DialogPrimitive.Title>Add Location</DialogPrimitive.Title>
// <DialogPrimitive.Description>Choose a location from the list</DialogPrimitive.Description>
// <div className="flex flex-row space-x-2 mt-1">
// <DialogPrimitive.Close asChild>
// <Button>Close</Button>
// </DialogPrimitive.Close>
// <Button variant="primary">Add Location</Button>
// </div>
// </DialogPrimitive.Content>
// </DialogPrimitive.Portal>
// </DialogPrimitive.Root>
// );
// }

View file

@ -1,33 +1,25 @@
import { Transition } from '@headlessui/react';
import clsx from 'clsx';
import React from 'react';
import { atom, useAtom, WritableAtom } from 'jotai';
import { useHotkeys } from 'react-hotkeys-hook';
import { XIcon } from '@heroicons/react/solid';
import { Button } from '../primitive';
import { useNavigate } from 'react-router-dom';
import { MacOSTrafficLights } from '../file/Sidebar';
export interface ModalProps {
name: string;
open: WritableAtom<boolean, boolean>;
full?: boolean;
}
export function createModal(name: string): ModalProps {
return { name, open: atom(false) as WritableAtom<boolean, boolean> };
}
export const Modal: React.FC<ModalProps> = (props) => {
const [open, setOpen] = useAtom(props.open);
useHotkeys('esc', () => setOpen(false));
const navigate = useNavigate();
return (
<div
className={clsx('absolute w-screen h-screen z-30', { 'pointer-events-none hidden': !open })}
>
<MacOSTrafficLights />
<div className="flex w-screen h-screen p-2 pt-12">
<Transition
show={open}
appear
show
enter="transition duration-150"
enterFrom="opacity-0"
enterTo="opacity-100"
@ -37,19 +29,19 @@ export const Modal: React.FC<ModalProps> = (props) => {
>
<div
data-tauri-drag-region
onClick={() => setOpen(false)}
className="absolute -z-50 w-screen h-screen left-0 top-0 bg-white dark:bg-gray-800 bg-opacity-90 rounded-2xl"
onClick={() => navigate('/')}
className="absolute -z-50 w-screen h-screen left-0 top-0 rounded-2xl bg-white dark:bg-gray-800 bg-opacity-90"
/>
</Transition>
<Button
onClick={() => setOpen(false)}
onClick={() => navigate('/')}
variant="gray"
className="!px-1.5 absolute top-2 right-2"
>
<XIcon className="w-4 h-4" />
</Button>
<Transition
show={open}
show
className="flex flex-grow"
appear
enter="transition ease-in-out-back duration-200"

View file

@ -1,28 +1,13 @@
import { ChevronLeftIcon, ChevronRightIcon, CogIcon } from '@heroicons/react/outline';
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/outline';
import clsx from 'clsx';
import {
ArrowsLeftRight,
Cloud,
Columns,
FolderPlus,
HouseSimple,
Key,
SquaresFour,
Tag,
TerminalWindow
} from 'phosphor-react';
import { ArrowsLeftRight, Cloud, FolderPlus, Key, Tag, TerminalWindow } from 'phosphor-react';
import React from 'react';
import { useExplorerStore } from '../../store/explorer';
import { TrafficLights } from '../os/TrafficLights';
import { Button, ButtonProps, Input } from '../primitive';
import { ButtonProps } from '../primitive';
import { Shortcut } from '../primitive/Shortcut';
import { DefaultProps } from '../primitive/types';
import { appWindow } from '@tauri-apps/api/window';
import { HeartIcon } from '@heroicons/react/solid';
import { invoke } from '@tauri-apps/api';
import { SettingsModal } from '../../App'
import {useAtom} from "jotai";
import { useLocation } from 'react-router-dom';
export interface TopBarProps extends DefaultProps {}
export interface TopBarButtonProps extends ButtonProps {
@ -54,13 +39,13 @@ const TopBarButton: React.FC<TopBarButtonProps> = ({ icon: Icon, ...props }) =>
};
export const TopBar: React.FC<TopBarProps> = (props) => {
const [settingsOpen, setSettingsOpen] = useAtom(SettingsModal.open)
let location = useLocation();
const [goBack] = useExplorerStore((state) => [state.goBack]);
return (
<>
<div
data-tauri-drag-region
className="flex h-[2.95rem] -mt-0.5 max-w z-10 pl-3 rounded-tr-2xl items-center border-b bg-gray-50 dark:bg-gray-600 border-gray-100 dark:border-gray-800 !bg-opacity-100 backdrop-blur"
className="flex h-[2.95rem] -mt-0.5 max-w z-10 pl-3 rounded-tr-2xl flex-shrink-0 items-center border-b bg-gray-50 dark:bg-gray-600 border-gray-100 dark:border-gray-800 !bg-opacity-100 backdrop-blur"
>
<div className="flex">
<TopBarButton icon={ChevronLeftIcon} onClick={goBack} />
@ -71,7 +56,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
<TopBarButton group icon={Columns} />
<TopBarButton group right icon={SquaresFour} />
</div> */}
<div data-tauri-drag-region className="flex flex-row justify-center flex-grow">
<div data-tauri-drag-region className="flex flex-row justify-center flex-grow ">
<div className="flex mx-8 space-x-2 pointer-events-auto">
<TopBarButton icon={Tag} />
<TopBarButton icon={FolderPlus} />
@ -96,9 +81,9 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
/>
</div>
</div>
<TopBarButton onClick={() => {
setSettingsOpen(!settingsOpen);
}} className="mr-[8px]" icon={CogIcon} />
{/*<TopBarButton onClick={() => {*/}
{/* setSettingsOpen(!settingsOpen);*/}
{/*}} className="mr-[8px]" icon={CogIcon} />*/}
</div>
{/* <div className="h-[1px] flex-shrink-0 max-w bg-gray-200 dark:bg-gray-700" /> */}
</>

View file

@ -1,6 +1,4 @@
import React from 'react';
import { ButtonHTMLAttributes, useState } from 'react';
import { Switch } from '@headlessui/react';
import clsx from 'clsx';
const sizes = {
@ -11,20 +9,20 @@ const sizes = {
const variants = {
default: `
bg-gray-50
shadow-sm
shadow-sm
hover:bg-gray-100
active:bg-gray-50
dark:bg-gray-650
dark:hover:bg-gray-600
dark:active:bg-gray-700
dark:active:opacity-80
dark:bg-transparent
dark:active:bg-gray-600
dark:hover:bg-gray-550
dark:active:opacity-80
border-gray-100
hover:border-gray-200
active:border-gray-200
dark:border-gray-600
hover:border-gray-200
active:border-gray-200
dark:border-transparent
dark:active:border-gray-600
dark:hover:border-gray-600
dark:hover:border-gray-500
text-gray-700
hover:text-gray-900

View file

@ -1,6 +1,5 @@
import React from 'react';
import React, { Fragment } from 'react';
import { Menu, Transition } from '@headlessui/react';
import { Fragment, useEffect, useRef, useState } from 'react';
import { ChevronDownIcon } from '@heroicons/react/solid';
import { DefaultOptions } from '@apollo/client';
import { Button, ButtonProps } from '.';

View file

@ -31,15 +31,17 @@ const variants = {
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
variant?: keyof typeof variants;
size?: 'sm';
}
export const Input = (props: InputProps) => {
export const Input = ({ size, ...props }: InputProps) => {
return (
<input
{...props}
className={clsx(
`px-3 py-1 rounded-md border leading-7 outline-none shadow-xs focus:ring-2 transition-all`,
variants[props.variant || 'default'],
size && '',
props.className
)}
/>

View file

@ -1,22 +1,25 @@
import React from 'react';
import clsx from 'clsx';
import { DefaultProps } from './types';
import { Label } from './Input';
interface InputContainerProps extends DefaultProps {
title: string;
description?: string;
children: React.ReactNode;
mini?: boolean;
}
export const InputContainer: React.FC<InputContainerProps> = (props) => {
return (
<div className={clsx('flex flex-col w-full pb-6', props.className)} {...props}>
<h3 className="text-gray-700 dark:text-gray-100 font-medium mb-1">{props.title}</h3>
{!!props.description && (
<p className="text-gray-400 text-sm max-w-md mb-2">{props.description}</p>
)}
{props.children}
<div className="flex flex-row max-w-4xl">
<div className={clsx('flex flex-col w-full pb-6', props.className)} {...props}>
<h3 className="text-gray-700 dark:text-gray-100 font-medium mb-1">{props.title}</h3>
{!!props.description && (
<p className="text-gray-400 text-sm max-w-md mb-2">{props.description}</p>
)}
{!props.mini && props.children}
</div>
{props.mini && props.children}
</div>
);
};

View file

@ -0,0 +1,103 @@
import React, { Fragment, useEffect, useState } from 'react';
import { Listbox as ListboxPrimitive, Transition } from '@headlessui/react';
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
import clsx from 'clsx';
interface ListboxOption {
option: string;
description?: string;
key: string;
}
export default function Listbox(props: { options: ListboxOption[]; className?: string }) {
const [selected, setSelected] = useState(props.options[0]);
useEffect(() => {
if (!selected) {
setSelected(props.options[0]);
}
}, [props.options]);
console.log({ jeff: props.options[0] });
return (
<>
<ListboxPrimitive value={selected} onChange={setSelected}>
<div className="relative w-full">
<ListboxPrimitive.Button
className={clsx(
`relative w-full py-2 pl-3 pr-10 text-left bg-white dark:bg-gray-500
rounded-lg shadow-md cursor-default focus:outline-none focus-visible:ring-2
focus-visible:ring-opacity-75 focus-visible:ring-white focus-visible:ring-offset-orange-300
focus-visible:ring-offset-2 focus-visible:border-indigo-500 sm:text-sm`,
props.className
)}
>
{selected?.option ? (
<span className="block truncate">{selected?.option}</span>
) : (
<span className="block truncate opacity-70">Nothing selected...</span>
)}
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<SelectorIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
</span>
</ListboxPrimitive.Button>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<ListboxPrimitive.Options
className={`
absolute w-full mt-1 overflow-auto rounded-md sm:text-sm
text-base bg-white dark:bg-gray-500 shadow-lg max-h-60
ring-1 ring-black ring-opacity-5 focus:outline-none
`}
>
{props.options.map((person, personIdx) => (
<ListboxPrimitive.Option
key={personIdx}
className={({ active }) =>
`cursor-default select-none relative rounded m-1 py-2 pl-8 pr-4 dark:text-white focus:outline-none ${
active
? 'text-primary-900 bg-primary-600'
: 'text-gray-900 dark:hover:bg-gray-600 dark:hover:bg-opacity-20'
}`
}
value={person}
>
{({ selected }) => (
<>
<span
className={`block truncate ${selected ? 'font-medium' : 'font-normal'}`}
>
{person.option}
{person.description && (
<span
className={clsx(
'text-gray-300 leading-5 ml-3 text-xs',
selected && 'text-white'
)}
>
{person.description}
</span>
)}
</span>
{selected ? (
<span className="absolute inset-y-0 left-0 flex items-center pl-2 text-white">
<CheckIcon className="w-5 h-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</ListboxPrimitive.Option>
))}
</ListboxPrimitive.Options>
</Transition>
</div>
</ListboxPrimitive>
</>
);
}

View file

@ -1,9 +1,10 @@
import React from 'react';
import { useState } from 'react';
import React, { useState } from 'react';
import { Switch } from '@headlessui/react';
import clsx from 'clsx';
export const Toggle = (props: { initialState: boolean }) => {
export const Toggle = (
props: { initialState: boolean; size: 'sm' | 'md' } = { initialState: false, size: 'sm' }
) => {
const [enabled, setEnabled] = useState(props.initialState || false);
return (
@ -11,16 +12,24 @@ export const Toggle = (props: { initialState: boolean }) => {
checked={enabled}
onChange={setEnabled}
className={clsx(
'relative inline-flex items-center h-6 rounded-full w-11 bg-gray-200 dark:bg-gray-750',
'transition relative flex-shrink-0 inline-flex items-center h-6 w-11 rounded-full bg-gray-200 dark:bg-gray-550',
{
'bg-primary-500 dark:bg-primary-500': enabled
'bg-primary-500 dark:bg-primary-500': enabled,
'h-6 w-11': props.size === 'sm',
'h-8 w-[55px]': props.size === 'md'
}
)}
>
<span
className={`${
enabled ? 'translate-x-6' : 'translate-x-1'
} inline-block w-4 h-4 transform bg-white rounded-full`}
className={clsx(
'transition inline-block w-4 h-4 transform bg-white rounded-full',
enabled ? 'translate-x-6' : 'translate-x-1',
{
'w-4 h-4': props.size === 'sm',
'h-6 w-6': props.size === 'md',
'translate-x-7': props.size === 'md' && enabled
}
)}
/>
</Switch>
);

View file

@ -0,0 +1,20 @@
import React from 'react';
import { Transition } from '@headlessui/react';
export default function SlideUp(props: { children: React.ReactNode }) {
return (
<Transition
show
className="flex flex-grow"
appear
enter="transition ease-in-out-back duration-200"
enterFrom="opacity-0 translate-y-5"
enterTo="opacity-100"
leave="transition duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
{props.children}
</Transition>
);
}

View file

@ -1,11 +1,9 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import { FileList } from '../components/file/FileList';
import { emit, listen } from '@tauri-apps/api/event';
import { invoke } from '@tauri-apps/api';
import { IFile } from '../types';
import { useExplorerStore } from '../store/explorer';
import { Inspector } from '../components/file/Inspector';
import {useParams} from "react-router-dom";
export interface DirectoryResponse {
directory: IFile;
@ -13,9 +11,7 @@ export interface DirectoryResponse {
}
export const ExplorerScreen: React.FC<{}> = () => {
// let { slug } = useParams();
const [currentDir, tempWatchDir] = useExplorerStore((state) => [
state.currentDir,
state.tempWatchDir

View file

@ -1,7 +1,5 @@
import React, { useState } from 'react';
import FileItem from '../components/file/FileItem';
import { Button } from '../components/primitive';
import { Tag } from '../components/primitive/Tag';
interface StatItemProps {
name: string;

View file

@ -12,8 +12,7 @@ import React from 'react';
import { SidebarLink } from '../components/file/Sidebar';
import { HardDrive, PaintBrush } from 'phosphor-react';
import clsx from 'clsx';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import GeneralSettings from './settings/General';
import { Outlet } from 'react-router-dom';
//@ts-ignore
// import { Spline } from 'react-spline';
@ -31,80 +30,56 @@ const Heading: React.FC<{ className?: string }> = ({ children, className }) => (
export const SettingsScreen: React.FC<{}> = () => {
return (
<Router>
<div className="flex flex-row w-full">
<div className="p-8 w-60 h-full border-r border-gray-550">
<Heading className="mt-0">Client</Heading>
<SidebarLink to="/general">
<Icon component={CogIcon} />
General
</SidebarLink>
<SidebarLink to="/security">
<Icon component={LockClosedIcon} />
Security
</SidebarLink>
<div className="flex flex-row w-full">
<div className="p-5 w-60 h-full border-r border-gray-550">
<Heading className="mt-0">Client</Heading>
<SidebarLink to="/settings/general">
<Icon component={CogIcon} />
General
</SidebarLink>
<SidebarLink to="/settings/security">
<Icon component={LockClosedIcon} />
Security
</SidebarLink>
<SidebarLink to="/settings/appearance">
<Icon component={PaintBrush} />
Appearance
</SidebarLink>
<SidebarLink to="/appearance">
<Icon component={PaintBrush} />
Appearance
</SidebarLink>
<Heading>Library</Heading>
<Heading>Library</Heading>
<SidebarLink to="/settings/locations">
<Icon component={HardDrive} />
Locations
</SidebarLink>
<SidebarLink to="/settings/media">
<Icon component={PhotographIcon} />
Media
</SidebarLink>
<SidebarLink to="/settings/keys">
<Icon component={KeyIcon} />
Keys
</SidebarLink>
<SidebarLink to="/settings/tags">
<Icon component={TagIcon} />
Tags
</SidebarLink>
<SidebarLink to="/locations">
<Icon component={HardDrive} />
Locations
</SidebarLink>
<SidebarLink to="/media">
<Icon component={PhotographIcon} />
Media
</SidebarLink>
<SidebarLink to="/keys">
<Icon component={KeyIcon} />
Keys
</SidebarLink>
<SidebarLink to="/tags">
<Icon component={TagIcon} />
Tags
</SidebarLink>
<Heading>Cloud</Heading>
<SidebarLink to="/sync">
<Icon component={CloudIcon} />
Sync
</SidebarLink>
<SidebarLink to="/contacts">
<Icon component={UsersIcon} />
Contacts
</SidebarLink>
</div>
<div className="w-full flex-grow overflow-y-scroll">
<div className="p-8">
<Switch>
<Route path="/general">
<GeneralSettings />
</Route>
<Route path="/spaces"></Route>
<Route path="/explorer"></Route>
</Switch>
</div>
{/*<div className="flex flex-row mt-4 space-x-2">*/}
{/* <Toggle initialState={false} />*/}
{/*</div>*/}
{/*<Dropdown*/}
{/* buttonProps={{}}*/}
{/* buttonText="My Library"*/}
{/* items={[*/}
{/* [*/}
{/* { name: 'Edit', icon: PencilAltIcon },*/}
{/* { name: 'Copy', icon: DuplicateIcon }*/}
{/* ],*/}
{/* [{ name: 'Delete', icon: TrashIcon }]*/}
{/* ]}*/}
{/*/>*/}
<Heading>Cloud</Heading>
<SidebarLink to="/settings/sync">
<Icon component={CloudIcon} />
Sync
</SidebarLink>
<SidebarLink to="/settings/contacts">
<Icon component={UsersIcon} />
Contacts
</SidebarLink>
</div>
<div className="flex flex-grow-0 w-full h-full max-h-screen overflow-y-scroll bg-gray-600">
<div className="px-12 py-5">
<Outlet />
<div className="block h-20" />
</div>
</div>
</Router>
</div>
);
};

View file

@ -4,8 +4,12 @@ import { invoke } from '@tauri-apps/api';
import React, { useRef } from 'react';
import { useExplorerStore } from '../../store/explorer';
import { useAppState } from '../../store/global';
import Listbox from '../../components/primitive/Listbox';
import { useLocations } from '../../store/locations';
export default function GeneralSettings() {
const locations = useLocations();
const fileUploader = useRef<HTMLInputElement | null>(null);
const config = useAppState();
@ -13,21 +17,29 @@ export default function GeneralSettings() {
state.tempWatchDir,
state.setTempWatchDir
]);
return (
<div className="space-y-4">
<div className="mb-6">
<h1 className="text-2xl font-bold">General Settings</h1>
<p className="text-sm mt-1 text-gray-400">Basic settings related to this client</p>
<hr className="border-gray-550 mt-4" />
</div>
<InputContainer
title="Quick scan directory"
description="The directory for which this application will perform a detailed scan of the contents and sub directories"
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={tempWatchDir}
size="sm"
className="flex-grow"
onChange={(e) => setTempWatchDir(e.target.value)}
placeholder="/users/jamie/Desktop"
/>
<Button
className="ml-2"
size="sm"
variant="primary"
onClick={async () => {
await invoke('scan_dir', {
@ -44,71 +56,35 @@ export default function GeneralSettings() {
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={config.file_type_thumb_dir}
placeholder="/users/jamie/Desktop"
/>
<Input className="flex-grow" value={config.data_dir} placeholder="/users/jamie/Desktop" />
</div>
</InputContainer>
<InputContainer
title="Media cache directory"
title="Something about a vault"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={config.file_type_thumb_dir}
placeholder="/users/jamie/Desktop"
/>
<Button variant="primary">Enable Vault</Button>
{/*<Input className="flex-grow" value="jeff" placeholder="/users/jamie/Desktop" />*/}
</div>
</InputContainer>
<InputContainer
title="Media cache directory"
title="Something about a vault"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={config.file_type_thumb_dir}
placeholder="/users/jamie/Desktop"
/>
</div>
</InputContainer>
<InputContainer
title="Media cache directory"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={config.file_type_thumb_dir}
placeholder="/users/jamie/Desktop"
/>
</div>
</InputContainer>
<InputContainer
title="Media cache directory"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={config.file_type_thumb_dir}
placeholder="/users/jamie/Desktop"
/>
</div>
</InputContainer>
<InputContainer
title="Media cache directory"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Input
className="w-3/5"
value={config.file_type_thumb_dir}
placeholder="/users/jamie/Desktop"
/>
<div className="flex flex-row space-x-2">
<div className="flex flex-grow">
<Listbox
options={locations.map((location) => ({
key: location.name,
option: location.name,
description: location.path
}))}
/>
</div>
<Button className="mb-3" variant="primary">
Add Location
</Button>
</div>
</InputContainer>
</div>

View file

@ -0,0 +1,40 @@
import React from 'react';
import { Button } from '../../components/primitive';
import { useLocations } from '../../store/locations';
import Listbox from '../../components/primitive/Listbox';
import { InputContainer } from '../../components/primitive/InputContainer';
const exampleLocations = [
{ option: 'Macintosh HD', key: 'macintosh_hd' },
{ option: 'Lacie External', key: 'lacie_external' },
{ option: 'Seagate 8TB', key: 'seagate_8tb' }
];
export default function LocationSettings() {
const locations = useLocations();
return (
<div className="max-w-md">
{/*<Button size="sm">Add Location</Button>*/}
<InputContainer
title="Something about a vault"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row space-x-2">
<div className="flex flex-grow">
<Listbox
options={locations.map((location) => ({
key: location.name,
option: location.name,
description: location.path
}))}
/>
</div>
<Button className="mb-3" variant="primary">
Add Location
</Button>
</div>
</InputContainer>
</div>
);
}

View file

@ -0,0 +1,19 @@
import React from 'react';
import { InputContainer } from '../../components/primitive/InputContainer';
import { Button } from '../../components/primitive';
export default function SecuritySettings() {
return (
<div className="space-y-4">
<InputContainer
title="Something about a vault"
description="Local cache storage for media previews and thumbnails."
>
<div className="flex flex-row">
<Button variant="primary">Enable Vault</Button>
{/*<Input className="flex-grow" value="jeff" placeholder="/users/jamie/Desktop" />*/}
</div>
</InputContainer>
</div>
);
}

View file

View file

View file

View file

View file

View file

@ -0,0 +1,24 @@
# Locations
Locations are paths to a directory or volume on a [Client]() to be indexed and stored within a [Library]().
The user should be promted to add at least one location during onboarding.
Locations are immediately indexed in their entirety.
```rust
struct Location {
id: u32,
name: String,
total_capacity: u32,
available_capacity: u32,
is_removable: bool,
is_ejectable: bool,
is_root_filesystem: bool,
is_online: bool,
library_id: u32,
client_id: u32,
date_created: Option<NaiveDateTime>,
last_indexed: Option<NaiveDateTime>,
}
```

View file

View file

View file

View file

View file

View file

View file

2088
packages/core/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -43,5 +43,6 @@ sea-orm = { version = "^0.4.2", features = [ "sqlx-sqlite", "runtime-async-std-r
walkdir = "^2.3.2"
bytesize = "1.1.0"
env_logger = "0.9.0"
libp2p = "0.43.0"
tokio = {version = "1.15.0", features=["sync"]}

View file

@ -1,46 +0,0 @@
use chrono::NaiveDateTime;
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
// -------------------------------------
// Entity: LocationPaths
//
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, DeriveEntityModel, TS)]
#[sea_orm(table_name = "location_paths")]
#[serde(rename = "LocationPaths")]
#[ts(export)]
// -------------------------------------
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub path: String,
pub rule: PathRule,
pub location_id: u32,
#[ts(type = "string")]
pub date_created: Option<NaiveDateTime>,
#[ts(type = "string")]
pub date_modified: Option<NaiveDateTime>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, EnumIter, DeriveActiveEnum, TS)]
#[sea_orm(rs_type = "i32", db_type = "Integer")]
#[ts(export)]
pub enum PathRule {
#[sea_orm(num_value = 0)]
Exclude,
#[sea_orm(num_value = 1)]
NoWatch,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::locations::Entity",
from = "Column::LocationId",
to = "super::locations::Column::Id"
)]
Locations,
}
impl ActiveModelBehavior for ActiveModel {}

View file

@ -17,6 +17,7 @@ pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub name: String,
pub path: String,
pub total_capacity: u32,
pub available_capacity: u32,
pub is_removable: bool,

View file

@ -3,7 +3,6 @@ pub mod capture_device;
pub mod client;
pub mod file;
pub mod library;
pub mod location_paths;
pub mod locations;
pub mod space;
pub mod tag;

View file

@ -59,15 +59,6 @@ CREATE TABLE IF NOT EXISTS files (
FOREIGN KEY(location_id) REFERENCES locations(id),
FOREIGN KEY(capture_device_id) REFERENCES capture_devices(id)
);
CREATE TABLE IF NOT EXISTS location_paths (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
path TEXT,
rule INTEGER,
location_id INTEGER,
date_created DATE NOT NULL DEFAULT (datetime('now')),
last_indexed DATE NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,

View file

@ -1,3 +1,13 @@
use std::env;
use std::io::Write;
use anyhow::Result;
use once_cell::sync::OnceCell;
use sea_orm::{ActiveModelTrait, QueryOrder};
use sea_orm::EntityTrait;
use sea_orm::Set;
use serde::{Deserialize, Serialize};
use crate::{
db::{
connection::db_instance,
@ -5,20 +15,18 @@ use crate::{
},
get_core_config,
};
use std::env;
use anyhow::Result;
use sea_orm::EntityTrait;
use sea_orm::Set;
use sea_orm::{ActiveModelTrait, QueryOrder};
use serde::{Deserialize, Serialize};
use std::io::Write;
// client config file struct
#[derive(Serialize, Deserialize, Debug)]
pub struct DotClientData {
pub client_id: u32,
pub client_name: Option<String>,
pub tcp_port: Option<u32>
}
// in memory storage for config file
pub static client_config: OnceCell<DotClientData> = OnceCell::new();
pub async fn init_client() -> Result<()> {
let config = get_core_config();
@ -29,11 +37,13 @@ pub async fn init_client() -> Result<()> {
match client_data_file {
Ok(file) => {
let client_data: DotClientData = serde_json::from_reader(file).unwrap();
println!("loaded existing client: {:?}", client_data);
client_config.set(client_data);
println!("loaded existing client: {:?}", client_config.get().unwrap());
}
Err(_) => {
let client_data = create_client().await?;
println!("created new client {:?}", client_data);
client_config.set(client_data);
println!("created new client {:?}", client_config.get().unwrap());
}
};
@ -81,12 +91,30 @@ pub async fn create_client() -> Result<DotClientData> {
// write a file called .spacedrive to path containing the location id in JSON format
let mut dotfile = std::fs::File::create(format!("{}/.client_data", config.data_dir.display()))?;
let data = DotClientData {
client_id: next_client_id,
tcp_port: None,
client_name: None
};
let json = serde_json::to_string(&data)?;
dotfile.write_all(json.as_bytes())?;
Ok(data)
}
fn get_client_config() -> Result<&'static DotClientData> {
let client = client_config.get().unwrap();
Ok(client)
}
// fn update_client_config(key: String, value: String) -> Result<&'static DotClientData> {
// let mut client = client_config.get().unwrap();
//
// let existing_value = client[key];
//
// Ok(client)
// }

View file

@ -1,31 +1,23 @@
use crate::db::{connection::DB_INSTANCE, entity::file, entity::location_paths, entity::locations};
use crate::file::{checksum::create_meta_integrity_hash, init};
use crate::util::time;
use std::{collections::HashMap, ffi::OsStr, fs, path::Path, path::PathBuf, time::Instant};
use anyhow::Result;
use chrono::Utc;
use sea_orm::QueryFilter;
use sea_orm::{entity::*, QueryOrder};
use std::{collections::HashMap, ffi::OsStr, fs, path::Path, path::PathBuf, time::Instant};
use walkdir::{DirEntry, WalkDir};
use super::locations::get_location_and_paths;
use crate::db::{connection::DB_INSTANCE, entity::file};
use crate::file::{checksum::create_meta_integrity_hash, init};
use crate::util::time;
use super::locations::get_location;
use super::watcher::watch_dir;
pub async fn scan_paths(location_id: u32) -> Result<()> {
// get location by location_id from db and include location_paths
let (_location, location_paths) = get_location_and_paths(location_id).await?;
let location = get_location(location_id).await?;
// loop over and scan() paths
if !location_paths.is_empty() {
for location_path in location_paths {
if location_path.rule != location_paths::PathRule::Exclude {
scan(&location_path.path).await?;
}
if location_path.rule != location_paths::PathRule::NoWatch {
watch_dir(&location_path.path);
}
}
}
scan(&location.path).await?;
watch_dir(&location.path);
Ok(())
}

View file

@ -1,30 +1,32 @@
use super::init;
use crate::{
db::{
connection::DB_INSTANCE,
entity::{file, location_paths, locations},
},
native::methods::get_mounts,
};
use anyhow::{anyhow, Result};
use chrono::Utc;
use sea_orm::ColumnTrait;
use sea_orm::Set;
use sea_orm::{ActiveModelTrait, QueryOrder};
use sea_orm::{EntityTrait, QueryFilter};
use sea_orm::ColumnTrait;
use sea_orm::Set;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::io::Write;
use std::path::Path;
use crate::{
db::{
connection::DB_INSTANCE,
entity::{file, locations},
},
native::methods::get_mounts,
};
use super::init;
#[derive(Serialize, Deserialize)]
struct DotSpaceDrive {
location_id: u32,
}
pub async fn get_location_and_paths(
pub async fn get_location(
location_id: u32,
) -> Result<(locations::Model, Vec<location_paths::Model>)> {
) -> Result<locations::Model> {
let db = DB_INSTANCE.get().unwrap();
// get location by location_id from db and include location_paths
@ -37,17 +39,7 @@ pub async fn get_location_and_paths(
Err(_) => return Err(anyhow!("location_not_found")),
};
// get location paths
let location_paths = match location_paths::Entity::find()
.filter(location_paths::Column::LocationId.eq(location_id))
.all(db)
.await
{
Ok(location_paths) => location_paths,
Err(_) => vec![],
};
Ok((location.unwrap(), location_paths))
Ok(location.unwrap())
}
pub async fn create_location(path: &str) -> Result<()> {
@ -76,7 +68,8 @@ pub async fn create_location(path: &str) -> Result<()> {
let location = locations::ActiveModel {
id: Set(next_location_id),
client_id: Set(1),
name: Set(Path::new(path)
name: Set(mount.name.to_owned()),
path: Set(Path::new(path)
.file_name()
.unwrap()
.to_str()
@ -95,14 +88,6 @@ pub async fn create_location(path: &str) -> Result<()> {
};
location.save(db).await?;
// insert root path as location_path to database
let location_path = location_paths::ActiveModel {
location_id: Set(next_location_id),
path: Set(path.to_owned()),
..Default::default()
};
location_path.save(db).await?;
// write a file called .spacedrive to path containing the location id in JSON format
let mut dotfile = std::fs::File::create(format!("{}/.spacedrive", path))?;
let data = DotSpaceDrive {

View file

@ -1,4 +1,3 @@
use anyhow::Result;
use futures::{stream::StreamExt, Stream};
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
@ -10,10 +9,11 @@ pub mod crypto;
pub mod db;
pub mod file;
pub mod native;
pub mod p2p;
pub mod util;
use futures::executor::block_on;
// static configuration
// static configuration passed in by host application
#[derive(Serialize, Deserialize, Debug)]
pub struct CoreConfig {
pub data_dir: std::path::PathBuf,
@ -86,6 +86,8 @@ pub fn configure(mut data_dir: std::path::PathBuf) -> mpsc::Receiver<ClientEvent
println!("Spacedrive daemon online");
p2p::listener::listen(None);
// env_logger::builder()
// .filter_level(log::LevelFilter::Debug)
// .is_test(true)

View file

@ -0,0 +1,43 @@
use async_std::task;
use libp2p::{identity, Multiaddr, PeerId, ping};
use libp2p::swarm::{Swarm, SwarmEvent};
use std::error::Error;
pub async fn listen(port: Option<u32>) -> Result<(), Box<dyn Error>> {
let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
println!("Local peer id: {:?}", local_peer_id);
let transport = libp2p::development_transport(local_key).await?;
// Create a ping network behaviour.
//
// For illustrative purposes, the ping protocol is configured to
// keep the connection alive, so a continuous sequence of pings
// can be observed.
let behaviour = ping::Behaviour::new(ping::Config::new().with_keep_alive(true));
let mut swarm = Swarm::new(transport, behaviour, local_peer_id);
// Tell the swarm to listen on all interfaces and a random, OS-assigned
// port.
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
// Dial the peer identified by the multi-address given as the second
// command-line argument, if any.
let address = format!("{}{}", "/ip4/127.0.0.1/tcp/", port);
if let Some(addr) = address {
let remote: Multiaddr = addr.parse()?;
swarm.dial(remote)?;
println!("Dialed {}", addr)
}
loop {
match swarm.select_next_some().await {
SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {:?}", address),
SwarmEvent::Behaviour(event) => println!("{:?}", event),
_ => {}
}
}
}

View file

@ -0,0 +1 @@
pub mod listener;

320
yarn.lock
View file

@ -393,14 +393,14 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3":
"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3":
version "7.16.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a"
integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.10.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
"@babel/runtime@^7.10.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7":
version "7.17.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
@ -769,6 +769,158 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@radix-ui/primitive@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-0.1.0.tgz#6206b97d379994f0d1929809db035733b337e543"
integrity sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95"
integrity sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-context@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-0.1.1.tgz#06996829ea124d9a1bc1dbe3e51f33588fab0875"
integrity sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-dialog@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-0.1.5.tgz#4310659607f5ad0b8796623d5f7490dc47d3d295"
integrity sha512-WftvXcQSszUphCTLQkkpBIkrYYU0IYqgIvACLQady4BN4YHDgdNlrwdg2ti9QrXgq1PZ+0S/6BIaA1dmSuRQ2g==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "0.1.0"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-dismissable-layer" "0.1.3"
"@radix-ui/react-focus-guards" "0.1.0"
"@radix-ui/react-focus-scope" "0.1.3"
"@radix-ui/react-id" "0.1.4"
"@radix-ui/react-portal" "0.1.3"
"@radix-ui/react-presence" "0.1.1"
"@radix-ui/react-primitive" "0.1.3"
"@radix-ui/react-slot" "0.1.2"
"@radix-ui/react-use-controllable-state" "0.1.0"
aria-hidden "^1.1.1"
react-remove-scroll "^2.4.0"
"@radix-ui/react-dismissable-layer@0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.3.tgz#d427c7520c3799d2b957e40e7d67045d96120356"
integrity sha512-3veE7M8K13Qb+6+tC3DHWmWV9VMuuRoZvRLdrvz7biSraK/qkGBN4LbKZDaTdw2D2HS7RNpSd/sF8pFd3TaAgA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "0.1.0"
"@radix-ui/react-context" "0.1.1"
"@radix-ui/react-primitive" "0.1.3"
"@radix-ui/react-use-body-pointer-events" "0.1.0"
"@radix-ui/react-use-callback-ref" "0.1.0"
"@radix-ui/react-use-escape-keydown" "0.1.0"
"@radix-ui/react-focus-guards@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-0.1.0.tgz#ba3b6f902cba7826569f8edc21ff8223dece7def"
integrity sha512-kRx/swAjEfBpQ3ns7J3H4uxpXuWCqN7MpALiSDOXiyo2vkWv0L9sxvbpZeTulINuE3CGMzicVMuNc/VWXjFKOg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-focus-scope@0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-0.1.3.tgz#b1cc825b6190001d731417ed90d192d13b41bce1"
integrity sha512-bKi+lw14SriQqYWMBe13b/wvxSqYMC+3FylMUEwOKA6JrBoldpkhX5XffGDdpDRTTpjbncdH3H7d1PL5Bs7Ikg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-primitive" "0.1.3"
"@radix-ui/react-use-callback-ref" "0.1.0"
"@radix-ui/react-id@0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-0.1.4.tgz#4cd6126e6ac8a43ebe6d52948a068b797cc9ad71"
integrity sha512-/hq5m/D0ZfJWOS7TLF+G0l08KDRs87LBE46JkAvgKkg1fW4jkucx9At9D9vauIPSbdNmww5kXEp566hMlA8eXA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "0.1.0"
"@radix-ui/react-portal@0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-0.1.3.tgz#56826e789b3d4e37983f6d23666e3f1b1b9ee358"
integrity sha512-DrV+sPYLs0HhmX5/b7yRT6nLM9Nl6FtQe2KUG+46kiCOKQ+0XzNMO5hmeQtyq0mRf/qlC02rFu6OMsWpIqVsJg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "0.1.3"
"@radix-ui/react-use-layout-effect" "0.1.0"
"@radix-ui/react-presence@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-0.1.1.tgz#2088dec6f4f8042f83dd2d6bf9e8ef09dadbbc15"
integrity sha512-LsL+NcWDpFUAYCmXeH02o4pgqcSLpwxP84UIjCtpIKrsPe2vLuhcp79KC/jZJeXz+of2lUpMAxpM+eCpxFZtlg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-use-layout-effect" "0.1.0"
"@radix-ui/react-primitive@0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-0.1.3.tgz#585c35ef2ec06bab0ea9e0fc5c916e556661b881"
integrity sha512-fcyADaaAx2jdqEDLsTs6aX50S3L1c9K9CC6XMpJpuXFJCU4n9PGTFDZRtY2gAoXXoRCPIBsklCopSmGb6SsDjQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-slot" "0.1.2"
"@radix-ui/react-slot@0.1.2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-0.1.2.tgz#e6f7ad9caa8ce81cc8d532c854c56f9b8b6307c8"
integrity sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-use-body-pointer-events@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-body-pointer-events/-/react-use-body-pointer-events-0.1.0.tgz#29b211464493f8ca5149ce34b96b95abbc97d741"
integrity sha512-svPyoHCcwOq/vpWNEvdH/yD91vN9p8BtiozNQbjVmJRxQ/vS12zqk70AxTGWe+2ZKHq2sggpEQNTv1JHyVFlnQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "0.1.0"
"@radix-ui/react-use-callback-ref@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz#934b6e123330f5b3a6b116460e6662cbc663493f"
integrity sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-controllable-state@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz#4fced164acfc69a4e34fb9d193afdab973a55de1"
integrity sha512-zv7CX/PgsRl46a52Tl45TwqwVJdmqnlQEQhaYMz/yBOD2sx2gCkCFSoF/z9mpnYWmS6DTLNTg5lIps3fV6EnXg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "0.1.0"
"@radix-ui/react-use-escape-keydown@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.0.tgz#dc80cb3753e9d1bd992adbad9a149fb6ea941874"
integrity sha512-tDLZbTGFmvXaazUXXv8kYbiCcbAE8yKgng9s95d8fCO+Eundv0Jngbn/hKPhDDs4jj9ChwRX5cDDnlaN+ugYYQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "0.1.0"
"@radix-ui/react-use-layout-effect@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223"
integrity sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==
dependencies:
"@babel/runtime" "^7.13.10"
"@reach/skip-nav@^0.11.2":
version "0.11.2"
resolved "https://registry.yarnpkg.com/@reach/skip-nav/-/skip-nav-0.11.2.tgz#015498b2125ad8ef1e48cb8ab33dca93925fcbc8"
@ -1493,6 +1645,13 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
aria-hidden@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254"
integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==
dependencies:
tslib "^1.0.0"
aria-query@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
@ -2750,6 +2909,11 @@ detect-libc@^1.0.3:
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
detect-node-es@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
detect-node@^2.0.4:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
@ -3828,6 +3992,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
get-nonce@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
get-orientation@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/get-orientation/-/get-orientation-1.1.2.tgz#20507928951814f8a91ded0a0e67b29dfab98947"
@ -4231,17 +4400,12 @@ he@1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
history@^4.9.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
history@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/history/-/history-5.2.0.tgz#7cdd31cf9bac3c5d31f09c231c9928fad0007b7c"
integrity sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==
dependencies:
"@babel/runtime" "^7.1.2"
loose-envify "^1.2.0"
resolve-pathname "^3.0.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
value-equal "^1.0.1"
"@babel/runtime" "^7.7.6"
hmac-drbg@^1.0.1:
version "1.0.1"
@ -4252,7 +4416,7 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2:
hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@ -4489,6 +4653,13 @@ into-stream@^3.1.0:
from2 "^2.1.1"
p-is-promise "^1.1.0"
invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"
is-alphabetical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
@ -4817,11 +4988,6 @@ is-yarn-global@^0.3.0:
resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232"
integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@ -5111,7 +5277,7 @@ longest@^1.0.0:
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@ -5835,14 +6001,6 @@ mimic-response@^3.1.0:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
mini-create-react-context@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e"
integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
dependencies:
"@babel/runtime" "^7.12.1"
tiny-warning "^1.0.3"
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@ -6578,13 +6736,6 @@ path-parse@^1.0.6:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-to-regexp@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
dependencies:
isarray "0.0.1"
path-type@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
@ -7021,7 +7172,7 @@ react-is@17.0.2:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@ -7043,34 +7194,39 @@ react-refresh@^0.10.0:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.10.0.tgz#2f536c9660c0b9b1d500684d9e52a65e7404f7e3"
integrity sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==
react-router-dom@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363"
integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==
react-remove-scroll-bar@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz#d4d545a7df024f75d67e151499a6ab5ac97c8cdd"
integrity sha512-UU9ZBP1wdMR8qoUs7owiVcpaPwsQxUDC2lypP6mmixaGlARZa7ZIBx1jcuObLdhMOvCsnZcvetOho0wzPa9PYg==
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
loose-envify "^1.3.1"
prop-types "^15.6.2"
react-router "5.2.1"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-style-singleton "^2.1.0"
tslib "^1.0.0"
react-router@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d"
integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==
react-remove-scroll@^2.4.0:
version "2.4.4"
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.4.4.tgz#2dfff377cf17efc00de39dad51c143fc7a1b9e3e"
integrity sha512-EyC5ohYhaeKbThMSQxuN2i+QC5HqV3AJvNZKEdiATITexu0gHm00+5ko0ltNS1ajYJVeDgVG2baRSCei0AUWlQ==
dependencies:
"@babel/runtime" "^7.12.13"
history "^4.9.0"
hoist-non-react-statics "^3.1.0"
loose-envify "^1.3.1"
mini-create-react-context "^0.4.0"
path-to-regexp "^1.7.0"
prop-types "^15.6.2"
react-is "^16.6.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
react-remove-scroll-bar "^2.1.0"
react-style-singleton "^2.1.0"
tslib "^1.0.0"
use-callback-ref "^1.2.3"
use-sidecar "^1.0.1"
react-router-dom@6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.2.1.tgz#32ec81829152fbb8a7b045bf593a22eadf019bec"
integrity sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==
dependencies:
history "^5.2.0"
react-router "6.2.1"
react-router@6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.2.1.tgz#be2a97a6006ce1d9123c28934e604faef51448a3"
integrity sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==
dependencies:
history "^5.2.0"
react-spline@^1.2.1:
version "1.2.1"
@ -7079,6 +7235,15 @@ react-spline@^1.2.1:
dependencies:
three "0.123.0"
react-style-singleton@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.1.1.tgz#ce7f90b67618be2b6b94902a30aaea152ce52e66"
integrity sha512-jNRp07Jza6CBqdRKNgGhT3u9umWvils1xsuMOjZlghBDH2MU0PL2WZor4PGYjXpnRCa9DQSlHMs/xnABWOwYbA==
dependencies:
get-nonce "^1.0.0"
invariant "^2.2.4"
tslib "^1.0.0"
react-transition-group@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
@ -7333,11 +7498,6 @@ resolve-from@^5.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve-pathname@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
resolve@^1.10.0, resolve@^1.20.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
@ -8199,16 +8359,6 @@ timers-browserify@2.0.12:
dependencies:
setimmediate "^1.0.4"
tiny-invariant@^1.0.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9"
integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
tiny-warning@^1.0.0, tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
title@^3.4.2:
version "3.4.4"
resolved "https://registry.yarnpkg.com/title/-/title-3.4.4.tgz#5c0ab11fd69643bc05dc006bba52aaf5c1630f5e"
@ -8334,7 +8484,7 @@ tsconfig@*:
strip-bom "^3.0.0"
strip-json-comments "^2.0.0"
tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
tslib@^1.0.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@ -8694,6 +8844,19 @@ url-to-options@^1.0.1:
resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
use-callback-ref@^1.2.3:
version "1.2.5"
resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.5.tgz#6115ed242cfbaed5915499c0a9842ca2912f38a5"
integrity sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==
use-sidecar@^1.0.1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.5.tgz#ffff2a17c1df42e348624b699ba6e5c220527f2b"
integrity sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==
dependencies:
detect-node-es "^1.1.0"
tslib "^1.9.3"
use-subscription@1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
@ -8756,11 +8919,6 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
value-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
vfile-message@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a"