improve page layouts

This commit is contained in:
SrGooglo 2023-04-04 10:49:45 +00:00
parent 2dc5abd65f
commit 47032ea0ff
13 changed files with 319 additions and 208 deletions

View File

@ -2,20 +2,23 @@ import FeedTab from "./components/feed"
import GlobalTab from "./components/global" import GlobalTab from "./components/global"
import SavedPostsTab from "./components/savedPosts" import SavedPostsTab from "./components/savedPosts"
export default { export default [
"feed": { {
key: "feed",
label: "Feed", label: "Feed",
icon: "Rss", icon: "IoMdPaper",
component: FeedTab component: FeedTab
}, },
"global": { {
key: "global",
label: "Global", label: "Global",
icon: "Globe", icon: "Globe",
component: GlobalTab component: GlobalTab
}, },
"savedPosts": { {
key: "savedPosts",
label: "Saved posts", label: "Saved posts",
icon: "Bookmark", icon: "Bookmark",
component: SavedPostsTab component: SavedPostsTab
} }
} ]

View File

@ -14,7 +14,7 @@ export default class Home extends React.Component {
render() { render() {
const navMenuHeader = <> const navMenuHeader = <>
<h1> <h1>
<Icons.MdTag /> <Icons.Home />
<Translation>{(t) => t("Timeline")}</Translation> <Translation>{(t) => t("Timeline")}</Translation>
</h1> </h1>
<antd.Button <antd.Button

View File

@ -1,130 +1,7 @@
import React from "react" import React from "react"
import { Icons } from "components/Icons"
import { ImageViewer } from "components"
import * as antd from "antd"
import PlaylistsModel from "models/playlists"
import "./index.less"
const getReleases = async () => {
const response = await PlaylistsModel.getMyReleases().catch((err) => {
console.error(err)
app.message.error("Failed to load releases")
return null
})
return response
}
const ReleaseItem = (props) => {
const { key, release } = props
console.log(props)
return <div
className="music_panel_releases_item"
key={key}
id={key}
>
<div
className="music_panel_releases_info"
>
<div
className="music_panel_releases_info_cover"
>
<ImageViewer
src={release.thumbnail ?? "/assets/no_song.png"}
/>
</div>
<div
className="music_panel_releases_info_title"
>
<h1>
{release.title}
</h1>
<h4>
{release.description}
</h4>
</div>
</div>
<div
className="music_panel_releases_actions"
>
<antd.Button
onClick={props.onClickEditTrack}
icon={<Icons.Edit />}
>
Modify
</antd.Button>
</div>
</div>
}
export default (props) => { export default (props) => {
const [releases, setReleases] = React.useState([]) return <div>
const [loading, setLoading] = React.useState(false) Dashboard
const onClickEditTrack = (track_id) => {
console.log("Edit track", track_id)
app.setLocation(`/music/creator?playlist_id=${track_id}`)
}
const loadData = async () => {
setLoading(true)
const releases = await getReleases()
setLoading(false)
console.log(releases)
if (releases) {
setReleases(releases)
}
}
React.useEffect(() => {
loadData()
}, [])
if (loading) {
return <antd.Skeleton active />
}
return <div
className="music_panel_creator"
>
<div className="music_panel_releases_header">
<h1>
<Icons.Music />
Your releases
</h1>
<div className="music_panel_releases_header_actions">
<antd.Button
onClick={() => app.setLocation("/music/creator")}
icon={<Icons.Plus />}
type="primary"
>
New release
</antd.Button>
</div>
</div>
<div className="music_panel_releases_list">
{
releases.map((release) => {
return <ReleaseItem
key={release._id}
release={release}
onClickEditTrack={() => onClickEditTrack(release._id)}
/>
})
}
</div>
</div> </div>
} }

View File

@ -0,0 +1,108 @@
import React from "react"
import { Icons } from "components/Icons"
import { ImageViewer } from "components"
import * as antd from "antd"
import PlaylistsModel from "models/playlists"
import "./index.less"
const ReleaseItem = (props) => {
const { key, release } = props
return <div
className="music_panel_releases_item"
key={key}
id={key}
>
<div
className="music_panel_releases_info"
>
<div
className="music_panel_releases_info_cover"
>
<ImageViewer
src={release.thumbnail ?? "/assets/no_song.png"}
/>
</div>
<div
className="music_panel_releases_info_title"
>
<h1>
{release.title}
</h1>
<h4>
{release.description}
</h4>
</div>
</div>
<div
className="music_panel_releases_actions"
>
<antd.Button
onClick={props.onClickEditTrack}
icon={<Icons.Edit />}
>
Modify
</antd.Button>
</div>
</div>
}
export default (props) => {
const onClickEditTrack = (track_id) => {
console.log("Edit track", track_id)
app.setLocation(`/music/creator?playlist_id=${track_id}`)
}
const [L_Releases, R_Releases, E_Releases] = app.cores.api.useRequest(PlaylistsModel.getMyReleases)
if (E_Releases) {
console.error(E_Releases)
return <antd.Result
status="warning"
title="Failed to load"
subTitle="We are sorry, but we could not load your releases. Please try again later."
/>
}
if (L_Releases) {
return <antd.Skeleton active />
}
return <div
className="music_panel_creator"
>
<div className="music_panel_releases_header">
<h1>
<Icons.Music />
Your releases
</h1>
<div className="music_panel_releases_header_actions">
<antd.Button
onClick={() => app.setLocation("/music/creator")}
icon={<Icons.Plus />}
type="primary"
>
New release
</antd.Button>
</div>
</div>
<div className="music_panel_releases_list">
{
R_Releases.map((release) => {
return <ReleaseItem
key={release._id}
release={release}
onClickEditTrack={() => onClickEditTrack(release._id)}
/>
})
}
</div>
</div>
}

View File

@ -4,7 +4,6 @@
width: 100%; width: 100%;
.music_panel_releases_header { .music_panel_releases_header {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -76,6 +75,8 @@
height: 100px; height: 100px;
border-radius: 8px; border-radius: 8px;
object-fit: cover;
} }
} }
@ -87,7 +88,6 @@
margin: 0 !important; margin: 0 !important;
} }
} }
} }
.music_panel_releases_actions { .music_panel_releases_actions {

View File

@ -53,59 +53,137 @@ const PlaylistItem = (props) => {
</div> </div>
} }
export default () => { const RecentlyPlayed = (props) => {
const [loading, setLoading] = React.useState(true) return <div className="playlistExplorer_section">
const [list, setList] = React.useState([]) <div className="playlistExplorer_section_header">
<h1>
<Icons.MdReplay />
<Translation>
{(t) => t("Recently Played")}
</Translation>
</h1>
</div>
const loadData = async () => { <div>
setLoading(true) <antd.Result
status="warning"
const response = await FeedModel.getPlaylistsFeed({ title="Failed to load"
limit: 10, subTitle="We are sorry, but we could not load your playlists. Please try again later."
trim: 0, />
}).catch((err) => {
console.error(err)
app.message.error("Failed to load playlists")
return null
})
setLoading(false)
console.log(response)
if (response) {
setList(response)
}
}
React.useEffect(() => {
loadData()
}, [])
if (loading) {
return <antd.Skeleton active />
}
return <div className="playlistExplorer">
<div className="playlistExplorer_section">
<div className="playlistExplorer_section_header">
<h1>
<Icons.MdOutlineMarkunreadMailbox />
<Translation>
{(t) => t("Releases from your artists")}
</Translation>
</h1>
</div>
<div className="playlistExplorer_section_list">
{
list.map((playlist, index) => {
return <PlaylistItem
key={index}
playlist={playlist}
/>
})
}
</div>
</div> </div>
</div> </div>
}
const FollowingArtists = (props) => {
const [L_MusicFeed, R_MusicFeed, E_MusicFeed] = app.cores.api.useRequest(FeedModel.getPlaylistsFeed)
if (E_MusicFeed) {
console.error(E_MusicFeed)
return <div className="playlistExplorer_section">
<antd.Result
status="warning"
title="Failed to load"
subTitle="We are sorry, but we could not load your playlists. Please try again later."
/>
</div>
}
return <div className="playlistExplorer_section">
<div className="playlistExplorer_section_header">
<h1>
<Icons.MdPerson />
<Translation>
{(t) => t("From following artists")}
</Translation>
</h1>
</div>
<div className="playlistExplorer_section_list">
{
L_MusicFeed && <antd.Skeleton active />
}
{
!L_MusicFeed && R_MusicFeed.map((playlist, index) => {
return <PlaylistItem
key={index}
playlist={playlist}
/>
})
}
</div>
</div>
}
const PlaylistExplorer = (props) => {
const [L_MusicFeed, R_MusicFeed, E_MusicFeed] = app.cores.api.useRequest(FeedModel.getGlobalMusicFeed)
if (E_MusicFeed) {
console.error(E_MusicFeed)
return <div className="playlistExplorer_section">
<antd.Result
status="warning"
title="Failed to load"
subTitle="We are sorry, but we could not load your playlists. Please try again later."
/>
</div>
}
return <div className="playlistExplorer_section">
<div className="playlistExplorer_section_header">
<h1>
<Icons.MdExplore />
<Translation>
{(t) => t("Explore from global")}
</Translation>
</h1>
</div>
<div className="playlistExplorer_section_list">
{
L_MusicFeed && <antd.Skeleton active />
}
{
!L_MusicFeed && R_MusicFeed.map((playlist, index) => {
return <PlaylistItem
key={index}
playlist={playlist}
/>
})
}
</div>
</div>
}
const MayLike = (props) => {
return <div className="playlistExplorer_section">
<div className="playlistExplorer_section_header">
<h1>
<Icons.MdRecommend />
<Translation>
{(t) => t("May you like")}
</Translation>
</h1>
</div>
<div>
<antd.Result
status="warning"
title="Failed to load"
subTitle="We are sorry, but we could not load your recomendations. Please try again later."
/>
</div>
</div>
}
export default () => {
return <div className="playlistExplorer">
<RecentlyPlayed />
<FollowingArtists />
<PlaylistExplorer />
<MayLike />
</div>
} }

View File

@ -25,9 +25,13 @@
//flex-direction: row; //flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
max-height: 30vh;
align-items: center; align-items: center;
gap: 20px; gap: 20px;
overflow-x: scroll;
} }
} }
} }

