Connect Apple Music and Spotify-via-Last.fm on iPhone
- Local Expo module (Swift): MusicKit authorization, Music User Token via MusicUserTokenProvider, and live Music app now-playing while the app is open (MediaPlayer notifications), reported through the device endpoint - One-tap Apple Music onboarding on iOS; Apple Music row in Settings - Sign in with Last.fm, plus a guided Spotify-via-Last.fm flow when direct Spotify sign-in is capped - Device registration moved to shared code used by Android and iOS Not yet compiled for iOS (no Xcode here); needs an EAS build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MzFywujuH9TiuXbr9vjoX8
This commit is contained in:
@@ -3,13 +3,15 @@ import { useEffect, useState } from 'react';
|
||||
import { FlatList, RefreshControl, StyleSheet, Text, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import useSWR from 'swr';
|
||||
import { sortFeed, type FeedItemDTO, type ProfileDTO } from '@musicshare/shared';
|
||||
import { sortFeed, type ConnectionDTO, type FeedItemDTO, type ProfileDTO } from '@musicshare/shared';
|
||||
import { NowPlayingCard } from '@/components/NowPlayingCard';
|
||||
import { SharingControls } from '@/components/SharingControls';
|
||||
import { Body, Button, Card, Title } from '@/components/ui';
|
||||
import { api } from '@/lib/api';
|
||||
import { showError } from '@/lib/errors';
|
||||
import { shouldOfferSetup, useReader } from '@/lib/nowPlayingReader';
|
||||
import { appleMusicAvailable } from '@/lib/appleMusic';
|
||||
import { useReader } from '@/lib/nowPlayingReader';
|
||||
import { shouldOfferSetup } from '@/lib/setup';
|
||||
import { useRealtime } from '@/lib/useRealtime';
|
||||
import { useSession } from '@/lib/session';
|
||||
import { colors, space } from '@/lib/theme';
|
||||
@@ -22,6 +24,8 @@ export default function FeedScreen() {
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const reader = useReader();
|
||||
const { data: connections } = useSWR<ConnectionDTO[]>(appleMusicAvailable ? '/connections' : null);
|
||||
const offerAppleMusic = appleMusicAvailable && connections !== undefined && connections.length === 0;
|
||||
|
||||
// First run on Android: open the one-tap setup once (deferred so navigation has mounted).
|
||||
useEffect(() => {
|
||||
@@ -74,6 +78,12 @@ export default function FeedScreen() {
|
||||
ListHeaderComponent={
|
||||
<View style={styles.header}>
|
||||
<SharingControls compact />
|
||||
{offerAppleMusic && (
|
||||
<Card>
|
||||
<Body>Connect Apple Music so friends see what you play. One tap.</Body>
|
||||
<Button small variant="primary" title="Connect" onPress={() => router.push('/share-setup')} style={{ alignSelf: 'flex-start' }} />
|
||||
</Card>
|
||||
)}
|
||||
{reader.available && !reader.granted && (
|
||||
<Card>
|
||||
<Body>Share what you’re playing in Spotify, YouTube Music and other apps. One tap, no accounts.</Body>
|
||||
|
||||
Reference in New Issue
Block a user