optimize further

This commit is contained in:
Boof2015
2026-07-12 12:16:52 -04:00
parent 5cc1099853
commit 804e47a7ca
69 changed files with 588 additions and 292 deletions
+5 -2
View File
@@ -26,6 +26,7 @@ import {
spacing,
} from '@/theme';
import { createThemedStyles, useColors } from '@/theme/themed';
import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import type { Palette } from '@/theme/palettes';
import { useLibraryStore } from '@/stores/libraryStore';
import { usePlayerStore } from '@/stores/playerStore';
@@ -291,6 +292,7 @@ function SectionHeader({
onPress?: () => void;
}) {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
return (
<View style={styles.sectionHeader}>
@@ -303,7 +305,7 @@ function SectionHeader({
</Text>
</View>
{onPress ? (
<Pressable style={styles.seeAllButton} onPress={onPress} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY} style={styles.seeAllButton} onPress={onPress} accessibilityRole="button">
<Text variant="label" color={colors.accentText}>
See all
</Text>
@@ -322,6 +324,7 @@ function AlbumRail({
onAlbumPress: (album: ArtistAlbum) => void;
}) {
const styles = useStyles();
const ripple = useRipple();
return (
<ScrollView
horizontal
@@ -329,7 +332,7 @@ function AlbumRail({
contentContainerStyle={styles.albumRail}
>
{albums.map((album) => (
<Pressable
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY}
key={album.identity_key}
style={styles.albumCard}
onPress={() => onAlbumPress(album)}
@@ -12,12 +12,14 @@ import { Text } from '@/components/Text';
import { AlbumGridItem } from '@/components/library/AlbumGridItem';
import { spacing } from '@/theme';
import { useColors } from '@/theme/themed';
import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import { useLibraryStore } from '@/stores/libraryStore';
import { useSettingsStore } from '@/stores/settingsStore';
import { buildArtistDetail } from '@/library/artistDetail';
export default function ArtistAlbumsScreen() {
const colors = useColors();
const ripple = useRipple();
const router = useRouter();
const { name = 'Artist' } = useLocalSearchParams<{ name: string }>();
const allTracks = useLibraryStore((s) => s.tracks);
@@ -30,7 +32,7 @@ export default function ArtistAlbumsScreen() {
return (
<Screen>
<Pressable style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY} style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Ionicons name="chevron-back" size={22} color={colors.textSecondary} />
<Text variant="body" color={colors.textSecondary} numberOfLines={1}>
{name}
@@ -13,6 +13,7 @@ import { TrackRow } from '@/components/library/TrackRow';
import { TrackActionsSheet } from '@/components/library/TrackActionsSheet';
import { spacing } from '@/theme';
import { useColors } from '@/theme/themed';
import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import { useLibraryStore } from '@/stores/libraryStore';
import { usePlayerStore } from '@/stores/playerStore';
import { useSettingsStore } from '@/stores/settingsStore';
@@ -23,6 +24,7 @@ import type { DbTrack } from '@/types/library';
export default function ArtistAppearancesScreen() {
const colors = useColors();
const ripple = useRipple();
const router = useRouter();
const { name = 'Artist' } = useLocalSearchParams<{ name: string }>();
const allTracks = useLibraryStore((s) => s.tracks);
@@ -43,7 +45,7 @@ export default function ArtistAppearancesScreen() {
return (
<Screen>
<Pressable style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY} style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Ionicons name="chevron-back" size={22} color={colors.textSecondary} />
<Text variant="body" color={colors.textSecondary} numberOfLines={1}>
{name}
@@ -13,6 +13,7 @@ import { TrackRow } from '@/components/library/TrackRow';
import { TrackActionsSheet } from '@/components/library/TrackActionsSheet';
import { spacing } from '@/theme';
import { useColors } from '@/theme/themed';
import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import { useLibraryStore } from '@/stores/libraryStore';
import { usePlayerStore } from '@/stores/playerStore';
import { useSettingsStore } from '@/stores/settingsStore';
@@ -23,6 +24,7 @@ import type { DbTrack } from '@/types/library';
export default function ArtistSongsScreen() {
const colors = useColors();
const ripple = useRipple();
const router = useRouter();
const { name = 'Artist' } = useLocalSearchParams<{ name: string }>();
const allTracks = useLibraryStore((s) => s.tracks);
@@ -43,7 +45,7 @@ export default function ArtistSongsScreen() {
return (
<Screen>
<Pressable style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY} style={styles.back} onPress={() => router.back()} hitSlop={8}>
<Ionicons name="chevron-back" size={22} color={colors.textSecondary} />
<Text variant="body" color={colors.textSecondary} numberOfLines={1}>
{name}
+5 -3
View File
@@ -39,6 +39,7 @@ import {
} from '@/components/search/PullSearchGesture';
import { spacing } from '@/theme';
import { useColors } from '@/theme/themed';
import { useRipple } from '@/theme/ripple';
import { useLibraryStore } from '@/stores/libraryStore';
import { usePlayerStore } from '@/stores/playerStore';
import { useSearchStore } from '@/stores/searchStore';
@@ -77,6 +78,7 @@ const ARTIST_SORT_OPTIONS: ArtistSort[] = ['name', 'track_count'];
export default function LibraryScreen() {
const colors = useColors();
const ripple = useRipple();
const router = useRouter();
const viewMode = useLibraryStore((s) => s.viewMode);
const setViewMode = useLibraryStore((s) => s.setViewMode);
@@ -244,7 +246,7 @@ export default function LibraryScreen() {
Library
</Text>
{!isEmpty ? (
<Pressable
<Pressable android_ripple={ripple.bounded}
hitSlop={8}
onPress={() => openQuickSearch()}
accessibilityRole="button"
@@ -281,14 +283,14 @@ export default function LibraryScreen() {
<Text variant="label">
{selectedIds.size} selected
</Text>
<Pressable onPress={exitSelection} hitSlop={8} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} onPress={exitSelection} hitSlop={8} accessibilityRole="button">
<Text variant="label" color={colors.accentText}>
Cancel
</Text>
</Pressable>
</View>
) : sortable ? (
<Pressable
<Pressable android_ripple={ripple.bounded}
style={styles.sortTrigger}
onPress={() => setSortSheetOpen(true)}
accessibilityRole="button"
+5 -2
View File
@@ -27,6 +27,7 @@ import { TextPromptModal } from '@/components/sheets/TextPromptModal';
import { CollapsingHeader, useDetailCollapse } from '@/components/library/CollapsingDetail';
import { spacing } from '@/theme';
import { createThemedStyles, useColors } from '@/theme/themed';
import { SCROLL_PRESS_DELAY, useRipple } from '@/theme/ripple';
import { usePlaylistStore } from '@/stores/playlistStore';
import { usePlayerStore } from '@/stores/playerStore';
import { playTracks, shuffleTracks } from '@/audio/playbackController';
@@ -54,9 +55,10 @@ function basename(path: string): string {
function MissingRow({ entry, onLongPress }: { entry: PlaylistTrackEntry; onLongPress: () => void }) {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
return (
<Pressable style={styles.missingRow} onLongPress={onLongPress} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY} style={styles.missingRow} onLongPress={onLongPress} accessibilityRole="button">
<View style={styles.missingMeta}>
<Text variant="body" numberOfLines={1} color={colors.textTertiary}>
{entry.fallback_title ?? basename(entry.track_path)}
@@ -74,6 +76,7 @@ type Prompt = { kind: 'rename'; playlist: Playlist } | null;
export default function PlaylistScreen() {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
const router = useRouter();
const { id } = useLocalSearchParams<{ id: string }>();
@@ -283,7 +286,7 @@ export default function PlaylistScreen() {
heroMeta={<Text variant="label">{meta}</Text>}
heroExtra={
isDynamic && playlistId != null ? (
<Pressable
<Pressable android_ripple={ripple.bounded} unstable_pressDelay={SCROLL_PRESS_DELAY}
style={styles.editRules}
onPress={() =>
router.push({
@@ -27,6 +27,7 @@ import {
} from '@/components/sheets/AppSheet';
import { fonts, fontSize, radius, spacing } from '@/theme';
import { createThemedStyles, useColors } from '@/theme/themed';
import { useRipple } from '@/theme/ripple';
import { usePlaylistStore } from '@/stores/playlistStore';
import {
DYNAMIC_PLAYLIST_PRESETS,
@@ -327,15 +328,16 @@ function DraftActions({
onApply: () => void;
}) {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
return (
<View style={styles.sheetActions}>
<Pressable style={[styles.sheetButton, styles.cancelButton]} onPress={onCancel} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} style={[styles.sheetButton, styles.cancelButton]} onPress={onCancel} accessibilityRole="button">
<Text variant="label" color={colors.textSecondary}>
Cancel
</Text>
</Pressable>
<Pressable
<Pressable android_ripple={ripple.bounded}
style={[styles.sheetButton, styles.applyButton, disabled && styles.applyDisabled]}
disabled={disabled}
onPress={onApply}
@@ -529,6 +531,7 @@ function ConditionEditorSheet({
onApply: () => void;
}) {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
const draft = target.draft;
const error = validateCondition(draft);
@@ -536,7 +539,7 @@ function ConditionEditorSheet({
return (
<AppSheet onClose={onCancel}>
<AppSheetTitle title={target.mode === 'new' ? 'Add filter' : 'Edit filter'} />
<Pressable style={styles.sheetSelectRow} onPress={onChangeField} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} style={styles.sheetSelectRow} onPress={onChangeField} accessibilityRole="button">
<View style={styles.sheetSelectText}>
<Text variant="caption" color={colors.textTertiary}>
FIELD
@@ -568,7 +571,7 @@ function ConditionEditorSheet({
<View style={styles.conditionSheetFooter}>
{target.mode === 'edit' ? (
<Pressable style={styles.removeButton} onPress={onRemove} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} style={styles.removeButton} onPress={onRemove} accessibilityRole="button">
<Ionicons name="trash-outline" size={17} color={colors.warning} />
<Text variant="label" color={colors.warning}>
Remove
@@ -713,11 +716,12 @@ function FilterCard({
onRemove: () => void;
}) {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
const option = fieldOptionForKey(getConditionFieldKey(condition));
return (
<Pressable style={styles.ruleCard} onPress={onPress} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} style={styles.ruleCard} onPress={onPress} accessibilityRole="button">
<View style={styles.cardIcon}>
<Ionicons name={option?.icon ?? 'options-outline'} size={18} color={colors.accent} />
</View>
@@ -729,7 +733,7 @@ function FilterCard({
{fieldGroupLabel(condition)}
</Text>
</View>
<Pressable
<Pressable android_ripple={ripple.bounded}
style={styles.cardRemove}
onPress={onRemove}
hitSlop={8}
@@ -744,6 +748,7 @@ function FilterCard({
export default function DynamicPlaylistEditorScreen() {
const styles = useStyles();
const ripple = useRipple();
const colors = useColors();
const router = useRouter();
const { id } = useLocalSearchParams<{ id?: string }>();
@@ -1036,7 +1041,7 @@ export default function DynamicPlaylistEditorScreen() {
>
<Screen padded={false}>
<View style={styles.header}>
<Pressable
<Pressable android_ripple={ripple.bounded}
onPress={() => router.back()}
hitSlop={8}
style={styles.headerButton}
@@ -1080,7 +1085,7 @@ export default function DynamicPlaylistEditorScreen() {
contentContainerStyle={styles.presetRow}
>
{DYNAMIC_PLAYLIST_PRESETS.map((preset) => (
<Pressable
<Pressable android_ripple={ripple.bounded}
key={preset.id}
style={styles.presetChip}
onPress={() => applyPreset(preset.rules)}
@@ -1100,7 +1105,7 @@ export default function DynamicPlaylistEditorScreen() {
<Text variant="caption" style={styles.sectionLabel}>
FILTERS
</Text>
<Pressable style={styles.inlineAction} onPress={() => openFieldPicker('new')} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} style={styles.inlineAction} onPress={() => openFieldPicker('new')} accessibilityRole="button">
<Ionicons name="add" size={16} color={colors.accent} />
<Text variant="label" color={colors.accent}>
Add filter
@@ -1133,7 +1138,7 @@ export default function DynamicPlaylistEditorScreen() {
<Text variant="caption" style={styles.sectionLabel}>
ORDER
</Text>
<Pressable style={styles.sortCard} onPress={openSortSheet} accessibilityRole="button">
<Pressable android_ripple={ripple.bounded} style={styles.sortCard} onPress={openSortSheet} accessibilityRole="button">
<View style={styles.cardIcon}>
<Ionicons name="swap-vertical" size={18} color={colors.accent} />
</View>
@@ -1161,7 +1166,7 @@ export default function DynamicPlaylistEditorScreen() {
{status.label}
</Text>
</View>
<Pressable
<Pressable android_ripple={ripple.bounded}
style={[styles.previewButton, normalizedRulesError !== null && styles.disabled]}
disabled={normalizedRulesError !== null}
onPress={() => setSheet({ kind: 'preview' })}
@@ -1172,7 +1177,7 @@ export default function DynamicPlaylistEditorScreen() {
Preview
</Text>
</Pressable>
<Pressable
<Pressable android_ripple={ripple.bounded}
style={[styles.saveButton, saveDisabled && styles.disabled]}
disabled={saveDisabled}
onPress={save}