library softlock fix

This commit is contained in:
Boof2015
2026-07-02 11:22:10 -04:00
parent c6c24cf1a5
commit 428f6fc2fb
5 changed files with 57 additions and 39 deletions
+5 -26
View File
@@ -1,9 +1,9 @@
import { useCallback, useMemo, useState } from 'react';
import { BackHandler, View, Pressable, StyleSheet } from 'react-native';
import { useMemo, useState } from 'react';
import { View, Pressable, StyleSheet } from 'react-native';
import { Image } from 'expo-image';
import { Ionicons } from '@expo/vector-icons';
import { FlashList } from '@shopify/flash-list';
import { useFocusEffect, useLocalSearchParams, useRouter } from 'expo-router';
import { useLocalSearchParams } from 'expo-router';
import { Screen } from '@/components/Screen';
import { Text } from '@/components/Text';
import { AstraLogo } from '@/components/AstraLogo';
@@ -16,15 +16,15 @@ import { playTracks, shuffleTracks } from '@/audio/playbackController';
import { dbTrackToTrack } from '@/library/trackAdapter';
import { albumArtworkSource } from '@/library/artwork';
import { formatDuration } from '@/lib/format';
import { useLibraryDetailBack } from '@/navigation/useLibraryDetailBack';
import type { DbTrack } from '@/types/library';
export default function AlbumScreen() {
const router = useRouter();
const { key, from } = useLocalSearchParams<{ key: string; from?: string }>();
const albums = useLibraryStore((s) => s.albums);
const allTracks = useLibraryStore((s) => s.tracks);
const currentPath = usePlayerStore((s) => s.currentTrack?.path);
const openedFromHome = from === 'home';
const handleBack = useLibraryDetailBack(from);
const album = albums.find((entry) => entry.identity_key === key);
// Store tracks are ordered artist/album/disc/track, so the filtered slice
@@ -41,27 +41,6 @@ export default function AlbumScreen() {
void playTracks(tracks.map(dbTrackToTrack), index);
};
const handleBack = useCallback(() => {
if (openedFromHome) {
router.replace('/library');
return;
}
router.back();
}, [openedFromHome, router]);
useFocusEffect(
useCallback(() => {
if (!openedFromHome) return;
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
handleBack();
return true;
});
return () => subscription.remove();
}, [handleBack, openedFromHome])
);
return (
<Screen>
<Pressable style={styles.back} onPress={handleBack} hitSlop={8}>
+4 -2
View File
@@ -17,6 +17,7 @@ import { playTracks, shuffleTracks } from '@/audio/playbackController';
import { dbTrackToTrack } from '@/library/trackAdapter';
import { artworkUri } from '@/library/artwork';
import { buildArtistDetail, type ArtistAlbum, type ArtistDetail } from '@/library/artistDetail';
import { useLibraryDetailBack } from '@/navigation/useLibraryDetailBack';
import type { DbTrack } from '@/types/library';
type IconName = ComponentProps<typeof Ionicons>['name'];
@@ -41,7 +42,8 @@ type ArtistPageItem =
export default function ArtistScreen() {
const router = useRouter();
const { name = 'Artist' } = useLocalSearchParams<{ name: string }>();
const { name = 'Artist', from } = useLocalSearchParams<{ name: string; from?: string }>();
const handleBack = useLibraryDetailBack(from);
const { width } = useWindowDimensions();
const allTracks = useLibraryStore((s) => s.tracks);
const groupingMode = useSettingsStore((s) => s.artistGroupingMode);
@@ -134,7 +136,7 @@ export default function ArtistScreen() {
return (
<Screen>
<Pressable style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Pressable style={styles.back} onPress={handleBack} hitSlop={8}>
<Ionicons name="chevron-back" size={22} color={colors.textSecondary} />
<Text variant="body" color={colors.textSecondary}>
Library
+5 -4
View File
@@ -3,7 +3,7 @@ import { View, Pressable, StyleSheet } from 'react-native';
import { Image } from 'expo-image';
import { Ionicons } from '@expo/vector-icons';
import { FlashList } from '@shopify/flash-list';
import { useLocalSearchParams, useRouter } from 'expo-router';
import { useLocalSearchParams } from 'expo-router';
import { Screen } from '@/components/Screen';
import { Text } from '@/components/Text';
import { TrackRow } from '@/components/library/TrackRow';
@@ -16,6 +16,7 @@ import { playTracks, shuffleTracks } from '@/audio/playbackController';
import { dbTrackToTrack } from '@/library/trackAdapter';
import { artworkUri } from '@/library/artwork';
import { formatDuration } from '@/lib/format';
import { useLibraryDetailBack } from '@/navigation/useLibraryDetailBack';
import type { DbTrack } from '@/types/library';
import type { PlaylistTrackEntry } from '@/types/playlist';
@@ -41,8 +42,8 @@ function MissingRow({ entry, onLongPress }: { entry: PlaylistTrackEntry; onLongP
}
export default function PlaylistScreen() {
const router = useRouter();
const { id } = useLocalSearchParams<{ id: string }>();
const { id, from } = useLocalSearchParams<{ id: string; from?: string }>();
const handleBack = useLibraryDetailBack(from);
const isFavorites = id === 'favorites';
const playlistId = isFavorites ? null : Number(id);
@@ -155,7 +156,7 @@ export default function PlaylistScreen() {
return (
<Screen>
<Pressable style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Pressable style={styles.back} onPress={handleBack} hitSlop={8}>
<Ionicons name="chevron-back" size={22} color={colors.textSecondary} />
<Text variant="body" color={colors.textSecondary}>
Library
+6 -7
View File
@@ -830,7 +830,7 @@ function QuickSearchPanel({
if (result.kind === 'album') {
router.push({
pathname: '/library/album/[key]',
params: { key: result.album.identity_key },
params: { key: result.album.identity_key, from: 'search' },
});
return;
}
@@ -838,17 +838,16 @@ function QuickSearchPanel({
if (result.kind === 'artist') {
router.push({
pathname: '/library/artist/[name]',
params: { name: result.artist.artist },
params: { name: result.artist.artist, from: 'search' },
});
return;
}
if (result.kind === 'playlist') {
router.push(
result.playlist.id === 'favorites'
? '/library/playlist/favorites'
: `/library/playlist/${result.playlist.id}`
);
router.push({
pathname: '/library/playlist/[id]',
params: { id: result.playlist.id, from: 'search' },
});
return;
}
+37
View File
@@ -0,0 +1,37 @@
import { useCallback } from 'react';
import { BackHandler } from 'react-native';
import { useFocusEffect, useRouter } from 'expo-router';
type LibraryDetailSource = 'home' | 'search';
function shouldReturnToLibraryRoot(from: string | string[] | undefined): from is LibraryDetailSource {
return from === 'home' || from === 'search';
}
export function useLibraryDetailBack(from?: string | string[]) {
const router = useRouter();
const returnToLibraryRoot = shouldReturnToLibraryRoot(from);
const handleBack = useCallback(() => {
if (returnToLibraryRoot) {
router.replace('/library');
return;
}
router.back();
}, [returnToLibraryRoot, router]);
useFocusEffect(
useCallback(() => {
if (!returnToLibraryRoot) return;
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
handleBack();
return true;
});
return () => subscription.remove();
}, [handleBack, returnToLibraryRoot])
);
return handleBack;
}