Map track coauthors, coauthor invites and invitations
This commit is contained in:
@@ -5,6 +5,8 @@ import {
|
|||||||
toCount,
|
toCount,
|
||||||
toDatedTrack,
|
toDatedTrack,
|
||||||
toLikedTrack,
|
toLikedTrack,
|
||||||
|
toCoauthorInvitation,
|
||||||
|
toLibraryTrack,
|
||||||
toListeningStats,
|
toListeningStats,
|
||||||
toMix,
|
toMix,
|
||||||
toPage,
|
toPage,
|
||||||
@@ -25,7 +27,7 @@ const trackDto: components['schemas']['TrackApplicationResponse'] = {
|
|||||||
tags: [],
|
tags: [],
|
||||||
isExplicit: true,
|
isExplicit: true,
|
||||||
isPublished: true,
|
isPublished: true,
|
||||||
coauthors: []
|
coauthors: [{ id: 'u2', name: 'Guest' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('toTrack', () => {
|
describe('toTrack', () => {
|
||||||
@@ -37,7 +39,8 @@ describe('toTrack', () => {
|
|||||||
ownerUserId: '42',
|
ownerUserId: '42',
|
||||||
explicit: true,
|
explicit: true,
|
||||||
duration: 183.5,
|
duration: 183.5,
|
||||||
listensCount: 12
|
listensCount: 12,
|
||||||
|
coauthors: [{ id: 'u2', name: 'Guest' }]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('falls back to 0 for invalid numbers', () => {
|
it('falls back to 0 for invalid numbers', () => {
|
||||||
@@ -71,7 +74,8 @@ describe('toMix', () => {
|
|||||||
ownerUserId: null,
|
ownerUserId: null,
|
||||||
explicit: false,
|
explicit: false,
|
||||||
duration: 60,
|
duration: 60,
|
||||||
listensCount: 3
|
listensCount: 3,
|
||||||
|
coauthors: []
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@@ -168,3 +172,35 @@ describe('toListeningStats', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('toLibraryTrack', () => {
|
||||||
|
it('keeps the coauthor invites with their status', () => {
|
||||||
|
const track = toLibraryTrack({
|
||||||
|
...trackDto,
|
||||||
|
albums: [],
|
||||||
|
coauthorInvites: [
|
||||||
|
{ userId: 'u2', name: 'Guest', status: 'Accepted' },
|
||||||
|
{ userId: 'u3', name: 'Other', status: 'Pending' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
expect(track.coauthorInvites).toEqual([
|
||||||
|
{ userId: 'u2', name: 'Guest', status: 'Accepted' },
|
||||||
|
{ userId: 'u3', name: 'Other', status: 'Pending' }
|
||||||
|
]);
|
||||||
|
expect(track.coauthors).toEqual([{ id: 'u2', name: 'Guest' }]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toCoauthorInvitation', () => {
|
||||||
|
it('copies the invitation fields', () => {
|
||||||
|
const dto = {
|
||||||
|
id: 'i1',
|
||||||
|
trackId: 't1',
|
||||||
|
trackTitle: 'Song',
|
||||||
|
artist: null,
|
||||||
|
ownerUserId: '42',
|
||||||
|
invitedAt: '2026-01-02T00:00:00Z'
|
||||||
|
};
|
||||||
|
expect(toCoauthorInvitation(dto)).toEqual(dto);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { components } from '$lib/api/schema';
|
import type { components } from '$lib/api/schema';
|
||||||
import type {
|
import type {
|
||||||
Album,
|
Album,
|
||||||
|
CoauthorInvitation,
|
||||||
|
CoauthorInvite,
|
||||||
LibraryTrack,
|
LibraryTrack,
|
||||||
TrackStatusCounts,
|
TrackStatusCounts,
|
||||||
LikedTrack,
|
LikedTrack,
|
||||||
@@ -13,6 +15,8 @@ import type {
|
|||||||
|
|
||||||
type TrackDto = components['schemas']['TrackApplicationResponse'];
|
type TrackDto = components['schemas']['TrackApplicationResponse'];
|
||||||
type UserTrackDto = components['schemas']['UserTrackApplicationResponse'];
|
type UserTrackDto = components['schemas']['UserTrackApplicationResponse'];
|
||||||
|
type CoauthorInviteDto = components['schemas']['TrackCoauthorInviteReference'];
|
||||||
|
type CoauthorInvitationDto = components['schemas']['CoauthorInvitationResponse'];
|
||||||
type StatusCountsDto = components['schemas']['TrackStatusCountsResponse'];
|
type StatusCountsDto = components['schemas']['TrackStatusCountsResponse'];
|
||||||
type AlbumDto = components['schemas']['AlbumApplicationResponse'];
|
type AlbumDto = components['schemas']['AlbumApplicationResponse'];
|
||||||
type PlaylistDto = components['schemas']['PlayListApplicationResponse'];
|
type PlaylistDto = components['schemas']['PlayListApplicationResponse'];
|
||||||
@@ -34,7 +38,8 @@ export function toTrack(dto: TrackDto): Track {
|
|||||||
ownerUserId: dto.ownerUserId,
|
ownerUserId: dto.ownerUserId,
|
||||||
explicit: dto.isExplicit,
|
explicit: dto.isExplicit,
|
||||||
duration: Number(dto.duration) || 0,
|
duration: Number(dto.duration) || 0,
|
||||||
listensCount: Number(dto.listensCount) || 0
|
listensCount: Number(dto.listensCount) || 0,
|
||||||
|
coauthors: dto.coauthors.map(({ id, name }) => ({ id, name }))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +47,21 @@ export function toDatedTrack(dto: TrackDto): Track & { date: string } {
|
|||||||
return { ...toTrack(dto), date: dto.createdAt };
|
return { ...toTrack(dto), date: dto.createdAt };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toCoauthorInvite({ userId, name, status }: CoauthorInviteDto): CoauthorInvite {
|
||||||
|
return { userId, name, status };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toCoauthorInvitation(dto: CoauthorInvitationDto): CoauthorInvitation {
|
||||||
|
return {
|
||||||
|
id: dto.id,
|
||||||
|
trackId: dto.trackId,
|
||||||
|
trackTitle: dto.trackTitle,
|
||||||
|
artist: dto.artist,
|
||||||
|
ownerUserId: dto.ownerUserId,
|
||||||
|
invitedAt: dto.invitedAt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function toLibraryTrack(dto: UserTrackDto): LibraryTrack {
|
export function toLibraryTrack(dto: UserTrackDto): LibraryTrack {
|
||||||
return {
|
return {
|
||||||
...toDatedTrack(dto),
|
...toDatedTrack(dto),
|
||||||
@@ -49,7 +69,8 @@ export function toLibraryTrack(dto: UserTrackDto): LibraryTrack {
|
|||||||
genres: dto.tags,
|
genres: dto.tags,
|
||||||
albums: dto.albums,
|
albums: dto.albums,
|
||||||
albumTitle: dto.albums.length > 0 ? dto.albums.map((album) => album.title).join(', ') : null,
|
albumTitle: dto.albums.length > 0 ? dto.albums.map((album) => album.title).join(', ') : null,
|
||||||
published: dto.isPublished
|
published: dto.isPublished,
|
||||||
|
coauthorInvites: dto.coauthorInvites.map(toCoauthorInvite)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +96,8 @@ export function toMixTrack(item: MixItemDto): Track {
|
|||||||
ownerUserId: null,
|
ownerUserId: null,
|
||||||
explicit: false,
|
explicit: false,
|
||||||
duration: Number(item.durationSeconds) || 0,
|
duration: Number(item.durationSeconds) || 0,
|
||||||
listensCount: Number(item.listensCount) || 0
|
listensCount: Number(item.listensCount) || 0,
|
||||||
|
coauthors: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,28 @@ export interface SessionUser {
|
|||||||
|
|
||||||
export type FollowList = 'followers' | 'following';
|
export type FollowList = 'followers' | 'following';
|
||||||
|
|
||||||
|
export interface TrackCoauthor {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CoauthorStatus = 'Pending' | 'Accepted' | 'Rejected';
|
||||||
|
|
||||||
|
export interface CoauthorInvite {
|
||||||
|
userId: string;
|
||||||
|
name: string;
|
||||||
|
status: CoauthorStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CoauthorInvitation {
|
||||||
|
id: string;
|
||||||
|
trackId: string;
|
||||||
|
trackTitle: string;
|
||||||
|
artist: string | null;
|
||||||
|
ownerUserId: string;
|
||||||
|
invitedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Track {
|
export interface Track {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -15,6 +37,7 @@ export interface Track {
|
|||||||
explicit: boolean;
|
explicit: boolean;
|
||||||
duration: number;
|
duration: number;
|
||||||
listensCount: number;
|
listensCount: number;
|
||||||
|
coauthors: TrackCoauthor[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GenreOption {
|
export interface GenreOption {
|
||||||
@@ -31,6 +54,7 @@ export interface LibraryTrack extends Track {
|
|||||||
albumTitle: string | null;
|
albumTitle: string | null;
|
||||||
albums: { id: string; title: string }[];
|
albums: { id: string; title: string }[];
|
||||||
published: boolean;
|
published: boolean;
|
||||||
|
coauthorInvites: CoauthorInvite[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TrackStatusCounts {
|
export interface TrackStatusCounts {
|
||||||
|
|||||||
Reference in New Issue
Block a user