Files
spacedrive/interface/app/$libraryId/Explorer/OptionsPanel.tsx
Oscar Beaumont f7cd96732f @sd/client SolidJS support - Part 1 (#1920)
* `createSolid` + `createPersistedMutable`

* Move all Valtio stores to SolidJS

* Remove Valtio from `@sd/client`

* Missed auth store

* wip

* `useSolidStore` allow mutable setting

* Restructure `@sd/client` a bit

* Add `WithSolid` + custom `useObserver`

* Parse props both ways

* Universal Context

* Solid to React context working

* Working universal context

* context inheritance

* whoops

* Make it clearer how the demo works

* wip: `useUniversalQuery`
2024-01-09 08:05:01 +00:00

222 lines
6.1 KiB
TypeScript

import { RadixCheckbox, Select, SelectOption, Slider, tw, z } from '@sd/ui';
import { explorerLayout, useExplorerLayoutStore } from '~/../packages/client/src';
import i18n from '~/app/I18n';
import { SortOrderSchema } from '~/app/route-schemas';
import { useLocale } from '~/hooks';
import { useExplorerContext } from './Context';
import { createOrdering, getOrderingDirection, orderingKey } from './store';
const Subheading = tw.div`text-ink-dull mb-1 text-xs font-medium`;
export default () => {
const { t } = useLocale();
const explorer = useExplorerContext();
const layoutStore = useExplorerLayoutStore();
const settings = explorer.useSettingsSnapshot();
return (
<div className="flex w-80 flex-col gap-4 p-4">
{(settings.layoutMode === 'grid' || settings.layoutMode === 'media') && (
<div>
<Subheading>{t('item_size')}</Subheading>
{settings.layoutMode === 'grid' ? (
<Slider
onValueChange={(value) => {
explorer.settingsStore.gridItemSize = value[0] || 100;
}}
defaultValue={[settings.gridItemSize]}
max={200}
step={10}
min={60}
/>
) : (
<Slider
defaultValue={[10 - settings.mediaColumns]}
min={0}
max={6}
step={1}
onValueChange={([val]) => {
if (val !== undefined)
explorer.settingsStore.mediaColumns = 10 - val;
}}
/>
)}
</div>
)}
{settings.layoutMode === 'grid' && (
<div>
<Subheading>{t('grid_gap')}</Subheading>
<Slider
onValueChange={([val]) => {
if (val) explorer.settingsStore.gridGap = val;
}}
defaultValue={[settings.gridGap]}
max={16}
min={4}
step={4}
/>
</div>
)}
{(settings.layoutMode === 'grid' || settings.layoutMode === 'media') && (
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col">
<Subheading>{t('sort_by')}</Subheading>
<Select
value={settings.order ? orderingKey(settings.order) : 'none'}
size="sm"
className="w-full"
onChange={(key) => {
if (key === 'none') explorer.settingsStore.order = null;
else
explorer.settingsStore.order = createOrdering(
key,
explorer.settingsStore.order
? getOrderingDirection(explorer.settingsStore.order)
: 'Asc'
);
}}
>
<SelectOption value="none">{t('none')}</SelectOption>
{explorer.orderingKeys?.options.map((option) => (
<SelectOption key={option.value} value={option.value}>
{option.description}
</SelectOption>
))}
</Select>
</div>
<div className="flex flex-col">
<Subheading>{t('direction')}</Subheading>
<Select
value={settings.order ? getOrderingDirection(settings.order) : 'Asc'}
size="sm"
className="w-full"
disabled={explorer.settingsStore.order === null}
onChange={(order) => {
if (explorer.settingsStore.order === null) return;
explorer.settingsStore.order = createOrdering(
orderingKey(explorer.settingsStore.order),
order
);
}}
>
{SortOrderSchema.options.map((o) => (
<SelectOption key={o.value} value={o.value}>
{o.value}
</SelectOption>
))}
</Select>
</div>
</div>
)}
<div>
<Subheading>{t('explorer')}</Subheading>
<div className="grid grid-cols-2 gap-y-1">
<RadixCheckbox
checked={layoutStore.showPathBar}
label={t('show_path_bar')}
name="showPathBar"
onCheckedChange={(value) => {
if (typeof value !== 'boolean') return;
explorerLayout.showPathBar = value;
}}
/>
{settings.layoutMode === 'grid' && (
<RadixCheckbox
checked={settings.showBytesInGridView}
label={t('show_object_size')}
name="showBytesInGridView"
onCheckedChange={(value) => {
if (typeof value !== 'boolean') return;
explorer.settingsStore.showBytesInGridView = value;
}}
/>
)}
<RadixCheckbox
checked={settings.showHiddenFiles}
label={t('show_hidden_files')}
name="showHiddenFiles"
onCheckedChange={(value) => {
if (typeof value !== 'boolean') return;
explorer.settingsStore.showHiddenFiles = value;
}}
/>
{settings.layoutMode === 'media' && (
<RadixCheckbox
checked={settings.mediaAspectSquare}
label={t('square_thumbnails')}
name="mediaAspectSquare"
onCheckedChange={(value) => {
if (typeof value !== 'boolean') return;
explorer.settingsStore.mediaAspectSquare = value;
}}
/>
)}
</div>
</div>
{settings.layoutMode === 'media' && (
<div>
<Subheading>{t('media_view_context')}</Subheading>
<Select
className="w-full"
value={
explorer.settingsStore.mediaViewWithDescendants
? 'withDescendants'
: 'withoutDescendants'
}
onChange={(value) => {
explorer.settingsStore.mediaViewWithDescendants =
value === 'withDescendants';
}}
>
{mediaViewContextActions.options.map((option) => (
<SelectOption key={option.value} value={option.value}>
{option.description}
</SelectOption>
))}
</Select>
</div>
)}
<div>
<Subheading>{t('double_click_action')}</Subheading>
<Select
className="w-full"
value={settings.openOnDoubleClick}
onChange={(value) => {
explorer.settingsStore.openOnDoubleClick = value;
}}
>
{doubleClickActions.options.map((option) => (
<SelectOption key={option.value} value={option.value}>
{option.description}
</SelectOption>
))}
</Select>
</div>
</div>
);
};
const doubleClickActions = z.union([
z.literal('openFile').describe(i18n.t('open_file')),
z.literal('quickPreview').describe(i18n.t('quick_preview'))
]);
const mediaViewContextActions = z.union([
z.literal('withDescendants').describe(i18n.t('current_directory_with_descendants')),
z.literal('withoutDescendants').describe(i18n.t('current_directory'))
]);