diff --git a/package.json b/package.json index d08368b59..be6cd06cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.110.1", + "version": "1.111.0", "private": true, "engines": { "node": ">=20" -- 2.51.2 From 9136be68b3c5ad50b9497520ecd88354165552df Mon Sep 17 00:00:00 2001 From: tomsqrd Date: Sat, 22 Nov 2025 12:03:30 +0100 Subject: [PATCH 2/5] Reading the optional String extras from attachment share intents (#9396) and adding them to the compose intents for images and videos if they exist. Co-authored-by: Tom Quinders --- .../ExpoReceiveAndroidIntentsModule.kt | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt b/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt index bee835247..2aaee3b8e 100644 --- a/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt +++ b/modules/expo-receive-android-intents/android/src/main/java/xyz/blueskyweb/app/exporeceiveandroidintents/ExpoReceiveAndroidIntentsModule.kt @@ -78,10 +78,12 @@ class ExpoReceiveAndroidIntentsModule : Module() { intent.getParcelableExtra(Intent.EXTRA_STREAM) } + val text = intent.getStringExtra(Intent.EXTRA_TEXT) + uri?.let { when (type) { - AttachmentType.IMAGE -> handleImageIntents(listOf(it)) - AttachmentType.VIDEO -> handleVideoIntents(listOf(it)) + AttachmentType.IMAGE -> handleImageIntents(listOf(it), text) + AttachmentType.VIDEO -> handleVideoIntents(listOf(it), text) } } } @@ -103,15 +105,20 @@ class ExpoReceiveAndroidIntentsModule : Module() { ?.take(4) } + val text = intent.getStringExtra(Intent.EXTRA_TEXT) + uris?.let { when (type) { - AttachmentType.IMAGE -> handleImageIntents(it) + AttachmentType.IMAGE -> handleImageIntents(it, text) else -> return } } } - private fun handleImageIntents(uris: List) { + private fun handleImageIntents( + uris: List, + text: String? + ) { var allParams = "" uris.forEachIndexed { index, uri -> @@ -124,15 +131,22 @@ class ExpoReceiveAndroidIntentsModule : Module() { } } - val encoded = URLEncoder.encode(allParams, "UTF-8") + val encodedUris = URLEncoder.encode(allParams, "UTF-8") + val encodedText = text?.let { URLEncoder.encode(it, "UTF-8") } + + var composeIntent = "bluesky://intent/compose?imageUris=$encodedUris" + encodedText?.let { composeIntent += "&text=$it" } - "bluesky://intent/compose?imageUris=$encoded".toUri().let { + composeIntent.toUri().let { val newIntent = Intent(Intent.ACTION_VIEW, it) appContext.currentActivity?.startActivity(newIntent) } } - private fun handleVideoIntents(uris: List) { + private fun handleVideoIntents( + uris: List, + text: String? + ) { val uri = uris[0] // If there is no extension for the file, substringAfterLast returns the original string - not // null, so we check for that below @@ -151,7 +165,12 @@ class ExpoReceiveAndroidIntentsModule : Module() { val info = getVideoInfo(uri) ?: return - "bluesky://intent/compose?videoUri=${URLEncoder.encode(file.path, "UTF-8")}|${info["width"]}|${info["height"]}".toUri().let { + val encodedText = text?.let { URLEncoder.encode(it, "UTF-8") } + + var composeIntent = "bluesky://intent/compose?videoUri=${URLEncoder.encode(file.path, "UTF-8")}|${info["width"]}|${info["height"]}" + encodedText?.let { composeIntent += "&text=$it" } + + composeIntent.toUri().let { val newIntent = Intent(Intent.ACTION_VIEW, it) appContext.currentActivity?.startActivity(newIntent) } -- 2.51.2 From 8b00b8f9457a8f69502e43c1a656cd6e6e05d180 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Sat, 22 Nov 2025 23:49:57 +0200 Subject: [PATCH 3/5] Split React Native patches into individual patches (#9429) --- package.json | 2 +- ... => react-native+0.81.5+001+initial.patch} | 73 +---------- ...ct-native+0.81.5+002+ScrollForwarder.patch | 67 ++++++++++ ...1.5+003+ScrollView-disable-recycling.patch | 16 +++ yarn.lock | 124 +++++++----------- 5 files changed, 134 insertions(+), 148 deletions(-) rename patches/{react-native+0.81.5.patch => react-native+0.81.5+001+initial.patch} (52%) create mode 100644 patches/react-native+0.81.5+002+ScrollForwarder.patch create mode 100644 patches/react-native+0.81.5+003+ScrollView-disable-recycling.patch diff --git a/package.json b/package.json index be6cd06cc..e2653d588 100644 --- a/package.json +++ b/package.json @@ -176,7 +176,7 @@ "multiformats": "9.9.0", "nanoid": "^5.0.5", "normalize-url": "^8.0.0", - "patch-package": "^6.5.1", + "patch-package": "^8.0.1", "postinstall-postinstall": "^2.1.0", "psl": "^1.9.0", "radix-ui": "^1.4.3", diff --git a/patches/react-native+0.81.5.patch b/patches/react-native+0.81.5+001+initial.patch similarity index 52% rename from patches/react-native+0.81.5.patch rename to patches/react-native+0.81.5+001+initial.patch index 5a372d81b..cc73cec3a 100644 --- a/patches/react-native+0.81.5.patch +++ b/patches/react-native+0.81.5+001+initial.patch @@ -1,47 +1,16 @@ -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 -@@ -1038,6 +1038,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 +index e9b330f..5fbb2e0 100644 --- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h +++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h -@@ -15,5 +15,8 @@ +@@ -15,5 +15,6 @@ @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) RCTDirectEventBlock onRefresh; @property (nonatomic, weak) UIScrollView *scrollView; +@property (nonatomic, copy) UIColor *customTintColor; -+ -+- (void)forwarderBeginRefreshing; @end diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m -index 53bfd04..ff1b1ed 100644 +index 53bfd04..e2e0c9f 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 @@ @implementation RCTRefreshControl { @@ -65,7 +34,7 @@ index 53bfd04..ff1b1ed 100644 - (void)didMoveToWindow { [super didMoveToWindow]; -@@ -221,4 +228,50 @@ - (void)refreshControlValueChanged +@@ -221,4 +228,16 @@ - (void)refreshControlValueChanged } } @@ -80,40 +49,6 @@ index 53bfd04..ff1b1ed 100644 + [super setTintColor:tintColor]; + } +} -+ -+// This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native -+// libraries to perform a refresh of a scrollview and access the refresh control's onRefresh -+// function. -+- (void)forwarderBeginRefreshing -+{ -+ _refreshingProgrammatically = NO; -+ -+ [self sizeToFit]; -+ -+ if (!self.scrollView) { -+ return; -+ } -+ -+ UIScrollView *scrollView = (UIScrollView *)self.scrollView; -+ -+ [UIView animateWithDuration:0.3 -+ delay:0 -+ options:UIViewAnimationOptionBeginFromCurrentState -+ animations:^(void) { -+ // Whenever we call this method, the scrollview will always be at a position of -+ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl -+ [scrollView setContentOffset:CGPointMake(0, -65)]; -+ } -+ completion:^(__unused BOOL finished) { -+ [super beginRefreshing]; -+ [self setCurrentRefreshingState:super.refreshing]; -+ -+ if (self->_onRefresh) { -+ self->_onRefresh(nil); -+ } -+ } -+ ]; -+} + @end diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m diff --git a/patches/react-native+0.81.5+002+ScrollForwarder.patch b/patches/react-native+0.81.5+002+ScrollForwarder.patch new file mode 100644 index 000000000..9e28d2045 --- /dev/null +++ b/patches/react-native+0.81.5+002+ScrollForwarder.patch @@ -0,0 +1,67 @@ +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/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h +index 5fbb2e0..ec5f58c 100644 +--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h ++++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h +@@ -17,4 +17,6 @@ + @property (nonatomic, weak) UIScrollView *scrollView; + @property (nonatomic, copy) UIColor *customTintColor; + ++- (void)forwarderBeginRefreshing; ++ + @end +diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +index e2e0c9f..ff1b1ed 100644 +--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m ++++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m +@@ -240,4 +240,38 @@ - (void)setTintColor:(UIColor *)tintColor + } + } + ++// This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native ++// libraries to perform a refresh of a scrollview and access the refresh control's onRefresh ++// function. ++- (void)forwarderBeginRefreshing ++{ ++ _refreshingProgrammatically = NO; ++ ++ [self sizeToFit]; ++ ++ if (!self.scrollView) { ++ return; ++ } ++ ++ UIScrollView *scrollView = (UIScrollView *)self.scrollView; ++ ++ [UIView animateWithDuration:0.3 ++ delay:0 ++ options:UIViewAnimationOptionBeginFromCurrentState ++ animations:^(void) { ++ // Whenever we call this method, the scrollview will always be at a position of ++ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl ++ [scrollView setContentOffset:CGPointMake(0, -65)]; ++ } ++ completion:^(__unused BOOL finished) { ++ [super beginRefreshing]; ++ [self setCurrentRefreshingState:super.refreshing]; ++ ++ if (self->_onRefresh) { ++ self->_onRefresh(nil); ++ } ++ } ++ ]; ++} ++ + @end diff --git a/patches/react-native+0.81.5+003+ScrollView-disable-recycling.patch b/patches/react-native+0.81.5+003+ScrollView-disable-recycling.patch new file mode 100644 index 000000000..2488a8edf --- /dev/null +++ b/patches/react-native+0.81.5+003+ScrollView-disable-recycling.patch @@ -0,0 +1,16 @@ +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 +@@ -1038,6 +1038,11 @@ - (void)_adjustForMaintainVisibleContentPosition + } + } + +++ (BOOL)shouldBeRecycled ++{ ++ return NO; ++} ++ + @end + + Class RCTScrollViewCls(void) diff --git a/yarn.lock b/yarn.lock index 345b99969..67ac38084 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8579,11 +8579,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - atomic-sleep@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" @@ -9368,6 +9363,11 @@ ci-info@^3.2.0, ci-info@^3.3.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== +ci-info@^3.7.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + cjs-module-lexer@^1.0.0: version "1.2.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" @@ -9770,17 +9770,6 @@ cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.12" -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -11974,21 +11963,20 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^11.2.0: - version "11.3.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" - integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== +fs-extra@^11.2.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d" + integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== dependencies: - at-least-node "^1.0.0" graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" @@ -12962,13 +12950,6 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - is-ci@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" @@ -14077,6 +14058,17 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json-stable-stringify@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz#8903cfac42ea1a0f97f35d63a4ce0518f0cc6a70" + integrity sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg== + dependencies: + call-bind "^1.0.8" + call-bound "^1.0.4" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" @@ -14098,6 +14090,11 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.2.1: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -15117,11 +15114,6 @@ nested-error-stacks@~2.0.1: resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.0.1.tgz#d2cc9fc5235ddb371fc44d506234339c8e4b0a4b" integrity sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - no-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" @@ -15680,25 +15672,25 @@ password-prompt@^1.0.4: ansi-escapes "^4.3.2" cross-spawn "^7.0.3" -patch-package@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.1.tgz#3e5d00c16997e6160291fee06a521c42ac99b621" - integrity sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA== +patch-package@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.1.tgz#79d02f953f711e06d1f8949c8a13e5d3d7ba1a60" + integrity sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw== dependencies: "@yarnpkg/lockfile" "^1.1.0" chalk "^4.1.2" - cross-spawn "^6.0.5" + ci-info "^3.7.0" + cross-spawn "^7.0.3" find-yarn-workspace-root "^2.0.0" - fs-extra "^9.0.0" - is-ci "^2.0.0" + fs-extra "^10.0.0" + json-stable-stringify "^1.0.2" klaw-sync "^6.0.0" minimist "^1.2.6" open "^7.4.2" - rimraf "^2.6.3" - semver "^5.6.0" + semver "^7.5.3" slash "^2.0.0" - tmp "^0.0.33" - yaml "^1.10.2" + tmp "^0.2.4" + yaml "^2.2.2" path-exists@^3.0.0: version "3.0.0" @@ -15720,11 +15712,6 @@ path-is-inside@^1.0.2: resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -17785,11 +17772,6 @@ semver@7.6.3, semver@^7.1.3, semver@^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" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" @@ -18008,13 +17990,6 @@ sharp@^0.33.5: "@img/sharp-win32-ia32" "0.33.5" "@img/sharp-win32-x64" "0.33.5" -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -18022,11 +17997,6 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" @@ -18953,6 +18923,11 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.2.4: + version "0.2.5" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" + integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -19947,13 +19922,6 @@ which-typed-array@^1.1.9: has-tostringtag "^1.0.0" is-typed-array "^1.1.10" -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -20142,7 +20110,7 @@ yaml@^1.10.0, yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.6.1: +yaml@^2.2.2, yaml@^2.6.1: version "2.8.1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.1.tgz#1870aa02b631f7e8328b93f8bc574fac5d6c4d79" integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw== -- 2.51.2 From 54af170448b1ef37317ea6108942ae56282f3a3c Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Sun, 23 Nov 2025 00:20:37 +0200 Subject: [PATCH 4/5] Use new blue everywhere (#9435) --- src/view/com/util/fab/FABInner.tsx | 40 +++++++++---------- src/view/icons/Logo.tsx | 10 +++-- src/view/shell/bottom-bar/BottomBar.tsx | 15 +++++-- src/view/shell/bottom-bar/BottomBarStyles.tsx | 7 ---- src/view/shell/bottom-bar/BottomBarWeb.tsx | 7 +++- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/view/com/util/fab/FABInner.tsx b/src/view/com/util/fab/FABInner.tsx index 53dac103f..3d6af65c5 100644 --- a/src/view/com/util/fab/FABInner.tsx +++ b/src/view/com/util/fab/FABInner.tsx @@ -7,16 +7,13 @@ import { } from 'react-native' import Animated from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {LinearGradient} from 'expo-linear-gradient' import {PressableScale} from '#/lib/custom-animations/PressableScale' import {useHaptics} from '#/lib/haptics' import {useMinimalShellFabTransform} from '#/lib/hooks/useMinimalShellTransform' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {clamp} from '#/lib/numbers' -import {gradients} from '#/lib/styles' import {isWeb} from '#/platform/detection' -import {ios} from '#/alf' +import {ios, useBreakpoints, useTheme} from '#/alf' import {atoms as a} from '#/alf' export interface FABProps extends ComponentProps { @@ -27,13 +24,14 @@ export interface FABProps extends ComponentProps { export function FABInner({testID, icon, onPress, style, ...props}: FABProps) { const insets = useSafeAreaInsets() - const {isMobile, isTablet} = useWebMediaQueries() + const {gtMobile} = useBreakpoints() + const t = useTheme() const playHaptic = useHaptics() const fabMinimalShellTransform = useMinimalShellFabTransform() - const size = isTablet ? styles.sizeLarge : styles.sizeRegular + const size = gtMobile ? styles.sizeLarge : styles.sizeRegular - const tabletSpacing = isTablet + const tabletSpacing = gtMobile ? {right: 50, bottom: 50} : {right: 24, bottom: clamp(insets.bottom, 15, 60) + 15} @@ -43,7 +41,7 @@ export function FABInner({testID, icon, onPress, style, ...props}: FABProps) { styles.outer, size, tabletSpacing, - isMobile && fabMinimalShellTransform, + !gtMobile && fabMinimalShellTransform, ]}> - - {icon} - + {icon} ) @@ -73,8 +73,8 @@ export function FABInner({testID, icon, onPress, style, ...props}: FABProps) { const styles = StyleSheet.create({ sizeRegular: { - width: 60, - height: 60, + width: 56, + height: 56, borderRadius: 30, }, sizeLarge: { @@ -88,8 +88,4 @@ const styles = StyleSheet.create({ zIndex: 1, cursor: 'pointer', }, - inner: { - justifyContent: 'center', - alignItems: 'center', - }, }) diff --git a/src/view/icons/Logo.tsx b/src/view/icons/Logo.tsx index 2b5884b88..d7208df13 100644 --- a/src/view/icons/Logo.tsx +++ b/src/view/icons/Logo.tsx @@ -10,9 +10,8 @@ import Svg, { } from 'react-native-svg' import {Image} from 'expo-image' -import {colors} from '#/lib/styles' import {useKawaiiMode} from '#/state/preferences/kawaii' -import {flatten} from '#/alf' +import {flatten, useTheme} from '#/alf' const ratio = 57 / 64 @@ -22,12 +21,15 @@ type Props = { } & Omit export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { + const t = useTheme() const {fill, ...rest} = props const gradient = fill === 'sky' const styles = flatten(props.style) - const _fill = gradient ? 'url(#sky)' : fill || styles?.color || colors.blue3 + const _fill = gradient + ? 'url(#sky)' + : fill || styles?.color || t.palette.primary_500 // @ts-ignore it's fiiiiine - const size = parseInt(rest.width || 32) + const size = parseInt(rest.width || 32, 10) const isKawaii = useKawaiiMode() diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx index 0e0eb79e8..779ebda68 100644 --- a/src/view/shell/bottom-bar/BottomBar.tsx +++ b/src/view/shell/bottom-bar/BottomBar.tsx @@ -28,11 +28,10 @@ import {useSession} from '#/state/session' import {useLoggedOutViewControls} from '#/state/shell/logged-out' import {useShellLayout} from '#/state/shell/shell-layout' import {useCloseAllActiveElements} from '#/state/util' -import {Text} from '#/view/com/util/text/Text' import {UserAvatar} from '#/view/com/util/UserAvatar' import {Logo} from '#/view/icons/Logo' import {Logotype} from '#/view/icons/Logotype' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import {useDialogControl} from '#/components/Dialog' import {SwitchAccountDialog} from '#/components/dialogs/SwitchAccount' @@ -50,6 +49,7 @@ import { Message_Stroke2_Corner0_Rounded as Message, Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, } from '#/components/icons/Message' +import {Text} from '#/components/Typography' import {useDemoMode} from '#/storage/hooks/demo-mode' import {styles} from './BottomBarStyles' @@ -396,6 +396,8 @@ function Btn({ accessibilityHint, accessibilityLabel, }: BtnProps) { + const t = useTheme() + return ( {icon} {notificationCount ? ( - - {notificationCount} + + 1 ) : hasNew ? ( diff --git a/src/view/shell/bottom-bar/BottomBarStyles.tsx b/src/view/shell/bottom-bar/BottomBarStyles.tsx index ad1cc48fd..3c99eaf6f 100644 --- a/src/view/shell/bottom-bar/BottomBarStyles.tsx +++ b/src/view/shell/bottom-bar/BottomBarStyles.tsx @@ -24,7 +24,6 @@ export const styles = StyleSheet.create({ position: 'absolute', left: '52%', top: 8, - backgroundColor: colors.blue3, paddingHorizontal: 4, paddingBottom: 1, borderRadius: 6, @@ -35,12 +34,6 @@ export const styles = StyleSheet.create({ paddingBottom: 3, borderRadius: 12, }, - notificationCountLight: { - borderColor: colors.white, - }, - notificationCountDark: { - borderColor: colors.gray8, - }, notificationCountLabel: { fontSize: 12, fontWeight: '600', diff --git a/src/view/shell/bottom-bar/BottomBarWeb.tsx b/src/view/shell/bottom-bar/BottomBarWeb.tsx index c884673cd..61b32c643 100644 --- a/src/view/shell/bottom-bar/BottomBarWeb.tsx +++ b/src/view/shell/bottom-bar/BottomBarWeb.tsx @@ -236,6 +236,7 @@ const NavItem: React.FC<{ hasNew?: boolean notificationCount?: string }> = ({children, href, routeName, hasNew, notificationCount}) => { + const t = useTheme() const {_} = useLingui() const {currentAccount} = useSession() const currentRoute = useNavigationState(state => { @@ -272,7 +273,11 @@ const NavItem: React.FC<{ {children({isActive})} {notificationCount ? ( Date: Sun, 23 Nov 2025 02:47:44 +0000 Subject: [PATCH 5/5] Nightly source-language update --- src/locale/locales/en/messages.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index aecd39519..3770f0380 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -422,7 +422,7 @@ msgstr "" msgid "{minutes, plural, one {# minute} other {# minutes}}" msgstr "" -#: src/view/shell/bottom-bar/BottomBarWeb.tsx:277 +#: src/view/shell/bottom-bar/BottomBarWeb.tsx:282 msgid "{notificationCount, plural, one {# unread item} other {# unread items}}" msgstr ""