mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
support extended tidal funcionality & favourite tracks
This commit is contained in:
parent
1228b5bbcb
commit
97a34baed7
@ -9,7 +9,6 @@ import { Icons, createIconRender } from "components/Icons"
|
||||
import { WithPlayerContext } from "contexts/WithPlayerContext"
|
||||
|
||||
import FeedModel from "models/feed"
|
||||
import PlaylistModel from "models/playlists"
|
||||
import MusicModel from "models/music"
|
||||
import SyncModel from "models/sync"
|
||||
|
||||
@ -19,32 +18,13 @@ import PlaylistItem from "components/Music/PlaylistItem"
|
||||
import "./index.less"
|
||||
|
||||
const MusicNavbar = (props) => {
|
||||
const [loading, setLoading] = React.useState(true)
|
||||
const [hasTidal, setHasTidal] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
SyncModel.hasServiceLinked("tidal")
|
||||
.catch(() => {
|
||||
setHasTidal(false)
|
||||
setLoading(false)
|
||||
})
|
||||
.then((value) => {
|
||||
setHasTidal(value.active)
|
||||
setLoading(false)
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (loading) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <div className="music_navbar">
|
||||
<Searcher
|
||||
useUrlQuery
|
||||
renderResults={false}
|
||||
model={MusicModel.search}
|
||||
modelParams={{
|
||||
useTidal: hasTidal,
|
||||
useTidal: app.cores.sync.getActiveLinkedServices().tidal,
|
||||
}}
|
||||
onSearchResult={props.setSearchResults}
|
||||
onEmpty={() => props.setSearchResults(false)}
|
||||
|
@ -3,10 +3,12 @@ import * as antd from "antd"
|
||||
|
||||
import PlaylistView from "components/Music/PlaylistView"
|
||||
|
||||
import MusicModel from "comty.js/models/music"
|
||||
import MusicModel from "models/music"
|
||||
|
||||
export default () => {
|
||||
const [L_Favorites, R_Favorites, E_Favorites] = app.cores.api.useRequest(MusicModel.getFavorites)
|
||||
const [L_Favorites, R_Favorites, E_Favorites] = app.cores.api.useRequest(MusicModel.getFavorites, {
|
||||
useTidal: app.cores.sync.getActiveLinkedServices().tidal
|
||||
})
|
||||
|
||||
if (E_Favorites) {
|
||||
return <antd.Result
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import { Track } from "@shared-classes/DbModels"
|
||||
import getEnhancedLyricsFromTrack from "@services/getEnhancedLyricsFromTrack"
|
||||
|
||||
|
@ -52,27 +52,7 @@ async function searchRoute(req, res) {
|
||||
query: keywords
|
||||
})
|
||||
|
||||
tidalResult.tracks.items.forEach((element) => {
|
||||
element._id = element.id
|
||||
|
||||
const coverUID = element.album.cover.replace(/-/g, "/")
|
||||
|
||||
element.cover = `https://resources.tidal.com/images/${coverUID}/1280x1280.jpg`
|
||||
|
||||
element.artist = element.artists.map(artist => artist.name).join(", ")
|
||||
|
||||
element.metadata = {
|
||||
title: element.title,
|
||||
artists: element.artists.map(artist => artist.name).join(", "),
|
||||
artist: element.artists.map(artist => artist.name).join(", "),
|
||||
album: element.album.title,
|
||||
duration: element.duration
|
||||
}
|
||||
|
||||
element.service = "tidal"
|
||||
|
||||
results.tracks.push(element)
|
||||
})
|
||||
results.tracks = [...results.tracks, ...tidalResult]
|
||||
}
|
||||
|
||||
return res.json(results)
|
||||
|
@ -6,17 +6,17 @@ export default async (req, res) => {
|
||||
return new AuthorizationError(req, res)
|
||||
}
|
||||
|
||||
let likedIds = await TrackLike.find({
|
||||
let likedTracks = await TrackLike.find({
|
||||
user_id: req.session.user_id,
|
||||
})
|
||||
.sort({ created_at: -1 })
|
||||
|
||||
likedIds = likedIds.map((item) => {
|
||||
const likedTracksIds = likedTracks.map((item) => {
|
||||
return item.track_id
|
||||
})
|
||||
|
||||
let tracks = await Track.find({
|
||||
_id: [...likedIds],
|
||||
_id: likedTracksIds,
|
||||
//public: true,
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -26,14 +26,20 @@ export default async (req, res) => {
|
||||
tracks = tracks.map((item) => {
|
||||
item = item.toObject()
|
||||
|
||||
const likeIndex = likedTracksIds.indexOf(item._id.toString())
|
||||
|
||||
if (likeIndex !== -1) {
|
||||
item.liked_at = new Date(likedTracks[likeIndex].created_at).getTime()
|
||||
}
|
||||
|
||||
item.liked = true
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
tracks.sort((a, b) => {
|
||||
const indexA = likedIds.indexOf(a._id.toString())
|
||||
const indexB = likedIds.indexOf(b._id.toString())
|
||||
const indexA = likedTracksIds.indexOf(a._id.toString())
|
||||
const indexB = likedTracksIds.indexOf(b._id.toString())
|
||||
|
||||
return indexA - indexB
|
||||
})
|
||||
|
@ -0,0 +1,15 @@
|
||||
import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
|
||||
import { AuthorizationError } from "@shared-classes/Errors"
|
||||
|
||||
export default async (req, res) => {
|
||||
if (!req.session) {
|
||||
return new AuthorizationError(req, res)
|
||||
}
|
||||
|
||||
const tidal_access = await SecureSyncEntry.has(req.session.user_id.toString(), "tidal_access_token")
|
||||
|
||||
return res.json({
|
||||
spotify: null,
|
||||
tidal: tidal_access,
|
||||
})
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
import SecureSyncEntry from "@shared-classes/SecureSyncEntry"
|
||||
import { AuthorizationError, InternalServerError, NotFoundError } from "@shared-classes/Errors"
|
||||
|
||||
import TidalAPI from "@shared-classes/TidalAPI"
|
||||
|
||||
export default async (req, res) => {
|
||||
if (!req.session) {
|
||||
return new AuthorizationError(req, res)
|
||||
}
|
||||
|
||||
try {
|
||||
const access_token = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_access_token")
|
||||
|
||||
if (!access_token) {
|
||||
return new AuthorizationError(req, res, "Its needed to link your TIDAL account to perform this action.")
|
||||
}
|
||||
|
||||
let user_data = await SecureSyncEntry.get(req.session.user_id.toString(), "tidal_user")
|
||||
|
||||
user_data = JSON.parse(user_data)
|
||||
|
||||
const response = await TidalAPI.getFavoriteTracks({
|
||||
user_id: user_data.id,
|
||||
country: user_data.countryCode,
|
||||
access_token: access_token,
|
||||
})
|
||||
|
||||
return res.json(response)
|
||||
} catch (error) {
|
||||
return new InternalServerError(req, res, error)
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import axios from "axios"
|
||||
import { DateTime } from "luxon"
|
||||
|
||||
const TIDAL_CLIENT_ID = process.env.TIDAL_CLIENT_ID
|
||||
const TIDAL_CLIENT_SECRET = process.env.TIDAL_CLIENT_SECRET
|
||||
@ -169,6 +170,73 @@ export default class TidalAPI {
|
||||
}
|
||||
})
|
||||
|
||||
return response.data
|
||||
return response.data.tracks.items.map((item) => {
|
||||
item._id = item.id
|
||||
|
||||
const coverUID = item.album.cover.replace(/-/g, "/")
|
||||
|
||||
item.cover = `https://resources.tidal.com/images/${coverUID}/1280x1280.jpg`
|
||||
|
||||
item.artist = item.artists.map(artist => artist.name).join(", ")
|
||||
|
||||
item.metadata = {
|
||||
title: item.title,
|
||||
artists: item.artists.map(artist => artist.name).join(", "),
|
||||
artist: item.artists.map(artist => artist.name).join(", "),
|
||||
album: item.album.title,
|
||||
duration: item.duration
|
||||
}
|
||||
|
||||
item.service = "tidal"
|
||||
|
||||
return item
|
||||
})
|
||||
}
|
||||
static async getFavoriteTracks({
|
||||
user_id,
|
||||
country,
|
||||
access_token,
|
||||
}) {
|
||||
const url = `https://api.tidal.com/v1/users/${user_id}/favorites/tracks?countryCode=${country}`
|
||||
|
||||
const response = await axios({
|
||||
method: "GET",
|
||||
url,
|
||||
headers: {
|
||||
"Origin": "http://listen.tidal.com",
|
||||
Authorization: `Bearer ${access_token}`
|
||||
},
|
||||
params: {
|
||||
order: "DATE",
|
||||
orderDirection: "DESC"
|
||||
}
|
||||
})
|
||||
|
||||
return response.data.items.map((item) => {
|
||||
// get js time
|
||||
item.item.liked_at = new Date(item.created).getTime()
|
||||
item.item.service = "tidal"
|
||||
|
||||
item.item._id = item.item.id
|
||||
|
||||
const coverUID = item.item.album.cover.replace(/-/g, "/")
|
||||
|
||||
item.item.cover = `https://resources.tidal.com/images/${coverUID}/1280x1280.jpg`
|
||||
|
||||
item.item.artist = item.item.artists.map(artist => artist.name).join(", ")
|
||||
|
||||
item.item.metadata = {
|
||||
title: item.item.title,
|
||||
artists: item.item.artists.map(artist => artist.name).join(", "),
|
||||
artist: item.item.artists.map(artist => artist.name).join(", "),
|
||||
album: item.item.album.title,
|
||||
duration: item.item.duration
|
||||
}
|
||||
|
||||
item.item.liked = true
|
||||
item.item._computed = true
|
||||
|
||||
return item.item
|
||||
})
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user