View File

@ -7,7 +7,7 @@ import { PagePanelWithNavMenu } from "components/PagePanels"
import Tabs from "./tabs" import Tabs from "./tabs"
const NavMenuHeader = <h2> const NavMenuHeader = <h2>
<Icons.MdLiveTv /> <Icons.MdAlbum />
Music Music
</h2> </h2>

View File

@ -1,28 +1,48 @@
import FeedTab from "./components/feed" import FeedTab from "./components/feed"
import SpacesTab from "./components/spaces" import SpacesTab from "./components/spaces"
import DashboardTab from "./components/dashboard"
export default { import DashboardTab from "./components/dashboard"
"feed": { import ReleasesTab from "./components/dashboard/releases"
export default [
{
key: "feed",
label: "Feed", label: "Feed",
icon: "Compass", icon: "Compass",
component: FeedTab component: FeedTab
}, },
"library": { {
key: "radio",
label: "Radio",
icon: "Radio",
disabled: true
},
{
key: "library",
label: "Library", label: "Library",
icon: "MdLibraryMusic", icon: "MdLibraryMusic",
component: FeedTab, component: FeedTab,
disabled: true disabled: true
}, },
"spaces": { {
key: "spaces",
label: "Spaces", label: "Spaces",
icon: "MdDeck", icon: "MdDeck",
component: SpacesTab, component: SpacesTab,
disabled: true disabled: true
}, },
"artistPanel": { {
label: "Artist Panel", key: "artist_panel",
icon: "MdOutlineDashboard", label: "Creator Panel",
icon: "MdSpaceDashboard",
component: DashboardTab, component: DashboardTab,
children: [
{
key: "artist_panel.releases",
label: "Releases",
icon: "MdUpcoming",
component: ReleasesTab,
}
]
}, },
} ]

