mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-02 10:03:28 +00:00
Overdue wide boi commit
- Files table - Sidebar + router - Get files
This commit is contained in:
parent
2af3e6c3d8
commit
0a021982c6
|
@ -9,6 +9,7 @@
|
|||
"@types/babel-core": "^6.25.7",
|
||||
"@types/react": "^17.0.18",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/react-router-dom": "^5.3.1",
|
||||
"@types/tailwindcss": "^2.2.1",
|
||||
"concurrently": "^6.2.1",
|
||||
"prettier": "^2.3.2",
|
||||
|
@ -25,6 +26,7 @@
|
|||
"@headlessui/react": "^1.4.0",
|
||||
"@heroicons/react": "^1.0.4",
|
||||
"@tauri-apps/api": "^1.0.0-beta.5",
|
||||
"@types/react-table": "^7.7.6",
|
||||
"@vitejs/plugin-react-refresh": "^1.3.6",
|
||||
"autoprefixer": "^9",
|
||||
"clsx": "^1.1.1",
|
||||
|
|
66
src-tauri/Cargo.lock
generated
66
src-tauri/Cargo.lock
generated
|
@ -2,6 +2,39 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "SpaceDrive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytesize",
|
||||
"cargo-edit",
|
||||
"chrono",
|
||||
"crossbeam",
|
||||
"data-encoding",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"int-enum",
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.23.0",
|
||||
"once_cell",
|
||||
"rebind",
|
||||
"refinery",
|
||||
"ring 0.17.0-alpha.10",
|
||||
"rusqlite",
|
||||
"sea-orm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha256",
|
||||
"snafu",
|
||||
"sqlx",
|
||||
"strum 0.21.0",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.16.0"
|
||||
|
@ -3364,39 +3397,6 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sd"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytesize",
|
||||
"cargo-edit",
|
||||
"chrono",
|
||||
"crossbeam",
|
||||
"data-encoding",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"int-enum",
|
||||
"libc",
|
||||
"log",
|
||||
"nix 0.23.0",
|
||||
"once_cell",
|
||||
"rebind",
|
||||
"refinery",
|
||||
"ring 0.17.0-alpha.10",
|
||||
"rusqlite",
|
||||
"sea-orm",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha256",
|
||||
"snafu",
|
||||
"sqlx",
|
||||
"strum 0.21.0",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sea-orm"
|
||||
version = "0.2.3"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
[package]
|
||||
name = "sd"
|
||||
name = "SpaceDrive"
|
||||
version = "0.1.0"
|
||||
description = "The next gen private virtual filesystem."
|
||||
authors = ["you"]
|
||||
license = ""
|
||||
repository = ""
|
||||
default-run = "sd"
|
||||
default-run = "SpaceDrive"
|
||||
edition = "2018"
|
||||
build = "src/build.rs"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ pub struct AppConfig {
|
|||
|
||||
// returns the app config struct with complete values
|
||||
pub fn get_config() -> AppConfig {
|
||||
let app_name = "sd";
|
||||
let app_name = "SpaceDrive";
|
||||
let data_dir = path::data_dir()
|
||||
.unwrap_or(std::path::PathBuf::from("./"))
|
||||
.join(app_name);
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
use crate::db::entity::file;
|
||||
use crate::filesystem::{init, reader};
|
||||
use crate::{db, filesystem};
|
||||
use anyhow::Result;
|
||||
use once_cell::sync::OnceCell;
|
||||
use sea_orm::DatabaseConnection;
|
||||
use sea_orm::{DatabaseConnection, EntityTrait};
|
||||
|
||||
pub static DB_INSTANCE: OnceCell<DatabaseConnection> = OnceCell::new();
|
||||
|
||||
async fn init_db_instance() -> Result<()> {
|
||||
let db = db::connection::get_connection().await?;
|
||||
async fn db_instance() -> Result<&'static DatabaseConnection> {
|
||||
if DB_INSTANCE.get().is_none() {
|
||||
let db = db::connection::get_connection().await?;
|
||||
DB_INSTANCE.set(db).unwrap_or_default();
|
||||
Ok(DB_INSTANCE.get().unwrap())
|
||||
} else {
|
||||
Ok(DB_INSTANCE.get().unwrap())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
pub async fn scan_dir(path: &str) -> Result<(), String> {
|
||||
init_db_instance().await.map_err(|e| e.to_string())?;
|
||||
db_instance().await.map_err(|e| e.to_string())?;
|
||||
|
||||
let directories = filesystem::explorer::scan(path)
|
||||
.await
|
||||
|
@ -26,6 +29,21 @@ pub async fn scan_dir(path: &str) -> Result<(), String> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
pub async fn get_files() -> Result<Vec<file::Model>, String> {
|
||||
let connection = db_instance().await.map_err(|e| e.to_string())?;
|
||||
|
||||
let files = file::Entity::find()
|
||||
.all(connection)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
println!("files found, {:?}", files.len());
|
||||
|
||||
Ok(files[..100].to_vec())
|
||||
}
|
||||
|
||||
// #[tauri::command(async)]
|
||||
// pub async fn generate_buffer_checksum(path: &str) -> Result<File, InvokeError> {
|
||||
// let mut file = file::read_file(path)
|
||||
|
|
|
@ -30,7 +30,10 @@ fn main() {
|
|||
// block_on(filesystem::device::discover_storage_devices()).unwrap();
|
||||
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![commands::scan_dir])
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::scan_dir,
|
||||
commands::get_files
|
||||
])
|
||||
.menu(menu::get_menu())
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"package": {
|
||||
"productName": "sd",
|
||||
"productName": "SpaceDrive",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"build": {
|
||||
|
@ -52,7 +52,7 @@
|
|||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "sd",
|
||||
"title": "SpaceDrive",
|
||||
"width": 1200,
|
||||
"height": 700,
|
||||
"resizable": true,
|
||||
|
|
105
src/App.tsx
105
src/App.tsx
|
@ -1,93 +1,30 @@
|
|||
import React, { useRef, useState } from 'react';
|
||||
import { CookingPot, Copy, Gear, Pencil, TrashSimple } from 'phosphor-react';
|
||||
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { Button } from './components/primative/Button';
|
||||
import { Input, Toggle } from './components/primative';
|
||||
import { InputContainer } from './components/primative/InputContainer';
|
||||
import { TrafficLights } from './components/os/TrafficLights';
|
||||
import { Checkbox } from './components/primative/Checkbox';
|
||||
import { useInputState } from './hooks/useInputState';
|
||||
import { Dropdown } from './components/primative/Dropdown';
|
||||
import { DuplicateIcon, PencilAltIcon, TrashIcon } from '@heroicons/react/solid';
|
||||
import { FileRow } from './components/file/FileRow';
|
||||
import React, { useRef } from 'react';
|
||||
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom';
|
||||
import { Sidebar } from './components/file/Sidebar';
|
||||
import { TopBar } from './components/layout/TopBar';
|
||||
import { useInputState } from './hooks/useInputState';
|
||||
import { SettingsScreen } from './screens/Settings';
|
||||
import { ExplorerScreen } from './screens/Explorer';
|
||||
|
||||
export default function App() {
|
||||
const fileUploader = useRef<HTMLInputElement | null>(null);
|
||||
const inputState = useInputState('/Users/jamie/Downloads');
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen rounded-xl border border-gray-200 dark:border-gray-600 bg-white text-gray-900 dark:text-white dark:bg-gray-800 overflow-hidden ">
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
className="flex flex-grow flex-shrink-0 max-w items-center bg-gray-50 dark:bg-gray-900 h-8 border-gray-100 dark:border-gray-900 shadow-sm justify-between dark:border-t "
|
||||
>
|
||||
<TrafficLights className="p-1.5" />
|
||||
<Button noBorder noPadding className="mr-2">
|
||||
<Gear weight="fill" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="h-[1px] flex-shrink-0 max-w bg-gray-100 dark:bg-gray-700" />
|
||||
<div className="flex flex-row min-h-full">
|
||||
<Sidebar />
|
||||
<div className="px-6 py-4">
|
||||
<div className="flex space-x-2">
|
||||
<InputContainer
|
||||
title="Quick scan directory"
|
||||
description="The directory for which this application will perform a detailed scan of the contents and sub directories"
|
||||
>
|
||||
<Input {...inputState} placeholder="/users/jamie/Desktop" />
|
||||
</InputContainer>
|
||||
<InputContainer
|
||||
title="Quick scan directory"
|
||||
description="The directory for which this application will perform a detailed scan of the contents and sub directories"
|
||||
>
|
||||
<Input {...inputState} placeholder="/users/jamie/Desktop" />
|
||||
</InputContainer>
|
||||
<Router>
|
||||
<div className="flex flex-col h-screen rounded-xl border border-gray-200 dark:border-gray-600 bg-white text-gray-900 dark:text-white dark:bg-gray-800 overflow-hidden ">
|
||||
<TopBar />
|
||||
<div className="flex flex-row min-h-full">
|
||||
<Sidebar />
|
||||
<div className="w-full flex">
|
||||
<Switch>
|
||||
<Route path="/settings">
|
||||
<SettingsScreen />
|
||||
</Route>
|
||||
<Route path="/explorer">
|
||||
<ExplorerScreen />
|
||||
</Route>
|
||||
</Switch>
|
||||
</div>
|
||||
<div className="space-x-2 flex flex-row mt-6">
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
invoke('scan_dir', {
|
||||
path: inputState.value
|
||||
});
|
||||
}}
|
||||
>
|
||||
Scan Now
|
||||
</Button>
|
||||
<Button>Cancel</Button>
|
||||
</div>
|
||||
<div className="flex space-x-2 mt-2">
|
||||
<Button size="sm" variant="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size="sm">Cancel</Button>
|
||||
</div>
|
||||
<div className="space-x-2 flex flex-row mt-4">
|
||||
<Toggle initialState={false} />
|
||||
</div>
|
||||
<div className="space-x-2 flex flex-row mt-4 mb-5 ml-1">
|
||||
<Checkbox />
|
||||
<Checkbox />
|
||||
<Checkbox />
|
||||
</div>
|
||||
<Dropdown
|
||||
buttonText="My Library"
|
||||
items={[
|
||||
[
|
||||
{ name: 'Edit', icon: PencilAltIcon },
|
||||
{ name: 'Copy', icon: DuplicateIcon }
|
||||
],
|
||||
[{ name: 'Delete', icon: TrashIcon }]
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div className="px-6 mt-4">
|
||||
<FileRow />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
|
126
src/components/file/FileList.tsx
Normal file
126
src/components/file/FileList.tsx
Normal file
|
@ -0,0 +1,126 @@
|
|||
import { DocumentIcon, DotsVerticalIcon, FilmIcon, MusicNoteIcon } from '@heroicons/react/solid';
|
||||
import clsx from 'clsx';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { FileData } from '../../types';
|
||||
|
||||
interface Column {
|
||||
column: string;
|
||||
key: string;
|
||||
width: number;
|
||||
}
|
||||
|
||||
interface FileListData {
|
||||
id: number;
|
||||
type?: string;
|
||||
tags?: Tag[];
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface Tag {
|
||||
name: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
// Function ensure no types are loss, but guarantees that they are Column[]
|
||||
function ensureIsColumns<T extends Column[]>(data: T) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const columns = ensureIsColumns([
|
||||
{ column: 'Name', key: 'name', width: 280 } as const,
|
||||
{ column: 'Size', key: 'size_in_bytes', width: 120 } as const,
|
||||
{ column: 'Checksum', key: 'meta_checksum', width: 120 } as const
|
||||
// { column: 'Tags', key: 'tags', width: 120 } as const
|
||||
]);
|
||||
|
||||
type ColumnKey = typeof columns[number]['key'];
|
||||
|
||||
// const data: FileListData[] = [
|
||||
// {
|
||||
// id: 1,
|
||||
// name: 'MyNameJeff.mp4',
|
||||
// type: 'video',
|
||||
// size: '5GB'
|
||||
// // tags: [{ name: 'Keepsafe', color: '#3076E6' }]
|
||||
// },
|
||||
// { id: 2, name: 'cow.ogg', type: 'audio', size: '345KB' },
|
||||
// { id: 3, name: 'calvin.fig', size: '34MB' },
|
||||
// { id: 4, name: 'calvin.fig' },
|
||||
// { id: 5, name: 'calvin.fig' },
|
||||
// { id: 6, name: 'calvin.fig' }
|
||||
// ];
|
||||
|
||||
const RenderCell = ({ colKey, row }: { colKey?: ColumnKey; row?: FileData }) => {
|
||||
if (!row || !colKey || !row[colKey]) return <></>;
|
||||
|
||||
const renderCellWithIcon = (Icon: any) => {
|
||||
return (
|
||||
<div className="flex flex-row items-center">
|
||||
{colKey == 'name' && <Icon className="w-5 h-5 mr-3 flex-shrink-0" />}
|
||||
<span className="truncate">{row[colKey]}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
switch (colKey) {
|
||||
case 'name':
|
||||
return renderCellWithIcon(FilmIcon);
|
||||
case 'size_in_bytes':
|
||||
return renderCellWithIcon(MusicNoteIcon);
|
||||
// case 'tags':
|
||||
// return renderCellWithIcon(MusicNoteIcon);
|
||||
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
};
|
||||
|
||||
export const FileList: React.FC<{ files: FileData[] }> = (props) => {
|
||||
const [selectedRow, setSelectedRow] = useState(0);
|
||||
return (
|
||||
<div className="table-container w-full h-full overflow-scroll bg-gray-900 rounded-md p-2 shadow-md">
|
||||
<div className="table-head">
|
||||
<div className="table-head-row flex flex-row p-2">
|
||||
{columns.map((col) => (
|
||||
<div
|
||||
key={col.key}
|
||||
className="table-head-cell flex flex-row items-center relative group px-4"
|
||||
style={{ width: col.width }}
|
||||
>
|
||||
<DotsVerticalIcon className="hidden absolute group-hover:block drag-handle w-5 h-5 opacity-10 -ml-5 cursor-move" />
|
||||
<span className="">{col.column}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="table-body">
|
||||
{props.files?.map((row, index) => (
|
||||
<div
|
||||
key={row.id}
|
||||
onClick={() => setSelectedRow(row.id as number)}
|
||||
className={clsx('table-body-row flex flex-row rounded-lg border-2 border-[#00000000]', {
|
||||
'bg-[#00000030]': index % 2 == 0,
|
||||
'border-primary-500': selectedRow === row.id
|
||||
})}
|
||||
>
|
||||
{columns.map((col) => (
|
||||
<div key={col.key} className="table-body-cell px-4 py-2" style={{ width: col.width }}>
|
||||
{useMemo(
|
||||
() => (
|
||||
<RenderCell row={row} colKey={col?.key} />
|
||||
),
|
||||
[row, col?.key]
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// const columnKeyMap = columns.reduce((obj, column, index) => {
|
||||
// obj[column.key] = index;
|
||||
// return obj;
|
||||
// }, {} as Record<string, number>);
|
67
src/components/file/FileListTable.tsx
Normal file
67
src/components/file/FileListTable.tsx
Normal file
|
@ -0,0 +1,67 @@
|
|||
import clsx from 'clsx';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useTable } from 'react-table';
|
||||
|
||||
const columns = [
|
||||
{ Header: 'Name', accessor: 'name' },
|
||||
{ Header: 'Size', accessor: 'size' }
|
||||
];
|
||||
|
||||
export const dummyFileData = [
|
||||
{ id: 1, name: 'MyNameJeff.mp4', type: 'video', size: '5GB' },
|
||||
{ id: 2, name: 'cow.ogg', type: 'audio', size: '345KB' },
|
||||
{ id: 3, name: 'calvin.fig' },
|
||||
{ id: 4, name: 'calvin.fig' },
|
||||
{ id: 5, name: 'calvin.fig' },
|
||||
{ id: 6, name: 'calvin.fig' }
|
||||
];
|
||||
|
||||
export const FileListTable: React.FC<{}> = (props) => {
|
||||
// @ts-expect-error
|
||||
const tableInstance = useTable({ columns, data: dummyFileData });
|
||||
const [selectedRow, setSelectedRow] = useState(0);
|
||||
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = tableInstance;
|
||||
|
||||
return (
|
||||
<div className="w-full bg-gray-900 p-2 rounded-lg">
|
||||
<table className="w-full rounded-lg shadow-lg border-collapse" {...getTableProps()}>
|
||||
<thead>
|
||||
{headerGroups.map((headerGroup) => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map((column) => (
|
||||
<th
|
||||
className="px-3 pt-2 text-left text-gray-500 text-sm"
|
||||
{...column.getHeaderProps()}
|
||||
>
|
||||
{column.render('Header')}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody {...getTableBodyProps()}>
|
||||
{rows.map((row) => {
|
||||
prepareRow(row);
|
||||
return (
|
||||
<tr
|
||||
onClick={() => setSelectedRow(row.original.id || 0)}
|
||||
className={clsx('even:bg-[#00000040] border-2 border-opacity-0 rounded-sm', {
|
||||
'border-2 border-opacity-100 border-primary z-50': selectedRow === row.original.id
|
||||
})}
|
||||
{...row.getRowProps()}
|
||||
>
|
||||
{row.cells.map((cell) => {
|
||||
return (
|
||||
<td className={clsx('py-2 px-4 rounded-sm')} {...cell.getCellProps()}>
|
||||
{cell.render('Cell')}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -1,52 +1,34 @@
|
|||
import { CogIcon, CollectionIcon, CubeTransparentIcon, DatabaseIcon } from '@heroicons/react/solid';
|
||||
import { GearSix } from 'phosphor-react';
|
||||
import React, { SetStateAction, useState } from 'react';
|
||||
import { Button, ButtonVariant } from '../primative';
|
||||
import {
|
||||
CogIcon,
|
||||
CollectionIcon,
|
||||
CubeTransparentIcon,
|
||||
DatabaseIcon,
|
||||
PhotographIcon,
|
||||
ServerIcon
|
||||
} from '@heroicons/react/solid';
|
||||
import { Planet } from 'phosphor-react';
|
||||
import React from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { Dropdown } from '../primative/Dropdown';
|
||||
import { DefaultProps } from '../primative/types';
|
||||
|
||||
const tabs = [
|
||||
{ name: 'Drive', icon: CollectionIcon },
|
||||
{ name: 'Storage', icon: DatabaseIcon },
|
||||
{ name: 'Explorer', icon: CubeTransparentIcon },
|
||||
{ name: 'Settings', icon: CogIcon }
|
||||
{ name: 'Spaces', icon: Planet, uri: '/spaces' },
|
||||
{ name: 'Photos', icon: PhotographIcon, uri: '/photos' },
|
||||
{ name: 'Storage', icon: ServerIcon, uri: '/storage' },
|
||||
{ name: 'Explorer', icon: CubeTransparentIcon, uri: '/explorer' },
|
||||
{ name: 'Settings', icon: CogIcon, uri: '/settings' }
|
||||
];
|
||||
|
||||
interface SidebarButtonProps extends DefaultProps {
|
||||
name: string;
|
||||
icon: any;
|
||||
setActiveTab: (name: string) => any;
|
||||
getVarient: (name: string) => ButtonVariant;
|
||||
}
|
||||
interface SidebarProps extends DefaultProps {}
|
||||
|
||||
const SidebarButton: React.FC<SidebarButtonProps> = (props) => {
|
||||
return (
|
||||
<Button
|
||||
onClick={() => props.setActiveTab(props.name)}
|
||||
variant={props.getVarient(props.name)}
|
||||
justifyLeft
|
||||
noBorder
|
||||
className="items-center shadow-none text-gray-500 hover:text-gray-500 cursor-default"
|
||||
size="sm"
|
||||
>
|
||||
{props.icon && <props.icon className="w-4 h-4 mr-2" />}
|
||||
{props.name}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const Sidebar: React.FC<SidebarProps> = (props) => {
|
||||
const [activeTab, setActiveTab] = useState(tabs[0].name);
|
||||
|
||||
const getVarient = (name: string) => (activeTab == name ? 'selected' : 'default');
|
||||
|
||||
return (
|
||||
<div className="w-48 flex flex-col flex-wrap flex-shrink-0 min-h-full bg-gray-50 dark:bg-gray-800 border-gray-100 border-r dark:border-gray-700 px-2 space-y-0.5">
|
||||
<div className="w-46 flex flex-col flex-wrap flex-shrink-0 min-h-full bg-gray-50 dark:bg-gray-800 border-gray-100 border-r dark:border-gray-700 px-3 space-y-0.5">
|
||||
<Dropdown
|
||||
buttonProps={{
|
||||
justifyLeft: true,
|
||||
className: 'mb-1 flex-shrink-0 w-175px]',
|
||||
className: 'mb-1 flex-shrink-0 w-[175px]',
|
||||
variant: 'gray'
|
||||
}}
|
||||
buttonText="Jamie's Library"
|
||||
|
@ -54,13 +36,14 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
|
|||
/>
|
||||
|
||||
{tabs.map((button, index) => (
|
||||
<SidebarButton
|
||||
name={button.name}
|
||||
icon={button.icon}
|
||||
key={index}
|
||||
getVarient={getVarient}
|
||||
setActiveTab={setActiveTab}
|
||||
/>
|
||||
<NavLink
|
||||
className="max-w rounded px-2 py-1 flex flex-row items-center hover:bg-gray-700 text-sm"
|
||||
activeClassName="bg-gray-500 hover:bg-gray-500"
|
||||
to={button.uri}
|
||||
>
|
||||
{button.icon && <button.icon className="w-4 h-4 mr-2" />}
|
||||
{button.name}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
|
64
src/components/layout/TopBar.tsx
Normal file
64
src/components/layout/TopBar.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
import {
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
CogIcon,
|
||||
HomeIcon,
|
||||
ViewBoardsIcon,
|
||||
ViewGridIcon,
|
||||
ViewListIcon
|
||||
} from '@heroicons/react/outline';
|
||||
import { HouseSimple } from 'phosphor-react';
|
||||
import React from 'react';
|
||||
import { TrafficLights } from '../os/TrafficLights';
|
||||
import { Button, Input } from '../primative';
|
||||
import { Shortcut } from '../primative/Shortcut';
|
||||
import { DefaultProps } from '../primative/types';
|
||||
|
||||
export interface TopBarProps extends DefaultProps {}
|
||||
|
||||
export const TopBar: React.FC<TopBarProps> = (props) => {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
className="flex flex-shrink-0 h-10 max-w items-center bg-gray-50 dark:bg-gray-900 border-gray-100 dark:border-gray-900 shadow-sm dark:border-t"
|
||||
>
|
||||
<div className="w-52 ml-1" data-tauri-drag-region>
|
||||
<TrafficLights className="p-1.5" />
|
||||
</div>
|
||||
<Button noBorder noPadding className="rounded-r-none mr-[1px]">
|
||||
<ChevronLeftIcon className="m-0.5 w-4 h-4 dark:text-white" />
|
||||
</Button>
|
||||
<Button noBorder noPadding className="rounded-l-none">
|
||||
<ChevronRightIcon className="m-0.5 w-4 h-4 dark:text-white" />
|
||||
</Button>
|
||||
<div className="w-4"></div>
|
||||
<Button noBorder noPadding className="rounded-r-none mr-[1px]">
|
||||
<ViewGridIcon className="m-0.5 w-4 h-4 dark:text-white" />
|
||||
</Button>
|
||||
<Button noBorder noPadding className="rounded-none mr-[1px]">
|
||||
<ViewBoardsIcon className="m-0.5 w-4 h-4 dark:text-white" />
|
||||
</Button>
|
||||
<Button noBorder noPadding className="rounded-l-none">
|
||||
<ViewListIcon className="m-0.5 w-4 h-4 dark:text-white" />
|
||||
</Button>
|
||||
<div className="w-4"></div>
|
||||
<div className="relative flex h-7">
|
||||
<Input
|
||||
placeholder="Search"
|
||||
className="placeholder-gray-600 bg-gray-50 text-xs w-32 focus:w-52 transition-all"
|
||||
/>
|
||||
<div className="space-x-1 absolute top-[1px] right-1">
|
||||
<Shortcut chars="⌘" />
|
||||
<Shortcut chars="S" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-grow"></div>
|
||||
<Button noBorder noPadding className="mr-2">
|
||||
<CogIcon className="m-0.5 w-4 h-4 text-white" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="h-[1px] flex-shrink-0 max-w bg-gray-100 dark:bg-gray-700" />
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -60,8 +60,9 @@ const variants = {
|
|||
`,
|
||||
primary:
|
||||
'bg-primary text-white shadow-sm border-primary-600 dark:border-primary-400 active:bg-primary-600 active:border-primary-700 hover:bg-primary-400 hover:border-primary-500',
|
||||
selected:
|
||||
'bg-gray-100 dark:bg-gray-500 active:text-gray-100 dark:hover:text-white dark:text-white'
|
||||
selected: `bg-gray-100 dark:bg-gray-500
|
||||
text-black hover:text-black active:text-black dark:hover:text-white dark:text-white
|
||||
`
|
||||
};
|
||||
|
||||
export type ButtonVariant = keyof typeof variants;
|
||||
|
|
33
src/components/primative/Shortcut.tsx
Normal file
33
src/components/primative/Shortcut.tsx
Normal file
|
@ -0,0 +1,33 @@
|
|||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { DefaultProps } from './types';
|
||||
|
||||
export interface ShortcutProps extends DefaultProps {
|
||||
chars: string;
|
||||
}
|
||||
|
||||
export const Shortcut: React.FC<ShortcutProps> = (props) => {
|
||||
return (
|
||||
<span
|
||||
className={clsx(
|
||||
`
|
||||
px-1
|
||||
py-0.5
|
||||
text-xs
|
||||
font-bold
|
||||
text-gray-400
|
||||
bg-gray-200
|
||||
border-gray-300
|
||||
dark:text-gray-300
|
||||
dark:bg-gray-700
|
||||
dark:border-gray-600
|
||||
border-t-2
|
||||
rounded-md
|
||||
`,
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
{props.chars}
|
||||
</span>
|
||||
);
|
||||
};
|
9
src/components/primative/Tag.tsx
Normal file
9
src/components/primative/Tag.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import { DefaultProps } from './types';
|
||||
|
||||
export interface TagProps extends DefaultProps {}
|
||||
|
||||
export const Tag: React.FC<TagProps> = (props) => {
|
||||
return <div className={clsx('rounded px-2 py-1', props.className)}>{props.children}</div>;
|
||||
};
|
23
src/screens/Explorer.tsx
Normal file
23
src/screens/Explorer.tsx
Normal file
|
@ -0,0 +1,23 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { FileList } from '../components/file/FileList';
|
||||
import { emit, listen } from '@tauri-apps/api/event';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { FileData } from '../types';
|
||||
|
||||
export const ExplorerScreen: React.FC<{}> = () => {
|
||||
const [files, setFiles] = useState<FileData[] | null>(null);
|
||||
useEffect(() => {
|
||||
invoke('get_files').then((res) => {
|
||||
setFiles(res as FileData[]);
|
||||
});
|
||||
}, []);
|
||||
console.log({ files });
|
||||
|
||||
if (!files) return <></>;
|
||||
|
||||
return (
|
||||
<div className="w-full m-3">
|
||||
<FileList files={files} />
|
||||
</div>
|
||||
);
|
||||
};
|
80
src/screens/Settings.tsx
Normal file
80
src/screens/Settings.tsx
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { DuplicateIcon, PencilAltIcon, TrashIcon } from '@heroicons/react/solid';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import React, { useRef } from 'react';
|
||||
// import { dummyFileData, FileList } from '../components/file/FileList';
|
||||
import { Input, Toggle } from '../components/primative';
|
||||
import { Button } from '../components/primative/Button';
|
||||
import { Checkbox } from '../components/primative/Checkbox';
|
||||
import { Dropdown } from '../components/primative/Dropdown';
|
||||
import { InputContainer } from '../components/primative/InputContainer';
|
||||
import { Shortcut } from '../components/primative/Shortcut';
|
||||
import { useInputState } from '../hooks/useInputState';
|
||||
|
||||
export const SettingsScreen: React.FC<{}> = () => {
|
||||
const fileUploader = useRef<HTMLInputElement | null>(null);
|
||||
const inputState = useInputState('/Users/jamie/Downloads');
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="p-3">
|
||||
{/* <FileList files={dummyFileData} /> */}
|
||||
<div className="flex space-x-2 mt-4">
|
||||
<InputContainer
|
||||
title="Quick scan directory"
|
||||
description="The directory for which this application will perform a detailed scan of the contents and sub directories"
|
||||
>
|
||||
<Input {...inputState} placeholder="/users/jamie/Desktop" />
|
||||
</InputContainer>
|
||||
<InputContainer
|
||||
title="Quick scan directory"
|
||||
description="The directory for which this application will perform a detailed scan of the contents and sub directories"
|
||||
>
|
||||
<Input {...inputState} placeholder="/users/jamie/Desktop" />
|
||||
</InputContainer>
|
||||
</div>
|
||||
<div className="space-x-2 flex flex-row mt-6">
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
invoke('scan_dir', {
|
||||
path: inputState.value
|
||||
});
|
||||
}}
|
||||
>
|
||||
Scan Now
|
||||
</Button>
|
||||
<Button>Cancel</Button>
|
||||
</div>
|
||||
<div className="flex space-x-2 mt-2">
|
||||
<Button size="sm" variant="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button size="sm">Cancel</Button>
|
||||
</div>
|
||||
<div className="space-x-2 flex flex-row mt-4">
|
||||
<Toggle initialState={false} />
|
||||
</div>
|
||||
<div className="space-x-2 flex flex-row mt-4 mb-5 ml-1">
|
||||
<Checkbox />
|
||||
<Checkbox />
|
||||
<Checkbox />
|
||||
</div>
|
||||
<Dropdown
|
||||
buttonProps={{}}
|
||||
buttonText="My Library"
|
||||
items={[
|
||||
[
|
||||
{ name: 'Edit', icon: PencilAltIcon },
|
||||
{ name: 'Copy', icon: DuplicateIcon }
|
||||
],
|
||||
[{ name: 'Delete', icon: TrashIcon }]
|
||||
]}
|
||||
/>
|
||||
<div className="mt-3 space-x-1">
|
||||
<Shortcut chars="⌘" />
|
||||
<Shortcut chars="S" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -1,3 +1,23 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
/*
|
||||
.table-container {
|
||||
@apply w-full bg-gray-900;
|
||||
}
|
||||
.table-head {
|
||||
@apply w-full;
|
||||
}
|
||||
.table-head-row {
|
||||
@apply w-full flex flex-row;
|
||||
}
|
||||
.table-head-cell {
|
||||
}
|
||||
.table-body {
|
||||
@apply w-full;
|
||||
}
|
||||
.table-row {
|
||||
@apply w-full flex flex-row;
|
||||
}
|
||||
.table-cell {
|
||||
} */
|
||||
|
|
|
@ -1,31 +1,25 @@
|
|||
import { Encryption } from './library';
|
||||
import { ImageMeta, VideoMeta } from './media';
|
||||
|
||||
export interface Object {
|
||||
export interface FileData {
|
||||
id?: number;
|
||||
checksum: string;
|
||||
type: ObjectType;
|
||||
|
||||
meta_checksum: string;
|
||||
uri: string;
|
||||
name: string;
|
||||
extension: string;
|
||||
size: number;
|
||||
mime: string;
|
||||
encryption?: Encryption;
|
||||
|
||||
date_created: Date;
|
||||
date_modified: Date;
|
||||
date_indexed: Date;
|
||||
|
||||
name: string;
|
||||
extension: string;
|
||||
size_in_bytes: string;
|
||||
|
||||
library_id: string;
|
||||
directory_id: string;
|
||||
ipfs_id: string;
|
||||
storage_device_id: string;
|
||||
capture_device_id: string;
|
||||
parent_object_id: string;
|
||||
user_id: string;
|
||||
|
||||
geolocation: string;
|
||||
extra_data: null | ImageMeta | VideoMeta;
|
||||
ipfs_id: string;
|
||||
parent_file_id: string;
|
||||
}
|
||||
|
||||
export interface Directory {
|
||||
|
|
|
@ -42,12 +42,12 @@ module.exports = {
|
|||
800: '#282A34',
|
||||
900: '#1B1C23'
|
||||
}
|
||||
},
|
||||
fontFamily: { sans: ['Inter', ...defaultTheme.fontFamily.sans] }
|
||||
}
|
||||
// fontFamily: { sans: ['Inter', ...defaultTheme.fontFamily.sans] }
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
extend: {}
|
||||
},
|
||||
plugins: [require('@tailwindcss/forms')]
|
||||
plugins: []
|
||||
};
|
||||
|
|
238
yarn.lock
238
yarn.lock
|
@ -62,6 +62,22 @@
|
|||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.15.4":
|
||||
version "7.15.8"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1"
|
||||
integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==
|
||||
dependencies:
|
||||
"@babel/types" "^7.15.6"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.0.0":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835"
|
||||
integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/helper-compilation-targets@^7.15.0":
|
||||
version "7.15.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818"
|
||||
|
@ -81,6 +97,15 @@
|
|||
"@babel/template" "^7.14.5"
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-function-name@^7.15.4":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc"
|
||||
integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==
|
||||
dependencies:
|
||||
"@babel/helper-get-function-arity" "^7.15.4"
|
||||
"@babel/template" "^7.15.4"
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815"
|
||||
|
@ -88,6 +113,13 @@
|
|||
dependencies:
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.15.4":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b"
|
||||
integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/helper-hoist-variables@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d"
|
||||
|
@ -95,6 +127,13 @@
|
|||
dependencies:
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-hoist-variables@^7.15.4":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df"
|
||||
integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/helper-member-expression-to-functions@^7.15.0":
|
||||
version "7.15.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b"
|
||||
|
@ -102,6 +141,13 @@
|
|||
dependencies:
|
||||
"@babel/types" "^7.15.0"
|
||||
|
||||
"@babel/helper-module-imports@^7.0.0":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f"
|
||||
integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/helper-module-imports@^7.14.5":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3"
|
||||
|
@ -159,6 +205,13 @@
|
|||
dependencies:
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.15.4":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257"
|
||||
integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9":
|
||||
version "7.14.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
|
||||
|
@ -192,6 +245,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862"
|
||||
integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==
|
||||
|
||||
"@babel/parser@^7.15.4":
|
||||
version "7.15.8"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016"
|
||||
integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==
|
||||
|
||||
"@babel/plugin-transform-react-jsx-self@^7.14.5":
|
||||
version "7.14.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.14.9.tgz#33041e665453391eb6ee54a2ecf3ba1d46bd30f4"
|
||||
|
@ -222,6 +280,15 @@
|
|||
"@babel/parser" "^7.14.5"
|
||||
"@babel/types" "^7.14.5"
|
||||
|
||||
"@babel/template@^7.15.4":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194"
|
||||
integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.14.5"
|
||||
"@babel/parser" "^7.15.4"
|
||||
"@babel/types" "^7.15.4"
|
||||
|
||||
"@babel/traverse@^7.15.0":
|
||||
version "7.15.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98"
|
||||
|
@ -237,6 +304,21 @@
|
|||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/traverse@^7.4.5":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d"
|
||||
integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.14.5"
|
||||
"@babel/generator" "^7.15.4"
|
||||
"@babel/helper-function-name" "^7.15.4"
|
||||
"@babel/helper-hoist-variables" "^7.15.4"
|
||||
"@babel/helper-split-export-declaration" "^7.15.4"
|
||||
"@babel/parser" "^7.15.4"
|
||||
"@babel/types" "^7.15.4"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0":
|
||||
version "7.15.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd"
|
||||
|
@ -245,11 +327,41 @@
|
|||
"@babel/helper-validator-identifier" "^7.14.9"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.15.4", "@babel/types@^7.15.6":
|
||||
version "7.15.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f"
|
||||
integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.14.9"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@cush/relative@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@cush/relative/-/relative-1.0.0.tgz#8cd1769bf9bde3bb27dac356b1bc94af40f6cc16"
|
||||
integrity sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==
|
||||
|
||||
"@emotion/is-prop-valid@^0.8.8":
|
||||
version "0.8.8"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||
dependencies:
|
||||
"@emotion/memoize" "0.7.4"
|
||||
|
||||
"@emotion/memoize@0.7.4":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||
|
||||
"@emotion/stylis@^0.8.4":
|
||||
version "0.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
|
||||
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
|
||||
|
||||
"@emotion/unitless@^0.7.4":
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
|
||||
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
|
||||
|
||||
"@graphql-typed-document-node/core@^3.0.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.0.tgz#0eee6373e11418bfe0b5638f654df7a4ca6a3950"
|
||||
|
@ -323,13 +435,6 @@
|
|||
dependencies:
|
||||
defer-to-connect "^2.0.0"
|
||||
|
||||
"@tailwindcss/forms@^0.3.3":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.3.3.tgz#a29d22668804f3dae293dcadbef1aa6315c45b64"
|
||||
integrity sha512-U8Fi/gq4mSuaLyLtFISwuDYzPB73YzgozjxOIHsK6NXgg/IWD1FLaHbFlWmurAMyy98O+ao74ksdQefsquBV1Q==
|
||||
dependencies:
|
||||
mini-svg-data-uri "^1.2.3"
|
||||
|
||||
"@tauri-apps/api@^1.0.0-beta.5":
|
||||
version "1.0.0-beta.5"
|
||||
resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.0.0-beta.5.tgz#32727b3b478f67330a79409ceaf16a4a51410fce"
|
||||
|
@ -429,6 +534,19 @@
|
|||
"@types/node" "*"
|
||||
"@types/responselike" "*"
|
||||
|
||||
"@types/history@*":
|
||||
version "4.7.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.9.tgz#1cfb6d60ef3822c589f18e70f8b12f9a28ce8724"
|
||||
integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==
|
||||
|
||||
"@types/hoist-non-react-statics@*":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
|
||||
"@types/http-cache-semantics@*":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"
|
||||
|
@ -468,6 +586,30 @@
|
|||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router-dom@^5.3.1":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.1.tgz#76700ccce6529413ec723024b71f01fc77a4a980"
|
||||
integrity sha512-UvyRy73318QI83haXlaMwmklHHzV9hjl3u71MmM6wYNu0hOVk9NLTa0vGukf8zXUqnwz4O06ig876YSPpeK28A==
|
||||
dependencies:
|
||||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
"@types/react-router" "*"
|
||||
|
||||
"@types/react-router@*":
|
||||
version "5.1.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.17.tgz#087091006213b11042f39570e5cd414863693968"
|
||||
integrity sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==
|
||||
dependencies:
|
||||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-table@^7.7.6":
|
||||
version "7.7.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-table/-/react-table-7.7.6.tgz#4899ccc46b4a1de08cc1daf120842e37e112e51e"
|
||||
integrity sha512-ZMFHh1sG5AGDmhVRpz9mgGByGmBFAqnZ7QnyqGa5iAlKtcSC3vb/gul47lM0kJ1uvlawc+qN5k+++pe+GBdJ+g==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^17.0.18":
|
||||
version "17.0.18"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.18.tgz#4109cbbd901be9582e5e39e3d77acd7b66bb7fbe"
|
||||
|
@ -489,6 +631,15 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
||||
|
||||
"@types/styled-components@^5.1.14":
|
||||
version "5.1.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.14.tgz#e9cf8cdb5eef9d139628183a84c083f630635d67"
|
||||
integrity sha512-d6P1/tyNytqKwam3cQXq7a9uPtovc/mdAs7dBiz1YbDdNIT3X4WmuFU78YdSYh84TXVuhOwezZ3EeKuNBhwsHQ==
|
||||
dependencies:
|
||||
"@types/hoist-non-react-statics" "*"
|
||||
"@types/react" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/tailwindcss@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/tailwindcss/-/tailwindcss-2.2.1.tgz#891349cc71b5a85208ca5796938d91dd48cc0417"
|
||||
|
@ -669,6 +820,21 @@ autoprefixer@^9:
|
|||
postcss "^7.0.32"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
"babel-plugin-styled-components@>= 1.12.0":
|
||||
version "1.13.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.2.tgz#ebe0e6deff51d7f93fceda1819e9b96aeb88278d"
|
||||
integrity sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.0.0"
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
babel-plugin-syntax-jsx "^6.18.0"
|
||||
lodash "^4.17.11"
|
||||
|
||||
babel-plugin-syntax-jsx@^6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||
integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
|
@ -897,6 +1063,11 @@ camelcase@^6.2.0:
|
|||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
|
||||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||
|
||||
camelize@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b"
|
||||
integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
|
||||
|
||||
caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001248:
|
||||
version "1.0.30001251"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz#6853a606ec50893115db660f82c094d18f096d85"
|
||||
|
@ -1215,11 +1386,25 @@ crypto-random-string@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
|
||||
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
|
||||
|
||||
css-color-keywords@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
|
||||
integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
|
||||
|
||||
css-color-names@^0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
|
||||
integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
|
||||
|
||||
css-to-react-native@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756"
|
||||
integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
|
||||
dependencies:
|
||||
camelize "^1.0.0"
|
||||
css-color-keywords "^1.0.0"
|
||||
postcss-value-parser "^4.0.2"
|
||||
|
||||
css-unit-converter@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
|
||||
|
@ -2010,7 +2195,7 @@ history@^4.9.0:
|
|||
tiny-warning "^1.0.0"
|
||||
value-equal "^1.0.1"
|
||||
|
||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2:
|
||||
hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||
|
@ -2492,7 +2677,7 @@ lodash.topath@^4.5.2:
|
|||
resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009"
|
||||
integrity sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=
|
||||
|
||||
lodash@^4.17.21:
|
||||
lodash@^4.17.11, lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
@ -2654,11 +2839,6 @@ mini-create-react-context@^0.4.0:
|
|||
"@babel/runtime" "^7.12.1"
|
||||
tiny-warning "^1.0.3"
|
||||
|
||||
mini-svg-data-uri@^1.2.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.3.3.tgz#91d2c09f45e056e5e1043340b8b37ba7b50f4fac"
|
||||
integrity sha512-+fA2oRcR1dJI/7ITmeQJDrYWks0wodlOz0pAEhKYJ2IVc1z0AnwJUsKY2fzFmPAM3Jo9J0rBx8JAA9QQSJ5PuA==
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
|
@ -3148,7 +3328,7 @@ postcss-value-parser@^3.3.0:
|
|||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
|
||||
integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
|
||||
|
||||
postcss-value-parser@^4.1.0:
|
||||
postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
|
||||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
|
||||
|
@ -3354,6 +3534,11 @@ react-router@5.2.0:
|
|||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-table@^7.7.0:
|
||||
version "7.7.0"
|
||||
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.7.0.tgz#e2ce14d7fe3a559f7444e9ecfe8231ea8373f912"
|
||||
integrity sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==
|
||||
|
||||
react@^17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||
|
@ -3669,6 +3854,11 @@ set-blocking@~2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||
|
||||
shallowequal@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||
|
||||
sharp@0.28.3:
|
||||
version "0.28.3"
|
||||
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.28.3.tgz#ecd74cefd020bee4891bb137c9850ee2ce277a8b"
|
||||
|
@ -3947,12 +4137,28 @@ strtok3@^6.0.3:
|
|||
"@tokenizer/token" "^0.3.0"
|
||||
peek-readable "^4.0.1"
|
||||
|
||||
styled-components@^5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.1.tgz#8a86dcd31bff7049c2ed408bae36fa23f03f071a"
|
||||
integrity sha512-JThv2JRzyH0NOIURrk9iskdxMSAAtCfj/b2Sf1WJaCUsloQkblepy1jaCLX/bYE+mhYo3unmwVSI9I5d9ncSiQ==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@babel/traverse" "^7.4.5"
|
||||
"@emotion/is-prop-valid" "^0.8.8"
|
||||
"@emotion/stylis" "^0.8.4"
|
||||
"@emotion/unitless" "^0.7.4"
|
||||
babel-plugin-styled-components ">= 1.12.0"
|
||||
css-to-react-native "^3.0.0"
|
||||
hoist-non-react-statics "^3.0.0"
|
||||
shallowequal "^1.1.0"
|
||||
supports-color "^5.5.0"
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
||||
|
||||
supports-color@^5.3.0:
|
||||
supports-color@^5.3.0, supports-color@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
|
|
Loading…
Reference in a new issue