chore(lint): hoist dictation-controls inline arrays

This commit is contained in:
Mohamed Boudra
2026-04-24 01:47:15 +07:00
parent 892b9d1ae9
commit 405b964d41

View File

@@ -1,3 +1,4 @@
import { useMemo } from "react";
import { View, Text, Pressable, ActivityIndicator } from "react-native";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { X, ArrowUp, RefreshCcw, Check, Mic, Pencil } from "lucide-react-native";
@@ -47,6 +48,23 @@ export function DictationControls({
const actionsDisabled = isProcessing;
const handleCancel = isFailed && onDiscard ? onDiscard : onCancel;
const micButtonStyle = useMemo(
() => [styles.micButton, disabled && styles.buttonDisabled],
[disabled],
);
const timerTextStyle = useMemo(
() => [styles.timerText, { color: theme.colors.foreground }],
[theme.colors.foreground],
);
const cancelButtonStyle = useMemo(
() => [
styles.actionButton,
styles.actionButtonCancel,
actionsDisabled && !isFailed ? styles.buttonDisabled : undefined,
],
[actionsDisabled, isFailed],
);
if (!showActiveState) {
return (
<Pressable
@@ -54,7 +72,7 @@ export function DictationControls({
disabled={disabled}
accessibilityRole="button"
accessibilityLabel="Start voice dictation"
style={[styles.micButton, disabled && styles.buttonDisabled]}
style={micButtonStyle}
>
<Mic size={theme.iconSize.md} color={theme.colors.foreground} />
</Pressable>
@@ -66,19 +84,13 @@ export function DictationControls({
<View style={styles.meterWrapper}>
<VolumeMeter volume={volume} isMuted={false} isSpeaking={false} orientation="horizontal" />
</View>
<Text style={[styles.timerText, { color: theme.colors.foreground }]}>
{formatDuration(duration)}
</Text>
<Text style={timerTextStyle}>{formatDuration(duration)}</Text>
<View style={styles.actionGroup}>
<Pressable
onPress={handleCancel}
disabled={actionsDisabled && !isFailed}
accessibilityLabel="Cancel dictation"
style={[
styles.actionButton,
styles.actionButtonCancel,
actionsDisabled && !isFailed ? styles.buttonDisabled : undefined,
]}
style={cancelButtonStyle}
>
<X size={theme.iconSize.sm} color={theme.colors.foreground} />
</Pressable>
@@ -90,7 +102,7 @@ export function DictationControls({
<Pressable
onPress={onRetry}
accessibilityLabel="Retry dictation"
style={[styles.actionButton, styles.actionButtonConfirm]}
style={ACTION_CONFIRM_STYLE}
>
<RefreshCcw size={theme.iconSize.sm} color={theme.colors.surface0} />
</Pressable>
@@ -99,14 +111,14 @@ export function DictationControls({
<Pressable
onPress={onAccept}
accessibilityLabel="Insert transcription"
style={[styles.actionButton, styles.actionButtonSecondary]}
style={ACTION_SECONDARY_STYLE}
>
<Check size={theme.iconSize.sm} color={theme.colors.foreground} />
</Pressable>
<Pressable
onPress={onAcceptAndSend}
accessibilityLabel="Insert transcription and send"
style={[styles.actionButton, styles.actionButtonConfirm]}
style={ACTION_CONFIRM_STYLE}
>
<ArrowUp size={theme.iconSize.sm} color={theme.colors.surface0} />
</Pressable>
@@ -140,21 +152,43 @@ export function DictationOverlay({
const actionsDisabled = isProcessing;
const handleCancel = isFailed && onDiscard ? onDiscard : onCancel;
const containerStyle = useMemo(
() => [overlayStyles.container, { backgroundColor: theme.colors.accent }],
[theme.colors.accent],
);
const overlayCancelButtonStyle = useMemo(
() => [
overlayStyles.cancelButton,
actionsDisabled && !isFailed && overlayStyles.buttonDisabled,
],
[actionsDisabled, isFailed],
);
const overlayTimerTextStyle = useMemo(
() => [overlayStyles.timerText, { color: theme.colors.palette.white }],
[theme.colors.palette.white],
);
const overlayTranscriptTextStyle = useMemo(
() => [overlayStyles.transcriptText, { color: theme.colors.palette.white, opacity: 0.95 }],
[theme.colors.palette.white],
);
const overlayRetryButtonStyle = useMemo(
() => [overlayStyles.actionButton, { backgroundColor: theme.colors.palette.white }],
[theme.colors.palette.white],
);
const overlayConfirmButtonStyle = overlayRetryButtonStyle;
if (!showActiveState) {
return null;
}
return (
<View style={[overlayStyles.container, { backgroundColor: theme.colors.accent }]}>
<View style={containerStyle}>
<Pressable
onPress={handleCancel}
disabled={actionsDisabled && !isFailed}
accessibilityRole="button"
accessibilityLabel="Cancel dictation"
style={[
overlayStyles.cancelButton,
actionsDisabled && !isFailed && overlayStyles.buttonDisabled,
]}
style={overlayCancelButtonStyle}
>
<X size={theme.iconSize.lg} color={theme.colors.palette.white} strokeWidth={2.5} />
</Pressable>
@@ -168,18 +202,10 @@ export function DictationOverlay({
orientation="horizontal"
color={theme.colors.palette.white}
/>
<Text style={[overlayStyles.timerText, { color: theme.colors.palette.white }]}>
{formatDuration(duration)}
</Text>
<Text style={overlayTimerTextStyle}>{formatDuration(duration)}</Text>
</View>
{isFailed ? (
<Text
numberOfLines={2}
style={[
overlayStyles.transcriptText,
{ color: theme.colors.palette.white, opacity: 0.95 },
]}
>
<Text numberOfLines={2} style={overlayTranscriptTextStyle}>
{errorText ? `Dictation failed: ${errorText}` : "Dictation failed. Tap retry."}
</Text>
) : null}
@@ -195,7 +221,7 @@ export function DictationOverlay({
onPress={onRetry}
accessibilityRole="button"
accessibilityLabel="Retry dictation"
style={[overlayStyles.actionButton, { backgroundColor: theme.colors.palette.white }]}
style={overlayRetryButtonStyle}
>
<RefreshCcw size={theme.iconSize.lg} color={theme.colors.accent} strokeWidth={2.5} />
</Pressable>
@@ -205,7 +231,7 @@ export function DictationOverlay({
onPress={onAccept}
accessibilityRole="button"
accessibilityLabel="Insert transcription"
style={[overlayStyles.actionButton, { backgroundColor: "rgba(255, 255, 255, 0.25)" }]}
style={OVERLAY_ACCEPT_BUTTON_STYLE}
>
<Pencil
size={theme.iconSize.lg}
@@ -217,7 +243,7 @@ export function DictationOverlay({
onPress={onAcceptAndSend}
accessibilityRole="button"
accessibilityLabel="Insert transcription and send"
style={[overlayStyles.actionButton, { backgroundColor: theme.colors.palette.white }]}
style={overlayConfirmButtonStyle}
>
<ArrowUp size={theme.iconSize.lg} color={theme.colors.accent} strokeWidth={2.5} />
</Pressable>
@@ -364,3 +390,8 @@ const overlayStyles = StyleSheet.create((theme) => ({
justifyContent: "center",
},
}));
const ACTION_CONFIRM_STYLE = [styles.actionButton, styles.actionButtonConfirm];
const ACTION_SECONDARY_STYLE = [styles.actionButton, styles.actionButtonSecondary];
const OVERLAY_ACCEPT_BUTTON_BG = { backgroundColor: "rgba(255, 255, 255, 0.25)" };
const OVERLAY_ACCEPT_BUTTON_STYLE = [overlayStyles.actionButton, OVERLAY_ACCEPT_BUTTON_BG];