mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* build(mobile): upgrade to Expo SDK 58 and React Native 0.88 Expo 58 drops Zod from @expo/cli, which clears the last Zod 3 advisory (GHSA-mrhx-c7xc-m3w5) in mobile along with its local patch and override. - Expo 55 -> 58, React Native 0.83 -> 0.88, React 19.3, gesture-handler 3, webview 14, reanimated 4.7, worklets 0.13 (SDK 58 bundled versions, pinned below today's batch to respect minimumReleaseAge). - Port the react-native and react-native-webview patches unchanged; drop expo-constants, expo-notifications, @expo/cli, expo-router, zod and query-string patches plus the zod/query-string/xcode>uuid overrides, which upstream fixed or no longer need. - iOS minimum rises to 16.4 (Expo 58 / RN 0.88 requirement). - Migrate to RN 0.88 strict types: instance ref types, NamedStyles, AppState.currentState, list header/footer nulls. - Replace removed runtime APIs: InteractionManager -> idle callback with a macrotask fallback; StyleSheet.absoluteFillObject -> absoluteFill; FileHandle.readBytes -> readBytesSync (it became async). - Resolve react-native/asset-registry for shared assets in Metro and alias the old registry path for react-native-svg in the desktop mobile-web bundle. - Reduce the iOS scene plugin to the reconnect override; Expo 58's template now ships the scene delegate itself. * fix(mobile): bridge react-native-svg web imports and libsodium runtime for RN 0.88 - Share react-native-svg web shims between the mobile-web build and its render checks: map the old asset-registry path to react-native-web's registry and stub the Android-only touch-sound TurboModule. - Patch react-native-libsodium 1.7.0 to read the JSI runtime from the bridge proxy; RN 0.88 removed RCTCxxBridge.runtime. * fix(mobile): use Expo 58's legacy promise resolver for audio permissions * fix(mobile): skip null handles in the RPC recording timer shims for RN 0.88 types * style(mobile): format MobilePRSidebar after rebase * fix(mobile): name RN 0.88 text input refs for declarations; allow queued back in stack render check - Type text input refs with an exported interface so declaration emit can name hook results (RN 0.88 aliases TextInputInstance to an unexported class). - Expo Router 58 drains back() after a commit; check the interrupted push's exit from the frame it starts, bounded to three frames of lag. * chore(mobile): justify the text input handle interface for React Doctor * chore(mobile): use a nameable intersection alias for text input refs * fix(mobile): use sync expo-file-system writes, copies and moves on Expo 58 Expo 58 made File.write/copy/move and FileHandle.writeBytes return promises. Our callers never awaited them, so failures escaped their try/catch and the store's tmp-then-move and PDF writes could race their close or rename. * build(mobile): raise the page bundle budget to 10 MiB for Expo 58 Expo 58 adds about 310 KB to the page: expo-router (+258 KB, now carrying React Navigation, net about +110 KB) and Reanimated 4.7 (+152 KB). Main had 85 KB of headroom left. 10 MiB still stays within the 10 MiB per-asset contract. * fix(mobile): drop the window-metrics seed RN 0.88 removed from Android RN 0.88 no longer holds window metrics: DeviceInfoModule reads the activity's WindowMetrics on demand and setWindowDisplayMetrics is gone, so MainActivity no longer compiled. Layout scale still comes from the screen metrics we reseed. --------- Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
155 lines
7.1 KiB
Diff
155 lines
7.1 KiB
Diff
diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.mm b/Libraries/Text/TextInput/Multiline/RCTUITextView.mm
|
|
index a803387b98bfb68e0c9bbb783e25bc649566e6a3..53adfdd413797871d29e13770f50e9be6377c3e1 100644
|
|
--- a/Libraries/Text/TextInput/Multiline/RCTUITextView.mm
|
|
+++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.mm
|
|
@@ -326,6 +326,11 @@ static UIColor *defaultPlaceholderColor(void)
|
|
|
|
#pragma mark - Dictation
|
|
|
|
+- (void)resetDictationRecognition
|
|
+{
|
|
+ _dictationRecognizing = NO;
|
|
+}
|
|
+
|
|
- (void)dictationRecordingDidEnd
|
|
{
|
|
_dictationRecognizing = YES;
|
|
diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h
|
|
index 2f32b96d2a17b1fd512c2d985dd536ffd4c011c8..4089c3a940a7c389c17500667b6c026bc741034d 100644
|
|
--- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h
|
|
+++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h
|
|
@@ -47,6 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange NS_UNAVAILABLE;
|
|
- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate;
|
|
- (void)scrollRangeToVisible:(NSRange)selectedTextRange;
|
|
+- (void)resetDictationRecognition;
|
|
|
|
// This protocol disallows direct access to `text` property because
|
|
// unwise usage of it can break the `attributeText` behavior.
|
|
diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.mm b/Libraries/Text/TextInput/Singleline/RCTUITextField.mm
|
|
index 064b48bb372074df29f961ff8d79e7caba8520c5..b0b73ecba1f42a7789ede064aa83f4ae9f62c1fb 100644
|
|
--- a/Libraries/Text/TextInput/Singleline/RCTUITextField.mm
|
|
+++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.mm
|
|
@@ -197,6 +197,11 @@
|
|
|
|
#pragma mark - Dictation
|
|
|
|
+- (void)resetDictationRecognition
|
|
+{
|
|
+ _dictationRecognizing = NO;
|
|
+}
|
|
+
|
|
- (void)dictationRecordingDidEnd
|
|
{
|
|
_dictationRecognizing = YES;
|
|
diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm
|
|
index 228ec0d2a28feeee886e1105f4b1e6cd18649b42..c50f79b48e0d4ae0fcdcfb49d0b9db949f55f5d7 100644
|
|
--- a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm
|
|
+++ b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm
|
|
@@ -167,6 +167,7 @@ using namespace facebook::react;
|
|
{
|
|
[super prepareForRecycle];
|
|
_textView.state = nullptr;
|
|
+ _textView.layoutMetrics = EmptyLayoutMetrics;
|
|
_accessibilityProvider = nil;
|
|
}
|
|
|
|
diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
|
|
index 8f55121cd23d27577bab45716d91d6cdad878e41..05529db1a074652d2ca45abd70e421484b38e87b 100644
|
|
--- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
|
|
+++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm
|
|
@@ -397,6 +397,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
_backedTextInputView.inputAccessoryView = nil;
|
|
_hasInputAccessoryView = false;
|
|
[_backedTextInputView resignFirstResponder];
|
|
+ [_backedTextInputView resetDictationRecognition];
|
|
}
|
|
|
|
#pragma mark - RCTBackedTextInputDelegate
|
|
@@ -733,6 +734,7 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
{
|
|
return {
|
|
.text = RCTStringFromNSString(_backedTextInputView.attributedText.string),
|
|
+ .isComposing = _backedTextInputView.markedTextRange != nil,
|
|
.selectionRange = [self _selectionRange],
|
|
.contentSize = RCTSizeFromCGSize(_backedTextInputView.contentSize),
|
|
.contentOffset = RCTPointFromCGPoint(_backedTextInputView.contentOffset),
|
|
@@ -892,8 +894,10 @@ static NSSet<NSNumber *> *returnKeyTypesSet;
|
|
}
|
|
}];
|
|
|
|
+ // Preserve the native recognition placeholder while iOS finalizes dictation.
|
|
BOOL shouldFallbackToBareTextComparison =
|
|
[_backedTextInputView.textInputMode.primaryLanguage isEqualToString:@"dictation"] ||
|
|
+ _backedTextInputView.dictationRecognizing ||
|
|
[_backedTextInputView.textInputMode.primaryLanguage isEqualToString:@"ko-KR"] ||
|
|
_backedTextInputView.markedTextRange || _backedTextInputView.isSecureTextEntry || fontHasBeenUpdatedBySystem;
|
|
|
|
diff --git a/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp b/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp
|
|
index 7da2622926dcb85968d0d8f17a2ec57098117bdd..42d814740d9cfd46bfd40f1cc5b9e851d3765fbd 100644
|
|
--- a/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp
|
|
+++ b/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.cpp
|
|
@@ -24,6 +24,10 @@ static jsi::Value textInputMetricsPayload(
|
|
|
|
payload.setProperty(runtime, "eventCount", textInputMetrics.eventCount);
|
|
|
|
+ if (textInputMetrics.isComposing.has_value()) {
|
|
+ payload.setProperty(runtime, "isComposing", *textInputMetrics.isComposing);
|
|
+ }
|
|
+
|
|
if (includeSelectionState) {
|
|
auto selection = jsi::Object(runtime);
|
|
selection.setProperty(
|
|
diff --git a/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.h b/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.h
|
|
index 8c1a443f9e5f769ea0a1e50e818ab7aae63c72b2..cf6aa26c9a1b6469f110fb0d39e2456bb464bb4f 100644
|
|
--- a/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.h
|
|
+++ b/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.h
|
|
@@ -9,6 +9,8 @@
|
|
|
|
#include <react/cxxstableapi/FrameworksGuard.h>
|
|
|
|
+#include <optional>
|
|
+
|
|
#include <react/renderer/attributedstring/AttributedString.h>
|
|
#include <react/renderer/components/view/ViewEventEmitter.h>
|
|
|
|
@@ -20,6 +22,7 @@ class TextInputEventEmitter : public ViewEventEmitter {
|
|
|
|
struct Metrics {
|
|
std::string text;
|
|
+ std::optional<bool> isComposing;
|
|
AttributedString::Range selectionRange;
|
|
// ScrollView-like metrics
|
|
Size contentSize;
|
|
diff --git a/Libraries/WebSocket/WebSocket.js b/Libraries/WebSocket/WebSocket.js
|
|
index 2eccf43..b5dfad2 100644
|
|
--- a/Libraries/WebSocket/WebSocket.js
|
|
+++ b/Libraries/WebSocket/WebSocket.js
|
|
@@ -90,6 +90,8 @@ class WebSocket extends EventTarget {
|
|
_eventEmitter: NativeEventEmitter<WebSocketEventDefinitions>;
|
|
_subscriptions: Array<EventSubscription>;
|
|
_binaryType: ?BinaryType;
|
|
+ // Orca: opt-in per socket; binary messages arrive as {base64} so the app decodes them natively.
|
|
+ orcaBinaryAsBase64: boolean = false;
|
|
|
|
bufferedAmount: number;
|
|
extension: ?string;
|
|
@@ -241,11 +243,14 @@ class WebSocket extends EventTarget {
|
|
if (ev.id !== this._socketId) {
|
|
return;
|
|
}
|
|
- let data: Blob | BlobData | ArrayBuffer | string = ev.data;
|
|
+ let data: Blob | BlobData | ArrayBuffer | string | {base64: string} =
|
|
+ ev.data;
|
|
switch (ev.type) {
|
|
case 'binary':
|
|
- // $FlowFixMe[incompatible-type]
|
|
- data = base64.toByteArray(ev.data).buffer;
|
|
+ data = this.orcaBinaryAsBase64
|
|
+ ? {base64: ev.data}
|
|
+ : // $FlowFixMe[incompatible-type]
|
|
+ base64.toByteArray(ev.data).buffer;
|
|
break;
|
|
case 'blob':
|
|
data = BlobManager.createFromOptions(ev.data);
|