diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts new file mode 100644 index 0000000..5817d21 --- /dev/null +++ b/apps/mobile/app.config.ts @@ -0,0 +1,20 @@ +import type { ConfigContext, ExpoConfig } from 'expo/config'; + +/** + * app.json holds the real config; this only adds build-time switches. + * + * Local test builds point at a dev server over plain http://, which Android + * blocks by default in release builds. Allow cleartext only when the API URL + * itself is http://, so store builds (https) stay locked down. + */ +export default ({ config }: ConfigContext): ExpoConfig => { + const apiUrl = process.env.EXPO_PUBLIC_API_URL ?? ''; + const localHttp = apiUrl.startsWith('http://'); + return { + ...(config as ExpoConfig), + plugins: [ + ...(config.plugins ?? []), + ['expo-build-properties', { android: { usesCleartextTraffic: localHttp } }], + ], + }; +}; diff --git a/apps/mobile/app.json b/apps/mobile/app.json index 2c4421b..d16207d 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -8,7 +8,7 @@ "scheme": "musicshare", "userInterfaceStyle": "dark", "ios": { - "icon": "./assets/expo.icon", + "icon": "./assets/images/icon.png", "bundleIdentifier": "tech.chrisedwards.musicshare", "infoPlist": { "NSAppleMusicUsageDescription": "musicshare shows your friends what you play in Apple Music, and opens their songs for you." @@ -16,7 +16,7 @@ }, "android": { "adaptiveIcon": { - "backgroundColor": "#0e0f13", + "backgroundColor": "#1a0a4a", "foregroundImage": "./assets/images/android-icon-foreground.png", "backgroundImage": "./assets/images/android-icon-background.png", "monochromeImage": "./assets/images/android-icon-monochrome.png" @@ -30,9 +30,17 @@ [ "expo-splash-screen", { - "backgroundColor": "#0e0f13", + "backgroundColor": "#0b0820", "image": "./assets/images/splash-icon.png", - "imageWidth": 76 + "imageWidth": 150 + } + ], + [ + "expo-camera", + { + "cameraPermission": "musicshare uses the camera to scan friends' QR codes.", + "microphonePermission": false, + "recordAudioAndroid": false } ] ], diff --git a/apps/mobile/assets/images/ambient-blue.png b/apps/mobile/assets/images/ambient-blue.png new file mode 100644 index 0000000..1524ed1 Binary files /dev/null and b/apps/mobile/assets/images/ambient-blue.png differ diff --git a/apps/mobile/assets/images/ambient-purple.png b/apps/mobile/assets/images/ambient-purple.png new file mode 100644 index 0000000..c603188 Binary files /dev/null and b/apps/mobile/assets/images/ambient-purple.png differ diff --git a/apps/mobile/assets/images/android-icon-background.png b/apps/mobile/assets/images/android-icon-background.png index 5ffefc5..8f75e47 100644 Binary files a/apps/mobile/assets/images/android-icon-background.png and b/apps/mobile/assets/images/android-icon-background.png differ diff --git a/apps/mobile/assets/images/android-icon-foreground.png b/apps/mobile/assets/images/android-icon-foreground.png index 3a9e501..eeef14e 100644 Binary files a/apps/mobile/assets/images/android-icon-foreground.png and b/apps/mobile/assets/images/android-icon-foreground.png differ diff --git a/apps/mobile/assets/images/android-icon-monochrome.png b/apps/mobile/assets/images/android-icon-monochrome.png index 77484eb..eeef14e 100644 Binary files a/apps/mobile/assets/images/android-icon-monochrome.png and b/apps/mobile/assets/images/android-icon-monochrome.png differ diff --git a/apps/mobile/assets/images/icon.png b/apps/mobile/assets/images/icon.png index 67c777a..6c5516d 100644 Binary files a/apps/mobile/assets/images/icon.png and b/apps/mobile/assets/images/icon.png differ diff --git a/apps/mobile/assets/images/splash-icon.png b/apps/mobile/assets/images/splash-icon.png index 6b1642a..bf3a8da 100644 Binary files a/apps/mobile/assets/images/splash-icon.png and b/apps/mobile/assets/images/splash-icon.png differ diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 37b4fce..be490fd 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -3,14 +3,19 @@ "main": "expo-router/entry", "version": "1.0.0", "dependencies": { + "@expo-google-fonts/space-grotesk": "^0.4.1", "@expo/ui": "~57.0.21", "@musicshare/shared": "*", "expo": "~57.0.26", + "expo-build-properties": "~57.0.22", + "expo-camera": "~57.0.6", "expo-constants": "~57.0.20", "expo-device": "~57.0.2", "expo-font": "~57.0.4", "expo-glass-effect": "~57.0.4", + "expo-haptics": "~57.0.3", "expo-image": "~57.0.5", + "expo-linear-gradient": "~57.0.2", "expo-linking": "~57.0.11", "expo-router": "~57.0.24", "expo-secure-store": "~57.0.4", @@ -26,6 +31,7 @@ "react-native-reanimated": "4.5.1", "react-native-safe-area-context": "~5.7.0", "react-native-screens": "~4.26.0", + "react-native-svg": "15.15.4", "react-native-web": "~0.21.0", "react-native-worklets": "0.10.1", "swr": "^2.5.1" diff --git a/apps/mobile/src/app/(tabs)/index.tsx b/apps/mobile/src/app/(tabs)/index.tsx index 7dda3cc..37422b2 100644 --- a/apps/mobile/src/app/(tabs)/index.tsx +++ b/apps/mobile/src/app/(tabs)/index.tsx @@ -1,9 +1,11 @@ import { router } from 'expo-router'; import { useEffect, useState } from 'react'; -import { FlatList, RefreshControl, StyleSheet, Text, View } from 'react-native'; +import { RefreshControl, StyleSheet, Text, View } from 'react-native'; +import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated'; import { SafeAreaView } from 'react-native-safe-area-context'; import useSWR from 'swr'; import { sortFeed, type ConnectionDTO, type FeedItemDTO, type ProfileDTO } from '@musicshare/shared'; +import { AmbientBackground } from '@/components/AmbientBackground'; import { NowPlayingCard } from '@/components/NowPlayingCard'; import { RelinkReminder } from '@/components/RelinkReminder'; import { SharingControls } from '@/components/SharingControls'; @@ -71,7 +73,10 @@ export default function FeedScreen() { return ( - + {/* Cards rise in on load and glide to new positions when someone pins or starts playing. */} + item.user.id} contentContainerStyle={styles.list} @@ -115,13 +120,15 @@ export default function FeedScreen() { ) } - renderItem={({ item }) => ( - togglePin(item)} - /> + renderItem={({ item, index }) => ( + + togglePin(item)} + /> + )} /> diff --git a/apps/mobile/src/app/(tabs)/search.tsx b/apps/mobile/src/app/(tabs)/search.tsx index 2a24032..6b0c2ac 100644 --- a/apps/mobile/src/app/(tabs)/search.tsx +++ b/apps/mobile/src/app/(tabs)/search.tsx @@ -4,8 +4,9 @@ import { FlatList, Pressable, StyleSheet, Text, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import useSWR from 'swr'; import type { UserSummaryDTO } from '@musicshare/shared'; +import { AmbientBackground } from '@/components/AmbientBackground'; import { Avatar } from '@/components/Avatar'; -import { Body, Field, Title } from '@/components/ui'; +import { Body, Button, Field, Row, Title } from '@/components/ui'; import { useDebounced } from '@/lib/useDebounced'; import { colors, space } from '@/lib/theme'; @@ -16,6 +17,7 @@ export default function SearchScreen() { return ( + = 2 ? (data ?? []) : []} keyExtractor={(u) => u.id} @@ -24,6 +26,10 @@ export default function SearchScreen() { ListHeaderComponent={ Find friends + +