The Android app updates itself from our Gitea releases; feed cards fade in instead of bouncing
- API: GET /app/android/latest reads the latest Gitea release (ANDROID_RELEASES_URL, optional token for a private repo) with the APK's SHA-256 from SHA256SUMS; GET /app/android/apk/:name streams that APK. - App (modules/updater): downloads in the background, checks the SHA-256, and installs through PackageInstaller: quietly once when leaving the app (Android 12+), otherwise from the feed banner or Settings > App version. F-Droid builds leave it out and drop the install permissions. - CI: the release notes come from the fastlane changelog; the app shows the part above ---. - Settings: Create-account and Link Spotify buttons for Last.fm and ListenBrainz. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { router } from 'expo-router';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Pressable, RefreshControl, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import Animated, { FadeInDown, LinearTransition } from 'react-native-reanimated';
|
||||
import Animated, { FadeIn, LinearTransition } from 'react-native-reanimated';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import useSWR, { useSWRConfig } from 'swr';
|
||||
import { sortFeed, type ConnectionDTO, type FeedItemDTO, type FollowListDTO, type ProfileDTO } from '@musicshare/shared';
|
||||
@@ -10,6 +10,7 @@ import { ActivityBell } from '@/components/ActivityBell';
|
||||
import { Avatar } from '@/components/Avatar';
|
||||
import { NowPlayingCard } from '@/components/NowPlayingCard';
|
||||
import { RelinkReminder } from '@/components/RelinkReminder';
|
||||
import { UpdateBanner } from '@/components/UpdateBanner';
|
||||
import { SharingControls } from '@/components/SharingControls';
|
||||
import { Body, Button, Card, Title } from '@/components/ui';
|
||||
import { api } from '@/lib/api';
|
||||
@@ -84,9 +85,9 @@ export default function FeedScreen() {
|
||||
return (
|
||||
<SafeAreaView style={styles.safe} edges={['top']}>
|
||||
<AmbientBackground />
|
||||
{/* Cards rise in on load and glide to new positions when someone pins or starts playing. */}
|
||||
{/* Cards fade in and slide to new positions when someone pins or starts playing. */}
|
||||
<Animated.FlatList
|
||||
itemLayoutAnimation={LinearTransition.springify().damping(18)}
|
||||
itemLayoutAnimation={LinearTransition.duration(200)}
|
||||
data={feed ?? []}
|
||||
keyExtractor={(item) => item.user.id}
|
||||
contentContainerStyle={styles.list}
|
||||
@@ -97,6 +98,7 @@ export default function FeedScreen() {
|
||||
<Text style={styles.brand}>musicshare</Text>
|
||||
<ActivityBell />
|
||||
</View>
|
||||
<UpdateBanner />
|
||||
<SharingControls compact />
|
||||
<RelinkReminder />
|
||||
{offerAppleMusic && (
|
||||
@@ -160,8 +162,8 @@ export default function FeedScreen() {
|
||||
</View>
|
||||
) : null
|
||||
}
|
||||
renderItem={({ item, index }) => (
|
||||
<Animated.View entering={FadeInDown.delay(Math.min(index, 8) * 60).springify().damping(16)}>
|
||||
renderItem={({ item }) => (
|
||||
<Animated.View entering={FadeIn.duration(180)}>
|
||||
<NowPlayingCard
|
||||
np={item}
|
||||
preferred={me?.preferredService}
|
||||
|
||||
Reference in New Issue
Block a user