mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 13:23:28 +00:00
merge duplicate prettier config and format repo with it
This commit is contained in:
parent
fe4da9048a
commit
aacdf33216
2
.prettierignore
Normal file
2
.prettierignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
.build
|
|
@ -7,7 +7,7 @@ module.exports = {
|
|||
bracketSameLine: false,
|
||||
semi: true,
|
||||
quoteProps: 'consistent',
|
||||
importOrder: ['^@sd/interface/(.*)$', '^@sd/client/(.*)$', '^@sd/ui/(.*)$', '^[./]'],
|
||||
importOrder: ['^[./]', '^@sd/interface/(.*)$', '^@sd/client/(.*)$', '^@sd/ui/(.*)$'],
|
||||
importOrderSeparation: true,
|
||||
importOrderSortSpecifiers: true,
|
||||
plugins: ['@trivago/prettier-plugin-sort-imports']
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"pluginSearchDirs": [
|
||||
"."
|
||||
],
|
||||
"useTabs": true,
|
||||
"printWidth": 100,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSameLine": false,
|
||||
"semi": true,
|
||||
"quoteProps": "consistent",
|
||||
"importOrder": [
|
||||
"^[./]",
|
||||
"^@sd/ui/(.*)$",
|
||||
"^@sd/client/(.*)$",
|
||||
"^@sd/interface/(.*)$"
|
||||
],
|
||||
"importOrderSeparation": true,
|
||||
"importOrderSortSpecifiers": true
|
||||
}
|
|
@ -109,4 +109,3 @@ This project is using what I'm calling the **"PRRTT"** stack (Prisma, Rust, Reac
|
|||
- `ios`: A [Swift](https://developer.apple.com/swift/) Native binary (planned).
|
||||
- `windows`: A [C#](https://docs.microsoft.com/en-us/dotnet/csharp/) Native binary (planned).
|
||||
- `android`: A [Kotlin](https://kotlinlang.org/) Native binary (planned).
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@ import { Button } from '@sd/ui';
|
|||
import React from 'react';
|
||||
import { PageContextBuiltIn } from 'vite-plugin-ssr';
|
||||
|
||||
import '@sd/ui/style';
|
||||
|
||||
import { Footer } from './components/Footer';
|
||||
import NavBar from './components/NavBar';
|
||||
import { PageContextProvider } from './renderer/usePageContext';
|
||||
import './style.scss';
|
||||
|
||||
import '@sd/ui/style';
|
||||
|
||||
export default function App({
|
||||
children,
|
||||
pageContext
|
||||
|
|
|
@ -2,8 +2,6 @@ import clsx from 'clsx';
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import { ReactComponent as Info } from '@sd/interface/assets/svg/info.svg';
|
||||
|
||||
import AppEmbed, { AppEmbedPlaceholder } from '../components/AppEmbed';
|
||||
import { Bubbles } from '../components/Bubbles';
|
||||
// import { Bubbles } from '../components/Bubbles';
|
||||
|
@ -12,6 +10,8 @@ import NewBanner from '../components/NewBanner';
|
|||
import { usePageContext } from '../renderer/usePageContext';
|
||||
import { getWindow } from '../utils';
|
||||
|
||||
import { ReactComponent as Info } from '@sd/interface/assets/svg/info.svg';
|
||||
|
||||
interface SectionProps {
|
||||
orientation: 'left' | 'right';
|
||||
heading?: string;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import { ReactComponent as ArrowRight } from '@sd/interface/assets/svg/arrow-right.svg';
|
||||
|
||||
import Markdown from '../components/Markdown';
|
||||
import { TeamMember, TeamMemberProps } from '../components/TeamMember';
|
||||
import { resolveFilesGlob } from '../utils';
|
||||
|
||||
import { ReactComponent as ArrowRight } from '@sd/interface/assets/svg/arrow-right.svg';
|
||||
|
||||
const teamImages = resolveFilesGlob(import.meta.globEager('../assets/images/team/*'));
|
||||
const investorImages = resolveFilesGlob(import.meta.globEager('../assets/images/investors/*'));
|
||||
|
||||
|
|
|
@ -139,7 +139,6 @@ html {
|
|||
background: url('/egg-bloom-two.png') no-repeat center center;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes bloomBurst {
|
||||
|
@ -170,47 +169,48 @@ html {
|
|||
}
|
||||
|
||||
.slot-block {
|
||||
@apply bg-gray-550 py-3 px-4 border-l-4 border-gray-400 rounded mb-2
|
||||
@apply bg-gray-550 py-3 px-4 border-l-4 border-gray-400 rounded mb-2;
|
||||
}
|
||||
.slot-block.note {
|
||||
@apply border-yellow-400 bg-yellow-300/20
|
||||
@apply border-yellow-400 bg-yellow-300/20;
|
||||
}
|
||||
.slot-block.info {
|
||||
@apply border-green-400 bg-green-400/20
|
||||
@apply border-green-400 bg-green-400/20;
|
||||
}
|
||||
.slot-block.warning {
|
||||
@apply border-red-400 bg-red-400/20
|
||||
@apply border-red-400 bg-red-400/20;
|
||||
}
|
||||
.slot-block-title {
|
||||
@apply text-white font-bold text-sm m-0 uppercase;
|
||||
}
|
||||
.slot-block-content {
|
||||
@apply my-1 mx-0 mb-0 text-white
|
||||
@apply my-1 mx-0 mb-0 text-white;
|
||||
}
|
||||
|
||||
.doc-sidebar-button:hover, .doc-sidebar-button.nav-active {
|
||||
.doc-sidebar-button:hover,
|
||||
.doc-sidebar-button.nav-active {
|
||||
&.product {
|
||||
color:#459EE8;
|
||||
color: #459ee8;
|
||||
div {
|
||||
background-color: #459EE8;
|
||||
background-color: #459ee8;
|
||||
}
|
||||
}
|
||||
&.developers {
|
||||
color:#48BB78;
|
||||
color: #48bb78;
|
||||
div {
|
||||
background-color: #48BB78;
|
||||
background-color: #48bb78;
|
||||
}
|
||||
}
|
||||
&.company {
|
||||
color:#bb9247;
|
||||
color: #bb9247;
|
||||
div {
|
||||
background-color: #bb9247;
|
||||
}
|
||||
}
|
||||
&.changelog {
|
||||
color:#8A47BB;
|
||||
color: #8a47bb;
|
||||
div {
|
||||
background-color: #8A47BB;
|
||||
background-color: #8a47bb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,6 @@ html {
|
|||
// #1D054B
|
||||
// #9A3F8C
|
||||
|
||||
|
||||
.custom-scroll {
|
||||
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
||||
scrollbar-width: none; /* for Firefox */
|
||||
|
@ -238,7 +237,6 @@ html {
|
|||
@apply bg-[#00000006] dark:bg-[#00000030] my-[10px] rounded-[6px];
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply rounded-[6px] bg-gray-300 dark:bg-gray-550 ;
|
||||
|
||||
@apply rounded-[6px] bg-gray-300 dark:bg-gray-550;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "expo"
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "expo"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,110 +3,357 @@
|
|||
|
||||
export type Procedures = {
|
||||
queries:
|
||||
{ key: "files.readMetadata", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "getNode", input: never, result: NodeState } |
|
||||
{ key: "jobs.getHistory", input: LibraryArgs<null>, result: Array<JobReport> } |
|
||||
{ key: "jobs.getRunning", input: LibraryArgs<null>, result: Array<JobReport> } |
|
||||
{ key: "library.getStatistics", input: LibraryArgs<null>, result: Statistics } |
|
||||
{ key: "library.list", input: never, result: Array<LibraryConfigWrapped> } |
|
||||
{ key: "locations.getById", input: LibraryArgs<number>, result: Location | null } |
|
||||
{ key: "locations.getExplorerData", input: LibraryArgs<LocationExplorerArgs>, result: ExplorerData } |
|
||||
{ key: "locations.indexer_rules.get", input: LibraryArgs<number>, result: IndexerRule } |
|
||||
{ key: "locations.indexer_rules.list", input: LibraryArgs<null>, result: Array<IndexerRule> } |
|
||||
{ key: "locations.list", input: LibraryArgs<null>, result: Array<{ id: number, pub_id: Array<number>, node_id: number, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, is_archived: boolean, date_created: string, node: Node }> } |
|
||||
{ key: "tags.get", input: LibraryArgs<number>, result: Tag | null } |
|
||||
{ key: "tags.getExplorerData", input: LibraryArgs<number>, result: ExplorerData } |
|
||||
{ key: "tags.getForObject", input: LibraryArgs<number>, result: Array<Tag> } |
|
||||
{ key: "tags.list", input: LibraryArgs<null>, result: Array<Tag> } |
|
||||
{ key: "version", input: never, result: string } |
|
||||
{ key: "volumes.list", input: never, result: Array<Volume> },
|
||||
| { key: 'files.readMetadata'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'getNode'; input: never; result: NodeState }
|
||||
| { key: 'jobs.getHistory'; input: LibraryArgs<null>; result: Array<JobReport> }
|
||||
| { key: 'jobs.getRunning'; input: LibraryArgs<null>; result: Array<JobReport> }
|
||||
| { key: 'library.getStatistics'; input: LibraryArgs<null>; result: Statistics }
|
||||
| { key: 'library.list'; input: never; result: Array<LibraryConfigWrapped> }
|
||||
| { key: 'locations.getById'; input: LibraryArgs<number>; result: Location | null }
|
||||
| {
|
||||
key: 'locations.getExplorerData';
|
||||
input: LibraryArgs<LocationExplorerArgs>;
|
||||
result: ExplorerData;
|
||||
}
|
||||
| { key: 'locations.indexer_rules.get'; input: LibraryArgs<number>; result: IndexerRule }
|
||||
| { key: 'locations.indexer_rules.list'; input: LibraryArgs<null>; result: Array<IndexerRule> }
|
||||
| {
|
||||
key: 'locations.list';
|
||||
input: LibraryArgs<null>;
|
||||
result: Array<{
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
node_id: number;
|
||||
name: string | null;
|
||||
local_path: string | null;
|
||||
total_capacity: number | null;
|
||||
available_capacity: number | null;
|
||||
filesystem: string | null;
|
||||
disk_type: number | null;
|
||||
is_removable: boolean | null;
|
||||
is_online: boolean;
|
||||
is_archived: boolean;
|
||||
date_created: string;
|
||||
node: Node;
|
||||
}>;
|
||||
}
|
||||
| { key: 'tags.get'; input: LibraryArgs<number>; result: Tag | null }
|
||||
| { key: 'tags.getExplorerData'; input: LibraryArgs<number>; result: ExplorerData }
|
||||
| { key: 'tags.getForObject'; input: LibraryArgs<number>; result: Array<Tag> }
|
||||
| { key: 'tags.list'; input: LibraryArgs<null>; result: Array<Tag> }
|
||||
| { key: 'version'; input: never; result: string }
|
||||
| { key: 'volumes.list'; input: never; result: Array<Volume> };
|
||||
mutations:
|
||||
{ key: "files.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "files.setFavorite", input: LibraryArgs<SetFavoriteArgs>, result: null } |
|
||||
{ key: "files.setNote", input: LibraryArgs<SetNoteArgs>, result: null } |
|
||||
{ key: "jobs.generateThumbsForLocation", input: LibraryArgs<GenerateThumbsForLocationArgs>, result: null } |
|
||||
{ key: "jobs.identifyUniqueFiles", input: LibraryArgs<IdentifyUniqueFilesArgs>, result: null } |
|
||||
{ key: "library.create", input: string, result: LibraryConfigWrapped } |
|
||||
{ key: "library.delete", input: string, result: null } |
|
||||
{ key: "library.edit", input: EditLibraryArgs, result: null } |
|
||||
{ key: "locations.create", input: LibraryArgs<LocationCreateArgs>, result: null } |
|
||||
{ key: "locations.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.fullRescan", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.indexer_rules.create", input: LibraryArgs<IndexerRuleCreateArgs>, result: IndexerRule } |
|
||||
{ key: "locations.indexer_rules.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.quickRescan", input: LibraryArgs<null>, result: null } |
|
||||
{ key: "locations.update", input: LibraryArgs<LocationUpdateArgs>, result: null } |
|
||||
{ key: "tags.assign", input: LibraryArgs<TagAssignArgs>, result: null } |
|
||||
{ key: "tags.create", input: LibraryArgs<TagCreateArgs>, result: Tag } |
|
||||
{ key: "tags.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "tags.update", input: LibraryArgs<TagUpdateArgs>, result: null },
|
||||
| { key: 'files.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'files.setFavorite'; input: LibraryArgs<SetFavoriteArgs>; result: null }
|
||||
| { key: 'files.setNote'; input: LibraryArgs<SetNoteArgs>; result: null }
|
||||
| {
|
||||
key: 'jobs.generateThumbsForLocation';
|
||||
input: LibraryArgs<GenerateThumbsForLocationArgs>;
|
||||
result: null;
|
||||
}
|
||||
| { key: 'jobs.identifyUniqueFiles'; input: LibraryArgs<IdentifyUniqueFilesArgs>; result: null }
|
||||
| { key: 'library.create'; input: string; result: LibraryConfigWrapped }
|
||||
| { key: 'library.delete'; input: string; result: null }
|
||||
| { key: 'library.edit'; input: EditLibraryArgs; result: null }
|
||||
| { key: 'locations.create'; input: LibraryArgs<LocationCreateArgs>; result: null }
|
||||
| { key: 'locations.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'locations.fullRescan'; input: LibraryArgs<number>; result: null }
|
||||
| {
|
||||
key: 'locations.indexer_rules.create';
|
||||
input: LibraryArgs<IndexerRuleCreateArgs>;
|
||||
result: IndexerRule;
|
||||
}
|
||||
| { key: 'locations.indexer_rules.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'locations.quickRescan'; input: LibraryArgs<null>; result: null }
|
||||
| { key: 'locations.update'; input: LibraryArgs<LocationUpdateArgs>; result: null }
|
||||
| { key: 'tags.assign'; input: LibraryArgs<TagAssignArgs>; result: null }
|
||||
| { key: 'tags.create'; input: LibraryArgs<TagCreateArgs>; result: Tag }
|
||||
| { key: 'tags.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'tags.update'; input: LibraryArgs<TagUpdateArgs>; result: null };
|
||||
subscriptions:
|
||||
{ key: "invalidateQuery", input: never, result: InvalidateOperationEvent } |
|
||||
{ key: "jobs.newThumbnail", input: LibraryArgs<null>, result: string }
|
||||
| { key: 'invalidateQuery'; input: never; result: InvalidateOperationEvent }
|
||||
| { key: 'jobs.newThumbnail'; input: LibraryArgs<null>; result: string };
|
||||
};
|
||||
|
||||
export interface ConfigMetadata { version: string | null }
|
||||
export interface ConfigMetadata {
|
||||
version: string | null;
|
||||
}
|
||||
|
||||
export interface EditLibraryArgs { id: string, name: string | null, description: string | null }
|
||||
export interface EditLibraryArgs {
|
||||
id: string;
|
||||
name: string | null;
|
||||
description: string | null;
|
||||
}
|
||||
|
||||
export type ExplorerContext = { type: "Location" } & Location | { type: "Tag" } & Tag
|
||||
export type ExplorerContext = ({ type: 'Location' } & Location) | ({ type: 'Tag' } & Tag);
|
||||
|
||||
export interface ExplorerData { context: ExplorerContext, items: Array<ExplorerItem> }
|
||||
export interface ExplorerData {
|
||||
context: ExplorerContext;
|
||||
items: Array<ExplorerItem>;
|
||||
}
|
||||
|
||||
export type ExplorerItem = { type: "Path" } & { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, object_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string, object: Object | null } | { type: "Object" } & { id: number, cas_id: string, integrity_checksum: string | null, name: string | null, extension: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string, file_paths: Array<FilePath> }
|
||||
export type ExplorerItem =
|
||||
| ({ type: 'Path' } & {
|
||||
id: number;
|
||||
is_dir: boolean;
|
||||
location_id: number;
|
||||
materialized_path: string;
|
||||
name: string;
|
||||
extension: string | null;
|
||||
object_id: number | null;
|
||||
parent_id: number | null;
|
||||
key_id: number | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
object: Object | null;
|
||||
})
|
||||
| ({ type: 'Object' } & {
|
||||
id: number;
|
||||
cas_id: string;
|
||||
integrity_checksum: string | null;
|
||||
name: string | null;
|
||||
extension: string | null;
|
||||
kind: number;
|
||||
size_in_bytes: string;
|
||||
key_id: number | null;
|
||||
hidden: boolean;
|
||||
favorite: boolean;
|
||||
important: boolean;
|
||||
has_thumbnail: boolean;
|
||||
has_thumbstrip: boolean;
|
||||
has_video_preview: boolean;
|
||||
ipfs_id: string | null;
|
||||
note: string | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
file_paths: Array<FilePath>;
|
||||
});
|
||||
|
||||
export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, object_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string }
|
||||
export interface FilePath {
|
||||
id: number;
|
||||
is_dir: boolean;
|
||||
location_id: number;
|
||||
materialized_path: string;
|
||||
name: string;
|
||||
extension: string | null;
|
||||
object_id: number | null;
|
||||
parent_id: number | null;
|
||||
key_id: number | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
}
|
||||
|
||||
export interface GenerateThumbsForLocationArgs { id: number, path: string }
|
||||
export interface GenerateThumbsForLocationArgs {
|
||||
id: number;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface IdentifyUniqueFilesArgs { id: number, path: string }
|
||||
export interface IdentifyUniqueFilesArgs {
|
||||
id: number;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface IndexerRule { id: number, kind: number, name: string, parameters: Array<number>, date_created: string, date_modified: string }
|
||||
export interface IndexerRule {
|
||||
id: number;
|
||||
kind: number;
|
||||
name: string;
|
||||
parameters: Array<number>;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
}
|
||||
|
||||
export interface IndexerRuleCreateArgs { kind: RuleKind, name: string, parameters: Array<number> }
|
||||
export interface IndexerRuleCreateArgs {
|
||||
kind: RuleKind;
|
||||
name: string;
|
||||
parameters: Array<number>;
|
||||
}
|
||||
|
||||
export interface InvalidateOperationEvent { key: string, arg: any }
|
||||
export interface InvalidateOperationEvent {
|
||||
key: string;
|
||||
arg: any;
|
||||
}
|
||||
|
||||
export interface JobReport { id: string, name: string, data: Array<number> | null, metadata: any | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number }
|
||||
export interface JobReport {
|
||||
id: string;
|
||||
name: string;
|
||||
data: Array<number> | null;
|
||||
metadata: any | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
status: JobStatus;
|
||||
task_count: number;
|
||||
completed_task_count: number;
|
||||
message: string;
|
||||
seconds_elapsed: number;
|
||||
}
|
||||
|
||||
export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused"
|
||||
export type JobStatus = 'Queued' | 'Running' | 'Completed' | 'Canceled' | 'Failed' | 'Paused';
|
||||
|
||||
export interface LibraryArgs<T> { library_id: string, arg: T }
|
||||
export interface LibraryArgs<T> {
|
||||
library_id: string;
|
||||
arg: T;
|
||||
}
|
||||
|
||||
export interface LibraryConfig { version: string | null, name: string, description: string }
|
||||
export interface LibraryConfig {
|
||||
version: string | null;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig }
|
||||
export interface LibraryConfigWrapped {
|
||||
uuid: string;
|
||||
config: LibraryConfig;
|
||||
}
|
||||
|
||||
export interface Location { id: number, pub_id: Array<number>, node_id: number, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, is_archived: boolean, date_created: string }
|
||||
export interface Location {
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
node_id: number;
|
||||
name: string | null;
|
||||
local_path: string | null;
|
||||
total_capacity: number | null;
|
||||
available_capacity: number | null;
|
||||
filesystem: string | null;
|
||||
disk_type: number | null;
|
||||
is_removable: boolean | null;
|
||||
is_online: boolean;
|
||||
is_archived: boolean;
|
||||
date_created: string;
|
||||
}
|
||||
|
||||
export interface LocationCreateArgs { path: string, indexer_rules_ids: Array<number> }
|
||||
export interface LocationCreateArgs {
|
||||
path: string;
|
||||
indexer_rules_ids: Array<number>;
|
||||
}
|
||||
|
||||
export interface LocationExplorerArgs { location_id: number, path: string, limit: number, cursor: string | null }
|
||||
export interface LocationExplorerArgs {
|
||||
location_id: number;
|
||||
path: string;
|
||||
limit: number;
|
||||
cursor: string | null;
|
||||
}
|
||||
|
||||
export interface LocationUpdateArgs { id: number, name: string | null, indexer_rules_ids: Array<number> }
|
||||
export interface LocationUpdateArgs {
|
||||
id: number;
|
||||
name: string | null;
|
||||
indexer_rules_ids: Array<number>;
|
||||
}
|
||||
|
||||
export interface Node { id: number, pub_id: Array<number>, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string }
|
||||
export interface Node {
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
name: string;
|
||||
platform: number;
|
||||
version: string | null;
|
||||
last_seen: string;
|
||||
timezone: string | null;
|
||||
date_created: string;
|
||||
}
|
||||
|
||||
export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null }
|
||||
export interface NodeConfig {
|
||||
version: string | null;
|
||||
id: string;
|
||||
name: string;
|
||||
p2p_port: number | null;
|
||||
}
|
||||
|
||||
export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string }
|
||||
export interface NodeState {
|
||||
version: string | null;
|
||||
id: string;
|
||||
name: string;
|
||||
p2p_port: number | null;
|
||||
data_path: string;
|
||||
}
|
||||
|
||||
export interface Object { id: number, cas_id: string, integrity_checksum: string | null, name: string | null, extension: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string }
|
||||
export interface Object {
|
||||
id: number;
|
||||
cas_id: string;
|
||||
integrity_checksum: string | null;
|
||||
name: string | null;
|
||||
extension: string | null;
|
||||
kind: number;
|
||||
size_in_bytes: string;
|
||||
key_id: number | null;
|
||||
hidden: boolean;
|
||||
favorite: boolean;
|
||||
important: boolean;
|
||||
has_thumbnail: boolean;
|
||||
has_thumbstrip: boolean;
|
||||
has_video_preview: boolean;
|
||||
ipfs_id: string | null;
|
||||
note: string | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
}
|
||||
|
||||
export type RuleKind = "AcceptFilesByGlob" | "RejectFilesByGlob" | "AcceptIfChildrenDirectoriesArePresent" | "RejectIfChildrenDirectoriesArePresent"
|
||||
export type RuleKind =
|
||||
| 'AcceptFilesByGlob'
|
||||
| 'RejectFilesByGlob'
|
||||
| 'AcceptIfChildrenDirectoriesArePresent'
|
||||
| 'RejectIfChildrenDirectoriesArePresent';
|
||||
|
||||
export interface SetFavoriteArgs { id: number, favorite: boolean }
|
||||
export interface SetFavoriteArgs {
|
||||
id: number;
|
||||
favorite: boolean;
|
||||
}
|
||||
|
||||
export interface SetNoteArgs { id: number, note: string | null }
|
||||
export interface SetNoteArgs {
|
||||
id: number;
|
||||
note: string | null;
|
||||
}
|
||||
|
||||
export interface Statistics { id: number, date_captured: string, total_object_count: number, library_db_size: string, total_bytes_used: string, total_bytes_capacity: string, total_unique_bytes: string, total_bytes_free: string, preview_media_bytes: string }
|
||||
export interface Statistics {
|
||||
id: number;
|
||||
date_captured: string;
|
||||
total_object_count: number;
|
||||
library_db_size: string;
|
||||
total_bytes_used: string;
|
||||
total_bytes_capacity: string;
|
||||
total_unique_bytes: string;
|
||||
total_bytes_free: string;
|
||||
preview_media_bytes: string;
|
||||
}
|
||||
|
||||
export interface Tag { id: number, pub_id: Array<number>, name: string | null, color: string | null, total_objects: number | null, redundancy_goal: number | null, date_created: string, date_modified: string }
|
||||
export interface Tag {
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
name: string | null;
|
||||
color: string | null;
|
||||
total_objects: number | null;
|
||||
redundancy_goal: number | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
}
|
||||
|
||||
export interface TagAssignArgs { object_id: number, tag_id: number, unassign: boolean }
|
||||
export interface TagAssignArgs {
|
||||
object_id: number;
|
||||
tag_id: number;
|
||||
unassign: boolean;
|
||||
}
|
||||
|
||||
export interface TagCreateArgs { name: string, color: string }
|
||||
export interface TagCreateArgs {
|
||||
name: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface TagUpdateArgs { id: number, name: string | null, color: string | null }
|
||||
export interface TagUpdateArgs {
|
||||
id: number;
|
||||
name: string | null;
|
||||
color: string | null;
|
||||
}
|
||||
|
||||
export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean }
|
||||
export interface Volume {
|
||||
name: string;
|
||||
mount_point: string;
|
||||
total_capacity: bigint;
|
||||
available_capacity: bigint;
|
||||
is_removable: boolean;
|
||||
disk_type: string | null;
|
||||
file_system: string | null;
|
||||
is_root_filesystem: boolean;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="dark">
|
||||
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Spacedrive</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
</head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="./index.tsx"></script>
|
||||
</body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import App from './App';
|
||||
import '@sd/ui/style';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
import App from './App';
|
||||
|
||||
import '@sd/ui/style';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
{
|
||||
"extends": "../../packages/config/interface.tsconfig.json",
|
||||
"compilerOptions": {},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ This document outlines the peer to peer protocol used by the Spacedrive desktop
|
|||
|
||||
## Concepts
|
||||
|
||||
- **Peer** - TODO
|
||||
- **Peer** - TODO
|
||||
|
||||
### P2PManager
|
||||
|
||||
|
@ -34,7 +34,7 @@ To discovery other machines running Spacedrive over your local network, we make
|
|||
|
||||
Spacedrive advertise a SRV record that looks like:
|
||||
|
||||
_{peer_id}_spacedrive_._udp_.local. 86400 IN SRV 10 5 5223 server.example.com.
|
||||
_{peer_id}\_spacedrive_._udp_.local. 86400 IN SRV 10 5 5223 server.example.com.
|
||||
|
||||
This system will continue to passively discover clients while Spacedrive is running.
|
||||
|
||||
|
@ -58,24 +58,11 @@ TODO
|
|||
Message::QueryClientAnnouncement(vec![peer_id, peer_id2]);
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## General Overview
|
||||
|
||||
This system is designed on top of the following main technologies:
|
||||
- [QUIC]() - A tcp-like protocol built on top of UDP. QUIC also supports [TLS 1.3]() for encryption and pro
|
||||
|
||||
|
||||
|
||||
|
||||
- [QUIC]() - A tcp-like protocol built on top of UDP. QUIC also supports [TLS 1.3]() for encryption and pro
|
||||
|
||||
## Pairing
|
||||
|
||||
|
@ -83,5 +70,5 @@ TODO
|
|||
|
||||
# External Resources
|
||||
|
||||
- TODO: Magic Wormhole talk
|
||||
- TODO: Syncthing spec
|
||||
- TODO: Magic Wormhole talk
|
||||
- TODO: Syncthing spec
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# crdt-rs
|
||||
|
||||
Just @brendonovich experimenting with CRDT stuff.
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
```rust
|
||||
pub fn update_with_timestamp(&self, timestamp: &Timestamp) -> Result<(), String> {
|
||||
let mut now = (self.clock)();
|
||||
|
@ -31,7 +29,7 @@ pub fn update_with_timestamp(&self, timestamp: &Timestamp) -> Result<(), String>
|
|||
```
|
||||
|
||||
```javascript
|
||||
Timestamp.recv = function(msg) {
|
||||
Timestamp.recv = function (msg) {
|
||||
if (!clock) {
|
||||
return null;
|
||||
}
|
||||
|
@ -70,10 +68,6 @@ Timestamp.recv = function(msg) {
|
|||
clock.timestamp.setMillis(max_time);
|
||||
clock.timestamp.setCounter(last_time);
|
||||
|
||||
return new Timestamp(
|
||||
clock.timestamp.millis(),
|
||||
clock.timestamp.counter(),
|
||||
clock.timestamp.node()
|
||||
);
|
||||
return new Timestamp(clock.timestamp.millis(), clock.timestamp.counter(), clock.timestamp.node());
|
||||
};
|
||||
```
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
import clsx from "clsx";
|
||||
import { createSignal, For, JSX, Suspense } from "solid-js";
|
||||
import { queryClient, rspc } from "./rspc";
|
||||
import clsx from 'clsx';
|
||||
import { For, JSX, Suspense, createSignal } from 'solid-js';
|
||||
|
||||
import { queryClient, rspc } from './rspc';
|
||||
|
||||
export function App() {
|
||||
const dbs = rspc.createQuery(() => ["dbs"]);
|
||||
const dbs = rspc.createQuery(() => ['dbs']);
|
||||
|
||||
const createDb = rspc.createMutation("createDatabase", {
|
||||
const createDb = rspc.createMutation('createDatabase', {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries();
|
||||
},
|
||||
}
|
||||
});
|
||||
const removeDbs = rspc.createMutation("removeDatabases", {
|
||||
onSuccess: () => queryClient.invalidateQueries(),
|
||||
const removeDbs = rspc.createMutation('removeDatabases', {
|
||||
onSuccess: () => queryClient.invalidateQueries()
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="p-4 space-y-4">
|
||||
<div class="space-x-4">
|
||||
<Button onClick={() => createDb.mutate(undefined)}>Add Database</Button>
|
||||
<Button onClick={() => removeDbs.mutate(undefined)}>
|
||||
Remove Databases
|
||||
</Button>
|
||||
<Button onClick={() => removeDbs.mutate(undefined)}>Remove Databases</Button>
|
||||
</div>
|
||||
<ul class="gap-2 flex flex-row flex-wrap">
|
||||
<For each={dbs.data}>
|
||||
|
@ -38,10 +37,10 @@ export function App() {
|
|||
interface DatabaseViewProps {
|
||||
id: string;
|
||||
}
|
||||
const TABS = ["Tags", "Files", "File Paths", "Messages"];
|
||||
const TABS = ['Tags', 'Files', 'File Paths', 'Messages'];
|
||||
|
||||
function DatabaseView(props: DatabaseViewProps) {
|
||||
const [currentTab, setCurrentTab] = createSignal<typeof TABS[number]>("Tags");
|
||||
const [currentTab, setCurrentTab] = createSignal<typeof TABS[number]>('Tags');
|
||||
|
||||
return (
|
||||
<div class="bg-indigo-300 rounded-md min-w-[40rem] flex-1 overflow-hidden">
|
||||
|
@ -51,10 +50,7 @@ function DatabaseView(props: DatabaseViewProps) {
|
|||
<For each={TABS}>
|
||||
{(tab) => (
|
||||
<button
|
||||
class={clsx(
|
||||
"px-2 py-1",
|
||||
tab === currentTab() && "bg-indigo-400"
|
||||
)}
|
||||
class={clsx('px-2 py-1', tab === currentTab() && 'bg-indigo-400')}
|
||||
onClick={() => setCurrentTab(tab)}
|
||||
>
|
||||
{tab}
|
||||
|
@ -69,7 +65,5 @@ function DatabaseView(props: DatabaseViewProps) {
|
|||
}
|
||||
|
||||
function Button(props: JSX.ButtonHTMLAttributes<HTMLButtonElement>) {
|
||||
return (
|
||||
<button {...props} class="bg-blue-500 text-white px-2 py-1 rounded-md" />
|
||||
);
|
||||
return <button {...props} class="bg-blue-500 text-white px-2 py-1 rounded-md" />;
|
||||
}
|
||||
|
|
|
@ -2,14 +2,21 @@
|
|||
|
||||
export type Procedures = {
|
||||
queries:
|
||||
{ key: "db.tags", input: string, result: Record<string, Tag> } |
|
||||
{ key: "dbs", input: never, result: Array<string> },
|
||||
| { key: 'db.tags'; input: string; result: Record<string, Tag> }
|
||||
| { key: 'dbs'; input: never; result: Array<string> };
|
||||
mutations:
|
||||
{ key: "createDatabase", input: never, result: string } |
|
||||
{ key: "removeDatabases", input: never, result: null },
|
||||
subscriptions: never
|
||||
| { key: 'createDatabase'; input: never; result: string }
|
||||
| { key: 'removeDatabases'; input: never; result: null };
|
||||
subscriptions: never;
|
||||
};
|
||||
|
||||
export interface Color { red: number, green: number, blue: number }
|
||||
export interface Color {
|
||||
red: number;
|
||||
green: number;
|
||||
blue: number;
|
||||
}
|
||||
|
||||
export interface Tag { color: Color, name: string }
|
||||
export interface Tag {
|
||||
color: Color;
|
||||
name: string;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* @refresh reload */
|
||||
import { render, Suspense } from "solid-js/web";
|
||||
import { Suspense, render } from 'solid-js/web';
|
||||
|
||||
import "./index.css";
|
||||
import { App } from "./App";
|
||||
import { queryClient, rspc, rspcClient } from "./rspc";
|
||||
import { App } from './App';
|
||||
import './index.css';
|
||||
import { queryClient, rspc, rspcClient } from './rspc';
|
||||
|
||||
render(
|
||||
() => (
|
||||
|
@ -13,5 +13,5 @@ render(
|
|||
</Suspense>
|
||||
</rspc.Provider>
|
||||
),
|
||||
document.getElementById("root") as HTMLElement
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
import { QueryClient } from "@tanstack/solid-query";
|
||||
import { createSolidQueryHooks } from "@rspc/solid";
|
||||
import { createClient } from "@rspc/client";
|
||||
import { TauriTransport } from "@rspc/tauri";
|
||||
import { createClient } from '@rspc/client';
|
||||
import { createSolidQueryHooks } from '@rspc/solid';
|
||||
import { TauriTransport } from '@rspc/tauri';
|
||||
import { QueryClient } from '@tanstack/solid-query';
|
||||
|
||||
import type { Procedures } from "./bindings"; // These were the bindings exported from your Rust code!
|
||||
import type { Procedures } from './bindings';
|
||||
|
||||
// These were the bindings exported from your Rust code!
|
||||
|
||||
// You must provide the generated types as a generic and create a transport (in this example we are using HTTP Fetch) so that the client knows how to communicate with your API.
|
||||
export const rspcClient = createClient<Procedures>({
|
||||
// Refer to the integration your using for the correct transport.
|
||||
transport: new TauriTransport(),
|
||||
transport: new TauriTransport()
|
||||
});
|
||||
|
||||
export const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
suspense: true,
|
||||
},
|
||||
},
|
||||
suspense: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const rspc = createSolidQueryHooks<Procedures>();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { defineConfig } from "vite";
|
||||
import solidPlugin from "vite-plugin-solid";
|
||||
import { defineConfig } from 'vite';
|
||||
import solidPlugin from 'vite-plugin-solid';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [solidPlugin()],
|
||||
|
@ -9,17 +9,17 @@ export default defineConfig({
|
|||
// tauri expects a fixed port, fail if that port is not available
|
||||
server: {
|
||||
port: 1420,
|
||||
strictPort: true,
|
||||
strictPort: true
|
||||
},
|
||||
// to make use of `TAURI_DEBUG` and other env variables
|
||||
// https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
|
||||
envPrefix: ["VITE_", "TAURI_"],
|
||||
envPrefix: ['VITE_', 'TAURI_'],
|
||||
build: {
|
||||
// Tauri supports es2021
|
||||
target: ["es2021", "chrome100", "safari13"],
|
||||
target: ['es2021', 'chrome100', 'safari13'],
|
||||
// don't minify for debug builds
|
||||
minify: !process.env.TAURI_DEBUG ? "esbuild" : false,
|
||||
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
|
||||
// produce sourcemaps for debug builds
|
||||
sourcemap: !!process.env.TAURI_DEBUG,
|
||||
},
|
||||
sourcemap: !!process.env.TAURI_DEBUG
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
This release has not happened yet, stay tuned...
|
||||
:::
|
||||
|
||||
After __ months of development we are extremely excited to be releasing the first version of Spacedrive as an early public beta.
|
||||
After \_\_ months of development we are extremely excited to be releasing the first version of Spacedrive as an early public beta.
|
||||
|
||||
This is an MVP, and by no means feature complete. Please test out the features listed below and give us feedback via Discord, email or GitHub Issues :D
|
||||
|
||||
This release is missing database synchronization between nodes (your devices), for now this renders connecting nodes useless, other than to transfer individual files. But don't worry, its coming very soon!
|
||||
|
||||
*Features:*
|
||||
_Features:_
|
||||
|
||||
- Support for Windows, Linux and macOS, iOS and Android.
|
||||
|
||||
|
@ -21,20 +21,20 @@ This release is missing database synchronization between nodes (your devices), f
|
|||
- Connect multiple [Nodes](../architecture/nodes.md) to a Library via LAN.
|
||||
|
||||
- Add [Locations](../architecture/locations.md) to import files into Spacedrive.
|
||||
|
||||
- Indexer watch for changes and performs light re-scans.
|
||||
|
||||
- Identifier generates checksum and categorizes files into [Objects]()
|
||||
|
||||
- Define rules for indexer to ignore certain files or folders.
|
||||
|
||||
*Eventually Clouds will be supported and added as Cloud Locations*
|
||||
_Eventually Clouds will be supported and added as Cloud Locations_
|
||||
|
||||
- Browse Locations via the [Explorer](../architecture/explorer.md) and view previews and metadata.
|
||||
- Viewer options: row/grid item size, gap adjustment, show/hide info.
|
||||
- Context menu: rename, copy, duplicate, delete, favorite and add tags.
|
||||
- Multi-select with dedicated context menu options.
|
||||
- Open with default OS app, in-app viewer (images/text only) or Apple Quicklook
|
||||
|
||||
- Automatically identify unique files to discover duplicates, shown in the inspector.
|
||||
|
||||
- Generate [Preview Media](../architecture/preview-media.md) for image, video and text.
|
||||
|
@ -45,7 +45,7 @@ This release is missing database synchronization between nodes (your devices), f
|
|||
|
||||
- Automated Spaces can include files that match criteria.
|
||||
|
||||
*Eventually Spaces will be sharable, publically or privately*
|
||||
_Eventually Spaces will be sharable, publically or privately_
|
||||
|
||||
- Create photo [Albums](../architecture/albums.md) and add images.
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
index: 10
|
||||
---
|
||||
|
||||
# Albums
|
||||
|
||||
you can put photos here
|
|
@ -2,7 +2,6 @@
|
|||
index: 10
|
||||
---
|
||||
|
||||
|
||||
# Explorer
|
||||
|
||||
using the interface, features
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
index: 1
|
||||
---
|
||||
|
||||
# Libraries
|
||||
|
||||
A library is the database that Spacedrive stores all file structures and metadata. It can be synchronized with other [Nodes]()
|
|
@ -1,10 +1,9 @@
|
|||
---
|
||||
index: 3
|
||||
---
|
||||
|
||||
# Nodes
|
||||
|
||||
Nodes are instances of the Spacedrive core running on a device, they are able to connect to each other via a peer-to-peer network. A node is able to run many libraries simultaneously, but must be authorized per-library in order to synchronize.
|
||||
|
||||
|
||||
|
||||
p2p, connecting nodes, protocols.
|
||||
|
|
|
@ -19,7 +19,7 @@ Some Objects are purely virtual, meaning they have no Path and are likely only u
|
|||
## Types of object
|
||||
|
||||
| Name | Description | Code |
|
||||
| ---------------- | ------------------------------------------------------------ | ---- |
|
||||
| ---------------- | ---------------------------------------------------------------------------------------------------------- | ---- |
|
||||
| Unknown | A file that can not be identified by the indexer | 0 |
|
||||
| Document | A known filetype, but without specific support | 1 |
|
||||
| Folder | A virtual filesystem directory | 2 |
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
index: 11
|
||||
---
|
||||
|
||||
|
||||
# Search
|
||||
|
||||
Press CTRL+F while on a Spacedrive window to access search.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
index: 3
|
||||
---
|
||||
|
||||
# Spaces
|
||||
|
||||
Spaces are virtual folders that can be shared publicly on the internet, or privately with friends, family and teams. Spaces contain [Objects](/docs/developers/architecture/objects) which can be physically stored on any connected Node, or by Spacedrive as a service. Objects can be organized and presented spatially, with various layouts and variable grid placements. Color theme, icon packs and typography can be customized per Space.
|
||||
|
|
|
@ -3,4 +3,3 @@ index: 10
|
|||
---
|
||||
|
||||
# Virtual Filesystem
|
||||
|
||||
|
|
|
@ -4,23 +4,27 @@ index: 500
|
|||
---
|
||||
|
||||
# JavaScript Client
|
||||
|
||||
For developers who want to extend the functionality of Spacedrive, this library allows easy development of [Extensions](), providing full access to Spacedrive's functionality.
|
||||
|
||||
### Installation
|
||||
|
||||
```shell
|
||||
$ npm i @spacedrive/client
|
||||
```
|
||||
|
||||
Initialize the Spacedrive client
|
||||
```ts
|
||||
import spacedrive from "@spacedrive/client";
|
||||
|
||||
spacedrive.start()
|
||||
```ts
|
||||
import spacedrive from '@spacedrive/client';
|
||||
|
||||
spacedrive.start();
|
||||
```
|
||||
|
||||
Add a location
|
||||
|
||||
```ts
|
||||
const location = await spacedrive.location.create("/Users/jamie/Documents");
|
||||
const location = await spacedrive.location.create('/Users/jamie/Documents');
|
||||
|
||||
location.scan();
|
||||
```
|
|
@ -17,16 +17,21 @@ This project uses [Cargo](https://doc.rust-lang.org/cargo/getting-started/instal
|
|||
2. **Run setup script**
|
||||
|
||||
**For Linux or MacOS users run:**
|
||||
|
||||
```shell
|
||||
./.github/scripts/setup-system.sh
|
||||
```
|
||||
|
||||
This will install FFMPEG and any other required dependencies for Spacedrive to build.
|
||||
|
||||
**...or for Windows users run using PowerShell:**
|
||||
|
||||
```shell
|
||||
.\.github\scripts\setup-system.ps1
|
||||
```
|
||||
|
||||
_This will install pnpm, LLVM, FFMPEG and any other required dependencies for Spacedrive to build. Ensure you run it like documented above as it expects it is executed from the root of the repository._
|
||||
|
||||
3. **Install dependencies**
|
||||
```shell
|
||||
pnpm i
|
||||
|
|
|
@ -4,4 +4,3 @@ index: 0
|
|||
---
|
||||
|
||||
# Terminology
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ Locations are places Spacedrive looks for files. You can add Locations from any
|
|||
Locations can be managed from the settings. The "online" indicator shows if that Location is currently accessible from one of your devices.
|
||||
|
||||
## Scanning
|
||||
|
||||
When a Location is added it is immediately scanned. The scan happens via several phases.
|
||||
|
||||
1. The [Indexer](): directory structure is indexed and saved to your library's database.
|
||||
|
@ -28,6 +29,7 @@ There is a button to trigger a full re-scan of this Location. Otherwise the loca
|
|||
Deleting a location will remove the data from the database permanently.
|
||||
|
||||
## Archiving
|
||||
|
||||
::: slot warning
|
||||
This feature is WIP
|
||||
:::
|
||||
|
@ -36,7 +38,9 @@ Locations can be archived, meaning the directory structure is extracted from the
|
|||
Archives are useful when files have been moved or deleted from a Location, but you want to keep a record of the directory structure of that Location without cluttering the Spacedrive interface. File metadata can optionally be included/excluded from the archive file.
|
||||
|
||||
## Dynamic Space
|
||||
|
||||
A slider in the Location settings allows you to allocate an amount of GB to use as redundancy for other Locations. The storage space will be filled and emptied dynamically, recent and important files will be copied as priority.
|
||||
|
||||
## Encrypted Space
|
||||
|
||||
Allocate a portion of this location to be encrypted
|
|
@ -11,4 +11,3 @@ It is not possible to connect Nodes yet, please check our [roadmap](/roadmap).
|
|||
Nodes are instances of Spacedrive, commonly your devices. Currently Spacedrive supports Windows, Linux, Mac, iOS and Android.
|
||||
|
||||
These devices can be connected via P2P to directly and securely synchronize and move data.
|
||||
|
||||
|
|
|
@ -11,4 +11,5 @@ For the convenience of finding, organizing and sharing files even when you don't
|
|||
This data is heavily compressed and very portable, you can have multiple libraries and even lock and encrypt them.
|
||||
|
||||
## Deleting a Library
|
||||
|
||||
A Library can be deleted,
|
|
@ -8,7 +8,7 @@
|
|||
"landing-web": "turbo run dev --parallel --filter=@sd/landing --filter=@sd/web",
|
||||
"gen:migrations": "cd core && cargo prisma migrate dev",
|
||||
"gen:prisma": "cd core && cargo prisma generate",
|
||||
"format": "prettier --config .prettierrc.cli.js --write \"**/*.{ts,tsx,html,scss,json,yml,md}\"",
|
||||
"format": "prettier --config .prettierrc.js --write \"**/*.{ts,tsx,html,scss,json,yml,md}\"",
|
||||
"desktop": "pnpm --filter @sd/desktop --",
|
||||
"web": "pnpm --filter @sd/web -- ",
|
||||
"landing": "pnpm --filter @sd/landing -- ",
|
||||
|
|
|
@ -3,110 +3,357 @@
|
|||
|
||||
export type Procedures = {
|
||||
queries:
|
||||
{ key: "files.readMetadata", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "getNode", input: never, result: NodeState } |
|
||||
{ key: "jobs.getHistory", input: LibraryArgs<null>, result: Array<JobReport> } |
|
||||
{ key: "jobs.getRunning", input: LibraryArgs<null>, result: Array<JobReport> } |
|
||||
{ key: "library.getStatistics", input: LibraryArgs<null>, result: Statistics } |
|
||||
{ key: "library.list", input: never, result: Array<LibraryConfigWrapped> } |
|
||||
{ key: "locations.getById", input: LibraryArgs<number>, result: Location | null } |
|
||||
{ key: "locations.getExplorerData", input: LibraryArgs<LocationExplorerArgs>, result: ExplorerData } |
|
||||
{ key: "locations.indexer_rules.get", input: LibraryArgs<number>, result: IndexerRule } |
|
||||
{ key: "locations.indexer_rules.list", input: LibraryArgs<null>, result: Array<IndexerRule> } |
|
||||
{ key: "locations.list", input: LibraryArgs<null>, result: Array<{ id: number, pub_id: Array<number>, node_id: number, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, is_archived: boolean, date_created: string, node: Node }> } |
|
||||
{ key: "tags.get", input: LibraryArgs<number>, result: Tag | null } |
|
||||
{ key: "tags.getExplorerData", input: LibraryArgs<number>, result: ExplorerData } |
|
||||
{ key: "tags.getForObject", input: LibraryArgs<number>, result: Array<Tag> } |
|
||||
{ key: "tags.list", input: LibraryArgs<null>, result: Array<Tag> } |
|
||||
{ key: "version", input: never, result: string } |
|
||||
{ key: "volumes.list", input: never, result: Array<Volume> },
|
||||
| { key: 'files.readMetadata'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'getNode'; input: never; result: NodeState }
|
||||
| { key: 'jobs.getHistory'; input: LibraryArgs<null>; result: Array<JobReport> }
|
||||
| { key: 'jobs.getRunning'; input: LibraryArgs<null>; result: Array<JobReport> }
|
||||
| { key: 'library.getStatistics'; input: LibraryArgs<null>; result: Statistics }
|
||||
| { key: 'library.list'; input: never; result: Array<LibraryConfigWrapped> }
|
||||
| { key: 'locations.getById'; input: LibraryArgs<number>; result: Location | null }
|
||||
| {
|
||||
key: 'locations.getExplorerData';
|
||||
input: LibraryArgs<LocationExplorerArgs>;
|
||||
result: ExplorerData;
|
||||
}
|
||||
| { key: 'locations.indexer_rules.get'; input: LibraryArgs<number>; result: IndexerRule }
|
||||
| { key: 'locations.indexer_rules.list'; input: LibraryArgs<null>; result: Array<IndexerRule> }
|
||||
| {
|
||||
key: 'locations.list';
|
||||
input: LibraryArgs<null>;
|
||||
result: Array<{
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
node_id: number;
|
||||
name: string | null;
|
||||
local_path: string | null;
|
||||
total_capacity: number | null;
|
||||
available_capacity: number | null;
|
||||
filesystem: string | null;
|
||||
disk_type: number | null;
|
||||
is_removable: boolean | null;
|
||||
is_online: boolean;
|
||||
is_archived: boolean;
|
||||
date_created: string;
|
||||
node: Node;
|
||||
}>;
|
||||
}
|
||||
| { key: 'tags.get'; input: LibraryArgs<number>; result: Tag | null }
|
||||
| { key: 'tags.getExplorerData'; input: LibraryArgs<number>; result: ExplorerData }
|
||||
| { key: 'tags.getForObject'; input: LibraryArgs<number>; result: Array<Tag> }
|
||||
| { key: 'tags.list'; input: LibraryArgs<null>; result: Array<Tag> }
|
||||
| { key: 'version'; input: never; result: string }
|
||||
| { key: 'volumes.list'; input: never; result: Array<Volume> };
|
||||
mutations:
|
||||
{ key: "files.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "files.setFavorite", input: LibraryArgs<SetFavoriteArgs>, result: null } |
|
||||
{ key: "files.setNote", input: LibraryArgs<SetNoteArgs>, result: null } |
|
||||
{ key: "jobs.generateThumbsForLocation", input: LibraryArgs<GenerateThumbsForLocationArgs>, result: null } |
|
||||
{ key: "jobs.identifyUniqueFiles", input: LibraryArgs<IdentifyUniqueFilesArgs>, result: null } |
|
||||
{ key: "library.create", input: string, result: LibraryConfigWrapped } |
|
||||
{ key: "library.delete", input: string, result: null } |
|
||||
{ key: "library.edit", input: EditLibraryArgs, result: null } |
|
||||
{ key: "locations.create", input: LibraryArgs<LocationCreateArgs>, result: null } |
|
||||
{ key: "locations.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.fullRescan", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.indexer_rules.create", input: LibraryArgs<IndexerRuleCreateArgs>, result: IndexerRule } |
|
||||
{ key: "locations.indexer_rules.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.quickRescan", input: LibraryArgs<null>, result: null } |
|
||||
{ key: "locations.update", input: LibraryArgs<LocationUpdateArgs>, result: null } |
|
||||
{ key: "tags.assign", input: LibraryArgs<TagAssignArgs>, result: null } |
|
||||
{ key: "tags.create", input: LibraryArgs<TagCreateArgs>, result: Tag } |
|
||||
{ key: "tags.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "tags.update", input: LibraryArgs<TagUpdateArgs>, result: null },
|
||||
| { key: 'files.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'files.setFavorite'; input: LibraryArgs<SetFavoriteArgs>; result: null }
|
||||
| { key: 'files.setNote'; input: LibraryArgs<SetNoteArgs>; result: null }
|
||||
| {
|
||||
key: 'jobs.generateThumbsForLocation';
|
||||
input: LibraryArgs<GenerateThumbsForLocationArgs>;
|
||||
result: null;
|
||||
}
|
||||
| { key: 'jobs.identifyUniqueFiles'; input: LibraryArgs<IdentifyUniqueFilesArgs>; result: null }
|
||||
| { key: 'library.create'; input: string; result: LibraryConfigWrapped }
|
||||
| { key: 'library.delete'; input: string; result: null }
|
||||
| { key: 'library.edit'; input: EditLibraryArgs; result: null }
|
||||
| { key: 'locations.create'; input: LibraryArgs<LocationCreateArgs>; result: null }
|
||||
| { key: 'locations.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'locations.fullRescan'; input: LibraryArgs<number>; result: null }
|
||||
| {
|
||||
key: 'locations.indexer_rules.create';
|
||||
input: LibraryArgs<IndexerRuleCreateArgs>;
|
||||
result: IndexerRule;
|
||||
}
|
||||
| { key: 'locations.indexer_rules.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'locations.quickRescan'; input: LibraryArgs<null>; result: null }
|
||||
| { key: 'locations.update'; input: LibraryArgs<LocationUpdateArgs>; result: null }
|
||||
| { key: 'tags.assign'; input: LibraryArgs<TagAssignArgs>; result: null }
|
||||
| { key: 'tags.create'; input: LibraryArgs<TagCreateArgs>; result: Tag }
|
||||
| { key: 'tags.delete'; input: LibraryArgs<number>; result: null }
|
||||
| { key: 'tags.update'; input: LibraryArgs<TagUpdateArgs>; result: null };
|
||||
subscriptions:
|
||||
{ key: "invalidateQuery", input: never, result: InvalidateOperationEvent } |
|
||||
{ key: "jobs.newThumbnail", input: LibraryArgs<null>, result: string }
|
||||
| { key: 'invalidateQuery'; input: never; result: InvalidateOperationEvent }
|
||||
| { key: 'jobs.newThumbnail'; input: LibraryArgs<null>; result: string };
|
||||
};
|
||||
|
||||
export interface ConfigMetadata { version: string | null }
|
||||
export interface ConfigMetadata {
|
||||
version: string | null;
|
||||
}
|
||||
|
||||
export interface EditLibraryArgs { id: string, name: string | null, description: string | null }
|
||||
export interface EditLibraryArgs {
|
||||
id: string;
|
||||
name: string | null;
|
||||
description: string | null;
|
||||
}
|
||||
|
||||
export type ExplorerContext = { type: "Location" } & Location | { type: "Tag" } & Tag
|
||||
export type ExplorerContext = ({ type: 'Location' } & Location) | ({ type: 'Tag' } & Tag);
|
||||
|
||||
export interface ExplorerData { context: ExplorerContext, items: Array<ExplorerItem> }
|
||||
export interface ExplorerData {
|
||||
context: ExplorerContext;
|
||||
items: Array<ExplorerItem>;
|
||||
}
|
||||
|
||||
export type ExplorerItem = { type: "Path" } & { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, object_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string, object: Object | null } | { type: "Object" } & { id: number, cas_id: string, integrity_checksum: string | null, name: string | null, extension: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string, file_paths: Array<FilePath> }
|
||||
export type ExplorerItem =
|
||||
| ({ type: 'Path' } & {
|
||||
id: number;
|
||||
is_dir: boolean;
|
||||
location_id: number;
|
||||
materialized_path: string;
|
||||
name: string;
|
||||
extension: string | null;
|
||||
object_id: number | null;
|
||||
parent_id: number | null;
|
||||
key_id: number | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
object: Object | null;
|
||||
})
|
||||
| ({ type: 'Object' } & {
|
||||
id: number;
|
||||
cas_id: string;
|
||||
integrity_checksum: string | null;
|
||||
name: string | null;
|
||||
extension: string | null;
|
||||
kind: number;
|
||||
size_in_bytes: string;
|
||||
key_id: number | null;
|
||||
hidden: boolean;
|
||||
favorite: boolean;
|
||||
important: boolean;
|
||||
has_thumbnail: boolean;
|
||||
has_thumbstrip: boolean;
|
||||
has_video_preview: boolean;
|
||||
ipfs_id: string | null;
|
||||
note: string | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
file_paths: Array<FilePath>;
|
||||
});
|
||||
|
||||
export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, object_id: number | null, parent_id: number | null, key_id: number | null, date_created: string, date_modified: string, date_indexed: string }
|
||||
export interface FilePath {
|
||||
id: number;
|
||||
is_dir: boolean;
|
||||
location_id: number;
|
||||
materialized_path: string;
|
||||
name: string;
|
||||
extension: string | null;
|
||||
object_id: number | null;
|
||||
parent_id: number | null;
|
||||
key_id: number | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
}
|
||||
|
||||
export interface GenerateThumbsForLocationArgs { id: number, path: string }
|
||||
export interface GenerateThumbsForLocationArgs {
|
||||
id: number;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface IdentifyUniqueFilesArgs { id: number, path: string }
|
||||
export interface IdentifyUniqueFilesArgs {
|
||||
id: number;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface IndexerRule { id: number, kind: number, name: string, parameters: Array<number>, date_created: string, date_modified: string }
|
||||
export interface IndexerRule {
|
||||
id: number;
|
||||
kind: number;
|
||||
name: string;
|
||||
parameters: Array<number>;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
}
|
||||
|
||||
export interface IndexerRuleCreateArgs { kind: RuleKind, name: string, parameters: Array<number> }
|
||||
export interface IndexerRuleCreateArgs {
|
||||
kind: RuleKind;
|
||||
name: string;
|
||||
parameters: Array<number>;
|
||||
}
|
||||
|
||||
export interface InvalidateOperationEvent { key: string, arg: any }
|
||||
export interface InvalidateOperationEvent {
|
||||
key: string;
|
||||
arg: any;
|
||||
}
|
||||
|
||||
export interface JobReport { id: string, name: string, data: Array<number> | null, metadata: any | null, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: number }
|
||||
export interface JobReport {
|
||||
id: string;
|
||||
name: string;
|
||||
data: Array<number> | null;
|
||||
metadata: any | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
status: JobStatus;
|
||||
task_count: number;
|
||||
completed_task_count: number;
|
||||
message: string;
|
||||
seconds_elapsed: number;
|
||||
}
|
||||
|
||||
export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed" | "Paused"
|
||||
export type JobStatus = 'Queued' | 'Running' | 'Completed' | 'Canceled' | 'Failed' | 'Paused';
|
||||
|
||||
export interface LibraryArgs<T> { library_id: string, arg: T }
|
||||
export interface LibraryArgs<T> {
|
||||
library_id: string;
|
||||
arg: T;
|
||||
}
|
||||
|
||||
export interface LibraryConfig { version: string | null, name: string, description: string }
|
||||
export interface LibraryConfig {
|
||||
version: string | null;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface LibraryConfigWrapped { uuid: string, config: LibraryConfig }
|
||||
export interface LibraryConfigWrapped {
|
||||
uuid: string;
|
||||
config: LibraryConfig;
|
||||
}
|
||||
|
||||
export interface Location { id: number, pub_id: Array<number>, node_id: number, name: string | null, local_path: string | null, total_capacity: number | null, available_capacity: number | null, filesystem: string | null, disk_type: number | null, is_removable: boolean | null, is_online: boolean, is_archived: boolean, date_created: string }
|
||||
export interface Location {
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
node_id: number;
|
||||
name: string | null;
|
||||
local_path: string | null;
|
||||
total_capacity: number | null;
|
||||
available_capacity: number | null;
|
||||
filesystem: string | null;
|
||||
disk_type: number | null;
|
||||
is_removable: boolean | null;
|
||||
is_online: boolean;
|
||||
is_archived: boolean;
|
||||
date_created: string;
|
||||
}
|
||||
|
||||
export interface LocationCreateArgs { path: string, indexer_rules_ids: Array<number> }
|
||||
export interface LocationCreateArgs {
|
||||
path: string;
|
||||
indexer_rules_ids: Array<number>;
|
||||
}
|
||||
|
||||
export interface LocationExplorerArgs { location_id: number, path: string, limit: number, cursor: string | null }
|
||||
export interface LocationExplorerArgs {
|
||||
location_id: number;
|
||||
path: string;
|
||||
limit: number;
|
||||
cursor: string | null;
|
||||
}
|
||||
|
||||
export interface LocationUpdateArgs { id: number, name: string | null, indexer_rules_ids: Array<number> }
|
||||
export interface LocationUpdateArgs {
|
||||
id: number;
|
||||
name: string | null;
|
||||
indexer_rules_ids: Array<number>;
|
||||
}
|
||||
|
||||
export interface Node { id: number, pub_id: Array<number>, name: string, platform: number, version: string | null, last_seen: string, timezone: string | null, date_created: string }
|
||||
export interface Node {
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
name: string;
|
||||
platform: number;
|
||||
version: string | null;
|
||||
last_seen: string;
|
||||
timezone: string | null;
|
||||
date_created: string;
|
||||
}
|
||||
|
||||
export interface NodeConfig { version: string | null, id: string, name: string, p2p_port: number | null }
|
||||
export interface NodeConfig {
|
||||
version: string | null;
|
||||
id: string;
|
||||
name: string;
|
||||
p2p_port: number | null;
|
||||
}
|
||||
|
||||
export interface NodeState { version: string | null, id: string, name: string, p2p_port: number | null, data_path: string }
|
||||
export interface NodeState {
|
||||
version: string | null;
|
||||
id: string;
|
||||
name: string;
|
||||
p2p_port: number | null;
|
||||
data_path: string;
|
||||
}
|
||||
|
||||
export interface Object { id: number, cas_id: string, integrity_checksum: string | null, name: string | null, extension: string | null, kind: number, size_in_bytes: string, key_id: number | null, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, ipfs_id: string | null, note: string | null, date_created: string, date_modified: string, date_indexed: string }
|
||||
export interface Object {
|
||||
id: number;
|
||||
cas_id: string;
|
||||
integrity_checksum: string | null;
|
||||
name: string | null;
|
||||
extension: string | null;
|
||||
kind: number;
|
||||
size_in_bytes: string;
|
||||
key_id: number | null;
|
||||
hidden: boolean;
|
||||
favorite: boolean;
|
||||
important: boolean;
|
||||
has_thumbnail: boolean;
|
||||
has_thumbstrip: boolean;
|
||||
has_video_preview: boolean;
|
||||
ipfs_id: string | null;
|
||||
note: string | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
date_indexed: string;
|
||||
}
|
||||
|
||||
export type RuleKind = "AcceptFilesByGlob" | "RejectFilesByGlob" | "AcceptIfChildrenDirectoriesArePresent" | "RejectIfChildrenDirectoriesArePresent"
|
||||
export type RuleKind =
|
||||
| 'AcceptFilesByGlob'
|
||||
| 'RejectFilesByGlob'
|
||||
| 'AcceptIfChildrenDirectoriesArePresent'
|
||||
| 'RejectIfChildrenDirectoriesArePresent';
|
||||
|
||||
export interface SetFavoriteArgs { id: number, favorite: boolean }
|
||||
export interface SetFavoriteArgs {
|
||||
id: number;
|
||||
favorite: boolean;
|
||||
}
|
||||
|
||||
export interface SetNoteArgs { id: number, note: string | null }
|
||||
export interface SetNoteArgs {
|
||||
id: number;
|
||||
note: string | null;
|
||||
}
|
||||
|
||||
export interface Statistics { id: number, date_captured: string, total_object_count: number, library_db_size: string, total_bytes_used: string, total_bytes_capacity: string, total_unique_bytes: string, total_bytes_free: string, preview_media_bytes: string }
|
||||
export interface Statistics {
|
||||
id: number;
|
||||
date_captured: string;
|
||||
total_object_count: number;
|
||||
library_db_size: string;
|
||||
total_bytes_used: string;
|
||||
total_bytes_capacity: string;
|
||||
total_unique_bytes: string;
|
||||
total_bytes_free: string;
|
||||
preview_media_bytes: string;
|
||||
}
|
||||
|
||||
export interface Tag { id: number, pub_id: Array<number>, name: string | null, color: string | null, total_objects: number | null, redundancy_goal: number | null, date_created: string, date_modified: string }
|
||||
export interface Tag {
|
||||
id: number;
|
||||
pub_id: Array<number>;
|
||||
name: string | null;
|
||||
color: string | null;
|
||||
total_objects: number | null;
|
||||
redundancy_goal: number | null;
|
||||
date_created: string;
|
||||
date_modified: string;
|
||||
}
|
||||
|
||||
export interface TagAssignArgs { object_id: number, tag_id: number, unassign: boolean }
|
||||
export interface TagAssignArgs {
|
||||
object_id: number;
|
||||
tag_id: number;
|
||||
unassign: boolean;
|
||||
}
|
||||
|
||||
export interface TagCreateArgs { name: string, color: string }
|
||||
export interface TagCreateArgs {
|
||||
name: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface TagUpdateArgs { id: number, name: string | null, color: string | null }
|
||||
export interface TagUpdateArgs {
|
||||
id: number;
|
||||
name: string | null;
|
||||
color: string | null;
|
||||
}
|
||||
|
||||
export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean }
|
||||
export interface Volume {
|
||||
name: string;
|
||||
mount_point: string;
|
||||
total_capacity: bigint;
|
||||
available_capacity: bigint;
|
||||
is_removable: boolean;
|
||||
disk_type: string | null;
|
||||
file_system: string | null;
|
||||
is_root_filesystem: boolean;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { useCurrentLibrary, useInvalidateQuery } from '@sd/client';
|
||||
import { Suspense, lazy } from 'react';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
|
||||
import { AppLayout } from './AppLayout';
|
||||
import { useKeybindHandler } from './hooks/useKeyboardHandler';
|
||||
import { useCurrentLibrary, useInvalidateQuery } from '@sd/client';
|
||||
import { lazy, Suspense } from 'react';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
|
||||
const DebugScreen = lazy(() => import('./screens/Debug'));
|
||||
const SettingsScreen = lazy(() => import('./screens/settings/Settings'));
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { Folder } from '../icons/Folder';
|
||||
import { isObject, isPath } from './utils';
|
||||
import videoSvg from '@sd/assets/svgs/video.svg';
|
||||
import zipSvg from '@sd/assets/svgs/zip.svg';
|
||||
import { getExplorerStore, usePlatform } from '@sd/client';
|
||||
|
@ -10,6 +8,9 @@ import { useState } from 'react';
|
|||
import { Suspense, lazy, useMemo } from 'react';
|
||||
import { useSnapshot } from 'valtio';
|
||||
|
||||
import { Folder } from '../icons/Folder';
|
||||
import { isObject, isPath } from './utils';
|
||||
|
||||
interface Props {
|
||||
data: ExplorerItem;
|
||||
size: number;
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
// import types from '../../constants/file-types.json';
|
||||
import { Tooltip } from '../tooltip/Tooltip';
|
||||
import FileThumb from './FileThumb';
|
||||
import { Divider } from './inspector/Divider';
|
||||
import FavoriteButton from './inspector/FavoriteButton';
|
||||
import { MetaItem } from './inspector/MetaItem';
|
||||
import Note from './inspector/Note';
|
||||
import { isObject } from './utils';
|
||||
import { ShareIcon } from '@heroicons/react/24/solid';
|
||||
import { useLibraryQuery } from '@sd/client';
|
||||
import { ExplorerContext, ExplorerItem } from '@sd/client';
|
||||
|
@ -16,6 +9,14 @@ import dayjs from 'dayjs';
|
|||
import { Link } from 'phosphor-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { Tooltip } from '../tooltip/Tooltip';
|
||||
import FileThumb from './FileThumb';
|
||||
import { Divider } from './inspector/Divider';
|
||||
import FavoriteButton from './inspector/FavoriteButton';
|
||||
import { MetaItem } from './inspector/MetaItem';
|
||||
import Note from './inspector/Note';
|
||||
import { isObject } from './utils';
|
||||
|
||||
interface Props {
|
||||
context?: ExplorerContext;
|
||||
data?: ExplorerItem;
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import FileItem from './FileItem';
|
||||
import FileRow from './FileRow';
|
||||
import { isPath } from './utils';
|
||||
import { ExplorerLayoutMode, getExplorerStore, useExplorerStore } from '@sd/client';
|
||||
import { ExplorerContext, ExplorerItem } from '@sd/client';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
|
@ -8,6 +5,10 @@ import { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from
|
|||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useKey, useOnWindowResize } from 'rooks';
|
||||
|
||||
import FileItem from './FileItem';
|
||||
import FileRow from './FileRow';
|
||||
import { isPath } from './utils';
|
||||
|
||||
const TOP_BAR_HEIGHT = 50;
|
||||
const GRID_TEXT_AREA_HEIGHT = 25;
|
||||
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
"$schema": "https://turborepo.org/schema.json",
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"outputs": [
|
||||
"dist/**"
|
||||
]
|
||||
"outputs": ["dist/**"]
|
||||
},
|
||||
"lint": {
|
||||
"outputs": []
|
||||
|
|
Loading…
Reference in a new issue