Skip to content

Commit

Permalink
Removed all circular dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Frei committed Jun 23, 2024
1 parent 64dba39 commit a4e73a3
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 144 deletions.
70 changes: 70 additions & 0 deletions src/Recoil/MusicLibrarySchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { FlatAudioDatabase } from '@freik/audiodb';
import {
Album,
AlbumKey,
Artist,
ArtistKey,
Song,
SongKey,
} from '@freik/media-core';
import {
chkArrayOf,
chkObjectOfType,
isArrayOfString,
isNumber,
isString,
} from '@freik/typechk';

export type SongMap = Map<SongKey, Song>;
export type AlbumMap = Map<AlbumKey, Album>;
export type ArtistMap = Map<ArtistKey, Artist>;
export type MusicLibrary = {
songs: SongMap;
albums: AlbumMap;
artists: ArtistMap;
};

const isSong = chkObjectOfType<Song & { path?: string }>(
{
key: isString,
track: isNumber,
title: isString,
albumId: isString,
artistIds: isArrayOfString,
secondaryIds: isArrayOfString,
},
{ path: isString, variations: isArrayOfString },
);

const isAlbum = chkObjectOfType<Album>(
{
key: isString,
year: isNumber,
title: isString,
primaryArtists: isArrayOfString,
songs: isArrayOfString,
vatype: (o: unknown) => o === '' || o === 'ost' || o === 'va',
},
{
diskNames: isArrayOfString,
},
);

const isArtist = chkObjectOfType<Artist>({
key: isString,
name: isString,
albums: isArrayOfString,
songs: isArrayOfString,
});

export const isFlatAudioDatabase = chkObjectOfType<FlatAudioDatabase>({
songs: chkArrayOf(isSong),
albums: chkArrayOf(isAlbum),
artists: chkArrayOf(isArtist),
});

export const emptyLibrary = {
songs: new Map<SongKey, Song>(),
albums: new Map<AlbumKey, Album>(),
artists: new Map<ArtistKey, Artist>(),
};
16 changes: 16 additions & 0 deletions src/Recoil/PlaybackOrder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Effects } from '@freik/electron-render';
import { atom } from 'recoil';

// const log = MakeLogger('ReadWrite');
// const err = MakeError('ReadWrite-err');
export const shuffleState = atom<boolean>({
key: 'shuffle',
default: false,
effects: [Effects.syncWithMain<boolean>()],
});

export const repeatState = atom<boolean>({
key: 'repeat',
default: false,
effects: [Effects.syncWithMain<boolean>()],
});
17 changes: 17 additions & 0 deletions src/Recoil/Preferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Effects } from '@freik/electron-render';
import { atom } from 'recoil';

// Only show artists in the list who appear on full albums

export const showArtistsWithFullAlbumsState = atom({
key: 'FullAlbumsOnly',
default: false,
effects: [Effects.syncWithMain<boolean>()],
});
// The minimum # of songs an artist needs to show up in the artist list

export const minSongCountForArtistListState = atom({
key: 'MinSongCount',
default: 1,
effects: [Effects.syncWithMain<number>()],
});
71 changes: 11 additions & 60 deletions src/Recoil/ReadOnly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,24 @@ import {
SongKey,
isSongKey,
} from '@freik/media-core';
import {
chkArrayOf,
chkObjectOfType,
hasFieldType,
isArrayOfString,
isNumber,
isString,
} from '@freik/typechk';
import { hasFieldType, isArrayOfString, isString } from '@freik/typechk';
import { Catch, Fail } from '@freik/web-utils';
import { atom, selector, selectorFamily } from 'recoil';
import { SetDB } from '../MyWindow';
import { MetadataProps } from '../UI/DetailPanel/MetadataEditor';
import { MetadataProps } from '../UI/DetailPanel/MetadataProps';
import * as ipc from '../ipc';
import {
AlbumMap,
ArtistMap,
MusicLibrary,
SongMap,
emptyLibrary,
isFlatAudioDatabase,
} from './MusicLibrarySchema';
import {
minSongCountForArtistListState,
showArtistsWithFullAlbumsState,
} from './ReadWrite';
} from './Preferences';
import { songListState } from './SongPlaying';

const { wrn, log } = MakeLog('EMP:render:ReadOnly:log');
Expand Down Expand Up @@ -77,56 +78,6 @@ export const picForKeyFam = selectorFamily<string, MediaKey>({
},
});

type SongMap = Map<SongKey, Song>;
type AlbumMap = Map<AlbumKey, Album>;
type ArtistMap = Map<ArtistKey, Artist>;
type MusicLibrary = { songs: SongMap; albums: AlbumMap; artists: ArtistMap };

