Skip to content

Commit f91cf57

Browse files
Big ol' state rejig
A step towards where I want to be but still more to do. This separates global state from props enough to make track tables far more reusable, as they should be, but the data model needs to be tidier
1 parent 40facac commit f91cf57

File tree

9 files changed

+78
-105
lines changed

9 files changed

+78
-105
lines changed

app/src/lib/components/releases/ReleaseTrackButton.svelte

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
<script lang="ts">
22
import { setActiveSong, userState } from '$lib/global/state.svelte';
3-
import type { ReleaseHydrated, UserProfile, TrackRaw } from '../../../../../shared/types';
4-
import type { Session } from '@supabase/supabase-js';
3+
import type { ReleaseHydrated, TrackRaw } from '../../../../../shared/types';
54
import Pause from '../icons/Pause.svelte';
65
import Play from '../icons/Play.svelte';
76
import ButtonWrapper from '../layout/ButtonWrapper.svelte';
87
98
let {
109
track,
11-
release,
12-
profileData,
13-
session
10+
release
1411
}: {
1512
track: TrackRaw;
1613
release: ReleaseHydrated;
17-
profileData: UserProfile;
18-
session: Session;
1914
} = $props();
2015
</script>
2116

@@ -25,13 +20,7 @@
2520
if (track.ipfs_cid == userState.activeSong?.ipfs_cid) {
2621
userState.activeSongIsPaused = !userState.activeSongIsPaused;
2722
} else {
28-
setActiveSong(
29-
track,
30-
release,
31-
session.user.id,
32-
userState.liveBalance ?? profileData.tokens_balance,
33-
profileData.pay_per_stream
34-
);
23+
setActiveSong(track, release, userState.id, userState.liveBalance, userState.payPerStream);
3524
userState.autoPlay = false;
3625
}
3726
}}

