Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENG-1950] Improve UI structure #2799

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
506e6c1
refactored Filters.tsx and designed date range API
Sep 22, 2024
ca6d5ef
progress on implementation
Sep 22, 2024
5941d63
completed implementing previous filters
Sep 22, 2024
295b716
tweaks wip
Sep 22, 2024
5582653
packages
Sep 22, 2024
9ba33fb
tweaks + srt support
Sep 25, 2024
d8ffe86
Merge branch 'main' of github.com:spacedriveapp/spacedrive into eng-1…
iLynxcat Oct 31, 2024
88d9040
Merge branch 'main' of github.com:spacedriveapp/spacedrive into eng-1…
iLynxcat Oct 31, 2024
8c5dff1
Add devices module and integrate device management into API; enhance …
jamiepine Nov 5, 2024
cb81cfa
Make overview cards composable
jamiepine Nov 5, 2024
fe218fc
Implement lazy loading for overview cards and add CardWrapper for hot…
jamiepine Nov 5, 2024
167170d
use default card configurations and fix responsive grid sizings
jamiepine Nov 5, 2024
e1a0988
Implement .sdvolume file read/write operations. Enhance storage bar r…
jamiepine Nov 6, 2024
2da3ec6
storage meter, volume alerts and ui tweaks
jamiepine Nov 6, 2024
b41b92a
fix update lib stats + 0.5.0 version bump
jamiepine Nov 6, 2024
a277d05
0.5.0 lock
jamiepine Nov 6, 2024
0fa0a74
some experimental cards, will be feature flagged before merge
jamiepine Nov 7, 2024
b55310a
ignore swift vscode extension index files
iLynxcat Nov 7, 2024
a5ef958
add migration to remove old `storage_statistics`
iLynxcat Nov 7, 2024
7b1355e
relocate small screen override
iLynxcat Nov 7, 2024
43d9d2b
refresh the forbidden 404 page
iLynxcat Nov 7, 2024
bf0fb51
bring account tab back temp
jamiepine Nov 7, 2024
9a0ac02
Merge branch 'eng-1950-improve-ui-structure' of github.com:spacedrive…
iLynxcat Nov 10, 2024
7ee1065
Merge branch 'main' into eng-1896-add-date-range-to-search-options
jamiepine Dec 9, 2024
51a58f7
Merge branch 'main' into eng-1950-improve-ui-structure
jamiepine Dec 10, 2024
a12c337
Merge branch 'eng-1896-add-date-range-to-search-options' into eng-195…
jamiepine Dec 10, 2024
9df4b07
swapy
jamiepine Dec 10, 2024
83651c1
wip
jamiepine Dec 10, 2024
36d3faa
working point
jamiepine Dec 10, 2024
04a12d0
fix types
jamiepine Dec 10, 2024
21e985c
better swappy
jamiepine Dec 10, 2024
483e749
better search
jamiepine Dec 10, 2024
331ea45
better swappy
jamiepine Dec 10, 2024
440d1b8
performance fix
jamiepine Dec 10, 2024
04bab6c
yes
jamiepine Dec 10, 2024
e93477f
checkpoint
jamiepine Dec 10, 2024
841ce12
checkpoint
jamiepine Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
better search
jamiepine committed Dec 10, 2024
commit 483e749be80329258c289f5b9d8d0ce12be08c6e
5 changes: 4 additions & 1 deletion interface/app/$libraryId/TopBar/Context.tsx
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ export function useContextValue() {
const [children, setChildren] = useState<HTMLDivElement | null>(null);
const [fixedArgs, setFixedArgs] = useState<SearchFilterArgs[] | null>(null);
const [topBarHeight, setTopBarHeight] = useState(0);
const [isSearchExpanded, setIsSearchExpanded] = useState(false);

return {
left,
@@ -23,7 +24,9 @@ export function useContextValue() {
fixedArgs,
setFixedArgs,
topBarHeight,
setTopBarHeight
setTopBarHeight,
isSearchExpanded,
setIsSearchExpanded
};
}

26 changes: 20 additions & 6 deletions interface/app/$libraryId/TopBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Plus, X } from '@phosphor-icons/react';
import clsx from 'clsx';
import { useEffect, useLayoutEffect, useRef } from 'react';
import React, { useEffect, useLayoutEffect, useRef } from 'react';
import useResizeObserver from 'use-resize-observer';
import { useSelector } from '@sd/client';
import { Tooltip } from '@sd/ui';
@@ -75,7 +75,7 @@ const TopBar = () => {
<div
data-tauri-drag-region
className={clsx(
'flex h-12 items-center gap-3.5 overflow-hidden px-3.5',
'flex h-[50px] items-center gap-3.5 overflow-hidden px-3.5',
'duration-250 transition-[background-color,border-color] ease-out',
isDragSelecting && 'pointer-events-none',
platform === 'macOS' &&
@@ -84,17 +84,31 @@ const TopBar = () => {
'pl-20'
)}
>
<NavigationButtons />

<div
data-tauri-drag-region
className="flex flex-1 items-center gap-3.5 overflow-hidden"
className={clsx(
'flex items-center gap-3.5 overflow-hidden',
ctx.isSearchExpanded ? 'w-0 opacity-0' : 'flex-1'
)}
>
<NavigationButtons />
<div ref={ctx.setLeft} className="overflow-hidden" />
</div>

<div ref={ctx.setCenter} />
<div
className={clsx(
'transition-all duration-200',
ctx.isSearchExpanded ? 'absolute inset-x-14 z-10' : 'relative w-auto'
)}
>
<div ref={(node) => node && ctx.setCenter(node)} />
</div>

<div ref={ctx.setRight} className="flex-1" />
<div
ref={ctx.setRight}
className={clsx('flex-1', ctx.isSearchExpanded ? 'w-0 opacity-0' : 'visible')}
/>
</div>

{tabs && <Tabs />}
4 changes: 2 additions & 2 deletions interface/app/$libraryId/location/$id.tsx
Original file line number Diff line number Diff line change
@@ -161,12 +161,12 @@ const LocationExplorer = ({ location }: { location: Location; path?: string }) =
/>
}
>
{search.open && (
{/* {search.open && (
<>
<hr className="w-full border-t border-sidebar-divider bg-sidebar-divider" />
<SearchOptions />
</>
)}
)} */}
</TopBarPortal>
</SearchContextProvider>
{isLocationIndexing ? (
96 changes: 61 additions & 35 deletions interface/app/$libraryId/search/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import clsx from 'clsx';
import { motion } from 'framer-motion';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useLocation, useNavigate } from 'react-router';
import { createSearchParams } from 'react-router-dom';
@@ -7,6 +9,7 @@ import { Input, ModifierKeys, Shortcut } from '@sd/ui';
import { useLocale, useOperatingSystem } from '~/hooks';
import { keybindForOs } from '~/util/keybinds';

import { useTopBarContext } from '../TopBar/Context';
import { useSearchContext } from './context';
import { useSearchStore } from './store';
import { SearchTarget } from './useSearch';
@@ -23,6 +26,7 @@ export default ({ redirectToSearch, defaultFilters, defaultTarget }: Props) => {
const navigate = useNavigate();
const searchStore = useSearchStore();
const locationState: { focusSearch?: boolean } = useLocation().state;
const topBarCtx = useTopBarContext();

const os = useOperatingSystem(true);
const keybind = keybindForOs(os);
@@ -67,6 +71,7 @@ export default ({ redirectToSearch, defaultFilters, defaultTarget }: Props) => {
}, [blurHandler, focusHandler]);

const [value, setValue] = useState(search.rawSearch);
const [isAnimating, setIsAnimating] = useState(false);

useEffect(() => {
if (search.rawSearch !== undefined) setValue(search.rawSearch);
@@ -105,43 +110,64 @@ export default ({ redirectToSearch, defaultFilters, defaultTarget }: Props) => {
const { t } = useLocale();

return (
<Input
ref={searchRef}
placeholder={t('search')}
className="mx-2 w-48 transition-all duration-200 focus-within:w-60"
size="sm"
value={value}
onChange={(e) => {
updateValue(e.target.value);
<motion.div
layout
className="mx-auto"
style={{ width: topBarCtx.isSearchExpanded ? 'calc(100% - 40px)' : '300px' }}
transition={{
type: 'spring',
stiffness: 300,
damping: 30
}}
autoFocus={locationState?.focusSearch || false}
onBlur={() => {
if (search.rawSearch === '' && !searchStore.interactingWithSearchOptions) {
clearValue();
search.setSearchBarFocused(false);
onAnimationStart={() => setIsAnimating(true)}
onAnimationComplete={() => setIsAnimating(false)}
>
<Input
ref={searchRef}
placeholder={
isAnimating
? ''
: topBarCtx.isSearchExpanded
? t('Find all files created today')
: t('search')
}
}}
onFocus={() => {
search.setSearchBarFocused(true);
search.setFilters?.((f) => {
if (!f) return defaultFilters ?? [];
else return f;
});
search.setTarget?.(search.target ?? defaultTarget);
}}
right={
<div className="pointer-events-none flex h-7 items-center space-x-1 opacity-70 group-focus-within:hidden">
{
<Shortcut
chars={keybind([ModifierKeys.Control], ['F'])}
aria-label={`Press ${
os === 'macOS' ? 'Command' : ModifierKeys.Control
}-F to focus search bar`}
className="border-none"
/>
className={clsx('mx-2', topBarCtx.isSearchExpanded ? '!rounded-xl' : '!rounded-lg')}
size={topBarCtx.isSearchExpanded ? 'md' : 'sm'}
value={value}
onChange={(e) => {
updateValue(e.target.value);
}}
autoFocus={locationState?.focusSearch || false}
onBlur={() => {
if (search.rawSearch === '' && !searchStore.interactingWithSearchOptions) {
clearValue();
search.setSearchBarFocused(false);
topBarCtx.setIsSearchExpanded(false);
}
</div>
}
/>
}}
onFocus={() => {
search.setSearchBarFocused(true);
search.setFilters?.((f) => {
if (!f) return defaultFilters ?? [];
else return f;
});
search.setTarget?.(search.target ?? defaultTarget);
topBarCtx.setIsSearchExpanded(true);
}}
right={
<div className="pointer-events-none flex h-7 items-center space-x-1 opacity-70 group-focus-within:hidden">
{
<Shortcut
chars={keybind([ModifierKeys.Control], ['F'])}
aria-label={`Press ${
os === 'macOS' ? 'Command' : ModifierKeys.Control
}-F to focus search bar`}
className="border-none"
/>
}
</div>
}
/>
</motion.div>
);
};

Unchanged files with check annotations Beta

await devices.refetch();
}, 10000);
return () => clearInterval(interval);
}, []);

Check warning on line 64 in apps/mobile/src/components/overview/Devices.tsx

GitHub Actions / ESLint

React Hook useEffect has a missing dependency: 'devices'. Either include it or remove the dependency array
useEffect(() => {
const getFSInfo = async () => {
} else if (swapyErrorsRef.current >= 3) {
console.error('Too many swapy errors, disabling drag functionality');
}
}, []);

Check warning on line 204 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

React Hook useCallback has a missing dependency: 'initializeSwapy'. Either include it or remove the dependency array
const [isSwapping, setIsSwapping] = useState(false);
const swapTimeoutRef = useRef<any>(null);
useEffect(() => {
return () => {
if (domCheckIntervalRef.current) {
clearInterval(domCheckIntervalRef.current);

Check warning on line 459 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

The ref value 'domCheckIntervalRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'domCheckIntervalRef.current' to a variable inside the effect, and use that variable in the cleanup function
}
if (swapTimeoutRef.current) {
clearTimeout(swapTimeoutRef.current);

Check warning on line 462 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

The ref value 'swapTimeoutRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'swapTimeoutRef.current' to a variable inside the effect, and use that variable in the cleanup function
}
};
}, []);
return () => {
resetInitializationState();
if (domCheckIntervalRef.current) {
cancelAnimationFrame(domCheckIntervalRef.current);

Check warning on line 472 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

The ref value 'domCheckIntervalRef.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'domCheckIntervalRef.current' to a variable inside the effect, and use that variable in the cleanup function
}
if (swapyRef.current) {
try {
else cardRefs.current.delete(card.id);
}}
data-swapy-slot={card.id}
className={clsx('flex-shrink-0', {

Check warning on line 495 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

Classname 'flex-shrink-0' should be updated to 'shrink-0' in Tailwind CSS v3!
'w-full sm:w-[calc(50%-8px)] lg:w-[calc(33.333%-12px)]': card.size === 'small',
'w-full lg:w-[calc(66.666%-8px)]': card.size === 'medium',
'w-full': card.size === 'large'
>
<div
data-swapy-item={card.id}
className="h-full w-full"

Check warning on line 511 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

Classnames 'h-full, w-full' could be replaced by the 'size-full' shorthand!
onTransitionEnd={() => {
console.log(`Card ${card.id} ready`);
handleCardLoad();
}}
>
<Card className="flex h-full w-full flex-col overflow-hidden bg-app-box/70">

Check warning on line 517 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

Classnames 'h-full, w-full' could be replaced by the 'size-full' shorthand!
<div
data-swapy-handle
className="flex cursor-grab items-center gap-2 border-b border-app-line/50 p-3 active:cursor-grabbing"
<div
ref={containerRef}
className="flex h-full w-full flex-wrap content-start gap-4 overflow-y-auto p-5"

Check warning on line 572 in interface/app/$libraryId/overview/index.tsx

GitHub Actions / ESLint

Classnames 'h-full, w-full' could be replaced by the 'size-full' shorthand!
>
{enabledCards.map(renderCard)}
</div>
</div>
<div className="mb-1">
<Label className="text-sm font-medium text-ink-faint">
<Icon name="Database" className="mr-1 mt-[-2px] inline h-4 w-4" />{' '}

Check warning on line 194 in interface/app/$libraryId/settings/client/general.tsx

GitHub Actions / ESLint

Classnames 'h-4, w-4' could be replaced by the 'size-4' shorthand!
Logs Folder
</Label>
<Input value={node.data?.data_path + '/logs'} />