|
2 | 2 | import type { SessionContext } from '~~/shared/types' |
3 | 3 | import type { ClientSettings } from '~/state/settings' |
4 | 4 | import { useRpc } from '#imports' |
5 | | -import { useAsyncState } from '@vueuse/core' |
| 5 | +import { computedWithControl, useAsyncState } from '@vueuse/core' |
| 6 | +import Fuse from 'fuse.js' |
| 7 | +import { computed, ref } from 'vue' |
6 | 8 | import { settings } from '~/state/settings' |
7 | 9 |
|
8 | 10 | const props = defineProps<{ |
9 | 11 | session: SessionContext |
10 | 12 | }>() |
11 | 13 |
|
| 14 | +const searchValue = ref<{ search: string }>({ |
| 15 | + search: '', |
| 16 | +}) |
| 17 | +
|
12 | 18 | const assetViewTpyes = [ |
13 | 19 | { |
14 | 20 | label: 'List', |
@@ -36,34 +42,65 @@ const { state: assets, isLoading } = useAsyncState( |
36 | 42 | null, |
37 | 43 | ) |
38 | 44 |
|
| 45 | +const fuse = computedWithControl( |
| 46 | + () => assets.value, |
| 47 | + () => new Fuse(assets.value!, { |
| 48 | + includeScore: true, |
| 49 | + keys: ['filename'], |
| 50 | + ignoreLocation: true, |
| 51 | + threshold: 0.4, |
| 52 | + }), |
| 53 | +) |
| 54 | +
|
| 55 | +const searched = computed(() => { |
| 56 | + if (!searchValue.value.search) { |
| 57 | + return assets.value! |
| 58 | + } |
| 59 | + return fuse.value |
| 60 | + .search(searchValue.value.search) |
| 61 | + .map(r => r.item) |
| 62 | +}) |
| 63 | +
|
39 | 64 | function toggleDisplay(type: ClientSettings['assetViewType']) { |
40 | 65 | settings.value.assetViewType = type |
41 | 66 | } |
42 | 67 | </script> |
43 | 68 |
|
44 | 69 | <template> |
45 | 70 | <VisualLoading v-if="isLoading" /> |
46 | | - <div v-else p4 flex="~ col gap-4"> |
47 | | - <div flex="~ gap-2"> |
48 | | - <button |
49 | | - v-for="viewType of assetViewTpyes" |
50 | | - :key="viewType.value" |
51 | | - btn-action |
52 | | - :class="settings.assetViewType === viewType.value ? 'bg-active' : 'grayscale op50'" |
53 | | - @click="toggleDisplay(viewType.value)" |
54 | | - > |
55 | | - <div :class="viewType.icon" /> |
56 | | - {{ viewType.label }} |
57 | | - </button> |
| 71 | + <div v-else relative max-h-screen of-hidden> |
| 72 | + <div absolute left-4 top-4 z-panel-nav> |
| 73 | + <DataSearchPanel v-model="searchValue" :rules="[]"> |
| 74 | + <div flex="~ gap-2 items-center" p2 border="t base"> |
| 75 | + <span op50 pl2 text-sm>View as</span> |
| 76 | + <button |
| 77 | + v-for="viewType of assetViewTpyes" |
| 78 | + :key="viewType.value" |
| 79 | + btn-action |
| 80 | + :class="settings.assetViewType === viewType.value ? 'bg-active' : 'grayscale op50'" |
| 81 | + @click="toggleDisplay(viewType.value)" |
| 82 | + > |
| 83 | + <div :class="viewType.icon" /> |
| 84 | + {{ viewType.label }} |
| 85 | + </button> |
| 86 | + </div> |
| 87 | + </DataSearchPanel> |
| 88 | + </div> |
| 89 | + <div of-auto h-screen flex="~ col gap-2" pt32> |
| 90 | + <template v-if="settings.assetViewType === 'list'"> |
| 91 | + <AssetsList v-if="searched?.length" :assets="searched" :session="session" /> |
| 92 | + </template> |
| 93 | + <template v-else-if="settings.assetViewType === 'folder'"> |
| 94 | + <AssetsFolder v-if="searched?.length" :assets="searched" :session="session" /> |
| 95 | + </template> |
| 96 | + <template v-else-if="settings.assetViewType === 'treemap'"> |
| 97 | + <AssetsTreemap v-if="searched?.length" :assets="searched" :session="session" /> |
| 98 | + </template> |
| 99 | + </div> |
| 100 | + <div |
| 101 | + absolute bottom-4 py-1 px-2 bg-glass left="1/2" translate-x="-1/2" border="~ base rounded-full" text="center xs" |
| 102 | + > |
| 103 | + <span op50>{{ searched.length }} of {{ assets?.length || 0 }}</span> |
58 | 104 | </div> |
59 | | - <template v-if="settings.assetViewType === 'list'"> |
60 | | - <AssetsList v-if="assets?.length" :assets="assets" :session="session" /> |
61 | | - </template> |
62 | | - <template v-else-if="settings.assetViewType === 'folder'"> |
63 | | - <AssetsFolder v-if="assets?.length" :assets="assets" :session="session" /> |
64 | | - </template> |
65 | | - <template v-else-if="settings.assetViewType === 'treemap'"> |
66 | | - <AssetsTreemap v-if="assets?.length" :assets="assets" :session="session" /> |
67 | | - </template> |
68 | 105 | </div> |
69 | 106 | </template> |
0 commit comments