app/src/lib/components/releases/TracksTable.svelte

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,12 @@
11
<script lang="ts">
2-
import type {
3-
LikedTrackObject,
4-
Mixtape,
5-
ReleaseHydrated,
6-
UserProfile
7-
} from '../../../../../shared/types';
8-
import type { Session } from '@supabase/supabase-js';
2+
import type { ReleaseHydrated, TrackRaw } from '../../../../../shared/types';
93
import TrackTableRow from './TracksTableRow.svelte';
104
115
const {
12-
release,
13-
profileData,
14-
likedTracks,
15-
mixtapes,
16-
session,
6+
tracksAndTheirReleases,
177
showReleaseAndArtist = false
188
}: {
19-
release: ReleaseHydrated;
20-
profileData: UserProfile;
21-
likedTracks: LikedTrackObject[];
22-
mixtapes: Mixtape[];
23-
session: Session;
9+
tracksAndTheirReleases: { track: TrackRaw; release: ReleaseHydrated }[];
2410
showReleaseAndArtist?: boolean;
2511
} = $props();
2612
</script>
@@ -41,17 +27,8 @@
4127
</tr>
4228
</thead>
4329
<tbody>
44-
{#each release.tracks as track, i}
45-
<TrackTableRow
46-
i={i + 1}
47-
{track}
48-
{release}
49-
{profileData}
50-
{session}
51-
{likedTracks}
52-
{mixtapes}
53-
{showReleaseAndArtist}
54-
/>
30+
{#each tracksAndTheirReleases as { track, release }, i}
31+
<TrackTableRow i={i + 1} {track} {release} {showReleaseAndArtist} />
5532
{/each}
5633
</tbody>
5734
</table>

app/src/lib/components/releases/TracksTableRow.svelte

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,22 @@
11
<script lang="ts">
2-
import type {
3-
LikedTrackObject,
4-
Mixtape,
5-
ReleaseHydrated,
6-
TrackRaw,
7-
UserProfile
8-
} from '../../../../../shared/types';
2+
import type { ReleaseHydrated, TrackRaw } from '../../../../../shared/types';
93
import { prettifyDuration } from '../../../../../shared/utils';
10-
import type { Session } from '@supabase/supabase-js';
114
import ReleaseTrackButton from './ReleaseTrackButton.svelte';
125
import TrackLikeButton from './TrackLikeButton.svelte';
136
import ThreeDots from '../icons/ThreeDots.svelte';
147
import PopupWrapper from '../layout/PopupWrapper.svelte';
158
import { addTrackToMixtape } from '$lib/remote-functions/mixtapes.remote';
9+
import { userState } from '$lib/global/state.svelte';
1610
1711
const {
1812
i = undefined,
1913
track,
2014
release,
21-
profileData,
22-
session,
23-
likedTracks,
24-
mixtapes,
2515
showReleaseAndArtist = false
2616
}: {
2717
i?: number;
2818
track: TrackRaw;
2919
release: ReleaseHydrated;
30-
profileData: UserProfile;
31-
session: Session;
32-
likedTracks: LikedTrackObject[];
33-
mixtapes: Mixtape[];
3420
showReleaseAndArtist: boolean;
3521
} = $props();
3622
@@ -46,10 +32,14 @@
4632
{/if}
4733
<td>{prettifyDuration(track.duration_seconds)}</td>
4834
<td class="play-button-container">
49-
<ReleaseTrackButton {track} {release} {profileData} {session} />
35+
<ReleaseTrackButton {track} {release} />
5036
</td>
5137
<td>
52-
<TrackLikeButton trackID={track.id} {likedTracks} lightOrDark={'light'} />
38+
<TrackLikeButton
39+
trackID={track.id}
40+
likedTracks={userState.music.likedTracks}
41+
lightOrDark={'light'}
42+
/>
5343
</td>
5444
<td>
5545
<div onclick={() => (popupMenuOpen = !popupMenuOpen)}><ThreeDots /></div>
@@ -65,7 +55,7 @@
6555
>Add to mixtape:
6656
<select {...addTrackToMixtape.fields.mixtapeId.as('select')}>
6757
<option value="" disabled selected>Select a mixtape</option>
68-
{#each mixtapes as mixtape}
58+
{#each userState.music.mixtapes as mixtape}
6959
<option value={mixtape.id}>{mixtape.name}</option>
7060
{/each}
7161
</select>

app/src/lib/global/state.svelte.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,39 @@
1-
import type { ReleaseHydrated, TrackRaw } from '../../../../shared/types';
1+
import type {
2+
LikedTrackObject,
3+
Mixtape,
4+
ReleaseHydrated,
5+
TrackRaw
6+
} from '../../../../shared/types';
27
import { API_BASE } from './config';
38

49
interface UserState {
10+
id: string;
511
activeSong: TrackRaw | null;
612
activeSongRelease: ReleaseHydrated | null;
713
activeSongUrl: string | null;
814
activeSongIsPaused: boolean;
915
autoPlay: boolean;
10-
liveBalance: number | null;
16+
liveBalance: number;
1117
payPerStream: number;
18+
music: {
19+
likedTracks: LikedTrackObject[];
20+
mixtapes: Mixtape[];
21+
};
1222
}
1323

1424
export const userState: UserState = $state({
25+
id: '',
1526
activeSong: null,
1627
activeSongRelease: null,
1728
activeSongUrl: null,
1829
activeSongIsPaused: false,
1930
autoPlay: false,
2031
liveBalance: 0,
21-
payPerStream: 3
32+
payPerStream: 3,
33+
music: {
34+
likedTracks: [],
35+
mixtapes: []
36+
}
2237
});
2338

2439
const logStream = async (userId: string, artistId: string, trackId: string, tokensUsed: number) => {

app/src/routes/+layout.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
3939
if (data.profileData) {
4040
userState.liveBalance = data.profileData.tokens_balance;
4141
userState.payPerStream = data.profileData.pay_per_stream;
42+
userState.music.likedTracks = data.likedTracks;
43+
userState.music.mixtapes = data.mixtapes;
4244
}
4345

4446
return {

app/src/routes/me/liked-tracks/+page.svelte

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,7 @@
2626
</thead>
2727
<tbody>
2828
{#each data.likedTracks as { track, release }}
29-
<TracksTableRow
30-
{track}
31-
{release}
32-
session={data.session}
33-
profileData={data.profileData}
34-
likedTracks={data.likedTracks}
35-
mixtapes={data.mixtapes}
36-
showReleaseAndArtist={true}
37-
/>
29+
<TracksTableRow {track} {release} showReleaseAndArtist={true} />
3830
{/each}
3931
</tbody>
4032
</table>

app/src/routes/me/mixtapes/+page.svelte

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import TracksTable from '$lib/components/releases/TracksTable.svelte';
23
import { makeMixtape } from '$lib/remote-functions/mixtapes.remote';
34
45
let { data } = $props();
@@ -7,8 +8,8 @@
78
</script>
89

910
<svelte:head>
10-
<title>Your mixtapes · Soli</title>
11-
<meta name="description" content="Browse your mixtapes on Soli." />
11+
<title>Your mixtapes · Soli</title>
12+
<meta name="description" content="Browse your mixtapes on Soli." />
1213
</svelte:head>
1314

1415
<h2>Your mixtapes</h2>
@@ -20,15 +21,13 @@
2021
{#if mixtape.description}
2122
<div>{mixtape.description}</div>
2223
{/if}
23-
{#if mixtape.tracks.length > 0}
24-
{#each mixtape.tracks as track, i}
25-
<div>
26-
{i + 1}. {track.title} by <a href="/artists/{track.artist.id}">{track.artist.name}</a>
27-
</div>
28-
{/each}
29-
{:else}
30-
<div>This mixtape has no tracks yet.</div>
31-
{/if}
24+
<TracksTable
25+
tracksAndTheirReleases={mixtape.tracks.map((track) => ({
26+
track,
27+
release: { ...track.release, artist_id: track.artist.id, artist_name: track.artist.name }
28+
}))}
29+
showReleaseAndArtist={true}
30+
/>
3231
</div>
3332
</div>
3433
{/each}

app/src/routes/releases/[slug]/+page.svelte

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
} from '../../../../../shared/types';
99
import { makeImageLink } from '$lib/utils';
1010
import type { Session } from '@supabase/supabase-js';
11-
import ReleaseTracks from '$lib/components/releases/TracksTable.svelte';
11+
import TracksTable from '$lib/components/releases/TracksTable.svelte';
1212
import { setActiveSong, userState } from '$lib/global/state.svelte';
1313
import ButtonWrapper from '$lib/components/layout/ButtonWrapper.svelte';
1414
import { formatReleaseType } from '../../../../../shared/utils';
@@ -88,12 +88,11 @@
8888
</div>
8989
</ButtonWrapper>
9090

91-
<ReleaseTracks
92-
{release}
93-
profileData={data.profileData}
94-
likedTracks={data.likedTracks}
95-
mixtapes={data.mixtapes}
96-
session={data.session}
91+
<TracksTable
92+
tracksAndTheirReleases={release.tracks.map((track) => ({
93+
track,
94+
release
95+
}))}
9796
/>
9897

9998
<hr />

shared/types/index.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,32 @@ export interface Collection {
8484

8585
export interface Mixtape {
8686
id: string;
87-
user_id: string;
87+
user_id: string | null;
8888
name: string;
89-
description?: string;
89+
description: string | null;
9090
is_public: boolean;
9191
created_at: string;
9292
updated_at: string;
93-
tracks?: {
93+
tracks: HydratedTrack[];
94+
}
95+
96+
export interface HydratedTrack {
97+
id: string;
98+
title: string;
99+
ipfs_cid: string;
100+
duration_seconds: number | null;
101+
added_at: string;
102+
artist: {
94103
id: string;
95-
title: string;
96-
ipfs_cid: string;
97-
duration_seconds: number;
98-
artist: {
99-
id: string;
100-
name: string;
101-
image_ipfs_cid?: string;
102-
};
103-
added_at: string;
104-
}[];
105-
}
104+
name: string;
105+
image_ipfs_cid: string | null;
106+
} | null;
107+
release: ParentRelease | null;
108+
}
109+
110+
export interface ParentRelease {
111+
id: string;
112+
title: string;
113+
artwork_ipfs_cid: string | null;
114+
release_date: string | null;
115+
}

0 commit comments

Comments
 (0)