Merge branch 'landing-preview'

This commit is contained in:
Jamie Pine
2022-04-26 18:15:48 -07:00
21 changed files with 174 additions and 46 deletions

View File

@@ -21,12 +21,4 @@ declare module '*.md' {
// When "Mode.React" is requested. VFC could take a generic like React.VFC<{ MyComponent: TypeOfMyComponent }>
import React from 'react';
const ReactComponent: React.VFC;
// When "Mode.Vue" is requested
import { ComponentOptions, Component } from 'vue';
const VueComponent: ComponentOptions;
const VueComponentWith: (components: Record<string, Component>) => ComponentOptions;
// Modify below per your usage
export { attributes, toc, html, ReactComponent, VueComponent, VueComponentWith };
}

View File

@@ -8,6 +8,8 @@
"serve": "vite preview"
},
"dependencies": {
"@fontsource/inter": "^4.5.7",
"@headlessui/react": "^1.5.0",
"@heroicons/react": "^1.0.6",
"@icons-pack/react-simple-icons": "^4.6.1",
"@sd/client": "workspace:*",
@@ -23,6 +25,7 @@
"phosphor-react": "^1.4.1",
"prismjs": "^1.28.0",
"react": "^18.0.0",
"react-device-detect": "^2.2.2",
"react-dom": "^18.0.0",
"react-helmet": "^6.1.0",
"react-router-dom": "6.3.0",

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1,49 @@
import clsx from 'clsx';
import React, { useState } from 'react';
import { useEffect } from 'react';
import { isMobile } from 'react-device-detect';
export default function AppEmbed() {
const [showApp, setShowApp] = useState(false);
const [iFrameAppReady, setIframeAppReady] = useState(false);
const [imgFallback, setImageFallback] = useState(false);
function handleEvent(e: any) {
if (e.data === 'spacedrive-hello') {
if (!iFrameAppReady && !isMobile) setIframeAppReady(true);
}
}
useEffect(() => {
window.addEventListener('message', handleEvent, false);
setShowApp(true);
return () => window.removeEventListener('message', handleEvent);
}, []);
useEffect(() => {
setTimeout(() => {
if (!iFrameAppReady) setImageFallback(true);
}, 1000);
}, []);
return (
<div className="w-screen ">
<div className="relative z-30 h-[300px] lg:h-[628px] mt-16 overflow-hidden ">
{imgFallback && <div className="h-full fade-in-image landing-img" />}
{showApp && (
<iframe
referrerPolicy="origin-when-cross-origin"
className={clsx(
'opacity-0 pointer-events-none absolute w-[1200px] h-[300px] lg:h-[628px] z-30 border rounded-lg shadow-2xl inset-center bg-gray-850 border-gray-550',
iFrameAppReady && 'fade-in-image !opacity-100 !pointer-events-auto'
)}
src={`${
import.meta.env.VITE_SDWEB_BASE_URL || 'http://localhost:8002'
}?library_id=9068c6ec-cf90-451b-bb30-4174781e7bc6`}
/>
)}
</div>
</div>
);
}

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import { Button } from '@sd/ui';
import { Bubbles } from '../components/Bubbles';
@@ -7,6 +7,7 @@ import { Footer } from '../components/Footer';
import { Apple, Github, Linux, Windows } from '@icons-pack/react-simple-icons';
import { useState } from 'react';
import clsx from 'clsx';
import AppEmbed from '../components/AppEmbed';
interface SectionProps {
orientation: 'left' | 'right';
@@ -40,7 +41,18 @@ function Section(props: SectionProps = { orientation: 'left' }) {
}
function Page() {
const [showApp, setShowApp] = useState(false);
// const [appLoaded, setAppLoaded] = useState(false);
// function handleResize(event: Event) {
// if (window.innerWidth > 1000) setShowApp(true);
// else if (showApp) setShowApp(false);
// }
// useEffect(() => {
// window.addEventListener('resize', handleResize);
// return () => window.removeEventListener('resize', handleResize);
// }, []);
return (
<>
<div className="mt-28 lg:mt-36" />
@@ -85,21 +97,7 @@ function Page() {
Shortly after to iOS & Android.
</p>
<div className="h-[300px] lg:h-[600px] mt-16 w-screen max-w-[100vw] relative overflow-hidden relative">
<iframe
className={clsx(
'absolute w-[1200px] h-[300px] lg:h-[600px] z-30 border rounded-lg shadow-2xl inset-center bg-gray-850 border-gray-550',
showApp ? 'opacity-100' : 'opacity-0'
)}
onLoad={(event) => {
setShowApp(true);
}}
src={`${
import.meta.env.VITE_SDWEB_BASE_URL || 'http://localhost:8002'
}?library_id=9068c6ec-cf90-451b-bb30-4174781e7bc6`}
/>
<div className="w-[800px] ml-[230px] md:ml-[100px] lg:ml-0 lg:w-[1200px] h-[300px] lg:h-[600px] inset-center absolute z-20 landing-img" />
</div>
<AppEmbed />
<Section
orientation="right"
heading="Never leave a file behind."

View File

@@ -8,6 +8,7 @@
"preview": "vite preview"
},
"dependencies": {
"@fontsource/inter": "^4.5.7",
"@sd/client": "*",
"@sd/core": "*",
"@sd/interface": "*",

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import SpacedriveInterface from '@sd/interface';
import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core';
@@ -64,6 +64,10 @@ class Transport extends BaseTransport {
}
function App() {
useEffect(() => {
window.parent.postMessage('spacedrive-hello', '*');
}, []);
return (
<div className="App">
{/* <header className="App-header"></header> */}

View File

@@ -12,6 +12,7 @@
},
"dependencies": {
"@apollo/client": "^3.5.10",
"@fontsource/inter": "^4.5.7",
"@headlessui/react": "^1.5.0",
"@heroicons/react": "^1.0.6",
"@radix-ui/react-dialog": "^0.1.7",

View File

@@ -28,6 +28,9 @@ import { CoreEvent } from '@sd/core';
import clsx from 'clsx';
import './style.scss';
import { ContentScreen } from './screens/Content';
import LibrarySettings from './screens/settings/LibrarySettings';
import '@fontsource/inter/variable.css';
const queryClient = new QueryClient();
@@ -92,9 +95,12 @@ function SettingsRoutes({ modal = false }) {
<Route path="security" element={<SecuritySettings />} />
<Route path="appearance" element={<></>} />
<Route path="locations" element={<LocationSettings />} />
<Route path="library" element={<LibrarySettings />} />
<Route path="media" element={<></>} />
<Route path="keys" element={<></>} />
<Route path="tags" element={<></>} />
<Route path="sync" element={<></>} />
<Route path="contacts" element={<></>} />
</Route>
</Routes>
</SlideUp>

View File

@@ -78,8 +78,9 @@ export function Device(props: DeviceProps) {
{/* <hr className="border-gray-700" />
<hr className="border-gray-550" /> */}
<div className="px-4 pb-3 mt-3">
{props.locations.map((location) => (
{props.locations.map((location, key) => (
<FileItem
key={key}
selected={selectedFile == location.name}
onClick={() => handleSelect(location.name)}
fileName={location.name}

View File

@@ -21,7 +21,7 @@ export const SidebarLink = (props: NavLinkProps & { children: React.ReactNode })
{({ isActive }) => (
<span
className={clsx(
'max-w mb-[2px] text-gray-550 dark:text-gray-150 rounded px-2 py-1 flex flex-row flex-grow items-center hover:bg-gray-100 dark:hover:bg-gray-600 text-sm',
'max-w mb-[2px] text-gray-550 dark:text-gray-150 rounded px-2 py-1 flex flex-row flex-grow items-center font-medium hover:bg-gray-100 dark:hover:bg-gray-600 text-sm',
{ '!bg-primary !text-white hover:bg-primary dark:hover:bg-primary': isActive },
props.className
)}
@@ -81,7 +81,7 @@ export const Sidebar: React.FC<SidebarProps> = (props) => {
<Dropdown
buttonProps={{
justifyLeft: true,
className: `flex w-full text-left max-w-full mb-1 mt-1 shadow-xs rounded
className: `flex w-full text-left max-w-full mb-1 mt-1 -mr-0.5 shadow-xs rounded
!bg-gray-50
border-gray-150
hover:!bg-gray-1000

View File

@@ -12,7 +12,10 @@ interface InputContainerProps extends DefaultProps {
export const InputContainer: React.FC<InputContainerProps> = (props) => {
return (
<div className="flex flex-row">
<div className={clsx('flex flex-col w-full pb-6', props.className)} {...props}>
<div
className={clsx('flex flex-col w-full', !props.mini && 'pb-6', props.className)}
{...props}
>
<h3 className="mb-1 font-medium text-gray-700 dark:text-gray-100">{props.title}</h3>
{!!props.description && <p className="mb-2 text-sm text-gray-400 ">{props.description}</p>}
{!props.mini && props.children}

View File

@@ -33,8 +33,8 @@ export const OverviewScreen: React.FC<{}> = (props) => {
<div className="flex flex-col w-full h-screen overflow-x-hidden overflow-y-scroll no-scrollbar">
<div data-tauri-drag-region className="flex flex-shrink-0 w-full h-7" />
<div className="flex flex-col w-full h-screen px-3">
<div className="flex items-center w-full ml-4">
<div className="flex flex-wrap p-2 space-x-6">
<div className="flex items-center w-full">
<div className="flex flex-wrap pb-4 space-x-6">
<StatItem name="Total capacity" value="26.5" unit="TB" />
<StatItem name="Index size" value="103" unit="MB" />
<StatItem name="Preview media" value="23.5" unit="GB" />
@@ -43,7 +43,7 @@ export const OverviewScreen: React.FC<{}> = (props) => {
<StatItem name="Total backed up" value="25.3" unit="TB" />
</div>
</div>
<div className="mt-5" />
{/* <div className="mt-5" /> */}
<div className="flex flex-col pb-4 space-y-4">
<Device
name="James' MBP"

View File

@@ -6,11 +6,11 @@ import {
PhotographIcon,
TagIcon,
UsersIcon
} from '@heroicons/react/solid';
} from '@heroicons/react/outline';
import React from 'react';
// import { dummyIFile, FileList } from '../components/file/FileList';
import { SidebarLink } from '../components/file/Sidebar';
import { HardDrive, PaintBrush } from 'phosphor-react';
import { Book, Database, HardDrive, PaintBrush } from 'phosphor-react';
import clsx from 'clsx';
import { Outlet } from 'react-router-dom';
@@ -47,14 +47,15 @@ export const SettingsScreen: React.FC<{}> = () => {
</SidebarLink>
<Heading>Library</Heading>
<SidebarLink to="/settings/library">
<Icon component={Database} />
Database
</SidebarLink>
<SidebarLink to="/settings/locations">
<Icon component={HardDrive} />
Locations
</SidebarLink>
<SidebarLink to="/settings/media">
<Icon component={PhotographIcon} />
Media
</SidebarLink>
<SidebarLink to="/settings/keys">
<Icon component={KeyIcon} />
Keys

View File

@@ -48,10 +48,7 @@ export default function GeneralSettings() {
</div>
</InputContainer> */}
<InputContainer
title="Locations"
description="Local cache storage for media previews and thumbnails."
>
<InputContainer title="Volumes" description="A list of volumes running on this device.">
<div className="flex flex-row space-x-2">
<div className="flex flex-grow">
<Listbox

View File

@@ -0,0 +1,31 @@
import React from 'react';
import { Button } from '@sd/ui';
import { InputContainer } from '../../components/primitive/InputContainer';
import { Toggle } from '../../components/primitive';
type LibrarySecurity = 'public' | 'password' | 'vault';
export default function LibrarySettings() {
// const locations = useBridgeQuery("SysGetLocation")
return (
<div className="flex flex-col flex-grow max-w-4xl space-y-4">
{/*<Button size="sm">Add Location</Button>*/}
<div className="mt-3 mb-3">
<h1 className="text-2xl font-bold">Library database</h1>
<p className="mt-1 text-sm text-gray-400">
The database contains all library data and file metadata.
</p>
</div>
<InputContainer
mini
title="Encrypt on cloud"
description="Enable if library contains sensitive data and should not be synced to the cloud without full encryption."
>
<div className="flex items-center h-full">
<Toggle initialState={true} size={'sm'} />
</div>
</InputContainer>
</div>
);
}

View File

@@ -6,8 +6,8 @@ export default function SecuritySettings() {
return (
<div className="space-y-4">
<InputContainer
title="Something about a vault"
description="Local cache storage for media previews and thumbnails."
title="Vault"
description="You'll need to set a passphrase to enable the vault."
>
<div className="flex flex-row">
<Button variant="primary">Enable Vault</Button>

View File

@@ -3,7 +3,7 @@ button {
@apply cursor-default;
}
body { font-family: "InterVariable", sans-serif; }
.no-scrollbar {
-ms-overflow-style: none; /* for Internet Explorer, Edge */

View File

@@ -22,4 +22,38 @@
background-image: url('/app.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.fade-in-image {
animation: fadeIn 1s;
-webkit-animation: fadeIn 1s;
-moz-animation: fadeIn 1s;
-o-animation: fadeIn 1s;
-ms-animation: fadeIn 1s;
}
@keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
}
@-moz-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
}
@-webkit-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
}
@-o-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
}
@-ms-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
}

View File

@@ -11,6 +11,13 @@ module.exports = function (app, options) {
darkMode: app == 'landing' ? 'class' : 'class',
mode: 'jit',
theme: {
// fontFamily: {
// sans: ['Inter', 'ui-sans-serif', 'system-ui'],
// serif: ['Inter', 'ui-serif', 'Georgia'],
// mono: ['ui-monospace', 'SFMono-Regular'],
// display: ['Inter'],
// body: ['"Inter"']
// },
fontSize: {
'tiny': '.65rem',
'xs': '.75rem',

BIN
pnpm-lock.yaml generated
View File

Binary file not shown.