mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
chore(lint): memoize inline styles in autocomplete, message-input, composer
This commit is contained in:
@@ -115,7 +115,7 @@ function QueuedMessageRow({ item, onEdit, onSendNow }: QueuedMessageRowProps) {
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={handleSendNow}
|
||||
style={[styles.queueActionButton, styles.queueSendButton]}
|
||||
style={QUEUE_SEND_BUTTON_STYLE}
|
||||
>
|
||||
<ArrowUp size={theme.iconSize.sm} color="white" />
|
||||
</Pressable>
|
||||
@@ -126,10 +126,11 @@ function QueuedMessageRow({ item, onEdit, onSendNow }: QueuedMessageRowProps) {
|
||||
|
||||
function ImageAttachmentThumbnail({ image }: { image: ImageAttachment }) {
|
||||
const uri = useAttachmentPreviewUrl(image);
|
||||
const source = useMemo(() => ({ uri: uri ?? "" }), [uri]);
|
||||
if (!uri) {
|
||||
return <View style={styles.imageThumbnailPlaceholder} />;
|
||||
}
|
||||
return <Image source={{ uri }} style={styles.imageThumbnail} />;
|
||||
return <Image source={source} style={styles.imageThumbnail} />;
|
||||
}
|
||||
|
||||
interface ImageAttachmentPillProps {
|
||||
@@ -833,6 +834,14 @@ export function Composer({
|
||||
[],
|
||||
);
|
||||
|
||||
const cancelButtonStyle = useMemo(
|
||||
() => [
|
||||
styles.cancelButton as any,
|
||||
(!isConnected || isCancellingAgent ? styles.buttonDisabled : undefined) as any,
|
||||
],
|
||||
[isConnected, isCancellingAgent],
|
||||
);
|
||||
|
||||
const cancelButton = useMemo(
|
||||
() =>
|
||||
isAgentRunning && !hasSendableContent && !isProcessing ? (
|
||||
@@ -842,10 +851,7 @@ export function Composer({
|
||||
disabled={!isConnected || isCancellingAgent}
|
||||
accessibilityLabel={isCancellingAgent ? "Canceling agent" : "Stop agent"}
|
||||
accessibilityRole="button"
|
||||
style={[
|
||||
styles.cancelButton as any,
|
||||
(!isConnected || isCancellingAgent ? styles.buttonDisabled : undefined) as any,
|
||||
]}
|
||||
style={cancelButtonStyle}
|
||||
>
|
||||
{isCancellingAgent ? (
|
||||
<ActivityIndicator size="small" color="white" />
|
||||
@@ -1100,11 +1106,20 @@ export function Composer({
|
||||
[voiceButtonDisabled],
|
||||
);
|
||||
|
||||
const composerContainerStyle = useMemo(
|
||||
() => [styles.container, keyboardAnimatedStyle],
|
||||
[keyboardAnimatedStyle],
|
||||
);
|
||||
const inputAreaContainerStyle = useMemo(
|
||||
() => [styles.inputAreaContainer, isComposerLocked && styles.inputAreaLocked],
|
||||
[isComposerLocked],
|
||||
);
|
||||
|
||||
return (
|
||||
<Animated.View style={[styles.container, keyboardAnimatedStyle]}>
|
||||
<Animated.View style={composerContainerStyle}>
|
||||
<AttachmentLightbox metadata={lightboxMetadata} onClose={handleLightboxClose} />
|
||||
{/* Input area */}
|
||||
<View style={[styles.inputAreaContainer, isComposerLocked && styles.inputAreaLocked]}>
|
||||
<View style={inputAreaContainerStyle}>
|
||||
<View style={styles.inputAreaContent}>
|
||||
{/* Queue list */}
|
||||
{queuedMessages.length > 0 && (
|
||||
@@ -1397,3 +1412,5 @@ const styles = StyleSheet.create(((theme: Theme) => ({
|
||||
fontSize: theme.fontSize.sm,
|
||||
},
|
||||
})) as any) as Record<string, any>;
|
||||
|
||||
const QUEUE_SEND_BUTTON_STYLE = [styles.queueActionButton, styles.queueSendButton];
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
forwardRef,
|
||||
} from "react";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
@@ -981,13 +982,39 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
void handleStopRealtimeVoice();
|
||||
}, [handleStopRealtimeVoice]);
|
||||
|
||||
const inputWrapperCombinedStyle = useMemo(
|
||||
() => [styles.inputWrapper, inputWrapperStyle, inputAnimatedStyle],
|
||||
[inputWrapperStyle, inputAnimatedStyle],
|
||||
);
|
||||
const textInputStyle = useMemo(
|
||||
() => [
|
||||
styles.textInput,
|
||||
isWeb
|
||||
? {
|
||||
height: inputHeight,
|
||||
minHeight: MIN_INPUT_HEIGHT,
|
||||
maxHeight: MAX_INPUT_HEIGHT,
|
||||
}
|
||||
: {
|
||||
minHeight: MIN_INPUT_HEIGHT,
|
||||
maxHeight: MAX_INPUT_HEIGHT,
|
||||
},
|
||||
],
|
||||
[inputHeight],
|
||||
);
|
||||
const sendButtonCombinedStyle = useMemo(
|
||||
() => [styles.sendButton, isSendButtonDisabled && styles.buttonDisabled],
|
||||
[isSendButtonDisabled],
|
||||
);
|
||||
const overlayContainerStyle = useMemo(
|
||||
() => [styles.overlayContainer, overlayAnimatedStyle],
|
||||
[overlayAnimatedStyle],
|
||||
);
|
||||
|
||||
return (
|
||||
<View ref={rootRef} style={styles.container} testID="message-input-root">
|
||||
{/* Regular input */}
|
||||
<Animated.View
|
||||
ref={inputWrapperRef}
|
||||
style={[styles.inputWrapper, inputWrapperStyle, inputAnimatedStyle]}
|
||||
>
|
||||
<Animated.View ref={inputWrapperRef} style={inputWrapperCombinedStyle}>
|
||||
{/* Text input */}
|
||||
<View style={styles.textInputScrollWrapper}>
|
||||
<TextInput
|
||||
@@ -999,19 +1026,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
accessibilityLabel="Message agent..."
|
||||
onFocus={handleInputFocus}
|
||||
onBlur={handleInputBlur}
|
||||
style={[
|
||||
styles.textInput,
|
||||
isWeb
|
||||
? {
|
||||
height: inputHeight,
|
||||
minHeight: MIN_INPUT_HEIGHT,
|
||||
maxHeight: MAX_INPUT_HEIGHT,
|
||||
}
|
||||
: {
|
||||
minHeight: MIN_INPUT_HEIGHT,
|
||||
maxHeight: MAX_INPUT_HEIGHT,
|
||||
},
|
||||
]}
|
||||
style={textInputStyle}
|
||||
multiline
|
||||
scrollEnabled={isWeb ? inputHeight >= MAX_INPUT_HEIGHT : true}
|
||||
onContentSizeChange={handleContentSizeChange}
|
||||
@@ -1148,7 +1163,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
disabled={isSendButtonDisabled}
|
||||
accessibilityLabel={submitAccessibilityLabel}
|
||||
accessibilityRole="button"
|
||||
style={[styles.sendButton, isSendButtonDisabled && styles.buttonDisabled]}
|
||||
style={sendButtonCombinedStyle}
|
||||
>
|
||||
{isSubmitLoading ? (
|
||||
<ActivityIndicator size="small" color="white" />
|
||||
@@ -1173,7 +1188,7 @@ export const MessageInput = forwardRef<MessageInputRef, MessageInputProps>(funct
|
||||
</Animated.View>
|
||||
|
||||
{/* Dictation overlay */}
|
||||
<Animated.View style={[styles.overlayContainer, overlayAnimatedStyle]}>
|
||||
<Animated.View style={overlayContainerStyle}>
|
||||
{showDictationOverlay ? (
|
||||
<DictationOverlay
|
||||
volume={dictationVolume}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
Text,
|
||||
@@ -206,9 +206,14 @@ export function Autocomplete({
|
||||
[ensureActiveItemVisible],
|
||||
);
|
||||
|
||||
const containerStyle = useMemo(
|
||||
() => [styles.container, { maxHeight }],
|
||||
[maxHeight],
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<View style={[styles.container, { maxHeight }]}>
|
||||
<View style={containerStyle}>
|
||||
<View style={styles.emptyItem}>
|
||||
<Text style={styles.emptyText}>{loadingText}</Text>
|
||||
</View>
|
||||
@@ -218,7 +223,7 @@ export function Autocomplete({
|
||||
|
||||
if (errorMessage) {
|
||||
return (
|
||||
<View style={[styles.container, { maxHeight }]}>
|
||||
<View style={containerStyle}>
|
||||
<View style={styles.emptyItem}>
|
||||
<Text style={styles.emptyText}>Error: {errorMessage}</Text>
|
||||
</View>
|
||||
@@ -228,7 +233,7 @@ export function Autocomplete({
|
||||
|
||||
if (options.length === 0) {
|
||||
return (
|
||||
<View style={[styles.container, { maxHeight }]}>
|
||||
<View style={containerStyle}>
|
||||
<View style={styles.emptyItem}>
|
||||
<Text style={styles.emptyText}>{emptyText}</Text>
|
||||
</View>
|
||||
@@ -253,7 +258,7 @@ export function Autocomplete({
|
||||
) : null}
|
||||
</View>
|
||||
) : null}
|
||||
<View style={[styles.container, { maxHeight }]}>
|
||||
<View style={containerStyle}>
|
||||
<ScrollView
|
||||
ref={scrollRef}
|
||||
onLayout={handleScrollViewLayout}
|
||||
|
||||
Reference in New Issue
Block a user