{"version":3,"sources":["themes/dark.css.js","themes/light.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/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/SongDetails.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","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","song/SongList.js","song/index.js","album/AlbumListActions.js","album/AlbumTableView.js","album/AlbumGridView.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/index.js","playlist/PlaylistListActions.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/Personal.js","routes.js","reducers/themeReducer.js","reducers/dialogReducer.js","reducers/playerReducer.js","reducers/albumView.js","reducers/activityReducer.js","reducers/settingsReducer.js","store/createAdminStore.js","store/persistState.js","useChangeThemeColor.js","App.js","serviceWorker.js","index.js"],"names":["module","exports","config","defaultConfig","version","firstTime","baseURL","loginBackgroundURL","enableTranscodingConfig","enableDownloads","enableFavourites","losslessFormats","welcomeMessage","gaTrackingId","devActivityPanel","devFastAccessCoverArt","enableStarRating","defaultTheme","enableUserEditing","devEnableShare","lastFMEnabled","lastFMApiKey","enableCoverAnimation","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","dataProvider","jsonServerProvider","mapResource","resource","params","plsId","playlist_id","wrapperDataProvider","getList","r","p","getOne","getMany","getManyReference","update","updateMany","create","delete","deleteMany","PLAYER_ADD_TRACKS","PLAYER_PLAY_NEXT","PLAYER_SET_TRACK","PLAYER_SYNC_QUEUE","PLAYER_CLEAR_QUEUE","PLAYER_PLAY_TRACKS","PLAYER_CURRENT","PLAYER_SET_VOLUME","setTrack","data","type","filterSongs","ids","acc","id","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","openAddToPlaylist","selectedIds","onSuccess","closeAddToPlaylist","closeDuplicateSongDialog","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","eventHandler","event","processEvent","throttledEventHandler","throttle","trailing","console","Promise","reject","newStream","addEventListener","onerror","catch","auth","storeAuthenticationInfo","authInfo","name","username","avatar","isAdmin","subsonicSalt","subsonicToken","authProvider","login","password","request","Request","method","body","stringify","fetch","status","Error","statusText","json","error","message","stack","logout","removeItems","resolve","checkAuth","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","player","theme","stylesheet","require","primary","blue","MuiFormGroup","welcome","background","paper","default","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","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","height","overflow","RaDatagridHeaderCell","RaAutocompleteSuggestionList","suggestionsPaper","RaLink","link","RaLogout","RaMenuItemLink","active","RaSidebar","drawerPaper","RaBulkActionsToolbar","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","SubMenu","handleToggle","isOpen","children","dense","header","MenuItem","ListItemIcon","Typography","Tooltip","placement","Collapse","in","unmountOnExit","disablePadding","Divider","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","IconButton","aria-label","DialogContent","MuiDialogContent","links","homepage","reddit","twitter","discord","source","featureRequests","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","record","artistLink","to","albumArtistId","stopPropagation","albumArtist","defaultProps","addLabel","BatchPlayButton","action","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","useToggleLove","mountedRef","useRef","current","refreshRecord","toggleLove","toggle","subsonic","love","visibility","visible","loved","LoveButton","Button","handleToggleLove","preventDefault","noWrap","whiteSpace","menu","ContextMenu","showLove","songQueryParams","anchorEl","setAnchorEl","play","needData","addToQueue","addToPlaylist","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","opacity","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","isDesktop","DiscSubtitleRow","colSpan","contextAlwaysVisible","breakpoints","up","discSubtitle","hover","albumId","SongDatagridRow","firstTracks","onClickDiscSubtitle","fields","React","Children","toArray","c","isValidElement","childCount","has","expand","SongDatagridBody","showDiscSubtitles","playDisc","idsToPlay","useMemo","Set","foundSubtitle","last","clear","SongDatagrid","Datagrid","tableCell","SongDetails","album","genre","FunctionField","genres","g","compilation","BooleanField","bitRate","showTime","playCount","bpm","NumberField","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","owner","Writable","child","cloneElement","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","filtered","omitted","entries","arrayOf","useSetToggleableFields","toggleableColumns","menuIcon","maxHeight","ToggleFieldsMenu","TopBarComponent","topbarComponent","selectedColumn","Checkbox","checked","llFormats","useStyle","QualityInfo","suffix","info","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","playlistId","distinctIds","trackIds","Array","isArray","len","checkDuplicateSong","dupSng","some","dupIds","openDuplicateSongWarning","maxWidth","pls","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","translatedResourceName","pluralize","withRouter","subMenu","onMenuClick","ui","sidebarOpen","getResources","menuAlbumList","menuLibrary","menuSettings","setState","al","albumListAddress","MenuItemLink","activeClassName","exact","renderAlbumMenuItemLink","hasList","menuItem","PersonalMenu","forwardRef","ref","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","user","usernameWrap","UserMenu","useGetIdentity","loaded","identity","handleClose","aria-owns","MenuList","elevation","AboutMenuItem","titleAccess","settingsResources","CustomUserMenu","permissions","usePermissions","renderSettingsMenuItemLink","resourceName","userResource","PersonIcon","SupervisorAccountIcon","renderUserMenuItemLink","AppBar","userMenu","paddingBottom","addPadding","Layout","queue","keyHandlers","toggleSidebar","Menu","appBar","notification","TranscodingList","isXsmall","down","exporter","targetFormat","defaultBitRate","rowClick","Interpolate","TranscodingNote","TranscodingTitle","TranscodingEdit","Edit","SimpleForm","TextInput","required","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","payload","returnPromise","undoable","email","FormDataConsumer","formDataProps","initialValue","SongListActions","currentSort","displayedFilters","filterValues","showFilter","permanentFilter","onUnselectItems","maxResults","isNotSmall","TopToolbar","context","AlbumLinkField","contextHeader","ratingField","SongFilter","filterToQuery","searchText","AutocompleteInput","SongList","year","quality","duration","MusicNoteOutlinedIcon","MusicNoteIcon","buttonGroup","leftButton","rightButton","AlbumViewToggler","showTitle","disableElevation","albumView","ButtonGroup","grid","AlbumListActions","columnIcon","AlbumDetails","ArrayField","SingleFieldList","ChipField","AlbumTableView","hasShow","hasEdit","syncWithLocation","songCount","tileBar","tileBarMobile","albumArtistName","albumLink","useCoverStyles","cover","objectFit","getColsForWidth","Cover","withContentRect","measureRef","contentRect","bounds","AlbumGridTile","showArtist","noSsr","GridListTileBar","actionIcon","LoadedAlbumGrid","useListContext","isArtistView","artist_id","GridList","cellHeight","cols","GridListTile","gridListTile","albumListType","Loading","AlbumFilter","NullableBooleanInput","NumberInput","AlbumListTitle","listTitle","perPageOptions","search","listParams","transitions","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","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","ArtistListView","handleArtistLink","history","useHistory","albumCount","ArtistList","MicNoneOutlinedIcon","MicIcon","PlaylistListActions","CreateButton","PlaylistFilter","TogglePublicInput","useUpdate","public","onFailure","togglePublic","canChange","Switch","PlaylistList","isRowSelectable","EditButton","SyncFragment","PlaylistTitle","PlaylistEdit","multiline","PlaylistCreate","PlaylistDetails","PlaylistSongBulkActions","mappedResource","ResourceContextProvider","BulkDeleteButton","ReorderableList","readOnly","PlaylistSongs","listContext","reorder","newPos","insert_before","handleDragEnd","from","toId","fromId","draggable","onDragEnd","nodeSelector","SanitizedPlaylistSongs","ListBase","PlaylistActions","getAllSongsAndDispatch","curr","handleExport","blob","Blob","URL","createObjectURL","click","parentNode","PlaylistShowLayout","QueueMusicOutlinedIcon","QueueMusicIcon","songAlbum","fontStyle","qualityInfo","aspectRatio","AudioTitle","isMobile","qi","songArtist","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","item","uuid","prevSong","playPrev","nextSong","Player","playerTheme","setStartTime","scrobbled","setScrobbled","setAudioInstance","useAuthState","authenticated","showNotifications","notifications","defaultOptions","mode","loadAudioErrorPlayNext","autoPlayInitLoadPlayList","clearPriorAudioLists","showDestroy","showDownload","showReload","toggleMode","glassBg","showThemeSwitch","showMediaSession","restartCurrentOnPrev","quietUpdate","defaultPosition","volumeFade","fadeIn","fadeOut","renderAudioTitle","audioLists","playIndex","autoPlay","extendsContent","defaultVolume","onAudioListsChange","syncQueue","onAudioProgress","ended","currentTime","isNaN","onAudioVolumeChange","setVolume","sqrt","onAudioPlay","ReactGA","category","image","silent","sendNotification","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","setLinked","setCheckingLink","linkCheckDelay","linkChecks","openedTab","callbackEndpoint","callbackUrl","origin","endChecking","success","result","closed","LinearProgress","LastfmScrobbleToggle","linked","checkingLink","Personal","routes","themeReducer","previousState","addToPlaylistDialogReducer","initialState","savedPlayIndex","mapToAudioLists","singer","musicSrc","reduceClearQueue","reducePlayTracks","reduceSetTrack","reduceAddTracks","reducePlayNext","newQueue","foundPos","reduceSetVolume","reduceSyncQueue","reduceCurrent","playerReducer","albumViewReducer","count","activityReducer","settingsReducer","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","App","Admin","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.5d17c301.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","// 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 // 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 lastFMEnabled: true,\n lastFMApiKey: '9b94a5515ea66b2da3ec03c12300327e',\n enableCoverAnimation: 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","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 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 return dataProvider.deleteMany(r, p)\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 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","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 if (es) {\n es.close()\n }\n es = null\n await startEventStream()\n }, currentIntervalCheck)\n}\n\nconst stopEventStream = () => {\n if (es) {\n es.close()\n }\n es = null\n if (timeout) {\n window.clearTimeout(timeout)\n }\n timeout = null\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 console.log('Cannot create a unauthenticated EventSource connection')\n return Promise.reject()\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 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 },\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 },\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 },\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 },\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 },\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 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 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'\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 SpotifyTheme,\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 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 Navidrome\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 ExpandMore from '@material-ui/icons/ExpandMore'\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 Divider from '@material-ui/core/Divider'\nimport Collapse from '@material-ui/core/Collapse'\nimport Tooltip from '@material-ui/core/Tooltip'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useTranslate } from 'react-admin'\n\nconst useStyles = makeStyles(\n (theme) => ({\n icon: { minWidth: theme.spacing(5) },\n sidebarIsOpen: {\n paddingLeft: 25,\n transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',\n },\n sidebarIsClosed: {\n paddingLeft: 0,\n transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',\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}) => {\n const translate = useTranslate()\n const classes = useStyles()\n\n const header = (\n \n \n {isOpen ? : icon}\n \n \n {translate(name)}\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}\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: 'navidrome.org',\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://github.com/navidrome/navidrome/compare/v${\n parts[0].split('-')[0]\n }...${commitID}`\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 Navidrome 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 ko-fi.com/deluan\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 { useAlbumsPerPage } from './index'\nimport { withWidth } from '@material-ui/core'\n\nexport const useGetHandleArtistClick = (width) => {\n const [perPage] = useAlbumsPerPage(width)\n\n return (id) => {\n return `/album?filter={\"artist_id\":\"${id}\"}&order=ASC&sort=maxYear&displayedFilters={\"compilation\":true}&perPage=${perPage}`\n }\n}\n\nexport const ArtistLinkField = withWidth()(({ record, className, width }) => {\n const artistLink = useGetHandleArtistClick(width)\n return (\n e.stopPropagation()}\n className={className}\n >\n {record.albumArtist}\n \n )\n})\n\nArtistLinkField.propTypes = {\n record: PropTypes.object,\n className: PropTypes.string,\n}\n\nArtistLinkField.defaultProps = {\n addLabel: true,\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 return baseUrl(url('getCoverArt', record.coverArtId || 'not_found', options))\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}\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} 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}) => {\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 }\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'\n\nexport const SizeField = ({ source, ...rest }) => {\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 { playNext, addTracks, setTrack, openAddToPlaylist } 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 }\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 } 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 { playTracks } from '../actions'\nimport { AlbumContextMenu } from '../common'\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 = ({\n record,\n onClick,\n colSpan,\n contextAlwaysVisible,\n}) => {\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\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 if (!record || !record.title) {\n return null\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 SongDetails = (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 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 Navidrome {text ? ` - ${text}` : ''}\n }\n return {text ? text : 'Navidrome'}\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 = (owner) => {\n return (\n localStorage.getItem('username') === owner ||\n localStorage.getItem('role') === 'admin'\n )\n}\n\nexport const isReadOnly = (owner) => {\n return !isWritable(owner)\n}\n\nexport const Writable = (props) => {\n const { record = {}, children } = props\n if (isWritable(record.owner)) {\n return Children.map(children, (child) =>\n isValidElement(child) ? cloneElement(child, props) : child\n )\n }\n return null\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 { 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\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 ) {\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.owner))\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 { useDataProvider, useNotify, useTranslate } 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 [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 })\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 { 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 ))}\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, { useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { makeStyles } from '@material-ui/core'\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'\n\nconst useStyles = makeStyles((theme) => ({\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 = ({ onMenuClick, dense }) => {\n const open = useSelector((state) => state.admin.ui.sidebarOpen)\n const translate = useTranslate()\n const classes = useStyles()\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 menuLibrary: true,\n menuSettings: false,\n })\n\n const handleToggle = (menu) => {\n setState((state) => ({ ...state, [menu]: !state[menu] }))\n }\n\n const renderResourceMenuItemLink = (resource) => (\n }\n onClick={onMenuClick}\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 onClick={onMenuClick}\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 \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 } 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\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 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\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 && (\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 {\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 SongDetails,\n QuickFilter,\n SongTitleField,\n SongSimpleList,\n RatingField,\n useResourceRefresh,\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'\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: <TextField source=\"artist\" />,\n albumArtist: <TextField 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 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: ['bpm', 'playDate', 'albumArtist', 'genre', 'comment'],\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 expand={<SongDetails />}\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 </>\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 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 Datagrid,\n DateField,\n NumberField,\n SingleFieldList,\n TextField,\n useRecordContext,\n useTranslate,\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 {\n ArtistLinkField,\n DurationField,\n RangeField,\n SimpleList,\n MultiLineTextField,\n AlbumContextMenu,\n RatingField,\n useSelectedFields,\n} from '../common'\nimport config from '../config'\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 AlbumDetails = (props) => {\n const classes = useStyles()\n const translate = useTranslate()\n const record = useRecordContext(props)\n const data = {\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\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={'maxYear'} 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={'maxYear'} />\n      \n </>\n )}\n linkType={'show'}\n rightIcon={(r) => <AlbumContextMenu record={r} />}\n {...rest}\n />\n ) : (\n <Datagrid\n expand={<AlbumDetails />}\n rowClick={'show'}\n classes={{ row: classes.row }}\n {...rest}\n >\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 </Datagrid>\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 subsonic from '../subsonic'\nimport {\n AlbumContextMenu,\n PlayButton,\n ArtistLinkField,\n RangeField,\n} from '../common'\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 ({ album, 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 return (\n <div ref={measureRef}>\n <img\n src={subsonic.getCoverArtUrl(album, 300)}\n alt={album.name}\n className={classes.cover}\n />\n </div>\n )\n }\n)\n\nconst AlbumGridTile = ({ showArtist, record, basePath }) => {\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\n return (\n <div className={classes.albumContainer}>\n <Link\n className={classes.link}\n to={linkToRecord(basePath, record.id, 'show')}\n >\n <Cover album={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={'maxYear'}\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\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 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'\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 </>\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 SongDetails,\n SongTitleField,\n RatingField,\n QualityInfo,\n useSelectedFields,\n useResourceRefresh,\n} from '../common'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport config from '../config'\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 isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\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 quality: isDesktop && <QualityInfo source=\"quality\" 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: ['bpm', 'year'],\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 expand={isXsmall ? null : <SongDetails />}\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 </>\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-all',\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 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={'p'} 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 {isDesktop && (\n <Typography component={'p'} 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 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 { 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'\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 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 <Datagrid 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 </Datagrid>\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 from 'react'\nimport ArtistList from './ArtistList'\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 icon: (\n <DynamicMenuIcon\n path={'artist'}\n icon={MicNoneOutlinedIcon}\n activeIcon={MicIcon}\n />\n ),\n}\n","import React 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 <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 React, { useMemo } from 'react'\nimport {\n Datagrid,\n DateField,\n EditButton,\n Filter,\n NumberField,\n SearchInput,\n TextField,\n useUpdate,\n useNotify,\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'\n\nconst PlaylistFilter = (props) => (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n </Filter>\n)\n\nconst TogglePublicInput = ({ permissions, resource, record = {}, source }) => {\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 const canChange =\n permissions === 'admin' ||\n localStorage.getItem('username') === record['owner']\n\n return (\n <Switch\n checked={record[source]}\n onClick={handleClick}\n disabled={!canChange}\n />\n )\n}\n\nconst PlaylistList = ({ permissions, ...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 return {\n owner: <TextField source=\"owner\" />,\n songCount: isDesktop && <NumberField source=\"songCount\" />,\n duration: isDesktop && <DurationField source=\"duration\" />,\n updatedAt: isDesktop && (\n <DateField source=\"updatedAt\" sortByOrder={'DESC'} />\n ),\n public: !isXsmall && (\n <TogglePublicInput\n source=\"public\"\n permissions={permissions}\n sortByOrder={'DESC'}\n />\n ),\n }\n }, [isDesktop, isXsmall, permissions])\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 >\n <Datagrid\n rowClick=\"show\"\n isRowSelectable={(r) => isWritable(r && r.owner)}\n >\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} from 'react-admin'\nimport { 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 PlaylistEdit = (props) => (\n <Edit title={<PlaylistTitle />} {...props}>\n <SimpleForm redirect=\"list\" variant={'outlined'}>\n <TextInput source=\"name\" validate={required()} />\n <TextInput multiline source=\"comment\" />\n <BooleanInput source=\"public\" />\n <FormDataConsumer>\n {(formDataProps) => <SyncFragment {...formDataProps} />}\n </FormDataConsumer>\n </SimpleForm>\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} from 'react-admin'\nimport { Title } from '../common'\n\nconst PlaylistCreate = (props) => {\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 return (\n <Create title={<Title subTitle={title} />} {...props}>\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 useRefresh,\n useDataProvider,\n useNotify,\n useVersion,\n useListContext,\n ListBase,\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 SongDetails,\n SongContextMenu,\n SongDatagrid,\n SongTitleField,\n QualityInfo,\n useSelectedFields,\n useResourceRefresh,\n} from '../common'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport { AlbumLinkField } from '../song/AlbumLinkField'\nimport { playTracks } from '../actions'\nimport PlaylistSongBulkActions from './PlaylistSongBulkActions'\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, onUnselectItems } = listContext\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const dispatch = useDispatch()\n const dataProvider = useDataProvider()\n const refresh = useRefresh()\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 refresh()\n }\n },\n [playlistId, refresh]\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 refresh()\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n },\n [dataProvider, notify, refresh]\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 && <TextField source=\"artist\" />,\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 quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n bpm: isDesktop && <NumberField source=\"bpm\" />,\n }\n }, [isDesktop, classes.draggable])\n\n const columns = useSelectedFields({\n resource: 'playlistTrack',\n columns: toggleableFields,\n defaultOff: ['bpm', 'year'],\n })\n\n return (\n <>\n <ListToolbar\n classes={{ toolbar: classes.toolbar }}\n filters={props.filters}\n actions={actions}\n {...listContext}\n />\n <div className={classes.main}>\n <Card\n className={clsx(classes.content, {\n [classes.bulkActionsDisplayed]: listContext.selectedIds.length > 0,\n })}\n key={version}\n >\n <BulkActionsToolbar {...listContext}>\n <PlaylistSongBulkActions\n playlistId={playlistId}\n onUnselectItems={onUnselectItems}\n />\n </BulkActionsToolbar>\n <ReorderableList\n readOnly={readOnly}\n onDragEnd={handleDragEnd}\n nodeSelector={'tr'}\n >\n <SongDatagrid\n expand={!isXsmall && <SongDetails />}\n rowClick={(id) => dispatch(playTracks(data, ids, id))}\n {...listContext}\n hasBulkActions={true}\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 {React.cloneElement(props.pagination, listContext)}\n </>\n )\n}\n\nconst SanitizedPlaylistSongs = (props) => {\n const { loaded, ...rest } = props\n return (\n <>\n {loaded && (\n <>\n <ListBase {...props}>\n <PlaylistSongs\n playlistId={props.id}\n actions={props.actions}\n pagination={props.pagination}\n {...rest}\n />\n </ListBase>\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 as RaPagination,\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, isReadOnly } from '../common'\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={isReadOnly(record.owner)}\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={<RaPagination 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 <span className={clsx(classes.songInfo)}>\n {`${song.artist} - ${song.album}` +\n (song.year ? ` - ${song.year}` : '')}\n </span>\n )}\n {isMobile && (\n <>\n <span className={clsx(classes.songInfo, classes.songArtist)}>\n {`${song.artist}`}\n </span>\n <span className={clsx(classes.songInfo, classes.songAlbum)}>\n {song.year ? `${song.album} - ${song.year}` : `${song.album}`}\n </span>\n </>\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, 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 [audioInstance, setAudioInstance] = useState(null)\n const isDesktop = useMediaQuery('(min-width:810px)')\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 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: playerState.volume,\n }\n }, [playerState, defaultOptions])\n\n const onAudioListsChange = useCallback(\n (_, audioLists, audioInfo) => dispatch(syncQueue(audioInfo, audioLists)),\n [dispatch]\n )\n\n const onAudioProgress = useCallback(\n (info) => {\n if (info.ended) {\n document.title = 'Navidrome'\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 (!scrobbled) {\n info.trackId && subsonic.scrobble(info.trackId, startTime)\n setScrobbled(true)\n }\n },\n [startTime, scrobbled]\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 if (audioInstance) {\n audioInstance.volume = playerState.volume\n }\n dispatch(currentPlaying(info))\n setStartTime(Date.now())\n if (info.duration) {\n const song = info.song\n document.title = `${song.title} - ${song.artist} - Navidrome`\n subsonic.nowPlaying(info.trackId)\n setScrobbled(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, audioInstance, playerState.volume]\n )\n\n const onAudioPause = useCallback(\n (info) => dispatch(currentPlaying(info)),\n [dispatch]\n )\n\n const onAudioEnded = useCallback(\n (currentPlayId, audioLists, info) => {\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 = 'Navidrome'\n }\n\n const handlers = useMemo(\n () => keyHandlers(audioInstance, playerState),\n [audioInstance, playerState]\n )\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 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 { 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 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={'Navidrome - ' + translate('menu.personal.name')} />\n <SimpleForm toolbar={null} variant={'outlined'}>\n <SelectTheme />\n <SelectLanguage />\n <SelectDefaultView />\n <NotificationsToggle />\n {config.lastFMEnabled && <LastfmScrobbleToggle />}\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 {\n ADD_TO_PLAYLIST_CLOSE,\n ADD_TO_PLAYLIST_OPEN,\n DUPLICATE_SONG_WARNING_OPEN,\n DUPLICATE_SONG_WARNING_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","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: Math.pow(0.5, 2), // 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 return {\n trackId,\n uuid: uuidv4(),\n song: item,\n name: item.title,\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 { 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 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, useDispatch } 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 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 } 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 App = () => (\n <Provider\n store={createAdminStore({\n authProvider,\n dataProvider,\n history,\n customReducers: {\n player: playerReducer,\n albumView: albumViewReducer,\n theme: themeReducer,\n addToPlaylistDialog: addToPlaylistDialogReducer,\n activity: activityReducer,\n settings: settingsReducer,\n },\n })}\n >\n <Admin />\n </Provider>\n)\n\nconst Admin = (props) => {\n useChangeThemeColor()\n const dispatch = useDispatch()\n useEffect(() => {\n if (config.devActivityPanel) {\n setDispatch(dispatch)\n authProvider\n .checkAuth()\n .then(() => startEventStream())\n .catch(() => {}) // ignore if not logged in\n }\n }, [dispatch])\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 name=\"playlist\" {...playlist} />,\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","// 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":""}