mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-02 11:13:29 +00:00
Tailwind Prettier Plugin (#557)
* add tailwind prettier plugin + run prettier * add eslint tailwind plugin and eslint fix to turbo * Ran eslint fix + fixed every other lint issues * twStyle and lint stuff * remove auto lint as it's buggy * update eslint & add twStyle to tailwind regex * Fix auto lint + config inconsistencies * Add tailwind config to prettier config * run lint:fix --------- Co-authored-by: Brendan Allan <brendonovich@outlook.com>
This commit is contained in:
parent
a9fceae819
commit
b856f15b22
|
@ -1,84 +1,84 @@
|
|||
pnpm
|
||||
titlebar
|
||||
consts
|
||||
pallete
|
||||
unlisten
|
||||
svgr
|
||||
middlewares
|
||||
clsx
|
||||
SDWEB
|
||||
tryghost
|
||||
tsparticles
|
||||
Opencollective
|
||||
Waitlist
|
||||
heroicons
|
||||
roadmap
|
||||
semibold
|
||||
noreferer
|
||||
Rescan
|
||||
subpackage
|
||||
photoslibrary
|
||||
fontsource
|
||||
audiomp
|
||||
audioogg
|
||||
audiowav
|
||||
browserslist
|
||||
bsconfig
|
||||
cheader
|
||||
classname
|
||||
clsx
|
||||
compodoc
|
||||
consts
|
||||
cssmap
|
||||
dartlang
|
||||
dockerdebug
|
||||
falsey
|
||||
folderlight
|
||||
folderopen
|
||||
fontotf
|
||||
fontsource
|
||||
fontttf
|
||||
fontwoff
|
||||
gopackage
|
||||
haml
|
||||
headlessui
|
||||
heroicons
|
||||
imagegif
|
||||
imageico
|
||||
imagejpg
|
||||
imagepng
|
||||
imagewebp
|
||||
immer
|
||||
ipynb
|
||||
jsmap
|
||||
lacie
|
||||
lighteditorconfig
|
||||
nestjscontroller
|
||||
middlewares
|
||||
moti
|
||||
nestjs
|
||||
nestjscontroller
|
||||
nestjsdecorator
|
||||
nestjsfilter
|
||||
nestjsguard
|
||||
nestjsmodule
|
||||
nestjsservice
|
||||
noreferer
|
||||
npmlock
|
||||
nums
|
||||
nuxt
|
||||
Opencollective
|
||||
opengl
|
||||
overscan
|
||||
pallete
|
||||
photoshop
|
||||
photoslibrary
|
||||
pnpm
|
||||
postcssconfig
|
||||
powershelldata
|
||||
reactjs
|
||||
rjson
|
||||
symfony
|
||||
testjs
|
||||
tmpl
|
||||
typescriptdef
|
||||
windi
|
||||
yarnerror
|
||||
unlisten
|
||||
imagewebp
|
||||
powershellmodule
|
||||
pressable
|
||||
reactjs
|
||||
reactts
|
||||
testts
|
||||
zustand
|
||||
overscan
|
||||
webp
|
||||
headlessui
|
||||
falsey
|
||||
nums
|
||||
lacie
|
||||
classname
|
||||
wunsub
|
||||
immer
|
||||
Rescan
|
||||
rjson
|
||||
roadmap
|
||||
SDWEB
|
||||
semibold
|
||||
subpackage
|
||||
svgr
|
||||
swipeable
|
||||
symfony
|
||||
tada
|
||||
moti
|
||||
pressable
|
||||
testjs
|
||||
testts
|
||||
titlebar
|
||||
tmpl
|
||||
tryghost
|
||||
tsparticles
|
||||
typescriptdef
|
||||
unlisten
|
||||
Waitlist
|
||||
webp
|
||||
windi
|
||||
wunsub
|
||||
yarnerror
|
||||
zustand
|
||||
|
|
|
@ -21,6 +21,7 @@ module.exports = {
|
|||
],
|
||||
importOrderSortSpecifiers: true,
|
||||
importOrderParserPlugins: ['importAssertions', 'typescript', 'jsx'],
|
||||
pluginSearchDirs: ['.'],
|
||||
plugins: ['@trivago/prettier-plugin-sort-imports']
|
||||
pluginSearchDirs: false,
|
||||
plugins: ['@trivago/prettier-plugin-sort-imports', 'prettier-plugin-tailwindcss'],
|
||||
tailwindConfig: 'packages/ui/tailwind.config.js'
|
||||
};
|
||||
|
|
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
|
@ -2,6 +2,7 @@
|
|||
"cSpell.words": [
|
||||
"actix",
|
||||
"bpfrpt",
|
||||
"callees",
|
||||
"consts",
|
||||
"countup",
|
||||
"creationdate",
|
||||
|
@ -41,7 +42,8 @@
|
|||
"tw`([^`]*)",
|
||||
"tw\\.[^`]+`([^`]*)`",
|
||||
"tw\\(.*?\\).*?`([^`]*)",
|
||||
"tw\\.style\\(([^)]*)\\)"
|
||||
"tw\\.style\\(([^)]*)\\)",
|
||||
"twStyle\\(([^)]*)\\)"
|
||||
],
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
|
@ -50,5 +52,12 @@
|
|||
// Hiding these folders bcs they create a lot of noise in the search results
|
||||
"apps/mobile/android": true,
|
||||
"apps/mobile/ios": true
|
||||
}
|
||||
},
|
||||
"eslint.workingDirectories": [
|
||||
"apps/landing",
|
||||
"apps/mobile",
|
||||
"packages/ui",
|
||||
"packages/client",
|
||||
"packages/interface"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ export default function App({
|
|||
|
||||
<>
|
||||
<NavBar />
|
||||
<div className="dark dark:bg-black dark:text-white z-10 max-w-[100rem] m-auto">
|
||||
<div className="dark z-10 m-auto max-w-[100rem] dark:bg-black dark:text-white">
|
||||
{children}
|
||||
</div>
|
||||
<Footer />
|
||||
|
|
|
@ -59,18 +59,18 @@ const AppEmbed = () => {
|
|||
return (
|
||||
<div className="w-screen">
|
||||
{renderBloom && (
|
||||
<div className="relative max-w-full sm:w-full sm:max-w-[1400px] mx-auto">
|
||||
<div className="relative mx-auto max-w-full sm:w-full sm:max-w-[1400px]">
|
||||
<div className="bloom burst bloom-one" />
|
||||
<div className="bloom burst bloom-three" />
|
||||
<div className="bloom burst bloom-two" />
|
||||
</div>
|
||||
)}
|
||||
<div className="relative z-30 h-[255px] px-1 sm:h-[428px] md:h-[428px] lg:h-[628px] mt-8 sm:mt-16">
|
||||
<div className="relative z-30 mt-8 h-[255px] px-1 sm:mt-16 sm:h-[428px] md:h-[428px] lg:h-[628px]">
|
||||
<div
|
||||
className={clsx(
|
||||
'relative h-full m-auto border rounded-lg max-w-7xl transition-opacity border-gray-550 opacity-0',
|
||||
'border-gray-550 relative m-auto h-full max-w-7xl rounded-lg border opacity-0 transition-opacity',
|
||||
renderBloom && '!opacity-100',
|
||||
renderImage && 'bg-transparent border-none'
|
||||
renderImage && 'border-none bg-transparent'
|
||||
)}
|
||||
>
|
||||
{showApp && !forceImg && (
|
||||
|
@ -78,8 +78,8 @@ const AppEmbed = () => {
|
|||
ref={iFrame}
|
||||
referrerPolicy="origin-when-cross-origin"
|
||||
className={clsx(
|
||||
'w-full h-full z-30 rounded-lg shadow-iframe inset-center bg-gray-850',
|
||||
iFrameAppReady ? 'fade-in-app-embed opacity-100' : 'opacity-0 -ml-[10000px]'
|
||||
'shadow-iframe inset-center bg-gray-850 z-30 h-full w-full rounded-lg',
|
||||
iFrameAppReady ? 'fade-in-app-embed opacity-100' : 'ml-[-10000px] opacity-0'
|
||||
)}
|
||||
src={`${
|
||||
import.meta.env.VITE_SDWEB_BASE_URL || 'http://localhost:8002'
|
||||
|
@ -87,7 +87,7 @@ const AppEmbed = () => {
|
|||
/>
|
||||
)}
|
||||
|
||||
{renderImage && <div className="z-40 h-full w-auto fade-in-app-embed landing-img" />}
|
||||
{renderImage && <div className="fade-in-app-embed landing-img z-40 h-full w-auto" />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -96,7 +96,7 @@ const AppEmbed = () => {
|
|||
|
||||
export const AppEmbedPlaceholder = () => {
|
||||
return (
|
||||
<div className="w-screen relative z-30 h-[228px] px-5 sm:h-[428px] md:h-[428px] lg:h-[628px] mt-8 sm:mt-16" />
|
||||
<div className="relative z-30 mt-8 h-[228px] w-screen px-5 sm:mt-16 sm:h-[428px] md:h-[428px] lg:h-[628px]" />
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ export interface BlogTagProps {
|
|||
export const BlogTag = (props: BlogTagProps) => {
|
||||
return (
|
||||
<span
|
||||
className={`px-2 py-0.5 rounded-md text-gray-500 text-sm bg-gray-550`}
|
||||
className={`bg-gray-550 rounded-md px-2 py-0.5 text-sm text-gray-500`}
|
||||
style={{
|
||||
backgroundColor: props.tag.accent_color + '' ?? '',
|
||||
color: parseInt(props.tag.accent_color?.slice(1) ?? '', 16) > 0xffffff / 2 ? '#000' : '#fff'
|
||||
|
|
|
@ -17,7 +17,7 @@ export default function DocsLayout(props: Props) {
|
|||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-start w-full sm:flex-row">
|
||||
<div className="flex w-full flex-col items-start sm:flex-row">
|
||||
<Menu
|
||||
onClose={() => setMenuOpen(false)}
|
||||
customBurgerIcon={false}
|
||||
|
@ -25,33 +25,33 @@ export default function DocsLayout(props: Props) {
|
|||
pageWrapId="page-container"
|
||||
className="shadow-2xl shadow-black"
|
||||
>
|
||||
<div className="visible h-screen pb-20 overflow-x-hidden custom-scroll doc-sidebar-scroll bg-gray-650 pt-7 px-7 sm:invisible">
|
||||
<div className="custom-scroll doc-sidebar-scroll bg-gray-650 visible h-screen overflow-x-hidden px-7 pb-20 pt-7 sm:invisible">
|
||||
<Button
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
className="!px-1 -ml-0.5 mb-3 !border-none"
|
||||
className="-ml-0.5 mb-3 !border-none !px-1"
|
||||
>
|
||||
<X weight="bold" className="w-6 h-6" />
|
||||
<X weight="bold" className="h-6 w-6" />
|
||||
</Button>
|
||||
<DocsSidebar activePath={props?.doc?.url} navigation={props.navigation} />
|
||||
</div>
|
||||
</Menu>
|
||||
|
||||
<aside className="sticky hidden px-5 mt-32 mb-20 ml-2 mr-0 lg:mr-4 top-32 sm:inline">
|
||||
<aside className="sticky top-32 mt-32 mb-20 ml-2 mr-0 hidden px-5 sm:inline lg:mr-4">
|
||||
<DocsSidebar activePath={props?.doc?.url} navigation={props.navigation} />
|
||||
</aside>
|
||||
<div className="flex flex-col w-full sm:flex-row" id="page-container">
|
||||
<div className="h-12 px-5 flex w-full border-t border-gray-600 border-b mt-[65px] sm:hidden items-center ">
|
||||
<div className="flex w-full flex-col sm:flex-row" id="page-container">
|
||||
<div className="mt-[65px] flex h-12 w-full items-center border-y border-gray-600 px-5 sm:hidden">
|
||||
<div className="flex sm:hidden">
|
||||
<Button onClick={() => setMenuOpen(!menuOpen)} className="!px-2 ml-1 !border-none">
|
||||
<List weight="bold" className="w-6 h-6" />
|
||||
<Button onClick={() => setMenuOpen(!menuOpen)} className="ml-1 !border-none !px-2">
|
||||
<List weight="bold" className="h-6 w-6" />
|
||||
</Button>
|
||||
</div>
|
||||
{props.doc?.url.split('/').map((item, index) => {
|
||||
if (index === 2) return null;
|
||||
return (
|
||||
<div key={index} className="flex flex-row items-center ml-2">
|
||||
<div key={index} className="ml-2 flex flex-row items-center">
|
||||
<a className="px-1 text-sm">{toTitleCase(item)}</a>
|
||||
{index < 1 && <CaretRight className="w-4 h-4 ml-1 -mr-2" />}
|
||||
{index < 1 && <CaretRight className="ml-1 -mr-2 h-4 w-4" />}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -15,13 +15,13 @@ export default function DocsSidebar(props: Props) {
|
|||
const activeSectionData = props.navigation.find((section) => section.slug === activeSection);
|
||||
|
||||
return (
|
||||
<nav className="flex flex-col w-full mr-8 sm:w-52">
|
||||
<nav className="mr-8 flex w-full flex-col sm:w-52">
|
||||
<div onClick={() => alert('Search coming soon...')} className="relative w-full">
|
||||
<MagnifyingGlass weight="bold" className="absolute top-3 left-3" />
|
||||
<Input className="w-full mb-5 pointer-events-none pl-9" placeholder="Search" />
|
||||
<span className="absolute text-sm font-semibold text-gray-400 right-3 top-[9px]">⌘K</span>
|
||||
<Input className="pointer-events-none mb-5 w-full pl-9" placeholder="Search" />
|
||||
<span className="absolute right-3 top-[9px] text-sm font-semibold text-gray-400">⌘K</span>
|
||||
</div>
|
||||
<div className="flex flex-col mb-6">
|
||||
<div className="mb-6 flex flex-col">
|
||||
{props.navigation.map((section) => {
|
||||
const isActive = section.slug === activeSection;
|
||||
const Icon = config.sections.find((s) => s.slug === section.slug)?.icon;
|
||||
|
@ -30,13 +30,13 @@ export default function DocsSidebar(props: Props) {
|
|||
href={`/docs/${section.section[0].category[0].url}`}
|
||||
key={section.slug}
|
||||
className={clsx(
|
||||
`flex font-semibold text-[14px] items-center py-1.5 doc-sidebar-button`,
|
||||
`doc-sidebar-button flex items-center py-1.5 text-[14px] font-semibold`,
|
||||
section.slug,
|
||||
isActive && 'nav-active'
|
||||
)}
|
||||
>
|
||||
<div className={clsx(`p-1 mr-4 bg-gray-500 border-t rounded-lg border-gray-400/20`)}>
|
||||
<Icon weight="bold" className="w-4 h-4 text-white opacity-80" />
|
||||
<div className={clsx(`mr-4 rounded-lg border-t border-gray-400/20 bg-gray-500 p-1`)}>
|
||||
<Icon weight="bold" className="h-4 w-4 text-white opacity-80" />
|
||||
</div>
|
||||
{section.title}
|
||||
</a>
|
||||
|
@ -54,15 +54,15 @@ export default function DocsSidebar(props: Props) {
|
|||
<li
|
||||
className={clsx(
|
||||
'flex border-l border-gray-600',
|
||||
active && 'border-l-2 border-primary'
|
||||
active && 'border-primary border-l-2'
|
||||
)}
|
||||
key={page.title}
|
||||
>
|
||||
<a
|
||||
href={`/docs/${page.url}`}
|
||||
className={clsx(
|
||||
'font-normal w-full rounded px-3 py-1 hover:text-gray-50 no-underline text-[14px] text-gray-350',
|
||||
active && '!text-white !font-medium '
|
||||
'text-gray-350 w-full rounded px-3 py-1 text-[14px] font-normal no-underline hover:text-gray-50',
|
||||
active && '!font-medium !text-white '
|
||||
)}
|
||||
>
|
||||
{page.title}
|
||||
|
|
|
@ -24,16 +24,16 @@ function FooterLink(props: PropsWithChildren<{ link: string; blank?: boolean }>)
|
|||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer id="footer" className="z-50 w-screen pt-3 border-t border-gray-550 bg-gray-850">
|
||||
<div className="max-w-[100rem] mx-auto grid grid-cols-2 gap-6 p-8 pt-10 pb-20 m-auto text-white min-h-64 sm:grid-cols-2 lg:grid-cols-6">
|
||||
<footer id="footer" className="border-gray-550 bg-gray-850 z-50 w-screen border-t pt-3">
|
||||
<div className="min-h-64 m-auto grid max-w-[100rem] grid-cols-2 gap-6 p-8 pt-10 pb-20 text-white sm:grid-cols-2 lg:grid-cols-6">
|
||||
<div className="col-span-2">
|
||||
<img src={AppLogo} className="w-10 h-10 mb-5" />
|
||||
<img src={AppLogo} className="mb-5 h-10 w-10" />
|
||||
|
||||
<h3 className="mb-1 text-xl font-bold">Spacedrive</h3>
|
||||
<p className="text-sm text-gray-350">
|
||||
<p className="text-gray-350 text-sm">
|
||||
© Copyright {new Date().getFullYear()} Spacedrive Technology Inc.
|
||||
</p>
|
||||
<div className="flex flex-row mt-6 mb-10 space-x-3">
|
||||
<div className="mt-6 mb-10 flex flex-row space-x-3">
|
||||
<FooterLink link="https://twitter.com/spacedriveapp">
|
||||
<Twitter />
|
||||
</FooterLink>
|
||||
|
@ -55,7 +55,7 @@ export function Footer() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col col-span-1 space-y-2">
|
||||
<div className="col-span-1 flex flex-col space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase ">About</h3>
|
||||
|
||||
<FooterLink link="/team">Team</FooterLink>
|
||||
|
@ -64,15 +64,15 @@ export function Footer() {
|
|||
<FooterLink link="/docs/changelog/beta/0.1.0">Changelog</FooterLink>
|
||||
<FooterLink link="/blog">Blog</FooterLink>
|
||||
</div>
|
||||
<div className="flex flex-col col-span-1 space-y-2 pointer-events-none">
|
||||
<div className="pointer-events-none col-span-1 flex flex-col space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase">Downloads</h3>
|
||||
<div className="flex flex-col col-span-1 space-y-2 opacity-50">
|
||||
<div className="col-span-1 flex flex-col 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">
|
||||
<div className="col-span-1 flex flex-col space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase ">Developers</h3>
|
||||
<FooterLink blank link="https://github.com/spacedriveapp/spacedrive/tree/main/docs">
|
||||
Documentation
|
||||
|
@ -83,14 +83,14 @@ export function Footer() {
|
|||
>
|
||||
Contribute
|
||||
</FooterLink>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<div className="pointer-events-none opacity-50">
|
||||
<FooterLink link="#">Extensions</FooterLink>
|
||||
</div>
|
||||
<div className="opacity-50 pointer-events-none">
|
||||
<div className="pointer-events-none opacity-50">
|
||||
<FooterLink link="#">Self Host</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col col-span-1 space-y-2">
|
||||
<div className="col-span-1 flex flex-col space-y-2">
|
||||
<h3 className="mb-1 text-xs font-bold uppercase ">Org</h3>
|
||||
<FooterLink blank link="https://opencollective.com/spacedrive">
|
||||
Open Collective
|
||||
|
|
|
@ -81,12 +81,12 @@ export function HomeCTA() {
|
|||
useWorker
|
||||
zIndex={-1}
|
||||
/> */}
|
||||
<div className="z-30 flex flex-row items-center h-10 space-x-4 animation-delay-2 fade-in">
|
||||
<div className="animation-delay-2 fade-in z-30 flex h-10 flex-row items-center space-x-4">
|
||||
{!showWaitlistInput ? (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => setShowWaitlistInput(true)}
|
||||
className="z-30 border-0 cursor-pointer"
|
||||
className="z-30 cursor-pointer border-0"
|
||||
variant="gray"
|
||||
>
|
||||
Join Waitlist
|
||||
|
@ -97,7 +97,7 @@ export function HomeCTA() {
|
|||
className="z-30 cursor-pointer"
|
||||
variant="accent"
|
||||
>
|
||||
<Github className="inline w-5 h-5 -mt-[4px] -ml-1 mr-2" fill="white" />
|
||||
<Github className="mt-[-4px] -ml-1 mr-2 inline h-5 w-5" fill="white" />
|
||||
Star on GitHub
|
||||
</Button>
|
||||
</>
|
||||
|
@ -107,16 +107,16 @@ export function HomeCTA() {
|
|||
{(waitlistError || waitlistSubmitted) && (
|
||||
<div
|
||||
className={clsx({
|
||||
'flex flex-row items-center bg-opacity-20 border-2 my-2 px-2 rounded-md': true,
|
||||
'bg-red-800 border-red-900': waitlistError,
|
||||
'bg-green-800 border-green-900': !waitlistError,
|
||||
'bg-opacity/20 my-2 flex flex-row items-center rounded-md border-2 px-2': true,
|
||||
'border-red-900 bg-red-800': waitlistError,
|
||||
'border-green-900 bg-green-800': !waitlistError,
|
||||
'-mt-2': waitlistSubmitted
|
||||
})}
|
||||
>
|
||||
{waitlistError ? (
|
||||
<Alert className="w-5 mr-1 fill-red-500" />
|
||||
<Alert className="mr-1 w-5 fill-red-500" />
|
||||
) : (
|
||||
<Info className="w-5 mr-1 fill-green-500" />
|
||||
<Info className="mr-1 w-5 fill-green-500" />
|
||||
)}
|
||||
<p
|
||||
className={clsx({
|
||||
|
@ -145,15 +145,15 @@ export function HomeCTA() {
|
|||
{!waitlistSubmitted && (
|
||||
<Button
|
||||
onClick={() => setShowWaitlistInput(true)}
|
||||
className={clsx('z-30 border-0 rounded-l-none cursor-pointer', {
|
||||
'opacity-50 cursor-default': loading
|
||||
className={clsx('z-30 cursor-pointer rounded-l-none border-0', {
|
||||
'cursor-default opacity-50': loading
|
||||
})}
|
||||
disabled={loading}
|
||||
variant="accent"
|
||||
type="submit"
|
||||
>
|
||||
{loading ? (
|
||||
<Spinner className="w-6 h-6 text-white text-opacity-40 animate-spin fill-white" />
|
||||
<Spinner className="h-6 w-6 animate-spin fill-white text-white text-opacity-40" />
|
||||
) : (
|
||||
'Submit'
|
||||
)}
|
||||
|
@ -165,7 +165,7 @@ export function HomeCTA() {
|
|||
)}
|
||||
</div>
|
||||
<p
|
||||
className={clsx('z-30 px-6 text-sm text-center text-gray-450 animation-delay-3 fade-in', {
|
||||
className={clsx('animation-delay-3 fade-in text-gray-450 z-30 px-6 text-center text-sm', {
|
||||
'mt-10': waitlistError,
|
||||
'mt-3': !waitlistError
|
||||
})}
|
||||
|
|
|
@ -16,11 +16,11 @@ function MarkdownPage(props: PropsWithChildren<MarkdownPageProps>) {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<div className={clsx('p-4 mb-10', props.classNames)}>
|
||||
<div className={clsx('mb-10 p-4', props.classNames)}>
|
||||
<article
|
||||
id="content"
|
||||
className={clsx(
|
||||
'prose text-[15px] sm:text-[16px] prose-img:rounded prose-code:text-gray-400 prose-code:font-normal prose-code:before:hidden prose-code:p-1 prose-code:bg-gray-650 prose-code:rounded-md prose-code:after:hidden prose-h1:text-[3.25em] prose-blockquote:bg-gray-600 prose-blockquote:rounded prose-a:text-primary prose-a:no-underline lg:prose-xs dark:prose-invert prose-td:p-2 prose-th:p-2 prose-td:border-l prose-td:border-gray-500 prose-td:last:border-r prose-table:border-b prose-table:border-gray-500 prose-tr:even:bg-gray-700',
|
||||
'lg:prose-xs prose prose-h1:text-[3.25em] prose-a:text-primary prose-a:no-underline prose-blockquote:rounded prose-blockquote:bg-gray-600 prose-code:rounded-md prose-code:bg-gray-650 prose-code:p-1 prose-code:font-normal prose-code:text-gray-400 prose-code:before:hidden prose-code:after:hidden prose-table:border-b prose-table:border-gray-500 prose-tr:even:bg-gray-700 prose-th:p-2 prose-td:border-l prose-td:border-gray-500 prose-td:p-2 prose-td:last:border-r prose-img:rounded dark:prose-invert text-[15px] sm:text-[16px]',
|
||||
props.articleClassNames
|
||||
)}
|
||||
>
|
||||
|
|
|
@ -13,7 +13,7 @@ function NavLink(props: PropsWithChildren<{ link?: string }>) {
|
|||
<a
|
||||
href={props.link ?? '#'}
|
||||
target={props.link?.startsWith('http') ? '_blank' : undefined}
|
||||
className="p-4 text-gray-300 no-underline transition cursor-pointer hover:text-gray-50"
|
||||
className="cursor-pointer p-4 text-gray-300 no-underline transition hover:text-gray-50"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{props.children}
|
||||
|
@ -52,19 +52,19 @@ export default function NavBar() {
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'fixed transition px-2 z-[55] w-full h-16 border-b ',
|
||||
'fixed z-[55] h-16 w-full border-b px-2 transition ',
|
||||
isAtTop
|
||||
? 'bg-transparent border-transparent'
|
||||
: 'border-gray-550 bg-gray-700 bg-opacity-80 backdrop-blur'
|
||||
? 'border-transparent bg-transparent'
|
||||
: 'bg-opacity/80 border-gray-550 bg-gray-700 backdrop-blur'
|
||||
)}
|
||||
>
|
||||
<div className="relative flex max-w-[100rem] mx-auto items-center h-full m-auto p-5">
|
||||
<div className="relative m-auto flex h-full max-w-[100rem] items-center p-5">
|
||||
<a href="/" className="absolute flex flex-row items-center">
|
||||
<img src={AppLogo} className="z-30 w-8 h-8 mr-3" />
|
||||
<img src={AppLogo} className="z-30 mr-3 h-8 w-8" />
|
||||
<h3 className="text-xl font-bold text-white">Spacedrive</h3>
|
||||
</a>
|
||||
|
||||
<div className="hidden m-auto space-x-4 text-white lg:block ">
|
||||
<div className="m-auto hidden space-x-4 text-white lg:block ">
|
||||
<NavLink link="/roadmap">Roadmap</NavLink>
|
||||
<NavLink link="/team">Team</NavLink>
|
||||
<NavLink link="/blog">Blog</NavLink>
|
||||
|
@ -72,7 +72,7 @@ export default function NavBar() {
|
|||
<div className="relative inline">
|
||||
<NavLink link="/careers">Careers</NavLink>
|
||||
{positions.length > 0 ? (
|
||||
<span className="absolute bg-opacity-80 px-[5px] text-xs rounded-md bg-primary -top-1 -right-2">
|
||||
<span className="bg-opacity/80 bg-primary absolute -top-1 -right-2 rounded-md px-[5px] text-xs">
|
||||
{` ${positions.length} `}
|
||||
</span>
|
||||
) : null}
|
||||
|
@ -82,10 +82,10 @@ export default function NavBar() {
|
|||
<Dropdown.Root
|
||||
button={
|
||||
<Button className="ml-[140px] hover:!bg-transparent" size="icon">
|
||||
<DotsThreeVertical weight="bold" className="w-6 h-6 " />
|
||||
<DotsThreeVertical weight="bold" className="h-6 w-6 " />
|
||||
</Button>
|
||||
}
|
||||
className="block h-6 text-white w-44 top-2 right-4 lg:hidden"
|
||||
className="top-2 right-4 block h-6 w-44 text-white lg:hidden"
|
||||
itemsClassName="!rounded-2xl shadow-2xl shadow-black p-2 !bg-gray-850 mt-2 !border-gray-500 text-[15px]"
|
||||
>
|
||||
<Dropdown.Section>
|
||||
|
@ -118,7 +118,7 @@ export default function NavBar() {
|
|||
</Dropdown.Section>
|
||||
</Dropdown.Root>
|
||||
|
||||
<div className="absolute flex-row hidden space-x-5 right-3 lg:flex">
|
||||
<div className="absolute right-3 hidden flex-row space-x-5 lg:flex">
|
||||
<a href="https://discord.gg/gTaF2Z44f5" target="_blank" rel="noreferrer">
|
||||
<Discord className="text-white" />
|
||||
</a>
|
||||
|
|
|
@ -10,13 +10,13 @@ const NewBanner: React.FC<NewBannerProps> = (props) => {
|
|||
return (
|
||||
<aside
|
||||
onClick={() => (window.location.href = href)}
|
||||
className="z-10 text-xs w-10/12 cursor-pointer sm:w-auto sm:text-base fade-in-whats-new px-5 py-1.5 bg-opacity-50 mb-5 flex flex-row bg-gray-800 hover:bg-gray-750 border border-gray-600 hover:border-gray-550 rounded-full transition"
|
||||
className="fade-in-whats-new bg-opacity/50 hover:border-gray-550 hover:bg-gray-750 z-10 mb-5 flex w-10/12 cursor-pointer flex-row rounded-full border border-gray-600 bg-gray-800 px-5 py-1.5 text-xs transition sm:w-auto sm:text-base"
|
||||
>
|
||||
<strong className="font-semibold truncate text-gray-350">{headline}</strong>
|
||||
<div role="separator" className="w-[1px] mx-4 h-22 bg-gray-500" />
|
||||
<strong className="text-gray-350 truncate font-semibold">{headline}</strong>
|
||||
<div role="separator" className="h-22 mx-4 w-[1px] bg-gray-500" />
|
||||
<a
|
||||
href={href}
|
||||
className="flex-shrink-0 text-transparent font-regular bg-clip-text bg-gradient-to-r from-primary-400 to-blue-600 decoration-primary-600"
|
||||
className="font-regular from-primary-400 decoration-primary-600 shrink-0 bg-gradient-to-r to-blue-600 bg-clip-text text-transparent"
|
||||
>
|
||||
{link} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
|
|
|
@ -52,9 +52,9 @@ export function TeamMember(props: TeamMemberProps) {
|
|||
alt={`Portrait of ${props.name}`}
|
||||
width={size}
|
||||
height={size}
|
||||
className={clsx('inline-flex m-0 rounded-md', {
|
||||
'w-32 h-32 !xs:w-36 !xs:h-36 !sm:w-40 !sm:h-40': !props.investmentRound,
|
||||
'lg:w-28 lg:h-28': props.investmentRound
|
||||
className={clsx('m-0 inline-flex rounded-md', {
|
||||
'!xs:w-36 !xs:h-36 !sm:w-40 !sm:h-40 h-32 w-32': !props.investmentRound,
|
||||
'lg:h-28 lg:w-28': props.investmentRound
|
||||
})}
|
||||
/>
|
||||
<h3 className="mt-4 mb-0 text-base">{props.name}</h3>
|
||||
|
@ -66,27 +66,27 @@ export function TeamMember(props: TeamMemberProps) {
|
|||
{props.role}
|
||||
</p>
|
||||
{props.investmentRound && (
|
||||
<p className="mt-0 mb-0 text-sm font-semibold text-gray-450">{props.investmentRound}</p>
|
||||
<p className="text-gray-450 my-0 text-sm font-semibold">{props.investmentRound}</p>
|
||||
)}
|
||||
<div className="flex flex-row mt-auto space-x-2">
|
||||
<div className="mt-auto flex flex-row space-x-2">
|
||||
{props.socials?.twitter && (
|
||||
<Link href={props.socials.twitter}>
|
||||
<Twitter className="w-[20px] h-[20px]" />
|
||||
<Twitter className="h-[20px] w-[20px]" />
|
||||
</Link>
|
||||
)}
|
||||
{props.socials?.github && (
|
||||
<Link href={props.socials.github}>
|
||||
<Github className="w-[20px] h-[20px]" />
|
||||
<Github className="h-[20px] w-[20px]" />
|
||||
</Link>
|
||||
)}
|
||||
{props.socials?.twitch && (
|
||||
<Link href={props.socials.twitch}>
|
||||
<Twitch className="w-[20px] h-[20px]" />
|
||||
<Twitch className="h-[20px] w-[20px]" />
|
||||
</Link>
|
||||
)}
|
||||
{props.socials?.dribbble && (
|
||||
<Link href={props.socials.dribbble}>
|
||||
<Dribbble className="w-[20px] h-[20px]" />
|
||||
<Dribbble className="h-[20px] w-[20px]" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -13,16 +13,16 @@ function Page({ posts }: { posts: PostOrPage[] }) {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="container flex flex-col max-w-4xl gap-20 p-4 pt-32 m-auto mb-20 prose lg:prose-xs dark:prose-invert">
|
||||
<div className="lg:prose-xs prose dark:prose-invert container m-auto mb-20 flex max-w-4xl flex-col gap-20 p-4 pt-32">
|
||||
<Helmet>
|
||||
<title>Spacedrive Blog</title>
|
||||
<meta name="description" content="Get the latest from Spacedrive." />
|
||||
</Helmet>
|
||||
<section>
|
||||
<h1 className="m-0 fade-in-heading">Blog</h1>
|
||||
<h1 className="fade-in-heading m-0">Blog</h1>
|
||||
<p className="fade-in-heading animation-delay-1">Get the latest from Spacedrive.</p>
|
||||
</section>
|
||||
<section className="grid grid-cols-1 gap-4 sm:grid-cols-1 lg:grid-cols-1 fade-in will-change-transform animation-delay-2">
|
||||
<section className="fade-in animation-delay-2 grid grid-cols-1 gap-4 will-change-transform sm:grid-cols-1 lg:grid-cols-1">
|
||||
{posts.map((post) => {
|
||||
return (
|
||||
<div
|
||||
|
@ -30,24 +30,24 @@ function Page({ posts }: { posts: PostOrPage[] }) {
|
|||
onClick={() => {
|
||||
window.location.href = `/blog/${post.slug}`;
|
||||
}}
|
||||
className="relative z-0 flex flex-col gap-2 mb-8 overflow-hidden transition-colors border border-gray-500 cursor-pointer rounded-xl"
|
||||
className="relative z-0 mb-8 flex cursor-pointer flex-col gap-2 overflow-hidden rounded-xl border border-gray-500 transition-colors"
|
||||
>
|
||||
{post.feature_image && (
|
||||
<img
|
||||
src={post.feature_image}
|
||||
alt=""
|
||||
className="inset-0 object-cover w-full m-0 md:h-96 -z-10 rounded-t-xl"
|
||||
className="inset-0 -z-10 m-0 w-full rounded-t-xl object-cover md:h-96"
|
||||
/>
|
||||
)}
|
||||
<div className="p-8">
|
||||
<h2 className="m-0 text2xl md:text-4xl">{post.title}</h2>
|
||||
<h2 className="text2xl m-0 md:text-4xl">{post.title}</h2>
|
||||
<small className="m-0">{post.reading_time} minute read.</small>
|
||||
<p className="my-2 line-clamp-3">{post.excerpt}</p>
|
||||
<p className="line-clamp-3 my-2">{post.excerpt}</p>
|
||||
<p className="m-0 text-white">
|
||||
by {post.primary_author?.name} ·{' '}
|
||||
{new Date(post.published_at ?? '').toLocaleDateString()}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2 mt-4">
|
||||
<div className="mt-4 flex flex-wrap gap-2">
|
||||
{post.tags?.map((tag: Tag) => (
|
||||
<BlogTag key={tag.id} tag={tag} />
|
||||
))}
|
||||
|
|
|
@ -29,7 +29,7 @@ function Page({ post }: { post: PostOrPage }) {
|
|||
<meta content="summary_large_image" name="twitter:card" />
|
||||
<meta name="author" content={post?.primary_author?.name || 'Spacedrive Technology Inc.'} />
|
||||
</Helmet>
|
||||
<div className="container max-w-4xl p-4 m-auto mb-20 prose pt-14 lg:prose-xs dark:prose-invert">
|
||||
<div className="lg:prose-xs prose dark:prose-invert container m-auto mb-20 max-w-4xl p-4 pt-14">
|
||||
{post && (
|
||||
<>
|
||||
<figure>
|
||||
|
@ -38,9 +38,9 @@ function Page({ post }: { post: PostOrPage }) {
|
|||
></figcaption>
|
||||
<img src={featured_image} alt="" className="mt-8 rounded-xl" />
|
||||
</figure>
|
||||
<section className="flex flex-wrap gap-4 px-8 -mx-8 rounded-xl">
|
||||
<div className="flex-grow">
|
||||
<h1 className="m-0 text-2xl leading-snug sm:leading-normal sm:text-4xl">
|
||||
<section className="-mx-8 flex flex-wrap gap-4 rounded-xl px-8">
|
||||
<div className="grow">
|
||||
<h1 className="m-0 text-2xl leading-snug sm:text-4xl sm:leading-normal">
|
||||
{post?.title}
|
||||
</h1>
|
||||
<p className="m-0 mt-2">
|
||||
|
|
|
@ -93,96 +93,96 @@ function Page() {
|
|||
<title>Careers - Spacedrive</title>
|
||||
<meta name="description" content="Work with us to build the future of file management." />
|
||||
</Helmet>
|
||||
<div className="container relative max-w-4xl min-h-screen p-4 pt-32 m-auto mb-20 prose text-white prose-invert">
|
||||
<div className="prose prose-invert container relative m-auto mb-20 min-h-screen max-w-4xl p-4 pt-32 text-white">
|
||||
<div
|
||||
className="bloom subtle egg-bloom-two -top-60 -right-[400px]"
|
||||
className="bloom subtle egg-bloom-two -top-60 right-[-400px]"
|
||||
style={{ transform: 'scale(2)' }}
|
||||
/>
|
||||
<h1 className="px-2 mb-3 text-4xl font-black leading-tight text-center text-white fade-in-heading md:text-5xl">
|
||||
<h1 className="fade-in-heading mb-3 px-2 text-center text-4xl font-black leading-tight text-white md:text-5xl">
|
||||
Build the future of files.
|
||||
</h1>
|
||||
<div className="z-30 flex flex-col items-center fade-in animation-delay-1">
|
||||
<p className="z-40 text-lg text-center text-gray-350">
|
||||
<div className="fade-in animation-delay-1 z-30 flex flex-col items-center">
|
||||
<p className="text-gray-350 z-40 text-center text-lg">
|
||||
Spacedrive is redefining the way we think about our personal data, building a open
|
||||
ecosystem to help preserve your digital legacy and make cross-platform file management a
|
||||
breeze.
|
||||
</p>
|
||||
<Button
|
||||
onClick={scrollToPositions}
|
||||
className="z-30 border-0 cursor-pointer"
|
||||
className="z-30 cursor-pointer border-0"
|
||||
variant="accent"
|
||||
>
|
||||
See Open Positions
|
||||
</Button>
|
||||
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" />
|
||||
<h2 className="px-2 mb-0 text-4xl font-black leading-tight text-center">Our Values</h2>
|
||||
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" />
|
||||
<h2 className="mb-0 px-2 text-center text-4xl font-black leading-tight">Our Values</h2>
|
||||
<p className="mt-2 mb-4">What drives us daily.</p>
|
||||
<div className="grid w-full grid-cols-1 gap-4 mt-5 sm:grid-cols-2">
|
||||
<div className="mt-5 grid w-full grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
{values.map((value, index) => (
|
||||
<div
|
||||
key={value.title + index}
|
||||
className="flex flex-col p-10 bg-opacity-50 border border-gray-500 rounded-md bg-gray-550"
|
||||
className="bg-opacity/50 bg-gray-550 flex flex-col rounded-md border border-gray-500 p-10"
|
||||
>
|
||||
<value.icon className="w-8 m-0" />
|
||||
<value.icon className="m-0 w-8" />
|
||||
<h3 className="mt-4 mb-1 text-2xl font-bold leading-snug">{value.title}</h3>
|
||||
<p className="mt-1 mb-0 text-gray-350">{value.desc}</p>
|
||||
<p className="text-gray-350 mt-1 mb-0">{value.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" />
|
||||
<h2 className="px-2 mb-0 text-4xl font-black leading-tight text-center text-white">
|
||||
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" />
|
||||
<h2 className="mb-0 px-2 text-center text-4xl font-black leading-tight text-white">
|
||||
Perks and Benefits
|
||||
</h2>
|
||||
<p className="mt-2 mb-4">We're behind you 100%.</p>
|
||||
<div className="grid w-full grid-cols-1 gap-4 mt-5 sm:grid-cols-3">
|
||||
<div className="mt-5 grid w-full grid-cols-1 gap-4 sm:grid-cols-3">
|
||||
{perks.map((value, index) => (
|
||||
<div
|
||||
key={value.title + index}
|
||||
style={{ backgroundColor: value.color + '10', borderColor: value.color + '30' }}
|
||||
className="flex flex-col p-8 border rounded-md bg-gray-550 bg-opacity-30"
|
||||
className="bg-opacity30 bg-gray-550 flex flex-col rounded-md border p-8"
|
||||
>
|
||||
<value.icon className="w-8 m-0" color={value.color} />
|
||||
<value.icon className="m-0 w-8" color={value.color} />
|
||||
<h3 className="mt-4 mb-1">{value.title}</h3>
|
||||
<p className="mt-1 mb-0 text-sm text-white opacity-60">{value.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" ref={openPositionsRef} />
|
||||
<h2 className="px-2 mb-0 text-4xl font-black leading-tight text-center text-white">
|
||||
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" ref={openPositionsRef} />
|
||||
<h2 className="mb-0 px-2 text-center text-4xl font-black leading-tight text-white">
|
||||
Open Positions
|
||||
</h2>
|
||||
<p className="mt-2 mb-4">If any open positions suit you, apply now!</p>
|
||||
<div className="grid w-full grid-cols-1 gap-4 mt-5">
|
||||
<div className="mt-5 grid w-full grid-cols-1 gap-4">
|
||||
{positions.length === 0 ? (
|
||||
<p className="m-0 text-center text-gray-350">
|
||||
<p className="text-gray-350 m-0 text-center">
|
||||
There are no positions open at this time. Please check back later!
|
||||
</p>
|
||||
) : (
|
||||
positions.map((value, index) => (
|
||||
<div
|
||||
key={value.name + index}
|
||||
className="flex flex-col p-10 bg-opacity-50 border border-gray-500 rounded-md bg-gray-550"
|
||||
className="bg-opacity/50 bg-gray-550 flex flex-col rounded-md border border-gray-500 p-10"
|
||||
>
|
||||
<div className="flex flex-col sm:flex-row">
|
||||
<h3 className="m-0 text-2xl leading-tight">{value.name}</h3>
|
||||
<div className="mt-3 sm:mt-0.5">
|
||||
<span className="text-sm font-semibold text-gray-300 sm:ml-4">
|
||||
<CurrencyDollar className="inline w-4 mr-1 -mt-1" />
|
||||
<CurrencyDollar className="mr-1 -mt-1 inline w-4" />
|
||||
{value.salary}
|
||||
</span>
|
||||
<span className="ml-4 text-sm font-semibold text-gray-300">
|
||||
<Clock className="inline w-4 mr-1 -mt-1" />
|
||||
<Clock className="mr-1 -mt-1 inline w-4" />
|
||||
{value.type}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-3 mb-0 text-gray-350">{value.description}</p>
|
||||
<p className="text-gray-350 mt-3 mb-0">{value.description}</p>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
<hr className="w-full my-24 border-gray-200 opacity-10 border-1" />
|
||||
<h2 className="px-2 mb-0 text-3xl font-black text-center text-white">How to apply?</h2>
|
||||
<hr className="border-1 my-24 w-full border-gray-200 opacity-10" />
|
||||
<h2 className="mb-0 px-2 text-center text-3xl font-black text-white">How to apply?</h2>
|
||||
<p className="mt-2">
|
||||
Send your cover letter and resume to <strong>careers at spacedrive dot com</strong> and
|
||||
we'll get back to you shortly!
|
||||
|
|
|
@ -5,11 +5,11 @@ import { Helmet } from 'react-helmet';
|
|||
import '../../atom-one.css';
|
||||
import DocsLayout from '../../components/DocsLayout';
|
||||
import Markdown from '../../components/Markdown';
|
||||
import { SingleDocResponse, toTitleCase } from './api';
|
||||
import { SingleDocResponse } from './api';
|
||||
|
||||
function BottomCard(props: PropsWithChildren) {
|
||||
return (
|
||||
<div className="flex flex-row items-center p-4 text-sm border border-gray-700 rounded-lg group !text-gray-200 hover:!text-primary hover:shadow-xl hover:border-primary hover:shadow-primary/10 transition-all duration-200 hover:-translate-y-[2px]">
|
||||
<div className="hover:border-primary hover:!text-primary hover:shadow-primary/10 group flex flex-row items-center rounded-lg border border-gray-700 p-4 text-sm !text-gray-200 transition-all duration-200 hover:translate-y-[-2px] hover:shadow-xl">
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
@ -31,11 +31,11 @@ function Page({ doc, navigation, nextDoc }: SingleDocResponse) {
|
|||
|
||||
<DocsLayout doc={doc} navigation={navigation}>
|
||||
<Markdown classNames="sm:mt-[105px] mt-6 min-h-screen ">
|
||||
<h5 className="mb-2 text-sm font-semibold text-primary lg:min-w-[700px]">
|
||||
<h5 className="text-primary mb-2 text-sm font-semibold lg:min-w-[700px]">
|
||||
{doc.categoryName}
|
||||
</h5>
|
||||
<div dangerouslySetInnerHTML={{ __html: doc?.html as string }} />
|
||||
<div className="flex flex-col gap-3 mt-10 sm:flex-row">
|
||||
<div className="mt-10 flex flex-col gap-3 sm:flex-row">
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
|
@ -43,14 +43,14 @@ function Page({ doc, navigation, nextDoc }: SingleDocResponse) {
|
|||
className="w-full"
|
||||
>
|
||||
<BottomCard>
|
||||
<Github className="w-5 mr-3" />
|
||||
<Github className="mr-3 w-5" />
|
||||
Edit this page on GitHub
|
||||
</BottomCard>
|
||||
</a>
|
||||
{nextDoc && (
|
||||
<a href={`/docs/${nextDoc.url}`} className="w-full">
|
||||
<BottomCard>
|
||||
<CaretRight className="w-5 mr-3" />
|
||||
<CaretRight className="mr-3 w-5" />
|
||||
Next article: {nextDoc?.title}
|
||||
</BottomCard>
|
||||
</a>
|
||||
|
|
|
@ -20,7 +20,7 @@ function Page({ navigation }: { navigation: DocsNavigation }) {
|
|||
need to get started with Spacedrive.
|
||||
</p>
|
||||
<a
|
||||
className="transition text-primary-600 hover:text-primary-500"
|
||||
className="text-primary-600 hover:text-primary-500 transition"
|
||||
href="/docs/product/getting-started/introduction"
|
||||
>
|
||||
Get Started →
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ReactComponent as Info } from '@sd/assets/svgs/info.svg';
|
|||
import clsx from 'clsx';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import AppEmbed, { AppEmbedPlaceholder } from '../components/AppEmbed';
|
||||
import AppEmbed from '../components/AppEmbed';
|
||||
import { Bubbles } from '../components/Bubbles';
|
||||
// import { Bubbles } from '../components/Bubbles';
|
||||
import HomeCTA from '../components/HomeCTA';
|
||||
|
@ -23,12 +23,12 @@ function Section(props: SectionProps = { orientation: 'left' }) {
|
|||
<div className="px-4 py-10 sm:px-10">
|
||||
{props.heading && <h1 className="text-2xl font-black sm:text-4xl">{props.heading}</h1>}
|
||||
{props.description && (
|
||||
<p className="mt-5 text-md sm:text-xl text-gray-450">{props.description}</p>
|
||||
<p className="text-md text-gray-450 mt-5 sm:text-xl">{props.description}</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className={clsx('grid grid-cols-1 my-10 lg:grid-cols-2 lg:my-44', props.className)}>
|
||||
<div className={clsx('my-10 grid grid-cols-1 lg:my-44 lg:grid-cols-2', props.className)}>
|
||||
{props.orientation === 'right' ? (
|
||||
<>
|
||||
{info}
|
||||
|
@ -77,10 +77,11 @@ function Page() {
|
|||
alert('An error occurred while unsubscribing from waitlist');
|
||||
}
|
||||
})();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center w-full px-4">
|
||||
<div className="flex w-full flex-col items-center px-4">
|
||||
<Helmet>
|
||||
<title>Spacedrive — A file manager from the future.</title>
|
||||
<meta
|
||||
|
@ -107,18 +108,18 @@ function Page() {
|
|||
{unsubscribedFromWaitlist && (
|
||||
<div
|
||||
className={
|
||||
'-mt-8 flex flex-row items-center bg-opacity-20 border-2 my-2 px-2 rounded-md bg-green-800 border-green-900'
|
||||
'bg-opacity/20 my-2 -mt-8 flex flex-row items-center rounded-md border-2 border-green-900 bg-green-800 px-2'
|
||||
}
|
||||
>
|
||||
<Info className="w-5 mr-1 fill-green-500" />
|
||||
<Info className="mr-1 w-5 fill-green-500" />
|
||||
<p className={'text-sm text-green-500'}>You have been unsubscribed from the waitlist</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h1 className="z-30 px-2 mb-3 text-4xl font-black leading-tight text-center text-white fade-in-heading md:text-6xl">
|
||||
<h1 className="fade-in-heading z-30 mb-3 px-2 text-center text-4xl font-black leading-tight text-white md:text-6xl">
|
||||
A file explorer from the future.
|
||||
</h1>
|
||||
<p className="z-30 max-w-4xl mt-1 mb-8 text-center animation-delay-1 fade-in-heading text-md lg:text-lg leading-2 lg:leading-8 text-gray-450">
|
||||
<p className="animation-delay-1 fade-in-heading text-md leading-2 text-gray-450 z-30 mt-1 mb-8 max-w-4xl text-center lg:text-lg lg:leading-8">
|
||||
Combine your drives and clouds into one database that you can organize and explore from any
|
||||
device.
|
||||
<br />
|
||||
|
@ -140,7 +141,7 @@ function Page() {
|
|||
<br />
|
||||
<br />
|
||||
<a
|
||||
className="transition text-primary-600 hover:text-primary-500"
|
||||
className="text-primary-600 hover:text-primary-500 transition"
|
||||
href="/docs/product/getting-started/introduction"
|
||||
>
|
||||
Find out more →
|
||||
|
|
|
@ -123,25 +123,25 @@ function Page() {
|
|||
<title>Roadmap - Spacedrive</title>
|
||||
<meta name="description" content="What can Spacedrive do?" />
|
||||
</Helmet>
|
||||
<div className="container flex flex-col max-w-4xl gap-20 p-4 pt-32 m-auto mb-20 prose lg:prose-xs dark:prose-invert">
|
||||
<div className="lg:prose-xs prose dark:prose-invert container m-auto mb-20 flex max-w-4xl flex-col gap-20 p-4 pt-32">
|
||||
<section className="flex flex-col items-center">
|
||||
<img className="w-24 pointer-events-none" />
|
||||
<h1 className="mb-0 text-5xl leading-snug text-center fade-in-heading">
|
||||
<img className="pointer-events-none w-24" />
|
||||
<h1 className="fade-in-heading mb-0 text-center text-5xl leading-snug">
|
||||
What's next for Spacedrive?
|
||||
</h1>
|
||||
<p className="text-center text-gray-400 animation-delay-2 fade-in-heading">
|
||||
<p className="animation-delay-2 fade-in-heading text-center text-gray-400">
|
||||
Here is a list of the features we are working on, and the progress we have made so far.
|
||||
</p>
|
||||
</section>
|
||||
<section className="grid grid-cols-[auto_1fr] grid-flow-row auto-cols-auto gap-x-4">
|
||||
<section className="grid auto-cols-auto grid-flow-row grid-cols-[auto_1fr] gap-x-4">
|
||||
{items.map((item, i) => (
|
||||
<>
|
||||
{/* Using span so i can use the group-last-of-type selector */}
|
||||
<span className="max-w-[10rem] flex items-start first:items-start justify-end gap-4 group">
|
||||
<span className="group flex max-w-[10rem] items-start justify-end gap-4 first:items-start">
|
||||
<div className="flex flex-col items-end">
|
||||
<h3
|
||||
className={
|
||||
`m-0 hidden lg:block text-right ` +
|
||||
`m-0 hidden text-right lg:block ` +
|
||||
(i === 0 ? '-translate-y-1/4' : '-translate-y-1/2')
|
||||
}
|
||||
>
|
||||
|
@ -149,17 +149,17 @@ function Page() {
|
|||
</h3>
|
||||
{item?.subtext && <span className="text-sm text-gray-300">{item?.subtext}</span>}
|
||||
</div>
|
||||
<div className="flex w-2 h-full group-first:rounded-t-full group-last-of-type:rounded-b-full lg:items-center group-first:mt-2">
|
||||
<div className="flex h-full w-2 group-first:mt-2 group-first:rounded-t-full group-last-of-type:rounded-b-full lg:items-center">
|
||||
<div
|
||||
className={
|
||||
'w-full h-full flex ' +
|
||||
'flex h-full w-full ' +
|
||||
(item.completed ? 'bg-primary-500 z-10' : 'bg-gray-550')
|
||||
}
|
||||
>
|
||||
{item?.when !== undefined ? (
|
||||
<div
|
||||
className={clsx(
|
||||
'absolute z-20 w-4 h-4 mt-5 -translate-y-1/2 border-2 border-gray-200 rounded-full group-first:mt-0 lg:mt-0 group-first:self-start -translate-x-1/4',
|
||||
'absolute z-20 mt-5 h-4 w-4 -translate-y-1/2 -translate-x-1/4 rounded-full border-2 border-gray-200 group-first:mt-0 group-first:self-start lg:mt-0',
|
||||
items[i - 1]?.completed || i === 0 ? 'bg-primary-500 z-10' : 'bg-gray-550'
|
||||
)}
|
||||
>
|
||||
|
@ -171,11 +171,11 @@ function Page() {
|
|||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<div className="flex flex-col items-start justify-center gap-4 group">
|
||||
<div className="group flex flex-col items-start justify-center gap-4">
|
||||
{item?.when && (
|
||||
<h3 className="mb-0 group-first-of-type:m-0 lg:hidden">{item.when}</h3>
|
||||
)}
|
||||
<div className="flex flex-col w-full p-4 my-2 space-y-2 border border-gray-500 rounded-xl group-first-of-type:mt-0 group-last:mb-0">
|
||||
<div className="my-2 flex w-full flex-col space-y-2 rounded-xl border border-gray-500 p-4 group-last:mb-0 group-first-of-type:mt-0">
|
||||
<h3 className="m-0">{item.title}</h3>
|
||||
<p>{item.description}</p>
|
||||
</div>
|
||||
|
@ -183,7 +183,7 @@ function Page() {
|
|||
</>
|
||||
))}
|
||||
</section>
|
||||
<section className="p-8 space-y-2 bg-gray-850 rounded-xl">
|
||||
<section className="bg-gray-850 space-y-2 rounded-xl p-8">
|
||||
<h2 className="my-1">That's not all.</h2>
|
||||
<p>
|
||||
We're always open to ideas and feedback over{' '}
|
||||
|
|
|
@ -202,34 +202,34 @@ function Page() {
|
|||
<title>Our Team - Spacedrive</title>
|
||||
<meta name="description" content="Who's behind Spacedrive?" />
|
||||
</Helmet>
|
||||
<div className="relative mx-auto team-page">
|
||||
<div className="team-page relative mx-auto">
|
||||
<div
|
||||
className="bloom subtle egg-bloom-one -top-60 -right-[400px]"
|
||||
className="bloom subtle egg-bloom-one -top-60 right-[-400px]"
|
||||
style={{ transform: 'scale(2)' }}
|
||||
/>
|
||||
<div className="relative z-10">
|
||||
<h1 className="text-5xl leading-tight sm:leading-snug fade-in-heading ">
|
||||
<h1 className="fade-in-heading text-5xl leading-tight sm:leading-snug ">
|
||||
We believe file management should be <span className="title-gradient">universal</span>.
|
||||
</h1>
|
||||
<p className="text-white/50 animation-delay-2 fade-in-heading ">
|
||||
<p className="animation-delay-2 fade-in-heading text-white/50 ">
|
||||
Your priceless personal data shouldn't be stuck in a device ecosystem. It should be OS
|
||||
agnostic, permanent and owned by you.
|
||||
</p>
|
||||
<p className="text-white/50 animation-delay-2 fade-in-heading ">
|
||||
<p className="animation-delay-2 fade-in-heading text-white/50 ">
|
||||
The data we create daily is our legacy—that will long outlive us. Open source technology
|
||||
is the only way to ensure we retain absolute control over the files that define our
|
||||
lives, at unlimited scale.
|
||||
</p>
|
||||
<a
|
||||
href="/docs/product/resources/faq"
|
||||
className="flex flex-row items-center text-gray-400 duration-150 animation-delay-3 fade-in-heading hover:text-white text-underline underline-offset-4"
|
||||
className="animation-delay-3 fade-in-heading text-underline flex flex-row items-center text-gray-400 underline-offset-4 duration-150 hover:text-white"
|
||||
>
|
||||
<ArrowRight className="mr-2" />
|
||||
Read more
|
||||
</a>
|
||||
<div className="fade-in-heading animation-delay-5">
|
||||
<h2 className="mt-10 text-2xl leading-relaxed sm:mt-20 ">Meet the team</h2>
|
||||
<div className="grid grid-cols-2 my-10 xs:grid-cols-3 sm:grid-cols-4 gap-x-5 gap-y-10">
|
||||
<div className="xs:grid-cols-3 my-10 grid grid-cols-2 gap-x-5 gap-y-10 sm:grid-cols-4">
|
||||
{teamMembers.map((member) => (
|
||||
<TeamMember key={member.name} {...member} />
|
||||
))}
|
||||
|
@ -240,7 +240,7 @@ function Page() {
|
|||
href="https://github.com/spacedriveapp/spacedrive/graphs/contributors"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="duration-200 oss-credit-gradient hover:opacity-75"
|
||||
className="oss-credit-gradient duration-200 hover:opacity-75"
|
||||
>
|
||||
open source contributors
|
||||
</a>{' '}
|
||||
|
@ -252,7 +252,7 @@ function Page() {
|
|||
<p className="text-sm text-gray-400 ">
|
||||
We're backed by some of the greatest leaders in the technology industry.
|
||||
</p>
|
||||
<div className="grid grid-cols-3 my-10 sm:grid-cols-5 gap-x-5 gap-y-10">
|
||||
<div className="my-10 grid grid-cols-3 gap-x-5 gap-y-10 sm:grid-cols-5">
|
||||
{investors.map((investor) => (
|
||||
<TeamMember key={investor.name + investor.investmentRound} {...investor} />
|
||||
))}
|
||||
|
|
|
@ -13,9 +13,9 @@ function Page({ is404 }: { is404: boolean }) {
|
|||
<Helmet>
|
||||
<title>Not Found - Spacedrive</title>
|
||||
</Helmet>
|
||||
<div className="flex flex-col items-center m-auto ">
|
||||
<div className="m-auto flex flex-col items-center ">
|
||||
<div className="h-32" />
|
||||
<SmileyXEyes className="mb-3 w-44 h-44" />
|
||||
<SmileyXEyes className="mb-3 h-44 w-44" />
|
||||
<h1 className="mb-2 text-center">In the quantum realm this page potentially exists.</h1>
|
||||
<p>In other words, thats a 404.</p>
|
||||
<div className="flex flex-wrap justify-center">
|
||||
|
|
|
@ -97,7 +97,7 @@ html {
|
|||
}
|
||||
|
||||
.bloom {
|
||||
@apply absolute w-[1200px] h-[1200px] -mt-[320px];
|
||||
@apply absolute -mt-[320px] h-[1200px] w-[1200px];
|
||||
will-change: opacity;
|
||||
opacity: 0;
|
||||
will-change: filter opacity;
|
||||
|
@ -126,7 +126,7 @@ html {
|
|||
animation-delay: 0ms;
|
||||
}
|
||||
&.bloom-three {
|
||||
@apply left-auto right-auto invisible md:visible -mt-[250px] ml-24;
|
||||
@apply invisible left-auto right-auto -mt-[250px] ml-24 md:visible;
|
||||
background: url('/bloom-three.png') no-repeat center center;
|
||||
background-size: contain;
|
||||
animation-delay: 800ms;
|
||||
|
@ -169,7 +169,7 @@ html {
|
|||
}
|
||||
|
||||
.slot-block {
|
||||
@apply bg-app-box py-3 px-4 border-l-4 border-app-line rounded mb-2;
|
||||
@apply bg-app-box border-app-line mb-2 rounded border-l-4 py-3 px-4;
|
||||
}
|
||||
.slot-block.note {
|
||||
@apply border-yellow-400 bg-yellow-300/20;
|
||||
|
@ -181,7 +181,7 @@ html {
|
|||
@apply border-red-400 bg-red-400/20;
|
||||
}
|
||||
.slot-block-title {
|
||||
@apply text-white font-bold text-sm m-0 uppercase;
|
||||
@apply m-0 text-sm font-bold uppercase text-white;
|
||||
}
|
||||
.slot-block-content {
|
||||
@apply my-1 mx-0 mb-0 text-white;
|
||||
|
@ -234,9 +234,9 @@ html {
|
|||
width: 7px;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
@apply bg-[#00000006] dark:bg-[#00000030] my-[10px] rounded-[6px];
|
||||
@apply my-[10px] rounded-[6px] bg-[#00000006] dark:bg-[#00000030];
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply rounded-[6px] bg-app-selected;
|
||||
@apply bg-app-selected rounded-[6px];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ function AppContainer() {
|
|||
|
||||
const { library } = useCurrentLibrary();
|
||||
return (
|
||||
<SafeAreaProvider style={tw`flex-1 bg-app`}>
|
||||
<SafeAreaProvider style={tw`bg-app flex-1`}>
|
||||
<GestureHandlerRootView style={tw`flex-1`}>
|
||||
<MenuProvider>
|
||||
<BottomSheetModalProvider>
|
||||
|
|
|
@ -114,19 +114,19 @@ const DeviceIcon = {
|
|||
|
||||
const Device = ({ name, size, type }: DeviceProps) => {
|
||||
return (
|
||||
<View style={tw`my-2 border rounded-md bg-app-overlay border-app-line`}>
|
||||
<View style={tw`bg-app-overlay border-app-line my-2 rounded-md border`}>
|
||||
<View style={tw`flex flex-row items-center px-3.5 pt-3 pb-2`}>
|
||||
<View style={tw`flex flex-row items-center`}>
|
||||
{DeviceIcon[type]}
|
||||
<Text style={tw`text-base font-semibold text-ink`}>{name || 'Unnamed Device'}</Text>
|
||||
<Text style={tw`text-ink text-base font-semibold`}>{name || 'Unnamed Device'}</Text>
|
||||
{/* P2P Lock */}
|
||||
<View style={tw`flex flex-row rounded items-center ml-2 bg-app-box py-[1px] px-[4px]`}>
|
||||
<View style={tw`bg-app-box ml-2 flex flex-row items-center rounded py-[1px] px-[4px]`}>
|
||||
<Lock weight="bold" size={12} color={tw.color('ink-dull')} />
|
||||
<Text style={tw`text-ink-dull font-semibold ml-0.5 text-xs`}>P2P</Text>
|
||||
<Text style={tw`text-ink-dull ml-0.5 text-xs font-semibold`}>P2P</Text>
|
||||
</View>
|
||||
</View>
|
||||
{/* Size */}
|
||||
<Text style={tw`ml-2 text-sm font-semibold text-ink-dull`}>{size}</Text>
|
||||
<Text style={tw`text-ink-dull ml-2 text-sm font-semibold`}>{size}</Text>
|
||||
</View>
|
||||
<FlatList
|
||||
data={placeholderFileItems}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Text, View } from 'react-native';
|
||||
import { ExplorerItem, ObjectKind } from '@sd/client';
|
||||
import Layout from '~/constants/Layout';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { getExplorerStore } from '~/stores/explorerStore';
|
||||
import { isObject } from '~/types/helper';
|
||||
import tw from '../../lib/tailwind';
|
||||
import FileThumb from './FileThumb';
|
||||
|
||||
type FileItemProps = {
|
||||
|
@ -21,7 +21,7 @@ const FileItem = ({ data }: FileItemProps) => {
|
|||
|
||||
return (
|
||||
<View
|
||||
style={tw.style('items-center', {
|
||||
style={twStyle('items-center', {
|
||||
width: gridItemSize,
|
||||
height: gridItemSize
|
||||
})}
|
||||
|
@ -31,12 +31,12 @@ const FileItem = ({ data }: FileItemProps) => {
|
|||
kind={data.item.extension === 'zip' ? 'zip' : isVid ? 'video' : 'other'}
|
||||
/>
|
||||
{item.extension && isVid && (
|
||||
<View style={tw`absolute bottom-8 opacity-70 right-5 py-0.5 px-1 bg-black/70 rounded`}>
|
||||
<Text style={tw`text-[9px] text-white uppercase font-semibold`}>{item.extension}</Text>
|
||||
<View style={tw`absolute bottom-8 right-5 rounded bg-black/70 py-0.5 px-1 opacity-70`}>
|
||||
<Text style={tw`text-[9px] font-semibold uppercase text-white`}>{item.extension}</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={tw`px-1.5 py-[1px] mt-1`}>
|
||||
<Text numberOfLines={1} style={tw`text-xs font-medium text-center text-white`}>
|
||||
<View style={tw`mt-1 px-1.5 py-[1px]`}>
|
||||
<Text numberOfLines={1} style={tw`text-center text-xs font-medium text-white`}>
|
||||
{item?.name}
|
||||
{item?.extension && `.${item.extension}`}
|
||||
</Text>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import { ExplorerItem, ObjectKind } from '@sd/client';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { getExplorerStore } from '~/stores/explorerStore';
|
||||
import { isObject } from '~/types/helper';
|
||||
import FileThumb from './FileThumb';
|
||||
|
@ -19,7 +19,7 @@ const FileRow = ({ data }: FileRowProps) => {
|
|||
|
||||
return (
|
||||
<View
|
||||
style={tw.style('flex flex-row items-center px-3', {
|
||||
style={twStyle('flex flex-row items-center px-3', {
|
||||
height: getExplorerStore().listItemSize
|
||||
})}
|
||||
>
|
||||
|
@ -29,7 +29,7 @@ const FileRow = ({ data }: FileRowProps) => {
|
|||
size={0.6}
|
||||
/>
|
||||
<View style={tw`ml-3`}>
|
||||
<Text numberOfLines={1} style={tw`text-xs font-medium text-center text-ink-dull`}>
|
||||
<Text numberOfLines={1} style={tw`text-ink-dull text-center text-xs font-medium`}>
|
||||
{item?.name}
|
||||
{item?.extension && `.${item.extension}`}
|
||||
</Text>
|
||||
|
|
|
@ -20,7 +20,7 @@ export const getThumbnailUrlById = (casId: string) =>
|
|||
`${DocumentDirectoryPath}/thumbnails/${encodeURIComponent(casId)}.webp`;
|
||||
|
||||
const FileThumbWrapper = ({ children, size = 1 }) => (
|
||||
<View style={[tw`justify-center items-center`, { width: 80 * size, height: 80 * size }]}>
|
||||
<View style={[tw`items-center justify-center`, { width: 80 * size, height: 80 * size }]}>
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
|
@ -63,7 +63,7 @@ export default function FileThumb({ data, size = 1, kind }: FileThumbProps) {
|
|||
if (data.has_thumbnail && url) {
|
||||
return (
|
||||
<FileThumbWrapper size={size}>
|
||||
<Image source={{ uri: url }} resizeMode="contain" style={tw`w-full h-full`} />
|
||||
<Image source={{ uri: url }} resizeMode="contain" style={tw`h-full w-full`} />
|
||||
</FileThumbWrapper>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { MotiView } from 'moti';
|
|||
import { List } from 'phosphor-react-native';
|
||||
import { Pressable, Text, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
|
||||
// Default header with search bar and button to open drawer
|
||||
export default function Header() {
|
||||
|
@ -17,12 +17,12 @@ export default function Header() {
|
|||
|
||||
return (
|
||||
<View
|
||||
style={tw.style('mx-4 bg-app-overlay border border-app-line rounded', {
|
||||
style={twStyle('border-app-line bg-app-overlay mx-4 rounded border', {
|
||||
marginTop: top + 10
|
||||
})}
|
||||
>
|
||||
<View style={tw`flex flex-row items-center h-10`}>
|
||||
<Pressable style={tw`px-3 h-full justify-center`} onPress={() => navigation.openDrawer()}>
|
||||
<View style={tw`flex h-10 flex-row items-center`}>
|
||||
<Pressable style={tw`h-full justify-center px-3`} onPress={() => navigation.openDrawer()}>
|
||||
<MotiView
|
||||
animate={{ rotate: isDrawerOpen ? '90deg' : '0deg' }}
|
||||
transition={{ type: 'timing' }}
|
||||
|
@ -31,10 +31,10 @@ export default function Header() {
|
|||
</MotiView>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={tw`flex-1 h-full justify-center`}
|
||||
style={tw`h-full flex-1 justify-center`}
|
||||
onPress={() => navigation.navigate('Search')}
|
||||
>
|
||||
<Text style={tw`text-ink-dull font-medium text-sm`}>Search</Text>
|
||||
<Text style={tw`text-ink-dull text-sm font-medium`}>Search</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { View, ViewProps } from 'react-native';
|
||||
import tw from '~/lib/tailwind';
|
||||
import { twStyle } from '~/lib/tailwind';
|
||||
|
||||
type CardProps = {
|
||||
children: React.ReactNode;
|
||||
|
@ -11,10 +11,7 @@ const Card = ({ children, ...props }: CardProps) => {
|
|||
|
||||
return (
|
||||
<View
|
||||
style={tw.style(
|
||||
'px-4 py-3 border border-app-line rounded-lg bg-app-overlay',
|
||||
style as string
|
||||
)}
|
||||
style={twStyle('border-app-line bg-app-overlay rounded-lg border px-4 py-3', style as string)}
|
||||
{...otherProps}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -16,7 +16,7 @@ const CollapsibleView = ({ title, titleStyle, containerStyle, children }: Collap
|
|||
|
||||
return (
|
||||
<View style={containerStyle}>
|
||||
<Pressable onPress={toggle} style={tw`flex flex-row justify-between items-center`}>
|
||||
<Pressable onPress={toggle} style={tw`flex flex-row items-center justify-between`}>
|
||||
<Text style={titleStyle} selectable={false}>
|
||||
{title}
|
||||
</Text>
|
||||
|
|
|
@ -74,14 +74,14 @@ const Dialog = (props: DialogProps) => {
|
|||
>
|
||||
{/* TODO: Blur may look cool here */}
|
||||
<View
|
||||
style={tw`min-w-[360px] max-w-[380px] rounded-md bg-app border border-app-line shadow shadow-app-shade overflow-hidden`}
|
||||
style={tw`border-app-line bg-app shadow-app-shade min-w-[360px] max-w-[380px] overflow-hidden rounded-md border shadow`}
|
||||
>
|
||||
<View style={tw`p-5`}>
|
||||
{/* Title */}
|
||||
<Text style={tw`font-bold text-ink text-base`}>{props.title}</Text>
|
||||
<Text style={tw`text-ink text-base font-bold`}>{props.title}</Text>
|
||||
{/* Description */}
|
||||
{props.description && (
|
||||
<Text style={tw`text-sm text-ink-dull mt-2 leading-normal`}>
|
||||
<Text style={tw`text-ink-dull mt-2 text-sm leading-normal`}>
|
||||
{props.description}
|
||||
</Text>
|
||||
)}
|
||||
|
@ -90,10 +90,10 @@ const Dialog = (props: DialogProps) => {
|
|||
</View>
|
||||
{/* Actions */}
|
||||
<View
|
||||
style={tw`flex flex-row items-center px-3 py-3 bg-app-highlight border-t border-app-line`}
|
||||
style={tw`border-app-line bg-app-highlight flex flex-row items-center border-t p-3`}
|
||||
>
|
||||
{props.loading && <PulseAnimation style={tw`h-7`} />}
|
||||
<View style={tw`flex-grow`} />
|
||||
<View style={tw`grow`} />
|
||||
<Button
|
||||
variant="dark_gray"
|
||||
size="md"
|
||||
|
|
|
@ -2,15 +2,15 @@ import { VariantProps, cva } from 'class-variance-authority';
|
|||
import { MotiPressable, MotiPressableProps } from 'moti/interactions';
|
||||
import { FC, useMemo } from 'react';
|
||||
import { Pressable, PressableProps } from 'react-native';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
|
||||
const button = cva(['border rounded-md items-center justify-center shadow-sm'], {
|
||||
const button = cva(['items-center justify-center rounded-md border shadow-sm'], {
|
||||
variants: {
|
||||
variant: {
|
||||
danger: ['bg-red-600 border-red-800'],
|
||||
gray: ['bg-app-button border-app-line'],
|
||||
dark_gray: ['bg-app border-app-box'],
|
||||
accent: ['bg-accent border-accent-deep shadow-md shadow-app-shade/10']
|
||||
danger: ['border-red-800 bg-red-600'],
|
||||
gray: ['border-app-line bg-app-button'],
|
||||
dark_gray: ['border-app-box bg-app'],
|
||||
accent: ['border-accent-deep bg-accent shadow-app-shade/10 shadow-md']
|
||||
},
|
||||
size: {
|
||||
default: ['py-1', 'px-3'],
|
||||
|
@ -35,7 +35,7 @@ export const Button: FC<ButtonProps> = ({ variant, size, disabled, ...props }) =
|
|||
return (
|
||||
<Pressable
|
||||
disabled={disabled}
|
||||
style={tw.style(button({ variant, size, disabled }), style as string)}
|
||||
style={twStyle(button({ variant, size, disabled }), style as string)}
|
||||
{...otherProps}
|
||||
>
|
||||
{props.children}
|
||||
|
@ -61,7 +61,7 @@ export const AnimatedButton: FC<AnimatedButtonProps> = ({ variant, size, disable
|
|||
},
|
||||
[]
|
||||
)}
|
||||
style={tw.style(button({ variant, size, disabled }), style as string)}
|
||||
style={twStyle(button({ variant, size, disabled }), style as string)}
|
||||
// MotiPressable acts differently than Pressable so containerStyle might need to used to achieve the same effect
|
||||
containerStyle={containerStyle}
|
||||
{...otherProps}
|
||||
|
|
|
@ -6,7 +6,7 @@ type DividerProps = {
|
|||
};
|
||||
|
||||
const Divider = ({ style }: DividerProps) => {
|
||||
return <View style={[tw`w-full my-1 h-[1px] bg-app-line`, style]} />;
|
||||
return <View style={[tw`bg-app-line my-1 h-[1px] w-full`, style]} />;
|
||||
};
|
||||
|
||||
export default Divider;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { VariantProps, cva } from 'class-variance-authority';
|
||||
import { FC } from 'react';
|
||||
import { TextInputProps as RNTextInputProps, TextInput } from 'react-native';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
|
||||
const input = cva(['text-sm rounded-md border shadow-sm'], {
|
||||
const input = cva(['rounded-md border text-sm shadow-sm'], {
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-app border-app-line text-ink'
|
||||
default: 'border-app-line bg-app text-ink'
|
||||
},
|
||||
size: {
|
||||
default: ['py-2', 'px-3']
|
||||
|
@ -25,7 +25,7 @@ export const Input: FC<InputProps> = ({ variant, ...props }) => {
|
|||
return (
|
||||
<TextInput
|
||||
placeholderTextColor={tw.color('ink-dull')}
|
||||
style={tw.style(input({ variant }), style as string)}
|
||||
style={twStyle(input({ variant }), style as string)}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -19,7 +19,7 @@ export const Menu = (props: MenuProps) => (
|
|||
<View>
|
||||
<PMenu>
|
||||
<MenuTrigger>{props.trigger}</MenuTrigger>
|
||||
<MenuOptions optionsContainerStyle={tw`bg-app-menu p-1 rounded`}>
|
||||
<MenuOptions optionsContainerStyle={tw`bg-app-menu rounded p-1`}>
|
||||
{props.children}
|
||||
</MenuOptions>
|
||||
</PMenu>
|
||||
|
@ -43,7 +43,7 @@ export const MenuItem = ({ icon, ...props }: MenuItemProps) => {
|
|||
<MenuOption
|
||||
{...props}
|
||||
customStyles={{
|
||||
optionText: tw`text-ink text-sm font-medium py-0.5`
|
||||
optionText: tw`text-ink py-0.5 text-sm font-medium`
|
||||
}}
|
||||
style={tw`flex flex-row items-center`}
|
||||
/>
|
||||
|
|
|
@ -14,8 +14,8 @@ export const SwitchContainer: FC<SwitchContainerProps> = ({ title, description,
|
|||
return (
|
||||
<View style={tw`flex flex-row items-center justify-between pb-6`}>
|
||||
<View style={tw`w-[80%]`}>
|
||||
<Text style={tw`font-medium text-ink text-sm`}>{title}</Text>
|
||||
{description && <Text style={tw`text-ink-dull text-sm mt-2`}>{description}</Text>}
|
||||
<Text style={tw`text-ink text-sm font-medium`}>{title}</Text>
|
||||
{description && <Text style={tw`text-ink-dull mt-2 text-sm`}>{description}</Text>}
|
||||
</View>
|
||||
<Switch trackColor={{ false: tw.color('app-line'), true: tw.color('accent') }} {...props} />
|
||||
</View>
|
||||
|
|
|
@ -10,9 +10,9 @@ type SettingsContainerProps = PropsWithChildren<{
|
|||
export function SettingsContainer({ children, title, description }: SettingsContainerProps) {
|
||||
return (
|
||||
<View style={tw``}>
|
||||
{title && <Text style={tw`pb-2 pl-3 text-sm font-semibold text-ink-dull`}>{title}</Text>}
|
||||
{title && <Text style={tw`text-ink-dull pb-2 pl-3 text-sm font-semibold`}>{title}</Text>}
|
||||
{children}
|
||||
{description && <Text style={tw`text-ink-dull text-sm px-3 pt-2`}>{description}</Text>}
|
||||
{description && <Text style={tw`text-ink-dull px-3 pt-2 text-sm`}>{description}</Text>}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ type SettingsItemProps = {
|
|||
export function SettingsItem(props: SettingsItemProps) {
|
||||
return (
|
||||
<Pressable onPress={props.onPress}>
|
||||
<View style={tw`flex flex-row items-center justify-between px-3 bg-app-overlay`}>
|
||||
<View style={tw`bg-app-overlay flex flex-row items-center justify-between px-3`}>
|
||||
<View style={tw`flex flex-row items-center py-4`}>
|
||||
{props.leftIcon && props.leftIcon({ size: 18, color: tw.color('ink'), style: tw`mr-2` })}
|
||||
<Text style={tw`text-sm text-ink`}>{props.title}</Text>
|
||||
<Text style={tw`text-ink text-sm`}>{props.title}</Text>
|
||||
</View>
|
||||
{props.rightArea ? props.rightArea : <CaretRight size={20} color={tw.color('ink-faint')} />}
|
||||
</View>
|
||||
|
@ -26,7 +26,7 @@ export function SettingsItem(props: SettingsItemProps) {
|
|||
export function SettingsItemDivider() {
|
||||
return (
|
||||
<View style={tw`bg-app-overlay`}>
|
||||
<View style={tw`mx-3 border-b border-b-app-line`} />
|
||||
<View style={tw`border-b-app-line mx-3 border-b`} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { ScrollView, Text, View } from 'react-native';
|
|||
import RNFS from 'react-native-fs';
|
||||
import { Statistics, useLibraryQuery } from '@sd/client';
|
||||
import useCounter from '../hooks/useCounter';
|
||||
import tw from '../lib/tailwind';
|
||||
import tw, { twStyle } from '../lib/tailwind';
|
||||
|
||||
const StatItemNames: Partial<Record<keyof Statistics, string>> = {
|
||||
total_bytes_capacity: 'Total capacity',
|
||||
|
@ -21,8 +21,8 @@ const StatItem: FC<{ title: string; bytes: bigint }> = ({ title, bytes }) => {
|
|||
return (
|
||||
<View style={tw`flex flex-col p-4`}>
|
||||
<Text style={tw`text-sm text-gray-400`}>{title}</Text>
|
||||
<View style={tw`flex-row items-baseline mt-1`}>
|
||||
<Text style={tw.style('text-2xl font-bold text-white tabular-nums')}>{count}</Text>
|
||||
<View style={tw`mt-1 flex-row items-baseline`}>
|
||||
<Text style={twStyle('text-2xl font-bold tabular-nums text-white')}>{count}</Text>
|
||||
<Text style={tw`ml-1 text-sm text-gray-400`}>{unit}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -64,7 +64,7 @@ const OverviewStats = () => {
|
|||
</ScrollView>
|
||||
) : (
|
||||
<View>
|
||||
<Text style={tw`text-red-600 text-center font-bold`}>No library found...</Text>
|
||||
<Text style={tw`text-center font-bold text-red-600`}>No library found...</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ import ColorPicker from 'react-native-wheel-color-picker';
|
|||
import { queryClient, useLibraryMutation } from '@sd/client';
|
||||
import Dialog from '~/components/layout/Dialog';
|
||||
import { Input } from '~/components/primitive/Input';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
|
||||
type Props = {
|
||||
onSubmit?: () => void;
|
||||
|
@ -57,17 +57,17 @@ const CreateTagDialog = ({ children, onSubmit, disableBackdropClose }: Props) =>
|
|||
<View style={tw`flex flex-row items-center`}>
|
||||
<Pressable
|
||||
onPress={() => setShowPicker((v) => !v)}
|
||||
style={tw.style({ backgroundColor: tagColor }, 'w-5 h-5 rounded-full')}
|
||||
style={twStyle({ backgroundColor: tagColor }, 'h-5 w-5 rounded-full')}
|
||||
/>
|
||||
<Input
|
||||
style={tw`flex-1 ml-2`}
|
||||
style={tw`ml-2 flex-1`}
|
||||
value={tagName}
|
||||
onChangeText={(text) => setTagName(text)}
|
||||
placeholder="Name"
|
||||
/>
|
||||
</View>
|
||||
{showPicker && (
|
||||
<View style={tw`h-64 mt-4`}>
|
||||
<View style={tw`my-4 h-64`}>
|
||||
<ColorPicker
|
||||
autoResetSlider
|
||||
gapSize={0}
|
||||
|
|
|
@ -4,7 +4,7 @@ import ColorPicker from 'react-native-wheel-color-picker';
|
|||
import { Tag, queryClient, useLibraryMutation } from '@sd/client';
|
||||
import Dialog from '~/components/layout/Dialog';
|
||||
import { Input } from '~/components/primitive/Input';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
|
||||
type Props = {
|
||||
tag: Tag;
|
||||
|
@ -48,20 +48,20 @@ const UpdateTagDialog = ({ children, onSubmit, tag }: Props) => {
|
|||
setShowPicker(false); // Reset form
|
||||
}}
|
||||
>
|
||||
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1 mt-3`}>Name</Text>
|
||||
<Text style={tw`text-ink-dull mb-1 ml-1 mt-3 text-xs font-medium`}>Name</Text>
|
||||
<Input value={tagName} onChangeText={(t) => setTagName(t)} />
|
||||
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1 mt-3`}>Color</Text>
|
||||
<View style={tw`flex flex-row items-center ml-2`}>
|
||||
<Text style={tw`text-ink-dull mb-1 ml-1 mt-3 text-xs font-medium`}>Color</Text>
|
||||
<View style={tw`ml-2 flex flex-row items-center`}>
|
||||
<Pressable
|
||||
onPress={() => setShowPicker((v) => !v)}
|
||||
style={tw.style({ backgroundColor: tagColor }, 'w-5 h-5 rounded-full')}
|
||||
style={twStyle({ backgroundColor: tagColor }, 'h-5 w-5 rounded-full')}
|
||||
/>
|
||||
{/* TODO: Make this editable. Need to make sure color is a valid hexcode and update the color on picker etc. etc. */}
|
||||
<Input editable={false} value={tagColor} style={tw`flex-1 ml-2`} />
|
||||
<Input editable={false} value={tagColor} style={tw`ml-2 flex-1`} />
|
||||
</View>
|
||||
|
||||
{showPicker && (
|
||||
<View style={tw`h-64 mt-4`}>
|
||||
<View style={tw`mt-4 h-64`}>
|
||||
<ColorPicker
|
||||
autoResetSlider
|
||||
gapSize={0}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { DrawerContentComponentProps } from '@react-navigation/drawer/lib/typesc
|
|||
import { Gear } from 'phosphor-react-native';
|
||||
import { Image, Platform, Pressable, Text, View } from 'react-native';
|
||||
import Layout from '~/constants/Layout';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { getStackNameFromState } from '~/utils/nav';
|
||||
import Divider from '../../components/primitive/Divider';
|
||||
import DrawerLibraryManager from './DrawerLibraryManager';
|
||||
|
@ -20,11 +20,11 @@ const DrawerContent = ({ navigation, state }: DrawerContentComponentProps) => {
|
|||
|
||||
return (
|
||||
<DrawerContentScrollView style={tw`flex-1 px-4 py-2`} scrollEnabled={false}>
|
||||
<View style={tw.style('justify-between', { height: drawerHeight })}>
|
||||
<View style={twStyle('justify-between', { height: drawerHeight })}>
|
||||
<View>
|
||||
<View style={tw`flex flex-row items-center`}>
|
||||
<Image source={require('@sd/assets/images/logo.png')} style={tw`w-[35px] h-[35px]`} />
|
||||
<Text style={tw`text-base font-bold text-ink ml-2`}>Spacedrive</Text>
|
||||
<Image source={require('@sd/assets/images/logo.png')} style={tw`h-[35px] w-[35px]`} />
|
||||
<Text style={tw`text-ink ml-2 text-base font-bold`}>Spacedrive</Text>
|
||||
</View>
|
||||
<Divider style={tw`my-4`} />
|
||||
{/* Library Manager */}
|
||||
|
|
|
@ -5,7 +5,7 @@ import { CaretRight, Gear, Lock, Plus } from 'phosphor-react-native';
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Pressable, Text, View } from 'react-native';
|
||||
import { useCurrentLibrary } from '~/../../../packages/client/src';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { AnimatedHeight } from '../../components/animation/layout';
|
||||
import Divider from '../../components/primitive/Divider';
|
||||
import CreateLibraryDialog from '../dialog/CreateLibraryDialog';
|
||||
|
@ -27,9 +27,9 @@ const DrawerLibraryManager = () => {
|
|||
<View>
|
||||
<Pressable onPress={() => setDropdownClosed((v) => !v)}>
|
||||
<View
|
||||
style={tw.style(
|
||||
'flex flex-row justify-between items-center px-3 h-10 w-full bg-app-box border border-app-darkLine shadow-sm',
|
||||
dropdownClosed ? 'rounded' : 'rounded-t border-b-app-box'
|
||||
style={twStyle(
|
||||
'border-app-darkLine bg-app-box flex h-10 w-full flex-row items-center justify-between border px-3 shadow-sm',
|
||||
dropdownClosed ? 'rounded' : 'border-b-app-box rounded-t'
|
||||
)}
|
||||
>
|
||||
<Text style={tw`text-ink text-sm font-semibold`}>{currentLibrary?.config.name}</Text>
|
||||
|
@ -44,21 +44,19 @@ const DrawerLibraryManager = () => {
|
|||
</View>
|
||||
</Pressable>
|
||||
<AnimatedHeight hide={dropdownClosed}>
|
||||
<View
|
||||
style={tw`py-2 px-2 bg-app-box border-l border-b border-r border-app-darkLine rounded-b`}
|
||||
>
|
||||
<View style={tw`border-app-darkLine bg-app-box rounded-b border-x border-b p-2`}>
|
||||
{/* Libraries */}
|
||||
{libraries?.map((library) => (
|
||||
<Pressable key={library.uuid} onPress={() => switchLibrary(library.uuid)}>
|
||||
<View
|
||||
style={tw.style(
|
||||
'p-2 mt-1',
|
||||
style={twStyle(
|
||||
'mt-1 p-2',
|
||||
currentLibrary.uuid === library.uuid && 'bg-accent rounded'
|
||||
)}
|
||||
>
|
||||
<Text
|
||||
style={tw.style(
|
||||
'text-sm text-ink font-semibold',
|
||||
style={twStyle(
|
||||
'text-ink text-sm font-semibold',
|
||||
currentLibrary.uuid === library.uuid && 'text-white'
|
||||
)}
|
||||
>
|
||||
|
@ -67,27 +65,27 @@ const DrawerLibraryManager = () => {
|
|||
</View>
|
||||
</Pressable>
|
||||
))}
|
||||
<Divider style={tw`mt-2 mb-2`} />
|
||||
<Divider style={tw`my-2`} />
|
||||
{/* Menu */}
|
||||
<Pressable
|
||||
onPress={() => navigation.navigate('Settings', { screen: 'LibraryGeneralSettings' })}
|
||||
>
|
||||
<View style={tw`flex flex-row items-center px-1.5 py-[8px]`}>
|
||||
<Gear size={16} color={tw.color('ink-dull')} style={tw`mr-2`} />
|
||||
<Text style={tw`text-sm text-ink font-semibold`}>Library Settings</Text>
|
||||
<Text style={tw`text-ink text-sm font-semibold`}>Library Settings</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
{/* Create Library */}
|
||||
<CreateLibraryDialog>
|
||||
<View style={tw`flex flex-row items-center px-1.5 py-[8px]`}>
|
||||
<Plus size={16} weight="bold" color={tw.color('ink-dull')} style={tw`mr-2`} />
|
||||
<Text style={tw`text-sm text-ink font-semibold`}>Add Library</Text>
|
||||
<Text style={tw`text-ink text-sm font-semibold`}>Add Library</Text>
|
||||
</View>
|
||||
</CreateLibraryDialog>
|
||||
<Pressable onPress={() => console.log('TODO: lock')}>
|
||||
<View style={tw`flex flex-row items-center px-1.5 py-[8px]`}>
|
||||
<Lock size={16} weight="bold" color={tw.color('ink-dull')} style={tw`mr-2`} />
|
||||
<Text style={tw`text-sm text-ink font-semibold`}>Lock</Text>
|
||||
<Text style={tw`text-ink text-sm font-semibold`}>Lock</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
</View>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useNavigation } from '@react-navigation/native';
|
|||
import { useRef } from 'react';
|
||||
import { Pressable, Text, View } from 'react-native';
|
||||
import { useLibraryQuery } from '@sd/client';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import FolderIcon from '../../components/icons/FolderIcon';
|
||||
import CollapsibleView from '../../components/layout/CollapsibleView';
|
||||
import ImportModal from '../modal/ImportModal';
|
||||
|
@ -19,9 +19,9 @@ const DrawerLocationItem: React.FC<DrawerLocationItemProps> = (props) => {
|
|||
|
||||
return (
|
||||
<Pressable onPress={onPress}>
|
||||
<View style={tw.style('flex mb-[4px] flex-row items-center py-2 px-1 rounded')}>
|
||||
<View style={twStyle('mb-[4px] flex flex-row items-center rounded py-2 px-1')}>
|
||||
<FolderIcon size={18} />
|
||||
<Text style={tw.style('text-gray-300 text-sm font-medium ml-2')} numberOfLines={1}>
|
||||
<Text style={twStyle('ml-2 text-sm font-medium text-gray-300')} numberOfLines={1}>
|
||||
{folderName}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -63,10 +63,8 @@ const DrawerLocations = ({ stackName }: DrawerLocationsProp) => {
|
|||
</View>
|
||||
{/* Add Location */}
|
||||
<Pressable onPress={() => importModalRef.current.present()}>
|
||||
<View style={tw`border border-dashed rounded border-app-line border-opacity-80 mt-1`}>
|
||||
<Text style={tw`text-xs font-bold text-center text-gray-400 px-2 py-2`}>
|
||||
Add Location
|
||||
</Text>
|
||||
<View style={tw`border-opacity/80 border-app-line mt-1 rounded border border-dashed`}>
|
||||
<Text style={tw`p-2 text-center text-xs font-bold text-gray-400`}>Add Location</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
</CollapsibleView>
|
||||
|
|
|
@ -2,7 +2,7 @@ import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript
|
|||
import { useNavigation } from '@react-navigation/native';
|
||||
import { ColorValue, Pressable, Text, View } from 'react-native';
|
||||
import { useLibraryQuery } from '@sd/client';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import CollapsibleView from '../../components/layout/CollapsibleView';
|
||||
import CreateTagDialog from '../dialog/tag/CreateTagDialog';
|
||||
|
||||
|
@ -16,9 +16,9 @@ const DrawerTagItem: React.FC<DrawerTagItemProps> = (props) => {
|
|||
const { tagName, tagColor, onPress } = props;
|
||||
return (
|
||||
<Pressable onPress={onPress}>
|
||||
<View style={tw.style('flex mb-[4px] flex-row items-center py-2 px-1 rounded')}>
|
||||
<View style={tw.style('w-3 h-3 rounded-full', { backgroundColor: tagColor })} />
|
||||
<Text style={tw.style('text-gray-300 text-sm font-medium ml-2')} numberOfLines={1}>
|
||||
<View style={twStyle('mb-[4px] flex flex-row items-center rounded py-2 px-1')}>
|
||||
<View style={twStyle('h-3 w-3 rounded-full', { backgroundColor: tagColor })} />
|
||||
<Text style={twStyle('ml-2 text-sm font-medium text-gray-300')} numberOfLines={1}>
|
||||
{tagName}
|
||||
</Text>
|
||||
</View>
|
||||
|
@ -58,8 +58,8 @@ const DrawerTags = ({ stackName }: DrawerTagsProp) => {
|
|||
</View>
|
||||
{/* Add Tag */}
|
||||
<CreateTagDialog>
|
||||
<View style={tw`border border-dashed rounded border-app-line border-opacity-80 mt-1`}>
|
||||
<Text style={tw`text-xs font-bold text-center text-gray-400 px-2 py-2`}>Add Tag</Text>
|
||||
<View style={tw`border-opacity/80 border-app-line mt-1 rounded border border-dashed`}>
|
||||
<Text style={tw`p-2 text-center text-xs font-bold text-gray-400`}>Add Tag</Text>
|
||||
</View>
|
||||
</CreateTagDialog>
|
||||
</CollapsibleView>
|
||||
|
|
|
@ -24,7 +24,7 @@ const SortByMenu = () => {
|
|||
<Menu
|
||||
trigger={
|
||||
<View style={tw`flex flex-row items-center`}>
|
||||
<Text style={tw`text-ink font-medium mr-0.5`}>{sortOptions[sortBy]}</Text>
|
||||
<Text style={tw`text-ink mr-0.5 font-medium`}>{sortOptions[sortBy]}</Text>
|
||||
{sortDirection === 'asc' ? <ArrowUpIcon /> : <ArrowDownIcon />}
|
||||
</View>
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ function MetaItem({ title, value }: MetaItemProps) {
|
|||
return (
|
||||
<View>
|
||||
<Text style={tw`text-sm font-bold text-white`}>{title}</Text>
|
||||
<Text style={tw`text-sm text-gray-400 mt-1`}>{value}</Text>
|
||||
<Text style={tw`mt-1 text-sm text-gray-400`}>{value}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -34,14 +34,14 @@ export const FileModal = () => {
|
|||
<>
|
||||
<Modal ref={fileRef} snapPoints={['60%', '90%']}>
|
||||
{data && (
|
||||
<View style={tw`flex-1 p-4 bg-app`}>
|
||||
<View style={tw`bg-app flex-1 p-4`}>
|
||||
{/* File Icon / Name */}
|
||||
<View style={tw`flex flex-row items-center`}>
|
||||
<FileIcon data={data} size={1.6} />
|
||||
{/* File Name, Details etc. */}
|
||||
<View style={tw`ml-2`}>
|
||||
<Text style={tw`text-base font-bold text-gray-200`}>{item.name}</Text>
|
||||
<View style={tw`flex flex-row mt-2`}>
|
||||
<View style={tw`mt-2 flex flex-row`}>
|
||||
<Text style={tw`text-xs text-gray-400`}>5 MB,</Text>
|
||||
<Text style={tw`ml-1 text-xs text-gray-400`}>
|
||||
{item.extension.toUpperCase()},
|
||||
|
@ -49,7 +49,7 @@ export const FileModal = () => {
|
|||
<Text style={tw`ml-1 text-xs text-gray-400`}>15 Aug</Text>
|
||||
</View>
|
||||
<Pressable style={tw`mt-2`} onPress={() => fileDetailsRef.current.present()}>
|
||||
<Text style={tw`text-sm text-accent`}>More</Text>
|
||||
<Text style={tw`text-accent text-sm`}>More</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -71,15 +71,15 @@ export const FileModal = () => {
|
|||
snapPoints={['70%']}
|
||||
>
|
||||
{data && (
|
||||
<BottomSheetScrollView style={tw`flex-1 p-4 bg-app`}>
|
||||
<BottomSheetScrollView style={tw`bg-app flex-1 p-4`}>
|
||||
{/* Back Button */}
|
||||
<Pressable style={tw`w-full ml-4`} onPress={() => fileDetailsRef.current.close()}>
|
||||
<Pressable style={tw`ml-4 w-full`} onPress={() => fileDetailsRef.current.close()}>
|
||||
<CaretLeft color={tw.color('accent')} size={20} />
|
||||
</Pressable>
|
||||
{/* File Icon / Name */}
|
||||
<View style={tw`items-center`}>
|
||||
<FileThumb data={data} size={1.8} />
|
||||
<Text style={tw`text-base font-bold text-gray-200 mt-3`}>{item.name}</Text>
|
||||
<Text style={tw`mt-3 text-base font-bold text-gray-200`}>{item.name}</Text>
|
||||
</View>
|
||||
{/* Details */}
|
||||
<Divider style={tw`mt-6 mb-4`} />
|
||||
|
|
|
@ -126,7 +126,7 @@ const ImportModal = forwardRef<BottomSheetModal, unknown>((_, ref) => {
|
|||
|
||||
return (
|
||||
<Modal ref={modalRef} snapPoints={['20%']}>
|
||||
<View style={tw`flex-1 px-6 pt-1 pb-2 bg-app-box`}>
|
||||
<View style={tw`bg-app-box flex-1 px-6 pt-1 pb-2`}>
|
||||
{/* <Button size="md" variant="accent" style={tw`my-2`} onPress={testFN}>
|
||||
<Text>TEST</Text>
|
||||
</Button> */}
|
||||
|
|
|
@ -3,3 +3,4 @@ import { create } from 'twrnc';
|
|||
const tw = create(require(`../../tailwind.config.js`));
|
||||
|
||||
export default tw;
|
||||
export const twStyle = tw.style;
|
||||
|
|
|
@ -36,7 +36,7 @@ export default function TabNavigator() {
|
|||
/>
|
||||
),
|
||||
tabBarLabel: 'Overview',
|
||||
tabBarLabelStyle: tw`font-semibold text-tiny`
|
||||
tabBarLabelStyle: tw`text-tiny font-semibold`
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
|
@ -51,7 +51,7 @@ export default function TabNavigator() {
|
|||
/>
|
||||
),
|
||||
tabBarLabel: 'Nodes',
|
||||
tabBarLabelStyle: tw`font-semibold text-tiny`
|
||||
tabBarLabelStyle: tw`text-tiny font-semibold`
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
|
@ -66,7 +66,7 @@ export default function TabNavigator() {
|
|||
/>
|
||||
),
|
||||
tabBarLabel: 'Spaces',
|
||||
tabBarLabelStyle: tw`font-semibold text-tiny`
|
||||
tabBarLabelStyle: tw`text-tiny font-semibold`
|
||||
}}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { NodesStackScreenProps } from '~/navigation/tabs/NodesStack';
|
|||
export default function NodesScreen({ navigation }: NodesStackScreenProps<'Nodes'>) {
|
||||
return (
|
||||
<View style={tw`flex-1 items-center justify-center`}>
|
||||
<Text style={tw`font-bold text-xl text-ink`}>Nodes</Text>
|
||||
<Text style={tw`text-ink text-xl font-bold`}>Nodes</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ import { RootStackScreenProps } from '~/navigation';
|
|||
export default function NotFoundScreen({ navigation }: RootStackScreenProps<'NotFound'>) {
|
||||
return (
|
||||
<View style={tw`flex-1 items-center justify-center p-5`}>
|
||||
<Text style={tw`font-bold text-xl`}>This screen doesn't exist.</Text>
|
||||
<Text style={tw`text-xl font-bold`}>This screen doesn't exist.</Text>
|
||||
<TouchableOpacity onPress={() => navigation.replace('Root')} style={tw`mt-4 py-4`}>
|
||||
<Text style={tw`text-sm text-ink-dull`}>Go to home screen!</Text>
|
||||
<Text style={tw`text-ink-dull text-sm`}>Go to home screen!</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -34,7 +34,7 @@ import { OverviewStackScreenProps } from '~/navigation/tabs/OverviewStack';
|
|||
export default function OverviewScreen({ navigation }: OverviewStackScreenProps<'Overview'>) {
|
||||
return (
|
||||
<VirtualizedListWrapper>
|
||||
<View style={tw`px-4 mt-4`}>
|
||||
<View style={tw`mt-4 px-4`}>
|
||||
{/* Stats */}
|
||||
<OverviewStats />
|
||||
{/* Devices */}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useState } from 'react';
|
|||
import { ActivityIndicator, Pressable, Text, TextInput, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { Button } from '~/components/primitive/Button';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { RootStackScreenProps } from '~/navigation';
|
||||
|
||||
const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
|
||||
|
@ -14,12 +14,12 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
|
|||
// TODO: Animations!
|
||||
|
||||
return (
|
||||
<View style={tw.style('flex-1', { marginTop: top + 10 })}>
|
||||
<View style={twStyle('flex-1', { marginTop: top + 10 })}>
|
||||
{/* Header */}
|
||||
<View style={tw`flex flex-row items-center mx-4`}>
|
||||
<View style={tw`mx-4 flex flex-row items-center`}>
|
||||
{/* Search Input */}
|
||||
<View style={tw`flex-1 bg-app-overlay border border-app-line rounded h-10 mr-3`}>
|
||||
<View style={tw`flex flex-row h-full items-center px-3`}>
|
||||
<View style={tw`border-app-line bg-app-overlay mr-3 h-10 flex-1 rounded border`}>
|
||||
<View style={tw`flex h-full flex-row items-center px-3`}>
|
||||
<View style={tw`mr-3`}>
|
||||
{loading ? (
|
||||
<ActivityIndicator size={'small'} color={'white'} />
|
||||
|
@ -32,7 +32,7 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
|
|||
clearButtonMode="never" // can't change the color??
|
||||
underlineColorAndroid="transparent"
|
||||
placeholderTextColor={tw.color('ink-dull')}
|
||||
style={tw`flex-1 text-ink font-medium text-sm`}
|
||||
style={tw`text-ink flex-1 text-sm font-medium`}
|
||||
textContentType={'none'}
|
||||
autoFocus
|
||||
autoCapitalize="none"
|
||||
|
@ -46,7 +46,7 @@ const SearchScreen = ({ navigation }: RootStackScreenProps<'Search'>) => {
|
|||
</Pressable>
|
||||
</View>
|
||||
{/* Content */}
|
||||
<View style={tw`flex-1 items-center mt-8`}>
|
||||
<View style={tw`mt-8 flex-1 items-center`}>
|
||||
<Button variant="accent" onPress={() => setLoading((v) => !v)}>
|
||||
<Text>Toggle loading</Text>
|
||||
</Button>
|
||||
|
|
|
@ -4,8 +4,8 @@ import { SpacesStackScreenProps } from '~/navigation/tabs/SpacesStack';
|
|||
|
||||
export default function SpacesScreen({ navigation }: SpacesStackScreenProps<'Spaces'>) {
|
||||
return (
|
||||
<View style={tw`items-center justify-center flex-1`}>
|
||||
<Text style={tw`text-xl font-bold text-ink`}>Spaces</Text>
|
||||
<View style={tw`flex-1 items-center justify-center`}>
|
||||
<Text style={tw`text-ink text-xl font-bold`}>Spaces</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ export default function TagScreen({ navigation, route }: SharedScreenProps<'Tag'
|
|||
|
||||
return (
|
||||
<View style={tw`flex-1 items-center justify-center`}>
|
||||
<Text style={tw`font-bold text-xl text-ink`}>Tag {id}</Text>
|
||||
<Text style={tw`text-ink text-xl font-bold`}>Tag {id}</Text>
|
||||
<Explorer data={data} />
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -6,13 +6,13 @@ import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
|
|||
|
||||
const CreateLibraryScreen = ({ navigation }: OnboardingStackScreenProps<'CreateLibrary'>) => {
|
||||
return (
|
||||
<View style={tw`flex-1 items-center justify-center bg-app p-4`}>
|
||||
<Text style={tw`text-ink-dull text-center px-6 my-8 text-base leading-relaxed`}>
|
||||
<View style={tw`bg-app flex-1 items-center justify-center p-4`}>
|
||||
<Text style={tw`text-ink-dull my-8 px-6 text-center text-base leading-relaxed`}>
|
||||
Onboarding screen for users to create their first library
|
||||
</Text>
|
||||
<CreateLibraryDialog disableBackdropClose>
|
||||
<AnimatedButton variant="accent">
|
||||
<Text style={tw`text-ink text-center px-6 py-2 text-base font-medium`}>
|
||||
<Text style={tw`text-ink px-6 py-2 text-center text-base font-medium`}>
|
||||
Create Library
|
||||
</Text>
|
||||
</AnimatedButton>
|
||||
|
|
|
@ -6,11 +6,11 @@ import { OnboardingStackScreenProps } from '~/navigation/OnboardingNavigator';
|
|||
|
||||
const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding'>) => {
|
||||
return (
|
||||
<View style={tw`flex-1 items-center justify-around bg-app p-4 z-10`}>
|
||||
<View style={tw`bg-app z-10 flex-1 items-center justify-around p-4`}>
|
||||
{/* Logo */}
|
||||
<LogoAnimation>
|
||||
<View style={tw`items-center mt-2`}>
|
||||
<Image source={require('@sd/assets/images/logo.png')} style={tw`w-24 h-24`} />
|
||||
<View style={tw`mt-2 items-center`}>
|
||||
<Image source={require('@sd/assets/images/logo.png')} style={tw`h-24 w-24`} />
|
||||
</View>
|
||||
</LogoAnimation>
|
||||
{/* Text */}
|
||||
|
@ -21,7 +21,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding
|
|||
</Text>
|
||||
</FadeInUpAnimation>
|
||||
<FadeInUpAnimation delay={800}>
|
||||
<Text style={tw`text-ink-dull text-center px-6 mt-8 text-base leading-relaxed`}>
|
||||
<Text style={tw`text-ink-dull mt-8 px-6 text-center text-base leading-relaxed`}>
|
||||
Combine your drives and clouds into one database that you can organize and explore from
|
||||
any device.
|
||||
</Text>
|
||||
|
@ -30,7 +30,7 @@ const OnboardingScreen = ({ navigation }: OnboardingStackScreenProps<'Onboarding
|
|||
{/* Get Started Button */}
|
||||
<FadeInUpAnimation delay={1200}>
|
||||
<AnimatedButton variant="accent" onPress={() => navigation.navigate('CreateLibrary')}>
|
||||
<Text style={tw`text-ink text-center px-6 py-2 text-base font-medium`}>Get Started</Text>
|
||||
<Text style={tw`text-ink px-6 py-2 text-center text-base font-medium`}>Get Started</Text>
|
||||
</AnimatedButton>
|
||||
</FadeInUpAnimation>
|
||||
</View>
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
import React from 'react';
|
||||
import { SectionList, Text, View } from 'react-native';
|
||||
import { SettingsItem, SettingsItemDivider } from '~/components/settings/SettingsItem';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { SettingsStackParamList, SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
|
||||
|
||||
type SectionType = {
|
||||
|
@ -108,8 +108,8 @@ const sections: SectionType[] = [
|
|||
function renderSectionHeader({ section }: { section: { title: string } }) {
|
||||
return (
|
||||
<Text
|
||||
style={tw.style(
|
||||
'mb-2 ml-2 text-sm font-semibold text-ink-dull',
|
||||
style={twStyle(
|
||||
'text-ink-dull mb-2 ml-2 text-sm font-semibold',
|
||||
section.title === 'Client' ? 'mt-2' : 'mt-5'
|
||||
)}
|
||||
>
|
||||
|
@ -134,9 +134,9 @@ export default function SettingsScreen({ navigation }: SettingsStackScreenProps<
|
|||
)}
|
||||
renderSectionHeader={renderSectionHeader}
|
||||
ListFooterComponent={
|
||||
<View style={tw`items-center mt-6 mb-4`}>
|
||||
<Text style={tw`text-sm font-bold text-ink`}>Spacedrive</Text>
|
||||
<Text style={tw`text-ink-dull text-xs mt-0.5`}>v0.1.0</Text>
|
||||
<View style={tw`mt-6 mb-4 items-center`}>
|
||||
<Text style={tw`text-ink text-sm font-bold`}>Spacedrive</Text>
|
||||
<Text style={tw`text-ink-dull mt-0.5 text-xs`}>v0.1.0</Text>
|
||||
</View>
|
||||
}
|
||||
showsVerticalScrollIndicator={false}
|
||||
|
|
|
@ -17,24 +17,24 @@ const GeneralSettingsScreen = ({ navigation }: SettingsStackScreenProps<'General
|
|||
<Card>
|
||||
{/* Card Header */}
|
||||
<View style={tw`flex flex-row justify-between`}>
|
||||
<Text style={tw`font-semibold text-ink`}>Connected Node</Text>
|
||||
<Text style={tw`text-ink font-semibold`}>Connected Node</Text>
|
||||
<View style={tw`flex flex-row`}>
|
||||
{/* Peers */}
|
||||
<View style={tw`rounded bg-app-highlight self-start px-1.5 py-[2px] mr-2`}>
|
||||
<Text style={tw`text-xs font-semibold text-ink`}>0 Peers</Text>
|
||||
<View style={tw`bg-app-highlight mr-2 self-start rounded px-1.5 py-[2px]`}>
|
||||
<Text style={tw`text-ink text-xs font-semibold`}>0 Peers</Text>
|
||||
</View>
|
||||
{/* Status */}
|
||||
<View style={tw`px-1.5 py-[2px] rounded bg-accent`}>
|
||||
<Text style={tw`text-xs font-semibold text-ink`}>Running</Text>
|
||||
<View style={tw`bg-accent rounded px-1.5 py-[2px]`}>
|
||||
<Text style={tw`text-ink text-xs font-semibold`}>Running</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
{/* Divider */}
|
||||
<Divider style={tw`mt-2 mb-4`} />
|
||||
{/* Node Name and Port */}
|
||||
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1`}>Node Name</Text>
|
||||
<Text style={tw`text-ink-dull mb-1 ml-1 text-xs font-medium`}>Node Name</Text>
|
||||
<Input value={node.name} />
|
||||
<Text style={tw`mt-2 mb-1 text-xs font-medium text-ink-dull ml-1`}>Node Port</Text>
|
||||
<Text style={tw`text-ink-dull mt-2 mb-1 ml-1 text-xs font-medium`}>Node Port</Text>
|
||||
<Input value={node.p2p_port?.toString() ?? '5795'} keyboardType="numeric" />
|
||||
</Card>
|
||||
</View>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Swipeable } from 'react-native-gesture-handler';
|
|||
import { LibraryConfigWrapped, useBridgeQuery } from '@sd/client';
|
||||
import { AnimatedButton } from '~/components/primitive/Button';
|
||||
import DeleteLibraryDialog from '~/containers/dialog/DeleteLibraryDialog';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
|
||||
|
||||
function LibraryItem({
|
||||
|
@ -45,17 +45,17 @@ function LibraryItem({
|
|||
|
||||
return (
|
||||
<Swipeable
|
||||
containerStyle={tw.style(
|
||||
containerStyle={twStyle(
|
||||
index !== 0 && 'mt-2',
|
||||
'bg-app-overlay border border-app-line rounded-lg px-4 py-3'
|
||||
'border-app-line bg-app-overlay rounded-lg border px-4 py-3'
|
||||
)}
|
||||
enableTrackpadTwoFingerGesture
|
||||
renderRightActions={renderRightActions}
|
||||
>
|
||||
<View style={tw`flex flex-row items-center justify-between`}>
|
||||
<View>
|
||||
<Text style={tw`font-semibold text-ink`}>{library.config.name}</Text>
|
||||
<Text style={tw`mt-0.5 text-xs text-ink-dull`}>{library.uuid}</Text>
|
||||
<Text style={tw`text-ink font-semibold`}>{library.config.name}</Text>
|
||||
<Text style={tw`text-ink-dull mt-0.5 text-xs`}>{library.uuid}</Text>
|
||||
</View>
|
||||
<CaretRight color={tw.color('ink-dull')} size={18} />
|
||||
</View>
|
||||
|
@ -67,7 +67,7 @@ const LibrarySettingsScreen = ({ navigation }: SettingsStackScreenProps<'Library
|
|||
const { data: libraries } = useBridgeQuery(['library.list']);
|
||||
|
||||
return (
|
||||
<View style={tw`py-4 px-3 flex-1`}>
|
||||
<View style={tw`flex-1 py-4 px-3`}>
|
||||
<FlatList
|
||||
data={libraries}
|
||||
keyExtractor={(item) => item.uuid}
|
||||
|
|
|
@ -32,8 +32,8 @@ const LibraryGeneralSettingsScreen = ({
|
|||
return (
|
||||
<View>
|
||||
{/* This looks bad... */}
|
||||
<View style={tw`mt-4 px-2 py-4 bg-app-overlay`}>
|
||||
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1`}>Name</Text>
|
||||
<View style={tw`bg-app-overlay mt-4 px-2 py-4`}>
|
||||
<Text style={tw`text-ink-dull mb-1 ml-1 text-xs font-medium`}>Name</Text>
|
||||
<Controller
|
||||
name="name"
|
||||
control={form.control}
|
||||
|
@ -42,7 +42,7 @@ const LibraryGeneralSettingsScreen = ({
|
|||
)}
|
||||
/>
|
||||
{/* Description */}
|
||||
<Text style={tw`mb-1 text-xs font-medium text-ink-dull ml-1 mt-3`}>Description</Text>
|
||||
<Text style={tw`text-ink-dull mb-1 ml-1 mt-3 text-xs font-medium`}>Description</Text>
|
||||
<Controller
|
||||
name="description"
|
||||
control={form.control}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from '@sd/client';
|
||||
import FolderIcon from '~/components/icons/FolderIcon';
|
||||
import DeleteLocationDialog from '~/containers/dialog/DeleteLocationDialog';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
|
||||
|
||||
function LocationItem({ location, index }: { location: Location & { node: Node }; index: number }) {
|
||||
|
@ -36,14 +36,14 @@ function LocationItem({ location, index }: { location: Location & { node: Node }
|
|||
>
|
||||
<DeleteLocationDialog locationId={location.id}>
|
||||
<View
|
||||
style={tw`py-1.5 px-3 bg-app-button border-app-line border rounded-md items-center justify-center shadow-sm`}
|
||||
style={tw`border-app-line bg-app-button items-center justify-center rounded-md border py-1.5 px-3 shadow-sm`}
|
||||
>
|
||||
<Trash size={18} color="white" />
|
||||
</View>
|
||||
</DeleteLocationDialog>
|
||||
{/* Full Re-scan IS too much here */}
|
||||
<Pressable
|
||||
style={tw`py-1.5 px-3 bg-app-button border-app-line border rounded-md items-center justify-center shadow-sm mx-2`}
|
||||
style={tw`border-app-line bg-app-button mx-2 items-center justify-center rounded-md border py-1.5 px-3 shadow-sm`}
|
||||
onPress={() => fullRescan.mutate(location.id)}
|
||||
>
|
||||
<Repeat size={18} color="white" />
|
||||
|
@ -54,8 +54,8 @@ function LocationItem({ location, index }: { location: Location & { node: Node }
|
|||
|
||||
return (
|
||||
<Swipeable
|
||||
containerStyle={tw.style(
|
||||
'bg-app-overlay border border-app-line rounded-lg px-4 py-3',
|
||||
containerStyle={twStyle(
|
||||
'border-app-line bg-app-overlay rounded-lg border px-4 py-3',
|
||||
index !== 0 && 'mt-2'
|
||||
)}
|
||||
enableTrackpadTwoFingerGesture
|
||||
|
@ -66,24 +66,24 @@ function LocationItem({ location, index }: { location: Location & { node: Node }
|
|||
<FolderIcon size={32} />
|
||||
{/* Online/Offline Indicator */}
|
||||
<View
|
||||
style={tw.style(
|
||||
'absolute w-2 h-2 right-0 bottom-0.5 rounded-full',
|
||||
style={twStyle(
|
||||
'absolute right-0 bottom-0.5 h-2 w-2 rounded-full',
|
||||
onlineLocations.some((l) => arraysEqual(location.pub_id, l))
|
||||
? 'bg-green-500'
|
||||
: 'bg-red-500'
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
<View style={tw`flex-1 mx-4`}>
|
||||
<Text numberOfLines={1} style={tw`text-sm font-semibold text-ink`}>
|
||||
<View style={tw`mx-4 flex-1`}>
|
||||
<Text numberOfLines={1} style={tw`text-ink text-sm font-semibold`}>
|
||||
{location.name}
|
||||
</Text>
|
||||
<View style={tw`self-start bg-app-highlight py-[1px] px-1 rounded mt-0.5`}>
|
||||
<Text numberOfLines={1} style={tw`text-xs font-semibold text-ink-dull`}>
|
||||
<View style={tw`bg-app-highlight mt-0.5 self-start rounded py-[1px] px-1`}>
|
||||
<Text numberOfLines={1} style={tw`text-ink-dull text-xs font-semibold`}>
|
||||
{location.node.name}
|
||||
</Text>
|
||||
</View>
|
||||
<Text numberOfLines={1} style={tw`mt-0.5 text-[10px] font-semibold text-ink-dull`}>
|
||||
<Text numberOfLines={1} style={tw`text-ink-dull mt-0.5 text-[10px] font-semibold`}>
|
||||
{location.local_path}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Tag, useLibraryQuery } from '@sd/client';
|
|||
import { AnimatedButton } from '~/components/primitive/Button';
|
||||
import DeleteTagDialog from '~/containers/dialog/tag/DeleteTagDialog';
|
||||
import UpdateTagDialog from '~/containers/dialog/tag/UpdateTagDialog';
|
||||
import tw from '~/lib/tailwind';
|
||||
import tw, { twStyle } from '~/lib/tailwind';
|
||||
import { SettingsStackScreenProps } from '~/navigation/SettingsNavigator';
|
||||
|
||||
function TagItem({ tag, index }: { tag: Tag; index: number }) {
|
||||
|
@ -40,8 +40,8 @@ function TagItem({ tag, index }: { tag: Tag; index: number }) {
|
|||
|
||||
return (
|
||||
<Swipeable
|
||||
containerStyle={tw.style(
|
||||
'bg-app-overlay border border-app-line rounded-lg px-4 py-3',
|
||||
containerStyle={twStyle(
|
||||
'border-app-line bg-app-overlay rounded-lg border px-4 py-3',
|
||||
index !== 0 && 'mt-2'
|
||||
)}
|
||||
enableTrackpadTwoFingerGesture
|
||||
|
@ -49,8 +49,8 @@ function TagItem({ tag, index }: { tag: Tag; index: number }) {
|
|||
>
|
||||
<View style={tw`flex flex-row items-center justify-between`}>
|
||||
<View style={tw`flex flex-row`}>
|
||||
<View style={tw.style({ backgroundColor: tag.color }, 'w-4 h-4 rounded-full')} />
|
||||
<Text style={tw`ml-3 text-ink`}>{tag.name}</Text>
|
||||
<View style={twStyle({ backgroundColor: tag.color }, 'h-4 w-4 rounded-full')} />
|
||||
<Text style={tw`text-ink ml-3`}>{tag.name}</Text>
|
||||
</View>
|
||||
<CaretRight color={tw.color('ink-dull')} size={18} />
|
||||
</View>
|
||||
|
|
|
@ -13,8 +13,8 @@ export function App() {
|
|||
const testCreate = rspc.useMutation('testCreate');
|
||||
|
||||
return (
|
||||
<div className="w-screen h-screen flex flex-row divide-x divide-gray-300">
|
||||
<div className="p-2 space-y-2 flex flex-col">
|
||||
<div className="flex h-screen w-screen flex-row divide-x divide-gray-300">
|
||||
<div className="flex flex-col space-y-2 p-2">
|
||||
<div className="space-x-2">
|
||||
<button className={ButtonStyles} onClick={() => createDb.mutate('pullOperations')}>
|
||||
Add Database
|
||||
|
@ -29,7 +29,7 @@ export function App() {
|
|||
<ul className="w-full">
|
||||
{Object.entries(tests).map(([key, test]) => (
|
||||
<li key={key}>
|
||||
<button className="p-2 bg-green-300" onClick={() => test.run()}>
|
||||
<button className="bg-green-300 p-2" onClick={() => test.run()}>
|
||||
{test.name}
|
||||
</button>
|
||||
</li>
|
||||
|
@ -37,7 +37,7 @@ export function App() {
|
|||
</ul>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<ul className="p-2 gap-2 flex flex-row flex-wrap">
|
||||
<ul className="flex flex-row flex-wrap gap-2 p-2">
|
||||
{dbs.data?.map((id) => (
|
||||
<Suspense fallback={null} key={id}>
|
||||
<DatabaseView id={id} />
|
||||
|
@ -45,11 +45,11 @@ export function App() {
|
|||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="w-96 p-2 flex flex-col items-stretch">
|
||||
<h1 className="text-center font-bold text-2xl">All Operations</h1>
|
||||
<div className="flex w-96 flex-col items-stretch p-2">
|
||||
<h1 className="text-center text-2xl font-bold">All Operations</h1>
|
||||
<ul className="space-y-2">
|
||||
{operations.data?.map((op) => (
|
||||
<li key={op.id} className="bg-indigo-200 rounded-md p-2">
|
||||
<li key={op.id} className="rounded-md bg-indigo-200 p-2">
|
||||
<p className="truncate">ID: {op.id}</p>
|
||||
<p className="truncate">Timestamp: {op.timestamp.toString()}</p>
|
||||
<p className="truncate">Node: {op.node}</p>
|
||||
|
@ -72,8 +72,8 @@ function DatabaseView(props: DatabaseViewProps) {
|
|||
const pullOperations = rspc.useMutation('pullOperations');
|
||||
|
||||
return (
|
||||
<div className="bg-indigo-300 rounded-md min-w-[32rem] flex-1 overflow-hidden">
|
||||
<div className="flex flex-row justify-between items-center mx-2">
|
||||
<div className="min-w-[32rem] flex-1 overflow-hidden rounded-md bg-indigo-300">
|
||||
<div className="mx-2 flex flex-row items-center justify-between">
|
||||
<h1 className="p-2 text-xl font-medium">{props.id}</h1>
|
||||
<button className={ButtonStyles} onClick={() => pullOperations.mutate(props.id)}>
|
||||
Pull Operations
|
||||
|
@ -136,7 +136,7 @@ function OperationList(props: { db: string }) {
|
|||
return (
|
||||
<div>
|
||||
{messages.data && (
|
||||
<table className="font-mono border-spacing-x-4 border-separate">
|
||||
<table className="border-separate border-spacing-x-4 font-mono">
|
||||
{messages.data
|
||||
.sort((a, b) => Number(a.timestamp - b.timestamp))
|
||||
.map((message) => (
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"codegen": "cargo test -p sd-core api::tests::test_and_export_rspc_bindings -- --exact",
|
||||
"typecheck": "turbo run typecheck",
|
||||
"lint": "turbo run lint",
|
||||
"lint:fix": "turbo run lint -- --fix",
|
||||
"clean": "rimraf node_modules/ **/node_modules/ target/ **/.build/ **/.next/ **/dist/**"
|
||||
},
|
||||
"pnpm": {
|
||||
|
@ -40,6 +41,7 @@
|
|||
"lint-staged": "^13.1.0",
|
||||
"markdown-link-check": "^3.10.3",
|
||||
"prettier": "^2.8.3",
|
||||
"prettier-plugin-tailwindcss": "^0.2.2",
|
||||
"rimraf": "^4.1.1",
|
||||
"turbo": "^1.5.5",
|
||||
"turbo-ignore": "^0.3.0",
|
||||
|
|
|
@ -12,6 +12,7 @@ module.exports = {
|
|||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:tailwindcss/recommended',
|
||||
'prettier',
|
||||
'turbo'
|
||||
],
|
||||
|
@ -32,12 +33,19 @@ module.exports = {
|
|||
'@typescript-eslint/no-empty-interface': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'no-control-regex': 'off',
|
||||
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs']
|
||||
'no-mixed-spaces-and-tabs': ['warn', 'smart-tabs'],
|
||||
'tailwindcss/no-custom-classname': 'off',
|
||||
'tailwindcss/no-contradicting-classname': 'warn'
|
||||
},
|
||||
ignorePatterns: ['dist', '**/*.js', '**/*.json', 'node_modules'],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
},
|
||||
tailwindcss: {
|
||||
config: 'packages/ui/style/tailwind.js',
|
||||
callees: ['classnames', 'clsx', 'ctl', 'cva', 'tw', `twStyle`],
|
||||
tags: ['tw', 'twStyle']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -23,5 +23,10 @@ module.exports = {
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
settings: {
|
||||
tailwindcss: {
|
||||
config: 'apps/mobile/tailwind.config.js'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,12 +10,13 @@
|
|||
"eslint-react.js"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||
"@typescript-eslint/parser": "^5.48.2",
|
||||
"eslint": "^8.24.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
||||
"@typescript-eslint/parser": "^5.51.0",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-turbo": "^0.0.7",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"eslint-plugin-react-hooks": "^4.6.0"
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-tailwindcss": "^3.8.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ export function AppLayout() {
|
|||
<div
|
||||
className={clsx(
|
||||
// App level styles
|
||||
'flex h-screen overflow-hidden text-ink select-none cursor-default',
|
||||
os === 'browser' && 'bg-app border-t border-app-line/50',
|
||||
os === 'macOS' && 'rounded-[10px] has-blur-effects',
|
||||
os !== 'browser' && os !== 'windows' && 'border border-app-frame'
|
||||
'text-ink flex h-screen cursor-default select-none overflow-hidden',
|
||||
os === 'browser' && 'bg-app border-app-line/50 border-t',
|
||||
os === 'macOS' && 'has-blur-effects rounded-[10px]',
|
||||
os !== 'browser' && os !== 'windows' && 'border-app-frame border'
|
||||
)}
|
||||
onContextMenu={(e) => {
|
||||
// TODO: allow this on some UI text at least / disable default browser context menu
|
||||
|
@ -32,7 +32,7 @@ export function AppLayout() {
|
|||
>
|
||||
<Sidebar />
|
||||
<div className="relative flex w-full">
|
||||
<Suspense fallback={<div className="w-screen h-screen bg-app" />}>
|
||||
<Suspense fallback={<div className="bg-app h-screen w-screen" />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
|
|
@ -12,12 +12,12 @@ export function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
|||
<div
|
||||
data-tauri-drag-region
|
||||
role="alert"
|
||||
className="flex flex-col items-center justify-center w-screen h-screen p-4 border rounded-lg border-app-divider bg-app"
|
||||
className="border-app-divider bg-app flex h-screen w-screen flex-col items-center justify-center rounded-lg border p-4"
|
||||
>
|
||||
<p className="m-3 text-sm font-bold text-ink-faint">APP CRASHED</p>
|
||||
<h1 className="text-2xl font-bold text-ink">We're past the event horizon...</h1>
|
||||
<pre className="m-2 text-ink">Error: {error.message}</pre>
|
||||
<div className="flex flex-row space-x-2 text-ink">
|
||||
<p className="text-ink-faint m-3 text-sm font-bold">APP CRASHED</p>
|
||||
<h1 className="text-ink text-2xl font-bold">We're past the event horizon...</h1>
|
||||
<pre className="text-ink m-2">Error: {error.message}</pre>
|
||||
<div className="text-ink flex flex-row space-x-2">
|
||||
<Button variant="accent" className="mt-2" onClick={resetErrorBoundary}>
|
||||
Reload
|
||||
</Button>
|
||||
|
|
|
@ -7,9 +7,9 @@ export default function NotFound() {
|
|||
<div
|
||||
data-tauri-drag-region
|
||||
role="alert"
|
||||
className="flex flex-col items-center justify-center w-full h-full p-4 rounded-lg"
|
||||
className="flex h-full w-full flex-col items-center justify-center rounded-lg p-4"
|
||||
>
|
||||
<p className="m-3 text-sm font-semibold uppercase text-ink-faint">Error: 404</p>
|
||||
<p className="text-ink-faint m-3 text-sm font-semibold uppercase">Error: 404</p>
|
||||
<h1 className="text-4xl font-bold">You chose nothingness.</h1>
|
||||
<div className="flex flex-row space-x-2">
|
||||
<Button variant="accent" className="mt-4" onClick={() => navigate(-1)}>
|
||||
|
|
|
@ -32,7 +32,7 @@ export default function AddLocationDialog(props: Props) {
|
|||
ctaLabel="Add"
|
||||
>
|
||||
<Input
|
||||
className="flex-grow w-full mt-3"
|
||||
className="mt-3 w-full grow"
|
||||
placeholder="/Users/jamie/Movies"
|
||||
required
|
||||
{...form.register('path')}
|
||||
|
|
|
@ -23,17 +23,17 @@ export const AlertDialog = (props: AlertDialogProps) => {
|
|||
ctaLabel={props.label !== undefined ? props.label : 'Done'}
|
||||
>
|
||||
{props.inputBox && (
|
||||
<div className="relative flex flex-grow mt-3">
|
||||
<Input value={props.value} disabled className="flex-grow !py-0.5" />
|
||||
<div className="relative mt-3 flex grow">
|
||||
<Input value={props.value} disabled className="grow !py-0.5" />
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(props.value);
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<Clipboard className="w-4 h-4" />
|
||||
<Clipboard className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -69,9 +69,9 @@ export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
|
|||
loading={restoreKeystoreMutation.isLoading}
|
||||
ctaLabel="Restore"
|
||||
>
|
||||
<div className="relative flex flex-grow mt-3 mb-2">
|
||||
<div className="relative mt-3 mb-2 flex grow">
|
||||
<Input
|
||||
className="flex-grow !py-0.5"
|
||||
className="grow !py-0.5"
|
||||
placeholder="Master Password"
|
||||
type={show.masterPassword ? 'text' : 'password'}
|
||||
{...form.register('masterPassword', { required: true })}
|
||||
|
@ -79,15 +79,15 @@ export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
|
|||
<Button
|
||||
onClick={() => setShow((old) => ({ ...old, masterPassword: !old.masterPassword }))}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
type="button"
|
||||
>
|
||||
<MPCurrentEyeIcon className="w-4 h-4" />
|
||||
<MPCurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="relative flex flex-grow mb-3">
|
||||
<div className="relative mb-3 flex grow">
|
||||
<Input
|
||||
className="flex-grow !py-0.5"
|
||||
className="grow !py-0.5"
|
||||
placeholder="Secret Key"
|
||||
type={show.secretKey ? 'text' : 'password'}
|
||||
{...form.register('secretKey')}
|
||||
|
@ -95,12 +95,12 @@ export const BackupRestoreDialog = (props: BackupRestorationDialogProps) => {
|
|||
<Button
|
||||
onClick={() => setShow((old) => ({ ...old, secretKey: !old.secretKey }))}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<SKCurrentEyeIcon className="w-4 h-4" />
|
||||
<SKCurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="relative flex flex-grow mb-2">
|
||||
<div className="relative mb-2 flex grow">
|
||||
<Button
|
||||
size="sm"
|
||||
variant={form.watch('filePath') !== '' ? 'accent' : 'gray'}
|
||||
|
|
|
@ -77,9 +77,9 @@ export default function CreateLibraryDialog(props: Props) {
|
|||
ctaLabel="Create"
|
||||
>
|
||||
<div className="relative flex flex-col">
|
||||
<p className="text-sm mt-2 mb-2 font-bold">Library name</p>
|
||||
<p className="my-2 text-sm font-bold">Library name</p>
|
||||
<Input
|
||||
className="flex-grow w-full"
|
||||
className="w-full grow"
|
||||
placeholder="My Cool Library"
|
||||
{...form.register('name', { required: true })}
|
||||
/>
|
||||
|
@ -89,13 +89,13 @@ export default function CreateLibraryDialog(props: Props) {
|
|||
{/* <span className="text-sm">Make the secret key field empty to skip key setup.</span> */}
|
||||
|
||||
<div className="relative flex flex-col">
|
||||
<p className="text-center mt-2 mb-1 text-[0.95rem] font-bold">Key Manager</p>
|
||||
<div className="w-full my-1 h-[2px] bg-gray-500" />
|
||||
<p className="mt-2 mb-1 text-center text-[0.95rem] font-bold">Key Manager</p>
|
||||
<div className="my-1 h-[2px] w-full bg-gray-500" />
|
||||
|
||||
<p className="text-sm mt-2 mb-2 font-bold">Master password</p>
|
||||
<div className="relative flex flex-grow mb-2">
|
||||
<p className="my-2 text-sm font-bold">Master password</p>
|
||||
<div className="relative mb-2 flex grow">
|
||||
<Input
|
||||
className="flex-grow !py-0.5"
|
||||
className="grow !py-0.5"
|
||||
placeholder="Password"
|
||||
type={showMasterPassword1 ? 'text' : 'password'}
|
||||
{...form.register('password')}
|
||||
|
@ -111,33 +111,33 @@ export default function CreateLibraryDialog(props: Props) {
|
|||
setShowMasterPassword2(true);
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[65px] top-[5px]"
|
||||
className="absolute right-[65px] top-[5px] border-none"
|
||||
>
|
||||
<ArrowsClockwise className="w-4 h-4" />
|
||||
<ArrowsClockwise className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(form.watch('password') as string);
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[35px] top-[5px]"
|
||||
className="absolute right-[35px] top-[5px] border-none"
|
||||
>
|
||||
<Clipboard className="w-4 h-4" />
|
||||
<Clipboard className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setShowMasterPassword1(!showMasterPassword1)}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<MP1CurrentEyeIcon className="w-4 h-4" />
|
||||
<MP1CurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative flex flex-col">
|
||||
<p className="text-sm mt-2 mb-2 font-bold">Master password (again)</p>
|
||||
<div className="relative flex flex-grow mb-2">
|
||||
<p className="my-2 text-sm font-bold">Master password (again)</p>
|
||||
<div className="relative mb-2 flex grow">
|
||||
<Input
|
||||
className="flex-grow !py-0.5"
|
||||
className="grow !py-0.5"
|
||||
placeholder="Password"
|
||||
type={showMasterPassword2 ? 'text' : 'password'}
|
||||
{...form.register('password_validate')}
|
||||
|
@ -145,14 +145,14 @@ export default function CreateLibraryDialog(props: Props) {
|
|||
<Button
|
||||
onClick={() => setShowMasterPassword2(!showMasterPassword2)}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<MP2CurrentEyeIcon className="w-4 h-4" />
|
||||
<MP2CurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-sm font-bold">Encryption</span>
|
||||
<Select
|
||||
|
|
|
@ -97,7 +97,7 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
|
|||
className="mt-2"
|
||||
>
|
||||
<span className="text-xs font-bold">Key Type</span>
|
||||
<div className="flex flex-row gap-2 mt-2">
|
||||
<div className="mt-2 flex flex-row gap-2">
|
||||
<RadioGroup.Option disabled={!hasMountedKeys} value="key">
|
||||
{({ checked }) => (
|
||||
<Button
|
||||
|
@ -121,7 +121,7 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
|
|||
</RadioGroup>
|
||||
|
||||
{form.watch('type') === 'key' && (
|
||||
<div className="relative flex flex-grow mt-3 mb-2">
|
||||
<div className="relative mt-3 mb-2 flex grow">
|
||||
<div className="space-x-2">
|
||||
<Switch
|
||||
className="bg-app-selected"
|
||||
|
@ -131,18 +131,18 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
|
|||
onCheckedChange={(e) => form.setValue('mountAssociatedKey', e)}
|
||||
/>
|
||||
</div>
|
||||
<span className="ml-3 text-xs font-medium mt-0.5">Automatically mount key</span>
|
||||
<span className="ml-3 mt-0.5 text-xs font-medium">Automatically mount key</span>
|
||||
<Tooltip label="The key linked with the file will be automatically mounted">
|
||||
<Info className="w-4 h-4 ml-1.5 text-ink-faint mt-0.5" />
|
||||
<Info className="text-ink-faint ml-1.5 mt-0.5 h-4 w-4" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{form.watch('type') === 'password' && (
|
||||
<>
|
||||
<div className="relative flex flex-grow mt-3 mb-2">
|
||||
<div className="relative mt-3 mb-2 flex grow">
|
||||
<Input
|
||||
className={`flex-grow w-max !py-0.5`}
|
||||
className={`w-max grow !py-0.5`}
|
||||
placeholder="Password"
|
||||
type={show.password ? 'text' : 'password'}
|
||||
{...form.register('password', { required: true })}
|
||||
|
@ -150,14 +150,14 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
|
|||
<Button
|
||||
onClick={() => setShow((old) => ({ ...old, password: !old.password }))}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
type="button"
|
||||
>
|
||||
<PasswordCurrentEyeIcon className="w-4 h-4" />
|
||||
<PasswordCurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="relative flex flex-grow mt-3 mb-2">
|
||||
<div className="relative mt-3 mb-2 flex grow">
|
||||
<div className="space-x-2">
|
||||
<Switch
|
||||
className="bg-app-selected"
|
||||
|
@ -165,22 +165,22 @@ export const DecryptFileDialog = (props: DecryptDialogProps) => {
|
|||
{...form.register('saveToKeyManager')}
|
||||
/>
|
||||
</div>
|
||||
<span className="ml-3 text-xs font-medium mt-0.5">Save to Key Manager</span>
|
||||
<span className="ml-3 mt-0.5 text-xs font-medium">Save to Key Manager</span>
|
||||
<Tooltip label="This key will be saved to the key manager">
|
||||
<Info className="w-4 h-4 ml-1.5 text-ink-faint mt-0.5" />
|
||||
<Info className="text-ink-faint ml-1.5 mt-0.5 h-4 w-4" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold">Output file</span>
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
variant={form.watch('outputPath') !== '' ? 'accent' : 'gray'}
|
||||
className="h-[23px] text-xs leading-3 mt-2"
|
||||
className="mt-2 h-[23px] text-xs leading-3"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
// if we allow the user to encrypt multiple files simultaneously, this should become a directory instead
|
||||
|
|
|
@ -86,7 +86,7 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
|
|||
loading={encryptFile.isLoading}
|
||||
ctaLabel="Encrypt"
|
||||
>
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold">Key</span>
|
||||
<Select
|
||||
|
@ -105,7 +105,7 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
|
|||
<Button
|
||||
size="sm"
|
||||
variant={form.watch('outputPath') !== '' ? 'accent' : 'gray'}
|
||||
className="h-[23px] text-xs leading-3 mt-2"
|
||||
className="mt-2 h-[23px] text-xs leading-3"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
// if we allow the user to encrypt multiple files simultaneously, this should become a directory instead
|
||||
|
@ -130,7 +130,7 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold">Encryption</span>
|
||||
<Select
|
||||
|
@ -160,13 +160,13 @@ export const EncryptFileDialog = ({ ...props }: EncryptDialogProps) => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex">
|
||||
<span className="text-sm font-bold mr-3 ml-0.5 mt-0.5">Metadata</span>
|
||||
<span className="mr-3 ml-0.5 mt-0.5 text-sm font-bold">Metadata</span>
|
||||
<CheckBox {...form.register('metadata')} />
|
||||
</div>
|
||||
<div className="flex">
|
||||
<span className="text-sm font-bold mr-3 ml-0.5 mt-0.5">Preview Media</span>
|
||||
<span className="mr-3 ml-0.5 mt-0.5 text-sm font-bold">Preview Media</span>
|
||||
<CheckBox {...form.register('previewMedia')} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -45,11 +45,11 @@ export const EraseFileDialog = (props: EraseDialogProps) => {
|
|||
loading={eraseFile.isLoading}
|
||||
ctaLabel="Erase"
|
||||
>
|
||||
<div className="flex flex-col mt-2">
|
||||
<div className="mt-2 flex flex-col">
|
||||
<span className="text-xs font-bold"># of passes</span>
|
||||
|
||||
<div className="flex flex-row space-x-2">
|
||||
<div className="relative flex flex-grow mt-2">
|
||||
<div className="relative mt-2 flex grow">
|
||||
<Slider
|
||||
value={passes}
|
||||
max={16}
|
||||
|
@ -62,7 +62,7 @@ export const EraseFileDialog = (props: EraseDialogProps) => {
|
|||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="text-sm mt-2.5 font-medium">{passes}</span>
|
||||
<span className="mt-2.5 text-sm font-medium">{passes}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@ export const KeyViewerDialog = (props: KeyViewerDialogProps) => {
|
|||
setContentSalt={setContentSalt}
|
||||
/>
|
||||
|
||||
<div className="grid w-full gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold">Key</span>
|
||||
<Select
|
||||
className="mt-2 flex-grow"
|
||||
className="mt-2 grow"
|
||||
value={key}
|
||||
onChange={(e) => {
|
||||
setKey(e);
|
||||
|
@ -83,7 +83,7 @@ export const KeyViewerDialog = (props: KeyViewerDialogProps) => {
|
|||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold">Encryption</span>
|
||||
<Select
|
||||
|
@ -108,38 +108,38 @@ export const KeyViewerDialog = (props: KeyViewerDialogProps) => {
|
|||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid w-full gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold mb-2">Content Salt (hex)</span>
|
||||
<div className="relative flex flex-grow">
|
||||
<Input value={contentSalt} disabled className="flex-grow !py-0.5" />
|
||||
<span className="mb-2 text-xs font-bold">Content Salt (hex)</span>
|
||||
<div className="relative flex grow">
|
||||
<Input value={contentSalt} disabled className="grow !py-0.5" />
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(contentSalt);
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<Clipboard className="w-4 h-4" />
|
||||
<Clipboard className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid w-full gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold mb-2">Key Value</span>
|
||||
<div className="relative flex flex-grow">
|
||||
<Input value={keyValue} disabled className="flex-grow !py-0.5" />
|
||||
<span className="mb-2 text-xs font-bold">Key Value</span>
|
||||
<div className="relative flex grow">
|
||||
<Input value={keyValue} disabled className="grow !py-0.5" />
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(keyValue);
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<Clipboard className="w-4 h-4" />
|
||||
<Clipboard className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -80,9 +80,9 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
|
|||
ctaDanger={true}
|
||||
ctaLabel="Change"
|
||||
>
|
||||
<div className="relative flex flex-grow mt-3 mb-2">
|
||||
<div className="relative mt-3 mb-2 flex grow">
|
||||
<Input
|
||||
className={`flex-grow w-max !py-0.5`}
|
||||
className={`w-max grow !py-0.5`}
|
||||
placeholder="New password"
|
||||
type={show.masterPassword ? 'text' : 'password'}
|
||||
{...form.register('masterPassword', { required: true })}
|
||||
|
@ -99,10 +99,10 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
|
|||
}));
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[65px] top-[5px]"
|
||||
className="absolute right-[65px] top-[5px] border-none"
|
||||
type="button"
|
||||
>
|
||||
<ArrowsClockwise className="w-4 h-4" />
|
||||
<ArrowsClockwise className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
|
@ -110,22 +110,22 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
|
|||
navigator.clipboard.writeText(form.watch('masterPassword') as string);
|
||||
}}
|
||||
size="icon"
|
||||
className="border-none absolute right-[35px] top-[5px]"
|
||||
className="absolute right-[35px] top-[5px] border-none"
|
||||
>
|
||||
<Clipboard className="w-4 h-4" />
|
||||
<Clipboard className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setShow((old) => ({ ...old, masterPassword: !old.masterPassword }))}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
type="button"
|
||||
>
|
||||
<MP1CurrentEyeIcon className="w-4 h-4" />
|
||||
<MP1CurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div className="relative flex flex-grow mb-2">
|
||||
<div className="relative mb-2 flex grow">
|
||||
<Input
|
||||
className={`flex-grow !py-0.5}`}
|
||||
className={`!py-0.5} grow`}
|
||||
placeholder="New password (again)"
|
||||
type={show.masterPassword2 ? 'text' : 'password'}
|
||||
{...form.register('masterPassword2', { required: true })}
|
||||
|
@ -133,16 +133,16 @@ export const MasterPasswordChangeDialog = (props: MasterPasswordChangeDialogProp
|
|||
<Button
|
||||
onClick={() => setShow((old) => ({ ...old, masterPassword2: !old.masterPassword2 }))}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
type="button"
|
||||
>
|
||||
<MP2CurrentEyeIcon className="w-4 h-4" />
|
||||
<MP2CurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<PasswordMeter password={form.watch('masterPassword')} />
|
||||
|
||||
<div className="grid w-full grid-cols-2 gap-4 mt-4 mb-3">
|
||||
<div className="mt-4 mb-3 grid w-full grid-cols-2 gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs font-bold">Encryption</span>
|
||||
<Select
|
||||
|
|
|
@ -44,10 +44,10 @@ export default function Explorer(props: Props) {
|
|||
return (
|
||||
<div className="relative">
|
||||
<ExplorerContextMenu>
|
||||
<div className="relative flex flex-col w-full">
|
||||
<div className="relative flex w-full flex-col">
|
||||
<TopBar showSeparator={separateTopBar} />
|
||||
|
||||
<div className="relative flex flex-row w-full max-h-full app-background">
|
||||
<div className="app-background relative flex max-h-full w-full flex-row">
|
||||
{props.data && (
|
||||
<VirtualizedList
|
||||
data={props.data.items}
|
||||
|
|
|
@ -17,15 +17,8 @@ import {
|
|||
TrashSimple
|
||||
} from 'phosphor-react';
|
||||
import { PropsWithChildren, useMemo } from 'react';
|
||||
import {
|
||||
ExplorerItem,
|
||||
getLibraryIdRaw,
|
||||
useDebugState,
|
||||
useLibraryMutation,
|
||||
useLibraryQuery
|
||||
} from '@sd/client';
|
||||
import { ContextMenu as CM } from '@sd/ui';
|
||||
import { dialogManager } from '@sd/ui';
|
||||
import { ExplorerItem, getLibraryIdRaw, useLibraryMutation, useLibraryQuery } from '@sd/client';
|
||||
import { ContextMenu as CM, dialogManager } from '@sd/ui';
|
||||
import { getExplorerStore, useExplorerStore } from '~/hooks/useExplorerStore';
|
||||
import { useOperatingSystem } from '~/hooks/useOperatingSystem';
|
||||
import { useExplorerParams } from '~/screens/LocationExplorer';
|
||||
|
@ -63,7 +56,7 @@ const AssignTagMenuItems = (props: { objectId: number }) => {
|
|||
}}
|
||||
>
|
||||
<div
|
||||
className="block w-[15px] h-[15px] mr-0.5 border rounded-full"
|
||||
className="mr-0.5 block h-[15px] w-[15px] rounded-full border"
|
||||
style={{
|
||||
backgroundColor: active ? tag.color || '#efefef' : 'transparent' || '#efefef',
|
||||
borderColor: tag.color || '#efefef'
|
||||
|
|
|
@ -3,11 +3,11 @@ import { Select, SelectOption } from '@sd/ui';
|
|||
import Slider from '../primitive/Slider';
|
||||
|
||||
function Heading({ children }: PropsWithChildren) {
|
||||
return <div className="text-xs font-semibold text-ink-dull">{children}</div>;
|
||||
return <div className="text-ink-dull text-xs font-semibold">{children}</div>;
|
||||
}
|
||||
|
||||
function SubHeading({ children }: PropsWithChildren) {
|
||||
return <div className="mb-1 text-xs font-medium text-ink-dull">{children}</div>;
|
||||
return <div className="text-ink-dull mb-1 text-xs font-medium">{children}</div>;
|
||||
}
|
||||
|
||||
const sortOptions = {
|
||||
|
@ -29,7 +29,7 @@ export function ExplorerOptionsPanel() {
|
|||
{/* <Heading>Explorer Appearance</Heading> */}
|
||||
<SubHeading>Item size</SubHeading>
|
||||
<Slider defaultValue={size} step={10} />
|
||||
<div className="grid grid-cols-2 gap-2 my-2 mt-4">
|
||||
<div className="my-2 mt-4 grid grid-cols-2 gap-2">
|
||||
<div className="flex flex-col">
|
||||
<SubHeading>Sort by</SubHeading>
|
||||
<Select value={sortBy} size="sm" onChange={setSortBy}>
|
||||
|
|
|
@ -36,7 +36,7 @@ export interface TopBarButtonProps {
|
|||
// export const TopBarIcon = (icon: any) => tw(icon)`m-0.5 w-5 h-5 text-ink-dull`;
|
||||
|
||||
const topBarButtonStyle = cva(
|
||||
'border-none text-ink hover:text-ink mr-[1px] flex py-0.5 px-0.5 text-md font-medium transition-colors duration-100 outline-none hover:bg-app-selected radix-state-open:bg-app-selected',
|
||||
'text-ink hover:text-ink text-md hover:bg-app-selected radix-state-open:bg-app-selected mr-[1px] flex border-none p-0.5 font-medium outline-none transition-colors duration-100',
|
||||
{
|
||||
variants: {
|
||||
active: {
|
||||
|
@ -101,7 +101,7 @@ const SearchBar = forwardRef<HTMLInputElement, DefaultProps>((props, forwardedRe
|
|||
{...searchField}
|
||||
/>
|
||||
|
||||
<div className={clsx('space-x-1 absolute right-1 peer-focus:invisible pointer-events-none')}>
|
||||
<div className={clsx('pointer-events-none absolute right-1 space-x-1 peer-focus:invisible')}>
|
||||
{platform === 'browser' ? (
|
||||
<Shortcut chars="⌘F" aria-label={'Press Command-F to focus search bar'} />
|
||||
) : os === 'macOS' ? (
|
||||
|
@ -187,8 +187,9 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
|||
<>
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
// eslint-disable-next-line tailwindcss/no-contradicting-classname
|
||||
className={clsx(
|
||||
'flex h-[46px] max-w z-20 pl-3 flex-shrink-0 items-center border-transparent border-b bg-app overflow-hidden transition-[background-color] transition-[border-color] duration-250 ease-out',
|
||||
'max-w bg-app duration-250 z-20 flex h-[46px] shrink-0 items-center overflow-hidden border-b border-transparent pl-3 transition-[background-color] transition-[border-color] ease-out',
|
||||
props.showSeparator && 'top-bar-blur !bg-app/90'
|
||||
)}
|
||||
>
|
||||
|
@ -211,8 +212,8 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
|||
<TopBarButton group right icon={SquaresFour} />
|
||||
</div> */}
|
||||
|
||||
<div data-tauri-drag-region className="flex flex-row justify-center flex-grow">
|
||||
<div className="flex mx-8">
|
||||
<div data-tauri-drag-region className="flex grow flex-row justify-center">
|
||||
<div className="mx-8 flex">
|
||||
<Tooltip label="Grid view">
|
||||
<TopBarButton
|
||||
rounding="left"
|
||||
|
@ -263,7 +264,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
|||
|
||||
<SearchBar ref={searchRef} />
|
||||
|
||||
<div className="flex mx-8 space-x-2">
|
||||
<div className="mx-8 flex space-x-2">
|
||||
<Tooltip label="Key Manager">
|
||||
<Popover
|
||||
className="focus:outline-none"
|
||||
|
@ -303,7 +304,7 @@ export const TopBar: React.FC<TopBarProps> = (props) => {
|
|||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex mr-3 space-x-2">
|
||||
<div className="mr-3 flex space-x-2">
|
||||
<Tooltip label="File display options" position="left">
|
||||
<Popover
|
||||
className="focus:outline-none"
|
||||
|
|
|
@ -10,7 +10,7 @@ import { isObject } from './utils';
|
|||
const NameArea = tw.div`flex justify-center`;
|
||||
|
||||
const nameContainerStyles = cva(
|
||||
'px-1.5 py-[1px] truncate text-center rounded-md text-xs font-medium cursor-default',
|
||||
'cursor-default truncate rounded-md px-1.5 py-[1px] text-center text-xs font-medium',
|
||||
{
|
||||
variants: {
|
||||
selected: {
|
||||
|
@ -41,7 +41,7 @@ function FileItem({ data, selected, index, ...rest }: Props) {
|
|||
}}
|
||||
{...rest}
|
||||
draggable
|
||||
className={clsx('inline-block w-[100px] mb-3', rest.className)}
|
||||
className={clsx('mb-3 inline-block w-[100px]', rest.className)}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
|
@ -49,7 +49,7 @@ function FileItem({ data, selected, index, ...rest }: Props) {
|
|||
height: getExplorerStore().gridItemSize
|
||||
}}
|
||||
className={clsx(
|
||||
'border-2 border-transparent rounded-lg text-center mb-1 active:translate-y-[1px]',
|
||||
'mb-1 rounded-lg border-2 border-transparent text-center active:translate-y-[1px]',
|
||||
{
|
||||
'bg-app-selected/30': selected
|
||||
}
|
||||
|
@ -57,20 +57,20 @@ function FileItem({ data, selected, index, ...rest }: Props) {
|
|||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'flex relative items-center justify-center h-full p-1 rounded border-transparent border-2 shrink-0'
|
||||
'relative flex h-full shrink-0 items-center justify-center rounded border-2 border-transparent p-1'
|
||||
)}
|
||||
>
|
||||
<FileThumb
|
||||
className={clsx(
|
||||
'border-2 border-app-line rounded-sm shadow shadow-black/40 object-cover max-w-full max-h-full w-auto overflow-hidden',
|
||||
isVid && '!border-black rounded border-x-0 border-y-[7px]'
|
||||
'border-app-line max-h-full w-auto max-w-full overflow-hidden rounded-sm border-2 object-cover shadow shadow-black/40',
|
||||
isVid && 'rounded border-x-0 border-y-[7px] !border-black'
|
||||
)}
|
||||
data={data}
|
||||
kind={ObjectKind[objectData?.kind || 0]}
|
||||
size={getExplorerStore().gridItemSize}
|
||||
/>
|
||||
{item.extension && isVid && (
|
||||
<div className="absolute bottom-4 font-semibold opacity-70 right-2 py-0.5 px-1 text-[9px] uppercase bg-black/60 rounded">
|
||||
<div className="absolute bottom-4 right-2 rounded bg-black/60 py-0.5 px-1 text-[9px] font-semibold uppercase opacity-70">
|
||||
{item.extension}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -22,7 +22,7 @@ function FileRow({ data, index, selected, ...props }: Props) {
|
|||
{columns.map((col) => (
|
||||
<div
|
||||
key={col.key}
|
||||
className="flex items-center px-4 py-2 pr-2 table-body-cell"
|
||||
className="table-body-cell flex items-center px-4 py-2 pr-2"
|
||||
style={{ width: col.width }}
|
||||
>
|
||||
<RenderCell data={data} colKey={col.key} />
|
||||
|
@ -40,7 +40,7 @@ const RenderCell: React.FC<{
|
|||
case 'name':
|
||||
return (
|
||||
<div className="flex flex-row items-center overflow-hidden">
|
||||
<div className="flex items-center justify-center w-6 h-6 mr-3 shrink-0">
|
||||
<div className="mr-3 flex h-6 w-6 shrink-0 items-center justify-center">
|
||||
<FileThumb data={data} size={0} />
|
||||
</div>
|
||||
{/* {colKey == 'name' &&
|
||||
|
@ -55,13 +55,13 @@ const RenderCell: React.FC<{
|
|||
return <DocumentIcon className="flex-shrink-0 w-5 h-5 mr-3 text-gray-300" />;
|
||||
}
|
||||
})()} */}
|
||||
<span className="text-xs truncate">{data.item[colKey]}</span>
|
||||
<span className="truncate text-xs">{data.item[colKey]}</span>
|
||||
</div>
|
||||
);
|
||||
// case 'size_in_bytes':
|
||||
// return <span className="text-xs text-left">{byteSize(Number(value || 0))}</span>;
|
||||
case 'extension':
|
||||
return <span className="text-xs text-left">{data.item[colKey]}</span>;
|
||||
return <span className="text-left text-xs">{data.item[colKey]}</span>;
|
||||
// case 'meta_integrity_hash':
|
||||
// return <span className="truncate">{value}</span>;
|
||||
// case 'tags':
|
||||
|
|
|
@ -51,7 +51,7 @@ export default function FileThumb({ data, ...props }: Props) {
|
|||
style={props.style}
|
||||
decoding="async"
|
||||
// width={props.size}
|
||||
className={clsx('pointer-events-none z-90', props.className)}
|
||||
className={clsx('z-90 pointer-events-none', props.className)}
|
||||
src={url}
|
||||
/>
|
||||
);
|
||||
|
@ -64,5 +64,5 @@ export default function FileThumb({ data, ...props }: Props) {
|
|||
else if (props.kind === 'Executable') icon = executable;
|
||||
else if (props.kind === 'Encrypted') icon = archive;
|
||||
|
||||
return <img src={icon} className={clsx('overflow-hidden h-full', props.iconClassNames)} />;
|
||||
return <img src={icon} className={clsx('h-full overflow-hidden', props.iconClassNames)} />;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export const MetaValue = tw.p`text-xs break-all text-ink truncate`;
|
|||
const MetaTextLine = tw.div`flex items-center my-0.5 text-xs text-ink-dull`;
|
||||
|
||||
const InspectorIcon = ({ component: Icon, ...props }: any) => (
|
||||
<Icon weight="bold" {...props} className={clsx('mr-2 flex-shrink-0', props.className)} />
|
||||
<Icon weight="bold" {...props} className={clsx('mr-2 shrink-0', props.className)} />
|
||||
);
|
||||
|
||||
interface Props extends DefaultProps<HTMLDivElement> {
|
||||
|
@ -63,13 +63,13 @@ export const Inspector = ({ data, context, ...elementProps }: Props) => {
|
|||
return (
|
||||
<div
|
||||
{...elementProps}
|
||||
className="-mt-[50px] pt-[55px] z-10 pl-1.5 pr-1 w-full h-screen overflow-x-hidden custom-scroll inspector-scroll pb-4"
|
||||
className="custom-scroll inspector-scroll z-10 mt-[-50px] h-screen w-full overflow-x-hidden pt-[55px] pl-1.5 pr-1 pb-4"
|
||||
>
|
||||
{data && (
|
||||
<>
|
||||
<div
|
||||
className={clsx(
|
||||
'flex h-52 items-center justify-center w-full mb-[10px] overflow-hidden rounded-lg',
|
||||
'mb-[10px] flex h-52 w-full items-center justify-center overflow-hidden rounded-lg',
|
||||
objectData?.kind === 7 && objectData?.has_thumbnail && 'bg-black'
|
||||
)}
|
||||
>
|
||||
|
@ -77,29 +77,29 @@ export const Inspector = ({ data, context, ...elementProps }: Props) => {
|
|||
iconClassNames="my-3 max-h-[150px]"
|
||||
size={230}
|
||||
kind={ObjectKind[objectData?.kind || 0]}
|
||||
className="flex flex-grow-0 flex-shrink bg-green-500"
|
||||
className="flex shrink grow-0 bg-green-500"
|
||||
data={data}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col w-full pt-0.5 pb-0.5 overflow-hidden bg-app-box rounded-lg select-text shadow-app-shade/10 border border-app-line">
|
||||
<h3 className="px-3 pt-2 pb-1 text-base font-bold truncate">
|
||||
<div className="bg-app-box shadow-app-shade/10 border-app-line flex w-full select-text flex-col overflow-hidden rounded-lg border py-0.5">
|
||||
<h3 className="truncate px-3 pt-2 pb-1 text-base font-bold">
|
||||
{item?.name}
|
||||
{item?.extension && `.${item.extension}`}
|
||||
</h3>
|
||||
{objectData && (
|
||||
<div className="flex flex-row mt-1 mb-0.5 mx-3 space-x-0.5">
|
||||
<div className="mx-3 mt-1 mb-0.5 flex flex-row space-x-0.5">
|
||||
<Tooltip label="Favorite">
|
||||
<FavoriteButton data={objectData} />
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip label="Encrypt">
|
||||
<Button size="icon">
|
||||
<Lock className="w-[18px] h-[18px]" />
|
||||
<Lock className="h-[18px] w-[18px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip label="Share">
|
||||
<Button size="icon">
|
||||
<Link className="w-[18px] h-[18px]" />
|
||||
<Link className="h-[18px] w-[18px]" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
|
|
@ -116,10 +116,10 @@ export const VirtualizedList = memo(({ data, context, onScroll }: Props) => {
|
|||
// );
|
||||
|
||||
return (
|
||||
<div style={{ marginTop: -TOP_BAR_HEIGHT }} className="w-full pl-2 cursor-default">
|
||||
<div style={{ marginTop: -TOP_BAR_HEIGHT }} className="w-full cursor-default pl-2">
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className="h-screen custom-scroll explorer-scroll"
|
||||
className="custom-scroll explorer-scroll h-screen"
|
||||
onClick={(e) => {
|
||||
getExplorerStore().selectedRowIndex = -1;
|
||||
}}
|
||||
|
|
|
@ -1 +1 @@
|
|||
export const Divider = () => <div className="w-full my-1 h-[1px] bg-app-line/60" />;
|
||||
export const Divider = () => <div className="bg-app-line/60 my-1 h-[1px] w-full" />;
|
||||
|
|
|
@ -31,7 +31,7 @@ export default function FavoriteButton(props: Props) {
|
|||
|
||||
return (
|
||||
<Button onClick={toggleFavorite} size="icon">
|
||||
<Heart weight={favorite ? 'fill' : 'regular'} className="w-[18px] h-[18px]" />
|
||||
<Heart weight={favorite ? 'fill' : 'regular'} className="h-[18px] w-[18px]" />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ export default function Note(props: Props) {
|
|||
2000
|
||||
);
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const debouncedNote = useCallback((note: string) => debounce(note), [props.data.id, fileSetNote]);
|
||||
|
||||
// when input is updated, cache note
|
||||
|
@ -43,7 +44,7 @@ export default function Note(props: Props) {
|
|||
<MetaContainer>
|
||||
<MetaTitle>Note</MetaTitle>
|
||||
<TextArea
|
||||
className="mt-2 mb-1 text-xs leading-snug !py-2"
|
||||
className="mt-2 mb-1 !py-2 text-xs leading-snug"
|
||||
value={note || ''}
|
||||
onChange={handleNoteUpdate}
|
||||
/>{' '}
|
||||
|
|
|
@ -9,7 +9,7 @@ export const DriveListItem: React.FC<DriveListItemProps> = (props) => {
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'rounded px-1.5 py-1 text-xs font-medium inline-block cursor-default',
|
||||
'inline-block cursor-default rounded px-1.5 py-1 text-xs font-medium',
|
||||
props.className
|
||||
)}
|
||||
></div>
|
||||
|
|
|
@ -105,25 +105,25 @@ export function JobsManager() {
|
|||
const clearAllJobs = useLibraryMutation(['jobs.clearAll']);
|
||||
|
||||
return (
|
||||
<div className="h-full pb-10 overflow-hidden">
|
||||
<div className="h-full overflow-hidden pb-10">
|
||||
<HeaderContainer>
|
||||
<CategoryHeading className="ml-2">Recent Jobs</CategoryHeading>
|
||||
<div className="flex-grow" />
|
||||
<div className="grow" />
|
||||
|
||||
<Button onClick={() => clearAllJobs.mutate(null)} size="icon">
|
||||
<Tooltip label="Clear out finished jobs">
|
||||
<Trash className="w-5 h-5" />
|
||||
<Trash className="h-5 w-5" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
<PopoverClose asChild>
|
||||
<Button size="icon">
|
||||
<Tooltip label="Close">
|
||||
<X className="w-5 h-5" />
|
||||
<X className="h-5 w-5" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
</PopoverClose>
|
||||
</HeaderContainer>
|
||||
<div className="h-full mr-1 overflow-x-hidden custom-scroll inspector-scroll">
|
||||
<div className="custom-scroll inspector-scroll mr-1 h-full overflow-x-hidden">
|
||||
<div className="">
|
||||
<div className="py-1">
|
||||
{runningJobs.data?.map((job) => (
|
||||
|
@ -133,7 +133,7 @@ export function JobsManager() {
|
|||
<Job key={job.id} job={job} />
|
||||
))}
|
||||
{jobs.data?.length === 0 && runningJobs.data?.length === 0 && (
|
||||
<div className="flex items-center justify-center h-32 text-ink-dull">No jobs.</div>
|
||||
<div className="text-ink-dull flex h-32 items-center justify-center">No jobs.</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -149,20 +149,20 @@ function Job({ job }: { job: JobReport }) {
|
|||
};
|
||||
const isRunning = job.status === 'Running';
|
||||
return (
|
||||
<div className="flex items-center px-2 py-2 pl-4 border-b border-app-line/50 bg-opacity-60">
|
||||
<div className="border-app-line/50 bg-opacity/60 flex items-center border-b p-2 pl-4">
|
||||
<Tooltip label={job.status}>
|
||||
<niceData.icon className={clsx('w-5 h-5 mr-3')} />
|
||||
<niceData.icon className={clsx('mr-3 h-5 w-5')} />
|
||||
</Tooltip>
|
||||
<div className="flex flex-col truncate">
|
||||
<span className="mt-0.5 font-semibold truncate">
|
||||
<span className="mt-0.5 truncate font-semibold">
|
||||
{isRunning ? job.message : niceData.name}
|
||||
</span>
|
||||
{isRunning && (
|
||||
<div className="w-full my-1">
|
||||
<div className="my-1 w-full">
|
||||
<ProgressBar value={job.completed_task_count} total={job.task_count} />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center truncate text-ink-faint">
|
||||
<div className="text-ink-faint flex items-center truncate">
|
||||
<span className="text-xs">
|
||||
{isRunning ? 'Elapsed' : job.status === 'Failed' ? 'Failed after' : 'Took'}{' '}
|
||||
{job.seconds_elapsed
|
||||
|
@ -178,12 +178,12 @@ function Job({ job }: { job: JobReport }) {
|
|||
</div>
|
||||
{/* <span className="mt-0.5 opacity-50 text-tiny text-ink-faint">{job.id}</span> */}
|
||||
</div>
|
||||
<div className="flex-grow" />
|
||||
<div className="flex flex-row space-x-2 ml-7">
|
||||
<div className="grow" />
|
||||
<div className="ml-7 flex flex-row space-x-2">
|
||||
{job.status === 'Running' && (
|
||||
<Button size="icon">
|
||||
<Tooltip label="Pause">
|
||||
<Pause className="w-4 h-4" />
|
||||
<Pause className="h-4 w-4" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
)}
|
||||
|
@ -196,7 +196,7 @@ function Job({ job }: { job: JobReport }) {
|
|||
)}
|
||||
<Button size="icon">
|
||||
<Tooltip label="Remove">
|
||||
<X className="w-4 h-4" />
|
||||
<X className="h-4 w-4" />
|
||||
</Tooltip>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -67,9 +67,9 @@ export const KeyDropdown = ({
|
|||
// most of this is copied over from the `OverlayPanel`
|
||||
className={clsx(
|
||||
'flex flex-col',
|
||||
'pl-4 pr-4 pt-2 pb-2 z-50 m-2 space-y-1',
|
||||
'select-none cursor-default rounded-lg',
|
||||
'text-left text-sm text-ink',
|
||||
'z-50 m-2 space-y-1 px-4 py-2',
|
||||
'cursor-default select-none rounded-lg',
|
||||
'text-ink text-left text-sm',
|
||||
'bg-app-overlay/80 backdrop-blur',
|
||||
// 'border border-app-overlay',
|
||||
'shadow-2xl shadow-black/60 ',
|
||||
|
@ -102,13 +102,13 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'flex items-center justify-between px-2 py-1.5 shadow-app-shade/10 text-sm bg-app-box shadow-lg rounded-lg'
|
||||
'shadow-app-shade/10 bg-app-box flex items-center justify-between rounded-lg px-2 py-1.5 text-sm shadow-lg'
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<KeyIcon
|
||||
className={clsx(
|
||||
'w-5 h-5 ml-1 mr-3',
|
||||
'ml-1 mr-3 h-5 w-5',
|
||||
data.mounted ? (data.locked ? 'text-accent' : 'text-accent') : 'text-gray-400/80'
|
||||
)}
|
||||
/>
|
||||
|
@ -116,33 +116,33 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
|
|||
<div className="flex flex-row items-center">
|
||||
<div className="font-semibold">{data.name}</div>
|
||||
{data.mounted && (
|
||||
<div className="inline ml-2 px-1 text-[8pt] font-medium text-gray-300 bg-gray-500 rounded">
|
||||
<div className="ml-2 inline rounded bg-gray-500 px-1 text-[8pt] font-medium text-gray-300">
|
||||
{data.nodes?.length || 0 > 0 ? `${data.nodes?.length || 0} nodes` : 'This node'}
|
||||
</div>
|
||||
)}
|
||||
{data.default && (
|
||||
<div className="inline ml-2 px-1 text-[8pt] font-medium text-gray-300 bg-gray-500 rounded">
|
||||
<div className="ml-2 inline rounded bg-gray-500 px-1 text-[8pt] font-medium text-gray-300">
|
||||
Default
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* <div className="text-xs text-gray-300 opacity-30">#{data.id}</div> */}
|
||||
{data.stats ? (
|
||||
<div className="flex flex-row mt-[1px] space-x-3">
|
||||
<div className="mt-[1px] flex flex-row space-x-3">
|
||||
{data.stats.objectCount && (
|
||||
<div className="text-[8pt] font-medium text-ink-dull opacity-30">
|
||||
<div className="text-ink-dull text-[8pt] font-medium opacity-30">
|
||||
{data.stats.objectCount} Objects
|
||||
</div>
|
||||
)}
|
||||
{data.stats.containerCount && (
|
||||
<div className="text-[8pt] font-medium text-ink-dull opacity-30">
|
||||
<div className="text-ink-dull text-[8pt] font-medium opacity-30">
|
||||
{data.stats.containerCount} Containers
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
!data.mounted && (
|
||||
<div className="text-[8pt] font-medium text-ink-dull opacity-30">
|
||||
<div className="text-ink-dull text-[8pt] font-medium opacity-30">
|
||||
{data.queue.has(data.id) ? 'Key mounting...' : 'Key not mounted'}
|
||||
</div>
|
||||
)
|
||||
|
@ -153,14 +153,14 @@ export const Key: React.FC<{ data: Key; index: number }> = ({ data, index }) =>
|
|||
{data.mounted && (
|
||||
<Tooltip label="Browse files">
|
||||
<Button size="icon">
|
||||
<Eye className="w-4 h-4 text-ink-faint" />
|
||||
<Eye className="text-ink-faint h-4 w-4" />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
<KeyDropdown
|
||||
trigger={
|
||||
<Button size="icon">
|
||||
<DotsThree className="w-4 h-4 text-ink-faint" />
|
||||
<DotsThree className="text-ink-faint h-4 w-4" />
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
|
@ -226,7 +226,7 @@ export const KeyDropdownItem = (props: {
|
|||
}) => {
|
||||
return (
|
||||
<DropdownMenu.DropdownMenuItem
|
||||
className="!cursor-default select-none text-menu-ink focus:outline-none py-0.5 active:opacity-80"
|
||||
className="text-menu-ink !cursor-default select-none py-0.5 focus:outline-none active:opacity-80"
|
||||
onClick={props.onClick}
|
||||
hidden={props.hidden}
|
||||
>
|
||||
|
@ -237,9 +237,9 @@ export const KeyDropdownItem = (props: {
|
|||
|
||||
export const DummyKey = (props: { text: string }) => {
|
||||
return (
|
||||
<div className="flex items-center justify-between px-2 py-1.5 pt-2 pb-2 shadow-app-shade/10 text-sm bg-app-box shadow-lg rounded-lg">
|
||||
<div className="shadow-app-shade/10 bg-app-box flex items-center justify-between rounded-lg p-2 py-1.5 text-sm shadow-lg">
|
||||
<div className="flex items-center">
|
||||
<KeyIcon className="w-5 h-5 ml-1 mr-3 text-gray-400/80" />
|
||||
<KeyIcon className="ml-1 mr-3 h-5 w-5 text-gray-400/80" />
|
||||
<div className="flex flex-col ">
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="font-medium">{props.text}</div>
|
||||
|
|
|
@ -65,8 +65,8 @@ export const KeyList = (props: KeyListProps) => {
|
|||
const unmountAll = useLibraryMutation(['keys.unmountAll']);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full max-h-[360px]">
|
||||
<div className="p-3 custom-scroll overlay-scroll">
|
||||
<div className="flex h-full max-h-[360px] flex-col">
|
||||
<div className="custom-scroll overlay-scroll p-3">
|
||||
<div className="">
|
||||
{/* <CategoryHeading>Mounted keys</CategoryHeading> */}
|
||||
<div className="space-y-1.5">
|
||||
|
@ -74,7 +74,7 @@ export const KeyList = (props: KeyListProps) => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full p-2 border-t border-app-line rounded-b-md">
|
||||
<div className="border-app-line flex w-full rounded-b-md border-t p-2">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="gray"
|
||||
|
@ -84,7 +84,7 @@ export const KeyList = (props: KeyListProps) => {
|
|||
>
|
||||
Unmount All
|
||||
</Button>
|
||||
<div className="flex-grow" />
|
||||
<div className="grow" />
|
||||
<Button size="sm" variant="gray">
|
||||
Close
|
||||
</Button>
|
||||
|
|
|
@ -38,39 +38,39 @@ export function KeyManager(props: KeyManagerProps) {
|
|||
|
||||
return (
|
||||
<div className="p-2">
|
||||
<div className="relative flex flex-grow mb-2">
|
||||
<div className="relative mb-2 flex grow">
|
||||
<Input
|
||||
value={masterPassword}
|
||||
onChange={(e) => setMasterPassword(e.target.value)}
|
||||
autoFocus
|
||||
type={showMasterPassword ? 'text' : 'password'}
|
||||
className="flex-grow !py-0.5"
|
||||
className="grow !py-0.5"
|
||||
placeholder="Master Password"
|
||||
/>
|
||||
<Button
|
||||
onClick={() => setShowMasterPassword(!showMasterPassword)}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<MPCurrentEyeIcon className="w-4 h-4" />
|
||||
<MPCurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{enterSkManually && (
|
||||
<div className="relative flex flex-grow mb-2">
|
||||
<div className="relative mb-2 flex grow">
|
||||
<Input
|
||||
value={secretKey}
|
||||
onChange={(e) => setSecretKey(e.target.value)}
|
||||
type={showSecretKey ? 'text' : 'password'}
|
||||
className="flex-grow !py-0.5"
|
||||
className="grow !py-0.5"
|
||||
placeholder="Secret Key"
|
||||
/>
|
||||
<Button
|
||||
onClick={() => setShowSecretKey(!showSecretKey)}
|
||||
size="icon"
|
||||
className="border-none absolute right-[5px] top-[5px]"
|
||||
className="absolute right-[5px] top-[5px] border-none"
|
||||
>
|
||||
<SKCurrentEyeIcon className="w-4 h-4" />
|
||||
<SKCurrentEyeIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
@ -93,7 +93,7 @@ export function KeyManager(props: KeyManagerProps) {
|
|||
Unlock
|
||||
</Button>
|
||||
{!enterSkManually && (
|
||||
<div className="relative flex flex-grow">
|
||||
<div className="relative flex grow">
|
||||
<p
|
||||
className="text-accent mt-2"
|
||||
onClick={(e) => {
|
||||
|
@ -118,7 +118,7 @@ export function KeyManager(props: KeyManagerProps) {
|
|||
<Tabs.Trigger className="text-sm font-medium" value="keys">
|
||||
Keys
|
||||
</Tabs.Trigger>
|
||||
<div className="flex-grow" />
|
||||
<div className="grow" />
|
||||
<Button
|
||||
size="icon"
|
||||
onClick={() => {
|
||||
|
@ -128,7 +128,7 @@ export function KeyManager(props: KeyManagerProps) {
|
|||
variant="subtle"
|
||||
className="text-ink-faint"
|
||||
>
|
||||
<Lock className="w-4 h-4 text-ink-faint" />
|
||||
<Lock className="text-ink-faint h-4 w-4" />
|
||||
</Button>
|
||||
<ButtonLink
|
||||
to="/settings/keys"
|
||||
|
@ -136,7 +136,7 @@ export function KeyManager(props: KeyManagerProps) {
|
|||
variant="subtle"
|
||||
className="text-ink-faint"
|
||||
>
|
||||
<Gear className="w-4 h-4 text-ink-faint" />
|
||||
<Gear className="text-ink-faint h-4 w-4" />
|
||||
</ButtonLink>
|
||||
</Tabs.List>
|
||||
</div>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue