From 0223a6a60c8e74212beacf6a0611418a488e4c27 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Thu, 13 Jul 2023 15:50:14 +0000 Subject: [PATCH] move music components to `Music` into components --- .../{ => Music}/PlaylistItem/index.jsx | 0 .../{ => Music}/PlaylistItem/index.less | 0 .../PlaylistTimelineEntry/index.jsx | 0 .../PlaylistTimelineEntry/index.less | 0 .../components/Music/PlaylistView/index.jsx | 207 ++++++++++++++++ .../components/Music/PlaylistView/index.less | 233 ++++++++++++++++++ .../{MusicTrack => Music/Track}/index.jsx | 2 +- .../{MusicTrack => Music/Track}/index.less | 0 .../app/src/components/PostsList/index.jsx | 2 +- .../app/src/components/Searcher/index.jsx | 4 +- 10 files changed, 444 insertions(+), 4 deletions(-) rename packages/app/src/components/{ => Music}/PlaylistItem/index.jsx (100%) rename packages/app/src/components/{ => Music}/PlaylistItem/index.less (100%) rename packages/app/src/components/{ => Music}/PlaylistTimelineEntry/index.jsx (100%) rename packages/app/src/components/{ => Music}/PlaylistTimelineEntry/index.less (100%) create mode 100644 packages/app/src/components/Music/PlaylistView/index.jsx create mode 100755 packages/app/src/components/Music/PlaylistView/index.less rename packages/app/src/components/{MusicTrack => Music/Track}/index.jsx (98%) rename packages/app/src/components/{MusicTrack => Music/Track}/index.less (100%) diff --git a/packages/app/src/components/PlaylistItem/index.jsx b/packages/app/src/components/Music/PlaylistItem/index.jsx similarity index 100% rename from packages/app/src/components/PlaylistItem/index.jsx rename to packages/app/src/components/Music/PlaylistItem/index.jsx diff --git a/packages/app/src/components/PlaylistItem/index.less b/packages/app/src/components/Music/PlaylistItem/index.less similarity index 100% rename from packages/app/src/components/PlaylistItem/index.less rename to packages/app/src/components/Music/PlaylistItem/index.less diff --git a/packages/app/src/components/PlaylistTimelineEntry/index.jsx b/packages/app/src/components/Music/PlaylistTimelineEntry/index.jsx similarity index 100% rename from packages/app/src/components/PlaylistTimelineEntry/index.jsx rename to packages/app/src/components/Music/PlaylistTimelineEntry/index.jsx diff --git a/packages/app/src/components/PlaylistTimelineEntry/index.less b/packages/app/src/components/Music/PlaylistTimelineEntry/index.less similarity index 100% rename from packages/app/src/components/PlaylistTimelineEntry/index.less rename to packages/app/src/components/Music/PlaylistTimelineEntry/index.less diff --git a/packages/app/src/components/Music/PlaylistView/index.jsx b/packages/app/src/components/Music/PlaylistView/index.jsx new file mode 100644 index 00000000..80decd3e --- /dev/null +++ b/packages/app/src/components/Music/PlaylistView/index.jsx @@ -0,0 +1,207 @@ +import React from "react" +import * as antd from "antd" +import classnames from "classnames" +import ReactMarkdown from "react-markdown" +import remarkGfm from "remark-gfm" +import moment from "moment" +import fuse from "fuse.js" +import useWsEvents from "hooks/useWsEvents" + +import { WithPlayerContext } from "contexts/WithPlayerContext" + +import { ImageViewer } from "components" +import { Icons } from "components/Icons" + +import PlaylistsModel from "models/playlists" +import MusicTrack from "components/Music/Track" + +import SearchButton from "components/SearchButton" + +import "./index.less" + +export default (props) => { + const [playlist, setPlaylist] = React.useState(props.playlist) + const [searchResults, setSearchResults] = React.useState(null) + + let debounceSearch = null + + const handleOnClickTrack = (track) => { + // search index of track + const index = playlist.list.findIndex((item) => { + return item._id === track._id + }) + + if (index === -1) { + return + } + + app.cores.player.startPlaylist(playlist.list, index) + } + + const handleTrackLike = async (track) => { + return await PlaylistsModel.toggleTrackLike(track._id) + } + + const makeSearch = (value) => { + const options = { + includeScore: true, + keys: [ + "title", + "artist", + "album", + ], + } + + const fuseInstance = new fuse(playlist.list, options) + const results = fuseInstance.search(value) + + setSearchResults(results.map((result) => { + return result.item + })) + } + + const returnTracks = (list) => { + return list.map((item, index) => { + return handleOnClickTrack(item)} + onLike={() => handleTrackLike(item)} + /> + }) + } + + const handleOnSearchChange = (value) => { + debounceSearch = setTimeout(() => { + makeSearch(value) + }, 500) + } + + const handleOnSearchEmpty = () => { + if (debounceSearch) { + clearTimeout(debounceSearch) + } + + setSearchResults(null) + } + + const updateTrackLike = (track_id, liked) => { + setPlaylist((prev) => { + const index = prev.list.findIndex((item) => { + return item._id === track_id + }) + + if (index !== -1) { + const newState = { + ...prev, + } + + newState.list[index].liked = liked + + return newState + } + + return prev + }) + } + + useWsEvents({ + "music:self:track:toggle:like": (data) => { + updateTrackLike(data.track_id, data.action === "liked") + } + }, { + socketName: "music", + }) + + React.useEffect(() => { + if (props.centered) { + app.layout.toggleCenteredContent(true) + } + + return () => { + if (props.centered) { + app.layout.toggleCenteredContent(false) + } + } + }, []) + + if (!playlist) { + return + } + + return
+
+
+
+ +
+ +
+
+ {typeof playlist.title === "function" ? playlist.title :

{playlist.title}

} +
+ + { + playlist.description &&
+ + {playlist.description} + +
+ } + +
+ { + playlist.publisher &&
+

{ + app.navigation.goToAccount(playlist.publisher.username) + }} + > + + + Publised by {playlist.publisher.username} +

+
+ } +
+

+ {playlist.list.length} Tracks +

+
+ + { + playlist.created_at &&
+

+ Released on {moment(playlist.created_at).format("DD/MM/YYYY")} +

+
+ } +
+
+
+
+ +
+
+

+ Tracks +

+ + +
+ + + { + returnTracks(searchResults ?? playlist.list) + } + +
+
+} \ No newline at end of file diff --git a/packages/app/src/components/Music/PlaylistView/index.less b/packages/app/src/components/Music/PlaylistView/index.less new file mode 100755 index 00000000..1a7952f2 --- /dev/null +++ b/packages/app/src/components/Music/PlaylistView/index.less @@ -0,0 +1,233 @@ +#root { + &.mobile { + .playlist_view { + display: flex; + flex-direction: column; + + width: 100%; + + .play_info_wrapper { + position: relative; + + width: 100%; + + .play_info { + width: 100%; + + .play_info_cover { + width: 30vh; + height: 30vh; + + img { + width: 100%; + height: 100%; + + object-fit: contain; + } + } + } + } + + .list { + padding: 30px 0; + } + } + } +} + +.playlist_view { + display: flex; + flex-direction: row; + + align-items: flex-start; + + width: 100%; + + &.vertical { + flex-direction: column; + + .play_info_wrapper { + width: 100%; + + .play_info { + flex-direction: row; + width: 100%; + + .play_info_cover { + height: 15vh !important; + width: 15vh !important; + + min-height: 15vh; + min-width: 15vh; + } + + .play_info_details { + width: 100%; + + h1 { + font-size: 1.2rem; + } + } + } + } + } + + .play_info_wrapper { + position: sticky; + + top: 0; + left: 0; + + display: flex; + flex-direction: column; + + align-items: center; + justify-content: center; + + width: fit-content; + height: fit-content; + + color: var(--text-color); + + .play_info { + display: flex; + flex-direction: column; + + align-self: center; + + height: 100%; + + padding: 20px; + + background-color: var(--background-color-accent); + border-radius: 12px; + + .play_info_cover { + display: flex; + flex-direction: column; + + align-items: center; + justify-content: center; + + align-self: center; + + width: 20vw; + height: 20vw; + + min-height: 20vw; + min-width: 20vw; + + max-width: 400px; + max-height: 400px; + + background-color: black; + border-radius: 12px; + + overflow: hidden; + + img { + width: 100%; + height: 100%; + + object-fit: contain; + } + } + + .play_info_details { + padding: 20px; + + .play_info_title { + font-size: 1.5rem; + font-family: "Space Grotesk", sans-serif; + + h1 { + margin: 0; + } + + word-break: break-all; + + font-weight: 600; + + margin-bottom: 10px; + } + + .play_info_description { + font-size: 0.8rem; + font-weight: 400; + } + + .play_info_statistics { + display: flex; + flex-direction: column; + + margin-top: 20px; + + background-color: var(--background-color-primary); + + padding: 20px; + + border-radius: 8px; + + .play_info_statistics_item { + display: flex; + flex-direction: row; + + align-items: center; + + margin-bottom: 10px; + + h1, + h2, + h3, + h4, + h5, + h6, + p, + span { + margin: 0; + } + + .play_info_statistics_item_icon { + margin-right: 10px; + } + + .play_info_statistics_item_text { + font-size: 0.8rem; + font-weight: 400; + } + + &:last-child { + margin-bottom: 0; + } + } + + } + } + } + } + + .list { + display: flex; + flex-direction: column; + + color: var(--text-color); + + padding: 20px 30px; + + gap: 10px; + + width: 100%; + + h1 { + margin: 0; + } + + .list_header { + display: flex; + flex-direction: row; + + align-items: center; + justify-content: space-between; + } + } +} \ No newline at end of file diff --git a/packages/app/src/components/MusicTrack/index.jsx b/packages/app/src/components/Music/Track/index.jsx similarity index 98% rename from packages/app/src/components/MusicTrack/index.jsx rename to packages/app/src/components/Music/Track/index.jsx index 10adc94b..bbaca546 100644 --- a/packages/app/src/components/MusicTrack/index.jsx +++ b/packages/app/src/components/Music/Track/index.jsx @@ -24,7 +24,7 @@ export default (props) => { const handleClickPlayBtn = React.useCallback(() => { if (typeof props.onClickPlayBtn === "function") { - props.onClick(props.track) + props.onClickPlayBtn(props.track) } else { console.warn("Searcher: onClick is not a function, using default action...") app.cores.player.start(props.track) diff --git a/packages/app/src/components/MusicTrack/index.less b/packages/app/src/components/Music/Track/index.less similarity index 100% rename from packages/app/src/components/MusicTrack/index.less rename to packages/app/src/components/Music/Track/index.less diff --git a/packages/app/src/components/PostsList/index.jsx b/packages/app/src/components/PostsList/index.jsx index 8d0c1df6..3e1fffdb 100755 --- a/packages/app/src/components/PostsList/index.jsx +++ b/packages/app/src/components/PostsList/index.jsx @@ -3,7 +3,7 @@ import * as antd from "antd" import { Icons } from "components/Icons" import PostCard from "components/PostCard" -import PlaylistTimelineEntry from "components/PlaylistTimelineEntry" +import PlaylistTimelineEntry from "components/Music/PlaylistTimelineEntry" import LoadMore from "components/LoadMore" //import { ViewportList } from "react-viewport-list" diff --git a/packages/app/src/components/Searcher/index.jsx b/packages/app/src/components/Searcher/index.jsx index 4672b8ba..056b81dc 100755 --- a/packages/app/src/components/Searcher/index.jsx +++ b/packages/app/src/components/Searcher/index.jsx @@ -8,8 +8,8 @@ import { Translation } from "react-i18next" import { Icons, createIconRender } from "components/Icons" import UserPreview from "components/UserPreview" -import MusicTrack from "components/MusicTrack" -import PlaylistItem from "components/PlaylistItem" +import MusicTrack from "components/Music/Track" +import PlaylistItem from "components/Music/PlaylistItem" import SearchModel from "models/search"