diff --git a/interface/app/$libraryId/Explorer/OptionsPanel/index.tsx b/interface/app/$libraryId/Explorer/OptionsPanel/index.tsx index e0fedb388..61091f41b 100644 --- a/interface/app/$libraryId/Explorer/OptionsPanel/index.tsx +++ b/interface/app/$libraryId/Explorer/OptionsPanel/index.tsx @@ -174,6 +174,15 @@ export default () => { explorerLayout.showPathBar = value; }} /> + { + if (typeof value !== 'boolean') return; + explorerLayout.showTags = value; + }} + /> {settings.layoutMode === 'grid' && ( { const InnerDroppable = () => { const item = useGridViewItemContext(); const { isDroppable } = useExplorerDroppableContext(); - return ( <>
{ >
- ); @@ -103,6 +104,7 @@ const ItemFileThumb = () => { const ItemMetadata = () => { const item = useGridViewItemContext(); const { isDroppable } = useExplorerDroppableContext(); + const explorerLayout = useExplorerLayoutStore(); const isRenaming = useSelector(explorerStore, (s) => s.isRenaming && item.selected); @@ -117,11 +119,35 @@ const ItemMetadata = () => { selected={item.selected} /> + {explorerLayout.showTags && } {item.data.type === 'Label' && } ); }; +const ItemTags = () => { + const item = useGridViewItemContext(); + const object = getItemObject(item.data); + const filePath = getItemFilePath(item.data); + const data = object || filePath; + const tags = data && 'tags' in data ? data.tags : []; + return ( +
+ {tags?.slice(0, 3).map((tag: {tag: Tag}, i: number) => ( +
+ ))} +
+ ); +} + const ItemSize = () => { const item = useGridViewItemContext(); const { showBytesInGridView } = useExplorerContext().useSettingsSnapshot(); diff --git a/interface/app/$libraryId/Explorer/View/GridView/index.tsx b/interface/app/$libraryId/Explorer/View/GridView/index.tsx index daf89cae9..15d3b6101 100644 --- a/interface/app/$libraryId/Explorer/View/GridView/index.tsx +++ b/interface/app/$libraryId/Explorer/View/GridView/index.tsx @@ -1,6 +1,7 @@ import { Grid, useGrid } from '@virtual-grid/react'; import { useCallback } from 'react'; +import { useExplorerLayoutStore } from '@sd/client'; import { useExplorerContext } from '../../Context'; import { getItemData, getItemId, uniqueId } from '../../util'; import { useExplorerViewContext } from '../Context'; @@ -15,10 +16,12 @@ export const GridView = () => { const explorer = useExplorerContext(); const explorerView = useExplorerViewContext(); const explorerSettings = explorer.useSettingsSnapshot(); + const layoutStore = useExplorerLayoutStore(); - const itemDetailsHeight = 44 + (explorerSettings.showBytesInGridView ? 20 : 0); + const itemDetailsHeight = (layoutStore.showTags ? 60 : 44) + (explorerSettings.showBytesInGridView ? 20 : 0); const itemHeight = explorerSettings.gridItemSize + itemDetailsHeight; + const BOTTOM_PADDING = layoutStore.showTags ? 16 : 12; const grid = useGrid({ scrollRef: explorer.scrollRef, count: explorer.items?.length ?? 0, @@ -26,7 +29,7 @@ export const GridView = () => { columns: 'auto', size: { width: explorerSettings.gridItemSize, height: itemHeight }, padding: { - bottom: PADDING + (explorerView.scrollPadding?.bottom ?? 0), + bottom: BOTTOM_PADDING + (explorerView.scrollPadding?.bottom ?? 0), x: PADDING, y: PADDING }, diff --git a/interface/app/$libraryId/Explorer/View/ListView/Item.tsx b/interface/app/$libraryId/Explorer/View/ListView/Item.tsx index 879b38c46..7f9c2cdab 100644 --- a/interface/app/$libraryId/Explorer/View/ListView/Item.tsx +++ b/interface/app/$libraryId/Explorer/View/ListView/Item.tsx @@ -1,7 +1,7 @@ +import { getItemFilePath, useSelector, type ExplorerItem } from '@sd/client'; import { flexRender, type Cell } from '@tanstack/react-table'; import clsx from 'clsx'; import { memo, useMemo } from 'react'; -import { getItemFilePath, useSelector, type ExplorerItem } from '@sd/client'; import { TABLE_PADDING_X } from '.'; import { useExplorerContext } from '../../Context'; diff --git a/interface/app/$libraryId/Explorer/View/ListView/useTable.tsx b/interface/app/$libraryId/Explorer/View/ListView/useTable.tsx index 75d6e5d62..2e1e01702 100644 --- a/interface/app/$libraryId/Explorer/View/ListView/useTable.tsx +++ b/interface/app/$libraryId/Explorer/View/ListView/useTable.tsx @@ -1,3 +1,13 @@ +import { + getExplorerItemData, + getIndexedItemFilePath, + getItemFilePath, + getItemObject, + humanizeSize, + useExplorerLayoutStore, + useSelector, + type ExplorerItem +} from '@sd/client'; import { CellContext, functionalUpdate, @@ -9,15 +19,6 @@ import clsx from 'clsx'; import dayjs from 'dayjs'; import { memo, useMemo } from 'react'; import { stringify } from 'uuid'; -import { - getExplorerItemData, - getIndexedItemFilePath, - getItemFilePath, - getItemObject, - humanizeSize, - useSelector, - type ExplorerItem -} from '@sd/client'; import { useLocale } from '~/hooks'; import { useExplorerContext } from '../../Context'; @@ -48,6 +49,7 @@ const NameCell = memo(({ item, selected }: { item: ExplorerItem; selected: boole const explorer = useExplorerContext(); const explorerSettings = explorer.useSettingsSnapshot(); + const explorerLayout = useExplorerLayoutStore(); return (
@@ -66,15 +68,41 @@ const NameCell = memo(({ item, selected }: { item: ExplorerItem; selected: boole selected={selected} allowHighlight={false} style={{ fontSize: LIST_VIEW_TEXT_SIZES[explorerSettings.listViewTextSize] }} - className="absolute top-1/2 z-10 max-w-full -translate-y-1/2" - idleClassName="!w-full" + className="absolute top-1/2 z-10 -translate-y-1/2" + idleClassName={clsx(explorerLayout.showTags ? '!w-4/5' : '!w-full')} editLines={3} /> + {explorerLayout.showTags && ( + + )}
); }); +const Tags = ({item}: {item: ExplorerItem}) => { + const object = getItemObject(item); + const filePath = getItemFilePath(item); + const data = object || filePath; + const tags = data && 'tags' in data ? data.tags : []; + return ( +
+ {tags.map(({tag}, i: number) => ( +
+ ))} +
+ ) +} + + const KindCell = ({ kind }: { kind: string }) => { const explorer = useExplorerContext(); const explorerSettings = explorer.useSettingsSnapshot(); diff --git a/interface/app/$libraryId/Explorer/useExplorer.ts b/interface/app/$libraryId/Explorer/useExplorer.ts index 36c798e62..88af654df 100644 --- a/interface/app/$libraryId/Explorer/useExplorer.ts +++ b/interface/app/$libraryId/Explorer/useExplorer.ts @@ -1,7 +1,3 @@ -import { useCallback, useEffect, useMemo, useRef, useState, type RefObject } from 'react'; -import { useDebouncedCallback } from 'use-debounce'; -import { proxy, snapshot, subscribe, useSnapshot } from 'valtio'; -import { z } from 'zod'; import type { ExplorerItem, ExplorerLayout, @@ -12,6 +8,10 @@ import type { Tag } from '@sd/client'; import { ObjectKindEnum, type Ordering, type OrderingKeys } from '@sd/client'; +import { useCallback, useEffect, useMemo, useRef, useState, type RefObject } from 'react'; +import { useDebouncedCallback } from 'use-debounce'; +import { proxy, snapshot, subscribe, useSnapshot } from 'valtio'; +import { z } from 'zod'; import { createDefaultExplorerSettings } from './store'; import { uniqueId } from './util'; diff --git a/interface/app/$libraryId/settings/library/tags/CreateDialog.tsx b/interface/app/$libraryId/settings/library/tags/CreateDialog.tsx index 27f57e2c8..4c7933aeb 100644 --- a/interface/app/$libraryId/settings/library/tags/CreateDialog.tsx +++ b/interface/app/$libraryId/settings/library/tags/CreateDialog.tsx @@ -5,9 +5,10 @@ import { ToastDefautlColor, useLibraryMutation, usePlausibleEvent, + useRspcLibraryContext, useZodForm } from '@sd/client'; -import { Dialog, InputField, useDialog, UseDialogProps, z } from '@sd/ui'; +import { Dialog, InputField, UseDialogProps, useDialog, z } from '@sd/ui'; import { ColorPicker } from '~/components'; import { useLocale } from '~/hooks'; @@ -22,10 +23,12 @@ export type AssignTagItems = Array< export function useAssignItemsToTag() { const submitPlausibleEvent = usePlausibleEvent(); + const rspc = useRspcLibraryContext(); const mutation = useLibraryMutation(['tags.assign'], { onSuccess: () => { submitPlausibleEvent({ event: { type: 'tagAssign' } }); + rspc.queryClient.invalidateQueries(['search.paths']); } }); diff --git a/interface/locales/ar/common.json b/interface/locales/ar/common.json index 6824da1e4..d7224ef55 100644 --- a/interface/locales/ar/common.json +++ b/interface/locales/ar/common.json @@ -614,6 +614,7 @@ "show_object_size": "إظهار حجم الكائن", "show_path_bar": "إظهار شريط المسار", "show_slider": "إظهار المنزلق", + "show_tags": "أضهر العلامات", "size": "الحجم", "size_b": "بايت", "size_bs": "ب", diff --git a/interface/locales/be/common.json b/interface/locales/be/common.json index 93519b552..f5b4bcf7b 100644 --- a/interface/locales/be/common.json +++ b/interface/locales/be/common.json @@ -605,6 +605,7 @@ "show_object_size": "Памер аб'екта", "show_path_bar": "Адрасны радок", "show_slider": "Паказаць паўзунок", + "show_tags": "Паказаць тэгі", "size": "Памер", "size_b": "Б", "size_bs": "Б", diff --git a/interface/locales/de/common.json b/interface/locales/de/common.json index 00aa5daf9..86c5e729c 100644 --- a/interface/locales/de/common.json +++ b/interface/locales/de/common.json @@ -602,6 +602,7 @@ "show_object_size": "Objektgröße anzeigen", "show_path_bar": "Pfadleiste anzeigen", "show_slider": "Slider anzeigen", + "show_tags": "Tags anzeigen", "size": "Größe", "size_b": "B", "size_bs": "B", diff --git a/interface/locales/en/common.json b/interface/locales/en/common.json index e46ec5ec9..f6cefe418 100644 --- a/interface/locales/en/common.json +++ b/interface/locales/en/common.json @@ -614,6 +614,7 @@ "show_object_size": "Show Object size", "show_path_bar": "Show Path Bar", "show_slider": "Show slider", + "show_tags": "Show Tags", "size": "Size", "size_b": "B", "size_bs": "Bs", diff --git a/interface/locales/es/common.json b/interface/locales/es/common.json index 46d363ddf..c6b789406 100644 --- a/interface/locales/es/common.json +++ b/interface/locales/es/common.json @@ -604,6 +604,7 @@ "show_object_size": "Mostrar Tamaño del Objeto", "show_path_bar": "Mostrar Barra de Ruta", "show_slider": "Mostrar deslizador", + "show_tags": "Mostrar etiquetas", "size": "Tamaño", "size_b": "B", "size_bs": "B", diff --git a/interface/locales/fr/common.json b/interface/locales/fr/common.json index f4d127deb..6a6ebe196 100644 --- a/interface/locales/fr/common.json +++ b/interface/locales/fr/common.json @@ -604,6 +604,7 @@ "show_object_size": "Afficher la taille de l'objet", "show_path_bar": "Afficher la barre de chemin", "show_slider": "Afficher le curseur", + "show_tags": "Voir les étiquettes", "size": "Taille", "size_b": "o", "size_bs": "B", diff --git a/interface/locales/it/common.json b/interface/locales/it/common.json index c00a9d0f8..e8575a279 100644 --- a/interface/locales/it/common.json +++ b/interface/locales/it/common.json @@ -604,6 +604,7 @@ "show_object_size": "Mostra la dimensione dell'oggetto", "show_path_bar": "Mostra barra del percorso", "show_slider": "Mostra slider", + "show_tags": "Mostra tag", "size": "Dimensione", "size_b": "B", "size_bs": "B", diff --git a/interface/locales/ja/common.json b/interface/locales/ja/common.json index 15d969a41..81a472219 100644 --- a/interface/locales/ja/common.json +++ b/interface/locales/ja/common.json @@ -598,6 +598,7 @@ "show_object_size": "ファイルサイズを表示", "show_path_bar": "パスバーを表示", "show_slider": "スライダーを表示", + "show_tags": "タグを表示", "size": "サイズ", "size_b": "バイト", "size_bs": "B", diff --git a/interface/locales/nl/common.json b/interface/locales/nl/common.json index 4876ec4c3..4855c07b3 100644 --- a/interface/locales/nl/common.json +++ b/interface/locales/nl/common.json @@ -602,6 +602,7 @@ "show_object_size": "Toon Object grootte", "show_path_bar": "Padbalk Tonen", "show_slider": "Toon schuifregelaar", + "show_tags": "Toon labels", "size": "Grootte", "size_b": "B", "size_bs": "B", diff --git a/interface/locales/ru/common.json b/interface/locales/ru/common.json index 83a4e9f5c..a1bf8bdc9 100644 --- a/interface/locales/ru/common.json +++ b/interface/locales/ru/common.json @@ -605,6 +605,7 @@ "show_object_size": "Размер объекта", "show_path_bar": "Адресная строка", "show_slider": "Показать ползунок", + "show_tags": "Показать теги", "size": "Размер", "size_b": "Б", "size_bs": "Б", diff --git a/interface/locales/tr/common.json b/interface/locales/tr/common.json index 7b1134e54..76b9ef593 100644 --- a/interface/locales/tr/common.json +++ b/interface/locales/tr/common.json @@ -602,6 +602,7 @@ "show_object_size": "Nesne Boyutunu Göster", "show_path_bar": "Yol Çubuğunu Göster", "show_slider": "Kaydırıcıyı Göster", + "show_tags": "Etiketleri göster", "size": "Boyut", "size_b": "B", "size_bs": "B", diff --git a/interface/locales/zh-CN/common.json b/interface/locales/zh-CN/common.json index 5534fbf47..e90b90b3d 100644 --- a/interface/locales/zh-CN/common.json +++ b/interface/locales/zh-CN/common.json @@ -598,6 +598,7 @@ "show_object_size": "显示对象大小", "show_path_bar": "显示路径栏", "show_slider": "显示滑块", + "show_tags": "显示标签", "size": "大小", "size_b": "乙", "size_bs": "乙", diff --git a/interface/locales/zh-TW/common.json b/interface/locales/zh-TW/common.json index 4a9f43c74..0a438011d 100644 --- a/interface/locales/zh-TW/common.json +++ b/interface/locales/zh-TW/common.json @@ -598,6 +598,7 @@ "show_object_size": "顯示對象大小", "show_path_bar": "顯示路徑條", "show_slider": "顯示滑塊", + "show_tags": "顯示標籤", "size": "大小", "size_b": "乙", "size_bs": "乙", diff --git a/packages/client/src/stores/explorerLayout.ts b/packages/client/src/stores/explorerLayout.ts index baccfb010..01d9fbba4 100644 --- a/packages/client/src/stores/explorerLayout.ts +++ b/packages/client/src/stores/explorerLayout.ts @@ -7,6 +7,7 @@ export const explorerLayout = createPersistedMutable( 'sd-explorer-layout', createMutable({ showPathBar: true, + showTags: true, showImageSlider: true, // might move this to a store called settings defaultView: 'grid' as ExplorerLayout