const isSong = chkObjectOfType<Song & { path?: string }>(
{
key: isString,
track: isNumber,
title: isString,
albumId: isString,
artistIds: isArrayOfString,
secondaryIds: isArrayOfString,
},
{ path: isString, variations: isArrayOfString },
);

const isAlbum = chkObjectOfType<Album>(
{
key: isString,
year: isNumber,
title: isString,
primaryArtists: isArrayOfString,
songs: isArrayOfString,
vatype: (o: unknown) => o === '' || o === 'ost' || o === 'va',
},
{
diskNames: isArrayOfString,
},
);

const isArtist = chkObjectOfType<Artist>({
key: isString,
name: isString,
albums: isArrayOfString,
songs: isArrayOfString,
});

const isFlatAudioDatabase = chkObjectOfType<FlatAudioDatabase>({
songs: chkArrayOf(isSong),
albums: chkArrayOf(isAlbum),
artists: chkArrayOf(isArtist),
});

const emptyLibrary = {
songs: new Map<SongKey, Song>(),
albums: new Map<AlbumKey, Album>(),
artists: new Map<ArtistKey, Artist>(),
};

function MakeMusicLibraryFromFlatAudioDatabase(fad: FlatAudioDatabase) {
// For debugging, this is helpful sometimes:
SetDB(fad);
Expand Down
31 changes: 1 addition & 30 deletions src/Recoil/ReadWrite.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Effects } from '@freik/electron-render';
import { isAlbumKey, isArtistKey, isSongKey, SongKey } from '@freik/media-core';
import { atom, selector, selectorFamily } from 'recoil';
import { ShuffleArray } from '../Tools';
import { shuffleState } from './PlaybackOrder';
import { maybeAlbumByKeyFuncFam, maybeArtistByKeyFuncFam } from './ReadOnly';
import {
currentIndexState,
Expand All @@ -10,21 +10,6 @@ import {
songPlaybackOrderState,
} from './SongPlaying';

// const log = MakeLogger('ReadWrite');
// const err = MakeError('ReadWrite-err');

const shuffleState = atom<boolean>({
key: 'shuffle',
default: false,
effects: [Effects.syncWithMain<boolean>()],
});

export const repeatState = atom<boolean>({
key: 'repeat',
default: false,
effects: [Effects.syncWithMain<boolean>()],
});

// This handles dealing with the playback order along with the state change
export const shuffleFunc = selector<boolean>({
key: 'shuffleFunc',
Expand Down Expand Up @@ -73,20 +58,6 @@ export const shuffleFunc = selector<boolean>({
},
});

// Only show artists in the list who appear on full albums
export const showArtistsWithFullAlbumsState = atom({
key: 'FullAlbumsOnly',
default: false,
effects: [Effects.syncWithMain<boolean>()],
});

// The minimum # of songs an artist needs to show up in the artist list
export const minSongCountForArtistListState = atom({
key: 'MinSongCount',
default: 1,
effects: [Effects.syncWithMain<number>()],
});

// For these things:
// n= Track #, r= Artist, l= Album, t= Title, y= Year
// Capital = descending, lowercase = ascending
Expand Down
2 changes: 1 addition & 1 deletion src/Recoil/SongPlaying.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Effects } from '@freik/electron-render';
import { SongKey } from '@freik/media-core';
import { isNumber } from '@freik/typechk';
import { atom, selector } from 'recoil';
import { repeatState } from './ReadWrite';
import { repeatState } from './PlaybackOrder';

// The position in the active playlist of the current song
// For 'ordered' playback, it's the index in the songList
Expand Down
3 changes: 2 additions & 1 deletion src/Recoil/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ import {
onlyPlayLikesState,
songHateFuncFam,
} from './Likes';
import { repeatState } from './PlaybackOrder';
import { playlistFuncFam, playlistNamesFunc } from './PlaylistsState';
import { albumByKeyFuncFam, artistByKeyFuncFam } from './ReadOnly';
import { repeatState, shuffleFunc } from './ReadWrite';
import { shuffleFunc } from './ReadWrite';
import {
activePlaylistState,
currentIndexState,
Expand Down
16 changes: 1 addition & 15 deletions src/UI/DetailPanel/MetadataEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,10 @@ import {
import { picCacheAvoiderStateFam } from '../../Recoil/cacheAvoider';
import { getAlbumImageUrl } from '../../Tools';
import { SetMediaInfo } from '../../ipc';
import { MetadataProps } from './MetadataProps';

const { log } = MakeLog('EMP:render:MetadataEditor');

export type MetadataProps = {
forSong?: SongKey;
forSongs?: SongKey[];
artist?: string;
album?: string;
track?: string;
title?: string;
year?: string;
va?: string;
variations?: string;
moreArtists?: string;
albumId?: AlbumKey;
diskName?: string;
};

export function MetadataEditor(props: MetadataProps): JSX.Element {
const [artist, setArtist] = useState<false | string>(false);
const [album, setAlbum] = useState<false | string>(false);
Expand Down
16 changes: 16 additions & 0 deletions src/UI/DetailPanel/MetadataProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AlbumKey, SongKey } from '@freik/media-core';

export type MetadataProps = {
forSong?: SongKey;
forSongs?: SongKey[];
artist?: string;
album?: string;
track?: string;
title?: string;
year?: string;
va?: string;
variations?: string;
moreArtists?: string;
albumId?: AlbumKey;
diskName?: string;
};
3 changes: 2 additions & 1 deletion src/UI/MenuHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { mediaTimePercentFunc, mediaTimeState } from '../Jotai/MediaPlaying';
import { mutedState, volumeState } from '../Jotai/SimpleSettings';
import { MyStore, getStore } from '../Jotai/Storage';
import { FocusSearch } from '../MyWindow';
import { repeatState } from '../Recoil/PlaybackOrder';
import { playlistFuncFam } from '../Recoil/PlaylistsState';
import { repeatState, shuffleFunc } from '../Recoil/ReadWrite';
import { shuffleFunc } from '../Recoil/ReadWrite';
import { activePlaylistState, songListState } from '../Recoil/SongPlaying';
import { MaybePlayNext, MaybePlayPrev } from '../Recoil/api';
import { onClickPlayPause } from './PlaybackControls';
Expand Down
26 changes: 26 additions & 0 deletions src/UI/MenuHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Keys } from '@freik/emp-shared';

const HostOs: 'mac' | 'windows' | 'linux' = (() => {
const ua = window.navigator.userAgent;
if (ua.indexOf('Mac') >= 0) {
return 'mac';
}
if (ua.indexOf('Windows') >= 0) {
return 'windows';
}
return 'linux';
})();

const accPrefix = HostOs === 'mac' ? '⌘' : 'Ctrl';

export function GetHelperText(key: Keys) {
if (key.length === 1) {
return `${accPrefix}-${key}`;
}
if (key === Keys.PreviousTrack) {
return accPrefix + '-←';
}
if (key === Keys.NextTrack) {
return accPrefix + '-→';
}
}
5 changes: 3 additions & 2 deletions src/UI/PlaybackControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import { ForwardedRef, MouseEventHandler } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { playingState } from '../Jotai/MediaPlaying';
import { MyStore } from '../Jotai/Storage';
import { repeatState, shuffleFunc } from '../Recoil/ReadWrite';
import { repeatState } from '../Recoil/PlaybackOrder';
import { shuffleFunc } from '../Recoil/ReadWrite';
import {
hasAnySongsFunc,
hasNextSongFunc,
hasPrevSongFunc,
} from '../Recoil/SongPlaying';
import { MaybePlayNext, MaybePlayPrev } from '../Recoil/api';
import { isMutableRefObject } from '../Tools';
import { GetHelperText } from './Utilities';
import { GetHelperText } from './MenuHelpers';
import './styles/PlaybackControls.css';

const { log, wrn } = MakeLog('EMP:render:SongControls');
Expand Down
2 changes: 1 addition & 1 deletion src/UI/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useRecoilCallback } from 'recoil';
import { curViewFunc } from '../Jotai/CurrentView';
import { SetSearch, isHostMac } from '../MyWindow';
import { searchTermState } from '../Recoil/ReadOnly';
import { GetHelperText } from './MenuHelpers';
import { Notifier } from './Notifier';
import { GetHelperText } from './Utilities';
import './styles/Sidebar.css';

type ViewEntry = { name: CurrentView; title: StrId; accelerator: Keys };
Expand Down
3 changes: 2 additions & 1 deletion src/UI/SongPlaying.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ import {
playingState,
} from '../Jotai/MediaPlaying';
import { mutedState, volumeState } from '../Jotai/SimpleSettings';
import { repeatState } from '../Recoil/PlaybackOrder';
import {
SongDescription,
albumKeyForSongKeyFuncFam,
allSongsFunc,
dataForSongFuncFam,
picForKeyFam,
} from '../Recoil/ReadOnly';
import { repeatState, shuffleFunc } from '../Recoil/ReadWrite';
import { shuffleFunc } from '../Recoil/ReadWrite';
import { currentSongKeyFunc, songListState } from '../Recoil/SongPlaying';
import { MaybePlayNext } from '../Recoil/api';
import { getAlbumImageUrl, isMutableRefObject } from '../Tools';
Expand Down
Loading

0 comments on commit a4e73a3

Please sign in to comment.