import React from "react" import * as antd from "antd" import classnames from "classnames" import { Translation } from "react-i18next" import Searcher from "components/Searcher" import { ImageViewer, UserPreview } from "components" import { Icons, createIconRender } from "components/Icons" import { WithPlayerContext } from "contexts/WithPlayerContext" import FeedModel from "models/feed" import PlaylistModel from "models/playlists" import MusicTrack from "components/MusicTrack" import "./index.less" 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 PlaylistItem = (props) => { const [coverHover, setCoverHover] = React.useState(false) const { playlist } = props const onClick = () => { if (typeof props.onClick === "function") { return props.onClick(playlist) } return app.setLocation(`/play/${playlist._id}`) } const onClickPlay = (e) => { e.stopPropagation() app.cores.player.startPlaylist(playlist.list) } return
setCoverHover(true)} onMouseLeave={() => setCoverHover(false)} onClick={onClickPlay} >

{playlist.title}

{ playlist.publisher && }
} const RecentlyPlayed = (props) => { return

{(t) => t("Recently Played")}

} const MayLike = (props) => { return

{(t) => t("May you like")}

} const ResultGroupsDecorators = { "playlists": { icon: "MdPlaylistPlay", label: "Playlists", renderItem: (props) => { return } }, "tracks": { icon: "MdMusicNote", label: "Tracks", renderItem: (props) => { return app.cores.player.start(props.item)} /> } } } 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) return
setSearchResults(false)} /> { searchResults && } { !searchResults &&
} fetchMethod={FeedModel.getPlaylistsFeed} /> } fetchMethod={FeedModel.getGlobalMusicFeed} />
}
}