mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-13 07:14:03 +00:00
- tcp listener WIP
- better settings
This commit is contained in:
parent
d065937c35
commit
764b052c3f
6
.idea/jsLinters/eslint.xml
Normal file
6
.idea/jsLinters/eslint.xml
Normal 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
6
.idea/prettier.xml
Normal 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>
|
|
@ -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
255
.idea/workspace.xml
Normal 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>
|
|
@ -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",
|
||||
|
|
1847
apps/desktop/src-tauri/Cargo.lock
generated
1847
apps/desktop/src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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(())
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
// });
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
26
apps/desktop/src/components/layout/Dialog.tsx
Normal file
26
apps/desktop/src/components/layout/Dialog.tsx
Normal 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>
|
||||
// );
|
||||
// }
|
|
@ -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"
|
||||
|
|
|
@ -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" /> */}
|
||||
</>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 '.';
|
||||
|
|
|
@ -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
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
103
apps/desktop/src/components/primitive/Listbox.tsx
Normal file
103
apps/desktop/src/components/primitive/Listbox.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
|
|
20
apps/desktop/src/components/transitions/SlideUp.tsx
Normal file
20
apps/desktop/src/components/transitions/SlideUp.tsx
Normal 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>
|
||||
);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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>
|
40
apps/desktop/src/screens/settings/LocationSettings.tsx
Normal file
40
apps/desktop/src/screens/settings/LocationSettings.tsx
Normal 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>
|
||||
);
|
||||
}
|
19
apps/desktop/src/screens/settings/SecuritySettings.tsx
Normal file
19
apps/desktop/src/screens/settings/SecuritySettings.tsx
Normal 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>
|
||||
);
|
||||
}
|
0
apps/docs/pages/features/albums.mdx
Normal file
0
apps/docs/pages/features/albums.mdx
Normal file
0
apps/docs/pages/features/encoder.mdx
Normal file
0
apps/docs/pages/features/encoder.mdx
Normal file
0
apps/docs/pages/features/encryption.mdx
Normal file
0
apps/docs/pages/features/encryption.mdx
Normal file
0
apps/docs/pages/features/key-manager.mdx
Normal file
0
apps/docs/pages/features/key-manager.mdx
Normal file
0
apps/docs/pages/features/library.mdx
Normal file
0
apps/docs/pages/features/library.mdx
Normal file
24
apps/docs/pages/features/locations.mdx
Normal file
24
apps/docs/pages/features/locations.mdx
Normal 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>,
|
||||
}
|
||||
```
|
0
apps/docs/pages/features/media-viewer.mdx
Normal file
0
apps/docs/pages/features/media-viewer.mdx
Normal file
0
apps/docs/pages/features/preview-generation.mdx
Normal file
0
apps/docs/pages/features/preview-generation.mdx
Normal file
0
apps/docs/pages/features/search.mdx
Normal file
0
apps/docs/pages/features/search.mdx
Normal file
0
apps/docs/pages/features/smart-tags.mdx
Normal file
0
apps/docs/pages/features/smart-tags.mdx
Normal file
0
apps/docs/pages/features/spaces.mdx
Normal file
0
apps/docs/pages/features/spaces.mdx
Normal file
0
apps/docs/pages/features/statistics.mdx
Normal file
0
apps/docs/pages/features/statistics.mdx
Normal file
0
apps/docs/pages/features/sync.mdx
Normal file
0
apps/docs/pages/features/sync.mdx
Normal file
0
apps/docs/pages/features/timeline.mdx
Normal file
0
apps/docs/pages/features/timeline.mdx
Normal file
0
apps/docs/pages/features/workers.mdx
Normal file
0
apps/docs/pages/features/workers.mdx
Normal file
2088
packages/core/Cargo.lock
generated
2088
packages/core/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -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"]}
|
|
@ -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 {}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
// }
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
43
packages/core/lib/p2p/listener.rs
Normal file
43
packages/core/lib/p2p/listener.rs
Normal 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),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
1
packages/core/lib/p2p/mod.rs
Normal file
1
packages/core/lib/p2p/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod listener;
|
320
yarn.lock
320
yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue