Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions packages/web/src/lib/icons/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ export {default as ArrowTopRightOnSquare} from './svgs/arrow-top-right-on-square
export {default as MagnifyingGlassPlus} from './svgs/magnifying-glass-plus.svg?raw'
export {default as Trash} from './svgs/trash.svg?raw'
export {default as TrashOutline} from './svgs/outline/trash.svg?raw'
export {default as Eye} from './svgs/outline/eye.svg?raw'
export {default as EyeSlash} from './svgs/outline/eye-slash.svg?raw'
export {default as TagIcon} from './svgs/outline/tag.svg?raw'
export {default as Calendar} from './svgs/outline/calendar.svg?raw'
3 changes: 3 additions & 0 deletions packages/web/src/lib/icons/svgs/outline/calendar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/web/src/lib/icons/svgs/outline/eye-slash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/web/src/lib/icons/svgs/outline/eye.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/web/src/lib/icons/svgs/outline/tag.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions packages/web/src/lib/runes/settings_rune.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { BaseController } from '$lib/base_controller.ts'
interface MutatableSettings {
'ui.media_list.thumbnail_size': Config['web']['ui_defaults']['media_list']['thumbnail_size']
'ui.media_list.thumbnail_shape': Config['web']['ui_defaults']['media_list']['thumbnail_shape']
'ui.media_list.info_tiles.enabled': Config['web']['ui_defaults']['media_list']['info_tiles']['enabled']
'ui.search.advanced_filters.hide': Config['web']['ui_defaults']['search']['advanced_filters']['hide']
'ui.sidebar.hide': Config['web']['ui_defaults']['sidebar']['hide']
}
Expand Down Expand Up @@ -35,6 +36,10 @@ export class SettingsRune extends Rune {
this.ui.media_list.thumbnail_shape = value
break
}
case 'ui.media_list.info_tiles.enabled': {
this.ui.media_list.info_tiles.enabled = value
break
}
case 'ui.search.advanced_filters.hide': {
this.ui.search.advanced_filters.hide = value
break
Expand Down Expand Up @@ -65,6 +70,9 @@ export class SettingsRune extends Rune {
case 'ui.media_list.thumbnail_shape': {
return this.ui.media_list.thumbnail_shape
}
case 'ui.media_list.info_tiles.enabled': {
return this.ui.media_list.info_tiles.enabled
}
case 'ui.search.advanced_filters.hide': {
return this.ui.search.advanced_filters.hide
}
Expand Down
31 changes: 30 additions & 1 deletion packages/web/src/lib/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ import * as forager from '@forager/core'

const LogLevel = z.enum(['SILENT', 'ERROR', 'WARN', 'INFO', 'DEBUG'])

const MediaTileInfoTableTypes = z.enum(['tag_group', 'sort_top'])
const MediaTileInfoTableTypes = z.enum([
'tag_group',
'sort_top',
'tag_count',
'unread',
'stars',
'datetime',
'series_count',
])

const Keybind = (default_keybind: string) => z.union([z.string(), z.string().array()]).default(default_keybind).transform(keybind => {
if (Array.isArray(keybind)) return keybind
Expand Down Expand Up @@ -43,6 +51,7 @@ export const PackagesConfig = z.object({
thumbnail_shape: z.enum(['square', 'original']).prefault('original'),

info_tiles: z.object({
enabled: z.boolean().default(true),
tag_group: z.object({
enabled: z.boolean().default(true),
order: z.number().optional(), // TBD if needed. We may be able to get away with yaml ordering if the serialization is consistent
Expand All @@ -51,6 +60,26 @@ export const PackagesConfig = z.object({
enabled: z.boolean().default(true),
order: z.number().optional(), // TBD if needed. We may be able to get away with yaml ordering if the serialization is consistent
}).prefault({}),
tag_count: z.object({
enabled: z.boolean().default(true),
order: z.number().optional(),
}).prefault({}),
unread: z.object({
enabled: z.boolean().default(true),
order: z.number().optional(),
}).prefault({}),
stars: z.object({
enabled: z.boolean().default(true),
order: z.number().optional(),
}).prefault({}),
datetime: z.object({
enabled: z.boolean().default(true),
order: z.number().optional(),
}).prefault({}),
series_count: z.object({
enabled: z.boolean().default(true),
order: z.number().optional(),
}).prefault({}),
}).prefault({}),
}).strict().prefault({}),

Expand Down
7 changes: 6 additions & 1 deletion packages/web/src/routes/browse/components/Footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<span>{runes.settings.ui.media_list.thumbnail_size}px</span>
</div>

<div>
<div class="flex gap-2">
<button
title="Toggle thumbnail shape"
class="rounded-sm bg-gray-800 px-2 text-slate-400 hover:bg-gray-600"
Expand All @@ -82,6 +82,11 @@
runes.settings.set('ui.media_list.thumbnail_shape', updated_shape)
}}
>{runes.settings.ui.media_list.thumbnail_shape}</button>
<button
title="Toggle media info tiles"
class="rounded-sm bg-gray-800 px-2 text-slate-400 hover:bg-gray-600"
onclick={() => runes.settings.toggle('ui.media_list.info_tiles.enabled')}
>info tiles: {runes.settings.ui.media_list.info_tiles.enabled ? 'on' : 'off'}</button>
</div>

<span class="">
Expand Down
47 changes: 32 additions & 15 deletions packages/web/src/routes/browse/components/MediaTileInfoTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
import Icon from '$lib/components/Icon.svelte'
import SearchLink from './SearchLink.svelte'

interface InfoEntry {
interface StarsValue {
type: 'stars'
value: number
max?: number
}

export interface InfoEntry {
name: string
icon: string
title?: string
stat?: object
queryparams?: string
value: object
stat?: unknown
queryparams?: Partial<BrowseController['runes']['queryparams']['DEFAULTS']>
value: string | number | StarsValue
enabled: boolean
order: number
}
Expand All @@ -25,41 +31,52 @@
.filter(entry => entry.enabled)
.sort((a, b) => a.order - b.order)
)
const {queryparams, settings, media_selections, media_list} = controller.runes

const icon_size = 14
const icon_color = theme.colors.green[200]
const star_filled_color = theme.colors.yellow?.[300] ?? theme.colors.green[200]
const star_empty_color = theme.colors.gray[600]

const row_colors = [
theme.colors.gray[800],
theme.colors.gray[700],
]
function is_stars(value: InfoEntry['value']): value is StarsValue {
return typeof value === 'object' && value !== null && (value as StarsValue).type === 'stars'
}
</script>


<table class="w-full">
<tbody>
{#each entries as entry, index}
<tr class={[
"grid grid-cols-[auto_auto_auto] justify-between px-3 py-1",
"grid grid-cols-[auto_1fr_auto] gap-2 items-center px-3 py-1",
index !== entries.length - 1 && "border-b-gray-500 border-b",
]}
>
<!-- style={`background-color: ${row_colors[index % 2]}`} -->
<td>
<Icon data={entry.icon} fill={icon_color} stroke="none" size={icon_size} title={entry.title} />
</td>
<td>
{#if entry.queryparams}
<td class="justify-self-start">
{#if is_stars(entry.value)}
{@const max = entry.value.max ?? 5}
<span class="flex items-center gap-0.5" title={entry.title}>
{#each Array(max) as _, i}
<Icon
data={icons.Star}
fill={i < entry.value.value ? star_filled_color : star_empty_color}
stroke="none"
size={icon_size}
/>
{/each}
</span>
{:else if entry.queryparams}
<SearchLink
class="hover:text-green-500 hover:bg-gray-800 bg-gray-700 px-2 rounded-sm"
{controller} params={entry.queryparams}> {entry.value}
</SearchLink>
{:else}
<span>{entry.value} </span>
<span title={entry.title}>{entry.value}</span>
{/if}
</td>
<td>{entry.stat}</td>
<td class="justify-self-end">{entry.stat ?? ''}</td>
</tr>
{/each}
</tbody>
Expand Down
Loading