View File

@ -390,7 +390,7 @@ export default (props) => {
<h2><Icons.Link /> URL Information</h2> <h2><Icons.Link /> URL Information</h2>
<div className="content"> <div className="content">
<span>AAC URL</span> <span>AAC URL (Only Audio)</span>
<code> <code>
{addresses.aacURL ?? "No AAC URL available"} {addresses.aacURL ?? "No AAC URL available"}

View File

@ -1,15 +1,36 @@
import ExploreTab from "./components/explore" import FeedTab from "./components/feed"
import ControlPanelTab from "./components/controlPanel" import ControlPanelTab from "./components/controlPanel"
export default { export default [
"explore": { {
label: "Explore", key: "feed",
icon: "Search", label: "Feed",
component: ExploreTab icon: "Compass",
component: FeedTab
}, },
"controlPanel": { {
label: "Control Panel", key: "controlPanel",
icon: "Settings", label: "Creator Panel",
component: ControlPanelTab icon: "MdSpaceDashboard",
children: [
{
key: "controlPanel.uploads",
label: "Uploads",
icon: "Upload",
disabled: true
},
{
key: "controlPanel.streaming_settings",
label: "Livestreaming",
icon: "Settings",
component: ControlPanelTab
},
{
key: "controlPanel.dvr_settings",
label: "DVR",
icon: "MdFiberDvr",
disabled: true
}
]
} }
} ]