Songs offered links to all five services. Settings now has "Your music services": pick the ones you use and songs only show those, with the main one as the big button. Until someone picks, they still see all of them. Onboarding sets it to the app you said you listen with. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -222,6 +222,8 @@ input:focus, textarea:focus, select:focus {
|
||||
.card-header .pin { flex-shrink: 0; }
|
||||
.form { display: flex; flex-direction: column; gap: 0.8rem; }
|
||||
.form label { display: flex; flex-direction: column; gap: 0.35rem; font-weight: 600; font-size: 0.9rem; }
|
||||
.services-picker { border: 0; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.35rem; }
|
||||
.services-picker legend { font-weight: 600; font-size: 0.9rem; padding: 0; margin-bottom: 0.35rem; }
|
||||
.form label.checkbox { flex-direction: row; align-items: center; gap: 0.5rem; font-weight: 500; }
|
||||
|
||||
/* Now-playing cards take their colour from the album art. */
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
type MeDTO,
|
||||
type NowPlayingProvider,
|
||||
type ProfileDTO,
|
||||
type StreamingService,
|
||||
type TrackSearchResultDTO,
|
||||
type UserSummaryDTO,
|
||||
} from '@musicshare/shared';
|
||||
@@ -58,10 +59,18 @@ function ProfileForm({ me }: { me: MeDTO }) {
|
||||
e.preventDefault();
|
||||
const f = new FormData(e.currentTarget);
|
||||
const str = (k: string) => (f.get(k) as string).trim() || null;
|
||||
const services = f.getAll('services') as StreamingService[];
|
||||
const preferred = str('preferredService') as StreamingService | null;
|
||||
try {
|
||||
const updated = await api<MeDTO>('/me', {
|
||||
method: 'PATCH',
|
||||
body: { displayName: str('displayName'), bio: str('bio'), preferredService: str('preferredService') },
|
||||
body: {
|
||||
displayName: str('displayName'),
|
||||
bio: str('bio'),
|
||||
services: services.length ? services : null,
|
||||
// The main service has to be one you use.
|
||||
preferredService: preferred && (!services.length || services.includes(preferred)) ? preferred : (services[0] ?? null),
|
||||
},
|
||||
});
|
||||
await mutate(updated, { revalidate: false });
|
||||
setError(null);
|
||||
@@ -84,6 +93,18 @@ function ProfileForm({ me }: { me: MeDTO }) {
|
||||
Bio
|
||||
<textarea name="bio" defaultValue={me.bio ?? ''} maxLength={280} rows={2} />
|
||||
</label>
|
||||
<fieldset className="services-picker">
|
||||
<legend>Your music services</legend>
|
||||
<span className="muted">Songs only show links for the ones you pick.</span>
|
||||
<div className="row">
|
||||
{STREAMING_SERVICES.map((s) => (
|
||||
<label key={s} className="checkbox">
|
||||
<input type="checkbox" name="services" value={s} defaultChecked={me.services?.includes(s)} />
|
||||
{SERVICE_LABELS[s]}
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</fieldset>
|
||||
<label>
|
||||
Open songs in
|
||||
<select name="preferredService" defaultValue={me.preferredService ?? ''}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { STREAMING_SERVICES, SERVICE_LABELS, openUrl, type StreamingService, type TrackDTO } from '@musicshare/shared';
|
||||
import { SERVICE_LABELS, openUrl, viewerServices, type StreamingService, type TrackDTO } from '@musicshare/shared';
|
||||
import { useMe } from '@/lib/api';
|
||||
import { ShareButton } from './ShareButton';
|
||||
|
||||
/**
|
||||
@@ -20,7 +21,8 @@ export function TrackCard({
|
||||
/** When the page already shows the artwork big. */
|
||||
hideArtwork?: boolean;
|
||||
}) {
|
||||
const others = STREAMING_SERVICES.filter((s) => s !== preferred);
|
||||
const { me } = useMe();
|
||||
const others = viewerServices(me).filter((s) => s !== preferred);
|
||||
const primary = preferred ? openUrl(track, preferred) : null;
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user