mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-12 05:10:52 +02:00
library softlock fix
This commit is contained in:
@@ -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}>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user