{"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/SongInfo.js","common/SongTitleField.js","icons/paused-light.png","icons/paused-dark.png","icons/playing-light.gif","icons/playing-dark.gif","common/Title.js","common/SongBulkActions.js","common/useAlbumsPerPage.js","common/useInterval.js","common/useResourceRefresh.js","common/Writable.js","common/SongSimpleList.js","common/ArtistSimpleList.js","common/RatingField.js","common/useRating.js","common/useSelectedFields.js","common/ToggleFieldsMenu.js","common/QualityInfo.js","dialogs/SelectPlaylistInput.js","dialogs/DuplicateSongDialog.js","dialogs/AddToPlaylistDialog.js","hotkeys.js","dialogs/HelpDialog.js","dialogs/ListenBrainzTokenDialog.js","layout/PlaylistsSubMenu.js","layout/Menu.js","layout/PersonalMenu.js","layout/ActivityPanel.js","layout/UserMenu.js","layout/AppBar.js","layout/Layout.js","transcoding/TranscodingList.js","transcoding/TranscodingNote.js","transcoding/TranscodingEdit.js","transcoding/TranscodingCreate.js","transcoding/TranscodingShow.js","transcoding/index.js","player/PlayerList.js","player/PlayerEdit.js","player/index.js","user/UserList.js","user/DeleteUserButton.js","user/UserEdit.js","user/index.js","user/UserCreate.js","song/SongListActions.js","song/AlbumLinkField.js","dialogs/ExpandInfoDialog.js","song/SongList.js","song/index.js","album/AlbumListActions.js","album/AlbumTableView.js","album/AlbumGridView.js","album/AlbumInfo.js","album/AlbumList.js","album/AlbumSongs.js","icons/MusicBrainz.js","album/AlbumExternalLinks.js","album/AlbumDetails.js","album/AlbumActions.js","album/AlbumShow.js","album/index.js","artist/ArtistListActions.js","artist/ArtistList.js","artist/MobileArtistDetails.js","artist/ArtistExternalLink.js","artist/DesktopArtistDetails.js","artist/ArtistShow.js","artist/index.js","playlist/PlaylistListActions.js","playlist/ChangePublicStatusButton.js","playlist/PlaylistList.js","playlist/PlaylistEdit.js","playlist/PlaylistCreate.js","playlist/PlaylistDetails.js","playlist/PlaylistSongBulkActions.js","playlist/PlaylistSongs.js","playlist/PlaylistActions.js","playlist/PlaylistShow.js","playlist/index.js","audioplayer/styles.js","audioplayer/AudioTitle.js","audioplayer/PlayerToolbar.js","audioplayer/locale.js","audioplayer/keyHandlers.js","audioplayer/Player.js","i18n/provider.js","i18n/useGetLanguageChoices.js","personal/HelpMsg.js","personal/SelectLanguage.js","personal/SelectTheme.js","personal/SelectDefaultView.js","personal/NotificationsToggle.js","personal/LastfmScrobbleToggle.js","personal/ListenBrainzScrobbleToggle.js","personal/Personal.js","routes.js","reducers/themeReducer.js","reducers/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","variousArtistsId","loginBackgroundURL","enableTranscodingConfig","enableDownloads","enableFavourites","losslessFormats","welcomeMessage","gaTrackingId","devActivityPanel","devFastAccessCoverArt","enableStarRating","defaultTheme","enableUserEditing","devEnableShare","devSidebarPlaylists","lastFMEnabled","lastFMApiKey","listenBrainzEnabled","enableCoverAnimation","devShowArtistPage","appConfig","JSON","parse","window","__APP_CONFIG__","e","baseUrl","path","parts","push","replace","join","docsUrl","formatBytes","bytes","decimals","k","dm","sizes","i","Math","floor","log","parseFloat","pow","toFixed","formatDuration","d","days","f","map","v","toString","length","filter","intersperse","arr","sep","slice","reduce","xs","x","concat","checkForNotificationPermission","Notification","permission","openInNewTab","url","win","open","focus","customAuthorizationHeader","clientUniqueIdHeader","clientUniqueId","uuidv4","httpClient","options","headers","Headers","Accept","set","token","localStorage","getItem","fetchUtils","fetchJson","then","response","get","decoded","jwtDecode","setItem","uid","REST_URL","M3U_MIME_TYPE","AUTO_THEME_ID","DraggableTypes","SONG","ALBUM","DISC","ARTIST","ALL","dataProvider","jsonServerProvider","mapResource","resource","params","plsId","playlist_id","wrapperDataProvider","getList","r","p","getOne","getMany","getManyReference","update","updateMany","create","delete","deleteMany","endsWith","idsParam","ids","id","method","data","json","callDeleteMany","addToPlaylist","playlistId","body","stringify","PLAYER_ADD_TRACKS","PLAYER_PLAY_NEXT","PLAYER_SET_TRACK","PLAYER_SYNC_QUEUE","PLAYER_CLEAR_QUEUE","PLAYER_PLAY_TRACKS","PLAYER_CURRENT","PLAYER_SET_VOLUME","setTrack","type","filterSongs","acc","addTracks","songs","playNext","shuffleTracks","shuffled","Object","keys","j","random","forEach","shuffle","firstId","playTracks","selectedId","clearQueue","currentPlaying","audioInfo","CHANGE_THEME","ALBUM_MODE_GRID","ALBUM_MODE_TABLE","ADD_TO_PLAYLIST_OPEN","ADD_TO_PLAYLIST_CLOSE","DUPLICATE_SONG_WARNING_OPEN","DUPLICATE_SONG_WARNING_CLOSE","EXTENDED_INFO_OPEN","EXTENDED_INFO_CLOSE","LISTENBRAINZ_TOKEN_OPEN","LISTENBRAINZ_TOKEN_CLOSE","openAddToPlaylist","selectedIds","onSuccess","closeAddToPlaylist","closeDuplicateSongDialog","openExtendedInfoDialog","record","closeListenBrainzTokenDialog","EVENT_SCAN_STATUS","EVENT_SERVER_START","EVENT_REFRESH_RESOURCE","SET_NOTIFICATIONS_STATE","SET_TOGGLEABLE_FIELDS","SET_OMITTED_FIELDS","setNotificationsState","enabled","setToggleableFields","obj","setOmittedFields","currentIntervalCheck","es","dispatch","timeout","getEventStream","a","EventSource","setTimeout","value","clearTimeout","close","startEventStream","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","fetch","status","Error","statusText","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","NDMobileArtistDetails","bgContainer","background","player","theme","stylesheet","require","primary","blue","MuiFormGroup","welcome","paper","default","NDArtistPage","green","spotifyGreen","musicListActions","padding","alignItems","margin","border","transform","transition","borderRadius","display","typography","fontFamily","h6","fontSize","MuiMenuItem","MuiDivider","MuiButton","textSecondary","label","paddingRight","paddingLeft","MuiDrawer","paddingTop","MuiTableRow","MuiTableCell","head","textTransform","letterSpacing","MuiAppBar","positionFixed","NDAlbumGridView","albumName","fontWeight","albumSubtitle","albumContainer","albumPlayButton","NDPlaylistDetails","container","title","details","NDAlbumDetails","cardContents","recordName","recordArtist","recordMeta","commentBlock","NDAlbumShow","albumActions","NDPlaylistShow","playlistActions","NDAudioPlayer","audioTitle","songTitle","songInfo","marginBottom","RaLayout","content","RaList","RaListToolbar","toolbar","RaSearchInput","input","RaFilterButton","marginRight","RaPaginationActions","currentPageButton","actions","marginLeft","RaSidebar","height","bLight","LightTheme","DarkTheme","ExtraDarkTheme","GreenTheme","LigeraTheme","text","MuiAutocomplete","popper","MuiCard","MuiPopover","MuiTypography","colorTextSecondary","MuiDialog","MuiFormLabel","MuiCheckbox","MuiIconButton","containedPrimary","textPrimary","colorSecondary","NDAppBar","NDSubMenu","textDecoration","systemName","width","overflow","RaDatagridHeaderCell","RaAutocompleteSuggestionList","suggestionsPaper","RaLink","link","RaLogout","RaMenuItemLink","active","drawerPaper","RaBulkActionsToolbar","SpotifyTheme","useCurrentTheme","prefersLightMode","useMediaQuery","useSelector","state","themes","find","t","useEffect","style","styles","document","getElementsByTagName","undefined","createElement","innerHTML","appendChild","removeChild","useStyles","makeStyles","flexDirection","minHeight","justifyContent","backgroundRepeat","backgroundSize","backgroundPosition","flexWrap","form","renderInput","meta","touched","inputProps","TextField","helperText","fullWidth","FormLogin","loading","handleSubmit","validate","translate","useTranslate","classes","onSubmit","render","noValidate","className","Card","src","Logo","alt","href","target","rel","dangerouslySetInnerHTML","__html","autoFocus","component","disabled","CardActions","variant","CircularProgress","size","thickness","FormSignUp","Login","location","useState","setLoading","notify","useNotify","useLogin","useDispatch","useCallback","nextPathname","validateLogin","values","errors","validateSignup","match","confirmPassword","LoginWithTheme","ThemeProvider","createMuiTheme","Logout","handleClick","onClick","spacing","sidebarIsOpen","sidebarIsClosed","actionIcon","opacity","menuHeader","headerWrapper","SubMenu","handleToggle","isOpen","children","dense","onAction","isDesktop","breakpoints","up","isSmall","down","header","MenuItem","ListItemIcon","Typography","IconButton","stopPropagation","setSidebarVisibility","Tooltip","placement","Collapse","in","unmountOnExit","disablePadding","defaultProps","action","DynamicMenuIcon","activeIcon","useLocation","pathname","startsWith","propTypes","PropTypes","string","isRequired","object","albumLists","all","AlbumOutlinedIcon","AlbumIcon","starred","FavoriteBorderIcon","FavoriteIcon","topRated","StarBorderIcon","StarIcon","recentlyAdded","LibraryAddOutlinedIcon","LibraryAddIcon","recentlyPlayed","VideoLibraryOutlinedIcon","VideoLibraryIcon","mostPlayed","defaultAlbumList","DialogTitle","withStyles","closeButton","position","right","top","grey","onClose","other","disableTypography","aria-label","DialogContent","MuiDialogContent","links","homepage","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","artistLink","to","addLabel","BatchPlayButton","useDataProvider","caption","tracks","cur","BitrateField","rest","useRecordContext","command","URLSearchParams","append","ts","Date","getTime","scrobble","time","submission","nowPlaying","download","star","unstar","setRating","rating","startScan","getScanStatus","getCoverArtUrl","updatedAt","coverArtId","streamUrl","getArtistInfo","useToggleLove","mountedRef","useRef","current","refreshRecord","toggleLove","toggle","subsonic","love","visibility","visible","loved","LoveButton","Button","handleToggleLove","preventDefault","noWrap","whiteSpace","menu","ContextMenu","showLove","songQueryParams","hideInfo","anchorEl","setAnchorEl","play","needData","addToQueue","info","handleItemClick","getAttribute","extractSongsData","Boolean","clsx","currentTarget","keepMounted","AlbumContextMenu","pagination","page","sort","field","order","album_id","disc_number","discNumber","ArtistContextMenu","album_artist_id","DateField","DurationField","Pagination","rowsPerPageOptions","List","subTitle","args","smart_count","sanitizeFieldRestProps","allowEmpty","basePath","cellClassName","emptyText","formClassName","headerClassName","linkType","locale","sortable","sortBy","sortByOrder","textAlign","translateChoice","MultiLineTextField","memo","firstLine","maxLines","lines","line","idx","md5","data-testid","PlayButton","playAlbum","useQuickFilterStyles","chip","QuickFilter","defaultValue","lbl","String","Chip","formatRange","nameCapitalized","charAt","toUpperCase","min","max","range","RangeField","ShuffleAllButton","filters","res","song","tertiary","float","LinkOrNot","classesOverride","linkToRecord","SimpleList","hasBulkActions","leftAvatar","leftIcon","primaryText","onToggleItem","rightAvatar","rightIcon","secondaryText","tertiaryText","total","sanitizeListRestProps","ListItem","ListItemAvatar","Avatar","ListItemText","ListItemSecondaryAction","SizeField","SongContextMenu","onAddToPlaylist","playNow","mediaFileId","subtitle","textOverflow","verticalAlign","discIcon","row","cursor","headerStyle","contextMenu","DiscSubtitleRow","forwardRef","ref","colSpan","contextAlwaysVisible","discSubtitle","hover","albumId","SongDatagridRow","firstTracks","onClickDiscSubtitle","fields","React","Children","toArray","c","isValidElement","useDrag","item","discs","dropEffect","dragDiscRef","dragSongRef","childCount","has","expand","SongDatagridBody","showDiscSubtitles","playDisc","idsToPlay","useMemo","Set","foundSubtitle","last","clear","SongDatagrid","Datagrid","tableCell","SongInfo","album","albumArtist","genre","FunctionField","genres","g","compilation","BooleanField","bitRate","channels","NumberField","showTime","playCount","bpm","comment","playDate","SongTitleField","showTrackNumbers","useTheme","currentTrack","currentId","trackId","paused","isCurrent","Icon","trackNumber","padStart","Title","SongBulkActions","getPerPageOptions","admin","resources","list","getPerPage","useInterval","callback","delay","savedCallback","setInterval","clearInterval","useResourceRefresh","visibleResources","now","lastTime","setLastTime","refresh","useRefresh","refreshData","activity","lastReceived","v2","isWritable","ownerId","Writable","child","cloneElement","canChangeTracks","pls","rules","isSmartPlaylist","listItem","artist","timeStamp","SongSimpleList","ArtistSimpleList","show","hide","RatingField","refreshRating","val","useRating","rate","handleRating","Rating","emptyIcon","onChange","newValue","useSelectedFields","columns","omittedColumns","defaultOff","resourceFields","settings","toggleableFields","omittedFields","filteredComponents","setFilteredComponents","every","filtered","omitted","entries","arrayOf","useSetToggleableFields","toggleableColumns","menuIcon","maxHeight","ToggleFieldsMenu","TopBarComponent","topbarComponent","selectedColumn","Checkbox","checked","llFormats","useStyle","QualityInfo","suffix","createFilterOptions","checkbox","SelectPlaylistInput","useGetList","option","checkedIcon","Autocomplete","multiple","disableCloseOnSelect","newState","playlistObject","inputValue","filterOptions","clearOnBlur","handleHomeEndKeys","openOnFocus","selectOnFocus","getOptionLabel","renderOption","selected","Fragment","freeSolo","DuplicateSongDialog","handleClickClose","handleSkip","DialogActions","AddToPlaylistDialog","addToPlaylistDialog","duplicateSong","duplicateIds","setValue","check","setCheck","distinctIds","trackIds","Array","isArray","len","checkDuplicateSong","dupSng","some","dupIds","openDuplicateSongWarning","maxWidth","newlyAdded","pop","createAndAddToPlaylist","distinctSongs","indexOf","keyMap","SHOW_HELP","sequence","group","TOGGLE_MENU","TOGGLE_PLAY","PREV_SONG","NEXT_SONG","VOL_UP","VOL_DOWN","TOGGLE_LOVE","HelpTable","getApplicationKeyMap","ReactDOM","createPortal","sequences","description","HelpDialog","setOpen","handlers","allowChanges","ListenBrainzTokenDialog","setLinked","listenBrainzTokenDialog","setToken","checking","setChecking","inputRef","createRef","handleSave","user","finally","handleKeyPress","DialogContentText","onKeyPress","required","LinearProgress","PlaylistMenuItemLink","useDrop","accept","drop","added","dropRef","MenuItemLink","PlaylistsSubMenu","setState","history","useHistory","useQueryWithStore","payload","loaded","renderPlaylistMenuItemLink","userId","myPlaylists","sharedPlaylists","onPlaylistConfig","menuPlaylists","menuSharedPlaylists","transitions","easing","sharp","duration","leavingScreen","paddingBottom","addPadding","closed","translatedResourceName","pluralize","withRouter","ui","sidebarOpen","queue","getResources","menuAlbumList","renderResourceMenuItemLink","activeClassName","subItems","subMenu","hasList","al","albumListAddress","exact","renderAlbumMenuItemLink","Divider","menuItem","PersonalMenu","wrapper","progress","left","zIndex","counterStatus","getUptime","serverStart","startTime","Uptime","uptime","setUptime","ActivityPanel","scanStatus","triggerScan","full","fullScan","resp","scanStatusUpdate","Badge","badgeContent","scanning","Popover","transformOrigin","CardContent","Box","flex","folderCount","usernameWrap","UserMenu","useGetIdentity","identity","handleClose","aria-owns","MenuList","elevation","AboutMenuItem","titleAccess","settingsResources","CustomUserMenu","permissions","usePermissions","renderSettingsMenuItemLink","resourceName","userResource","PersonIcon","SupervisorAccountIcon","renderUserMenuItemLink","AppBar","userMenu","Layout","keyHandlers","toggleSidebar","DndProvider","backend","HTML5Backend","Menu","appBar","notification","TranscodingList","isXsmall","exporter","targetFormat","defaultBitRate","rowClick","Interpolate","TranscodingNote","TranscodingTitle","TranscodingEdit","Edit","SimpleForm","TextInput","SelectInput","choices","TranscodingCreate","Create","TranscodingShow","Show","SimpleShowLayout","edit","TransformIcon","PlayerFilter","Filter","SearchInput","alwaysOn","PlayerList","client","userName","maxBitRate","ReferenceField","reference","PlayerTitle","ReferenceInput","resettable","BooleanInput","RadioIcon","UserFilter","UserList","bulkActionButtons","lastLoginAt","toLocaleString","deleteButton","fade","DeleteUserButton","redirect","useRedirect","useDeleteWithConfirmController","handleDialogOpen","handleDialogClose","handleDelete","Confirm","translateOptions","onConfirm","UserTitle","UserToolbar","showDelete","SaveButton","pristine","CurrentPasswordInput","formData","isMyself","changePassword","PasswordInput","NewPasswordInput","useMutation","mutate","canDelete","save","returnPromise","undoable","email","FormDataConsumer","formDataProps","initialValue","SongListActions","currentSort","displayedFilters","filterValues","showFilter","permanentFilter","onUnselectItems","maxResults","isNotSmall","TopToolbar","context","AlbumLinkField","ExpandInfoDialog","expandInfoDialog","RecordContext","contextHeader","ratingField","SongFilter","filterToQuery","searchText","AutocompleteInput","SongList","year","quality","MusicNoteOutlinedIcon","MusicNoteIcon","buttonGroup","leftButton","rightButton","AlbumViewToggler","showTitle","disableElevation","albumView","ButtonGroup","grid","AlbumListActions","columnIcon","AlbumDatagridRow","albumIds","dragAlbumRef","DatagridRow","AlbumDatagridBody","DatagridBody","AlbumDatagrid","AlbumTableView","hasShow","hasEdit","syncWithLocation","songCount","tileBar","tileBarMobile","albumArtistName","albumLink","useCoverStyles","cover","objectFit","getColsForWidth","Cover","withContentRect","measureRef","contentRect","bounds","AlbumGridTile","showArtist","noSsr","GridListTileBar","LoadedAlbumGrid","useListContext","isArtistView","artist_id","GridList","cellHeight","cols","GridListTile","gridListTile","albumListType","Loading","AlbumInfo","ArrayField","SingleFieldList","ChipField","AlbumFilter","NullableBooleanInput","NumberInput","AlbumListTitle","listTitle","perPageOptions","search","listParams","bulkActionsDisplayed","noResults","AlbumSongs","useVersion","ListToolbar","BulkActionsToolbar","SanitizedAlbumSongs","removeAlbumCommentsFromSongs","MusicBrainz","SvgIcon","xmlns","viewBox","AlbumExternalLinks","addLink","translatedTitle","encodeURIComponent","mbzAlbumId","coverParent","loveButton","wordBreak","pointerCursor","genreList","externalLinks","AlbumComment","expanded","setExpanded","formatted","handleExpandClick","collapsedHeight","GenreChipField","genreLink","useGetHandleGenreClick","GenreList","Details","addDetail","AlbumDetails","isLightboxOpen","setLightboxOpen","imageUrl","fullImageUrl","handleOpenLightbox","handleCloseLightbox","CardMedia","imagePadding","animationDuration","imageTitle","mainSrc","onCloseRequest","AlbumActions","handlePlay","handlePlayNext","handlePlayLater","handleShuffle","handleAddToPlaylist","handleDownload","AlbumShowLayout","useShowContext","ReferenceManyField","AlbumList","controllerProps","useShowController","ShowContextProvider","ArtistListActions","ArtistFilter","ArtistDatagridRow","artistIds","dragArtistRef","ArtistDatagridBody","ArtistDatagrid","ArtistListView","handleArtistLink","albumCount","img","backdropFilter","biography","artistImage","artistName","MobileArtistDetails","artistInfo","image","mediumImageUrl","largeImageUrl","ArtistExternalLinks","linkButtons","lastFMlink","musicBrainzId","artistDetail","DesktopArtistDetails","ArtistExternalLink","ArtistDetails","setArtistInfo","RegExp","showContext","ArtistShow","ArtistList","MicNoneOutlinedIcon","MicIcon","PlaylistListActions","CreateButton","ChangePublicStatusButton","playlists","public","LockOpen","Lock","BulkUpdateButton","PlaylistFilter","optionText","TogglePublicInput","useUpdate","onFailure","togglePublic","Switch","PlaylistListBulkActions","BulkDeleteButton","PlaylistList","ownerName","isRowSelectable","EditButton","SyncFragment","PlaylistTitle","PlaylistEditForm","multiline","PlaylistEdit","PlaylistCreate","PlaylistDetails","PlaylistSongBulkActions","mappedResource","ResourceContextProvider","ReorderableList","readOnly","PlaylistSongs","listContext","refetch","reorder","newPos","insert_before","handleDragEnd","from","toId","fromId","draggable","onDragEnd","nodeSelector","SanitizedPlaylistSongs","PlaylistActions","getAllSongsAndDispatch","curr","handleExport","blob","Blob","URL","createObjectURL","click","parentNode","PlaylistShowLayout","QueueMusicOutlinedIcon","QueueMusicIcon","songAlbum","fontStyle","qualityInfo","aspectRatio","AudioTitle","isMobile","qi","Placeholder","Toolbar","useGetOne","toggling","PlayerToolbar","playListsText","openText","closeText","notContentText","clickToPlayText","clickToPauseText","nextTrackText","previousTrackText","reloadText","volumeText","toggleLyricText","toggleMiniModeText","destroyText","downloadText","removeAudioListsText","clickToDeleteText","emptyLyricText","playModeText","orderLoop","singleLoop","shufflePlay","audioInstance","playerState","togglePlay","volume","metaKey","findIndex","uuid","prevSong","playPrev","nextSong","Player","playerTheme","setStartTime","scrobbled","setScrobbled","preloaded","setPreload","setAudioInstance","useAuthState","authenticated","showNotifications","notifications","defaultOptions","mode","loadAudioErrorPlayNext","autoPlayInitLoadPlayList","clearPriorAudioLists","showDestroy","showDownload","showLyric","showReload","toggleMode","glassBg","showThemeSwitch","showMediaSession","restartCurrentOnPrev","quietUpdate","defaultPosition","volumeFade","fadeIn","fadeOut","renderAudioTitle","audioLists","playIndex","autoPlay","extendsContent","defaultVolume","onAudioListsChange","syncQueue","onAudioProgress","ended","currentTime","isNaN","next","Audio","musicSrc","onAudioVolumeChange","setVolume","sqrt","onAudioPlay","ReactGA","category","silent","sendNotification","onAudioPlayTrackChange","onAudioPause","onAudioEnded","currentPlayId","onCoverClick","onBeforeDestroy","getAudioInstance","retrieveTranslation","prepareLanguage","removeEmpty","hasOwnProperty","lang","albumSong","playlistTrack","ra","boolean","null","deepmerge","en","polyglotI18nProvider","i18nProvider","changeLocale","defaultLocale","useGetLanguageChoices","b","localeCompare","HelpMsg","helpKey","SelectLanguage","setLocale","useSetLocale","useLocale","SelectTheme","currentTheme","themeChoices","SelectDefaultView","NotificationsToggle","currentSetting","notAvailable","isSecureContext","FormControl","FormControlLabel","control","requestPermission","FormHelperText","Progress","setCheckingLink","linkCheckDelay","linkChecks","openedTab","callbackEndpoint","callbackUrl","origin","endChecking","success","result","LastfmScrobbleToggle","linked","checkingLink","ListenBrainzScrobbleToggle","Personal","routes","themeReducer","previousState","addToPlaylistDialogReducer","expandInfoDialogReducer","listenBrainzTokenDialogReducer","initialState","savedPlayIndex","mapToAudioLists","lyrics","lyric","test","singer","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.d881c2de.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 variousArtistsId: '03b645ef2100dfc42fa9785ea3102295', // See consts.VariousArtistsID in consts.go\n // Login backgrounds from https://unsplash.com/collections/1065384/music-wallpapers\n loginBackgroundURL: 'https://source.unsplash.com/collection/1065384/1600x900',\n enableTranscodingConfig: true,\n enableDownloads: true,\n enableFavourites: true,\n losslessFormats: 'FLAC,WAV,ALAC,DSF',\n welcomeMessage: '',\n gaTrackingId: '',\n devActivityPanel: true,\n devFastAccessCoverArt: false,\n enableStarRating: true,\n defaultTheme: 'Dark',\n enableUserEditing: true,\n devEnableShare: true,\n devSidebarPlaylists: true,\n lastFMEnabled: true,\n lastFMApiKey: '9b94a5515ea66b2da3ec03c12300327e',\n listenBrainzEnabled: true,\n enableCoverAnimation: true,\n devShowArtistPage: true,\n}\n\nlet config\n\ntry {\n const appConfig = JSON.parse(window.__APP_CONFIG__)\n\n config = {\n ...defaultConfig,\n ...appConfig,\n }\n} catch (e) {\n config = defaultConfig\n}\n\nexport default config\n","import config from '../config'\n\nexport const baseUrl = (path) => {\n const base = config.baseURL || ''\n const parts = [base]\n parts.push(path.replace(/^\\//, ''))\n return parts.join('/')\n}\n","export const docsUrl = (path) => `https://www.navidrome.org${path}`\n","export const formatBytes = (bytes, decimals = 2) => {\n if (bytes === 0) return '0 Bytes'\n\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]\n}\n\nexport const formatDuration = (d) => {\n const days = Math.floor(d / 86400)\n const hours = Math.floor(d / 3600) % 24\n const minutes = Math.floor(d / 60) % 60\n const seconds = Math.floor(d % 60)\n const f = [hours, minutes, seconds]\n .map((v) => v.toString())\n .map((v) => (v.length !== 2 ? '0' + v : v))\n .filter((v, i) => v !== '00' || i > 0)\n .join(':')\n\n return `${days > 0 ? days + ':' : ''}${f}`\n}\n","/* intersperse: Return an array with the separator interspersed between\n * each element of the input array.\n *\n * > _([1,2,3]).intersperse(0)\n * [1,0,2,0,3]\n *\n * From: https://stackoverflow.com/a/23619085\n */\nexport const intersperse = (arr, sep) => {\n if (arr.length === 0) {\n return []\n }\n\n return arr.slice(1).reduce(\n function (xs, x, i) {\n return xs.concat([sep, x])\n },\n [arr[0]]\n )\n}\n","export const sendNotification = (title, body = '', image = '') => {\n checkForNotificationPermission()\n new Notification(title, {\n body: body,\n icon: image,\n silent: true,\n })\n}\n\nconst checkForNotificationPermission = () => {\n return 'Notification' in window && Notification.permission === 'granted'\n}\n","export const openInNewTab = (url) => {\n const win = window.open(url, '_blank')\n win.focus()\n return win\n}\n","import { fetchUtils } from 'react-admin'\nimport { v4 as uuidv4 } from 'uuid'\nimport { baseUrl } from '../utils'\nimport config from '../config'\nimport jwtDecode from 'jwt-decode'\n\nconst customAuthorizationHeader = 'X-ND-Authorization'\nconst clientUniqueIdHeader = 'X-ND-Client-Unique-Id'\nconst clientUniqueId = uuidv4()\n\nconst httpClient = (url, options = {}) => {\n url = baseUrl(url)\n if (!options.headers) {\n options.headers = new Headers({ Accept: 'application/json' })\n }\n options.headers.set(clientUniqueIdHeader, clientUniqueId)\n const token = localStorage.getItem('token')\n if (token) {\n options.headers.set(customAuthorizationHeader, `Bearer ${token}`)\n }\n return fetchUtils.fetchJson(url, options).then((response) => {\n const token = response.headers.get(customAuthorizationHeader)\n if (token) {\n const decoded = jwtDecode(token)\n localStorage.setItem('token', token)\n localStorage.setItem('userId', decoded.uid)\n // Avoid going to create admin dialog after logout/login without a refresh\n config.firstTime = false\n }\n return response\n })\n}\n\nexport default httpClient\n","export const REST_URL = '/api'\n\nexport const M3U_MIME_TYPE = 'audio/x-mpegurl'\n\nexport const AUTO_THEME_ID = 'AUTO_THEME_ID'\n\nexport const DraggableTypes = {\n SONG: 'song',\n ALBUM: 'album',\n DISC: 'disc',\n ARTIST: 'artist',\n ALL: [],\n}\n\nDraggableTypes.ALL.push(\n DraggableTypes.SONG,\n DraggableTypes.ALBUM,\n DraggableTypes.DISC,\n DraggableTypes.ARTIST\n)\n\nexport const MAX_SIDEBAR_PLAYLISTS = 100\n","import jsonServerProvider from 'ra-data-json-server'\nimport httpClient from './httpClient'\nimport { REST_URL } from '../consts'\n\nconst dataProvider = jsonServerProvider(REST_URL, httpClient)\n\nconst mapResource = (resource, params) => {\n switch (resource) {\n case 'playlistTrack':\n // /api/playlistTrack?playlist_id=123 => /api/playlist/123/tracks\n let plsId = '0'\n if (params.filter) {\n plsId = params.filter.playlist_id\n }\n return [`playlist/${plsId}/tracks`, params]\n\n default:\n return [resource, params]\n }\n}\n\nconst callDeleteMany = (resource, params) => {\n const ids = params.ids.map((id) => `id=${id}`)\n const idsParam = ids.join('&')\n return httpClient(`${REST_URL}/${resource}?${idsParam}`, {\n method: 'DELETE',\n }).then((response) => ({ data: response.json.ids || [] }))\n}\n\nconst wrapperDataProvider = {\n ...dataProvider,\n getList: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getList(r, p)\n },\n getOne: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getOne(r, p)\n },\n getMany: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getMany(r, p)\n },\n getManyReference: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.getManyReference(r, p)\n },\n update: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.update(r, p)\n },\n updateMany: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.updateMany(r, p)\n },\n create: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.create(r, p)\n },\n delete: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n return dataProvider.delete(r, p)\n },\n deleteMany: (resource, params) => {\n const [r, p] = mapResource(resource, params)\n if (r.endsWith('/tracks')) {\n return callDeleteMany(r, p)\n }\n return dataProvider.deleteMany(r, p)\n },\n addToPlaylist: (playlistId, data) => {\n return httpClient(`${REST_URL}/playlist/${playlistId}/tracks`, {\n method: 'POST',\n body: JSON.stringify(data),\n }).then(({ json }) => ({ data: json }))\n },\n}\n\nexport default wrapperDataProvider\n","import httpClient from './httpClient'\nimport wrapperDataProvider from './wrapperDataProvider'\n\nexport { httpClient }\n\nexport default wrapperDataProvider\n","export const PLAYER_ADD_TRACKS = 'PLAYER_ADD_TRACKS'\nexport const PLAYER_PLAY_NEXT = 'PLAYER_PLAY_NEXT'\nexport const PLAYER_SET_TRACK = 'PLAYER_SET_TRACK'\nexport const PLAYER_SYNC_QUEUE = 'PLAYER_SYNC_QUEUE'\nexport const PLAYER_CLEAR_QUEUE = 'PLAYER_CLEAR_QUEUE'\nexport const PLAYER_PLAY_TRACKS = 'PLAYER_PLAY_TRACKS'\nexport const PLAYER_CURRENT = 'PLAYER_CURRENT'\nexport const PLAYER_SET_VOLUME = 'PLAYER_SET_VOLUME'\n\nexport const setTrack = (data) => ({\n type: PLAYER_SET_TRACK,\n data,\n})\n\nexport const filterSongs = (data, ids) => {\n if (!ids) {\n return data\n }\n return ids.reduce((acc, id) => ({ ...acc, [id]: data[id] }), {})\n}\n\nexport const addTracks = (data, ids) => {\n const songs = filterSongs(data, ids)\n return {\n type: PLAYER_ADD_TRACKS,\n data: songs,\n }\n}\n\nexport const playNext = (data, ids) => {\n const songs = filterSongs(data, ids)\n return {\n type: PLAYER_PLAY_NEXT,\n data: songs,\n }\n}\n\nexport const shuffle = (data) => {\n const ids = Object.keys(data)\n for (let i = ids.length - 1; i > 0; i--) {\n let j = Math.floor(Math.random() * (i + 1))\n ;[ids[i], ids[j]] = [ids[j], ids[i]]\n }\n const shuffled = {}\n // The \"_\" is to force the object key to be a string, so it keeps the order when adding to object\n // or else the keys will always be in the same (numerically) order\n ids.forEach((id) => (shuffled['_' + id] = data[id]))\n return shuffled\n}\n\nexport const shuffleTracks = (data, ids) => {\n const songs = filterSongs(data, ids)\n const shuffled = shuffle(songs)\n const firstId = Object.keys(shuffled)[0]\n return {\n type: PLAYER_PLAY_TRACKS,\n id: firstId,\n data: shuffled,\n }\n}\n\nexport const playTracks = (data, ids, selectedId) => {\n const songs = filterSongs(data, ids)\n return {\n type: PLAYER_PLAY_TRACKS,\n id: selectedId || Object.keys(songs)[0],\n data: songs,\n }\n}\n\nexport const syncQueue = (audioInfo, audioLists) => ({\n type: PLAYER_SYNC_QUEUE,\n data: {\n audioInfo,\n audioLists,\n },\n})\n\nexport const clearQueue = () => ({\n type: PLAYER_CLEAR_QUEUE,\n})\n\nexport const currentPlaying = (audioInfo) => ({\n type: PLAYER_CURRENT,\n data: audioInfo,\n})\n\nexport const setVolume = (volume) => ({\n type: PLAYER_SET_VOLUME,\n data: { volume },\n})\n","export const CHANGE_THEME = 'CHANGE_THEME'\n\nexport const changeTheme = (theme) => ({\n type: CHANGE_THEME,\n payload: theme,\n})\n","export const ALBUM_MODE_GRID = 'ALBUM_GRID_MODE'\nexport const ALBUM_MODE_TABLE = 'ALBUM_TABLE_MODE'\n\nexport const albumViewGrid = () => ({ type: ALBUM_MODE_GRID })\n\nexport const albumViewTable = () => ({ type: ALBUM_MODE_TABLE })\n","export const ADD_TO_PLAYLIST_OPEN = 'ADD_TO_PLAYLIST_OPEN'\nexport const ADD_TO_PLAYLIST_CLOSE = 'ADD_TO_PLAYLIST_CLOSE'\nexport const DUPLICATE_SONG_WARNING_OPEN = 'DUPLICATE_SONG_WARNING_OPEN'\nexport const DUPLICATE_SONG_WARNING_CLOSE = 'DUPLICATE_SONG_WARNING_CLOSE'\nexport const EXTENDED_INFO_OPEN = 'EXTENDED_INFO_OPEN'\nexport const EXTENDED_INFO_CLOSE = 'EXTENDED_INFO_CLOSE'\nexport const LISTENBRAINZ_TOKEN_OPEN = 'LISTENBRAINZ_TOKEN_OPEN'\nexport const LISTENBRAINZ_TOKEN_CLOSE = 'LISTENBRAINZ_TOKEN_CLOSE'\n\nexport const openAddToPlaylist = ({ selectedIds, onSuccess }) => ({\n type: ADD_TO_PLAYLIST_OPEN,\n selectedIds,\n onSuccess,\n})\n\nexport const closeAddToPlaylist = () => ({\n type: ADD_TO_PLAYLIST_CLOSE,\n})\n\nexport const openDuplicateSongWarning = (duplicateIds) => ({\n type: DUPLICATE_SONG_WARNING_OPEN,\n duplicateIds,\n})\n\nexport const closeDuplicateSongDialog = () => ({\n type: DUPLICATE_SONG_WARNING_CLOSE,\n})\n\nexport const openExtendedInfoDialog = (record) => {\n return {\n type: EXTENDED_INFO_OPEN,\n record,\n }\n}\n\nexport const closeExtendedInfoDialog = () => ({\n type: EXTENDED_INFO_CLOSE,\n})\n\nexport const openListenBrainzTokenDialog = () => ({\n type: LISTENBRAINZ_TOKEN_OPEN,\n})\n\nexport const closeListenBrainzTokenDialog = () => ({\n type: LISTENBRAINZ_TOKEN_CLOSE,\n})\n","export const EVENT_SCAN_STATUS = 'scanStatus'\nexport const EVENT_SERVER_START = 'serverStart'\nexport const EVENT_REFRESH_RESOURCE = 'refreshResource'\n\nexport const processEvent = (type, data) => {\n return {\n type,\n data: data,\n }\n}\n\nexport const scanStatusUpdate = (data) => ({\n type: EVENT_SCAN_STATUS,\n data: data,\n})\n\nexport const serverDown = () => ({\n type: EVENT_SERVER_START,\n data: {},\n})\n","export const SET_NOTIFICATIONS_STATE = 'SET_NOTIFICATIONS_STATE'\nexport const SET_TOGGLEABLE_FIELDS = 'SET_TOGGLEABLE_FIELDS'\nexport const SET_OMITTED_FIELDS = 'SET_OMITTED_FIELDS'\n\nexport const setNotificationsState = (enabled) => ({\n type: SET_NOTIFICATIONS_STATE,\n data: enabled,\n})\n\nexport const setToggleableFields = (obj) => ({\n type: SET_TOGGLEABLE_FIELDS,\n data: obj,\n})\n\nexport const setOmittedFields = (obj) => ({\n type: SET_OMITTED_FIELDS,\n data: obj,\n})\n","import { baseUrl } from './utils'\nimport throttle from 'lodash.throttle'\nimport { processEvent, serverDown } from './actions'\nimport { httpClient } from './dataProvider'\nimport { REST_URL } from './consts'\n\nconst defaultIntervalCheck = 20000\nconst reconnectIntervalCheck = 2000\nlet currentIntervalCheck = reconnectIntervalCheck\nlet es = null\nlet dispatch = null\nlet timeout = null\n\nconst getEventStream = async () => {\n if (!es) {\n // Call `keepalive` to refresh the jwt token\n await httpClient(`${REST_URL}/keepalive/keepalive`)\n let url = baseUrl(`${REST_URL}/events`)\n if (localStorage.getItem('token')) {\n url = url + `?jwt=${localStorage.getItem('token')}`\n }\n es = new EventSource(url)\n }\n return es\n}\n\n// Reestablish the event stream after 20 secs of inactivity\nconst setTimeout = (value) => {\n currentIntervalCheck = value\n if (timeout) {\n window.clearTimeout(timeout)\n }\n timeout = window.setTimeout(async () => {\n 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 NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(250 250 250))!important',\n },\n },\n },\n player: {\n theme: 'light',\n stylesheet: require('./light.css.js'),\n },\n}\n","import blue from '@material-ui/core/colors/blue'\n\nexport default {\n themeName: 'Dark',\n palette: {\n primary: {\n main: '#90caf9',\n },\n secondary: blue,\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: 'white',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#0085ff',\n },\n icon: {},\n welcome: {\n color: '#eee',\n },\n card: {\n minWidth: 300,\n backgroundColor: '#424242ed',\n },\n avatar: {},\n button: {\n boxShadow: '3px 3px 5px #000000a3',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',\n },\n },\n },\n player: {\n theme: 'dark',\n stylesheet: require('./dark.css.js'),\n },\n}\n","import blue from '@material-ui/core/colors/blue'\n\nexport default {\n themeName: 'Extra Dark',\n palette: {\n background: {\n paper: '#000000',\n default: '#000000',\n },\n primary: {\n main: '#0f60b6',\n contrastText: '#909090',\n },\n secondary: blue,\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: 'white',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#fff',\n },\n welcome: {\n color: '#eee',\n },\n },\n NDArtistPage: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(0 0 0))!important',\n },\n },\n },\n\n player: {\n theme: 'dark',\n stylesheet: require('./dark.css.js'),\n },\n}\n","import green from '@material-ui/core/colors/green'\n\nexport default {\n themeName: 'Green',\n palette: {\n primary: {\n light: green['300'],\n main: green['500'],\n },\n secondary: {\n main: green['900'],\n contrastText: '#fff',\n },\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: 'white',\n },\n },\n NDLogin: {\n systemNameLink: {\n color: '#fff',\n },\n welcome: {\n color: '#eee',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgba(52 52 52 / 72%), rgb(48 48 48))!important',\n },\n },\n },\n player: {\n theme: 'dark',\n },\n}\n","const spotifyGreen = {\n 300: '#62ec83',\n 500: '#1db954',\n 900: '#008827',\n}\n\n// For Album, Playlist\nconst musicListActions = {\n padding: '1rem 0',\n alignItems: 'center',\n '@global': {\n button: {\n margin: 5,\n border: '1px solid transparent',\n backgroundColor: 'inherit',\n color: '#b3b3b3',\n '&:hover': {\n border: '1px solid #b3b3b3',\n backgroundColor: 'inherit !important',\n },\n },\n 'button:first-child:not(:only-child)': {\n '@media screen and (max-width: 720px)': {\n transform: 'scale(1.5)',\n margin: '1rem',\n '&:hover': {\n transform: 'scale(1.6) !important',\n },\n },\n transform: 'scale(2)',\n margin: '1.5rem',\n minWidth: 0,\n padding: 5,\n transition: 'transform .3s ease',\n background: spotifyGreen['500'],\n color: '#fff',\n borderRadius: 500,\n border: 0,\n '&:hover': {\n transform: 'scale(2.1)',\n backgroundColor: `${spotifyGreen['500']} !important`,\n border: 0,\n },\n },\n 'button:only-child': {\n margin: '1.5rem',\n },\n 'button:first-child>span:first-child': {\n padding: 0,\n },\n 'button:first-child>span:first-child>span': {\n display: 'none',\n },\n 'button>span:first-child>span, button:not(:first-child)>span:first-child>svg':\n {\n color: '#b3b3b3',\n },\n },\n}\n\nexport default {\n themeName: 'Spotify-ish',\n typography: {\n fontFamily: \"system-ui, 'Helvetica Neue', Helvetica, Arial\",\n h6: {\n fontSize: '1rem', // AppBar title\n },\n },\n palette: {\n primary: {\n light: spotifyGreen['300'],\n main: spotifyGreen['500'],\n },\n secondary: {\n main: '#fff',\n contrastText: '#fff',\n },\n background: {\n default: '#121212',\n paper: '#121212',\n },\n type: 'dark',\n },\n overrides: {\n MuiFormGroup: {\n root: {\n color: spotifyGreen['500'],\n },\n },\n MuiMenuItem: {\n root: {\n fontSize: '0.875rem',\n },\n },\n MuiDivider: {\n root: {\n margin: '.75rem 0',\n },\n },\n MuiButton: {\n root: {\n background: spotifyGreen['500'],\n color: '#fff',\n border: '1px solid transparent',\n borderRadius: 500,\n '&:hover': {\n background: `${spotifyGreen['900']} !important`,\n },\n },\n textSecondary: {\n border: '1px solid #b3b3b3',\n background: '#000',\n '&:hover': {\n border: '1px solid #fff !important',\n background: '#000 !important',\n },\n },\n label: {\n color: '#fff',\n paddingRight: '1rem',\n paddingLeft: '0.7rem',\n },\n },\n MuiDrawer: {\n root: {\n background: '#000',\n paddingTop: '10px',\n },\n },\n MuiTableRow: {\n root: {\n padding: '10px 0',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#1d1d1d !important',\n },\n '@global': {\n 'td:nth-child(4)': {\n color: '#fff !important',\n },\n },\n },\n },\n MuiTableCell: {\n root: {\n borderBottom: '1px solid #1d1d1d',\n padding: '10px !important',\n color: '#b3b3b3 !important',\n },\n head: {\n borderBottom: '1px solid #282828',\n fontSize: '0.75rem',\n textTransform: 'uppercase',\n letterSpacing: 1.2,\n },\n },\n MuiAppBar: {\n positionFixed: {\n backgroundColor: '#000 !important',\n boxShadow: 'none',\n },\n },\n NDAlbumGridView: {\n albumName: {\n marginTop: '0.5rem',\n fontWeight: 700,\n textTransform: 'none',\n color: '#fff',\n },\n albumSubtitle: {\n color: '#b3b3b3',\n },\n albumContainer: {\n backgroundColor: '#181818',\n borderRadius: '.5rem',\n padding: '.75rem',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#282828',\n },\n },\n albumPlayButton: {\n backgroundColor: spotifyGreen['500'],\n borderRadius: '50%',\n boxShadow: '0 8px 8px rgb(0 0 0 / 30%)',\n padding: '0.35rem',\n transition: 'padding .3s ease',\n '&:hover': {\n background: `${spotifyGreen['500']} !important`,\n padding: '0.45rem',\n },\n },\n },\n NDPlaylistDetails: {\n container: {\n background: 'linear-gradient(#1d1d1d, transparent)',\n borderRadius: 0,\n paddingTop: '2.5rem !important',\n boxShadow: 'none',\n },\n title: {\n fontSize: 'calc(1.5rem + 1.5vw);',\n fontWeight: 700,\n color: '#fff',\n },\n details: {\n fontSize: '.875rem',\n minWidth: '75vw',\n color: 'rgba(255,255,255, 0.8)',\n },\n },\n NDAlbumDetails: {\n root: {\n background: 'linear-gradient(#1d1d1d, transparent)',\n borderRadius: 0,\n boxShadow: 'none',\n },\n cardContents: {\n alignItems: 'center',\n paddingTop: '1.5rem',\n },\n recordName: {\n fontSize: 'calc(1rem + 1.5vw);',\n fontWeight: 700,\n },\n recordArtist: {\n fontSize: '.875rem',\n fontWeight: 700,\n },\n recordMeta: {\n fontSize: '.875rem',\n color: 'rgba(255,255,255, 0.8)',\n },\n commentBlock: {\n fontSize: '.875rem',\n color: 'rgba(255,255,255, 0.8)',\n },\n },\n NDAlbumShow: {\n albumActions: musicListActions,\n },\n NDPlaylistShow: {\n playlistActions: musicListActions,\n },\n NDAudioPlayer: {\n audioTitle: {\n color: '#fff',\n fontSize: '0.875rem',\n },\n songTitle: {\n fontWeight: 400,\n },\n songInfo: {\n fontSize: '0.675rem',\n color: '#b3b3b3',\n },\n player: {\n border: '10px solid blue',\n },\n },\n NDLogin: {\n main: {\n boxShadow: 'inset 0 0 0 2000px rgba(0, 0, 0, .75)',\n },\n systemNameLink: {\n color: '#fff',\n },\n card: {\n border: '1px solid #282828',\n },\n avatar: {\n marginBottom: 0,\n },\n },\n RaLayout: {\n content: {\n padding: '0 !important',\n background: 'linear-gradient(#171717, #121212)',\n },\n },\n RaList: {\n content: {\n backgroundColor: 'inherit',\n },\n },\n RaListToolbar: {\n toolbar: {\n padding: '0 .55rem !important',\n },\n },\n RaSearchInput: {\n input: {\n paddingLeft: '.9rem',\n border: 0,\n },\n },\n RaFilterButton: {\n root: {\n marginRight: '1rem',\n },\n },\n RaPaginationActions: {\n currentPageButton: {\n border: '1px solid #b3b3b3',\n },\n button: {\n backgroundColor: 'inherit',\n minWidth: 48,\n margin: '0 4px',\n border: '1px solid #282828',\n '@global': {\n '> .MuiButton-label': {\n padding: 0,\n },\n },\n },\n actions: {\n '@global': {\n '.next-page': {\n marginLeft: 8,\n marginRight: 8,\n },\n '.previous-page': {\n marginRight: 8,\n },\n },\n },\n },\n RaSidebar: {\n root: {\n height: 'initial',\n },\n },\n },\n player: {\n theme: 'dark',\n },\n}\n","const bLight = {\n 300: '#0054df',\n 500: '#ffffff',\n}\nconst musicListActions = {\n padding: '1rem 0',\n alignItems: 'center',\n '@global': {\n button: {\n margin: 5,\n border: '1px solid #cccccc',\n backgroundColor: '#fff',\n color: '#b3b3b3',\n '&:hover': {\n border: '1px solid #224bff',\n backgroundColor: 'inherit !important',\n },\n },\n 'button:first-child:not(:only-child)': {\n '@media screen and (max-width: 720px)': {\n transform: 'scale(1.5)',\n margin: '1rem',\n '&:hover': {\n transform: 'scale(1.6) !important',\n },\n },\n transform: 'scale(2)',\n margin: '1.5rem',\n minWidth: 0,\n padding: 5,\n transition: 'transform .3s ease',\n background: bLight['500'],\n color: '#fff',\n borderRadius: 500,\n border: 0,\n '&:hover': {\n transform: 'scale(2.1)',\n backgroundColor: `${bLight['500']} !important`,\n border: 0,\n boxShadow: '0px 0px 4px 0px #5656567d',\n },\n },\n 'button:only-child': {\n margin: '1.5rem',\n },\n 'button:first-child>span:first-child': {\n padding: 0,\n color: bLight['300'],\n },\n 'button:first-child>span:first-child>span': {\n display: 'none',\n },\n 'button>span:first-child>span, button:not(:first-child)>span:first-child>svg':\n {\n color: '#656565',\n },\n },\n}\n\nexport default {\n themeName: 'Ligera',\n palette: {\n primary: {\n light: bLight['300'],\n main: '#464646',\n },\n secondary: {\n main: '#000',\n contrastText: '#fff',\n },\n background: {\n default: '#f0f2f5',\n paper: 'inherit',\n },\n text: {\n secondary: '#232323',\n },\n },\n typography: {\n fontFamily: \"system-ui, 'Helvetica Neue', Helvetica, Arial\",\n h6: {\n fontSize: '1rem',\n },\n },\n overrides: {\n MuiAutocomplete: {\n popper: {\n background: bLight['500'],\n },\n },\n MuiCard: {\n root: {\n marginLeft: '1%',\n marginRight: '1%',\n background: bLight['500'],\n },\n },\n MuiPopover: {\n paper: {\n backgroundColor: bLight['500'],\n '& .MuiListItemIcon-root': {\n color: '#656565',\n },\n },\n },\n MuiTypography: {\n colorTextSecondary: {\n color: '#0a0a0a',\n },\n },\n MuiDialog: {\n paper: {\n backgroundColor: bLight['500'],\n },\n },\n MuiFormGroup: {\n root: {\n color: bLight['500'],\n },\n },\n MuiMenuItem: {\n root: {\n fontSize: '0.875rem',\n },\n },\n MuiDivider: {\n root: {\n margin: '.75rem 0',\n },\n },\n MuiFormLabel: {\n root: {\n color: '#91b1b0',\n },\n },\n MuiCheckbox: {\n root: {\n color: '#616161',\n },\n },\n MuiIconButton: {\n label: {},\n },\n MuiButton: {\n root: {\n background: '#fff',\n color: '#000',\n border: '1px solid transparent',\n borderRadius: 500,\n '&:hover': {\n background: `${bLight['300']} !important`,\n color: '#fff',\n },\n },\n containedPrimary: {\n backgroundColor: '#fff',\n },\n textPrimary: {\n backgroundColor: bLight['300'],\n '& span': {\n color: '#fff',\n },\n '&:hover': {\n backgroundColor: '#3079ff !important',\n },\n },\n textSecondary: {\n border: '1px solid #b3b3b3',\n background: '#fff',\n '&:hover': {\n border: '1px solid #fff !important',\n background: '#dedede !important',\n },\n },\n label: {\n color: '#000',\n paddingRight: '1rem',\n paddingLeft: '0.7rem',\n },\n },\n MuiDrawer: {\n root: {\n background: bLight['500'],\n paddingTop: '10px',\n boxShadow: '-14px -7px 20px black',\n },\n },\n MuiTableRow: {\n root: {\n padding: '10px 0',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#e4e4e4 !important',\n },\n '@global': {\n 'td:nth-child(4)': {\n color: '#3c3c3c !important',\n },\n },\n },\n head: {\n backgroundColor: '#e0efff',\n },\n },\n MuiTableCell: {\n root: {\n borderBottom: '1px solid #1d1d1d',\n padding: '10px !important',\n color: '#656565 !important',\n },\n head: {\n borderBottom: '1px solid #282828',\n fontSize: '0.75rem',\n textTransform: 'uppercase',\n letterSpacing: 1.2,\n },\n },\n MuiAppBar: {\n positionFixed: {\n background: `${bLight['500']} !important`,\n boxShadow: '13px -12px 20px 0px #000',\n },\n colorSecondary: {\n color: bLight['300'],\n },\n },\n NDAppBar: {\n icon: {\n color: '#fff',\n },\n },\n NDAlbumGridView: {\n albumName: {\n marginTop: '0.5rem',\n fontWeight: 700,\n textTransform: 'none',\n color: '#000000b0',\n },\n albumSubtitle: {\n color: '#000000ad',\n display: 'block',\n },\n albumContainer: {\n backgroundColor: '#e0efff7d',\n borderRadius: '.5rem',\n padding: '.75rem',\n transition: 'background-color .3s ease',\n '&:hover': {\n backgroundColor: '#c6dbff',\n },\n },\n albumPlayButton: {\n backgroundColor: bLight['500'],\n borderRadius: '50%',\n boxShadow: '0 8px 8px rgb(0 0 0 / 30%)',\n padding: '0.35rem',\n transition: 'padding .3s ease',\n color: bLight['300'],\n '&:hover': {\n background: `${bLight['300']} !important`,\n padding: '0.45rem',\n color: bLight['500'],\n },\n },\n },\n NDPlaylistDetails: {\n container: {\n borderRadius: 0,\n paddingTop: '2.5rem !important',\n boxShadow: 'none',\n },\n title: {\n fontSize: 'calc(1.5rem + 1.5vw);',\n fontWeight: 700,\n color: '#000000b0',\n },\n details: {\n fontSize: '.875rem',\n color: 'rgba(255,255,255, 0.8)',\n },\n },\n NDAlbumDetails: {\n root: {\n borderRadius: 0,\n boxShadow: '-1px 1px 6px 0px #00000057',\n },\n cardContents: {\n alignItems: 'center',\n paddingTop: '1.5rem',\n },\n recordName: {\n fontSize: 'calc(1rem + 1.5vw);',\n fontWeight: 700,\n },\n recordArtist: {\n fontSize: '.875rem',\n fontWeight: 700,\n },\n recordMeta: {\n fontSize: '.875rem',\n color: 'rgb(113 113 113 / 80%)',\n },\n commentBlock: {\n fontSize: '.875rem',\n color: 'rgb(113 113 113 / 80%)',\n },\n },\n NDAlbumShow: {\n albumActions: musicListActions,\n },\n NDPlaylistShow: {\n playlistActions: musicListActions,\n },\n NDSubMenu: {\n icon: {\n color: '#656565',\n },\n },\n NDAudioPlayer: {\n audioTitle: {\n color: '#000',\n fontSize: '0.875rem',\n },\n songTitle: {\n fontWeight: 400,\n },\n songInfo: {\n fontSize: '0.675rem',\n color: '#b3b3b3',\n },\n player: {},\n },\n NDLogin: {\n actions: {\n '& button': {\n backgroundColor: '#3c9cff',\n },\n },\n systemNameLink: {\n textDecoration: 'none',\n color: bLight['300'],\n },\n systemName: {\n marginTop: '0.5em',\n marginBottom: '1em',\n },\n icon: {\n backgroundColor: 'transparent',\n width: '100px',\n height: '100px',\n },\n card: {\n minWidth: 300,\n marginTop: '6em',\n overflow: 'visible',\n backgroundColor: '#ffffffe6',\n },\n avatar: {\n marginTop: '-50px',\n },\n },\n NDMobileArtistDetails: {\n bgContainer: {\n background:\n 'linear-gradient(to bottom, rgb(255 255 255 / 51%), rgb(240 242 245))!important',\n },\n },\n RaLayout: {\n content: {\n padding: '0 !important',\n },\n },\n RaListToolbar: {\n toolbar: {\n padding: '0 .55rem !important',\n },\n },\n RaDatagridHeaderCell: {\n icon: {\n color: '#717171 !important',\n },\n },\n RaSearchInput: {\n input: {\n paddingLeft: '.9rem',\n border: 0,\n },\n },\n RaFilterButton: {\n root: {\n marginRight: '1rem',\n '& button': {\n color: '#0f0f0f',\n backgroundColor: '#fff',\n '& span': {\n color: '#101010',\n },\n '&:hover': {\n backgroundColor: '#dedede !important',\n },\n },\n },\n },\n RaAutocompleteSuggestionList: {\n suggestionsPaper: {\n backgroundColor: '#fff',\n },\n },\n RaLink: {\n link: {\n color: '#287eff',\n },\n },\n RaLogout: {\n icon: {\n color: '#f90000!important',\n },\n },\n RaMenuItemLink: {\n root: {\n color: '#232323 !important',\n '& .MuiListItemIcon-root': {\n color: '#656565',\n },\n },\n active: {\n backgroundColor: '#44a0ff1f',\n color: '#232323 !important',\n '& .MuiListItemIcon-root': {\n color: '#0066ff',\n },\n },\n },\n RaSidebar: {\n root: {\n height: 'initial',\n },\n drawerPaper: {\n '@media (min-width: 0px) and (max-width: 599.95px)': {\n backgroundColor: `${bLight['500']} !important`,\n },\n },\n },\n RaBulkActionsToolbar: {\n toolbar: {\n backgroundColor: bLight['500'],\n },\n },\n RaPaginationActions: {\n button: {\n backgroundColor: 'inherit',\n minWidth: 48,\n margin: '0 4px',\n border: '1px solid #282828',\n '@global': {\n '> .MuiButton-label': {\n padding: 0,\n },\n },\n },\n actions: {\n '@global': {\n '.next-page': {\n marginLeft: 8,\n marginRight: 8,\n },\n '.previous-page': {\n marginRight: 8,\n },\n },\n },\n },\n },\n player: {\n theme: 'light',\n },\n}\n","import LightTheme from './light'\nimport DarkTheme from './dark'\nimport ExtraDarkTheme from './extradark'\nimport GreenTheme from './green'\nimport SpotifyTheme from './spotify'\nimport LigeraTheme from './ligera'\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 { useDispatch } from 'react-redux'\nimport ExpandMore from '@material-ui/icons/ExpandMore'\nimport ArrowRightOutlined from '@material-ui/icons/ArrowRightOutlined'\nimport List from '@material-ui/core/List'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport Typography from '@material-ui/core/Typography'\nimport Collapse from '@material-ui/core/Collapse'\nimport Tooltip from '@material-ui/core/Tooltip'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { setSidebarVisibility, useTranslate } from 'react-admin'\nimport { IconButton, useMediaQuery } from '@material-ui/core'\n\nconst useStyles = makeStyles(\n (theme) => ({\n icon: { minWidth: theme.spacing(5) },\n sidebarIsOpen: {\n '& a': {\n transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',\n paddingLeft: theme.spacing(4),\n },\n },\n sidebarIsClosed: {\n '& a': {\n transition: 'padding-left 195ms cubic-bezier(0.4, 0, 0.6, 1) 0ms',\n paddingLeft: theme.spacing(2),\n },\n },\n actionIcon: {\n opacity: 0,\n },\n menuHeader: {\n width: '100%',\n },\n headerWrapper: {\n display: 'flex',\n '&:hover $actionIcon': {\n opacity: 1,\n },\n },\n }),\n {\n name: 'NDSubMenu',\n }\n)\n\nconst SubMenu = ({\n handleToggle,\n sidebarIsOpen,\n isOpen,\n name,\n icon,\n children,\n dense,\n onAction,\n actionIcon,\n}) => {\n const translate = useTranslate()\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n const isSmall = useMediaQuery((theme) => theme.breakpoints.down('sm'))\n const dispatch = useDispatch()\n\n const handleOnClick = (e) => {\n e.stopPropagation()\n onAction(e)\n if (isSmall) {\n dispatch(setSidebarVisibility(false))\n }\n }\n\n const header = (\n
\n \n \n {isOpen ? : icon}\n \n \n {translate(name)}\n \n {onAction && sidebarIsOpen && (\n \n {actionIcon}\n \n )}\n \n
\n )\n\n return (\n \n {sidebarIsOpen || isOpen ? (\n header\n ) : (\n \n {header}\n \n )}\n \n \n {children}\n \n \n \n )\n}\n\nSubMenu.defaultProps = {\n action: null,\n actionIcon: ,\n}\n\nexport default SubMenu\n","import PropTypes from 'prop-types'\nimport { useLocation } from 'react-router-dom'\nimport { createElement } from 'react'\n\nconst DynamicMenuIcon = ({ icon, activeIcon, path }) => {\n const location = useLocation()\n\n if (!activeIcon) {\n return createElement(icon, { 'data-testid': 'icon' })\n }\n\n return location.pathname.startsWith('/' + path)\n ? createElement(activeIcon, { 'data-testid': 'activeIcon' })\n : createElement(icon, { 'data-testid': 'icon' })\n}\n\nDynamicMenuIcon.propTypes = {\n path: PropTypes.string.isRequired,\n icon: PropTypes.object.isRequired,\n activeIcon: PropTypes.object,\n}\n\nexport default DynamicMenuIcon\n","import React from 'react'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport LibraryAddIcon from '@material-ui/icons/LibraryAdd'\nimport VideoLibraryIcon from '@material-ui/icons/VideoLibrary'\nimport RepeatIcon from '@material-ui/icons/Repeat'\nimport AlbumIcon from '@material-ui/icons/Album'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport StarIcon from '@material-ui/icons/Star'\nimport StarBorderIcon from '@material-ui/icons/StarBorder'\nimport AlbumOutlinedIcon from '@material-ui/icons/AlbumOutlined'\nimport LibraryAddOutlinedIcon from '@material-ui/icons/LibraryAddOutlined'\nimport VideoLibraryOutlinedIcon from '@material-ui/icons/VideoLibraryOutlined'\nimport config from '../config'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\n\nconst albumLists = {\n all: {\n icon: (\n \n ),\n params: 'sort=name&order=ASC&filter={}',\n },\n random: {\n icon: ,\n params: 'sort=random&order=ASC&filter={}',\n },\n ...(config.enableFavourites && {\n starred: {\n icon: (\n \n ),\n params: 'sort=starred_at&order=DESC&filter={\"starred\":true}',\n },\n }),\n ...(config.enableStarRating && {\n topRated: {\n icon: (\n \n ),\n params: 'sort=rating&order=DESC&filter={\"has_rating\":true}',\n },\n }),\n recentlyAdded: {\n icon: (\n \n ),\n params: 'sort=recently_added&order=DESC&filter={}',\n },\n recentlyPlayed: {\n icon: (\n \n ),\n params: 'sort=play_date&order=DESC&filter={\"recently_played\":true}',\n },\n mostPlayed: {\n icon: ,\n params: 'sort=play_count&order=DESC&filter={\"recently_played\":true}',\n },\n}\n\nexport default albumLists\nexport const defaultAlbumList = 'recentlyAdded'\n","import { withStyles } from '@material-ui/core/styles'\nimport MuiDialogTitle from '@material-ui/core/DialogTitle'\nimport Typography from '@material-ui/core/Typography'\nimport IconButton from '@material-ui/core/IconButton'\nimport CloseIcon from '@material-ui/icons/Close'\nimport React from 'react'\n\nconst styles = (theme) => ({\n root: {\n margin: 0,\n padding: theme.spacing(2),\n },\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n },\n})\n\nexport const DialogTitle = withStyles(styles)((props) => {\n const { children, classes, onClose, ...other } = props\n return (\n \n {children}\n \n \n \n \n )\n})\n","import { withStyles } from '@material-ui/core/styles'\nimport MuiDialogContent from '@material-ui/core/DialogContent'\n\nexport const DialogContent = withStyles((theme) => ({\n root: {\n padding: theme.spacing(2),\n },\n}))(MuiDialogContent)\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Link from '@material-ui/core/Link'\nimport Dialog from '@material-ui/core/Dialog'\nimport IconButton from '@material-ui/core/IconButton'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableRow from '@material-ui/core/TableRow'\nimport TableCell from '@material-ui/core/TableCell'\nimport Paper from '@material-ui/core/Paper'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport inflection from 'inflection'\nimport { useTranslate } from 'react-admin'\nimport config from '../config'\nimport { DialogTitle } from './DialogTitle'\nimport { DialogContent } from './DialogContent'\n\nconst links = {\n homepage: '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 { withWidth } from '@material-ui/core'\nimport { useAlbumsPerPage } from './index'\nimport config from '../config'\n\nexport const useGetHandleArtistClick = (width) => {\n const [perPage] = useAlbumsPerPage(width)\n return (id) => {\n return config.devShowArtistPage && id !== config.variousArtistsId\n ? `/artist/${id}/show`\n : `/album?filter={\"artist_id\":\"${id}\"}&order=ASC&sort=max_year&displayedFilters={\"compilation\":true}&perPage=${perPage}`\n }\n}\n\nexport const ArtistLinkField = withWidth()(\n ({ record, className, width, source }) => {\n const artistLink = useGetHandleArtistClick(width)\n\n const id = record[source + 'Id']\n return (\n <>\n {id ? (\n e.stopPropagation()}\n className={className}\n >\n {record[source]}\n \n ) : (\n record[source]\n )}\n \n )\n }\n)\n\nArtistLinkField.propTypes = {\n record: PropTypes.object,\n className: PropTypes.string,\n source: PropTypes.string,\n}\n\nArtistLinkField.defaultProps = {\n addLabel: true,\n source: 'albumArtist',\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport {\n Button,\n useDataProvider,\n useTranslate,\n useUnselectAll,\n useNotify,\n} from 'react-admin'\nimport { useDispatch } from 'react-redux'\n\nexport const BatchPlayButton = ({\n resource,\n selectedIds,\n action,\n label,\n icon,\n className,\n}) => {\n const dispatch = useDispatch()\n const translate = useTranslate()\n const dataProvider = useDataProvider()\n const unselectAll = useUnselectAll()\n const notify = useNotify()\n\n const addToQueue = () => {\n dataProvider\n .getMany(resource, { ids: selectedIds })\n .then((response) => {\n // Add tracks to a map for easy lookup by ID, needed for the next step\n const tracks = response.data.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {}\n )\n // Add the tracks to the queue in the selection order\n dispatch(action(tracks, selectedIds))\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n unselectAll(resource)\n }\n\n const caption = translate(label)\n return (\n \n {icon}\n \n )\n}\n\nBatchPlayButton.propTypes = {\n action: PropTypes.func.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.object.isRequired,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useRecordContext } from 'react-admin'\n\nexport const BitrateField = ({ source, ...rest }) => {\n const record = useRecordContext(rest)\n return {`${record[source]} kbps`}\n}\n\nBitrateField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nBitrateField.defaultProps = {\n addLabel: true,\n}\n","import { baseUrl } from '../utils'\nimport { httpClient } from '../dataProvider'\n\nconst url = (command, id, options) => {\n const params = new URLSearchParams()\n params.append('u', localStorage.getItem('username'))\n params.append('t', localStorage.getItem('subsonic-token'))\n params.append('s', localStorage.getItem('subsonic-salt'))\n params.append('f', 'json')\n params.append('v', '1.8.0')\n params.append('c', 'NavidromeUI')\n id && params.append('id', id)\n if (options) {\n if (options.ts) {\n options['_'] = new Date().getTime()\n delete options.ts\n }\n Object.keys(options).forEach((k) => {\n params.append(k, options[k])\n })\n }\n return `/rest/${command}?${params.toString()}`\n}\n\nconst scrobble = (id, time, submission = true) =>\n httpClient(\n url('scrobble', id, {\n ...(submission && time && { time }),\n submission,\n })\n )\n\nconst nowPlaying = (id) => scrobble(id, null, false)\n\nconst star = (id) => httpClient(url('star', id))\n\nconst unstar = (id) => httpClient(url('unstar', id))\n\nconst setRating = (id, rating) => httpClient(url('setRating', id, { rating }))\n\nconst download = (id) => (window.location.href = baseUrl(url('download', id)))\n\nconst startScan = (options) => httpClient(url('startScan', null, options))\n\nconst getScanStatus = () => httpClient(url('getScanStatus'))\n\nconst getCoverArtUrl = (record, size) => {\n const options = {\n ...(record.updatedAt && { _: record.updatedAt }),\n ...(size && { size }),\n }\n\n if (record.coverArtId) {\n return baseUrl(url('getCoverArt', record.coverArtId, options))\n } else {\n return baseUrl(url('getCoverArt', 'not_found', size && { size }))\n }\n}\n\nconst getArtistInfo = (id) => {\n return httpClient(url('getArtistInfo', id))\n}\n\nconst streamUrl = (id) => {\n return baseUrl(url('stream', id, { ts: true }))\n}\n\nexport default {\n url,\n scrobble,\n nowPlaying,\n download,\n star,\n unstar,\n setRating,\n startScan,\n getScanStatus,\n getCoverArtUrl,\n streamUrl,\n getArtistInfo,\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport { useDataProvider, useNotify } from 'react-admin'\nimport subsonic from '../subsonic'\n\nexport const useToggleLove = (resource, record = {}) => {\n const [loading, setLoading] = useState(false)\n const notify = useNotify()\n\n const mountedRef = useRef(false)\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n const dataProvider = useDataProvider()\n\n const refreshRecord = useCallback(() => {\n dataProvider.getOne(resource, { id: record.id }).then(() => {\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n }, [dataProvider, record.id, resource])\n\n const toggleLove = () => {\n const toggle = record.starred ? subsonic.unstar : subsonic.star\n\n setLoading(true)\n toggle(record.id)\n .then(refreshRecord)\n .catch((e) => {\n console.log('Error toggling love: ', e)\n notify('ra.page.error', 'warning')\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n }\n\n return [toggleLove, loading]\n}\n","import React, { useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport IconButton from '@material-ui/core/IconButton'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useToggleLove } from './useToggleLove'\nimport { useRecordContext } from 'react-admin'\n\nconst useStyles = makeStyles({\n love: {\n color: (props) => props.color,\n visibility: (props) =>\n props.visible === false ? 'hidden' : props.loved ? 'visible' : 'inherit',\n },\n})\n\nexport const LoveButton = ({\n resource,\n color,\n visible,\n size,\n component: Button,\n addLabel,\n disabled,\n ...rest\n}) => {\n const record = useRecordContext(rest) || {}\n const classes = useStyles({ color, visible, loved: record.starred })\n const [toggleLove, loading] = useToggleLove(resource, record)\n\n const handleToggleLove = useCallback(\n (e) => {\n e.preventDefault()\n toggleLove()\n e.stopPropagation()\n },\n [toggleLove]\n )\n\n return (\n \n {record.starred ? (\n \n ) : (\n \n )}\n \n )\n}\n\nLoveButton.propTypes = {\n resource: PropTypes.string.isRequired,\n record: PropTypes.object,\n visible: PropTypes.bool,\n color: PropTypes.string,\n size: PropTypes.string,\n component: PropTypes.object,\n disabled: PropTypes.bool,\n}\n\nLoveButton.defaultProps = {\n addLabel: true,\n visible: true,\n size: 'small',\n color: 'inherit',\n component: IconButton,\n disabled: false,\n}\n","import React, { useState } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport IconButton from '@material-ui/core/IconButton'\nimport Menu from '@material-ui/core/Menu'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport MoreVertIcon from '@material-ui/icons/MoreVert'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useDataProvider, useNotify, useTranslate } from 'react-admin'\nimport clsx from 'clsx'\nimport {\n playNext,\n addTracks,\n playTracks,\n shuffleTracks,\n openAddToPlaylist,\n openExtendedInfoDialog,\n} from '../actions'\nimport subsonic from '../subsonic'\nimport { LoveButton } from './LoveButton'\nimport config from '../config'\nimport { formatBytes } from '../utils'\n\nconst useStyles = makeStyles({\n noWrap: {\n whiteSpace: 'nowrap',\n },\n menu: {\n color: (props) => props.color,\n },\n})\n\nconst ContextMenu = ({\n resource,\n showLove,\n record,\n color,\n className,\n songQueryParams,\n hideInfo,\n}) => {\n const classes = useStyles({ color })\n const dataProvider = useDataProvider()\n const dispatch = useDispatch()\n const translate = useTranslate()\n const notify = useNotify()\n const [anchorEl, setAnchorEl] = useState(null)\n\n const options = {\n play: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.playAll'),\n action: (data, ids) => dispatch(playTracks(data, ids)),\n },\n playNext: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.playNext'),\n action: (data, ids) => dispatch(playNext(data, ids)),\n },\n addToQueue: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.addToQueue'),\n action: (data, ids) => dispatch(addTracks(data, ids)),\n },\n shuffle: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.shuffle'),\n action: (data, ids) => dispatch(shuffleTracks(data, ids)),\n },\n addToPlaylist: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.addToPlaylist'),\n action: (data, ids) => dispatch(openAddToPlaylist({ selectedIds: ids })),\n },\n download: {\n enabled: config.enableDownloads && record.size,\n needData: false,\n label: `${translate('resources.album.actions.download')} (${formatBytes(\n record.size\n )})`,\n action: () => subsonic.download(record.id),\n },\n ...(!hideInfo && {\n info: {\n enabled: true,\n needData: true,\n label: translate('resources.album.actions.info'),\n action: () => dispatch(openExtendedInfoDialog(record)),\n },\n }),\n }\n\n const handleClick = (e) => {\n e.preventDefault()\n setAnchorEl(e.currentTarget)\n e.stopPropagation()\n }\n\n const handleOnClose = (e) => {\n e.preventDefault()\n setAnchorEl(null)\n e.stopPropagation()\n }\n\n let extractSongsData = function (response) {\n const data = response.data.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {}\n )\n const ids = response.data.map((r) => r.id)\n return { data, ids }\n }\n\n const handleItemClick = (e) => {\n setAnchorEl(null)\n const key = e.target.getAttribute('value')\n if (options[key].needData) {\n dataProvider\n .getList('song', songQueryParams)\n .then((response) => {\n let { data, ids } = extractSongsData(response)\n options[key].action(data, ids)\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n } else {\n options[key].action()\n }\n\n e.stopPropagation()\n }\n\n const open = Boolean(anchorEl)\n\n return (\n \n \n \n \n \n \n {Object.keys(options).map(\n (key) =>\n options[key].enabled && (\n \n {options[key].label}\n \n )\n )}\n \n \n )\n}\n\nexport const AlbumContextMenu = (props) =>\n props.record ? (\n \n ) : null\n\nAlbumContextMenu.propTypes = {\n record: PropTypes.object,\n discNumber: PropTypes.number,\n color: PropTypes.string,\n showLove: PropTypes.bool,\n}\n\nAlbumContextMenu.defaultProps = {\n showLove: true,\n addLabel: true,\n}\n\nexport const ArtistContextMenu = (props) =>\n props.record ? (\n \n ) : null\n\nArtistContextMenu.propTypes = {\n record: PropTypes.object,\n color: PropTypes.string,\n showLove: PropTypes.bool,\n}\n\nArtistContextMenu.defaultProps = {\n showLove: true,\n addLabel: true,\n}\n","import React from 'react'\nimport { DateField as RADateField } from 'react-admin'\n\nexport const DateField = (props) => {\n const { record, source } = props\n const value = record?.[source]\n if (value === '0001-01-01T00:00:00Z' || value === null) return null\n return \n}\n\nDateField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport { docsUrl } from '../utils'\n\nexport const DocLink = ({ path, children }) => (\n \n {children}\n \n)\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { formatDuration } from '../utils'\nimport { useRecordContext } from 'react-admin'\n\nexport const DurationField = ({ source, ...rest }) => {\n const record = useRecordContext(rest)\n try {\n return {formatDuration(record[source])}\n } catch (e) {\n console.log('Error in DurationField! Record:', record)\n return 00:00\n }\n}\n\nDurationField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nDurationField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport { Pagination as RAPagination } from 'react-admin'\n\nexport const Pagination = (props) => (\n \n)\n","import React from 'react'\nimport { List as RAList } from 'react-admin'\nimport { Pagination } from './Pagination'\nimport { Title } from './index'\n\nexport const List = (props) => {\n const { resource } = props\n return (\n \n }\n perPage={15}\n pagination={}\n {...props}\n />\n )\n}\n","const sanitizeFieldRestProps = ({\n addLabel,\n allowEmpty,\n basePath,\n cellClassName,\n className,\n emptyText,\n formClassName,\n fullWidth,\n headerClassName,\n label,\n linkType,\n link,\n locale,\n record,\n resource,\n sortable,\n sortBy,\n sortByOrder,\n source,\n textAlign,\n translateChoice,\n ...props\n}) => props\n\nexport default sanitizeFieldRestProps\n","import React, { memo } from 'react'\nimport Typography from '@material-ui/core/Typography'\nimport sanitizeFieldRestProps from './sanitizeFieldRestProps'\nimport md5 from 'blueimp-md5'\nimport { useRecordContext } from 'react-admin'\n\nexport const MultiLineTextField = memo(\n ({\n className,\n emptyText,\n source,\n firstLine,\n maxLines,\n addLabel,\n ...rest\n }) => {\n const record = useRecordContext(rest)\n const value = record && record[source]\n let lines = value ? value.split('\\n') : []\n if (maxLines || firstLine) {\n lines = lines.slice(firstLine, maxLines)\n }\n\n return (\n \n {lines.length === 0 && emptyText\n ? emptyText\n : lines.map((line, idx) =>\n line === '' ? (\n
\n ) : (\n \n )\n )}\n \n )\n }\n)\n\nMultiLineTextField.defaultProps = {\n addLabel: true,\n firstLine: 0,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport { IconButton } from '@material-ui/core'\nimport { useDispatch } from 'react-redux'\nimport { useDataProvider } from 'react-admin'\nimport { playTracks } from '../actions'\n\nexport const PlayButton = ({ record, size, className }) => {\n let extractSongsData = function (response) {\n const data = response.data.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {}\n )\n const ids = response.data.map((r) => r.id)\n return { data, ids }\n }\n const dataProvider = useDataProvider()\n const dispatch = useDispatch()\n const playAlbum = (record) => {\n dataProvider\n .getList('song', {\n pagination: { page: 1, perPage: -1 },\n sort: { field: 'discNumber, trackNumber', order: 'ASC' },\n filter: { album_id: record.id, disc_number: record.discNumber },\n })\n .then((response) => {\n let { data, ids } = extractSongsData(response)\n dispatch(playTracks(data, ids))\n })\n }\n\n return (\n {\n e.stopPropagation()\n e.preventDefault()\n playAlbum(record)\n }}\n aria-label=\"play\"\n className={className}\n size={size}\n >\n \n \n )\n}\n\nPlayButton.propTypes = {\n record: PropTypes.object.isRequired,\n size: PropTypes.string,\n className: PropTypes.string,\n}\n\nPlayButton.defaultProps = {\n size: 'small',\n}\n","import React from 'react'\nimport { Chip, makeStyles } from '@material-ui/core'\nimport { useTranslate } from 'react-admin'\nimport inflection from 'inflection'\n\nconst useQuickFilterStyles = makeStyles((theme) => ({\n chip: {\n marginBottom: theme.spacing(1),\n },\n}))\n\nexport const QuickFilter = ({ source, resource, label, defaultValue }) => {\n const translate = useTranslate()\n const classes = useQuickFilterStyles()\n let lbl = label || source\n if (typeof lbl === 'string' || lbl instanceof String) {\n if (label) {\n lbl = translate(lbl, {\n _: inflection.humanize(inflection.underscore(lbl)),\n })\n } else {\n lbl = translate(`resources.${resource}.fields.${source}`, {\n _: inflection.humanize(inflection.underscore(source)),\n })\n }\n }\n return \n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useRecordContext } from 'react-admin'\n\nexport const formatRange = (record, source) => {\n const nameCapitalized = source.charAt(0).toUpperCase() + source.slice(1)\n const min = record[`min${nameCapitalized}`]\n const max = record[`max${nameCapitalized}`]\n let range = []\n if (min) {\n range.push(min)\n }\n if (max && max !== min) {\n range.push(max)\n }\n return range.join('-')\n}\n\nexport const RangeField = ({ className, source, ...rest }) => {\n const record = useRecordContext(rest)\n return {formatRange(record, source)}\n}\n\nRangeField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nRangeField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport { Button, useDataProvider, useNotify, useTranslate } from 'react-admin'\nimport { useDispatch } from 'react-redux'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport { playTracks } from '../actions'\nimport PropTypes from 'prop-types'\n\nexport const ShuffleAllButton = ({ filters }) => {\n const translate = useTranslate()\n const dataProvider = useDataProvider()\n const dispatch = useDispatch()\n const notify = useNotify()\n\n const handleOnClick = () => {\n dataProvider\n .getList('song', {\n pagination: { page: 1, perPage: 200 },\n sort: { field: 'random', order: 'ASC' },\n filter: filters,\n })\n .then((res) => {\n const data = {}\n res.data.forEach((song) => {\n data[song.id] = song\n })\n dispatch(playTracks(data))\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n }\n\n return (\n \n \n \n )\n}\n\nShuffleAllButton.propTypes = {\n filters: PropTypes.object,\n}\nShuffleAllButton.defaultProps = {\n filters: {},\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Avatar from '@material-ui/core/Avatar'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemAvatar from '@material-ui/core/ListItemAvatar'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { Link } from 'react-router-dom'\nimport { linkToRecord, sanitizeListRestProps } from 'react-admin'\n\nconst useStyles = makeStyles(\n {\n link: {\n textDecoration: 'none',\n color: 'inherit',\n },\n tertiary: { float: 'right', opacity: 0.541176 },\n },\n { name: 'RaSimpleList' }\n)\n\nconst LinkOrNot = ({\n classes: classesOverride,\n linkType,\n basePath,\n id,\n record,\n children,\n}) => {\n const classes = useStyles({ classes: classesOverride })\n return linkType === 'edit' || linkType === true ? (\n \n {children}\n \n ) : linkType === 'show' ? (\n \n {children}\n \n ) : typeof linkType === 'function' ? (\n linkType(id, basePath, record)}>{children}\n ) : (\n {children}\n )\n}\n\nexport const SimpleList = ({\n basePath,\n className,\n classes: classesOverride,\n data,\n hasBulkActions,\n ids,\n loading,\n leftAvatar,\n leftIcon,\n linkType,\n onToggleItem,\n primaryText,\n rightAvatar,\n rightIcon,\n secondaryText,\n selectedIds,\n tertiaryText,\n total,\n ...rest\n}) => {\n const classes = useStyles({ classes: classesOverride })\n return (\n (loading || total > 0) && (\n \n {ids.map((id) => (\n \n \n {leftIcon && (\n {leftIcon(data[id], id)}\n )}\n {leftAvatar && (\n \n {leftAvatar(data[id], id)}\n \n )}\n \n {primaryText(data[id], id)}\n {tertiaryText && (\n \n {tertiaryText(data[id], id)}\n \n )}\n \n }\n secondary={secondaryText && secondaryText(data[id], id)}\n />\n {(rightAvatar || rightIcon) && (\n \n {rightAvatar && {rightAvatar(data[id], id)}}\n {rightIcon && (\n {rightIcon(data[id], id)}\n )}\n \n )}\n \n \n ))}\n \n )\n )\n}\n\nSimpleList.propTypes = {\n basePath: PropTypes.string,\n className: PropTypes.string,\n classes: PropTypes.object,\n data: PropTypes.object,\n hasBulkActions: PropTypes.bool.isRequired,\n ids: PropTypes.array,\n leftAvatar: PropTypes.func,\n leftIcon: PropTypes.func,\n linkType: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.bool,\n PropTypes.func,\n ]).isRequired,\n onToggleItem: PropTypes.func,\n primaryText: PropTypes.func,\n rightAvatar: PropTypes.func,\n rightIcon: PropTypes.func,\n secondaryText: PropTypes.func,\n selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,\n tertiaryText: PropTypes.func,\n}\n\nSimpleList.defaultProps = {\n linkType: 'edit',\n hasBulkActions: false,\n selectedIds: [],\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { formatBytes } from '../utils'\nimport { useRecordContext } from 'react-admin'\nimport { makeStyles } from '@material-ui/core'\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n display: 'inline-block',\n },\n}))\n\nexport const SizeField = ({ source, ...rest }) => {\n const classes = useStyles()\n const record = useRecordContext(rest)\n return {formatBytes(record[source])}\n}\n\nSizeField.propTypes = {\n label: PropTypes.string,\n record: PropTypes.object,\n source: PropTypes.string.isRequired,\n}\n\nSizeField.defaultProps = {\n addLabel: true,\n}\n","import React, { useState } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport { useTranslate } from 'react-admin'\nimport { IconButton, Menu, MenuItem } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport MoreVertIcon from '@material-ui/icons/MoreVert'\nimport clsx from 'clsx'\nimport {\n playNext,\n addTracks,\n setTrack,\n openAddToPlaylist,\n openExtendedInfoDialog,\n} from '../actions'\nimport subsonic from '../subsonic'\nimport { LoveButton } from './LoveButton'\nimport config from '../config'\nimport { formatBytes } from '../utils'\n\nconst useStyles = makeStyles({\n noWrap: {\n whiteSpace: 'nowrap',\n },\n})\n\nexport const SongContextMenu = ({\n resource,\n record,\n showLove,\n onAddToPlaylist,\n className,\n}) => {\n const classes = useStyles()\n const dispatch = useDispatch()\n const translate = useTranslate()\n const [anchorEl, setAnchorEl] = useState(null)\n const options = {\n playNow: {\n enabled: true,\n label: translate('resources.song.actions.playNow'),\n action: (record) => dispatch(setTrack(record)),\n },\n playNext: {\n enabled: true,\n label: translate('resources.song.actions.playNext'),\n action: (record) => dispatch(playNext({ [record.id]: record })),\n },\n addToQueue: {\n enabled: true,\n label: translate('resources.song.actions.addToQueue'),\n action: (record) => dispatch(addTracks({ [record.id]: record })),\n },\n addToPlaylist: {\n enabled: true,\n label: translate('resources.song.actions.addToPlaylist'),\n action: (record) =>\n dispatch(\n openAddToPlaylist({\n selectedIds: [record.mediaFileId || record.id],\n onSuccess: (id) => onAddToPlaylist(id),\n })\n ),\n },\n download: {\n enabled: config.enableDownloads,\n label: `${translate('resources.song.actions.download')} (${formatBytes(\n record.size\n )})`,\n action: (record) => subsonic.download(record.mediaFileId || record.id),\n },\n info: {\n enabled: true,\n label: translate('resources.song.actions.info'),\n action: (record) => dispatch(openExtendedInfoDialog(record)),\n },\n }\n\n const handleClick = (e) => {\n setAnchorEl(e.currentTarget)\n e.stopPropagation()\n }\n\n const handleClose = (e) => {\n setAnchorEl(null)\n e.stopPropagation()\n }\n\n const handleItemClick = (e) => {\n e.preventDefault()\n setAnchorEl(null)\n const key = e.target.getAttribute('value')\n options[key].action(record)\n e.stopPropagation()\n }\n\n const open = Boolean(anchorEl)\n\n return (\n \n \n \n \n \n \n {Object.keys(options).map(\n (key) =>\n options[key].enabled && (\n \n {options[key].label}\n \n )\n )}\n \n \n )\n}\n\nSongContextMenu.propTypes = {\n resource: PropTypes.string.isRequired,\n record: PropTypes.object.isRequired,\n onAddToPlaylist: PropTypes.func,\n showLove: PropTypes.bool,\n}\n\nSongContextMenu.defaultProps = {\n onAddToPlaylist: () => {},\n record: {},\n resource: 'song',\n showLove: true,\n addLabel: true,\n}\n","import React, { isValidElement, useMemo, useCallback, forwardRef } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { Datagrid, PureDatagridBody, PureDatagridRow } from 'react-admin'\nimport {\n TableCell,\n TableRow,\n Typography,\n useMediaQuery,\n} from '@material-ui/core'\nimport PropTypes from 'prop-types'\nimport { makeStyles } from '@material-ui/core/styles'\nimport AlbumIcon from '@material-ui/icons/Album'\nimport clsx from 'clsx'\nimport { useDrag } from 'react-dnd'\nimport { playTracks } from '../actions'\nimport { AlbumContextMenu } from '../common'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles({\n subtitle: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n verticalAlign: 'middle',\n },\n discIcon: {\n verticalAlign: 'text-top',\n marginRight: '4px',\n },\n row: {\n cursor: 'pointer',\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n },\n },\n headerStyle: {\n '& thead': {\n boxShadow: '0px 3px 3px rgba(0, 0, 0, 0.15)',\n },\n '& th': {\n fontWeight: 'bold',\n padding: '15px',\n },\n },\n contextMenu: {\n visibility: (props) => (props.isDesktop ? 'hidden' : 'visible'),\n },\n})\n\nconst DiscSubtitleRow = forwardRef(\n ({ record, onClick, colSpan, contextAlwaysVisible }, ref) => {\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const handlePlayDisc = (discNumber) => () => {\n onClick(discNumber)\n }\n\n let subtitle = []\n if (record.discNumber > 0) {\n subtitle.push(record.discNumber)\n }\n if (record.discSubtitle) {\n subtitle.push(record.discSubtitle)\n }\n\n return (\n \n \n \n \n {subtitle.join(': ')}\n \n \n \n \n \n \n )\n }\n)\n\nexport const SongDatagridRow = ({\n record,\n children,\n firstTracks,\n contextAlwaysVisible,\n onClickDiscSubtitle,\n className,\n ...rest\n}) => {\n const classes = useStyles()\n const fields = React.Children.toArray(children).filter((c) =>\n isValidElement(c)\n )\n\n const [, dragDiscRef] = useDrag(\n () => ({\n type: DraggableTypes.DISC,\n item: {\n discs: [{ albumId: record?.albumId, discNumber: record?.discNumber }],\n },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n\n const [, dragSongRef] = useDrag(\n () => ({\n type: DraggableTypes.SONG,\n item: { ids: [record?.mediaFileId || record?.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n\n if (!record || !record.title) {\n return null\n }\n\n const childCount = fields.length\n return (\n <>\n {firstTracks.has(record.id) && (\n \n )}\n \n {fields}\n \n \n )\n}\n\nSongDatagridRow.propTypes = {\n record: PropTypes.object,\n children: PropTypes.node,\n firstTracks: PropTypes.instanceOf(Set),\n contextAlwaysVisible: PropTypes.bool,\n onClickDiscSubtitle: PropTypes.func,\n}\n\nSongDatagridRow.defaultProps = {\n onClickDiscSubtitle: () => {},\n}\n\nconst SongDatagridBody = ({\n contextAlwaysVisible,\n showDiscSubtitles,\n ...rest\n}) => {\n const dispatch = useDispatch()\n const { ids, data } = rest\n\n const playDisc = useCallback(\n (discNumber) => {\n const idsToPlay = ids.filter((id) => data[id].discNumber === discNumber)\n dispatch(playTracks(data, idsToPlay))\n },\n [dispatch, data, ids]\n )\n\n const firstTracks = useMemo(() => {\n if (!ids) {\n return new Set()\n }\n let foundSubtitle = false\n const set = new Set(\n ids\n .filter((i) => data[i])\n .reduce((acc, id) => {\n const last = acc && acc[acc.length - 1]\n foundSubtitle = foundSubtitle || data[id].discSubtitle\n if (\n acc.length === 0 ||\n (last && data[id].discNumber !== data[last].discNumber)\n ) {\n acc.push(id)\n }\n return acc\n }, [])\n )\n if (!showDiscSubtitles || (set.size < 2 && !foundSubtitle)) {\n set.clear()\n }\n return set\n }, [ids, data, showDiscSubtitles])\n\n return (\n \n }\n />\n )\n}\n\nexport const SongDatagrid = ({\n contextAlwaysVisible,\n showDiscSubtitles,\n ...rest\n}) => {\n const classes = useStyles()\n return (\n \n }\n />\n )\n}\n\nSongDatagrid.propTypes = {\n contextAlwaysVisible: PropTypes.bool,\n showDiscSubtitles: PropTypes.bool,\n classes: PropTypes.object,\n}\n","import React from 'react'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableCell from '@material-ui/core/TableCell'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport TableRow from '@material-ui/core/TableRow'\nimport {\n BooleanField,\n DateField,\n TextField,\n NumberField,\n FunctionField,\n useTranslate,\n useRecordContext,\n} from 'react-admin'\nimport inflection from 'inflection'\nimport { BitrateField, SizeField } from './index'\nimport { MultiLineTextField } from './MultiLineTextField'\nimport { makeStyles } from '@material-ui/core/styles'\n\nconst useStyles = makeStyles({\n tableCell: {\n width: '17.5%',\n },\n})\n\nexport const SongInfo = (props) => {\n const classes = useStyles()\n const translate = useTranslate()\n const record = useRecordContext(props)\n const data = {\n path: ,\n album: ,\n discSubtitle: ,\n albumArtist: ,\n genre: (\n r.genres?.map((g) => g.name).join(', ')} />\n ),\n compilation: ,\n bitRate: ,\n channels: ,\n size: ,\n updatedAt: ,\n playCount: ,\n bpm: ,\n comment: ,\n }\n\n const optionalFields = ['discSubtitle', 'comment', 'bpm', 'genre']\n optionalFields.forEach((field) => {\n !record[field] && delete data[field]\n })\n if (record.playCount > 0) {\n data.playDate = \n }\n\n return (\n \n \n \n {Object.keys(data).map((key) => {\n return (\n \n \n {translate(`resources.song.fields.${key}`, {\n _: inflection.humanize(inflection.underscore(key)),\n })}\n :\n \n {data[key]}\n \n )\n })}\n \n
\n
\n )\n}\n","import { makeStyles } from '@material-ui/core/styles'\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { useSelector } from 'react-redux'\nimport { FunctionField } from 'react-admin'\nimport { useTheme } from '@material-ui/core/styles'\nimport PlayingLight from '../icons/playing-light.gif'\nimport PlayingDark from '../icons/playing-dark.gif'\nimport PausedLight from '../icons/paused-light.png'\nimport PausedDark from '../icons/paused-dark.png'\n\nconst useStyles = makeStyles({\n icon: {\n width: '32px',\n height: '32px',\n verticalAlign: 'text-top',\n marginLeft: '-8px',\n marginTop: '-7px',\n paddingRight: '3px',\n },\n text: {\n verticalAlign: 'text-top',\n },\n})\n\nexport const SongTitleField = ({ showTrackNumbers, ...props }) => {\n const theme = useTheme()\n const classes = useStyles()\n const { record } = props\n const currentTrack = useSelector((state) => state?.player?.current || {})\n const currentId = currentTrack.trackId\n const paused = currentTrack.paused\n const isCurrent =\n currentId && (currentId === record.id || currentId === record.mediaFileId)\n\n const trackName = (r) => {\n const name = r.title\n if (r.trackNumber && showTrackNumbers) {\n return r.trackNumber.toString().padStart(2, '0') + ' ' + name\n }\n return name\n }\n\n const Icon = () => {\n let icon\n if (paused) {\n icon = theme.palette.type === 'light' ? PausedLight : PausedDark\n } else {\n icon = theme.palette.type === 'light' ? PlayingLight : PlayingDark\n }\n return (\n \n )\n }\n\n return (\n <>\n {isCurrent && }\n \n \n )\n}\n\nSongTitleField.propTypes = {\n record: PropTypes.object,\n showTrackNumbers: PropTypes.bool,\n}\n\nSongTitleField.defaultProps = {\n record: {},\n showTrackNumbers: false,\n}\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAAAAACreq1xAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAnRSTlMAAHaTzTgAAAACYktHRAD/h4/MvwAAAAd0SU1FB+UDFw4UEte6vnAAAAAnSURBVFjD7cyhEQAACMSwX4X9l8ThEFguUVVNAAAAgDdq7G0IAHDWO+8PeYnJa4QAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDMtMjNUMTQ6MTg6NTkrMDA6MDAXgf/NAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAzLTIzVDE0OjE4OjU5KzAwOjAwZtxHcQAAAABJRU5ErkJggg==\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAAAAACreq1xAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAnRSTlMAAHaTzTgAAAACYktHRAD/h4/MvwAAAAd0SU1FB+UDFw4UNuu5WqEAAAAnSURBVFjD7cyhEQAACMSw339OBsHhEFguUVVNAAAAgDdq7G0IAHDWlC1q4c5Yf/kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjEtMDMtMjNUMTQ6MTg6NTkrMDA6MDAXgf/NAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIxLTAzLTIzVDE0OjE4OjU5KzAwOjAwZtxHcQAAAABJRU5ErkJggg==\"","export default \"data:image/gif;base64,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\"","export default \"data:image/gif;base64,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\"","import React from 'react'\nimport { useMediaQuery } from '@material-ui/core'\nimport { useTranslate } from 'react-admin'\n\nexport const Title = ({ subTitle, args }) => {\n const translate = useTranslate()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const text = translate(subTitle, { ...args, _: subTitle })\n\n if (isDesktop) {\n return 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 = (ownerId) => {\n return (\n localStorage.getItem('userId') === ownerId ||\n localStorage.getItem('role') === 'admin'\n )\n}\n\nexport const isReadOnly = (ownerId) => {\n return !isWritable(ownerId)\n}\n\nexport const Writable = (props) => {\n const { record = {}, children } = props\n if (isWritable(record.ownerId)) {\n return Children.map(children, (child) =>\n isValidElement(child) ? cloneElement(child, props) : child\n )\n }\n return null\n}\n\nexport const isSmartPlaylist = (pls) => !!pls.rules\n\nexport const canChangeTracks = (pls) =>\n isWritable(pls.ownerId) && !isSmartPlaylist(pls)\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { sanitizeListRestProps } from 'react-admin'\nimport { DurationField, SongContextMenu, RatingField } from './index'\nimport { setTrack } from '../actions'\nimport { useDispatch } from 'react-redux'\nimport config from '../config'\n\nconst useStyles = makeStyles(\n {\n link: {\n textDecoration: 'none',\n color: 'inherit',\n },\n listItem: {\n padding: '10px',\n },\n title: {\n paddingRight: '10px',\n width: '80%',\n },\n secondary: {\n marginTop: '-3px',\n width: '96%',\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n },\n artist: {\n paddingRight: '30px',\n },\n timeStamp: {\n float: 'right',\n color: '#fff',\n fontWeight: '200',\n opacity: 0.6,\n fontSize: '12px',\n padding: '2px',\n },\n rightIcon: {\n top: '26px',\n },\n },\n { name: 'RaSongSimpleList' }\n)\n\nexport const SongSimpleList = ({\n basePath,\n className,\n classes: classesOverride,\n data,\n hasBulkActions,\n ids,\n loading,\n onToggleItem,\n selectedIds,\n total,\n ...rest\n}) => {\n const dispatch = useDispatch()\n const classes = useStyles({ classes: classesOverride })\n return (\n (loading || total > 0) && (\n \n {ids.map(\n (id) =>\n data[id] && (\n dispatch(setTrack(data[id]))}>\n \n {data[id].title}\n }\n secondary={\n <>\n \n \n {data[id].artist}\n \n \n \n \n \n {config.enableStarRating && (\n \n )}\n \n }\n />\n \n \n \n \n \n \n \n )\n )}\n \n )\n )\n}\n\nSongSimpleList.propTypes = {\n basePath: PropTypes.string,\n className: PropTypes.string,\n classes: PropTypes.object,\n data: PropTypes.object,\n hasBulkActions: PropTypes.bool.isRequired,\n ids: PropTypes.array,\n onToggleItem: PropTypes.func,\n selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,\n}\n\nSongSimpleList.defaultProps = {\n hasBulkActions: false,\n selectedIds: [],\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport List from '@material-ui/core/List'\nimport ListItem from '@material-ui/core/ListItem'\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'\nimport ListItemText from '@material-ui/core/ListItemText'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { sanitizeListRestProps } from 'react-admin'\nimport { ArtistContextMenu, RatingField } from './index'\nimport config from '../config'\n\nconst useStyles = makeStyles(\n {\n listItem: {\n padding: '10px',\n },\n title: {\n paddingRight: '10px',\n width: '80%',\n },\n rightIcon: {\n top: '26px',\n },\n },\n { name: 'RaArtistSimpleList' }\n)\n\nexport const ArtistSimpleList = ({\n linkType,\n className,\n classes: classesOverride,\n data,\n hasBulkActions,\n ids,\n loading,\n selectedIds,\n total,\n ...rest\n}) => {\n const classes = useStyles({ classes: classesOverride })\n return (\n (loading || total > 0) && (\n \n {ids.map(\n (id) =>\n data[id] && (\n linkType(id)}>\n \n \n
{data[id].name}
\n {config.enableStarRating && (\n \n )}\n \n }\n />\n \n \n \n \n \n
\n
\n )\n )}\n
\n )\n )\n}\n\nArtistSimpleList.propTypes = {\n className: PropTypes.string,\n classes: PropTypes.object,\n data: PropTypes.object,\n hasBulkActions: PropTypes.bool.isRequired,\n ids: PropTypes.array,\n selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired,\n}\n\nArtistSimpleList.defaultProps = {\n hasBulkActions: false,\n selectedIds: [],\n}\n","import React, { useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport Rating from '@material-ui/lab/Rating'\nimport { makeStyles } from '@material-ui/core/styles'\nimport StarBorderIcon from '@material-ui/icons/StarBorder'\nimport clsx from 'clsx'\nimport { useRating } from './useRating'\nimport { useRecordContext } from 'react-admin'\n\nconst useStyles = makeStyles({\n rating: {\n color: (props) => props.color,\n visibility: (props) => (props.visible === false ? 'hidden' : 'inherit'),\n },\n show: {\n visibility: 'visible !important',\n },\n hide: {\n visibility: 'hidden',\n },\n})\n\nexport const RatingField = ({\n resource,\n visible,\n className,\n size,\n color,\n ...rest\n}) => {\n const record = useRecordContext(rest) || {}\n const [rate, rating] = useRating(resource, record)\n const classes = useStyles({ color, visible })\n\n const stopPropagation = (e) => {\n e.stopPropagation()\n }\n\n const handleRating = useCallback(\n (e, val) => {\n rate(val, e.target.name)\n },\n [rate]\n )\n\n return (\n stopPropagation(e)}>\n 0 ? classes.show : classes.hide\n )}\n value={rating}\n size={size}\n emptyIcon={}\n onChange={(e, newValue) => handleRating(e, newValue)}\n />\n \n )\n}\nRatingField.propTypes = {\n resource: PropTypes.string.isRequired,\n record: PropTypes.object,\n visible: PropTypes.bool,\n size: PropTypes.string,\n}\n\nRatingField.defaultProps = {\n visible: true,\n size: 'small',\n color: 'inherit',\n}\n","import { useState, useCallback, useEffect, useRef } from 'react'\nimport { useDataProvider, useNotify } from 'react-admin'\nimport subsonic from '../subsonic'\n\nexport const useRating = (resource, record) => {\n const [loading, setLoading] = useState(false)\n const notify = useNotify()\n const dataProvider = useDataProvider()\n const mountedRef = useRef(false)\n const rating = record.rating\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n const refreshRating = useCallback(() => {\n dataProvider\n .getOne(resource, { id: record.id })\n .then(() => {\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n .catch((e) => {\n console.log('Error encountered: ' + e)\n })\n }, [dataProvider, record, resource])\n\n const rate = (val, id) => {\n setLoading(true)\n subsonic\n .setRating(id, val)\n .then(refreshRating)\n .catch((e) => {\n console.log('Error setting star rating: ', e)\n notify('ra.page.error', 'warning')\n if (mountedRef.current) {\n setLoading(false)\n }\n })\n }\n\n return [rate, rating, loading]\n}\n","import React, { useState, useEffect } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { setOmittedFields, setToggleableFields } from '../actions'\n\n// TODO Refactor\nexport const useSelectedFields = ({\n resource,\n columns,\n omittedColumns = [],\n defaultOff = [],\n}) => {\n const dispatch = useDispatch()\n const resourceFields = useSelector(\n (state) => state.settings.toggleableFields\n )?.[resource]\n const omittedFields = useSelector((state) => state.settings.omittedFields)?.[\n resource\n ]\n\n const [filteredComponents, setFilteredComponents] = useState([])\n\n useEffect(() => {\n if (\n !resourceFields ||\n Object.keys(resourceFields).length !== Object.keys(columns).length ||\n !Object.keys(columns).every((c) => c in resourceFields)\n ) {\n const obj = {}\n for (const key of Object.keys(columns)) {\n obj[key] = !defaultOff.includes(key)\n }\n dispatch(setToggleableFields({ [resource]: obj }))\n }\n if (!omittedFields) {\n dispatch(setOmittedFields({ [resource]: omittedColumns }))\n }\n }, [\n columns,\n defaultOff,\n dispatch,\n omittedColumns,\n omittedFields,\n resource,\n resourceFields,\n ])\n\n useEffect(() => {\n if (resourceFields) {\n const filtered = []\n const omitted = omittedColumns\n for (const [key, val] of Object.entries(columns)) {\n if (!val) omitted.push(key)\n else if (resourceFields[key]) filtered.push(val)\n }\n if (filteredComponents.length !== filtered.length)\n setFilteredComponents(filtered)\n if (omittedFields.length !== omitted.length)\n dispatch(setOmittedFields({ [resource]: omitted }))\n }\n }, [\n resourceFields,\n columns,\n dispatch,\n omittedColumns,\n omittedFields,\n resource,\n filteredComponents.length,\n ])\n\n return React.Children.toArray(filteredComponents)\n}\n\nuseSelectedFields.propTypes = {\n resource: PropTypes.string,\n columns: PropTypes.object,\n omittedColumns: PropTypes.arrayOf(PropTypes.string),\n defaultOff: PropTypes.arrayOf(PropTypes.string),\n}\n\nexport const useSetToggleableFields = (\n resource,\n toggleableColumns,\n defaultOff = []\n) => {\n const current = useSelector((state) => state.settings.toggleableFields)?.album\n const dispatch = useDispatch()\n useEffect(() => {\n if (!current) {\n dispatch(\n setToggleableFields({\n [resource]: toggleableColumns.reduce((acc, cur) => {\n return {\n ...acc,\n ...{ [cur]: true },\n }\n }, {}),\n })\n )\n dispatch(setOmittedFields({ [resource]: defaultOff }))\n }\n }, [resource, toggleableColumns, dispatch, current, defaultOff])\n}\n\nuseSetToggleableFields.propTypes = {\n resource: PropTypes.string,\n toggleableColumns: PropTypes.arrayOf(PropTypes.string),\n defaultOff: PropTypes.arrayOf(PropTypes.string),\n}\n","import React, { useState } from 'react'\nimport PropTypes from 'prop-types'\nimport IconButton from '@material-ui/core/IconButton'\nimport Menu from '@material-ui/core/Menu'\nimport MenuItem from '@material-ui/core/MenuItem'\nimport { makeStyles, Typography } from '@material-ui/core'\nimport MoreVertIcon from '@material-ui/icons/MoreVert'\nimport Checkbox from '@material-ui/core/Checkbox'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useTranslate } from 'react-admin'\nimport { setToggleableFields } from '../actions'\n\nconst useStyles = makeStyles({\n menuIcon: {\n position: 'relative',\n top: '-0.5em',\n },\n menu: {\n width: '24ch',\n },\n columns: {\n maxHeight: '21rem',\n overflow: 'auto',\n },\n title: {\n margin: '1rem',\n },\n})\n\nexport const ToggleFieldsMenu = ({\n resource,\n topbarComponent: TopBarComponent,\n}) => {\n const [anchorEl, setAnchorEl] = useState(null)\n const dispatch = useDispatch()\n const translate = useTranslate()\n const toggleableColumns = useSelector(\n (state) => state.settings.toggleableFields[resource]\n )\n const omittedColumns =\n useSelector((state) => state.settings.omittedFields[resource]) || []\n\n const classes = useStyles()\n const open = Boolean(anchorEl)\n\n const handleOpen = (event) => {\n setAnchorEl(event.currentTarget)\n }\n const handleClose = () => {\n setAnchorEl(null)\n }\n\n const handleClick = (selectedColumn) => {\n dispatch(\n setToggleableFields({\n [resource]: {\n ...toggleableColumns,\n [selectedColumn]: !toggleableColumns[selectedColumn],\n },\n })\n )\n }\n\n return (\n
\n \n \n \n \n {TopBarComponent && }\n {toggleableColumns ? (\n
\n \n {translate('ra.toggleFieldsMenu.columnsToDisplay')}\n \n
\n {Object.entries(toggleableColumns).map(([key, val]) =>\n !omittedColumns.includes(key) ? (\n handleClick(key)}>\n \n {translate(`resources.${resource}.fields.${key}`)}\n \n ) : null\n )}\n
\n
\n ) : null}\n \n
\n )\n}\n\nToggleFieldsMenu.propTypes = {\n resource: PropTypes.string.isRequired,\n topbarComponent: PropTypes.elementType,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport Chip from '@material-ui/core/Chip'\nimport config from '../config'\nimport { makeStyles } from '@material-ui/core'\nimport clsx from 'clsx'\n\nconst llFormats = new Set(config.losslessFormats.split(','))\nconst placeholder = 'N/A'\n\nconst useStyle = makeStyles(\n (theme) => ({\n chip: {\n transform: 'scale(0.8)',\n },\n }),\n {\n name: 'NDQualityInfo',\n }\n)\n\nexport const QualityInfo = ({ record, size, className }) => {\n const classes = useStyle()\n let { suffix, bitRate } = record\n let info = placeholder\n\n if (suffix) {\n suffix = suffix.toUpperCase()\n info = suffix\n if (!llFormats.has(suffix)) {\n info += ' ' + bitRate\n }\n }\n\n return (\n \n )\n}\n\nQualityInfo.propTypes = {\n record: PropTypes.object.isRequired,\n size: PropTypes.string,\n className: PropTypes.string,\n}\n\nQualityInfo.defaultProps = {\n record: {},\n size: 'small',\n}\n","import React from 'react'\nimport TextField from '@material-ui/core/TextField'\nimport Checkbox from '@material-ui/core/Checkbox'\nimport CheckBoxIcon from '@material-ui/icons/CheckBox'\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'\nimport Autocomplete, {\n createFilterOptions,\n} from '@material-ui/lab/Autocomplete'\nimport { useGetList, useTranslate } from 'react-admin'\nimport PropTypes from 'prop-types'\nimport { isWritable } from '../common'\nimport { makeStyles } from '@material-ui/core'\n\nconst filter = createFilterOptions()\n\nconst useStyles = makeStyles({\n root: { width: '100%' },\n checkbox: { marginRight: 8 },\n})\n\nexport const SelectPlaylistInput = ({ onChange }) => {\n const classes = useStyles()\n const translate = useTranslate()\n const { ids, data } = useGetList(\n 'playlist',\n { page: 1, perPage: -1 },\n { field: 'name', order: 'ASC' },\n {}\n )\n\n const options =\n ids &&\n ids.map((id) => data[id]).filter((option) => isWritable(option.ownerId))\n\n const handleOnChange = (event, newValue) => {\n let newState = []\n if (newValue && newValue.length) {\n newValue.forEach((playlistObject) => {\n if (playlistObject.inputValue) {\n newState.push({\n name: playlistObject.inputValue,\n })\n } else if (typeof playlistObject === 'string') {\n newState.push({\n name: playlistObject,\n })\n } else {\n newState.push(playlistObject)\n }\n })\n }\n onChange(newState)\n }\n\n const icon = \n const checkedIcon = \n\n return (\n {\n const filtered = filter(options, params)\n\n // Suggest the creation of a new value\n if (params.inputValue !== '') {\n filtered.push({\n inputValue: params.inputValue,\n name: translate('resources.playlist.actions.addNewPlaylist', {\n name: params.inputValue,\n }),\n })\n }\n\n return filtered\n }}\n clearOnBlur\n handleHomeEndKeys\n openOnFocus\n selectOnFocus\n id=\"select-playlist-input\"\n options={options}\n getOptionLabel={(option) => {\n // Value selected with enter, right from the input\n if (typeof option === 'string') {\n return option\n }\n // Add \"xxx\" option created dynamically\n if (option.inputValue) {\n return option.inputValue\n }\n // Regular option\n return option.name\n }}\n renderOption={(option, { selected }) => (\n \n \n {option.name}\n \n )}\n className={classes.root}\n freeSolo\n renderInput={(params) => (\n \n )}\n />\n )\n}\n\nSelectPlaylistInput.propTypes = {\n onChange: PropTypes.func.isRequired,\n}\n","import React from 'react'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\n\nimport { useTranslate } from 'react-admin'\n\nconst DuplicateSongDialog = ({\n open,\n handleClickClose,\n handleSubmit,\n handleSkip,\n}) => {\n const translate = useTranslate()\n\n return (\n \n \n {translate('resources.playlist.message.duplicate_song')}\n \n \n {translate('resources.playlist.message.song_exist')}\n \n \n \n \n \n \n \n )\n}\n\nexport default DuplicateSongDialog\n","import React, { useState } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport {\n useDataProvider,\n useNotify,\n useRefresh,\n useTranslate,\n} from 'react-admin'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\nimport {\n closeAddToPlaylist,\n closeDuplicateSongDialog,\n openDuplicateSongWarning,\n} from '../actions'\nimport { SelectPlaylistInput } from './SelectPlaylistInput'\nimport DuplicateSongDialog from './DuplicateSongDialog'\n\nexport const AddToPlaylistDialog = () => {\n const { open, selectedIds, onSuccess, duplicateSong, duplicateIds } =\n useSelector((state) => state.addToPlaylistDialog)\n const dispatch = useDispatch()\n const translate = useTranslate()\n const notify = useNotify()\n const refresh = useRefresh()\n const [value, setValue] = useState({})\n const [check, setCheck] = useState(false)\n const dataProvider = useDataProvider()\n const createAndAddToPlaylist = (playlistObject) => {\n dataProvider\n .create('playlist', {\n data: { name: playlistObject.name },\n })\n .then((res) => {\n addToPlaylist(res.data.id)\n })\n .catch((error) => notify(`Error: ${error.message}`, 'warning'))\n }\n\n const addToPlaylist = (playlistId, distinctIds) => {\n const trackIds = Array.isArray(distinctIds) ? distinctIds : selectedIds\n dataProvider\n .create('playlistTrack', {\n data: { ids: trackIds },\n filter: { playlist_id: playlistId },\n })\n .then(() => {\n const len = trackIds.length\n notify('message.songsAddedToPlaylist', 'info', { smart_count: len })\n onSuccess && onSuccess(value, len)\n refresh()\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n }\n\n const checkDuplicateSong = (playlistObject) => {\n dataProvider\n .getOne('playlist', { id: playlistObject.id })\n .then((res) => {\n const tracks = res.data.tracks\n if (tracks) {\n const dupSng = tracks.filter((song) =>\n selectedIds.some((id) => id === song.id)\n )\n\n if (dupSng.length) {\n const dupIds = dupSng.map((song) => song.id)\n dispatch(openDuplicateSongWarning(dupIds))\n }\n }\n setCheck(true)\n })\n .catch((error) => {\n console.error(error)\n notify('ra.page.error', 'warning')\n })\n }\n\n const handleSubmit = (e) => {\n value.forEach((playlistObject) => {\n if (playlistObject.id) {\n addToPlaylist(playlistObject.id, playlistObject.distinctIds)\n } else {\n createAndAddToPlaylist(playlistObject)\n }\n })\n setCheck(false)\n setValue({})\n dispatch(closeAddToPlaylist())\n e.stopPropagation()\n }\n\n const handleClickClose = (e) => {\n setCheck(false)\n setValue({})\n dispatch(closeAddToPlaylist())\n e.stopPropagation()\n }\n\n const handleChange = (pls) => {\n if (!value.length || pls.length > value.length) {\n let newlyAdded = pls.slice(-1).pop()\n if (newlyAdded.id) {\n setCheck(false)\n checkDuplicateSong(newlyAdded)\n } else setCheck(true)\n } else if (pls.length === 0) setCheck(false)\n setValue(pls)\n }\n\n const handleDuplicateClose = () => {\n dispatch(closeDuplicateSongDialog())\n }\n const handleDuplicateSubmit = () => {\n dispatch(closeDuplicateSongDialog())\n }\n const handleSkip = () => {\n const distinctSongs = selectedIds.filter(\n (id) => duplicateIds.indexOf(id) < 0\n )\n value.slice(-1).pop().distinctIds = distinctSongs\n dispatch(closeDuplicateSongDialog())\n }\n\n return (\n <>\n \n \n {translate('resources.playlist.actions.selectPlaylist')}\n \n \n \n \n \n \n \n {translate('ra.action.add')}\n \n \n \n \n \n )\n}\n","import config from './config'\nconst keyMap = {\n SHOW_HELP: { name: 'show_help', sequence: 'shift+?', group: 'Global' },\n TOGGLE_MENU: { name: 'toggle_menu', sequence: 'm', group: 'Global' },\n TOGGLE_PLAY: { name: 'toggle_play', sequence: 'space', group: 'Player' },\n PREV_SONG: { name: 'prev_song', sequence: 'left', group: 'Player' },\n NEXT_SONG: { name: 'next_song', sequence: 'right', group: 'Player' },\n VOL_UP: { name: 'vol_up', sequence: '=', group: 'Player' },\n VOL_DOWN: { name: 'vol_down', sequence: '-', group: 'Player' },\n ...(config.enableFavourites && {\n TOGGLE_LOVE: { name: 'toggle_love', sequence: 'l', group: 'Player' },\n }),\n}\n\nexport { keyMap }\n","import React, { useCallback, useState } from 'react'\nimport ReactDOM from 'react-dom'\nimport { Chip, Dialog } from '@material-ui/core'\nimport { getApplicationKeyMap, GlobalHotKeys } from 'react-hotkeys'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport Paper from '@material-ui/core/Paper'\nimport Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport TableRow from '@material-ui/core/TableRow'\nimport TableCell from '@material-ui/core/TableCell'\nimport { useTranslate } from 'react-admin'\nimport inflection from 'inflection'\nimport { keyMap } from '../hotkeys'\nimport { DialogTitle } from './DialogTitle'\nimport { DialogContent } from './DialogContent'\n\nconst HelpTable = (props) => {\n const keyMap = getApplicationKeyMap()\n const translate = useTranslate()\n return ReactDOM.createPortal(\n \n \n {translate('help.title')}\n \n \n \n \n \n {Object.keys(keyMap).map((key) => {\n const { sequences, name } = keyMap[key]\n const description = translate(`help.hotkeys.${name}`, {\n _: inflection.humanize(name),\n })\n return (\n \n \n {description}\n \n \n {sequences.map(({ sequence }) => (\n {sequence}}\n size=\"small\"\n variant={'outlined'}\n key={sequence}\n />\n ))}\n \n \n )\n })}\n \n
\n
\n
\n
,\n document.body\n )\n}\n\nexport const HelpDialog = (props) => {\n const [open, setOpen] = useState(false)\n\n const handleClickClose = (e) => {\n setOpen(false)\n e.stopPropagation()\n }\n\n const handlers = {\n SHOW_HELP: useCallback(() => setOpen(true), [setOpen]),\n }\n\n return (\n <>\n \n \n \n )\n}\n","import React, { createRef, useCallback, useState } from 'react'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n LinearProgress,\n Link,\n TextField,\n} from '@material-ui/core'\nimport { useNotify, useTranslate } from 'react-admin'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { closeListenBrainzTokenDialog } from '../actions'\nimport { httpClient } from '../dataProvider'\n\nexport const ListenBrainzTokenDialog = ({ setLinked }) => {\n const dispatch = useDispatch()\n const notify = useNotify()\n const translate = useTranslate()\n const { open } = useSelector((state) => state.listenBrainzTokenDialog)\n const [token, setToken] = useState('')\n const [checking, setChecking] = useState(false)\n const inputRef = createRef()\n\n const handleChange = (event) => {\n setToken(event.target.value)\n }\n\n const handleLinkClick = (event) => {\n inputRef.current.focus()\n }\n\n const handleSave = useCallback(\n (event) => {\n setChecking(true)\n httpClient('/api/listenbrainz/link', {\n method: 'PUT',\n body: JSON.stringify({ token: token }),\n })\n .then((response) => {\n notify('message.listenBrainzLinkSuccess', 'success', {\n user: response.json.user,\n })\n setLinked(true)\n setToken('')\n })\n .catch((error) => {\n notify('message.listenBrainzLinkFailure', 'warning', {\n error: error.body?.error || error.message,\n })\n setLinked(false)\n })\n .finally(() => {\n setChecking(false)\n dispatch(closeListenBrainzTokenDialog())\n event.stopPropagation()\n })\n },\n [dispatch, notify, setLinked, token]\n )\n\n const handleClickClose = (event) => {\n if (!checking) {\n dispatch(closeListenBrainzTokenDialog())\n event.stopPropagation()\n }\n }\n\n const handleKeyPress = useCallback(\n (event) => {\n if (event.key === 'Enter' && token !== '') {\n handleSave(event)\n }\n },\n [token, handleSave]\n )\n\n return (\n <>\n \n \n ListenBrainz\n \n \n \n {translate('resources.user.message.listenBrainzToken')}{' '}\n \n {translate('resources.user.message.clickHereForToken')}\n \n \n \n {checking && }\n \n \n \n {translate('ra.action.cancel')}\n \n \n {translate('ra.action.save')}\n \n \n \n \n )\n}\n","import React, { useCallback } from 'react'\nimport {\n MenuItemLink,\n useDataProvider,\n useNotify,\n useQueryWithStore,\n} from 'react-admin'\nimport { useHistory } from 'react-router-dom'\nimport QueueMusicIcon from '@material-ui/icons/QueueMusic'\nimport { Typography } from '@material-ui/core'\nimport QueueMusicOutlinedIcon from '@material-ui/icons/QueueMusicOutlined'\nimport { BiCog } from 'react-icons/all'\nimport { useDrop } from 'react-dnd'\nimport SubMenu from './SubMenu'\nimport { canChangeTracks } from '../common'\nimport { DraggableTypes, MAX_SIDEBAR_PLAYLISTS } from '../consts'\n\nconst PlaylistMenuItemLink = ({ pls, sidebarIsOpen }) => {\n const dataProvider = useDataProvider()\n const notify = useNotify()\n\n const [, dropRef] = useDrop(() => ({\n accept: canChangeTracks(pls) ? DraggableTypes.ALL : [],\n drop: (item) =>\n dataProvider\n .addToPlaylist(pls.id, item)\n .then((res) => {\n notify('message.songsAddedToPlaylist', 'info', {\n smart_count: res.data?.added,\n })\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n }),\n }))\n\n return (\n \n {pls.name}\n \n }\n sidebarIsOpen={sidebarIsOpen}\n dense={false}\n />\n )\n}\n\nconst PlaylistsSubMenu = ({ state, setState, sidebarIsOpen, dense }) => {\n const history = useHistory()\n const { data, loaded } = useQueryWithStore({\n type: 'getList',\n resource: 'playlist',\n payload: {\n pagination: {\n page: 0,\n perPage: MAX_SIDEBAR_PLAYLISTS,\n },\n sort: { field: 'name' },\n },\n })\n\n const handleToggle = (menu) => {\n setState((state) => ({ ...state, [menu]: !state[menu] }))\n }\n\n const renderPlaylistMenuItemLink = (pls) => (\n \n )\n\n const userId = localStorage.getItem('userId')\n const myPlaylists = []\n const sharedPlaylists = []\n\n if (loaded && data) {\n const allPlaylists = Object.keys(data).map((id) => data[id])\n\n allPlaylists.forEach((pls) => {\n if (userId === pls.ownerId) {\n myPlaylists.push(pls)\n } else {\n sharedPlaylists.push(pls)\n }\n })\n }\n\n const onPlaylistConfig = useCallback(\n () => history.push('/playlist'),\n [history]\n )\n\n return (\n <>\n handleToggle('menuPlaylists')}\n isOpen={state.menuPlaylists}\n sidebarIsOpen={sidebarIsOpen}\n name={'menu.playlists'}\n icon={}\n dense={dense}\n actionIcon={}\n onAction={onPlaylistConfig}\n >\n {myPlaylists.map(renderPlaylistMenuItemLink)}\n \n {sharedPlaylists?.length > 0 && (\n handleToggle('menuSharedPlaylists')}\n isOpen={state.menuSharedPlaylists}\n sidebarIsOpen={sidebarIsOpen}\n name={'menu.sharedPlaylists'}\n icon={}\n dense={dense}\n >\n {sharedPlaylists.map(renderPlaylistMenuItemLink)}\n \n )}\n \n )\n}\n\nexport default PlaylistsSubMenu\n","import React, { useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { Divider, makeStyles } from '@material-ui/core'\nimport clsx from 'clsx'\nimport { useTranslate, MenuItemLink, getResources } from 'react-admin'\nimport { withRouter } from 'react-router-dom'\nimport ViewListIcon from '@material-ui/icons/ViewList'\nimport AlbumIcon from '@material-ui/icons/Album'\nimport SubMenu from './SubMenu'\nimport inflection from 'inflection'\nimport albumLists from '../album/albumLists'\nimport { HelpDialog } from '../dialogs'\nimport PlaylistsSubMenu from './PlaylistsSubMenu'\nimport config from '../config'\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n transition: theme.transitions.create('width', {\n easing: theme.transitions.easing.sharp,\n duration: theme.transitions.duration.leavingScreen,\n }),\n paddingBottom: (props) => (props.addPadding ? '80px' : '20px'),\n },\n open: {\n width: 240,\n },\n closed: {\n width: 55,\n },\n active: {\n color: theme.palette.text.primary,\n fontWeight: 'bold',\n },\n}))\n\nconst translatedResourceName = (resource, translate) =>\n translate(`resources.${resource.name}.name`, {\n smart_count: 2,\n _:\n resource.options && resource.options.label\n ? translate(resource.options.label, {\n smart_count: 2,\n _: resource.options.label,\n })\n : inflection.humanize(inflection.pluralize(resource.name)),\n })\n\nconst Menu = ({ dense = false }) => {\n const open = useSelector((state) => state.admin.ui.sidebarOpen)\n const translate = useTranslate()\n const queue = useSelector((state) => state.player?.queue)\n const classes = useStyles({ addPadding: queue.length > 0 })\n const resources = useSelector(getResources)\n\n // TODO State is not persisted in mobile when you close the sidebar menu. Move to redux?\n const [state, setState] = useState({\n menuAlbumList: true,\n menuPlaylists: true,\n menuSharedPlaylists: true,\n })\n\n const handleToggle = (menu) => {\n setState((state) => ({ ...state, [menu]: !state[menu] }))\n }\n\n const renderResourceMenuItemLink = (resource) => (\n }\n sidebarIsOpen={open}\n dense={dense}\n />\n )\n\n const renderAlbumMenuItemLink = (type, al) => {\n const resource = resources.find((r) => r.name === 'album')\n if (!resource) {\n return null\n }\n\n const albumListAddress = `/album/${type}`\n\n const name = translate(`resources.album.lists.${type || 'default'}`, {\n _: translatedResourceName(resource, translate),\n })\n\n return (\n }\n sidebarIsOpen={open}\n dense={dense}\n exact\n />\n )\n }\n\n const subItems = (subMenu) => (resource) =>\n resource.hasList && resource.options && resource.options.subMenu === subMenu\n\n return (\n \n handleToggle('menuAlbumList')}\n isOpen={state.menuAlbumList}\n sidebarIsOpen={open}\n name=\"menu.albumList\"\n icon={}\n dense={dense}\n >\n {Object.keys(albumLists).map((type) =>\n renderAlbumMenuItemLink(type, albumLists[type])\n )}\n \n {resources.filter(subItems(undefined)).map(renderResourceMenuItemLink)}\n {config.devSidebarPlaylists && open ? (\n <>\n \n \n \n ) : (\n resources.filter(subItems('playlist')).map(renderResourceMenuItemLink)\n )}\n \n \n )\n}\n\nexport default withRouter(Menu)\n","import React, { forwardRef } from 'react'\nimport { MenuItemLink, useTranslate } from 'react-admin'\nimport { makeStyles } from '@material-ui/core'\nimport TuneIcon from '@material-ui/icons/Tune'\n\nconst useStyles = makeStyles((theme) => ({\n menuItem: {\n color: theme.palette.text.secondary,\n },\n}))\n\nconst PersonalMenu = forwardRef(({ onClick, sidebarIsOpen, dense }, ref) => {\n const translate = useTranslate()\n const classes = useStyles()\n return (\n }\n onClick={onClick}\n className={classes.menuItem}\n sidebarIsOpen={sidebarIsOpen}\n dense={dense}\n />\n )\n})\n\nexport default PersonalMenu\n","import React, { useState, useEffect } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useNotify, useTranslate } from 'react-admin'\nimport {\n Popover,\n Badge,\n CircularProgress,\n IconButton,\n makeStyles,\n Tooltip,\n Card,\n CardContent,\n CardActions,\n Divider,\n Box,\n} from '@material-ui/core'\nimport { FiActivity } from 'react-icons/fi'\nimport { BiError } from 'react-icons/bi'\nimport { VscSync } from 'react-icons/vsc'\nimport { GiMagnifyingGlass } from 'react-icons/gi'\nimport subsonic from '../subsonic'\nimport { scanStatusUpdate } from '../actions'\nimport { useInterval } from '../common'\nimport { formatDuration } from '../utils'\nimport config from '../config'\n\nconst useStyles = makeStyles((theme) => ({\n wrapper: {\n position: 'relative',\n color: (props) => (props.up ? null : 'orange'),\n },\n progress: {\n color: theme.palette.primary.light,\n position: 'absolute',\n top: 10,\n left: 10,\n zIndex: 1,\n },\n button: {\n color: 'inherit',\n zIndex: 2,\n },\n counterStatus: {\n minWidth: '15em',\n },\n}))\n\nconst getUptime = (serverStart) =>\n formatDuration((Date.now() - serverStart.startTime) / 1000)\n\nconst Uptime = () => {\n const serverStart = useSelector((state) => state.activity.serverStart)\n const [uptime, setUptime] = useState(getUptime(serverStart))\n useInterval(() => {\n setUptime(getUptime(serverStart))\n }, 1000)\n return {uptime}\n}\n\nconst ActivityPanel = () => {\n const serverStart = useSelector((state) => state.activity.serverStart)\n const up = serverStart.startTime\n const classes = useStyles({ up })\n const translate = useTranslate()\n const notify = useNotify()\n const [anchorEl, setAnchorEl] = useState(null)\n const open = Boolean(anchorEl)\n const dispatch = useDispatch()\n const scanStatus = useSelector((state) => state.activity.scanStatus)\n\n const handleMenuOpen = (event) => setAnchorEl(event.currentTarget)\n const handleMenuClose = () => setAnchorEl(null)\n const triggerScan = (full) => () => subsonic.startScan({ fullScan: full })\n\n // Get updated status on component mount\n useEffect(() => {\n subsonic\n .getScanStatus()\n .then((resp) => resp.json['subsonic-response'])\n .then((data) => {\n if (data.status === 'ok') {\n dispatch(scanStatusUpdate(data.scanStatus))\n }\n })\n }, [dispatch])\n\n useEffect(() => {\n if (serverStart.version && serverStart.version !== config.version) {\n notify('ra.notification.new_version', 'info', {}, false, 604800000 * 50)\n }\n }, [serverStart, notify])\n\n return (\n
\n \n \n \n {up ? : }\n \n \n \n {scanStatus.scanning && (\n \n )}\n \n \n \n \n \n {translate('activity.serverUptime')}:\n \n \n {up ? : translate('activity.serverDown')}\n \n \n \n \n \n \n \n {translate('activity.totalScanned')}:\n \n \n {scanStatus.folderCount || '-'}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n )\n}\n\nexport default ActivityPanel\n","import * as React from 'react'\nimport { Children, cloneElement, isValidElement, useState } from 'react'\nimport PropTypes from 'prop-types'\nimport { useTranslate, useGetIdentity } from 'react-admin'\nimport {\n Tooltip,\n IconButton,\n Popover,\n MenuList,\n Avatar,\n Card,\n CardContent,\n Divider,\n Typography,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport AccountCircle from '@material-ui/icons/AccountCircle'\nimport config from '../config'\n\nconst useStyles = makeStyles((theme) => ({\n user: {},\n avatar: {\n width: theme.spacing(4),\n height: theme.spacing(4),\n },\n username: {\n maxWidth: '11em',\n marginTop: '-0.7em',\n marginBottom: '-1em',\n },\n usernameWrap: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n}))\n\nconst UserMenu = (props) => {\n const [anchorEl, setAnchorEl] = useState(null)\n const translate = useTranslate()\n const { loaded, identity } = useGetIdentity()\n const classes = useStyles(props)\n\n const { children, label, icon, logout } = props\n if (!logout && !children) return null\n const open = Boolean(anchorEl)\n\n const handleMenu = (event) => setAnchorEl(event.currentTarget)\n const handleClose = () => setAnchorEl(null)\n\n return (\n
\n \n \n {loaded && identity.avatar ? (\n \n ) : (\n icon\n )}\n \n \n \n \n {loaded && (\n \n \n {identity.fullName}\n \n \n )}\n \n {Children.map(children, (menuItem) =>\n isValidElement(menuItem)\n ? cloneElement(menuItem, {\n onClick: handleClose,\n })\n : null\n )}\n {!config.auth && logout}\n \n \n
\n )\n}\n\nUserMenu.propTypes = {\n children: PropTypes.node,\n label: PropTypes.string.isRequired,\n logout: PropTypes.element,\n}\n\nUserMenu.defaultProps = {\n label: 'menu.settings',\n icon: ,\n}\n\nexport default UserMenu\n","import React, { createElement, forwardRef, Fragment } from 'react'\nimport {\n AppBar as RAAppBar,\n MenuItemLink,\n useTranslate,\n usePermissions,\n getResources,\n} from 'react-admin'\nimport { useSelector } from 'react-redux'\nimport { makeStyles, MenuItem, ListItemIcon, Divider } from '@material-ui/core'\nimport ViewListIcon from '@material-ui/icons/ViewList'\nimport InfoIcon from '@material-ui/icons/Info'\nimport PersonIcon from '@material-ui/icons/Person'\nimport SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount'\nimport { AboutDialog } from '../dialogs'\nimport PersonalMenu from './PersonalMenu'\nimport ActivityPanel from './ActivityPanel'\nimport UserMenu from './UserMenu'\nimport config from '../config'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n color: theme.palette.text.secondary,\n },\n active: {\n color: theme.palette.text.primary,\n },\n icon: { minWidth: theme.spacing(5) },\n }),\n {\n name: 'NDAppBar',\n }\n)\n\nconst AboutMenuItem = forwardRef(({ onClick, ...rest }, ref) => {\n const classes = useStyles(rest)\n const translate = useTranslate()\n const [open, setOpen] = React.useState(false)\n\n const handleOpen = () => {\n setOpen(true)\n }\n const handleClose = () => {\n onClick && onClick()\n setOpen(false)\n }\n const label = translate('menu.about')\n return (\n <>\n \n \n \n \n {label}\n \n \n \n )\n})\n\nconst settingsResources = (resource) =>\n resource.name !== 'user' &&\n resource.hasList &&\n resource.options &&\n resource.options.subMenu === 'settings'\n\nconst CustomUserMenu = ({ onClick, ...rest }) => {\n const translate = useTranslate()\n const resources = useSelector(getResources)\n const classes = useStyles(rest)\n const { permissions } = usePermissions()\n\n const resourceDefinition = (resourceName) =>\n resources.find((r) => r?.name === resourceName)\n\n const renderUserMenuItemLink = () => {\n const userResource = resourceDefinition('user')\n if (!userResource) {\n return null\n }\n if (permissions !== 'admin') {\n if (!config.enableUserEditing) {\n return null\n }\n userResource.icon = PersonIcon\n } else {\n userResource.icon = SupervisorAccountIcon\n }\n return renderSettingsMenuItemLink(\n userResource,\n permissions !== 'admin' ? localStorage.getItem('userId') : null\n )\n }\n\n const renderSettingsMenuItemLink = (resource, id) => {\n const label = translate(`resources.${resource.name}.name`, {\n smart_count: id ? 1 : 2,\n })\n const link = id ? `/${resource.name}/${id}` : `/${resource.name}`\n return (\n \n }\n onClick={onClick}\n sidebarIsOpen={true}\n />\n )\n }\n\n return (\n <>\n {config.devActivityPanel && permissions === 'admin' && }\n \n \n \n {renderUserMenuItemLink()}\n {resources\n .filter(settingsResources)\n .map((r) => renderSettingsMenuItemLink(r))}\n \n \n \n \n )\n}\n\nconst AppBar = (props) => (\n } />\n)\n\nexport default AppBar\n","import React, { useCallback } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { Layout as RALayout, toggleSidebar } from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { HotKeys } from 'react-hotkeys'\nimport { HTML5Backend } from 'react-dnd-html5-backend'\nimport { DndProvider } from 'react-dnd'\nimport Menu from './Menu'\nimport AppBar from './AppBar'\nimport Notification from './Notification'\nimport useCurrentTheme from '../themes/useCurrentTheme'\n\nconst useStyles = makeStyles({\n root: { paddingBottom: (props) => (props.addPadding ? '80px' : 0) },\n})\n\nconst Layout = (props) => {\n const theme = useCurrentTheme()\n const queue = useSelector((state) => state.player?.queue)\n const classes = useStyles({ addPadding: queue.length > 0 })\n const dispatch = useDispatch()\n\n const keyHandlers = {\n TOGGLE_MENU: useCallback(() => dispatch(toggleSidebar()), [dispatch]),\n }\n\n return (\n \n \n \n \n \n )\n}\n\nexport default Layout\n","import React from 'react'\nimport { Datagrid, TextField } from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { SimpleList, List } from '../common'\nimport config from '../config'\n\nconst TranscodingList = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n return (\n \n {isXsmall ? (\n r.name}\n secondaryText={(r) => `format: ${r.targetFormat}`}\n tertiaryText={(r) => r.defaultBitRate}\n />\n ) : (\n \n \n \n \n \n \n )}\n \n )\n}\n\nexport default TranscodingList\n","import React from 'react'\nimport { Card, CardContent, Typography, Box } from '@material-ui/core'\nimport { useTranslate } from 'react-admin'\n\nexport const Interpolate = ({ message, field, children }) => {\n const split = message.split(`%{${field}}`)\n return (\n \n {split[0]}\n {children}\n {split[1]}\n \n )\n}\nexport const TranscodingNote = ({ message }) => {\n const translate = useTranslate()\n return (\n \n \n \n \n {translate('message.note')}:\n {' '}\n \n \n ND_ENABLETRANSCODINGCONFIG=true\n \n \n \n \n \n )\n}\n","import React from 'react'\nimport {\n Edit,\n required,\n SelectInput,\n SimpleForm,\n TextInput,\n useTranslate,\n} from 'react-admin'\nimport { Title } from '../common'\nimport { TranscodingNote } from './TranscodingNote'\n\nconst TranscodingTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.transcoding.name', {\n smart_count: 1,\n })\n return \n}\n\nconst TranscodingEdit = (props) => {\n return (\n <>\n <TranscodingNote message={'message.transcodingEnabled'} />\n\n <Edit title={<TranscodingTitle />} {...props}>\n <SimpleForm variant={'outlined'}>\n <TextInput source=\"name\" validate={[required()]} />\n <TextInput source=\"targetFormat\" validate={[required()]} />\n <SelectInput\n source=\"defaultBitRate\"\n choices={[\n { id: 32, name: '32' },\n { id: 48, name: '48' },\n { id: 64, name: '64' },\n { id: 80, name: '80' },\n { id: 96, name: '96' },\n { id: 112, name: '112' },\n { id: 128, name: '128' },\n { id: 160, name: '160' },\n { id: 192, name: '192' },\n { id: 256, name: '256' },\n { id: 320, name: '320' },\n ]}\n />\n <TextInput source=\"command\" fullWidth validate={[required()]} />\n </SimpleForm>\n </Edit>\n </>\n )\n}\n\nexport default TranscodingEdit\n","import React from 'react'\nimport {\n TextInput,\n SelectInput,\n Create,\n required,\n SimpleForm,\n useTranslate,\n} from 'react-admin'\nimport { Title } from '../common'\n\nconst TranscodingTitle = () => {\n const translate = useTranslate()\n const resourceName = translate('resources.transcoding.name', {\n smart_count: 1,\n })\n const title = translate('ra.page.create', {\n name: `${resourceName}`,\n })\n return <Title subTitle={title} />\n}\n\nconst TranscodingCreate = (props) => (\n <Create title={<TranscodingTitle />} {...props}>\n <SimpleForm variant={'outlined'}>\n <TextInput source=\"name\" validate={[required()]} />\n <TextInput source=\"targetFormat\" validate={[required()]} />\n <SelectInput\n source=\"defaultBitRate\"\n choices={[\n { id: 32, name: '32' },\n { id: 48, name: '48' },\n { id: 64, name: '64' },\n { id: 80, name: '80' },\n { id: 96, name: '96' },\n { id: 112, name: '112' },\n { id: 128, name: '128' },\n { id: 160, name: '160' },\n { id: 192, name: '192' },\n { id: 256, name: '256' },\n { id: 320, name: '320' },\n ]}\n defaultValue={192}\n />\n <TextInput\n source=\"command\"\n fullWidth\n validate={[required()]}\n helperText={\n <span>\n Substitutions: <br />\n %s: File path <br />\n %b: BitRate (in kbps)\n <br />\n </span>\n }\n />\n </SimpleForm>\n </Create>\n)\n\nexport default TranscodingCreate\n","import React from 'react'\nimport { Show, SimpleShowLayout, TextField } from 'react-admin'\nimport { Title } from '../common'\nimport { TranscodingNote } from './TranscodingNote'\n\nconst TranscodingTitle = ({ record }) => {\n return <Title subTitle={`Transcoding ${record ? record.name : ''}`} />\n}\n\nconst TranscodingShow = (props) => {\n return (\n <>\n <TranscodingNote message={'message.transcodingDisabled'} />\n\n <Show title={<TranscodingTitle />} {...props}>\n <SimpleShowLayout>\n <TextField source=\"name\" />\n <TextField source=\"targetFormat\" />\n <TextField source=\"defaultBitRate\" />\n <TextField source=\"command\" />\n </SimpleShowLayout>\n </Show>\n </>\n )\n}\n\nexport default TranscodingShow\n","import TransformIcon from '@material-ui/icons/Transform'\nimport TranscodingList from './TranscodingList'\nimport TranscodingEdit from './TranscodingEdit'\nimport TranscodingCreate from './TranscodingCreate'\nimport TranscodingShow from './TranscodingShow'\nimport config from '../config'\n\nexport default {\n list: TranscodingList,\n edit: config.enableTranscodingConfig && TranscodingEdit,\n create: config.enableTranscodingConfig && TranscodingCreate,\n show: !config.enableTranscodingConfig && TranscodingShow,\n icon: TransformIcon,\n}\n","import React from 'react'\nimport {\n Datagrid,\n TextField,\n DateField,\n FunctionField,\n ReferenceField,\n Filter,\n SearchInput,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { SimpleList, List } from '../common'\n\nconst PlayerFilter = (props) => (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n </Filter>\n)\n\nconst PlayerList = ({ permissions, ...props }) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n return (\n <List\n {...props}\n sort={{ field: 'lastSeen', order: 'DESC' }}\n exporter={false}\n filters={<PlayerFilter />}\n >\n {isXsmall ? (\n <SimpleList\n primaryText={(r) => r.client}\n secondaryText={(r) => r.userName}\n tertiaryText={(r) => (r.maxBitRate ? r.maxBitRate : '-')}\n />\n ) : (\n <Datagrid rowClick=\"edit\">\n <TextField source=\"name\" />\n {permissions === 'admin' && <TextField source=\"userName\" />}\n <ReferenceField source=\"transcodingId\" reference=\"transcoding\">\n <TextField source=\"name\" />\n </ReferenceField>\n <FunctionField\n source=\"maxBitRate\"\n render={(r) => (r.maxBitRate ? r.maxBitRate : '-')}\n />\n <DateField source=\"lastSeen\" showTime sortByOrder={'DESC'} />\n </Datagrid>\n )}\n </List>\n )\n}\n\nexport default PlayerList\n","import React from 'react'\nimport {\n TextInput,\n BooleanInput,\n TextField,\n Edit,\n required,\n SimpleForm,\n SelectInput,\n ReferenceInput,\n useTranslate,\n} from 'react-admin'\nimport { Title } from '../common'\nimport config from '../config'\n\nconst PlayerTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.player.name', { smart_count: 1 })\n return <Title subTitle={`${resourceName} ${record ? record.name : ''}`} />\n}\n\nconst PlayerEdit = (props) => (\n <Edit title={<PlayerTitle />} {...props}>\n <SimpleForm variant={'outlined'}>\n <TextInput source=\"name\" validate={[required()]} />\n <ReferenceInput\n source=\"transcodingId\"\n reference=\"transcoding\"\n sort={{ field: 'name', order: 'ASC' }}\n >\n <SelectInput source=\"name\" resettable />\n </ReferenceInput>\n <SelectInput\n source=\"maxBitRate\"\n choices={[\n { id: 32, name: '32' },\n { id: 48, name: '48' },\n { id: 64, name: '64' },\n { id: 80, name: '80' },\n { id: 96, name: '96' },\n { id: 112, name: '112' },\n { id: 128, name: '128' },\n { id: 160, name: '160' },\n { id: 192, name: '192' },\n { id: 256, name: '256' },\n { id: 320, name: '320' },\n { id: 0, name: '-' },\n ]}\n />\n <BooleanInput source=\"reportRealPath\" fullWidth />\n {(config.lastFMEnabled || config.listenBrainzEnabled) && (\n <BooleanInput source=\"scrobbleEnabled\" fullWidth />\n )}\n <TextField source=\"client\" />\n <TextField source=\"userName\" />\n </SimpleForm>\n </Edit>\n)\n\nexport default PlayerEdit\n","import RadioIcon from '@material-ui/icons/Radio'\nimport PlayerList from './PlayerList'\nimport PlayerEdit from './PlayerEdit'\n\nexport default {\n list: PlayerList,\n edit: PlayerEdit,\n icon: RadioIcon,\n}\n","import React from 'react'\nimport {\n BooleanField,\n Datagrid,\n Filter,\n SearchInput,\n SimpleList,\n TextField,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { List, DateField } from '../common'\n\nconst UserFilter = (props) => (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n </Filter>\n)\n\nconst UserList = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n\n return (\n <List\n {...props}\n sort={{ field: 'userName', order: 'ASC' }}\n exporter={false}\n bulkActionButtons={false}\n filters={<UserFilter />}\n >\n {isXsmall ? (\n <SimpleList\n primaryText={(record) => record.userName}\n secondaryText={(record) =>\n record.lastLoginAt && new Date(record.lastLoginAt).toLocaleString()\n }\n tertiaryText={(record) => (record.isAdmin ? '[admin]️' : '')}\n />\n ) : (\n <Datagrid rowClick=\"edit\">\n <TextField source=\"userName\" />\n <TextField source=\"name\" />\n <BooleanField source=\"isAdmin\" />\n <DateField source=\"lastLoginAt\" sortByOrder={'DESC'} />\n <DateField source=\"updatedAt\" sortByOrder={'DESC'} />\n </Datagrid>\n )}\n </List>\n )\n}\n\nexport default UserList\n","import React from 'react'\nimport DeleteIcon from '@material-ui/icons/Delete'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { fade } from '@material-ui/core/styles/colorManipulator'\nimport clsx from 'clsx'\nimport {\n useDeleteWithConfirmController,\n Button,\n Confirm,\n useNotify,\n useRedirect,\n} from 'react-admin'\n\nconst useStyles = makeStyles(\n (theme) => ({\n deleteButton: {\n color: theme.palette.error.main,\n '&:hover': {\n backgroundColor: fade(theme.palette.error.main, 0.12),\n // Reset on mouse devices\n '@media (hover: none)': {\n backgroundColor: 'transparent',\n },\n },\n },\n }),\n { name: 'RaDeleteWithConfirmButton' }\n)\n\nconst DeleteUserButton = (props) => {\n const { resource, record, basePath, className, onClick, ...rest } = props\n\n const notify = useNotify()\n const redirect = useRedirect()\n\n const onSuccess = () => {\n notify('resources.user.notifications.deleted')\n redirect('/user')\n }\n\n const { open, loading, handleDialogOpen, handleDialogClose, handleDelete } =\n useDeleteWithConfirmController({\n resource,\n record,\n basePath,\n onClick,\n onSuccess,\n })\n\n const classes = useStyles(props)\n return (\n <>\n <Button\n onClick={handleDialogOpen}\n label=\"ra.action.delete\"\n className={clsx('ra-delete-button', classes.deleteButton, className)}\n key=\"button\"\n {...rest}\n >\n <DeleteIcon />\n </Button>\n <Confirm\n isOpen={open}\n loading={loading}\n title=\"message.delete_user_title\"\n content=\"message.delete_user_content\"\n translateOptions={{\n name: record.name,\n }}\n onConfirm={handleDelete}\n onClose={handleDialogClose}\n />\n </>\n )\n}\n\nexport default DeleteUserButton\n","import React, { useCallback } from 'react'\nimport { makeStyles } from '@material-ui/core/styles'\nimport {\n TextInput,\n BooleanInput,\n DateField,\n PasswordInput,\n Edit,\n required,\n email,\n SimpleForm,\n useTranslate,\n Toolbar,\n SaveButton,\n useMutation,\n useNotify,\n useRedirect,\n useRefresh,\n FormDataConsumer,\n usePermissions,\n} from 'react-admin'\nimport { Title } from '../common'\nimport DeleteUserButton from './DeleteUserButton'\n\nconst useStyles = makeStyles({\n toolbar: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n})\n\nconst UserTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.user.name', { smart_count: 1 })\n return <Title subTitle={`${resourceName} ${record ? record.name : ''}`} />\n}\n\nconst UserToolbar = ({ showDelete, ...props }) => (\n <Toolbar {...props} classes={useStyles()}>\n <SaveButton disabled={props.pristine} />\n {showDelete && <DeleteUserButton />}\n </Toolbar>\n)\n\nconst CurrentPasswordInput = ({ formData, isMyself, ...rest }) => {\n const { permissions } = usePermissions()\n return formData.changePassword && (isMyself || permissions !== 'admin') ? (\n <PasswordInput className=\"ra-input\" source=\"currentPassword\" {...rest} />\n ) : null\n}\n\nconst NewPasswordInput = ({ formData, ...rest }) => {\n const translate = useTranslate()\n return formData.changePassword ? (\n <PasswordInput\n source=\"password\"\n className=\"ra-input\"\n label={translate('resources.user.fields.newPassword')}\n {...rest}\n />\n ) : null\n}\n\nconst UserEdit = (props) => {\n const { permissions } = props\n const translate = useTranslate()\n const [mutate] = useMutation()\n const notify = useNotify()\n const redirect = useRedirect()\n const refresh = useRefresh()\n\n const isMyself = props.id === localStorage.getItem('userId')\n const getNameHelperText = () =>\n isMyself && {\n helperText: translate('resources.user.helperTexts.name'),\n }\n const canDelete = permissions === 'admin' && !isMyself\n\n const save = useCallback(\n async (values) => {\n try {\n await mutate(\n {\n type: 'update',\n resource: 'user',\n payload: { id: values.id, data: values },\n },\n { returnPromise: true }\n )\n notify('resources.user.notifications.updated', 'info', {\n smart_count: 1,\n })\n permissions === 'admin' ? redirect('/user') : refresh()\n } catch (error) {\n if (error.body.errors) {\n return error.body.errors\n }\n }\n },\n [mutate, notify, permissions, redirect, refresh]\n )\n\n return (\n <Edit title={<UserTitle />} undoable={false} {...props}>\n <SimpleForm\n variant={'outlined'}\n toolbar={<UserToolbar showDelete={canDelete} />}\n save={save}\n >\n {permissions === 'admin' && (\n <TextInput source=\"userName\" validate={[required()]} />\n )}\n <TextInput\n source=\"name\"\n validate={[required()]}\n {...getNameHelperText()}\n />\n <TextInput source=\"email\" validate={[email()]} />\n <BooleanInput source=\"changePassword\" />\n <FormDataConsumer>\n {(formDataProps) => (\n <CurrentPasswordInput isMyself={isMyself} {...formDataProps} />\n )}\n </FormDataConsumer>\n <FormDataConsumer>\n {(formDataProps) => <NewPasswordInput {...formDataProps} />}\n </FormDataConsumer>\n\n {permissions === 'admin' && (\n <BooleanInput source=\"isAdmin\" initialValue={false} />\n )}\n <DateField variant=\"body1\" source=\"lastLoginAt\" showTime />\n {/*<DateField source=\"lastAccessAt\" showTime />*/}\n <DateField variant=\"body1\" source=\"updatedAt\" showTime />\n <DateField variant=\"body1\" source=\"createdAt\" showTime />\n </SimpleForm>\n </Edit>\n )\n}\n\nexport default UserEdit\n","import UserList from './UserList'\nimport UserEdit from './UserEdit'\nimport UserCreate from './UserCreate'\n\nexport default {\n list: UserList,\n edit: UserEdit,\n create: UserCreate,\n}\n","import React, { useCallback } from 'react'\nimport {\n BooleanInput,\n Create,\n TextInput,\n PasswordInput,\n required,\n email,\n SimpleForm,\n useTranslate,\n useMutation,\n useNotify,\n useRedirect,\n} from 'react-admin'\nimport { Title } from '../common'\n\nconst UserCreate = (props) => {\n const translate = useTranslate()\n const [mutate] = useMutation()\n const notify = useNotify()\n const redirect = useRedirect()\n const resourceName = translate('resources.user.name', { smart_count: 1 })\n const title = translate('ra.page.create', {\n name: `${resourceName}`,\n })\n\n const save = useCallback(\n async (values) => {\n try {\n await mutate(\n {\n type: 'create',\n resource: 'user',\n payload: { data: values },\n },\n { returnPromise: true }\n )\n notify('resources.user.notifications.created', 'info', {\n smart_count: 1,\n })\n redirect('/user')\n } catch (error) {\n if (error.body.errors) {\n return error.body.errors\n }\n }\n },\n [mutate, notify, redirect]\n )\n\n return (\n <Create title={<Title subTitle={title} />} {...props}>\n <SimpleForm save={save} variant={'outlined'}>\n <TextInput source=\"userName\" validate={[required()]} />\n <TextInput source=\"name\" validate={[required()]} />\n <TextInput source=\"email\" validate={[email()]} />\n <PasswordInput source=\"password\" validate={[required()]} />\n <BooleanInput source=\"isAdmin\" defaultValue={false} />\n </SimpleForm>\n </Create>\n )\n}\n\nexport default UserCreate\n","import React, { cloneElement } from 'react'\nimport { sanitizeListRestProps, TopToolbar } from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ShuffleAllButton, ToggleFieldsMenu } from '../common'\n\nexport const SongListActions = ({\n currentSort,\n className,\n resource,\n filters,\n displayedFilters,\n filterValues,\n permanentFilter,\n exporter,\n basePath,\n selectedIds,\n onUnselectItems,\n showFilter,\n maxResults,\n total,\n ids,\n ...rest\n}) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {filters &&\n cloneElement(filters, {\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n context: 'button',\n })}\n <ShuffleAllButton filters={filterValues} />\n {isNotSmall && <ToggleFieldsMenu resource=\"song\" />}\n </TopToolbar>\n )\n}\n\nSongListActions.defaultProps = {\n selectedIds: [],\n onUnselectItems: () => null,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { Link } from 'react-admin'\n\nexport const AlbumLinkField = (props) => (\n <Link\n to={`/album/${props.record.albumId}/show`}\n onClick={(e) => e.stopPropagation()}\n >\n {props.record.album}\n </Link>\n)\n\nAlbumLinkField.propTypes = {\n sortBy: PropTypes.string,\n sortByOrder: PropTypes.oneOf(['ASC', 'DESC']),\n}\n\nAlbumLinkField.defaultProps = {\n addLabel: true,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { RecordContextProvider, useTranslate } from 'react-admin'\nimport {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@material-ui/core'\nimport { closeExtendedInfoDialog } from '../actions'\n\nconst ExpandInfoDialog = ({ title, content }) => {\n const { open, record } = useSelector((state) => state.expandInfoDialog)\n const dispatch = useDispatch()\n const translate = useTranslate()\n\n const handleClose = (e) => {\n dispatch(closeExtendedInfoDialog())\n e.stopPropagation()\n }\n\n return (\n <Dialog\n open={open}\n onClose={handleClose}\n onBackdropClick={handleClose}\n aria-labelledby=\"info-dialog-album\"\n fullWidth={true}\n maxWidth={'sm'}\n >\n <DialogTitle id=\"info-dialog-album\">\n {translate(title || 'resources.song.actions.info')}\n </DialogTitle>\n <DialogContent>\n {record && (\n <RecordContextProvider value={record}>\n {content}\n </RecordContextProvider>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={handleClose} color=\"primary\">\n {translate('ra.action.close')}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nExpandInfoDialog.propTypes = {\n title: PropTypes.string,\n content: PropTypes.object.isRequired,\n}\n\nexport default ExpandInfoDialog\n","import React from 'react'\nimport {\n AutocompleteInput,\n Filter,\n FunctionField,\n NumberField,\n ReferenceInput,\n SearchInput,\n TextField,\n useTranslate,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport {\n DateField,\n DurationField,\n List,\n SongContextMenu,\n SongDatagrid,\n SongInfo,\n QuickFilter,\n SongTitleField,\n SongSimpleList,\n RatingField,\n useResourceRefresh,\n ArtistLinkField,\n} from '../common'\nimport { useDispatch } from 'react-redux'\nimport { makeStyles } from '@material-ui/core/styles'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { setTrack } from '../actions'\nimport { SongListActions } from './SongListActions'\nimport { AlbumLinkField } from './AlbumLinkField'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport { SongBulkActions, QualityInfo, useSelectedFields } from '../common'\nimport config from '../config'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst useStyles = makeStyles({\n contextHeader: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: 'hidden',\n },\n ratingField: {\n visibility: 'hidden',\n },\n})\n\nconst SongFilter = (props) => {\n const translate = useTranslate()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"title\" alwaysOn />\n <ReferenceInput\n label={translate('resources.song.fields.genre')}\n source=\"genre_id\"\n reference=\"genre\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n {config.enableFavourites && (\n <QuickFilter\n source=\"starred\"\n label={<FavoriteIcon fontSize={'small'} />}\n defaultValue={true}\n />\n )}\n </Filter>\n )\n}\n\nconst SongList = (props) => {\n const classes = useStyles()\n const dispatch = useDispatch()\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n useResourceRefresh('song')\n\n const handleRowClick = (id, basePath, record) => {\n dispatch(setTrack(record))\n }\n\n const toggleableFields = React.useMemo(() => {\n return {\n album: isDesktop && (\n <AlbumLinkField\n source=\"album\"\n sortBy={\n 'album, order_album_artist_name, disc_number, track_number, title'\n }\n sortByOrder={'ASC'}\n />\n ),\n artist: <ArtistLinkField source=\"artist\" />,\n albumArtist: <ArtistLinkField source=\"albumArtist\" />,\n trackNumber: isDesktop && <NumberField source=\"trackNumber\" />,\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortByOrder={'DESC'} />\n ),\n playDate: <DateField source=\"playDate\" sortByOrder={'DESC'} showTime />,\n year: isDesktop && (\n <FunctionField\n source=\"year\"\n render={(r) => r.year || ''}\n sortByOrder={'DESC'}\n />\n ),\n quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n channels: isDesktop && (\n <NumberField source=\"channels\" sortByOrder={'ASC'} />\n ),\n duration: <DurationField source=\"duration\" />,\n rating: config.enableStarRating && (\n <RatingField\n source=\"rating\"\n sortByOrder={'DESC'}\n resource={'song'}\n className={classes.ratingField}\n />\n ),\n bpm: isDesktop && <NumberField source=\"bpm\" />,\n genre: <TextField source=\"genre\" />,\n comment: <TextField source=\"comment\" />,\n }\n }, [isDesktop, classes.ratingField])\n\n const columns = useSelectedFields({\n resource: 'song',\n columns: toggleableFields,\n defaultOff: [\n 'channels',\n 'bpm',\n 'playDate',\n 'albumArtist',\n 'genre',\n 'comment',\n ],\n })\n\n return (\n <>\n <List\n {...props}\n sort={{ field: 'title', order: 'ASC' }}\n exporter={false}\n bulkActionButtons={<SongBulkActions />}\n actions={<SongListActions />}\n filters={<SongFilter />}\n perPage={isXsmall ? 50 : 15}\n >\n {isXsmall ? (\n <SongSimpleList />\n ) : (\n <SongDatagrid\n rowClick={handleRowClick}\n contextAlwaysVisible={!isDesktop}\n classes={{ row: classes.row }}\n >\n <SongTitleField source=\"title\" showTrackNumbers={false} />\n {columns}\n <SongContextMenu\n source={'starred'}\n sortBy={'starred ASC, starredAt ASC'}\n sortByOrder={'DESC'}\n sortable={config.enableFavourites}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.contextHeader}\n />\n )\n }\n />\n </SongDatagrid>\n )}\n </List>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<SongInfo />} />\n </>\n )\n}\n\nexport default SongList\n","import React from 'react'\nimport SongList from './SongList'\nimport MusicNoteOutlinedIcon from '@material-ui/icons/MusicNoteOutlined'\nimport MusicNoteIcon from '@material-ui/icons/MusicNote'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\n\nexport default {\n list: SongList,\n icon: (\n <DynamicMenuIcon\n path={'song'}\n icon={MusicNoteOutlinedIcon}\n activeIcon={MusicNoteIcon}\n />\n ),\n}\n","import React, { cloneElement } from 'react'\nimport {\n Button,\n sanitizeListRestProps,\n TopToolbar,\n useTranslate,\n} from 'react-admin'\nimport {\n ButtonGroup,\n useMediaQuery,\n Typography,\n makeStyles,\n} from '@material-ui/core'\nimport ViewHeadlineIcon from '@material-ui/icons/ViewHeadline'\nimport ViewModuleIcon from '@material-ui/icons/ViewModule'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { albumViewGrid, albumViewTable } from '../actions'\nimport { ToggleFieldsMenu } from '../common'\n\nconst useStyles = makeStyles({\n title: { margin: '1rem' },\n buttonGroup: { width: '100%', justifyContent: 'center' },\n leftButton: { paddingRight: '0.5rem' },\n rightButton: { paddingLeft: '0.5rem' },\n})\n\nconst AlbumViewToggler = React.forwardRef(\n ({ showTitle = true, disableElevation, fullWidth }, ref) => {\n const dispatch = useDispatch()\n const albumView = useSelector((state) => state.albumView)\n const classes = useStyles()\n const translate = useTranslate()\n return (\n <div ref={ref}>\n {showTitle && (\n <Typography className={classes.title}>\n {translate('ra.toggleFieldsMenu.layout')}\n </Typography>\n )}\n <ButtonGroup\n variant=\"text\"\n color=\"primary\"\n aria-label=\"text primary button group\"\n className={classes.buttonGroup}\n >\n <Button\n size=\"small\"\n className={classes.leftButton}\n label={translate('ra.toggleFieldsMenu.grid')}\n color={albumView.grid ? 'primary' : 'secondary'}\n onClick={() => dispatch(albumViewGrid())}\n >\n <ViewModuleIcon fontSize=\"inherit\" />\n </Button>\n <Button\n size=\"small\"\n className={classes.rightButton}\n label={translate('ra.toggleFieldsMenu.table')}\n color={albumView.grid ? 'secondary' : 'primary'}\n onClick={() => dispatch(albumViewTable())}\n >\n <ViewHeadlineIcon fontSize=\"inherit\" />\n </Button>\n </ButtonGroup>\n </div>\n )\n }\n)\n\nconst AlbumListActions = ({\n currentSort,\n className,\n resource,\n filters,\n displayedFilters,\n filterValues,\n permanentFilter,\n exporter,\n basePath,\n selectedIds,\n onUnselectItems,\n showFilter,\n maxResults,\n total,\n fullWidth,\n ...rest\n}) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {filters &&\n cloneElement(filters, {\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n context: 'button',\n })}\n {isNotSmall ? (\n <ToggleFieldsMenu resource=\"album\" topbarComponent={AlbumViewToggler} />\n ) : (\n <AlbumViewToggler showTitle={false} />\n )}\n </TopToolbar>\n )\n}\n\nAlbumListActions.defaultProps = {\n selectedIds: [],\n onUnselectItems: () => null,\n}\n\nexport default AlbumListActions\n","import React, { useMemo } from 'react'\nimport {\n Datagrid,\n DatagridBody,\n DatagridRow,\n NumberField,\n TextField,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useDrag } from 'react-dnd'\nimport {\n ArtistLinkField,\n DurationField,\n RangeField,\n SimpleList,\n AlbumContextMenu,\n RatingField,\n useSelectedFields,\n} from '../common'\nimport config from '../config'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles({\n columnIcon: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n tableCell: {\n width: '17.5%',\n },\n contextMenu: {\n visibility: 'hidden',\n },\n ratingField: {\n visibility: 'hidden',\n },\n})\n\nconst AlbumDatagridRow = (props) => {\n const { record } = props\n const [, dragAlbumRef] = useDrag(\n () => ({\n type: DraggableTypes.ALBUM,\n item: { albumIds: [record.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n return <DatagridRow ref={dragAlbumRef} {...props} />\n}\n\nconst AlbumDatagridBody = (props) => (\n <DatagridBody {...props} row={<AlbumDatagridRow />} />\n)\n\nconst AlbumDatagrid = (props) => (\n <Datagrid {...props} body={<AlbumDatagridBody />} />\n)\n\nconst AlbumTableView = ({\n hasShow,\n hasEdit,\n hasList,\n syncWithLocation,\n ...rest\n}) => {\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n\n const toggleableFields = useMemo(() => {\n return {\n artist: <ArtistLinkField source=\"artist\" />,\n songCount: isDesktop && (\n <NumberField source=\"songCount\" sortByOrder={'DESC'} />\n ),\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortByOrder={'DESC'} />\n ),\n year: (\n <RangeField source={'year'} sortBy={'max_year'} sortByOrder={'DESC'} />\n ),\n duration: isDesktop && <DurationField source=\"duration\" />,\n rating: config.enableStarRating && (\n <RatingField\n source={'rating'}\n resource={'album'}\n sortByOrder={'DESC'}\n className={classes.ratingField}\n />\n ),\n }\n }, [classes.ratingField, isDesktop])\n\n const columns = useSelectedFields({\n resource: 'album',\n columns: toggleableFields,\n })\n\n return isXsmall ? (\n <SimpleList\n primaryText={(r) => r.name}\n secondaryText={(r) => (\n <>\n {r.albumArtist}\n {config.enableStarRating && (\n <>\n <br />\n <RatingField\n record={r}\n sortByOrder={'DESC'}\n source={'rating'}\n resource={'album'}\n size={'small'}\n />\n </>\n )}\n </>\n )}\n tertiaryText={(r) => (\n <>\n <RangeField record={r} source={'year'} sortBy={'max_year'} />\n      \n </>\n )}\n linkType={'show'}\n rightIcon={(r) => <AlbumContextMenu record={r} />}\n {...rest}\n />\n ) : (\n <AlbumDatagrid rowClick={'show'} classes={{ row: classes.row }} {...rest}>\n <TextField source=\"name\" />\n {columns}\n <AlbumContextMenu\n source={'starred'}\n sortBy={'starred ASC, starredAt ASC'}\n sortByOrder={'DESC'}\n sortable={config.enableFavourites}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.columnIcon}\n />\n )\n }\n />\n </AlbumDatagrid>\n )\n}\n\nexport default AlbumTableView\n","import React from 'react'\nimport {\n GridList,\n GridListTile,\n Typography,\n GridListTileBar,\n useMediaQuery,\n} from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport withWidth from '@material-ui/core/withWidth'\nimport { Link } from 'react-router-dom'\nimport { linkToRecord, useListContext, Loading } from 'react-admin'\nimport { withContentRect } from 'react-measure'\nimport { useDrag } from 'react-dnd'\nimport subsonic from '../subsonic'\nimport {\n AlbumContextMenu,\n PlayButton,\n ArtistLinkField,\n RangeField,\n} from '../common'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n margin: '20px',\n display: 'grid',\n },\n tileBar: {\n transition: 'all 150ms ease-out',\n opacity: 0,\n textAlign: 'left',\n marginBottom: '3px',\n background:\n 'linear-gradient(to top, rgba(0,0,0,0.7) 0%,rgba(0,0,0,0.4) 70%,rgba(0,0,0,0) 100%)',\n },\n tileBarMobile: {\n textAlign: 'left',\n marginBottom: '3px',\n background:\n 'linear-gradient(to top, rgba(0,0,0,0.7) 0%,rgba(0,0,0,0.4) 70%,rgba(0,0,0,0) 100%)',\n },\n albumArtistName: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n textAlign: 'left',\n fontSize: '1em',\n },\n albumName: {\n fontSize: '14px',\n color: theme.palette.type === 'dark' ? '#eee' : 'black',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n },\n albumSubtitle: {\n fontSize: '12px',\n color: theme.palette.type === 'dark' ? '#c5c5c5' : '#696969',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n },\n link: {\n position: 'relative',\n display: 'block',\n textDecoration: 'none',\n '&:hover $tileBar': {\n opacity: 1,\n },\n },\n albumLink: {\n position: 'relative',\n display: 'block',\n textDecoration: 'none',\n },\n albumContainer: {},\n albumPlayButton: { color: 'white' },\n }),\n { name: 'NDAlbumGridView' }\n)\n\nconst useCoverStyles = makeStyles({\n cover: {\n display: 'inline-block',\n width: '100%',\n objectFit: 'contain',\n height: (props) => props.height,\n },\n})\n\nconst getColsForWidth = (width) => {\n if (width === 'xs') return 2\n if (width === 'sm') return 3\n if (width === 'md') return 4\n if (width === 'lg') return 6\n return 9\n}\n\nconst Cover = withContentRect('bounds')(\n ({ record, measureRef, contentRect }) => {\n // Force height to be the same as the width determined by the GridList\n // noinspection JSSuspiciousNameCombination\n const classes = useCoverStyles({ height: contentRect.bounds.width })\n const [, dragAlbumRef] = useDrag(\n () => ({\n type: DraggableTypes.ALBUM,\n item: { albumIds: [record.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n return (\n <div ref={measureRef}>\n <div ref={dragAlbumRef}>\n <img\n src={subsonic.getCoverArtUrl(record, 300)}\n alt={record.name}\n className={classes.cover}\n />\n </div>\n </div>\n )\n }\n)\n\nconst AlbumGridTile = ({ showArtist, record, basePath, ...props }) => {\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'), {\n noSsr: true,\n })\n if (!record) {\n return null\n }\n return (\n <div className={classes.albumContainer}>\n <Link\n className={classes.link}\n to={linkToRecord(basePath, record.id, 'show')}\n >\n <Cover record={record} />\n <GridListTileBar\n className={isDesktop ? classes.tileBar : classes.tileBarMobile}\n subtitle={\n <PlayButton\n className={classes.albumPlayButton}\n record={record}\n size=\"small\"\n />\n }\n actionIcon={<AlbumContextMenu record={record} color={'white'} />}\n />\n </Link>\n <Link\n className={classes.albumLink}\n to={linkToRecord(basePath, record.id, 'show')}\n >\n <Typography className={classes.albumName}>{record.name}</Typography>\n </Link>\n {showArtist ? (\n <ArtistLinkField record={record} className={classes.albumSubtitle} />\n ) : (\n <RangeField\n record={record}\n source={'year'}\n sortBy={'max_year'}\n sortByOrder={'DESC'}\n className={classes.albumSubtitle}\n />\n )}\n </div>\n )\n}\n\nconst LoadedAlbumGrid = ({ ids, data, basePath, width }) => {\n const classes = useStyles()\n const { filterValues } = useListContext()\n const isArtistView = !!(filterValues && filterValues.artist_id)\n return (\n <div className={classes.root}>\n <GridList\n component={'div'}\n cellHeight={'auto'}\n cols={getColsForWidth(width)}\n spacing={20}\n >\n {ids.map((id) => (\n <GridListTile className={classes.gridListTile} key={id}>\n <AlbumGridTile\n record={data[id]}\n basePath={basePath}\n showArtist={!isArtistView}\n />\n </GridListTile>\n ))}\n </GridList>\n </div>\n )\n}\n\nconst AlbumGridView = ({ albumListType, loaded, loading, ...props }) => {\n const hide =\n (loading && albumListType === 'random') || !props.data || !props.ids\n return hide ? <Loading /> : <LoadedAlbumGrid {...props} />\n}\n\nexport default withWidth()(AlbumGridView)\n","import Table from '@material-ui/core/Table'\nimport TableBody from '@material-ui/core/TableBody'\nimport inflection from 'inflection'\nimport TableCell from '@material-ui/core/TableCell'\nimport TableContainer from '@material-ui/core/TableContainer'\nimport TableRow from '@material-ui/core/TableRow'\nimport {\n ArrayField,\n BooleanField,\n ChipField,\n DateField,\n SingleFieldList,\n TextField,\n useRecordContext,\n useTranslate,\n} from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { MultiLineTextField } from '../common'\n\nconst useStyles = makeStyles({\n tableCell: {\n width: '17.5%',\n },\n})\n\nconst AlbumInfo = (props) => {\n const classes = useStyles()\n const translate = useTranslate()\n const record = useRecordContext(props)\n const data = {\n album: <TextField source={'name'} />,\n albumArtist: <TextField source={'albumArtist'} />,\n genre: (\n <ArrayField source={'genres'}>\n <SingleFieldList linkType={false}>\n <ChipField source={'name'} />\n </SingleFieldList>\n </ArrayField>\n ),\n compilation: <BooleanField source={'compilation'} />,\n updatedAt: <DateField source={'updatedAt'} showTime />,\n comment: <MultiLineTextField source={'comment'} />,\n }\n\n const optionalFields = ['comment', 'genre']\n optionalFields.forEach((field) => {\n !record[field] && delete data[field]\n })\n\n return (\n <TableContainer>\n <Table aria-label=\"album details\" size=\"small\">\n <TableBody>\n {Object.keys(data).map((key) => {\n return (\n <TableRow key={`${record.id}-${key}`}>\n <TableCell\n component=\"th\"\n scope=\"row\"\n className={classes.tableCell}\n >\n {translate(`resources.album.fields.${key}`, {\n _: inflection.humanize(inflection.underscore(key)),\n })}\n :\n </TableCell>\n <TableCell align=\"left\">{data[key]}</TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </TableContainer>\n )\n}\n\nexport default AlbumInfo\n","import React from 'react'\nimport { useSelector } from 'react-redux'\nimport { Redirect, useLocation } from 'react-router-dom'\nimport {\n AutocompleteInput,\n Filter,\n NullableBooleanInput,\n NumberInput,\n Pagination,\n ReferenceInput,\n SearchInput,\n useTranslate,\n} from 'react-admin'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport { withWidth } from '@material-ui/core'\nimport {\n List,\n QuickFilter,\n Title,\n useAlbumsPerPage,\n useResourceRefresh,\n useSetToggleableFields,\n} from '../common'\nimport AlbumListActions from './AlbumListActions'\nimport AlbumTableView from './AlbumTableView'\nimport AlbumGridView from './AlbumGridView'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport albumLists, { defaultAlbumList } from './albumLists'\nimport config from '../config'\nimport AlbumInfo from './AlbumInfo'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst AlbumFilter = (props) => {\n const translate = useTranslate()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n <ReferenceInput\n label={translate('resources.album.fields.artist')}\n source=\"artist_id\"\n reference=\"artist\"\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n <ReferenceInput\n label={translate('resources.album.fields.genre')}\n source=\"genre_id\"\n reference=\"genre\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n <NullableBooleanInput source=\"compilation\" />\n <NumberInput source=\"year\" />\n {config.enableFavourites && (\n <QuickFilter\n source=\"starred\"\n label={<FavoriteIcon fontSize={'small'} />}\n defaultValue={true}\n />\n )}\n </Filter>\n )\n}\n\nconst AlbumListTitle = ({ albumListType }) => {\n const translate = useTranslate()\n let title = translate('resources.album.name', { smart_count: 2 })\n if (albumListType) {\n let listTitle = translate(`resources.album.lists.${albumListType}`, {\n smart_count: 2,\n })\n title = `${title} - ${listTitle}`\n }\n return <Title subTitle={title} args={{ smart_count: 2 }} />\n}\n\nconst AlbumList = (props) => {\n const { width } = props\n const albumView = useSelector((state) => state.albumView)\n const [perPage, perPageOptions] = useAlbumsPerPage(width)\n const location = useLocation()\n useResourceRefresh('album')\n\n const albumListType = location.pathname\n .replace(/^\\/album/, '')\n .replace(/^\\//, '')\n\n // Workaround to force album columns to appear the first time.\n // See https://github.com/navidrome/navidrome/pull/923#issuecomment-833004842\n // TODO: Find a better solution\n useSetToggleableFields('album', [\n 'artist',\n 'songCount',\n 'playCount',\n 'year',\n 'duration',\n 'rating',\n ])\n\n // If it does not have filter/sort params (usually coming from Menu),\n // reload with correct filter/sort params\n if (!location.search) {\n const type =\n albumListType || localStorage.getItem('defaultView') || defaultAlbumList\n const listParams = albumLists[type]\n if (listParams) {\n return <Redirect to={`/album/${type}?${listParams.params}`} />\n }\n }\n\n return (\n <>\n <List\n {...props}\n exporter={false}\n bulkActionButtons={false}\n actions={<AlbumListActions />}\n filters={<AlbumFilter />}\n perPage={perPage}\n pagination={<Pagination rowsPerPageOptions={perPageOptions} />}\n title={<AlbumListTitle albumListType={albumListType} />}\n >\n {albumView.grid ? (\n <AlbumGridView albumListType={albumListType} {...props} />\n ) : (\n <AlbumTableView {...props} />\n )}\n </List>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<AlbumInfo />} />\n </>\n )\n}\n\nexport default withWidth()(AlbumList)\n","import React, { useMemo } from 'react'\nimport {\n BulkActionsToolbar,\n ListToolbar,\n TextField,\n NumberField,\n useVersion,\n useListContext,\n FunctionField,\n} from 'react-admin'\nimport clsx from 'clsx'\nimport { useDispatch } from 'react-redux'\nimport { Card, useMediaQuery } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { playTracks } from '../actions'\nimport {\n DurationField,\n SongBulkActions,\n SongContextMenu,\n SongDatagrid,\n SongInfo,\n SongTitleField,\n RatingField,\n QualityInfo,\n useSelectedFields,\n useResourceRefresh,\n DateField,\n} from '../common'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport config from '../config'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {},\n main: {\n display: 'flex',\n },\n content: {\n marginTop: 0,\n transition: theme.transitions.create('margin-top'),\n position: 'relative',\n flex: '1 1 auto',\n [theme.breakpoints.down('xs')]: {\n boxShadow: 'none',\n },\n },\n bulkActionsDisplayed: {\n marginTop: -theme.spacing(8),\n transition: theme.transitions.create('margin-top'),\n },\n actions: {\n zIndex: 2,\n display: 'flex',\n justifyContent: 'flex-end',\n flexWrap: 'wrap',\n },\n noResults: { padding: 20 },\n columnIcon: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n toolbar: {\n justifyContent: 'flex-start',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: (props) => (props.isDesktop ? 'hidden' : 'visible'),\n },\n ratingField: {\n visibility: 'hidden',\n },\n }),\n { name: 'RaList' }\n)\n\nconst AlbumSongs = (props) => {\n const { data, ids } = props\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const dispatch = useDispatch()\n const version = useVersion()\n useResourceRefresh('song', 'album')\n\n const toggleableFields = useMemo(() => {\n return {\n trackNumber: isDesktop && (\n <TextField\n source=\"trackNumber\"\n sortBy=\"discNumber asc, trackNumber asc\"\n label=\"#\"\n sortable={false}\n />\n ),\n title: (\n <SongTitleField\n source=\"title\"\n sortable={false}\n showTrackNumbers={!isDesktop}\n />\n ),\n artist: isDesktop && <TextField source=\"artist\" sortable={false} />,\n duration: <DurationField source=\"duration\" sortable={false} />,\n year: isDesktop && (\n <FunctionField\n source=\"year\"\n render={(r) => r.year || ''}\n sortByOrder={'DESC'}\n />\n ),\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortable={false} />\n ),\n playDate: <DateField source=\"playDate\" sortable={false} showTime />,\n quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n channels: isDesktop && <NumberField source=\"channels\" sortable={false} />,\n bpm: isDesktop && <NumberField source=\"bpm\" sortable={false} />,\n rating: isDesktop && config.enableStarRating && (\n <RatingField\n resource={'song'}\n source=\"rating\"\n sortable={false}\n className={classes.ratingField}\n />\n ),\n }\n }, [isDesktop, classes.ratingField])\n\n const columns = useSelectedFields({\n resource: 'albumSong',\n columns: toggleableFields,\n omittedColumns: ['title'],\n defaultOff: ['channels', 'bpm', 'year', 'playCount', 'playDate'],\n })\n\n return (\n <>\n <ListToolbar\n classes={{ toolbar: classes.toolbar }}\n actions={props.actions}\n {...props}\n />\n <div className={classes.main}>\n <Card\n className={clsx(classes.content, {\n [classes.bulkActionsDisplayed]: props.selectedIds.length > 0,\n })}\n key={version}\n >\n <BulkActionsToolbar {...props}>\n <SongBulkActions />\n </BulkActionsToolbar>\n <SongDatagrid\n rowClick={(id) => dispatch(playTracks(data, ids, id))}\n {...props}\n hasBulkActions={true}\n showDiscSubtitles={true}\n contextAlwaysVisible={!isDesktop}\n classes={{ row: classes.row }}\n >\n {columns}\n <SongContextMenu\n source={'starred'}\n sortable={false}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.columnIcon}\n />\n )\n }\n />\n </SongDatagrid>\n </Card>\n </div>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<SongInfo />} />\n </>\n )\n}\n\nexport const removeAlbumCommentsFromSongs = ({ album, data }) => {\n if (album?.comment && data) {\n Object.values(data).forEach((song) => {\n song.comment = ''\n })\n }\n}\n\nconst SanitizedAlbumSongs = (props) => {\n removeAlbumCommentsFromSongs(props)\n\n const { loaded, loading, total, ...rest } = useListContext(props)\n return <>{loaded && <AlbumSongs {...rest} actions={props.actions} />}</>\n}\n\nexport default SanitizedAlbumSongs\n","import React from 'react'\nimport SvgIcon from '@material-ui/core/SvgIcon'\n\nconst MusicBrainz = (props) => {\n return (\n <SvgIcon xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 26 26\" {...props}>\n <path d=\"M11.582 0L1.418 5.832v12.336L11.582 24V10.01L7.1 12.668v3.664c.01.111.01.225 0 .336-.103.435-.54.804-1 1.111-.802.537-1.752.509-2.166-.111-.413-.62-.141-1.631.666-2.168.384-.28.863-.399 1.334-.332V6.619c0-.154.134-.252.226-.308L11.582 3zm.836 0v6.162c.574.03 1.14.16 1.668.387a2.225 2.225 0 0 0 1.656-.717 1.02 1.02 0 1 1 1.832-.803l.004.006a1.022 1.022 0 0 1-1.295 1.197c-.34.403-.792.698-1.297.85.34.263.641.576.891.928a1.04 1.04 0 0 1 .777.125c.768.486.568 1.657-.318 1.857-.886.2-1.574-.77-1.09-1.539.02-.03.042-.06.065-.09a3.598 3.598 0 0 0-1.436-1.166 4.142 4.142 0 0 0-1.457-.369v4.01c.855.06 1.256.493 1.555.834.227.256.356.39.578.402.323.018.568.008.806 0a5.44 5.44 0 0 1 .895.022c.94-.017 1.272-.226 1.605-.446a2.533 2.533 0 0 1 1.131-.463 1.027 1.027 0 0 1 .12-.263 1.04 1.04 0 0 1 .105-.137c.023-.025.047-.044.07-.066a4.775 4.775 0 0 1 0-2.405l-.012-.01a1.02 1.02 0 1 1 .692.272h-.057a4.288 4.288 0 0 0 0 1.877h.063a1.02 1.02 0 1 1-.545 1.883l-.047-.033a1 1 0 0 1-.352-.442 1.885 1.885 0 0 0-.814.354 3.03 3.03 0 0 1-.703.365c.757.555 1.772 1.6 2.199 2.299a1.03 1.03 0 0 1 .256-.033 1.02 1.02 0 1 1-.545 1.88l-.047-.03a1.017 1.017 0 0 1-.27-1.376.72.72 0 0 1 .051-.072c-.445-.775-2.026-2.28-2.46-2.387a4.037 4.037 0 0 0-1.31-.117c-.24.008-.513.018-.866 0-.515-.027-.783-.333-1.043-.629-.26-.296-.51-.56-1.055-.611V18.5a1.877 1.877 0 0 0 .426-.135.333.333 0 0 1 .058-.027c.56-.267 1.421-.91 2.096-2.447a1.02 1.02 0 0 1-.27-1.344 1.02 1.02 0 1 1 .915 1.54 6.273 6.273 0 0 1-1.432 2.136 1.785 1.785 0 0 1 .691.306.667.667 0 0 0 .37.168 3.31 3.31 0 0 0 .888-.222 1.02 1.02 0 0 1 1.787-.79v-.005a1.02 1.02 0 0 1-.773 1.683 1.022 1.022 0 0 1-.719-.287 3.935 3.935 0 0 1-1.168.287h-.05a1.313 1.313 0 0 1-.71-.275c-.262-.177-.51-.345-1.402-.12a2.098 2.098 0 0 1-.707.2V24l10.164-5.832V5.832zm4.154 4.904a.352.352 0 0 0-.197.639l.018.01c.163.1.378.053.484-.108v-.002a.352.352 0 0 0-.303-.539zm-4.99 1.928L7.082 9.5v2l4.5-2.668zm8.385.38a.352.352 0 0 0-.295.165v.002a.35.35 0 0 0 .096.473l.013.01a.357.357 0 0 0 .487-.108.352.352 0 0 0-.301-.541zM16.09 8.647a.352.352 0 0 0-.277.163.355.355 0 0 0 .296.54c.482 0 .463-.73-.02-.703zm3.877 2.477a.352.352 0 0 0-.295.164.35.35 0 0 0 .094.475l.015.01a.357.357 0 0 0 .485-.11.352.352 0 0 0-.3-.539zm-4.375 3.594a.352.352 0 0 0-.291.172.35.35 0 0 0-.04.265.352.352 0 1 0 .33-.437zm4.375.789a.352.352 0 0 0-.295.164v.002a.352.352 0 0 0 .094.473l.015.01a.357.357 0 0 0 .485-.108.352.352 0 0 0-.3-.54zm-2.803 2.488v.002a.347.347 0 0 0-.223.084.352.352 0 0 0 .23.62.347.347 0 0 0 .23-.085.348.348 0 0 0 .12-.24.353.353 0 0 0-.35-.38.347.347 0 0 0-.007 0Z\" />\n </SvgIcon>\n )\n}\n\nexport default MusicBrainz\n","import React from 'react'\nimport { useRecordContext, useTranslate } from 'react-admin'\nimport { IconButton, Tooltip, Link } from '@material-ui/core'\nimport { ImLastfm2 } from 'react-icons/im'\nimport MusicBrainz from '../icons/MusicBrainz'\nimport { intersperse } from '../utils'\n\nconst AlbumExternalLinks = (props) => {\n const { className } = props\n const translate = useTranslate()\n const record = useRecordContext(props)\n let links = []\n\n const addLink = (url, title, icon) => {\n const translatedTitle = translate(title)\n const link = (\n <Link href={url} target=\"_blank\" rel=\"noopener noreferrer\">\n <Tooltip title={translatedTitle}>\n <IconButton size={'small'} aria-label={translatedTitle}>\n {icon}\n </IconButton>\n </Tooltip>\n </Link>\n )\n const id = links.length\n links.push(<span key={`link-${record.id}-${id}`}>{link}</span>)\n }\n\n addLink(\n `https://last.fm/music/${\n encodeURIComponent(record.albumArtist) +\n '/' +\n encodeURIComponent(record.name)\n }`,\n 'message.openIn.lastfm',\n <ImLastfm2 />\n )\n\n record.mbzAlbumId &&\n addLink(\n `https://musicbrainz.org/release/${record.mbzAlbumId}`,\n 'message.openIn.musicbrainz',\n <MusicBrainz />\n )\n\n return <div className={className}>{intersperse(links, ' ')}</div>\n}\n\nexport default AlbumExternalLinks\n","import React, { useMemo, useCallback } from 'react'\nimport {\n Card,\n CardContent,\n CardMedia,\n Collapse,\n makeStyles,\n Typography,\n useMediaQuery,\n withWidth,\n} from '@material-ui/core'\nimport {\n useRecordContext,\n useTranslate,\n ArrayField,\n SingleFieldList,\n ChipField,\n Link,\n} from 'react-admin'\nimport clsx from 'clsx'\nimport Lightbox from 'react-image-lightbox'\nimport 'react-image-lightbox/style.css'\nimport subsonic from '../subsonic'\nimport {\n ArtistLinkField,\n DurationField,\n formatRange,\n SizeField,\n LoveButton,\n RatingField,\n useAlbumsPerPage,\n} from '../common'\nimport config from '../config'\nimport { intersperse } from '../utils'\nimport AlbumExternalLinks from './AlbumExternalLinks'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n [theme.breakpoints.down('xs')]: {\n padding: '0.7em',\n minWidth: '20em',\n },\n [theme.breakpoints.up('sm')]: {\n padding: '1em',\n minWidth: '32em',\n },\n },\n cardContents: {\n display: 'flex',\n },\n details: {\n display: 'flex',\n flexDirection: 'column',\n },\n content: {\n flex: '2 0 auto',\n },\n coverParent: {\n [theme.breakpoints.down('xs')]: {\n height: '8em',\n width: '8em',\n minWidth: '8em',\n },\n [theme.breakpoints.up('sm')]: {\n height: '10em',\n width: '10em',\n minWidth: '10em',\n },\n [theme.breakpoints.up('lg')]: {\n height: '15em',\n width: '15em',\n minWidth: '15em',\n },\n },\n cover: {\n objectFit: 'contain',\n cursor: 'pointer',\n display: 'block',\n width: '100%',\n height: '100%',\n },\n loveButton: {\n top: theme.spacing(-0.2),\n left: theme.spacing(0.5),\n },\n commentBlock: {\n display: 'inline-block',\n marginTop: '1em',\n float: 'left',\n wordBreak: 'break-word',\n },\n pointerCursor: {\n cursor: 'pointer',\n },\n recordName: {},\n recordArtist: {},\n recordMeta: {},\n genreList: {\n marginTop: theme.spacing(0.5),\n },\n externalLinks: {\n marginTop: theme.spacing(1.5),\n },\n }),\n {\n name: 'NDAlbumDetails',\n }\n)\n\nconst AlbumComment = ({ record }) => {\n const classes = useStyles()\n const [expanded, setExpanded] = React.useState(false)\n\n const lines = record.comment.split('\\n')\n const formatted = useMemo(() => {\n return lines.map((line, idx) => (\n <span key={record.id + '-comment-' + idx}>\n <span dangerouslySetInnerHTML={{ __html: line }} />\n <br />\n </span>\n ))\n }, [lines, record.id])\n\n const handleExpandClick = useCallback(() => {\n setExpanded(!expanded)\n }, [expanded, setExpanded])\n\n return (\n <Collapse\n collapsedHeight={'1.5em'}\n in={expanded}\n timeout={'auto'}\n className={clsx(\n classes.commentBlock,\n lines.length > 1 && classes.pointerCursor\n )}\n >\n <Typography variant={'body1'} onClick={handleExpandClick}>\n {formatted}\n </Typography>\n </Collapse>\n )\n}\n\nexport const useGetHandleGenreClick = (width) => {\n const [perPage] = useAlbumsPerPage(width)\n\n return (id) => {\n return `/album?filter={\"genre_id\":\"${id}\"}&order=ASC&sort=name&perPage=${perPage}`\n }\n}\n\nconst GenreChipField = withWidth()(({ width, ...rest }) => {\n const record = useRecordContext(rest)\n const genreLink = useGetHandleGenreClick(width)\n\n return (\n <Link to={genreLink(record.id)} onClick={(e) => e.stopPropagation()}>\n <ChipField\n source=\"name\"\n // Workaround to force ChipField to be clickable\n onClick={() => {}}\n />\n </Link>\n )\n})\n\nconst GenreList = () => {\n const classes = useStyles()\n return (\n <ArrayField className={classes.genreList} source={'genres'}>\n <SingleFieldList linkType={false}>\n <GenreChipField />\n </SingleFieldList>\n </ArrayField>\n )\n}\n\nconst Details = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const translate = useTranslate()\n const record = useRecordContext(props)\n let details = []\n const addDetail = (obj) => {\n const id = details.length\n details.push(<span key={`detail-${record.id}-${id}`}>{obj}</span>)\n }\n\n const year = formatRange(record, 'year')\n year && addDetail(<>{year}</>)\n addDetail(\n <>\n {record.songCount +\n ' ' +\n translate('resources.song.name', {\n smart_count: record.songCount,\n })}\n </>\n )\n !isXsmall && addDetail(<DurationField source={'duration'} />)\n !isXsmall && addDetail(<SizeField source=\"size\" />)\n\n return <>{intersperse(details, ' · ')}</>\n}\n\nconst AlbumDetails = (props) => {\n const record = useRecordContext(props)\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('lg'))\n const classes = useStyles()\n const [isLightboxOpen, setLightboxOpen] = React.useState(false)\n\n const imageUrl = subsonic.getCoverArtUrl(record, 300)\n const fullImageUrl = subsonic.getCoverArtUrl(record)\n\n const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])\n const handleCloseLightbox = React.useCallback(\n () => setLightboxOpen(false),\n []\n )\n return (\n <Card className={classes.root}>\n <div className={classes.cardContents}>\n <div className={classes.coverParent}>\n <CardMedia\n component={'img'}\n src={imageUrl}\n width=\"400\"\n height=\"400\"\n className={classes.cover}\n onClick={handleOpenLightbox}\n title={record.name}\n />\n </div>\n <div className={classes.details}>\n <CardContent className={classes.content}>\n <Typography\n variant={isDesktop ? 'h5' : 'h6'}\n className={classes.recordName}\n >\n {record.name}\n {config.enableFavourites && (\n <LoveButton\n className={classes.loveButton}\n record={record}\n resource={'album'}\n size={isDesktop ? 'default' : 'small'}\n aria-label=\"love\"\n color=\"primary\"\n />\n )}\n </Typography>\n <Typography component={'h6'} className={classes.recordArtist}>\n <ArtistLinkField record={record} />\n </Typography>\n <Typography component={'div'} className={classes.recordMeta}>\n <Details />\n </Typography>\n {config.enableStarRating && (\n <div>\n <RatingField\n record={record}\n resource={'album'}\n size={isDesktop ? 'medium' : 'small'}\n />\n </div>\n )}\n {isDesktop ? (\n <GenreList />\n ) : (\n <Typography component={'p'}>{record.genre}</Typography>\n )}\n {!isXsmall && (\n <Typography component={'div'} className={classes.recordMeta}>\n <AlbumExternalLinks className={classes.externalLinks} />\n </Typography>\n )}\n {isDesktop && record['comment'] && <AlbumComment record={record} />}\n </CardContent>\n </div>\n </div>\n {!isDesktop && record['comment'] && <AlbumComment record={record} />}\n {isLightboxOpen && (\n <Lightbox\n imagePadding={50}\n animationDuration={200}\n imageTitle={record.name}\n mainSrc={fullImageUrl}\n onCloseRequest={handleCloseLightbox}\n />\n )}\n </Card>\n )\n}\n\nexport default AlbumDetails\n","import React from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport {\n Button,\n sanitizeListRestProps,\n TopToolbar,\n useTranslate,\n} from 'react-admin'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'\nimport { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'\nimport PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'\nimport {\n playNext,\n addTracks,\n playTracks,\n shuffleTracks,\n openAddToPlaylist,\n} from '../actions'\nimport subsonic from '../subsonic'\nimport { formatBytes } from '../utils'\nimport { useMediaQuery, makeStyles } from '@material-ui/core'\nimport config from '../config'\nimport { ToggleFieldsMenu } from '../common'\n\nconst useStyles = makeStyles({\n toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' },\n})\n\nconst AlbumActions = ({\n className,\n ids,\n data,\n record,\n permanentFilter,\n ...rest\n}) => {\n const dispatch = useDispatch()\n const translate = useTranslate()\n const classes = useStyles()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n\n const handlePlay = React.useCallback(() => {\n dispatch(playTracks(data, ids))\n }, [dispatch, data, ids])\n\n const handlePlayNext = React.useCallback(() => {\n dispatch(playNext(data, ids))\n }, [dispatch, data, ids])\n\n const handlePlayLater = React.useCallback(() => {\n dispatch(addTracks(data, ids))\n }, [dispatch, data, ids])\n\n const handleShuffle = React.useCallback(() => {\n dispatch(shuffleTracks(data, ids))\n }, [dispatch, data, ids])\n\n const handleAddToPlaylist = React.useCallback(() => {\n dispatch(openAddToPlaylist({ selectedIds: ids }))\n }, [dispatch, ids])\n\n const handleDownload = React.useCallback(() => {\n subsonic.download(record.id)\n }, [record])\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n <div className={classes.toolbar}>\n <div>\n <Button\n onClick={handlePlay}\n label={translate('resources.album.actions.playAll')}\n >\n <PlayArrowIcon />\n </Button>\n <Button\n onClick={handleShuffle}\n label={translate('resources.album.actions.shuffle')}\n >\n <ShuffleIcon />\n </Button>\n <Button\n onClick={handlePlayNext}\n label={translate('resources.album.actions.playNext')}\n >\n <RiPlayList2Fill />\n </Button>\n <Button\n onClick={handlePlayLater}\n label={translate('resources.album.actions.addToQueue')}\n >\n <RiPlayListAddFill />\n </Button>\n <Button\n onClick={handleAddToPlaylist}\n label={translate('resources.album.actions.addToPlaylist')}\n >\n <PlaylistAddIcon />\n </Button>\n {config.enableDownloads && (\n <Button\n onClick={handleDownload}\n label={\n translate('resources.album.actions.download') +\n (isDesktop ? ` (${formatBytes(record.size)})` : '')\n }\n >\n <CloudDownloadOutlinedIcon />\n </Button>\n )}\n </div>\n <div>{isNotSmall && <ToggleFieldsMenu resource=\"albumSong\" />}</div>\n </div>\n </TopToolbar>\n )\n}\n\nAlbumActions.propTypes = {\n record: PropTypes.object.isRequired,\n selectedIds: PropTypes.arrayOf(PropTypes.number),\n}\n\nAlbumActions.defaultProps = {\n record: {},\n selectedIds: [],\n onUnselectItems: () => null,\n}\n\nexport default AlbumActions\n","import React from 'react'\nimport {\n ReferenceManyField,\n ShowContextProvider,\n useShowContext,\n useShowController,\n} from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport AlbumSongs from './AlbumSongs'\nimport AlbumDetails from './AlbumDetails'\nimport AlbumActions from './AlbumActions'\n\nconst useStyles = makeStyles(\n (theme) => ({\n albumActions: {\n width: '100%',\n },\n }),\n {\n name: 'NDAlbumShow',\n }\n)\n\nconst AlbumShowLayout = (props) => {\n const { loading, ...context } = useShowContext(props)\n const { record } = context\n const classes = useStyles()\n\n return (\n <>\n {record && <AlbumDetails {...context} />}\n {record && (\n <ReferenceManyField\n {...context}\n addLabel={false}\n reference=\"song\"\n target=\"album_id\"\n sort={{ field: 'album', order: 'ASC' }}\n perPage={0}\n pagination={null}\n >\n <AlbumSongs\n resource={'song'}\n exporter={false}\n album={record}\n actions={\n <AlbumActions className={classes.albumActions} record={record} />\n }\n />\n </ReferenceManyField>\n )}\n </>\n )\n}\n\nconst AlbumShow = (props) => {\n const controllerProps = useShowController(props)\n return (\n <ShowContextProvider value={controllerProps}>\n <AlbumShowLayout {...props} {...controllerProps} />\n </ShowContextProvider>\n )\n}\n\nexport default AlbumShow\n","import AlbumList from './AlbumList'\nimport AlbumShow from './AlbumShow'\n\nexport default {\n list: AlbumList,\n show: AlbumShow,\n}\n","import React, { cloneElement } from 'react'\nimport { sanitizeListRestProps, TopToolbar } from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ToggleFieldsMenu } from '../common'\n\nconst ArtistListActions = ({\n className,\n filters,\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n ...rest\n}) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {filters &&\n cloneElement(filters, {\n resource,\n showFilter,\n displayedFilters,\n filterValues,\n context: 'button',\n })}\n {isNotSmall && <ToggleFieldsMenu resource=\"artist\" />}\n </TopToolbar>\n )\n}\n\nexport default ArtistListActions\n","import React, { useMemo } from 'react'\nimport { useHistory } from 'react-router-dom'\nimport {\n AutocompleteInput,\n Datagrid,\n DatagridBody,\n DatagridRow,\n Filter,\n NumberField,\n ReferenceInput,\n SearchInput,\n TextField,\n useTranslate,\n} from 'react-admin'\nimport { useMediaQuery, withWidth } from '@material-ui/core'\nimport FavoriteIcon from '@material-ui/icons/Favorite'\nimport FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useDrag } from 'react-dnd'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport {\n ArtistContextMenu,\n List,\n QuickFilter,\n useGetHandleArtistClick,\n ArtistSimpleList,\n RatingField,\n useSelectedFields,\n useResourceRefresh,\n} from '../common'\nimport config from '../config'\nimport ArtistListActions from './ArtistListActions'\nimport { DraggableTypes } from '../consts'\n\nconst useStyles = makeStyles({\n contextHeader: {\n marginLeft: '3px',\n marginTop: '-2px',\n verticalAlign: 'text-top',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n '& $ratingField': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: 'hidden',\n },\n ratingField: {\n visibility: 'hidden',\n },\n})\n\nconst ArtistFilter = (props) => {\n const translate = useTranslate()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"name\" alwaysOn />\n <ReferenceInput\n label={translate('resources.artist.fields.genre')}\n source=\"genre_id\"\n reference=\"genre\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n filterToQuery={(searchText) => ({ name: [searchText] })}\n >\n <AutocompleteInput emptyText=\"-- None --\" />\n </ReferenceInput>\n {config.enableFavourites && (\n <QuickFilter\n source=\"starred\"\n label={<FavoriteIcon fontSize={'small'} />}\n defaultValue={true}\n />\n )}\n </Filter>\n )\n}\n\nconst ArtistDatagridRow = (props) => {\n const { record } = props\n const [, dragArtistRef] = useDrag(\n () => ({\n type: DraggableTypes.ARTIST,\n item: { artistIds: [record?.id] },\n options: { dropEffect: 'copy' },\n }),\n [record]\n )\n return <DatagridRow ref={dragArtistRef} {...props} />\n}\n\nconst ArtistDatagridBody = (props) => (\n <DatagridBody {...props} row={<ArtistDatagridRow />} />\n)\n\nconst ArtistDatagrid = (props) => (\n <Datagrid {...props} body={<ArtistDatagridBody />} />\n)\n\nconst ArtistListView = ({ hasShow, hasEdit, hasList, width, ...rest }) => {\n const classes = useStyles()\n const handleArtistLink = useGetHandleArtistClick(width)\n const history = useHistory()\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n useResourceRefresh('artist')\n\n const toggleableFields = useMemo(() => {\n return {\n albumCount: <NumberField source=\"albumCount\" sortByOrder={'DESC'} />,\n songCount: <NumberField source=\"songCount\" sortByOrder={'DESC'} />,\n playCount: <NumberField source=\"playCount\" sortByOrder={'DESC'} />,\n rating: config.enableStarRating && (\n <RatingField\n source=\"rating\"\n sortByOrder={'DESC'}\n resource={'artist'}\n className={classes.ratingField}\n />\n ),\n }\n }, [classes.ratingField])\n\n const columns = useSelectedFields({\n resource: 'artist',\n columns: toggleableFields,\n })\n\n return isXsmall ? (\n <ArtistSimpleList\n linkType={(id) => history.push(handleArtistLink(id))}\n {...rest}\n />\n ) : (\n <ArtistDatagrid rowClick={handleArtistLink} classes={{ row: classes.row }}>\n <TextField source=\"name\" />\n {columns}\n <ArtistContextMenu\n source={'starred'}\n sortBy={'starred ASC, starredAt ASC'}\n sortByOrder={'DESC'}\n sortable={config.enableFavourites}\n className={classes.contextMenu}\n label={\n config.enableFavourites && (\n <FavoriteBorderIcon\n fontSize={'small'}\n className={classes.contextHeader}\n />\n )\n }\n />\n </ArtistDatagrid>\n )\n}\n\nconst ArtistList = (props) => {\n return (\n <>\n <List\n {...props}\n sort={{ field: 'name', order: 'ASC' }}\n exporter={false}\n bulkActionButtons={false}\n filters={<ArtistFilter />}\n actions={<ArtistListActions />}\n >\n <ArtistListView {...props} />\n </List>\n <AddToPlaylistDialog />\n </>\n )\n}\n\nexport default withWidth()(ArtistList)\n","import React, { useState } from 'react'\nimport { Typography, Collapse } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport Card from '@material-ui/core/Card'\nimport CardMedia from '@material-ui/core/CardMedia'\nimport config from '../config'\nimport { LoveButton, RatingField } from '../common'\nimport Lightbox from 'react-image-lightbox'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n display: 'flex',\n background: ({ img }) => `url(${img})`,\n },\n bgContainer: {\n display: 'flex',\n height: '15rem',\n width: '100vw',\n padding: 'unset',\n backdropFilter: 'blur(1px)',\n backgroundPosition: '50% 30%',\n background: `linear-gradient(to bottom, rgba(52 52 52 / 72%), rgba(21 21 21))`,\n },\n link: {\n margin: '1px',\n },\n details: {\n display: 'flex',\n alignItems: 'flex-start',\n flexDirection: 'column',\n justifyContent: 'center',\n marginLeft: '0.5rem',\n },\n biography: {\n display: 'flex',\n marginLeft: '3%',\n marginRight: '3%',\n marginTop: '-2em',\n zIndex: '1',\n '& p': {\n whiteSpace: ({ expanded }) => (expanded ? 'unset' : 'nowrap'),\n overflow: 'hidden',\n width: '95vw',\n textOverflow: 'ellipsis',\n },\n },\n cover: {\n width: 151,\n boxShadow: '0px 0px 6px 0px #565656',\n borderRadius: '5px',\n },\n artistImage: {\n marginLeft: '1em',\n maxHeight: '7rem',\n backgroundColor: 'inherit',\n marginTop: '4rem',\n width: '7rem',\n minWidth: '7rem',\n display: 'flex',\n borderRadius: '5em',\n },\n loveButton: {\n top: theme.spacing(-0.2),\n left: theme.spacing(0.5),\n },\n rating: {\n marginTop: '5px',\n },\n artistName: {\n wordBreak: 'break-word',\n },\n }),\n { name: 'NDMobileArtistDetails' }\n)\n\nconst MobileArtistDetails = ({ img, artistInfo, biography, record }) => {\n const [expanded, setExpanded] = useState(false)\n const classes = useStyles({ img, expanded })\n const title = record.name\n const [isLightboxOpen, setLightboxOpen] = React.useState(false)\n\n const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])\n const handleCloseLightbox = React.useCallback(\n () => setLightboxOpen(false),\n []\n )\n\n return (\n <>\n <div className={classes.root}>\n <div className={classes.bgContainer}>\n <Card className={classes.artistImage}>\n {artistInfo && (\n <CardMedia\n className={classes.cover}\n image={artistInfo.mediumImageUrl}\n onClick={handleOpenLightbox}\n title={title}\n />\n )}\n </Card>\n <div className={classes.details}>\n <Typography\n component=\"h5\"\n variant=\"h5\"\n className={classes.artistName}\n >\n {title}\n {config.enableFavourites && (\n <LoveButton\n className={classes.loveButton}\n record={record}\n resource={'artist'}\n size={'small'}\n aria-label=\"love\"\n color=\"primary\"\n />\n )}\n </Typography>\n {config.enableStarRating && (\n <RatingField\n record={record}\n resource={'artist'}\n size={'small'}\n className={classes.rating}\n />\n )}\n </div>\n </div>\n </div>\n <div className={classes.biography}>\n <Collapse collapsedHeight={'1.5em'} in={expanded} timeout={'auto'}>\n <Typography variant={'body1'} onClick={() => setExpanded(!expanded)}>\n <span dangerouslySetInnerHTML={{ __html: biography }} />\n </Typography>\n </Collapse>\n </div>\n {isLightboxOpen && (\n <Lightbox\n imagePadding={50}\n animationDuration={200}\n imageTitle={record.name}\n mainSrc={artistInfo.largeImageUrl}\n onCloseRequest={handleCloseLightbox}\n />\n )}\n </>\n )\n}\n\nexport default MobileArtistDetails\n","import React from 'react'\nimport { useTranslate } from 'react-admin'\nimport { IconButton, Tooltip, Link } from '@material-ui/core'\n\nimport { ImLastfm2 } from 'react-icons/im'\nimport MusicBrainz from '../icons/MusicBrainz'\nimport { intersperse } from '../utils'\n\nconst ArtistExternalLinks = ({ artistInfo, record }) => {\n const translate = useTranslate()\n let links = []\n let linkButtons = []\n const lastFMlink = artistInfo?.biography?.match(\n /<a\\s+(?:[^>]*?\\s+)?href=([\"'])(.*?)\\1/\n )\n\n if (lastFMlink) {\n links.push(lastFMlink[2])\n }\n if (artistInfo && artistInfo.musicBrainzId) {\n links.push(`https://musicbrainz.org/artist/${artistInfo.musicBrainzId}`)\n }\n\n const addLink = (url, title, icon) => {\n const translatedTitle = translate(title)\n const link = (\n <Link href={url} target=\"_blank\" rel=\"noopener noreferrer\">\n <Tooltip title={translatedTitle}>\n <IconButton size={'small'} aria-label={translatedTitle}>\n {icon}\n </IconButton>\n </Tooltip>\n </Link>\n )\n const id = linkButtons.length\n linkButtons.push(<span key={`link-${record.id}-${id}`}>{link}</span>)\n }\n\n addLink(links[0], 'message.openIn.lastfm', <ImLastfm2 />)\n artistInfo?.musicBrainzId &&\n addLink(links[1], 'message.openIn.musicbrainz', <MusicBrainz />)\n\n return <div>{intersperse(linkButtons, ' ')}</div>\n}\n\nexport default ArtistExternalLinks\n","import React, { useState } from 'react'\nimport { Typography, Collapse } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core'\nimport Card from '@material-ui/core/Card'\nimport CardContent from '@material-ui/core/CardContent'\nimport CardMedia from '@material-ui/core/CardMedia'\nimport ArtistExternalLinks from './ArtistExternalLink'\nimport config from '../config'\nimport { LoveButton, RatingField } from '../common'\nimport Lightbox from 'react-image-lightbox'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {\n display: 'flex',\n padding: '1em',\n },\n details: {\n display: 'flex',\n flex: '1',\n flexDirection: 'column',\n },\n biography: {\n display: 'inline-block',\n marginTop: '1em',\n float: 'left',\n wordBreak: 'break-word',\n cursor: 'pointer',\n },\n content: {\n flex: '1 0 auto',\n },\n cover: {\n width: 151,\n borderRadius: '6em',\n cursor: 'pointer',\n },\n artistImage: {\n maxHeight: '9.5rem',\n backgroundColor: 'inherit',\n display: 'flex',\n boxShadow: 'none',\n },\n artistDetail: {\n flex: '1',\n padding: '3%',\n display: 'flex',\n minHeight: '10rem',\n },\n button: {\n marginLeft: '0.9em',\n },\n loveButton: {\n top: theme.spacing(-0.2),\n left: theme.spacing(0.5),\n },\n rating: {\n marginTop: '5px',\n },\n artistName: {\n wordBreak: 'break-word',\n },\n }),\n { name: 'NDDesktopArtistDetails' }\n)\n\nconst DesktopArtistDetails = ({ img, artistInfo, record, biography }) => {\n const [expanded, setExpanded] = useState(false)\n const classes = useStyles({ img, expanded })\n const title = record.name\n const [isLightboxOpen, setLightboxOpen] = React.useState(false)\n\n const handleOpenLightbox = React.useCallback(() => setLightboxOpen(true), [])\n const handleCloseLightbox = React.useCallback(\n () => setLightboxOpen(false),\n []\n )\n\n return (\n <div className={classes.root}>\n <Card className={classes.artistDetail}>\n <Card className={classes.artistImage}>\n {artistInfo && (\n <CardMedia\n className={classes.cover}\n image={artistInfo.mediumImageUrl}\n onClick={handleOpenLightbox}\n title={title}\n />\n )}\n </Card>\n <div className={classes.details}>\n <CardContent className={classes.content}>\n <Typography\n component=\"h5\"\n variant=\"h5\"\n className={classes.artistName}\n >\n {title}\n {config.enableFavourites && (\n <LoveButton\n className={classes.loveButton}\n record={record}\n resource={'artist'}\n size={'default'}\n aria-label=\"love\"\n color=\"primary\"\n />\n )}\n </Typography>\n {config.enableStarRating && (\n <div>\n <RatingField\n record={record}\n resource={'artist'}\n size={'small'}\n className={classes.rating}\n />\n </div>\n )}\n <Collapse\n collapsedHeight={'4.5em'}\n in={expanded}\n timeout={'auto'}\n className={classes.biography}\n >\n <Typography\n variant={'body1'}\n onClick={() => setExpanded(!expanded)}\n >\n <span dangerouslySetInnerHTML={{ __html: biography }} />\n </Typography>\n </Collapse>\n </CardContent>\n <Typography component={'div'} className={classes.button}>\n <ArtistExternalLinks artistInfo={artistInfo} record={record} />\n </Typography>\n </div>\n {isLightboxOpen && (\n <Lightbox\n imagePadding={50}\n animationDuration={200}\n imageTitle={record.name}\n mainSrc={artistInfo.largeImageUrl}\n onCloseRequest={handleCloseLightbox}\n />\n )}\n </Card>\n </div>\n )\n}\n\nexport default DesktopArtistDetails\n","import React, { useState, createElement, useEffect } from 'react'\nimport { useMediaQuery } from '@material-ui/core'\nimport {\n useShowController,\n ShowContextProvider,\n useRecordContext,\n useShowContext,\n ReferenceManyField,\n} from 'react-admin'\nimport subsonic from '../subsonic'\nimport AlbumGridView from '../album/AlbumGridView'\nimport MobileArtistDetails from './MobileArtistDetails'\nimport DesktopArtistDetails from './DesktopArtistDetails'\n\nconst ArtistDetails = (props) => {\n const record = useRecordContext(props)\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n const [artistInfo, setArtistInfo] = useState()\n\n const biography =\n artistInfo?.biography?.replace(new RegExp('<.*>', 'g'), '') ||\n record.biography\n const img = artistInfo?.largeImageUrl || record.largeImageUrl\n\n useEffect(() => {\n subsonic\n .getArtistInfo(record.id)\n .then((resp) => resp.json['subsonic-response'])\n .then((data) => {\n if (data.status === 'ok') {\n setArtistInfo(data.artistInfo)\n }\n })\n .catch((e) => {\n console.error('error on artist page', e)\n })\n }, [record])\n\n const component = isDesktop ? DesktopArtistDetails : MobileArtistDetails\n return (\n <>\n {createElement(component, {\n img,\n artistInfo,\n record,\n biography,\n })}\n </>\n )\n}\n\nconst AlbumShowLayout = (props) => {\n const showContext = useShowContext(props)\n const record = useRecordContext()\n\n return (\n <>\n {record && <ArtistDetails />}\n {record && (\n <ReferenceManyField\n {...showContext}\n addLabel={false}\n reference=\"album\"\n target=\"artist_id\"\n sort={{ field: 'max_year', order: 'ASC' }}\n filter={{ artist_id: record?.id }}\n perPage={0}\n pagination={null}\n >\n <AlbumGridView {...props} />\n </ReferenceManyField>\n )}\n </>\n )\n}\n\nconst ArtistShow = (props) => {\n const controllerProps = useShowController(props)\n return (\n <ShowContextProvider value={controllerProps}>\n <AlbumShowLayout {...controllerProps} />\n </ShowContextProvider>\n )\n}\n\nexport default ArtistShow\n","import React from 'react'\nimport ArtistList from './ArtistList'\nimport ArtistShow from './ArtistShow'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\nimport MicNoneOutlinedIcon from '@material-ui/icons/MicNoneOutlined'\nimport MicIcon from '@material-ui/icons/Mic'\n\nexport default {\n list: ArtistList,\n show: ArtistShow,\n icon: (\n <DynamicMenuIcon\n path={'artist'}\n icon={MicNoneOutlinedIcon}\n activeIcon={MicIcon}\n />\n ),\n}\n","import React, { cloneElement } from 'react'\nimport {\n sanitizeListRestProps,\n TopToolbar,\n CreateButton,\n useTranslate,\n} from 'react-admin'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ToggleFieldsMenu } from '../common'\n\nconst PlaylistListActions = ({ className, ...rest }) => {\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n const translate = useTranslate()\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n {cloneElement(rest.filters, { context: 'button' })}\n <CreateButton basePath=\"/playlist\">\n {translate('ra.action.create')}\n </CreateButton>\n {isNotSmall && <ToggleFieldsMenu resource=\"playlist\" />}\n </TopToolbar>\n )\n}\n\nexport default PlaylistListActions\n","import * as React from 'react'\nimport { LockOpen, Lock } from '@material-ui/icons'\nimport { BulkUpdateButton, useTranslate } from 'react-admin'\n\nconst ChangePublicStatusButton = (props) => {\n const translate = useTranslate()\n const playlists = { public: props?.public }\n const label = props?.public\n ? translate('resources.playlist.actions.makePublic')\n : translate('resources.playlist.actions.makePrivate')\n const icon = props?.public ? <LockOpen /> : <Lock />\n return (\n <BulkUpdateButton {...props} data={playlists} label={label} icon={icon} />\n )\n}\n\nexport default ChangePublicStatusButton\n","import React, { useMemo } from 'react'\nimport {\n Datagrid,\n DateField,\n EditButton,\n Filter,\n NumberField,\n ReferenceInput,\n SearchInput,\n SelectInput,\n TextField,\n useUpdate,\n useNotify,\n useRecordContext,\n BulkDeleteButton,\n usePermissions,\n} from 'react-admin'\nimport Switch from '@material-ui/core/Switch'\nimport { useMediaQuery } from '@material-ui/core'\nimport {\n DurationField,\n List,\n Writable,\n isWritable,\n useSelectedFields,\n useResourceRefresh,\n} from '../common'\nimport PlaylistListActions from './PlaylistListActions'\nimport ChangePublicStatusButton from './ChangePublicStatusButton'\n\nconst PlaylistFilter = (props) => {\n const { permissions } = usePermissions()\n return (\n <Filter {...props} variant={'outlined'}>\n <SearchInput source=\"q\" alwaysOn />\n {permissions === 'admin' && (\n <ReferenceInput\n source=\"owner_id\"\n reference=\"user\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n alwaysOn\n >\n <SelectInput optionText=\"name\" />\n </ReferenceInput>\n )}\n </Filter>\n )\n}\n\nconst TogglePublicInput = ({ resource, source }) => {\n const record = useRecordContext()\n const notify = useNotify()\n const [togglePublic] = useUpdate(\n resource,\n record.id,\n {\n ...record,\n public: !record.public,\n },\n {\n undoable: false,\n onFailure: (error) => {\n console.log(error)\n notify('ra.page.error', 'warning')\n },\n }\n )\n\n const handleClick = (e) => {\n togglePublic()\n e.stopPropagation()\n }\n\n return (\n <Switch\n checked={record[source]}\n onClick={handleClick}\n disabled={!isWritable(record.ownerId)}\n />\n )\n}\n\nconst PlaylistListBulkActions = (props) => (\n <>\n <ChangePublicStatusButton public={true} {...props} />\n <ChangePublicStatusButton public={false} {...props} />\n <BulkDeleteButton {...props} />\n </>\n)\n\nconst PlaylistList = (props) => {\n const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n useResourceRefresh('playlist')\n\n const toggleableFields = useMemo(\n () => ({\n ownerName: isDesktop && <TextField source=\"ownerName\" />,\n songCount: !isXsmall && <NumberField source=\"songCount\" />,\n duration: <DurationField source=\"duration\" />,\n updatedAt: isDesktop && (\n <DateField source=\"updatedAt\" sortByOrder={'DESC'} />\n ),\n public: !isXsmall && (\n <TogglePublicInput source=\"public\" sortByOrder={'DESC'} />\n ),\n }),\n [isDesktop, isXsmall]\n )\n\n const columns = useSelectedFields({\n resource: 'playlist',\n columns: toggleableFields,\n })\n\n return (\n <List\n {...props}\n exporter={false}\n filters={<PlaylistFilter />}\n actions={<PlaylistListActions />}\n bulkActionButtons={!isXsmall && <PlaylistListBulkActions />}\n >\n <Datagrid rowClick=\"show\" isRowSelectable={(r) => isWritable(r?.ownerId)}>\n <TextField source=\"name\" />\n {columns}\n <Writable>\n <EditButton />\n </Writable>\n </Datagrid>\n </List>\n )\n}\n\nexport default PlaylistList\n","import React, { Fragment } from 'react'\n\nimport {\n Edit,\n FormDataConsumer,\n SimpleForm,\n TextInput,\n TextField,\n BooleanInput,\n required,\n useTranslate,\n usePermissions,\n ReferenceInput,\n SelectInput,\n} from 'react-admin'\nimport { isWritable, Title } from '../common'\n\nconst SyncFragment = ({ formData, variant, ...rest }) => {\n return (\n <Fragment>\n {formData.path && <BooleanInput source=\"sync\" {...rest} />}\n {formData.path && <TextField source=\"path\" {...rest} />}\n </Fragment>\n )\n}\n\nconst PlaylistTitle = ({ record }) => {\n const translate = useTranslate()\n const resourceName = translate('resources.playlist.name', { smart_count: 1 })\n return <Title subTitle={`${resourceName} \"${record ? record.name : ''}\"`} />\n}\n\nconst PlaylistEditForm = (props) => {\n const { record } = props\n const { permissions } = usePermissions()\n return (\n <SimpleForm redirect=\"list\" variant={'outlined'} {...props}>\n <TextInput source=\"name\" validate={required()} />\n <TextInput multiline source=\"comment\" />\n {permissions === 'admin' ? (\n <ReferenceInput\n source=\"ownerId\"\n reference=\"user\"\n perPage={0}\n sort={{ field: 'name', order: 'ASC' }}\n >\n <SelectInput\n label={'resources.playlist.fields.ownerName'}\n optionText=\"userName\"\n />\n </ReferenceInput>\n ) : (\n <TextField source=\"ownerName\" />\n )}\n <BooleanInput source=\"public\" disabled={!isWritable(record.ownerId)} />\n <FormDataConsumer>\n {(formDataProps) => <SyncFragment {...formDataProps} />}\n </FormDataConsumer>\n </SimpleForm>\n )\n}\n\nconst PlaylistEdit = (props) => (\n <Edit title={<PlaylistTitle />} actions={false} {...props}>\n <PlaylistEditForm {...props} />\n </Edit>\n)\n\nexport default PlaylistEdit\n","import React from 'react'\nimport {\n Create,\n SimpleForm,\n TextInput,\n BooleanInput,\n required,\n useTranslate,\n useRefresh,\n useNotify,\n useRedirect,\n} from 'react-admin'\nimport { Title } from '../common'\n\nconst PlaylistCreate = (props) => {\n const { basePath } = props\n const refresh = useRefresh()\n const notify = useNotify()\n const redirect = useRedirect()\n const translate = useTranslate()\n const resourceName = translate('resources.playlist.name', { smart_count: 1 })\n const title = translate('ra.page.create', {\n name: `${resourceName}`,\n })\n\n const onSuccess = () => {\n notify('ra.notification.created', 'info', { smart_count: 1 })\n redirect('list', basePath)\n refresh()\n }\n\n return (\n <Create title={<Title subTitle={title} />} {...props} onSuccess={onSuccess}>\n <SimpleForm redirect=\"list\" variant={'outlined'}>\n <TextInput source=\"name\" validate={required()} />\n <TextInput multiline source=\"comment\" />\n <BooleanInput source=\"public\" initialValue={true} />\n </SimpleForm>\n </Create>\n )\n}\n\nexport default PlaylistCreate\n","import React from 'react'\nimport { Card, CardContent, Typography } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { useTranslate } from 'react-admin'\nimport { DurationField, SizeField } from '../common'\n\nconst useStyles = makeStyles(\n (theme) => ({\n container: {\n [theme.breakpoints.down('xs')]: {\n padding: '0.7em',\n minWidth: '24em',\n },\n [theme.breakpoints.up('sm')]: {\n padding: '1em',\n minWidth: '32em',\n },\n },\n details: {\n display: 'inline-block',\n verticalAlign: 'top',\n [theme.breakpoints.down('xs')]: {\n width: '14em',\n },\n [theme.breakpoints.up('sm')]: {\n width: '26em',\n },\n [theme.breakpoints.up('lg')]: {\n width: '38em',\n },\n },\n title: {\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n }),\n {\n name: 'NDPlaylistDetails',\n }\n)\n\nconst PlaylistDetails = (props) => {\n const { record = {} } = props\n const translate = useTranslate()\n const classes = useStyles()\n\n return (\n <Card className={classes.container}>\n <CardContent className={classes.details}>\n <Typography variant=\"h5\" className={classes.title}>\n {record.name || translate('ra.page.loading')}\n </Typography>\n <Typography component=\"h6\">{record.comment}</Typography>\n <Typography component=\"p\">\n {record.songCount ? (\n <span>\n {record.songCount}{' '}\n {translate('resources.song.name', {\n smart_count: record.songCount,\n })}\n {' · '}\n <DurationField record={record} source={'duration'} />\n {' · '}\n <SizeField record={record} source={'size'} />\n </span>\n ) : (\n <span> </span>\n )}\n </Typography>\n </CardContent>\n </Card>\n )\n}\n\nexport default PlaylistDetails\n","import React, { Fragment, useEffect } from 'react'\nimport {\n BulkDeleteButton,\n useUnselectAll,\n ResourceContextProvider,\n} from 'react-admin'\nimport PropTypes from 'prop-types'\n\n// Replace original resource with \"fake\" one for removing tracks from playlist\nconst PlaylistSongBulkActions = ({\n playlistId,\n resource,\n onUnselectItems,\n ...rest\n}) => {\n const unselectAll = useUnselectAll()\n useEffect(() => {\n unselectAll('playlistTrack')\n }, [unselectAll])\n\n const mappedResource = `playlist/${playlistId}/tracks`\n return (\n <ResourceContextProvider value={mappedResource}>\n <Fragment>\n <BulkDeleteButton\n {...rest}\n resource={mappedResource}\n onClick={onUnselectItems}\n />\n </Fragment>\n </ResourceContextProvider>\n )\n}\n\nPlaylistSongBulkActions.propTypes = {\n playlistId: PropTypes.string.isRequired,\n}\n\nexport default PlaylistSongBulkActions\n","import React, { useCallback, useMemo } from 'react'\nimport {\n BulkActionsToolbar,\n ListToolbar,\n TextField,\n NumberField,\n useDataProvider,\n useNotify,\n useVersion,\n useListContext,\n FunctionField,\n} from 'react-admin'\nimport clsx from 'clsx'\nimport { useDispatch } from 'react-redux'\nimport { Card, useMediaQuery } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport ReactDragListView from 'react-drag-listview'\nimport {\n DurationField,\n SongInfo,\n SongContextMenu,\n SongDatagrid,\n SongTitleField,\n QualityInfo,\n useSelectedFields,\n useResourceRefresh,\n DateField,\n ArtistLinkField,\n} from '../common'\nimport { AddToPlaylistDialog } from '../dialogs'\nimport { AlbumLinkField } from '../song/AlbumLinkField'\nimport { playTracks } from '../actions'\nimport PlaylistSongBulkActions from './PlaylistSongBulkActions'\nimport ExpandInfoDialog from '../dialogs/ExpandInfoDialog'\n\nconst useStyles = makeStyles(\n (theme) => ({\n root: {},\n main: {\n display: 'flex',\n },\n content: {\n marginTop: 0,\n transition: theme.transitions.create('margin-top'),\n position: 'relative',\n flex: '1 1 auto',\n [theme.breakpoints.down('xs')]: {\n boxShadow: 'none',\n },\n },\n bulkActionsDisplayed: {\n marginTop: -theme.spacing(8),\n transition: theme.transitions.create('margin-top'),\n },\n actions: {\n zIndex: 2,\n display: 'flex',\n justifyContent: 'flex-end',\n flexWrap: 'wrap',\n },\n noResults: { padding: 20 },\n toolbar: {\n justifyContent: 'flex-start',\n },\n row: {\n '&:hover': {\n '& $contextMenu': {\n visibility: 'visible',\n },\n },\n },\n contextMenu: {\n visibility: (props) => (props.isDesktop ? 'hidden' : 'visible'),\n },\n }),\n { name: 'RaList' }\n)\n\nconst ReorderableList = ({ readOnly, children, ...rest }) => {\n if (readOnly) {\n return children\n }\n return <ReactDragListView {...rest}>{children}</ReactDragListView>\n}\n\nconst PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {\n const listContext = useListContext()\n const { data, ids, selectedIds, onUnselectItems, refetch } = listContext\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const classes = useStyles({ isDesktop })\n const dispatch = useDispatch()\n const dataProvider = useDataProvider()\n const notify = useNotify()\n const version = useVersion()\n useResourceRefresh('song', 'playlist')\n\n const onAddToPlaylist = useCallback(\n (pls) => {\n if (pls.id === playlistId) {\n refetch()\n }\n },\n [playlistId, refetch]\n )\n\n const reorder = useCallback(\n (playlistId, id, newPos) => {\n dataProvider\n .update('playlistTrack', {\n id,\n data: { insert_before: newPos },\n filter: { playlist_id: playlistId },\n })\n .then(() => {\n refetch()\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n },\n [dataProvider, notify, refetch]\n )\n\n const handleDragEnd = useCallback(\n (from, to) => {\n const toId = ids[to]\n const fromId = ids[from]\n reorder(playlistId, fromId, toId)\n },\n [playlistId, reorder, ids]\n )\n\n const toggleableFields = useMemo(() => {\n return {\n trackNumber: isDesktop && <TextField source=\"id\" label={'#'} />,\n title: <SongTitleField source=\"title\" showTrackNumbers={false} />,\n album: isDesktop && <AlbumLinkField source=\"album\" />,\n artist: isDesktop && <ArtistLinkField source=\"artist\" />,\n albumArtist: isDesktop && <ArtistLinkField source=\"albumArtist\" />,\n duration: (\n <DurationField source=\"duration\" className={classes.draggable} />\n ),\n year: isDesktop && (\n <FunctionField\n source=\"year\"\n render={(r) => r.year || ''}\n sortByOrder={'DESC'}\n />\n ),\n playCount: isDesktop && (\n <NumberField source=\"playCount\" sortByOrder={'DESC'} />\n ),\n playDate: <DateField source=\"playDate\" sortByOrder={'DESC'} showTime />,\n quality: isDesktop && <QualityInfo source=\"quality\" sortable={false} />,\n channels: isDesktop && <NumberField source=\"channels\" />,\n bpm: isDesktop && <NumberField source=\"bpm\" />,\n }\n }, [isDesktop, classes.draggable])\n\n const columns = useSelectedFields({\n resource: 'playlistTrack',\n columns: toggleableFields,\n defaultOff: [\n 'channels',\n 'bpm',\n 'year',\n 'playCount',\n 'playDate',\n 'albumArtist',\n ],\n })\n\n return (\n <>\n <ListToolbar\n classes={{ toolbar: classes.toolbar }}\n filters={props.filters}\n actions={actions}\n />\n <div className={classes.main}>\n <Card\n className={clsx(classes.content, {\n [classes.bulkActionsDisplayed]: selectedIds.length > 0,\n })}\n key={version}\n >\n <BulkActionsToolbar>\n <PlaylistSongBulkActions\n playlistId={playlistId}\n onUnselectItems={onUnselectItems}\n readOnly={readOnly}\n />\n </BulkActionsToolbar>\n <ReorderableList\n readOnly={readOnly}\n onDragEnd={handleDragEnd}\n nodeSelector={'tr'}\n >\n <SongDatagrid\n rowClick={(id) => dispatch(playTracks(data, ids, id))}\n {...listContext}\n hasBulkActions={!readOnly}\n contextAlwaysVisible={!isDesktop}\n classes={{ row: classes.row }}\n >\n {columns}\n <SongContextMenu\n onAddToPlaylist={onAddToPlaylist}\n showLove={false}\n className={classes.contextMenu}\n />\n </SongDatagrid>\n </ReorderableList>\n </Card>\n </div>\n <AddToPlaylistDialog />\n <ExpandInfoDialog content={<SongInfo />} />\n {React.cloneElement(props.pagination, listContext)}\n </>\n )\n}\n\nconst SanitizedPlaylistSongs = (props) => {\n const { loaded, ...rest } = props\n return (\n <>\n {loaded && (\n <PlaylistSongs\n playlistId={props.id}\n actions={props.actions}\n pagination={props.pagination}\n {...rest}\n />\n )}\n </>\n )\n}\n\nexport default SanitizedPlaylistSongs\n","import React from 'react'\nimport { useDispatch } from 'react-redux'\nimport {\n Button,\n sanitizeListRestProps,\n TopToolbar,\n useTranslate,\n useDataProvider,\n useNotify,\n} from 'react-admin'\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow'\nimport ShuffleIcon from '@material-ui/icons/Shuffle'\nimport CloudDownloadOutlinedIcon from '@material-ui/icons/CloudDownloadOutlined'\nimport { RiPlayListAddFill, RiPlayList2Fill } from 'react-icons/ri'\nimport QueueMusicIcon from '@material-ui/icons/QueueMusic'\nimport { httpClient } from '../dataProvider'\nimport { playNext, addTracks, playTracks, shuffleTracks } from '../actions'\nimport { M3U_MIME_TYPE, REST_URL } from '../consts'\nimport subsonic from '../subsonic'\nimport PropTypes from 'prop-types'\nimport { formatBytes } from '../utils'\nimport { useMediaQuery, makeStyles } from '@material-ui/core'\nimport config from '../config'\nimport { ToggleFieldsMenu } from '../common'\n\nconst useStyles = makeStyles({\n toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' },\n})\n\nconst PlaylistActions = ({ className, ids, data, record, ...rest }) => {\n const dispatch = useDispatch()\n const translate = useTranslate()\n const classes = useStyles()\n const dataProvider = useDataProvider()\n const notify = useNotify()\n const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))\n const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))\n\n const getAllSongsAndDispatch = React.useCallback(\n (action) => {\n if (ids?.length === record.songCount) {\n return dispatch(action(data, ids))\n }\n\n dataProvider\n .getList('playlistTrack', {\n pagination: { page: 1, perPage: 0 },\n sort: { field: 'id', order: 'ASC' },\n filter: { playlist_id: record.id },\n })\n .then((res) => {\n const data = res.data.reduce(\n (acc, curr) => ({ ...acc, [curr.id]: curr }),\n {}\n )\n dispatch(action(data))\n })\n .catch(() => {\n notify('ra.page.error', 'warning')\n })\n },\n [dataProvider, dispatch, record, data, ids, notify]\n )\n\n const handlePlay = React.useCallback(() => {\n getAllSongsAndDispatch(playTracks)\n }, [getAllSongsAndDispatch])\n\n const handlePlayNext = React.useCallback(() => {\n getAllSongsAndDispatch(playNext)\n }, [getAllSongsAndDispatch])\n\n const handlePlayLater = React.useCallback(() => {\n getAllSongsAndDispatch(addTracks)\n }, [getAllSongsAndDispatch])\n\n const handleShuffle = React.useCallback(() => {\n getAllSongsAndDispatch(shuffleTracks)\n }, [getAllSongsAndDispatch])\n\n const handleDownload = React.useCallback(() => {\n subsonic.download(record.id)\n }, [record])\n\n const handleExport = React.useCallback(\n () =>\n httpClient(`${REST_URL}/playlist/${record.id}/tracks`, {\n headers: new Headers({ Accept: M3U_MIME_TYPE }),\n }).then((res) => {\n const blob = new Blob([res.body], { type: M3U_MIME_TYPE })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `${record.name}.m3u`\n document.body.appendChild(link)\n link.click()\n link.parentNode.removeChild(link)\n }),\n [record]\n )\n\n return (\n <TopToolbar className={className} {...sanitizeListRestProps(rest)}>\n <div className={classes.toolbar}>\n <div>\n <Button\n onClick={handlePlay}\n label={translate('resources.album.actions.playAll')}\n >\n <PlayArrowIcon />\n </Button>\n <Button\n onClick={handleShuffle}\n label={translate('resources.album.actions.shuffle')}\n >\n <ShuffleIcon />\n </Button>\n <Button\n onClick={handlePlayNext}\n label={translate('resources.album.actions.playNext')}\n >\n <RiPlayList2Fill />\n </Button>\n <Button\n onClick={handlePlayLater}\n label={translate('resources.album.actions.addToQueue')}\n >\n <RiPlayListAddFill />\n </Button>\n {config.enableDownloads && (\n <Button\n onClick={handleDownload}\n label={\n translate('resources.album.actions.download') +\n (isDesktop ? ` (${formatBytes(record.size)})` : '')\n }\n >\n <CloudDownloadOutlinedIcon />\n </Button>\n )}\n <Button\n onClick={handleExport}\n label={translate('resources.playlist.actions.export')}\n >\n <QueueMusicIcon />\n </Button>\n </div>\n <div>{isNotSmall && <ToggleFieldsMenu resource=\"playlistTrack\" />}</div>\n </div>\n </TopToolbar>\n )\n}\n\nPlaylistActions.propTypes = {\n record: PropTypes.object.isRequired,\n selectedIds: PropTypes.arrayOf(PropTypes.number),\n}\n\nPlaylistActions.defaultProps = {\n record: {},\n selectedIds: [],\n onUnselectItems: () => null,\n}\n\nexport default PlaylistActions\n","import React from 'react'\nimport {\n ReferenceManyField,\n ShowContextProvider,\n useShowContext,\n useShowController,\n Pagination,\n} from 'react-admin'\nimport { makeStyles } from '@material-ui/core/styles'\nimport PlaylistDetails from './PlaylistDetails'\nimport PlaylistSongs from './PlaylistSongs'\nimport PlaylistActions from './PlaylistActions'\nimport { Title, canChangeTracks } from '../common'\n\nconst useStyles = makeStyles(\n (theme) => ({\n playlistActions: {\n width: '100%',\n },\n }),\n {\n name: 'NDPlaylistShow',\n }\n)\n\nconst PlaylistShowLayout = (props) => {\n const { loading, ...context } = useShowContext(props)\n const { record } = context\n const classes = useStyles()\n\n return (\n <>\n {record && <PlaylistDetails {...context} />}\n {record && (\n <ReferenceManyField\n {...context}\n addLabel={false}\n reference=\"playlistTrack\"\n target=\"playlist_id\"\n sort={{ field: 'id', order: 'ASC' }}\n perPage={100}\n filter={{ playlist_id: props.id }}\n >\n <PlaylistSongs\n {...props}\n readOnly={!canChangeTracks(record)}\n title={<Title subTitle={record.name} />}\n actions={\n <PlaylistActions\n className={classes.playlistActions}\n record={record}\n />\n }\n resource={'playlistTrack'}\n exporter={false}\n pagination={<Pagination rowsPerPageOptions={[100, 250, 500]} />}\n />\n </ReferenceManyField>\n )}\n </>\n )\n}\n\nconst PlaylistShow = (props) => {\n const controllerProps = useShowController(props)\n return (\n <ShowContextProvider value={controllerProps}>\n <PlaylistShowLayout {...props} {...controllerProps} />\n </ShowContextProvider>\n )\n}\n\nexport default PlaylistShow\n","import React from 'react'\nimport QueueMusicOutlinedIcon from '@material-ui/icons/QueueMusicOutlined'\nimport QueueMusicIcon from '@material-ui/icons/QueueMusic'\nimport DynamicMenuIcon from '../layout/DynamicMenuIcon'\nimport PlaylistList from './PlaylistList'\nimport PlaylistEdit from './PlaylistEdit'\nimport PlaylistCreate from './PlaylistCreate'\nimport PlaylistShow from './PlaylistShow'\n\nexport default {\n list: PlaylistList,\n create: PlaylistCreate,\n edit: PlaylistEdit,\n show: PlaylistShow,\n icon: (\n <DynamicMenuIcon\n path={'playlist'}\n icon={QueueMusicOutlinedIcon}\n activeIcon={QueueMusicIcon}\n />\n ),\n}\n","import { makeStyles } from '@material-ui/core/styles'\n\nconst useStyle = makeStyles(\n (theme) => ({\n audioTitle: {\n textDecoration: 'none',\n color: theme.palette.primary.dark,\n },\n songTitle: {\n fontWeight: 'bold',\n '&:hover + $qualityInfo': {\n opacity: 1,\n },\n },\n songInfo: {\n display: 'block',\n marginTop: '2px',\n },\n songAlbum: {\n fontStyle: 'italic',\n fontSize: 'smaller',\n },\n qualityInfo: {\n marginTop: '-4px',\n opacity: 0,\n transition: 'all 500ms ease-out',\n },\n player: {\n display: (props) => (props.visible ? 'block' : 'none'),\n '@media screen and (max-width:810px)': {\n '& .sound-operation': {\n display: 'none',\n },\n },\n '& .progress-bar-content': {\n display: 'flex',\n flexDirection: 'column',\n },\n '& .play-mode-title': {\n 'pointer-events': 'none',\n },\n '& .music-player-panel .panel-content div.img-rotate': {\n // Customize desktop player when cover animation is disabled\n animationDuration: (props) => !props.enableCoverAnimation && '0s',\n borderRadius: (props) => !props.enableCoverAnimation && '0',\n // Fix cover display when image is not square\n backgroundSize: 'contain',\n backgroundPosition: 'center',\n },\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-cover':\n {\n // Customize mobile player when cover animation is disabled\n borderRadius: (props) => !props.enableCoverAnimation && '0',\n width: (props) => !props.enableCoverAnimation && '85%',\n maxWidth: (props) => !props.enableCoverAnimation && '600px',\n height: (props) => !props.enableCoverAnimation && 'auto',\n // Fix cover display when image is not square\n aspectRatio: '1/1',\n display: 'flex',\n },\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-cover img.cover':\n {\n animationDuration: (props) => !props.enableCoverAnimation && '0s',\n objectFit: 'contain', // Fix cover display when image is not square\n },\n // Hide old singer display\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-singer':\n {\n display: 'none',\n },\n // Hide extra whitespace from switch div\n '& .react-jinke-music-player-mobile .react-jinke-music-player-mobile-switch':\n {\n display: 'none',\n },\n },\n }),\n { name: 'NDAudioPlayer' }\n)\n\nexport default useStyle\n","import React from 'react'\nimport { useMediaQuery } from '@material-ui/core'\nimport { Link } from 'react-router-dom'\nimport clsx from 'clsx'\nimport { QualityInfo } from '../common'\nimport useStyle from './styles'\n\nconst AudioTitle = React.memo(({ audioInfo, isMobile }) => {\n const classes = useStyle()\n const className = classes.audioTitle\n const isDesktop = useMediaQuery('(min-width:810px)')\n\n if (!audioInfo.song) {\n return ''\n }\n\n const song = audioInfo.song\n const qi = { suffix: song.suffix, bitRate: song.bitRate }\n\n return (\n <Link to={`/album/${song.albumId}/show`} className={className}>\n <span>\n <span className={clsx(classes.songTitle, 'songTitle')}>\n {song.title}\n </span>\n {isDesktop && (\n <QualityInfo record={qi} className={classes.qualityInfo} />\n )}\n </span>\n {isMobile ? (\n <>\n <span className={classes.songInfo}>\n <span className={'songArtist'}>{song.artist}</span>\n </span>\n <span className={clsx(classes.songInfo, classes.songAlbum)}>\n <span className={'songAlbum'}>{song.album}</span>\n {song.year ? ` - ${song.year}` : ''}\n </span>\n </>\n ) : (\n <span className={classes.songInfo}>\n <span className={'songArtist'}>{song.artist}</span> -{' '}\n <span className={'songAlbum'}>{song.album}</span>\n {song.year ? ` - ${song.year}` : ''}\n </span>\n )}\n </Link>\n )\n})\n\nexport default AudioTitle\n","import React, { useCallback } from 'react'\nimport { useGetOne } from 'react-admin'\nimport { GlobalHotKeys } from 'react-hotkeys'\nimport { LoveButton, useToggleLove } from '../common'\nimport { keyMap } from '../hotkeys'\nimport config from '../config'\n\nconst Placeholder = () =>\n config.enableFavourites && <LoveButton disabled={true} resource={'song'} />\n\nconst Toolbar = ({ id }) => {\n const { data, loading } = useGetOne('song', id)\n const [toggleLove, toggling] = useToggleLove('song', data)\n\n const handlers = {\n TOGGLE_LOVE: useCallback(() => toggleLove(), [toggleLove]),\n }\n return (\n <>\n <GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />\n {config.enableFavourites && (\n <LoveButton\n record={data}\n resource={'song'}\n disabled={loading || toggling}\n />\n )}\n </>\n )\n}\n\nconst PlayerToolbar = ({ id }) => (id ? <Toolbar id={id} /> : <Placeholder />)\n\nexport default PlayerToolbar\n","const locale = (translate) => ({\n playListsText: translate('player.playListsText'),\n openText: translate('player.openText'),\n closeText: translate('player.closeText'),\n notContentText: translate('player.notContentText'),\n clickToPlayText: translate('player.clickToPlayText'),\n clickToPauseText: translate('player.clickToPauseText'),\n nextTrackText: translate('player.nextTrackText'),\n previousTrackText: translate('player.previousTrackText'),\n reloadText: translate('player.reloadText'),\n volumeText: translate('player.volumeText'),\n toggleLyricText: translate('player.toggleLyricText'),\n toggleMiniModeText: translate('player.toggleMiniModeText'),\n destroyText: translate('player.destroyText'),\n downloadText: translate('player.downloadText'),\n removeAudioListsText: translate('player.removeAudioListsText'),\n clickToDeleteText: (name) => translate('player.clickToDeleteText', { name }),\n emptyLyricText: translate('player.emptyLyricText'),\n playModeText: {\n order: translate('player.playModeText.order'),\n orderLoop: translate('player.playModeText.orderLoop'),\n singleLoop: translate('player.playModeText.singleLoop'),\n shufflePlay: translate('player.playModeText.shufflePlay'),\n },\n})\n\nexport default locale\n","const keyHandlers = (audioInstance, playerState) => {\n const nextSong = () => {\n const idx = playerState.queue.findIndex(\n (item) => item.uuid === playerState.current.uuid\n )\n return idx !== null ? playerState.queue[idx + 1] : null\n }\n\n const prevSong = () => {\n const idx = playerState.queue.findIndex(\n (item) => item.uuid === playerState.current.uuid\n )\n return idx !== null ? playerState.queue[idx - 1] : null\n }\n\n return {\n TOGGLE_PLAY: (e) => {\n e.preventDefault()\n audioInstance && audioInstance.togglePlay()\n },\n VOL_UP: () =>\n (audioInstance.volume = Math.min(1, audioInstance.volume + 0.1)),\n VOL_DOWN: () =>\n (audioInstance.volume = Math.max(0, audioInstance.volume - 0.1)),\n PREV_SONG: (e) => {\n if (!e.metaKey && prevSong()) audioInstance && audioInstance.playPrev()\n },\n\n NEXT_SONG: (e) => {\n if (!e.metaKey && nextSong()) audioInstance && audioInstance.playNext()\n },\n }\n}\n\nexport default keyHandlers\n","import React, { useCallback, useMemo, useState } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useMediaQuery } from '@material-ui/core'\nimport { ThemeProvider } from '@material-ui/core/styles'\nimport {\n createMuiTheme,\n useAuthState,\n useDataProvider,\n useTranslate,\n} from 'react-admin'\nimport ReactGA from 'react-ga'\nimport { GlobalHotKeys } from 'react-hotkeys'\nimport ReactJkMusicPlayer from 'react-jinke-music-player'\nimport 'react-jinke-music-player/assets/index.css'\nimport useCurrentTheme from '../themes/useCurrentTheme'\nimport config from '../config'\nimport useStyle from './styles'\nimport AudioTitle from './AudioTitle'\nimport { clearQueue, currentPlaying, setVolume, syncQueue } from '../actions'\nimport PlayerToolbar from './PlayerToolbar'\nimport { sendNotification } from '../utils'\nimport subsonic from '../subsonic'\nimport locale from './locale'\nimport { keyMap } from '../hotkeys'\nimport keyHandlers from './keyHandlers'\n\nconst Player = () => {\n const theme = useCurrentTheme()\n const translate = useTranslate()\n const playerTheme = theme.player?.theme || 'dark'\n const dataProvider = useDataProvider()\n const playerState = useSelector((state) => state.player)\n const dispatch = useDispatch()\n const [startTime, setStartTime] = useState(null)\n const [scrobbled, setScrobbled] = useState(false)\n const [preloaded, setPreload] = useState(false)\n const [audioInstance, setAudioInstance] = useState(null)\n const isDesktop = useMediaQuery('(min-width:810px)')\n const { authenticated } = useAuthState()\n const visible = authenticated && playerState.queue.length > 0\n const classes = useStyle({\n visible,\n enableCoverAnimation: config.enableCoverAnimation,\n })\n const showNotifications = useSelector(\n (state) => state.settings.notifications || false\n )\n\n const defaultOptions = useMemo(\n () => ({\n theme: playerTheme,\n bounds: 'body',\n mode: 'full',\n loadAudioErrorPlayNext: false,\n autoPlayInitLoadPlayList: true,\n clearPriorAudioLists: false,\n showDestroy: true,\n showDownload: false,\n showLyric: true,\n showReload: false,\n toggleMode: !isDesktop,\n glassBg: false,\n showThemeSwitch: false,\n showMediaSession: true,\n restartCurrentOnPrev: true,\n quietUpdate: true,\n defaultPosition: {\n top: 300,\n left: 120,\n },\n volumeFade: { fadeIn: 200, fadeOut: 200 },\n renderAudioTitle: (audioInfo, isMobile) => (\n <AudioTitle audioInfo={audioInfo} isMobile={isMobile} />\n ),\n locale: locale(translate),\n }),\n [isDesktop, playerTheme, translate]\n )\n\n const options = useMemo(() => {\n const current = playerState.current || {}\n return {\n ...defaultOptions,\n audioLists: playerState.queue.map((item) => item),\n playIndex: playerState.playIndex,\n autoPlay: playerState.clear || playerState.playIndex === 0,\n clearPriorAudioLists: playerState.clear,\n extendsContent: <PlayerToolbar id={current.trackId} />,\n defaultVolume: playerState.volume,\n }\n }, [playerState, defaultOptions])\n\n const onAudioListsChange = useCallback(\n (_, audioLists, audioInfo) => dispatch(syncQueue(audioInfo, audioLists)),\n [dispatch]\n )\n\n const nextSong = useCallback(() => {\n const idx = playerState.queue.findIndex(\n (item) => item.uuid === playerState.current.uuid\n )\n return idx !== null ? playerState.queue[idx + 1] : null\n }, [playerState])\n\n const onAudioProgress = useCallback(\n (info) => {\n if (info.ended) {\n document.title = '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 (!preloaded) {\n const next = nextSong()\n if (next != null) {\n const audio = new Audio()\n audio.src = next.musicSrc\n }\n setPreload(true)\n return\n }\n\n if (!scrobbled) {\n info.trackId && subsonic.scrobble(info.trackId, startTime)\n setScrobbled(true)\n }\n },\n [startTime, scrobbled, nextSong, preloaded]\n )\n\n const onAudioVolumeChange = useCallback(\n // sqrt to compensate for the logarithmic volume\n (volume) => dispatch(setVolume(Math.sqrt(volume))),\n [dispatch]\n )\n\n const onAudioPlay = useCallback(\n (info) => {\n dispatch(currentPlaying(info))\n if (startTime === null) {\n setStartTime(Date.now())\n }\n if (info.duration) {\n const song = info.song\n document.title = `${song.title} - ${song.artist} - Navidrome`\n subsonic.nowPlaying(info.trackId)\n setPreload(false)\n if (config.gaTrackingId) {\n ReactGA.event({\n category: 'Player',\n action: 'Play song',\n label: `${song.title} - ${song.artist}`,\n })\n }\n if (showNotifications) {\n sendNotification(\n song.title,\n `${song.artist} - ${song.album}`,\n info.cover\n )\n }\n }\n },\n [dispatch, showNotifications, startTime]\n )\n\n const onAudioPlayTrackChange = useCallback(() => {\n if (scrobbled) {\n setScrobbled(false)\n }\n if (startTime !== null) {\n setStartTime(null)\n }\n }, [scrobbled, startTime])\n\n const onAudioPause = useCallback(\n (info) => dispatch(currentPlaying(info)),\n [dispatch]\n )\n\n const onAudioEnded = useCallback(\n (currentPlayId, audioLists, info) => {\n setScrobbled(false)\n setStartTime(null)\n dispatch(currentPlaying(info))\n dataProvider\n .getOne('keepalive', { id: info.trackId })\n .catch((e) => console.log('Keepalive error:', e))\n },\n [dispatch, dataProvider]\n )\n\n const onCoverClick = useCallback((mode, audioLists, audioInfo) => {\n if (mode === 'full' && audioInfo?.song?.albumId) {\n window.location.href = `#/album/${audioInfo.song.albumId}/show`\n }\n }, [])\n\n const onBeforeDestroy = useCallback(() => {\n return new Promise((resolve, reject) => {\n dispatch(clearQueue())\n reject()\n })\n }, [dispatch])\n\n if (!visible) {\n document.title = '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 onAudioPlayTrackChange={onAudioPlayTrackChange}\n onAudioPause={onAudioPause}\n onAudioEnded={onAudioEnded}\n onCoverClick={onCoverClick}\n onBeforeDestroy={onBeforeDestroy}\n getAudioInstance={setAudioInstance}\n />\n <GlobalHotKeys handlers={handlers} keyMap={keyMap} allowChanges />\n </ThemeProvider>\n )\n}\n\nexport { Player }\n","import polyglotI18nProvider from 'ra-i18n-polyglot'\nimport deepmerge from 'deepmerge'\nimport dataProvider from '../dataProvider'\nimport en from './en.json'\nimport { i18nProvider } from './index'\n\n// Only returns current selected locale if its translations are found in localStorage\nconst defaultLocale = function () {\n const locale = localStorage.getItem('locale')\n const current = JSON.parse(localStorage.getItem('translation'))\n if (current && current.id === locale) {\n // Asynchronously reload the translation from the server\n retrieveTranslation(locale).then(() => {\n i18nProvider.changeLocale(locale)\n })\n return locale\n }\n return 'en'\n}\n\nfunction retrieveTranslation(locale) {\n return dataProvider.getOne('translation', { id: locale }).then((res) => {\n localStorage.setItem('translation', JSON.stringify(res.data))\n return prepareLanguage(JSON.parse(res.data.data))\n })\n}\n\nconst removeEmpty = (obj) => {\n for (let k in obj) {\n if (obj.hasOwnProperty(k) && typeof obj[k] === 'object') {\n removeEmpty(obj[k])\n } else {\n if (!obj[k]) {\n delete obj[k]\n }\n }\n }\n}\n\nconst prepareLanguage = (lang) => {\n removeEmpty(lang)\n // Make \"albumSong\" and \"playlistTrack\" resource use the same translations as \"song\"\n lang.resources.albumSong = lang.resources.song\n lang.resources.playlistTrack = lang.resources.song\n // ra.boolean.null should always be empty\n lang.ra.boolean.null = ''\n // Fallback to english translations\n return deepmerge(en, lang)\n}\n\nexport default polyglotI18nProvider((locale) => {\n // English is bundled\n if (locale === 'en') {\n return prepareLanguage(en)\n }\n // If the requested locale is in already loaded, return it\n const current = JSON.parse(localStorage.getItem('translation'))\n if (current && current.id === locale) {\n return prepareLanguage(JSON.parse(current.data))\n }\n // If not, get it from the server, and store it in localStorage\n return retrieveTranslation(locale)\n}, defaultLocale())\n","// React Hook to get a list of all languages available. English is hardcoded\nimport { useGetList } from 'react-admin'\n\nconst useGetLanguageChoices = () => {\n const { ids, data, loaded, loading } = useGetList(\n 'translation',\n { page: 1, perPage: -1 },\n { field: '', order: '' },\n {}\n )\n\n const choices = [{ id: 'en', name: 'English' }]\n if (loaded) {\n ids.forEach((id) => choices.push({ id: id, name: data[id].name }))\n }\n choices.sort((a, b) => a.name.localeCompare(b.name))\n\n return { choices, loaded, loading }\n}\n\nexport default useGetLanguageChoices\n","import HelpOutlineIcon from '@material-ui/icons/HelpOutline'\n\nexport const HelpMsg = ({ caption }) => (\n <>\n <HelpOutlineIcon />\n    {caption}\n </>\n)\n","import { SelectInput, useLocale, useSetLocale, useTranslate } from 'react-admin'\nimport { useGetLanguageChoices } from '../i18n'\nimport { HelpMsg } from './HelpMsg'\nimport { docsUrl, openInNewTab } from '../utils'\n\nconst helpKey = '_help'\n\nexport const SelectLanguage = (props) => {\n const translate = useTranslate()\n const setLocale = useSetLocale()\n const locale = useLocale()\n const { choices } = useGetLanguageChoices()\n\n choices.push({\n id: helpKey,\n name: <HelpMsg caption={'Help to translate'} />,\n })\n\n return (\n <SelectInput\n {...props}\n source=\"language\"\n label={translate('menu.personal.options.language')}\n defaultValue={locale}\n choices={choices}\n translateChoice={false}\n onChange={(event) => {\n if (event.target.value === helpKey) {\n openInNewTab(docsUrl('/docs/developers/translations/'))\n return\n }\n setLocale(event.target.value).then(() => {\n localStorage.setItem('locale', event.target.value)\n })\n }}\n />\n )\n}\n","import { SelectInput, useTranslate } from 'react-admin'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { AUTO_THEME_ID } from '../consts'\nimport themes from '../themes'\nimport { HelpMsg } from './HelpMsg'\nimport { docsUrl, openInNewTab } from '../utils'\nimport { changeTheme } from '../actions'\n\nconst helpKey = '_help'\n\nexport const SelectTheme = (props) => {\n const translate = useTranslate()\n const dispatch = useDispatch()\n const currentTheme = useSelector((state) => state.theme)\n const themeChoices = [\n {\n id: AUTO_THEME_ID,\n name: 'Auto',\n },\n ]\n themeChoices.push(\n ...Object.keys(themes).map((key) => {\n return { id: key, name: themes[key].themeName }\n })\n )\n themeChoices.push({\n id: helpKey,\n name: <HelpMsg caption={'Create your own'} />,\n })\n return (\n <SelectInput\n {...props}\n source=\"theme\"\n label={translate('menu.personal.options.theme')}\n defaultValue={currentTheme}\n translateChoice={false}\n choices={themeChoices}\n onChange={(event) => {\n if (event.target.value === helpKey) {\n openInNewTab(docsUrl('/docs/developers/creating-themes/'))\n return\n }\n dispatch(changeTheme(event.target.value))\n }}\n />\n )\n}\n","import { SelectInput, useTranslate } from 'react-admin'\nimport albumLists, { defaultAlbumList } from '../album/albumLists'\n\nexport const SelectDefaultView = (props) => {\n const translate = useTranslate()\n const current = localStorage.getItem('defaultView') || defaultAlbumList\n const choices = Object.keys(albumLists).map((type) => ({\n id: type,\n name: translate(`resources.album.lists.${type}`),\n }))\n\n return (\n <SelectInput\n {...props}\n source=\"defaultView\"\n label={translate('menu.personal.options.defaultView')}\n defaultValue={current}\n choices={choices}\n translateChoice={false}\n onChange={(event) => {\n localStorage.setItem('defaultView', event.target.value)\n }}\n />\n )\n}\n","import { useNotify, useTranslate } from 'react-admin'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { setNotificationsState } from '../actions'\nimport {\n FormControl,\n FormControlLabel,\n FormHelperText,\n Switch,\n} from '@material-ui/core'\n\nexport const NotificationsToggle = () => {\n const translate = useTranslate()\n const dispatch = useDispatch()\n const notify = useNotify()\n const currentSetting = useSelector((state) => state.settings.notifications)\n const notAvailable = !('Notification' in window) || !window.isSecureContext\n\n if (\n (currentSetting && Notification.permission !== 'granted') ||\n notAvailable\n ) {\n dispatch(setNotificationsState(false))\n }\n\n const toggleNotifications = (event) => {\n if (currentSetting && !event.target.checked) {\n dispatch(setNotificationsState(false))\n } else {\n if (Notification.permission === 'denied') {\n notify(translate('message.notifications_blocked'), 'warning')\n } else {\n Notification.requestPermission().then((permission) => {\n dispatch(setNotificationsState(permission === 'granted'))\n })\n }\n }\n }\n\n return (\n <FormControl>\n <FormControlLabel\n control={\n <Switch\n id={'notifications'}\n color=\"primary\"\n checked={currentSetting}\n disabled={notAvailable}\n onChange={toggleNotifications}\n />\n }\n label={\n <span>\n {translate('menu.personal.options.desktop_notifications')}\n </span>\n }\n />\n {notAvailable && (\n <FormHelperText id=\"notifications-disabled-helper-text\">\n {translate('message.notifications_not_available')}\n </FormHelperText>\n )}\n </FormControl>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { useNotify, useTranslate } from 'react-admin'\nimport {\n FormControl,\n FormControlLabel,\n LinearProgress,\n Switch,\n} from '@material-ui/core'\nimport { useInterval } from '../common'\nimport config from '../config'\nimport { baseUrl, openInNewTab } from '../utils'\nimport { httpClient } from '../dataProvider'\n\nconst Progress = (props) => {\n const { setLinked, setCheckingLink } = props\n const notify = useNotify()\n let linkCheckDelay = 2000\n let linkChecks = 30\n const openedTab = useRef()\n\n useEffect(() => {\n const callbackEndpoint = baseUrl(\n `/api/lastfm/link/callback?uid=${localStorage.getItem('userId')}`\n )\n const callbackUrl = `${window.location.origin}${callbackEndpoint}`\n openedTab.current = openInNewTab(\n `https://www.last.fm/api/auth/?api_key=${config.lastFMApiKey}&cb=${callbackUrl}`\n )\n }, [])\n\n const endChecking = (success) => {\n linkCheckDelay = null\n setCheckingLink(false)\n if (success) {\n notify('message.lastfmLinkSuccess', 'success')\n } else {\n notify('message.lastfmLinkFailure', 'warning')\n }\n setLinked(success)\n }\n\n useInterval(() => {\n httpClient('/api/lastfm/link')\n .then((response) => {\n let result = false\n if (response.json.status === true) {\n result = true\n endChecking(true)\n }\n return result\n })\n .then((result) => {\n if (!result && openedTab.current?.closed === true) {\n endChecking(false)\n result = true\n }\n return result\n })\n .then((result) => {\n if (!result && --linkChecks === 0) {\n endChecking(false)\n }\n })\n .catch(() => {\n endChecking(false)\n })\n }, linkCheckDelay)\n\n return <LinearProgress />\n}\n\nexport const LastfmScrobbleToggle = (props) => {\n const notify = useNotify()\n const translate = useTranslate()\n const [linked, setLinked] = useState(null)\n const [checkingLink, setCheckingLink] = useState(false)\n\n const toggleScrobble = () => {\n if (!linked) {\n setCheckingLink(true)\n } else {\n httpClient('/api/lastfm/link', { method: 'DELETE' })\n .then(() => {\n setLinked(false)\n notify('message.lastfmUnlinkSuccess', 'success')\n })\n .catch(() => notify('message.lastfmUnlinkFailure', 'warning'))\n }\n }\n\n useEffect(() => {\n httpClient('/api/lastfm/link')\n .then((response) => {\n setLinked(response.json.status === true)\n })\n .catch(() => {\n setLinked(false)\n })\n }, [])\n\n return (\n <FormControl>\n <FormControlLabel\n control={\n <Switch\n id={'lastfm'}\n color=\"primary\"\n checked={linked || checkingLink}\n disabled={linked === null || checkingLink}\n onChange={toggleScrobble}\n />\n }\n label={\n <span>{translate('menu.personal.options.lastfmScrobbling')}</span>\n }\n />\n {checkingLink && (\n <Progress setLinked={setLinked} setCheckingLink={setCheckingLink} />\n )}\n </FormControl>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { useNotify, useTranslate } from 'react-admin'\nimport { FormControl, FormControlLabel, Switch } from '@material-ui/core'\nimport { httpClient } from '../dataProvider'\nimport { ListenBrainzTokenDialog } from '../dialogs'\nimport { useDispatch } from 'react-redux'\nimport { openListenBrainzTokenDialog } from '../actions'\n\nexport const ListenBrainzScrobbleToggle = () => {\n const dispatch = useDispatch()\n const notify = useNotify()\n const translate = useTranslate()\n const [linked, setLinked] = useState(null)\n\n const toggleScrobble = () => {\n if (linked) {\n httpClient('/api/listenbrainz/link', { method: 'DELETE' })\n .then(() => {\n setLinked(false)\n notify('message.listenBrainzUnlinkSuccess', 'success')\n })\n .catch(() => notify('message.listenBrainzUnlinkFailure', 'warning'))\n } else {\n dispatch(openListenBrainzTokenDialog())\n }\n }\n\n useEffect(() => {\n httpClient('/api/listenbrainz/link')\n .then((response) => {\n setLinked(response.json.status === true)\n })\n .catch(() => {\n setLinked(false)\n })\n }, [])\n\n return (\n <>\n <FormControl>\n <FormControlLabel\n control={\n <Switch\n id={'listenbrainz'}\n color=\"primary\"\n checked={linked === true}\n disabled={linked === null}\n onChange={toggleScrobble}\n />\n }\n label={\n <span>\n {translate('menu.personal.options.listenBrainzScrobbling')}\n </span>\n }\n />\n </FormControl>\n <ListenBrainzTokenDialog setLinked={setLinked} />\n </>\n )\n}\n","import { SimpleForm, Title, useTranslate } from 'react-admin'\nimport { Card } from '@material-ui/core'\nimport { makeStyles } from '@material-ui/core/styles'\nimport { SelectLanguage } from './SelectLanguage'\nimport { SelectTheme } from './SelectTheme'\nimport { SelectDefaultView } from './SelectDefaultView'\nimport { NotificationsToggle } from './NotificationsToggle'\nimport { LastfmScrobbleToggle } from './LastfmScrobbleToggle'\nimport { ListenBrainzScrobbleToggle } from './ListenBrainzScrobbleToggle'\nimport config from '../config'\n\nconst useStyles = makeStyles({\n root: { marginTop: '1em' },\n})\n\nconst Personal = () => {\n const translate = useTranslate()\n const classes = useStyles()\n\n return (\n <Card className={classes.root}>\n <Title title={'Navidrome - ' + translate('menu.personal.name')} />\n <SimpleForm toolbar={null} variant={'outlined'}>\n <SelectTheme />\n <SelectLanguage />\n <SelectDefaultView />\n <NotificationsToggle />\n {config.lastFMEnabled && <LastfmScrobbleToggle />}\n {config.listenBrainzEnabled && <ListenBrainzScrobbleToggle />}\n </SimpleForm>\n </Card>\n )\n}\n\nexport default Personal\n","import React from 'react'\nimport { Route } from 'react-router-dom'\nimport Personal from './personal/Personal'\n\nconst routes = [<Route exact path=\"/personal\" render={() => <Personal />} />]\n\nexport default routes\n","import { CHANGE_THEME } from '../actions'\nimport config from '../config'\nimport themes from '../themes'\n\nconst defaultTheme = () => {\n return (\n Object.keys(themes).find(\n (t) => themes[t].themeName === config.defaultTheme\n ) || 'DarkTheme'\n )\n}\n\nexport const themeReducer = (\n previousState = defaultTheme(),\n { type, payload }\n) => {\n if (type === CHANGE_THEME) {\n return payload\n }\n return previousState\n}\n","import {\n ADD_TO_PLAYLIST_CLOSE,\n ADD_TO_PLAYLIST_OPEN,\n DUPLICATE_SONG_WARNING_OPEN,\n DUPLICATE_SONG_WARNING_CLOSE,\n EXTENDED_INFO_OPEN,\n EXTENDED_INFO_CLOSE,\n LISTENBRAINZ_TOKEN_OPEN,\n LISTENBRAINZ_TOKEN_CLOSE,\n} from '../actions'\n\nexport const addToPlaylistDialogReducer = (\n previousState = {\n open: false,\n duplicateSong: false,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case ADD_TO_PLAYLIST_OPEN:\n return {\n ...previousState,\n open: true,\n selectedIds: payload.selectedIds,\n onSuccess: payload.onSuccess,\n }\n case ADD_TO_PLAYLIST_CLOSE:\n return { ...previousState, open: false, onSuccess: undefined }\n case DUPLICATE_SONG_WARNING_OPEN:\n return {\n ...previousState,\n duplicateSong: true,\n duplicateIds: payload.duplicateIds,\n }\n case DUPLICATE_SONG_WARNING_CLOSE:\n return { ...previousState, duplicateSong: false }\n default:\n return previousState\n }\n}\n\nexport const expandInfoDialogReducer = (\n previousState = {\n open: false,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case EXTENDED_INFO_OPEN:\n return {\n ...previousState,\n open: true,\n record: payload.record,\n }\n case EXTENDED_INFO_CLOSE:\n return {\n ...previousState,\n open: false,\n }\n default:\n return previousState\n }\n}\n\nexport const listenBrainzTokenDialogReducer = (\n previousState = {\n open: false,\n },\n payload\n) => {\n const { type } = payload\n switch (type) {\n case LISTENBRAINZ_TOKEN_OPEN:\n return {\n ...previousState,\n open: true,\n }\n case LISTENBRAINZ_TOKEN_CLOSE:\n return {\n ...previousState,\n open: false,\n }\n default:\n return previousState\n }\n}\n","import { v4 as uuidv4 } from 'uuid'\nimport subsonic from '../subsonic'\nimport {\n PLAYER_ADD_TRACKS,\n PLAYER_CLEAR_QUEUE,\n PLAYER_CURRENT,\n PLAYER_PLAY_NEXT,\n PLAYER_PLAY_TRACKS,\n PLAYER_SET_TRACK,\n PLAYER_SET_VOLUME,\n PLAYER_SYNC_QUEUE,\n} from '../actions'\nimport config from '../config'\n\nconst initialState = {\n queue: [],\n current: {},\n clear: false,\n volume: 0.5, // 50%\n savedPlayIndex: 0,\n}\n\nconst mapToAudioLists = (item) => {\n // If item comes from a playlist, trackId is mediaFileId\n const trackId = item.mediaFileId || item.id\n const { lyrics } = item\n const timestampRegex =\n /(\\[([0-9]{1,2}:)?([0-9]{1,2}:)([0-9]{1,2})(\\.[0-9]{1,2})?\\])/g\n return {\n trackId,\n uuid: uuidv4(),\n song: item,\n name: item.title,\n lyric: timestampRegex.test(lyrics) ? lyrics : '',\n singer: item.artist,\n duration: item.duration,\n musicSrc: subsonic.streamUrl(trackId),\n cover: subsonic.getCoverArtUrl(\n {\n coverArtId: config.devFastAccessCoverArt ? item.albumId : trackId,\n updatedAt: item.updatedAt,\n },\n 300\n ),\n }\n}\n\nconst reduceClearQueue = () => ({ ...initialState, clear: true })\n\nconst reducePlayTracks = (state, { data, id }) => {\n let playIndex = 0\n const queue = Object.keys(data).map((key, idx) => {\n if (key === id) {\n playIndex = idx\n }\n return mapToAudioLists(data[key])\n })\n return {\n ...state,\n queue,\n playIndex,\n clear: true,\n }\n}\n\nconst reduceSetTrack = (state, { data }) => {\n return {\n ...state,\n queue: [mapToAudioLists(data)],\n playIndex: 0,\n clear: true,\n }\n}\n\nconst reduceAddTracks = (state, { data }) => {\n const queue = state.queue\n Object.keys(data).forEach((id) => {\n queue.push(mapToAudioLists(data[id]))\n })\n return { ...state, queue, clear: false }\n}\n\nconst reducePlayNext = (state, { data }) => {\n const newQueue = []\n const current = state.current || {}\n let foundPos = false\n state.queue.forEach((item) => {\n newQueue.push(item)\n if (item.uuid === current.uuid) {\n foundPos = true\n Object.keys(data).forEach((id) => {\n newQueue.push(mapToAudioLists(data[id]))\n })\n }\n })\n if (!foundPos) {\n Object.keys(data).forEach((id) => {\n newQueue.push(mapToAudioLists(data[id]))\n })\n }\n\n return {\n ...state,\n queue: newQueue,\n clear: true,\n }\n}\n\nconst reduceSetVolume = (state, { data: { volume } }) => {\n return {\n ...state,\n volume,\n }\n}\n\nconst reduceSyncQueue = (state, { data: { audioInfo, audioLists } }) => {\n return {\n ...state,\n queue: audioLists,\n clear: false,\n playIndex: undefined,\n }\n}\n\nconst reduceCurrent = (state, { data }) => {\n const current = data.ended ? {} : data\n const savedPlayIndex = state.queue.findIndex(\n (item) => item.uuid === current.uuid\n )\n return {\n ...state,\n current,\n playIndex: undefined,\n savedPlayIndex,\n volume: data.volume,\n }\n}\n\nexport const playerReducer = (previousState = initialState, payload) => {\n const { type } = payload\n switch (type) {\n case PLAYER_CLEAR_QUEUE:\n return reduceClearQueue()\n case PLAYER_PLAY_TRACKS:\n return reducePlayTracks(previousState, payload)\n case PLAYER_SET_TRACK:\n return reduceSetTrack(previousState, payload)\n case PLAYER_ADD_TRACKS:\n return reduceAddTracks(previousState, payload)\n case PLAYER_PLAY_NEXT:\n return reducePlayNext(previousState, payload)\n case PLAYER_SET_VOLUME:\n return reduceSetVolume(previousState, payload)\n case PLAYER_SYNC_QUEUE:\n return reduceSyncQueue(previousState, payload)\n case PLAYER_CURRENT:\n return reduceCurrent(previousState, payload)\n default:\n return previousState\n }\n}\n","import { 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 expandInfoDialogReducer,\n listenBrainzTokenDialogReducer,\n playerReducer,\n albumViewReducer,\n activityReducer,\n settingsReducer,\n} from './reducers'\nimport createAdminStore from './store/createAdminStore'\nimport { i18nProvider } from './i18n'\nimport config from './config'\nimport { setDispatch, startEventStream } 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 expandInfoDialog: expandInfoDialogReducer,\n listenBrainzTokenDialog: listenBrainzTokenDialogReducer,\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\n name=\"playlist\"\n {...playlist}\n options={{ subMenu: 'playlist' }}\n />,\n <Resource name=\"user\" {...user} options={{ subMenu: 'settings' }} />,\n <Resource\n name=\"player\"\n {...player}\n options={{ subMenu: 'settings' }}\n />,\n permissions === 'admin' ? (\n <Resource\n name=\"transcoding\"\n {...transcoding}\n options={{ subMenu: 'settings' }}\n />\n ) : (\n <Resource name=\"transcoding\" />\n ),\n <Resource name=\"translation\" />,\n <Resource name=\"genre\" />,\n <Resource name=\"playlistTrack\" />,\n <Resource name=\"keepalive\" />,\n <Player />,\n ]}\n </RAAdmin>\n )\n}\n\nconst AppWithHotkeys = () => (\n <HotKeys keyMap={keyMap}>\n <App />\n </HotKeys>\n)\n\nexport default AppWithHotkeys\n","// 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":""}