feat(ui): add layout toggle + hidden toggle, cleanup and formatting (#213)

This commit is contained in:
Ainaemaet
2026-02-26 14:24:50 +08:00
committed by GitHub
parent e88a77f224
commit 60837ae35f
2 changed files with 50 additions and 34 deletions
+27 -10
View File
@@ -81,24 +81,28 @@ onMounted(() => {
}
const toggleLayout = () => {
// flip the flat setting
const newValue = !config.flat.value
config.flat.value = newValue
// persist so it survives reloads
app.ui?.settings.setSettingValue('ModelManager.UI.Flat', newValue)
// close the current dialog (because it is keepAlive)
dialog.closeAll()
// reopen with the new layout
openManagerDialog()
}
const openManagerDialog = () => {
const { cardWidth, gutter, aspect, flat } = config
// choose icon depending on current layout
const layoutIcon = flat.value ? 'pi pi-folder-open' : 'pi pi-th-large'
const layoutIcon = flat.value ? 'pi pi-th-large' : 'pi pi-folder-open'
const includeHidden =
app.ui?.settings.getSettingValue(
'ModelManager.Scan.IncludeHiddenFiles',
) ?? false
const hiddenIcon = includeHidden ? 'pi pi-eye' : 'pi pi-eye-slash'
const hiddenTooltip = includeHidden
? t('hideHiddenFiles')
: t('showHiddenFiles')
if (firstOpenManager.value) {
models.refresh(true)
@@ -120,9 +124,22 @@ onMounted(() => {
key: 'toggle-layout',
icon: layoutIcon,
command: toggleLayout,
tooltip: flat.value
? t('switchToFolderView')
: t('switchToFlatView'),
tooltip: flat.value ? t('switchToFolderView') : t('switchToFlatView'),
},
{
key: 'toggle-hidden',
icon: hiddenIcon,
command: async () => {
const newValue = !includeHidden
app.ui?.settings.setSettingValue(
'ModelManager.Scan.IncludeHiddenFiles',
newValue,
)
await refreshModelsAndConfig() // ensure updated model list
dialog.closeAll()
openManagerDialog()
},
tooltip: hiddenTooltip,
},
{
key: 'refresh',
+23 -24
View File
@@ -225,33 +225,33 @@ const list = computed(() => {
return !item.isFolder
})
function buildRegex(raw: string): RegExp {
try {
// Escape regex specials, then restore * wildcards as .*
const escaped = raw
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/\\\*/g, '.*')
return new RegExp(escaped, 'i') // case-insensitive
} catch (e) {
return new RegExp(raw, 'i')
function buildRegex(raw: string): RegExp {
try {
// Escape regex specials, then restore * wildcards as .*
const escaped = raw
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
.replace(/\\\*/g, '.*')
return new RegExp(escaped, 'i') // case-insensitive
} catch {
return new RegExp(raw, 'i')
}
}
}
const filterList = pureModels.filter((model) => {
const showAllModel = currentType.value === allType
const matchType = showAllModel || model.type === currentType.value
const filterList = pureModels.filter((model) => {
const showAllModel = currentType.value === allType
const matchType = showAllModel || model.type === currentType.value
const rawFilter = searchContent.value ?? ''
const tokens = rawFilter.split(/\s+/).filter(Boolean)
const regexes = tokens.map(buildRegex)
const rawFilter = searchContent.value ?? ''
const tokens = rawFilter.split(/\s+/).filter(Boolean)
const regexes = tokens.map(buildRegex)
// Require every token to match either the folder or the name
const matchesAll = regexes.every((re) =>
re.test(model.subFolder) || re.test(model.basename)
)
return matchType && matchesAll
})
// Require every token to match either the folder or the name
const matchesAll = regexes.every(
(re) => re.test(model.subFolder) || re.test(model.basename),
)
return matchType && matchesAll
})
let sortStrategy: (a: Model, b: Model) => number = () => 0
switch (sortOrder.value) {
@@ -278,7 +278,6 @@ const filterList = pureModels.filter((model) => {
})
})
const contentStyle = computed(() => ({
gridTemplateColumns: `repeat(auto-fit, ${cardSize.value.width}px)`,
gap: `${gutter}px`,