Skip to content

Commit

Permalink
Persists misc list view preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
agersant committed Oct 14, 2024
1 parent df666fd commit f0c7ecd
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 39 deletions.
20 changes: 9 additions & 11 deletions src/components/library/Artist.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
<div v-if="artist" class="flex flex-col min-h-0">
<div ref="viewport" class="relative grow -m-4 p-4 mb-0 overflow-y-scroll flex flex-col gap-8">

<Switch class="absolute mt-0.5 top-4 right-4" v-model="displayMode" :items="[
<Switch class="absolute mt-0.5 top-4 right-4" v-model="preferences.artistDisplayMode" :items="[
{ icon: 'apps', value: 'grid5' },
{ icon: 'grid_view', value: 'grid3' },
{ icon: 'timeline', value: 'timeline' }
]" />

<div v-if="displayMode != 'timeline' && mainWorks?.length">
<div v-if="preferences.artistDisplayMode != 'timeline' && mainWorks?.length">
<SectionTitle label="Main Releases" class="h-10">
<ButtonGroup>
<Button icon="play_arrow" severity="secondary" size="sm" @click="play(mainWorks)" />
Expand All @@ -27,7 +27,7 @@
<AlbumGrid :albums="mainWorks" :num-columns="numColumns" :show-artists="false" />
</div>
<div v-if="displayMode != 'timeline' && otherWorks?.length">
<div v-if="preferences.artistDisplayMode != 'timeline' && otherWorks?.length">
<SectionTitle label="Featured On" class="h-10">
<ButtonGroup>
<Button icon="play_arrow" severity="secondary" size="sm" @click="play(otherWorks)" />
Expand All @@ -37,7 +37,8 @@
<AlbumGrid :albums="otherWorks" :num-columns="numColumns" :show-artists="true" />
</div>
<Timeline v-if="displayMode == 'timeline'" :artist="artist.name" :albums="artist.albums" class="m-16" />
<Timeline v-if="preferences.artistDisplayMode == 'timeline'" :artist="artist.name"
:albums="artist.albums" class="m-16" />
</div>
Expand All @@ -57,7 +58,7 @@
</template>
<script setup lang="ts">
import { computed, Ref, ref, useTemplateRef, watch } from "vue";
import { computed, useTemplateRef, watch } from "vue";
import { useAsyncState } from "@vueuse/core";
import { useRouter } from "vue-router";
Expand All @@ -76,9 +77,11 @@ import Timeline from '@/components/library/Timeline.vue';
import { saveScrollState, useHistory } from "@/history";
import { makeGenreURL } from "@/router";
import { usePlaybackStore } from "@/stores/playback";
import { usePreferencesStore } from "@/stores/preferences";
const router = useRouter();
const playback = usePlaybackStore();
const preferences = usePreferencesStore();
const props = defineProps<{
name: string,
Expand All @@ -90,13 +93,8 @@ const { state: artist, isLoading, error, execute: fetchArtist } = useAsyncState(
{ immediate: false, resetOnExecute: true }
);
type DisplayMode = "grid5" | "grid3" | "timeline";
// TODO save in preferences
const displayMode: Ref<DisplayMode> = ref("grid5");
const numColumns = computed(() => {
switch (displayMode.value) {
switch (preferences.artistDisplayMode) {
case "grid5": return 5;
case "grid3": return 3;
case "timeline": return 1;
Expand Down
11 changes: 5 additions & 6 deletions src/components/library/ArtistList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
<span @click="router.push(makeArtistURL(item.data.name))" class="cursor-pointer font-semibold
overflow-hidden text-ellipsis
text-ls-700 dark:text-ds-300
hover:text-accent-600 hover:underline" :class="displayMode == 'fixed' ? 'text-sm' : ''"
hover:text-accent-600 hover:underline" :class="listMode == 'fixed' ? 'text-sm' : ''"
:style="proportionalStyle[item.data.name]">
{{ item.data.name }}
</span>
<span v-if="displayMode == 'fixed'" class="mt-1 text-xs text-ls-500 dark:text-ds-500">
<span v-if="listMode == 'fixed'" class="mt-1 text-xs text-ls-500 dark:text-ds-500">
{{ `${item.data.num_songs} ${pluralize('song', item.data.num_songs)}` }}
</span>
</div>
Expand All @@ -41,15 +41,14 @@ import { ArtistHeader } from '@/api/dto';
import Badge from "@/components/basic/Badge.vue";
import { pluralize } from '@/format';
import { makeArtistURL, makeGenreURL } from "@/router";
import { usePreferencesStore } from '@/stores/preferences';
import { ArtistListMode, usePreferencesStore } from '@/stores/preferences';
const router = useRouter();
const preferences = usePreferencesStore();
export type DisplayMode = "fixed" | "proportional";
const props = defineProps<{
artists: ArtistHeader[],
displayMode: DisplayMode,
listMode: ArtistListMode,
}>();
const itemHeight = 73;
Expand All @@ -61,7 +60,7 @@ function remap(value: number, fromA: number, fromB: number, toA: number, toB: nu
}
const proportionalStyle: Ref<{ [key: string]: CSSProperties }> = computed(() => {
if (props.displayMode != "proportional" || !props.artists.length) {
if (props.listMode != "proportional" || !props.artists.length) {
return {};
}
Expand Down
12 changes: 6 additions & 6 deletions src/components/library/Artists.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
<InputText class="w-80" v-model="filter" id="filter" placeholder="Filter" icon="filter_alt" autofocus
clearable />
<!-- TODO tooltips -->
<Switch v-model="displayMode"
<Switch v-model="preferences.artistListMode"
:items="[{ icon: 'view_list', value: 'fixed' }, { icon: 'text_fields', value: 'proportional' }]" />
</div>
<ArtistList v-if="filtered.length" ref="list" class="grow min-h-0 -mr-4 pr-4" :artists="filtered"
:display-mode="displayMode" />
:list-mode="preferences.artistListMode" />
<div v-else class="grow flex mt-40 justify-center text-center">
<BlankStateFiller icon="filter_alt_off">
No artists match this filter.
Expand Down Expand Up @@ -59,8 +59,11 @@ import Switch from "@/components/basic/Switch.vue";
import SwitchText from "@/components/basic/SwitchText.vue";
import PageTitle from "@/components/basic/PageTitle.vue";
import Spinner from "@/components/basic/Spinner.vue";
import ArtistList, { DisplayMode } from "@/components/library/ArtistList.vue";
import ArtistList from "@/components/library/ArtistList.vue";
import { saveScrollState, useHistory } from "@/history";
import { usePreferencesStore } from "@/stores/preferences";
const preferences = usePreferencesStore();
const artists: Ref<ArtistHeader[]> = ref([]);
Expand All @@ -73,9 +76,6 @@ watch(fetchedArtists, (a) => {
const filter = ref("");
// TODO save in preferences
const displayMode: Ref<DisplayMode> = ref("fixed");
type ArtistRole = "performer" | "composer" | "lyricist";
const roleFilter: Ref<ArtistRole> = ref("performer");
Expand Down
13 changes: 7 additions & 6 deletions src/components/library/Search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
</div>
<template #right>
<!-- TODO tooltips -->
<Switch v-model="listMode"
:items="[{ icon: 'compress', value: 'compact' }, { icon: 'view_list', value: 'tall' }]" />
<Switch v-model="preferences.searchResultsDisplayMode" :items="[
{ icon: 'compress', value: 'compact' },
{ icon: 'view_list', value: 'tall' },
]" />
</template>
</SectionTitle>
<SongList v-model="songPaths" :compact="listMode == 'compact'" invert-stripes />
<SongList v-model="songPaths" :compact="preferences.searchResultsDisplayMode == 'compact'" invert-stripes />
</div>

<div v-if="songPaths.length" />
Expand Down Expand Up @@ -141,14 +143,13 @@ import Switch from "@/components/basic/Switch.vue";
import SongList from "@/components/SongList.vue";
import { pluralize } from "@/format";
import { usePlaybackStore } from "@/stores/playback";
import { usePreferencesStore } from "@/stores/preferences";
const playback = usePlaybackStore();
const preferences = usePreferencesStore();
const query = ref("");
// TODO save to preferences
const listMode = ref("compact");
const showHelp = ref(false);
const { state: results, isLoading, error, execute: runQuery } = useAsyncState(
Expand Down
8 changes: 4 additions & 4 deletions src/components/playback/Playlist.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<Button label="Shuffle" severity="secondary" size="base" icon="shuffle" @click="playback.shuffle" />
</div>
<!-- TODO tooltips -->
<Switch v-model="listMode"
<Switch v-model="preferences.playlistDisplayMode"
:items="[{ icon: 'compress', value: 'compact' }, { icon: 'view_list', value: 'tall' }]" />
</div>

Expand Down Expand Up @@ -93,15 +93,15 @@ import PlaylistSong from '@/components/playback/PlaylistSong.vue';
import { useDragAndDrop } from '@/dnd';
import { usePlaybackStore, PlaylistEntry, PlaybackOrder } from '@/stores/playback';
import { usePlaylistsStore } from "@/stores/playlists";
import { usePreferencesStore } from "@/stores/preferences";
const playback = usePlaybackStore();
const playlists = usePlaylistsStore();
const preferences = usePreferencesStore();
const orderableList = useTemplateRef("orderableList");
// TODO save to preferences
const listMode = ref("compact");
const compact = computed(() => listMode.value == "compact");
const compact = computed(() => preferences.playlistDisplayMode == "compact");
const itemHeight = computed(() => compact.value ? 32 : 48);
const savingPlaylist = ref(false);
Expand Down
4 changes: 2 additions & 2 deletions src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ export function useUserStorage<T>(key: string, defaultValue: T): WritableCompute
if (!user.name) {
return defaultValue;
}
asRef.value;
return read(`${user.name}.${key}`, defaultValue, serializer);
asRef.value = read(`${user.name}.${key}`, defaultValue, serializer);
return asRef.value;
};

const setter = (value: T) => {
Expand Down
22 changes: 18 additions & 4 deletions src/stores/preferences.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import { defineStore, acceptHMRUpdate } from "pinia";
import { computed } from "vue";
import { computed, WritableComputedRef } from "vue";
import { watchImmediate } from "@vueuse/core";

import { useUserStorage } from "@/storage";
import { applyTheme, getDefaultAccentHue, getDefaultTheme, getThemePolarity, Theme } from "@/theming";

export type ArtistDisplayMode = "grid5" | "grid3" | "timeline";
export type ArtistListMode = "fixed" | "proportional";
export type SongListDisplayMode = "compact" | "tall";

export const usePreferencesStore = defineStore("preferences", () => {
const theme = useUserStorage("theme", getDefaultTheme());
const accentBaseHue = useUserStorage("accentBaseHue", getDefaultAccentHue());
const accentChromaMultiplier = useUserStorage("accentChromaMultiplier", 1.0);

const theme = useUserStorage("theme", getDefaultTheme());
const polarity = computed(() => getThemePolarity(theme.value));

const artistDisplayMode: WritableComputedRef<ArtistDisplayMode> = useUserStorage("artistDisplayMode", "grid5");
const artistListMode: WritableComputedRef<ArtistListMode> = useUserStorage("artistListMode", "fixed");
const playlistDisplayMode: WritableComputedRef<SongListDisplayMode> = useUserStorage("playlistDisplayMode", "tall");
const searchResultsDisplayMode: WritableComputedRef<SongListDisplayMode> = useUserStorage("searchResultsDisplayMode", "compact");

watchImmediate([theme, accentBaseHue, accentChromaMultiplier], () => {
applyTheme(theme.value, accentBaseHue.value, accentChromaMultiplier.value);
});
Expand All @@ -29,8 +37,14 @@ export const usePreferencesStore = defineStore("preferences", () => {
return {
accentBaseHue,
accentChromaMultiplier,
theme,
polarity,
theme,

artistDisplayMode,
artistListMode,
playlistDisplayMode,
searchResultsDisplayMode,

setTheme,
resetTheme,
};
Expand Down

0 comments on commit f0c7ecd

Please sign in to comment.