minor ui/ux stuff

This commit is contained in:
Boof2015
2026-07-07 20:45:09 -04:00
parent 6aa4b544fc
commit f0a5ea1de4
5 changed files with 46 additions and 7 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ export default function TabsLayout() {
const colors = useColors(); const colors = useColors();
return ( return (
<Tabs <Tabs
detachInactiveScreens detachInactiveScreens={false}
screenOptions={{ screenOptions={{
headerShown: false, headerShown: false,
freezeOnBlur: false, freezeOnBlur: false,
+7 -3
View File
@@ -89,7 +89,8 @@ export default function EQScreen() {
const { width: windowWidth, height: windowHeight } = useWindowDimensions(); const { width: windowWidth, height: windowHeight } = useWindowDimensions();
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const availableWidth = windowWidth - insets.left - insets.right; const availableWidth = windowWidth - insets.left - insets.right;
const isWide = isWideWindow(availableWidth, windowHeight - insets.top - insets.bottom); const availableHeight = windowHeight - insets.top - insets.bottom;
const isWide = isWideWindow(availableWidth, availableHeight);
// Editing pane keeps a phone-ish width; the graph gets everything else. // Editing pane keeps a phone-ish width; the graph gets everything else.
const sidePaneWidth = Math.min(360, Math.max(280, Math.round(availableWidth * 0.4))); const sidePaneWidth = Math.min(360, Math.max(280, Math.round(availableWidth * 0.4)));
@@ -273,7 +274,7 @@ export default function EQScreen() {
); );
const bottomBarEl = ( const bottomBarEl = (
<View style={[styles.bottomBar, isWide && styles.bottomBarWide]}> <View style={[styles.bottomBar, !isWide && styles.bottomBarNarrow, isWide && styles.bottomBarWide]}>
<View style={styles.preamp}> <View style={styles.preamp}>
<EQSlider <EQSlider
label="Preamp" label="Preamp"
@@ -660,7 +661,7 @@ const useStyles = createThemedStyles((colors) => ({
}, },
graphWrap: { graphWrap: {
flex: 1, flex: 1,
minHeight: 180, minHeight: 168,
marginHorizontal: spacing.lg, marginHorizontal: spacing.lg,
}, },
section: { section: {
@@ -697,6 +698,9 @@ const useStyles = createThemedStyles((colors) => ({
paddingTop: spacing.md, paddingTop: spacing.md,
paddingBottom: spacing.sm, paddingBottom: spacing.sm,
}, },
bottomBarNarrow: {
paddingTop: spacing.xs,
},
preamp: { preamp: {
flex: 1, flex: 1,
}, },
+1 -1
View File
@@ -363,7 +363,7 @@ export default function RootLayout() {
presentation: 'transparentModal', presentation: 'transparentModal',
animation: 'none', animation: 'none',
gestureEnabled: false, gestureEnabled: false,
contentStyle: { backgroundColor: 'transparent' }, contentStyle: { backgroundColor: theme.colors.bgPrimary },
}} }}
/> />
</Stack> </Stack>
+1 -1
View File
@@ -1064,7 +1064,7 @@ export default function NowPlayingScreen() {
const useStyles = createThemedStyles((colors) => ({ const useStyles = createThemedStyles((colors) => ({
backdrop: { backdrop: {
flex: 1, flex: 1,
backgroundColor: 'transparent', backgroundColor: colors.bgPrimary,
}, },
content: { content: {
flex: 1, flex: 1,
+36 -1
View File
@@ -75,6 +75,7 @@ const PLAYLIST_RESULT_LIMIT = 4;
const EMPTY_RECENT_TRACKS_LIMIT = 3; const EMPTY_RECENT_TRACKS_LIMIT = 3;
const ALL_TRACK_RESULT_LIMIT = 120; const ALL_TRACK_RESULT_LIMIT = 120;
const ALL_ENTITY_RESULT_LIMIT = 80; const ALL_ENTITY_RESULT_LIMIT = 80;
const QUEUED_FEEDBACK_MS = 1000;
const NAV_ENTRIES: { const NAV_ENTRIES: {
id: string; id: string;
@@ -470,12 +471,14 @@ function ResultRow({
result, result,
query, query,
active, active,
queued,
onPress, onPress,
onQueueTrack, onQueueTrack,
}: { }: {
result: SearchResult; result: SearchResult;
query: string; query: string;
active: boolean; active: boolean;
queued: boolean;
onPress: () => void; onPress: () => void;
onQueueTrack: (track: DbTrack) => void; onQueueTrack: (track: DbTrack) => void;
}) { }) {
@@ -513,7 +516,7 @@ function ResultRow({
accessibilityRole="button" accessibilityRole="button"
accessibilityLabel={`Play ${result.track.title} next`} accessibilityLabel={`Play ${result.track.title} next`}
> >
<Ionicons name="add" size={18} color={colors.accentTextStrong} /> <Ionicons name={queued ? 'checkmark' : 'add'} size={18} color={colors.accentTextStrong} />
</Pressable> </Pressable>
) : result.kind === 'playlist' && result.playlist.remote ? ( ) : result.kind === 'playlist' && result.playlist.remote ? (
<Ionicons name="cloud" size={14} color={colors.accent} /> <Ionicons name="cloud" size={14} color={colors.accent} />
@@ -550,6 +553,8 @@ function QuickSearchPanel({
const [query, setQuery] = useState(initialQuery); const [query, setQuery] = useState(initialQuery);
const [showAllLibrary, setShowAllLibrary] = useState(false); const [showAllLibrary, setShowAllLibrary] = useState(false);
const [queuedTrackPaths, setQueuedTrackPaths] = useState<Set<string>>(() => new Set());
const queuedFeedbackTimers = useRef(new Map<string, ReturnType<typeof setTimeout>>());
const trimmedQuery = query.trim(); const trimmedQuery = query.trim();
const hasQuery = trimmedQuery.length > 0; const hasQuery = trimmedQuery.length > 0;
@@ -558,6 +563,14 @@ function QuickSearchPanel({
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, []); }, []);
useEffect(
() => () => {
queuedFeedbackTimers.current.forEach(clearTimeout);
queuedFeedbackTimers.current.clear();
},
[]
);
const updateQuery = (value: string) => { const updateQuery = (value: string) => {
setQuery(value); setQuery(value);
setShowAllLibrary(false); setShowAllLibrary(false);
@@ -930,6 +943,27 @@ function QuickSearchPanel({
const queueTrack = (track: DbTrack) => { const queueTrack = (track: DbTrack) => {
commitHaptic(); commitHaptic();
const existingTimer = queuedFeedbackTimers.current.get(track.path);
if (existingTimer) clearTimeout(existingTimer);
setQueuedTrackPaths((current) => {
if (current.has(track.path)) return current;
const next = new Set(current);
next.add(track.path);
return next;
});
const feedbackTimer = setTimeout(() => {
queuedFeedbackTimers.current.delete(track.path);
setQueuedTrackPaths((current) => {
if (!current.has(track.path)) return current;
const next = new Set(current);
next.delete(track.path);
return next;
});
}, QUEUED_FEEDBACK_MS);
queuedFeedbackTimers.current.set(track.path, feedbackTimer);
void enqueueTop(dbTrackToTrack(track)); void enqueueTop(dbTrackToTrack(track));
}; };
@@ -1018,6 +1052,7 @@ function QuickSearchPanel({
result={item.result} result={item.result}
query={trimmedQuery} query={trimmedQuery}
active={item.result.kind === 'track' && item.result.track.path === currentPath} active={item.result.kind === 'track' && item.result.track.path === currentPath}
queued={item.result.kind === 'track' && queuedTrackPaths.has(item.result.track.path)}
onPress={() => executeResult(item.result)} onPress={() => executeResult(item.result)}
onQueueTrack={queueTrack} onQueueTrack={queueTrack}
/> />