import React from "react" import * as antd from "antd" import classnames from "classnames" import { Translation } from "react-i18next" import Searcher from "components/Searcher" import { Icons, createIconRender } from "components/Icons" import { WithPlayerContext } from "contexts/WithPlayerContext" import FeedModel from "models/feed" import MusicModel from "models/music" import MusicTrack from "components/Music/Track" import PlaylistItem from "components/Music/PlaylistItem" import "./index.less" const MusicNavbar = (props) => { return
props.setSearchResults(false)} />
} const PlaylistsList = (props) => { const hopNumber = props.hopsPerPage ?? 6 const [offset, setOffset] = React.useState(0) const [ended, setEnded] = React.useState(false) const [loading, result, error, makeRequest] = app.cores.api.useRequest(props.fetchMethod, { limit: hopNumber, trim: offset }) const onClickPrev = () => { if (offset === 0) { return } setOffset((value) => { const newOffset = value - hopNumber // check if newOffset is NaN if (newOffset !== newOffset) { return false } if (typeof makeRequest === "function") { makeRequest({ trim: newOffset, limit: hopNumber, }) } return newOffset }) } const onClickNext = () => { if (ended) { return } setOffset((value) => { const newOffset = value + hopNumber // check if newOffset is NaN if (newOffset !== newOffset) { return false } if (typeof makeRequest === "function") { makeRequest({ trim: newOffset, limit: hopNumber, }) } return newOffset }) } React.useEffect(() => { if (result) { setEnded(result.length < hopNumber) } }, [result]) if (error) { console.error(error) return
} return

{ props.headerIcon } {(t) => t(props.headerTitle)}

} onClick={onClickPrev} disabled={offset === 0 || loading} /> } onClick={onClickNext} disabled={ended || loading} />
{ loading && } { !loading && result.map((playlist, index) => { return }) }
} const ResultGroupsDecorators = { "playlists": { icon: "MdPlaylistPlay", label: "Playlists", renderItem: (props) => { return } }, "tracks": { icon: "MdMusicNote", label: "Tracks", renderItem: (props) => { return app.cores.player.start(props.item)} onClick={() => app.location.push(`/play/${props.item._id}`)} /> } } } const SearchResults = ({ data }) => { if (typeof data !== "object") { return null } let groupsKeys = Object.keys(data) // filter out empty groups groupsKeys = groupsKeys.filter((key) => { return data[key].length > 0 }) if (groupsKeys.length === 0) { return
} return
{ groupsKeys.map((key, index) => { const decorator = ResultGroupsDecorators[key] ?? { icon: null, label: key, renderItem: () => null } return

{ createIconRender(decorator.icon) } {(t) => t(decorator.label)}

{ data[key].map((item, index) => { return decorator.renderItem({ key: index, item }) }) }
}) }
} export default (props) => { const [searchResults, setSearchResults] = React.useState(false) React.useEffect(() => { app.layout.toggleCenteredContent(true) app.layout.page_panels.attachComponent("music_navbar", MusicNavbar, { props: { setSearchResults: setSearchResults, } }) return () => { if (app.layout.page_panels) { app.layout.page_panels.detachComponent("music_navbar") } } }, []) return
{ app.isMobile && setSearchResults(false)} /> } { searchResults && } { !searchResults &&
} fetchMethod={FeedModel.getMusicFeed} /> } fetchMethod={FeedModel.getGlobalMusicFeed} />
}
}