| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | import { collectComposerInlineTokens } from "@t3tools/shared/composerInlineTokens"; |
| 2 | 2 | import { requireNativeView } from "expo"; |
| 3 | import { TextInputWrapper } from "expo-paste-input"; |
| 3 | 4 | import { |
| 4 | 5 | useCallback, |
| 5 | 6 | useEffect, |
| ... | ... | @@ -9,12 +10,13 @@ import { |
| 9 | 10 | useState, |
| 10 | 11 | type Ref, |
| 11 | 12 | } from "react"; |
| 12 | | import type { NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle } from "react-native"; |
| 13 | import type { NativeSyntheticEvent, ViewProps } from "react-native"; |
| 13 | 14 | import { Image, StyleSheet } from "react-native"; |
| 14 | 15 | |
| 15 | 16 | import { markdownFileIconSource } from "@t3tools/mobile-markdown-text/file-icons"; |
| 16 | 17 | import { resolveMarkdownFileIcon } from "@t3tools/mobile-markdown-text/links"; |
| 17 | 18 | import { MOBILE_TYPOGRAPHY } from "../lib/typography"; |
| 19 | import { useNativePaste } from "../lib/useNativePaste"; |
| 18 | 20 | import { useFontFamily } from "../lib/useFontFamily"; |
| 19 | 21 | import { useThemeColor } from "../lib/useThemeColor"; |
| 20 | 22 | import { |
| ... | ... | @@ -117,6 +119,7 @@ export function ComposerEditor({ |
| 117 | 119 | const skillBorder = useThemeColor("--color-inline-skill-border"); |
| 118 | 120 | const skillText = useThemeColor("--color-inline-skill-foreground"); |
| 119 | 121 | const fileTint = useThemeColor("--color-icon-muted"); |
| 122 | const handlePaste = useNativePaste((uris) => onPasteImages?.(uris)); |
| 120 | 123 | |
| 121 | 124 | useImperativeHandle( |
| 122 | 125 | ref, |
| ... | ... | @@ -221,61 +224,63 @@ export function ComposerEditor({ |
| 221 | 224 | const resolvedTextStyle = StyleSheet.flatten(textStyle) ?? {}; |
| 222 | 225 | const regularFontFamily = useFontFamily("regular"); |
| 223 | 226 | return ( |
| 224 | | <NativeView |
| 225 | | ref={nativeRef} |
| 226 | | controlledDocumentJson={controlledDocumentJson} |
| 227 | | themeJson={themeJson} |
| 228 | | placeholder={props.placeholder ?? ""} |
| 229 | | fontFamily={ |
| 230 | | typeof resolvedTextStyle.fontFamily === "string" |
| 231 | | ? resolvedTextStyle.fontFamily |
| 232 | | : regularFontFamily |
| 233 | | } |
| 234 | | fontSize={ |
| 235 | | typeof resolvedTextStyle.fontSize === "number" |
| 236 | | ? resolvedTextStyle.fontSize |
| 237 | | : MOBILE_TYPOGRAPHY.body.fontSize |
| 238 | | } |
| 239 | | lineHeight={ |
| 240 | | typeof resolvedTextStyle.lineHeight === "number" |
| 241 | | ? resolvedTextStyle.lineHeight |
| 242 | | : MOBILE_TYPOGRAPHY.body.lineHeight |
| 243 | | } |
| 244 | | contentInsetVertical={contentInsetVertical} |
| 245 | | singleLineCentered={props.singleLineCentered ?? false} |
| 246 | | editable={props.editable ?? true} |
| 247 | | scrollEnabled={props.scrollEnabled ?? true} |
| 248 | | autoFocus={props.autoFocus ?? false} |
| 249 | | autoCorrect={props.autoCorrect ?? true} |
| 250 | | spellCheck={props.spellCheck ?? true} |
| 251 | | style={style as StyleProp<ViewStyle>} |
| 252 | | onComposerChange={(event) => { |
| 253 | | const acknowledgedEventCount = acceptNativeEvent( |
| 254 | | event.nativeEvent.eventCount, |
| 255 | | event.nativeEvent.value, |
| 256 | | event.nativeEvent.selection, |
| 257 | | ); |
| 258 | | if (acknowledgedEventCount === false) return; |
| 259 | | onChangeText(event.nativeEvent.value); |
| 260 | | onSelectionChange?.(event.nativeEvent.selection); |
| 261 | | setMostRecentEventCount(acknowledgedEventCount); |
| 262 | | setNativeEventSequence((sequence) => sequence + 1); |
| 263 | | }} |
| 264 | | onComposerSelectionChange={(event) => { |
| 265 | | const acknowledgedEventCount = acceptNativeEvent( |
| 266 | | event.nativeEvent.eventCount, |
| 267 | | event.nativeEvent.value, |
| 268 | | event.nativeEvent.selection, |
| 269 | | ); |
| 270 | | if (acknowledgedEventCount === false) return; |
| 271 | | onSelectionChange?.(event.nativeEvent.selection); |
| 272 | | setMostRecentEventCount(acknowledgedEventCount); |
| 273 | | setNativeEventSequence((sequence) => sequence + 1); |
| 274 | | }} |
| 275 | | onComposerPasteImages={(event) => onPasteImages?.(event.nativeEvent.uris)} |
| 276 | | onComposerFocus={onFocus} |
| 277 | | onComposerBlur={onBlur} |
| 278 | | /> |
| 227 | <TextInputWrapper onPaste={handlePaste} style={[{ minHeight: 0 }, style]}> |
| 228 | <NativeView |
| 229 | ref={nativeRef} |
| 230 | controlledDocumentJson={controlledDocumentJson} |
| 231 | themeJson={themeJson} |
| 232 | placeholder={props.placeholder ?? ""} |
| 233 | fontFamily={ |
| 234 | typeof resolvedTextStyle.fontFamily === "string" |
| 235 | ? resolvedTextStyle.fontFamily |
| 236 | : regularFontFamily |
| 237 | } |
| 238 | fontSize={ |
| 239 | typeof resolvedTextStyle.fontSize === "number" |
| 240 | ? resolvedTextStyle.fontSize |
| 241 | : MOBILE_TYPOGRAPHY.body.fontSize |
| 242 | } |
| 243 | lineHeight={ |
| 244 | typeof resolvedTextStyle.lineHeight === "number" |
| 245 | ? resolvedTextStyle.lineHeight |
| 246 | : MOBILE_TYPOGRAPHY.body.lineHeight |
| 247 | } |
| 248 | contentInsetVertical={contentInsetVertical} |
| 249 | singleLineCentered={props.singleLineCentered ?? false} |
| 250 | editable={props.editable ?? true} |
| 251 | scrollEnabled={props.scrollEnabled ?? true} |
| 252 | autoFocus={props.autoFocus ?? false} |
| 253 | autoCorrect={props.autoCorrect ?? true} |
| 254 | spellCheck={props.spellCheck ?? true} |
| 255 | style={{ flex: 1, minHeight: 0 }} |
| 256 | onComposerChange={(event) => { |
| 257 | const acknowledgedEventCount = acceptNativeEvent( |
| 258 | event.nativeEvent.eventCount, |
| 259 | event.nativeEvent.value, |
| 260 | event.nativeEvent.selection, |
| 261 | ); |
| 262 | if (acknowledgedEventCount === false) return; |
| 263 | onChangeText(event.nativeEvent.value); |
| 264 | onSelectionChange?.(event.nativeEvent.selection); |
| 265 | setMostRecentEventCount(acknowledgedEventCount); |
| 266 | setNativeEventSequence((sequence) => sequence + 1); |
| 267 | }} |
| 268 | onComposerSelectionChange={(event) => { |
| 269 | const acknowledgedEventCount = acceptNativeEvent( |
| 270 | event.nativeEvent.eventCount, |
| 271 | event.nativeEvent.value, |
| 272 | event.nativeEvent.selection, |
| 273 | ); |
| 274 | if (acknowledgedEventCount === false) return; |
| 275 | onSelectionChange?.(event.nativeEvent.selection); |
| 276 | setMostRecentEventCount(acknowledgedEventCount); |
| 277 | setNativeEventSequence((sequence) => sequence + 1); |
| 278 | }} |
| 279 | onComposerPasteImages={(event) => onPasteImages?.(event.nativeEvent.uris)} |
| 280 | onComposerFocus={onFocus} |
| 281 | onComposerBlur={onBlur} |
| 282 | /> |
| 283 | </TextInputWrapper> |
| 279 | 284 | ); |
| 280 | 285 | } |
| 281 | 286 | |