-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Album list prefs partly done * Not working, but lots of progress on Likes & Hates support * Added a read only with translation storage helper * Fixed Likes and Hates
- Loading branch information
Showing
10 changed files
with
314 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import { | ||
AlbumKey, | ||
ArtistKey, | ||
isAlbumKey, | ||
isArtistKey, | ||
SongKey, | ||
} from '@freik/media-core'; | ||
import { isArrayOfString, isBoolean } from '@freik/typechk'; | ||
import { atom } from 'jotai'; | ||
import { atomFamily } from 'jotai/utils'; | ||
import { atomWithMainStorage, atomWithMainStorageTranslation } from './Storage'; | ||
|
||
// const log = MakeLogger('Likes'); | ||
// const err = MakeError('Likes-err'); | ||
|
||
export const neverPlayHatesState = atomWithMainStorage( | ||
'neverPlayHates', | ||
true, | ||
isBoolean, | ||
); | ||
|
||
export const onlyPlayLikesState = atomWithMainStorage( | ||
'onlyPlayLikes', | ||
false, | ||
isBoolean, | ||
); | ||
|
||
const songLikeBackerState = atomWithMainStorageTranslation( | ||
'likedSongs', | ||
new Set<SongKey>(), | ||
isArrayOfString, | ||
(val: Set<string>) => [...val], | ||
(val: string[]) => new Set<string>(val), | ||
); | ||
|
||
const songHateBackerState = atomWithMainStorageTranslation( | ||
'hatedSongs', | ||
new Set<SongKey>(), | ||
isArrayOfString, | ||
(val: Set<string>) => [...val], | ||
(val: string[]) => new Set<string>(val), | ||
); | ||
|
||
export const isSongLikedFam = atomFamily((key: SongKey) => | ||
atom( | ||
async (get) => (await get(songLikeBackerState)).has(key), | ||
async (get, set, newVal: boolean) => { | ||
const likeSet = await get(songLikeBackerState); | ||
if (likeSet.has(key) === newVal) { | ||
return; | ||
} | ||
const newLikes = new Set(likeSet); | ||
if (newVal) { | ||
newLikes.add(key); | ||
const hateSet = await get(songHateBackerState); | ||
if (hateSet.has(key)) { | ||
const newHates = new Set(hateSet); | ||
newHates.delete(key); | ||
set(songHateBackerState, newHates); | ||
} | ||
} else { | ||
newLikes.delete(key); | ||
} | ||
set(songLikeBackerState, newLikes); | ||
}, | ||
), | ||
); | ||
|
||
export const isSongHatedFam = atomFamily((key: SongKey) => | ||
atom( | ||
async (get) => (await get(songHateBackerState)).has(key), | ||
async (get, set, newVal: boolean) => { | ||
const hateSet = await get(songHateBackerState); | ||
if (hateSet.has(key) === newVal) { | ||
return; | ||
} | ||
const newHates = new Set(hateSet); | ||
if (newVal) { | ||
newHates.add(key); | ||
const likeSet = await get(songLikeBackerState); | ||
if (likeSet.has(key)) { | ||
const newLikes = new Set(likeSet); | ||
newLikes.delete(key); | ||
set(songLikeBackerState, newLikes); | ||
} | ||
} else { | ||
newHates.delete(key); | ||
} | ||
set(songHateBackerState, newHates); | ||
}, | ||
), | ||
); | ||
|
||
// JODO: This doesn't handle song lists. Need to get them from the incomplete media interface | ||
// 0 = neutral, 1 == like, 2 = hate, 3 = mixed | ||
export const songListLikeNumberFromStringFam = atomFamily( | ||
(key: AlbumKey | ArtistKey | SongKey) => | ||
atom(async (get) => { | ||
if (isAlbumKey(key) || isArtistKey(key)) { | ||
// JODO: Fix this to get the song list from the key | ||
return 0; | ||
} | ||
const songs = [key]; | ||
let likes = false; | ||
let hates = false; | ||
for (const sk of songs) { | ||
if (!likes) likes = await get(isSongLikedFam(sk)); | ||
if (!hates) hates = await get(isSongHatedFam(sk)); | ||
if (likes && hates) { | ||
break; | ||
} | ||
} | ||
if (likes === hates) { | ||
return likes ? 3 : 0; | ||
} else { | ||
return likes ? 1 : 2; | ||
} | ||
}), | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Only show artists in the list who appear on full albums | ||
|
||
import { isBoolean, isNumber } from '@freik/typechk'; | ||
import { atomWithMainStorage } from './Storage'; | ||
|
||
export const showArtistsWithFullAlbumsState = atomWithMainStorage( | ||
'FullAlbumsOnly', | ||
false, | ||
isBoolean, | ||
); | ||
|
||
// The minimum # of songs an artist needs to show up in the artist list | ||
export const minSongCountForArtistListState = atomWithMainStorage( | ||
'MinSongCount', | ||
1, | ||
isNumber, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.