{"version":3,"sources":["themes/dark.css.js","themes/light.css.js","themes/monokai.css.js","config.js","utils/baseUrl.js","utils/docsUrl.js","utils/formatters.js","utils/intersperse.js","utils/notifications.js","utils/openInNewTab.js","dataProvider/httpClient.js","consts.js","dataProvider/wrapperDataProvider.js","dataProvider/index.js","actions/player.js","actions/themes.js","actions/albumView.js","actions/dialogs.js","actions/serverEvents.js","actions/settings.js","eventStream.js","authProvider.js","icons/android-icon-192x192.png","layout/Notification.js","themes/light.js","themes/dark.js","themes/extradark.js","themes/green.js","themes/spotify.js","themes/ligera.js","themes/index.js","themes/monokai.js","themes/useCurrentTheme.js","layout/Login.js","layout/Logout.js","layout/SubMenu.js","layout/DynamicMenuIcon.js","album/albumLists.js","dialogs/DialogTitle.js","dialogs/DialogContent.js","dialogs/AboutDialog.js","common/AddToPlaylistButton.js","common/ArtistLinkField.js","common/BatchPlayButton.js","common/BitrateField.js","subsonic/index.js","common/useToggleLove.js","common/LoveButton.js","common/ContextMenus.js","common/DateField.js","common/DocLink.js","common/DurationField.js","common/Pagination.js","common/List.js","common/sanitizeFieldRestProps.js","common/MultiLineTextField.js","common/PlayButton.js","common/QuickFilter.js","common/RangeField.js","common/ShuffleAllButton.js","common/SimpleList.js","common/SizeField.js","common/SongContextMenu.js","common/SongDatagrid.js","common/SongInfo.js","common/SongTitleField.js","icons/paused-light.png","icons/paused-dark.png","icons/playing-light.gif","icons/playing-dark.gif","common/Title.js","common/SongBulkActions.js","common/useAlbumsPerPage.js","common/useInterval.js","common/useResourceRefresh.js","common/Writable.js","common/SongSimpleList.js","common/ArtistSimpleList.js","common/RatingField.js","common/useRating.js","common/useSelectedFields.js","common/ToggleFieldsMenu.js","common/QualityInfo.js","dialogs/SelectPlaylistInput.js","dialogs/DuplicateSongDialog.js","dialogs/AddToPlaylistDialog.js","hotkeys.js","dialogs/HelpDialog.js","dialogs/ListenBrainzTokenDialog.js","layout/PlaylistsSubMenu.js","layout/Menu.js","layout/PersonalMenu.js","layout/ActivityPanel.js","layout/UserMenu.js","layout/AppBar.js","layout/Layout.js","transcoding/TranscodingList.js","transcoding/TranscodingNote.js","transcoding/TranscodingEdit.js","transcoding/TranscodingCreate.js","transcoding/TranscodingShow.js","transcoding/index.js","player/PlayerList.js","player/PlayerEdit.js","player/index.js","user/UserList.js","user/DeleteUserButton.js","user/UserEdit.js","user/index.js","user/UserCreate.js","song/SongListActions.js","song/AlbumLinkField.js","dialogs/ExpandInfoDialog.js","song/SongList.js","song/index.js","album/AlbumListActions.js","album/AlbumTableView.js","album/AlbumGridView.js","album/AlbumInfo.js","album/AlbumList.js","album/AlbumSongs.js","icons/MusicBrainz.js","album/AlbumExternalLinks.js","album/AlbumDetails.js","album/AlbumActions.js","album/AlbumShow.js","album/index.js","artist/ArtistListActions.js","artist/ArtistList.js","artist/MobileArtistDetails.js","artist/ArtistExternalLink.js","artist/DesktopArtistDetails.js","artist/ArtistShow.js","artist/index.js","playlist/PlaylistListActions.js","playlist/ChangePublicStatusButton.js","playlist/PlaylistList.js","playlist/PlaylistEdit.js","playlist/PlaylistCreate.js","playlist/PlaylistDetails.js","playlist/PlaylistSongBulkActions.js","playlist/PlaylistSongs.js","playlist/PlaylistActions.js","playlist/PlaylistShow.js","playlist/index.js","audioplayer/styles.js","audioplayer/AudioTitle.js","audioplayer/PlayerToolbar.js","audioplayer/locale.js","audioplayer/keyHandlers.js","audioplayer/Player.js","i18n/provider.js","i18n/useGetLanguageChoices.js","personal/HelpMsg.js","personal/SelectLanguage.js","personal/SelectTheme.js","personal/SelectDefaultView.js","personal/NotificationsToggle.js","personal/LastfmScrobbleToggle.js","personal/ListenBrainzScrobbleToggle.js","personal/Personal.js","routes.js","reducers/themeReducer.js","reducers/playerReducer.js","reducers/activityReducer.js","reducers/settingsReducer.js","store/createAdminStore.js","store/persistState.js","useChangeThemeColor.js","App.js","reducers/albumView.js","reducers/dialogReducer.js","serviceWorker.js","index.js"],"names":["module","exports","config","defaultConfig","version","firstTime","baseURL","variousArtistsId","loginBackgroundURL","enableTranscodingConfig","enableDownloads","enableFavourites","losslessFormats","welcomeMessage","gaTrackingId","devActivityPanel","devFastAccessCoverArt","enableStarRating","defaultTheme","enableUserEditing","devEnableShare","devSidebarPlaylists","lastFMEnabled","lastFMApiKey","listenBrainzEnabled","enableCoverAnimation","devShowArtistPage","appConfig","JSON","parse","window","__APP_CONFIG__","e","baseUrl","path","parts","push","replace","join","docsUrl","formatBytes","bytes","decimals","k","dm","sizes","i","Math","floor","log","parseFloat","pow","toFixed","formatDuration","d","days","f","map","v","toString","length","filter","intersperse","arr","sep","slice","reduce","xs","x","concat","checkForNotificationPermission","Notification","permission","openInNewTab","url","win","open","focus","customAuthorizationHeader","clientUniqueIdHeader","clientUniqueId","uuidv4","httpClient","options","headers","Headers","Accept","set","token","localStorage","getItem","fetchUtils","fetchJson","then","response","get","decoded","jwtDecode","setItem","uid","REST_URL","M3U_MIME_TYPE","AUTO_THEME_ID","DraggableTypes","SONG","ALBUM","DISC","ARTIST","ALL","dataProvider","jsonServerProvider","mapResource","resource","params","plsId","playlist_id","wrapperDataProvider","getList","r","p","getOne","getMany","getManyReference","update","updateMany","create","delete","deleteMany","endsWith","idsParam","ids","id","method","data","json","callDeleteMany","addToPlaylist","playlistId","body","stringify","PLAYER_ADD_TRACKS","PLAYER_PLAY_NEXT","PLAYER_SET_TRACK","PLAYER_SYNC_QUEUE","PLAYER_CLEAR_QUEUE","PLAYER_PLAY_TRACKS","PLAYER_CURRENT","PLAYER_SET_VOLUME","setTrack","type","filterSongs","acc","addTracks","songs","playNext","shuffleTracks","shuffled","Object","keys","j","random","forEach","shuffle","firstId","playTracks","selectedId","clearQueue","currentPlaying","audioInfo","CHANGE_THEME","ALBUM_MODE_GRID","ALBUM_MODE_TABLE","ADD_TO_PLAYLIST_OPEN","ADD_TO_PLAYLIST_CLOSE","DUPLICATE_SONG_WARNING_OPEN","DUPLICATE_SONG_WARNING_CLOSE","EXTENDED_INFO_OPEN","EXTENDED_INFO_CLOSE","LISTENBRAINZ_TOKEN_OPEN","LISTENBRAINZ_TOKEN_CLOSE","openAddToPlaylist","selectedIds","onSuccess","closeAddToPlaylist","closeDuplicateSongDialog","openExtendedInfoDialog","record","closeListenBrainzTokenDialog","EVENT_SCAN_STATUS","EVENT_SERVER_START","EVENT_REFRESH_RESOURCE","SET_NOTIFICATIONS_STATE","SET_TOGGLEABLE_FIELDS","SET_OMITTED_FIELDS","setNotificationsState","enabled","setToggleableFields","obj","setOmittedFields","currentIntervalCheck","es","dispatch","timeout","getEventStream","a","EventSource","setTimeout","value","clearTimeout","close","startEventStream","stopEventStream","console","eventHandler","event","processEvent","throttledEventHandler","throttle","trailing","Promise","resolve","newStream","addEventListener","onerror","catch","auth","storeAuthenticationInfo","authInfo","name","username","avatar","isAdmin","subsonicSalt","subsonicToken","authProvider","login","password","request","Request","fetch","status","Error","statusText","error","message","stack","logout","removeItems","checkAuth","reject","checkError","getPermissions","role","getIdentity","fullName","removeItem","props","anchorOrigin","vertical","horizontal","themeName","palette","secondary","light","dark","main","contrastText","overrides","MuiFilledInput","root","backgroundColor","NDLogin","color","borderBottom","card","minWidth","marginTop","icon","button","boxShadow","systemNameLink","NDMobileArtistDetails","bgContainer","background","player","theme","stylesheet","require","primary","blue","MuiFormGroup","welcome","paper","default","NDArtistPage","green","spotifyGreen","musicListActions","padding","alignItems","margin","border","transform","transition","borderRadius","display","typography","fontFamily","h6","fontSize","MuiMenuItem","MuiDivider","MuiButton","textSecondary","label","paddingRight","paddingLeft","MuiDrawer","paddingTop","MuiTableRow","MuiTableCell","head","textTransform","letterSpacing","MuiAppBar","positionFixed","NDAlbumGridView","albumName","fontWeight","albumSubtitle","albumContainer","albumPlayButton","NDPlaylistDetails","container","title","details","NDAlbumDetails","cardContents","recordName","recordArtist","recordMeta","commentBlock","NDAlbumShow","albumActions","NDPlaylistShow","playlistActions","NDAudioPlayer","audioTitle","songTitle","songInfo","marginBottom","RaLayout","content","RaList","RaListToolbar","toolbar","RaSearchInput","input","RaFilterButton","marginRight","RaPaginationActions","currentPageButton","actions","marginLeft","RaSidebar","height","bLight","LightTheme","DarkTheme","ExtraDarkTheme","GreenTheme","LigeraTheme","text","MuiAutocomplete","popper","MuiCard","MuiPopover","MuiTypography","colorTextSecondary","MuiDialog","MuiFormLabel","MuiCheckbox","MuiIconButton","containedPrimary","textPrimary","colorSecondary","NDAppBar","NDSubMenu","textDecoration","systemName","width","overflow","RaDatagridHeaderCell","RaAutocompleteSuggestionList","suggestionsPaper","RaLink","link","RaLogout","RaMenuItemLink","active","drawerPaper","RaBulkActionsToolbar","MonokaiTheme","MuiPaper","MuiSnackbarContent","MuiChip","clickable","MuiFormHelperText","Mui","MuiTableHead","SpotifyTheme","useCurrentTheme","prefersLightMode","useMediaQuery","useSelector","state","themes","find","t","useEffect","style","styles","document","getElementsByTagName","undefined","createElement","innerHTML","appendChild","removeChild","useStyles","makeStyles","flexDirection","minHeight","justifyContent","backgroundRepeat","backgroundSize","backgroundPosition","flexWrap","form","renderInput","meta","touched","inputProps","TextField","helperText","fullWidth","FormLogin","loading","handleSubmit","validate","translate","useTranslate","classes","onSubmit","render","noValidate","className","Card","src","Logo","alt","href","target","rel","dangerouslySetInnerHTML","__html","autoFocus","component","disabled","CardActions","variant","CircularProgress","size","thickness","FormSignUp","Login","location","useState","setLoading","notify","useNotify","useLogin","useDispatch","useCallback","nextPathname","validateLogin","values","errors","validateSignup","match","confirmPassword","LoginWithTheme","ThemeProvider","createMuiTheme","Logout","handleClick","onClick","spacing","sidebarIsOpen","sidebarIsClosed","actionIcon","opacity","menuHeader","headerWrapper","SubMenu","handleToggle","isOpen","children","dense","onAction","isDesktop","breakpoints","up","isSmall","down","header","MenuItem","ListItemIcon","Typography","IconButton","stopPropagation","setSidebarVisibility","Tooltip","placement","Collapse","in","unmountOnExit","disablePadding","defaultProps","action","DynamicMenuIcon","activeIcon","useLocation","pathname","startsWith","propTypes","PropTypes","string","isRequired","object","albumLists","all","AlbumOutlinedIcon","AlbumIcon","starred","FavoriteBorderIcon","FavoriteIcon","topRated","StarBorderIcon","StarIcon","recentlyAdded","LibraryAddOutlinedIcon","LibraryAddIcon","recentlyPlayed","VideoLibraryOutlinedIcon","VideoLibraryIcon","mostPlayed","defaultAlbumList","DialogTitle","withStyles","closeButton","position","right","top","grey","onClose","other","disableTypography","aria-label","DialogContent","MuiDialogContent","links","homepage","LinkToVersion","TableCell","align","split","commitID","includes","Link","AboutDialog","Dialog","onBackdropClick","aria-labelledby","dividers","TableContainer","Paper","Table","TableBody","TableRow","scope","key","_","inflection","humanize","underscore","AddToPlaylistButton","unselectAll","useUnselectAll","aria-controls","aria-haspopup","useGetHandleArtistClick","useAlbumsPerPage","perPage","ArtistLinkField","withWidth","source","artistLink","to","addLabel","BatchPlayButton","useDataProvider","caption","tracks","cur","BitrateField","rest","useRecordContext","command","URLSearchParams","append","ts","Date","getTime","scrobble","time","submission","nowPlaying","download","star","unstar","setRating","rating","startScan","getScanStatus","getCoverArtUrl","updatedAt","coverArtId","streamUrl","getArtistInfo","useToggleLove","mountedRef","useRef","current","refreshRecord","toggleLove","toggle","subsonic","love","visibility","visible","loved","LoveButton","Button","handleToggleLove","preventDefault","noWrap","whiteSpace","menu","ContextMenu","showLove","songQueryParams","hideInfo","anchorEl","setAnchorEl","play","needData","addToQueue","info","handleItemClick","getAttribute","extractSongsData","Boolean","clsx","currentTarget","keepMounted","AlbumContextMenu","pagination","page","sort","field","order","album_id","disc_number","discNumber","ArtistContextMenu","album_artist_id","DateField","DurationField","Pagination","rowsPerPageOptions","List","subTitle","args","smart_count","sanitizeFieldRestProps","allowEmpty","basePath","cellClassName","emptyText","formClassName","headerClassName","linkType","locale","sortable","sortBy","sortByOrder","textAlign","translateChoice","MultiLineTextField","memo","firstLine","maxLines","lines","line","idx","md5","data-testid","PlayButton","playAlbum","useQuickFilterStyles","chip","QuickFilter","defaultValue","lbl","String","Chip","formatRange","nameCapitalized","charAt","toUpperCase","min","max","range","RangeField","ShuffleAllButton","filters","res","song","tertiary","float","LinkOrNot","classesOverride","linkToRecord","SimpleList","hasBulkActions","leftAvatar","leftIcon","primaryText","onToggleItem","rightAvatar","rightIcon","secondaryText","tertiaryText","total","sanitizeListRestProps","ListItem","ListItemAvatar","Avatar","ListItemText","ListItemSecondaryAction","SizeField","SongContextMenu","onAddToPlaylist","playNow","mediaFileId","subtitle","textOverflow","verticalAlign","discIcon","row","cursor","headerStyle","contextMenu","DiscSubtitleRow","forwardRef","ref","colSpan","contextAlwaysVisible","discSubtitle","hover","albumId","SongDatagridRow","firstTracks","onClickDiscSubtitle","fields","React","Children","toArray","c","isValidElement","useDrag","item","discs","dropEffect","dragDiscRef","dragSongRef","childCount","has","expand","SongDatagridBody","showDiscSubtitles","playDisc","idsToPlay","useMemo","Set","foundSubtitle","last","clear","SongDatagrid","Datagrid","tableCell","SongInfo","album","albumArtist","genre","FunctionField","genres","g","compilation","BooleanField","bitRate","channels","NumberField","showTime","playCount","bpm","comment","playDate","SongTitleField","showTrackNumbers","useTheme","currentTrack","currentId","trackId","paused","isCurrent","Icon","trackNumber","padStart","Title","SongBulkActions","getPerPageOptions","admin","resources","list","getPerPage","useInterval","callback","delay","savedCallback","setInterval","clearInterval","useResourceRefresh","visibleResources","now","lastTime","setLastTime","refresh","useRefresh","refreshData","activity","lastReceived","v2","isWritable","ownerId","Writable","child","cloneElement","canChangeTracks","pls","rules","isSmartPlaylist","listItem","artist","timeStamp","SongSimpleList","ArtistSimpleList","show","hide","RatingField","refreshRating","val","useRating","rate","handleRating","Rating","emptyIcon","onChange","newValue","useSelectedFields","columns","omittedColumns","defaultOff","resourceFields","settings","toggleableFields","omittedFields","filteredComponents","setFilteredComponents","every","filtered","omitted","entries","arrayOf","useSetToggleableFields","toggleableColumns","menuIcon","maxHeight","ToggleFieldsMenu","TopBarComponent","topbarComponent","selectedColumn","Checkbox","checked","llFormats","useStyle","QualityInfo","suffix","createFilterOptions","checkbox","SelectPlaylistInput","useGetList","option","checkedIcon","Autocomplete","multiple","disableCloseOnSelect","newState","playlistObject","inputValue","filterOptions","clearOnBlur","handleHomeEndKeys","openOnFocus","selectOnFocus","getOptionLabel","renderOption","selected","Fragment","freeSolo","DuplicateSongDialog","handleClickClose","handleSkip","DialogActions","AddToPlaylistDialog","addToPlaylistDialog","duplicateSong","duplicateIds","setValue","check","setCheck","distinctIds","trackIds","Array","isArray","len","checkDuplicateSong","dupSng","some","dupIds","openDuplicateSongWarning","maxWidth","newlyAdded","pop","createAndAddToPlaylist","distinctSongs","indexOf","keyMap","SHOW_HELP","sequence","group","TOGGLE_MENU","TOGGLE_PLAY","PREV_SONG","NEXT_SONG","VOL_UP","VOL_DOWN","TOGGLE_LOVE","HelpTable","getApplicationKeyMap","ReactDOM","createPortal","sequences","description","HelpDialog","setOpen","handlers","allowChanges","ListenBrainzTokenDialog","setLinked","listenBrainzTokenDialog","setToken","checking","setChecking","inputRef","createRef","handleSave","user","finally","handleKeyPress","DialogContentText","onKeyPress","required","LinearProgress","PlaylistMenuItemLink","useDrop","accept","drop","added","dropRef","MenuItemLink","PlaylistsSubMenu","setState","history","useHistory","useQueryWithStore","payload","loaded","renderPlaylistMenuItemLink","userId","myPlaylists","sharedPlaylists","onPlaylistConfig","menuPlaylists","menuSharedPlaylists","transitions","easing","sharp","duration","leavingScreen","paddingBottom","addPadding","closed","translatedResourceName","pluralize","withRouter","ui","sidebarOpen","queue","getResources","menuAlbumList","renderResourceMenuItemLink","activeClassName","subItems","subMenu","hasList","al","albumListAddress","exact","renderAlbumMenuItemLink","Divider","menuItem","PersonalMenu","wrapper","progress","left","zIndex","counterStatus","getUptime","serverStart","startTime","Uptime","uptime","setUptime","ActivityPanel","scanStatus","triggerScan","full","fullScan","resp","scanStatusUpdate","Badge","badgeContent","scanning","Popover","transformOrigin","CardContent","Box","flex","folderCount","usernameWrap","UserMenu","useGetIdentity","identity","handleClose","aria-owns","MenuList","elevation","AboutMenuItem","titleAccess","settingsResources","CustomUserMenu","permissions","usePermissions","renderSettingsMenuItemLink","resourceName","userResource","PersonIcon","SupervisorAccountIcon","renderUserMenuItemLink","AppBar","userMenu","Layout","keyHandlers","toggleSidebar","DndProvider","backend","HTML5Backend","Menu","appBar","notification","TranscodingList","isXsmall","exporter","targetFormat","defaultBitRate","rowClick","Interpolate","TranscodingNote","TranscodingTitle","TranscodingEdit","Edit","SimpleForm","TextInput","SelectInput","choices","TranscodingCreate","Create","TranscodingShow","Show","SimpleShowLayout","edit","TransformIcon","PlayerFilter","Filter","SearchInput","alwaysOn","PlayerList","client","userName","maxBitRate","ReferenceField","reference","PlayerTitle","ReferenceInput","resettable","BooleanInput","RadioIcon","UserFilter","UserList","bulkActionButtons","lastLoginAt","toLocaleString","deleteButton","fade","DeleteUserButton","redirect","useRedirect","useDeleteWithConfirmController","handleDialogOpen","handleDialogClose","handleDelete","Confirm","translateOptions","onConfirm","UserTitle","UserToolbar","showDelete","SaveButton","pristine","CurrentPasswordInput","formData","isMyself","changePassword","PasswordInput","NewPasswordInput","useMutation","mutate","canDelete","save","returnPromise","undoable","email","FormDataConsumer","formDataProps","initialValue","SongListActions","currentSort","displayedFilters","filterValues","showFilter","permanentFilter","onUnselectItems","maxResults","isNotSmall","TopToolbar","context","AlbumLinkField","ExpandInfoDialog","expandInfoDialog","RecordContext","contextHeader","ratingField","SongFilter","filterToQuery","searchText","AutocompleteInput","SongList","year","quality","MusicNoteOutlinedIcon","MusicNoteIcon","buttonGroup","leftButton","rightButton","AlbumViewToggler","showTitle","disableElevation","albumView","ButtonGroup","grid","AlbumListActions","columnIcon","AlbumDatagridRow","albumIds","dragAlbumRef","DatagridRow","AlbumDatagridBody","DatagridBody","AlbumDatagrid","AlbumTableView","hasShow","hasEdit","syncWithLocation","songCount","tileBar","tileBarMobile","albumArtistName","albumLink","useCoverStyles","cover","objectFit","getColsForWidth","Cover","withContentRect","measureRef","contentRect","bounds","AlbumGridTile","showArtist","noSsr","GridListTileBar","LoadedAlbumGrid","useListContext","isArtistView","artist_id","GridList","cellHeight","cols","GridListTile","gridListTile","albumListType","Loading","AlbumInfo","ArrayField","SingleFieldList","ChipField","AlbumFilter","NullableBooleanInput","NumberInput","AlbumListTitle","listTitle","perPageOptions","search","listParams","bulkActionsDisplayed","noResults","AlbumSongs","useVersion","ListToolbar","BulkActionsToolbar","SanitizedAlbumSongs","removeAlbumCommentsFromSongs","MusicBrainz","SvgIcon","xmlns","viewBox","AlbumExternalLinks","addLink","translatedTitle","encodeURIComponent","mbzAlbumId","coverParent","loveButton","wordBreak","pointerCursor","genreList","externalLinks","AlbumComment","expanded","setExpanded","formatted","handleExpandClick","collapsedHeight","GenreChipField","genreLink","useGetHandleGenreClick","GenreList","Details","addDetail","AlbumDetails","isLightboxOpen","setLightboxOpen","imageUrl","fullImageUrl","handleOpenLightbox","handleCloseLightbox","CardMedia","imagePadding","animationDuration","imageTitle","mainSrc","onCloseRequest","AlbumActions","handlePlay","handlePlayNext","handlePlayLater","handleShuffle","handleAddToPlaylist","handleDownload","AlbumShowLayout","useShowContext","ReferenceManyField","AlbumList","controllerProps","useShowController","ShowContextProvider","ArtistListActions","ArtistFilter","ArtistDatagridRow","artistIds","dragArtistRef","ArtistDatagridBody","ArtistDatagrid","ArtistListView","handleArtistLink","albumCount","img","backdropFilter","biography","artistImage","artistName","MobileArtistDetails","artistInfo","image","mediumImageUrl","largeImageUrl","ArtistExternalLinks","linkButtons","lastFMlink","musicBrainzId","artistDetail","DesktopArtistDetails","ArtistExternalLink","ArtistDetails","setArtistInfo","RegExp","showContext","ArtistShow","ArtistList","MicNoneOutlinedIcon","MicIcon","PlaylistListActions","CreateButton","ChangePublicStatusButton","playlists","public","LockOpen","Lock","BulkUpdateButton","PlaylistFilter","optionText","TogglePublicInput","useUpdate","onFailure","togglePublic","Switch","PlaylistListBulkActions","BulkDeleteButton","PlaylistList","ownerName","isRowSelectable","EditButton","SyncFragment","PlaylistTitle","PlaylistEditForm","multiline","PlaylistEdit","PlaylistCreate","PlaylistDetails","PlaylistSongBulkActions","mappedResource","ResourceContextProvider","ReorderableList","readOnly","PlaylistSongs","listContext","refetch","reorder","newPos","insert_before","handleDragEnd","from","toId","fromId","draggable","onDragEnd","nodeSelector","SanitizedPlaylistSongs","PlaylistActions","getAllSongsAndDispatch","curr","handleExport","blob","Blob","URL","createObjectURL","click","parentNode","PlaylistShowLayout","QueueMusicOutlinedIcon","QueueMusicIcon","songAlbum","fontStyle","qualityInfo","aspectRatio","AudioTitle","isMobile","qi","Placeholder","Toolbar","useGetOne","toggling","PlayerToolbar","playListsText","openText","closeText","notContentText","clickToPlayText","clickToPauseText","nextTrackText","previousTrackText","reloadText","volumeText","toggleLyricText","toggleMiniModeText","destroyText","downloadText","removeAudioListsText","clickToDeleteText","emptyLyricText","playModeText","orderLoop","singleLoop","shufflePlay","audioInstance","playerState","togglePlay","volume","metaKey","findIndex","uuid","prevSong","playPrev","nextSong","Player","playerTheme","setStartTime","scrobbled","setScrobbled","preloaded","setPreload","setAudioInstance","isMobilePlayer","useAuthState","authenticated","showNotifications","notifications","defaultOptions","mode","loadAudioErrorPlayNext","autoPlayInitLoadPlayList","clearPriorAudioLists","showDestroy","showDownload","showLyric","showReload","toggleMode","glassBg","showThemeSwitch","showMediaSession","restartCurrentOnPrev","quietUpdate","defaultPosition","volumeFade","fadeIn","fadeOut","renderAudioTitle","audioLists","playIndex","autoPlay","extendsContent","defaultVolume","onAudioListsChange","syncQueue","onAudioProgress","ended","currentTime","isNaN","next","Audio","musicSrc","onAudioVolumeChange","setVolume","sqrt","onAudioPlay","ReactGA","category","silent","sendNotification","onAudioPlayTrackChange","onAudioPause","onAudioEnded","currentPlayId","onCoverClick","onBeforeDestroy","getAudioInstance","retrieveTranslation","prepareLanguage","removeEmpty","hasOwnProperty","lang","albumSong","playlistTrack","ra","boolean","null","deepmerge","en","polyglotI18nProvider","i18nProvider","changeLocale","defaultLocale","useGetLanguageChoices","b","localeCompare","HelpMsg","helpKey","SelectLanguage","setLocale","useSetLocale","useLocale","SelectTheme","currentTheme","themeChoices","SelectDefaultView","NotificationsToggle","currentSetting","notAvailable","isSecureContext","FormControl","FormControlLabel","control","requestPermission","FormHelperText","Progress","setCheckingLink","linkCheckDelay","linkChecks","openedTab","callbackEndpoint","callbackUrl","origin","endChecking","success","result","LastfmScrobbleToggle","linked","checkingLink","ListenBrainzScrobbleToggle","Personal","routes","initialState","savedPlayIndex","mapToAudioLists","lyrics","lyric","test","singer","reduceClearQueue","reducePlayTracks","reduceSetTrack","reduceAddTracks","reducePlayNext","newQueue","foundPos","reduceSetVolume","reduceSyncQueue","reduceCurrent","count","createAdminStore","customReducers","reducer","combineReducers","adminReducer","router","connectRouter","saga","rootSaga","adminSaga","fork","sagaMiddleware","createSagaMiddleware","composeEnhancers","compose","persistedState","serializedState","err","loadState","store","createStore","USER_LOGOUT","applyMiddleware","routerMiddleware","subscribe","getState","saveState","pick","run","useChangeThemeColor","querySelector","setAttribute","createHashHistory","initialize","listen","pageview","adminStore","previousState","App","Admin","dispatchFunc","disableTelemetry","customRoutes","layout","loginPage","logoutButton","Resource","playlist","transcoding","AppWithHotkeys","isLocalhost","hostname","registerValidSW","swUrl","navigator","serviceWorker","register","registration","onupdatefound","installingWorker","installing","onstatechange","controller","onUpdate","getElementById","process","contentType","ready","unregister","reload","checkValidServiceWorker"],"mappings":"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","file":"static/js/main.5547b6f1.chunk.js","sourcesContent":["module.exports = `\n\n.react-jinke-music-player-main svg:active, .react-jinke-music-player-main svg:hover {\n color: #7171d5\n}\n\n.react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-handle, .react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-track {\n background-color: #5f5fc4\n}\n\n.react-jinke-music-player-main ::-webkit-scrollbar-thumb {\n background-color: #5f5fc4;\n}\n\n.react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-handle:active {\n box-shadow: 0 0 2px #5f5fc4\n}\n\n.react-jinke-music-player-main .audio-item.playing svg {\n color: #5f5fc4\n}\n\n.react-jinke-music-player-main .audio-item.playing .player-singer {\n color: #5f5fc4 !important\n}\n\n.audio-lists-panel-content .audio-item.playing, .audio-lists-panel-content .audio-item.playing svg {\n color: #5f5fc4\n}\n.audio-lists-panel-content .audio-item:active .group:not([class=\".player-delete\"]) svg, .audio-lists-panel-content .audio-item:hover .group:not([class=\".player-delete\"]) svg {\n color: #5f5fc4\n}\n\n`\n","module.exports = `\n.react-jinke-music-player-main.light-theme .loading svg {\n color: #5f5fc4;\n font-size: 24px\n}\n\n.react-jinke-music-player-mobile-play-model-tip {\n background-color: #5f5fc4;\n}\n\n.react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-handle, .react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-track {\n background-color: #5f5fc4\n}\n\n.react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-handle:active {\n box-shadow: 0 0 2px #5f5fc4\n}\n\n.react-jinke-music-player-main.light-theme .audio-item.playing svg {\n color: #5f5fc4\n}\n\n.react-jinke-music-player-main.light-theme .audio-item.playing .player-singer {\n color: #5f5fc4 !important\n}\n\n.audio-lists-panel-content .audio-item.playing, .audio-lists-panel-content .audio-item.playing svg {\n color: #5f5fc4\n}\n.audio-lists-panel-content .audio-item:active .group:not([class=\".player-delete\"]) svg, .audio-lists-panel-content .audio-item:hover .group:not([class=\".player-delete\"]) svg {\n color: #5f5fc4\n}\n\n.react-jinke-music-player-main.light-theme ::-webkit-scrollbar-thumb {\n background-color: #5f5fc4;\n}\n\n.react-jinke-music-player-main.light-theme svg {\n color: #5f5fc4\n}\n\n.react-jinke-music-player-main.light-theme svg:active, .react-jinke-music-player-main.light-theme svg:hover {\n color: #7171d5\n}\n\n.react-jinke-music-player-main.light-theme .rc-slider-rail {\n background-color: rgba(0, 0, 0, .09) !important\n}\n\n.react-jinke-music-player-main.light-theme .music-player-controller {\n background-color: #fff;\n border-color: #fff\n}\n\n.react-jinke-music-player-main.light-theme .music-player-panel {\n background-color: #fff;\n box-shadow: 0 1px 2px 0 rgba(0, 34, 77, .05);\n color: #5f5fc4\n}\n\n.react-jinke-music-player-main.light-theme .music-player-panel .img-content {\n box-shadow: 0 0 10px #dcdcdc\n}\n\n.react-jinke-music-player-main.light-theme .music-player-panel .progress-load-bar {\n background-color: rgba(0, 0, 0, .06) !important\n}\n\n.react-jinke-music-player-main.light-theme .rc-switch {\n color: #fff\n}\n\n.react-jinke-music-player-main.light-theme .rc-switch:after {\n background-color: #fff\n}\n\n.react-jinke-music-player-main.light-theme .rc-switch-checked {\n background-color: #5f5fc4 !important;\n border: 1px solid #5f5fc4\n}\n\n.react-jinke-music-player-main.light-theme .rc-switch-inner {\n color: #fff\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-btn {\n background-color: #f7f8fa !important\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-btn:active, .react-jinke-music-player-main.light-theme .audio-lists-btn:hover {\n background-color: #fdfdfe;\n color: #444\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-btn > .group:hover, .react-jinke-music-player-main.light-theme .audio-lists-btn > .group:hover > svg {\n color: #444\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-panel {\n background-color: #fff;\n box-shadow: 0 0 2px #dcdcdc;\n color: #444\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-panel .audio-item {\n background-color: #fff\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-panel .audio-item:nth-child(odd) {\n background-color: #fafafa !important\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-panel .audio-item.playing {\n background-color: #f2f2f2 !important\n}\n\n.react-jinke-music-player-main.light-theme .audio-lists-panel .audio-item.playing, .react-jinke-music-player-main.light-theme .audio-lists-panel .audio-item.playing svg {\n color: #5f5fc4 !important\n}\n`\n","module.exports = `\n\n.react-jinke-music-player-main svg:active, .react-jinke-music-player-main svg:hover {\n color: #fd971f\n}\n\n.react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-handle, .react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-track {\n background-color: #fd971f\n}\n\n.react-jinke-music-player-main ::-webkit-scrollbar-thumb {\n background-color: #fd971f;\n}\n\n.react-jinke-music-player-main .music-player-panel .panel-content .rc-slider-handle:active {\n box-shadow: 0 0 2px #fd971f\n}\n\n.react-jinke-music-player-main .audio-item.playing svg {\n color: #fd971f\n}\n\n.react-jinke-music-player-main .audio-item.playing .player-singer {\n color: #fd971f !important\n}\n\n.react-jinke-music-player-main .lyric-btn {\n color: #f8f8f2 !important\n}\n\n.react-jinke-music-player-main .lyric-btn-active svg {\n color: #fd971f !important\n}\n\n.music-player-lyric {\n color: #fd971f !important\n}\n\n.audio-lists-panel-content .audio-item.playing, .audio-lists-panel-content .audio-item.playing svg {\n color: #fd971f\n}\n.audio-lists-panel-content .audio-item:active .group:not([class=\".player-delete\"]) svg, .audio-lists-panel-content .audio-item:hover .group:not([class=\".player-delete\"]) svg {\n color: #fd971f\n}\n\n.progress-bar-content .audio-title a {\n color: #f8f8f2\n}\n\n`\n","// These defaults are only used in development mode. When bundled in the app,\n// the __APP_CONFIG__ object is dynamically filled by the ServeIndex function,\n// in the /server/app/serve_index.go\nconst defaultConfig = {\n version: 'dev',\n firstTime: false,\n baseURL: '',\n variousArtistsId: '03b645ef2100dfc42fa9785ea3102295', // See consts.VariousArtistsID in consts.go\n // Login backgrounds from https://unsplash.com/collections/1065384/music-wallpapers\n loginBackgroundURL: 'https://source.unsplash.com/collection/1065384/1600x900',\n enableTranscodingConfig: true,\n enableDownloads: true,\n enableFavourites: true,\n losslessFormats: 'FLAC,WAV,ALAC,DSF',\n welcomeMessage: '',\n gaTrackingId: '',\n devActivityPanel: true,\n devFastAccessCoverArt: false,\n enableStarRating: true,\n defaultTheme: 'Dark',\n enableUserEditing: true,\n devEnableShare: true,\n devSidebarPlaylists: true,\n lastFMEnabled: true,\n lastFMApiKey: '9b94a5515ea66b2da3ec03c12300327e',\n listenBrainzEnabled: true,\n enableCoverAnimation: true,\n devShowArtistPage: true,\n}\n\nlet config\n\ntry {\n const appConfig = JSON.parse(window.__APP_CONFIG__)\n\n config = {\n ...defaultConfig,\n ...appConfig,\n }\n} catch (e) {\n config = defaultConfig\n}\n\nexport default config\n","import config from '../config'\n\nexport const baseUrl = (path) => {\n const base = config.baseURL || ''\n const parts = [base]\n parts.push(path.replace(/^\\//, ''))\n return parts.join('/')\n}\n","export const docsUrl = (path) => `https://www.navidrome.org${path}`\n","export const formatBytes = (bytes, decimals = 2) => {\n if (bytes === 0) return '0 Bytes'\n\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]\n}\n\nexport const formatDuration = (d) => {\n const days = Math.floor(d / 86400)\n const hours = Math.floor(d / 3600) % 24\n const minutes = Math.floor(d / 60) % 60\n const seconds = Math.floor(d % 60)\n const f = [hours, minutes, seconds]\n .map((v) => v.toString())\n .map((v) => (v.length !== 2 ? '0' + v : v))\n .filter((v, i) => v !== '00' || i > 0)\n .join(':')\n\n return `${days > 0 ? days + ':' : ''}${f}`\n}\n","/* intersperse: Return an array with the separator interspersed between\n * each element of the input array.\n *\n * > _([1,2,3]).intersperse(0)\n * [1,0,2,0,3]\n *\n * From: https://stackoverflow.com/a/23619085\n */\nexport const intersperse = (arr, sep) => {\n if (arr.length === 0) {\n return []\n }\n\n return arr.slice(1).reduce(\n function (xs, x, i) {\n return xs.concat([sep, x])\n },\n [arr[0]]\n )\n}\n","export const sendNotification = (title, body = '', image = '') => {\n checkForNotificationPermission()\n new Notification(title, {\n body: body,\n icon: image,\n silent: true,\n })\n}\n\nconst checkForNotificationPermission = () => {\n return 'Notification' in window && Notification.permission === 'granted'\n}\n","export const openInNewTab = (url) => {\n const win = window.open(url, '_blank')\n win.focus()\n return win\n}\n","import { fetchUtils } from 'react-admin'\nimport { v4 as uuidv4 } from 'uuid'\nimport { baseUrl } from '../utils'\nimport config from '../config'\nimport jwtDecode from 'jwt-decode'\n\nconst customAuthorizationHeader = 'X-ND-Authorization'\nconst clientUniqueIdHeader = 'X-ND-Client-Unique-Id'\nconst clientUniqueId = uuidv4()\n\nconst httpClient = (url, options = {}) => {\n url = baseUrl(url)\n if (!options.headers) {\n options.headers = new Headers({ Accept: 'application/json' })\n }\n options.headers.set(clientUniqueIdHeader, clientUniqueId)\n const token = localStorage.getItem('token')\n if (token) {\n options.headers.set(customAuthorizationHeader, `Bearer ${token}`)\n }\n return fetchUtils.fetchJson(url, options).then((response) => {\n const token = response.headers.get(customAuthorizationHeader)\n if (token) {\n const decoded = jwtDecode(token)\n localStorage.setItem('token', token)\n localStorage.setItem('userId', decoded.uid)\n // Avoid going to create admin dialog after logout/login without a refresh\n config.firstTime = false\n }\n return response\n })\n}\n\nexport default httpClient\n","export const REST_URL = '/api'\n\nexport const M3U_MIME_TYPE = 'audio/x-mpegurl'\n\nexport const AUTO_THEME_ID = 'AUTO_THEME_ID'\n\nexport const DraggableTypes = {\n SONG: 'song',\n ALBUM: 'album',\n DISC: 'disc',\n ARTIST: 'artist',\n ALL: [],\n}\n\nDraggableTypes.ALL.push(\n DraggableTypes.SONG,\n DraggableTypes.ALBUM,\n DraggableTypes.DISC,\n DraggableTypes.ARTIST\n)\n\nexport const MAX_SIDEBAR_PLAYLISTS = 100\n","import jsonServerProvider from 'ra-data-json-server'\nimport httpClient from './httpClient'\nimport { REST_URL } from '../consts'\n\nconst dataProvider = jsonServerProvider(REST_URL, httpClient)\n\nconst mapResource = (resource, params) => {\n switch (resource) {\n case 'playlistTrack':\n // /api/playlistTrack?playlist_id=123 => /api/playlist/123/tracks\n let plsId = '0'\n if (params.filter) {\n plsId = params.filter.playlist_id\n }\n return [`playlist/${plsId}/tracks`, params]\n\n default:\n return [resource, params]\n }\n}\n\nconst callDeleteMany = (resource, params) => {\n const ids = params.ids.map((id) => `id=${id}`)\n const idsParam = ids.join('&')\n return httpClient(`${REST_URL}/${resource}?${idsParam}`, {\n method: 'DELETE',\n }).then((response) => ({ data: response.json.ids || [] }))\n}\n\nconst wrapperDataProvider = {\n ...dataProvider,\n getList: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getList(r, p)\n },\n getOne: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getOne(r, p)\n },\n getMany: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getMany(r, p)\n },\n getManyReference: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getManyReference(r, p)\n },\n update: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.update(r, p)\n },\n updateMany: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.updateMany(r, p)\n },\n create: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.create(r, p)\n },\n delete: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.delete(r, p)\n },\n deleteMany: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n if (r.endsWith('/tracks')) {\n return callDeleteMany(r, p)\n }\n return dataProvider.deleteMany(r, p)\n },\n addToPlaylist: (playlistId, data) => {\n return httpClient(`${REST_URL}/playlist/${playlistId}/tracks`, {\n method: 'POST',\n body: JSON.stringify(data),\n }).then(({ json }) => ({ data: json }))\n },\n}\n\nexport default wrapperDataProvider\n","import httpClient from './httpClient'\nimport wrapperDataProvider from './wrapperDataProvider'\n\nexport { httpClient }\n\nexport default wrapperDataProvider\n","export const PLAYER_ADD_TRACKS = 'PLAYER_ADD_TRACKS'\nexport const PLAYER_PLAY_NEXT = 'PLAYER_PLAY_NEXT'\nexport const PLAYER_SET_TRACK = 'PLAYER_SET_TRACK'\nexport const PLAYER_SYNC_QUEUE = 'PLAYER_SYNC_QUEUE'\nexport const PLAYER_CLEAR_QUEUE = 'PLAYER_CLEAR_QUEUE'\nexport const PLAYER_PLAY_TRACKS = 'PLAYER_PLAY_TRACKS'\nexport const PLAYER_CURRENT = 'PLAYER_CURRENT'\nexport const PLAYER_SET_VOLUME = 'PLAYER_SET_VOLUME'\n\nexport const setTrack = (data) => ({\n type: PLAYER_SET_TRACK,\n data,\n})\n\nexport const filterSongs = (data, ids) => {\n if (!ids) {\n return data\n }\n return ids.reduce((acc, id) => ({ ...acc, [id]: data[id] }), {})\n}\n\nexport const addTracks = (data, ids) => {\n const songs = filterSongs(data, ids)\n return {\n type: PLAYER_ADD_TRACKS,\n data: songs,\n }\n}\n\nexport const playNext = (data, ids) => {\n const songs = filterSongs(data, ids)\n return {\n type: PLAYER_PLAY_NEXT,\n data: songs,\n }\n}\n\nexport const shuffle = (data) => {\n const ids = Object.keys(data)\n for (let i = ids.length - 1; i > 0; i--) {\n let j = Math.floor(Math.random() * (i + 1))\n ;[ids[i], ids[j]] = [ids[j], ids[i]]\n }\n const shuffled = {}\n // The \"_\" is to force the object key to be a string, so it keeps the order when adding to object\n // or else the keys will always be in the same (numerically) order\n ids.forEach((id) => (shuffled['_' + id] = data[id]))\n return shuffled\n}\n\nexport const shuffleTracks = (data, ids) => {\n const songs = filterSongs(data, ids)\n const shuffled = shuffle(songs)\n const firstId = Object.keys(shuffled)[0]\n return {\n type: PLAYER_PLAY_TRACKS,\n id: firstId,\n data: shuffled,\n }\n}\n\nexport const playTracks = (data, ids, selectedId) => {\n const songs = filterSongs(data, ids)\n return {\n type: PLAYER_PLAY_TRACKS,\n id: selectedId || Object.keys(songs)[0],\n data: songs,\n }\n}\n\nexport const syncQueue = (audioInfo, audioLists) => ({\n type: PLAYER_SYNC_QUEUE,\n data: {\n audioInfo,\n audioLists,\n },\n})\n\nexport const clearQueue = () => ({\n type: PLAYER_CLEAR_QUEUE,\n})\n\nexport const currentPlaying = (audioInfo) => ({\n type: PLAYER_CURRENT,\n data: audioInfo,\n})\n\nexport const setVolume = (volume) => ({\n type: PLAYER_SET_VOLUME,\n data: { volume },\n})\n","export const CHANGE_THEME = 'CHANGE_THEME'\n\nexport const changeTheme = (theme) => ({\n type: CHANGE_THEME,\n payload: theme,\n})\n","export const ALBUM_MODE_GRID = 'ALBUM_GRID_MODE'\nexport const ALBUM_MODE_TABLE = 'ALBUM_TABLE_MODE'\n\nexport const albumViewGrid = () => ({ type: ALBUM_MODE_GRID })\n\nexport const albumViewTable = () => ({ type: ALBUM_MODE_TABLE })\n","export const ADD_TO_PLAYLIST_OPEN = 'ADD_TO_PLAYLIST_OPEN'\nexport const ADD_TO_PLAYLIST_CLOSE = 'ADD_TO_PLAYLIST_CLOSE'\nexport const DUPLICATE_SONG_WARNING_OPEN = 'DUPLICATE_SONG_WARNING_OPEN'\nexport const DUPLICATE_SONG_WARNING_CLOSE = 'DUPLICATE_SONG_WARNING_CLOSE'\nexport const EXTENDED_INFO_OPEN = 'EXTENDED_INFO_OPEN'\nexport const EXTENDED_INFO_CLOSE = 'EXTENDED_INFO_CLOSE'\nexport const LISTENBRAINZ_TOKEN_OPEN = 'LISTENBRAINZ_TOKEN_OPEN'\nexport const LISTENBRAINZ_TOKEN_CLOSE = 'LISTENBRAINZ_TOKEN_CLOSE'\n\nexport const openAddToPlaylist = ({ selectedIds, onSuccess }) => ({\n type: ADD_TO_PLAYLIST_OPEN,\n selectedIds,\n onSuccess,\n})\n\nexport const closeAddToPlaylist = () => ({\n type: ADD_TO_PLAYLIST_CLOSE,\n})\n\nexport const openDuplicateSongWarning = (duplicateIds) => ({\n type: DUPLICATE_SONG_WARNING_OPEN,\n duplicateIds,\n})\n\nexport const closeDuplicateSongDialog = () => ({\n type: DUPLICATE_SONG_WARNING_CLOSE,\n})\n\nexport const openExtendedInfoDialog = (record) => {\n return {\n type: EXTENDED_INFO_OPEN,\n record,\n }\n}\n\nexport const closeExtendedInfoDialog = () => ({\n type: EXTENDED_INFO_CLOSE,\n})\n\nexport const openListenBrainzTokenDialog = () => ({\n type: LISTENBRAINZ_TOKEN_OPEN,\n})\n\nexport const closeListenBrainzTokenDialog = () => ({\n type: LISTENBRAINZ_TOKEN_CLOSE,\n})\n","export const EVENT_SCAN_STATUS = 'scanStatus'\nexport const EVENT_SERVER_START = 'serverStart'\nexport const EVENT_REFRESH_RESOURCE = 'refreshResource'\n\nexport const processEvent = (type, data) => {\n return {\n type,\n data: data,\n }\n}\n\nexport const scanStatusUpdate = (data) => ({\n type: EVENT_SCAN_STATUS,\n data: data,\n})\n\nexport const serverDown = () => ({\n type: EVENT_SERVER_START,\n data: {},\n})\n","export const SET_NOTIFICATIONS_STATE = 'SET_NOTIFICATIONS_STATE'\nexport const SET_TOGGLEABLE_FIELDS = 'SET_TOGGLEABLE_FIELDS'\nexport const SET_OMITTED_FIELDS = 'SET_OMITTED_FIELDS'\n\nexport const setNotificationsState = (enabled) => ({\n type: SET_NOTIFICATIONS_STATE,\n data: enabled,\n})\n\nexport const setToggleableFields = (obj) => ({\n type: SET_TOGGLEABLE_FIELDS,\n data: obj,\n})\n\nexport const setOmittedFields = (obj) => ({\n type: SET_OMITTED_FIELDS,\n data: obj,\n})\n","import { baseUrl } from './utils'\nimport throttle from 'lodash.throttle'\nimport { processEvent, serverDown } from './actions'\nimport { httpClient } from './dataProvider'\nimport { REST_URL } from './consts'\n\nconst defaultIntervalCheck = 20000\nconst reconnectIntervalCheck = 2000\nlet currentIntervalCheck = reconnectIntervalCheck\nlet es = null\nlet dispatch = null\nlet timeout = null\n\nconst getEventStream = async () => {\n if (!es) {\n // Call `keepalive` to refresh the jwt token\n await httpClient(`${REST_URL}/keepalive/keepalive`)\n let url = baseUrl(`${REST_URL}/events`)\n if (localStorage.getItem('token')) {\n url = url + `?jwt=${localStorage.getItem('token')}`\n }\n es = new EventSource(url)\n }\n return es\n}\n\n// Reestablish the event stream after 20 secs of inactivity\nconst setTimeout = (value) => {\n currentIntervalCheck = value\n if (timeout) {\n window.clearTimeout(timeout)\n }\n timeout = window.setTimeout(async () => {\n es?.close()\n es = null\n await startEventStream()\n }, currentIntervalCheck)\n}\n\nconst stopEventStream = () => {\n es?.close()\n es = null\n if (timeout) {\n window.clearTimeout(timeout)\n }\n timeout = null\n console.log('eventSource closed') // TODO For debug purposes. Remove later\n}\n\nconst setDispatch = (dispatchFunc) => {\n dispatch = dispatchFunc\n}\n\nconst eventHandler = (event) => {\n const data = JSON.parse(event.data)\n if (event.type !== 'keepAlive') {\n dispatch(processEvent(event.type, data))\n }\n setTimeout(defaultIntervalCheck) // Reset timeout on every received message\n}\n\nconst throttledEventHandler = throttle(eventHandler, 100, { trailing: true })\n\nconst startEventStream = async () => {\n setTimeout(currentIntervalCheck)\n if (!localStorage.getItem('is-authenticated')) {\n return Promise.resolve()\n }\n return getEventStream()\n .then((newStream) => {\n newStream.addEventListener('serverStart', eventHandler)\n newStream.addEventListener('scanStatus', throttledEventHandler)\n newStream.addEventListener('refreshResource', eventHandler)\n newStream.addEventListener('keepAlive', eventHandler)\n newStream.onerror = (e) => {\n console.log('EventStream error', e)\n es?.close()\n es = null\n setTimeout(reconnectIntervalCheck)\n dispatch(serverDown())\n }\n return newStream\n })\n .catch((e) => {\n console.log(`Error connecting to server:`, e)\n })\n}\n\nexport { setDispatch, startEventStream, stopEventStream }\n","import jwtDecode from 'jwt-decode'\nimport { baseUrl } from './utils'\nimport config from './config'\nimport { startEventStream, stopEventStream } from './eventStream'\n\n// config sent from server may contain authentication info, for example when the user is authenticated\n// by a reverse proxy request header\nif (config.auth) {\n try {\n storeAuthenticationInfo(config.auth)\n } catch (e) {\n console.log(e)\n }\n}\n\nfunction storeAuthenticationInfo(authInfo) {\n authInfo.token && localStorage.setItem('token', authInfo.token)\n localStorage.setItem('userId', authInfo.id)\n localStorage.setItem('name', authInfo.name)\n localStorage.setItem('username', authInfo.username)\n authInfo.avatar && localStorage.setItem('avatar', authInfo.avatar)\n localStorage.setItem('role', authInfo.isAdmin ? 'admin' : 'regular')\n localStorage.setItem('subsonic-salt', authInfo.subsonicSalt)\n localStorage.setItem('subsonic-token', authInfo.subsonicToken)\n localStorage.setItem('is-authenticated', 'true')\n}\n\nconst authProvider = {\n login: ({ username, password }) => {\n let url = baseUrl('/auth/login')\n if (config.firstTime) {\n url = baseUrl('/auth/createAdmin')\n }\n const request = new Request(url, {\n method: 'POST',\n body: JSON.stringify({ username, password }),\n headers: new Headers({ 'Content-Type': 'application/json' }),\n })\n return fetch(request)\n .then((response) => {\n if (response.status < 200 || response.status >= 300) {\n throw new Error(response.statusText)\n }\n return response.json()\n })\n .then((response) => {\n jwtDecode(response.token) // Validate token\n storeAuthenticationInfo(response)\n // Avoid \"going to create admin\" dialog after logout/login without a refresh\n config.firstTime = false\n if (config.devActivityPanel) {\n startEventStream()\n }\n return response\n })\n .catch((error) => {\n if (\n error.message === 'Failed to fetch' ||\n error.stack === 'TypeError: Failed to fetch'\n ) {\n throw new Error('errors.network_error')\n }\n\n throw new Error(error)\n })\n },\n\n logout: () => {\n stopEventStream()\n removeItems()\n return Promise.resolve()\n },\n\n checkAuth: () =>\n localStorage.getItem('is-authenticated')\n ? Promise.resolve()\n : Promise.reject(),\n\n checkError: ({ status }) => {\n if (status === 401) {\n removeItems()\n return Promise.reject()\n }\n return Promise.resolve()\n },\n\n getPermissions: () => {\n const role = localStorage.getItem('role')\n return role ? Promise.resolve(role) : Promise.reject()\n },\n\n getIdentity: () => {\n return {\n id: localStorage.getItem('username'),\n fullName: localStorage.getItem('name'),\n avatar: localStorage.getItem('avatar'),\n }\n },\n}\n\nconst removeItems = () => {\n localStorage.removeItem('token')\n localStorage.removeItem('userId')\n localStorage.removeItem('name')\n localStorage.removeItem('username')\n localStorage.removeItem('avatar')\n localStorage.removeItem('role')\n localStorage.removeItem('subsonic-salt')\n localStorage.removeItem('subsonic-token')\n localStorage.removeItem('is-authenticated')\n}\n\nexport default authProvider\n","export default __webpack_public_path__ + \"static/media/android-icon-192x192.949cf2e3.png\";","import React from 'react'\nimport { Notification as RANotification } from 'react-admin'\n\nconst Notification = (props) => (\n \n)\n\nexport default Notification\n","export default {\n themeName: 'Light',\n palette: {\n secondary: {\n light: '#5f5fc4',\n dark: '#001064',\n main: '#3f51b5',\n contrastText: '#fff',\n },\n },\n overrides: {\n MuiFilledInput: {\n root: {\n backgroundColor: 'rgba(0, 0, 0, 0.04)',\n '&$disabled': {\n backgroundColor: 'rgba(0, 0, 0, 0.04)',\n },\n },\n },\n NDLogin: {\n main: {\n '& .MuiFormLabel-root': {\n color: '#000000',\n },\n '& .MuiFormLabel-root.Mui-focused': {\n color: '#0085ff',\n },\n '& .MuiFormLabel-root.Mui-error': {\n color: '#f44336',\n },\n '& .MuiInput-underline:after': {\n borderBottom: '2px solid #0085ff',\n },\n },\n card: {\n minWidth: 300,\n marginTop: '6em',\n backgroundColor: '#ffffffe6',\n },\n avatar: {},\n icon: {},\n button: {\n boxShadow: '3px 3px 5px #000000a3',\n },\n systemNameLink: {\n color: '#0085ff',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(250 250 250))!important',\n },\n },\n },\n player: {\n theme: 'light',\n stylesheet: require('./light.css.js'),\n },\n}\n","import blue from '@material-ui/core/colors/blue'\n\nexport default {\n themeName: 'Dark',\n palette: {\n primary: {\n main: '#90caf9',\n },\n secondary: blue,\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: 'white',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#0085ff',\n },\n icon: {},\n welcome: {\n color: '#eee',\n },\n card: {\n minWidth: 300,\n backgroundColor: '#424242ed',\n },\n avatar: {},\n button: {\n boxShadow: '3px 3px 5px #000000a3',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',\n },\n },\n },\n player: {\n theme: 'dark',\n stylesheet: require('./dark.css.js'),\n },\n}\n","import blue from '@material-ui/core/colors/blue'\n\nexport default {\n themeName: 'Extra Dark',\n palette: {\n background: {\n paper: '#000000',\n default: '#000000',\n },\n primary: {\n main: '#0f60b6',\n contrastText: '#909090',\n },\n secondary: blue,\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: 'white',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#fff',\n },\n welcome: {\n color: '#eee',\n },\n },\n NDArtistPage: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(0 0 0))!important',\n },\n },\n },\n\n player: {\n theme: 'dark',\n stylesheet: require('./dark.css.js'),\n },\n}\n","import green from '@material-ui/core/colors/green'\n\nexport default {\n themeName: 'Green',\n palette: {\n primary: {\n light: green['300'],\n main: green['500'],\n },\n secondary: {\n main: green['900'],\n contrastText: '#fff',\n },\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: 'white',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#fff',\n },\n welcome: {\n color: '#eee',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',\n },\n },\n },\n player: {\n theme: 'dark',\n },\n}\n","const spotifyGreen = {\n 300: '#62ec83',\n 500: '#1db954',\n 900: '#008827',\n}\n\n// For Album, Playlist\nconst musicListActions = {\n padding: '1rem 0',\n alignItems: 'center',\n '@global': {\n button: {\n margin: 5,\n border: '1px solid transparent',\n backgroundColor: 'inherit',\n color: '#b3b3b3',\n '&:hover': {\n border: '1px solid #b3b3b3',\n backgroundColor: 'inherit !important',\n },\n },\n 'button:first-child:not(:only-child)': {\n '@media screen and (max-width: 720px)': {\n transform: 'scale(1.5)',\n margin: '1rem',\n '&:hover': {\n transform: 'scale(1.6) !important',\n },\n },\n transform: 'scale(2)',\n margin: '1.5rem',\n minWidth: 0,\n padding: 5,\n transition: 'transform .3s ease',\n background: spotifyGreen['500'],\n color: '#fff',\n borderRadius: 500,\n border: 0,\n '&:hover': {\n transform: 'scale(2.1)',\n backgroundColor: `${spotifyGreen['500']} !important`,\n border: 0,\n },\n },\n 'button:only-child': {\n margin: '1.5rem',\n },\n 'button:first-child>span:first-child': {\n padding: 0,\n },\n 'button:first-child>span:first-child>span': {\n display: 'none',\n },\n 'button>span:first-child>span, button:not(:first-child)>span:first-child>svg':\n {\n color: '#b3b3b3',\n },\n },\n}\n\nexport default {\n themeName: 'Spotify-ish',\n typography: {\n fontFamily: \"system-ui, 'Helvetica Neue', Helvetica, Arial\",\n h6: {\n fontSize: '1rem', // AppBar title\n },\n },\n palette: {\n primary: {\n light: spotifyGreen['300'],\n main: spotifyGreen['500'],\n },\n secondary: {\n main: '#fff',\n contrastText: '#fff',\n },\n background: {\n default: '#121212',\n paper: '#121212',\n },\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: spotifyGreen['500'],\n },\n },\n MuiMenuItem: {\n root: {\n fontSize: '0.875rem',\n },\n },\n MuiDivider: {\n root: {\n margin: '.75rem 0',\n },\n },\n MuiButton: {\n root: {\n background: spotifyGreen['500'],\n color: '#fff',\n border: '1px solid transparent',\n borderRadius: 500,\n '&:hover': {\n background: `${spotifyGreen['900']} !important`,\n },\n },\n textSecondary: {\n border: '1px solid #b3b3b3',\n background: '#000',\n '&:hover': {\n border: '1px solid #fff !important',\n background: '#000 !important',\n },\n },\n label: {\n color: '#fff',\n paddingRight: '1rem',\n paddingLeft: '0.7rem',\n },\n },\n MuiDrawer: {\n root: {\n background: '#000',\n paddingTop: '10px',\n },\n },\n MuiTableRow: {\n root: {\n padding: '10px 0',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#1d1d1d !important',\n },\n '@global': {\n 'td:nth-child(4)': {\n color: '#fff !important',\n },\n },\n },\n },\n MuiTableCell: {\n root: {\n borderBottom: '1px solid #1d1d1d',\n padding: '10px !important',\n color: '#b3b3b3 !important',\n },\n head: {\n borderBottom: '1px solid #282828',\n fontSize: '0.75rem',\n textTransform: 'uppercase',\n letterSpacing: 1.2,\n },\n },\n MuiAppBar: {\n positionFixed: {\n backgroundColor: '#000 !important',\n boxShadow: 'none',\n },\n },\n NDAlbumGridView: {\n albumName: {\n marginTop: '0.5rem',\n fontWeight: 700,\n textTransform: 'none',\n color: '#fff',\n },\n albumSubtitle: {\n color: '#b3b3b3',\n },\n albumContainer: {\n backgroundColor: '#181818',\n borderRadius: '.5rem',\n padding: '.75rem',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#282828',\n },\n },\n albumPlayButton: {\n backgroundColor: spotifyGreen['500'],\n borderRadius: '50%',\n boxShadow: '0 8px 8px rgb(0 0 0 / 30%)',\n padding: '0.35rem',\n transition: 'padding .3s ease',\n '&:hover': {\n background: `${spotifyGreen['500']} !important`,\n padding: '0.45rem',\n },\n },\n },\n NDPlaylistDetails: {\n container: {\n background: 'linear-gradient(#1d1d1d, transparent)',\n borderRadius: 0,\n paddingTop: '2.5rem !important',\n boxShadow: 'none',\n },\n title: {\n fontSize: 'calc(1.5rem + 1.5vw);',\n fontWeight: 700,\n color: '#fff',\n },\n details: {\n fontSize: '.875rem',\n minWidth: '75vw',\n color: 'rgba(255,255,255, 0.8)',\n },\n },\n NDAlbumDetails: {\n root: {\n background: 'linear-gradient(#1d1d1d, transparent)',\n borderRadius: 0,\n boxShadow: 'none',\n },\n cardContents: {\n alignItems: 'center',\n paddingTop: '1.5rem',\n },\n recordName: {\n fontSize: 'calc(1rem + 1.5vw);',\n fontWeight: 700,\n },\n recordArtist: {\n fontSize: '.875rem',\n fontWeight: 700,\n },\n recordMeta: {\n fontSize: '.875rem',\n color: 'rgba(255,255,255, 0.8)',\n },\n commentBlock: {\n fontSize: '.875rem',\n color: 'rgba(255,255,255, 0.8)',\n },\n },\n NDAlbumShow: {\n albumActions: musicListActions,\n },\n NDPlaylistShow: {\n playlistActions: musicListActions,\n },\n NDAudioPlayer: {\n audioTitle: {\n color: '#fff',\n fontSize: '0.875rem',\n },\n songTitle: {\n fontWeight: 400,\n },\n songInfo: {\n fontSize: '0.675rem',\n color: '#b3b3b3',\n },\n player: {\n border: '10px solid blue',\n },\n },\n NDLogin: {\n main: {\n boxShadow: 'inset 0 0 0 2000px rgba(0, 0, 0, .75)',\n },\n systemNameLink: {\n color: '#fff',\n },\n card: {\n border: '1px solid #282828',\n },\n avatar: {\n marginBottom: 0,\n },\n },\n RaLayout: {\n content: {\n padding: '0 !important',\n background: 'linear-gradient(#171717, #121212)',\n },\n },\n RaList: {\n content: {\n backgroundColor: 'inherit',\n },\n },\n RaListToolbar: {\n toolbar: {\n padding: '0 .55rem !important',\n },\n },\n RaSearchInput: {\n input: {\n paddingLeft: '.9rem',\n border: 0,\n },\n },\n RaFilterButton: {\n root: {\n marginRight: '1rem',\n },\n },\n RaPaginationActions: {\n currentPageButton: {\n border: '1px solid #b3b3b3',\n },\n button: {\n backgroundColor: 'inherit',\n minWidth: 48,\n margin: '0 4px',\n border: '1px solid #282828',\n '@global': {\n '> .MuiButton-label': {\n padding: 0,\n },\n },\n },\n actions: {\n '@global': {\n '.next-page': {\n marginLeft: 8,\n marginRight: 8,\n },\n '.previous-page': {\n marginRight: 8,\n },\n },\n },\n },\n RaSidebar: {\n root: {\n height: 'initial',\n },\n },\n },\n player: {\n theme: 'dark',\n },\n}\n","const bLight = {\n 300: '#0054df',\n 500: '#ffffff',\n}\nconst musicListActions = {\n padding: '1rem 0',\n alignItems: 'center',\n '@global': {\n button: {\n margin: 5,\n border: '1px solid #cccccc',\n backgroundColor: '#fff',\n color: '#b3b3b3',\n '&:hover': {\n border: '1px solid #224bff',\n backgroundColor: 'inherit !important',\n },\n },\n 'button:first-child:not(:only-child)': {\n '@media screen and (max-width: 720px)': {\n transform: 'scale(1.5)',\n margin: '1rem',\n '&:hover': {\n transform: 'scale(1.6) !important',\n },\n },\n transform: 'scale(2)',\n margin: '1.5rem',\n minWidth: 0,\n padding: 5,\n transition: 'transform .3s ease',\n background: bLight['500'],\n color: '#fff',\n borderRadius: 500,\n border: 0,\n '&:hover': {\n transform: 'scale(2.1)',\n backgroundColor: `${bLight['500']} !important`,\n border: 0,\n boxShadow: '0px 0px 4px 0px #5656567d',\n },\n },\n 'button:only-child': {\n margin: '1.5rem',\n },\n 'button:first-child>span:first-child': {\n padding: 0,\n color: bLight['300'],\n },\n 'button:first-child>span:first-child>span': {\n display: 'none',\n },\n 'button>span:first-child>span, button:not(:first-child)>span:first-child>svg':\n {\n color: '#656565',\n },\n },\n}\n\nexport default {\n themeName: 'Ligera',\n palette: {\n primary: {\n light: bLight['300'],\n main: '#464646',\n },\n secondary: {\n main: '#000',\n contrastText: '#fff',\n },\n background: {\n default: '#f0f2f5',\n paper: 'inherit',\n },\n text: {\n secondary: '#232323',\n },\n },\n typography: {\n fontFamily: \"system-ui, 'Helvetica Neue', Helvetica, Arial\",\n h6: {\n fontSize: '1rem',\n },\n },\n overrides: {\n MuiAutocomplete: {\n popper: {\n background: bLight['500'],\n },\n },\n MuiCard: {\n root: {\n marginLeft: '1%',\n marginRight: '1%',\n background: bLight['500'],\n },\n },\n MuiPopover: {\n paper: {\n backgroundColor: bLight['500'],\n '& .MuiListItemIcon-root': {\n color: '#656565',\n },\n },\n },\n MuiTypography: {\n colorTextSecondary: {\n color: '#0a0a0a',\n },\n },\n MuiDialog: {\n paper: {\n backgroundColor: bLight['500'],\n },\n },\n MuiFormGroup: {\n root: {\n color: bLight['500'],\n },\n },\n MuiMenuItem: {\n root: {\n fontSize: '0.875rem',\n },\n },\n MuiDivider: {\n root: {\n margin: '.75rem 0',\n },\n },\n MuiFormLabel: {\n root: {\n color: '#91b1b0',\n },\n },\n MuiCheckbox: {\n root: {\n color: '#616161',\n },\n },\n MuiIconButton: {\n label: {},\n },\n MuiButton: {\n root: {\n background: '#fff',\n color: '#000',\n border: '1px solid transparent',\n borderRadius: 500,\n '&:hover': {\n background: `${bLight['300']} !important`,\n color: '#fff',\n },\n },\n containedPrimary: {\n backgroundColor: '#fff',\n },\n textPrimary: {\n backgroundColor: bLight['300'],\n '& span': {\n color: '#fff',\n },\n '&:hover': {\n backgroundColor: '#3079ff !important',\n },\n },\n textSecondary: {\n border: '1px solid #b3b3b3',\n background: '#fff',\n '&:hover': {\n border: '1px solid #fff !important',\n background: '#dedede !important',\n },\n },\n label: {\n color: '#000',\n paddingRight: '1rem',\n paddingLeft: '0.7rem',\n },\n },\n MuiDrawer: {\n root: {\n background: bLight['500'],\n paddingTop: '10px',\n boxShadow: '-14px -7px 20px black',\n },\n },\n MuiTableRow: {\n root: {\n padding: '10px 0',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#e4e4e4 !important',\n },\n '@global': {\n 'td:nth-child(4)': {\n color: '#3c3c3c !important',\n },\n },\n },\n head: {\n backgroundColor: '#e0efff',\n },\n },\n MuiTableCell: {\n root: {\n borderBottom: '1px solid #1d1d1d',\n padding: '10px !important',\n color: '#656565 !important',\n },\n head: {\n borderBottom: '1px solid #282828',\n fontSize: '0.75rem',\n textTransform: 'uppercase',\n letterSpacing: 1.2,\n },\n },\n MuiAppBar: {\n positionFixed: {\n background: `${bLight['500']} !important`,\n boxShadow: '13px -12px 20px 0px #000',\n },\n colorSecondary: {\n color: bLight['300'],\n },\n },\n NDAppBar: {\n icon: {\n color: '#fff',\n },\n },\n NDAlbumGridView: {\n albumName: {\n marginTop: '0.5rem',\n fontWeight: 700,\n textTransform: 'none',\n color: '#000000b0',\n },\n albumSubtitle: {\n color: '#000000ad',\n display: 'block',\n },\n albumContainer: {\n backgroundColor: '#e0efff7d',\n borderRadius: '.5rem',\n padding: '.75rem',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#c6dbff',\n },\n },\n albumPlayButton: {\n backgroundColor: bLight['500'],\n borderRadius: '50%',\n boxShadow: '0 8px 8px rgb(0 0 0 / 30%)',\n padding: '0.35rem',\n transition: 'padding .3s ease',\n color: bLight['300'],\n '&:hover': {\n background: `${bLight['300']} !important`,\n padding: '0.45rem',\n color: bLight['500'],\n },\n },\n },\n NDPlaylistDetails: {\n container: {\n borderRadius: 0,\n paddingTop: '2.5rem !important',\n boxShadow: 'none',\n },\n title: {\n fontSize: 'calc(1.5rem + 1.5vw);',\n fontWeight: 700,\n color: '#000000b0',\n },\n details: {\n fontSize: '.875rem',\n color: 'rgba(255,255,255, 0.8)',\n },\n },\n NDAlbumDetails: {\n root: {\n borderRadius: 0,\n boxShadow: '-1px 1px 6px 0px #00000057',\n },\n cardContents: {\n alignItems: 'center',\n paddingTop: '1.5rem',\n },\n recordName: {\n fontSize: 'calc(1rem + 1.5vw);',\n fontWeight: 700,\n },\n recordArtist: {\n fontSize: '.875rem',\n fontWeight: 700,\n },\n recordMeta: {\n fontSize: '.875rem',\n color: 'rgb(113 113 113 / 80%)',\n },\n commentBlock: {\n fontSize: '.875rem',\n color: 'rgb(113 113 113 / 80%)',\n },\n },\n NDAlbumShow: {\n albumActions: musicListActions,\n },\n NDPlaylistShow: {\n playlistActions: musicListActions,\n },\n NDSubMenu: {\n icon: {\n color: '#656565',\n },\n },\n NDAudioPlayer: {\n audioTitle: {\n color: '#000',\n fontSize: '0.875rem',\n },\n songTitle: {\n fontWeight: 400,\n },\n songInfo: {\n fontSize: '0.675rem',\n color: '#b3b3b3',\n },\n player: {},\n },\n NDLogin: {\n actions: {\n '& button': {\n backgroundColor: '#3c9cff',\n },\n },\n systemNameLink: {\n textDecoration: 'none',\n color: bLight['300'],\n },\n systemName: {\n marginTop: '0.5em',\n marginBottom: '1em',\n },\n icon: {\n backgroundColor: 'transparent',\n width: '100px',\n height: '100px',\n },\n card: {\n minWidth: 300,\n marginTop: '6em',\n overflow: 'visible',\n backgroundColor: '#ffffffe6',\n },\n avatar: {\n marginTop: '-50px',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(240 242 245))!important',\n },\n },\n RaLayout: {\n content: {\n padding: '0 !important',\n },\n },\n RaListToolbar: {\n toolbar: {\n padding: '0 .55rem !important',\n },\n },\n RaDatagridHeaderCell: {\n icon: {\n color: '#717171 !important',\n },\n },\n RaSearchInput: {\n input: {\n paddingLeft: '.9rem',\n border: 0,\n },\n },\n RaFilterButton: {\n root: {\n marginRight: '1rem',\n '& button': {\n color: '#0f0f0f',\n backgroundColor: '#fff',\n '& span': {\n color: '#101010',\n },\n '&:hover': {\n backgroundColor: '#dedede !important',\n },\n },\n },\n },\n RaAutocompleteSuggestionList: {\n suggestionsPaper: {\n backgroundColor: '#fff',\n },\n },\n RaLink: {\n link: {\n color: '#287eff',\n },\n },\n RaLogout: {\n icon: {\n color: '#f90000!important',\n },\n },\n RaMenuItemLink: {\n root: {\n color: '#232323 !important',\n '& .MuiListItemIcon-root': {\n color: '#656565',\n },\n },\n active: {\n backgroundColor: '#44a0ff1f',\n color: '#232323 !important',\n '& .MuiListItemIcon-root': {\n color: '#0066ff',\n },\n },\n },\n RaSidebar: {\n root: {\n height: 'initial',\n },\n drawerPaper: {\n '@media (min-width: 0px) and (max-width: 599.95px)': {\n backgroundColor: `${bLight['500']} !important`,\n },\n },\n },\n RaBulkActionsToolbar: {\n toolbar: {\n backgroundColor: bLight['500'],\n },\n },\n RaPaginationActions: {\n button: {\n backgroundColor: 'inherit',\n minWidth: 48,\n margin: '0 4px',\n border: '1px solid #282828',\n '@global': {\n '> .MuiButton-label': {\n padding: 0,\n },\n },\n },\n actions: {\n '@global': {\n '.next-page': {\n marginLeft: 8,\n marginRight: 8,\n },\n '.previous-page': {\n marginRight: 8,\n },\n },\n },\n },\n },\n player: {\n theme: 'light',\n },\n}\n","import LightTheme from './light'\nimport DarkTheme from './dark'\nimport ExtraDarkTheme from './extradark'\nimport GreenTheme from './green'\nimport SpotifyTheme from './spotify'\nimport LigeraTheme from './ligera'\nimport MonokaiTheme from './monokai'\n\nexport default {\n // Classic default themes\n LightTheme,\n DarkTheme,\n\n // New themes should be added here, in alphabetic order\n ExtraDarkTheme,\n GreenTheme,\n LigeraTheme,\n MonokaiTheme,\n SpotifyTheme,\n}\n","export default {\n themeName: 'Monokai',\n palette: {\n primary: {\n main: '#66d9ef',\n },\n secondary: {\n main: '#49483e',\n contrastText: '#f8f8f2',\n },\n type: 'dark',\n background: {\n default: '#272822',\n },\n },\n overrides: {\n MuiPaper: {\n root: {\n color: '#f8f8f2',\n backgroundColor: '#3b3a32',\n MuiSnackbarContent: {\n root: {\n color: '#f8f8f2',\n backgroundColor: '#f92672',\n },\n message: {\n color: '#f8f8f2',\n backgroundColor: '#f92672',\n },\n },\n },\n },\n MuiButton: {\n textPrimary: {\n color: '#66d9ef',\n },\n textSecondary: {\n color: '#f8f8f2',\n },\n },\n MuiChip: {\n clickable: {\n background: '#49483e',\n },\n },\n MuiFormGroup: {\n root: {\n color: '#f8f8f2',\n },\n },\n MuiFormHelperText: {\n root: {\n Mui: {\n error: {\n color: '#f92672',\n },\n },\n },\n },\n MuiTableHead: {\n root: {\n color: '#f8f8f2',\n background: '#3b3a32 !important',\n },\n },\n MuiTableCell: {\n root: {\n color: '#f8f8f2',\n background: '#3b3a32 !important',\n },\n head: {\n color: '#f8f8f2',\n background: '#3b3a32 !important',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#66d9ef',\n },\n icon: {},\n welcome: {\n color: '#f8f8f2',\n },\n card: {\n minWidth: 300,\n background: '#3b3a32',\n },\n avatar: {},\n button: {\n boxShadow: '3px 3px 5px #272822',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',\n },\n },\n },\n player: {\n theme: 'monokai',\n stylesheet: require('./monokai.css.js'),\n },\n}\n","import { useSelector } from 'react-redux'\nimport useMediaQuery from '@material-ui/core/useMediaQuery'\nimport themes from './index'\nimport { AUTO_THEME_ID } from '../consts'\nimport config from '../config'\nimport { useEffect } from 'react'\n\nconst useCurrentTheme = () => {\n const prefersLightMode = useMediaQuery('(prefers-color-scheme: light)')\n const theme = useSelector((state) => {\n if (state.theme === AUTO_THEME_ID) {\n return prefersLightMode ? themes.LightTheme : themes.DarkTheme\n }\n const themeName =\n Object.keys(themes).find((t) => t === state.theme) ||\n Object.keys(themes).find(\n (t) => themes[t].themeName === config.defaultTheme\n ) ||\n 'DarkTheme'\n return themes[themeName]\n })\n\n useEffect(() => {\n const styles = document.getElementsByTagName('style')\n let style\n for (let i = 0; i < styles.length; i++) {\n if (styles[i].id === 'nd-player-style-override') {\n style = styles[i]\n }\n }\n if (theme.player.stylesheet) {\n if (style === undefined) {\n style = document.createElement('style')\n style.id = 'nd-player-style-override'\n style.innerHTML = theme.player.stylesheet\n document.head.appendChild(style)\n } else {\n style.innerHTML = theme.player.stylesheet\n }\n } else {\n if (style !== undefined) {\n document.head.removeChild(style)\n }\n }\n }, [theme])\n\n return theme\n}\n\nexport default useCurrentTheme\n","import React, { useState, useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport { Field, Form } from 'react-final-form'\nimport { useDispatch } from 'react-redux'\nimport Button from '@material-ui/core/Button'\nimport Card from '@material-ui/core/Card'\nimport CardActions from '@material-ui/core/CardActions'\nimport CircularProgress from '@material-ui/core/CircularProgress'\nimport TextField from '@material-ui/core/TextField'\nimport { ThemeProvider, makeStyles } from '@material-ui/core/styles'\nimport { createMuiTheme, useLogin, useNotify, useTranslate } from 'react-admin'\nimport Logo from '../icons/android-icon-192x192.png'\n\nimport Notification from './Notification'\nimport useCurrentTheme from '../themes/useCurrentTheme'\nimport config from '../config'\nimport { clearQueue } from '../actions'\n\nconst useStyles = makeStyles(\n (theme) => ({\n main: {\n display: 'flex',\n flexDirection: 'column',\n minHeight: '100vh',\n alignItems: 'center',\n justifyContent: 'flex-start',\n background: `url(${config.loginBackgroundURL})`,\n backgroundRepeat: 'no-repeat',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n },\n card: {\n minWidth: 300,\n marginTop: '6em',\n overflow: 'visible',\n },\n avatar: {\n margin: '1em',\n display: 'flex',\n justifyContent: 'center',\n marginTop: '-3em',\n },\n icon: {\n backgroundColor: 'transparent',\n width: '6.3em',\n height: '6.3em',\n },\n systemName: {\n marginTop: '1em',\n display: 'flex',\n justifyContent: 'center',\n color: '#3f51b5', //theme.palette.grey[500]\n },\n welcome: {\n marginTop: '1em',\n padding: '0 1em 1em 1em',\n display: 'flex',\n justifyContent: 'center',\n flexWrap: 'wrap',\n color: '#3f51b5', //theme.palette.grey[500]\n },\n form: {\n padding: '0 1em 1em 1em',\n },\n input: {\n marginTop: '1em',\n },\n actions: {\n padding: '0 1em 1em 1em',\n },\n button: {},\n systemNameLink: {\n textDecoration: 'none',\n },\n }),\n { name: 'NDLogin' }\n)\n\nconst renderInput = ({\n meta: { touched, error } = {},\n input: { ...inputProps },\n ...props\n}) => (\n \n)\n\nconst FormLogin = ({ loading, handleSubmit, validate }) => {\n const translate = useTranslate()\n const classes = useStyles()\n\n return (\n (\n
\n
\n \n
\n {'logo'}\n
\n
\n \n Silver Moon Orchestra\n \n
\n {config.welcomeMessage && (\n \n )}\n
\n
\n \n
\n
\n \n
\n
\n \n \n {loading && }\n {translate('ra.auth.sign_in')}\n \n \n
\n \n
\n
\n )}\n />\n )\n}\n\nconst FormSignUp = ({ loading, handleSubmit, validate }) => {\n const translate = useTranslate()\n const classes = useStyles()\n\n return (\n (\n
\n
\n \n
\n {'logo'}\n
\n
\n {translate('ra.auth.welcome1')}\n
\n
\n {translate('ra.auth.welcome2')}\n
\n
\n
\n \n
\n
\n \n
\n
\n \n
\n
\n \n \n {loading && }\n {translate('ra.auth.buttonCreateAdmin')}\n \n \n
\n \n
\n
\n )}\n />\n )\n}\nconst Login = ({ location }) => {\n const [loading, setLoading] = useState(false)\n const translate = useTranslate()\n const notify = useNotify()\n const login = useLogin()\n const dispatch = useDispatch()\n\n const handleSubmit = useCallback(\n (auth) => {\n setLoading(true)\n dispatch(clearQueue())\n login(auth, location.state ? location.state.nextPathname : '/').catch(\n (error) => {\n setLoading(false)\n notify(\n typeof error === 'string'\n ? error\n : typeof error === 'undefined' || !error.message\n ? 'ra.auth.sign_in_error'\n : error.message,\n 'warning'\n )\n }\n )\n },\n [dispatch, login, notify, setLoading, location]\n )\n\n const validateLogin = useCallback(\n (values) => {\n const errors = {}\n if (!values.username) {\n errors.username = translate('ra.validation.required')\n }\n if (!values.password) {\n errors.password = translate('ra.validation.required')\n }\n return errors\n },\n [translate]\n )\n\n const validateSignup = useCallback(\n (values) => {\n const errors = validateLogin(values)\n const regex = /^\\w+$/g\n if (values.username && !values.username.match(regex)) {\n errors.username = translate('ra.validation.invalidChars')\n }\n if (!values.confirmPassword) {\n errors.confirmPassword = translate('ra.validation.required')\n }\n if (values.confirmPassword !== values.password) {\n errors.confirmPassword = translate('ra.validation.passwordDoesNotMatch')\n }\n return errors\n },\n [translate, validateLogin]\n )\n\n if (config.firstTime) {\n return (\n \n )\n }\n return (\n \n )\n}\n\nLogin.propTypes = {\n authProvider: PropTypes.func,\n previousRoute: PropTypes.string,\n}\n\n// We need to put the ThemeProvider decoration in another component\n// Because otherwise the useStyles() hook used in Login won't get\n// the right theme\nconst LoginWithTheme = (props) => {\n const theme = useCurrentTheme()\n return (\n \n \n \n )\n}\n\nexport default LoginWithTheme\n","import React, { useCallback } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { Logout as RALogout } from 'react-admin'\nimport { clearQueue } from '../actions'\n\nconst Logout = (props) => {\n const dispatch = useDispatch()\n const handleClick = useCallback(() => dispatch(clearQueue()), [dispatch])\n\n return (\n \n \n \n )\n}\n\nexport default Logout\n","import React, { Fragment } from 'react'\nimport { useDispatch } from 'react-redux'\nimport ExpandMore from '@material-ui/icons/ExpandMore'\nimport ArrowRightOutlined from '@material-ui/icons/ArrowRightOutlined'\nimport List from '@material-ui/core/List'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport Typography from '@material-ui/core/Typography'\nimport Collapse from '@material-ui/core/Collapse'\nimport Tooltip from '@material-ui/core/Tooltip'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { setSidebarVisibility, useTranslate } from 'react-admin'\nimport { IconButton, useMediaQuery } from '@material-ui/core'\n\nconst useStyles = makeStyles(\n (theme) => ({\n icon: { minWidth: theme.spacing(5) },\n sidebarIsOpen: {\n '& a': {\n transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',\n paddingLeft: theme.spacing(4),\n },\n },\n sidebarIsClosed: {\n '& a': {\n transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',\n paddingLeft: theme.spacing(2),\n },\n },\n actionIcon: {\n opacity: 0,\n },\n menuHeader: {\n width: '100%',\n },\n headerWrapper: {\n display: 'flex',\n '&:hover $actionIcon': {\n opacity: 1,\n },\n },\n }),\n {\n name: 'NDSubMenu',\n }\n)\n\nconst SubMenu = ({\n handleToggle,\n sidebarIsOpen,\n isOpen,\n name,\n icon,\n children,\n dense,\n onAction,\n actionIcon,\n}) => {\n const translate = useTranslate()\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n const isSmall = useMediaQuery((theme) => theme.breakpoints.down('sm'))\n const dispatch = useDispatch()\n\n const handleOnClick = (e) => {\n e.stopPropagation()\n onAction(e)\n if (isSmall) {\n dispatch(setSidebarVisibility(false))\n }\n }\n\n const header = (\n
\n \n \n {isOpen ? : icon}\n \n \n {translate(name)}\n \n {onAction && sidebarIsOpen && (\n \n {actionIcon}\n \n )}\n \n
\n )\n\n return (\n \n {sidebarIsOpen || isOpen ? (\n header\n ) : (\n \n {header}\n \n )}\n \n \n {children}\n \n \n \n )\n}\n\nSubMenu.defaultProps = {\n action: null,\n actionIcon: ,\n}\n\nexport default SubMenu\n","import PropTypes from 'prop-types'\nimport { useLocation } from 'react-router-dom'\nimport { createElement } from 'react'\n\nconst DynamicMenuIcon = ({ icon, activeIcon, path }) => {\n const location = useLocation()\n\n if (!activeIcon) {\n return createElement(icon, { 'data-testid': 'icon' })\n }\n\n return location.pathname.startsWith('/' + path)\n ? createElement(activeIcon, { 'data-testid': 'activeIcon' })\n : createElement(icon, { 'data-testid': 'icon' })\n}\n\nDynamicMenuIcon.propTypes = {\n path: PropTypes.string.isRequired,\n icon: PropTypes.object.isRequired,\n activeIcon: PropTypes.object,\n}\n\nexport default DynamicMenuIcon\n","import React from 'react'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport LibraryAddIcon from '@material-ui/icons/LibraryAdd'\nimport VideoLibraryIcon from '@material-ui/icons/VideoLibrary'\nimport RepeatIcon from '@material-ui/icons/Repeat'\nimport AlbumIcon from '@material-ui/icons/Album'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport StarIcon from '@material-ui/icons/Star'\nimport StarBorderIcon from '@material-ui/icons/StarBorder'\nimport AlbumOutlinedIcon from '@material-ui/icons/AlbumOutlined'\nimport LibraryAddOutlinedIcon from '@material-ui/icons/LibraryAddOutlined'\nimport VideoLibraryOutlinedIcon from '@material-ui/icons/VideoLibraryOutlined'\nimport config from '../config'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\n\nconst albumLists = {\n all: {\n icon: (\n \n ),\n params: 'sort=name&order=ASC&filter={}',\n },\n random: {\n icon: ,\n params: 'sort=random&order=ASC&filter={}',\n },\n ...(config.enableFavourites && {\n starred: {\n icon: (\n \n ),\n params: 'sort=starred_at&order=DESC&filter={\"starred\":true}',\n },\n }),\n ...(config.enableStarRating && {\n topRated: {\n icon: (\n \n ),\n params: 'sort=rating&order=DESC&filter={\"has_rating\":true}',\n },\n }),\n recentlyAdded: {\n icon: (\n \n ),\n params: 'sort=recently_added&order=DESC&filter={}',\n },\n recentlyPlayed: {\n icon: (\n \n ),\n params: 'sort=play_date&order=DESC&filter={\"recently_played\":true}',\n },\n mostPlayed: {\n icon: ,\n params: 'sort=play_count&order=DESC&filter={\"recently_played\":true}',\n },\n}\n\nexport default albumLists\nexport const defaultAlbumList = 'recentlyAdded'\n","import { withStyles } from '@material-ui/core/styles'\nimport MuiDialogTitle from '@material-ui/core/DialogTitle'\nimport Typography from '@material-ui/core/Typography'\nimport IconButton from '@material-ui/core/IconButton'\nimport CloseIcon from '@material-ui/icons/Close'\nimport React from 'react'\n\nconst styles = (theme) => ({\n root: {\n margin: 0,\n padding: theme.spacing(2),\n },\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n },\n})\n\nexport const DialogTitle = withStyles(styles)((props) => {\n const { children, classes, onClose, ...other } = props\n return (\n \n {children}\n \n \n \n \n )\n})\n","import { withStyles } from '@material-ui/core/styles'\nimport MuiDialogContent from '@material-ui/core/DialogContent'\n\nexport const DialogContent = withStyles((theme) => ({\n root: {\n padding: theme.spacing(2),\n },\n}))(MuiDialogContent)\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Link from '@material-ui/core/Link'\nimport Dialog from '@material-ui/core/Dialog'\nimport IconButton from '@material-ui/core/IconButton'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableRow from '@material-ui/core/TableRow'\nimport TableCell from '@material-ui/core/TableCell'\nimport Paper from '@material-ui/core/Paper'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport inflection from 'inflection'\nimport { useTranslate } from 'react-admin'\nimport config from '../config'\nimport { DialogTitle } from './DialogTitle'\nimport { DialogContent } from './DialogContent'\n\nconst links = {\n homepage: 'TheSilverMoonOrchestra.com',\n// reddit: 'reddit.com/r/Navidrome',\n// twitter: 'twitter.com/navidrome',\n// discord: 'discord.gg/xh7j7yF',\n// source: 'github.com/navidrome/navidrome',\n// featureRequests: 'github.com/navidrome/navidrome/issues',\n}\n\nconst LinkToVersion = ({ version }) => {\n if (version === 'dev') {\n return {version}\n }\n\n const parts = version.split(' ')\n const commitID = parts[1].replace(/[()]/g, '')\n const isSnapshot = version.includes('SNAPSHOT')\n const url = isSnapshot\n ? `https://liminis.com/v${\n// ? `https://github.com/navidrome/navidrome/compare/v${\n parts[0].split('-')[0]\n }...${commitID}`\n : `https://liminis.com`\n// : `https://github.com/navidrome/navidrome/releases/tag/v${parts[0]}`\n return (\n \n \n {parts[0]}\n \n {' (' + commitID + ')'}\n \n )\n}\n\nconst AboutDialog = ({ open, onClose }) => {\n const translate = useTranslate()\n return (\n \n \n The Silver Moon Orchestra Music Server\n \n \n \n \n \n \n \n {translate('menu.version')}:\n \n \n \n {Object.keys(links).map((key) => {\n return (\n \n \n {translate(`about.links.${key}`, {\n _: inflection.humanize(inflection.underscore(key)),\n })}\n :\n \n \n \n {links[key]}\n \n \n \n )\n })}\n \n \n \n \n \n \n \n \n \n \n TheSilverMoonOrchestra.com\n \n \n \n \n
\n
\n
\n \n )\n}\n\nAboutDialog.propTypes = {\n open: PropTypes.bool.isRequired,\n onClose: PropTypes.func.isRequired,\n}\n\nexport { AboutDialog, LinkToVersion }\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport { Button, useTranslate, useUnselectAll } from 'react-admin'\nimport PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'\nimport { openAddToPlaylist } from '../actions'\n\nexport const AddToPlaylistButton = ({ resource, selectedIds, className }) => {\n const translate = useTranslate()\n const dispatch = useDispatch()\n const unselectAll = useUnselectAll()\n\n const handleClick = () => {\n dispatch(\n openAddToPlaylist({ selectedIds, onSuccess: () => unselectAll(resource) })\n )\n }\n\n return (\n \n \n \n )\n}\n\nAddToPlaylistButton.propTypes = {\n resource: PropTypes.string.isRequired,\n selectedIds: PropTypes.arrayOf(PropTypes.string).isRequired,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { Link } from 'react-admin'\nimport { withWidth } from '@material-ui/core'\nimport { useAlbumsPerPage } from './index'\nimport config from '../config'\n\nexport const useGetHandleArtistClick = (width) => {\n const [perPage] = useAlbumsPerPage(width)\n return (id) => {\n return config.devShowArtistPage && id !== config.variousArtistsId\n ? `/artist/${id}/show`\n : `/album?filter={\"artist_id\":\"${id}\"}&order=ASC&sort=max_year&displayedFilters={\"compilation\":true}&perPage=${perPage}`\n }\n}\n\nexport const ArtistLinkField = withWidth()(\n ({ record, className, width, source }) => {\n const artistLink = useGetHandleArtistClick(width)\n\n const id = record[source + 'Id']\n return (\n <>\n {id ? (\n e.stopPropagation()}\n className={className}\n >\n {record[source]}\n \n ) : (\n record[source]\n )}\n \n )\n }\n)\n\nArtistLinkField.propTypes = {\n record: PropTypes.object,\n className: PropTypes.string,\n source: PropTypes.string,\n}\n\nArtistLinkField.defaultProps = {\n addLabel: true,\n source: 'albumArtist',\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport {\n Button,\n useDataProvider,\n useTranslate,\n useUnselectAll,\n useNotify,\n} from 'react-admin'\nimport { useDispatch } from 'react-redux'\n\nexport const BatchPlayButton = ({\n resource,\n selectedIds,\n action,\n label,\n icon,\n className,\n}) => {\n const dispatch = useDispatch()\n const translate = useTranslate()\n const dataProvider = useDataProvider()\n const unselectAll = useUnselectAll()\n const notify = useNotify()\n\n const addToQueue = () => {\n dataProvider\n .getMany(resource, { ids: selectedIds })\n .then((response) => {\n // Add tracks to a map for easy lookup by ID, needed for the next step\n const tracks = response.data.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {}\n )\n // Add the tracks to the queue in the selection order\n dispatch(action(tracks, selectedIds))\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n unselectAll(resource)\n }\n\n const caption = translate(label)\n return (\n \n {icon}\n \n )\n}\n\nBatchPlayButton.propTypes = {\n action: PropTypes.func.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.object.isRequired,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useRecordContext } from 'react-admin'\n\nexport const BitrateField = ({ source, ...rest }) => {\n const record = useRecordContext(rest)\n return {`${record[source]} kbps`}\n}\n\nBitrateField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nBitrateField.defaultProps = {\n addLabel: true,\n}\n","import { baseUrl } from '../utils'\nimport { httpClient } from '../dataProvider'\n\nconst url = (command, id, options) => {\n const params = new URLSearchParams()\n params.append('u', localStorage.getItem('username'))\n params.append('t', localStorage.getItem('subsonic-token'))\n params.append('s', localStorage.getItem('subsonic-salt'))\n params.append('f', 'json')\n params.append('v', '1.8.0')\n params.append('c', 'NavidromeUI')\n id && params.append('id', id)\n if (options) {\n if (options.ts) {\n options['_'] = new Date().getTime()\n delete options.ts\n }\n Object.keys(options).forEach((k) => {\n params.append(k, options[k])\n })\n }\n return `/rest/${command}?${params.toString()}`\n}\n\nconst scrobble = (id, time, submission = true) =>\n httpClient(\n url('scrobble', id, {\n ...(submission && time && { time }),\n submission,\n })\n )\n\nconst nowPlaying = (id) => scrobble(id, null, false)\n\nconst star = (id) => httpClient(url('star', id))\n\nconst unstar = (id) => httpClient(url('unstar', id))\n\nconst setRating = (id, rating) => httpClient(url('setRating', id, { rating }))\n\nconst download = (id) => (window.location.href = baseUrl(url('download', id)))\n\nconst startScan = (options) => httpClient(url('startScan', null, options))\n\nconst getScanStatus = () => httpClient(url('getScanStatus'))\n\nconst getCoverArtUrl = (record, size) => {\n const options = {\n ...(record.updatedAt && { _: record.updatedAt }),\n ...(size && { size }),\n }\n\n if (record.coverArtId) {\n return baseUrl(url('getCoverArt', record.coverArtId, options))\n } else {\n return baseUrl(url('getCoverArt', 'not_found', size && { size }))\n }\n}\n\nconst getArtistInfo = (id) => {\n return httpClient(url('getArtistInfo', id))\n}\n\nconst streamUrl = (id) => {\n return baseUrl(url('stream', id, { ts: true }))\n}\n\nexport default {\n url,\n scrobble,\n nowPlaying,\n download,\n star,\n unstar,\n setRating,\n startScan,\n getScanStatus,\n getCoverArtUrl,\n streamUrl,\n getArtistInfo,\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport { useDataProvider, useNotify } from 'react-admin'\nimport subsonic from '../subsonic'\n\nexport const useToggleLove = (resource, record = {}) => {\n const [loading, setLoading] = useState(false)\n const notify = useNotify()\n\n const mountedRef = useRef(false)\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n const dataProvider = useDataProvider()\n\n const refreshRecord = useCallback(() => {\n dataProvider.getOne(resource, { id: record.id }).then(() => {\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n }, [dataProvider, record.id, resource])\n\n const toggleLove = () => {\n const toggle = record.starred ? subsonic.unstar : subsonic.star\n\n setLoading(true)\n toggle(record.id)\n .then(refreshRecord)\n .catch((e) => {\n console.log('Error toggling love: ', e)\n notify('ra.page.error', 'warning')\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n }\n\n return [toggleLove, loading]\n}\n","import React, { useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport IconButton from '@material-ui/core/IconButton'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useToggleLove } from './useToggleLove'\nimport { useRecordContext } from 'react-admin'\n\nconst useStyles = makeStyles({\n love: {\n color: (props) => props.color,\n visibility: (props) =>\n props.visible === false ? 'hidden' : props.loved ? 'visible' : 'inherit',\n },\n})\n\nexport const LoveButton = ({\n resource,\n color,\n visible,\n size,\n component: Button,\n addLabel,\n disabled,\n ...rest\n}) => {\n const record = useRecordContext(rest) || {}\n const classes = useStyles({ color, visible, loved: record.starred })\n const [toggleLove, loading] = useToggleLove(resource, record)\n\n const handleToggleLove = useCallback(\n (e) => {\n e.preventDefault()\n toggleLove()\n e.stopPropagation()\n },\n [toggleLove]\n )\n\n return (\n \n {record.starred ? (\n \n ) : (\n \n )}\n \n )\n}\n\nLoveButton.propTypes = {\n resource: PropTypes.string.isRequired,\n record: PropTypes.object,\n visible: PropTypes.bool,\n color: PropTypes.string,\n size: PropTypes.string,\n component: PropTypes.object,\n disabled: PropTypes.bool,\n}\n\nLoveButton.defaultProps = {\n addLabel: true,\n visible: true,\n size: 'small',\n color: 'inherit',\n component: IconButton,\n disabled: false,\n}\n","import React, { useState } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport IconButton from '@material-ui/core/IconButton'\nimport Menu from '@material-ui/core/Menu'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport MoreVertIcon from '@material-ui/icons/MoreVert'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useDataProvider, useNotify, useTranslate } from 'react-admin'\nimport clsx from 'clsx'\nimport {\n playNext,\n addTracks,\n playTracks,\n shuffleTracks,\n openAddToPlaylist,\n openExtendedInfoDialog,\n} from '../actions'\nimport subsonic from '../subsonic'\nimport { LoveButton } from './LoveButton'\nimport config from '../config'\nimport { formatBytes } from '../utils'\n\nconst useStyles = makeStyles({\n noWrap: {\n whiteSpace: 'nowrap',\n },\n menu: {\n color: (props) => props.color,\n },\n})\n\nconst ContextMenu = ({\n resource,\n showLove,\n record,\n color,\n className,\n songQueryParams,\n hideInfo,\n}) => {\n const classes = useStyles({ color })\n const dataProvider = useDataProvider()\n const dispatch = useDispatch()\n const translate = useTranslate()\n const notify = useNotify()\n const [anchorEl, setAnchorEl] = useState(null)\n\n const options = {\n play: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.playAll'),\n action: (data, ids) => dispatch(playTracks(data, ids)),\n },\n playNext: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.playNext'),\n action: (data, ids) => dispatch(playNext(data, ids)),\n },\n addToQueue: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.addToQueue'),\n action: (data, ids) => dispatch(addTracks(data, ids)),\n },\n shuffle: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.shuffle'),\n action: (data, ids) => dispatch(shuffleTracks(data, ids)),\n },\n addToPlaylist: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.addToPlaylist'),\n action: (data, ids) => dispatch(openAddToPlaylist({ selectedIds: ids })),\n },\n download: {\n enabled: config.enableDownloads && record.size,\n needData: false,\n label: `${translate('resources.album.actions.download')} (${formatBytes(\n record.size\n )})`,\n action: () => subsonic.download(record.id),\n },\n ...(!hideInfo && {\n info: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.info'),\n action: () => dispatch(openExtendedInfoDialog(record)),\n },\n }),\n }\n\n const handleClick = (e) => {\n e.preventDefault()\n setAnchorEl(e.currentTarget)\n e.stopPropagation()\n }\n\n const handleOnClose = (e) => {\n e.preventDefault()\n setAnchorEl(null)\n e.stopPropagation()\n }\n\n let extractSongsData = function (response) {\n const data = response.data.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {}\n )\n const ids = response.data.map((r) => r.id)\n return { data, ids }\n }\n\n const handleItemClick = (e) => {\n setAnchorEl(null)\n const key = e.target.getAttribute('value')\n if (options[key].needData) {\n dataProvider\n .getList('song', songQueryParams)\n .then((response) => {\n let { data, ids } = extractSongsData(response)\n options[key].action(data, ids)\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n } else {\n options[key].action()\n }\n\n e.stopPropagation()\n }\n\n const open = Boolean(anchorEl)\n\n return (\n \n \n \n \n \n \n {Object.keys(options).map(\n (key) =>\n options[key].enabled && (\n \n {options[key].label}\n \n )\n )}\n \n \n )\n}\n\nexport const AlbumContextMenu = (props) =>\n props.record ? (\n \n ) : null\n\nAlbumContextMenu.propTypes = {\n record: PropTypes.object,\n discNumber: PropTypes.number,\n color: PropTypes.string,\n showLove: PropTypes.bool,\n}\n\nAlbumContextMenu.defaultProps = {\n showLove: true,\n addLabel: true,\n}\n\nexport const ArtistContextMenu = (props) =>\n props.record ? (\n \n ) : null\n\nArtistContextMenu.propTypes = {\n record: PropTypes.object,\n color: PropTypes.string,\n showLove: PropTypes.bool,\n}\n\nArtistContextMenu.defaultProps = {\n showLove: true,\n addLabel: true,\n}\n","import React from 'react'\nimport { DateField as RADateField } from 'react-admin'\n\nexport const DateField = (props) => {\n const { record, source } = props\n const value = record?.[source]\n if (value === '0001-01-01T00:00:00Z' || value === null) return null\n return \n}\n\nDateField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport { docsUrl } from '../utils'\n\nexport const DocLink = ({ path, children }) => (\n \n {children}\n \n)\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { formatDuration } from '../utils'\nimport { useRecordContext } from 'react-admin'\n\nexport const DurationField = ({ source, ...rest }) => {\n const record = useRecordContext(rest)\n try {\n return {formatDuration(record[source])}\n } catch (e) {\n console.log('Error in DurationField! Record:', record)\n return 00:00\n }\n}\n\nDurationField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nDurationField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport { Pagination as RAPagination } from 'react-admin'\n\nexport const Pagination = (props) => (\n \n)\n","import React from 'react'\nimport { List as RAList } from 'react-admin'\nimport { Pagination } from './Pagination'\nimport { Title } from './index'\n\nexport const List = (props) => {\n const { resource } = props\n return (\n \n }\n perPage={15}\n pagination={}\n {...props}\n />\n )\n}\n","const sanitizeFieldRestProps = ({\n addLabel,\n allowEmpty,\n basePath,\n cellClassName,\n className,\n emptyText,\n formClassName,\n fullWidth,\n headerClassName,\n label,\n linkType,\n link,\n locale,\n record,\n resource,\n sortable,\n sortBy,\n sortByOrder,\n source,\n textAlign,\n translateChoice,\n ...props\n}) => props\n\nexport default sanitizeFieldRestProps\n","import React, { memo } from 'react'\nimport Typography from '@material-ui/core/Typography'\nimport sanitizeFieldRestProps from './sanitizeFieldRestProps'\nimport md5 from 'blueimp-md5'\nimport { useRecordContext } from 'react-admin'\n\nexport const MultiLineTextField = memo(\n ({\n className,\n emptyText,\n source,\n firstLine,\n maxLines,\n addLabel,\n ...rest\n }) => {\n const record = useRecordContext(rest)\n const value = record && record[source]\n let lines = value ? value.split('\\n') : []\n if (maxLines || firstLine) {\n lines = lines.slice(firstLine, maxLines)\n }\n\n return (\n \n {lines.length === 0 && emptyText\n ? emptyText\n : lines.map((line, idx) =>\n line === '' ? (\n
\n ) : (\n \n )\n )}\n \n )\n }\n)\n\nMultiLineTextField.defaultProps = {\n addLabel: true,\n firstLine: 0,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport { IconButton } from '@material-ui/core'\nimport { useDispatch } from 'react-redux'\nimport { useDataProvider } from 'react-admin'\nimport { playTracks } from '../actions'\n\nexport const PlayButton = ({ record, size, className }) => {\n let extractSongsData = function (response) {\n const data = response.data.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {}\n )\n const ids = response.data.map((r) => r.id)\n return { data, ids }\n }\n const dataProvider = useDataProvider()\n const dispatch = useDispatch()\n const playAlbum = (record) => {\n dataProvider\n .getList('song', {\n pagination: { page: 1, perPage: -1 },\n sort: { field: 'discNumber, trackNumber', order: 'ASC' },\n filter: { album_id: record.id, disc_number: record.discNumber },\n })\n .then((response) => {\n let { data, ids } = extractSongsData(response)\n dispatch(playTracks(data, ids))\n })\n }\n\n return (\n {\n e.stopPropagation()\n e.preventDefault()\n playAlbum(record)\n }}\n aria-label=\"play\"\n className={className}\n size={size}\n >\n \n \n )\n}\n\nPlayButton.propTypes = {\n record: PropTypes.object.isRequired,\n size: PropTypes.string,\n className: PropTypes.string,\n}\n\nPlayButton.defaultProps = {\n size: 'small',\n}\n","import React from 'react'\nimport { Chip, makeStyles } from '@material-ui/core'\nimport { useTranslate } from 'react-admin'\nimport inflection from 'inflection'\n\nconst useQuickFilterStyles = makeStyles((theme) => ({\n chip: {\n marginBottom: theme.spacing(1),\n },\n}))\n\nexport const QuickFilter = ({ source, resource, label, defaultValue }) => {\n const translate = useTranslate()\n const classes = useQuickFilterStyles()\n let lbl = label || source\n if (typeof lbl === 'string' || lbl instanceof String) {\n if (label) {\n lbl = translate(lbl, {\n _: inflection.humanize(inflection.underscore(lbl)),\n })\n } else {\n lbl = translate(`resources.${resource}.fields.${source}`, {\n _: inflection.humanize(inflection.underscore(source)),\n })\n }\n }\n return \n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useRecordContext } from 'react-admin'\n\nexport const formatRange = (record, source) => {\n const nameCapitalized = source.charAt(0).toUpperCase() + source.slice(1)\n const min = record[`min${nameCapitalized}`]\n const max = record[`max${nameCapitalized}`]\n let range = []\n if (min) {\n range.push(min)\n }\n if (max && max !== min) {\n range.push(max)\n }\n return range.join('-')\n}\n\nexport const RangeField = ({ className, source, ...rest }) => {\n const record = useRecordContext(rest)\n return {formatRange(record, source)}\n}\n\nRangeField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nRangeField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport { Button, useDataProvider, useNotify, useTranslate } from 'react-admin'\nimport { useDispatch } from 'react-redux'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport { playTracks } from '../actions'\nimport PropTypes from 'prop-types'\n\nexport const ShuffleAllButton = ({ filters }) => {\n const translate = useTranslate()\n const dataProvider = useDataProvider()\n const dispatch = useDispatch()\n const notify = useNotify()\n\n const handleOnClick = () => {\n dataProvider\n .getList('song', {\n pagination: { page: 1, perPage: 200 },\n sort: { field: 'random', order: 'ASC' },\n filter: filters,\n })\n .then((res) => {\n const data = {}\n res.data.forEach((song) => {\n data[song.id] = song\n })\n dispatch(playTracks(data))\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n }\n\n return (\n \n \n \n )\n}\n\nShuffleAllButton.propTypes = {\n filters: PropTypes.object,\n}\nShuffleAllButton.defaultProps = {\n filters: {},\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Avatar from '@material-ui/core/Avatar'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemAvatar from '@material-ui/core/ListItemAvatar'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { Link } from 'react-router-dom'\nimport { linkToRecord, sanitizeListRestProps } from 'react-admin'\n\nconst useStyles = makeStyles(\n {\n link: {\n textDecoration: 'none',\n color: 'inherit',\n },\n tertiary: { float: 'right', opacity: 0.541176 },\n },\n { name: 'RaSimpleList' }\n)\n\nconst LinkOrNot = ({\n classes: classesOverride,\n linkType,\n basePath,\n id,\n record,\n children,\n}) => {\n const classes = useStyles({ classes: classesOverride })\n return linkType === 'edit' || linkType === true ? (\n \n {children}\n \n ) : linkType === 'show' ? (\n \n {children}\n \n ) : typeof linkType === 'function' ? (\n linkType(id, basePath, record)}>{children}\n ) : (\n {children}\n )\n}\n\nexport const SimpleList = ({\n basePath,\n className,\n classes: classesOverride,\n data,\n hasBulkActions,\n ids,\n loading,\n leftAvatar,\n leftIcon,\n linkType,\n onToggleItem,\n primaryText,\n rightAvatar,\n rightIcon,\n secondaryText,\n selectedIds,\n tertiaryText,\n total,\n ...rest\n}) => {\n const classes = useStyles({ classes: classesOverride })\n return (\n (loading || total > 0) && (\n \n {ids.map((id) => (\n \n \n {leftIcon && (\n {leftIcon(data[id], id)}\n )}\n {leftAvatar && (\n \n {leftAvatar(data[id], id)}\n \n )}\n \n {primaryText(data[id], id)}\n {tertiaryText && (\n \n {tertiaryText(data[id], id)}\n \n )}\n \n }\n secondary={secondaryText && secondaryText(data[id], id)}\n />\n {(rightAvatar || rightIcon) && (\n \n {rightAvatar && {rightAvatar(data[id], id)}}\n {rightIcon && (\n {rightIcon(data[id], id)}\n )}\n \n )}\n \n \n ))}\n \n )\n )\n}\n\nSimpleList.propTypes = {\n basePath: PropTypes.string,\n className: PropTypes.string,\n classes: PropTypes.object,\n data: PropTypes.object,\n hasBulkActions: PropTypes.bool.isRequired,\n ids: PropTypes.array,\n leftAvatar: PropTypes.func,\n leftIcon: PropTypes.func,\n linkType: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.bool,\n PropTypes.func,\n ]).isRequired,\n onToggleItem: PropTypes.func,\n primaryText: PropTypes.func,\n rightAvatar: PropTypes.func,\n rightIcon: PropTypes.func,\n secondaryText: PropTypes.func,\n selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,\n tertiaryText: PropTypes.func,\n}\n\nSimpleList.defaultProps = {\n linkType: 'edit',\n hasBulkActions: false,\n selectedIds: [],\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { formatBytes } from '../utils'\nimport { useRecordContext } from 'react-admin'\nimport { makeStyles } from '@material-ui/core'\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: 'inline-block',\n },\n}))\n\nexport const SizeField = ({ source, ...rest }) => {\n const classes = useStyles()\n const record = useRecordContext(rest)\n return {formatBytes(record[source])}\n}\n\nSizeField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nSizeField.defaultProps = {\n addLabel: true,\n}\n","import React, { useState } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport { useTranslate } from 'react-admin'\nimport { IconButton, Menu, MenuItem } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport MoreVertIcon from '@material-ui/icons/MoreVert'\nimport clsx from 'clsx'\nimport {\n playNext,\n addTracks,\n setTrack,\n openAddToPlaylist,\n openExtendedInfoDialog,\n} from '../actions'\nimport subsonic from '../subsonic'\nimport { LoveButton } from './LoveButton'\nimport config from '../config'\nimport { formatBytes } from '../utils'\n\nconst useStyles = makeStyles({\n noWrap: {\n whiteSpace: 'nowrap',\n },\n})\n\nexport const SongContextMenu = ({\n resource,\n record,\n showLove,\n onAddToPlaylist,\n className,\n}) => {\n const classes = useStyles()\n const dispatch = useDispatch()\n const translate = useTranslate()\n const [anchorEl, setAnchorEl] = useState(null)\n const options = {\n playNow: {\n enabled: true,\n label: translate('resources.song.actions.playNow'),\n action: (record) => dispatch(setTrack(record)),\n },\n playNext: {\n enabled: true,\n label: translate('resources.song.actions.playNext'),\n action: (record) => dispatch(playNext({ [record.id]: record })),\n },\n addToQueue: {\n enabled: true,\n label: translate('resources.song.actions.addToQueue'),\n action: (record) => dispatch(addTracks({ [record.id]: record })),\n },\n addToPlaylist: {\n enabled: true,\n label: translate('resources.song.actions.addToPlaylist'),\n action: (record) =>\n dispatch(\n openAddToPlaylist({\n selectedIds: [record.mediaFileId || record.id],\n onSuccess: (id) => onAddToPlaylist(id),\n })\n ),\n },\n download: {\n enabled: config.enableDownloads,\n label: `${translate('resources.song.actions.download')} (${formatBytes(\n record.size\n )})`,\n action: (record) => subsonic.download(record.mediaFileId || record.id),\n },\n info: {\n enabled: true,\n label: translate('resources.song.actions.info'),\n action: (record) => dispatch(openExtendedInfoDialog(record)),\n },\n }\n\n const handleClick = (e) => {\n setAnchorEl(e.currentTarget)\n e.stopPropagation()\n }\n\n const handleClose = (e) => {\n setAnchorEl(null)\n e.stopPropagation()\n }\n\n const handleItemClick = (e) => {\n e.preventDefault()\n setAnchorEl(null)\n const key = e.target.getAttribute('value')\n options[key].action(record)\n e.stopPropagation()\n }\n\n const open = Boolean(anchorEl)\n\n return (\n \n \n \n \n \n \n {Object.keys(options).map(\n (key) =>\n options[key].enabled && (\n \n {options[key].label}\n \n )\n )}\n \n \n )\n}\n\nSongContextMenu.propTypes = {\n resource: PropTypes.string.isRequired,\n record: PropTypes.object.isRequired,\n onAddToPlaylist: PropTypes.func,\n showLove: PropTypes.bool,\n}\n\nSongContextMenu.defaultProps = {\n onAddToPlaylist: () => {},\n record: {},\n resource: 'song',\n showLove: true,\n addLabel: true,\n}\n","import React, { isValidElement, useMemo, useCallback, forwardRef } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { Datagrid, PureDatagridBody, PureDatagridRow } from 'react-admin'\nimport {\n TableCell,\n TableRow,\n Typography,\n useMediaQuery,\n} from '@material-ui/core'\nimport PropTypes from 'prop-types'\nimport { makeStyles } from '@material-ui/core/styles'\nimport AlbumIcon from '@material-ui/icons/Album'\nimport clsx from 'clsx'\nimport { useDrag } from 'react-dnd'\nimport { playTracks } from '../actions'\nimport { AlbumContextMenu } from '../common'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles({\n subtitle: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n verticalAlign: 'middle',\n },\n discIcon: {\n verticalAlign: 'text-top',\n marginRight: '4px',\n },\n row: {\n cursor: 'pointer',\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n },\n },\n headerStyle: {\n '& thead': {\n boxShadow: '0px 3px 3px rgba(0, 0, 0, 0.15)',\n },\n '& th': {\n fontWeight: 'bold',\n padding: '15px',\n },\n },\n contextMenu: {\n visibility: (props) => (props.isDesktop ? 'hidden' : 'visible'),\n },\n})\n\nconst DiscSubtitleRow = forwardRef(\n ({ record, onClick, colSpan, contextAlwaysVisible }, ref) => {\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const handlePlayDisc = (discNumber) => () => {\n onClick(discNumber)\n }\n\n let subtitle = []\n if (record.discNumber > 0) {\n subtitle.push(record.discNumber)\n }\n if (record.discSubtitle) {\n subtitle.push(record.discSubtitle)\n }\n\n return (\n \n \n \n \n {subtitle.join(': ')}\n \n \n \n \n \n \n )\n }\n)\n\nexport const SongDatagridRow = ({\n record,\n children,\n firstTracks,\n contextAlwaysVisible,\n onClickDiscSubtitle,\n className,\n ...rest\n}) => {\n const classes = useStyles()\n const fields = React.Children.toArray(children).filter((c) =>\n isValidElement(c)\n )\n\n const [, dragDiscRef] = useDrag(\n () => ({\n type: DraggableTypes.DISC,\n item: {\n discs: [{ albumId: record?.albumId, discNumber: record?.discNumber }],\n },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n\n const [, dragSongRef] = useDrag(\n () => ({\n type: DraggableTypes.SONG,\n item: { ids: [record?.mediaFileId || record?.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n\n if (!record || !record.title) {\n return null\n }\n\n const childCount = fields.length\n return (\n <>\n {firstTracks.has(record.id) && (\n \n )}\n \n {fields}\n \n \n )\n}\n\nSongDatagridRow.propTypes = {\n record: PropTypes.object,\n children: PropTypes.node,\n firstTracks: PropTypes.instanceOf(Set),\n contextAlwaysVisible: PropTypes.bool,\n onClickDiscSubtitle: PropTypes.func,\n}\n\nSongDatagridRow.defaultProps = {\n onClickDiscSubtitle: () => {},\n}\n\nconst SongDatagridBody = ({\n contextAlwaysVisible,\n showDiscSubtitles,\n ...rest\n}) => {\n const dispatch = useDispatch()\n const { ids, data } = rest\n\n const playDisc = useCallback(\n (discNumber) => {\n const idsToPlay = ids.filter((id) => data[id].discNumber === discNumber)\n dispatch(playTracks(data, idsToPlay))\n },\n [dispatch, data, ids]\n )\n\n const firstTracks = useMemo(() => {\n if (!ids) {\n return new Set()\n }\n let foundSubtitle = false\n const set = new Set(\n ids\n .filter((i) => data[i])\n .reduce((acc, id) => {\n const last = acc && acc[acc.length - 1]\n foundSubtitle = foundSubtitle || data[id].discSubtitle\n if (\n acc.length === 0 ||\n (last && data[id].discNumber !== data[last].discNumber)\n ) {\n acc.push(id)\n }\n return acc\n }, [])\n )\n if (!showDiscSubtitles || (set.size < 2 && !foundSubtitle)) {\n set.clear()\n }\n return set\n }, [ids, data, showDiscSubtitles])\n\n return (\n \n }\n />\n )\n}\n\nexport const SongDatagrid = ({\n contextAlwaysVisible,\n showDiscSubtitles,\n ...rest\n}) => {\n const classes = useStyles()\n return (\n \n }\n />\n )\n}\n\nSongDatagrid.propTypes = {\n contextAlwaysVisible: PropTypes.bool,\n showDiscSubtitles: PropTypes.bool,\n classes: PropTypes.object,\n}\n","import React from 'react'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableCell from '@material-ui/core/TableCell'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport TableRow from '@material-ui/core/TableRow'\nimport {\n BooleanField,\n DateField,\n TextField,\n NumberField,\n FunctionField,\n useTranslate,\n useRecordContext,\n} from 'react-admin'\nimport inflection from 'inflection'\nimport { BitrateField, SizeField } from './index'\nimport { MultiLineTextField } from './MultiLineTextField'\nimport { makeStyles } from '@material-ui/core/styles'\n\nconst useStyles = makeStyles({\n tableCell: {\n width: '17.5%',\n },\n})\n\nexport const SongInfo = (props) => {\n const classes = useStyles()\n const translate = useTranslate()\n const record = useRecordContext(props)\n const data = {\n path: ,\n album: ,\n discSubtitle: ,\n albumArtist: ,\n genre: (\n r.genres?.map((g) => g.name).join(', ')} />\n ),\n compilation: ,\n bitRate: ,\n channels: ,\n size: ,\n updatedAt: ,\n playCount: ,\n bpm: ,\n comment: ,\n }\n\n const optionalFields = ['discSubtitle', 'comment', 'bpm', 'genre']\n optionalFields.forEach((field) => {\n !record[field] && delete data[field]\n })\n if (record.playCount > 0) {\n data.playDate = \n }\n\n return (\n \n \n \n {Object.keys(data).map((key) => {\n return (\n \n \n {translate(`resources.song.fields.${key}`, {\n _: inflection.humanize(inflection.underscore(key)),\n })}\n :\n \n {data[key]}\n \n )\n })}\n \n
\n
\n )\n}\n","import { makeStyles } from '@material-ui/core/styles'\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { useSelector } from 'react-redux'\nimport { FunctionField } from 'react-admin'\nimport { useTheme } from '@material-ui/core/styles'\nimport PlayingLight from '../icons/playing-light.gif'\nimport PlayingDark from '../icons/playing-dark.gif'\nimport PausedLight from '../icons/paused-light.png'\nimport PausedDark from '../icons/paused-dark.png'\n\nconst useStyles = makeStyles({\n icon: {\n width: '32px',\n height: '32px',\n verticalAlign: 'text-top',\n marginLeft: '-8px',\n marginTop: '-7px',\n paddingRight: '3px',\n },\n text: {\n verticalAlign: 'text-top',\n },\n})\n\nexport const SongTitleField = ({ showTrackNumbers, ...props }) => {\n const theme = useTheme()\n const classes = useStyles()\n const { record } = props\n const currentTrack = useSelector((state) => state?.player?.current || {})\n const currentId = currentTrack.trackId\n const paused = currentTrack.paused\n const isCurrent =\n currentId && (currentId === record.id || currentId === record.mediaFileId)\n\n const trackName = (r) => {\n const name = r.title\n if (r.trackNumber && showTrackNumbers) {\n return r.trackNumber.toString().padStart(2, '0') + ' ' + name\n }\n return name\n }\n\n const Icon = () => {\n let icon\n if (paused) {\n icon = theme.palette.type === 'light' ? PausedLight : PausedDark\n } else {\n icon = theme.palette.type === 'light' ? PlayingLight : PlayingDark\n }\n return (\n \n )\n }\n\n return (\n <>\n {isCurrent && }\n \n \n )\n}\n\nSongTitleField.propTypes = {\n record: PropTypes.object,\n showTrackNumbers: PropTypes.bool,\n}\n\nSongTitleField.defaultProps = {\n record: {},\n showTrackNumbers: false,\n}\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAAAAACreq1xAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAnRSTlMAAHaTzTgAAAACYktHRAD/h4/MvwAAAAd0SU1FB+UDFw4UEte6vnAAAAAnSURBVFjD7cyhEQAACMSwX4X9l8ThEFguUVVNAAAAgDdq7G0IAHDWO+8PeYnJa4QAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDMtMjNUMTQ6MTg6NTkrMDA6MDAXgf/NAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAzLTIzVDE0OjE4OjU5KzAwOjAwZtxHcQAAAABJRU5ErkJggg==\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAAAAACreq1xAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAnRSTlMAAHaTzTgAAAACYktHRAD/h4/MvwAAAAd0SU1FB+UDFw4UNuu5WqEAAAAnSURBVFjD7cyhEQAACMSw339OBsHhEFguUVVNAAAAgDdq7G0IAHDWlC1q4c5Yf/kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDMtMjNUMTQ6MTg6NTkrMDA6MDAXgf/NAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAzLTIzVDE0OjE4OjU5KzAwOjAwZtxHcQAAAABJRU5ErkJggg==\"","export default \"data:image/gif;base64,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\"","export default \"data:image/gif;base64,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\"","import React from 'react'\nimport { useMediaQuery } from '@material-ui/core'\nimport { useTranslate } from 'react-admin'\n\nexport const Title = ({ subTitle, args }) => {\n const translate = useTranslate()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const text = translate(subTitle, { ...args, _: subTitle })\n\n if (isDesktop) {\n return SilverMoonOrchestra {text ? ` - ${text}` : ''}\n }\n return {text ? text : 'SilverMoonOrchestra'}\n}\n","import React, { Fragment, useEffect } from 'react'\nimport { useUnselectAll } from 'react-admin'\nimport { addTracks, playNext, playTracks } from '../actions'\nimport { RiPlayList2Fill, RiPlayListAddFill } from 'react-icons/ri'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport { BatchPlayButton } from './index'\nimport { AddToPlaylistButton } from './AddToPlaylistButton'\nimport { makeStyles } from '@material-ui/core/styles'\n\nconst useStyles = makeStyles((theme) => ({\n button: {\n color: theme.palette.type === 'dark' ? 'white' : undefined,\n },\n}))\n\nexport const SongBulkActions = (props) => {\n const classes = useStyles()\n const unselectAll = useUnselectAll()\n useEffect(() => {\n unselectAll(props.resource)\n }, [unselectAll, props.resource])\n return (\n \n }\n className={classes.button}\n />\n }\n className={classes.button}\n />\n }\n className={classes.button}\n />\n \n \n )\n}\n","import { useSelector } from 'react-redux'\n\nconst getPerPage = (width) => {\n if (width === 'xs') return 12\n if (width === 'sm') return 12\n if (width === 'md') return 12\n if (width === 'lg') return 18\n return 36\n}\n\nconst getPerPageOptions = (width) => {\n const options = [3, 6, 12]\n if (width === 'xs') return [12]\n if (width === 'sm') return [12]\n if (width === 'md') return options.map((v) => v * 4)\n return options.map((v) => v * 6)\n}\n\nexport const useAlbumsPerPage = (width) => {\n const perPage =\n useSelector(\n (state) => state?.admin.resources?.album?.list?.params?.perPage\n ) || getPerPage(width)\n\n return [perPage, getPerPageOptions(width)]\n}\n","// From https://overreacted.io/making-setinterval-declarative-with-react-hooks/\n\nimport { useEffect, useRef } from 'react'\n\nexport const useInterval = (callback, delay) => {\n const savedCallback = useRef()\n\n // Remember the latest callback.\n useEffect(() => {\n savedCallback.current = callback\n }, [callback])\n\n // Set up the interval.\n useEffect(() => {\n function tick() {\n savedCallback.current()\n }\n if (delay !== null) {\n let id = setInterval(tick, delay)\n return () => clearInterval(id)\n }\n }, [delay])\n}\n","import { useSelector } from 'react-redux'\nimport { useState } from 'react'\nimport { useRefresh, useDataProvider } from 'react-admin'\n\nexport const useResourceRefresh = (...visibleResources) => {\n const [lastTime, setLastTime] = useState(Date.now())\n const refresh = useRefresh()\n const dataProvider = useDataProvider()\n const refreshData = useSelector(\n (state) => state.activity?.refresh || { lastReceived: lastTime }\n )\n const { resources, lastReceived } = refreshData\n\n if (lastReceived <= lastTime) {\n return\n }\n setLastTime(lastReceived)\n\n if (\n resources &&\n (resources['*'] === '*' ||\n Object.values(resources).find((v) => v.find((v2) => v2 === '*')))\n ) {\n refresh()\n return\n }\n if (resources) {\n Object.keys(resources).forEach((r) => {\n if (visibleResources.length === 0 || visibleResources?.includes(r)) {\n if (resources[r]?.length > 0) {\n dataProvider.getMany(r, { ids: resources[r] })\n }\n }\n })\n }\n}\n","import { cloneElement, Children, isValidElement } from 'react'\n\nexport const isWritable = (ownerId) => {\n return (\n localStorage.getItem('userId') === ownerId ||\n localStorage.getItem('role') === 'admin'\n )\n}\n\nexport const isReadOnly = (ownerId) => {\n return !isWritable(ownerId)\n}\n\nexport const Writable = (props) => {\n const { record = {}, children } = props\n if (isWritable(record.ownerId)) {\n return Children.map(children, (child) =>\n isValidElement(child) ? cloneElement(child, props) : child\n )\n }\n return null\n}\n\nexport const isSmartPlaylist = (pls) => !!pls.rules\n\nexport const canChangeTracks = (pls) =>\n isWritable(pls.ownerId) && !isSmartPlaylist(pls)\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { sanitizeListRestProps } from 'react-admin'\nimport { DurationField, SongContextMenu, RatingField } from './index'\nimport { setTrack } from '../actions'\nimport { useDispatch } from 'react-redux'\nimport config from '../config'\n\nconst useStyles = makeStyles(\n {\n link: {\n textDecoration: 'none',\n color: 'inherit',\n },\n listItem: {\n padding: '10px',\n },\n title: {\n paddingRight: '10px',\n width: '80%',\n },\n secondary: {\n marginTop: '-3px',\n width: '96%',\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n },\n artist: {\n paddingRight: '30px',\n },\n timeStamp: {\n float: 'right',\n color: '#fff',\n fontWeight: '200',\n opacity: 0.6,\n fontSize: '12px',\n padding: '2px',\n },\n rightIcon: {\n top: '26px',\n },\n },\n { name: 'RaSongSimpleList' }\n)\n\nexport const SongSimpleList = ({\n basePath,\n className,\n classes: classesOverride,\n data,\n hasBulkActions,\n ids,\n loading,\n onToggleItem,\n selectedIds,\n total,\n ...rest\n}) => {\n const dispatch = useDispatch()\n const classes = useStyles({ classes: classesOverride })\n return (\n (loading || total > 0) && (\n \n {ids.map(\n (id) =>\n data[id] && (\n dispatch(setTrack(data[id]))}>\n \n {data[id].title}\n }\n secondary={\n <>\n \n \n {data[id].artist}\n \n \n \n \n \n {config.enableStarRating && (\n \n )}\n \n }\n />\n \n \n \n \n \n \n \n )\n )}\n \n )\n )\n}\n\nSongSimpleList.propTypes = {\n basePath: PropTypes.string,\n className: PropTypes.string,\n classes: PropTypes.object,\n data: PropTypes.object,\n hasBulkActions: PropTypes.bool.isRequired,\n ids: PropTypes.array,\n onToggleItem: PropTypes.func,\n selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,\n}\n\nSongSimpleList.defaultProps = {\n hasBulkActions: false,\n selectedIds: [],\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { sanitizeListRestProps } from 'react-admin'\nimport { ArtistContextMenu, RatingField } from './index'\nimport config from '../config'\n\nconst useStyles = makeStyles(\n {\n listItem: {\n padding: '10px',\n },\n title: {\n paddingRight: '10px',\n width: '80%',\n },\n rightIcon: {\n top: '26px',\n },\n },\n { name: 'RaArtistSimpleList' }\n)\n\nexport const ArtistSimpleList = ({\n linkType,\n className,\n classes: classesOverride,\n data,\n hasBulkActions,\n ids,\n loading,\n selectedIds,\n total,\n ...rest\n}) => {\n const classes = useStyles({ classes: classesOverride })\n return (\n (loading || total > 0) && (\n \n {ids.map(\n (id) =>\n data[id] && (\n linkType(id)}>\n \n \n
{data[id].name}
\n {config.enableStarRating && (\n \n )}\n \n }\n />\n \n \n \n \n \n
\n
\n )\n )}\n
\n )\n )\n}\n\nArtistSimpleList.propTypes = {\n className: PropTypes.string,\n classes: PropTypes.object,\n data: PropTypes.object,\n hasBulkActions: PropTypes.bool.isRequired,\n ids: PropTypes.array,\n selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,\n}\n\nArtistSimpleList.defaultProps = {\n hasBulkActions: false,\n selectedIds: [],\n}\n","import React, { useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport Rating from '@material-ui/lab/Rating'\nimport { makeStyles } from '@material-ui/core/styles'\nimport StarBorderIcon from '@material-ui/icons/StarBorder'\nimport clsx from 'clsx'\nimport { useRating } from './useRating'\nimport { useRecordContext } from 'react-admin'\n\nconst useStyles = makeStyles({\n rating: {\n color: (props) => props.color,\n visibility: (props) => (props.visible === false ? 'hidden' : 'inherit'),\n },\n show: {\n visibility: 'visible !important',\n },\n hide: {\n visibility: 'hidden',\n },\n})\n\nexport const RatingField = ({\n resource,\n visible,\n className,\n size,\n color,\n ...rest\n}) => {\n const record = useRecordContext(rest) || {}\n const [rate, rating] = useRating(resource, record)\n const classes = useStyles({ color, visible })\n\n const stopPropagation = (e) => {\n e.stopPropagation()\n }\n\n const handleRating = useCallback(\n (e, val) => {\n rate(val, e.target.name)\n },\n [rate]\n )\n\n return (\n stopPropagation(e)}>\n 0 ? classes.show : classes.hide\n )}\n value={rating}\n size={size}\n emptyIcon={}\n onChange={(e, newValue) => handleRating(e, newValue)}\n />\n \n )\n}\nRatingField.propTypes = {\n resource: PropTypes.string.isRequired,\n record: PropTypes.object,\n visible: PropTypes.bool,\n size: PropTypes.string,\n}\n\nRatingField.defaultProps = {\n visible: true,\n size: 'small',\n color: 'inherit',\n}\n","import { useState, useCallback, useEffect, useRef } from 'react'\nimport { useDataProvider, useNotify } from 'react-admin'\nimport subsonic from '../subsonic'\n\nexport const useRating = (resource, record) => {\n const [loading, setLoading] = useState(false)\n const notify = useNotify()\n const dataProvider = useDataProvider()\n const mountedRef = useRef(false)\n const rating = record.rating\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n const refreshRating = useCallback(() => {\n dataProvider\n .getOne(resource, { id: record.id })\n .then(() => {\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n .catch((e) => {\n console.log('Error encountered: ' + e)\n })\n }, [dataProvider, record, resource])\n\n const rate = (val, id) => {\n setLoading(true)\n subsonic\n .setRating(id, val)\n .then(refreshRating)\n .catch((e) => {\n console.log('Error setting star rating: ', e)\n notify('ra.page.error', 'warning')\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n }\n\n return [rate, rating, loading]\n}\n","import React, { useState, useEffect } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { setOmittedFields, setToggleableFields } from '../actions'\n\n// TODO Refactor\nexport const useSelectedFields = ({\n resource,\n columns,\n omittedColumns = [],\n defaultOff = [],\n}) => {\n const dispatch = useDispatch()\n const resourceFields = useSelector(\n (state) => state.settings.toggleableFields\n )?.[resource]\n const omittedFields = useSelector((state) => state.settings.omittedFields)?.[\n resource\n ]\n\n const [filteredComponents, setFilteredComponents] = useState([])\n\n useEffect(() => {\n if (\n !resourceFields ||\n Object.keys(resourceFields).length !== Object.keys(columns).length ||\n !Object.keys(columns).every((c) => c in resourceFields)\n ) {\n const obj = {}\n for (const key of Object.keys(columns)) {\n obj[key] = !defaultOff.includes(key)\n }\n dispatch(setToggleableFields({ [resource]: obj }))\n }\n if (!omittedFields) {\n dispatch(setOmittedFields({ [resource]: omittedColumns }))\n }\n }, [\n columns,\n defaultOff,\n dispatch,\n omittedColumns,\n omittedFields,\n resource,\n resourceFields,\n ])\n\n useEffect(() => {\n if (resourceFields) {\n const filtered = []\n const omitted = omittedColumns\n for (const [key, val] of Object.entries(columns)) {\n if (!val) omitted.push(key)\n else if (resourceFields[key]) filtered.push(val)\n }\n if (filteredComponents.length !== filtered.length)\n setFilteredComponents(filtered)\n if (omittedFields.length !== omitted.length)\n dispatch(setOmittedFields({ [resource]: omitted }))\n }\n }, [\n resourceFields,\n columns,\n dispatch,\n omittedColumns,\n omittedFields,\n resource,\n filteredComponents.length,\n ])\n\n return React.Children.toArray(filteredComponents)\n}\n\nuseSelectedFields.propTypes = {\n resource: PropTypes.string,\n columns: PropTypes.object,\n omittedColumns: PropTypes.arrayOf(PropTypes.string),\n defaultOff: PropTypes.arrayOf(PropTypes.string),\n}\n\nexport const useSetToggleableFields = (\n resource,\n toggleableColumns,\n defaultOff = []\n) => {\n const current = useSelector((state) => state.settings.toggleableFields)?.album\n const dispatch = useDispatch()\n useEffect(() => {\n if (!current) {\n dispatch(\n setToggleableFields({\n [resource]: toggleableColumns.reduce((acc, cur) => {\n return {\n ...acc,\n ...{ [cur]: true },\n }\n }, {}),\n })\n )\n dispatch(setOmittedFields({ [resource]: defaultOff }))\n }\n }, [resource, toggleableColumns, dispatch, current, defaultOff])\n}\n\nuseSetToggleableFields.propTypes = {\n resource: PropTypes.string,\n toggleableColumns: PropTypes.arrayOf(PropTypes.string),\n defaultOff: PropTypes.arrayOf(PropTypes.string),\n}\n","import React, { useState } from 'react'\nimport PropTypes from 'prop-types'\nimport IconButton from '@material-ui/core/IconButton'\nimport Menu from '@material-ui/core/Menu'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport { makeStyles, Typography } from '@material-ui/core'\nimport MoreVertIcon from '@material-ui/icons/MoreVert'\nimport Checkbox from '@material-ui/core/Checkbox'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useTranslate } from 'react-admin'\nimport { setToggleableFields } from '../actions'\n\nconst useStyles = makeStyles({\n menuIcon: {\n position: 'relative',\n top: '-0.5em',\n },\n menu: {\n width: '24ch',\n },\n columns: {\n maxHeight: '21rem',\n overflow: 'auto',\n },\n title: {\n margin: '1rem',\n },\n})\n\nexport const ToggleFieldsMenu = ({\n resource,\n topbarComponent: TopBarComponent,\n}) => {\n const [anchorEl, setAnchorEl] = useState(null)\n const dispatch = useDispatch()\n const translate = useTranslate()\n const toggleableColumns = useSelector(\n (state) => state.settings.toggleableFields[resource]\n )\n const omittedColumns =\n useSelector((state) => state.settings.omittedFields[resource]) || []\n\n const classes = useStyles()\n const open = Boolean(anchorEl)\n\n const handleOpen = (event) => {\n setAnchorEl(event.currentTarget)\n }\n const handleClose = () => {\n setAnchorEl(null)\n }\n\n const handleClick = (selectedColumn) => {\n dispatch(\n setToggleableFields({\n [resource]: {\n ...toggleableColumns,\n [selectedColumn]: !toggleableColumns[selectedColumn],\n },\n })\n )\n }\n\n return (\n
\n \n \n \n \n {TopBarComponent && }\n {toggleableColumns ? (\n
\n \n {translate('ra.toggleFieldsMenu.columnsToDisplay')}\n \n
\n {Object.entries(toggleableColumns).map(([key, val]) =>\n !omittedColumns.includes(key) ? (\n handleClick(key)}>\n \n {translate(`resources.${resource}.fields.${key}`)}\n \n ) : null\n )}\n
\n
\n ) : null}\n \n
\n )\n}\n\nToggleFieldsMenu.propTypes = {\n resource: PropTypes.string.isRequired,\n topbarComponent: PropTypes.elementType,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Chip from '@material-ui/core/Chip'\nimport config from '../config'\nimport { makeStyles } from '@material-ui/core'\nimport clsx from 'clsx'\n\nconst llFormats = new Set(config.losslessFormats.split(','))\nconst placeholder = 'N/A'\n\nconst useStyle = makeStyles(\n (theme) => ({\n chip: {\n transform: 'scale(0.8)',\n },\n }),\n {\n name: 'NDQualityInfo',\n }\n)\n\nexport const QualityInfo = ({ record, size, className }) => {\n const classes = useStyle()\n let { suffix, bitRate } = record\n let info = placeholder\n\n if (suffix) {\n suffix = suffix.toUpperCase()\n info = suffix\n if (!llFormats.has(suffix)) {\n info += ' ' + bitRate\n }\n }\n\n return (\n \n )\n}\n\nQualityInfo.propTypes = {\n record: PropTypes.object.isRequired,\n size: PropTypes.string,\n className: PropTypes.string,\n}\n\nQualityInfo.defaultProps = {\n record: {},\n size: 'small',\n}\n","import React from 'react'\nimport TextField from '@material-ui/core/TextField'\nimport Checkbox from '@material-ui/core/Checkbox'\nimport CheckBoxIcon from '@material-ui/icons/CheckBox'\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'\nimport Autocomplete, {\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete'\nimport { useGetList, useTranslate } from 'react-admin'\nimport PropTypes from 'prop-types'\nimport { isWritable } from '../common'\nimport { makeStyles } from '@material-ui/core'\n\nconst filter = createFilterOptions()\n\nconst useStyles = makeStyles({\n root: { width: '100%' },\n checkbox: { marginRight: 8 },\n})\n\nexport const SelectPlaylistInput = ({ onChange }) => {\n const classes = useStyles()\n const translate = useTranslate()\n const { ids, data } = useGetList(\n 'playlist',\n { page: 1, perPage: -1 },\n { field: 'name', order: 'ASC' },\n {}\n )\n\n const options =\n ids &&\n ids.map((id) => data[id]).filter((option) => isWritable(option.ownerId))\n\n const handleOnChange = (event, newValue) => {\n let newState = []\n if (newValue && newValue.length) {\n newValue.forEach((playlistObject) => {\n if (playlistObject.inputValue) {\n newState.push({\n name: playlistObject.inputValue,\n })\n } else if (typeof playlistObject === 'string') {\n newState.push({\n name: playlistObject,\n })\n } else {\n newState.push(playlistObject)\n }\n })\n }\n onChange(newState)\n }\n\n const icon = \n const checkedIcon = \n\n return (\n {\n const filtered = filter(options, params)\n\n // Suggest the creation of a new value\n if (params.inputValue !== '') {\n filtered.push({\n inputValue: params.inputValue,\n name: translate('resources.playlist.actions.addNewPlaylist', {\n name: params.inputValue,\n }),\n })\n }\n\n return filtered\n }}\n clearOnBlur\n handleHomeEndKeys\n openOnFocus\n selectOnFocus\n id=\"select-playlist-input\"\n options={options}\n getOptionLabel={(option) => {\n // Value selected with enter, right from the input\n if (typeof option === 'string') {\n return option\n }\n // Add \"xxx\" option created dynamically\n if (option.inputValue) {\n return option.inputValue\n }\n // Regular option\n return option.name\n }}\n renderOption={(option, { selected }) => (\n \n \n {option.name}\n \n )}\n className={classes.root}\n freeSolo\n renderInput={(params) => (\n \n )}\n />\n )\n}\n\nSelectPlaylistInput.propTypes = {\n onChange: PropTypes.func.isRequired,\n}\n","import React from 'react'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\n\nimport { useTranslate } from 'react-admin'\n\nconst DuplicateSongDialog = ({\n open,\n handleClickClose,\n handleSubmit,\n handleSkip,\n}) => {\n const translate = useTranslate()\n\n return (\n \n \n {translate('resources.playlist.message.duplicate_song')}\n \n \n {translate('resources.playlist.message.song_exist')}\n \n \n \n \n \n \n \n )\n}\n\nexport default DuplicateSongDialog\n","import React, { useState } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport {\n useDataProvider,\n useNotify,\n useRefresh,\n useTranslate,\n} from 'react-admin'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\nimport {\n closeAddToPlaylist,\n closeDuplicateSongDialog,\n openDuplicateSongWarning,\n} from '../actions'\nimport { SelectPlaylistInput } from './SelectPlaylistInput'\nimport DuplicateSongDialog from './DuplicateSongDialog'\n\nexport const AddToPlaylistDialog = () => {\n const { open, selectedIds, onSuccess, duplicateSong, duplicateIds } =\n useSelector((state) => state.addToPlaylistDialog)\n const dispatch = useDispatch()\n const translate = useTranslate()\n const notify = useNotify()\n const refresh = useRefresh()\n const [value, setValue] = useState({})\n const [check, setCheck] = useState(false)\n const dataProvider = useDataProvider()\n const createAndAddToPlaylist = (playlistObject) => {\n dataProvider\n .create('playlist', {\n data: { name: playlistObject.name },\n })\n .then((res) => {\n addToPlaylist(res.data.id)\n })\n .catch((error) => notify(`Error: ${error.message}`, 'warning'))\n }\n\n const addToPlaylist = (playlistId, distinctIds) => {\n const trackIds = Array.isArray(distinctIds) ? distinctIds : selectedIds\n dataProvider\n .create('playlistTrack', {\n data: { ids: trackIds },\n filter: { playlist_id: playlistId },\n })\n .then(() => {\n const len = trackIds.length\n notify('message.songsAddedToPlaylist', 'info', { smart_count: len })\n onSuccess && onSuccess(value, len)\n refresh()\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n }\n\n const checkDuplicateSong = (playlistObject) => {\n dataProvider\n .getOne('playlist', { id: playlistObject.id })\n .then((res) => {\n const tracks = res.data.tracks\n if (tracks) {\n const dupSng = tracks.filter((song) =>\n selectedIds.some((id) => id === song.id)\n )\n\n if (dupSng.length) {\n const dupIds = dupSng.map((song) => song.id)\n dispatch(openDuplicateSongWarning(dupIds))\n }\n }\n setCheck(true)\n })\n .catch((error) => {\n console.error(error)\n notify('ra.page.error', 'warning')\n })\n }\n\n const handleSubmit = (e) => {\n value.forEach((playlistObject) => {\n if (playlistObject.id) {\n addToPlaylist(playlistObject.id, playlistObject.distinctIds)\n } else {\n createAndAddToPlaylist(playlistObject)\n }\n })\n setCheck(false)\n setValue({})\n dispatch(closeAddToPlaylist())\n e.stopPropagation()\n }\n\n const handleClickClose = (e) => {\n setCheck(false)\n setValue({})\n dispatch(closeAddToPlaylist())\n e.stopPropagation()\n }\n\n const handleChange = (pls) => {\n if (!value.length || pls.length > value.length) {\n let newlyAdded = pls.slice(-1).pop()\n if (newlyAdded.id) {\n setCheck(false)\n checkDuplicateSong(newlyAdded)\n } else setCheck(true)\n } else if (pls.length === 0) setCheck(false)\n setValue(pls)\n }\n\n const handleDuplicateClose = () => {\n dispatch(closeDuplicateSongDialog())\n }\n const handleDuplicateSubmit = () => {\n dispatch(closeDuplicateSongDialog())\n }\n const handleSkip = () => {\n const distinctSongs = selectedIds.filter(\n (id) => duplicateIds.indexOf(id) < 0\n )\n value.slice(-1).pop().distinctIds = distinctSongs\n dispatch(closeDuplicateSongDialog())\n }\n\n return (\n <>\n \n \n {translate('resources.playlist.actions.selectPlaylist')}\n \n \n \n \n \n \n \n {translate('ra.action.add')}\n \n \n \n \n \n )\n}\n","import config from './config'\nconst keyMap = {\n SHOW_HELP: { name: 'show_help', sequence: 'shift+?', group: 'Global' },\n TOGGLE_MENU: { name: 'toggle_menu', sequence: 'm', group: 'Global' },\n TOGGLE_PLAY: { name: 'toggle_play', sequence: 'space', group: 'Player' },\n PREV_SONG: { name: 'prev_song', sequence: 'left', group: 'Player' },\n NEXT_SONG: { name: 'next_song', sequence: 'right', group: 'Player' },\n VOL_UP: { name: 'vol_up', sequence: '=', group: 'Player' },\n VOL_DOWN: { name: 'vol_down', sequence: '-', group: 'Player' },\n ...(config.enableFavourites && {\n TOGGLE_LOVE: { name: 'toggle_love', sequence: 'l', group: 'Player' },\n }),\n}\n\nexport { keyMap }\n","import React, { useCallback, useState } from 'react'\nimport ReactDOM from 'react-dom'\nimport { Chip, Dialog } from '@material-ui/core'\nimport { getApplicationKeyMap, GlobalHotKeys } from 'react-hotkeys'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport Paper from '@material-ui/core/Paper'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableRow from '@material-ui/core/TableRow'\nimport TableCell from '@material-ui/core/TableCell'\nimport { useTranslate } from 'react-admin'\nimport inflection from 'inflection'\nimport { keyMap } from '../hotkeys'\nimport { DialogTitle } from './DialogTitle'\nimport { DialogContent } from './DialogContent'\n\nconst HelpTable = (props) => {\n const keyMap = getApplicationKeyMap()\n const translate = useTranslate()\n return ReactDOM.createPortal(\n \n \n {translate('help.title')}\n \n \n \n \n \n {Object.keys(keyMap).map((key) => {\n const { sequences, name } = keyMap[key]\n const description = translate(`help.hotkeys.${name}`, {\n _: inflection.humanize(name),\n })\n return (\n \n \n {description}\n \n \n {sequences.map(({ sequence }) => (\n {sequence}}\n size=\"small\"\n variant={'outlined'}\n key={sequence}\n />\n ))}\n \n \n )\n })}\n \n
\n
\n
\n
,\n document.body\n )\n}\n\nexport const HelpDialog = (props) => {\n const [open, setOpen] = useState(false)\n\n const handleClickClose = (e) => {\n setOpen(false)\n e.stopPropagation()\n }\n\n const handlers = {\n SHOW_HELP: useCallback(() => setOpen(true), [setOpen]),\n }\n\n return (\n <>\n \n \n \n )\n}\n","import React, { createRef, useCallback, useState } from 'react'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n LinearProgress,\n Link,\n TextField,\n} from '@material-ui/core'\nimport { useNotify, useTranslate } from 'react-admin'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { closeListenBrainzTokenDialog } from '../actions'\nimport { httpClient } from '../dataProvider'\n\nexport const ListenBrainzTokenDialog = ({ setLinked }) => {\n const dispatch = useDispatch()\n const notify = useNotify()\n const translate = useTranslate()\n const { open } = useSelector((state) => state.listenBrainzTokenDialog)\n const [token, setToken] = useState('')\n const [checking, setChecking] = useState(false)\n const inputRef = createRef()\n\n const handleChange = (event) => {\n setToken(event.target.value)\n }\n\n const handleLinkClick = (event) => {\n inputRef.current.focus()\n }\n\n const handleSave = useCallback(\n (event) => {\n setChecking(true)\n httpClient('/api/listenbrainz/link', {\n method: 'PUT',\n body: JSON.stringify({ token: token }),\n })\n .then((response) => {\n notify('message.listenBrainzLinkSuccess', 'success', {\n user: response.json.user,\n })\n setLinked(true)\n setToken('')\n })\n .catch((error) => {\n notify('message.listenBrainzLinkFailure', 'warning', {\n error: error.body?.error || error.message,\n })\n setLinked(false)\n })\n .finally(() => {\n setChecking(false)\n dispatch(closeListenBrainzTokenDialog())\n event.stopPropagation()\n })\n },\n [dispatch, notify, setLinked, token]\n )\n\n const handleClickClose = (event) => {\n if (!checking) {\n dispatch(closeListenBrainzTokenDialog())\n event.stopPropagation()\n }\n }\n\n const handleKeyPress = useCallback(\n (event) => {\n if (event.key === 'Enter' && token !== '') {\n handleSave(event)\n }\n },\n [token, handleSave]\n )\n\n return (\n <>\n \n \n ListenBrainz\n \n \n \n {translate('resources.user.message.listenBrainzToken')}{' '}\n \n {translate('resources.user.message.clickHereForToken')}\n \n \n \n {checking && }\n \n \n \n {translate('ra.action.cancel')}\n \n \n {translate('ra.action.save')}\n \n \n \n \n )\n}\n","import React, { useCallback } from 'react'\nimport {\n MenuItemLink,\n useDataProvider,\n useNotify,\n useQueryWithStore,\n} from 'react-admin'\nimport { useHistory } from 'react-router-dom'\nimport QueueMusicIcon from '@material-ui/icons/QueueMusic'\nimport { Typography } from '@material-ui/core'\nimport QueueMusicOutlinedIcon from '@material-ui/icons/QueueMusicOutlined'\nimport { BiCog } from 'react-icons/all'\nimport { useDrop } from 'react-dnd'\nimport SubMenu from './SubMenu'\nimport { canChangeTracks } from '../common'\nimport { DraggableTypes, MAX_SIDEBAR_PLAYLISTS } from '../consts'\n\nconst PlaylistMenuItemLink = ({ pls, sidebarIsOpen }) => {\n const dataProvider = useDataProvider()\n const notify = useNotify()\n\n const [, dropRef] = useDrop(() => ({\n accept: canChangeTracks(pls) ? DraggableTypes.ALL : [],\n drop: (item) =>\n dataProvider\n .addToPlaylist(pls.id, item)\n .then((res) => {\n notify('message.songsAddedToPlaylist', 'info', {\n smart_count: res.data?.added,\n })\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n }),\n }))\n\n return (\n \n {pls.name}\n \n }\n sidebarIsOpen={sidebarIsOpen}\n dense={false}\n />\n )\n}\n\nconst PlaylistsSubMenu = ({ state, setState, sidebarIsOpen, dense }) => {\n const history = useHistory()\n const { data, loaded } = useQueryWithStore({\n type: 'getList',\n resource: 'playlist',\n payload: {\n pagination: {\n page: 0,\n perPage: MAX_SIDEBAR_PLAYLISTS,\n },\n sort: { field: 'name' },\n },\n })\n\n const handleToggle = (menu) => {\n setState((state) => ({ ...state, [menu]: !state[menu] }))\n }\n\n const renderPlaylistMenuItemLink = (pls) => (\n \n )\n\n const userId = localStorage.getItem('userId')\n const myPlaylists = []\n const sharedPlaylists = []\n\n if (loaded && data) {\n const allPlaylists = Object.keys(data).map((id) => data[id])\n\n allPlaylists.forEach((pls) => {\n if (userId === pls.ownerId) {\n myPlaylists.push(pls)\n } else {\n sharedPlaylists.push(pls)\n }\n })\n }\n\n const onPlaylistConfig = useCallback(\n () => history.push('/playlist'),\n [history]\n )\n\n return (\n <>\n handleToggle('menuPlaylists')}\n isOpen={state.menuPlaylists}\n sidebarIsOpen={sidebarIsOpen}\n name={'menu.playlists'}\n icon={}\n dense={dense}\n actionIcon={}\n onAction={onPlaylistConfig}\n >\n {myPlaylists.map(renderPlaylistMenuItemLink)}\n \n {sharedPlaylists?.length > 0 && (\n handleToggle('menuSharedPlaylists')}\n isOpen={state.menuSharedPlaylists}\n sidebarIsOpen={sidebarIsOpen}\n name={'menu.sharedPlaylists'}\n icon={}\n dense={dense}\n >\n {sharedPlaylists.map(renderPlaylistMenuItemLink)}\n \n )}\n \n )\n}\n\nexport default PlaylistsSubMenu\n","import React, { useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { Divider, makeStyles } from '@material-ui/core'\nimport clsx from 'clsx'\nimport { useTranslate, MenuItemLink, getResources } from 'react-admin'\nimport { withRouter } from 'react-router-dom'\nimport ViewListIcon from '@material-ui/icons/ViewList'\nimport AlbumIcon from '@material-ui/icons/Album'\nimport SubMenu from './SubMenu'\nimport inflection from 'inflection'\nimport albumLists from '../album/albumLists'\nimport { HelpDialog } from '../dialogs'\nimport PlaylistsSubMenu from './PlaylistsSubMenu'\nimport config from '../config'\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n transition: theme.transitions.create('width', {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n paddingBottom: (props) => (props.addPadding ? '80px' : '20px'),\n },\n open: {\n width: 240,\n },\n closed: {\n width: 55,\n },\n active: {\n color: theme.palette.text.primary,\n fontWeight: 'bold',\n },\n}))\n\nconst translatedResourceName = (resource, translate) =>\n translate(`resources.${resource.name}.name`, {\n smart_count: 2,\n _:\n resource.options && resource.options.label\n ? translate(resource.options.label, {\n smart_count: 2,\n _: resource.options.label,\n })\n : inflection.humanize(inflection.pluralize(resource.name)),\n })\n\nconst Menu = ({ dense = false }) => {\n const open = useSelector((state) => state.admin.ui.sidebarOpen)\n const translate = useTranslate()\n const queue = useSelector((state) => state.player?.queue)\n const classes = useStyles({ addPadding: queue.length > 0 })\n const resources = useSelector(getResources)\n\n // TODO State is not persisted in mobile when you close the sidebar menu. Move to redux?\n const [state, setState] = useState({\n menuAlbumList: true,\n menuPlaylists: true,\n menuSharedPlaylists: true,\n })\n\n const handleToggle = (menu) => {\n setState((state) => ({ ...state, [menu]: !state[menu] }))\n }\n\n const renderResourceMenuItemLink = (resource) => (\n }\n sidebarIsOpen={open}\n dense={dense}\n />\n )\n\n const renderAlbumMenuItemLink = (type, al) => {\n const resource = resources.find((r) => r.name === 'album')\n if (!resource) {\n return null\n }\n\n const albumListAddress = `/album/${type}`\n\n const name = translate(`resources.album.lists.${type || 'default'}`, {\n _: translatedResourceName(resource, translate),\n })\n\n return (\n }\n sidebarIsOpen={open}\n dense={dense}\n exact\n />\n )\n }\n\n const subItems = (subMenu) => (resource) =>\n resource.hasList && resource.options && resource.options.subMenu === subMenu\n\n return (\n \n handleToggle('menuAlbumList')}\n isOpen={state.menuAlbumList}\n sidebarIsOpen={open}\n name=\"menu.albumList\"\n icon={}\n dense={dense}\n >\n {Object.keys(albumLists).map((type) =>\n renderAlbumMenuItemLink(type, albumLists[type])\n )}\n \n {resources.filter(subItems(undefined)).map(renderResourceMenuItemLink)}\n {config.devSidebarPlaylists && open ? (\n <>\n \n \n \n ) : (\n resources.filter(subItems('playlist')).map(renderResourceMenuItemLink)\n )}\n \n \n )\n}\n\nexport default withRouter(Menu)\n","import React, { forwardRef } from 'react'\nimport { MenuItemLink, useTranslate } from 'react-admin'\nimport { makeStyles } from '@material-ui/core'\nimport TuneIcon from '@material-ui/icons/Tune'\n\nconst useStyles = makeStyles((theme) => ({\n menuItem: {\n color: theme.palette.text.secondary,\n },\n}))\n\nconst PersonalMenu = forwardRef(({ onClick, sidebarIsOpen, dense }, ref) => {\n const translate = useTranslate()\n const classes = useStyles()\n return (\n }\n onClick={onClick}\n className={classes.menuItem}\n sidebarIsOpen={sidebarIsOpen}\n dense={dense}\n />\n )\n})\n\nexport default PersonalMenu\n","import React, { useState, useEffect } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useNotify, useTranslate } from 'react-admin'\nimport {\n Popover,\n Badge,\n CircularProgress,\n IconButton,\n makeStyles,\n Tooltip,\n Card,\n CardContent,\n CardActions,\n Divider,\n Box,\n} from '@material-ui/core'\nimport { FiActivity } from 'react-icons/fi'\nimport { BiError } from 'react-icons/bi'\nimport { VscSync } from 'react-icons/vsc'\nimport { GiMagnifyingGlass } from 'react-icons/gi'\nimport subsonic from '../subsonic'\nimport { scanStatusUpdate } from '../actions'\nimport { useInterval } from '../common'\nimport { formatDuration } from '../utils'\nimport config from '../config'\n\nconst useStyles = makeStyles((theme) => ({\n wrapper: {\n position: 'relative',\n color: (props) => (props.up ? null : 'orange'),\n },\n progress: {\n color: theme.palette.primary.light,\n position: 'absolute',\n top: 10,\n left: 10,\n zIndex: 1,\n },\n button: {\n color: 'inherit',\n zIndex: 2,\n },\n counterStatus: {\n minWidth: '15em',\n },\n}))\n\nconst getUptime = (serverStart) =>\n formatDuration((Date.now() - serverStart.startTime) / 1000)\n\nconst Uptime = () => {\n const serverStart = useSelector((state) => state.activity.serverStart)\n const [uptime, setUptime] = useState(getUptime(serverStart))\n useInterval(() => {\n setUptime(getUptime(serverStart))\n }, 1000)\n return {uptime}\n}\n\nconst ActivityPanel = () => {\n const serverStart = useSelector((state) => state.activity.serverStart)\n const up = serverStart.startTime\n const classes = useStyles({ up })\n const translate = useTranslate()\n const notify = useNotify()\n const [anchorEl, setAnchorEl] = useState(null)\n const open = Boolean(anchorEl)\n const dispatch = useDispatch()\n const scanStatus = useSelector((state) => state.activity.scanStatus)\n\n const handleMenuOpen = (event) => setAnchorEl(event.currentTarget)\n const handleMenuClose = () => setAnchorEl(null)\n const triggerScan = (full) => () => subsonic.startScan({ fullScan: full })\n\n // Get updated status on component mount\n useEffect(() => {\n subsonic\n .getScanStatus()\n .then((resp) => resp.json['subsonic-response'])\n .then((data) => {\n if (data.status === 'ok') {\n dispatch(scanStatusUpdate(data.scanStatus))\n }\n })\n }, [dispatch])\n\n useEffect(() => {\n if (serverStart.version && serverStart.version !== config.version) {\n notify('ra.notification.new_version', 'info', {}, false, 604800000 * 50)\n }\n }, [serverStart, notify])\n\n return (\n
\n \n \n \n {up ? : }\n \n \n \n {scanStatus.scanning && (\n \n )}\n \n \n \n \n \n {translate('activity.serverUptime')}:\n \n \n {up ? : translate('activity.serverDown')}\n \n \n \n \n \n \n \n {translate('activity.totalScanned')}:\n \n \n {scanStatus.folderCount || '-'}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n )\n}\n\nexport default ActivityPanel\n","import * as React from 'react'\nimport { Children, cloneElement, isValidElement, useState } from 'react'\nimport PropTypes from 'prop-types'\nimport { useTranslate, useGetIdentity } from 'react-admin'\nimport {\n Tooltip,\n IconButton,\n Popover,\n MenuList,\n Avatar,\n Card,\n CardContent,\n Divider,\n Typography,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport AccountCircle from '@material-ui/icons/AccountCircle'\nimport config from '../config'\n\nconst useStyles = makeStyles((theme) => ({\n user: {},\n avatar: {\n width: theme.spacing(4),\n height: theme.spacing(4),\n },\n username: {\n maxWidth: '11em',\n marginTop: '-0.7em',\n marginBottom: '-1em',\n },\n usernameWrap: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n}))\n\nconst UserMenu = (props) => {\n const [anchorEl, setAnchorEl] = useState(null)\n const translate = useTranslate()\n const { loaded, identity } = useGetIdentity()\n const classes = useStyles(props)\n\n const { children, label, icon, logout } = props\n if (!logout && !children) return null\n const open = Boolean(anchorEl)\n\n const handleMenu = (event) => setAnchorEl(event.currentTarget)\n const handleClose = () => setAnchorEl(null)\n\n return (\n
\n \n \n {loaded && identity.avatar ? (\n \n ) : (\n icon\n )}\n \n \n \n \n {loaded && (\n \n \n {identity.fullName}\n \n \n )}\n \n {Children.map(children, (menuItem) =>\n isValidElement(menuItem)\n ? cloneElement(menuItem, {\n onClick: handleClose,\n })\n : null\n )}\n {!config.auth && logout}\n \n \n
\n )\n}\n\nUserMenu.propTypes = {\n children: PropTypes.node,\n label: PropTypes.string.isRequired,\n logout: PropTypes.element,\n}\n\nUserMenu.defaultProps = {\n label: 'menu.settings',\n icon: ,\n}\n\nexport default UserMenu\n","import React, { createElement, forwardRef, Fragment } from 'react'\nimport {\n AppBar as RAAppBar,\n MenuItemLink,\n useTranslate,\n usePermissions,\n getResources,\n} from 'react-admin'\nimport { useSelector } from 'react-redux'\nimport { makeStyles, MenuItem, ListItemIcon, Divider } from '@material-ui/core'\nimport ViewListIcon from '@material-ui/icons/ViewList'\nimport InfoIcon from '@material-ui/icons/Info'\nimport PersonIcon from '@material-ui/icons/Person'\nimport SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount'\nimport { AboutDialog } from '../dialogs'\nimport PersonalMenu from './PersonalMenu'\nimport ActivityPanel from './ActivityPanel'\nimport UserMenu from './UserMenu'\nimport config from '../config'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n color: theme.palette.text.secondary,\n },\n active: {\n color: theme.palette.text.primary,\n },\n icon: { minWidth: theme.spacing(5) },\n }),\n {\n name: 'NDAppBar',\n }\n)\n\nconst AboutMenuItem = forwardRef(({ onClick, ...rest }, ref) => {\n const classes = useStyles(rest)\n const translate = useTranslate()\n const [open, setOpen] = React.useState(false)\n\n const handleOpen = () => {\n setOpen(true)\n }\n const handleClose = () => {\n onClick && onClick()\n setOpen(false)\n }\n const label = translate('menu.about')\n return (\n <>\n \n \n \n \n {label}\n \n \n \n )\n})\n\nconst settingsResources = (resource) =>\n resource.name !== 'user' &&\n resource.hasList &&\n resource.options &&\n resource.options.subMenu === 'settings'\n\nconst CustomUserMenu = ({ onClick, ...rest }) => {\n const translate = useTranslate()\n const resources = useSelector(getResources)\n const classes = useStyles(rest)\n const { permissions } = usePermissions()\n\n const resourceDefinition = (resourceName) =>\n resources.find((r) => r?.name === resourceName)\n\n const renderUserMenuItemLink = () => {\n const userResource = resourceDefinition('user')\n if (!userResource) {\n return null\n }\n if (permissions !== 'admin') {\n if (!config.enableUserEditing) {\n return null\n }\n userResource.icon = PersonIcon\n } else {\n userResource.icon = SupervisorAccountIcon\n }\n return renderSettingsMenuItemLink(\n userResource,\n permissions !== 'admin' ? localStorage.getItem('userId') : null\n )\n }\n\n const renderSettingsMenuItemLink = (resource, id) => {\n const label = translate(`resources.${resource.name}.name`, {\n smart_count: id ? 1 : 2,\n })\n const link = id ? `/${resource.name}/${id}` : `/${resource.name}`\n return (\n \n }\n onClick={onClick}\n sidebarIsOpen={true}\n />\n )\n }\n\n return (\n <>\n {config.devActivityPanel && permissions === 'admin' && }\n \n \n \n {renderUserMenuItemLink()}\n {resources\n .filter(settingsResources)\n .map((r) => renderSettingsMenuItemLink(r))}\n \n \n \n \n )\n}\n\nconst AppBar = (props) => (\n } />\n)\n\nexport default AppBar\n","import React, { useCallback } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { Layout as RALayout, toggleSidebar } from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { HotKeys } from 'react-hotkeys'\nimport { HTML5Backend } from 'react-dnd-html5-backend'\nimport { DndProvider } from 'react-dnd'\nimport Menu from './Menu'\nimport AppBar from './AppBar'\nimport Notification from './Notification'\nimport useCurrentTheme from '../themes/useCurrentTheme'\n\nconst useStyles = makeStyles({\n root: { paddingBottom: (props) => (props.addPadding ? '80px' : 0) },\n})\n\nconst Layout = (props) => {\n const theme = useCurrentTheme()\n const queue = useSelector((state) => state.player?.queue)\n const classes = useStyles({ addPadding: queue.length > 0 })\n const dispatch = useDispatch()\n\n const keyHandlers = {\n TOGGLE_MENU: useCallback(() => dispatch(toggleSidebar()), [dispatch]),\n }\n\n return (\n \n \n \n \n \n )\n}\n\nexport default Layout\n","import React from 'react'\nimport { Datagrid, TextField } from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { SimpleList, List } from '../common'\nimport config from '../config'\n\nconst TranscodingList = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n return (\n \n {isXsmall ? (\n r.name}\n secondaryText={(r) => `format: ${r.targetFormat}`}\n tertiaryText={(r) => r.defaultBitRate}\n />\n ) : (\n \n \n \n \n \n \n )}\n \n )\n}\n\nexport default TranscodingList\n","import React from 'react'\nimport { Card, CardContent, Typography, Box } from '@material-ui/core'\nimport { useTranslate } from 'react-admin'\n\nexport const Interpolate = ({ message, field, children }) => {\n const split = message.split(`%{${field}}`)\n return (\n \n {split[0]}\n {children}\n {split[1]}\n \n )\n}\nexport const TranscodingNote = ({ message }) => {\n const translate = useTranslate()\n return (\n \n \n \n \n {translate('message.note')}:\n {' '}\n \n \n ND_ENABLETRANSCODINGCONFIG=true\n \n \n \n \n \n )\n}\n","import React from 'react'\nimport {\n Edit,\n required,\n SelectInput,\n SimpleForm,\n TextInput,\n useTranslate,\n} from 'react-admin'\nimport { Title } from '../common'\nimport { TranscodingNote } from './TranscodingNote'\n\nconst TranscodingTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.transcoding.name', {\n smart_count: 1,\n })\n return \n}\n\nconst TranscodingEdit = (props) => {\n return (\n <>\n <TranscodingNote message={'message.transcodingEnabled'} />\n\n <Edit title={<TranscodingTitle />} {...props}>\n <SimpleForm variant={'outlined'}>\n <TextInput source=\"name\" validate={[required()]} />\n <TextInput source=\"targetFormat\" validate={[required()]} />\n <SelectInput\n source=\"defaultBitRate\"\n choices={[\n { id: 32, name: '32' },\n { id: 48, name: '48' },\n { id: 64, name: '64' },\n { id: 80, name: '80' },\n { id: 96, name: '96' },\n { id: 112, name: '112' },\n { id: 128, name: '128' },\n { id: 160, name: '160' },\n { id: 192, name: '192' },\n { id: 256, name: '256' },\n { id: 320, name: '320' },\n ]}\n />\n <TextInput source=\"command\" fullWidth validate={[required()]} />\n </SimpleForm>\n </Edit>\n </>\n )\n}\n\nexport default TranscodingEdit\n","import React from 'react'\nimport {\n TextInput,\n SelectInput,\n Create,\n required,\n SimpleForm,\n useTranslate,\n} from 'react-admin'\nimport { Title } from '../common'\n\nconst TranscodingTitle = () => {\n const translate = useTranslate()\n const resourceName = translate('resources.transcoding.name', {\n smart_count: 1,\n })\n const title = translate('ra.page.create', {\n name: `${resourceName}`,\n })\n return <Title subTitle={title} />\n}\n\nconst TranscodingCreate = (props) => (\n <Create title={<TranscodingTitle />} {...props}>\n <SimpleForm variant={'outlined'}>\n <TextInput source=\"name\" validate={[required()]} />\n <TextInput source=\"targetFormat\" validate={[required()]} />\n <SelectInput\n source=\"defaultBitRate\"\n choices={[\n { id: 32, name: '32' },\n { id: 48, name: '48' },\n { id: 64, name: '64' },\n { id: 80, name: '80' },\n { id: 96, name: '96' },\n { id: 112, name: '112' },\n { id: 128, name: '128' },\n { id: 160, name: '160' },\n { id: 192, name: '192' },\n { id: 256, name: '256' },\n { id: 320, name: '320' },\n ]}\n defaultValue={192}\n />\n <TextInput\n source=\"command\"\n fullWidth\n validate={[required()]}\n helperText={\n <span>\n Substitutions: <br />\n %s: File path <br />\n %b: BitRate (in kbps)\n <br />\n </span>\n }\n />\n </SimpleForm>\n </Create>\n)\n\nexport default TranscodingCreate\n","import React from 'react'\nimport { Show, SimpleShowLayout, TextField } from 'react-admin'\nimport { Title } from '../common'\nimport { TranscodingNote } from './TranscodingNote'\n\nconst TranscodingTitle = ({ record }) => {\n return <Title subTitle={`Transcoding ${record ? record.name : ''}`} />\n}\n\nconst TranscodingShow = (props) => {\n return (\n <>\n <TranscodingNote message={'message.transcodingDisabled'} />\n\n <Show title={<TranscodingTitle />} {...props}>\n <SimpleShowLayout>\n <TextField source=\"name\" />\n <TextField source=\"targetFormat\" />\n <TextField source=\"defaultBitRate\" />\n <TextField source=\"command\" />\n </SimpleShowLayout>\n </Show>\n </>\n )\n}\n\nexport default TranscodingShow\n","import TransformIcon from '@material-ui/icons/Transform'\nimport TranscodingList from './TranscodingList'\nimport TranscodingEdit from './TranscodingEdit'\nimport TranscodingCreate from './TranscodingCreate'\nimport TranscodingShow from './TranscodingShow'\nimport config from '../config'\n\nexport default {\n list: TranscodingList,\n edit: config.enableTranscodingConfig && TranscodingEdit,\n create: config.enableTranscodingConfig && TranscodingCreate,\n show: !config.enableTranscodingConfig && TranscodingShow,\n icon: TransformIcon,\n}\n","import React from 'react'\nimport {\n Datagrid,\n TextField,\n DateField,\n FunctionField,\n ReferenceField,\n Filter,\n SearchInput,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { SimpleList, List } from '../common'\n\nconst PlayerFilter = (props) => (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n </Filter>\n)\n\nconst PlayerList = ({ permissions, ...props }) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n return (\n <List\n {...props}\n sort={{ field: 'lastSeen', order: 'DESC' }}\n exporter={false}\n filters={<PlayerFilter />}\n >\n {isXsmall ? (\n <SimpleList\n primaryText={(r) => r.client}\n secondaryText={(r) => r.userName}\n tertiaryText={(r) => (r.maxBitRate ? r.maxBitRate : '-')}\n />\n ) : (\n <Datagrid rowClick=\"edit\">\n <TextField source=\"name\" />\n {permissions === 'admin' && <TextField source=\"userName\" />}\n <ReferenceField source=\"transcodingId\" reference=\"transcoding\">\n <TextField source=\"name\" />\n </ReferenceField>\n <FunctionField\n source=\"maxBitRate\"\n render={(r) => (r.maxBitRate ? r.maxBitRate : '-')}\n />\n <DateField source=\"lastSeen\" showTime sortByOrder={'DESC'} />\n </Datagrid>\n )}\n </List>\n )\n}\n\nexport default PlayerList\n","import React from 'react'\nimport {\n TextInput,\n BooleanInput,\n TextField,\n Edit,\n required,\n SimpleForm,\n SelectInput,\n ReferenceInput,\n useTranslate,\n} from 'react-admin'\nimport { Title } from '../common'\nimport config from '../config'\n\nconst PlayerTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.player.name', { smart_count: 1 })\n return <Title subTitle={`${resourceName} ${record ? record.name : ''}`} />\n}\n\nconst PlayerEdit = (props) => (\n <Edit title={<PlayerTitle />} {...props}>\n <SimpleForm variant={'outlined'}>\n <TextInput source=\"name\" validate={[required()]} />\n <ReferenceInput\n source=\"transcodingId\"\n reference=\"transcoding\"\n sort={{ field: 'name', order: 'ASC' }}\n >\n <SelectInput source=\"name\" resettable />\n </ReferenceInput>\n <SelectInput\n source=\"maxBitRate\"\n choices={[\n { id: 32, name: '32' },\n { id: 48, name: '48' },\n { id: 64, name: '64' },\n { id: 80, name: '80' },\n { id: 96, name: '96' },\n { id: 112, name: '112' },\n { id: 128, name: '128' },\n { id: 160, name: '160' },\n { id: 192, name: '192' },\n { id: 256, name: '256' },\n { id: 320, name: '320' },\n { id: 0, name: '-' },\n ]}\n />\n <BooleanInput source=\"reportRealPath\" fullWidth />\n {(config.lastFMEnabled || config.listenBrainzEnabled) && (\n <BooleanInput source=\"scrobbleEnabled\" fullWidth />\n )}\n <TextField source=\"client\" />\n <TextField source=\"userName\" />\n </SimpleForm>\n </Edit>\n)\n\nexport default PlayerEdit\n","import RadioIcon from '@material-ui/icons/Radio'\nimport PlayerList from './PlayerList'\nimport PlayerEdit from './PlayerEdit'\n\nexport default {\n list: PlayerList,\n edit: PlayerEdit,\n icon: RadioIcon,\n}\n","import React from 'react'\nimport {\n BooleanField,\n Datagrid,\n Filter,\n SearchInput,\n SimpleList,\n TextField,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { List, DateField } from '../common'\n\nconst UserFilter = (props) => (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n </Filter>\n)\n\nconst UserList = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n\n return (\n <List\n {...props}\n sort={{ field: 'userName', order: 'ASC' }}\n exporter={false}\n bulkActionButtons={false}\n filters={<UserFilter />}\n >\n {isXsmall ? (\n <SimpleList\n primaryText={(record) => record.userName}\n secondaryText={(record) =>\n record.lastLoginAt && new Date(record.lastLoginAt).toLocaleString()\n }\n tertiaryText={(record) => (record.isAdmin ? '[admin]️' : '')}\n />\n ) : (\n <Datagrid rowClick=\"edit\">\n <TextField source=\"userName\" />\n <TextField source=\"name\" />\n <BooleanField source=\"isAdmin\" />\n <DateField source=\"lastLoginAt\" sortByOrder={'DESC'} />\n <DateField source=\"updatedAt\" sortByOrder={'DESC'} />\n </Datagrid>\n )}\n </List>\n )\n}\n\nexport default UserList\n","import React from 'react'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { fade } from '@material-ui/core/styles/colorManipulator'\nimport clsx from 'clsx'\nimport {\n useDeleteWithConfirmController,\n Button,\n Confirm,\n useNotify,\n useRedirect,\n} from 'react-admin'\n\nconst useStyles = makeStyles(\n (theme) => ({\n deleteButton: {\n color: theme.palette.error.main,\n '&:hover': {\n backgroundColor: fade(theme.palette.error.main, 0.12),\n // Reset on mouse devices\n '@media (hover: none)': {\n backgroundColor: 'transparent',\n },\n },\n },\n }),\n { name: 'RaDeleteWithConfirmButton' }\n)\n\nconst DeleteUserButton = (props) => {\n const { resource, record, basePath, className, onClick, ...rest } = props\n\n const notify = useNotify()\n const redirect = useRedirect()\n\n const onSuccess = () => {\n notify('resources.user.notifications.deleted')\n redirect('/user')\n }\n\n const { open, loading, handleDialogOpen, handleDialogClose, handleDelete } =\n useDeleteWithConfirmController({\n resource,\n record,\n basePath,\n onClick,\n onSuccess,\n })\n\n const classes = useStyles(props)\n return (\n <>\n <Button\n onClick={handleDialogOpen}\n label=\"ra.action.delete\"\n className={clsx('ra-delete-button', classes.deleteButton, className)}\n key=\"button\"\n {...rest}\n >\n <DeleteIcon />\n </Button>\n <Confirm\n isOpen={open}\n loading={loading}\n title=\"message.delete_user_title\"\n content=\"message.delete_user_content\"\n translateOptions={{\n name: record.name,\n }}\n onConfirm={handleDelete}\n onClose={handleDialogClose}\n />\n </>\n )\n}\n\nexport default DeleteUserButton\n","import React, { useCallback } from 'react'\nimport { makeStyles } from '@material-ui/core/styles'\nimport {\n TextInput,\n BooleanInput,\n DateField,\n PasswordInput,\n Edit,\n required,\n email,\n SimpleForm,\n useTranslate,\n Toolbar,\n SaveButton,\n useMutation,\n useNotify,\n useRedirect,\n useRefresh,\n FormDataConsumer,\n usePermissions,\n} from 'react-admin'\nimport { Title } from '../common'\nimport DeleteUserButton from './DeleteUserButton'\n\nconst useStyles = makeStyles({\n toolbar: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n})\n\nconst UserTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.user.name', { smart_count: 1 })\n return <Title subTitle={`${resourceName} ${record ? record.name : ''}`} />\n}\n\nconst UserToolbar = ({ showDelete, ...props }) => (\n <Toolbar {...props} classes={useStyles()}>\n <SaveButton disabled={props.pristine} />\n {showDelete && <DeleteUserButton />}\n </Toolbar>\n)\n\nconst CurrentPasswordInput = ({ formData, isMyself, ...rest }) => {\n const { permissions } = usePermissions()\n return formData.changePassword && (isMyself || permissions !== 'admin') ? (\n <PasswordInput className=\"ra-input\" source=\"currentPassword\" {...rest} />\n ) : null\n}\n\nconst NewPasswordInput = ({ formData, ...rest }) => {\n const translate = useTranslate()\n return formData.changePassword ? (\n <PasswordInput\n source=\"password\"\n className=\"ra-input\"\n label={translate('resources.user.fields.newPassword')}\n {...rest}\n />\n ) : null\n}\n\nconst UserEdit = (props) => {\n const { permissions } = props\n const translate = useTranslate()\n const [mutate] = useMutation()\n const notify = useNotify()\n const redirect = useRedirect()\n const refresh = useRefresh()\n\n const isMyself = props.id === localStorage.getItem('userId')\n const getNameHelperText = () =>\n isMyself && {\n helperText: translate('resources.user.helperTexts.name'),\n }\n const canDelete = permissions === 'admin' && !isMyself\n\n const save = useCallback(\n async (values) => {\n try {\n await mutate(\n {\n type: 'update',\n resource: 'user',\n payload: { id: values.id, data: values },\n },\n { returnPromise: true }\n )\n notify('resources.user.notifications.updated', 'info', {\n smart_count: 1,\n })\n permissions === 'admin' ? redirect('/user') : refresh()\n } catch (error) {\n if (error.body.errors) {\n return error.body.errors\n }\n }\n },\n [mutate, notify, permissions, redirect, refresh]\n )\n\n return (\n <Edit title={<UserTitle />} undoable={false} {...props}>\n <SimpleForm\n variant={'outlined'}\n toolbar={<UserToolbar showDelete={canDelete} />}\n save={save}\n >\n {permissions === 'admin' && (\n <TextInput source=\"userName\" validate={[required()]} />\n )}\n <TextInput\n source=\"name\"\n validate={[required()]}\n {...getNameHelperText()}\n />\n <TextInput source=\"email\" validate={[email()]} />\n <BooleanInput source=\"changePassword\" />\n <FormDataConsumer>\n {(formDataProps) => (\n <CurrentPasswordInput isMyself={isMyself} {...formDataProps} />\n )}\n </FormDataConsumer>\n <FormDataConsumer>\n {(formDataProps) => <NewPasswordInput {...formDataProps} />}\n </FormDataConsumer>\n\n {permissions === 'admin' && (\n <BooleanInput source=\"isAdmin\" initialValue={false} />\n )}\n <DateField variant=\"body1\" source=\"lastLoginAt\" showTime />\n {/*<DateField source=\"lastAccessAt\" showTime />*/}\n <DateField variant=\"body1\" source=\"updatedAt\" showTime />\n <DateField variant=\"body1\" source=\"createdAt\" showTime />\n </SimpleForm>\n </Edit>\n )\n}\n\nexport default UserEdit\n","import UserList from './UserList'\nimport UserEdit from './UserEdit'\nimport UserCreate from './UserCreate'\n\nexport default {\n list: UserList,\n edit: UserEdit,\n create: UserCreate,\n}\n","import React, { useCallback } from 'react'\nimport {\n BooleanInput,\n Create,\n TextInput,\n PasswordInput,\n required,\n email,\n SimpleForm,\n useTranslate,\n useMutation,\n useNotify,\n useRedirect,\n} from 'react-admin'\nimport { Title } from '../common'\n\nconst UserCreate = (props) => {\n const translate = useTranslate()\n const [mutate] = useMutation()\n const notify = useNotify()\n const redirect = useRedirect()\n const resourceName = translate('resources.user.name', { smart_count: 1 })\n const title = translate('ra.page.create', {\n name: `${resourceName}`,\n })\n\n const save = useCallback(\n async (values) => {\n try {\n await mutate(\n {\n type: 'create',\n resource: 'user',\n payload: { data: values },\n },\n { returnPromise: true }\n )\n notify('resources.user.notifications.created', 'info', {\n smart_count: 1,\n })\n redirect('/user')\n } catch (error) {\n if (error.body.errors) {\n return error.body.errors\n }\n }\n },\n [mutate, notify, redirect]\n )\n\n return (\n <Create title={<Title subTitle={title} />} {...props}>\n <SimpleForm save={save} variant={'outlined'}>\n <TextInput source=\"userName\" validate={[required()]} />\n <TextInput source=\"name\" validate={[required()]} />\n <TextInput source=\"email\" validate={[email()]} />\n <PasswordInput source=\"password\" validate={[required()]} />\n <BooleanInput source=\"isAdmin\" defaultValue={false} />\n </SimpleForm>\n </Create>\n )\n}\n\nexport default UserCreate\n","import React, { cloneElement } from 'react'\nimport { sanitizeListRestProps, TopToolbar } from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ShuffleAllButton, ToggleFieldsMenu } from '../common'\n\nexport const SongListActions = ({\n currentSort,\n className,\n resource,\n filters,\n displayedFilters,\n filterValues,\n permanentFilter,\n exporter,\n basePath,\n selectedIds,\n onUnselectItems,\n showFilter,\n maxResults,\n total,\n ids,\n ...rest\n}) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {filters &&\n cloneElement(filters, {\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n context: 'button',\n })}\n <ShuffleAllButton filters={filterValues} />\n {isNotSmall && <ToggleFieldsMenu resource=\"song\" />}\n </TopToolbar>\n )\n}\n\nSongListActions.defaultProps = {\n selectedIds: [],\n onUnselectItems: () => null,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { Link } from 'react-admin'\n\nexport const AlbumLinkField = (props) => (\n <Link\n to={`/album/${props.record.albumId}/show`}\n onClick={(e) => e.stopPropagation()}\n >\n {props.record.album}\n </Link>\n)\n\nAlbumLinkField.propTypes = {\n sortBy: PropTypes.string,\n sortByOrder: PropTypes.oneOf(['ASC', 'DESC']),\n}\n\nAlbumLinkField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { RecordContextProvider, useTranslate } from 'react-admin'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\nimport { closeExtendedInfoDialog } from '../actions'\n\nconst ExpandInfoDialog = ({ title, content }) => {\n const { open, record } = useSelector((state) => state.expandInfoDialog)\n const dispatch = useDispatch()\n const translate = useTranslate()\n\n const handleClose = (e) => {\n dispatch(closeExtendedInfoDialog())\n e.stopPropagation()\n }\n\n return (\n <Dialog\n open={open}\n onClose={handleClose}\n onBackdropClick={handleClose}\n aria-labelledby=\"info-dialog-album\"\n fullWidth={true}\n maxWidth={'sm'}\n >\n <DialogTitle id=\"info-dialog-album\">\n {translate(title || 'resources.song.actions.info')}\n </DialogTitle>\n <DialogContent>\n {record && (\n <RecordContextProvider value={record}>\n {content}\n </RecordContextProvider>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={handleClose} color=\"primary\">\n {translate('ra.action.close')}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nExpandInfoDialog.propTypes = {\n title: PropTypes.string,\n content: PropTypes.object.isRequired,\n}\n\nexport default ExpandInfoDialog\n","import React from 'react'\nimport {\n AutocompleteInput,\n Filter,\n FunctionField,\n NumberField,\n ReferenceInput,\n SearchInput,\n TextField,\n useTranslate,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport {\n DateField,\n DurationField,\n List,\n SongContextMenu,\n SongDatagrid,\n SongInfo,\n QuickFilter,\n SongTitleField,\n SongSimpleList,\n RatingField,\n useResourceRefresh,\n ArtistLinkField,\n} from '../common'\nimport { useDispatch } from 'react-redux'\nimport { makeStyles } from '@material-ui/core/styles'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { setTrack } from '../actions'\nimport { SongListActions } from './SongListActions'\nimport { AlbumLinkField } from './AlbumLinkField'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport { SongBulkActions, QualityInfo, useSelectedFields } from '../common'\nimport config from '../config'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst useStyles = makeStyles({\n contextHeader: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: 'hidden',\n },\n ratingField: {\n visibility: 'hidden',\n },\n})\n\nconst SongFilter = (props) => {\n const translate = useTranslate()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"title\" alwaysOn />\n <ReferenceInput\n label={translate('resources.song.fields.genre')}\n source=\"genre_id\"\n reference=\"genre\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n {config.enableFavourites && (\n <QuickFilter\n source=\"starred\"\n label={<FavoriteIcon fontSize={'small'} />}\n defaultValue={true}\n />\n )}\n </Filter>\n )\n}\n\nconst SongList = (props) => {\n const classes = useStyles()\n const dispatch = useDispatch()\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n useResourceRefresh('song')\n\n const handleRowClick = (id, basePath, record) => {\n dispatch(setTrack(record))\n }\n\n const toggleableFields = React.useMemo(() => {\n return {\n album: isDesktop && (\n <AlbumLinkField\n source=\"album\"\n sortBy={\n 'album, order_album_artist_name, disc_number, track_number, title'\n }\n sortByOrder={'ASC'}\n />\n ),\n artist: <ArtistLinkField source=\"artist\" />,\n albumArtist: <ArtistLinkField source=\"albumArtist\" />,\n trackNumber: isDesktop && <NumberField source=\"trackNumber\" />,\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortByOrder={'DESC'} />\n ),\n playDate: <DateField source=\"playDate\" sortByOrder={'DESC'} showTime />,\n year: isDesktop && (\n <FunctionField\n source=\"year\"\n render={(r) => r.year || ''}\n sortByOrder={'DESC'}\n />\n ),\n quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n channels: isDesktop && (\n <NumberField source=\"channels\" sortByOrder={'ASC'} />\n ),\n duration: <DurationField source=\"duration\" />,\n rating: config.enableStarRating && (\n <RatingField\n source=\"rating\"\n sortByOrder={'DESC'}\n resource={'song'}\n className={classes.ratingField}\n />\n ),\n bpm: isDesktop && <NumberField source=\"bpm\" />,\n genre: <TextField source=\"genre\" />,\n comment: <TextField source=\"comment\" />,\n }\n }, [isDesktop, classes.ratingField])\n\n const columns = useSelectedFields({\n resource: 'song',\n columns: toggleableFields,\n defaultOff: [\n 'channels',\n 'bpm',\n 'playDate',\n 'albumArtist',\n 'genre',\n 'comment',\n ],\n })\n\n return (\n <>\n <List\n {...props}\n sort={{ field: 'title', order: 'ASC' }}\n exporter={false}\n bulkActionButtons={<SongBulkActions />}\n actions={<SongListActions />}\n filters={<SongFilter />}\n perPage={isXsmall ? 50 : 15}\n >\n {isXsmall ? (\n <SongSimpleList />\n ) : (\n <SongDatagrid\n rowClick={handleRowClick}\n contextAlwaysVisible={!isDesktop}\n classes={{ row: classes.row }}\n >\n <SongTitleField source=\"title\" showTrackNumbers={false} />\n {columns}\n <SongContextMenu\n source={'starred'}\n sortBy={'starred ASC, starredAt ASC'}\n sortByOrder={'DESC'}\n sortable={config.enableFavourites}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.contextHeader}\n />\n )\n }\n />\n </SongDatagrid>\n )}\n </List>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<SongInfo />} />\n </>\n )\n}\n\nexport default SongList\n","import React from 'react'\nimport SongList from './SongList'\nimport MusicNoteOutlinedIcon from '@material-ui/icons/MusicNoteOutlined'\nimport MusicNoteIcon from '@material-ui/icons/MusicNote'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\n\nexport default {\n list: SongList,\n icon: (\n <DynamicMenuIcon\n path={'song'}\n icon={MusicNoteOutlinedIcon}\n activeIcon={MusicNoteIcon}\n />\n ),\n}\n","import React, { cloneElement } from 'react'\nimport {\n Button,\n sanitizeListRestProps,\n TopToolbar,\n useTranslate,\n} from 'react-admin'\nimport {\n ButtonGroup,\n useMediaQuery,\n Typography,\n makeStyles,\n} from '@material-ui/core'\nimport ViewHeadlineIcon from '@material-ui/icons/ViewHeadline'\nimport ViewModuleIcon from '@material-ui/icons/ViewModule'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { albumViewGrid, albumViewTable } from '../actions'\nimport { ToggleFieldsMenu } from '../common'\n\nconst useStyles = makeStyles({\n title: { margin: '1rem' },\n buttonGroup: { width: '100%', justifyContent: 'center' },\n leftButton: { paddingRight: '0.5rem' },\n rightButton: { paddingLeft: '0.5rem' },\n})\n\nconst AlbumViewToggler = React.forwardRef(\n ({ showTitle = true, disableElevation, fullWidth }, ref) => {\n const dispatch = useDispatch()\n const albumView = useSelector((state) => state.albumView)\n const classes = useStyles()\n const translate = useTranslate()\n return (\n <div ref={ref}>\n {showTitle && (\n <Typography className={classes.title}>\n {translate('ra.toggleFieldsMenu.layout')}\n </Typography>\n )}\n <ButtonGroup\n variant=\"text\"\n color=\"primary\"\n aria-label=\"text primary button group\"\n className={classes.buttonGroup}\n >\n <Button\n size=\"small\"\n className={classes.leftButton}\n label={translate('ra.toggleFieldsMenu.grid')}\n color={albumView.grid ? 'primary' : 'secondary'}\n onClick={() => dispatch(albumViewGrid())}\n >\n <ViewModuleIcon fontSize=\"inherit\" />\n </Button>\n <Button\n size=\"small\"\n className={classes.rightButton}\n label={translate('ra.toggleFieldsMenu.table')}\n color={albumView.grid ? 'secondary' : 'primary'}\n onClick={() => dispatch(albumViewTable())}\n >\n <ViewHeadlineIcon fontSize=\"inherit\" />\n </Button>\n </ButtonGroup>\n </div>\n )\n }\n)\n\nconst AlbumListActions = ({\n currentSort,\n className,\n resource,\n filters,\n displayedFilters,\n filterValues,\n permanentFilter,\n exporter,\n basePath,\n selectedIds,\n onUnselectItems,\n showFilter,\n maxResults,\n total,\n fullWidth,\n ...rest\n}) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {filters &&\n cloneElement(filters, {\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n context: 'button',\n })}\n {isNotSmall ? (\n <ToggleFieldsMenu resource=\"album\" topbarComponent={AlbumViewToggler} />\n ) : (\n <AlbumViewToggler showTitle={false} />\n )}\n </TopToolbar>\n )\n}\n\nAlbumListActions.defaultProps = {\n selectedIds: [],\n onUnselectItems: () => null,\n}\n\nexport default AlbumListActions\n","import React, { useMemo } from 'react'\nimport {\n Datagrid,\n DatagridBody,\n DatagridRow,\n NumberField,\n TextField,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useDrag } from 'react-dnd'\nimport {\n ArtistLinkField,\n DurationField,\n RangeField,\n SimpleList,\n AlbumContextMenu,\n RatingField,\n useSelectedFields,\n} from '../common'\nimport config from '../config'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles({\n columnIcon: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n tableCell: {\n width: '17.5%',\n },\n contextMenu: {\n visibility: 'hidden',\n },\n ratingField: {\n visibility: 'hidden',\n },\n})\n\nconst AlbumDatagridRow = (props) => {\n const { record } = props\n const [, dragAlbumRef] = useDrag(\n () => ({\n type: DraggableTypes.ALBUM,\n item: { albumIds: [record?.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n return <DatagridRow ref={dragAlbumRef} {...props} />\n}\n\nconst AlbumDatagridBody = (props) => (\n <DatagridBody {...props} row={<AlbumDatagridRow />} />\n)\n\nconst AlbumDatagrid = (props) => (\n <Datagrid {...props} body={<AlbumDatagridBody />} />\n)\n\nconst AlbumTableView = ({\n hasShow,\n hasEdit,\n hasList,\n syncWithLocation,\n ...rest\n}) => {\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n\n const toggleableFields = useMemo(() => {\n return {\n artist: <ArtistLinkField source=\"artist\" />,\n songCount: isDesktop && (\n <NumberField source=\"songCount\" sortByOrder={'DESC'} />\n ),\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortByOrder={'DESC'} />\n ),\n year: (\n <RangeField source={'year'} sortBy={'max_year'} sortByOrder={'DESC'} />\n ),\n duration: isDesktop && <DurationField source=\"duration\" />,\n rating: config.enableStarRating && (\n <RatingField\n source={'rating'}\n resource={'album'}\n sortByOrder={'DESC'}\n className={classes.ratingField}\n />\n ),\n }\n }, [classes.ratingField, isDesktop])\n\n const columns = useSelectedFields({\n resource: 'album',\n columns: toggleableFields,\n })\n\n return isXsmall ? (\n <SimpleList\n primaryText={(r) => r.name}\n secondaryText={(r) => (\n <>\n {r.albumArtist}\n {config.enableStarRating && (\n <>\n <br />\n <RatingField\n record={r}\n sortByOrder={'DESC'}\n source={'rating'}\n resource={'album'}\n size={'small'}\n />\n </>\n )}\n </>\n )}\n tertiaryText={(r) => (\n <>\n <RangeField record={r} source={'year'} sortBy={'max_year'} />\n      \n </>\n )}\n linkType={'show'}\n rightIcon={(r) => <AlbumContextMenu record={r} />}\n {...rest}\n />\n ) : (\n <AlbumDatagrid rowClick={'show'} classes={{ row: classes.row }} {...rest}>\n <TextField source=\"name\" />\n {columns}\n <AlbumContextMenu\n source={'starred'}\n sortBy={'starred ASC, starredAt ASC'}\n sortByOrder={'DESC'}\n sortable={config.enableFavourites}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.columnIcon}\n />\n )\n }\n />\n </AlbumDatagrid>\n )\n}\n\nexport default AlbumTableView\n","import React from 'react'\nimport {\n GridList,\n GridListTile,\n Typography,\n GridListTileBar,\n useMediaQuery,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport withWidth from '@material-ui/core/withWidth'\nimport { Link } from 'react-router-dom'\nimport { linkToRecord, useListContext, Loading } from 'react-admin'\nimport { withContentRect } from 'react-measure'\nimport { useDrag } from 'react-dnd'\nimport subsonic from '../subsonic'\nimport {\n AlbumContextMenu,\n PlayButton,\n ArtistLinkField,\n RangeField,\n} from '../common'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n margin: '20px',\n display: 'grid',\n },\n tileBar: {\n transition: 'all 150ms ease-out',\n opacity: 0,\n textAlign: 'left',\n marginBottom: '3px',\n background:\n 'linear-gradient(to top, rgba(0,0,0,0.7) 0%,rgba(0,0,0,0.4) 70%,rgba(0,0,0,0) 100%)',\n },\n tileBarMobile: {\n textAlign: 'left',\n marginBottom: '3px',\n background:\n 'linear-gradient(to top, rgba(0,0,0,0.7) 0%,rgba(0,0,0,0.4) 70%,rgba(0,0,0,0) 100%)',\n },\n albumArtistName: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n textAlign: 'left',\n fontSize: '1em',\n },\n albumName: {\n fontSize: '14px',\n color: theme.palette.type === 'dark' ? '#eee' : 'black',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n },\n albumSubtitle: {\n fontSize: '12px',\n color: theme.palette.type === 'dark' ? '#c5c5c5' : '#696969',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n },\n link: {\n position: 'relative',\n display: 'block',\n textDecoration: 'none',\n '&:hover $tileBar': {\n opacity: 1,\n },\n },\n albumLink: {\n position: 'relative',\n display: 'block',\n textDecoration: 'none',\n },\n albumContainer: {},\n albumPlayButton: { color: 'white' },\n }),\n { name: 'NDAlbumGridView' }\n)\n\nconst useCoverStyles = makeStyles({\n cover: {\n display: 'inline-block',\n width: '100%',\n objectFit: 'contain',\n height: (props) => props.height,\n },\n})\n\nconst getColsForWidth = (width) => {\n if (width === 'xs') return 2\n if (width === 'sm') return 3\n if (width === 'md') return 4\n if (width === 'lg') return 6\n return 9\n}\n\nconst Cover = withContentRect('bounds')(\n ({ record, measureRef, contentRect }) => {\n // Force height to be the same as the width determined by the GridList\n // noinspection JSSuspiciousNameCombination\n const classes = useCoverStyles({ height: contentRect.bounds.width })\n const [, dragAlbumRef] = useDrag(\n () => ({\n type: DraggableTypes.ALBUM,\n item: { albumIds: [record.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n return (\n <div ref={measureRef}>\n <div ref={dragAlbumRef}>\n <img\n src={subsonic.getCoverArtUrl(record, 300)}\n alt={record.name}\n className={classes.cover}\n />\n </div>\n </div>\n )\n }\n)\n\nconst AlbumGridTile = ({ showArtist, record, basePath, ...props }) => {\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'), {\n noSsr: true,\n })\n if (!record) {\n return null\n }\n return (\n <div className={classes.albumContainer}>\n <Link\n className={classes.link}\n to={linkToRecord(basePath, record.id, 'show')}\n >\n <Cover record={record} />\n <GridListTileBar\n className={isDesktop ? classes.tileBar : classes.tileBarMobile}\n subtitle={\n <PlayButton\n className={classes.albumPlayButton}\n record={record}\n size=\"small\"\n />\n }\n actionIcon={<AlbumContextMenu record={record} color={'white'} />}\n />\n </Link>\n <Link\n className={classes.albumLink}\n to={linkToRecord(basePath, record.id, 'show')}\n >\n <Typography className={classes.albumName}>{record.name}</Typography>\n </Link>\n {showArtist ? (\n <ArtistLinkField record={record} className={classes.albumSubtitle} />\n ) : (\n <RangeField\n record={record}\n source={'year'}\n sortBy={'max_year'}\n sortByOrder={'DESC'}\n className={classes.albumSubtitle}\n />\n )}\n </div>\n )\n}\n\nconst LoadedAlbumGrid = ({ ids, data, basePath, width }) => {\n const classes = useStyles()\n const { filterValues } = useListContext()\n const isArtistView = !!(filterValues && filterValues.artist_id)\n return (\n <div className={classes.root}>\n <GridList\n component={'div'}\n cellHeight={'auto'}\n cols={getColsForWidth(width)}\n spacing={20}\n >\n {ids.map((id) => (\n <GridListTile className={classes.gridListTile} key={id}>\n <AlbumGridTile\n record={data[id]}\n basePath={basePath}\n showArtist={!isArtistView}\n />\n </GridListTile>\n ))}\n </GridList>\n </div>\n )\n}\n\nconst AlbumGridView = ({ albumListType, loaded, loading, ...props }) => {\n const hide =\n (loading && albumListType === 'random') || !props.data || !props.ids\n return hide ? <Loading /> : <LoadedAlbumGrid {...props} />\n}\n\nexport default withWidth()(AlbumGridView)\n","import Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport inflection from 'inflection'\nimport TableCell from '@material-ui/core/TableCell'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport TableRow from '@material-ui/core/TableRow'\nimport {\n ArrayField,\n BooleanField,\n ChipField,\n DateField,\n SingleFieldList,\n TextField,\n useRecordContext,\n useTranslate,\n} from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { MultiLineTextField } from '../common'\n\nconst useStyles = makeStyles({\n tableCell: {\n width: '17.5%',\n },\n})\n\nconst AlbumInfo = (props) => {\n const classes = useStyles()\n const translate = useTranslate()\n const record = useRecordContext(props)\n const data = {\n album: <TextField source={'name'} />,\n albumArtist: <TextField source={'albumArtist'} />,\n genre: (\n <ArrayField source={'genres'}>\n <SingleFieldList linkType={false}>\n <ChipField source={'name'} />\n </SingleFieldList>\n </ArrayField>\n ),\n compilation: <BooleanField source={'compilation'} />,\n updatedAt: <DateField source={'updatedAt'} showTime />,\n comment: <MultiLineTextField source={'comment'} />,\n }\n\n const optionalFields = ['comment', 'genre']\n optionalFields.forEach((field) => {\n !record[field] && delete data[field]\n })\n\n return (\n <TableContainer>\n <Table aria-label=\"album details\" size=\"small\">\n <TableBody>\n {Object.keys(data).map((key) => {\n return (\n <TableRow key={`${record.id}-${key}`}>\n <TableCell\n component=\"th\"\n scope=\"row\"\n className={classes.tableCell}\n >\n {translate(`resources.album.fields.${key}`, {\n _: inflection.humanize(inflection.underscore(key)),\n })}\n :\n </TableCell>\n <TableCell align=\"left\">{data[key]}</TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </TableContainer>\n )\n}\n\nexport default AlbumInfo\n","import React from 'react'\nimport { useSelector } from 'react-redux'\nimport { Redirect, useLocation } from 'react-router-dom'\nimport {\n AutocompleteInput,\n Filter,\n NullableBooleanInput,\n NumberInput,\n Pagination,\n ReferenceInput,\n SearchInput,\n useTranslate,\n} from 'react-admin'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport { withWidth } from '@material-ui/core'\nimport {\n List,\n QuickFilter,\n Title,\n useAlbumsPerPage,\n useResourceRefresh,\n useSetToggleableFields,\n} from '../common'\nimport AlbumListActions from './AlbumListActions'\nimport AlbumTableView from './AlbumTableView'\nimport AlbumGridView from './AlbumGridView'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport albumLists, { defaultAlbumList } from './albumLists'\nimport config from '../config'\nimport AlbumInfo from './AlbumInfo'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst AlbumFilter = (props) => {\n const translate = useTranslate()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n <ReferenceInput\n label={translate('resources.album.fields.artist')}\n source=\"artist_id\"\n reference=\"artist\"\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n <ReferenceInput\n label={translate('resources.album.fields.genre')}\n source=\"genre_id\"\n reference=\"genre\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n <NullableBooleanInput source=\"compilation\" />\n <NumberInput source=\"year\" />\n {config.enableFavourites && (\n <QuickFilter\n source=\"starred\"\n label={<FavoriteIcon fontSize={'small'} />}\n defaultValue={true}\n />\n )}\n </Filter>\n )\n}\n\nconst AlbumListTitle = ({ albumListType }) => {\n const translate = useTranslate()\n let title = translate('resources.album.name', { smart_count: 2 })\n if (albumListType) {\n let listTitle = translate(`resources.album.lists.${albumListType}`, {\n smart_count: 2,\n })\n title = `${title} - ${listTitle}`\n }\n return <Title subTitle={title} args={{ smart_count: 2 }} />\n}\n\nconst AlbumList = (props) => {\n const { width } = props\n const albumView = useSelector((state) => state.albumView)\n const [perPage, perPageOptions] = useAlbumsPerPage(width)\n const location = useLocation()\n useResourceRefresh('album')\n\n const albumListType = location.pathname\n .replace(/^\\/album/, '')\n .replace(/^\\//, '')\n\n // Workaround to force album columns to appear the first time.\n // See https://github.com/navidrome/navidrome/pull/923#issuecomment-833004842\n // TODO: Find a better solution\n useSetToggleableFields('album', [\n 'artist',\n 'songCount',\n 'playCount',\n 'year',\n 'duration',\n 'rating',\n ])\n\n // If it does not have filter/sort params (usually coming from Menu),\n // reload with correct filter/sort params\n if (!location.search) {\n const type =\n albumListType || localStorage.getItem('defaultView') || defaultAlbumList\n const listParams = albumLists[type]\n if (listParams) {\n return <Redirect to={`/album/${type}?${listParams.params}`} />\n }\n }\n\n return (\n <>\n <List\n {...props}\n exporter={false}\n bulkActionButtons={false}\n actions={<AlbumListActions />}\n filters={<AlbumFilter />}\n perPage={perPage}\n pagination={<Pagination rowsPerPageOptions={perPageOptions} />}\n title={<AlbumListTitle albumListType={albumListType} />}\n >\n {albumView.grid ? (\n <AlbumGridView albumListType={albumListType} {...props} />\n ) : (\n <AlbumTableView {...props} />\n )}\n </List>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<AlbumInfo />} />\n </>\n )\n}\n\nexport default withWidth()(AlbumList)\n","import React, { useMemo } from 'react'\nimport {\n BulkActionsToolbar,\n ListToolbar,\n TextField,\n NumberField,\n useVersion,\n useListContext,\n FunctionField,\n} from 'react-admin'\nimport clsx from 'clsx'\nimport { useDispatch } from 'react-redux'\nimport { Card, useMediaQuery } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { playTracks } from '../actions'\nimport {\n DurationField,\n SongBulkActions,\n SongContextMenu,\n SongDatagrid,\n SongInfo,\n SongTitleField,\n RatingField,\n QualityInfo,\n useSelectedFields,\n useResourceRefresh,\n DateField,\n} from '../common'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport config from '../config'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {},\n main: {\n display: 'flex',\n },\n content: {\n marginTop: 0,\n transition: theme.transitions.create('margin-top'),\n position: 'relative',\n flex: '1 1 auto',\n [theme.breakpoints.down('xs')]: {\n boxShadow: 'none',\n },\n },\n bulkActionsDisplayed: {\n marginTop: -theme.spacing(8),\n transition: theme.transitions.create('margin-top'),\n },\n actions: {\n zIndex: 2,\n display: 'flex',\n justifyContent: 'flex-end',\n flexWrap: 'wrap',\n },\n noResults: { padding: 20 },\n columnIcon: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n toolbar: {\n justifyContent: 'flex-start',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: (props) => (props.isDesktop ? 'hidden' : 'visible'),\n },\n ratingField: {\n visibility: 'hidden',\n },\n }),\n { name: 'RaList' }\n)\n\nconst AlbumSongs = (props) => {\n const { data, ids } = props\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const dispatch = useDispatch()\n const version = useVersion()\n useResourceRefresh('song', 'album')\n\n const toggleableFields = useMemo(() => {\n return {\n trackNumber: isDesktop && (\n <TextField\n source=\"trackNumber\"\n sortBy=\"discNumber asc, trackNumber asc\"\n label=\"#\"\n sortable={false}\n />\n ),\n title: (\n <SongTitleField\n source=\"title\"\n sortable={false}\n showTrackNumbers={!isDesktop}\n />\n ),\n artist: isDesktop && <TextField source=\"artist\" sortable={false} />,\n duration: <DurationField source=\"duration\" sortable={false} />,\n year: isDesktop && (\n <FunctionField\n source=\"year\"\n render={(r) => r.year || ''}\n sortByOrder={'DESC'}\n />\n ),\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortable={false} />\n ),\n playDate: <DateField source=\"playDate\" sortable={false} showTime />,\n quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n channels: isDesktop && <NumberField source=\"channels\" sortable={false} />,\n bpm: isDesktop && <NumberField source=\"bpm\" sortable={false} />,\n rating: isDesktop && config.enableStarRating && (\n <RatingField\n resource={'song'}\n source=\"rating\"\n sortable={false}\n className={classes.ratingField}\n />\n ),\n }\n }, [isDesktop, classes.ratingField])\n\n const columns = useSelectedFields({\n resource: 'albumSong',\n columns: toggleableFields,\n omittedColumns: ['title'],\n defaultOff: ['channels', 'bpm', 'year', 'playCount', 'playDate'],\n })\n\n return (\n <>\n <ListToolbar\n classes={{ toolbar: classes.toolbar }}\n actions={props.actions}\n {...props}\n />\n <div className={classes.main}>\n <Card\n className={clsx(classes.content, {\n [classes.bulkActionsDisplayed]: props.selectedIds.length > 0,\n })}\n key={version}\n >\n <BulkActionsToolbar {...props}>\n <SongBulkActions />\n </BulkActionsToolbar>\n <SongDatagrid\n rowClick={(id) => dispatch(playTracks(data, ids, id))}\n {...props}\n hasBulkActions={true}\n showDiscSubtitles={true}\n contextAlwaysVisible={!isDesktop}\n classes={{ row: classes.row }}\n >\n {columns}\n <SongContextMenu\n source={'starred'}\n sortable={false}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.columnIcon}\n />\n )\n }\n />\n </SongDatagrid>\n </Card>\n </div>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<SongInfo />} />\n </>\n )\n}\n\nexport const removeAlbumCommentsFromSongs = ({ album, data }) => {\n if (album?.comment && data) {\n Object.values(data).forEach((song) => {\n song.comment = ''\n })\n }\n}\n\nconst SanitizedAlbumSongs = (props) => {\n removeAlbumCommentsFromSongs(props)\n\n const { loaded, loading, total, ...rest } = useListContext(props)\n return <>{loaded && <AlbumSongs {...rest} actions={props.actions} />}</>\n}\n\nexport default SanitizedAlbumSongs\n","import React from 'react'\nimport SvgIcon from '@material-ui/core/SvgIcon'\n\nconst MusicBrainz = (props) => {\n return (\n <SvgIcon xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 26 26\" {...props}>\n <path d=\"M11.582 0L1.418 5.832v12.336L11.582 24V10.01L7.1 12.668v3.664c.01.111.01.225 0 .336-.103.435-.54.804-1 1.111-.802.537-1.752.509-2.166-.111-.413-.62-.141-1.631.666-2.168.384-.28.863-.399 1.334-.332V6.619c0-.154.134-.252.226-.308L11.582 3zm.836 0v6.162c.574.03 1.14.16 1.668.387a2.225 2.225 0 0 0 1.656-.717 1.02 1.02 0 1 1 1.832-.803l.004.006a1.022 1.022 0 0 1-1.295 1.197c-.34.403-.792.698-1.297.85.34.263.641.576.891.928a1.04 1.04 0 0 1 .777.125c.768.486.568 1.657-.318 1.857-.886.2-1.574-.77-1.09-1.539.02-.03.042-.06.065-.09a3.598 3.598 0 0 0-1.436-1.166 4.142 4.142 0 0 0-1.457-.369v4.01c.855.06 1.256.493 1.555.834.227.256.356.39.578.402.323.018.568.008.806 0a5.44 5.44 0 0 1 .895.022c.94-.017 1.272-.226 1.605-.446a2.533 2.533 0 0 1 1.131-.463 1.027 1.027 0 0 1 .12-.263 1.04 1.04 0 0 1 .105-.137c.023-.025.047-.044.07-.066a4.775 4.775 0 0 1 0-2.405l-.012-.01a1.02 1.02 0 1 1 .692.272h-.057a4.288 4.288 0 0 0 0 1.877h.063a1.02 1.02 0 1 1-.545 1.883l-.047-.033a1 1 0 0 1-.352-.442 1.885 1.885 0 0 0-.814.354 3.03 3.03 0 0 1-.703.365c.757.555 1.772 1.6 2.199 2.299a1.03 1.03 0 0 1 .256-.033 1.02 1.02 0 1 1-.545 1.88l-.047-.03a1.017 1.017 0 0 1-.27-1.376.72.72 0 0 1 .051-.072c-.445-.775-2.026-2.28-2.46-2.387a4.037 4.037 0 0 0-1.31-.117c-.24.008-.513.018-.866 0-.515-.027-.783-.333-1.043-.629-.26-.296-.51-.56-1.055-.611V18.5a1.877 1.877 0 0 0 .426-.135.333.333 0 0 1 .058-.027c.56-.267 1.421-.91 2.096-2.447a1.02 1.02 0 0 1-.27-1.344 1.02 1.02 0 1 1 .915 1.54 6.273 6.273 0 0 1-1.432 2.136 1.785 1.785 0 0 1 .691.306.667.667 0 0 0 .37.168 3.31 3.31 0 0 0 .888-.222 1.02 1.02 0 0 1 1.787-.79v-.005a1.02 1.02 0 0 1-.773 1.683 1.022 1.022 0 0 1-.719-.287 3.935 3.935 0 0 1-1.168.287h-.05a1.313 1.313 0 0 1-.71-.275c-.262-.177-.51-.345-1.402-.12a2.098 2.098 0 0 1-.707.2V24l10.164-5.832V5.832zm4.154 4.904a.352.352 0 0 0-.197.639l.018.01c.163.1.378.053.484-.108v-.002a.352.352 0 0 0-.303-.539zm-4.99 1.928L7.082 9.5v2l4.5-2.668zm8.385.38a.352.352 0 0 0-.295.165v.002a.35.35 0 0 0 .096.473l.013.01a.357.357 0 0 0 .487-.108.352.352 0 0 0-.301-.541zM16.09 8.647a.352.352 0 0 0-.277.163.355.355 0 0 0 .296.54c.482 0 .463-.73-.02-.703zm3.877 2.477a.352.352 0 0 0-.295.164.35.35 0 0 0 .094.475l.015.01a.357.357 0 0 0 .485-.11.352.352 0 0 0-.3-.539zm-4.375 3.594a.352.352 0 0 0-.291.172.35.35 0 0 0-.04.265.352.352 0 1 0 .33-.437zm4.375.789a.352.352 0 0 0-.295.164v.002a.352.352 0 0 0 .094.473l.015.01a.357.357 0 0 0 .485-.108.352.352 0 0 0-.3-.54zm-2.803 2.488v.002a.347.347 0 0 0-.223.084.352.352 0 0 0 .23.62.347.347 0 0 0 .23-.085.348.348 0 0 0 .12-.24.353.353 0 0 0-.35-.38.347.347 0 0 0-.007 0Z\" />\n </SvgIcon>\n )\n}\n\nexport default MusicBrainz\n","import React from 'react'\nimport { useRecordContext, useTranslate } from 'react-admin'\nimport { IconButton, Tooltip, Link } from '@material-ui/core'\nimport { ImLastfm2 } from 'react-icons/im'\nimport MusicBrainz from '../icons/MusicBrainz'\nimport { intersperse } from '../utils'\n\nconst AlbumExternalLinks = (props) => {\n const { className } = props\n const translate = useTranslate()\n const record = useRecordContext(props)\n let links = []\n\n const addLink = (url, title, icon) => {\n const translatedTitle = translate(title)\n const link = (\n <Link href={url} target=\"_blank\" rel=\"noopener noreferrer\">\n <Tooltip title={translatedTitle}>\n <IconButton size={'small'} aria-label={translatedTitle}>\n {icon}\n </IconButton>\n </Tooltip>\n </Link>\n )\n const id = links.length\n links.push(<span key={`link-${record.id}-${id}`}>{link}</span>)\n }\n\n addLink(\n `https://last.fm/music/${\n encodeURIComponent(record.albumArtist) +\n '/' +\n encodeURIComponent(record.name)\n }`,\n 'message.openIn.lastfm',\n <ImLastfm2 />\n )\n\n record.mbzAlbumId &&\n addLink(\n `https://musicbrainz.org/release/${record.mbzAlbumId}`,\n 'message.openIn.musicbrainz',\n <MusicBrainz />\n )\n\n return <div className={className}>{intersperse(links, ' ')}</div>\n}\n\nexport default AlbumExternalLinks\n","import React, { useMemo, useCallback } from 'react'\nimport {\n Card,\n CardContent,\n CardMedia,\n Collapse,\n makeStyles,\n Typography,\n useMediaQuery,\n withWidth,\n} from '@material-ui/core'\nimport {\n useRecordContext,\n useTranslate,\n ArrayField,\n SingleFieldList,\n ChipField,\n Link,\n} from 'react-admin'\nimport clsx from 'clsx'\nimport Lightbox from 'react-image-lightbox'\nimport 'react-image-lightbox/style.css'\nimport subsonic from '../subsonic'\nimport {\n ArtistLinkField,\n DurationField,\n formatRange,\n SizeField,\n LoveButton,\n RatingField,\n useAlbumsPerPage,\n} from '../common'\nimport config from '../config'\nimport { intersperse } from '../utils'\nimport AlbumExternalLinks from './AlbumExternalLinks'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n [theme.breakpoints.down('xs')]: {\n padding: '0.7em',\n minWidth: '20em',\n },\n [theme.breakpoints.up('sm')]: {\n padding: '1em',\n minWidth: '32em',\n },\n },\n cardContents: {\n display: 'flex',\n },\n details: {\n display: 'flex',\n flexDirection: 'column',\n },\n content: {\n flex: '2 0 auto',\n },\n coverParent: {\n [theme.breakpoints.down('xs')]: {\n height: '8em',\n width: '8em',\n minWidth: '8em',\n },\n [theme.breakpoints.up('sm')]: {\n height: '10em',\n width: '10em',\n minWidth: '10em',\n },\n [theme.breakpoints.up('lg')]: {\n height: '15em',\n width: '15em',\n minWidth: '15em',\n },\n },\n cover: {\n objectFit: 'contain',\n cursor: 'pointer',\n display: 'block',\n width: '100%',\n height: '100%',\n },\n loveButton: {\n top: theme.spacing(-0.2),\n left: theme.spacing(0.5),\n },\n commentBlock: {\n display: 'inline-block',\n marginTop: '1em',\n float: 'left',\n wordBreak: 'break-word',\n },\n pointerCursor: {\n cursor: 'pointer',\n },\n recordName: {},\n recordArtist: {},\n recordMeta: {},\n genreList: {\n marginTop: theme.spacing(0.5),\n },\n externalLinks: {\n marginTop: theme.spacing(1.5),\n },\n }),\n {\n name: 'NDAlbumDetails',\n }\n)\n\nconst AlbumComment = ({ record }) => {\n const classes = useStyles()\n const [expanded, setExpanded] = React.useState(false)\n\n const lines = record.comment.split('\\n')\n const formatted = useMemo(() => {\n return lines.map((line, idx) => (\n <span key={record.id + '-comment-' + idx}>\n <span dangerouslySetInnerHTML={{ __html: line }} />\n <br />\n </span>\n ))\n }, [lines, record.id])\n\n const handleExpandClick = useCallback(() => {\n setExpanded(!expanded)\n }, [expanded, setExpanded])\n\n return (\n <Collapse\n collapsedHeight={'1.5em'}\n in={expanded}\n timeout={'auto'}\n className={clsx(\n classes.commentBlock,\n lines.length > 1 && classes.pointerCursor\n )}\n >\n <Typography variant={'body1'} onClick={handleExpandClick}>\n {formatted}\n </Typography>\n </Collapse>\n )\n}\n\nexport const useGetHandleGenreClick = (width) => {\n const [perPage] = useAlbumsPerPage(width)\n\n return (id) => {\n return `/album?filter={\"genre_id\":\"${id}\"}&order=ASC&sort=name&perPage=${perPage}`\n }\n}\n\nconst GenreChipField = withWidth()(({ width, ...rest }) => {\n const record = useRecordContext(rest)\n const genreLink = useGetHandleGenreClick(width)\n\n return (\n <Link to={genreLink(record.id)} onClick={(e) => e.stopPropagation()}>\n <ChipField\n source=\"name\"\n // Workaround to force ChipField to be clickable\n onClick={() => {}}\n />\n </Link>\n )\n})\n\nconst GenreList = () => {\n const classes = useStyles()\n return (\n <ArrayField className={classes.genreList} source={'genres'}>\n <SingleFieldList linkType={false}>\n <GenreChipField />\n </SingleFieldList>\n </ArrayField>\n )\n}\n\nconst Details = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const translate = useTranslate()\n const record = useRecordContext(props)\n let details = []\n const addDetail = (obj) => {\n const id = details.length\n details.push(<span key={`detail-${record.id}-${id}`}>{obj}</span>)\n }\n\n const year = formatRange(record, 'year')\n year && addDetail(<>{year}</>)\n addDetail(\n <>\n {record.songCount +\n ' ' +\n translate('resources.song.name', {\n smart_count: record.songCount,\n })}\n </>\n )\n !isXsmall && addDetail(<DurationField source={'duration'} />)\n !isXsmall && addDetail(<SizeField source=\"size\" />)\n\n return <>{intersperse(details, ' · ')}</>\n}\n\nconst AlbumDetails = (props) => {\n const record = useRecordContext(props)\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('lg'))\n const classes = useStyles()\n const [isLightboxOpen, setLightboxOpen] = React.useState(false)\n\n const imageUrl = subsonic.getCoverArtUrl(record, 300)\n const fullImageUrl = subsonic.getCoverArtUrl(record)\n\n const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])\n const handleCloseLightbox = React.useCallback(\n () => setLightboxOpen(false),\n []\n )\n return (\n <Card className={classes.root}>\n <div className={classes.cardContents}>\n <div className={classes.coverParent}>\n <CardMedia\n component={'img'}\n src={imageUrl}\n width=\"400\"\n height=\"400\"\n className={classes.cover}\n onClick={handleOpenLightbox}\n title={record.name}\n />\n </div>\n <div className={classes.details}>\n <CardContent className={classes.content}>\n <Typography\n variant={isDesktop ? 'h5' : 'h6'}\n className={classes.recordName}\n >\n {record.name}\n {config.enableFavourites && (\n <LoveButton\n className={classes.loveButton}\n record={record}\n resource={'album'}\n size={isDesktop ? 'default' : 'small'}\n aria-label=\"love\"\n color=\"primary\"\n />\n )}\n </Typography>\n <Typography component={'h6'} className={classes.recordArtist}>\n <ArtistLinkField record={record} />\n </Typography>\n <Typography component={'div'} className={classes.recordMeta}>\n <Details />\n </Typography>\n {config.enableStarRating && (\n <div>\n <RatingField\n record={record}\n resource={'album'}\n size={isDesktop ? 'medium' : 'small'}\n />\n </div>\n )}\n {isDesktop ? (\n <GenreList />\n ) : (\n <Typography component={'p'}>{record.genre}</Typography>\n )}\n {!isXsmall && (\n <Typography component={'div'} className={classes.recordMeta}>\n <AlbumExternalLinks className={classes.externalLinks} />\n </Typography>\n )}\n {isDesktop && record['comment'] && <AlbumComment record={record} />}\n </CardContent>\n </div>\n </div>\n {!isDesktop && record['comment'] && <AlbumComment record={record} />}\n {isLightboxOpen && (\n <Lightbox\n imagePadding={50}\n animationDuration={200}\n imageTitle={record.name}\n mainSrc={fullImageUrl}\n onCloseRequest={handleCloseLightbox}\n />\n )}\n </Card>\n )\n}\n\nexport default AlbumDetails\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport {\n Button,\n sanitizeListRestProps,\n TopToolbar,\n useTranslate,\n} from 'react-admin'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'\nimport { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'\nimport PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'\nimport {\n playNext,\n addTracks,\n playTracks,\n shuffleTracks,\n openAddToPlaylist,\n} from '../actions'\nimport subsonic from '../subsonic'\nimport { formatBytes } from '../utils'\nimport { useMediaQuery, makeStyles } from '@material-ui/core'\nimport config from '../config'\nimport { ToggleFieldsMenu } from '../common'\n\nconst useStyles = makeStyles({\n toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' },\n})\n\nconst AlbumActions = ({\n className,\n ids,\n data,\n record,\n permanentFilter,\n ...rest\n}) => {\n const dispatch = useDispatch()\n const translate = useTranslate()\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n\n const handlePlay = React.useCallback(() => {\n dispatch(playTracks(data, ids))\n }, [dispatch, data, ids])\n\n const handlePlayNext = React.useCallback(() => {\n dispatch(playNext(data, ids))\n }, [dispatch, data, ids])\n\n const handlePlayLater = React.useCallback(() => {\n dispatch(addTracks(data, ids))\n }, [dispatch, data, ids])\n\n const handleShuffle = React.useCallback(() => {\n dispatch(shuffleTracks(data, ids))\n }, [dispatch, data, ids])\n\n const handleAddToPlaylist = React.useCallback(() => {\n dispatch(openAddToPlaylist({ selectedIds: ids }))\n }, [dispatch, ids])\n\n const handleDownload = React.useCallback(() => {\n subsonic.download(record.id)\n }, [record])\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n <div className={classes.toolbar}>\n <div>\n <Button\n onClick={handlePlay}\n label={translate('resources.album.actions.playAll')}\n >\n <PlayArrowIcon />\n </Button>\n <Button\n onClick={handleShuffle}\n label={translate('resources.album.actions.shuffle')}\n >\n <ShuffleIcon />\n </Button>\n <Button\n onClick={handlePlayNext}\n label={translate('resources.album.actions.playNext')}\n >\n <RiPlayList2Fill />\n </Button>\n <Button\n onClick={handlePlayLater}\n label={translate('resources.album.actions.addToQueue')}\n >\n <RiPlayListAddFill />\n </Button>\n <Button\n onClick={handleAddToPlaylist}\n label={translate('resources.album.actions.addToPlaylist')}\n >\n <PlaylistAddIcon />\n </Button>\n {config.enableDownloads && (\n <Button\n onClick={handleDownload}\n label={\n translate('resources.album.actions.download') +\n (isDesktop ? ` (${formatBytes(record.size)})` : '')\n }\n >\n <CloudDownloadOutlinedIcon />\n </Button>\n )}\n </div>\n <div>{isNotSmall && <ToggleFieldsMenu resource=\"albumSong\" />}</div>\n </div>\n </TopToolbar>\n )\n}\n\nAlbumActions.propTypes = {\n record: PropTypes.object.isRequired,\n selectedIds: PropTypes.arrayOf(PropTypes.number),\n}\n\nAlbumActions.defaultProps = {\n record: {},\n selectedIds: [],\n onUnselectItems: () => null,\n}\n\nexport default AlbumActions\n","import React from 'react'\nimport {\n ReferenceManyField,\n ShowContextProvider,\n useShowContext,\n useShowController,\n} from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport AlbumSongs from './AlbumSongs'\nimport AlbumDetails from './AlbumDetails'\nimport AlbumActions from './AlbumActions'\n\nconst useStyles = makeStyles(\n (theme) => ({\n albumActions: {\n width: '100%',\n },\n }),\n {\n name: 'NDAlbumShow',\n }\n)\n\nconst AlbumShowLayout = (props) => {\n const { loading, ...context } = useShowContext(props)\n const { record } = context\n const classes = useStyles()\n\n return (\n <>\n {record && <AlbumDetails {...context} />}\n {record && (\n <ReferenceManyField\n {...context}\n addLabel={false}\n reference=\"song\"\n target=\"album_id\"\n sort={{ field: 'album', order: 'ASC' }}\n perPage={0}\n pagination={null}\n >\n <AlbumSongs\n resource={'song'}\n exporter={false}\n album={record}\n actions={\n <AlbumActions className={classes.albumActions} record={record} />\n }\n />\n </ReferenceManyField>\n )}\n </>\n )\n}\n\nconst AlbumShow = (props) => {\n const controllerProps = useShowController(props)\n return (\n <ShowContextProvider value={controllerProps}>\n <AlbumShowLayout {...props} {...controllerProps} />\n </ShowContextProvider>\n )\n}\n\nexport default AlbumShow\n","import AlbumList from './AlbumList'\nimport AlbumShow from './AlbumShow'\n\nexport default {\n list: AlbumList,\n show: AlbumShow,\n}\n","import React, { cloneElement } from 'react'\nimport { sanitizeListRestProps, TopToolbar } from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ToggleFieldsMenu } from '../common'\n\nconst ArtistListActions = ({\n className,\n filters,\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n ...rest\n}) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {filters &&\n cloneElement(filters, {\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n context: 'button',\n })}\n {isNotSmall && <ToggleFieldsMenu resource=\"artist\" />}\n </TopToolbar>\n )\n}\n\nexport default ArtistListActions\n","import React, { useMemo } from 'react'\nimport { useHistory } from 'react-router-dom'\nimport {\n AutocompleteInput,\n Datagrid,\n DatagridBody,\n DatagridRow,\n Filter,\n NumberField,\n ReferenceInput,\n SearchInput,\n TextField,\n useTranslate,\n} from 'react-admin'\nimport { useMediaQuery, withWidth } from '@material-ui/core'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useDrag } from 'react-dnd'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport {\n ArtistContextMenu,\n List,\n QuickFilter,\n useGetHandleArtistClick,\n ArtistSimpleList,\n RatingField,\n useSelectedFields,\n useResourceRefresh,\n} from '../common'\nimport config from '../config'\nimport ArtistListActions from './ArtistListActions'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles({\n contextHeader: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: 'hidden',\n },\n ratingField: {\n visibility: 'hidden',\n },\n})\n\nconst ArtistFilter = (props) => {\n const translate = useTranslate()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n <ReferenceInput\n label={translate('resources.artist.fields.genre')}\n source=\"genre_id\"\n reference=\"genre\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n {config.enableFavourites && (\n <QuickFilter\n source=\"starred\"\n label={<FavoriteIcon fontSize={'small'} />}\n defaultValue={true}\n />\n )}\n </Filter>\n )\n}\n\nconst ArtistDatagridRow = (props) => {\n const { record } = props\n const [, dragArtistRef] = useDrag(\n () => ({\n type: DraggableTypes.ARTIST,\n item: { artistIds: [record?.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n return <DatagridRow ref={dragArtistRef} {...props} />\n}\n\nconst ArtistDatagridBody = (props) => (\n <DatagridBody {...props} row={<ArtistDatagridRow />} />\n)\n\nconst ArtistDatagrid = (props) => (\n <Datagrid {...props} body={<ArtistDatagridBody />} />\n)\n\nconst ArtistListView = ({ hasShow, hasEdit, hasList, width, ...rest }) => {\n const classes = useStyles()\n const handleArtistLink = useGetHandleArtistClick(width)\n const history = useHistory()\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n useResourceRefresh('artist')\n\n const toggleableFields = useMemo(() => {\n return {\n albumCount: <NumberField source=\"albumCount\" sortByOrder={'DESC'} />,\n songCount: <NumberField source=\"songCount\" sortByOrder={'DESC'} />,\n playCount: <NumberField source=\"playCount\" sortByOrder={'DESC'} />,\n rating: config.enableStarRating && (\n <RatingField\n source=\"rating\"\n sortByOrder={'DESC'}\n resource={'artist'}\n className={classes.ratingField}\n />\n ),\n }\n }, [classes.ratingField])\n\n const columns = useSelectedFields({\n resource: 'artist',\n columns: toggleableFields,\n })\n\n return isXsmall ? (\n <ArtistSimpleList\n linkType={(id) => history.push(handleArtistLink(id))}\n {...rest}\n />\n ) : (\n <ArtistDatagrid rowClick={handleArtistLink} classes={{ row: classes.row }}>\n <TextField source=\"name\" />\n {columns}\n <ArtistContextMenu\n source={'starred'}\n sortBy={'starred ASC, starredAt ASC'}\n sortByOrder={'DESC'}\n sortable={config.enableFavourites}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.contextHeader}\n />\n )\n }\n />\n </ArtistDatagrid>\n )\n}\n\nconst ArtistList = (props) => {\n return (\n <>\n <List\n {...props}\n sort={{ field: 'name', order: 'ASC' }}\n exporter={false}\n bulkActionButtons={false}\n filters={<ArtistFilter />}\n actions={<ArtistListActions />}\n >\n <ArtistListView {...props} />\n </List>\n <AddToPlaylistDialog />\n </>\n )\n}\n\nexport default withWidth()(ArtistList)\n","import React, { useState } from 'react'\nimport { Typography, Collapse } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport Card from '@material-ui/core/Card'\nimport CardMedia from '@material-ui/core/CardMedia'\nimport config from '../config'\nimport { LoveButton, RatingField } from '../common'\nimport Lightbox from 'react-image-lightbox'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n display: 'flex',\n background: ({ img }) => `url(${img})`,\n },\n bgContainer: {\n display: 'flex',\n height: '15rem',\n width: '100vw',\n padding: 'unset',\n backdropFilter: 'blur(1px)',\n backgroundPosition: '50% 30%',\n background: `linear-gradient(to bottom, rgba(52 52 52 / 72%), rgba(21 21 21))`,\n },\n link: {\n margin: '1px',\n },\n details: {\n display: 'flex',\n alignItems: 'flex-start',\n flexDirection: 'column',\n justifyContent: 'center',\n marginLeft: '0.5rem',\n },\n biography: {\n display: 'flex',\n marginLeft: '3%',\n marginRight: '3%',\n marginTop: '-2em',\n zIndex: '1',\n '& p': {\n whiteSpace: ({ expanded }) => (expanded ? 'unset' : 'nowrap'),\n overflow: 'hidden',\n width: '95vw',\n textOverflow: 'ellipsis',\n },\n },\n cover: {\n width: 151,\n boxShadow: '0px 0px 6px 0px #565656',\n borderRadius: '5px',\n },\n artistImage: {\n marginLeft: '1em',\n maxHeight: '7rem',\n backgroundColor: 'inherit',\n marginTop: '4rem',\n width: '7rem',\n minWidth: '7rem',\n display: 'flex',\n borderRadius: '5em',\n },\n loveButton: {\n top: theme.spacing(-0.2),\n left: theme.spacing(0.5),\n },\n rating: {\n marginTop: '5px',\n },\n artistName: {\n wordBreak: 'break-word',\n },\n }),\n { name: 'NDMobileArtistDetails' }\n)\n\nconst MobileArtistDetails = ({ img, artistInfo, biography, record }) => {\n const [expanded, setExpanded] = useState(false)\n const classes = useStyles({ img, expanded })\n const title = record.name\n const [isLightboxOpen, setLightboxOpen] = React.useState(false)\n\n const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])\n const handleCloseLightbox = React.useCallback(\n () => setLightboxOpen(false),\n []\n )\n\n return (\n <>\n <div className={classes.root}>\n <div className={classes.bgContainer}>\n <Card className={classes.artistImage}>\n {artistInfo && (\n <CardMedia\n className={classes.cover}\n image={artistInfo.mediumImageUrl}\n onClick={handleOpenLightbox}\n title={title}\n />\n )}\n </Card>\n <div className={classes.details}>\n <Typography\n component=\"h5\"\n variant=\"h5\"\n className={classes.artistName}\n >\n {title}\n {config.enableFavourites && (\n <LoveButton\n className={classes.loveButton}\n record={record}\n resource={'artist'}\n size={'small'}\n aria-label=\"love\"\n color=\"primary\"\n />\n )}\n </Typography>\n {config.enableStarRating && (\n <RatingField\n record={record}\n resource={'artist'}\n size={'small'}\n className={classes.rating}\n />\n )}\n </div>\n </div>\n </div>\n <div className={classes.biography}>\n <Collapse collapsedHeight={'1.5em'} in={expanded} timeout={'auto'}>\n <Typography variant={'body1'} onClick={() => setExpanded(!expanded)}>\n <span dangerouslySetInnerHTML={{ __html: biography }} />\n </Typography>\n </Collapse>\n </div>\n {isLightboxOpen && (\n <Lightbox\n imagePadding={50}\n animationDuration={200}\n imageTitle={record.name}\n mainSrc={artistInfo.largeImageUrl}\n onCloseRequest={handleCloseLightbox}\n />\n )}\n </>\n )\n}\n\nexport default MobileArtistDetails\n","import React from 'react'\nimport { useTranslate } from 'react-admin'\nimport { IconButton, Tooltip, Link } from '@material-ui/core'\n\nimport { ImLastfm2 } from 'react-icons/im'\nimport MusicBrainz from '../icons/MusicBrainz'\nimport { intersperse } from '../utils'\n\nconst ArtistExternalLinks = ({ artistInfo, record }) => {\n const translate = useTranslate()\n let links = []\n let linkButtons = []\n const lastFMlink = artistInfo?.biography?.match(\n /<a\\s+(?:[^>]*?\\s+)?href=([\"'])(.*?)\\1/\n )\n\n if (lastFMlink) {\n links.push(lastFMlink[2])\n }\n if (artistInfo && artistInfo.musicBrainzId) {\n links.push(`https://musicbrainz.org/artist/${artistInfo.musicBrainzId}`)\n }\n\n const addLink = (url, title, icon) => {\n const translatedTitle = translate(title)\n const link = (\n <Link href={url} target=\"_blank\" rel=\"noopener noreferrer\">\n <Tooltip title={translatedTitle}>\n <IconButton size={'small'} aria-label={translatedTitle}>\n {icon}\n </IconButton>\n </Tooltip>\n </Link>\n )\n const id = linkButtons.length\n linkButtons.push(<span key={`link-${record.id}-${id}`}>{link}</span>)\n }\n\n addLink(links[0], 'message.openIn.lastfm', <ImLastfm2 />)\n artistInfo?.musicBrainzId &&\n addLink(links[1], 'message.openIn.musicbrainz', <MusicBrainz />)\n\n return <div>{intersperse(linkButtons, ' ')}</div>\n}\n\nexport default ArtistExternalLinks\n","import React, { useState } from 'react'\nimport { Typography, Collapse } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core'\nimport Card from '@material-ui/core/Card'\nimport CardContent from '@material-ui/core/CardContent'\nimport CardMedia from '@material-ui/core/CardMedia'\nimport ArtistExternalLinks from './ArtistExternalLink'\nimport config from '../config'\nimport { LoveButton, RatingField } from '../common'\nimport Lightbox from 'react-image-lightbox'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n display: 'flex',\n padding: '1em',\n },\n details: {\n display: 'flex',\n flex: '1',\n flexDirection: 'column',\n },\n biography: {\n display: 'inline-block',\n marginTop: '1em',\n float: 'left',\n wordBreak: 'break-word',\n cursor: 'pointer',\n },\n content: {\n flex: '1 0 auto',\n },\n cover: {\n width: 151,\n borderRadius: '6em',\n cursor: 'pointer',\n },\n artistImage: {\n maxHeight: '9.5rem',\n backgroundColor: 'inherit',\n display: 'flex',\n boxShadow: 'none',\n },\n artistDetail: {\n flex: '1',\n padding: '3%',\n display: 'flex',\n minHeight: '10rem',\n },\n button: {\n marginLeft: '0.9em',\n },\n loveButton: {\n top: theme.spacing(-0.2),\n left: theme.spacing(0.5),\n },\n rating: {\n marginTop: '5px',\n },\n artistName: {\n wordBreak: 'break-word',\n },\n }),\n { name: 'NDDesktopArtistDetails' }\n)\n\nconst DesktopArtistDetails = ({ img, artistInfo, record, biography }) => {\n const [expanded, setExpanded] = useState(false)\n const classes = useStyles({ img, expanded })\n const title = record.name\n const [isLightboxOpen, setLightboxOpen] = React.useState(false)\n\n const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])\n const handleCloseLightbox = React.useCallback(\n () => setLightboxOpen(false),\n []\n )\n\n return (\n <div className={classes.root}>\n <Card className={classes.artistDetail}>\n <Card className={classes.artistImage}>\n {artistInfo && (\n <CardMedia\n className={classes.cover}\n image={artistInfo.mediumImageUrl}\n onClick={handleOpenLightbox}\n title={title}\n />\n )}\n </Card>\n <div className={classes.details}>\n <CardContent className={classes.content}>\n <Typography\n component=\"h5\"\n variant=\"h5\"\n className={classes.artistName}\n >\n {title}\n {config.enableFavourites && (\n <LoveButton\n className={classes.loveButton}\n record={record}\n resource={'artist'}\n size={'default'}\n aria-label=\"love\"\n color=\"primary\"\n />\n )}\n </Typography>\n {config.enableStarRating && (\n <div>\n <RatingField\n record={record}\n resource={'artist'}\n size={'small'}\n className={classes.rating}\n />\n </div>\n )}\n <Collapse\n collapsedHeight={'4.5em'}\n in={expanded}\n timeout={'auto'}\n className={classes.biography}\n >\n <Typography\n variant={'body1'}\n onClick={() => setExpanded(!expanded)}\n >\n <span dangerouslySetInnerHTML={{ __html: biography }} />\n </Typography>\n </Collapse>\n </CardContent>\n <Typography component={'div'} className={classes.button}>\n <ArtistExternalLinks artistInfo={artistInfo} record={record} />\n </Typography>\n </div>\n {isLightboxOpen && (\n <Lightbox\n imagePadding={50}\n animationDuration={200}\n imageTitle={record.name}\n mainSrc={artistInfo.largeImageUrl}\n onCloseRequest={handleCloseLightbox}\n />\n )}\n </Card>\n </div>\n )\n}\n\nexport default DesktopArtistDetails\n","import React, { useState, createElement, useEffect } from 'react'\nimport { useMediaQuery } from '@material-ui/core'\nimport {\n useShowController,\n ShowContextProvider,\n useRecordContext,\n useShowContext,\n ReferenceManyField,\n} from 'react-admin'\nimport subsonic from '../subsonic'\nimport AlbumGridView from '../album/AlbumGridView'\nimport MobileArtistDetails from './MobileArtistDetails'\nimport DesktopArtistDetails from './DesktopArtistDetails'\n\nconst ArtistDetails = (props) => {\n const record = useRecordContext(props)\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n const [artistInfo, setArtistInfo] = useState()\n\n const biography =\n artistInfo?.biography?.replace(new RegExp('<.*>', 'g'), '') ||\n record.biography\n const img = artistInfo?.largeImageUrl || record.largeImageUrl\n\n useEffect(() => {\n subsonic\n .getArtistInfo(record.id)\n .then((resp) => resp.json['subsonic-response'])\n .then((data) => {\n if (data.status === 'ok') {\n setArtistInfo(data.artistInfo)\n }\n })\n .catch((e) => {\n console.error('error on artist page', e)\n })\n }, [record])\n\n const component = isDesktop ? DesktopArtistDetails : MobileArtistDetails\n return (\n <>\n {createElement(component, {\n img,\n artistInfo,\n record,\n biography,\n })}\n </>\n )\n}\n\nconst AlbumShowLayout = (props) => {\n const showContext = useShowContext(props)\n const record = useRecordContext()\n\n return (\n <>\n {record && <ArtistDetails />}\n {record && (\n <ReferenceManyField\n {...showContext}\n addLabel={false}\n reference=\"album\"\n target=\"artist_id\"\n sort={{ field: 'max_year', order: 'ASC' }}\n filter={{ artist_id: record?.id }}\n perPage={0}\n pagination={null}\n >\n <AlbumGridView {...props} />\n </ReferenceManyField>\n )}\n </>\n )\n}\n\nconst ArtistShow = (props) => {\n const controllerProps = useShowController(props)\n return (\n <ShowContextProvider value={controllerProps}>\n <AlbumShowLayout {...controllerProps} />\n </ShowContextProvider>\n )\n}\n\nexport default ArtistShow\n","import React from 'react'\nimport ArtistList from './ArtistList'\nimport ArtistShow from './ArtistShow'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\nimport MicNoneOutlinedIcon from '@material-ui/icons/MicNoneOutlined'\nimport MicIcon from '@material-ui/icons/Mic'\n\nexport default {\n list: ArtistList,\n show: ArtistShow,\n icon: (\n <DynamicMenuIcon\n path={'artist'}\n icon={MicNoneOutlinedIcon}\n activeIcon={MicIcon}\n />\n ),\n}\n","import React, { cloneElement } from 'react'\nimport {\n sanitizeListRestProps,\n TopToolbar,\n CreateButton,\n useTranslate,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ToggleFieldsMenu } from '../common'\n\nconst PlaylistListActions = ({ className, ...rest }) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n const translate = useTranslate()\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {cloneElement(rest.filters, { context: 'button' })}\n <CreateButton basePath=\"/playlist\">\n {translate('ra.action.create')}\n </CreateButton>\n {isNotSmall && <ToggleFieldsMenu resource=\"playlist\" />}\n </TopToolbar>\n )\n}\n\nexport default PlaylistListActions\n","import * as React from 'react'\nimport { LockOpen, Lock } from '@material-ui/icons'\nimport { BulkUpdateButton, useTranslate } from 'react-admin'\n\nconst ChangePublicStatusButton = (props) => {\n const translate = useTranslate()\n const playlists = { public: props?.public }\n const label = props?.public\n ? translate('resources.playlist.actions.makePublic')\n : translate('resources.playlist.actions.makePrivate')\n const icon = props?.public ? <LockOpen /> : <Lock />\n return (\n <BulkUpdateButton {...props} data={playlists} label={label} icon={icon} />\n )\n}\n\nexport default ChangePublicStatusButton\n","import React, { useMemo } from 'react'\nimport {\n Datagrid,\n DateField,\n EditButton,\n Filter,\n NumberField,\n ReferenceInput,\n SearchInput,\n SelectInput,\n TextField,\n useUpdate,\n useNotify,\n useRecordContext,\n BulkDeleteButton,\n usePermissions,\n} from 'react-admin'\nimport Switch from '@material-ui/core/Switch'\nimport { useMediaQuery } from '@material-ui/core'\nimport {\n DurationField,\n List,\n Writable,\n isWritable,\n useSelectedFields,\n useResourceRefresh,\n} from '../common'\nimport PlaylistListActions from './PlaylistListActions'\nimport ChangePublicStatusButton from './ChangePublicStatusButton'\n\nconst PlaylistFilter = (props) => {\n const { permissions } = usePermissions()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"q\" alwaysOn />\n {permissions === 'admin' && (\n <ReferenceInput\n source=\"owner_id\"\n label={'resources.playlist.fields.ownerName'}\n reference=\"user\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n alwaysOn\n >\n <SelectInput optionText=\"name\" />\n </ReferenceInput>\n )}\n </Filter>\n )\n}\n\nconst TogglePublicInput = ({ resource, source }) => {\n const record = useRecordContext()\n const notify = useNotify()\n const [togglePublic] = useUpdate(\n resource,\n record.id,\n {\n ...record,\n public: !record.public,\n },\n {\n undoable: false,\n onFailure: (error) => {\n console.log(error)\n notify('ra.page.error', 'warning')\n },\n }\n )\n\n const handleClick = (e) => {\n togglePublic()\n e.stopPropagation()\n }\n\n return (\n <Switch\n checked={record[source]}\n onClick={handleClick}\n disabled={!isWritable(record.ownerId)}\n />\n )\n}\n\nconst PlaylistListBulkActions = (props) => (\n <>\n <ChangePublicStatusButton public={true} {...props} />\n <ChangePublicStatusButton public={false} {...props} />\n <BulkDeleteButton {...props} />\n </>\n)\n\nconst PlaylistList = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n useResourceRefresh('playlist')\n\n const toggleableFields = useMemo(\n () => ({\n ownerName: isDesktop && <TextField source=\"ownerName\" />,\n songCount: !isXsmall && <NumberField source=\"songCount\" />,\n duration: <DurationField source=\"duration\" />,\n updatedAt: isDesktop && (\n <DateField source=\"updatedAt\" sortByOrder={'DESC'} />\n ),\n public: !isXsmall && (\n <TogglePublicInput source=\"public\" sortByOrder={'DESC'} />\n ),\n }),\n [isDesktop, isXsmall]\n )\n\n const columns = useSelectedFields({\n resource: 'playlist',\n columns: toggleableFields,\n })\n\n return (\n <List\n {...props}\n exporter={false}\n filters={<PlaylistFilter />}\n actions={<PlaylistListActions />}\n bulkActionButtons={!isXsmall && <PlaylistListBulkActions />}\n >\n <Datagrid rowClick=\"show\" isRowSelectable={(r) => isWritable(r?.ownerId)}>\n <TextField source=\"name\" />\n {columns}\n <Writable>\n <EditButton />\n </Writable>\n </Datagrid>\n </List>\n )\n}\n\nexport default PlaylistList\n","import React, { Fragment } from 'react'\n\nimport {\n Edit,\n FormDataConsumer,\n SimpleForm,\n TextInput,\n TextField,\n BooleanInput,\n required,\n useTranslate,\n usePermissions,\n ReferenceInput,\n SelectInput,\n} from 'react-admin'\nimport { isWritable, Title } from '../common'\n\nconst SyncFragment = ({ formData, variant, ...rest }) => {\n return (\n <Fragment>\n {formData.path && <BooleanInput source=\"sync\" {...rest} />}\n {formData.path && <TextField source=\"path\" {...rest} />}\n </Fragment>\n )\n}\n\nconst PlaylistTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.playlist.name', { smart_count: 1 })\n return <Title subTitle={`${resourceName} \"${record ? record.name : ''}\"`} />\n}\n\nconst PlaylistEditForm = (props) => {\n const { record } = props\n const { permissions } = usePermissions()\n return (\n <SimpleForm redirect=\"list\" variant={'outlined'} {...props}>\n <TextInput source=\"name\" validate={required()} />\n <TextInput multiline source=\"comment\" />\n {permissions === 'admin' ? (\n <ReferenceInput\n source=\"ownerId\"\n reference=\"user\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n >\n <SelectInput\n label={'resources.playlist.fields.ownerName'}\n optionText=\"userName\"\n />\n </ReferenceInput>\n ) : (\n <TextField source=\"ownerName\" />\n )}\n <BooleanInput source=\"public\" disabled={!isWritable(record.ownerId)} />\n <FormDataConsumer>\n {(formDataProps) => <SyncFragment {...formDataProps} />}\n </FormDataConsumer>\n </SimpleForm>\n )\n}\n\nconst PlaylistEdit = (props) => (\n <Edit title={<PlaylistTitle />} actions={false} {...props}>\n <PlaylistEditForm {...props} />\n </Edit>\n)\n\nexport default PlaylistEdit\n","import React from 'react'\nimport {\n Create,\n SimpleForm,\n TextInput,\n BooleanInput,\n required,\n useTranslate,\n useRefresh,\n useNotify,\n useRedirect,\n} from 'react-admin'\nimport { Title } from '../common'\n\nconst PlaylistCreate = (props) => {\n const { basePath } = props\n const refresh = useRefresh()\n const notify = useNotify()\n const redirect = useRedirect()\n const translate = useTranslate()\n const resourceName = translate('resources.playlist.name', { smart_count: 1 })\n const title = translate('ra.page.create', {\n name: `${resourceName}`,\n })\n\n const onSuccess = () => {\n notify('ra.notification.created', 'info', { smart_count: 1 })\n redirect('list', basePath)\n refresh()\n }\n\n return (\n <Create title={<Title subTitle={title} />} {...props} onSuccess={onSuccess}>\n <SimpleForm redirect=\"list\" variant={'outlined'}>\n <TextInput source=\"name\" validate={required()} />\n <TextInput multiline source=\"comment\" />\n <BooleanInput source=\"public\" initialValue={true} />\n </SimpleForm>\n </Create>\n )\n}\n\nexport default PlaylistCreate\n","import React from 'react'\nimport { Card, CardContent, Typography } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useTranslate } from 'react-admin'\nimport { DurationField, SizeField } from '../common'\n\nconst useStyles = makeStyles(\n (theme) => ({\n container: {\n [theme.breakpoints.down('xs')]: {\n padding: '0.7em',\n minWidth: '24em',\n },\n [theme.breakpoints.up('sm')]: {\n padding: '1em',\n minWidth: '32em',\n },\n },\n details: {\n display: 'inline-block',\n verticalAlign: 'top',\n [theme.breakpoints.down('xs')]: {\n width: '14em',\n },\n [theme.breakpoints.up('sm')]: {\n width: '26em',\n },\n [theme.breakpoints.up('lg')]: {\n width: '38em',\n },\n },\n title: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n }),\n {\n name: 'NDPlaylistDetails',\n }\n)\n\nconst PlaylistDetails = (props) => {\n const { record = {} } = props\n const translate = useTranslate()\n const classes = useStyles()\n\n return (\n <Card className={classes.container}>\n <CardContent className={classes.details}>\n <Typography variant=\"h5\" className={classes.title}>\n {record.name || translate('ra.page.loading')}\n </Typography>\n <Typography component=\"h6\">{record.comment}</Typography>\n <Typography component=\"p\">\n {record.songCount ? (\n <span>\n {record.songCount}{' '}\n {translate('resources.song.name', {\n smart_count: record.songCount,\n })}\n {' · '}\n <DurationField record={record} source={'duration'} />\n {' · '}\n <SizeField record={record} source={'size'} />\n </span>\n ) : (\n <span> </span>\n )}\n </Typography>\n </CardContent>\n </Card>\n )\n}\n\nexport default PlaylistDetails\n","import React, { Fragment, useEffect } from 'react'\nimport {\n BulkDeleteButton,\n useUnselectAll,\n ResourceContextProvider,\n} from 'react-admin'\nimport PropTypes from 'prop-types'\n\n// Replace original resource with \"fake\" one for removing tracks from playlist\nconst PlaylistSongBulkActions = ({\n playlistId,\n resource,\n onUnselectItems,\n ...rest\n}) => {\n const unselectAll = useUnselectAll()\n useEffect(() => {\n unselectAll('playlistTrack')\n }, [unselectAll])\n\n const mappedResource = `playlist/${playlistId}/tracks`\n return (\n <ResourceContextProvider value={mappedResource}>\n <Fragment>\n <BulkDeleteButton\n {...rest}\n resource={mappedResource}\n onClick={onUnselectItems}\n />\n </Fragment>\n </ResourceContextProvider>\n )\n}\n\nPlaylistSongBulkActions.propTypes = {\n playlistId: PropTypes.string.isRequired,\n}\n\nexport default PlaylistSongBulkActions\n","import React, { useCallback, useMemo } from 'react'\nimport {\n BulkActionsToolbar,\n ListToolbar,\n TextField,\n NumberField,\n useDataProvider,\n useNotify,\n useVersion,\n useListContext,\n FunctionField,\n} from 'react-admin'\nimport clsx from 'clsx'\nimport { useDispatch } from 'react-redux'\nimport { Card, useMediaQuery } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport ReactDragListView from 'react-drag-listview'\nimport {\n DurationField,\n SongInfo,\n SongContextMenu,\n SongDatagrid,\n SongTitleField,\n QualityInfo,\n useSelectedFields,\n useResourceRefresh,\n DateField,\n ArtistLinkField,\n} from '../common'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport { AlbumLinkField } from '../song/AlbumLinkField'\nimport { playTracks } from '../actions'\nimport PlaylistSongBulkActions from './PlaylistSongBulkActions'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {},\n main: {\n display: 'flex',\n },\n content: {\n marginTop: 0,\n transition: theme.transitions.create('margin-top'),\n position: 'relative',\n flex: '1 1 auto',\n [theme.breakpoints.down('xs')]: {\n boxShadow: 'none',\n },\n },\n bulkActionsDisplayed: {\n marginTop: -theme.spacing(8),\n transition: theme.transitions.create('margin-top'),\n },\n actions: {\n zIndex: 2,\n display: 'flex',\n justifyContent: 'flex-end',\n flexWrap: 'wrap',\n },\n noResults: { padding: 20 },\n toolbar: {\n justifyContent: 'flex-start',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: (props) => (props.isDesktop ? 'hidden' : 'visible'),\n },\n }),\n { name: 'RaList' }\n)\n\nconst ReorderableList = ({ readOnly, children, ...rest }) => {\n if (readOnly) {\n return children\n }\n return <ReactDragListView {...rest}>{children}</ReactDragListView>\n}\n\nconst PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {\n const listContext = useListContext()\n const { data, ids, selectedIds, onUnselectItems, refetch } = listContext\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const dispatch = useDispatch()\n const dataProvider = useDataProvider()\n const notify = useNotify()\n const version = useVersion()\n useResourceRefresh('song', 'playlist')\n\n const onAddToPlaylist = useCallback(\n (pls) => {\n if (pls.id === playlistId) {\n refetch()\n }\n },\n [playlistId, refetch]\n )\n\n const reorder = useCallback(\n (playlistId, id, newPos) => {\n dataProvider\n .update('playlistTrack', {\n id,\n data: { insert_before: newPos },\n filter: { playlist_id: playlistId },\n })\n .then(() => {\n refetch()\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n },\n [dataProvider, notify, refetch]\n )\n\n const handleDragEnd = useCallback(\n (from, to) => {\n const toId = ids[to]\n const fromId = ids[from]\n reorder(playlistId, fromId, toId)\n },\n [playlistId, reorder, ids]\n )\n\n const toggleableFields = useMemo(() => {\n return {\n trackNumber: isDesktop && <TextField source=\"id\" label={'#'} />,\n title: <SongTitleField source=\"title\" showTrackNumbers={false} />,\n album: isDesktop && <AlbumLinkField source=\"album\" />,\n artist: isDesktop && <ArtistLinkField source=\"artist\" />,\n albumArtist: isDesktop && <ArtistLinkField source=\"albumArtist\" />,\n duration: (\n <DurationField source=\"duration\" className={classes.draggable} />\n ),\n year: isDesktop && (\n <FunctionField\n source=\"year\"\n render={(r) => r.year || ''}\n sortByOrder={'DESC'}\n />\n ),\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortByOrder={'DESC'} />\n ),\n playDate: <DateField source=\"playDate\" sortByOrder={'DESC'} showTime />,\n quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n channels: isDesktop && <NumberField source=\"channels\" />,\n bpm: isDesktop && <NumberField source=\"bpm\" />,\n }\n }, [isDesktop, classes.draggable])\n\n const columns = useSelectedFields({\n resource: 'playlistTrack',\n columns: toggleableFields,\n defaultOff: [\n 'channels',\n 'bpm',\n 'year',\n 'playCount',\n 'playDate',\n 'albumArtist',\n ],\n })\n\n return (\n <>\n <ListToolbar\n classes={{ toolbar: classes.toolbar }}\n filters={props.filters}\n actions={actions}\n />\n <div className={classes.main}>\n <Card\n className={clsx(classes.content, {\n [classes.bulkActionsDisplayed]: selectedIds.length > 0,\n })}\n key={version}\n >\n <BulkActionsToolbar>\n <PlaylistSongBulkActions\n playlistId={playlistId}\n onUnselectItems={onUnselectItems}\n readOnly={readOnly}\n />\n </BulkActionsToolbar>\n <ReorderableList\n readOnly={readOnly}\n onDragEnd={handleDragEnd}\n nodeSelector={'tr'}\n >\n <SongDatagrid\n rowClick={(id) => dispatch(playTracks(data, ids, id))}\n {...listContext}\n hasBulkActions={!readOnly}\n contextAlwaysVisible={!isDesktop}\n classes={{ row: classes.row }}\n >\n {columns}\n <SongContextMenu\n onAddToPlaylist={onAddToPlaylist}\n showLove={false}\n className={classes.contextMenu}\n />\n </SongDatagrid>\n </ReorderableList>\n </Card>\n </div>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<SongInfo />} />\n {React.cloneElement(props.pagination, listContext)}\n </>\n )\n}\n\nconst SanitizedPlaylistSongs = (props) => {\n const { loaded, ...rest } = props\n return (\n <>\n {loaded && (\n <PlaylistSongs\n playlistId={props.id}\n actions={props.actions}\n pagination={props.pagination}\n {...rest}\n />\n )}\n </>\n )\n}\n\nexport default SanitizedPlaylistSongs\n","import React from 'react'\nimport { useDispatch } from 'react-redux'\nimport {\n Button,\n sanitizeListRestProps,\n TopToolbar,\n useTranslate,\n useDataProvider,\n useNotify,\n} from 'react-admin'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'\nimport { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'\nimport QueueMusicIcon from '@material-ui/icons/QueueMusic'\nimport { httpClient } from '../dataProvider'\nimport { playNext, addTracks, playTracks, shuffleTracks } from '../actions'\nimport { M3U_MIME_TYPE, REST_URL } from '../consts'\nimport subsonic from '../subsonic'\nimport PropTypes from 'prop-types'\nimport { formatBytes } from '../utils'\nimport { useMediaQuery, makeStyles } from '@material-ui/core'\nimport config from '../config'\nimport { ToggleFieldsMenu } from '../common'\n\nconst useStyles = makeStyles({\n toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' },\n})\n\nconst PlaylistActions = ({ className, ids, data, record, ...rest }) => {\n const dispatch = useDispatch()\n const translate = useTranslate()\n const classes = useStyles()\n const dataProvider = useDataProvider()\n const notify = useNotify()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n\n const getAllSongsAndDispatch = React.useCallback(\n (action) => {\n if (ids?.length === record.songCount) {\n return dispatch(action(data, ids))\n }\n\n dataProvider\n .getList('playlistTrack', {\n pagination: { page: 1, perPage: 0 },\n sort: { field: 'id', order: 'ASC' },\n filter: { playlist_id: record.id },\n })\n .then((res) => {\n const data = res.data.reduce(\n (acc, curr) => ({ ...acc, [curr.id]: curr }),\n {}\n )\n dispatch(action(data))\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n },\n [dataProvider, dispatch, record, data, ids, notify]\n )\n\n const handlePlay = React.useCallback(() => {\n getAllSongsAndDispatch(playTracks)\n }, [getAllSongsAndDispatch])\n\n const handlePlayNext = React.useCallback(() => {\n getAllSongsAndDispatch(playNext)\n }, [getAllSongsAndDispatch])\n\n const handlePlayLater = React.useCallback(() => {\n getAllSongsAndDispatch(addTracks)\n }, [getAllSongsAndDispatch])\n\n const handleShuffle = React.useCallback(() => {\n getAllSongsAndDispatch(shuffleTracks)\n }, [getAllSongsAndDispatch])\n\n const handleDownload = React.useCallback(() => {\n subsonic.download(record.id)\n }, [record])\n\n const handleExport = React.useCallback(\n () =>\n httpClient(`${REST_URL}/playlist/${record.id}/tracks`, {\n headers: new Headers({ Accept: M3U_MIME_TYPE }),\n }).then((res) => {\n const blob = new Blob([res.body], { type: M3U_MIME_TYPE })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `${record.name}.m3u`\n document.body.appendChild(link)\n link.click()\n link.parentNode.removeChild(link)\n }),\n [record]\n )\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n <div className={classes.toolbar}>\n <div>\n <Button\n onClick={handlePlay}\n label={translate('resources.album.actions.playAll')}\n >\n <PlayArrowIcon />\n </Button>\n <Button\n onClick={handleShuffle}\n label={translate('resources.album.actions.shuffle')}\n >\n <ShuffleIcon />\n </Button>\n <Button\n onClick={handlePlayNext}\n label={translate('resources.album.actions.playNext')}\n >\n <RiPlayList2Fill />\n </Button>\n <Button\n onClick={handlePlayLater}\n label={translate('resources.album.actions.addToQueue')}\n >\n <RiPlayListAddFill />\n </Button>\n {config.enableDownloads && (\n <Button\n onClick={handleDownload}\n label={\n translate('resources.album.actions.download') +\n (isDesktop ? ` (${formatBytes(record.size)})` : '')\n }\n >\n <CloudDownloadOutlinedIcon />\n </Button>\n )}\n <Button\n onClick={handleExport}\n label={translate('resources.playlist.actions.export')}\n >\n <QueueMusicIcon />\n </Button>\n </div>\n <div>{isNotSmall && <ToggleFieldsMenu resource=\"playlistTrack\" />}</div>\n </div>\n </TopToolbar>\n )\n}\n\nPlaylistActions.propTypes = {\n record: PropTypes.object.isRequired,\n selectedIds: PropTypes.arrayOf(PropTypes.number),\n}\n\nPlaylistActions.defaultProps = {\n record: {},\n selectedIds: [],\n onUnselectItems: () => null,\n}\n\nexport default PlaylistActions\n","import React from 'react'\nimport {\n ReferenceManyField,\n ShowContextProvider,\n useShowContext,\n useShowController,\n Pagination,\n} from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport PlaylistDetails from './PlaylistDetails'\nimport PlaylistSongs from './PlaylistSongs'\nimport PlaylistActions from './PlaylistActions'\nimport { Title, canChangeTracks } from '../common'\n\nconst useStyles = makeStyles(\n (theme) => ({\n playlistActions: {\n width: '100%',\n },\n }),\n {\n name: 'NDPlaylistShow',\n }\n)\n\nconst PlaylistShowLayout = (props) => {\n const { loading, ...context } = useShowContext(props)\n const { record } = context\n const classes = useStyles()\n\n return (\n <>\n {record && <PlaylistDetails {...context} />}\n {record && (\n <ReferenceManyField\n {...context}\n addLabel={false}\n reference=\"playlistTrack\"\n target=\"playlist_id\"\n sort={{ field: 'id', order: 'ASC' }}\n perPage={100}\n filter={{ playlist_id: props.id }}\n >\n <PlaylistSongs\n {...props}\n readOnly={!canChangeTracks(record)}\n title={<Title subTitle={record.name} />}\n actions={\n <PlaylistActions\n className={classes.playlistActions}\n record={record}\n />\n }\n resource={'playlistTrack'}\n exporter={false}\n pagination={<Pagination rowsPerPageOptions={[100, 250, 500]} />}\n />\n </ReferenceManyField>\n )}\n </>\n )\n}\n\nconst PlaylistShow = (props) => {\n const controllerProps = useShowController(props)\n return (\n <ShowContextProvider value={controllerProps}>\n <PlaylistShowLayout {...props} {...controllerProps} />\n </ShowContextProvider>\n )\n}\n\nexport default PlaylistShow\n","import React from 'react'\nimport QueueMusicOutlinedIcon from '@material-ui/icons/QueueMusicOutlined'\nimport QueueMusicIcon from '@material-ui/icons/QueueMusic'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\nimport PlaylistList from './PlaylistList'\nimport PlaylistEdit from './PlaylistEdit'\nimport PlaylistCreate from './PlaylistCreate'\nimport PlaylistShow from './PlaylistShow'\n\nexport default {\n list: PlaylistList,\n create: PlaylistCreate,\n edit: PlaylistEdit,\n show: PlaylistShow,\n icon: (\n <DynamicMenuIcon\n path={'playlist'}\n icon={QueueMusicOutlinedIcon}\n activeIcon={QueueMusicIcon}\n />\n ),\n}\n","import { makeStyles } from '@material-ui/core/styles'\n\nconst useStyle = makeStyles(\n (theme) => ({\n audioTitle: {\n textDecoration: 'none',\n color: theme.palette.primary.dark,\n },\n songTitle: {\n fontWeight: 'bold',\n '&:hover + $qualityInfo': {\n opacity: 1,\n },\n },\n songInfo: {\n display: 'block',\n marginTop: '2px',\n },\n songAlbum: {\n fontStyle: 'italic',\n fontSize: 'smaller',\n },\n qualityInfo: {\n marginTop: '-4px',\n opacity: 0,\n transition: 'all 500ms ease-out',\n },\n player: {\n display: (props) => (props.visible ? 'block' : 'none'),\n '@media screen and (max-width:810px)': {\n '& .sound-operation': {\n display: 'none',\n },\n },\n '& .progress-bar-content': {\n display: 'flex',\n flexDirection: 'column',\n },\n '& .play-mode-title': {\n 'pointer-events': 'none',\n },\n '& .music-player-panel .panel-content div.img-rotate': {\n // Customize desktop player when cover animation is disabled\n animationDuration: (props) => !props.enableCoverAnimation && '0s',\n borderRadius: (props) => !props.enableCoverAnimation && '0',\n // Fix cover display when image is not square\n backgroundSize: 'contain',\n backgroundPosition: 'center',\n },\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-cover':\n {\n // Customize mobile player when cover animation is disabled\n borderRadius: (props) => !props.enableCoverAnimation && '0',\n width: (props) => !props.enableCoverAnimation && '85%',\n maxWidth: (props) => !props.enableCoverAnimation && '600px',\n height: (props) => !props.enableCoverAnimation && 'auto',\n // Fix cover display when image is not square\n aspectRatio: '1/1',\n display: 'flex',\n },\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-cover img.cover':\n {\n animationDuration: (props) => !props.enableCoverAnimation && '0s',\n objectFit: 'contain', // Fix cover display when image is not square\n },\n // Hide old singer display\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-singer':\n {\n display: 'none',\n },\n // Hide extra whitespace from switch div\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-switch':\n {\n display: 'none',\n },\n },\n }),\n { name: 'NDAudioPlayer' }\n)\n\nexport default useStyle\n","import React from 'react'\nimport { useMediaQuery } from '@material-ui/core'\nimport { Link } from 'react-router-dom'\nimport clsx from 'clsx'\nimport { QualityInfo } from '../common'\nimport useStyle from './styles'\n\nconst AudioTitle = React.memo(({ audioInfo, isMobile }) => {\n const classes = useStyle()\n const className = classes.audioTitle\n const isDesktop = useMediaQuery('(min-width:810px)')\n\n if (!audioInfo.song) {\n return ''\n }\n\n const song = audioInfo.song\n const qi = { suffix: song.suffix, bitRate: song.bitRate }\n\n return (\n <Link to={`/album/${song.albumId}/show`} className={className}>\n <span>\n <span className={clsx(classes.songTitle, 'songTitle')}>\n {song.title}\n </span>\n {isDesktop && (\n <QualityInfo record={qi} className={classes.qualityInfo} />\n )}\n </span>\n {isMobile ? (\n <>\n <span className={classes.songInfo}>\n <span className={'songArtist'}>{song.artist}</span>\n </span>\n <span className={clsx(classes.songInfo, classes.songAlbum)}>\n <span className={'songAlbum'}>{song.album}</span>\n {song.year ? ` - ${song.year}` : ''}\n </span>\n </>\n ) : (\n <span className={classes.songInfo}>\n <span className={'songArtist'}>{song.artist}</span> -{' '}\n <span className={'songAlbum'}>{song.album}</span>\n {song.year ? ` - ${song.year}` : ''}\n </span>\n )}\n </Link>\n )\n})\n\nexport default AudioTitle\n","import React, { useCallback } from 'react'\nimport { useGetOne } from 'react-admin'\nimport { GlobalHotKeys } from 'react-hotkeys'\nimport { LoveButton, useToggleLove } from '../common'\nimport { keyMap } from '../hotkeys'\nimport config from '../config'\n\nconst Placeholder = () =>\n config.enableFavourites && <LoveButton disabled={true} resource={'song'} />\n\nconst Toolbar = ({ id }) => {\n const { data, loading } = useGetOne('song', id)\n const [toggleLove, toggling] = useToggleLove('song', data)\n\n const handlers = {\n TOGGLE_LOVE: useCallback(() => toggleLove(), [toggleLove]),\n }\n return (\n <>\n <GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />\n {config.enableFavourites && (\n <LoveButton\n record={data}\n resource={'song'}\n disabled={loading || toggling}\n />\n )}\n </>\n )\n}\n\nconst PlayerToolbar = ({ id }) => (id ? <Toolbar id={id} /> : <Placeholder />)\n\nexport default PlayerToolbar\n","const locale = (translate) => ({\n playListsText: translate('player.playListsText'),\n openText: translate('player.openText'),\n closeText: translate('player.closeText'),\n notContentText: translate('player.notContentText'),\n clickToPlayText: translate('player.clickToPlayText'),\n clickToPauseText: translate('player.clickToPauseText'),\n nextTrackText: translate('player.nextTrackText'),\n previousTrackText: translate('player.previousTrackText'),\n reloadText: translate('player.reloadText'),\n volumeText: translate('player.volumeText'),\n toggleLyricText: translate('player.toggleLyricText'),\n toggleMiniModeText: translate('player.toggleMiniModeText'),\n destroyText: translate('player.destroyText'),\n downloadText: translate('player.downloadText'),\n removeAudioListsText: translate('player.removeAudioListsText'),\n clickToDeleteText: (name) => translate('player.clickToDeleteText', { name }),\n emptyLyricText: translate('player.emptyLyricText'),\n playModeText: {\n order: translate('player.playModeText.order'),\n orderLoop: translate('player.playModeText.orderLoop'),\n singleLoop: translate('player.playModeText.singleLoop'),\n shufflePlay: translate('player.playModeText.shufflePlay'),\n },\n})\n\nexport default locale\n","const keyHandlers = (audioInstance, playerState) => {\n const nextSong = () => {\n const idx = playerState.queue.findIndex(\n (item) => item.uuid === playerState.current.uuid\n )\n return idx !== null ? playerState.queue[idx + 1] : null\n }\n\n const prevSong = () => {\n const idx = playerState.queue.findIndex(\n (item) => item.uuid === playerState.current.uuid\n )\n return idx !== null ? playerState.queue[idx - 1] : null\n }\n\n return {\n TOGGLE_PLAY: (e) => {\n e.preventDefault()\n audioInstance && audioInstance.togglePlay()\n },\n VOL_UP: () =>\n (audioInstance.volume = Math.min(1, audioInstance.volume + 0.1)),\n VOL_DOWN: () =>\n (audioInstance.volume = Math.max(0, audioInstance.volume - 0.1)),\n PREV_SONG: (e) => {\n if (!e.metaKey && prevSong()) audioInstance && audioInstance.playPrev()\n },\n\n NEXT_SONG: (e) => {\n if (!e.metaKey && nextSong()) audioInstance && audioInstance.playNext()\n },\n }\n}\n\nexport default keyHandlers\n","import React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ThemeProvider } from '@material-ui/core/styles'\nimport {\n createMuiTheme,\n useAuthState,\n useDataProvider,\n useTranslate,\n} from 'react-admin'\nimport ReactGA from 'react-ga'\nimport { GlobalHotKeys } from 'react-hotkeys'\nimport ReactJkMusicPlayer from 'react-jinke-music-player'\nimport 'react-jinke-music-player/assets/index.css'\nimport useCurrentTheme from '../themes/useCurrentTheme'\nimport config from '../config'\nimport useStyle from './styles'\nimport AudioTitle from './AudioTitle'\nimport { clearQueue, currentPlaying, setVolume, syncQueue } from '../actions'\nimport PlayerToolbar from './PlayerToolbar'\nimport { sendNotification } from '../utils'\nimport subsonic from '../subsonic'\nimport locale from './locale'\nimport { keyMap } from '../hotkeys'\nimport keyHandlers from './keyHandlers'\n\nconst Player = () => {\n const theme = useCurrentTheme()\n const translate = useTranslate()\n const playerTheme = theme.player?.theme || 'dark'\n const dataProvider = useDataProvider()\n const playerState = useSelector((state) => state.player)\n const dispatch = useDispatch()\n const [startTime, setStartTime] = useState(null)\n const [scrobbled, setScrobbled] = useState(false)\n const [preloaded, setPreload] = useState(false)\n const [audioInstance, setAudioInstance] = useState(null)\n const isDesktop = useMediaQuery('(min-width:810px)')\n const isMobilePlayer = useMediaQuery(\n '(max-width: 768px) and (orientation : portrait)'\n )\n const { authenticated } = useAuthState()\n const visible = authenticated && playerState.queue.length > 0\n const classes = useStyle({\n visible,\n enableCoverAnimation: config.enableCoverAnimation,\n })\n const showNotifications = useSelector(\n (state) => state.settings.notifications || false\n )\n\n const defaultOptions = useMemo(\n () => ({\n theme: playerTheme,\n bounds: 'body',\n mode: 'full',\n loadAudioErrorPlayNext: false,\n autoPlayInitLoadPlayList: true,\n clearPriorAudioLists: false,\n showDestroy: true,\n showDownload: false,\n showLyric: true,\n showReload: false,\n toggleMode: !isDesktop,\n glassBg: false,\n showThemeSwitch: false,\n showMediaSession: true,\n restartCurrentOnPrev: true,\n quietUpdate: true,\n defaultPosition: {\n top: 300,\n left: 120,\n },\n volumeFade: { fadeIn: 200, fadeOut: 200 },\n renderAudioTitle: (audioInfo, isMobile) => (\n <AudioTitle audioInfo={audioInfo} isMobile={isMobile} />\n ),\n locale: locale(translate),\n }),\n [isDesktop, playerTheme, translate]\n )\n\n const options = useMemo(() => {\n const current = playerState.current || {}\n return {\n ...defaultOptions,\n audioLists: playerState.queue.map((item) => item),\n playIndex: playerState.playIndex,\n autoPlay: playerState.clear || playerState.playIndex === 0,\n clearPriorAudioLists: playerState.clear,\n extendsContent: <PlayerToolbar id={current.trackId} />,\n defaultVolume: isMobilePlayer ? 1 : playerState.volume,\n }\n }, [playerState, defaultOptions, isMobilePlayer])\n\n const onAudioListsChange = useCallback(\n (_, audioLists, audioInfo) => dispatch(syncQueue(audioInfo, audioLists)),\n [dispatch]\n )\n\n const nextSong = useCallback(() => {\n const idx = playerState.queue.findIndex(\n (item) => item.uuid === playerState.current.uuid\n )\n return idx !== null ? playerState.queue[idx + 1] : null\n }, [playerState])\n\n const onAudioProgress = useCallback(\n (info) => {\n if (info.ended) {\n document.title = 'SilverMoonOrchestra'\n }\n\n const progress = (info.currentTime / info.duration) * 100\n if (isNaN(info.duration) || (progress < 50 && info.currentTime < 240)) {\n return\n }\n\n if (!preloaded) {\n const next = nextSong()\n if (next != null) {\n const audio = new Audio()\n audio.src = next.musicSrc\n }\n setPreload(true)\n return\n }\n\n if (!scrobbled) {\n info.trackId && subsonic.scrobble(info.trackId, startTime)\n setScrobbled(true)\n }\n },\n [startTime, scrobbled, nextSong, preloaded]\n )\n\n const onAudioVolumeChange = useCallback(\n // sqrt to compensate for the logarithmic volume\n (volume) => dispatch(setVolume(Math.sqrt(volume))),\n [dispatch]\n )\n\n const onAudioPlay = useCallback(\n (info) => {\n dispatch(currentPlaying(info))\n if (startTime === null) {\n setStartTime(Date.now())\n }\n if (info.duration) {\n const song = info.song\n document.title = `${song.title} - ${song.artist} - SilverMoonOrchestra`\n subsonic.nowPlaying(info.trackId)\n setPreload(false)\n if (config.gaTrackingId) {\n ReactGA.event({\n category: 'Player',\n action: 'Play song',\n label: `${song.title} - ${song.artist}`,\n })\n }\n if (showNotifications) {\n sendNotification(\n song.title,\n `${song.artist} - ${song.album}`,\n info.cover\n )\n }\n }\n },\n [dispatch, showNotifications, startTime]\n )\n\n const onAudioPlayTrackChange = useCallback(() => {\n if (scrobbled) {\n setScrobbled(false)\n }\n if (startTime !== null) {\n setStartTime(null)\n }\n }, [scrobbled, startTime])\n\n const onAudioPause = useCallback(\n (info) => dispatch(currentPlaying(info)),\n [dispatch]\n )\n\n const onAudioEnded = useCallback(\n (currentPlayId, audioLists, info) => {\n setScrobbled(false)\n setStartTime(null)\n dispatch(currentPlaying(info))\n dataProvider\n .getOne('keepalive', { id: info.trackId })\n .catch((e) => console.log('Keepalive error:', e))\n },\n [dispatch, dataProvider]\n )\n\n const onCoverClick = useCallback((mode, audioLists, audioInfo) => {\n if (mode === 'full' && audioInfo?.song?.albumId) {\n window.location.href = `#/album/${audioInfo.song.albumId}/show`\n }\n }, [])\n\n const onBeforeDestroy = useCallback(() => {\n return new Promise((resolve, reject) => {\n dispatch(clearQueue())\n reject()\n })\n }, [dispatch])\n\n if (!visible) {\n document.title = 'SilverMoonOrchestra'\n }\n\n const handlers = useMemo(\n () => keyHandlers(audioInstance, playerState),\n [audioInstance, playerState]\n )\n\n useEffect(() => {\n if (isMobilePlayer && audioInstance) {\n audioInstance.volume = 1\n }\n }, [isMobilePlayer, audioInstance])\n\n return (\n <ThemeProvider theme={createMuiTheme(theme)}>\n <ReactJkMusicPlayer\n {...options}\n className={classes.player}\n onAudioListsChange={onAudioListsChange}\n onAudioVolumeChange={onAudioVolumeChange}\n onAudioProgress={onAudioProgress}\n onAudioPlay={onAudioPlay}\n onAudioPlayTrackChange={onAudioPlayTrackChange}\n onAudioPause={onAudioPause}\n onAudioEnded={onAudioEnded}\n onCoverClick={onCoverClick}\n onBeforeDestroy={onBeforeDestroy}\n getAudioInstance={setAudioInstance}\n />\n <GlobalHotKeys handlers={handlers} keyMap={keyMap} allowChanges />\n </ThemeProvider>\n )\n}\n\nexport { Player }\n","import polyglotI18nProvider from 'ra-i18n-polyglot'\nimport deepmerge from 'deepmerge'\nimport dataProvider from '../dataProvider'\nimport en from './en.json'\nimport { i18nProvider } from './index'\n\n// Only returns current selected locale if its translations are found in localStorage\nconst defaultLocale = function () {\n const locale = localStorage.getItem('locale')\n const current = JSON.parse(localStorage.getItem('translation'))\n if (current && current.id === locale) {\n // Asynchronously reload the translation from the server\n retrieveTranslation(locale).then(() => {\n i18nProvider.changeLocale(locale)\n })\n return locale\n }\n return 'en'\n}\n\nfunction retrieveTranslation(locale) {\n return dataProvider.getOne('translation', { id: locale }).then((res) => {\n localStorage.setItem('translation', JSON.stringify(res.data))\n return prepareLanguage(JSON.parse(res.data.data))\n })\n}\n\nconst removeEmpty = (obj) => {\n for (let k in obj) {\n if (obj.hasOwnProperty(k) && typeof obj[k] === 'object') {\n removeEmpty(obj[k])\n } else {\n if (!obj[k]) {\n delete obj[k]\n }\n }\n }\n}\n\nconst prepareLanguage = (lang) => {\n removeEmpty(lang)\n // Make \"albumSong\" and \"playlistTrack\" resource use the same translations as \"song\"\n lang.resources.albumSong = lang.resources.song\n lang.resources.playlistTrack = lang.resources.song\n // ra.boolean.null should always be empty\n lang.ra.boolean.null = ''\n // Fallback to english translations\n return deepmerge(en, lang)\n}\n\nexport default polyglotI18nProvider((locale) => {\n // English is bundled\n if (locale === 'en') {\n return prepareLanguage(en)\n }\n // If the requested locale is in already loaded, return it\n const current = JSON.parse(localStorage.getItem('translation'))\n if (current && current.id === locale) {\n return prepareLanguage(JSON.parse(current.data))\n }\n // If not, get it from the server, and store it in localStorage\n return retrieveTranslation(locale)\n}, defaultLocale())\n","// React Hook to get a list of all languages available. English is hardcoded\nimport { useGetList } from 'react-admin'\n\nconst useGetLanguageChoices = () => {\n const { ids, data, loaded, loading } = useGetList(\n 'translation',\n { page: 1, perPage: -1 },\n { field: '', order: '' },\n {}\n )\n\n const choices = [{ id: 'en', name: 'English' }]\n if (loaded) {\n ids.forEach((id) => choices.push({ id: id, name: data[id].name }))\n }\n choices.sort((a, b) => a.name.localeCompare(b.name))\n\n return { choices, loaded, loading }\n}\n\nexport default useGetLanguageChoices\n","import HelpOutlineIcon from '@material-ui/icons/HelpOutline'\n\nexport const HelpMsg = ({ caption }) => (\n <>\n <HelpOutlineIcon />\n    {caption}\n </>\n)\n","import { SelectInput, useLocale, useSetLocale, useTranslate } from 'react-admin'\nimport { useGetLanguageChoices } from '../i18n'\nimport { HelpMsg } from './HelpMsg'\nimport { docsUrl, openInNewTab } from '../utils'\n\nconst helpKey = '_help'\n\nexport const SelectLanguage = (props) => {\n const translate = useTranslate()\n const setLocale = useSetLocale()\n const locale = useLocale()\n const { choices } = useGetLanguageChoices()\n\n choices.push({\n id: helpKey,\n name: <HelpMsg caption={'Help to translate'} />,\n })\n\n return (\n <SelectInput\n {...props}\n source=\"language\"\n label={translate('menu.personal.options.language')}\n defaultValue={locale}\n choices={choices}\n translateChoice={false}\n onChange={(event) => {\n if (event.target.value === helpKey) {\n openInNewTab(docsUrl('/docs/developers/translations/'))\n return\n }\n setLocale(event.target.value).then(() => {\n localStorage.setItem('locale', event.target.value)\n })\n }}\n />\n )\n}\n","import { SelectInput, useTranslate } from 'react-admin'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { AUTO_THEME_ID } from '../consts'\nimport themes from '../themes'\nimport { HelpMsg } from './HelpMsg'\nimport { docsUrl, openInNewTab } from '../utils'\nimport { changeTheme } from '../actions'\n\nconst helpKey = '_help'\n\nexport const SelectTheme = (props) => {\n const translate = useTranslate()\n const dispatch = useDispatch()\n const currentTheme = useSelector((state) => state.theme)\n const themeChoices = [\n {\n id: AUTO_THEME_ID,\n name: 'Auto',\n },\n ]\n themeChoices.push(\n ...Object.keys(themes).map((key) => {\n return { id: key, name: themes[key].themeName }\n })\n )\n themeChoices.push({\n id: helpKey,\n name: <HelpMsg caption={'Create your own'} />,\n })\n return (\n <SelectInput\n {...props}\n source=\"theme\"\n label={translate('menu.personal.options.theme')}\n defaultValue={currentTheme}\n translateChoice={false}\n choices={themeChoices}\n onChange={(event) => {\n if (event.target.value === helpKey) {\n openInNewTab(docsUrl('/docs/developers/creating-themes/'))\n return\n }\n dispatch(changeTheme(event.target.value))\n }}\n />\n )\n}\n","import { SelectInput, useTranslate } from 'react-admin'\nimport albumLists, { defaultAlbumList } from '../album/albumLists'\n\nexport const SelectDefaultView = (props) => {\n const translate = useTranslate()\n const current = localStorage.getItem('defaultView') || defaultAlbumList\n const choices = Object.keys(albumLists).map((type) => ({\n id: type,\n name: translate(`resources.album.lists.${type}`),\n }))\n\n return (\n <SelectInput\n {...props}\n source=\"defaultView\"\n label={translate('menu.personal.options.defaultView')}\n defaultValue={current}\n choices={choices}\n translateChoice={false}\n onChange={(event) => {\n localStorage.setItem('defaultView', event.target.value)\n }}\n />\n )\n}\n","import { useNotify, useTranslate } from 'react-admin'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { setNotificationsState } from '../actions'\nimport {\n FormControl,\n FormControlLabel,\n FormHelperText,\n Switch,\n} from '@material-ui/core'\n\nexport const NotificationsToggle = () => {\n const translate = useTranslate()\n const dispatch = useDispatch()\n const notify = useNotify()\n const currentSetting = useSelector((state) => state.settings.notifications)\n const notAvailable = !('Notification' in window) || !window.isSecureContext\n\n if (\n (currentSetting && Notification.permission !== 'granted') ||\n notAvailable\n ) {\n dispatch(setNotificationsState(false))\n }\n\n const toggleNotifications = (event) => {\n if (currentSetting && !event.target.checked) {\n dispatch(setNotificationsState(false))\n } else {\n if (Notification.permission === 'denied') {\n notify(translate('message.notifications_blocked'), 'warning')\n } else {\n Notification.requestPermission().then((permission) => {\n dispatch(setNotificationsState(permission === 'granted'))\n })\n }\n }\n }\n\n return (\n <FormControl>\n <FormControlLabel\n control={\n <Switch\n id={'notifications'}\n color=\"primary\"\n checked={currentSetting}\n disabled={notAvailable}\n onChange={toggleNotifications}\n />\n }\n label={\n <span>\n {translate('menu.personal.options.desktop_notifications')}\n </span>\n }\n />\n {notAvailable && (\n <FormHelperText id=\"notifications-disabled-helper-text\">\n {translate('message.notifications_not_available')}\n </FormHelperText>\n )}\n </FormControl>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { useNotify, useTranslate } from 'react-admin'\nimport {\n FormControl,\n FormControlLabel,\n LinearProgress,\n Switch,\n} from '@material-ui/core'\nimport { useInterval } from '../common'\nimport config from '../config'\nimport { baseUrl, openInNewTab } from '../utils'\nimport { httpClient } from '../dataProvider'\n\nconst Progress = (props) => {\n const { setLinked, setCheckingLink } = props\n const notify = useNotify()\n let linkCheckDelay = 2000\n let linkChecks = 30\n const openedTab = useRef()\n\n useEffect(() => {\n const callbackEndpoint = baseUrl(\n `/api/lastfm/link/callback?uid=${localStorage.getItem('userId')}`\n )\n const callbackUrl = `${window.location.origin}${callbackEndpoint}`\n openedTab.current = openInNewTab(\n `https://www.last.fm/api/auth/?api_key=${config.lastFMApiKey}&cb=${callbackUrl}`\n )\n }, [])\n\n const endChecking = (success) => {\n linkCheckDelay = null\n setCheckingLink(false)\n if (success) {\n notify('message.lastfmLinkSuccess', 'success')\n } else {\n notify('message.lastfmLinkFailure', 'warning')\n }\n setLinked(success)\n }\n\n useInterval(() => {\n httpClient('/api/lastfm/link')\n .then((response) => {\n let result = false\n if (response.json.status === true) {\n result = true\n endChecking(true)\n }\n return result\n })\n .then((result) => {\n if (!result && openedTab.current?.closed === true) {\n endChecking(false)\n result = true\n }\n return result\n })\n .then((result) => {\n if (!result && --linkChecks === 0) {\n endChecking(false)\n }\n })\n .catch(() => {\n endChecking(false)\n })\n }, linkCheckDelay)\n\n return <LinearProgress />\n}\n\nexport const LastfmScrobbleToggle = (props) => {\n const notify = useNotify()\n const translate = useTranslate()\n const [linked, setLinked] = useState(null)\n const [checkingLink, setCheckingLink] = useState(false)\n\n const toggleScrobble = () => {\n if (!linked) {\n setCheckingLink(true)\n } else {\n httpClient('/api/lastfm/link', { method: 'DELETE' })\n .then(() => {\n setLinked(false)\n notify('message.lastfmUnlinkSuccess', 'success')\n })\n .catch(() => notify('message.lastfmUnlinkFailure', 'warning'))\n }\n }\n\n useEffect(() => {\n httpClient('/api/lastfm/link')\n .then((response) => {\n setLinked(response.json.status === true)\n })\n .catch(() => {\n setLinked(false)\n })\n }, [])\n\n return (\n <FormControl>\n <FormControlLabel\n control={\n <Switch\n id={'lastfm'}\n color=\"primary\"\n checked={linked || checkingLink}\n disabled={linked === null || checkingLink}\n onChange={toggleScrobble}\n />\n }\n label={\n <span>{translate('menu.personal.options.lastfmScrobbling')}</span>\n }\n />\n {checkingLink && (\n <Progress setLinked={setLinked} setCheckingLink={setCheckingLink} />\n )}\n </FormControl>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { useNotify, useTranslate } from 'react-admin'\nimport { FormControl, FormControlLabel, Switch } from '@material-ui/core'\nimport { httpClient } from '../dataProvider'\nimport { ListenBrainzTokenDialog } from '../dialogs'\nimport { useDispatch } from 'react-redux'\nimport { openListenBrainzTokenDialog } from '../actions'\n\nexport const ListenBrainzScrobbleToggle = () => {\n const dispatch = useDispatch()\n const notify = useNotify()\n const translate = useTranslate()\n const [linked, setLinked] = useState(null)\n\n const toggleScrobble = () => {\n if (linked) {\n httpClient('/api/listenbrainz/link', { method: 'DELETE' })\n .then(() => {\n setLinked(false)\n notify('message.listenBrainzUnlinkSuccess', 'success')\n })\n .catch(() => notify('message.listenBrainzUnlinkFailure', 'warning'))\n } else {\n dispatch(openListenBrainzTokenDialog())\n }\n }\n\n useEffect(() => {\n httpClient('/api/listenbrainz/link')\n .then((response) => {\n setLinked(response.json.status === true)\n })\n .catch(() => {\n setLinked(false)\n })\n }, [])\n\n return (\n <>\n <FormControl>\n <FormControlLabel\n control={\n <Switch\n id={'listenbrainz'}\n color=\"primary\"\n checked={linked === true}\n disabled={linked === null}\n onChange={toggleScrobble}\n />\n }\n label={\n <span>\n {translate('menu.personal.options.listenBrainzScrobbling')}\n </span>\n }\n />\n </FormControl>\n <ListenBrainzTokenDialog setLinked={setLinked} />\n </>\n )\n}\n","import { SimpleForm, Title, useTranslate } from 'react-admin'\nimport { Card } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { SelectLanguage } from './SelectLanguage'\nimport { SelectTheme } from './SelectTheme'\nimport { SelectDefaultView } from './SelectDefaultView'\nimport { NotificationsToggle } from './NotificationsToggle'\nimport { LastfmScrobbleToggle } from './LastfmScrobbleToggle'\nimport { ListenBrainzScrobbleToggle } from './ListenBrainzScrobbleToggle'\nimport config from '../config'\n\nconst useStyles = makeStyles({\n root: { marginTop: '1em' },\n})\n\nconst Personal = () => {\n const translate = useTranslate()\n const classes = useStyles()\n\n return (\n <Card className={classes.root}>\n <Title title={'SilverMoonOrchestra - ' + translate('menu.personal.name')} />\n <SimpleForm toolbar={null} variant={'outlined'}>\n <SelectTheme />\n <SelectLanguage />\n <SelectDefaultView />\n <NotificationsToggle />\n {config.lastFMEnabled && <LastfmScrobbleToggle />}\n {config.listenBrainzEnabled && <ListenBrainzScrobbleToggle />}\n </SimpleForm>\n </Card>\n )\n}\n\nexport default Personal\n","import React from 'react'\nimport { Route } from 'react-router-dom'\nimport Personal from './personal/Personal'\n\nconst routes = [<Route exact path=\"/personal\" render={() => <Personal />} />]\n\nexport default routes\n","import { CHANGE_THEME } from '../actions'\nimport config from '../config'\nimport themes from '../themes'\n\nconst defaultTheme = () => {\n return (\n Object.keys(themes).find(\n (t) => themes[t].themeName === config.defaultTheme\n ) || 'DarkTheme'\n )\n}\n\nexport const themeReducer = (\n previousState = defaultTheme(),\n { type, payload }\n) => {\n if (type === CHANGE_THEME) {\n return payload\n }\n return previousState\n}\n","import { v4 as uuidv4 } from 'uuid'\nimport subsonic from '../subsonic'\nimport {\n PLAYER_ADD_TRACKS,\n PLAYER_CLEAR_QUEUE,\n PLAYER_CURRENT,\n PLAYER_PLAY_NEXT,\n PLAYER_PLAY_TRACKS,\n PLAYER_SET_TRACK,\n PLAYER_SET_VOLUME,\n PLAYER_SYNC_QUEUE,\n} from '../actions'\nimport config from '../config'\n\nconst initialState = {\n queue: [],\n current: {},\n clear: false,\n volume: 0.5, // 50%\n savedPlayIndex: 0,\n}\n\nconst mapToAudioLists = (item) => {\n // If item comes from a playlist, trackId is mediaFileId\n const trackId = item.mediaFileId || item.id\n const { lyrics } = item\n const timestampRegex =\n /(\\[([0-9]{1,2}:)?([0-9]{1,2}:)([0-9]{1,2})(\\.[0-9]{1,2})?\\])/g\n return {\n trackId,\n uuid: uuidv4(),\n song: item,\n name: item.title,\n lyric: timestampRegex.test(lyrics) ? lyrics : '',\n singer: item.artist,\n duration: item.duration,\n musicSrc: subsonic.streamUrl(trackId),\n cover: subsonic.getCoverArtUrl(\n {\n coverArtId: config.devFastAccessCoverArt ? item.albumId : trackId,\n updatedAt: item.updatedAt,\n },\n 300\n ),\n }\n}\n\nconst reduceClearQueue = () => ({ ...initialState, clear: true })\n\nconst reducePlayTracks = (state, { data, id }) => {\n let playIndex = 0\n const queue = Object.keys(data).map((key, idx) => {\n if (key === id) {\n playIndex = idx\n }\n return mapToAudioLists(data[key])\n })\n return {\n ...state,\n queue,\n playIndex,\n clear: true,\n }\n}\n\nconst reduceSetTrack = (state, { data }) => {\n return {\n ...state,\n queue: [mapToAudioLists(data)],\n playIndex: 0,\n clear: true,\n }\n}\n\nconst reduceAddTracks = (state, { data }) => {\n const queue = state.queue\n Object.keys(data).forEach((id) => {\n queue.push(mapToAudioLists(data[id]))\n })\n return { ...state, queue, clear: false }\n}\n\nconst reducePlayNext = (state, { data }) => {\n const newQueue = []\n const current = state.current || {}\n let foundPos = false\n state.queue.forEach((item) => {\n newQueue.push(item)\n if (item.uuid === current.uuid) {\n foundPos = true\n Object.keys(data).forEach((id) => {\n newQueue.push(mapToAudioLists(data[id]))\n })\n }\n })\n if (!foundPos) {\n Object.keys(data).forEach((id) => {\n newQueue.push(mapToAudioLists(data[id]))\n })\n }\n\n return {\n ...state,\n queue: newQueue,\n clear: true,\n }\n}\n\nconst reduceSetVolume = (state, { data: { volume } }) => {\n return {\n ...state,\n volume,\n }\n}\n\nconst reduceSyncQueue = (state, { data: { audioInfo, audioLists } }) => {\n return {\n ...state,\n queue: audioLists,\n clear: false,\n playIndex: undefined,\n }\n}\n\nconst reduceCurrent = (state, { data }) => {\n const current = data.ended ? {} : data\n const savedPlayIndex = state.queue.findIndex(\n (item) => item.uuid === current.uuid\n )\n return {\n ...state,\n current,\n playIndex: undefined,\n savedPlayIndex,\n volume: data.volume,\n }\n}\n\nexport const playerReducer = (previousState = initialState, payload) => {\n const { type } = payload\n switch (type) {\n case PLAYER_CLEAR_QUEUE:\n return reduceClearQueue()\n case PLAYER_PLAY_TRACKS:\n return reducePlayTracks(previousState, payload)\n case PLAYER_SET_TRACK:\n return reduceSetTrack(previousState, payload)\n case PLAYER_ADD_TRACKS:\n return reduceAddTracks(previousState, payload)\n case PLAYER_PLAY_NEXT:\n return reducePlayNext(previousState, payload)\n case PLAYER_SET_VOLUME:\n return reduceSetVolume(previousState, payload)\n case PLAYER_SYNC_QUEUE:\n return reduceSyncQueue(previousState, payload)\n case PLAYER_CURRENT:\n return reduceCurrent(previousState, payload)\n default:\n return previousState\n }\n}\n","import {\n EVENT_REFRESH_RESOURCE,\n EVENT_SCAN_STATUS,\n EVENT_SERVER_START,\n} from '../actions'\nimport config from '../config'\n\nconst initialState = {\n scanStatus: { scanning: false, folderCount: 0, count: 0 },\n serverStart: { version: config.version },\n}\n\nexport const activityReducer = (previousState = initialState, payload) => {\n const { type, data } = payload\n switch (type) {\n case EVENT_SCAN_STATUS:\n return { ...previousState, scanStatus: data }\n case EVENT_SERVER_START:\n return {\n ...previousState,\n serverStart: {\n startTime: data.startTime && Date.parse(data.startTime),\n version: data.version,\n },\n }\n case EVENT_REFRESH_RESOURCE:\n return {\n ...previousState,\n refresh: {\n lastReceived: Date.now(),\n resources: data,\n },\n }\n default:\n return previousState\n }\n}\n","import {\n SET_NOTIFICATIONS_STATE,\n SET_OMITTED_FIELDS,\n SET_TOGGLEABLE_FIELDS,\n} from '../actions'\n\nconst initialState = {\n notifications: false,\n toggleableFields: {},\n omittedFields: {},\n}\n\nexport const settingsReducer = (previousState = initialState, payload) => {\n const { type, data } = payload\n switch (type) {\n case SET_NOTIFICATIONS_STATE:\n return {\n ...previousState,\n notifications: data,\n }\n case SET_TOGGLEABLE_FIELDS:\n return {\n ...previousState,\n toggleableFields: {\n ...previousState.toggleableFields,\n ...data,\n },\n }\n case SET_OMITTED_FIELDS:\n return {\n ...previousState,\n omittedFields: {\n ...previousState.omittedFields,\n ...data,\n },\n }\n default:\n return previousState\n }\n}\n","import { applyMiddleware, combineReducers, compose, createStore } from 'redux'\nimport { routerMiddleware, connectRouter } from 'connected-react-router'\nimport createSagaMiddleware from 'redux-saga'\nimport { all, fork } from 'redux-saga/effects'\nimport { adminReducer, adminSaga, USER_LOGOUT } from 'react-admin'\nimport throttle from 'lodash.throttle'\nimport pick from 'lodash.pick'\nimport { loadState, saveState } from './persistState'\n\nconst createAdminStore = ({\n authProvider,\n dataProvider,\n history,\n customReducers = {},\n}) => {\n const reducer = combineReducers({\n admin: adminReducer,\n router: connectRouter(history),\n ...customReducers,\n })\n const resettableAppReducer = (state, action) =>\n reducer(action.type !== USER_LOGOUT ? state : undefined, action)\n\n const saga = function* rootSaga() {\n yield all([adminSaga(dataProvider, authProvider)].map(fork))\n }\n const sagaMiddleware = createSagaMiddleware()\n\n const composeEnhancers =\n (process.env.NODE_ENV === 'development' &&\n typeof window !== 'undefined' &&\n window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&\n window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({\n trace: true,\n traceLimit: 25,\n })) ||\n compose\n\n const persistedState = loadState()\n if (persistedState?.player?.savedPlayIndex) {\n persistedState.player.playIndex = persistedState.player.savedPlayIndex\n }\n const store = createStore(\n resettableAppReducer,\n persistedState,\n composeEnhancers(applyMiddleware(sagaMiddleware, routerMiddleware(history)))\n )\n\n store.subscribe(\n throttle(() => {\n const state = store.getState()\n saveState({\n theme: state.theme,\n player: pick(state.player, ['queue', 'volume', 'savedPlayIndex']),\n albumView: state.albumView,\n settings: state.settings,\n })\n }),\n 1000\n )\n\n sagaMiddleware.run(saga)\n return store\n}\n\nexport default createAdminStore\n","export const loadState = () => {\n try {\n const serializedState = localStorage.getItem('state')\n if (serializedState === null) {\n return undefined\n }\n return JSON.parse(serializedState)\n } catch (err) {\n return undefined\n }\n}\n\nexport const saveState = (state) => {\n try {\n const serializedState = JSON.stringify(state)\n localStorage.setItem('state', serializedState)\n } catch (err) {\n // Ignore write errors\n }\n}\n","import { useEffect } from 'react'\nimport useCurrentTheme from './themes/useCurrentTheme'\n\nconst useChangeThemeColor = () => {\n const theme = useCurrentTheme()\n const color =\n theme.palette?.primary?.light || theme.palette?.primary?.main || '#ffffff'\n useEffect(() => {\n const themeColor = document.querySelector(\"meta[name='theme-color']\")\n themeColor.setAttribute('content', color)\n }, [color])\n}\n\nexport default useChangeThemeColor\n","import React, { useEffect } from 'react'\nimport ReactGA from 'react-ga'\nimport { Provider } from 'react-redux'\nimport { createHashHistory } from 'history'\nimport { Admin as RAAdmin, Resource } from 'react-admin'\nimport { HotKeys } from 'react-hotkeys'\nimport dataProvider from './dataProvider'\nimport authProvider from './authProvider'\nimport { Layout, Login, Logout } from './layout'\nimport transcoding from './transcoding'\nimport player from './player'\nimport user from './user'\nimport song from './song'\nimport album from './album'\nimport artist from './artist'\nimport playlist from './playlist'\nimport { Player } from './audioplayer'\nimport customRoutes from './routes'\nimport {\n themeReducer,\n addToPlaylistDialogReducer,\n expandInfoDialogReducer,\n listenBrainzTokenDialogReducer,\n playerReducer,\n albumViewReducer,\n activityReducer,\n settingsReducer,\n} from './reducers'\nimport createAdminStore from './store/createAdminStore'\nimport { i18nProvider } from './i18n'\nimport config from './config'\nimport { setDispatch, startEventStream, stopEventStream } from './eventStream'\nimport { keyMap } from './hotkeys'\nimport useChangeThemeColor from './useChangeThemeColor'\n\nconst history = createHashHistory()\n\nif (config.gaTrackingId) {\n ReactGA.initialize(config.gaTrackingId)\n history.listen((location) => {\n ReactGA.pageview(location.pathname)\n })\n ReactGA.pageview(window.location.pathname)\n}\n\nconst adminStore = createAdminStore({\n authProvider,\n dataProvider,\n history,\n customReducers: {\n player: playerReducer,\n albumView: albumViewReducer,\n theme: themeReducer,\n addToPlaylistDialog: addToPlaylistDialogReducer,\n expandInfoDialog: expandInfoDialogReducer,\n listenBrainzTokenDialog: listenBrainzTokenDialogReducer,\n activity: activityReducer,\n settings: settingsReducer,\n },\n})\n\nconst App = () => (\n <Provider store={adminStore}>\n <Admin />\n </Provider>\n)\n\nconst Admin = (props) => {\n useChangeThemeColor()\n useEffect(() => {\n if (config.devActivityPanel) {\n setDispatch(adminStore.dispatch)\n authProvider\n .checkAuth()\n .then(() => startEventStream(adminStore.dispatch))\n .catch(() => {})\n }\n return () => {\n stopEventStream()\n }\n }, [])\n\n return (\n <RAAdmin\n disableTelemetry\n dataProvider={dataProvider}\n authProvider={authProvider}\n i18nProvider={i18nProvider}\n customRoutes={customRoutes}\n history={history}\n layout={Layout}\n loginPage={Login}\n logoutButton={Logout}\n {...props}\n >\n {(permissions) => [\n <Resource name=\"album\" {...album} options={{ subMenu: 'albumList' }} />,\n <Resource name=\"artist\" {...artist} />,\n <Resource name=\"song\" {...song} />,\n <Resource\n name=\"playlist\"\n {...playlist}\n options={{ subMenu: 'playlist' }}\n />,\n <Resource name=\"user\" {...user} options={{ subMenu: 'settings' }} />,\n <Resource\n name=\"player\"\n {...player}\n options={{ subMenu: 'settings' }}\n />,\n permissions === 'admin' ? (\n <Resource\n name=\"transcoding\"\n {...transcoding}\n options={{ subMenu: 'settings' }}\n />\n ) : (\n <Resource name=\"transcoding\" />\n ),\n <Resource name=\"translation\" />,\n <Resource name=\"genre\" />,\n <Resource name=\"playlistTrack\" />,\n <Resource name=\"keepalive\" />,\n <Player />,\n ]}\n </RAAdmin>\n )\n}\n\nconst AppWithHotkeys = () => (\n <HotKeys keyMap={keyMap}>\n <App />\n </HotKeys>\n)\n\nexport default AppWithHotkeys\n","import { ALBUM_MODE_GRID, ALBUM_MODE_TABLE } from '../actions'\n\nexport const albumViewReducer = (\n previousState = {\n grid: true,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case ALBUM_MODE_GRID:\n case ALBUM_MODE_TABLE:\n return { ...previousState, grid: type === ALBUM_MODE_GRID }\n default:\n return previousState\n }\n}\n","import {\n ADD_TO_PLAYLIST_CLOSE,\n ADD_TO_PLAYLIST_OPEN,\n DUPLICATE_SONG_WARNING_OPEN,\n DUPLICATE_SONG_WARNING_CLOSE,\n EXTENDED_INFO_OPEN,\n EXTENDED_INFO_CLOSE,\n LISTENBRAINZ_TOKEN_OPEN,\n LISTENBRAINZ_TOKEN_CLOSE,\n} from '../actions'\n\nexport const addToPlaylistDialogReducer = (\n previousState = {\n open: false,\n duplicateSong: false,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case ADD_TO_PLAYLIST_OPEN:\n return {\n ...previousState,\n open: true,\n selectedIds: payload.selectedIds,\n onSuccess: payload.onSuccess,\n }\n case ADD_TO_PLAYLIST_CLOSE:\n return { ...previousState, open: false, onSuccess: undefined }\n case DUPLICATE_SONG_WARNING_OPEN:\n return {\n ...previousState,\n duplicateSong: true,\n duplicateIds: payload.duplicateIds,\n }\n case DUPLICATE_SONG_WARNING_CLOSE:\n return { ...previousState, duplicateSong: false }\n default:\n return previousState\n }\n}\n\nexport const expandInfoDialogReducer = (\n previousState = {\n open: false,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case EXTENDED_INFO_OPEN:\n return {\n ...previousState,\n open: true,\n record: payload.record,\n }\n case EXTENDED_INFO_CLOSE:\n return {\n ...previousState,\n open: false,\n }\n default:\n return previousState\n }\n}\n\nexport const listenBrainzTokenDialogReducer = (\n previousState = {\n open: false,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case LISTENBRAINZ_TOKEN_OPEN:\n return {\n ...previousState,\n open: true,\n }\n case LISTENBRAINZ_TOKEN_CLOSE:\n return {\n ...previousState,\n open: false,\n }\n default:\n return previousState\n }\n}\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n)\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href)\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/navidrome-service-worker.js`\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config)\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n )\n })\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config)\n }\n })\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then((registration) => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing\n if (installingWorker == null) {\n return\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n )\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration)\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.')\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration)\n }\n }\n }\n }\n }\n })\n .catch((error) => {\n console.error('Error during service worker registration:', error)\n })\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then((response) => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type')\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then((registration) => {\n registration.unregister().then(() => {\n window.location.reload()\n })\n })\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config)\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n )\n })\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then((registration) => {\n registration.unregister()\n })\n .catch((error) => {\n console.error(error.message)\n })\n }\n}\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport './index.css'\nimport App from './App'\nimport * as serviceWorker from './serviceWorker'\n\nReactDOM.render(<App />, document.getElementById('root'))\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.register()\n"],"sourceRoot":""}