mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
- Introduces a new Music Library system for managing favorites (tracks, playlists, releases), replacing the previous TrackLike model. - Completely revamps the Studio TV profile page, adding live statistics, stream configuration, restream management, and media URL display. - Enhances the media player with a custom seekbar and improved audio playback logic for MPD and non-MPD sources. - Lays foundational groundwork for chat encryption with new models and APIs. - Refactors critical UI components like PlaylistView and PagePanel. - Standardizes monorepo development scripts to use npm. - Updates comty.js submodule and adds various new UI components.
152 lines
3.0 KiB
JavaScript
152 lines
3.0 KiB
JavaScript
import { MusicRelease, Track } from "@db_models"
|
|
import TrackClass from "../track"
|
|
|
|
const AllowedUpdateFields = [
|
|
"title",
|
|
"cover",
|
|
"album",
|
|
"artist",
|
|
"type",
|
|
"public",
|
|
"items",
|
|
]
|
|
|
|
export default class Release {
|
|
// TODO: implement pagination
|
|
static async data(id, { user_id = null, limit = 10, offset = 0 } = {}) {
|
|
let release = await MusicRelease.findOne({
|
|
_id: id,
|
|
})
|
|
|
|
if (!release) {
|
|
throw new OperationError(404, "Release not found")
|
|
}
|
|
|
|
release = release.toObject()
|
|
|
|
const items = release.items ?? release.list
|
|
|
|
const totalTracks = await Track.countDocuments({
|
|
_id: items,
|
|
})
|
|
|
|
const tracks = await TrackClass.get(items, {
|
|
user_id: user_id,
|
|
onlyList: true,
|
|
})
|
|
|
|
release.total_duration = tracks.reduce((acc, track) => {
|
|
if (track.metadata?.duration) {
|
|
return acc + parseFloat(track.metadata.duration)
|
|
}
|
|
|
|
return acc
|
|
}, 0)
|
|
release.total_items = totalTracks
|
|
release.items = tracks
|
|
|
|
return release
|
|
}
|
|
|
|
static async create(payload) {
|
|
if (!payload.title) {
|
|
throw new OperationError(400, "Release title is required")
|
|
}
|
|
|
|
if (!payload.items) {
|
|
throw new OperationError(400, "Release items is required")
|
|
}
|
|
|
|
// ensure list is an array of strings with tracks ids only
|
|
payload.items = payload.items.map((item) => {
|
|
return item._id ?? item
|
|
})
|
|
|
|
const release = new MusicRelease({
|
|
user_id: payload.user_id,
|
|
created_at: Date.now(),
|
|
title: payload.title,
|
|
cover: payload.cover,
|
|
explicit: payload.explicit,
|
|
type: payload.type,
|
|
public: payload.public,
|
|
items: payload.items,
|
|
public: payload.public,
|
|
})
|
|
|
|
await release.save()
|
|
|
|
return release
|
|
}
|
|
|
|
static async update(id, payload) {
|
|
let release = await MusicRelease.findById(id).catch((err) => {
|
|
return false
|
|
})
|
|
|
|
if (!release) {
|
|
throw new OperationError(404, "Release not found")
|
|
}
|
|
|
|
if (release.user_id !== payload.user_id) {
|
|
throw new PermissionError(
|
|
403,
|
|
"You dont have permission to edit this release",
|
|
)
|
|
}
|
|
|
|
for (const field of AllowedUpdateFields) {
|
|
if (typeof payload[field] !== "undefined") {
|
|
release[field] = payload[field]
|
|
}
|
|
}
|
|
|
|
// ensure list is an array of strings with tracks ids only
|
|
release.items = release.items.map((item) => {
|
|
return item._id ?? item
|
|
})
|
|
|
|
await MusicRelease.findByIdAndUpdate(id, release)
|
|
|
|
return release
|
|
}
|
|
|
|
static async delete(id, payload = {}) {
|
|
let release = await MusicRelease.findById(id).catch((err) => {
|
|
return false
|
|
})
|
|
|
|
if (!release) {
|
|
throw new OperationError(404, "Release not found")
|
|
}
|
|
|
|
// check permission
|
|
if (release.user_id !== payload.user_id) {
|
|
throw new PermissionError(
|
|
403,
|
|
"You dont have permission to edit this release",
|
|
)
|
|
}
|
|
|
|
const items = release.items ?? release.list
|
|
|
|
const items_ids = items.map((item) => item._id.toString())
|
|
|
|
// delete all releated tracks
|
|
await Track.deleteMany({
|
|
_id: { $in: items_ids },
|
|
})
|
|
|
|
// delete release
|
|
await MusicRelease.deleteOne({
|
|
_id: id,
|
|
})
|
|
|
|
return release
|
|
}
|
|
|
|
static async fullfillItemData(release) {
|
|
return release
|
|
}
|
|
}
|