Files
musicshare/apps/mobile/src/app/qr.tsx
T
chrisandClaude Opus 5.5 3568b71e90 Mobile: redesign, onboarding, QR codes, logo, Spotify setup
- Redesign matching the web: album-art backdrops, Reanimated equalizer,
  spinning live ring, drifting ambient background, gradient buttons with
  spring press feedback and haptics, Space Grotesk headings, animated feed
  (enter + layout transitions); fix invisible tab labels
- Four-step onboarding for new accounts: which app you listen with (sets
  where songs open), the matching share setup, find friends (search,
  scan, invite), and a featured song. Skippable; stored server-side
- QR codes: My code (share link) and an in-app scanner (camera only, no
  microphone permission)
- Spotify setup via Last.fm or ListenBrainz with guided linking; Android
  shares Spotify automatically through the phone reader
- New logo as app icon, adaptive/monochrome icon and splash
- app.config.ts allows cleartext only for local http:// test builds

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
2026-10-05 19:16:40 -04:00

48 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { router } from 'expo-router';
import { Share, StyleSheet, Text, View } from 'react-native';
import { profileUrl } from '@musicshare/shared';
import { Avatar } from '@/components/Avatar';
import { QrCode } from '@/components/QrCode';
import { Screen } from '@/components/Screen';
import { Body, Button } from '@/components/ui';
import { WEB_URL } from '@/lib/config';
import { useSession } from '@/lib/session';
import { colors, space } from '@/lib/theme';
/** "My code": friends scan it (in musicshare or any camera app) to open your profile. */
export default function MyQrScreen() {
const { me } = useSession();
if (!me) return null;
const url = profileUrl(WEB_URL, me.username);
const share = () =>
Share.share({ message: `Follow me on musicshare and see what I'm listening to: ${url}`, url }).catch(() => {});
return (
<Screen edges={['bottom']} contentContainerStyle={styles.content}>
<View style={styles.who}>
<Avatar user={me} size={56} />
<Text style={styles.name}>{me.displayName ?? me.username}</Text>
<Text style={styles.handle}>@{me.username}</Text>
</View>
<QrCode value={url} size={260} />
<Body muted style={styles.hint}>
Friends scan this with musicshare (or their camera app) to open your profile.
</Body>
<View style={styles.actions}>
<Button variant="primary" title="Scan a friend’s code" onPress={() => router.replace('/scan')} />
<Button title="Share link" onPress={share} />
</View>
</Screen>
);
}
const styles = StyleSheet.create({
content: { flexGrow: 1, alignItems: 'center', justifyContent: 'center', gap: space.xl },
who: { alignItems: 'center', gap: space.xs },
name: { color: colors.text, fontSize: 22, fontWeight: '800' },
handle: { color: colors.muted, fontSize: 15 },
hint: { textAlign: 'center', maxWidth: 300 },
actions: { alignSelf: 'stretch', gap: space.sm },
});