diff --git a/packages/app/src/pages/music/tabs/explore/components/Navbar/index.jsx b/packages/app/src/pages/music/tabs/explore/components/Navbar/index.jsx index 0150a3bf..0d1cd58c 100644 --- a/packages/app/src/pages/music/tabs/explore/components/Navbar/index.jsx +++ b/packages/app/src/pages/music/tabs/explore/components/Navbar/index.jsx @@ -1,18 +1,22 @@ import React from "react" import Searcher from "@components/Searcher" -import MusicModel from "@models/music" +import SearchModel from "@models/search" const MusicNavbar = (props) => { - return
- props.setSearchResults(false)} - /> -
+ return ( +
+ + SearchModel.search(keywords, params, ["tracks"]) + } + onSearchResult={props.setSearchResults} + onEmpty={() => props.setSearchResults(false)} + /> +
+ ) } -export default MusicNavbar \ No newline at end of file +export default MusicNavbar diff --git a/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.jsx b/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.jsx index 4474e04e..5ce9bdc4 100644 --- a/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.jsx +++ b/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.jsx @@ -1,12 +1,66 @@ import React from "react" +import * as antd from "antd" + +import Image from "@components/Image" import { Icons } from "@components/Icons" +import MusicModel from "@models/music" import "./index.less" +const RecentlyPlayedItem = (props) => { + const { track } = props + + return
app.cores.player.start(track._id)} + > +
+ +
+ +
+ +
+ +
+

{track.title}

