New look: slate-indigo panels, pink accent, Poppins, and a gradient card for your song
Inspired by a dashboard design the user shared. - App: new palette and fonts, borderless rounded panels with soft shadows, a pink-to-blue gradient card for your own song (text and controls switch to white on it), flat cards for friends, a 'Hi Chris, welcome back' header, an outline bell, and a pink pill on the active tab. - Website: the same look, plus a wide-screen layout with a sidebar, the page in a rounded panel, and a right column with your profile, recent activity and recent plays. Phones keep the top bar and bottom tabs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011Y2iUsKEWDuRGjK5FPmcUP
This commit is contained in:
@@ -3,7 +3,7 @@ import { Linking, Pressable, StyleSheet, Text, View } from 'react-native';
|
||||
import Animated, { LinearTransition } from 'react-native-reanimated';
|
||||
import useSWR from 'swr';
|
||||
import { currentLyricIndex, playbackPosition, type LyricLine, type LyricsDTO, type NowPlayingDTO, type TrackDTO } from '@musicshare/shared';
|
||||
import { colors, fonts, space } from '@/lib/theme';
|
||||
import { colors, fonts, space, useInk } from '@/lib/theme';
|
||||
|
||||
/** Lines shown around the current one while following along. */
|
||||
const BEFORE = 1;
|
||||
@@ -16,13 +16,15 @@ const PREVIEW = 8;
|
||||
* lines around the one being sung and follows along; "All lyrics" shows the rest.
|
||||
*/
|
||||
export function Lyrics({ track, np }: { track: TrackDTO; np?: NowPlayingDTO }) {
|
||||
const ink = useInk();
|
||||
const note = [styles.note, { color: ink.muted }];
|
||||
const { data, error, isLoading } = useSWR<LyricsDTO | null>(`/tracks/${track.id}/lyrics`);
|
||||
const [full, setFull] = useState(false);
|
||||
|
||||
if (isLoading) return <Text style={styles.note}>Finding lyrics…</Text>;
|
||||
if (error) return <Text style={styles.note}>Couldn't load lyrics right now.</Text>;
|
||||
if (!data) return <Text style={styles.note}>No lyrics found for this song.</Text>;
|
||||
if (data.instrumental && !data.synced && !data.plain) return <Text style={styles.note}>♪ Instrumental</Text>;
|
||||
if (isLoading) return <Text style={note}>Finding lyrics…</Text>;
|
||||
if (error) return <Text style={note}>Couldn't load lyrics right now.</Text>;
|
||||
if (!data) return <Text style={note}>No lyrics found for this song.</Text>;
|
||||
if (data.instrumental && !data.synced && !data.plain) return <Text style={note}>♪ Instrumental</Text>;
|
||||
|
||||
const synced = data.synced;
|
||||
const live = Boolean(np?.isPlaying && playbackPosition(np, 0));
|
||||
@@ -48,11 +50,11 @@ export function Lyrics({ track, np }: { track: TrackDTO; np?: NowPlayingDTO }) {
|
||||
</Pressable>
|
||||
<View style={styles.footer}>
|
||||
{canToggle && (
|
||||
<Text style={styles.toggle} onPress={() => setFull((v) => !v)}>
|
||||
<Text style={[styles.toggle, ink.hero && { color: '#ffffff' }]} onPress={() => setFull((v) => !v)}>
|
||||
{!full ? 'All lyrics' : synced && live ? 'Follow along' : 'Less'}
|
||||
</Text>
|
||||
)}
|
||||
<Text style={styles.source} onPress={() => Linking.openURL(data.source.url)}>
|
||||
<Text style={[styles.source, { color: ink.muted }]} onPress={() => Linking.openURL(data.source.url)}>
|
||||
Lyrics from {data.source.name}
|
||||
</Text>
|
||||
</View>
|
||||
@@ -85,13 +87,13 @@ function FollowAlong({ lines, np }: { lines: LyricLine[]; np: NowPlayingDTO }) {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
wrap: { gap: space.sm },
|
||||
note: { color: colors.muted, fontSize: 13 },
|
||||
line: { color: colors.text, fontSize: 15, lineHeight: 22 },
|
||||
note: { color: colors.muted, fontSize: 13, fontFamily: fonts.body },
|
||||
line: { color: colors.text, fontSize: 14.5, lineHeight: 22, fontFamily: fonts.body },
|
||||
plain: { opacity: 0.9 },
|
||||
past: { opacity: 0.4 },
|
||||
now: { fontFamily: fonts.display, fontSize: 17, lineHeight: 24 },
|
||||
next: { opacity: 0.65 },
|
||||
footer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
|
||||
toggle: { color: colors.accent2, fontSize: 13, fontWeight: '600' },
|
||||
source: { color: colors.muted, fontSize: 11, marginLeft: 'auto' },
|
||||
toggle: { color: colors.accent, fontSize: 13, fontFamily: fonts.bodyMedium },
|
||||
source: { color: colors.muted, fontSize: 11, fontFamily: fonts.body, marginLeft: 'auto' },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user