mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-10-10 19:41:36 -04:00
Merge branch 'main' into main
This commit is contained in:
22 files changed
+350
-147
No files matched your search
@@ -15,7 +15,13 @@
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "app.spacedrive.desktop",
|
||||
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "Jamie Pine",
|
||||
@@ -56,8 +62,8 @@
|
||||
"windows": [
|
||||
{
|
||||
"title": "Spacedrive",
|
||||
"width": 1500,
|
||||
"height": 925,
|
||||
"width": 1200,
|
||||
"height": 725,
|
||||
"resizable": true,
|
||||
"fullscreen": false,
|
||||
"alwaysOnTop": false,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@icons-pack/react-simple-icons": "^4.6.1",
|
||||
"@sd/client": "workspace:*",
|
||||
"@sd/core": "workspace:*",
|
||||
"@sd/interface": "workspace:*",
|
||||
@@ -17,6 +18,7 @@
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-tsparticles": "^2.0.6",
|
||||
"simple-icons": "^6.19.0",
|
||||
"tsparticles": "^2.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
+56
-36
@@ -2,15 +2,15 @@ import { Button } from '@sd/ui';
|
||||
import { Bubbles } from './Bubbles';
|
||||
import './index.css';
|
||||
|
||||
import { ReactComponent as GithubLogo } from './assets/github.svg';
|
||||
import { ReactComponent as AppleLogo } from './assets/apple.svg';
|
||||
import { ReactComponent as AppLogo } from './assets/app-logo.svg';
|
||||
import NavBar from './components/NavBar';
|
||||
import { Footer } from './components/Footer';
|
||||
import { Apple, Github, Linux, Windows } from '@icons-pack/react-simple-icons';
|
||||
import { useState } from 'react';
|
||||
|
||||
interface SectionProps {
|
||||
orientation: 'left' | 'right';
|
||||
heading?: string;
|
||||
description?: string;
|
||||
description?: string | React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ function Section(props: SectionProps = { orientation: 'left' }) {
|
||||
);
|
||||
let children = <div className="p-10 ">{props.children}</div>;
|
||||
return (
|
||||
<div className="grid grid-cols-2 my-44">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 my-44">
|
||||
{props.orientation === 'right' ? (
|
||||
<>
|
||||
{info}
|
||||
@@ -40,16 +40,18 @@ function Section(props: SectionProps = { orientation: 'left' }) {
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [showApp, setShowApp] = useState(true);
|
||||
return (
|
||||
<div>
|
||||
<NavBar />
|
||||
<div className="container z-10 flex flex-col items-center px-4 mx-auto text-white bg-black">
|
||||
{/* <AppLogo className="z-30 w-40 h-40 mt-32" /> */}
|
||||
<h1 className="text-4xl font-black leading-snug text-center md:text-6xl mt-36">
|
||||
The file explorer from the future
|
||||
{/* One space, all your drives. */}A file explorer from the future.
|
||||
</h1>
|
||||
<p className="max-w-3xl mt-1 mb-8 text-lg text-center text-gray-450">
|
||||
Manage files across all devices, drives and clouds from one place.
|
||||
<p className="max-w-4xl mt-1 mb-8 text-lg text-center text-gray-450">
|
||||
Combine your drives and clouds into one database that you can organize and explore from
|
||||
any device.
|
||||
<br />
|
||||
Designed for creators, hoarders and the painfully disorganized.
|
||||
</p>
|
||||
@@ -57,14 +59,25 @@ function App() {
|
||||
{/* <Button className="px-2">
|
||||
<WindowsLogo className="" fill="white" />
|
||||
</Button> */}
|
||||
<Button className="cursor-pointer" variant="primary">
|
||||
<AppleLogo className="inline -mt-[3px] mr-1.5" fill="white" />
|
||||
|
||||
<Button
|
||||
onClick={() =>
|
||||
alert(
|
||||
"You're here early! This is the only button on this page that does not work, I promise. Release build coming very soon—follow @spacedriveapp for updates."
|
||||
)
|
||||
}
|
||||
className="cursor-pointer"
|
||||
variant="primary"
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
<Button className="cursor-pointer" variant="gray">
|
||||
<GithubLogo className="inline -mt-[3px] mr-1.5" fill="white" />
|
||||
Star on GitHub
|
||||
</Button>
|
||||
|
||||
<a href="https://github.com/spacedriveapp/spacedrive" target="_blank">
|
||||
<Button className="cursor-pointer" variant="gray">
|
||||
<Github className="inline w-5 h-5 -mt-[4px] -ml-1 mr-2" fill="white" />
|
||||
Star on GitHub
|
||||
</Button>
|
||||
</a>
|
||||
</div>
|
||||
<p className="mt-3 text-xs text-center text-gray-500">
|
||||
Available on macOS (Intel & Apple Silicon), Windows and Linux.
|
||||
@@ -72,31 +85,38 @@ function App() {
|
||||
Coming soon to iOS & Android.
|
||||
</p>
|
||||
|
||||
<iframe
|
||||
className="z-30 mt-20 border rounded-lg shadow-2xl bg-gray-850 border-gray-550"
|
||||
width={1200}
|
||||
height={600}
|
||||
src={`${import.meta.env.VITE_SDWEB_BASE_URL || "http://localhost:8002"}?library_id=9068c6ec-cf90-451b-bb30-4174781e7bc6`}
|
||||
/>
|
||||
{showApp && (
|
||||
<iframe
|
||||
className="z-30 mt-20 border rounded-lg shadow-2xl bg-gray-850 border-gray-550"
|
||||
width={1200}
|
||||
height={600}
|
||||
onError={(e) => {
|
||||
setShowApp(false);
|
||||
}}
|
||||
src={`${import.meta.env.VITE_SDWEB_BASE_URL || "http://localhost:8002"}?library_id=9068c6ec-cf90-451b-bb30-4174781e7bc6`}
|
||||
/>
|
||||
)}
|
||||
<Section
|
||||
orientation="right"
|
||||
heading="It's one big catalogue"
|
||||
description="Using content addressable storage in a virtual distributed filesystem, Spacedrive securely
|
||||
combines the storage capacity and processing power of your devices into one."
|
||||
heading="Never leave a file behind."
|
||||
description={
|
||||
<>
|
||||
Spacedrive accounts for every file you own, uniquely fingerprinting and extracting
|
||||
metadata so you can sort, tag, backup and share files without limitations of any one
|
||||
cloud provider.
|
||||
<br />
|
||||
<br />
|
||||
<a
|
||||
className="transition text-primary-600 hover:text-primary-500"
|
||||
href="https://github.com/spacedriveapp"
|
||||
target="_blank"
|
||||
>
|
||||
Find out more →
|
||||
</a>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Section
|
||||
orientation="left"
|
||||
heading="It's one big catalogue"
|
||||
description="Using content addressable storage in a virtual distributed filesystem, Spacedrive securely
|
||||
combines the storage capacity and processing power of your devices into one."
|
||||
/>
|
||||
<Section
|
||||
orientation="right"
|
||||
heading="It's one big catalogue"
|
||||
description="Using content addressable storage in a virtual distributed filesystem, Spacedrive securely
|
||||
combines the storage capacity and processing power of your devices into one."
|
||||
/>
|
||||
<div className="h-[500px]" />
|
||||
<Footer />
|
||||
</div>
|
||||
<Bubbles />
|
||||
</div>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="814px" height="1000px" viewBox="0 0 814 1000" enable-background="new 0 0 814 1000" xml:space="preserve">
|
||||
<path d="M788.1,340.9c-5.8,4.5-108.2,62.2-108.2,190.5c0,148.4,130.3,200.9,134.2,202.2c-0.6,3.2-20.7,71.9-68.7,141.9
|
||||
c-42.8,61.6-87.5,123.1-155.5,123.1s-85.5-39.5-164-39.5c-76.5,0-103.7,40.8-165.9,40.8s-105.6-57-155.5-127
|
||||
C46.7,790.7,0,663,0,541.8c0-194.4,126.4-297.5,250.8-297.5c66.1,0,121.2,43.4,162.7,43.4c39.5,0,101.1-46,176.3-46
|
||||
C618.3,241.7,720.7,244.3,788.1,340.9z M554.1,159.4c31.1-36.9,53.1-88.1,53.1-139.3c0-7.1-0.6-14.3-1.9-20.1
|
||||
c-50.6,1.9-110.8,33.7-147.1,75.8c-28.5,32.4-55.1,83.6-55.1,135.5c0,7.8,1.3,15.6,1.9,18.1c3.2,0.6,8.4,1.3,13.6,1.3
|
||||
C464,230.7,521.1,200.3,554.1,159.4z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 980 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
|
Before Width: | Height: | Size: 814 B |
@@ -1,46 +0,0 @@
|
||||
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 497.886 497.886" style="enable-background:new 0 0 497.886 497.886;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon points="227.959,39.869 227.959,242.386 496.549,242.386 496.549,0 "/>
|
||||
<polygon points="1.336,244.746 211.172,244.746 211.172,41.818 1.336,72.798 "/>
|
||||
<polygon points="227.959,458.017 496.549,497.886 496.549,261.535 227.959,261.535 "/>
|
||||
<polygon points="1.336,425.086 211.172,456.066 211.172,261.531 1.336,261.531 "/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 893 B |
@@ -0,0 +1,106 @@
|
||||
import { ReactComponent as AppLogo } from '../assets/app-logo.svg';
|
||||
import {
|
||||
Twitter,
|
||||
Discord,
|
||||
Instagram,
|
||||
Github,
|
||||
Opencollective,
|
||||
Twitch
|
||||
} from '@icons-pack/react-simple-icons';
|
||||
|
||||
function FooterLink(props: { children: string; link: string }) {
|
||||
return (
|
||||
<a href={props.link} target="_blank" className="text-gray-300 hover:text-white">
|
||||
{props.children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="z-50 w-screen bg-gray-900 border-gray-500 border-t-1">
|
||||
<div className="container grid grid-cols-1 gap-6 p-8 pt-10 pb-20 m-auto text-white min-h-64 sm:grid-cols-2 lg:grid-cols-6">
|
||||
<div className="col-span-1">
|
||||
<AppLogo className="w-10 h-10 mb-5" />
|
||||
|
||||
<h3 className="mb-1 text-xl font-bold">Spacedrive</h3>
|
||||
<p className="text-sm text-gray-350">© Copyright 2022 Jamie Pine</p>
|
||||
<div className="flex flex-row mt-6 space-x-3">
|
||||
<a href="https://twitter.com/spacedriveapp" target="_blank">
|
||||
<Twitter />
|
||||
</a>
|
||||
<a href="https://discord.gg/gTaF2Z44f5" target="_blank">
|
||||
<Discord />
|
||||
</a>
|
||||
<a href="https://instagram.com/spacedriveapp" target="_blank">
|
||||
<Instagram />
|
||||
</a>
|
||||
<a href="https://github.com/spacedriveapp" target="_blank">
|
||||
<Github />
|
||||
</a>
|
||||
<a href="https://opencollective.com/spacedrive" target="_blank">
|
||||
<Opencollective />
|
||||
</a>
|
||||
<a href="https://twitch.tv/jamiepinelive" target="_blank">
|
||||
<Twitch />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-1"></div>
|
||||
<div className="flex flex-col col-span-1 space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase ">About</h3>
|
||||
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive/blob/main/docs/product/credits.md">
|
||||
Team
|
||||
</FooterLink>
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive/blob/main/docs/product/faq.md">
|
||||
FAQ
|
||||
</FooterLink>
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive#motivation">Mission</FooterLink>
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive/tree/main/docs/changelog">
|
||||
Changelog
|
||||
</FooterLink>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<FooterLink link="#">Blog</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col col-span-1 space-y-2 pointer-events-none">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase">Downloads</h3>
|
||||
<div className="flex flex-col col-span-1 space-y-2 opacity-50">
|
||||
<FooterLink link="#">macOS</FooterLink>
|
||||
<FooterLink link="#">Windows</FooterLink>
|
||||
<FooterLink link="#">Linux</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col col-span-1 space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase ">Developers</h3>
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive/tree/main/docs">
|
||||
Documentation
|
||||
</FooterLink>
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive/tree/main/docs/developer/contributing.md">
|
||||
Contribute
|
||||
</FooterLink>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<FooterLink link="#">Extensions</FooterLink>
|
||||
</div>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<FooterLink link="#">Self Host</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col col-span-1 space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase ">Org</h3>
|
||||
<FooterLink link="https://opencollective.com/spacedrive">Open Collective</FooterLink>
|
||||
<FooterLink link="https://github.com/jamiepine/spacedrive/blob/main/LICENSE">
|
||||
License
|
||||
</FooterLink>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<FooterLink link="#">Privacy</FooterLink>
|
||||
</div>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<FooterLink link="#">Terms</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -2,9 +2,13 @@ import clsx from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ReactComponent as AppLogo } from '../assets/app-logo.svg';
|
||||
|
||||
function NavLink(props: { children: string }) {
|
||||
function NavLink(props: { link?: string; children: string }) {
|
||||
return (
|
||||
<a className="p-4 text-gray-300 no-underline transition cursor-pointer hover:text-gray-50">
|
||||
<a
|
||||
href={props.link ?? '#'}
|
||||
target="_blank"
|
||||
className="p-4 text-gray-300 no-underline transition cursor-pointer hover:text-gray-50"
|
||||
>
|
||||
{props.children}
|
||||
</a>
|
||||
);
|
||||
@@ -30,20 +34,25 @@ export default function NavBar() {
|
||||
isAtTop ? 'border-gray-550 bg-gray-750 bg-opacity-80' : 'bg-transparent border-transparent'
|
||||
)}
|
||||
>
|
||||
<div className="container flex items-center h-full m-auto ">
|
||||
<AppLogo className="z-30 w-8 h-8 mr-3" />
|
||||
<h3 className="text-xl font-bold text-white">
|
||||
Spacedrive
|
||||
<span className="ml-2 text-xs text-gray-400 uppercase">BETA</span>
|
||||
</h3>
|
||||
<div className="container relative flex items-center h-full px-5 m-auto">
|
||||
<div className="absolute flex flex-row items-center">
|
||||
<AppLogo className="z-30 w-8 h-8 mr-3" />
|
||||
<h3 className="text-xl font-bold text-white">
|
||||
Spacedrive
|
||||
<span className="ml-2 text-xs text-gray-400 uppercase">BETA</span>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className="space-x-4 text-white mx-28">
|
||||
<NavLink>Product</NavLink>
|
||||
<NavLink>Documentation</NavLink>
|
||||
<NavLink>Support</NavLink>
|
||||
<NavLink>FAQ</NavLink>
|
||||
<NavLink>Changelog</NavLink>
|
||||
<NavLink>Blog</NavLink>
|
||||
<div className="hidden m-auto space-x-4 text-white lg:block ">
|
||||
<NavLink link="https://github.com/spacedriveapp/#features">Features</NavLink>
|
||||
<NavLink link="https://github.com/spacedriveapp/spacedrive/tree/main/docs">Docs</NavLink>
|
||||
<NavLink link="https://github.com/spacedriveapp/spacedrive/blob/main/docs/product/faq.md">
|
||||
FAQ
|
||||
</NavLink>
|
||||
<NavLink link="https://github.com/spacedriveapp/spacedrive/tree/main/docs/changelog">
|
||||
Changelog
|
||||
</NavLink>
|
||||
<NavLink link="https://opencollective.com/spacedrive">Sponsor us</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -75,8 +75,10 @@ function App() {
|
||||
convertFileSrc={function (url: string): string {
|
||||
return url;
|
||||
}}
|
||||
openDialog={function (options: { directory?: boolean }): Promise<string | string[]> {
|
||||
return Promise.resolve('');
|
||||
openDialog={function (options: {
|
||||
directory?: boolean | undefined;
|
||||
}): Promise<string | string[]> {
|
||||
return Promise.resolve([]);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::{
|
||||
use anyhow::Result;
|
||||
use futures::executor::block_on;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use prisma_client_rust::Direction;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct FileCreated {
|
||||
@@ -35,40 +36,44 @@ impl Job for FileIdentifierJob {
|
||||
|
||||
let ctx = tokio::task::spawn_blocking(move || {
|
||||
let mut completed: usize = 0;
|
||||
let mut cursor:i32 = 0;
|
||||
|
||||
while completed < task_count {
|
||||
let file_paths = block_on(get_orphan_file_paths(&ctx.core_ctx, completed * 100)).unwrap();
|
||||
println!("Processing: {:?}", file_paths);
|
||||
|
||||
let file_paths = block_on(get_orphan_file_paths(&ctx.core_ctx, cursor)).unwrap();
|
||||
println!("Processing {:?} orphan files. ({} completed of {})", file_paths.len(), completed, task_count);
|
||||
|
||||
let mut rows: Vec<String> = Vec::new();
|
||||
// only rows that have a valid cas_id to be inserted
|
||||
for file_path in file_paths.iter() {
|
||||
if file_path.temp_cas_id.is_none() {
|
||||
continue;
|
||||
if file_path.temp_cas_id.is_some() {
|
||||
rows.push(prepare_file_values(file_path));
|
||||
}
|
||||
rows.push(prepare_file_values(file_path));
|
||||
}
|
||||
if rows.len() == 0 {
|
||||
println!("No orphan files to process, finishing...");
|
||||
break;
|
||||
}
|
||||
let insert_files = format!(
|
||||
r#"INSERT INTO files (cas_id, size_in_bytes) VALUES {} ON CONFLICT (cas_id) DO NOTHING RETURNING id, cas_id"#,
|
||||
rows.join(", ")
|
||||
);
|
||||
println!("{}", insert_files);
|
||||
|
||||
let files: Vec<FileCreated> = block_on(db._query_raw(&insert_files)).unwrap();
|
||||
|
||||
println!("FILES: {:?}", files);
|
||||
|
||||
for file in files.iter() {
|
||||
let update_file_path = format!(
|
||||
r#"UPDATE file_paths SET file_id = "{}" WHERE temp_cas_id = "{}""#,
|
||||
file.id, file.cas_id
|
||||
);
|
||||
println!("UPDATING PATH: {}", update_file_path);
|
||||
block_on(db._execute_raw(&update_file_path)).unwrap();
|
||||
}
|
||||
|
||||
let last_row = file_paths.last().unwrap();
|
||||
|
||||
cursor = last_row.id;
|
||||
|
||||
completed += 1;
|
||||
println!("completed: {}", completed);
|
||||
ctx.progress(vec![JobReportUpdate::CompletedTaskCount(completed)]);
|
||||
}
|
||||
ctx
|
||||
@@ -76,9 +81,11 @@ impl Job for FileIdentifierJob {
|
||||
|
||||
let remaining = count_orphan_file_paths(&ctx.core_ctx).await?;
|
||||
|
||||
if remaining > 0 {
|
||||
ctx.core_ctx.spawn_job(Box::new(FileIdentifierJob));
|
||||
}
|
||||
println!("Finished with {} files remaining because your code is bad.", remaining);
|
||||
|
||||
// if remaining > 0 {
|
||||
// ctx.core_ctx.spawn_job(Box::new(FileIdentifierJob));
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -101,17 +108,18 @@ pub async fn count_orphan_file_paths(ctx: &CoreContext) -> Result<usize, FileErr
|
||||
|
||||
pub async fn get_orphan_file_paths(
|
||||
ctx: &CoreContext,
|
||||
offset: usize,
|
||||
cursor: i32,
|
||||
) -> Result<Vec<file_path::Data>, FileError> {
|
||||
let db = &ctx.database;
|
||||
println!("offset: {}", offset);
|
||||
println!("cursor: {:?}", cursor);
|
||||
let files = db
|
||||
.file_path()
|
||||
.find_many(vec![
|
||||
file_path::file_id::equals(None),
|
||||
file_path::is_dir::equals(false),
|
||||
])
|
||||
.skip(offset)
|
||||
.order_by(file_path::id::order(Direction::Asc))
|
||||
.cursor(file_path::id::cursor(cursor))
|
||||
.take(100)
|
||||
.exec()
|
||||
.await?;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Contributing to Spacedrive
|
||||
|
||||
For now, if you wish to make any changes other than a bug fix, please create an issue first to get the developer's input. The project is in its infancy and the developers are making frequent breaking changes.
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
# Todo
|
||||
|
||||
- Landing sections
|
||||
- Custom scrollbars
|
||||
- Tag files
|
||||
- Right click menu
|
||||
- File explorer grid view
|
||||
- Albums
|
||||
- Content types screen
|
||||
- Show duplicate files on the inspector
|
||||
- Explorer filter by tag
|
||||
- Library statistics
|
||||
- File viewer
|
||||
- Open file
|
||||
@@ -18,6 +18,10 @@ This software is aimed at independent creatives such as filmmakers, streamers, m
|
||||
|
||||
In the same way we use finance apps to consolidate our books, Spacedrive consolidates files and the metadata associated with them. If you have external hard drives, cloud accounts and more than one device—you'll get a birds eye view of every file you own. With the ability to create folders, tags and albums that contain files from all different locations.
|
||||
|
||||
## Where are my files stored?
|
||||
|
||||
Exactly where they already are, Spacedrive simply indexes your existing storage locations, extracting metadata and fingerprinting the byte data. However, it will have the power to transfer files at your command.
|
||||
|
||||
## What makes this different to Dropbox or Google Drive?
|
||||
|
||||
It is not a storage provider, Spacedrive is simply a database that exists on top of existing storage layers, from cloud services like Dropbox, Google Drive and iCloud to physical devices and external drives you already own. It doesn't provide you more storage, rather a supercharged view of your existing storage.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
### One space, all your drives.
|
||||
|
||||
### The file explorer from the future.
|
||||
|
||||
### The file explorer of the future.
|
||||
|
||||
### All your files in one space.
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"react-query": "^3.34.19",
|
||||
"react-router": "6.3.0",
|
||||
"react-router-dom": "6.3.0",
|
||||
"react-scrollbars-custom": "^4.0.27",
|
||||
"react-spline": "^1.2.1",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"react-virtuoso": "^2.9.0",
|
||||
|
||||
@@ -26,6 +26,7 @@ import { BaseTransport, ClientProvider, setTransport } from '@sd/client';
|
||||
import { Button } from '@sd/ui';
|
||||
import { CoreEvent } from '@sd/core';
|
||||
import clsx from 'clsx';
|
||||
import './style.scss';
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@@ -183,9 +184,7 @@ export default function App(props: AppProps) {
|
||||
window.ReactQueryClient = queryClient;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setTransport(props.transport);
|
||||
}, [props.transport]);
|
||||
setTransport(props.transport);
|
||||
|
||||
console.log('App props', props);
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ export const FileList: React.FC<{ location_id: number; path: string; limit: numb
|
||||
<div
|
||||
ref={tableContainer}
|
||||
style={{ marginTop: -44 }}
|
||||
className="w-full px-2 bg-white cursor-default table-container dark:bg-gray-650"
|
||||
className="w-full pl-2 bg-white cursor-default table-container dark:bg-gray-650"
|
||||
>
|
||||
<LocationContext.Provider
|
||||
value={{ location_id: props.location_id, data_path: client?.data_path as string }}
|
||||
@@ -150,7 +150,8 @@ export const FileList: React.FC<{ location_id: number; path: string; limit: numb
|
||||
itemContent={Row}
|
||||
components={{ Header, Footer: () => <div className="w-full " /> }}
|
||||
increaseViewportBy={{ top: 400, bottom: 200 }}
|
||||
className="outline-none"
|
||||
className="outline-none explorer-scroll"
|
||||
// useWindowScroll
|
||||
/>
|
||||
</LocationContext.Provider>
|
||||
</div>
|
||||
@@ -184,7 +185,7 @@ const RenderRow: React.FC<{
|
||||
}
|
||||
}}
|
||||
className={clsx(
|
||||
'table-body-row flex flex-row rounded-lg border-2',
|
||||
'table-body-row mr-2 flex flex-row rounded-lg border-2',
|
||||
isActive ? 'border-primary-500' : 'border-transparent',
|
||||
rowIndex % 2 == 0 && 'bg-[#00000006] dark:bg-[#00000030]'
|
||||
)}
|
||||
@@ -220,14 +221,18 @@ const RenderCell: React.FC<{ colKey?: ColumnKey; dirId?: number; file?: FilePath
|
||||
const location = useContext(LocationContext);
|
||||
const { newThumbnails } = useExplorerState();
|
||||
|
||||
const hasThumbnail = !!row?.has_local_thumbnail || !!newThumbnails[row?.temp_cas_id ?? ''];
|
||||
const hasNewThumbnail = !!newThumbnails[row?.temp_cas_id ?? ''];
|
||||
|
||||
switch (colKey) {
|
||||
case 'name':
|
||||
return (
|
||||
<div className="flex flex-row items-center overflow-hidden">
|
||||
<div className="w-6 h-6 mr-3">
|
||||
<FileThumb file={row} locationId={location.location_id} />
|
||||
<FileThumb
|
||||
hasThumbnailOverride={hasNewThumbnail}
|
||||
file={row}
|
||||
locationId={location.location_id}
|
||||
/>
|
||||
</div>
|
||||
{/* {colKey == 'name' &&
|
||||
(() => {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ReactComponent as Folder } from '../../assets/svg/folder.svg';
|
||||
export default function FileThumb(props: {
|
||||
file: FilePath;
|
||||
locationId: number;
|
||||
hasThumbnailOverride: boolean;
|
||||
className?: string;
|
||||
}) {
|
||||
const appPropsContext = useContext(AppPropsContext);
|
||||
@@ -18,7 +19,7 @@ export default function FileThumb(props: {
|
||||
return <Folder className="max-w-[170px]" />;
|
||||
}
|
||||
|
||||
if (props.file.has_local_thumbnail && client?.data_path) {
|
||||
if (client?.data_path && (props.file.has_local_thumbnail || props.hasThumbnailOverride)) {
|
||||
return (
|
||||
<img
|
||||
className="mt-0.5 pointer-events-none z-90"
|
||||
|
||||
@@ -58,9 +58,10 @@ export function MacOSTrafficLights() {
|
||||
|
||||
export const Sidebar: React.FC<SidebarProps> = (props) => {
|
||||
const appPropsContext = useContext(AppPropsContext);
|
||||
const { data: locations } = useBridgeQuery('SysGetLocations', undefined, {});
|
||||
const { data: locations } = useBridgeQuery('SysGetLocations');
|
||||
const { data: clientState } = useBridgeQuery('ClientGetState');
|
||||
|
||||
const { mutate: createLocation } = useBridgeCommand('LocCreate');
|
||||
const { data: clientState } = useBridgeQuery('ClientGetState', undefined, {});
|
||||
|
||||
const tags = [
|
||||
{ id: 1, name: 'Keepsafe', color: '#FF6788' },
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
a,
|
||||
button {
|
||||
@apply cursor-default;
|
||||
}
|
||||
|
||||
// ::-webkit-scrollbar {
|
||||
// display: none;
|
||||
// }
|
||||
|
||||
.explorer-scroll {
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
width: 8px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
@apply bg-[#00000006] dark:bg-[#00000030] mt-[55px] rounded-[6px];
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply rounded-[6px] bg-gray-300 dark:bg-gray-550;
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,7 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
a,
|
||||
button {
|
||||
@apply cursor-default;
|
||||
}
|
||||
|
||||
|
||||
.html {
|
||||
background: #404040;
|
||||
|
||||
Generated
+54
-1
@@ -69,6 +69,7 @@ importers:
|
||||
|
||||
apps/landing:
|
||||
specifiers:
|
||||
'@icons-pack/react-simple-icons': ^4.6.1
|
||||
'@sd/client': workspace:*
|
||||
'@sd/core': workspace:*
|
||||
'@sd/interface': workspace:*
|
||||
@@ -83,12 +84,14 @@ importers:
|
||||
react: ^18.0.0
|
||||
react-dom: ^18.0.0
|
||||
react-tsparticles: ^2.0.6
|
||||
simple-icons: ^6.19.0
|
||||
tailwind: ^4.0.0
|
||||
tsparticles: ^2.0.6
|
||||
typescript: ^4.6.3
|
||||
vite: ^2.9.5
|
||||
vite-plugin-svgr: ^1.1.0
|
||||
dependencies:
|
||||
'@icons-pack/react-simple-icons': 4.6.1_react@18.0.0
|
||||
'@sd/client': link:../../packages/client
|
||||
'@sd/core': link:../../core
|
||||
'@sd/interface': link:../../packages/interface
|
||||
@@ -98,6 +101,7 @@ importers:
|
||||
react: 18.0.0
|
||||
react-dom: 18.0.0_react@18.0.0
|
||||
react-tsparticles: 2.0.6_react@18.0.0
|
||||
simple-icons: 6.19.0
|
||||
tsparticles: 2.0.6
|
||||
devDependencies:
|
||||
'@types/react': 18.0.5
|
||||
@@ -240,6 +244,7 @@ importers:
|
||||
react-query: ^3.34.19
|
||||
react-router: 6.3.0
|
||||
react-router-dom: 6.3.0
|
||||
react-scrollbars-custom: ^4.0.27
|
||||
react-spline: ^1.2.1
|
||||
react-transition-group: ^4.4.2
|
||||
react-virtuoso: ^2.9.0
|
||||
@@ -280,6 +285,7 @@ importers:
|
||||
react-query: 3.34.19_react-dom@18.0.0+react@18.0.0
|
||||
react-router: 6.3.0_react@18.0.0
|
||||
react-router-dom: 6.3.0_react-dom@18.0.0+react@18.0.0
|
||||
react-scrollbars-custom: 4.0.27_react-dom@18.0.0+react@18.0.0
|
||||
react-spline: 1.2.1_react@18.0.0
|
||||
react-transition-group: 4.4.2_react-dom@18.0.0+react@18.0.0
|
||||
react-virtuoso: 2.9.0_react@18.0.0
|
||||
@@ -764,6 +770,15 @@ packages:
|
||||
react: 18.0.0
|
||||
dev: false
|
||||
|
||||
/@icons-pack/react-simple-icons/4.6.1_react@18.0.0:
|
||||
resolution: {integrity: sha512-ICONbofFzeTkXvmbnptDv4P9cqtW/N/8EFOqyzJQJ80b8fJoLzqhM7EKslBmWziIwjY9FBnOoL2ofzQOoDG1Gg==}
|
||||
peerDependencies:
|
||||
react: ^16.13 || ^17
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
react: 18.0.0
|
||||
dev: false
|
||||
|
||||
/@jridgewell/resolve-uri/3.0.5:
|
||||
resolution: {integrity: sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
@@ -2100,6 +2115,10 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/cnbuilder/2.7.1:
|
||||
resolution: {integrity: sha512-kJ/X8vJOSeY0usRPuTlm+rtsB8iwpTs4JFOvDQxkFX6M/0D5IbOKZBJf822T3UIVNWOIXiewXh7l/ux1Feh1Yg==}
|
||||
dev: false
|
||||
|
||||
/coa/2.0.2:
|
||||
resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==}
|
||||
engines: {node: '>= 4.0'}
|
||||
@@ -3781,6 +3800,18 @@ packages:
|
||||
scheduler: 0.21.0
|
||||
dev: false
|
||||
|
||||
/react-draggable/4.4.4_react-dom@18.0.0+react@18.0.0:
|
||||
resolution: {integrity: sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA==}
|
||||
peerDependencies:
|
||||
react: '>= 16.3.0'
|
||||
react-dom: '>= 16.3.0'
|
||||
dependencies:
|
||||
clsx: 1.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.0.0
|
||||
react-dom: 18.0.0_react@18.0.0
|
||||
dev: false
|
||||
|
||||
/react-dropzone/12.0.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-fcqHEYe1MzAghU6/Hz86lHDlBNsA+lO48nAcm7/wA+kIzwS6uuJbUG33tBZjksj7GAZ1iUQ6NHwjUURPmSGang==}
|
||||
engines: {node: '>= 10.13'}
|
||||
@@ -3947,6 +3978,19 @@ packages:
|
||||
react: 18.0.0
|
||||
dev: false
|
||||
|
||||
/react-scrollbars-custom/4.0.27_react-dom@18.0.0+react@18.0.0:
|
||||
resolution: {integrity: sha512-vEIvb+AbxWHtU6yqNfIEtnm06vguFFxDK8UTC6hPMlgEPvrQX7ayoLp9MT+vyszouQ9NgcEtipLmNGEw31pQpQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.0.0'
|
||||
dependencies:
|
||||
cnbuilder: 2.7.1
|
||||
react: 18.0.0
|
||||
react-draggable: 4.4.4_react-dom@18.0.0+react@18.0.0
|
||||
zoom-level: 2.5.0
|
||||
transitivePeerDependencies:
|
||||
- react-dom
|
||||
dev: false
|
||||
|
||||
/react-spline/1.2.1_react@18.0.0:
|
||||
resolution: {integrity: sha512-d17gOvoKjWfHmsXm7H1YbK715dDEVuIc72eNcrrpNp7T/H8zH2yfNvk1NSJQSuGchTXaa90hbiGRC3FGpJHMZA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -4225,6 +4269,11 @@ packages:
|
||||
get-intrinsic: 1.1.1
|
||||
object-inspect: 1.12.0
|
||||
|
||||
/simple-icons/6.19.0:
|
||||
resolution: {integrity: sha512-HI7X+Ibu9FbphEJZzkOGu820Mp9JhUEAGf3qjooQkBXSgASt3HCJlhVsKxLzPAaXiSSMWupsf+rB2DwFQbRrKg==}
|
||||
engines: {node: '>=0.12.18'}
|
||||
dev: false
|
||||
|
||||
/slash/3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -5131,7 +5180,7 @@ packages:
|
||||
vite: ^2.6.0
|
||||
dependencies:
|
||||
'@svgr/core': 6.2.1
|
||||
vite: 2.9.5_sass@1.50.0
|
||||
vite: 2.9.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -5307,6 +5356,10 @@ packages:
|
||||
resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==}
|
||||
dev: false
|
||||
|
||||
/zoom-level/2.5.0:
|
||||
resolution: {integrity: sha512-7UlRWU4Q3uCMCeDVMOm7eBrIu145OqsIJ3p6zq58l8UsSYwKWxc6zEapC5YA9tIeh0oheb4cT9Kk2Wq353loFg==}
|
||||
dev: false
|
||||
|
||||
/zustand/3.7.2_react@18.0.0:
|
||||
resolution: {integrity: sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==}
|
||||
engines: {node: '>=12.7.0'}
|
||||
|
||||
Reference in new issue
Block a user