diff --git a/__tests__/lib/images.test.ts b/__tests__/lib/images.test.ts index a5acad25f6..c7a645d39c 100644 --- a/__tests__/lib/images.test.ts +++ b/__tests__/lib/images.test.ts @@ -1,10 +1,9 @@ -import {deleteAsync} from 'expo-file-system' +import {createDownloadResumable, deleteAsync} from 'expo-file-system' import {manipulateAsync, SaveFormat} from 'expo-image-manipulator' -import RNFetchBlob from 'rn-fetch-blob' import { downloadAndResize, - DownloadAndResizeOpts, + type DownloadAndResizeOpts, getResizedDimensions, } from '../../src/lib/media/manip' @@ -32,11 +31,12 @@ describe('downloadAndResize', () => { }) it('should return resized image for valid URI and options', async () => { - const mockedFetch = RNFetchBlob.fetch as jest.Mock - mockedFetch.mockResolvedValueOnce({ - path: jest.fn().mockReturnValue('file://downloaded-image.jpg'), - info: jest.fn().mockReturnValue({status: 200}), - flush: jest.fn(), + const mockedFetch = createDownloadResumable as jest.Mock + mockedFetch.mockReturnValue({ + cancelAsync: jest.fn(), + downloadAsync: jest + .fn() + .mockResolvedValue({uri: 'file://resized-image.jpg'}), }) const opts: DownloadAndResizeOpts = { @@ -50,13 +50,12 @@ describe('downloadAndResize', () => { const result = await downloadAndResize(opts) expect(result).toEqual(mockResizedImage) - expect(RNFetchBlob.config).toHaveBeenCalledWith({ - fileCache: true, - appendExt: 'jpeg', - }) - expect(RNFetchBlob.fetch).toHaveBeenCalledWith( - 'GET', - 'https://example.com/image.jpg', + expect(createDownloadResumable).toHaveBeenCalledWith( + opts.uri, + expect.anything(), + { + cache: true, + }, ) // First time it gets called is to get dimensions @@ -86,28 +85,6 @@ describe('downloadAndResize', () => { expect(result).toBeUndefined() }) - it('should return undefined for non-200 response', async () => { - const mockedFetch = RNFetchBlob.fetch as jest.Mock - mockedFetch.mockResolvedValueOnce({ - path: jest.fn().mockReturnValue('file://downloaded-image'), - info: jest.fn().mockReturnValue({status: 400}), - flush: jest.fn(), - }) - - const opts: DownloadAndResizeOpts = { - uri: 'https://example.com/image', - width: 100, - height: 100, - maxSize: 500000, - mode: 'cover', - timeout: 10000, - } - - const result = await downloadAndResize(opts) - expect(errorSpy).not.toHaveBeenCalled() - expect(result).toBeUndefined() - }) - it('should not downsize whenever dimensions are below the max dimensions', () => { const initialDimensionsOne = { width: 1200, diff --git a/app.config.js b/app.config.js index 0fa91f2ced..36af084158 100644 --- a/app.config.js +++ b/app.config.js @@ -219,7 +219,7 @@ module.exports = function (_config) { compileSdkVersion: 35, targetSdkVersion: 35, buildToolsVersion: '35.0.0', - newArchEnabled: false, + newArchEnabled: true, }, }, ], diff --git a/jest/jestSetup.js b/jest/jestSetup.js index d303225f6c..700d20afc0 100644 --- a/jest/jestSetup.js +++ b/jest/jestSetup.js @@ -33,15 +33,10 @@ jest.mock('react-native-safe-area-context', () => { } }) -jest.mock('rn-fetch-blob', () => ({ - config: jest.fn().mockReturnThis(), - cancel: jest.fn(), - fetch: jest.fn(), -})) - jest.mock('expo-file-system', () => ({ getInfoAsync: jest.fn().mockResolvedValue({exists: true, size: 100}), deleteAsync: jest.fn(), + createDownloadResumable: jest.fn(), })) jest.mock('expo-image-manipulator', () => ({ @@ -101,7 +96,7 @@ jest.mock('expo-modules-core', () => ({ } } }), - requireNativeViewManager: jest.fn().mockImplementation(moduleName => { + requireNativeViewManager: jest.fn().mockImplementation(_ => { return () => null }), })) diff --git a/package.json b/package.json index f0bc5bbe75..38f574f42f 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@braintree/sanitize-url": "^6.0.2", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", "@emoji-mart/react": "^1.1.1", - "@expo/html-elements": "^0.12.4", + "@expo/html-elements": "^0.12.5", "@expo/webpack-config": "^19.0.1", "@floating-ui/dom": "^1.6.3", "@floating-ui/react-dom": "^2.0.8", @@ -85,12 +85,12 @@ "@fortawesome/free-regular-svg-icons": "^6.1.1", "@fortawesome/free-solid-svg-icons": "^6.1.1", "@fortawesome/react-native-fontawesome": "^0.3.2", - "@haileyok/bluesky-video": "0.2.6", + "@haileyok/bluesky-video": "0.3.1", "@ipld/dag-cbor": "^9.2.0", "@lingui/react": "^4.14.1", - "@mattermost/react-native-paste-input": "^0.7.1", - "@miblanchard/react-native-slider": "^2.3.1", - "@mozzius/expo-dynamic-app-icon": "^1.5.0", + "@mattermost/react-native-paste-input": "mattermost/react-native-paste-input", + "@miblanchard/react-native-slider": "^2.6.0", + "@mozzius/expo-dynamic-app-icon": "1.5.0", "@react-native-async-storage/async-storage": "2.1.2", "@react-native-menu/menu": "^1.2.3", "@react-native-picker/picker": "2.11.0", @@ -98,7 +98,7 @@ "@react-navigation/drawer": "^7.3.12", "@react-navigation/native": "^7.1.9", "@react-navigation/native-stack": "^7.3.13", - "@sentry/react-native": "~6.10.0", + "@sentry/react-native": "~6.14.0", "@tanstack/query-async-storage-persister": "^5.25.0", "@tanstack/react-query": "^5.8.1", "@tanstack/react-query-persist-client": "^5.25.0", @@ -130,33 +130,33 @@ "emoji-mart": "^5.5.2", "emoji-regex": "^10.4.0", "eventemitter3": "^5.0.1", - "expo": "^53.0.5", + "expo": "53.0.11", "expo-application": "~6.1.4", - "expo-blur": "~14.1.4", + "expo-blur": "~14.1.5", "expo-build-properties": "~0.14.6", - "expo-camera": "~16.1.6", + "expo-camera": "~16.1.8", "expo-clipboard": "~7.1.4", - "expo-dev-client": "~5.1.7", + "expo-dev-client": "~5.2.0", "expo-device": "~7.1.4", - "expo-file-system": "~18.1.8", - "expo-font": "~13.3.0", + "expo-file-system": "~18.1.10", + "expo-font": "~13.3.1", "expo-haptics": "~14.1.4", - "expo-image": "~2.1.6", + "expo-image": "~2.2.1", "expo-image-crop-tool": "^0.1.8", - "expo-image-manipulator": "~13.1.5", + "expo-image-manipulator": "~13.1.7", "expo-image-picker": "~16.1.4", - "expo-linear-gradient": "~14.1.4", - "expo-linking": "~7.1.4", + "expo-linear-gradient": "~14.1.5", + "expo-linking": "~7.1.5", "expo-localization": "~16.1.5", - "expo-media-library": "~17.1.6", - "expo-notifications": "~0.31.1", - "expo-screen-orientation": "~8.1.5", + "expo-media-library": "~17.1.7", + "expo-notifications": "~0.31.3", + "expo-screen-orientation": "~8.1.7", "expo-sharing": "~13.1.5", - "expo-splash-screen": "~0.30.8", - "expo-system-ui": "~5.0.7", + "expo-splash-screen": "~0.30.9", + "expo-system-ui": "~5.0.8", "expo-task-manager": "~13.1.5", - "expo-updates": "~0.28.12", - "expo-video": "~2.1.8", + "expo-updates": "~0.28.14", + "expo-video": "~2.2.1", "expo-web-browser": "~14.1.6", "fast-text-encoding": "^1.0.6", "history": "^5.3.0", @@ -182,35 +182,34 @@ "react-image-crop": "^11.0.7", "react-is": "19", "react-keyed-flatten-children": "^5.0.0", - "react-native": "0.79.2", - "react-native-compressor": "1.11.0", + "react-native": "^0.79.3", + "react-native-compressor": "^1.11.0", "react-native-date-picker": "^5.0.12", - "react-native-drawer-layout": "^4.1.6", + "react-native-drawer-layout": "^4.1.8", "react-native-edge-to-edge": "^1.6.0", "react-native-gesture-handler": "2.25.0", "react-native-get-random-values": "~1.11.0", "react-native-ios-context-menu": "^1.15.3", "react-native-keyboard-controller": "^1.17.1", "react-native-mmkv": "^2.12.2", - "react-native-pager-view": "6.7.1", + "react-native-pager-view": "^6.7.1", "react-native-progress": "bluesky-social/react-native-progress", "react-native-qrcode-styled": "^0.3.3", "react-native-reanimated": "~3.17.5", - "react-native-root-siblings": "^4.1.1", + "react-native-root-siblings": "^5.0.1", "react-native-safe-area-context": "5.4.0", "react-native-screens": "^4.11.1", - "react-native-svg": "15.11.2", + "react-native-svg": "15.12.0", "react-native-uitextview": "^1.4.0", "react-native-url-polyfill": "^1.3.0", "react-native-uuid": "^2.0.3", "react-native-view-shot": "^4.0.3", "react-native-web": "~0.20.0", "react-native-web-webview": "^1.0.2", - "react-native-webview": "13.13.5", + "react-native-webview": "^13.13.5", "react-remove-scroll-bar": "^2.3.8", "react-responsive": "^9.0.2", "react-textarea-autosize": "^8.5.3", - "rn-fetch-blob": "^0.12.0", "statsig-react-native-expo": "^4.6.1", "tippy.js": "^6.3.7", "tlds": "^1.234.0", @@ -227,8 +226,9 @@ "@lingui/cli": "^4.14.1", "@lingui/macro": "^4.14.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", - "@react-native/eslint-config": "^0.79.2", - "@react-native/typescript-config": "^0.79.2", + "@react-native/babel-preset": "0.79.3", + "@react-native/eslint-config": "^0.79.3", + "@react-native/typescript-config": "^0.79.3", "@sentry/webpack-plugin": "^3.2.2", "@testing-library/jest-native": "^5.4.3", "@testing-library/react-native": "^13.2.0", @@ -247,6 +247,7 @@ "babel-plugin-module-resolver": "^5.0.2", "babel-plugin-react-compiler": "^19.1.0-rc.1", "babel-preset-expo": "~13.1.11", + "browserslist": "^4.25.0", "eslint": "^8.19.0", "eslint-plugin-bsky-internal": "link:./eslint", "eslint-plugin-ft-flow": "^2.0.3", @@ -260,7 +261,7 @@ "husky": "^8.0.3", "is-ci": "^3.0.1", "jest": "^29.7.0", - "jest-expo": "~53.0.3", + "jest-expo": "~53.0.7", "jest-junit": "^16.0.0", "lint-staged": "^13.2.3", "lockfile-lint": "^4.14.0", @@ -275,11 +276,11 @@ }, "resolutions": { "@expo/image-utils": "0.6.3", - "@react-native/babel-preset": "0.79.2", - "@react-native/normalize-colors": "0.79.2", + "@react-native/babel-preset": "0.79.3", + "@react-native/normalize-colors": "0.79.3", "@types/react": "^18", "**/expo-constants": "17.0.3", - "**/expo-device": "7.0.1", + "**/expo-device": "7.1.4", "**/zod": "3.23.8", "**/multiformats": "9.9.0" }, @@ -359,7 +360,8 @@ ], "allowedUrls": [ "https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908", - "https://codeload.github.com/bluesky-social/react-native-progress/tar.gz/5a372f4f2ce5feb26f4f47b6a4d187ab9b923ab4" + "https://codeload.github.com/bluesky-social/react-native-progress/tar.gz/5a372f4f2ce5feb26f4f47b6a4d187ab9b923ab4", + "https://codeload.github.com/mattermost/react-native-paste-input/tar.gz/f260447edc645a817ab1ba7b46d8341d84dba8e9" ], "emptyHostname": false, "validatePackageNames": true, diff --git a/patches/@mattermost+react-native-paste-input+0.7.1.patch b/patches/@mattermost+react-native-paste-input+0.8.1.patch.disabled similarity index 50% rename from patches/@mattermost+react-native-paste-input+0.7.1.patch rename to patches/@mattermost+react-native-paste-input+0.8.1.patch.disabled index f25b6a776e..a7f1461432 100644 --- a/patches/@mattermost+react-native-paste-input+0.7.1.patch +++ b/patches/@mattermost+react-native-paste-input+0.8.1.patch.disabled @@ -114,7 +114,7 @@ index e916023..5049c33 100644 } #pragma mark - UIScrollViewDelegate -@@ -62,7 +92,6 @@ +@@ -62,7 +92,6 @@ - (void)setSmartPunctuation:(NSString *)smartPunctuation { - (void)scrollViewDidScroll:(UIScrollView *)scrollView { RCTDirectEventBlock onScroll = self.onScroll; @@ -122,7 +122,7 @@ index e916023..5049c33 100644 if (onScroll) { CGPoint contentOffset = scrollView.contentOffset; CGSize contentSize = scrollView.contentSize; -@@ -71,22 +100,22 @@ +@@ -71,22 +100,22 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView onScroll(@{ @"contentOffset": @{ @@ -155,3 +155,110 @@ index e916023..5049c33 100644 }, @"zoomScale": @(scrollView.zoomScale ?: 1), }); +diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm +index dd50053..2ed7017 100644 +--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm ++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInput.mm +@@ -122,8 +122,8 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & + const auto &newTextInputProps = static_cast(*props); + + // Traits: +- if (newTextInputProps.traits.multiline != oldTextInputProps.traits.multiline) { +- [self _setMultiline:newTextInputProps.traits.multiline]; ++ if (newTextInputProps.multiline != oldTextInputProps.multiline) { ++ [self _setMultiline:newTextInputProps.multiline]; + } + + if (newTextInputProps.traits.autocapitalizationType != oldTextInputProps.traits.autocapitalizationType) { +@@ -421,7 +421,7 @@ - (void)textInputDidChangeSelection + return; + } + const auto &props = static_cast(*_props); +- if (props.traits.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { ++ if (props.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { + [self textInputDidChange]; + _ignoreNextTextInputCall = YES; + } +@@ -708,11 +708,11 @@ - (BOOL)_textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldTe + - (SubmitBehavior)getSubmitBehavior + { + const auto &props = static_cast(*_props); +- const SubmitBehavior submitBehaviorDefaultable = props.traits.submitBehavior; ++ const SubmitBehavior submitBehaviorDefaultable = props.submitBehavior; + + // We should always have a non-default `submitBehavior`, but in case we don't, set it based on multiline. + if (submitBehaviorDefaultable == SubmitBehavior::Default) { +- return props.traits.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit; ++ return props.multiline ? SubmitBehavior::Newline : SubmitBehavior::BlurAndSubmit; + } + + return submitBehaviorDefaultable; +diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp +index 29e094f..7ef519a 100644 +--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp ++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.cpp +@@ -22,8 +22,7 @@ PasteTextInputProps::PasteTextInputProps( + const PropsParserContext &context, + const PasteTextInputProps &sourceProps, + const RawProps& rawProps) +- : ViewProps(context, sourceProps, rawProps), +- BaseTextProps(context, sourceProps, rawProps), ++ : BaseTextInputProps(context, sourceProps, rawProps), + traits(convertRawProp(context, rawProps, sourceProps.traits, {})), + smartPunctuation(convertRawProp(context, rawProps, "smartPunctuation", sourceProps.smartPunctuation, {})), + disableCopyPaste(convertRawProp(context, rawProps, "disableCopyPaste", sourceProps.disableCopyPaste, {false})), +@@ -133,7 +132,7 @@ TextAttributes PasteTextInputProps::getEffectiveTextAttributes(Float fontSizeMul + ParagraphAttributes PasteTextInputProps::getEffectiveParagraphAttributes() const { + auto result = paragraphAttributes; + +- if (!traits.multiline) { ++ if (!multiline) { + result.maximumNumberOfLines = 1; + } + +diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h +index 723d00c..31cfe66 100644 +--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h ++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/Props.h +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -25,7 +26,7 @@ + + namespace facebook::react { + +-class PasteTextInputProps final : public ViewProps, public BaseTextProps { ++class PasteTextInputProps final : public BaseTextInputProps { + public: + PasteTextInputProps() = default; + PasteTextInputProps(const PropsParserContext& context, const PasteTextInputProps& sourceProps, const RawProps& rawProps); +diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp +index 31e07e3..7f0ebfb 100644 +--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp ++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteTextInputSpecs/ShadowNodes.cpp +@@ -91,20 +91,11 @@ void PasteTextInputShadowNode::updateStateIfNeeded( + const auto& state = getStateData(); + + react_native_assert(textLayoutManager_); +- react_native_assert( +- (!state.layoutManager || state.layoutManager == textLayoutManager_) && +- "`StateData` refers to a different `TextLayoutManager`"); +- +- if (state.reactTreeAttributedString == reactTreeAttributedString && +- state.layoutManager == textLayoutManager_) { +- return; +- } + + auto newState = TextInputState{}; + newState.attributedStringBox = AttributedStringBox{reactTreeAttributedString}; + newState.paragraphAttributes = getConcreteProps().paragraphAttributes; + newState.reactTreeAttributedString = reactTreeAttributedString; +- newState.layoutManager = textLayoutManager_; + newState.mostRecentEventCount = getConcreteProps().mostRecentEventCount; + setStateData(std::move(newState)); + } diff --git a/patches/@sentry+react-native+6.10.0.patch b/patches/@sentry+react-native+6.14.0.patch similarity index 100% rename from patches/@sentry+react-native+6.10.0.patch rename to patches/@sentry+react-native+6.14.0.patch diff --git a/patches/expo-media-library+17.1.6.patch b/patches/expo-media-library+17.1.7.patch similarity index 100% rename from patches/expo-media-library+17.1.6.patch rename to patches/expo-media-library+17.1.7.patch diff --git a/patches/expo-modules-core+2.3.12.patch b/patches/expo-modules-core+2.4.0.patch similarity index 100% rename from patches/expo-modules-core+2.3.12.patch rename to patches/expo-modules-core+2.4.0.patch diff --git a/patches/expo-modules-core+2.3.12.patch.md b/patches/expo-modules-core+2.4.0.patch.md similarity index 100% rename from patches/expo-modules-core+2.3.12.patch.md rename to patches/expo-modules-core+2.4.0.patch.md diff --git a/patches/expo-notifications+0.31.1.patch b/patches/expo-notifications+0.31.3.patch similarity index 100% rename from patches/expo-notifications+0.31.1.patch rename to patches/expo-notifications+0.31.3.patch diff --git a/patches/expo-notifications+0.31.1.patch.md b/patches/expo-notifications+0.31.3.patch.md similarity index 100% rename from patches/expo-notifications+0.31.1.patch.md rename to patches/expo-notifications+0.31.3.patch.md diff --git a/patches/expo-updates+0.28.12.patch b/patches/expo-updates+0.28.14.patch similarity index 100% rename from patches/expo-updates+0.28.12.patch rename to patches/expo-updates+0.28.14.patch diff --git a/patches/expo-updates+0.28.12.patch.md b/patches/expo-updates+0.28.14.patch.md similarity index 100% rename from patches/expo-updates+0.28.12.patch.md rename to patches/expo-updates+0.28.14.patch.md diff --git a/patches/react-native+0.79.2.patch b/patches/react-native+0.79.3.patch similarity index 70% rename from patches/react-native+0.79.2.patch rename to patches/react-native+0.79.3.patch index 609ae66178..6d465475eb 100644 --- a/patches/react-native+0.79.2.patch +++ b/patches/react-native+0.79.3.patch @@ -1,3 +1,32 @@ +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h +index 914a249..0deac55 100644 +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h +@@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN + */ + @interface RCTPullToRefreshViewComponentView : RCTViewComponentView + ++- (void)beginRefreshingProgrammatically; ++ + @end + + NS_ASSUME_NONNULL_END +diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +index d029337..0f63ea3 100644 +--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm ++++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +@@ -1003,6 +1003,11 @@ - (void)_adjustForMaintainVisibleContentPosition + } + } + +++ (BOOL)shouldBeRecycled ++{ ++ return NO; ++} ++ + @end + + Class RCTScrollViewCls(void) diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h index e9b330f..ec5f58c 100644 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h @@ -15,7 +44,7 @@ diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshCont index 53bfd04..ff1b1ed 100644 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m -@@ -23,6 +23,7 @@ +@@ -23,6 +23,7 @@ @implementation RCTRefreshControl { UIColor *_titleColor; CGFloat _progressViewOffset; BOOL _hasMovedToWindow; @@ -23,7 +52,7 @@ index 53bfd04..ff1b1ed 100644 } - (instancetype)init -@@ -58,6 +59,12 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) +@@ -58,6 +59,12 @@ - (void)layoutSubviews _isInitialRender = false; } @@ -36,7 +65,7 @@ index 53bfd04..ff1b1ed 100644 - (void)didMoveToWindow { [super didMoveToWindow]; -@@ -221,4 +228,50 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) +@@ -221,4 +228,50 @@ - (void)refreshControlValueChanged } } @@ -91,7 +120,7 @@ diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshCont index 40aaf9c..1c60164 100644 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m -@@ -22,11 +22,12 @@ RCT_EXPORT_MODULE() +@@ -22,11 +22,12 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL) @@ -105,15 +134,3 @@ index 40aaf9c..1c60164 100644 RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { -diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m -index cd1e7eb..c1d0172 100644 ---- a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m -+++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m -@@ -83,6 +83,7 @@ RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL) - RCT_EXPORT_VIEW_PROPERTY(scrollEventThrottle, NSTimeInterval) - RCT_EXPORT_VIEW_PROPERTY(zoomScale, CGFloat) - RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) -+RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets, UIEdgeInsets) - RCT_EXPORT_VIEW_PROPERTY(verticalScrollIndicatorInsets, UIEdgeInsets) - RCT_EXPORT_VIEW_PROPERTY(scrollToOverflowEnabled, BOOL) - RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int) diff --git a/patches/react-native+0.79.2.patch.md b/patches/react-native+0.79.3.patch.md similarity index 100% rename from patches/react-native+0.79.2.patch.md rename to patches/react-native+0.79.3.patch.md diff --git a/patches/react-native-svg+15.11.2.patch b/patches/react-native-svg+15.12.0.patch similarity index 100% rename from patches/react-native-svg+15.11.2.patch rename to patches/react-native-svg+15.12.0.patch diff --git a/src/components/Post/Embed/ImageEmbed.tsx b/src/components/Post/Embed/ImageEmbed.tsx index a45171ce2a..030d237a03 100644 --- a/src/components/Post/Embed/ImageEmbed.tsx +++ b/src/components/Post/Embed/ImageEmbed.tsx @@ -1,16 +1,21 @@ import {InteractionManager, View} from 'react-native' -import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated' +import { + type AnimatedRef, + measure, + type MeasuredDimensions, + runOnJS, + runOnUI, +} from 'react-native-reanimated' import {Image} from 'expo-image' -import {HandleRef, measureHandle} from '#/lib/hooks/useHandleRef' import {useLightboxControls} from '#/state/lightbox' -import {Dimensions} from '#/view/com/lightbox/ImageViewing/@types' +import {type Dimensions} from '#/view/com/lightbox/ImageViewing/@types' import {AutoSizedImage} from '#/view/com/util/images/AutoSizedImage' import {ImageLayoutGrid} from '#/view/com/util/images/ImageLayoutGrid' import {atoms as a} from '#/alf' import {PostEmbedViewContext} from '#/components/Post/Embed/types' -import {EmbedType} from '#/types/bsky/post' -import {CommonProps} from './types' +import {type EmbedType} from '#/types/bsky/post' +import {type CommonProps} from './types' export function ImageEmbed({ embed, @@ -45,13 +50,15 @@ export function ImageEmbed({ } const onPress = ( index: number, - refs: HandleRef[], + refs: AnimatedRef[], fetchedDims: (Dimensions | null)[], ) => { - const handles = refs.map(r => r.current) runOnUI(() => { 'worklet' - const rects = handles.map(measureHandle) + const rects: (MeasuredDimensions | null)[] = [] + for (const r of refs) { + rects.push(measure(r)) + } runOnJS(_openLightbox)(index, rects, fetchedDims) })() } diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index e5fb338497..ea7f8e94ef 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -1,12 +1,12 @@ import React from 'react' import { - AccessibilityProps, + type AccessibilityProps, StyleSheet, TextInput, - TextInputProps, - TextStyle, + type TextInputProps, + type TextStyle, View, - ViewStyle, + type ViewStyle, } from 'react-native' import {HITSLOP_20} from '#/lib/constants' @@ -16,13 +16,13 @@ import { applyFonts, atoms as a, ios, - TextStyleProp, + type TextStyleProp, useAlf, useTheme, web, } from '#/alf' import {useInteractionState} from '#/components/hooks/useInteractionState' -import {Props as SVGIconProps} from '#/components/icons/common' +import {type Props as SVGIconProps} from '#/components/icons/common' import {Text} from '#/components/Typography' const Context = React.createContext<{ @@ -196,7 +196,7 @@ export function createInput(Component: typeof TextInput) { minWidth: 0, }, ios({paddingTop: 12, paddingBottom: 13}), - android(a.py_sm), + android(a.py_md), // fix for autofill styles covering border web({ paddingTop: 10, diff --git a/src/lib/hooks/useHandleRef.ts b/src/lib/hooks/useHandleRef.ts deleted file mode 100644 index 167ba270b6..0000000000 --- a/src/lib/hooks/useHandleRef.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {useState} from 'react' -import {AnimatedRef, measure, MeasuredDimensions} from 'react-native-reanimated' - -export type HandleRef = { - (node: any): void - current: null | number -} - -// This is a lighterweight alternative to `useAnimatedRef()` for imperative UI thread actions. -// Render it like , then pass `ref.current` to `measureHandle()` and such. -export function useHandleRef(): HandleRef { - return useState(() => { - const ref = (node: any) => { - if (node) { - ref.current = - node._nativeTag ?? - node.__nativeTag ?? - node.canonical?.nativeTag ?? - null - } else { - ref.current = null - } - } - ref.current = null - return ref - })[0] as HandleRef -} - -// When using this version, you need to read ref.current on the JS thread, and pass it to UI. -export function measureHandle( - current: number | null, -): MeasuredDimensions | null { - 'worklet' - if (current !== null) { - return measure((() => current) as AnimatedRef) - } else { - return null - } -} diff --git a/src/lib/media/manip.ts b/src/lib/media/manip.ts index 62cbc55ac5..c7a429a243 100644 --- a/src/lib/media/manip.ts +++ b/src/lib/media/manip.ts @@ -1,8 +1,9 @@ -import {Image as RNImage, Share as RNShare} from 'react-native' +import {Image as RNImage} from 'react-native' import uuid from 'react-native-uuid' import { cacheDirectory, copyAsync, + createDownloadResumable, deleteAsync, EncodingType, getInfoAsync, @@ -14,7 +15,6 @@ import {manipulateAsync, SaveFormat} from 'expo-image-manipulator' import * as MediaLibrary from 'expo-media-library' import * as Sharing from 'expo-sharing' import {Buffer} from 'buffer' -import RNFetchBlob from 'rn-fetch-blob' import {POST_IMG_MAX} from '#/lib/constants' import {logger} from '#/logger' @@ -68,28 +68,13 @@ export async function downloadAndResize(opts: DownloadAndResizeOpts) { return } - let downloadRes + const path = createPath(appendExt) + try { - const downloadResPromise = RNFetchBlob.config({ - fileCache: true, - appendExt, - }).fetch('GET', opts.uri) - const to1 = setTimeout(() => downloadResPromise.cancel(), opts.timeout) - downloadRes = await downloadResPromise - clearTimeout(to1) - - const status = downloadRes.info().status - if (status !== 200) { - return - } - - const localUri = normalizePath(downloadRes.path(), true) - return await doResize(localUri, opts) + await downloadImage(opts.uri, path, opts.timeout) + return await doResize(path, opts) } finally { - // TODO Whenever we remove `rn-fetch-blob`, we will need to replace this `flush()` with a `deleteAsync()` -hailey - if (downloadRes) { - downloadRes.flush() - } + safeDeleteAsync(path) } } @@ -98,32 +83,16 @@ export async function shareImageModal({uri}: {uri: string}) { // TODO might need to give an error to the user in this case -prf return } - const downloadResponse = await RNFetchBlob.config({ - fileCache: true, - }).fetch('GET', uri) - // NOTE - // assuming PNG // we're currently relying on the fact our CDN only serves pngs // -prf - - let imagePath = downloadResponse.path() - imagePath = normalizePath(await moveToPermanentPath(imagePath, '.png'), true) - - // NOTE - // for some reason expo-sharing refuses to work on iOS - // ...and visa versa - // -prf - if (isIOS) { - await RNShare.share({url: imagePath}) - } else { - await Sharing.shareAsync(imagePath, { - mimeType: 'image/png', - UTI: 'image/png', - }) - } - - safeDeleteAsync(imagePath) + const imageUri = await downloadImage(uri, createPath('png'), 5e3) + const imagePath = await moveToPermanentPath(imageUri, '.png') + safeDeleteAsync(imageUri) + await Sharing.shareAsync(imagePath, { + mimeType: 'image/png', + UTI: 'image/png', + }) } const ALBUM_NAME = 'Bluesky' @@ -134,11 +103,8 @@ export async function saveImageToMediaLibrary({uri}: {uri: string}) { // assuming PNG // we're currently relying on the fact our CDN only serves pngs // -prf - const downloadResponse = await RNFetchBlob.config({ - fileCache: true, - }).fetch('GET', uri) - let imagePath = downloadResponse.path() - imagePath = normalizePath(await moveToPermanentPath(imagePath, '.png'), true) + const imageUri = await downloadImage(uri, createPath('png'), 5e3) + const imagePath = await moveToPermanentPath(imageUri, '.png') // save try { @@ -403,3 +369,24 @@ export function getResizedDimensions(originalDims: { height: Math.round(originalDims.height * ratio), } } + +function createPath(ext: string) { + // cacheDirectory will never be null on native, so the null check here is not necessary except for typescript. + // we use a web-only function for downloadAndResize on web + return `${cacheDirectory ?? ''}/${uuid.v4()}.${ext}` +} + +async function downloadImage(uri: string, path: string, timeout: number) { + const dlResumable = createDownloadResumable(uri, path, {cache: true}) + + const to1 = setTimeout(() => dlResumable.cancelAsync(), timeout) + + const dlRes = await dlResumable.downloadAsync() + clearTimeout(to1) + + if (!dlRes?.uri) { + throw new Error('Failed to download image - dlRes is undefined') + } + + return normalizePath(dlRes.uri) +} diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index 7f3d35dfce..8bb3dca9e5 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -74,8 +74,8 @@ msgstr "" msgid "{0, plural, one {# second} other {# seconds}}" msgstr "" -#: src/view/shell/bottom-bar/BottomBar.tsx:223 -#: src/view/shell/bottom-bar/BottomBar.tsx:255 +#: src/view/shell/bottom-bar/BottomBar.tsx:225 +#: src/view/shell/bottom-bar/BottomBar.tsx:257 #: src/view/shell/Drawer.tsx:487 msgid "{0, plural, one {# unread item} other {# unread items}}" msgstr "" @@ -95,7 +95,8 @@ msgstr "" msgid "{0, plural, one {following} other {following}}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:529 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:461 +#: src/view/com/post-thread/PostThreadItem.tsx:540 msgid "{0, plural, one {like} other {likes}}" msgstr "" @@ -103,11 +104,13 @@ msgstr "" msgid "{0, plural, one {post} other {posts}}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:513 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:445 +#: src/view/com/post-thread/PostThreadItem.tsx:524 msgid "{0, plural, one {quote} other {quotes}}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:495 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:427 +#: src/view/com/post-thread/PostThreadItem.tsx:506 msgid "{0, plural, one {repost} other {reposts}}" msgstr "" @@ -366,7 +369,7 @@ msgstr "" msgid "{following} following" msgstr "" -#: src/components/dialogs/SearchablePeopleList.tsx:412 +#: src/components/dialogs/SearchablePeopleList.tsx:413 msgid "{handle} can't be messaged" msgstr "" @@ -387,7 +390,7 @@ msgstr "" msgid "{minutes, plural, one {# minute} other {# minutes}}" msgstr "" -#: src/view/shell/bottom-bar/BottomBarWeb.tsx:270 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:277 msgid "{notificationCount, plural, one {# unread item} other {# unread items}}" msgstr "" @@ -647,7 +650,7 @@ msgstr "" msgid "Add another account" msgstr "" -#: src/view/com/composer/Composer.tsx:731 +#: src/view/com/composer/Composer.tsx:772 msgid "Add another post" msgstr "" @@ -678,7 +681,7 @@ msgstr "" msgid "Add muted words and tags" msgstr "" -#: src/view/com/composer/Composer.tsx:1287 +#: src/view/com/composer/Composer.tsx:1330 msgid "Add new post" msgstr "" @@ -1060,12 +1063,15 @@ msgstr "" msgid "Apply default recommended feeds" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:945 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:627 +#: src/view/com/post-thread/PostThreadItem.tsx:956 msgid "Archived from {0}" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:914 -#: src/view/com/post-thread/PostThreadItem.tsx:953 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:596 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:635 +#: src/view/com/post-thread/PostThreadItem.tsx:925 +#: src/view/com/post-thread/PostThreadItem.tsx:964 msgid "Archived post" msgstr "" @@ -1101,11 +1107,11 @@ msgstr "" msgid "Are you sure you want to remove this from your feeds?" msgstr "" -#: src/view/com/composer/Composer.tsx:682 +#: src/view/com/composer/Composer.tsx:723 msgid "Are you sure you'd like to discard this draft?" msgstr "" -#: src/view/com/composer/Composer.tsx:861 +#: src/view/com/composer/Composer.tsx:904 msgid "Are you sure you'd like to discard this post?" msgstr "" @@ -1279,7 +1285,7 @@ msgstr "" msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you. You will not see their content and they will be prevented from seeing yours." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:468 +#: src/view/com/post-thread/PostThread.tsx:488 msgid "Blocked post." msgstr "" @@ -1304,7 +1310,8 @@ msgstr "" msgid "Bluesky" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:970 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:652 +#: src/view/com/post-thread/PostThreadItem.tsx:981 msgid "Bluesky cannot confirm the authenticity of the claimed date." msgstr "" @@ -1464,8 +1471,8 @@ msgstr "" #: src/screens/Settings/Settings.tsx:270 #: src/screens/Takendown.tsx:99 #: src/screens/Takendown.tsx:102 -#: src/view/com/composer/Composer.tsx:916 -#: src/view/com/composer/Composer.tsx:927 +#: src/view/com/composer/Composer.tsx:959 +#: src/view/com/composer/Composer.tsx:970 #: src/view/com/composer/photos/EditImageDialog.web.tsx:43 #: src/view/com/composer/photos/EditImageDialog.web.tsx:52 #: src/view/com/modals/ChangePassword.tsx:279 @@ -1518,7 +1525,7 @@ msgstr "" #: src/components/PostControls/index.tsx:101 #: src/components/PostControls/index.tsx:132 #: src/components/PostControls/index.tsx:160 -#: src/state/shell/composer/index.tsx:82 +#: src/state/shell/composer/index.tsx:91 msgid "Cannot interact with a blocked user" msgstr "" @@ -1592,7 +1599,7 @@ msgid "Changes hosting provider" msgstr "" #: src/Navigation.tsx:428 -#: src/view/shell/bottom-bar/BottomBar.tsx:219 +#: src/view/shell/bottom-bar/BottomBar.tsx:221 #: src/view/shell/desktop/LeftNav.tsx:553 #: src/view/shell/Drawer.tsx:455 msgid "Chat" @@ -1825,7 +1832,7 @@ msgstr "" msgid "Closes password update alert" msgstr "" -#: src/view/com/composer/Composer.tsx:924 +#: src/view/com/composer/Composer.tsx:967 msgid "Closes post composer and discards post draft" msgstr "" @@ -1882,15 +1889,15 @@ msgstr "" msgid "Compose new post" msgstr "" -#: src/view/com/composer/Composer.tsx:825 +#: src/view/com/composer/Composer.tsx:868 msgid "Compose posts up to {0, plural, other {# characters}} in length" msgstr "" -#: src/view/com/post-thread/PostThreadComposePrompt.tsx:34 +#: src/view/com/post-thread/PostThreadComposePrompt.tsx:67 msgid "Compose reply" msgstr "" -#: src/view/com/composer/Composer.tsx:1669 +#: src/view/com/composer/Composer.tsx:1724 msgid "Compressing video..." msgstr "" @@ -2014,6 +2021,11 @@ msgstr "" msgid "Continue as {0} (currently signed in)" msgstr "" +#: src/screens/PostThread/components/ThreadItemReadMoreUp.tsx:27 +msgid "Continue thread" +msgstr "" + +#: src/screens/PostThread/components/ThreadItemReadMoreUp.tsx:63 #: src/view/com/post-thread/PostThreadLoadMore.tsx:60 msgid "Continue thread..." msgstr "" @@ -2196,10 +2208,10 @@ msgstr "" #: src/view/com/auth/SplashScreen.tsx:55 #: src/view/com/auth/SplashScreen.web.tsx:117 -#: src/view/shell/bottom-bar/BottomBar.tsx:343 -#: src/view/shell/bottom-bar/BottomBar.tsx:348 -#: src/view/shell/bottom-bar/BottomBarWeb.tsx:199 -#: src/view/shell/bottom-bar/BottomBarWeb.tsx:204 +#: src/view/shell/bottom-bar/BottomBar.tsx:345 +#: src/view/shell/bottom-bar/BottomBar.tsx:350 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:206 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:211 #: src/view/shell/NavSignupCard.tsx:47 #: src/view/shell/NavSignupCard.tsx:52 msgid "Create account" @@ -2383,7 +2395,7 @@ msgstr "" #: src/components/PostControls/PostMenu/PostMenuItems.tsx:682 #: src/components/PostControls/PostMenu/PostMenuItems.tsx:684 -#: src/view/com/composer/Composer.tsx:835 +#: src/view/com/composer/Composer.tsx:878 msgid "Delete post" msgstr "" @@ -2413,7 +2425,7 @@ msgstr "" msgid "Deleted Account" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:454 +#: src/view/com/post-thread/PostThread.tsx:474 msgid "Deleted post." msgstr "" @@ -2502,8 +2514,8 @@ msgid "Disabled" msgstr "" #: src/screens/Profile/Header/EditProfileDialog.tsx:88 -#: src/view/com/composer/Composer.tsx:684 -#: src/view/com/composer/Composer.tsx:868 +#: src/view/com/composer/Composer.tsx:725 +#: src/view/com/composer/Composer.tsx:911 msgid "Discard" msgstr "" @@ -2511,11 +2523,11 @@ msgstr "" msgid "Discard changes?" msgstr "" -#: src/view/com/composer/Composer.tsx:681 +#: src/view/com/composer/Composer.tsx:722 msgid "Discard draft?" msgstr "" -#: src/view/com/composer/Composer.tsx:860 +#: src/view/com/composer/Composer.tsx:903 msgid "Discard post?" msgstr "" @@ -2541,7 +2553,7 @@ msgstr "" msgid "Dismiss" msgstr "" -#: src/view/com/composer/Composer.tsx:1593 +#: src/view/com/composer/Composer.tsx:1648 msgid "Dismiss error" msgstr "" @@ -2651,7 +2663,7 @@ msgstr "" msgid "Double tap to close the dialog" msgstr "" -#: src/screens/VideoFeed/index.tsx:1077 +#: src/screens/VideoFeed/index.tsx:1080 msgid "Double tap to like" msgstr "" @@ -3021,11 +3033,15 @@ msgstr "" msgid "Entertainment" msgstr "" -#: src/view/com/composer/Composer.tsx:1678 +#: src/view/com/composer/Composer.tsx:1733 #: src/view/com/util/error/ErrorScreen.tsx:42 msgid "Error" msgstr "" +#: src/screens/PostThread/components/ThreadError.tsx:26 +msgid "Error loading post" +msgstr "" + #: src/screens/Settings/components/ExportCarDialog.tsx:47 msgid "Error occurred while saving file" msgstr "" @@ -3105,7 +3121,7 @@ msgstr "" msgid "Expand or collapse the full post you are replying to" msgstr "" -#: src/screens/VideoFeed/index.tsx:962 +#: src/screens/VideoFeed/index.tsx:965 msgid "Expands or collapses post text" msgstr "" @@ -3114,7 +3130,7 @@ msgid "Expected uri to resolve to a record" msgstr "" #: src/screens/Settings/FollowingFeedPreferences.tsx:123 -#: src/screens/Settings/ThreadPreferences.tsx:137 +#: src/screens/Settings/ThreadPreferences.tsx:271 msgid "Experimental" msgstr "" @@ -3638,7 +3654,7 @@ msgstr "" msgid "From @{sanitizedAuthor}" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:326 +#: src/view/com/posts/PostFeedItem.tsx:328 msgctxt "from-feed" msgid "From <0/>" msgstr "" @@ -3685,8 +3701,8 @@ msgstr "" #: src/screens/Messages/Inbox.tsx:228 #: src/screens/Profile/ProfileFeed/index.tsx:92 #: src/screens/VideoFeed/components/Header.tsx:163 -#: src/screens/VideoFeed/index.tsx:1138 -#: src/screens/VideoFeed/index.tsx:1142 +#: src/screens/VideoFeed/index.tsx:1141 +#: src/screens/VideoFeed/index.tsx:1145 #: src/view/com/auth/LoggedOut.tsx:72 #: src/view/screens/NotFound.tsx:57 #: src/view/screens/ProfileList.tsx:1038 @@ -3956,7 +3972,7 @@ msgstr "" #: src/Navigation.tsx:620 #: src/Navigation.tsx:640 -#: src/view/shell/bottom-bar/BottomBar.tsx:176 +#: src/view/shell/bottom-bar/BottomBar.tsx:178 #: src/view/shell/desktop/LeftNav.tsx:617 #: src/view/shell/Drawer.tsx:429 msgid "Home" @@ -3975,10 +3991,10 @@ msgstr "" msgid "Hot" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:67 -#: src/screens/Settings/ThreadPreferences.tsx:70 -#: src/view/com/post-thread/PostThread.tsx:655 -#: src/view/com/post-thread/PostThread.tsx:660 +#: src/screens/Settings/ThreadPreferences.tsx:201 +#: src/screens/Settings/ThreadPreferences.tsx:204 +#: src/view/com/post-thread/PostThread.tsx:679 +#: src/view/com/post-thread/PostThread.tsx:684 msgid "Hot replies first" msgstr "" @@ -4133,7 +4149,7 @@ msgstr "" msgid "Invalid handle. Please try a different one." msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:339 +#: src/view/com/post-thread/PostThreadItem.tsx:350 msgid "Invalid or unsupported post record" msgstr "" @@ -4185,7 +4201,7 @@ msgstr "" msgid "It's just you right now! Add more people to your starter pack by searching above." msgstr "" -#: src/view/com/composer/Composer.tsx:1612 +#: src/view/com/composer/Composer.tsx:1667 msgid "Job ID: {0}" msgstr "" @@ -4423,12 +4439,15 @@ msgstr "" msgid "Likes" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:232 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:454 +#: src/view/com/post-thread/PostThreadItem.tsx:242 msgid "Likes on this post" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:629 -#: src/view/com/post-thread/PostThread.tsx:634 +#: src/screens/PostThread/components/HeaderDropdown.tsx:47 +#: src/screens/PostThread/components/HeaderDropdown.tsx:52 +#: src/view/com/post-thread/PostThread.tsx:653 +#: src/view/com/post-thread/PostThread.tsx:658 msgid "Linear" msgstr "" @@ -4766,7 +4785,7 @@ msgstr "" msgid "Moderator has chosen to set a general warning on the content." msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:721 +#: src/view/com/post-thread/PostThreadItem.tsx:732 msgid "More" msgstr "" @@ -4781,13 +4800,13 @@ msgstr "" msgid "More options" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:94 +#: src/screens/Settings/ThreadPreferences.tsx:228 msgid "Most-liked first" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:91 -#: src/view/com/post-thread/PostThread.tsx:685 -#: src/view/com/post-thread/PostThread.tsx:690 +#: src/screens/Settings/ThreadPreferences.tsx:225 +#: src/view/com/post-thread/PostThread.tsx:709 +#: src/view/com/post-thread/PostThread.tsx:714 msgid "Most-liked replies first" msgstr "" @@ -5046,10 +5065,14 @@ msgstr "" msgid "New User List" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:83 -#: src/screens/Settings/ThreadPreferences.tsx:86 -#: src/view/com/post-thread/PostThread.tsx:675 -#: src/view/com/post-thread/PostThread.tsx:680 +#: src/screens/PostThread/components/HeaderDropdown.tsx:93 +#: src/screens/PostThread/components/HeaderDropdown.tsx:98 +#: src/screens/Settings/ThreadPreferences.tsx:96 +#: src/screens/Settings/ThreadPreferences.tsx:99 +#: src/screens/Settings/ThreadPreferences.tsx:217 +#: src/screens/Settings/ThreadPreferences.tsx:220 +#: src/view/com/post-thread/PostThread.tsx:699 +#: src/view/com/post-thread/PostThread.tsx:704 msgid "Newest replies first" msgstr "" @@ -5263,7 +5286,7 @@ msgstr "" #: src/Navigation.tsx:630 #: src/view/screens/Notifications.tsx:128 -#: src/view/shell/bottom-bar/BottomBar.tsx:250 +#: src/view/shell/bottom-bar/BottomBar.tsx:252 #: src/view/shell/desktop/LeftNav.tsx:654 #: src/view/shell/Drawer.tsx:482 msgid "Notifications" @@ -5309,14 +5332,19 @@ msgid "OK" msgstr "" #: src/screens/Login/PasswordUpdatedForm.tsx:37 -#: src/view/com/post-thread/PostThreadItem.tsx:975 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:657 +#: src/view/com/post-thread/PostThreadItem.tsx:986 msgid "Okay" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:75 -#: src/screens/Settings/ThreadPreferences.tsx:78 -#: src/view/com/post-thread/PostThread.tsx:665 -#: src/view/com/post-thread/PostThread.tsx:670 +#: src/screens/PostThread/components/HeaderDropdown.tsx:83 +#: src/screens/PostThread/components/HeaderDropdown.tsx:88 +#: src/screens/Settings/ThreadPreferences.tsx:88 +#: src/screens/Settings/ThreadPreferences.tsx:91 +#: src/screens/Settings/ThreadPreferences.tsx:209 +#: src/screens/Settings/ThreadPreferences.tsx:212 +#: src/view/com/post-thread/PostThread.tsx:689 +#: src/view/com/post-thread/PostThread.tsx:694 msgid "Oldest replies first" msgstr "" @@ -5328,15 +5356,15 @@ msgstr "" msgid "Onboarding reset" msgstr "" -#: src/view/com/composer/Composer.tsx:342 +#: src/view/com/composer/Composer.tsx:346 msgid "One or more GIFs is missing alt text." msgstr "" -#: src/view/com/composer/Composer.tsx:339 +#: src/view/com/composer/Composer.tsx:343 msgid "One or more images is missing alt text." msgstr "" -#: src/view/com/composer/Composer.tsx:349 +#: src/view/com/composer/Composer.tsx:353 msgid "One or more videos is missing alt text." msgstr "" @@ -5392,7 +5420,7 @@ msgid "Open drawer menu" msgstr "" #: src/screens/Messages/components/MessageInput.web.tsx:181 -#: src/view/com/composer/Composer.tsx:1272 +#: src/view/com/composer/Composer.tsx:1315 msgid "Open emoji picker" msgstr "" @@ -5487,7 +5515,7 @@ msgstr "" msgid "Opens change handle dialog" msgstr "" -#: src/view/com/post-thread/PostThreadComposePrompt.tsx:35 +#: src/view/com/post-thread/PostThreadComposePrompt.tsx:68 msgid "Opens composer" msgstr "" @@ -5495,7 +5523,7 @@ msgstr "" msgid "Opens device photo gallery" msgstr "" -#: src/view/com/composer/Composer.tsx:1273 +#: src/view/com/composer/Composer.tsx:1316 msgid "Opens emoji picker" msgstr "" @@ -5702,7 +5730,7 @@ msgstr "" msgid "Pin to your profile" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:407 +#: src/view/com/posts/PostFeedItem.tsx:409 msgid "Pinned" msgstr "" @@ -5877,22 +5905,27 @@ msgstr "" msgid "Porn" msgstr "" -#: src/view/com/composer/Composer.tsx:987 +#: src/view/com/composer/Composer.tsx:1030 msgctxt "action" msgid "Post" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:540 +#: src/screens/PostThread/index.tsx:490 +#: src/view/com/post-thread/PostThread.tsx:561 msgctxt "description" msgid "Post" msgstr "" -#: src/view/com/composer/Composer.tsx:985 +#: src/view/com/composer/Composer.tsx:1028 msgctxt "action" msgid "Post All" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:224 +#: src/screens/PostThread/components/ThreadItemPostTombstone.tsx:22 +msgid "Post blocked" +msgstr "" + +#: src/view/com/post-thread/PostThreadItem.tsx:234 msgid "Post by {0}" msgstr "" @@ -5912,11 +5945,14 @@ msgstr "" msgid "Post failed to upload. Please check your Internet connection and try again." msgstr "" +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:133 +#: src/screens/PostThread/components/ThreadItemPost.tsx:112 +#: src/screens/PostThread/components/ThreadItemTreePost.tsx:109 #: src/screens/VideoFeed/index.tsx:529 msgid "Post has been deleted" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:269 +#: src/view/com/post-thread/PostThread.tsx:271 msgid "Post hidden" msgstr "" @@ -5947,8 +5983,10 @@ msgstr "" msgid "Post Languages" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:264 -#: src/view/com/post-thread/PostThread.tsx:276 +#: src/screens/PostThread/components/ThreadError.tsx:32 +#: src/screens/PostThread/components/ThreadItemPostTombstone.tsx:25 +#: src/view/com/post-thread/PostThread.tsx:266 +#: src/view/com/post-thread/PostThread.tsx:278 msgid "Post not found" msgstr "" @@ -6008,8 +6046,10 @@ msgstr "" msgid "Primary Language" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:112 -#: src/screens/Settings/ThreadPreferences.tsx:117 +#: src/screens/Settings/ThreadPreferences.tsx:110 +#: src/screens/Settings/ThreadPreferences.tsx:115 +#: src/screens/Settings/ThreadPreferences.tsx:246 +#: src/screens/Settings/ThreadPreferences.tsx:251 msgid "Prioritize your Follows" msgstr "" @@ -6041,7 +6081,7 @@ msgstr "" msgid "Privacy Policy" msgstr "" -#: src/view/com/composer/Composer.tsx:1675 +#: src/view/com/composer/Composer.tsx:1730 msgid "Processing video..." msgstr "" @@ -6055,7 +6095,7 @@ msgstr "" msgid "profile" msgstr "" -#: src/view/shell/bottom-bar/BottomBar.tsx:314 +#: src/view/shell/bottom-bar/BottomBar.tsx:316 #: src/view/shell/desktop/LeftNav.tsx:709 #: src/view/shell/Drawer.tsx:76 #: src/view/shell/Drawer.tsx:559 @@ -6081,22 +6121,22 @@ msgid "Public, sharable lists which can be used to drive feeds." msgstr "" #. Accessibility label for button to publish a single post -#: src/view/com/composer/Composer.tsx:967 +#: src/view/com/composer/Composer.tsx:1010 msgid "Publish post" msgstr "" #. Accessibility label for button to publish multiple posts in a thread -#: src/view/com/composer/Composer.tsx:960 +#: src/view/com/composer/Composer.tsx:1003 msgid "Publish posts" msgstr "" #. Accessibility label for button to publish multiple replies in a thread -#: src/view/com/composer/Composer.tsx:945 +#: src/view/com/composer/Composer.tsx:988 msgid "Publish replies" msgstr "" #. Accessibility label for button to publish a single reply -#: src/view/com/composer/Composer.tsx:952 +#: src/view/com/composer/Composer.tsx:995 msgid "Publish reply" msgstr "" @@ -6142,14 +6182,15 @@ msgstr "" msgid "Quotes" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:258 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:438 +#: src/view/com/post-thread/PostThreadItem.tsx:268 msgid "Quotes of this post" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:99 -#: src/screens/Settings/ThreadPreferences.tsx:102 -#: src/view/com/post-thread/PostThread.tsx:695 -#: src/view/com/post-thread/PostThread.tsx:700 +#: src/screens/Settings/ThreadPreferences.tsx:233 +#: src/screens/Settings/ThreadPreferences.tsx:236 +#: src/view/com/post-thread/PostThread.tsx:719 +#: src/view/com/post-thread/PostThread.tsx:724 msgid "Random (aka \"Poster's Roulette\")" msgstr "" @@ -6170,19 +6211,27 @@ msgstr "" msgid "Reactivate your account" msgstr "" +#: src/screens/PostThread/components/ThreadItemReadMore.tsx:92 +msgid "Read {0} more {1, plural, one {reply} other {replies}}" +msgstr "" + #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:158 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:173 msgid "Read blog post" msgstr "" -#: src/screens/VideoFeed/index.tsx:963 +#: src/screens/VideoFeed/index.tsx:966 msgid "Read less" msgstr "" -#: src/screens/VideoFeed/index.tsx:963 +#: src/screens/VideoFeed/index.tsx:966 msgid "Read more" msgstr "" +#: src/screens/PostThread/components/ThreadItemReadMore.tsx:71 +msgid "Read more replies" +msgstr "" + #: src/view/com/auth/SplashScreen.web.tsx:173 msgid "Read the Bluesky blog" msgstr "" @@ -6409,7 +6458,7 @@ msgstr "" msgid "Replies to this post are disabled." msgstr "" -#: src/view/com/composer/Composer.tsx:983 +#: src/view/com/composer/Composer.tsx:1026 msgctxt "action" msgid "Reply" msgstr "" @@ -6437,28 +6486,29 @@ msgstr "" msgid "Reply settings are chosen by the author of the thread" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:651 +#: src/screens/PostThread/components/HeaderDropdown.tsx:69 +#: src/view/com/post-thread/PostThread.tsx:675 msgid "Reply sorting" msgstr "" #: src/view/com/post/Post.tsx:205 -#: src/view/com/posts/PostFeedItem.tsx:605 +#: src/view/com/posts/PostFeedItem.tsx:607 msgctxt "description" msgid "Reply to <0><1/>" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:596 +#: src/view/com/posts/PostFeedItem.tsx:598 msgctxt "description" msgid "Reply to a blocked post" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:598 +#: src/view/com/posts/PostFeedItem.tsx:600 msgctxt "description" msgid "Reply to a post" msgstr "" #: src/view/com/post/Post.tsx:203 -#: src/view/com/posts/PostFeedItem.tsx:602 +#: src/view/com/posts/PostFeedItem.tsx:604 msgctxt "description" msgid "Reply to you" msgstr "" @@ -6587,20 +6637,21 @@ msgstr "" msgid "Reposted By" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:347 +#: src/view/com/posts/PostFeedItem.tsx:349 msgid "Reposted by {0}" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:366 +#: src/view/com/posts/PostFeedItem.tsx:368 msgid "Reposted by <0><1/>" msgstr "" -#: src/view/com/posts/PostFeedItem.tsx:345 -#: src/view/com/posts/PostFeedItem.tsx:364 +#: src/view/com/posts/PostFeedItem.tsx:347 +#: src/view/com/posts/PostFeedItem.tsx:366 msgid "Reposted by you" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:237 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:420 +#: src/view/com/post-thread/PostThreadItem.tsx:247 msgid "Reposts of this post" msgstr "" @@ -6691,6 +6742,8 @@ msgstr "" #: src/screens/Messages/Inbox.tsx:197 #: src/screens/Onboarding/StepInterests/index.tsx:217 #: src/screens/Onboarding/StepInterests/index.tsx:220 +#: src/screens/PostThread/components/ThreadError.tsx:75 +#: src/screens/PostThread/components/ThreadError.tsx:81 #: src/screens/Signup/BackNextButtons.tsx:53 #: src/view/com/util/error/ErrorMessage.tsx:60 #: src/view/com/util/error/ErrorScreen.tsx:97 @@ -6715,7 +6768,7 @@ msgstr "" #: src/screens/Profile/ProfileFeed/index.tsx:93 #: src/screens/Settings/components/ChangeHandleDialog.tsx:559 -#: src/screens/VideoFeed/index.tsx:1139 +#: src/screens/VideoFeed/index.tsx:1142 #: src/view/screens/NotFound.tsx:60 #: src/view/screens/ProfileList.tsx:1039 msgid "Returns to previous page" @@ -6820,12 +6873,12 @@ msgstr "" msgid "Scroll to top" msgstr "" -#: src/components/dialogs/SearchablePeopleList.tsx:513 +#: src/components/dialogs/SearchablePeopleList.tsx:514 #: src/components/forms/SearchInput.tsx:34 #: src/components/forms/SearchInput.tsx:36 #: src/screens/Search/Shell.tsx:307 #: src/screens/Search/Shell.tsx:464 -#: src/view/shell/bottom-bar/BottomBar.tsx:196 +#: src/view/shell/bottom-bar/BottomBar.tsx:198 msgid "Search" msgstr "" @@ -6884,7 +6937,7 @@ msgstr "" msgid "Search posts" msgstr "" -#: src/components/dialogs/SearchablePeopleList.tsx:533 +#: src/components/dialogs/SearchablePeopleList.tsx:534 #: src/components/ProgressGuide/FollowDialog.tsx:702 msgid "Search profiles" msgstr "" @@ -6897,7 +6950,7 @@ msgstr "" msgid "Search..." msgstr "" -#: src/components/dialogs/SearchablePeopleList.tsx:534 +#: src/components/dialogs/SearchablePeopleList.tsx:535 #: src/components/ProgressGuide/FollowDialog.tsx:703 msgid "Searches for profiles" msgstr "" @@ -7304,9 +7357,11 @@ msgstr "" msgid "Show list anyway" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:681 +#: src/screens/PostThread/components/ThreadItemPost.tsx:318 +#: src/screens/PostThread/components/ThreadItemTreePost.tsx:364 +#: src/view/com/post-thread/PostThreadItem.tsx:692 #: src/view/com/post/Post.tsx:244 -#: src/view/com/posts/PostFeedItem.tsx:561 +#: src/view/com/posts/PostFeedItem.tsx:563 msgid "Show More" msgstr "" @@ -7315,10 +7370,18 @@ msgstr "" msgid "Show more like this" msgstr "" +#: src/screens/PostThread/components/ThreadItemShowOtherReplies.tsx:14 +msgid "Show more replies" +msgstr "" + #: src/view/com/post-thread/PostThreadShowHiddenReplies.tsx:22 msgid "Show muted replies" msgstr "" +#: src/screens/Settings/ThreadPreferences.tsx:143 +msgid "Show post replies in a threaded tree view" +msgstr "" + #: src/screens/Settings/FollowingFeedPreferences.tsx:104 #: src/screens/Settings/FollowingFeedPreferences.tsx:114 msgid "Show quote posts" @@ -7329,15 +7392,17 @@ msgstr "" msgid "Show replies" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:625 +#: src/screens/PostThread/components/HeaderDropdown.tsx:43 +#: src/view/com/post-thread/PostThread.tsx:649 msgid "Show replies as" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:151 +#: src/screens/Settings/ThreadPreferences.tsx:285 msgid "Show replies as threaded" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:126 +#: src/screens/Settings/ThreadPreferences.tsx:120 +#: src/screens/Settings/ThreadPreferences.tsx:260 msgid "Show replies by people you follow before all other replies" msgstr "" @@ -7364,7 +7429,8 @@ msgstr "" msgid "Show warning and filter from feeds" msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:916 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:598 +#: src/view/com/post-thread/PostThreadItem.tsx:927 msgid "Shows information about when this post was created" msgstr "" @@ -7386,10 +7452,10 @@ msgstr "" #: src/view/com/auth/SplashScreen.tsx:69 #: src/view/com/auth/SplashScreen.web.tsx:123 #: src/view/com/auth/SplashScreen.web.tsx:131 -#: src/view/shell/bottom-bar/BottomBar.tsx:353 -#: src/view/shell/bottom-bar/BottomBar.tsx:358 -#: src/view/shell/bottom-bar/BottomBarWeb.tsx:209 -#: src/view/shell/bottom-bar/BottomBarWeb.tsx:214 +#: src/view/shell/bottom-bar/BottomBar.tsx:355 +#: src/view/shell/bottom-bar/BottomBar.tsx:360 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:216 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:221 #: src/view/shell/NavSignupCard.tsx:57 #: src/view/shell/NavSignupCard.tsx:62 msgid "Sign in" @@ -7528,6 +7594,10 @@ msgstr "" msgid "Something went wrong!" msgstr "" +#: src/screens/PostThread/components/ThreadError.tsx:27 +msgid "Something went wrong. Please try again in a moment." +msgstr "" + #: src/components/moderation/ReportDialog/index.tsx:178 msgid "Something went wrong. Please try again." msgstr "" @@ -7541,15 +7611,18 @@ msgstr "" msgid "Sorry! Your session expired. Please sign in again." msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:55 +#: src/screens/Settings/ThreadPreferences.tsx:68 +#: src/screens/Settings/ThreadPreferences.tsx:189 msgid "Sort replies" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:62 +#: src/screens/Settings/ThreadPreferences.tsx:75 +#: src/screens/Settings/ThreadPreferences.tsx:196 msgid "Sort replies by" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:59 +#: src/screens/Settings/ThreadPreferences.tsx:72 +#: src/screens/Settings/ThreadPreferences.tsx:193 msgid "Sort replies to the same post by:" msgstr "" @@ -7878,7 +7951,7 @@ msgstr "" msgid "That's all, folks!" msgstr "" -#: src/screens/VideoFeed/index.tsx:1111 +#: src/screens/VideoFeed/index.tsx:1114 msgid "That's everything!" msgstr "" @@ -7941,8 +8014,8 @@ msgstr "" msgid "The following settings will be used as your defaults when creating new posts. You can edit these for a specific post from the composer." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:265 -#: src/view/com/post-thread/PostThread.tsx:277 +#: src/view/com/post-thread/PostThread.tsx:267 +#: src/view/com/post-thread/PostThread.tsx:279 msgid "The post may have been deleted." msgstr "" @@ -8230,7 +8303,8 @@ msgstr "" msgid "This moderation service is unavailable. See below for more details. If this issue persists, contact us." msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:956 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:638 +#: src/view/com/post-thread/PostThreadItem.tsx:967 msgid "This post claims to have been created on <0>{0}, but was first seen by Bluesky on <1>{1}." msgstr "" @@ -8238,7 +8312,7 @@ msgstr "" msgid "This post has an unknown type of threadgate on it. Your app may be out of date." msgstr "" -#: src/view/com/post-thread/PostThreadItem.tsx:163 +#: src/view/com/post-thread/PostThreadItem.tsx:170 msgid "This post has been deleted." msgstr "" @@ -8250,7 +8324,7 @@ msgstr "" msgid "This post will be hidden from feeds and threads. This cannot be undone." msgstr "" -#: src/view/com/composer/Composer.tsx:424 +#: src/view/com/composer/Composer.tsx:462 msgid "This post's author has disabled quote posts." msgstr "" @@ -8319,8 +8393,10 @@ msgstr "" msgid "This will remove your post from this quote post for all users, and replace it with a placeholder." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:609 -#: src/view/com/post-thread/PostThread.tsx:612 +#: src/screens/PostThread/components/HeaderDropdown.tsx:23 +#: src/screens/PostThread/components/HeaderDropdown.tsx:26 +#: src/view/com/post-thread/PostThread.tsx:633 +#: src/view/com/post-thread/PostThread.tsx:636 msgid "Thread options" msgstr "" @@ -8329,16 +8405,19 @@ msgstr "" msgid "Thread preferences" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:45 +#: src/screens/Settings/ThreadPreferences.tsx:58 +#: src/screens/Settings/ThreadPreferences.tsx:179 msgid "Thread Preferences" msgstr "" -#: src/view/com/post-thread/PostThread.tsx:639 -#: src/view/com/post-thread/PostThread.tsx:644 +#: src/screens/PostThread/components/HeaderDropdown.tsx:57 +#: src/screens/PostThread/components/HeaderDropdown.tsx:62 +#: src/view/com/post-thread/PostThread.tsx:663 +#: src/view/com/post-thread/PostThread.tsx:668 msgid "Threaded" msgstr "" -#: src/screens/Settings/ThreadPreferences.tsx:142 +#: src/screens/Settings/ThreadPreferences.tsx:276 msgid "Threaded mode" msgstr "" @@ -8389,6 +8468,13 @@ msgstr "" msgid "Top" msgstr "" +#: src/screens/PostThread/components/HeaderDropdown.tsx:73 +#: src/screens/PostThread/components/HeaderDropdown.tsx:78 +#: src/screens/Settings/ThreadPreferences.tsx:80 +#: src/screens/Settings/ThreadPreferences.tsx:83 +msgid "Top replies first" +msgstr "" + #: src/Navigation.tsx:423 msgid "Topic" msgstr "" @@ -8397,11 +8483,18 @@ msgstr "" #: src/components/dms/MessageContextMenu.tsx:145 #: src/components/PostControls/PostMenu/PostMenuItems.tsx:444 #: src/components/PostControls/PostMenu/PostMenuItems.tsx:446 -#: src/view/com/post-thread/PostThreadItem.tsx:878 -#: src/view/com/post-thread/PostThreadItem.tsx:881 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:560 +#: src/screens/PostThread/components/ThreadItemAnchor.tsx:563 +#: src/view/com/post-thread/PostThreadItem.tsx:889 +#: src/view/com/post-thread/PostThreadItem.tsx:892 msgid "Translate" msgstr "" +#: src/screens/Settings/ThreadPreferences.tsx:131 +#: src/screens/Settings/ThreadPreferences.tsx:136 +msgid "Tree view" +msgstr "" + #: src/view/shell/desktop/SidebarTrendingTopics.tsx:59 msgid "Trending" msgstr "" @@ -8631,7 +8724,7 @@ msgstr "" msgid "Unsubscribed from list" msgstr "" -#: src/view/com/composer/Composer.tsx:769 +#: src/view/com/composer/Composer.tsx:810 msgid "Unsupported video type" msgstr "" @@ -8721,7 +8814,7 @@ msgstr "" msgid "Uploading link thumbnail..." msgstr "" -#: src/view/com/composer/Composer.tsx:1672 +#: src/view/com/composer/Composer.tsx:1727 msgid "Uploading video..." msgstr "" @@ -8937,11 +9030,11 @@ msgstr "" msgid "Video Games" msgstr "" -#: src/screens/VideoFeed/index.tsx:1069 +#: src/screens/VideoFeed/index.tsx:1072 msgid "Video is paused" msgstr "" -#: src/screens/VideoFeed/index.tsx:1069 +#: src/screens/VideoFeed/index.tsx:1072 msgid "Video is playing" msgstr "" @@ -8953,7 +9046,7 @@ msgstr "" msgid "Video settings" msgstr "" -#: src/view/com/composer/Composer.tsx:1682 +#: src/view/com/composer/Composer.tsx:1737 msgid "Video uploaded" msgstr "" @@ -9062,7 +9155,7 @@ msgid "View your default post interaction settings" msgstr "" #: src/view/com/home/HomeHeaderLayout.web.tsx:56 -#: src/view/com/home/HomeHeaderLayoutMobile.tsx:77 +#: src/view/com/home/HomeHeaderLayoutMobile.tsx:71 msgid "View your feeds and explore more" msgstr "" @@ -9204,7 +9297,7 @@ msgstr "" msgid "We're sorry, but your search could not be completed. Please try again in a few minutes." msgstr "" -#: src/view/com/composer/Composer.tsx:421 +#: src/view/com/composer/Composer.tsx:459 msgid "We're sorry! The post you are replying to has been deleted." msgstr "" @@ -9235,7 +9328,7 @@ msgstr "" #: src/view/com/auth/SplashScreen.tsx:38 #: src/view/com/auth/SplashScreen.web.tsx:99 -#: src/view/com/composer/Composer.tsx:732 +#: src/view/com/composer/Composer.tsx:773 msgid "What's up?" msgstr "" @@ -9317,12 +9410,12 @@ msgstr "" msgid "Write a message" msgstr "" -#: src/view/com/composer/Composer.tsx:823 +#: src/view/com/composer/Composer.tsx:866 msgid "Write post" msgstr "" -#: src/view/com/composer/Composer.tsx:730 -#: src/view/com/post-thread/PostThreadComposePrompt.tsx:69 +#: src/view/com/composer/Composer.tsx:771 +#: src/view/com/post-thread/PostThreadComposePrompt.tsx:95 msgid "Write your reply" msgstr "" @@ -9483,7 +9576,7 @@ msgstr "" msgid "You don't have any saved feeds." msgstr "" -#: src/view/com/post-thread/PostThread.tsx:271 +#: src/view/com/post-thread/PostThread.tsx:273 msgid "You have blocked the author or you have been blocked by the author." msgstr "" @@ -9603,6 +9696,11 @@ msgstr "" msgid "You must select at least one labeler for a report" msgstr "" +#: src/screens/PostThread/components/ThreadItemAnchorNoUnauthenticated.tsx:27 +#: src/screens/PostThread/components/ThreadItemPostNoUnauthenticated.tsx:47 +msgid "You must sign in to view this post." +msgstr "" + #: src/components/dialogs/EmailDialog/screens/Manage2FA/index.tsx:23 msgid "You need to verify your email address before you can enable email 2FA." msgstr "" @@ -9714,7 +9812,7 @@ msgstr "" msgid "You've reached your daily limit for video uploads (too many videos)" msgstr "" -#: src/screens/VideoFeed/index.tsx:1120 +#: src/screens/VideoFeed/index.tsx:1123 msgid "You've run out of videos to watch. Maybe it's a good time to take a break?" msgstr "" @@ -9834,11 +9932,11 @@ msgstr "" msgid "Your password must be at least 8 characters long." msgstr "" -#: src/view/com/composer/Composer.tsx:481 +#: src/view/com/composer/Composer.tsx:521 msgid "Your post has been published" msgstr "" -#: src/view/com/composer/Composer.tsx:478 +#: src/view/com/composer/Composer.tsx:518 msgid "Your posts have been published" msgstr "" @@ -9850,7 +9948,7 @@ msgstr "" msgid "Your profile, posts, feeds, and lists will no longer be visible to other Bluesky users. You can reactivate your account at any time by logging in." msgstr "" -#: src/view/com/composer/Composer.tsx:480 +#: src/view/com/composer/Composer.tsx:520 msgid "Your reply has been published" msgstr "" diff --git a/src/screens/Profile/Header/Shell.tsx b/src/screens/Profile/Header/Shell.tsx index 9777c8cc78..53585c0947 100644 --- a/src/screens/Profile/Header/Shell.tsx +++ b/src/screens/Profile/Header/Shell.tsx @@ -1,9 +1,11 @@ -import React, {memo, useEffect} from 'react' +import {memo, useCallback, useEffect, useMemo} from 'react' import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' -import { +import Animated, { + measure, type MeasuredDimensions, runOnJS, runOnUI, + useAnimatedRef, } from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {type AppBskyActorDefs, type ModerationDecision} from '@atproto/api' @@ -14,7 +16,6 @@ import {useNavigation} from '@react-navigation/native' import {useActorStatus} from '#/lib/actor-status' import {BACK_HITSLOP} from '#/lib/constants' import {useHaptics} from '#/lib/haptics' -import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef' import {type NavigationProp} from '#/lib/routes/types' import {logger} from '#/logger' import {isIOS} from '#/platform/detection' @@ -59,9 +60,9 @@ let ProfileHeaderShell = ({ const playHaptic = useHaptics() const liveStatusControl = useDialogControl() - const aviRef = useHandleRef() + const aviRef = useAnimatedRef() - const onPressBack = React.useCallback(() => { + const onPressBack = useCallback(() => { if (navigation.canGoBack()) { navigation.goBack() } else { @@ -69,7 +70,7 @@ let ProfileHeaderShell = ({ } }, [navigation]) - const _openLightbox = React.useCallback( + const _openLightbox = useCallback( (uri: string, thumbRect: MeasuredDimensions | null) => { openLightbox({ images: [ @@ -92,7 +93,7 @@ let ProfileHeaderShell = ({ [openLightbox], ) - const isMe = React.useMemo( + const isMe = useMemo( () => currentAccount?.did === profile.did, [currentAccount, profile], ) @@ -109,7 +110,7 @@ let ProfileHeaderShell = ({ } }, [live.isActive, profile.did]) - const onPressAvi = React.useCallback(() => { + const onPressAvi = useCallback(() => { if (live.isActive) { playHaptic('Light') logger.metric( @@ -122,10 +123,9 @@ let ProfileHeaderShell = ({ const modui = moderation.ui('avatar') const avatar = profile.avatar if (avatar && !(modui.blur && modui.noOverride)) { - const aviHandle = aviRef.current runOnUI(() => { 'worklet' - const rect = measureHandle(aviHandle) + const rect = measure(aviRef) runOnJS(_openLightbox)(avatar, rect) })() } @@ -223,7 +223,7 @@ let ProfileHeaderShell = ({ styles.avi, profile.associated?.labeler && styles.aviLabeler, ]}> - + {live.isActive && } - + diff --git a/src/state/unstable-post-source.tsx b/src/state/unstable-post-source.tsx index ac126d79c6..450f2c120b 100644 --- a/src/state/unstable-post-source.tsx +++ b/src/state/unstable-post-source.tsx @@ -34,7 +34,7 @@ const consumedSources = new Map() * Used for FeedFeedback and other ephemeral non-critical systems. */ export function setUnstablePostSource(key: string, source: PostSource) { - assertValid( + assertValidDevOnly( key, `setUnstablePostSource key should be a URI containing a handle, received ${key} — use buildPostSourceKey`, ) @@ -51,9 +51,10 @@ export function setUnstablePostSource(key: string, source: PostSource) { export function useUnstablePostSource(key: string) { const id = useId() const [source] = useState(() => { - assertValid( + assertValidDevOnly( key, - `consumeUnstablePostSource key should be a URI containing a handle, received ${key} — use buildPostSourceKey`, + `consumeUnstablePostSource key should be a URI containing a handle, received ${key} — be sure to use buildPostSourceKey when setting the source`, + true, ) const source = consumedSources.get(id) || transientSources.get(key) if (source) { @@ -87,11 +88,15 @@ export function buildPostSourceKey(key: string, handle: string) { /** * Just a lil dev helper */ -function assertValid(key: string, message: string) { +function assertValidDevOnly(key: string, message: string, beChill = false) { if (__DEV__) { const urip = new AtUri(key) if (urip.host.startsWith('did:')) { - throw new Error(message) + if (beChill) { + logger.warn(message) + } else { + throw new Error(message) + } } } } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index da40235280..de060c6c22 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -64,6 +64,7 @@ import { type SupportedMimeTypes, } from '#/lib/constants' import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' +import {useAppState} from '#/lib/hooks/useAppState' import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {usePalette} from '#/lib/hooks/usePalette' @@ -823,6 +824,8 @@ let ComposerPost = React.memo(function ComposerPost({ [post.id, onSelectVideo, onImageAdd, _], ) + useHideKeyboardOnBackground() + return ( { + if (isIOS) { + if (appState === 'inactive') { + Keyboard.dismiss() + } + } + }, [appState]) +} + const styles = StyleSheet.create({ topbarInner: { flexDirection: 'row', diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx index c3e735e3e5..f927015af9 100644 --- a/src/view/com/composer/text-input/TextInput.tsx +++ b/src/view/com/composer/text-input/TextInput.tsx @@ -16,7 +16,7 @@ import { import {AppBskyRichtextFacet, RichText} from '@atproto/api' import PasteInput, { type PastedFile, - type PasteInputRef, + type PasteInputRef, // @ts-expect-error no types when installing from github } from '@mattermost/react-native-paste-input' import {POST_IMG_MAX} from '#/lib/constants' diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx index f62bffc534..8cc3469032 100644 --- a/src/view/com/pager/Pager.tsx +++ b/src/view/com/pager/Pager.tsx @@ -1,16 +1,22 @@ -import React, {forwardRef, useCallback, useContext} from 'react' +import { + useCallback, + useContext, + useImperativeHandle, + useRef, + useState, +} from 'react' import {View} from 'react-native' import {DrawerGestureContext} from 'react-native-drawer-layout' import {Gesture, GestureDetector} from 'react-native-gesture-handler' import PagerView, { - PagerViewOnPageScrollEventData, - PagerViewOnPageSelectedEvent, - PagerViewOnPageSelectedEventData, - PageScrollStateChangedNativeEventData, + type PagerViewOnPageScrollEventData, + type PagerViewOnPageSelectedEvent, + type PagerViewOnPageSelectedEventData, + type PageScrollStateChangedNativeEventData, } from 'react-native-pager-view' import Animated, { runOnJS, - SharedValue, + type SharedValue, useEvent, useHandler, useSharedValue, @@ -36,8 +42,12 @@ export interface RenderTabBarFnProps { export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element interface Props { + ref?: React.Ref initialPage?: number renderTabBar: RenderTabBarFn + // tab pressed, yet to scroll to page + onTabPressed?: (index: number) => void + // scroll settled onPageSelected?: (index: number) => void onPageScrollStateChanged?: ( scrollState: 'idle' | 'dragging' | 'settling', @@ -47,114 +57,112 @@ interface Props { const AnimatedPagerView = Animated.createAnimatedComponent(PagerView) -export const Pager = forwardRef>( - function PagerImpl( +export function Pager({ + ref, + children, + initialPage = 0, + renderTabBar, + onPageSelected: parentOnPageSelected, + onTabPressed: parentOnTabPressed, + onPageScrollStateChanged: parentOnPageScrollStateChanged, + testID, +}: React.PropsWithChildren) { + const [selectedPage, setSelectedPage] = useState(initialPage) + const pagerView = useRef(null) + + const [isIdle, setIsIdle] = useState(true) + const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled() + useFocusEffect( + useCallback(() => { + const canSwipeDrawer = selectedPage === 0 && isIdle + setDrawerSwipeDisabled(!canSwipeDrawer) + return () => { + setDrawerSwipeDisabled(false) + } + }, [setDrawerSwipeDisabled, selectedPage, isIdle]), + ) + + useImperativeHandle(ref, () => ({ + setPage: (index: number) => { + pagerView.current?.setPage(index) + }, + })) + + const onPageSelectedJSThread = useCallback( + (nextPosition: number) => { + setSelectedPage(nextPosition) + parentOnPageSelected?.(nextPosition) + }, + [setSelectedPage, parentOnPageSelected], + ) + + const onTabBarSelect = useCallback( + (index: number) => { + parentOnTabPressed?.(index) + pagerView.current?.setPage(index) + }, + [pagerView, parentOnTabPressed], + ) + + const dragState = useSharedValue<'idle' | 'settling' | 'dragging'>('idle') + const dragProgress = useSharedValue(selectedPage) + const didInit = useSharedValue(false) + const handlePageScroll = usePagerHandlers( { - children, - initialPage = 0, - renderTabBar, - onPageScrollStateChanged: parentOnPageScrollStateChanged, - onPageSelected: parentOnPageSelected, - testID, - }: React.PropsWithChildren, - ref, - ) { - const [selectedPage, setSelectedPage] = React.useState(initialPage) - const pagerView = React.useRef(null) - - const [isIdle, setIsIdle] = React.useState(true) - const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled() - useFocusEffect( - useCallback(() => { - const canSwipeDrawer = selectedPage === 0 && isIdle - setDrawerSwipeDisabled(!canSwipeDrawer) - return () => { - setDrawerSwipeDisabled(false) + onPageScroll(e: PagerViewOnPageScrollEventData) { + 'worklet' + if (didInit.get() === false) { + // On iOS, there's a spurious scroll event with 0 position + // even if a different page was supplied as the initial page. + // Ignore it and wait for the first confirmed selection instead. + return } - }, [setDrawerSwipeDisabled, selectedPage, isIdle]), - ) - - React.useImperativeHandle(ref, () => ({ - setPage: (index: number) => { - pagerView.current?.setPage(index) + dragProgress.set(e.offset + e.position) }, - })) - - const onPageSelectedJSThread = React.useCallback( - (nextPosition: number) => { - setSelectedPage(nextPosition) - parentOnPageSelected?.(nextPosition) + onPageScrollStateChanged(e: PageScrollStateChangedNativeEventData) { + 'worklet' + runOnJS(setIsIdle)(e.pageScrollState === 'idle') + if (dragState.get() === 'idle' && e.pageScrollState === 'settling') { + // This is a programmatic scroll on Android. + // Stay "idle" to match iOS and avoid confusing downstream code. + return + } + dragState.set(e.pageScrollState) + parentOnPageScrollStateChanged?.(e.pageScrollState) }, - [setSelectedPage, parentOnPageSelected], - ) - - const onTabBarSelect = React.useCallback( - (index: number) => { - pagerView.current?.setPage(index) + onPageSelected(e: PagerViewOnPageSelectedEventData) { + 'worklet' + didInit.set(true) + runOnJS(onPageSelectedJSThread)(e.position) }, - [pagerView], - ) + }, + [parentOnPageScrollStateChanged], + ) - const dragState = useSharedValue<'idle' | 'settling' | 'dragging'>('idle') - const dragProgress = useSharedValue(selectedPage) - const didInit = useSharedValue(false) - const handlePageScroll = usePagerHandlers( - { - onPageScroll(e: PagerViewOnPageScrollEventData) { - 'worklet' - if (didInit.get() === false) { - // On iOS, there's a spurious scroll event with 0 position - // even if a different page was supplied as the initial page. - // Ignore it and wait for the first confirmed selection instead. - return - } - dragProgress.set(e.offset + e.position) - }, - onPageScrollStateChanged(e: PageScrollStateChangedNativeEventData) { - 'worklet' - runOnJS(setIsIdle)(e.pageScrollState === 'idle') - if (dragState.get() === 'idle' && e.pageScrollState === 'settling') { - // This is a programmatic scroll on Android. - // Stay "idle" to match iOS and avoid confusing downstream code. - return - } - dragState.set(e.pageScrollState) - parentOnPageScrollStateChanged?.(e.pageScrollState) - }, - onPageSelected(e: PagerViewOnPageSelectedEventData) { - 'worklet' - didInit.set(true) - runOnJS(onPageSelectedJSThread)(e.position) - }, - }, - [parentOnPageScrollStateChanged], - ) + const drawerGesture = useContext(DrawerGestureContext) ?? Gesture.Native() // noop for web + const nativeGesture = + Gesture.Native().requireExternalGestureToFail(drawerGesture) - const drawerGesture = useContext(DrawerGestureContext) ?? Gesture.Native() // noop for web - const nativeGesture = - Gesture.Native().requireExternalGestureToFail(drawerGesture) - - return ( - - {renderTabBar({ - selectedPage, - onSelect: onTabBarSelect, - dragProgress, - dragState, - })} - - - {children} - - - - ) - }, -) + return ( + + {renderTabBar({ + selectedPage, + onSelect: onTabBarSelect, + dragProgress, + dragState, + })} + + + {children} + + + + ) +} function usePagerHandlers( handlers: { diff --git a/src/view/com/pager/Pager.web.tsx b/src/view/com/pager/Pager.web.tsx index c620e73e33..06aac169c8 100644 --- a/src/view/com/pager/Pager.web.tsx +++ b/src/view/com/pager/Pager.web.tsx @@ -1,8 +1,19 @@ -import React from 'react' +import { + Children, + useCallback, + useImperativeHandle, + useRef, + useState, +} from 'react' import {View} from 'react-native' import {flushSync} from 'react-dom' import {s} from '#/lib/styles' +import {atoms as a} from '#/alf' + +export interface PagerRef { + setPage: (index: number) => void +} export interface RenderTabBarFnProps { selectedPage: number @@ -12,30 +23,30 @@ export interface RenderTabBarFnProps { export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element interface Props { + ref?: React.Ref initialPage?: number renderTabBar: RenderTabBarFn onPageSelected?: (index: number) => void } -export const Pager = React.forwardRef(function PagerImpl( - { - children, - initialPage = 0, - renderTabBar, - onPageSelected, - }: React.PropsWithChildren, - ref, -) { - const [selectedPage, setSelectedPage] = React.useState(initialPage) - const scrollYs = React.useRef>([]) - const anchorRef = React.useRef(null) - React.useImperativeHandle(ref, () => ({ +export function Pager({ + ref, + children, + initialPage = 0, + renderTabBar, + onPageSelected, +}: React.PropsWithChildren) { + const [selectedPage, setSelectedPage] = useState(initialPage) + const scrollYs = useRef>([]) + const anchorRef = useRef(null) + + useImperativeHandle(ref, () => ({ setPage: (index: number) => { onTabBarSelect(index) }, })) - const onTabBarSelect = React.useCallback( + const onTabBarSelect = useCallback( (index: number) => { const scrollY = window.scrollY // We want to determine if the tabbar is already "sticking" at the top (in which @@ -75,11 +86,13 @@ export const Pager = React.forwardRef(function PagerImpl( tabBarAnchor: , onSelect: e => onTabBarSelect(e), })} - {React.Children.map(children, (child, i) => ( - + {Children.map(children, (child, i) => ( + {child} ))} ) -}) +} diff --git a/src/view/com/pager/PagerWithHeader.tsx b/src/view/com/pager/PagerWithHeader.tsx index 1746d2ca13..57aaac0740 100644 --- a/src/view/com/pager/PagerWithHeader.tsx +++ b/src/view/com/pager/PagerWithHeader.tsx @@ -1,17 +1,16 @@ -import * as React from 'react' +import {memo, useCallback, useEffect, useRef, useState} from 'react' import { - LayoutChangeEvent, - NativeScrollEvent, - ScrollView, + type LayoutChangeEvent, + type NativeScrollEvent, + type ScrollView, StyleSheet, View, } from 'react-native' import Animated, { - AnimatedRef, - runOnJS, + type AnimatedRef, runOnUI, scrollTo, - SharedValue, + type SharedValue, useAnimatedRef, useAnimatedStyle, useSharedValue, @@ -20,9 +19,13 @@ import Animated, { import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {ScrollProvider} from '#/lib/ScrollContext' import {isIOS} from '#/platform/detection' -import {Pager, PagerRef, RenderTabBarFnProps} from '#/view/com/pager/Pager' +import { + Pager, + type PagerRef, + type RenderTabBarFnProps, +} from '#/view/com/pager/Pager' import {useTheme} from '#/alf' -import {ListMethods} from '../util/List' +import {type ListMethods} from '../util/List' import {PagerHeaderProvider} from './PagerHeaderContext' import {TabBar} from './TabBar' @@ -33,6 +36,7 @@ export interface PagerWithHeaderChildParams { } export interface PagerWithHeaderProps { + ref?: React.Ref testID?: string children: | (((props: PagerWithHeaderChildParams) => JSX.Element) | null)[] @@ -49,97 +53,94 @@ export interface PagerWithHeaderProps { onCurrentPageSelected?: (index: number) => void allowHeaderOverScroll?: boolean } -export const PagerWithHeader = React.forwardRef( - function PageWithHeaderImpl( - { - children, - testID, +export function PagerWithHeader({ + ref, + children, + testID, + items, + isHeaderReady, + renderHeader, + initialPage, + onPageSelected, + onCurrentPageSelected, + allowHeaderOverScroll, +}: PagerWithHeaderProps) { + const [currentPage, setCurrentPage] = useState(0) + const [tabBarHeight, setTabBarHeight] = useState(0) + const [headerOnlyHeight, setHeaderOnlyHeight] = useState(0) + const scrollY = useSharedValue(0) + const headerHeight = headerOnlyHeight + tabBarHeight + + // capture the header bar sizing + const onTabBarLayout = useNonReactiveCallback((evt: LayoutChangeEvent) => { + const height = evt.nativeEvent.layout.height + if (height > 0) { + // The rounding is necessary to prevent jumps on iOS + setTabBarHeight(Math.round(height * 2) / 2) + } + }) + const onHeaderOnlyLayout = useNonReactiveCallback((height: number) => { + if (height > 0) { + // The rounding is necessary to prevent jumps on iOS + setHeaderOnlyHeight(Math.round(height * 2) / 2) + } + }) + + const renderTabBar = useCallback( + (props: RenderTabBarFnProps) => { + return ( + + + + ) + }, + [ + headerOnlyHeight, items, isHeaderReady, renderHeader, - initialPage, - onPageSelected, + currentPage, onCurrentPageSelected, + onTabBarLayout, + onHeaderOnlyLayout, + scrollY, + testID, allowHeaderOverScroll, - }: PagerWithHeaderProps, - ref, - ) { - const [currentPage, setCurrentPage] = React.useState(0) - const [tabBarHeight, setTabBarHeight] = React.useState(0) - const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0) - const scrollY = useSharedValue(0) - const headerHeight = headerOnlyHeight + tabBarHeight + ], + ) - // capture the header bar sizing - const onTabBarLayout = useNonReactiveCallback((evt: LayoutChangeEvent) => { - const height = evt.nativeEvent.layout.height - if (height > 0) { - // The rounding is necessary to prevent jumps on iOS - setTabBarHeight(Math.round(height * 2) / 2) - } - }) - const onHeaderOnlyLayout = useNonReactiveCallback((height: number) => { - if (height > 0) { - // The rounding is necessary to prevent jumps on iOS - setHeaderOnlyHeight(Math.round(height * 2) / 2) - } - }) + const scrollRefs = useSharedValue | null>>([]) + const registerRef = useCallback( + (scrollRef: AnimatedRef | null, atIndex: number) => { + scrollRefs.modify(refs => { + 'worklet' + refs[atIndex] = scrollRef + return refs + }) + }, + [scrollRefs], + ) - const renderTabBar = React.useCallback( - (props: RenderTabBarFnProps) => { - return ( - - - - ) - }, - [ - headerOnlyHeight, - items, - isHeaderReady, - renderHeader, - currentPage, - onCurrentPageSelected, - onTabBarLayout, - onHeaderOnlyLayout, - scrollY, - testID, - allowHeaderOverScroll, - ], - ) - - const scrollRefs = useSharedValue | null>>([]) - const registerRef = React.useCallback( - (scrollRef: AnimatedRef | null, atIndex: number) => { - scrollRefs.modify(refs => { - 'worklet' - refs[atIndex] = scrollRef - return refs - }) - }, - [scrollRefs], - ) - - const lastForcedScrollY = useSharedValue(0) - const adjustScrollForOtherPages = () => { + const lastForcedScrollY = useSharedValue(0) + const adjustScrollForOtherPages = useCallback( + (scrollState: 'idle' | 'dragging' | 'settling') => { 'worklet' + if (scrollState !== 'dragging') return const currentScrollY = scrollY.get() const forcedScrollY = Math.min(currentScrollY, headerOnlyHeight) if (lastForcedScrollY.get() !== forcedScrollY) { @@ -152,75 +153,69 @@ export const PagerWithHeader = React.forwardRef( } } } - } + }, + [currentPage, headerOnlyHeight, lastForcedScrollY, scrollRefs, scrollY], + ) - const throttleTimeout = React.useRef | null>( - null, - ) - const queueThrottledOnScroll = useNonReactiveCallback(() => { - if (!throttleTimeout.current) { - throttleTimeout.current = setTimeout(() => { - throttleTimeout.current = null - runOnUI(adjustScrollForOtherPages)() - }, 80 /* Sync often enough you're unlikely to catch it unsynced */) + const onScrollWorklet = useCallback( + (e: NativeScrollEvent) => { + 'worklet' + const nextScrollY = e.contentOffset.y + // HACK: onScroll is reporting some strange values on load (negative header height). + // Highly improbable that you'd be overscrolled by over 400px - + // in fact, I actually can't do it, so let's just ignore those. -sfn + const isPossiblyInvalid = + headerHeight > 0 && Math.round(nextScrollY * 2) / 2 === -headerHeight + if (!isPossiblyInvalid) { + scrollY.set(nextScrollY) } - }) + }, + [scrollY, headerHeight], + ) - const onScrollWorklet = React.useCallback( - (e: NativeScrollEvent) => { - 'worklet' - const nextScrollY = e.contentOffset.y - // HACK: onScroll is reporting some strange values on load (negative header height). - // Highly improbable that you'd be overscrolled by over 400px - - // in fact, I actually can't do it, so let's just ignore those. -sfn - const isPossiblyInvalid = - headerHeight > 0 && Math.round(nextScrollY * 2) / 2 === -headerHeight - if (!isPossiblyInvalid) { - scrollY.set(nextScrollY) - runOnJS(queueThrottledOnScroll)() - } - }, - [scrollY, queueThrottledOnScroll, headerHeight], - ) + const onPageSelectedInner = useCallback( + (index: number) => { + setCurrentPage(index) + onPageSelected?.(index) + }, + [onPageSelected, setCurrentPage], + ) - const onPageSelectedInner = React.useCallback( - (index: number) => { - setCurrentPage(index) - onPageSelected?.(index) - }, - [onPageSelected, setCurrentPage], - ) + const onTabPressed = useCallback(() => { + runOnUI(adjustScrollForOtherPages)('dragging') + }, [adjustScrollForOtherPages]) - return ( - - {toArray(children) - .filter(Boolean) - .map((child, i) => { - const isReady = - isHeaderReady && headerOnlyHeight > 0 && tabBarHeight > 0 - return ( - - - - ) - })} - - ) - }, -) + return ( + + {toArray(children) + .filter(Boolean) + .map((child, i) => { + const isReady = + isHeaderReady && headerOnlyHeight > 0 && tabBarHeight > 0 + return ( + + + + ) + })} + + ) +} let PagerTabBar = ({ currentPage, @@ -258,7 +253,7 @@ let PagerTabBar = ({ dragState: SharedValue<'idle' | 'dragging' | 'settling'> }): React.ReactNode => { const t = useTheme() - const [minimumHeaderHeight, setMinimumHeaderHeight] = React.useState(0) + const [minimumHeaderHeight, setMinimumHeaderHeight] = useState(0) const headerTransform = useAnimatedStyle(() => { const translateY = Math.min( @@ -275,7 +270,7 @@ let PagerTabBar = ({ ], } }) - const headerRef = React.useRef(null) + const headerRef = useRef(null) return ( ) } -PagerTabBar = React.memo(PagerTabBar) +PagerTabBar = memo(PagerTabBar) function PagerItem({ headerHeight, @@ -348,7 +343,7 @@ function PagerItem({ }) { const scrollElRef = useAnimatedRef() - React.useEffect(() => { + useEffect(() => { registerRef(scrollElRef, index) return () => { registerRef(null, index) diff --git a/src/view/com/profile/ProfileSubpageHeader.tsx b/src/view/com/profile/ProfileSubpageHeader.tsx index b0cf4d10e4..02a6704bf9 100644 --- a/src/view/com/profile/ProfileSubpageHeader.tsx +++ b/src/view/com/profile/ProfileSubpageHeader.tsx @@ -1,23 +1,28 @@ import React from 'react' import {Pressable, View} from 'react-native' -import {MeasuredDimensions, runOnJS, runOnUI} from 'react-native-reanimated' -import {AppBskyGraphDefs} from '@atproto/api' +import Animated, { + measure, + type MeasuredDimensions, + runOnJS, + runOnUI, + useAnimatedRef, +} from 'react-native-reanimated' +import {type AppBskyGraphDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {measureHandle, useHandleRef} from '#/lib/hooks/useHandleRef' import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {makeProfileLink} from '#/lib/routes/links' -import {NavigationProp} from '#/lib/routes/types' +import {type NavigationProp} from '#/lib/routes/types' import {sanitizeHandle} from '#/lib/strings/handles' import {emitSoftReset} from '#/state/events' import {useLightboxControls} from '#/state/lightbox' import {TextLink} from '#/view/com/util/Link' import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {Text} from '#/view/com/util/text/Text' -import {UserAvatar, UserAvatarType} from '#/view/com/util/UserAvatar' +import {UserAvatar, type UserAvatarType} from '#/view/com/util/UserAvatar' import {StarterPack} from '#/components/icons/StarterPack' import * as Layout from '#/components/Layout' @@ -52,7 +57,7 @@ export function ProfileSubpageHeader({ const {openLightbox} = useLightboxControls() const pal = usePalette('default') const canGoBack = navigation.canGoBack() - const aviRef = useHandleRef() + const aviRef = useAnimatedRef() const _openLightbox = React.useCallback( (uri: string, thumbRect: MeasuredDimensions | null) => { @@ -81,10 +86,9 @@ export function ProfileSubpageHeader({ if ( avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride) ) { - const aviHandle = aviRef.current runOnUI(() => { 'worklet' - const rect = measureHandle(aviHandle) + const rect = measure(aviRef) runOnJS(_openLightbox)(avatar, rect) })() } @@ -111,7 +115,7 @@ export function ProfileSubpageHeader({ paddingBottom: 14, paddingHorizontal: isMobile ? 12 : 14, }}> - + )} - + {isLoading ? ( void + onPress?: ( + containerRef: AnimatedRef, + fetchedDims: Dimensions | null, + ) => void onLongPress?: () => void onPressIn?: () => void }) { const t = useTheme() const {_} = useLingui() const largeAlt = useLargeAltBadgeEnabled() - const containerRef = useHandleRef() + const containerRef = useAnimatedRef() const fetchedDimsRef = useRef<{width: number; height: number} | null>(null) let aspectRatio: number | undefined @@ -103,7 +109,7 @@ export function AutoSizedImage({ const hasAlt = !!image.alt const contents = ( - + ) : null} - + ) if (cropDisabled) { diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx index 7b9019811c..323264ea4b 100644 --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -1,12 +1,12 @@ -import React from 'react' -import {Pressable, StyleProp, View, ViewStyle} from 'react-native' -import {Image, ImageStyle} from 'expo-image' -import {AppBskyEmbedImages} from '@atproto/api' +import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native' +import {type AnimatedRef} from 'react-native-reanimated' +import {Image, type ImageStyle} from 'expo-image' +import {type AppBskyEmbedImages} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import type React from 'react' -import {HandleRef} from '#/lib/hooks/useHandleRef' -import {Dimensions} from '#/lib/media/types' +import {type Dimensions} from '#/lib/media/types' import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge' import {atoms as a, useTheme} from '#/alf' import {MediaInsetBorder} from '#/components/MediaInsetBorder' @@ -20,7 +20,7 @@ interface Props { index: number onPress?: ( index: number, - containerRefs: HandleRef[], + containerRefs: AnimatedRef[], fetchedDims: (Dimensions | null)[], ) => void onLongPress?: EventFunction @@ -28,7 +28,7 @@ interface Props { imageStyle?: StyleProp viewContext?: PostEmbedViewContext insetBorderStyle?: StyleProp - containerRefs: HandleRef[] + containerRefs: AnimatedRef[] thumbDimsRef: React.MutableRefObject<(Dimensions | null)[]> } diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx index 6aa451bf47..757d952a19 100644 --- a/src/view/com/util/images/ImageLayoutGrid.tsx +++ b/src/view/com/util/images/ImageLayoutGrid.tsx @@ -1,18 +1,18 @@ import React from 'react' -import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native' -import {AppBskyEmbedImages} from '@atproto/api' +import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native' +import {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated' +import {type AppBskyEmbedImages} from '@atproto/api' -import {HandleRef, useHandleRef} from '#/lib/hooks/useHandleRef' import {atoms as a, useBreakpoints} from '#/alf' import {PostEmbedViewContext} from '#/components/Post/Embed/types' -import {Dimensions} from '../../lightbox/ImageViewing/@types' +import {type Dimensions} from '../../lightbox/ImageViewing/@types' import {GalleryItem} from './Gallery' interface ImageLayoutGridProps { images: AppBskyEmbedImages.ViewImage[] onPress?: ( index: number, - containerRefs: HandleRef[], + containerRefs: AnimatedRef[], fetchedDims: (Dimensions | null)[], ) => void onLongPress?: (index: number) => void @@ -43,7 +43,7 @@ interface ImageLayoutGridInnerProps { images: AppBskyEmbedImages.ViewImage[] onPress?: ( index: number, - containerRefs: HandleRef[], + containerRefs: AnimatedRef[], fetchedDims: (Dimensions | null)[], ) => void onLongPress?: (index: number) => void @@ -56,10 +56,10 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { const gap = props.gap const count = props.images.length - const containerRef1 = useHandleRef() - const containerRef2 = useHandleRef() - const containerRef3 = useHandleRef() - const containerRef4 = useHandleRef() + const containerRef1 = useAnimatedRef() + const containerRef2 = useAnimatedRef() + const containerRef3 = useAnimatedRef() + const containerRef4 = useAnimatedRef() const thumbDimsRef = React.useRef<(Dimensions | null)[]>([]) switch (count) { diff --git a/yarn.lock b/yarn.lock index 9c6a368472..125c985ea5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3776,29 +3776,29 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d" integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== -"@expo/cli@0.24.10": - version "0.24.10" - resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.24.10.tgz#f23d150f011cdebd6f503343d9be3c6283fb4096" - integrity sha512-auPE4MSRdkJkHsWJk935VoqX/BGMKARgXOLtJybTFUi64K3MkvdUoBrujcn/QzXl5DTGhacFd9qxUeQss6/qwg== +"@expo/cli@0.24.14": + version "0.24.14" + resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.24.14.tgz#af2e7ea5a08e3574e868cb0ec2110e68d32672e0" + integrity sha512-o+QYyfIBhSRTgaywKTLJhm2Fg5PrSeUVCXS+uQySamgoMjLNhHa8QwE64mW/FmJr5hZLiqUEQxb60FK4JcyqXg== dependencies: "@0no-co/graphql.web" "^1.0.8" "@babel/runtime" "^7.20.0" "@expo/code-signing-certificates" "^0.0.5" - "@expo/config" "~11.0.7" + "@expo/config" "~11.0.10" "@expo/config-plugins" "~10.0.2" "@expo/devcert" "^1.1.2" "@expo/env" "~1.0.5" "@expo/image-utils" "^0.7.4" "@expo/json-file" "^9.1.4" - "@expo/metro-config" "~0.20.12" + "@expo/metro-config" "~0.20.14" "@expo/osascript" "^2.2.4" "@expo/package-manager" "^1.8.4" "@expo/plist" "^0.3.4" - "@expo/prebuild-config" "^9.0.5" + "@expo/prebuild-config" "^9.0.6" "@expo/spawn-async" "^1.7.2" "@expo/ws-tunnel" "^1.0.1" "@expo/xcpretty" "^4.3.0" - "@react-native/dev-middleware" "0.79.2" + "@react-native/dev-middleware" "0.79.3" "@urql/core" "^5.0.6" "@urql/exchange-retry" "^1.3.0" accepts "^1.3.8" @@ -3813,9 +3813,9 @@ debug "^4.3.4" env-editor "^0.4.1" freeport-async "^2.0.0" - getenv "^1.0.0" + getenv "^2.0.0" glob "^10.4.2" - lan-network "^0.1.4" + lan-network "^0.1.6" minimatch "^9.0.0" node-forge "^1.3.1" npm-package-arg "^11.0.0" @@ -3871,7 +3871,7 @@ xcode "^3.0.1" xml2js "0.6.0" -"@expo/config-plugins@~10.0.1", "@expo/config-plugins@~10.0.2": +"@expo/config-plugins@~10.0.2": version "10.0.2" resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-10.0.2.tgz#040867991e9c8c527b4f5c13a47bcf040a7479fe" integrity sha512-TzUn3pPdpwCS0yYaSlZOClgDmCX8N4I2lfgitX5oStqmvpPtB+vqtdyqsVM02fQ2tlJIAqwBW+NHaHqqy8Jv7g== @@ -3926,6 +3926,11 @@ resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-53.0.3.tgz#d083d9b095972e89eee96c41d085feb5b92d2749" integrity sha512-V1e6CiM4TXtGxG/W2Msjp/QOx/vikLo5IUGMvEMjgAglBfGYx3PXfqsUb5aZDt6kqA3bDDwFuZoS5vNm/SYwSg== +"@expo/config-types@^53.0.4": + version "53.0.4" + resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-53.0.4.tgz#fe64fac734531ae883d18529b32586c23ffb1ceb" + integrity sha512-0s+9vFx83WIToEr0Iwy4CcmiUXa5BgwBmEjylBB2eojX5XAMm9mJvw9KpjAb8m7zq2G0Q6bRbeufkzgbipuNQg== + "@expo/config@~10.0.4": version "10.0.5" resolved "https://registry.yarnpkg.com/@expo/config/-/config-10.0.5.tgz#2de75e3f5d46a55f9f5140b73e0913265e6a41c6" @@ -3945,14 +3950,14 @@ slugify "^1.3.4" sucrase "3.35.0" -"@expo/config@~11.0.6", "@expo/config@~11.0.7": - version "11.0.7" - resolved "https://registry.yarnpkg.com/@expo/config/-/config-11.0.7.tgz#e6a6071942854269825e2450c3a115c963a4fd56" - integrity sha512-pppH3Cy2IfituiYACMeW7cWYezcjmHKq7lDLfH1gMHT+zZ1QaYNs3EN6Kcc/QAXV//KFFhU0Qq4H/UrLuPp/yg== +"@expo/config@~11.0.10", "@expo/config@~11.0.9": + version "11.0.10" + resolved "https://registry.yarnpkg.com/@expo/config/-/config-11.0.10.tgz#559d9425a4e0de4fab96ccac01ff40f5cebbc04b" + integrity sha512-8S8Krr/c5lnl0eF03tA2UGY9rGBhZcbWKz2UWw5dpL/+zstwUmog8oyuuC8aRcn7GiTQLlbBkxcMeT8sOGlhbA== dependencies: "@babel/code-frame" "~7.10.4" - "@expo/config-plugins" "~10.0.1" - "@expo/config-types" "^53.0.3" + "@expo/config-plugins" "~10.0.2" + "@expo/config-types" "^53.0.4" "@expo/json-file" "^9.1.4" deepmerge "^4.3.1" getenv "^1.0.0" @@ -4005,23 +4010,24 @@ dotenv-expand "~11.0.6" getenv "^1.0.0" -"@expo/fingerprint@0.12.4": - version "0.12.4" - resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.12.4.tgz#d4cc4de50e7b6d4e03b0d38850d1e4a136b74c8c" - integrity sha512-HOJVvjiQYVHIouCOfFf4JRrQvBDIV/12GVG2iwbw1iGwmpQVkPgEXa9lN0f2yuS4J3QXHs73wr9jvuCjMmJlfw== +"@expo/fingerprint@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.13.0.tgz#5f5600122940ac381ed697743c10bdbddf6c55c1" + integrity sha512-3IwpH0p3uO8jrJSLOUNDzJVh7VEBod0emnCBq0hD72sy6ICmzauM6Xf4he+2Tip7fzImCJRd63GaehV+CCtpvA== dependencies: "@expo/spawn-async" "^1.7.2" arg "^5.0.2" chalk "^4.1.2" debug "^4.3.4" find-up "^5.0.0" - getenv "^1.0.0" + getenv "^2.0.0" + ignore "^5.3.1" minimatch "^9.0.0" p-limit "^3.1.0" resolve-from "^5.0.0" semver "^7.6.0" -"@expo/html-elements@^0.12.4": +"@expo/html-elements@^0.12.5": version "0.12.5" resolved "https://registry.yarnpkg.com/@expo/html-elements/-/html-elements-0.12.5.tgz#be7e7af9f2be6d3f1aa3ec2e7ae1c121c91a9aa1" integrity sha512-28KWO88YKykKU7ke5sEQs5TivFRMs1Aktz13xxgqAf5rTgb+lka0VKVt3W2fG7ksbUQ407rtUqz7SEAq298NvQ== @@ -4068,16 +4074,16 @@ json5 "^2.2.3" write-file-atomic "^2.3.0" -"@expo/metro-config@0.20.12", "@expo/metro-config@~0.20.12": - version "0.20.12" - resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.20.12.tgz#f6e2c33a305cb0ab8b0aa0dadafd6adf09058b9c" - integrity sha512-O9zaAF3gH76EXkwuQCpXLKC5dBy344/pqoszWmtOloKo4gJy74aNPUy2LRS57pDHyjZe1HjrxVkMcr7lZCIsag== +"@expo/metro-config@0.20.14", "@expo/metro-config@~0.20.14": + version "0.20.14" + resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.20.14.tgz#5abf8cd6454fe7f75c1f8529cf79619da32af82d" + integrity sha512-tYDDubuZycK+NX00XN7BMu73kBur/evOPcKfxc+UBeFfgN2EifOITtdwSUDdRsbtJ2OnXwMY1HfRUG3Lq3l4cw== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.5" "@babel/parser" "^7.20.0" "@babel/types" "^7.20.0" - "@expo/config" "~11.0.7" + "@expo/config" "~11.0.9" "@expo/env" "~1.0.5" "@expo/json-file" "~9.1.4" "@expo/spawn-async" "^1.7.2" @@ -4140,14 +4146,14 @@ base64-js "^1.2.3" xmlbuilder "^15.1.1" -"@expo/prebuild-config@^9.0.5": - version "9.0.5" - resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-9.0.5.tgz#b8b864b5e19489a1f66442ae30d5d7295f658297" - integrity sha512-oiSVU5ePu9lsOvn5p4xplqjzPlcZHzKYwzuonTa9GCH1GxcOEIBsvMVQiHBXHtqvgV2dztjm34kdXV//+9jtCA== +"@expo/prebuild-config@^9.0.6": + version "9.0.6" + resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-9.0.6.tgz#f634e7b8f9ebebeaf2e7d2f2be46926c23834d2b" + integrity sha512-HDTdlMkTQZ95rd6EpvuLM+xkZV03yGLc38FqI37qKFLJtUN1WnYVaWsuXKoljd1OrVEVsHe6CfqKwaPZ52D56Q== dependencies: - "@expo/config" "~11.0.7" + "@expo/config" "~11.0.9" "@expo/config-plugins" "~10.0.2" - "@expo/config-types" "^53.0.3" + "@expo/config-types" "^53.0.4" "@expo/image-utils" "^0.7.4" "@expo/json-file" "^9.1.4" "@react-native/normalize-colors" "0.79.2" @@ -4416,10 +4422,10 @@ protobufjs "^7.2.5" yargs "^17.7.2" -"@haileyok/bluesky-video@0.2.6": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@haileyok/bluesky-video/-/bluesky-video-0.2.6.tgz#61bb4ff908498558fd2320f06ba0f74ea03598b4" - integrity sha512-IlzrTATD7ci/a+ehSA7pIhOvxxNTe35zdzBYt8EmVvKKafyeFhxGfDuuP5qxfQmHurcQMIL+3HeZgnAXwQQNmQ== +"@haileyok/bluesky-video@0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@haileyok/bluesky-video/-/bluesky-video-0.3.1.tgz#c996d8433e8f1988f2e9644adf39366fb4305d00" + integrity sha512-TU5c0RCV1yWF/HEZA22E0qXjxNzu0SOuMZpvdo+QVrO4tQcja9k8nHBbKRmyj60Odke4HQMoTOfNDNq/xo2Grw== "@hapi/accept@^6.0.3": version "6.0.3" @@ -5119,12 +5125,11 @@ "@babel/runtime" "^7.20.13" "@lingui/core" "4.14.1" -"@mattermost/react-native-paste-input@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@mattermost/react-native-paste-input/-/react-native-paste-input-0.7.1.tgz#f14585030b992cf7c9bbd0921225eefa501756ba" - integrity sha512-kY8LKtqRX2T/rtn/HNrzTitijuATvyzd6yl5WNWOsszmyzNcssKStjjCTBup04CyMxfwutUU1CWrYUb3hQO7oA== +"@mattermost/react-native-paste-input@mattermost/react-native-paste-input": + version "0.8.1" + resolved "https://codeload.github.com/mattermost/react-native-paste-input/tar.gz/f260447edc645a817ab1ba7b46d8341d84dba8e9" dependencies: - semver "7.6.0" + semver "7.6.3" "@messageformat/parser@^5.0.0": version "5.1.0" @@ -5133,12 +5138,12 @@ dependencies: moo "^0.5.1" -"@miblanchard/react-native-slider@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@miblanchard/react-native-slider/-/react-native-slider-2.3.1.tgz#79e0f1f9b1ce43ef25ee51ee9256c012e5dfa412" - integrity sha512-J/hZDBWmXq8fJeOnTVHqIUVDHshqMSpJVxJ4WqwuCBKl5Rke9OBYXIdkSlgi75OgtScAr8FKK5KNkDKHUf6JIg== +"@miblanchard/react-native-slider@^2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@miblanchard/react-native-slider/-/react-native-slider-2.6.0.tgz#9f78c805d637ffaff0e3e7429932d2995a67edc9" + integrity sha512-o7hk/f/8vkqh6QNR5L52m+ws846fQeD/qNCC9CCSRdBqjq66KiCgbxzlhRzKM/gbtxcvMYMIEEJ1yes5cr6I3A== -"@mozzius/expo-dynamic-app-icon@^1.5.0": +"@mozzius/expo-dynamic-app-icon@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@mozzius/expo-dynamic-app-icon/-/expo-dynamic-app-icon-1.5.0.tgz#c5f88c309965b6d6b89cfd5e2c00faa7bda736af" integrity sha512-yE2yEPO+HQmOqsX7cECh7/vu/LXnqhHGsVm3UiVi/3gaK8u5hAkPTNzZ0Qu6vnMwjPnY+uFbN6X+6Aj9c9yjMQ== @@ -6141,23 +6146,23 @@ resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.11.0.tgz#4587fbce6a382adedad74311e96ee10bb2b2d63a" integrity sha512-QuZU6gbxmOID5zZgd/H90NgBnbJ3VV6qVzp6c7/dDrmWdX8S0X5YFYgDcQFjE3dRen9wB9FWnj2VVdPU64adSg== -"@react-native/assets-registry@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.79.2.tgz#731963e664c8543f5b277e56c058bde612b69f50" - integrity sha512-5h2Z7/+/HL/0h88s0JHOdRCW4CXMCJoROxqzHqxdrjGL6EBD1DdaB4ZqkCOEVSW4Vjhir5Qb97C8i/MPWEYPtg== +"@react-native/assets-registry@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.79.3.tgz#022218d55a5d9d221a6d176987ab0b35c10d388b" + integrity sha512-Vy8DQXCJ21YSAiHxrNBz35VqVlZPpRYm50xRTWRf660JwHuJkFQG8cUkrLzm7AUriqUXxwpkQHcY+b0ibw9ejQ== -"@react-native/babel-plugin-codegen@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.2.tgz#f3f86766a01487aaaa623ec62514af4c84400953" - integrity sha512-d+NB7Uosn2ZWd4O4+7ZkB6q1a+0z2opD/4+Bzhk/Tv6fc5FrSftK2Noqxvo3/bhbdGFVPxf0yvLE8et4W17x/Q== +"@react-native/babel-plugin-codegen@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.79.3.tgz#acad4acaead398a8c8bcdecbe44040aa0c2dc2d7" + integrity sha512-Zb8F4bSEKKZfms5n1MQ0o5mudDcpAINkKiFuFTU0PErYGjY3kZ+JeIP+gS6KCXsckxCfMEKQwqKicP/4DWgsZQ== dependencies: "@babel/traverse" "^7.25.3" - "@react-native/codegen" "0.79.2" + "@react-native/codegen" "0.79.3" -"@react-native/babel-preset@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.2.tgz#5a683a6efeea357a326f70c84a881be2bafbeae3" - integrity sha512-/HNu869oUq4FUXizpiNWrIhucsYZqu0/0spudJEzk9SEKar0EjVDP7zkg/sKK+KccNypDQGW7nFXT8onzvQ3og== +"@react-native/babel-preset@0.79.2", "@react-native/babel-preset@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.79.3.tgz#8ad6c149cd488fbc18d62983119bdcbfc15ff651" + integrity sha512-VHGNP02bDD2Ul1my0pLVwe/0dsEBHxR343ySpgnkCNEEm9C1ANQIL2wvnJrHZPcqfAkWfFQ8Ln3t+6fdm4A/Dg== dependencies: "@babel/core" "^7.25.2" "@babel/plugin-proposal-export-default-from" "^7.24.7" @@ -6200,15 +6205,15 @@ "@babel/plugin-transform-typescript" "^7.25.2" "@babel/plugin-transform-unicode-regex" "^7.24.7" "@babel/template" "^7.25.0" - "@react-native/babel-plugin-codegen" "0.79.2" + "@react-native/babel-plugin-codegen" "0.79.3" babel-plugin-syntax-hermes-parser "0.25.1" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" -"@react-native/codegen@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.79.2.tgz#75270d8162e78c02b0272396a3c6942e39e8703d" - integrity sha512-8JTlGLuLi1p8Jx2N/enwwEd7/2CfrqJpv90Cp77QLRX3VHF2hdyavRIxAmXMwN95k+Me7CUuPtqn2X3IBXOWYg== +"@react-native/codegen@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.79.3.tgz#49689132718c81a3b25426769bc6fd8fd2a0469f" + integrity sha512-CZejXqKch/a5/s/MO5T8mkAgvzCXgsTkQtpCF15kWR9HN8T+16k0CsN7TXAxXycltoxiE3XRglOrZNEa/TiZUQ== dependencies: glob "^7.1.1" hermes-parser "0.25.1" @@ -6216,12 +6221,12 @@ nullthrows "^1.1.1" yargs "^17.6.2" -"@react-native/community-cli-plugin@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.2.tgz#d3a0efbdfb554cf3a7e9bfb27865a7caeeeaa1b3" - integrity sha512-E+YEY2dL+68HyR2iahsZdyBKBUi9QyPyaN9vsnda1jNgCjNpSPk2yAF5cXsho+zKK5ZQna3JSeE1Kbi2IfGJbw== +"@react-native/community-cli-plugin@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.3.tgz#84821d3401074e036ba05b8b6ca1ee122cb43e29" + integrity sha512-N/+p4HQqN4yK6IRzn7OgMvUIcrmEWkecglk1q5nj+AzNpfIOzB+mqR20SYmnPfeXF+mZzYCzRANb3KiM+WsSDA== dependencies: - "@react-native/dev-middleware" "0.79.2" + "@react-native/dev-middleware" "0.79.3" chalk "^4.0.0" debug "^2.2.0" invariant "^2.2.4" @@ -6230,18 +6235,18 @@ metro-core "^0.82.0" semver "^7.1.3" -"@react-native/debugger-frontend@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.79.2.tgz#1377de6d9cabe5455bf332e06408167da5f60c19" - integrity sha512-cGmC7X6kju76DopSBNc+PRAEetbd7TWF9J9o84hOp/xL3ahxR2kuxJy0oJX8Eg8oehhGGEXTuMKHzNa3rDBeSg== +"@react-native/debugger-frontend@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.79.3.tgz#9cb57d8e88c22552194ab5f6f257605b151bc5b3" + integrity sha512-ImNDuEeKH6lEsLXms3ZsgIrNF94jymfuhPcVY5L0trzaYNo9ZFE9Ni2/18E1IbfXxdeIHrCSBJlWD6CTm7wu5A== -"@react-native/dev-middleware@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.79.2.tgz#f09f1a75b4cd0b56dfd82a07bf41157a9c45619c" - integrity sha512-9q4CpkklsAs1L0Bw8XYCoqqyBSrfRALGEw4/r0EkR38Y/6fVfNfdsjSns0pTLO6h0VpxswK34L/hm4uK3MoLHw== +"@react-native/dev-middleware@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.79.3.tgz#3e315ef7516ebad60a4202b4094d84fedecb4064" + integrity sha512-x88+RGOyG71+idQefnQg7wLhzjn/Scs+re1O5vqCkTVzRAc/f7SdHMlbmECUxJPd08FqMcOJr7/X3nsJBrNuuw== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.79.2" + "@react-native/debugger-frontend" "0.79.3" chrome-launcher "^0.15.2" chromium-edge-launcher "^0.2.0" connect "^3.6.5" @@ -6252,14 +6257,14 @@ serve-static "^1.16.2" ws "^6.2.3" -"@react-native/eslint-config@^0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/eslint-config/-/eslint-config-0.79.2.tgz#b42c95fe2399aae84209356b0971dd68c4149e4e" - integrity sha512-ukb9qGvrFC/3YVlWVy/GGM+auKdGIsbbumCyfOYPfUdhHFWA/twz1zK4bJQmCZ38iINuTENYedRzoE+U57GclA== +"@react-native/eslint-config@^0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/eslint-config/-/eslint-config-0.79.3.tgz#a72352ce98a7d05b5686dc446ba933fee3b944a9" + integrity sha512-pvPXfXFoVfwqGEItIl7emv6bRTpi0NWv4jmb0ZBwSJ7+zM8bRRw7JwxLA+iwrevh0QAqrF66Nu5xl39ysWcavg== dependencies: "@babel/core" "^7.25.2" "@babel/eslint-parser" "^7.25.1" - "@react-native/eslint-plugin" "0.79.2" + "@react-native/eslint-plugin" "0.79.3" "@typescript-eslint/eslint-plugin" "^7.1.1" "@typescript-eslint/parser" "^7.1.1" eslint-config-prettier "^8.5.0" @@ -6270,35 +6275,35 @@ eslint-plugin-react-hooks "^4.6.0" eslint-plugin-react-native "^4.0.0" -"@react-native/eslint-plugin@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.79.2.tgz#23d18226bb4335404e6db561bf1a47ac7d1380ed" - integrity sha512-Abu+0OuwTje9E5eQOvYpTUuXvDgGjHeFhnfNVY9BXalBK8OrX20EFlonWvIbFqii136eS5KLEBm2Wjqk2V5XJg== +"@react-native/eslint-plugin@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.79.3.tgz#c1ac34d45b92f963b9af66e860c45cd891235741" + integrity sha512-6QZzCsV+Wc+HdOAMMoMqDea3SSzsvBBktGc/cqaLubKGiztTb22d+vtzZGWqCqUEVkhQKdK7qhWAs0kJPEbiXw== -"@react-native/gradle-plugin@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.79.2.tgz#d41d4e2c63baf688a2b47652c6260f2a2f1ec091" - integrity sha512-6MJFemrwR0bOT0QM+2BxX9k3/pvZQNmJ3Js5pF/6owsA0cUDiCO57otiEU8Fz+UywWEzn1FoQfOfQ8vt2GYmoA== +"@react-native/gradle-plugin@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.79.3.tgz#69ba47ac406ccdb3b3829f311bd7c27e6fad7ebc" + integrity sha512-imfpZLhNBc9UFSzb/MOy2tNcIBHqVmexh/qdzw83F75BmUtLb/Gs1L2V5gw+WI1r7RqDILbWk7gXB8zUllwd+g== -"@react-native/js-polyfills@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.79.2.tgz#15eb4da0fe9e8d61d2980d08fd06b5f49e133b0f" - integrity sha512-IaY87Ckd4GTPMkO1/Fe8fC1IgIx3vc3q9Tyt/6qS3Mtk9nC0x9q4kSR5t+HHq0/MuvGtu8HpdxXGy5wLaM+zUw== +"@react-native/js-polyfills@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.79.3.tgz#bf5614363f118c6bdf2f773c578e603c88d0425c" + integrity sha512-PEBtg6Kox6KahjCAch0UrqCAmHiNLEbp2SblUEoFAQnov4DSxBN9safh+QSVaCiMAwLjvNfXrJyygZz60Dqz3Q== -"@react-native/normalize-colors@0.79.2", "@react-native/normalize-colors@^0.73.0", "@react-native/normalize-colors@^0.74.1": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.79.2.tgz#9ab70ca257c7411e4ab74cf7f91332c27d39cc6f" - integrity sha512-+b+GNrupWrWw1okHnEENz63j7NSMqhKeFMOyzYLBwKcprG8fqJQhDIGXfizKdxeIa5NnGSAevKL1Ev1zJ56X8w== +"@react-native/normalize-colors@0.79.2", "@react-native/normalize-colors@0.79.3", "@react-native/normalize-colors@^0.73.0", "@react-native/normalize-colors@^0.74.1": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.79.3.tgz#e491937436a2c287707e24263308c818a66eb447" + integrity sha512-T75NIQPRFCj6DFMxtcVMJTZR+3vHXaUMSd15t+CkJpc5LnyX91GVaPxpRSAdjFh7m3Yppl5MpdjV/fntImheYQ== -"@react-native/typescript-config@^0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.79.2.tgz#02cb07db89ef80159b3c1b3e82e81b0c0d5ce908" - integrity sha512-krHAkkPRCOEhuqN3iwRUwIyE1rAnUQ9//huzUc1ukcoQ7Y4qFxM6amhNloAmYn4QH1Ay6o5At00VbEh2xoHISA== +"@react-native/typescript-config@^0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.79.3.tgz#21101b591c67ecef6ae5189f96a448b3bcaf1e9e" + integrity sha512-dqKAU8D3NkExthnpBOPZjZ/NGU5qqBaqZ12v9IlMqP9sVTWSuY1iswfzomp0AYeJBxo4ZpBNmrdlnQZYQSVWiw== -"@react-native/virtualized-lists@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.79.2.tgz#ed5a419a30b7ddec978b7816ff698a9d85507e15" - integrity sha512-9G6ROJeP+rdw9Bvr5ruOlag11ET7j1z/En1riFFNo6W3xZvJY+alCuH1ttm12y9+zBm4n8jwCk4lGhjYaV4dKw== +"@react-native/virtualized-lists@0.79.3": + version "0.79.3" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.79.3.tgz#4a2799017cd3795f519422f48b3c0bbc4739a245" + integrity sha512-/0rRozkn+iIHya2vnnvprDgT7QkfI54FLrACAN3BLP7MRlfOIGOrZsXpRLndnLBVnjNzkcre84i1RecjoXnwIA== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -6412,6 +6417,11 @@ resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-3.2.2.tgz#0c5f26e417b8f524924fa4531b82ad5603216e90" integrity sha512-D+SKQ266ra/wo87s9+UI/rKQi3qhGPCR8eSCDe0VJudhjHsqyNU+JJ5lnIGCgmZaWFTXgdBP/gdr1Iz1zqGs4Q== +"@sentry/babel-plugin-component-annotate@3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-3.4.0.tgz#f47a7652e16f84556df82cbc38f0004bca1335d1" + integrity sha512-tSzfc3aE7m0PM0Aj7HBDet5llH9AB9oc+tBQ8AvOqUSnWodLrNCuWeQszJ7mIBovD3figgCU3h0cvI6U5cDtsg== + "@sentry/browser@8.54.0": version "8.54.0" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-8.54.0.tgz#5487075908aac564892e689e1b6d233fdb314f5b" @@ -6442,70 +6452,75 @@ resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.42.2.tgz#a32a4f226e717122b37d9969e8d4d0e14779f720" integrity sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg== -"@sentry/cli-darwin@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.42.4.tgz#029521d3052c644e3bac1c926e53d1e658b8cb28" - integrity sha512-PZV4Y97VDWBR4rIt0HkJfXaBXlebIN2s/FDzC3iHINZE5OG62CDFsnC4/lbGlf2/UZLDaGGIK7mYwSHhTvN+HQ== +"@sentry/cli-darwin@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-darwin/-/cli-darwin-2.45.0.tgz#e3d6feae4fadcfdf91db9c7b9c4689a66d3d8d19" + integrity sha512-p4Uxfv/L2fQdP3/wYnKVVz9gzZJf/1Xp9D+6raax/3Bu5y87yHYUqcdt98y/VAXQD4ofp2QgmhGUVPofvQNZmg== "@sentry/cli-linux-arm64@2.42.2": version "2.42.2" resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.42.2.tgz#1c06c83ff21f51ec23acf5be3b1f8c7553bf86b1" integrity sha512-BOxzI7sgEU5Dhq3o4SblFXdE9zScpz6EXc5Zwr1UDZvzgXZGosUtKVc7d1LmkrHP8Q2o18HcDWtF3WvJRb5Zpw== -"@sentry/cli-linux-arm64@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.42.4.tgz#b5e2d2399764998e3d661f144aae0c3f3495d1f1" - integrity sha512-Ex8vRnryyzC/9e43daEmEqPS+9uirY/l6Hw2lAvhBblFaL7PTWNx52H+8GnYGd9Zy2H3rWNyBDYfHwnErg38zA== +"@sentry/cli-linux-arm64@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.45.0.tgz#384c8e17f7e7dc007d164033d0e7c75aa83a2e9b" + integrity sha512-gUcLoEjzg7AIc4QQGEZwRHri+EHf3Gcms9zAR1VHiNF3/C/jL4WeDPJF2YiWAQt6EtH84tHiyhw1Ab/R8XFClg== "@sentry/cli-linux-arm@2.42.2": version "2.42.2" resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.42.2.tgz#00cadc359ae3c051efb3e63873c033c61dbd1ca1" integrity sha512-7udCw+YL9lwq+9eL3WLspvnuG+k5Icg92YE7zsteTzWLwgPVzaxeZD2f8hwhsu+wmL+jNqbpCRmktPteh3i2mg== -"@sentry/cli-linux-arm@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.42.4.tgz#286996c3969a553c07a74a2a67c6d3671e2c79b5" - integrity sha512-lBn0oeeg62h68/4Eo6zbPq99Idz5t0VRV48rEU/WKeM4MtQCvG/iGGQ3lBFW2yNiUBzXZIK9poXLEcgbwmcRVw== +"@sentry/cli-linux-arm@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-arm/-/cli-linux-arm-2.45.0.tgz#b9d6f86f3934b4d9ced5b45a8158ff2ac2bdd25d" + integrity sha512-6sEskFLlFKJ+e0MOYgIclBTUX5jYMyYhHIxXahEkI/4vx6JO0uvpyRAkUJRpJkRh/lPog0FM+tbP3so+VxB2qQ== "@sentry/cli-linux-i686@2.42.2": version "2.42.2" resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.42.2.tgz#3b817b715dd806c20dfbffd539725ad8089c310a" integrity sha512-Sw/dQp5ZPvKnq3/y7wIJyxTUJYPGoTX/YeMbDs8BzDlu9to2LWV3K3r7hE7W1Lpbaw4tSquUHiQjP5QHCOS7aQ== -"@sentry/cli-linux-i686@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.42.4.tgz#03e72598dc37e96a99e4329e20db9e74df277f83" - integrity sha512-IBJg0aHjsLCL4LvcFa3cXIjA+4t5kPqBT9y+PoDu4goIFxYD8zl7mbUdGJutvJafTk8Akf4ss4JJXQBjg019zA== +"@sentry/cli-linux-i686@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-i686/-/cli-linux-i686-2.45.0.tgz#39e22beb84cfa26e11bdc198364315fdfb4da4d5" + integrity sha512-VmmOaEAzSW23YdGNdy/+oQjCNAMY+HmOGA77A25/ep/9AV7PQB6FI7xO5Y1PVvlkxZFJ23e373njSsEeg4uDZw== "@sentry/cli-linux-x64@2.42.2": version "2.42.2" resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.42.2.tgz#ddf906bc3071cc79ce6e633eddcb76bb9068e688" integrity sha512-mU4zUspAal6TIwlNLBV5oq6yYqiENnCWSxtSQVzWs0Jyq97wtqGNG9U+QrnwjJZ+ta/hvye9fvL2X25D/RxHQw== -"@sentry/cli-linux-x64@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.42.4.tgz#a3bc31a909f61029620e5d2ae0f8d8625ed8982a" - integrity sha512-gXI5OEiOSNiAEz7VCE6AZcAgHJ47mlgal3+NmbE8XcHmFOnyDws9FNie6PJAy8KZjXi3nqoBP9JVAbnmOix3uA== +"@sentry/cli-linux-x64@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-linux-x64/-/cli-linux-x64-2.45.0.tgz#25cd3699297f9433835fb5edd42dad722c11f041" + integrity sha512-a0Oj68mrb25a0WjX/ShZ6AAd4PPiuLcgyzQr7bl2+DvYxIOajwkGbR+CZFEhOVZcfhTnixKy/qIXEzApEPHPQg== + +"@sentry/cli-win32-arm64@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.45.0.tgz#50c7d29ea2169bdb4d98bbde81c5f7dac0dd3955" + integrity sha512-vn+CwS4p+52pQSLNPoi20ZOrQmv01ZgAmuMnjkh1oUZfTyBAwWLrAh6Cy4cztcN8DfL5dOWKQBo8DBKURE4ttg== "@sentry/cli-win32-i686@2.42.2": version "2.42.2" resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.42.2.tgz#9036085c7c6ce455ad45fda411c55ff39c06eb95" integrity sha512-iHvFHPGqgJMNqXJoQpqttfsv2GI3cGodeTq4aoVLU/BT3+hXzbV0x1VpvvEhncJkDgDicJpFLM8sEPHb3b8abw== -"@sentry/cli-win32-i686@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.42.4.tgz#0de663fc574f4bce2057e099c5b76b65f99a3bd6" - integrity sha512-vZuR3UPHKqOMniyrijrrsNwn9usaRysXq78F6WV0cL0ZyPLAmY+KBnTDSFk1Oig2pURnzaTm+RtcZu2fc8mlzg== +"@sentry/cli-win32-i686@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-win32-i686/-/cli-win32-i686-2.45.0.tgz#201075c4aec37a3e797160e0b468641245437f0c" + integrity sha512-8mMoDdlwxtcdNIMtteMK7dbi7054jak8wKSHJ5yzMw8UmWxC5thc/gXBc1uPduiaI56VjoJV+phWHBKCD+6I4w== "@sentry/cli-win32-x64@2.42.2": version "2.42.2" resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.42.2.tgz#7d6464b63f32c9f97fff428f246b1f039b402233" integrity sha512-vPPGHjYoaGmfrU7xhfFxG7qlTBacroz5NdT+0FmDn6692D8IvpNXl1K+eV3Kag44ipJBBeR8g1HRJyx/F/9ACw== -"@sentry/cli-win32-x64@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.42.4.tgz#f572a03084f3b1a4f355c1fbeb1339cb56ad91c9" - integrity sha512-OIBj3uaQ6nAERSm5Dcf8UIhyElEEwMNsZEEppQpN4IKl0mrwb/57AznM23Dvpu6GR8WGbVQUSolt879YZR5E9g== +"@sentry/cli-win32-x64@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli-win32-x64/-/cli-win32-x64-2.45.0.tgz#2075e9e1ea3c3609e0fa1a758ca033e94e1c600f" + integrity sha512-ZvK9cIqFaq7vZ0jkHJ/xh5au6902Dr+AUxSk6L6vCL7JCe2p93KGL/4d8VFB5PD/P7Y9b+105G/e0QIFKzpeOw== "@sentry/cli@2.42.2": version "2.42.2" @@ -6526,10 +6541,10 @@ "@sentry/cli-win32-i686" "2.42.2" "@sentry/cli-win32-x64" "2.42.2" -"@sentry/cli@2.42.4": - version "2.42.4" - resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.42.4.tgz#df6ac3e92a60a715b231873433894ed77e601086" - integrity sha512-BoSZDAWJiz/40tu6LuMDkSgwk4xTsq6zwqYoUqLU3vKBR/VsaaQGvu6EWxZXORthfZU2/5Agz0+t220cge6VQw== +"@sentry/cli@2.45.0": + version "2.45.0" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-2.45.0.tgz#35feed7a2fee54faf25daed73001a2a2a3143396" + integrity sha512-4sWu7zgzgHAjIxIjXUA/66qgeEf5ZOlloO+/JaGD5qXNSW0G7KMTR6iYjReNKMgdBCTH6bUUt9qiuA+Ex9Masw== dependencies: https-proxy-agent "^5.0.0" node-fetch "^2.6.7" @@ -6537,27 +6552,28 @@ proxy-from-env "^1.1.0" which "^2.0.2" optionalDependencies: - "@sentry/cli-darwin" "2.42.4" - "@sentry/cli-linux-arm" "2.42.4" - "@sentry/cli-linux-arm64" "2.42.4" - "@sentry/cli-linux-i686" "2.42.4" - "@sentry/cli-linux-x64" "2.42.4" - "@sentry/cli-win32-i686" "2.42.4" - "@sentry/cli-win32-x64" "2.42.4" + "@sentry/cli-darwin" "2.45.0" + "@sentry/cli-linux-arm" "2.45.0" + "@sentry/cli-linux-arm64" "2.45.0" + "@sentry/cli-linux-i686" "2.45.0" + "@sentry/cli-linux-x64" "2.45.0" + "@sentry/cli-win32-arm64" "2.45.0" + "@sentry/cli-win32-i686" "2.45.0" + "@sentry/cli-win32-x64" "2.45.0" "@sentry/core@8.54.0": version "8.54.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-8.54.0.tgz#a2ebec965cadcb6de89e116689feeef79d5862a6" integrity sha512-03bWf+D1j28unOocY/5FDB6bUHtYlm6m6ollVejhg45ZmK9iPjdtxNWbrLsjT1WRym0Tjzowu+A3p+eebYEv0Q== -"@sentry/react-native@~6.10.0": - version "6.10.0" - resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-6.10.0.tgz#9efafb9b85870bd4c5189763edde30709b9f3213" - integrity sha512-B56vc+pnFHMiu3cabFb454v4qD0zObW6JVzJ5Gb6fIMdt93AFIJg10ZErzC+ump7xM4BOEROFFRuLiyvadvlPA== +"@sentry/react-native@~6.14.0": + version "6.14.0" + resolved "https://registry.yarnpkg.com/@sentry/react-native/-/react-native-6.14.0.tgz#bc6bdaf03860bb8946f8c30570a9abd82ed6cfc0" + integrity sha512-BBqixN6oV6tCNp1ABXfzvD531zxj1fUAH0HDPvOR/jX0h9f9pYfxCyI64B+DoQbVZKFsg8nte0QIHkZDhRAW9A== dependencies: - "@sentry/babel-plugin-component-annotate" "3.2.2" + "@sentry/babel-plugin-component-annotate" "3.4.0" "@sentry/browser" "8.54.0" - "@sentry/cli" "2.42.4" + "@sentry/cli" "2.45.0" "@sentry/core" "8.54.0" "@sentry/react" "8.54.0" "@sentry/types" "8.54.0" @@ -8731,6 +8747,33 @@ babel-preset-expo@~13.1.11: react-refresh "^0.14.2" resolve-from "^5.0.0" +babel-preset-expo@~13.2.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-expo/-/babel-preset-expo-13.2.0.tgz#d4540009d07242e3c3d63184b7a34efda95e8e64" + integrity sha512-oNUeUZPMNRPmx/2jaKJLSQFP/MFI1M91vP+Gp+j8/FPl9p/ps603DNwCaRdcT/Vj3FfREdlIwRio1qDCjY0oAA== + dependencies: + "@babel/helper-module-imports" "^7.25.9" + "@babel/plugin-proposal-decorators" "^7.12.9" + "@babel/plugin-proposal-export-default-from" "^7.24.7" + "@babel/plugin-syntax-export-default-from" "^7.24.7" + "@babel/plugin-transform-export-namespace-from" "^7.25.9" + "@babel/plugin-transform-flow-strip-types" "^7.25.2" + "@babel/plugin-transform-modules-commonjs" "^7.24.8" + "@babel/plugin-transform-object-rest-spread" "^7.24.7" + "@babel/plugin-transform-parameters" "^7.24.7" + "@babel/plugin-transform-private-methods" "^7.24.7" + "@babel/plugin-transform-private-property-in-object" "^7.24.7" + "@babel/plugin-transform-runtime" "^7.24.7" + "@babel/preset-react" "^7.22.15" + "@babel/preset-typescript" "^7.23.0" + "@react-native/babel-preset" "0.79.3" + babel-plugin-react-native-web "~0.19.13" + babel-plugin-syntax-hermes-parser "^0.25.1" + babel-plugin-transform-flow-enums "^0.0.2" + debug "^4.3.4" + react-refresh "^0.14.2" + resolve-from "^5.0.0" + babel-preset-jest@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" @@ -8749,11 +8792,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-64@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" - integrity sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA== - base64-arraybuffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc" @@ -8960,6 +8998,16 @@ browserslist@^4.24.0, browserslist@^4.24.2: node-releases "^2.0.18" update-browserslist-db "^1.1.1" +browserslist@^4.25.0: + version "4.25.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c" + integrity sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA== + dependencies: + caniuse-lite "^1.0.30001718" + electron-to-chromium "^1.5.160" + node-releases "^2.0.19" + update-browserslist-db "^1.1.3" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -9102,6 +9150,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001587, can resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz" integrity sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ== +caniuse-lite@^1.0.30001718: + version "1.0.30001722" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001722.tgz#ec25a2b3085b25b9079b623db83c22a70882ce85" + integrity sha512-DCQHBBZtiK6JVkAGw7drvAMK0Q0POD/xZvEmDp6baiMMP6QXXk9HpD6mNYBZWhOPG6LvIDb82ITqtWjhDckHCA== + cbor-extract@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/cbor-extract/-/cbor-extract-2.1.1.tgz#f154b31529fdb6b7c70fb3ca448f44eda96a1b42" @@ -10340,6 +10393,11 @@ electron-to-chromium@^1.4.668: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.777.tgz#f846fbba23fd11b3c6f97848cdda94896fdb8baf" integrity sha512-n02NCwLJ3wexLfK/yQeqfywCblZqLcXphzmid5e8yVPdtEcida7li0A5WQKghHNG0FeOMCzeFOzEbtAh5riXFw== +electron-to-chromium@^1.5.160: + version "1.5.166" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.166.tgz#3fff386ed473cc2169dbe2d3ace9592262601114" + integrity sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw== + electron-to-chromium@^1.5.41: version "1.5.51" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz#bb99216fed4892d131a8585a8593b00739310163" @@ -11146,18 +11204,18 @@ expo-application@~6.1.4: resolved "https://registry.yarnpkg.com/expo-application/-/expo-application-6.1.4.tgz#34ee2f7a86e3689f15961b296e82934e0f85afd6" integrity sha512-jXVZb3llTQ5j4C/I03GxKjujmhKex9Xo5JDZo/pRjScHSr4NoeMjPKWThyWVlWDM1v5YSEcsRJebVfTvq9SR5Q== -expo-asset@~11.1.4: - version "11.1.4" - resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-11.1.4.tgz#0258156f76c306521eb2a0d27e98d26258d12ad9" - integrity sha512-e3210sF0YHKRTCjVUOVmDAJ0Dk4vepL9RocKe36S7S+VthoCZwsBGLAM2LLvBa1SdmODF92AS0Nrcfi/1/VlbQ== +expo-asset@~11.1.5: + version "11.1.5" + resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-11.1.5.tgz#5cad3d781c9d0edec31b9b3adbba574eb4d5dd3e" + integrity sha512-GEQDCqC25uDBoXHEnXeBuwpeXvI+3fRGvtzwwt0ZKKzWaN+TgeF8H7c76p3Zi4DfBMFDcduM0CmOvJX+yCCLUQ== dependencies: "@expo/image-utils" "^0.7.4" - expo-constants "~17.1.4" + expo-constants "~17.1.5" -expo-blur@~14.1.4: - version "14.1.4" - resolved "https://registry.yarnpkg.com/expo-blur/-/expo-blur-14.1.4.tgz#d246c0a224ce63321d022edfc0e6a8c5fa2cc865" - integrity sha512-55P9tK/RjJZEcu2tU7BqX3wmIOrGMOOkmHztJMMws+ZGHzvtjnPmT7dsQxhOU9vPj77oHnKetYHU2sik3iBcCw== +expo-blur@~14.1.5: + version "14.1.5" + resolved "https://registry.yarnpkg.com/expo-blur/-/expo-blur-14.1.5.tgz#910712389e19286ccdc136275bf569f427aa05ef" + integrity sha512-CCLJHxN4eoAl06ESKT3CbMasJ98WsjF9ZQEJnuxtDb9ffrYbZ+g9ru84fukjNUOTtc8A8yXE5z8NgY1l0OMrmQ== expo-build-properties@~0.14.6: version "0.14.6" @@ -11167,10 +11225,10 @@ expo-build-properties@~0.14.6: ajv "^8.11.0" semver "^7.6.0" -expo-camera@~16.1.6: - version "16.1.6" - resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-16.1.6.tgz#9badbc3b93cab3386e3e70721d4f3c1983ab539c" - integrity sha512-caVSfoTUaayYhH5gicrXWCgBQIVrotPOH3jUDr4vhN5VQDB/+TWaY+le2nQtNXgQEz14Af+H/TNvYpvvNj5Ktg== +expo-camera@~16.1.8: + version "16.1.8" + resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-16.1.8.tgz#6c30dfb5c982795351f1053c36f048a11869e21b" + integrity sha512-NpBbkUhHG6cs2TNUQBFSEtXb5j1/kTPIhiuqBcHosZG2yb/8MuM/ii4McJaqfe/6pn0YPqkH4k0Uod11DOSLmw== dependencies: invariant "^2.2.4" @@ -11179,7 +11237,7 @@ expo-clipboard@~7.1.4: resolved "https://registry.yarnpkg.com/expo-clipboard/-/expo-clipboard-7.1.4.tgz#f2cda0d3cbfd2d307aa85dd7ba6843d6bbaf4227" integrity sha512-NHhfKnrzb4o0PacUKD93ByadU0JmPBoFTFYbbFJZ9OAX6SImpSqG5gfrMUR3vVj4Qx9f1LpMcdAv5lBzv868ow== -expo-constants@17.0.3, expo-constants@^13.0.2, expo-constants@~17.1.4, expo-constants@~17.1.5: +expo-constants@17.0.3, expo-constants@^13.0.2, expo-constants@~17.1.5, expo-constants@~17.1.6: version "17.0.3" resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-17.0.3.tgz#a05b38e0417d59759ece1642b4d483889e04dbda" integrity sha512-lnbcX2sAu8SucHXEXxSkhiEpqH+jGrf+TF+MO6sHWIESjwOUVVYlT8qYdjR9xbxWmqFtrI4KV44FkeJf2DaFjQ== @@ -11187,25 +11245,25 @@ expo-constants@17.0.3, expo-constants@^13.0.2, expo-constants@~17.1.4, expo-cons "@expo/config" "~10.0.4" "@expo/env" "~0.4.0" -expo-dev-client@~5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-5.1.7.tgz#b75d5c4650a2b19e8d5c4666a798a4150a7fbd68" - integrity sha512-/xcwNIeZIBA/y6Io7jv1ZbEG8XRUuAynIJyIGJvpMxf6hm7eEw8rEzhO9rZNk6H8bMjTjASs0Vf1bqIV6v3j6A== +expo-dev-client@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-5.2.0.tgz#a3d4f8c79fafe747ea8d0bfc6e3918b02011025c" + integrity sha512-7GgO3BGlFM016Zkp3c9bUbi35pubqKh8Z/iHC1arIvckEjDrLER+92zfUTFr49XLk2o64arItRPJyQL49pA/hg== dependencies: - expo-dev-launcher "5.1.10" - expo-dev-menu "6.1.9" + expo-dev-launcher "5.1.12" + expo-dev-menu "6.1.11" expo-dev-menu-interface "1.10.0" - expo-manifests "~0.16.4" + expo-manifests "~0.16.5" expo-updates-interface "~1.1.0" -expo-dev-launcher@5.1.10: - version "5.1.10" - resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-5.1.10.tgz#eaa8a7a4edcab557e6623f176e60d964606651ff" - integrity sha512-OW4k0efB6cWigYj1GlJGObMuMpg6DIwsAZkECsGqNU3U80zE7pBMPB0sy1xehFuTplO6F+dCTLg0hPPuqkSsTg== +expo-dev-launcher@5.1.12: + version "5.1.12" + resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-5.1.12.tgz#cad239327e258d84c4221a212ecd30a051f9097d" + integrity sha512-ALedYerjJtSiPa95l41zMAO/m1m1kgS39i2H0io+6Ix4OksYNhILNzMNB1qDht/oWt2yjLBvXfWULfs5+3vnaA== dependencies: ajv "8.11.0" - expo-dev-menu "6.1.8" - expo-manifests "~0.16.4" + expo-dev-menu "6.1.11" + expo-manifests "~0.16.5" resolve-from "^5.0.0" expo-dev-menu-interface@1.10.0: @@ -11213,28 +11271,14 @@ expo-dev-menu-interface@1.10.0: resolved "https://registry.yarnpkg.com/expo-dev-menu-interface/-/expo-dev-menu-interface-1.10.0.tgz#04671bda3c163d1d7b9438ce7095c3913a3f53f9" integrity sha512-NxtM/qot5Rh2cY333iOE87dDg1S8CibW+Wu4WdLua3UMjy81pXYzAGCZGNOeY7k9GpNFqDPNDXWyBSlk9r2pBg== -expo-dev-menu@6.1.8: - version "6.1.8" - resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-6.1.8.tgz#cec53379b76f5cb53e2e87a8c62555610a26e6bb" - integrity sha512-i8DW1OXvj4yxQuPP8p2AMGoYdnyhfTkoqWI/AiDYReh2viZv4kZlRloGAemV2bIQwswMq2GsvZehYrQPEK9QBw== +expo-dev-menu@6.1.11: + version "6.1.11" + resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-6.1.11.tgz#829118326bcd618aec3941cfbb5b32fd3dd72379" + integrity sha512-yrlDXGcqlbQX3Pgw/iPLRea7+pHFC17MdtkNaXYQ5K5u64mn9l4KZ2ZYUeQ8cKDG5l8ZdC4F9R9vfCJYFi82AA== dependencies: expo-dev-menu-interface "1.10.0" -expo-dev-menu@6.1.9: - version "6.1.9" - resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-6.1.9.tgz#897dcb4c49aed9c1f871b13e1359079f23981050" - integrity sha512-Uz02Bsc1xsYzjW4Ld+PxWLRNkbsoJYSbQtw/pZDSrJk5Hj869M4KQSOI8JpZ7WVlKEKkIRA8kBLepjhdFhq+Dg== - dependencies: - expo-dev-menu-interface "1.10.0" - -expo-device@7.0.1, expo-device@~4.1.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-7.0.1.tgz#3702fe8b4475eac63ed27f9d580ec8a78546e0d1" - integrity sha512-/3lk0f9wvle+6svHqWSCBC1B5NYFmXp1D7hmIyecJJVYRLwzrwwTDyNs76oG/UDU5Appdu8QyDKycsx2hqv71w== - dependencies: - ua-parser-js "^0.7.33" - -expo-device@~7.1.4: +expo-device@7.1.4, expo-device@~4.1.1, expo-device@~7.1.4: version "7.1.4" resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-7.1.4.tgz#84ae7c2520cc45f15a9cb0433ae1226c33f7a8ef" integrity sha512-HS04IiE1Fy0FRjBLurr9e5A6yj3kbmQB+2jCZvbSGpsjBnCLdSk/LCii4f5VFhPIBWJLyYuN5QqJyEAw6BcS4Q== @@ -11246,15 +11290,15 @@ expo-eas-client@~0.14.3: resolved "https://registry.yarnpkg.com/expo-eas-client/-/expo-eas-client-0.14.3.tgz#3fc22378cc454953ecba88f70c16c20a74e0aa27" integrity sha512-BW2mSNEjFRFC8/CbkMQ3mfVhBdeZIjZhNfncw7PP80xEptLWhVjGTqwG8Usi0/yPpIu/YNYgop+XGMfhXyh9uA== -expo-file-system@~18.1.8: - version "18.1.8" - resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-18.1.8.tgz#caa0831b9826f568be36deb25aed835978e957b3" - integrity sha512-1HXpunpRMGnoIw0+f2urjUNaePAvac1X9wIwVRsGJTw7A2WHBFATRuFB7jUOhZac/qK1MDm0GZsggzoRi1oteQ== +expo-file-system@~18.1.10: + version "18.1.10" + resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-18.1.10.tgz#22f3bcc2c9a7edcd6bba5ece3c90a8467fda47be" + integrity sha512-SyaWg+HitScLuyEeSG9gMSDT0hIxbM9jiZjSBP9l9zMnwZjmQwsusE6+7qGiddxJzdOhTP4YGUfvEzeeS0YL3Q== -expo-font@~13.3.0: - version "13.3.0" - resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-13.3.0.tgz#139e6e1024e414afe1180ffed0add98aa8c8950b" - integrity sha512-TdbHoxCfLWN9Uvnqsrcak+5EkDCbNIWfgtNWx3JZ6sD9WYB7gvbS+Eu5YlZ85NvCOSJ9Khmw4mFQxEi2LUPZfQ== +expo-font@~13.3.1: + version "13.3.1" + resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-13.3.1.tgz#ed69ae14f263a4c447efb2615b60d9e045372e68" + integrity sha512-d+xrHYvSM9WB42wj8vP9OOFWyxed5R1evphfDb6zYBmC1dA9Hf89FpT7TNFtj2Bk3clTnpmVqQTCYbbA2P3CLg== dependencies: fontfaceobserver "^2.1.0" @@ -11273,10 +11317,10 @@ expo-image-loader@~5.1.0: resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-5.1.0.tgz#f7d65f9b9a9714eaaf5d50a406cb34cb25262153" integrity sha512-sEBx3zDQIODWbB5JwzE7ZL5FJD+DK3LVLWBVJy6VzsqIA6nDEnSFnsnWyCfCTSvbGigMATs1lgkC2nz3Jpve1Q== -expo-image-manipulator@~13.1.5: - version "13.1.5" - resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-13.1.5.tgz#d657dceeb8ce8da9345a1903f1327b0fedfd08c1" - integrity sha512-V9cGJp0zVwAvAyL3w9JsLH8UEQjQZfFmwJM1l9/oXjlDrSDynQrPFwJq4VI8dCOJ+/nhYZK37yytFNG14Sqt4Q== +expo-image-manipulator@~13.1.7: + version "13.1.7" + resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-13.1.7.tgz#e891ce9b49d75962eafdf5b7d670116583379e76" + integrity sha512-DBy/Xdd0E/yFind14x36XmwfWuUxOHI/oH97/giKjjPaRc2dlyjQ3tuW3x699hX6gAs9Sixj5WEJ1qNf3c8sag== dependencies: expo-image-loader "~5.1.0" @@ -11287,10 +11331,10 @@ expo-image-picker@~16.1.4: dependencies: expo-image-loader "~5.1.0" -expo-image@~2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-2.1.6.tgz#f046fa631768e37326cc14c49de9113ceffa9e8b" - integrity sha512-AFQxeAI1iTXFZ4dMxUB+SOACGMQxEk+t7PvT3j4mrvffRFoOLfHZ4uJc8SAdDFJak7ByqKhCIPIEhL+1Deq4Sg== +expo-image@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-2.2.1.tgz#b4aa706a25f7e8902ac854a8da249caf4a90cd67" + integrity sha512-5ZSggMi0X2G9AN0aM+sdkCyyZ6YcWvGs9KYLYrRBVUN3ph6RBiu6mKGpaNN1TAscySRnH1eHbUE1H+Qeq7qm1g== expo-json-utils@~0.15.0: version "0.15.0" @@ -11302,17 +11346,17 @@ expo-keep-awake@~14.1.4: resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-14.1.4.tgz#80197728563e0e17523e5a606fbd6fbed9639503" integrity sha512-wU9qOnosy4+U4z/o4h8W9PjPvcFMfZXrlUoKTMBW7F4pLqhkkP/5G4EviPZixv4XWFMjn1ExQ5rV6BX8GwJsWA== -expo-linear-gradient@~14.1.4: - version "14.1.4" - resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-14.1.4.tgz#fcb2b586cfd21dd5f3076de467f92b55d9c47cb2" - integrity sha512-bImj2qqIjnl+VHYGnIwan9LxmGvb8e4hFqHpxsPzUiK7Ady7uERrXPhJcyTKTxRf4RL2sQRDpoOKzBYNdQDmuw== +expo-linear-gradient@~14.1.5: + version "14.1.5" + resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-14.1.5.tgz#414bf0c8145089087198d4dd5a419eb324af2a02" + integrity sha512-BSN3MkSGLZoHMduEnAgfhoj3xqcDWaoICgIr4cIYEx1GcHfKMhzA/O4mpZJ/WC27BP1rnAqoKfbclk1eA70ndQ== -expo-linking@~7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-7.1.4.tgz#7d398d99788d8d95b67d1ae463d24686cbeb1c1b" - integrity sha512-zLAbUzTB3+KGjqqLeIdhhkXayyN0qulHGjRI24X7W/0Mq/4oPbPZklKtCP0k7XOn/k4553m8OgJ7GPC03PlV9g== +expo-linking@~7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-7.1.5.tgz#99633892712d5442ddb1c6c3857346eb7a67119b" + integrity sha512-8g20zOpROW78bF+bLI4a3ZWj4ntLgM0rCewKycPL0jk9WGvBrBtFtwwADJgOiV1EurNp3lcquerXGlWS+SOQyA== dependencies: - expo-constants "~17.1.4" + expo-constants "~17.1.6" invariant "^2.2.4" expo-localization@~16.1.5: @@ -11322,23 +11366,23 @@ expo-localization@~16.1.5: dependencies: rtl-detect "^1.0.2" -expo-manifests@~0.16.4: - version "0.16.4" - resolved "https://registry.yarnpkg.com/expo-manifests/-/expo-manifests-0.16.4.tgz#d1a648bab0068a2712cf49009a5f26377a585849" - integrity sha512-zB6ohgnsNbJDaLI/KRZQXxEHadhMJt+gA4LCqbiZQNa3P4FJq4JFRXPV6QQjgjJ998g9vY7eDCTduxTJYBqUaA== +expo-manifests@~0.16.5: + version "0.16.5" + resolved "https://registry.yarnpkg.com/expo-manifests/-/expo-manifests-0.16.5.tgz#bb57ceff3db4eb74679d4a155b2ca2050375ce10" + integrity sha512-zLUeJogn2C7qOE75Zz7jcmJorMfIbSRR35ctspN0OK/Hq/+PAAptA8p9jNVC8xp/91uP9uI8f3xPhh+A11eR2A== dependencies: - "@expo/config" "~11.0.6" + "@expo/config" "~11.0.10" expo-json-utils "~0.15.0" -expo-media-library@~17.1.6: - version "17.1.6" - resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-17.1.6.tgz#118ada2d28139d540861b338acf1d088bc03d51f" - integrity sha512-Py8Y9wJlNXBZkhtJYy9acj0oRoUV09WXsZnjcvy6xZjpniPQIq0wkIkgS2DLhlYmMdjBrSux2TGp7Omi2WHp1g== +expo-media-library@~17.1.7: + version "17.1.7" + resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-17.1.7.tgz#71ed3d2d246d33410d6aecc335098a23519bd890" + integrity sha512-hLCoMvlhjtt+iYxPe71P1F6t06mYGysuNOfjQzDbbf64PCkglCZJYmywPyUSV1V5Hu9DhRj//gEg+Ki+7VWXog== -expo-modules-autolinking@2.1.9: - version "2.1.9" - resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-2.1.9.tgz#7bf8338d4b7a1b6e8eccab51634de9b339e90c04" - integrity sha512-54InfnWy1BR54IDZoawqdFAaF2lyLHe9J+2dZ7y91/36jVpBtAval39ZKt2IISFJZ7TVglsojl4P5BDcDGcvjQ== +expo-modules-autolinking@2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-2.1.11.tgz#efc2e756ccc8b9e0b927596ba074aefe31b5cbe4" + integrity sha512-KrWQo+cE4gWYNePBBhmHGVzf63gYV19ZLXe9EIH3GHTkViVzIX+Lp618H/7GxfawpN5kbhvilATH1QEKKnUUww== dependencies: "@expo/spawn-async" "^1.7.2" chalk "^4.1.0" @@ -11348,10 +11392,10 @@ expo-modules-autolinking@2.1.9: require-from-string "^2.0.2" resolve-from "^5.0.0" -expo-modules-core@2.3.12: - version "2.3.12" - resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-2.3.12.tgz#1c06402564c02b32f192adfe6946e671d8a95e79" - integrity sha512-bOm83mskw1S7xuDX50DlLdx68u0doQ6BZHSU2qTv8P1/5QYeAae3pCgFLq2hoptUNeMF7W+68ShJFTOHAe68BQ== +expo-modules-core@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-2.4.0.tgz#3081d62fadff913090cc5abfe46d9ec6b0e75789" + integrity sha512-Ko5eHBdvuMykjw9P9C9PF54/wBSsGOxaOjx92I5BwgKvEmUwN3UrXFV4CXzlLVbLfSYUQaLcB220xmPfgvT7Fg== dependencies: invariant "^2.2.4" @@ -11362,10 +11406,10 @@ expo-modules-core@^2.1.1: dependencies: invariant "^2.2.4" -expo-notifications@~0.31.1: - version "0.31.1" - resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.31.1.tgz#3be669ab78c6099d82f4fc3607f77f7d9e1805b6" - integrity sha512-g1CMi+3wUaMuX+tAU+Fhnfs5bJtJ3JVRXihO415aOInQkox+Mh79n38RlT6snLWCHjfSojQIxmydzUHt6ywTIQ== +expo-notifications@~0.31.3: + version "0.31.3" + resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.31.3.tgz#eb82c9975e26dcc4fa694b79970792c897ad8d16" + integrity sha512-AATxKoav5ZvwcRel2SKYNZc+EvOAKvAjxyBezC8y3J5fMNe/uKIhMzh3FN4fKdOi9ao/UBHkvLiUO2MqVnvBNg== dependencies: "@expo/image-utils" "^0.7.4" "@ide/backoff" "^1.0.0" @@ -11373,7 +11417,7 @@ expo-notifications@~0.31.1: assert "^2.0.0" badgin "^1.1.5" expo-application "~6.1.4" - expo-constants "~17.1.4" + expo-constants "~17.1.6" expo-pwa@0.0.127: version "0.0.127" @@ -11385,34 +11429,34 @@ expo-pwa@0.0.127: commander "2.20.0" update-check "1.5.3" -expo-screen-orientation@~8.1.5: - version "8.1.5" - resolved "https://registry.yarnpkg.com/expo-screen-orientation/-/expo-screen-orientation-8.1.5.tgz#447c19b8ad59d1d2cf0894900ee273836367ca0d" - integrity sha512-t2ss7a52f1VNrugmIYj1wlnGICUgrkqu2+J3Csew8ixczI8s6r6EXT4E4EeyQ/9WvcEUOOyh8TWC9EbbswPhUw== +expo-screen-orientation@~8.1.7: + version "8.1.7" + resolved "https://registry.yarnpkg.com/expo-screen-orientation/-/expo-screen-orientation-8.1.7.tgz#3751b441f2bfcbde798b1508c0ff9f099f4be911" + integrity sha512-nYwadYtdU6mMDk0MCHMPPPQtBoeFYJ2FspLRW+J35CMLqzE4nbpwGeiImfXzkvD94fpOCfI4KgLj5vGauC3pfA== expo-sharing@~13.1.5: version "13.1.5" resolved "https://registry.yarnpkg.com/expo-sharing/-/expo-sharing-13.1.5.tgz#73d86cdcc037b46ddc82be224dfd3d6bceec497c" integrity sha512-X/5sAEiWXL2kdoGE3NO5KmbfcmaCWuWVZXHu8OQef7Yig4ZgHFkGD11HKJ5KqDrDg+SRZe4ISd6MxE7vGUgm4w== -expo-splash-screen@~0.30.8: - version "0.30.8" - resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.30.8.tgz#2e960ccff053bc8ace85eb56f7d6745e4ddfc6b6" - integrity sha512-2eh+uA543brfeG5HILXmtNKA7E2/pfywKzNumzy3Ef6OtDjYy6zJUGNSbhnZRbVEjUZo3/QNRs0JRBfY80okZg== +expo-splash-screen@~0.30.9: + version "0.30.9" + resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.30.9.tgz#8f2a86b3b802ea46065fc761ed60e77e81bdb84c" + integrity sha512-curHUaZxUTZ2dWvz32ao3xPv5mJr1LBqn5V8xm/IULAehB9RGCn8iKiROMN1PYebSG+56vPMuJmBm9P+ayvJpA== dependencies: - "@expo/prebuild-config" "^9.0.5" + "@expo/prebuild-config" "^9.0.6" expo-structured-headers@~4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/expo-structured-headers/-/expo-structured-headers-4.1.0.tgz#5475fc3f9559701cc755fd2d50605f8817d42ad0" integrity sha512-2X+aUNzC/qaw7/WyUhrVHNDB0uQ5rE12XA2H/rJXaAiYQSuOeU90ladaN0IJYV9I2XlhYrjXLktLXWbO7zgbag== -expo-system-ui@~5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-5.0.7.tgz#ccf047a689ab488d9bcda375afd063419578f494" - integrity sha512-ijSnSFA4VfuQc84N6WyCUNsKKTIyQb6QuC8q2zGvYC/sBXTMrOtZg0zrisQGzCRW+WhritQTiVqHlp3Ix9xDmQ== +expo-system-ui@~5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-5.0.8.tgz#1eaaa95cfa8b5e20750e5fb30918635a58276199" + integrity sha512-2sI7ALq3W8sKKa3FRW7PmuNznk+48cb1VzFy96vYZLZgTDZViz+fEJNdp1RHgLui/mAl3f8md1LneygSJvZ1EQ== dependencies: - "@react-native/normalize-colors" "0.79.2" + "@react-native/normalize-colors" "0.79.3" debug "^4.3.2" expo-task-manager@~13.1.5: @@ -11427,55 +11471,55 @@ expo-updates-interface@~1.1.0: resolved "https://registry.yarnpkg.com/expo-updates-interface/-/expo-updates-interface-1.1.0.tgz#62497d4647b381da9fdb68868ed180203ae737ef" integrity sha512-DeB+fRe0hUDPZhpJ4X4bFMAItatFBUPjw/TVSbJsaf3Exeami+2qbbJhWkcTMoYHOB73nOIcaYcWXYJnCJXO0w== -expo-updates@~0.28.12: - version "0.28.12" - resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.28.12.tgz#abf6e0c593837b20af64feee31aa018e1a85b332" - integrity sha512-GUQNI7apaQa8mVLGyeUQZsSaY75lq3yIp2OO+gX0BZIeD5hr8ADZ0Gw2+9+uRSB70B7AWQklUCMBxvOsA2DVfg== +expo-updates@~0.28.14: + version "0.28.14" + resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.28.14.tgz#bc75b00c0744fec33ba36f8c96e7c86ed0d3c7f6" + integrity sha512-kxI428W7LGSdDWmN/ud5cIg8+SjmQ5XSaUrYauZ0DKsHm2qq1Lh+NYSUWLvYmps+Baalafe6mILmAX8ZnNg26Q== dependencies: "@expo/code-signing-certificates" "0.0.5" - "@expo/config" "~11.0.7" + "@expo/config" "~11.0.10" "@expo/config-plugins" "~10.0.2" "@expo/spawn-async" "^1.7.2" arg "4.1.0" chalk "^4.1.2" expo-eas-client "~0.14.3" - expo-manifests "~0.16.4" + expo-manifests "~0.16.5" expo-structured-headers "~4.1.0" expo-updates-interface "~1.1.0" glob "^10.4.2" ignore "^5.3.1" resolve-from "^5.0.0" -expo-video@~2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/expo-video/-/expo-video-2.1.8.tgz#507305ae2ea18f435a51ababd6b2dec21291d328" - integrity sha512-OEToLVEGLvfTq7ypjgOf1DUNGHLGxUiL/1K6WHwdew5tgFxiLBZesGQhKToyrSVPVmWaxMBSP4sQuwtTjWUpHg== +expo-video@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/expo-video/-/expo-video-2.2.1.tgz#d45357ee7a7da5a87c49177587183d1c7feabc57" + integrity sha512-dw3h0eMLK8WpY1Tnwsgrxx3sFqXiOujmurjGdr+RFG63ZurAze/H9uuKMVl3ps/ZNuK4q/2ifIiJudoFJfwKwA== expo-web-browser@~14.1.6: version "14.1.6" resolved "https://registry.yarnpkg.com/expo-web-browser/-/expo-web-browser-14.1.6.tgz#26d66e641e6e96d155be6fa513e7e667a719a0b0" integrity sha512-/4P8eWqRyfXIMZna3acg320LXNA+P2cwyEVbjDX8vHnWU+UnOtyRKWy3XaAIyMPQ9hVjBNUQTh4MPvtnPRzakw== -expo@^53.0.5: - version "53.0.5" - resolved "https://registry.yarnpkg.com/expo/-/expo-53.0.5.tgz#f8c30643c4e45d769934415ea9196531612cb657" - integrity sha512-A9nh7ojGcdsv05TCH39q/7RRQsTfgcQ3qD2CFzlADVW8jIIFNiIg80shE8DQiXHkeCKWT78Iy7iog2yIu4sq3Q== +expo@53.0.11: + version "53.0.11" + resolved "https://registry.yarnpkg.com/expo/-/expo-53.0.11.tgz#66053862520ce2a6700d13346ebaf8210a68f24b" + integrity sha512-+QtvU+6VPd7/o4vmtwuRE/Li2rAiJtD25I6BOnoQSxphaWWaD0PdRQnIV3VQ0HESuJYRuKJ3DkAHNJ3jI6xwzA== dependencies: "@babel/runtime" "^7.20.0" - "@expo/cli" "0.24.10" - "@expo/config" "~11.0.7" + "@expo/cli" "0.24.14" + "@expo/config" "~11.0.10" "@expo/config-plugins" "~10.0.2" - "@expo/fingerprint" "0.12.4" - "@expo/metro-config" "0.20.12" + "@expo/fingerprint" "0.13.0" + "@expo/metro-config" "0.20.14" "@expo/vector-icons" "^14.0.0" - babel-preset-expo "~13.1.11" - expo-asset "~11.1.4" - expo-constants "~17.1.5" - expo-file-system "~18.1.8" - expo-font "~13.3.0" + babel-preset-expo "~13.2.0" + expo-asset "~11.1.5" + expo-constants "~17.1.6" + expo-file-system "~18.1.10" + expo-font "~13.3.1" expo-keep-awake "~14.1.4" - expo-modules-autolinking "2.1.9" - expo-modules-core "2.3.12" + expo-modules-autolinking "2.1.11" + expo-modules-core "2.4.0" react-native-edge-to-edge "1.6.0" whatwg-url-without-unicode "8.0.0-3" @@ -12055,6 +12099,11 @@ getenv@^1.0.0: resolved "https://registry.yarnpkg.com/getenv/-/getenv-1.0.0.tgz#874f2e7544fbca53c7a4738f37de8605c3fcfc31" integrity sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg== +getenv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/getenv/-/getenv-2.0.0.tgz#b1698c7b0f29588f4577d06c42c73a5b475c69e0" + integrity sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ== + github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" @@ -12079,18 +12128,6 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" - integrity sha512-f8c0rE8JiCxpa52kWPAOa3ZaYEnzofDzCQLCn3Vdk0Z5OVLq3BsRFJI4S4ykpeVW6QMGBUkMeUpoEgWnMTnw5Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^10.3.10: version "10.3.12" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" @@ -13469,12 +13506,12 @@ jest-environment-node@^29.7.0: jest-mock "^29.7.0" jest-util "^29.7.0" -jest-expo@~53.0.3: - version "53.0.3" - resolved "https://registry.yarnpkg.com/jest-expo/-/jest-expo-53.0.3.tgz#094da673d5b7953565c4cc6c41af4337465ddfc9" - integrity sha512-aOJyy/i0wPAWrQpSVNTTFWjcNTbUE/0eXr2cpdM3WW57K3EB1sueuKj8j2tWlzeKz4bk3+DVRy8K44V/XMoy3Q== +jest-expo@~53.0.7: + version "53.0.7" + resolved "https://registry.yarnpkg.com/jest-expo/-/jest-expo-53.0.7.tgz#ab1c288940dcdf470c25b7b18e2ed99f03d26bc6" + integrity sha512-Uiu3ES0sWbsxpifQuBzXMI1/N9JygfJfwEby/Qw/OPndIQ1YeeIQqkbP52xn6UhdSM4qYQiteX3EjY8TfrZIoA== dependencies: - "@expo/config" "~11.0.7" + "@expo/config" "~11.0.10" "@expo/json-file" "^9.1.4" "@jest/create-cache-key-function" "^29.2.1" "@jest/globals" "^29.2.1" @@ -14061,10 +14098,10 @@ kysely@^0.23.4: resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.23.5.tgz#60c63d94e1c42cc0411be8aaa688a0f27405f514" integrity sha512-TH+b56pVXQq0tsyooYLeNfV11j6ih7D50dyN8tkM0e7ndiUH28Nziojiog3qRFlmEj9XePYdZUrNJ2079Qjdow== -lan-network@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/lan-network/-/lan-network-0.1.5.tgz#e781889b7bd4dbedd9126fff3ceddd809a83c3ff" - integrity sha512-CV3k7l8jW0Z1b+G41tB7JInVyJEKQzh/YPl2v9uXpZMusp0aa+rh3OqG77xWuX7+eVBa8PsdTuMznTAssF4qwg== +lan-network@^0.1.6: + version "0.1.7" + resolved "https://registry.yarnpkg.com/lan-network/-/lan-network-0.1.7.tgz#9fcb9967c6d951f10b2f9a9ffabe4a312d63f69d" + integrity sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ== lande@^1.0.10: version "1.0.10" @@ -14846,7 +14883,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -15097,6 +15134,11 @@ node-releases@^2.0.18: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +node-releases@^2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" + integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== + nodemailer-html-to-text@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/nodemailer-html-to-text/-/nodemailer-html-to-text-3.2.0.tgz#91b959491fef8f7d91796047abb728aa86d4a12b" @@ -15755,7 +15797,7 @@ picocolors@^1.0.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== -picocolors@^1.1.0: +picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -16770,7 +16812,7 @@ react-keyed-flatten-children@^5.0.0: resolved "https://registry.yarnpkg.com/react-keyed-flatten-children/-/react-keyed-flatten-children-5.0.0.tgz#3024fc8819f7b60fc5039b527f133d9ac3a02a82" integrity sha512-XA5ah02sZAeDrbz4Lusd4acqG5q5BtVwPHWierruVhrgX6CMCldbGcTZZM14cQZ+GWq+tzRzEpsCvnTtLODvjw== -react-native-compressor@1.11.0: +react-native-compressor@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/react-native-compressor/-/react-native-compressor-1.11.0.tgz#e297fa650b09cc754392153c38ae2ca510aee024" integrity sha512-XaI0U2CtlW6ZYjwdQ4jdpnJa3C9CD1pc1a4jiUMtnUxWtCqgT7PNjOiEqlYLLwwGTvorXXNuby5In1yy7Vdmhg== @@ -16787,20 +16829,13 @@ react-native-dotenv@^3.4.11: dependencies: dotenv "^16.4.5" -react-native-drawer-layout@^4.1.10: +react-native-drawer-layout@^4.1.10, react-native-drawer-layout@^4.1.8: version "4.1.10" resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-4.1.10.tgz#9007cb747767ca8e1c9c3337671ad35ed95ad4d9" integrity sha512-wejQo0F+EffCkOkRh+DP6ENWMB+aWEHkXV8Pd564PmtoySZLUsV/ksYrh/mrufh7T7EuvGT8+fNHz7mMRYftWg== dependencies: use-latest-callback "^0.2.3" -react-native-drawer-layout@^4.1.6: - version "4.1.7" - resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-4.1.7.tgz#1c741c9bf9c739d6672201692e4ba4839ca0c8ff" - integrity sha512-KeTGZsNEDbOmgo8ICwr1vBmvWjRrRsvbLc2IAfQnW5h5UtxVZVRxY4QaN84BSBQPXm6tQ6AXfII8TCXCv3c0Ew== - dependencies: - use-latest-callback "^0.2.3" - react-native-edge-to-edge@1.6.0, react-native-edge-to-edge@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/react-native-edge-to-edge/-/react-native-edge-to-edge-1.6.0.tgz#2ba63b941704a7f713e298185c26cde4d9e4b973" @@ -16858,10 +16893,10 @@ react-native-mmkv@^2.12.2: resolved "https://registry.yarnpkg.com/react-native-mmkv/-/react-native-mmkv-2.12.2.tgz#4bba0f5f04e2cf222494cce3a9794ba6a4894dee" integrity sha512-6058Aq0p57chPrUutLGe9fYoiDVDNMU2PKV+lLFUJ3GhoHvUrLdsS1PDSCLr00yqzL4WJQ7TTzH+V8cpyrNcfg== -react-native-pager-view@6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.7.1.tgz#60d52dedbcc92ee7037a13287ebeed5f74e49df7" - integrity sha512-cBSr6xw4g5N7Kd3VGWcf+kmaH7iBWb0DXAf2bVo3bXkzBcBbTOmYSvc0LVLHhUPW8nEq5WjT9LCIYAzgF++EXw== +react-native-pager-view@^6.7.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.8.1.tgz#fa0ec09ea7c44190c7c013d75dd09fdc17b96100" + integrity sha512-XIyVEMhwq7sZqM7GobOJZXxFCfdFgVNq/CFB2rZIRNRSVPJqE1k1fsc8xfQKfdzsp6Rpt6I7VOIvhmP7/YHdVg== react-native-progress@bluesky-social/react-native-progress: version "5.0.0" @@ -16895,10 +16930,10 @@ react-native-reanimated@~3.17.5: invariant "^2.2.4" react-native-is-edge-to-edge "1.1.7" -react-native-root-siblings@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/react-native-root-siblings/-/react-native-root-siblings-4.1.1.tgz#b7742db7634a87f507eb99a5fd699c4f10c46ab0" - integrity sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA== +react-native-root-siblings@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/react-native-root-siblings/-/react-native-root-siblings-5.0.1.tgz#97e050e5155228f65810fb1c466ff8e769c5272c" + integrity sha512-Ay3k/fBj6ReUkWX5WNS+oEAcgPLEGOK8n7K/L7D85mf3xvd8rm/b4spsv26E4HlFzluVx5HKbxEt9cl0wQ1u3g== react-native-safe-area-context@5.4.0: version "5.4.0" @@ -16914,10 +16949,10 @@ react-native-screens@^4.11.1: react-native-is-edge-to-edge "^1.1.7" warn-once "^0.1.0" -react-native-svg@15.11.2: - version "15.11.2" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.11.2.tgz#7540e8e1eabc4dcd3b1e35ada5a1d9f1b96d37c4" - integrity sha512-+YfF72IbWQUKzCIydlijV1fLuBsQNGMT6Da2kFlo1sh+LE3BIm/2Q7AR1zAAR6L0BFLi1WaQPLfFUC9bNZpOmw== +react-native-svg@15.12.0: + version "15.12.0" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.12.0.tgz#0e2d476961e8b07f8c549fe4489c99b5130dc150" + integrity sha512-iE25PxIJ6V0C6krReLquVw6R0QTsRTmEQc4K2Co3P6zsimU/jltcDBKYDy1h/5j9S/fqmMeXnpM+9LEWKJKI6A== dependencies: css-select "^5.1.0" css-tree "^1.1.3" @@ -16968,27 +17003,27 @@ react-native-web@~0.20.0: postcss-value-parser "^4.2.0" styleq "^0.1.3" -react-native-webview@13.13.5: - version "13.13.5" - resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.13.5.tgz#4ef5f9310ddff5747f884a6655228ec9c7d52c73" - integrity sha512-MfC2B+woL4Hlj2WCzcb1USySKk+SteXnUKmKktOk/H/AQy5+LuVdkPKm8SknJ0/RxaxhZ48WBoTRGaqgR137hw== +react-native-webview@^13.13.5: + version "13.15.0" + resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.15.0.tgz#b6d2f8d8dd65897db76659ddd8198d2c74ec5a79" + integrity sha512-Vzjgy8mmxa/JO6l5KZrsTC7YemSdq+qB01diA0FqjUTaWGAGwuykpJ73MDj3+mzBSlaDxAEugHzTtkUQkQEQeQ== dependencies: escape-string-regexp "^4.0.0" invariant "2.2.4" -react-native@0.79.2: - version "0.79.2" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.79.2.tgz#f1a53099701c1736d09e441eb79f97cfc90dd202" - integrity sha512-AnGzb56JvU5YCL7cAwg10+ewDquzvmgrMddiBM0GAWLwQM/6DJfGd2ZKrMuKKehHerpDDZgG+EY64gk3x3dEkw== +react-native@^0.79.3: + version "0.79.3" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.79.3.tgz#16580ca202016c75e3c61116fcfe3b30f6d762fc" + integrity sha512-EzH1+9gzdyEo9zdP6u7Sh3Jtf5EOMwzy+TK65JysdlgAzfEVfq4mNeXcAZ6SmD+CW6M7ARJbvXLyTD0l2S5rpg== dependencies: "@jest/create-cache-key-function" "^29.7.0" - "@react-native/assets-registry" "0.79.2" - "@react-native/codegen" "0.79.2" - "@react-native/community-cli-plugin" "0.79.2" - "@react-native/gradle-plugin" "0.79.2" - "@react-native/js-polyfills" "0.79.2" - "@react-native/normalize-colors" "0.79.2" - "@react-native/virtualized-lists" "0.79.2" + "@react-native/assets-registry" "0.79.3" + "@react-native/codegen" "0.79.3" + "@react-native/community-cli-plugin" "0.79.3" + "@react-native/gradle-plugin" "0.79.3" + "@react-native/js-polyfills" "0.79.3" + "@react-native/normalize-colors" "0.79.3" + "@react-native/virtualized-lists" "0.79.3" abort-controller "^3.0.0" anser "^1.4.9" ansi-regex "^5.0.0" @@ -17541,14 +17576,6 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rn-fetch-blob@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.12.0.tgz#ec610d2f9b3f1065556b58ab9c106eeb256f3cba" - integrity sha512-+QnR7AsJ14zqpVVUbzbtAjq0iI8c9tCg49tIoKO2ezjzRunN7YL6zFSFSWZm6d+mE/l9r+OeDM3jmb2tBb2WbA== - dependencies: - base-64 "0.1.0" - glob "7.0.6" - roarr@^7.0.4: version "7.15.1" resolved "https://registry.yarnpkg.com/roarr/-/roarr-7.15.1.tgz#e4d93105c37b5ea7dd1200d96a3500f757ddc39f" @@ -17736,12 +17763,10 @@ semver-compare@^1.0.0: resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== -semver@7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" +semver@7.6.3, semver@^7.1.3, semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== semver@^5.5.0, semver@^5.6.0: version "5.7.2" @@ -17753,11 +17778,6 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.3, semver@^7.6.3: - version "7.6.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" - integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== - semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@~7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" @@ -19372,6 +19392,14 @@ update-browserslist-db@^1.1.1: escalade "^3.2.0" picocolors "^1.1.0" +update-browserslist-db@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" + integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + update-check@1.5.3: version "1.5.3" resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.3.tgz#45240fcfb8755a7c7fa68bbdd9eda026a41639ed"