Merge branch '0.5.0-dev' into eng-1828-migration-to-new-cloud-api-system
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 109 KiB |
@@ -77,7 +77,7 @@ const AboutScreen = () => {
|
||||
</View>
|
||||
<Divider />
|
||||
<View style={tw`my-5`}>
|
||||
<Text style={tw`mb-3 text-lg font-bold text-ink`}>Vision</Text>
|
||||
<Text style={tw`font-plex mb-3 text-lg font-bold text-ink`}>Vision</Text>
|
||||
<Text style={tw`w-full text-sm text-ink-faint`}>
|
||||
Many of us have multiple cloud accounts, drives that aren’t backed up and data
|
||||
at risk of loss. We depend on cloud services like Google Photos and iCloud, but
|
||||
@@ -91,7 +91,7 @@ const AboutScreen = () => {
|
||||
</View>
|
||||
<Divider />
|
||||
<View>
|
||||
<Text style={tw`my-5 text-lg font-bold text-ink`}>
|
||||
<Text style={tw`font-plex my-5 text-lg font-bold text-ink`}>
|
||||
Meet the contributors behind Spacedrive
|
||||
</Text>
|
||||
{/* TODO: Temporary image url approach until a solution is reached */}
|
||||
|
||||
@@ -113,13 +113,17 @@ export function ErrorPage({
|
||||
data-tauri-drag-region
|
||||
role="alert"
|
||||
className={
|
||||
'flex h-screen w-screen flex-col items-center justify-center border border-app-divider bg-app p-4' +
|
||||
(isMacOS ? ' rounded-lg' : '')
|
||||
'flex h-screen w-screen flex-col items-center justify-center border border-app-frame bg-app p-4' +
|
||||
(isMacOS ? ' rounded-[10px]' : '')
|
||||
}
|
||||
>
|
||||
<Dialogs />
|
||||
<p className="m-3 text-sm font-bold text-ink-faint">{t('app_crashed')}</p>
|
||||
<h1 className="text-2xl font-bold text-ink">{t('app_crashed_description')}</h1>
|
||||
<p className="m-3 font-plex text-sm font-bold tracking-wide text-ink-faint">
|
||||
{t('app_crashed')}
|
||||
</p>
|
||||
<h1 className="font-plex text-2xl font-bold tracking-tight text-ink">
|
||||
{t('app_crashed_description')}
|
||||
</h1>
|
||||
<pre className="m-2 max-w-[650px] whitespace-normal text-center text-ink">
|
||||
{message}
|
||||
</pre>
|
||||
|
||||
@@ -56,7 +56,7 @@ export default () => {
|
||||
popover={{ ...popover, setOpen: handleOpenChange }}
|
||||
className="z-[100] p-4 focus:outline-none"
|
||||
trigger={
|
||||
<h1 className="ml-1 w-full text-[7pt] text-sidebar-inkFaint/50">
|
||||
<h1 className="ml-1 w-full font-plex text-[7pt] tracking-widest text-sidebar-inkFaint/50">
|
||||
v{buildInfo.data?.version || '-.-.-'} - {buildInfo.data?.commit || 'dev'}
|
||||
</h1>
|
||||
}
|
||||
|
||||
@@ -106,7 +106,9 @@ const JobContainer = forwardRef<HTMLLIElement, JobContainerProps>((props, ref) =
|
||||
position="top"
|
||||
label={name}
|
||||
>
|
||||
<p className="w-fit max-w-[83%] truncate pl-1.5 font-semibold">{name}</p>
|
||||
<p className="w-fit max-w-[83%] truncate pl-1.5 font-plex font-semibold tracking-normal">
|
||||
{name}
|
||||
</p>
|
||||
</Tooltip>
|
||||
{textItems?.map((item, index) => {
|
||||
const filteredItems = item.filter((i) => i?.text);
|
||||
|
||||
@@ -121,7 +121,9 @@ export function JobManager() {
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
<span className="ml-1 font-medium">{t('recent_jobs')}</span>
|
||||
<span className="ml-1 font-plex font-semibold tracking-wide">
|
||||
{t('recent_jobs')}
|
||||
</span>
|
||||
<div className="grow" />
|
||||
{toggleConfirmation ? (
|
||||
<div className="flex h-[85%] w-fit items-center justify-center gap-2 rounded-md border border-app-line bg-app/40 px-2">
|
||||
@@ -165,7 +167,7 @@ export function JobManager() {
|
||||
<div className="h-full border-r border-app-line/50">
|
||||
{jobGroups.data &&
|
||||
(jobGroups.data.length === 0 ? (
|
||||
<div className="flex h-32 items-center justify-center text-sidebar-inkDull">
|
||||
<div className="flex h-32 items-center justify-center font-plex text-sidebar-inkDull">
|
||||
{t('no_jobs')}
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -53,7 +53,9 @@ export function FeedbackPopover() {
|
||||
popover={{ ...popover, setOpen: handleOpenChange }}
|
||||
trigger={
|
||||
<Button variant="outline" className="flex items-center gap-1">
|
||||
<p className="text-[11px] font-normal text-sidebar-inkFaint">{t('feedback')}</p>
|
||||
<p className="font-plex text-xs font-normal text-sidebar-inkFaint">
|
||||
{t('feedback')}
|
||||
</p>
|
||||
</Button>
|
||||
}
|
||||
className="z-[100]"
|
||||
|
||||
@@ -7,7 +7,7 @@ import { usePlatform } from '~/util/Platform';
|
||||
|
||||
const styles = cva(
|
||||
[
|
||||
'max-w flex grow flex-row items-center gap-0.5 truncate rounded px-2 py-1 text-sm font-medium outline-none',
|
||||
'max-w flex grow flex-row items-center gap-0.5 truncate rounded px-2 py-1 font-plex text-sm font-medium tracking-wide outline-none',
|
||||
'ring-inset ring-transparent ring-offset-0 focus:ring-1 focus:ring-accent focus:ring-offset-0'
|
||||
],
|
||||
{
|
||||
|
||||
@@ -18,10 +18,10 @@ import { FileKind } from '.';
|
||||
const INFO_ICON_CLASSLIST =
|
||||
'inline size-3 text-ink-faint opacity-0 ml-1 transition-opacity duration-300 group-hover:opacity-70';
|
||||
const TOTAL_FILES_CLASSLIST =
|
||||
'flex items-center justify-between whitespace-nowrap text-sm font-medium text-ink-dull mt-2 px-1';
|
||||
const UNIDENTIFIED_FILES_CLASSLIST = 'relative flex items-center text-xs text-ink-faint';
|
||||
'flex items-center justify-between whitespace-nowrap text-sm font-medium text-ink-dull mt-2 px-1 font-plex';
|
||||
const UNIDENTIFIED_FILES_CLASSLIST = 'relative flex items-center text-xs font-plex text-ink-faint';
|
||||
const BARS_CONTAINER_CLASSLIST =
|
||||
'relative mx-2.5 grid grow grid-cols-[repeat(auto-fit,_minmax(0,_1fr))] grid-rows-[136px_12px] items-end justify-items-center gap-x-1.5 gap-y-1 self-stretch';
|
||||
'relative mx-2.5 grid grow grid-cols-[repeat(auto-fit,_minmax(0,_1fr))] grid-rows-[136px_12px] font-plex tracking-wide items-end justify-items-center gap-x-1.5 gap-y-1 self-stretch';
|
||||
|
||||
const mapFractionalValue = (numerator: bigint, denominator: bigint, maxValue: bigint): string => {
|
||||
if (denominator === 0n) return '0';
|
||||
@@ -204,7 +204,7 @@ const FileKindStats: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex justify-center">
|
||||
<div className="flex justify-center tabular-nums">
|
||||
<Card
|
||||
ref={containerRef}
|
||||
className="max-w-1/2 group mx-1 flex h-[220px] w-full min-w-[400px] shrink-0 flex-col gap-2 bg-app-box/50"
|
||||
|
||||
@@ -14,7 +14,7 @@ const OverviewSection = ({
|
||||
<div className={clsx('group w-full', className)}>
|
||||
{title && (
|
||||
<div className="mb-3 flex w-full items-center gap-3 px-7">
|
||||
<div className="truncate font-bold">{title}</div>
|
||||
<div className="truncate font-plex font-bold">{title}</div>
|
||||
{typeof count === 'number' && <div className={COUNT_STYLE}>{count}</div>}
|
||||
<div className="grow" />
|
||||
<div className="flex flex-row gap-1 text-sidebar-inkFaint opacity-0 transition-all duration-300 hover:!opacity-100 group-hover:opacity-30">
|
||||
|
||||
@@ -65,7 +65,7 @@ const StatItem = ({ title, bytes, isLoading, info }: StatItemProps) => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'group/stat flex w-36 shrink-0 flex-col duration-75',
|
||||
'group/stat flex w-36 shrink-0 flex-col font-plex duration-75',
|
||||
!bytes && 'hidden'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { IconName } from '@sd/assets/util';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { humanizeSize } from '@sd/client';
|
||||
import { Card, CircularProgress, tw } from '@sd/ui';
|
||||
@@ -6,14 +7,16 @@ import { useIsDark, useLocale } from '~/hooks';
|
||||
|
||||
type StatCardProps = {
|
||||
name: string;
|
||||
icon: string;
|
||||
icon: IconName;
|
||||
totalSpace: string | number[];
|
||||
freeSpace?: string | number[];
|
||||
color: string;
|
||||
connectionType: 'lan' | 'p2p' | 'cloud' | null;
|
||||
};
|
||||
|
||||
const Pill = tw.div`px-1.5 py-[1px] rounded text-tiny font-medium text-ink-dull bg-app-box border border-app-line`;
|
||||
const NBSP = '\xa0';
|
||||
|
||||
const Pill = tw.div`px-1.5 py-[1px] rounded text-tiny font-medium text-ink-dull bg-app-box border border-app-line font-plex font-medium tracking-wide`;
|
||||
|
||||
const StatCard = ({ icon, name, connectionType, ...stats }: StatCardProps) => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
@@ -48,7 +51,7 @@ const StatCard = ({ icon, name, connectionType, ...stats }: StatCardProps) => {
|
||||
|
||||
return (
|
||||
<Card className="flex w-[280px] shrink-0 flex-col bg-app-box/50 !p-0">
|
||||
<div className="flex flex-row items-center gap-5 p-4 px-6">
|
||||
<div className="flex flex-row items-center gap-5 p-4">
|
||||
{stats.freeSpace && (
|
||||
<CircularProgress
|
||||
radius={40}
|
||||
@@ -79,13 +82,9 @@ const StatCard = ({ icon, name, connectionType, ...stats }: StatCardProps) => {
|
||||
</CircularProgress>
|
||||
)}
|
||||
<div className="flex flex-col overflow-hidden">
|
||||
<Icon
|
||||
className="-ml-1 min-h-[60px] min-w-[60px]"
|
||||
name={icon as any}
|
||||
size={60}
|
||||
/>
|
||||
<span className="truncate font-medium">{name}</span>
|
||||
<span className="mt-1 truncate text-tiny text-ink-faint">
|
||||
<Icon className="-ml-1 -mt-1 min-h-[60px] min-w-[60px]" name={icon} size={60} />
|
||||
<span className="mt-2 truncate font-plex font-bold">{name}</span>
|
||||
<span className="mt-0 whitespace-pre font-plex text-tiny font-semibold tracking-wide text-ink-faint">
|
||||
{freeSpace.value !== totalSpace.value && (
|
||||
<>
|
||||
{freeSpace.value} {t(`size_${freeSpace.unit.toLowerCase()}`)}{' '}
|
||||
@@ -99,8 +98,7 @@ const StatCard = ({ icon, name, connectionType, ...stats }: StatCardProps) => {
|
||||
<div className="flex h-10 flex-row items-center gap-1.5 border-t border-app-line px-2">
|
||||
{freeSpace.value === totalSpace.value && (
|
||||
<Pill>
|
||||
{totalSpace.value}
|
||||
{t(`size_${totalSpace.unit.toLowerCase()}`)}
|
||||
{totalSpace.value} {t(`size_${totalSpace.unit.toLowerCase()}`)}
|
||||
</Pill>
|
||||
)}
|
||||
<Pill className="uppercase">{connectionType || t('local')}</Pill>
|
||||
|
||||
@@ -30,7 +30,7 @@ const StorageBar: React.FC<StorageBarProps> = ({ sections }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-auto p-3">
|
||||
<div className="w-auto p-3 font-plex">
|
||||
<div className="relative mt-1 flex h-6 rounded">
|
||||
{sections.map((section, index) => {
|
||||
const isHovered = hoveredSectionIndex === index;
|
||||
|
||||
@@ -46,7 +46,7 @@ export const Heading = (props: HeaderProps) => {
|
||||
<div className="mb-3 flex">
|
||||
{props.children}
|
||||
<div className="grow">
|
||||
<h1 className="text-2xl font-bold">{props.title}</h1>
|
||||
<h1 className="font-plex text-2xl font-bold">{props.title}</h1>
|
||||
<p className="mt-1 text-sm text-gray-400">{props.description}</p>
|
||||
</div>
|
||||
{props.rightArea}
|
||||
|
||||
@@ -26,7 +26,7 @@ export default ({ mini, registerName, ...props }: PropsWithChildren<Props>) => {
|
||||
<div className={clsx('relative flex flex-row', props.containerClassName)}>
|
||||
<div className={clsx('flex w-full flex-col', !mini && 'pb-6', props.className)}>
|
||||
<div className="mb-1 flex items-center gap-1">
|
||||
<h3 className="text-sm font-medium text-ink">{props.title}</h3>
|
||||
<h3 className="font-plex text-sm font-semibold text-ink">{props.title}</h3>
|
||||
{props.toolTipLabel && (
|
||||
<Tooltip label={props.toolTipLabel as string}>
|
||||
<Info
|
||||
|
||||
@@ -27,7 +27,7 @@ import SidebarLink from '../Layout/Sidebar/SidebarLayout/Link';
|
||||
import { useLayoutStore } from '../Layout/store';
|
||||
import { NavigationButtons } from '../TopBar/NavigationButtons';
|
||||
|
||||
const Heading = tw.div`mb-1 ml-1 text-xs font-semibold text-gray-400`;
|
||||
const Heading = tw.div`mb-1 ml-1 text-xs font-semibold text-gray-400 font-plex tracking-wide`;
|
||||
const Section = tw.div`space-y-0.5`;
|
||||
|
||||
export default () => {
|
||||
|
||||
@@ -128,7 +128,7 @@ const UsageCard = memo(
|
||||
<div className="flex w-full items-center justify-center gap-3">
|
||||
<Icon name={icon} size={40} />
|
||||
<div className="w-full max-w-[120px]">
|
||||
<h1 className="text-lg font-medium">
|
||||
<h1 className="font-plex text-lg font-medium">
|
||||
{typeof titleCount === 'number' && (
|
||||
<span className="mr-1 text-ink-dull">{sizeCount}</span>
|
||||
)}
|
||||
|
||||
@@ -71,12 +71,14 @@ export const Component = () => {
|
||||
</div>
|
||||
<Divider />
|
||||
<div className="my-5">
|
||||
<h1 className="mb-3 text-lg font-bold text-ink">{t('about_vision_title')}</h1>
|
||||
<h1 className="mb-3 font-plex text-lg font-bold text-ink">
|
||||
{t('about_vision_title')}
|
||||
</h1>
|
||||
<p className="w-full text-sm text-ink-faint">{t('about_vision_text')}</p>
|
||||
</div>
|
||||
<Divider />
|
||||
<div>
|
||||
<h1 className="my-5 text-lg font-bold text-ink">
|
||||
<h1 className="my-5 font-plex text-lg font-bold text-ink">
|
||||
{t('meet_contributors_behind_spacedrive')}
|
||||
</h1>
|
||||
<img
|
||||
|
||||
@@ -24,7 +24,10 @@ export const Component = () => {
|
||||
{changelog.data?.map((release: any) => (
|
||||
<article
|
||||
key={release.version}
|
||||
className={clsx('prose prose-sm text-ink', isDark && 'prose-invert')}
|
||||
className={clsx(
|
||||
'prose prose-sm text-ink prose-headings:font-plex',
|
||||
isDark && 'prose-invert'
|
||||
)}
|
||||
>
|
||||
<Markdown
|
||||
skipHtml
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function OnboardingAlpha() {
|
||||
<div className="relative z-10 flex flex-col gap-5">
|
||||
<div className="mb-5 flex w-full items-center justify-center gap-2">
|
||||
<img src={AppLogo} alt="Spacedrive" className="size-8" />
|
||||
<h1 className="text-[25px] font-semibold">Spacedrive</h1>
|
||||
<h1 className="font-plex text-[25px] font-semibold">Spacedrive</h1>
|
||||
</div>
|
||||
<h1 className="text-[40px] font-bold">{t('alpha_release_title')}</h1>
|
||||
<p className="mx-auto w-full max-w-[450px] text-sm text-ink-faint">
|
||||
|
||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 214 KiB |
2
packages/assets/util/index.ts
generated
@@ -12,6 +12,8 @@ export const iconNames = Object.fromEntries(
|
||||
.map((key) => [key, key]) // Map key to [key, key] format
|
||||
) as Record<IconTypes, string>;
|
||||
|
||||
export type IconName = keyof typeof iconNames;
|
||||
|
||||
export const getIconByName = (name: IconTypes, isDark?: boolean) => {
|
||||
if (!isDark) name = (name + '_Light') as IconTypes;
|
||||
return icons[name];
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"typecheck": "tsc -b"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/ibm-plex-sans": "^5.1.0",
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"@phosphor-icons/react": "^2.0.13",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
|
||||
@@ -26,7 +26,7 @@ const hasHref = (props: ButtonProps | LinkButtonProps): props is LinkButtonProps
|
||||
|
||||
export const buttonStyles = cva(
|
||||
[
|
||||
'cursor-default items-center rounded-md border outline-none transition-colors duration-100',
|
||||
'cursor-default items-center rounded-md border font-plex font-semibold tracking-wide outline-none transition-colors duration-100',
|
||||
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-70',
|
||||
'focus:ring-none focus:ring-offset-none cursor-pointer ring-offset-app-box'
|
||||
],
|
||||
|
||||
@@ -145,7 +145,7 @@ export interface LabelProps extends Omit<React.ComponentProps<'label'>, 'htmlFor
|
||||
|
||||
export function Label({ slug, children, className, ...props }: LabelProps) {
|
||||
return (
|
||||
<label htmlFor={slug} className={clsx('text-sm font-bold', className)} {...props}>
|
||||
<label htmlFor={slug} className={clsx('font-plex text-sm font-bold', className)} {...props}>
|
||||
{children}
|
||||
</label>
|
||||
);
|
||||
|
||||
@@ -42,7 +42,7 @@ export const FormField = (props: FormFieldProps) => {
|
||||
return (
|
||||
<div className={props.className}>
|
||||
{props.label && (
|
||||
<Label slug={props.id} className="mb-1 flex font-medium">
|
||||
<Label slug={props.id} className="mb-1 flex font-semibold">
|
||||
{props.label}
|
||||
</Label>
|
||||
)}
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
import './style.scss';
|
||||
import '@fontsource/ibm-plex-sans/100.css';
|
||||
import '@fontsource/ibm-plex-sans/200.css';
|
||||
import '@fontsource/ibm-plex-sans/300.css';
|
||||
import '@fontsource/ibm-plex-sans/400.css';
|
||||
import '@fontsource/ibm-plex-sans/500.css';
|
||||
import '@fontsource/ibm-plex-sans/600.css';
|
||||
import '@fontsource/ibm-plex-sans/700.css';
|
||||
|
||||
@@ -23,6 +23,10 @@ module.exports = function (app, options) {
|
||||
xl: '1280px',
|
||||
...defaultTheme.screens
|
||||
},
|
||||
fontFamily: {
|
||||
sans: [...defaultTheme.fontFamily.sans],
|
||||
plex: ['IBM Plex Sans', ...defaultTheme.fontFamily.sans]
|
||||
},
|
||||
fontSize: {
|
||||
'tiny': '.65rem',
|
||||
'xs': '.75rem',
|
||||
|
||||