+
+
+} + const RecentlyPlayedList = (props) => { + const [L_Tracks, R_Tracks, E_Tracks, M_Tracks] = app.cores.api.useRequest(MusicModel.getRecentyPlayed, { + limit: 7 + }) + + if (E_Tracks) { + return null + } + return
-

Recently played

+

Recently played

+
+ +
+ { + L_Tracks && + } + + { + !L_Tracks &&
+ { + R_Tracks.map((track, index) => { + return + }) + } +
+ }
} diff --git a/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.less b/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.less index c964fc53..4314214f 100644 --- a/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.less +++ b/packages/app/src/pages/music/tabs/explore/components/RecentlyPlayedList/index.less @@ -14,4 +14,95 @@ font-size: 1rem; } + + .recently_played-content { + display: flex; + flex-direction: column; + + overflow: hidden; + overflow-x: scroll; + + padding: 0 20px; + + .recently_played-content-items { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: auto; + grid-column-gap: 20px; + grid-row-gap: 20px; + } + } +} + +.recently_played-item { + position: relative; + + z-index: 50; + + display: flex; + flex-direction: row; + + width: 100%; + height: 100px; + + overflow: hidden; + + background-color: var(--background-color-accent); + border-radius: 12px; + + cursor: pointer; + + &:hover { + .recently_played-item-icon { + opacity: 1; + } + + .recently_played-item-cover { + opacity: 0.1; + } + } + + .recently_played-item-icon { + z-index: 55; + position: absolute; + display: flex; + + flex-direction: column; + align-items: center; + justify-content: center; + + width: 100%; + height: 100%; + + opacity: 0; + + font-size: 3rem; + + transition: all 150ms ease-in-out; + } + + .recently_played-item-cover { + position: absolute; + + z-index: 50; + + width: 100%; + height: 100%; + + opacity: 0.5; + + transition: all 150ms ease-in-out; + + img { + width: 100%; + height: 100%; + + object-fit: cover; + } + } + + .recently_played-item-content { + z-index: 55; + padding: 10px; + } } \ No newline at end of file diff --git a/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.jsx b/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.jsx index df46425b..e201b4e9 100644 --- a/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.jsx +++ b/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.jsx @@ -3,130 +3,127 @@ import * as antd from "antd" import { Translation } from "react-i18next" import { Icons } from "@components/Icons" -import PlaylistItem from "@components/Music/PlaylistItem" +import Playlist from "@components/Music/Playlist" import "./index.less" const ReleasesList = (props) => { - const hopNumber = props.hopsPerPage ?? 6 + const hopNumber = props.hopsPerPage ?? 9 - const [offset, setOffset] = React.useState(0) - const [ended, setEnded] = React.useState(false) + 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 [loading, result, error, makeRequest] = app.cores.api.useRequest( + props.fetchMethod, + { + limit: hopNumber, + trim: offset, + }, + ) - const onClickPrev = () => { - if (offset === 0) { - return - } + const onClickPrev = () => { + if (offset === 0) { + return + } - setOffset((value) => { - const newOffset = value - hopNumber + setOffset((value) => { + const newOffset = value - hopNumber - // check if newOffset is NaN - if (newOffset !== newOffset) { - return false - } + // check if newOffset is NaN + if (newOffset !== newOffset) { + return false + } - if (typeof makeRequest === "function") { - makeRequest({ - trim: newOffset, - limit: hopNumber, - }) - } + if (typeof makeRequest === "function") { + makeRequest({ + trim: newOffset, + limit: hopNumber, + }) + } - return newOffset - }) - } + return newOffset + }) + } - const onClickNext = () => { - if (ended) { - return - } + const onClickNext = () => { + if (ended) { + return + } - setOffset((value) => { - const newOffset = value + hopNumber + setOffset((value) => { + const newOffset = value + hopNumber - // check if newOffset is NaN - if (newOffset !== newOffset) { - return false - } + // check if newOffset is NaN + if (newOffset !== newOffset) { + return false + } - if (typeof makeRequest === "function") { - makeRequest({ - trim: newOffset, - limit: hopNumber, - }) - } + if (typeof makeRequest === "function") { + makeRequest({ + trim: newOffset, + limit: hopNumber, + }) + } - return newOffset - }) - } + return newOffset + }) + } - React.useEffect(() => { - if (result) { - if (typeof result.has_more !== "undefined") { - setEnded(!result.has_more) - } else { - setEnded(result.items.length < hopNumber) - } - } - }, [result]) + React.useEffect(() => { + if (result) { + if (typeof result.has_more !== "undefined") { + setEnded(!result.has_more) + } else { + setEnded(result.items.length < hopNumber) + } + } + }, [result]) - if (error) { - console.error(error) + if (error) { + console.error(error) - return
- -
- } + return ( +
+ +
+ ) + } - return
-
-

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

+ return ( +
+
+

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

-
- } - onClick={onClickPrev} - disabled={offset === 0 || loading} - /> +
+ } + onClick={onClickPrev} + disabled={offset === 0 || loading} + /> - } - onClick={onClickNext} - disabled={ended || loading} - /> -
-
-
- { - loading && - } - { - !loading && result.items.map((playlist, index) => { - return - }) - } -
-
+ } + onClick={onClickNext} + disabled={ended || loading} + /> +
+
+
+ {loading && } + {!loading && + result.items.map((playlist, index) => { + return + })} +
+
+ ) } -export default ReleasesList \ No newline at end of file +export default ReleasesList diff --git a/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.less b/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.less index 7ec79333..a0a11241 100644 --- a/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.less +++ b/packages/app/src/pages/music/tabs/explore/components/ReleasesList/index.less @@ -1,52 +1,63 @@ .music-releases-list { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; - overflow-x: visible; + overflow-x: visible; - .music-releases-list-header { - display: flex; - flex-direction: row; + .music-releases-list-header { + display: flex; + flex-direction: row; - align-items: center; + align-items: center; - margin-bottom: 20px; + margin-bottom: 20px; - h1 { - font-size: 1.5rem; - margin: 0; - } + h1 { + font-size: 1.5rem; + margin: 0; + } - .music-releases-list-actions { - display: flex; - flex-direction: row; + .music-releases-list-actions { + display: flex; + flex-direction: row; - gap: 10px; + gap: 10px; - align-self: center; + align-self: center; - margin-left: auto; - } - } + margin-left: auto; + } + } - .music-releases-list-items { - display: grid; + .music-releases-list-items { + display: grid; - grid-gap: 20px; - grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-gap: 20px; + grid-template-columns: repeat(2, 1fr); - min-width: 372px !important; + @media (min-width: 768px) { + grid-template-columns: repeat(3, 1fr); + } - @media (min-width: 2000px) { - grid-template-columns: repeat(4, 1fr); - } + @media (min-width: 1000px) { + grid-template-columns: repeat(4, 1fr); + } - @media (min-width: 2300px) { - grid-template-columns: repeat(5, 1fr); - } + @media (min-width: 1500px) { + grid-template-columns: repeat(7, 1fr); + } - .playlistItem { - justify-self: center; - } - } -} \ No newline at end of file + @media (min-width: 1600px) { + grid-template-columns: repeat(7, 1fr); + } + + @media (min-width: 1920px) { + grid-template-columns: repeat(9, 1fr); + } + + .playlist { + justify-self: center; + //min-width: 372px !important; + } + } +} diff --git a/packages/app/src/pages/music/tabs/explore/components/SearchResults/index.jsx b/packages/app/src/pages/music/tabs/explore/components/SearchResults/index.jsx index b082ee28..fcb1f510 100644 --- a/packages/app/src/pages/music/tabs/explore/components/SearchResults/index.jsx +++ b/packages/app/src/pages/music/tabs/explore/components/SearchResults/index.jsx @@ -5,14 +5,14 @@ import { Translation } from "react-i18next" import { createIconRender } from "@components/Icons" import MusicTrack from "@components/Music/Track" -import PlaylistItem from "@components/Music/PlaylistItem" +import Playlist from "@components/Music/Playlist" const ResultGroupsDecorators = { "playlists": { icon: "MdPlaylistPlay", label: "Playlists", renderItem: (props) => { - return @@ -41,9 +41,18 @@ const SearchResults = ({ let groupsKeys = Object.keys(data) - // filter out empty groups + // filter out groups with no items array property groupsKeys = groupsKeys.filter((key) => { - return data[key].length > 0 + if (!Array.isArray(data[key].items)) { + return false + } + + return true + }) + + // filter out groups with empty items array + groupsKeys = groupsKeys.filter((key) => { + return data[key].items.length > 0 }) if (groupsKeys.length === 0) { @@ -86,7 +95,7 @@ const SearchResults = ({
{ - data[key].map((item, index) => { + data[key].items.map((item, index) => { return decorator.renderItem({ key: index, item diff --git a/packages/app/src/pages/music/tabs/explore/index.jsx b/packages/app/src/pages/music/tabs/explore/index.jsx index 9dc85f79..55858ba1 100755 --- a/packages/app/src/pages/music/tabs/explore/index.jsx +++ b/packages/app/src/pages/music/tabs/explore/index.jsx @@ -1,11 +1,13 @@ import React from "react" import classnames from "classnames" +import useCenteredContainer from "@hooks/useCenteredContainer" + import Searcher from "@components/Searcher" import { Icons } from "@components/Icons" import FeedModel from "@models/feed" -import MusicModel from "@models/music" +import SearchModel from "@models/search" import Navbar from "./components/Navbar" import RecentlyPlayedList from "./components/RecentlyPlayedList" @@ -15,12 +17,12 @@ import FeaturedPlaylist from "./components/FeaturedPlaylist" import "./index.less" - const MusicExploreTab = (props) => { +const MusicExploreTab = (props) => { const [searchResults, setSearchResults] = React.useState(false) - React.useEffect(() => { - app.layout.toggleCenteredContent(true) + useCenteredContainer(false) + React.useEffect(() => { app.layout.page_panels.attachComponent("music_navbar", Navbar, { props: { setSearchResults: setSearchResults, @@ -43,7 +45,7 @@ import "./index.less" app.isMobile && SearchModel.search("music", keywords, params)} onSearchResult={setSearchResults} onEmpty={() => setSearchResults(false)} /> @@ -62,13 +64,7 @@ import "./index.less" } - fetchMethod={FeedModel.getMusicFeed} - /> - - } fetchMethod={FeedModel.getGlobalMusicFeed} /> diff --git a/packages/app/src/pages/music/tabs/explore/index.less b/packages/app/src/pages/music/tabs/explore/index.less index ba35a49c..294ff2bf 100755 --- a/packages/app/src/pages/music/tabs/explore/index.less +++ b/packages/app/src/pages/music/tabs/explore/index.less @@ -1,288 +1,287 @@ html { - &.mobile { - .musicExplorer { - .playlistExplorer_section_list { - overflow: visible; - overflow-x: scroll; + &.mobile { + .musicExplorer { + .playlistExplorer_section_list { + overflow: visible; + overflow-x: scroll; - width: unset; - display: flex; - flex-direction: row; + width: unset; + display: flex; + flex-direction: row; - grid-gap: 10px; - } - } - } + grid-gap: 10px; + } + } + } } .featured_playlist { - position: relative; + position: relative; - display: flex; - flex-direction: row; + display: flex; + flex-direction: row; - overflow: hidden; + overflow: hidden; - background-color: var(--background-color-accent); + background-color: var(--background-color-accent); - width: 100%; - min-height: 200px; - height: fit-content; + width: 100%; + min-height: 200px; + height: fit-content; - border-radius: 12px; + border-radius: 12px; - cursor: pointer; + cursor: pointer; - &:hover { - .featured_playlist_content { + &:hover { + .featured_playlist_content { + h1, + p { + -webkit-text-stroke-width: 1.6px; + -webkit-text-stroke-color: var(--border-color); - h1, - p { - -webkit-text-stroke-width: 1.6px; - -webkit-text-stroke-color: var(--border-color); + color: var(--background-color-contrast); + } + } - color: var(--background-color-contrast); - } - } + .lazy-load-image-background { + opacity: 1; + } + } - .lazy-load-image-background { - opacity: 1; - } - } + .lazy-load-image-background { + z-index: 50; - .lazy-load-image-background { - z-index: 50; + position: absolute; - position: absolute; + opacity: 0.3; - opacity: 0.3; + transition: all 300ms ease-in-out !important; - transition: all 300ms ease-in-out !important; + img { + width: 100%; + height: 100%; + } + } - img { - width: 100%; - height: 100%; - } - } + .featured_playlist_content { + z-index: 55; - .featured_playlist_content { - z-index: 55; + padding: 20px; - padding: 20px; + display: flex; + flex-direction: column; - display: flex; - flex-direction: column; + h1 { + font-size: 2.5rem; + font-family: "Space Grotesk", sans-serif; + font-weight: 900; - h1 { - font-size: 2.5rem; - font-family: "Space Grotesk", sans-serif; - font-weight: 900; + transition: all 300ms ease-in-out !important; + } - transition: all 300ms ease-in-out !important; - } + p { + font-size: 1rem; + font-family: "Space Grotesk", sans-serif; - p { - font-size: 1rem; - font-family: "Space Grotesk", sans-serif; + transition: all 300ms ease-in-out !important; + } - transition: all 300ms ease-in-out !important; - } + .featured_playlist_genre { + z-index: 55; - .featured_playlist_genre { - z-index: 55; + position: absolute; - position: absolute; + left: 0; + bottom: 0; - left: 0; - bottom: 0; + margin: 10px; - margin: 10px; - - background-color: var(--background-color-accent); - border: 1px solid var(--border-color); - - border-radius: 12px; - - padding: 10px 20px; - } - } + background-color: var(--background-color-accent); + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 10px 20px; + } + } } .music_navbar { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; - width: 100%; + width: 100%; - background-color: var(--background-color-accent); + background-color: var(--background-color-accent); - border-radius: 12px; + border-radius: 12px; } .musicExplorer { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; - width: 100%; - height: 100%; + width: 100%; + height: 100%; - gap: 20px; + gap: 20px; - &.search-focused { - .feed_main { - height: 0px; - opacity: 0; - } - } + &.search-focused { + .feed_main { + height: 0px; + opacity: 0; + } + } - .feed_main { - display: flex; - flex-direction: column; + .feed_main { + display: flex; + flex-direction: column; - width: 100%; - height: 100%; + width: 100%; + height: 100%; - gap: 50px; + gap: 50px; - transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; - overflow-x: visible; - } + overflow-x: visible; + } } .music-explorer_search_results { - display: grid; + display: grid; - width: 100%; + width: 100%; - // if only need 1 column, it will be 1fr - // if need 2 colums, first column will be 1fr, and the second one will be 2fr - grid-template-columns: 1fr 2fr; + // if only need 1 column, it will be 1fr + // if need 2 colums, first column will be 1fr, and the second one will be 2fr + grid-template-columns: 1fr 2fr; - // auto generate rows - grid-template-rows: auto; + // auto generate rows + grid-template-rows: auto; - grid-column-gap: 20px; - grid-row-gap: 20px; + grid-column-gap: 20px; + grid-row-gap: 20px; - @media screen and (max-width: 1750px) { - display: flex; - flex-direction: column; - align-items: center; + @media screen and (max-width: 1750px) { + display: flex; + flex-direction: column; + align-items: center; - .music-explorer_search_results_group_list { - .playlistItem { - width: 100% !important; - max-width: 100% !important; + .music-explorer_search_results_group_list { + .playlistItem { + width: 100% !important; + max-width: 100% !important; - .playlistItem_info_subtitle { - max-width: 300px; - } + .playlistItem_info_subtitle { + max-width: 300px; + } - .playlistItem_bottom { - display: flex !important; - position: absolute; + .playlistItem_bottom { + display: flex !important; + position: absolute; - top: 0; - right: 0; + top: 0; + right: 0; - padding: 10px; + padding: 10px; - //-webkit-backdrop-filter: blur(5px); - //backdrop-filter: blur(5px); + //-webkit-backdrop-filter: blur(5px); + //backdrop-filter: blur(5px); - background-color: var(--background-color-primary); + background-color: var(--background-color-primary); - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; - p { - display: flex; - flex-direction: row-reverse; + p { + display: flex; + flex-direction: row-reverse; - gap: 7px; - } - } - } - } - } + gap: 7px; + } + } + } + } + } - &.one_column { - grid-template-columns: 1fr; - } + &.one_column { + grid-template-columns: 1fr; + } - &.no_results { - display: flex; - flex-direction: column; + &.no_results { + display: flex; + flex-direction: column; - align-items: center; - justify-content: center; - } + align-items: center; + justify-content: center; + } - .music-explorer_search_results_group { - background-color: var(--background-color-accent); + .music-explorer_search_results_group { + background-color: var(--background-color-accent); - padding: 20px; + padding: 20px; - border-radius: 8px; + border-radius: 8px; - height: fit-content; - width: 100%; + height: fit-content; + width: 100%; - gap: 20px; + gap: 20px; - .explorer_search_results_group_header { - h1 { - margin: 0; - } - } + .explorer_search_results_group_header { + h1 { + margin: 0; + } + } - .music-explorer_search_results_group_list { - display: flex; - flex-direction: column; + .music-explorer_search_results_group_list { + display: flex; + flex-direction: column; - gap: 10px; + gap: 10px; - @playlistItem_height: 80px; - @playlistItem_padding: 10px; + @playlistItem_height: 80px; + @playlistItem_padding: 10px; - @playlistItem_cover_size: calc(@playlistItem_height - @playlistItem_padding * 2); + @playlistItem_cover_size: calc( + @playlistItem_height - @playlistItem_padding * 2 + ); - .playlistItem { - flex-direction: row; - background-color: var(--background-color-primary); + .playlistItem { + flex-direction: row; + background-color: var(--background-color-primary); - max-width: 300px; - width: 100%; + max-width: 300px; + width: 100%; - height: @playlistItem_height; + height: @playlistItem_height; - padding: @playlistItem_padding; + padding: @playlistItem_padding; - .playlistItem_cover { - width: @playlistItem_cover_size; - height: @playlistItem_cover_size; + .playlistItem_cover { + width: @playlistItem_cover_size; + height: @playlistItem_cover_size; - min-height: @playlistItem_cover_size; - min-width: @playlistItem_cover_size; - } + min-height: @playlistItem_cover_size; + min-width: @playlistItem_cover_size; + } - .playlistItem_bottom { - display: none; - } + .playlistItem_bottom { + display: none; + } - &:hover { - .playlistItem_info { - transform: none; - } - } - } + &:hover { + .playlistItem_info { + transform: none; + } + } + } - .music-track { - background-color: var(--background-color-primary); - } - } - } -} \ No newline at end of file + .music-track { + background-color: var(--background-color-primary); + } + } + } +} diff --git a/packages/app/src/pages/music/tabs/library/index.jsx b/packages/app/src/pages/music/tabs/library/index.jsx index e2f558bc..0d27c2dc 100755 --- a/packages/app/src/pages/music/tabs/library/index.jsx +++ b/packages/app/src/pages/music/tabs/library/index.jsx @@ -9,56 +9,56 @@ import PlaylistLibraryView from "./views/playlists" import "./index.less" const TabToView = { - tracks: TracksLibraryView, - playlist: PlaylistLibraryView, - releases: PlaylistLibraryView, + tracks: TracksLibraryView, + playlist: PlaylistLibraryView, + releases: PlaylistLibraryView, } const TabToHeader = { - tracks: { - icon: , - label: "Tracks", - }, - playlist: { - icon: , - label: "Playlists", - }, + tracks: { + icon: , + label: "Tracks", + }, + playlist: { + icon: , + label: "Playlists", + }, } const Library = (props) => { - const [selectedTab, setSelectedTab] = React.useState("tracks") + const [selectedTab, setSelectedTab] = React.useState("tracks") - return
-
-

Library

+ return ( +
+
+ , + }, + { + value: "playlist", + label: "Playlists", + icon: , + }, + { + value: "releases", + label: "Releases", + icon: , + }, + ]} + /> +
- - }, - { - value: "playlist", - label: "Playlists", - icon: - }, - { - value: "releases", - label: "Releases", - icon: - } - ]} - /> -
- - { - selectedTab && TabToView[selectedTab] && React.createElement(TabToView[selectedTab]) - } -
+ {selectedTab && + TabToView[selectedTab] && + React.createElement(TabToView[selectedTab])} +
+ ) } -export default Library \ No newline at end of file +export default Library diff --git a/packages/app/src/pages/music/tabs/library/views/tracks/index.jsx b/packages/app/src/pages/music/tabs/library/views/tracks/index.jsx index 4f46e2c7..8db27e1f 100644 --- a/packages/app/src/pages/music/tabs/library/views/tracks/index.jsx +++ b/packages/app/src/pages/music/tabs/library/views/tracks/index.jsx @@ -8,71 +8,75 @@ import MusicModel from "@models/music" const loadLimit = 50 const TracksLibraryView = () => { - const [offset, setOffset] = React.useState(0) - const [list, setList] = React.useState([]) - const [hasMore, setHasMore] = React.useState(true) - const [initialLoading, setInitialLoading] = React.useState(true) + const [offset, setOffset] = React.useState(0) + const [items, setItems] = React.useState([]) + const [hasMore, setHasMore] = React.useState(true) + const [initialLoading, setInitialLoading] = React.useState(true) - const [L_Favourites, R_Favourites, E_Favourites, M_Favourites] = app.cores.api.useRequest(MusicModel.getFavouriteFolder, { - offset: offset, - limit: loadLimit, - }) + const [L_Favourites, R_Favourites, E_Favourites, M_Favourites] = + app.cores.api.useRequest(MusicModel.getFavouriteFolder, { + offset: offset, + limit: loadLimit, + }) - async function onLoadMore() { - const newOffset = offset + loadLimit + async function onLoadMore() { + const newOffset = offset + loadLimit - setOffset(newOffset) + setOffset(newOffset) - M_Favourites({ - offset: newOffset, - limit: loadLimit, - }) - } + M_Favourites({ + offset: newOffset, + limit: loadLimit, + }) + } - React.useEffect(() => { - if (R_Favourites && R_Favourites.tracks) { - if (initialLoading === true) { - setInitialLoading(false) - } + React.useEffect(() => { + if (R_Favourites && R_Favourites.tracks) { + if (initialLoading === true) { + setInitialLoading(false) + } - if (R_Favourites.tracks.list.length === 0) { - setHasMore(false) - } else { - setList((prev) => { - prev = [ - ...prev, - ...R_Favourites.tracks.list, - ] + if (R_Favourites.tracks.items.length === 0) { + setHasMore(false) + } else { + setItems((prev) => { + prev = [...prev, ...R_Favourites.tracks.items] - return prev - }) - } - } - }, [R_Favourites]) + return prev + }) + } + } + }, [R_Favourites]) - if (E_Favourites) { - return - } + if (E_Favourites) { + return ( + + ) + } - if (initialLoading) { - return - } + if (initialLoading) { + return + } - return + return ( + + ) } -export default TracksLibraryView \ No newline at end of file +export default TracksLibraryView