Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store and retrieve user track selector settings in local storage #4351

Merged
merged 2 commits into from
Apr 22, 2024
Merged
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
142 changes: 78 additions & 64 deletions plugins/data-management/src/HierarchicalTrackSelectorWidget/model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { types, addDisposer, Instance } from 'mobx-state-tree'
import { autorun } from 'mobx'
import { autorun, observable } from 'mobx'
import {
getConf,
readConfObject,
Expand All @@ -23,23 +23,57 @@ import { facetedStateTreeF } from './facetedModel'

type MaybeAnyConfigurationModel = AnyConfigurationModel | undefined

// for settings that are config dependent
function postNoConfigF() {
// for settings that are not config dependent
function keyNoConfigPostFix() {
return typeof window !== 'undefined'
? [window.location.host, window.location.pathname].join('-')
: 'empty'
}

// for settings that are not config dependent
function postF() {
// for settings that are config dependent
function keyConfigPostFix() {
return typeof window !== 'undefined'
? [
postNoConfigF(),
keyNoConfigPostFix(),
new URLSearchParams(window.location.search).get('config'),
].join('-')
: 'empty'
}

function recentlyUsedK(assemblyNames: string[]) {
return ['recentlyUsedTracks', keyConfigPostFix(), assemblyNames.join(',')]
.filter(f => !!f)
.join('-')
}

// this has a extra } at the end because that's how it was initially
// released
function favoritesK() {
return `favoriteTracks-${keyConfigPostFix()}}`
}

function collapsedK(assemblyNames: string[]) {
return [
'collapsedCategories',
keyConfigPostFix(),
assemblyNames.join(','),
].join('-')
}

function sortTrackNamesK() {
return 'sortTrackNames'
}
function sortCategoriesK() {
return 'sortCategories'
}

function localStorageGetJSON<T>(key: string, defaultValue: string) {
return JSON.parse(localStorageGetItem(key) ?? defaultValue) as T
}
function localStorageSetJSON(key: string, val: unknown) {
localStorageSetItem(key, JSON.stringify(val))
}

const MAX_RECENTLY_USED = 10

/**
Expand All @@ -60,18 +94,6 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
* #property
*/
initialized: types.maybe(types.boolean),
/**
* #property
*/
collapsed: types.map(types.boolean),
/**
* #property
*/
sortTrackNames: types.maybe(types.boolean),
/**
* #property
*/
sortCategories: types.maybe(types.boolean),
/**
* #property
*/
Expand All @@ -84,9 +106,18 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
faceted: types.optional(facetedStateTreeF(), {}),
})
.volatile(() => ({
favorites: [] as string[],
favorites: localStorageGetJSON<string[]>(favoritesK(), '[]'),
recentlyUsed: [] as string[],
selection: [] as AnyConfigurationModel[],
sortTrackNames: !!localStorageGetJSON<Boolean>(
sortTrackNamesK(),
'false',
),
sortCategories: !!localStorageGetJSON<Boolean>(
sortCategoriesK(),
'false',
),
collapsed: observable.map<string, boolean>(),
filterText: '',
recentlyUsedCounter: 0,
favoritesCounter: 0,
Expand Down Expand Up @@ -121,6 +152,12 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
get recentlyUsedSet() {
return new Set(self.recentlyUsed)
},
/**
* #getter
*/
get assemblyNames(): string[] {
return self.view?.assemblyNames || []
},
}))
.actions(self => ({
/**
Expand Down Expand Up @@ -250,6 +287,12 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
expandAllCategories() {
self.collapsed.clear()
},
/**
* #action
*/
setCollapsedCategories(str: string[]) {
self.collapsed.replace(new Map(str.map(s => [s, true])))
},
/**
* #action
*/
Expand Down Expand Up @@ -290,42 +333,18 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
const assembly = assemblyManager.get(assemblyName)
const trackConf = assembly?.configuration.sequence
const viewType = pluginManager.getViewType(self.view.type)
if (!trackConf) {
return undefined
}
for (const display of trackConf.displays) {
if (viewType.displayTypes.some(d => d.name === display.type)) {
return trackConf
if (trackConf) {
for (const display of trackConf.displays) {
if (viewType.displayTypes.some(d => d.name === display.type)) {
return trackConf
}
}
}
return undefined
},
}))

.views(self => ({
/**
* #getter
*/
get assemblyNames(): string[] {
return self.view?.assemblyNames || []
},
}))
.views(self => ({
/**
* #getter
*/
get recentlyUsedLocalStorageKey() {
return `recentlyUsedTracks-${[postF(), self.assemblyNames.join(',')]
.filter(f => !!f)
.join('-')}`
},
/**
* #getter
*/
get favoritesLocalStorageKey() {
// this has a extra } at the end because that's how it was initially
// released
return `favoriteTracks-${postF()}}`
},
/**
* #getter
*/
Expand Down Expand Up @@ -517,30 +536,25 @@ export default function stateTreeFactory(pluginManager: PluginManager) {
addDisposer(
self,
autorun(() => {
const { assemblyNames } = self
self.setRecentlyUsed(
JSON.parse(
localStorageGetItem(self.recentlyUsedLocalStorageKey) || '[]',
),
localStorageGetJSON<string[]>(recentlyUsedK(assemblyNames), '[]'),
)
self.setFavorites(
JSON.parse(
localStorageGetItem(self.favoritesLocalStorageKey) || '[]',
),
self.setCollapsedCategories(
localStorageGetJSON<string[]>(collapsedK(assemblyNames), '[]'),
)
}),
)
// this should be the second autorun
addDisposer(
self,
autorun(() => {
localStorageSetItem(
self.favoritesLocalStorageKey,
JSON.stringify(self.favorites),
)
localStorageSetItem(
self.recentlyUsedLocalStorageKey,
JSON.stringify(self.recentlyUsed),
)
const { assemblyNames } = self
localStorageSetJSON(recentlyUsedK(assemblyNames), self.recentlyUsed)
localStorageSetJSON(collapsedK(assemblyNames), self.collapsed)
localStorageSetJSON(favoritesK(), self.favorites)
localStorageSetJSON(sortTrackNamesK(), self.sortTrackNames)
localStorageSetJSON(sortCategoriesK(), self.sortCategories)
}),
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ interface Node {
id: string
}

export function findSubCategories(obj: Node[], paths: string[]) {
export function findSubCategories(obj: Node[], paths: string[], depth = 0) {
let hasSubs = false
for (const elt of obj) {
if (elt.children.length) {
const hasSubCategories = findSubCategories(elt.children, paths)
if (hasSubCategories) {
const hasSubCategories = findSubCategories(elt.children, paths, depth + 1)
// avoid pushing the root "Tracks" node by checking depth>0
if (hasSubCategories && depth > 0) {
paths.push(elt.id)
}
} else {
Expand Down
Loading