Compare commits

...

1147 Commits

Author SHA1 Message Date
Eric Bailey e2f6bb90e7 Fix missing spots 2026-03-17 13:45:11 -05:00
Eric Bailey 6a8a02eb43 Include if google was forced 2026-03-17 13:39:54 -05:00
Eric Bailey a00e5dd724 Just align naming conventions 2026-03-17 13:22:30 -05:00
Eric Bailey 389bea7c93 Make metrics really really clear 2026-03-17 13:11:58 -05:00
Eric Bailey c81214aeee Clarify metric values for result events 2026-03-17 12:36:22 -05:00
DS Boyce 1386a559b7 Log languages a post is tagged with after translating (#10014)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-17 12:31:23 -05:00
RetroSunstar be0d00de17 Set displayName and description to undefined if no values are provided during a profile edit (#10016) 2026-03-17 12:04:27 -05:00
RetroSunstar dbba97f28d Use proper constants.ts exports for Edit Profile Dialog limits (#10054) 2026-03-17 12:04:04 -05:00
Samuel Newman 5e8ef6aa9b Adjust VTT cue line to avoid occlusion by video controls (#10017)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:05:58 -05:00
surfdude29 177bdcd2b7 [bskylink] URL-encode apostrophes before HTML escaping (#9559) 2026-03-16 11:18:23 -07:00
pfrazee 2027589c55 Nightly source-language update 2026-03-14 03:04:35 +00:00
DS Boyce b8d60eb0e2 Address lint warnings in List.web.tsx (#10046) 2026-03-13 09:41:38 -07:00
DS Boyce 97fdd7c59b Create new useSuggestedFollowsByActorWithDismiss hook (#10048) 2026-03-13 09:18:23 -07:00
pfrazee 6afe48db6a Nightly source-language update 2026-03-13 03:06:17 +00:00
DS Boyce 0b6ff8000d Remove getSuggestedFollowsByActor fallbacks and use recIdStr (#9988) 2026-03-12 16:57:38 -07:00
DS Boyce 35cb2bcf94 Create codemod for updating Toast calls to v2 (#10045) 2026-03-12 11:35:58 -07:00
DS Boyce 9c9970f680 Don't show chat notification if viewer is age gated (#10042) 2026-03-12 11:21:57 -07:00
DS Boyce 7b5d5a4f76 Provide age-restricted viewers the option to delete their account (#10041) 2026-03-12 11:13:23 -07:00
Samuel Newman 4737bfb7ed Update expo deps, unpin things (#10044) 2026-03-12 05:33:11 -07:00
pfrazee 374ce2c39e Nightly source-language update 2026-03-12 03:08:04 +00:00
DS Boyce 1db01a09a8 Create codemod for addressing ESLint warnings (#10032) 2026-03-11 15:51:31 -07:00
Samuel Newman 80429ec902 Add “download image” option to web, simplify downloads (#10025) 2026-03-11 23:44:19 +02:00
heikadog 0c7b2d5353 Update issue templates to take uploads, and fix typo (#10036) 2026-03-11 14:50:35 -05:00
DS Boyce 850e6e6f52 Add new metrics for post menu interactions (#10022)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-11 13:30:33 -05:00
Eric Bailey 0937f522af Serve og:video tags on post URLs (#10039) 2026-03-11 11:46:27 -05:00
pfrazee f5994af620 Nightly source-language update 2026-03-11 03:04:18 +00:00
Samuel Newman 8b67a3ec2e First pass at fixing large type by adding maxFontSizeMultiplier (#10037) 2026-03-10 23:39:02 +02:00
Samuel Newman 6187e79b0e Update React Native Screens and React Navigation to latest (#9993)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-10 15:32:41 -05:00
Spence Pope 2bd9811652 [APP-1928] add bot/automated account badge and self-labeling settings (#10008)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-10 13:28:49 -05:00
pfrazee 8bdb1c30c8 Nightly source-language update 2026-03-10 03:05:11 +00:00
Samuel Newman aa897f55a0 The Great Unjanking of the Sheets (#9973) 2026-03-09 22:53:32 +02:00
devin ivy 18d7e775f6 ogcard: ensure we use jpeg images for satori compat (#10023) 2026-03-07 09:11:57 +00:00
pfrazee b8aae166d9 Nightly source-language update 2026-03-07 02:59:25 +00:00
DS Boyce f8886fbfe6 Refine presentation of translation results (#10015)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-06 13:36:58 -08:00
Samuel Newman 041e348581 Bump version to 1.119.0 (#10020) 2026-03-06 13:34:03 -08:00
Samuel Newman e2c54a858c Move dev-env to subdirectory (#10009) 2026-03-06 11:45:49 -06:00
Eric Bailey 60a0edbbe2 [APP-1960] Fix current session refresh bug (#10019) 2026-03-06 11:43:14 -06:00
pfrazee 562bf3be22 Nightly source-language update 2026-03-06 03:06:49 +00:00
DS Boyce 290e0f2b54 Disable animations for translation events on Android (#10013) 2026-03-05 15:01:29 -08:00
DS Boyce ece6dc251c Link to profile via handle vs did (#10012) 2026-03-05 12:52:39 -08:00
Eric Bailey 8c705864a2 Prep 1.118.1 patch relase (#10011) 2026-03-05 14:43:18 -06:00
Eric Bailey 7a08b82810 Fix deps (#10010) 2026-03-05 14:11:57 -06:00
Samuel Newman 20bf2cd117 Prevent over-eager translate button (#10007) 2026-03-05 12:07:34 -08:00
DS Boyce fe8e8ce7de Add README.md for lib/translation (#10005) 2026-03-05 10:53:25 -08:00
Eric Bailey 8b8acb7bd1 Add docs on directory structures and naming conventions (#10002) 2026-03-05 12:31:55 -06:00
DS Boyce 1a487d0943 Remove duplicate punctuation (#10004) 2026-03-05 10:16:20 -08:00
Samuel Newman 1ae77aa997 Fix findNodeHandle usage on web (#10001) 2026-03-05 07:22:13 -08:00
Samuel Newman 7cec490cef Use a different icon for testflight builds (#10000) 2026-03-05 07:04:59 -08:00
Eric Bailey 1281eb01e6 Prep 1.118.0 (#9999) 2026-03-04 21:08:55 -06:00
pfrazee 4339585b27 Nightly source-language update 2026-03-05 03:06:58 +00:00
Samuel Newman 30c9ea5789 v1.118.0 E2E tests (#9994) 2026-03-04 20:45:08 -06:00
DS Boyce afbade6f6f Refine UX for on-device translation for posts (#9987)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-04 20:37:44 -06:00
Samuel Newman 1782a65174 Add iOS 26 fluid zoom transition to alt text dialog (#9970)
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-04 20:32:08 -06:00
Eric Bailey 7fd218c97d Update API package to fix stale session issues (#9998) 2026-03-04 18:27:12 -06:00
DS Boyce 8446efb739 Pass feed URI to sendInteractions endpoint (#9989) 2026-03-04 12:38:24 -08:00
pfrazee b84f28f884 Nightly source-language update 2026-03-04 03:05:02 +00:00
DS Boyce 7dc3b4fa8e Add search event analytics (#9949)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-03-03 14:49:38 -06:00
Samuel Newman 37a82761f5 Cache profile view before opening AfterReportDialog (#9962) 2026-03-03 13:50:22 -06:00
Samuel Newman 612a778361 Set mute word dialog text input return key type to "done" (#9967)
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-03 13:35:09 -06:00
Samuel Newman 162a78e1ae Add 🪿 (#9983) 2026-03-03 06:06:13 -08:00
pfrazee c42502fdcb Nightly source-language update 2026-03-03 03:09:48 +00:00
Samuel Newman 8b1c47a499 bskyweb: use avatar thumbnail for post og:image fallback (#9923) 2026-03-02 22:28:16 +00:00
Samuel Newman c2fd87bd8b Remove JPG hardcoding from image processing systems (#9955) 2026-03-02 20:23:07 +00:00
Samuel Newman d247a65683 Add Trans to string (#9981) 2026-03-02 11:39:50 -08:00
Spence Pope a95b877ea3 [APP-1917] fix header measurement for android content disappearing on switch (#9964)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-03-02 14:20:16 -05:00
Samuel Newman f614bf650d Translation followups (#9980) 2026-03-02 11:01:09 -08:00
Samuel Newman 5ee667f307 Force relayout to fix stuck header blur (#9979) 2026-03-02 10:50:00 -08:00
Spence Pope 9c29b2867a [APP-1882] fix email not updating in session state after email change (#9953) 2026-03-02 06:09:21 -08:00
smileyhead 9746dd8e4c Make ALT labels translatable (#9976) 2026-03-02 13:14:07 +00:00
DS Boyce 8e2a5abfff Fix crash with translate link on web (#9972) 2026-02-28 23:53:42 +00:00
pfrazee 6cdc1fe2b5 Nightly source-language update 2026-02-28 02:56:49 +00:00
DS Boyce 9bbcb472ef Use on-device translation on mobile when available (#9930)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-02-27 16:59:19 -08:00
Samuel Newman 7c9f05a2af ContextMenu - return item to the right location if keyboard hides (#9963) 2026-02-27 22:19:04 +00:00
Samuel Newman d4357b2cb8 Fix iOS sheet keyboard handling using native scrollview features (#9959) 2026-02-27 13:59:24 -08:00
Spence Pope 576761a645 [APP-1819] fix progress guide flash and extra gap (#9960) 2026-02-27 08:31:35 -08:00
DS Boyce 8a1f8997fe Fix infinite loading spinner when changing search terms (#9950)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-02-27 03:42:31 -08:00
pfrazee 6cb88ce1f3 Nightly source-language update 2026-02-27 03:06:31 +00:00
Samuel Newman 65c4b7833d Blur effect on home screen (iOS 26) (#9935) 2026-02-26 07:00:12 -08:00
Spence Pope 9b24d75c9c [APP-1876] Fix pull-to-refresh getting stuck on tab switch (#9951) 2026-02-26 02:06:30 -08:00
Spence Pope 398df1a4b5 ensure app session state refreshes on reactivation (#9954)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 02:06:16 -08:00
pfrazee db9c2a1596 Nightly source-language update 2026-02-26 03:07:29 +00:00
Alex Benzer 00816b70dc [APP-1859] pinned feed drag n drop (#9893)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: vineyardbovines <spencerfpope@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:52:10 -08:00
Samuel Newman 49272be36b Fix up polyfills, remove unused deps (#9946) 2026-02-25 11:43:46 -08:00
surfdude29 85ffc77983 Show hashtag symbol for Mute option in menu (#9942) 2026-02-25 01:18:20 -08:00
pfrazee 95bede2dcb Nightly source-language update 2026-02-25 03:09:49 +00:00
surfdude29 e656fe688d Align strings from 'subtitles' to 'captions' (#9941) 2026-02-24 21:56:12 +00:00
Samuel Newman db1f45de92 iOS 26 tweaks #2 (#9938) 2026-02-24 12:14:19 -08:00
Samuel Newman bc61314c41 iOS 26 followups (#9936) 2026-02-24 08:12:57 -08:00
mozzius 1850042c37 Nightly source-language update 2026-02-24 07:17:35 +00:00
Samuel Newman 782edbf281 Restore type assert that got accidentally removed (#9934) 2026-02-23 23:11:39 -08:00
Samuel Newman 73b096e443 iOS 26 (#9047)
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 22:34:52 -08:00
pfrazee 9b0f0a8d24 Nightly source-language update 2026-02-24 03:09:35 +00:00
Samuel Newman 9ec06971af Upgrade Lingui to v5 (#9905) 2026-02-23 20:28:03 +00:00
Samuel Newman 75242b9b1f Bump version to v1.118.0 (#9931) 2026-02-23 12:04:58 -08:00
pfrazee 21e53b226d Nightly source-language update 2026-02-22 03:10:59 +00:00
surfdude29 02c2a9ea7c Mark admonition text for translation in CreateListFromStarterPackDialog (#9922) 2026-02-21 16:53:44 +00:00
Eric Bailey cb7e2ab976 Release prep 1.117.0 (#9920) 2026-02-20 14:30:14 -06:00
Eric Bailey 067c6dacc9 Update location copy (#9918) 2026-02-20 13:20:04 -06:00
Eric Bailey 9b8c46cdb7 Add A/A test (#9917) 2026-02-20 13:19:56 -06:00
Samuel Newman f3cc850b62 Fix up typescript config (#9910) 2026-02-20 18:07:17 +00:00
Samuel Newman 35f9ed82b9 Fix string concat bug with trending topics muteword moderation (#9914) 2026-02-20 11:29:08 -06:00
Samuel Newman 8c4fc087f8 Add ability to convert starter pack to list (#9675)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Samuel Newman <mozzius@users.noreply.github.com>
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2026-02-20 11:27:55 -06:00
Samuel Newman f3ddc074a6 Fork MCEmojiPicker (#9763) 2026-02-20 10:39:48 -06:00
Spence Pope 5e0ffc0917 [APP-1809] add cleanup button for unavailable moderation services (#9901)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-02-20 10:23:01 -06:00
Samuel Newman 3fae42c077 Remove hardcoded warning color, add yellow and pink to ALF palette (#9911) 2026-02-20 10:17:11 -06:00
Sylwia 80c0aa35e2 Add CORS headers to /oembed API (#9845) 2026-02-19 22:07:49 -08:00
Eric Bailey 4e3c3e9905 [APP-1805] Analytics tweaks and tracking callbacks (#9861) 2026-02-19 15:31:35 -06:00
pfrazee 1565e071c1 Nightly source-language update 2026-02-19 03:10:25 +00:00
Samuel Newman c906fea77a Fix webpack dev server freezing after repeated refreshes (#9865) 2026-02-18 11:03:23 -08:00
Samuel Newman 775a041b71 Add chat data export to Export My Data dialog (#9900)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 11:01:58 -08:00
Samuel Newman 98d17fd950 Fix native-only function being called on web (#9904) 2026-02-18 09:46:45 -08:00
Samuel Newman 41b3742365 Dynamically load date-fns locale data (#9535) 2026-02-18 11:30:32 -06:00
Samuel Newman 512ce3d5d0 ALF content language dialog (#9471)
Co-authored-by: Eric Bailey <git@esb.lol>
2026-02-18 08:57:32 -08:00
Samuel Newman bdf143ce79 Restructure notification/linking handling to use synchronous APIs (#9497)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-02-18 08:20:39 -08:00
Samuel Newman adc079e095 Get rid of Sentry Replay from web bundle (#9534) 2026-02-18 10:20:05 -06:00
DS Boyce 74330500de Improve error handling on Explore page (#9890) 2026-02-18 09:57:31 -06:00
DS Boyce ac939dc84e Update onboarding user suggestions with new endpoint (#9872) 2026-02-18 09:35:00 -06:00
Samuel Newman b12d703353 Enable profile hover card on quoted post authors (#9896)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 06:35:38 -08:00
DS Boyce c188fd4f04 Log onboarding errors for suggested accounts (#9892) 2026-02-18 00:18:22 -08:00
Samuel Newman a1cda126e6 ALF feed error screen (#9895) 2026-02-18 00:16:12 -08:00
pfrazee ae115ca17e Nightly source-language update 2026-02-18 03:10:48 +00:00
Spence Pope 197c069416 Clear link and gif caches to avoid pointing at missing files (#9898)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:39:34 -05:00
pfrazee e67d81f269 Nightly source-language update 2026-02-17 03:09:32 +00:00
DS Boyce 7c08bba6cf Use Prompt.Action for delete account buttons (#9889) 2026-02-16 16:23:27 -08:00
DS Boyce 29bc0f1372 Add optional props to Prompt.Action (#9887) 2026-02-16 13:29:25 -08:00
surfdude29 82f42e734c Wrap interaction counts with Trans to add translation flexibility (#9036) 2026-02-16 21:12:26 +00:00
surfdude29 3b9f0b0a68 Add plural formatting for several strings (#9576) 2026-02-16 21:10:57 +00:00
Samuel Newman a6ba0810b7 Be more descriptive with video errors, log less (#9886) 2026-02-16 21:09:49 +00:00
DS Boyce 49253dbd88 Refactor delete account dialog using ALF (#9863) 2026-02-16 12:00:46 -08:00
Eric Bailey cc2255cc49 [APP-1776] Refactor Live Now config, reorg files (#9871) 2026-02-16 11:44:22 -06:00
Eric Bailey 8ee9709fbb [APP-1764] Improve Age Assurance copy (#9885)
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2026-02-16 11:03:59 -06:00
Samuel Newman 90d650def2 Use video thumbnail as og:image for posts with video embeds (#9877) 2026-02-16 15:35:29 +00:00
Samuel Newman 79e27e303b Fix missing pixel row in text rendering on iOS (#9882)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 05:41:35 -08:00
Spence Pope 6be7751769 have back button dismiss lightbox on web (#9874) 2026-02-16 08:39:53 -05:00
Samuel Newman 9b830fd425 Use scroll position to gate post-created feed refresh (#9881)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 05:39:29 -08:00
Samuel Newman 4ebeb94b41 Add Renew menu for expired mute words (#9883)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 05:30:07 -08:00
Samuel Newman b6b364700e Make profile description text selectable (#9884)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 05:29:59 -08:00
pfrazee 95f9cc1ed5 Nightly source-language update 2026-02-16 03:11:39 +00:00
surfdude29 06fcea988e 'Log in' to 'Sign in' (#9875) 2026-02-15 19:02:01 +00:00
pfrazee b166d395d9 Nightly source-language update 2026-02-15 03:11:50 +00:00
Samuel Newman 1228306309 Fix quote embed clickability in composer on web (#9876) 2026-02-14 22:29:59 +00:00
pfrazee bc001168f3 Nightly source-language update 2026-02-14 03:05:51 +00:00
Spence Pope b4cb4c4d13 Revert "Add --what-to-test to iOS submissions (#9856)" (#9873) 2026-02-13 13:24:06 -08:00
Samuel Newman 2e34f965fc [Auth rework] Add a header to login flow (#9368) 2026-02-13 20:15:36 +00:00
Spence Pope 9cdfb40ce7 dedupe trending topics (#9870) 2026-02-13 13:03:36 -05:00
Samuel Newman c83dddce57 Bandcamp embed (#9445) 2026-02-13 13:30:10 +00:00
pfrazee 795428971d Nightly source-language update 2026-02-13 03:12:46 +00:00
Spence Pope 82fea6da7d [APP-1846] Remove trending post counts until we can improve accuracy (#9867) 2026-02-12 19:34:50 +00:00
Spence Pope 2f156bb906 [APP-1833] Handle errors on saving a draft over char limit (#9850)
* show composer error if draft over char limit

* adjust cancel discarding if over the limit

* use richtext for validation

* don't allow saving a draft that can't actually be saved

* account for 1k chars

* update discard sheet

* show composer error if draft over char limit

* adjust cancel discarding if over the limit

* use richtext for validation

* don't allow saving a draft that can't actually be saved

* account for 1k chars

* update discard sheet

* pr comment fixes

* pluralization
2026-02-12 09:24:38 -06:00
Samuel Newman c46219bc4d Fix keyboard flicker when selecting a draft in composer (#9864) 2026-02-12 15:07:26 +00:00
pfrazee 6d68a5bd21 Nightly source-language update 2026-02-12 03:12:33 +00:00
surfdude29 cbac380c96 Add profile error messages to cleanError (#9842) 2026-02-11 19:55:54 -06:00
Samuel Newman 8c4820b1f1 [Web] Fix splash flicker and add animation (#9860)
* manually hide non-React splash logo

* tweak comment

* animate out splash
2026-02-11 19:52:22 -06:00
Samuel Newman 93d2f3a8db Germ DM button (#9848)
* germ link (wip)

* add todos

* just yeet declaration for now

* ensure not proxied

* allow undo delete

* tweak styles

* ignore unknown values

* tweak styles

* fix boolean logic

* skip IAB

* fix mutationFn

* add link warning interstitial

* Logging and metrics

* Little more error handling

* Update copy

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2026-02-11 17:51:19 -06:00
Eric Bailey 3a9526d55e Bump API SDK (#9862)
* Bump API SDK

* Bump dev-env
2026-02-11 17:41:34 -06:00
Spence Pope 830f305d2d Merge pull request #9823 from bluesky-social/app-1788
[APP-1788] update design for stacked avatars
2026-02-11 15:57:07 -05:00
DS Boyce 8a088e8710 Merge pull request #9853 from bluesky-social/d/profile-screen
Use Tanstack Query isPending over isLoading
2026-02-11 10:27:13 -08:00
Spence Pope 8cbe3985fa Update src/components/ProgressGuide/List.tsx
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-02-11 13:11:30 -05:00
Spence Pope 1ec70420e6 Update src/components/ProgressGuide/List.tsx
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-02-11 13:11:24 -05:00
Spence Pope 63fbf577d9 Update src/components/ProgressGuide/List.tsx
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-02-11 13:11:15 -05:00
DS Boyce 355868e01e Address feedback and lint warnings 2026-02-11 09:46:47 -08:00
Samuel Newman 37e5a0f7a4 Clean up starter packs dialog styles + add optimistic updates (#9469) 2026-02-11 17:46:28 +00:00
DS Boyce 4356ff0040 Merge branch 'main' into d/profile-screen 2026-02-11 09:43:55 -08:00
Samuel Newman 4eca13941a Fix GIFs breaking mute state/pausing phone audio (#9859)
* fix operator precedence mistake

* ensure gifs can't change the global mute state
2026-02-11 08:51:23 -08:00
Samuel Newman 8580e4a00e absolutely position header, set a headerheight (#9858) 2026-02-11 07:22:13 -08:00
Samuel Newman 8581285d34 simplify some conditionals 2026-02-11 16:20:48 +02:00
Samuel Newman 57997d6d16 Add --what-to-test to iOS submissions (#9856)
Sets the "What to test" field in TestFlight to distinguish between
TestFlight and Production builds.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 06:01:27 -08:00
Samuel Newman a25bc8f249 Debounce thread preferences on leading edge, reduce to 2s (#9851)
* debounce on leading edge, reduce to 2s

* flush debounce on leave screen

* simplify by using useMutation properly
2026-02-10 23:41:04 -08:00
pfrazee 177a6e50bd Nightly source-language update 2026-02-11 03:12:22 +00:00
DS Boyce 5459857112 Use Tanstack Query status over isPending 2026-02-10 13:27:18 -08:00
Samuel Newman 338016ed5c Android sheets edge to edge (#8342) 2026-02-10 21:01:58 +00:00
Samuel Newman e2058c8ecc Update starter pack message to clarify users joined Bluesky (#9849) 2026-02-10 15:37:48 +00:00
surfdude29 3cbded0269 fix typos in drafts NUX alt text (#9832) 2026-02-10 10:41:47 +00:00
Samuel Newman 5ea96736de rm unused @testing-library/jest-native (#9820) 2026-02-10 08:36:27 +00:00
pfrazee efed955003 Nightly source-language update 2026-02-10 03:12:38 +00:00
surfdude29 b8db36afb0 Add context for translators for "No one" string (#9844)
* add context for translators 'No one' option

* update ActivityPrivacySettings to add context for translators

* update translation context for 'No one' option
2026-02-09 15:37:04 -08:00
Samuel Newman 5642bc40bb bump version to v1.117.0 (#9847) 2026-02-09 15:14:46 -08:00
Samuel Newman 3be1f5caa9 Add attribution for starter pack follows (#9834) 2026-02-09 10:01:55 -06:00
pfrazee 18eea81e76 Nightly source-language update 2026-02-08 03:12:29 +00:00
Samuel Newman 917f099e26 [Drafts] Some bugs (#9833)
* Fix text input not updating

* Fix autofocus

* make placeholder text fainter

* Await invalidation

* Image only drafts

* tweaks to gif presentation

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2026-02-07 15:38:48 +00:00
pfrazee 6bfe758d2a Nightly source-language update 2026-02-06 03:06:58 +00:00
Spence Pope 18ab5d6f34 [APP-1823] Fix 'create account' / 'sign in' buttons stacking (#9830)
* ensure enough space for sign in buttons

* smallest possible adjustment

* smallest possible adjustment
2026-02-05 08:40:25 -08:00
Spence Pope dc3f01591f [APP-1794] respect mute words for live event feed banners (#9831)
* respect mute words for live event feed banners

* linting
2026-02-05 09:36:19 -06:00
vineyardbovines 3a28a07081 Merge branch 'main' into app-1788 2026-02-05 08:59:22 -05:00
vineyardbovines a57faedbae update icon 2026-02-05 08:51:53 -05:00
pfrazee 423eddc474 Nightly source-language update 2026-02-05 03:07:42 +00:00
Darrin Loeliger 5c5b365ee9 Adding little message at the bottom of the drafts list (#9827)
* Add encouragement message to drafts list

Shows "So many thoughts, you should post one" at the bottom of the drafts list when user has more than 5 drafts.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Use Text component and center-align encouragement message

- Switch from ButtonText to Text component for better styling
- Add text-center alignment to the message

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 16:40:16 -06:00
Eric Bailey 1584c2de48 intl (#9826) 2026-02-04 15:49:33 -06:00
Samuel Newman bb6ce83198 [Drafts] NUX (#9825)
* drafts NUX

* use "Drafts" string

* change button copy
2026-02-04 15:39:55 -06:00
Samuel Newman 3abc361800 Exempt gifs from active video system (#9824) 2026-02-04 12:37:09 -08:00
Samuel Newman e6c4a539ca align alt text behaviour between gif types (#9822) 2026-02-04 12:34:14 -08:00
Eric Bailey 965b17ff86 Update android splash colors (#9821) 2026-02-04 14:07:18 -06:00
vineyardbovines a148b2477b update design for stacked avatars 2026-02-04 15:06:42 -05:00
Eric Bailey 546201c93c intl pull and extract:all (#9818) 2026-02-04 13:14:22 -06:00
Samuel Newman b3cbb3440a Make GIFs look like GIFs (#9809)
* set presentation field in record

* refer to it as a gif in the composer

* video player gif presentation style

* tweak badge

* only do the "manual loop" when absolutely necessary

* mute gifs

* reuse gif controls component for tenor gifs

* update media previews in notifications

* edit comment

* remove outdated prop
2026-02-04 13:05:17 -06:00
Samuel Newman da5c356fc7 Only treat animated gifs as videos, leave static gifs as images (#9814)
* only treat *animated* gifs as videos

* fix export
2026-02-04 13:00:29 -06:00
Eric Bailey 6f01503eac intl pull and extract:all (#9817) 2026-02-04 12:52:39 -06:00
pfrazee 24dbe799dc Nightly source-language update 2026-02-04 03:06:15 +00:00
Samuel Newman 3197cbcf36 disable saving drafts for replies (#9815) 2026-02-03 09:32:13 -08:00
Samuel Newman 017120b3e8 Add recId to suggestedUser:* events (#9764)
* add recId to onboarding

* add recId to follow dialog

* add recId to profile header suggestions

* add recId to feed interstitials, fix animation on native

* fix claude feedback

* fix yarn.lock ci
2026-02-03 10:42:12 -06:00
Samuel Newman 27d9462639 Add animation to content hider (#9812)
* add layout animation to contenthider

* add layout animation to posthider
2026-02-03 08:03:36 -08:00
Samuel Newman b2c95bc35a remove superjson (#9811) 2026-02-03 07:52:19 -08:00
pfrazee cbd48c855a Nightly source-language update 2026-02-03 03:09:12 +00:00
Samuel Newman 421c18ea7c fix image patch version (#9810) 2026-02-02 15:35:04 -08:00
Samuel Newman 26c84399dd Add light haptic feedback to Edit Profile button (#9787)
https://claude.ai/code/session_018ZjPcCUDPfTjQ5SGac3Zgs

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-02 15:33:55 -08:00
Samuel Newman 4f1d4821c5 Speed up startup by persisting some queries (#9594)
* persist startup queries

* Use IDB for query storage (#9687)

* Add storage abstraction for persisted query data

Introduce a platform-specific storage abstraction layer for react-query
persistence:
- Native: Uses MMKV for high-performance synchronous storage
- Web: Uses IndexedDB via the `idb` library for efficient async storage

This replaces the previous AsyncStorage implementation with more performant
platform-native solutions. The abstraction maintains API compatibility with
@tanstack/query-async-storage-persister.

* Refactor storage abstraction to use factory pattern

Change createPersistedQueryStorage to a factory function that accepts a
storage ID, allowing multiple isolated storage instances:
- Native: Each instance gets its own MMKV store
- Web: Each instance gets its own IndexedDB database

Adopt the factory pattern in:
- react-query.tsx: Uses 'persisted_queries' storage
- ageAssurance/data.tsx: Uses 'age_assurance' storage

This provides better separation between different query client caches
and allows each to be managed independently.

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Refactor to use archival storage

(cherry picked from commit a773b40e41c96f821cd32260919ce1437c0fc3ab)

* Improve archive db types

(cherry picked from commit 80e4959ba2aa00c984c26aed2f7dfae1095720b0)

* rm idb

* clear on logout, bust on app version

* create abstraction for persisting queries, make gcTime infinite

* Rm abstraction

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-02-02 11:55:01 -06:00
mozzius bfd5ed480f Nightly source-language update 2026-02-01 10:24:34 +00:00
Samuel Newman d9ef02737b Rename "lightbox" to "image viewer" in user-facing strings (#9807)
https://claude.ai/code/session_01LWKpUAY5WJL7UfeFJd9kVU

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 12:21:15 +02:00
mozzius 809b318fe4 Nightly source-language update 2026-02-01 08:10:57 +00:00
Samuel Newman 864af57fd9 Fix i18n string interpolation for device name (#9806)
Use a separate translatable string for "Media stored on another device"
instead of interpolating a translated fragment into another string.
This allows translators to properly handle the complete sentence for
languages with different grammar structures.

https://claude.ai/code/session_01TJMLcXE9HHneEXMEBJqL4u

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-01 00:08:28 -08:00
Eric Bailey ab98130295 Rm entitlement for now (#9804) 2026-01-30 20:30:00 -06:00
estrattonbailey a168e97d07 Nightly source-language update 2026-01-31 02:20:20 +00:00
Eric Bailey 748706daab Draft previews (#9803)
* Send deviceId and platform

* Add deviceId and deviceName to drafts, skip loading media for other devies

* WIP new preview

* show rich text in drafts list

(cherry picked from commit fb70d53d59)

* New draft preview UI

* Tighten up spacing in draft list

* Add i18n comments

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-01-30 17:00:54 -06:00
Spence Pope 45d6e50eb4 lint (#9802) 2026-01-30 22:48:31 +02:00
Eric Bailey e2a56b0191 Drafts fixes (#9795)
* Allow saving quote post drafts

* Remove warning logs for failed media loading

* Fix threadgates
2026-01-30 10:26:32 -06:00
Samuel Newman 1eb09b7210 Detect facets when composer is opened with mention (#9625)
* highlight the initial mention

* fix mention initalisation on web
2026-01-30 10:14:37 -06:00
Samuel Newman ee99320e1f fix copy-to-cache (#9799) 2026-01-30 09:47:35 -06:00
Samuel Newman 9689a6daaa add 2px margin below post text (#9748) 2026-01-30 05:44:04 -08:00
Samuel Newman 45735144ee adjust splash size (#9797) 2026-01-30 04:45:43 -08:00
pfrazee 4b86444bd8 Nightly source-language update 2026-01-30 03:07:37 +00:00
Samuel Newman 9ff5b2da50 Revert splash screen changes (#9792)
* Revert splash screen changes

This partially reverts commit 0ac5b07bfd.

* Keep android changes
2026-01-29 15:23:05 -06:00
Samuel Newman 58f532a495 [Drafts] Storage fixes (#9790)
* delete media from existsCache when deleting

* revoke media URLs

* skip revoking objecturls until the composer is completely closed

* [Drafts] Metrics (#9794)

* metrics for drafts

* Nit: format

* nit: use new util for clarity

* nit: use new util for clarity

---------

Co-authored-by: Eric Bailey <git@esb.lol>

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-29 15:21:38 -06:00
Samuel Newman 0babd0f475 [Drafts] Revert unnecessary gif changes (#9788)
* revert unnecessary gif changes

* Update ExternalEmbed.tsx
2026-01-29 15:08:48 -06:00
Samuel Newman 2cee96da8e Add ESLint rule to enforce Lingui msg usage (#9789)
* Add ESLint rule to enforce Lingui msg usage

Adds a custom ESLint rule 'lingui-msg-rule' that ensures the Lingui _()
function is called with msg`` template literals or plural/select macros,
preventing accidental misuse like _('string') which bypasses i18n.

https://claude.ai/code/session_01JMXXPUgAHiSBGmfGwUojKy

* Support msg({...}) descriptor form and add auto-fix

- Allow msg() function call form: _(msg({message: 'Hello'}))
- Add auto-fix for string literals: _('Bad') -> _(msg`Bad`)
- Add auto-fix for untagged templates: _(`Bad`) -> _(msg`Bad`)
- No auto-fix for variables/function calls (not safely fixable)

https://claude.ai/code/session_01JMXXPUgAHiSBGmfGwUojKy

* fix complex cases

* run autofix HELL YEAH

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-29 11:05:49 -08:00
pfrazee 31553f0d40 Nightly source-language update 2026-01-29 03:04:03 +00:00
Eric Bailey 0ac5b07bfd [APP-1801] New splash screen (#9780)
* MVP splash

* MVP of login screen

* Hack a footer into the logged out view

* revert unneeded

(cherry picked from commit 296420aa0df433b101389c44b05a40696e7389ae)

* Update config

(cherry picked from commit eac421966dfdee99d4c818ac07835a2a97e7590f)

* Bump size slightly
2026-01-28 20:05:14 -06:00
Samuel Newman d13df6c7e6 Drafts (#9691)
* Add drafts functionality to composer

- Add local storage layer for drafts (filesystem on native, IndexedDB on web)
- Add "Drafts" button to composer top bar showing badge with draft count
- Modify discard prompt to offer "Save Draft" option
- Add `restore_from_draft` action to composer reducer
- Support saving/restoring: text, facets, images, labels, threadgate, quote/link embeds
- Add placeholder hooks for future server API integration
- Add unit tests for draft serialization

Note: Video/GIF restoration marked as TODO for future implementation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix drafts button: always visible, adjacent to post button

- Make drafts button always visible (not just when drafts exist)
- Move button to be adjacent to the publish button
- If composer is empty: opens drafts list directly
- If composer has content: shows prompt to save/discard before viewing drafts
- Add badge showing draft count when drafts exist

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update drafts button: text-only, ghost/primary style

- Show "Drafts" or "Drafts (N)" as text, no icon
- Use ghost variant with primary color
- Match Cancel button styling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Remove draft count from button, just show "Drafts"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Increase drafts button horizontal padding and gap

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Use InnerFlatList and Dialog.Header for drafts dialog

- Switch from ScrollableInner to InnerFlatList
- Add Dialog.Header with back button in left slot
- Use sticky header

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Track draft ID in composer state machine

Adds draftId to ComposerState so that editing an existing draft and
saving it again updates the draft rather than creating a new one.

- Add draftId?: string to ComposerState type
- Set draftId when restoring from draft via restore_from_draft action
- Pass existingDraftId to save functions from composerState.draftId
- Add PageX icon for empty drafts state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add clear action to discard composer content

When pressing the Drafts button with content in the composer, the user
can choose to discard. This now properly clears the composer by
dispatching a 'clear' action that resets to an empty state.

- Add 'clear' action type to ComposerAction
- Implement clear case in composerReducer (resets to single empty post)
- Add handleClearComposer callback in Composer.tsx
- Pass onDiscard prop through ComposerTopBar to DraftsButton
- Call onDiscard before opening drafts dialog on discard

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Track dirty state to skip discard prompt for unchanged drafts

When a draft is loaded and the user hasn't made any changes, closing
the composer should not show the discard prompt since nothing would
be lost.

- Add isDirty field to ComposerState
- Set isDirty: true on all content-modifying actions
- Set isDirty: false on restore_from_draft, clear, and initial state
- Update onPressCancel to only show prompt if no draft or isDirty

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Redesign drafts list to show full thread preview

- Display all posts in a draft thread, not just the first
- First post uses larger avatar (42px), subsequent posts nested with
  smaller avatar (32px) and thread connector line
- Show author avatar, display name, handle, and relative timestamp
- Add overflow menu button (placeholder) on first post
- Display full text instead of truncated preview
- Add media preview component for images, GIFs, and videos
- Card layout with rounded corners and proper spacing
- Add gap separators between draft cards in list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix draft item styling based on feedback

- Add border and shadow to draft cards
- Remove trash button, move delete to overflow menu prompt
- Remove size differences for thread posts (same avatar/text size)
- Add spacing between header and first draft item
- Change prompt wording to "Discard draft"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Use real image embed components for draft preview

Replace custom image preview with AutoSizedImage for single images
and ImageLayoutGrid for multiple images. This gives drafts the same
polished image display as regular posts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Improve drafts dialog platform handling

- Render header outside FlatList on native, inside on web
- Use web() helper for conditional web-only props
- Replace ItemSeparatorComponent with mt_lg margin on items
- Add minHeight on web for better dialog sizing
- Simplify header structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Mark composer as clean after saving draft

Add mark_saved action that resets isDirty to false and updates the
draftId. This is dispatched after successfully saving a draft, allowing
the user to close the composer without a discard prompt since their
changes have been saved.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Apply dirty tracking to Drafts button prompt

Only show the save/discard prompt when pressing the Drafts button if
the composer has unsaved changes (isDirty). If the content is unchanged
from a loaded draft or was just saved, go directly to the drafts list.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix re-saving drafts with existing media

When re-saving a draft, the code was trying to copy media files that
were already in drafts storage to new locations, causing copy errors.

Changes:
- Add extractLocalIdFromPath() to detect if a path is already in drafts
- Track loadedMediaMap in ComposerState for identifying reusable media
- Only delete old media that wasn't reused during re-save
- Pass loadedMediaMap when saving to enable media reuse detection
- Disable pointer events on draft media preview

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* add vertical option to prompt, change copy

* fix import

* fix import

* Migrate drafts from local storage to server API

Replace local-only draft storage with the new `app.bsky.draft.*` server API:
- getDrafts, createDraft, updateDraft, deleteDraft endpoints

Key changes:
- Add api.ts with type converters (ComposerState <-> server Draft)
- Update hooks.ts to use server API instead of local storage
- Simplify storage.ts/storage.web.ts for local media caching only
- Media stored locally via localRef pattern (filepath in server draft)
- GIFs stored as external embeds with Tenor URL + dimensions
- Hide drafts button when replying (reply drafts not supported)
- Show "different device" note when media is missing locally

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* attempt to fix blob mangement

* Migrate storage.ts from expo-file-system/legacy to expo-file-system

Use the new object-based expo-file-system API (SDK 54+) with Directory
and File classes instead of the legacy function-based API. The new API
provides synchronous operations for file/directory existence checks,
creation, copying, deletion, and listing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add drafts-specific logger

Add a Drafts context to the logger system for better log categorization
and debugging of draft-related operations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: use drafts-specific logger in hooks and storage

Switch from the generic logger to the new drafts-specific logger
for better log categorization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: ensure media cache is populated before checking exists

On iOS (and web), the media cache wasn't populated before the drafts
query ran, causing drafts with local media to incorrectly show as
"missing media" on app restart. The issue would resolve itself after
closing and reopening the composer because by then the cache was ready.

This fix adds ensureMediaCachePopulated() and awaits it in useDrafts
before checking which media exists locally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: complete Gif object reconstruction for draft rehydration

Fix "Cannot read property 'url' of undefined" error when rehydrating
drafts with GIFs. The Gif object was missing required properties like
url, content_description, and media_formats.preview that are needed
by useResolveGifQuery and other components.

Also preserve alt text through serialization by storing it in URL
query params alongside dimensions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: load draft preview images and get dimensions

Fix draft preview images not showing on web and add proper aspect
ratio support:

1. Try to load all images regardless of the exists cache flag, which
   may be stale due to async cache population timing
2. Use Image.loadAsync() from expo-image to get image dimensions
3. Pass dimensions to viewImages for proper aspect ratio in previews

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: update save prompt copy when editing existing draft

When editing an existing draft (vs creating a new one), use "Save
changes" instead of "Save draft" in the save/discard prompts. This
provides clearer context to the user about what action they're taking.

Add isEditingDraft prop to DraftsButton and ComposerTopBar, and
update both prompts (in DraftsButton and Composer) with conditional
copy based on whether we're editing an existing draft.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* style: add bottom padding to drafts list

Add pb_xl padding to the drafts list content container for better
visual spacing at the bottom of the list.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: use typed error check for draft limit

Replace manual error object inspection with the proper
AppBskyDraftCreateDraft.DraftLimitReachedError type check for
cleaner and more reliable error handling.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* make storage functions async to match web

* log unknown errors

* delete left-over file

* move state to colo with composer

* fix: handle invalid GIF dimensions gracefully

Fix NaN aspectRatio when rehydrating GIFs from drafts by:

1. Adding validation in parseTenorGif to reject invalid dimensions
   (NaN, zero, or negative values)
2. Adding defensive checks in GifEmbed to fallback to 1:1 aspect
   ratio if dimensions are invalid
3. Adding defensive checks in composer ExternalEmbedGif to fallback
   to 16:9 if gif.media_formats.gif.dims is missing or invalid

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prevent double query string in GIF draft hydration

When loading a GIF from a draft, the URL was being corrupted with
double query strings like:
`?ww=498&hh=498?hh=498&ww=498`

This happened because:
1. serializeGif() adds ?ww=X&hh=Y&alt=Z to the Tenor URL
2. parseGifFromUrl() returned the full URL including our params
3. resolveGif() in resolve.ts then appends MORE params via string
   concatenation, creating a second ?

Fix: Strip our custom params (ww, hh, alt) from the URL in
parseGifFromUrl() before returning it, so the reconstructed GIF
has a clean base URL.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix draft button behaviour when publishing, tweak buttons

* ensure media unavaiable message is contrasty enough

* infinite query, rename file to queries

* simplify threadgate/postgate handling

* refactor: pass full draft data instead of re-fetching

The useLoadDraft and useDeleteDraftMutation hooks were fetching drafts
via getDrafts() to look up a draft by ID. This was problematic because
getDrafts is paginated, so drafts not on the first page wouldn't be
found.

Changes:
- Add full Draft object to DraftSummary type
- useLoadDraft now takes Draft directly (only loads local media)
- useDeleteDraftMutation now takes {draftId, draft} to avoid re-fetch
- Update DraftItem and DraftsListDialog to pass full draft data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix type errors

* docs: add notes on platform files and paginated APIs

- Platform-specific files (.web.ts, .native.ts) are resolved by the
  bundler automatically - just import normally, don't use require()
- Paginated APIs should use useInfiniteQuery, not useQuery

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* More CLAUDE.md updates

* Delete PLAN.md

* Use minimal media mode for draft display - REVERT IF NEEDED

* Enable pagination

* Add comment about headers

* remove extraneous comments

* Prevent runaway pagination

* fix detection rebase change

* use border_transparent

* Replace idb with idb-keyval for draft media storage

Simplifies web IndexedDB storage by using idb-keyval instead of the
full idb library. This reduces bundle size and aligns with the pattern
used in src/storage/archive/db/index.web.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix native draft media filename encoding

The previous approach replaced both / and : with _, but the reverse
transformation couldn't distinguish between them. This caused cache
misses for paths containing both characters.

Use encodeURIComponent/decodeURIComponent for a proper reversible
encoding.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* convert useLoadDraft() hook to regular async function

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* update atproto api

* clean up orphaned media

* restore videos

* save/restore captions

* restore postgates

* Copy updates from Darrin

* Ope fix missed vertical props

* get image aspect ratio when restoring

* get videos working on native

* get video restoration working on native

* sanitize handles properly in draftitem

* fix yarn.lock

* Swap console logs

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-28 16:54:26 -06:00
bnewbold a18f1b68e8 CI: auto-detect go runtime version from go.mod (#9766) 2026-01-28 13:16:55 -08:00
Spence Pope b9c92d39eb [APP-1761] Prevent welcome modal from reappearing (#9786)
* store welcome modal appearance in localstorage

* lint

* redundancy
2026-01-28 10:41:48 -08:00
Samuel Newman d45a2c832d Redo web lightbox, add animations and keyboard a11y (#9481)
* redo web lightbox, add animations

* add rect-avi to shell

* fix lingui msgs
2026-01-28 10:13:52 -08:00
Matthieu Sieben fd49349b71 update atproto deps (#9784) 2026-01-28 10:46:48 -06:00
Samuel Newman 277e985e1f prevent lightbox initial jitter (#9762) 2026-01-28 07:46:53 -08:00
Samuel Newman 3b2573bc56 [Lighbox perf - 1] Fix memoization of List component, defer re-rendering when opening lightbox (#9759)
* memoize FlatList_INTERNAL

* defer render, put handleScrolledDownChange in non reactive callback

* lintfix useDedupe
2026-01-28 07:35:43 -08:00
pfrazee ae77320d81 Nightly source-language update 2026-01-28 02:51:12 +00:00
Eric Bailey 72b7516d9b Prompts refresh (#9781)
* Round boi

* Wrap a few things in Prompt.Content

* Couple tweaks
2026-01-27 20:02:55 -06:00
Samuel Newman 220e989f3d improve lightbox smoothness (#9200) 2026-01-27 16:57:49 -06:00
Eric Bailey 39e7132fd8 [APP-1784] Proper fix for Live Now status not showing (#9779)
* Be sure to validate if actor is allowed to be live on certain domain

* Rename for clarity

* Memoize
2026-01-27 16:44:27 -06:00
Samuel Newman 26605ee730 Fix console logging in Firefox and other browsers (#9775)
Use CSS-based %c styling for browser consoles instead of ANSI escape codes, which don't render properly in Firefox. Keep ANSI codes for native/terminal environments.

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-27 16:24:29 -06:00
Spence Pope f1c50baa4e link to labelers by did (#9777) 2026-01-27 13:34:21 -08:00
Samuel Newman e49ce42a12 Disable KeyboardProvider preload for faster initial load (#9778)
Adds preload={false} to KeyboardProvider to prevent unnecessary keyboard controller initialization during app startup.

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-27 12:07:08 -08:00
Eric Bailey fd6b8fcbf1 Fix Live Now not showing for non-streamer (#9773)
* Fix Live Now not showing for non-streamer

* Rename for clarity

* Logged out users too
2026-01-27 12:16:54 -06:00
Samuel Newman 2953b3a094 Typecheck app.config.js (#9771)
* typecheck app.config.js

* fix eslint warning

* use import.meta.url instead of __dirname

* dirname, not url
2026-01-27 09:09:06 -08:00
Samuel Newman 69a765cc0d enable ccache for dev builds on iOS (#9770) 2026-01-27 08:46:05 -08:00
Samuel Newman dd7bb1bc14 fix IS_DEV in app config (#9769) 2026-01-27 06:22:32 -08:00
Alex Benzer d31bc7f335 Update suggested accounts heading (#9765) 2026-01-27 05:49:18 -08:00
Eric Bailey f26ac583e6 Add idb-keyval backed archival storage (#9754)
* Add idb-keyval backed archival storage

* Cleanup

* Remove test
2026-01-26 13:39:12 -06:00
pfrazee 2ad84d7dfc Nightly source-language update 2026-01-26 02:58:16 +00:00
Eric Bailey 282b5e8460 Bump version to 1.116.0 (#9751) 2026-01-25 16:04:27 -06:00
Eric Bailey f82bc98d8d Allow users to dismiss sidebar LEF banner (#9753) 2026-01-25 15:48:18 -06:00
Eric Bailey 3b7806963a Add more Live Event refreshing (#9745)
* Refresh on foreground

* Add back interval
2026-01-24 13:39:55 -06:00
pfrazee 49e7a96cd9 Nightly source-language update 2026-01-24 02:45:32 +00:00
Eric Bailey 3523e7ce58 1.115.0 fast follows (#9743)
* Fix caching, fix attributes setting

* Use useCallOnce hook

* Update dismissal handling

* Update copy
2026-01-23 16:28:40 -06:00
Eric Bailey 967b3b49d9 1.114.1 Release Prep (#9738)
* intl pull, extract:all

* Clean cache for e2e
2026-01-22 17:51:53 -06:00
Eric Bailey 97083bb55b Enable Bluecast for Live Now (#9737) 2026-01-22 16:59:13 -06:00
Eric Bailey df89b79c2a [APP-1787] Some analytics cleanup (#9736)
* Clean up flags

* Move getMetadataForLogger

* Nail down attributers

* Polyfill features cache
2026-01-22 16:57:59 -06:00
Samuel Newman 6534630d16 Refactor GrowthHack to always render on iOS with enabled prop (#9723)
Drill down an `enabled` prop to ThreadItemAnchorFollowButtonInner so
that the GrowthHack wrapper is always rendered on iOS, even when the
follow button shouldn't be displayed. The inner component returns null
when disabled, allowing GrowthHack to render its logo without children.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-22 16:48:33 -06:00
Eric Bailey 25a1ed1209 [APP-1782] Analytics migration (#9734)
* WIP

* Clean up growthbook code, integrate into init and sessions

* Move everything out of React

* Add metrics client

* Move to separate file

* Shared metadata cache

* Ensure we update metadata when session ID changes

* Ensure userMetadata is cleared when logging out

* WIP revamp

* Integrate feature gates into analytics context

* Clean up old code

* Fix useMeta util

* Some comments and cleanup

* Add logger to base analytics context

* Refactor current route handling

* Rip out LogEvent from navigation

* Update tracking endpoint

* Migrate toClout

* Clear out statsig client

* Add todo, reset logger readme

* Ope fix statsig noop

* Refactor logging in feed-feedback, add debug logging to metrics client

* Remove LogEvents alias for Metrics

* Prefer root package export

* Remove Metrics alias from logger

* [APP-1782] Migrate to new analytics APIs (#9735)

* Migrate logEvent to useAnalytics

* Migrate logger.metric to useAnalytics

* Migrate tricky spot, fix types

* Migrate remaining tricky spot

* Missed one

* Remove metric() from logger

* Migrate useGate to useAnalytics

* Remove all other StatSig mentions

* Update event payload

* Update logger tests

* Mock expo method

* Fix session ID bug

* Add session ID test

* Add test for metrics client

* Clarify intent

* Clean up core analytics file

* Clean up the call once utils

* Fix TODO

* Fix TODO

* Fix TODO

* Fix TODO

* Fix TODO

* Remove debug code

* Fix navigation context

* OK nav context is not working, todo

* Checkpoint: works but feels hacky

* Fix navigation context issue

* Improve feature API

* Improve metric logging

* Update logger tests
2026-01-22 15:33:45 -06:00
bnewbold 8614e5e105 bump copyright year to 2026 (#9732) 2026-01-20 08:50:07 +02:00
pfrazee 7da65efc08 Nightly source-language update 2026-01-20 02:49:52 +00:00
Eric Bailey 4f01d4cc81 Resolve same version of @types/estree (#9731) 2026-01-19 16:20:08 -06:00
Eric Bailey b4f57b94aa Fix Live Now reporting container collapse on Android (#9730) 2026-01-19 15:33:15 -06:00
Eric Bailey bd9e8244f1 [APP-1783] Clean up some feature gates and logging (#9729)
* Remove gates we don't need

* Clean up some logging

* Keep disable gates around for now

* Add missing gate

* Revert file

* Revert package changes
2026-01-19 15:32:02 -06:00
Eric Bailey 5989bf7fad Remove some unused things (#9719) 2026-01-19 10:48:13 -06:00
Samuel Newman a4f173d008 Bump version to 1.115.0 (#9726)
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-18 20:03:45 +02:00
pfrazee f244afcd9c Nightly source-language update 2026-01-17 02:42:35 +00:00
Eric Bailey 62c0c06bbf Move browser env into main env (#9718) 2026-01-16 17:20:03 -06:00
Eric Bailey 0589bd7d9e Move /platform/detection vars into /env (#9707)
* Add platform vars to env

* Replace /platform/detection with /env
2026-01-16 16:28:17 -06:00
Samuel Newman bd510d8468 Upgrade ESLint to v9 with flat config (#9680)
* Upgrade ESLint to v9 with flat config

- Upgrade eslint from v8 to v9.18.0
- Migrate from .eslintrc.js to eslint.config.mjs (flat config)
- Upgrade typescript-eslint to v8.20.0 (unified package)
- Replace eslint-plugin-import with eslint-plugin-import-x for flat config support
- Add globals package for environment globals
- Update eslint-plugin-bsky-internal with proper meta objects for ESLint v9
- Fix deprecated context.getScope() API usage
- Update bskyembed to use flat config
- Remove deprecated --ext flag from lint scripts
- Configure rules to maintain previous behavior while using new ESLint version

* Fix varsIgnorePattern to require character after underscore

Restore the original pattern `^_.+` instead of `^_` so that lingui's
`const { _ } = useLingui()` will still be flagged when unused.

* Update ESLint rule tests for flat config format

- Update RuleTester to use flat config languageOptions instead of
  eslintrc parser format
- Remove duplicate test case that ESLint v9 now detects
- Add Jest globals for test files

* update eslint package versions

* lint android a11y

* enable typechecked rules, switch them to warn

* fix yarn lock ci

* Fix CI failure

* Remove unused globals?

* Organize a bit, add quiet to main lint command

* Allow ternary

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-16 16:24:28 -06:00
Samuel Newman acc26c965d make live now gate fail-open (#9714) 2026-01-16 08:34:00 -08:00
Samuel Newman fbd1138d97 Add fishing minigame (#9713) 2026-01-16 08:31:01 -08:00
Samuel Newman 9c563f2a48 Fix collapsed button by simplifying, keep container width (#9712) 2026-01-16 10:18:41 -06:00
Eric Bailey 1d4263078d Refetch live events every 5 min (#9706) 2026-01-15 16:26:44 -06:00
Eric Bailey 367eebe600 Reset default AA debug for E2E (#9705) 2026-01-15 13:05:11 -06:00
Eric Bailey 06a8a7efc2 intl pull and extract:all (#9704) 2026-01-15 10:58:01 -06:00
Samuel Newman 29f8bc998d Highlight first feed in sidebar if non selected (#9703) 2026-01-15 07:12:15 -08:00
Eric Bailey 4760e59ea4 Add back deleted css block (#9702) 2026-01-15 08:09:24 -06:00
Samuel Newman d9e37a222a scope last-selected-feed to per-account (#9500) 2026-01-15 06:07:09 -08:00
estrattonbailey 3b98f2f8ab Nightly source-language update 2026-01-15 03:06:32 +00:00
Samuel Newman ab85b509c0 Watermark posts in screenshots (#9637)
* watermark posts in screenshots

* disable when app is backgrounded

* fix alignment

* show watermark even when there isn't a button
2026-01-14 21:03:13 -06:00
Samuel Newman 65faee4f08 Unregister push token on signout (#8661)
* unregister push - WIP

* create agent and submit push token revokation

* mock unregisterpush

* fix import

* Add proxy headers

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-14 20:55:35 -06:00
pfrazee 94be661794 Nightly source-language update 2026-01-15 02:48:02 +00:00
Samuel Newman 10aa46aa9e Prevent flash of wrong theme on startup (web) (#9577)
* prevent flash of wrong theme on startup

* move bg color to #root

* Update and use existing system

* Darken slightly, better contrast

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-14 20:41:59 -06:00
Samuel Newman 8f82ad66df make button blue when tooltip is visible (#9668) 2026-01-14 20:34:59 -06:00
Samuel Newman 1cb362b596 Add loading="lazy" to expo-image on web (#9480)
* add `loading="lazy"` to expo-image

* add `loading="lazy"` to embed cards, avatars

* get rid of useless image wrapper indirection

* move image components to components dir

* fix imports

* fix import

* Keep avis eager

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-14 20:29:13 -06:00
Eric Bailey f960d2fbc6 fix: make logo show in qr code by absolutely positioning svg on top of it (#9373) (#9700)
* fix: make logo show in qr code by absolutely positioning svg on top of it

* fix: remove log and add explanation comment

* fix: only apply qrcode fix to web

Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
2026-01-14 20:28:48 -06:00
Samuel Newman 58ac9a3e7b Patch video player to add a ton of debug logging (#9657) 2026-01-14 19:18:29 -06:00
Eric Bailey bbab7695f9 Add some device location debug (#9693) 2026-01-14 19:05:33 -06:00
Samuel Newman 26aa7c0d9a Add cashtag support for stock ticker discussions (#9689)
* Add cashtag support for stock ticker discussions

Display cashtags ($TICKER format) as clickable links with dedicated menu actions and search feed, alongside hashtags. Includes composer highlighting and proper formatting.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* Fix cashtag search query to use # prefix

Cashtags need to be searched as "#$BTC" rather than just "$BTC" to work
with the search API.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update @atproto/api to 0.18.14 with cashtag support

The updated package includes native CASHTAG_REGEX detection for stock
ticker symbols like $AAPL and $BTC.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix todo, remove redundant validation

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-01-14 19:03:48 -06:00
estrattonbailey 498a09e797 Nightly source-language update 2026-01-14 22:59:53 +00:00
Eric Bailey 2223babc2b [APP-1759] Live Now Open Beta (#9699)
* Add report dialog to LiveStatus dialog

* Mr Worldwide™

* Bug fix bug fix

* Copy update

* Simplify parsing

* Bump api sdk

* update dev-env

* Update yarn.lock

* Bump api sdk

* Refactor useActorStatus, add disablement and appeal dialog

* Fix types

* Guard against chat profile views

* Go live (disabled)

* Fix types

* Update config and gates

* Add allowed services

* Merge conflicts

* Fix gradient handling for nudge

* Only show nudge on your own profile

* Fix live avi overflow breakage

* Add TODO

* Feedback

* Update nux image

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-01-14 16:57:21 -06:00
Eric Bailey 5922c6622f [APP-1767] Live event feeds (#9696)
* Update env config for new worker setup

* Add liveEvents context

* Add live event feed card to Explore

* Add Discover banner/trending handling, device storage

* Add prefs methods, hook up to Discover banner

* Add settings toggle

* Fix up metrics and mutations

* Simplify undo logic

* Handle previews

* Update overlay color and text color handling

* Update metrics

* Handle live event in feed card

* Show multiple feeds on Explore for bsky team

* Fix dev/preview handling bug

* Add sidebar cards, update types

* Fix type error

* Fix type error

* Feedback

* Blurhash fix

* Copy update

* Dev only debug hook
2026-01-14 15:09:01 -06:00
Alex Benzer e684c21572 Improved client events for feed interactions (#9695) 2026-01-14 12:53:24 -08:00
Samuel Newman 226b19ae43 Reduce startup hang by not querying fonts (#9670)
* query fonts lazily

* use `lazy var`
2026-01-14 12:22:26 -08:00
Samuel Newman cb6e65e313 pin AsyncStorage to v2.2.0 (#9656) 2026-01-14 11:16:49 -08:00
Samuel Newman af92610864 Add comprehensive CLAUDE.md development guide (#9666)
* Add comprehensive CLAUDE.md development guide

Document the codebase architecture, styling system (ALF), component patterns
(Dialog, Menu, Button), i18n with Lingui, state management with TanStack Query,
and navigation patterns to help Claude work effectively in this codebase.

* Add footguns section to CLAUDE.md

Document critical pitfalls including:
- Dialog close callback pattern (control.close(() => ...)) for avoiding
  race conditions with navigation, state updates, and opening other dialogs
- Controlled vs uncontrolled input guidance
- Platform-specific component behavior differences

* Add React Compiler note to footguns section

Document that useMemo/useCallback are unnecessary since React Compiler
handles memoization automatically. Only use them for specific cases like
effect dependencies or non-React library interop.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-14 11:16:34 -08:00
pfrazee ca905eb3e1 Nightly source-language update 2026-01-14 02:52:08 +00:00
Samuel Newman 61c919110e Expose QueryClient for TanStack Query DevTools browser extension (#9678)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 09:56:06 -08:00
Eric Bailey 9aa360d328 Do not render links if uri is invalid (#9663)
* Do not render links if uri is invalid

* Update comment
2026-01-13 09:37:00 -06:00
Alex Benzer 2d8de1ddc3 Standardize metadata for client events in feeds (#9653) 2026-01-13 02:42:26 -08:00
Samuel Newman c540dae4e7 Set up conductor.json with yarn install and web server configuration (#9676)
Add conductor setup and run scripts that install dependencies and start the dev server with a dynamically allocated port.

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-10 01:52:59 -08:00
pfrazee 2818c7f508 Nightly source-language update 2026-01-10 02:43:34 +00:00
Alex Benzer c4fd9980cc Cleaner sidebar layout (#9603) 2026-01-10 00:13:43 +02:00
Samuel Newman 966ae68dd2 Set Claude model to Opus (#9672) 2026-01-09 08:45:38 -08:00
Samuel Newman d2aea9161b Delete claude-code-review.yml (#9671) 2026-01-09 08:35:38 -08:00
Eric Bailey edb19dd6cf [APP-1750] Add the ability to report livestreams (#9654)
* Add report dialog to LiveStatus dialog

* Mr Worldwide™

* Bug fix bug fix

* Copy update

* Simplify parsing

* Bump api sdk

* update dev-env

* Update yarn.lock

* Bump api sdk

* Refactor useActorStatus, add disablement and appeal dialog

* Fix types

* Guard against chat profile views

* Go live (disabled)

* Fix types

* Status reports should only go to bsky

* Ah yeah let's not override types

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2026-01-09 10:19:47 -06:00
Samuel Newman 85a616eee0 Add Claude Code GitHub Workflow (#9667)
* "Claude PR Assistant workflow"

* "Claude Code Review workflow"
2026-01-09 07:46:02 -08:00
pfrazee 7285157ab5 Nightly source-language update 2026-01-09 02:47:50 +00:00
Eric Bailey b3f775d1d8 [AAv2] Improve minimum age handling (#9650)
* Improve miminum age handling

* Update api sdk

* Fix bad import
2026-01-08 15:36:26 -06:00
Eric Bailey a1857d62bd Handle AA config failure (#9660)
* Clarify some comments

* Add error state in case of config failure

* Add retry button and relayout to accommodate
2026-01-08 14:35:43 -06:00
Samuel Newman d82592f072 Fix full-screen back gesture over PagerView on iOS 26 (#9659)
Patches react-native-pager-view to handle iOS 26's
interactiveContentPopGestureRecognizer, using the same logic that
already exists for RNSPanGestureRecognizer: on the leftmost page,
disable the scrollview's pan gesture to let the back gesture through.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 11:36:01 -08:00
Samuel Newman dae03312c9 Bump version to v1.114 (#9661) 2026-01-08 11:35:42 -08:00
Samuel Newman c2e5a18e42 Unify build concurrency to one build per platform (#9655)
Configure concurrency groups so only one iOS build and one Android build
can run at a time across all workflows. This prevents manual builds from
conflicting with automatic builds triggered by fingerprint changes.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 07:35:13 -08:00
Samuel Newman 2efc047f64 bump version to v1.113.1 (#9652) 2026-01-07 13:15:55 -08:00
Samuel Newman 80049bbe82 exclude images from bundle size workflow (#9647) 2026-01-07 02:54:59 -08:00
Samuel Newman e627d37f42 [v1.113 prep] Translations (#9646)
* intl:pull

* yarn intl:extract:all
2026-01-07 01:14:48 -08:00
pfrazee 24fe45aaa1 Nightly source-language update 2026-01-07 02:48:01 +00:00
Samuel Newman 0deb9511af Enable lightbox for profile banner (#9643)
* allow pressing banner to view

* remove special type
2026-01-06 10:37:47 -08:00
Samuel Newman 43ebb80a5b patch in proguard rules (#9447) 2026-01-06 09:31:54 -08:00
Samuel Newman d91e206e21 Fix prefetching starter pack query (#9595)
* fix prefetching starter pack query

* add comment
2026-01-06 10:58:46 -06:00
Samuel Newman 493bd6dcf6 update crop tool, use new package name (#9642) 2026-01-06 18:29:37 +02:00
Samuel Newman 4f6ff6fc73 lazy load storybook (#9612) 2026-01-06 08:03:21 -08:00
estrattonbailey 7ba2997af5 Nightly source-language update 2026-01-06 00:18:33 +00:00
Samuel Newman 4b6fbcc050 fix suggested follow card size (#9638) 2026-01-05 09:36:54 -08:00
chuanchuan 55806f1087 fix(native): dismiss recommendation bottom sheet on profile navigation (#9608) 2026-01-02 02:02:26 -08:00
Samuel Newman 0aaf11aa7b fix drawer layout on mobile web (#9618) 2025-12-30 09:56:05 -08:00
Samuel Newman 9cfa7d0ba8 Remove RNGH from web bundle (#9528)
* remove RNGH on web

* add intentionally-failing webpack alias

* Update webpack.config.js
2025-12-30 03:40:19 -08:00
Samuel Newman 9743149c26 Replace graphemer with unicode-segmenter (#9526)
* replace graphemer with unicode-segmenter

* use grapheme entrypoint

* force resolution of unicode-segmenter
2025-12-30 03:39:09 -08:00
Samuel Newman 82877a096d Manually update source languages (#9611)
* manually update source langs

* add `intl:push-sources` script
2025-12-30 02:08:26 -08:00
Samuel Newman 12dc38c5fc replace lodash.isequal with fast-deep-equal (#9529) 2025-12-30 01:47:29 -08:00
Samuel Newman 7d5de60401 fix long handles in account switch (#8373) 2025-12-30 01:35:24 -08:00
Samuel Newman 8136258cd8 add pressed state to quote embed (#9592) 2025-12-30 01:31:09 -08:00
Samuel Newman afe5db8b57 clamp gif size (#9610) 2025-12-30 01:30:49 -08:00
Samuel Newman 893dd78a00 remove unused dep (#9606) 2025-12-30 01:23:48 -08:00
Eric Bailey b38013a12f Small copy tweaks (#9557) 2025-12-29 10:21:09 -08:00
Samuel Newman aa1395542f tweak styles of composer prompt (#9524) 2025-12-29 10:19:08 -08:00
Samuel Newman caa02db87b Update react native screens, remove patch (#9210)
* update react native screens

* bump rns

* see if nightly works

* update nightly

* yay it's out

* update react-nav

* update drawer layout and remove patch

* Update createNativeStackNavigatorWithAuth.tsx

* render drawer as "layout" component

* rm react-nav/drawer (unused)

* restore drawer layout patch
2025-12-29 10:16:49 -08:00
Alex Benzer f390167f66 Remove unwanted drop shadow on "see more" card on Android (#9584) 2025-12-29 02:00:29 -08:00
surfdude29 6275d2e0fd Temporarily use English for Esperanto intl-displaynames polyfill (#9574)
* use English for Esperanto `intl-displaynames` until bug is fixed

* Update src/locale/i18n.ts

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-12-29 01:38:40 -08:00
Alex Benzer 3e1e1ba00e Better copy for "must be signed in" message (#9602) 2025-12-29 01:38:04 -08:00
hailey 699fdbac01 update actions (#9586)
* update actions

* update actions

* $

* procenv
2025-12-22 19:21:17 -08:00
pfrazee a14a9be127 Nightly source-language update 2025-12-19 02:44:03 +00:00
Eric Bailey 998ee78e3d Move NUXDialogs into shell (#9573) 2025-12-18 12:08:17 -06:00
Eric Bailey a355eedf85 Improve instructions on NoAccessScreen and bday dialog (#9571) 2025-12-18 11:05:39 -06:00
Eric Bailey 89cffdf5d0 Ignore new flag SVGs in build output (#9567) 2025-12-18 09:45:51 -06:00
pfrazee e9524d8a83 Nightly source-language update 2025-12-18 02:42:38 +00:00
Eric Bailey f50b70e2b4 Bump to v1.113.0 (#9569) 2025-12-17 17:03:16 -06:00
Alex Benzer e80e2f66c3 Adds a dismiss button to user suggestions (#9484)
* Add dismiss button to user suggestions

* Adds dismiss button to suggested user cards, behind a feature gate

* Reverse gate check, best practice

* Sync DISMISS_ANIMATION_DURATION

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-12-17 15:45:21 -06:00
Samuel Newman f02b9c323f Change empty states if not own profile (#9518)
* change empty states if not own profile

* Update ProfileFeedgens.tsx

* capitalise starter packs
2025-12-17 14:10:39 -06:00
estrattonbailey 2200cc95d8 Nightly source-language update 2025-12-15 20:49:31 +00:00
Eric Bailey f45e58e057 [AAv2] Add blurb for orgs (#9556)
* Add blurb for orgs

* Update
2025-12-15 14:38:05 -06:00
Eric Bailey da87515d0a [APP-1684] Some contact import tweaks (#9555)
* Handle download link

* Improve NUX geo gating from #9549

* Fix alignment of phone code select

* Show full name

* Add gate to nux banner

* Add gate to settings screen

* Invert gate check in settings, whoops
2025-12-15 13:35:28 -06:00
surfdude29 348e7fa379 Restore notification count in BottomBar (#9554) 2025-12-15 09:15:52 -06:00
Samuel Newman df4e888347 disable nux in e2e (#9551) 2025-12-13 11:59:07 -08:00
Samuel Newman b48ca13172 v112 Languages (#9550)
* intl:pull

* extract
2025-12-13 11:17:05 -08:00
pfrazee 3485dd37c2 Nightly source-language update 2025-12-13 02:41:21 +00:00
Samuel Newman c9ce214a66 Gate NUX by country allowlist (#9549)
* country gate nux

* whoops
2025-12-12 12:37:14 -08:00
Samuel Newman 9971e91f9c create profile record before upload (#9547) 2025-12-12 12:32:13 -08:00
Samuel Newman 8cee40beff Find Friend links (#9546)
* links

* policy

* Update PhoneInput.tsx
2025-12-12 12:23:19 -08:00
mozzius 4ffc1263e7 Nightly source-language update 2025-12-12 18:35:53 +00:00
Samuel Newman ad7d49ef8f [Contacts] Contacts matching flow (#9486)
* add expo-contacts

* add expo-sms

* update copy

* add basic settings screen

* state machine, flow screen

* phone input screen

* otp screen

* tweak spacing

* resend code logic

* add layoutanimationconfig

* check availablility in settings screen

* get contacts

* matches screen

* search, temp setup for matches UI

* add a bunch of number parsing logic with libphonenumber

* cast to looser type

* rename sync to find

FCF (Find Contacts Flow)

* update geolocation hook

* nicer design for settings screen

* add completed state

* up border contrast

* update expo deps

* add pending spinner

* add country whitelist

* add empty state screen

* drop add more functionality

* upload -> import

* fix typo

* fix permission string

* copy updates

* rm envelope icon

* update sms copy

* add inviteinfo component

* woke is back

* [Contacts] NUXes (#9515)

* add a bunch of number parsing logic with libphonenumber

* add banner nux

* add announcement nux

* native only nux

* rm shitty animation

* move isNative check

* [Contacts] Onboarding step (#9489)

* add a bunch of number parsing logic with libphonenumber

* restructure onboarding to better support dynamic screens

* integrate existing flow into onboarding

* add intro step

* lift state up to allow going back freely

* gate onboarding by geo if unsupported country

* add done button to standalone flow

* [Contacts] Add `contact-match` notification type to feed (#9519)

* add a bunch of number parsing logic with libphonenumber

* add contact-joined notif type

* update string, api package

* Update NotificationFeedItem.tsx

* Update NotificationFeedItem.tsx

* Delete SyncContactsFlow.web.tsx

* fix follow back btn for this case

* [Contacts] API integration (#9487)

* api integration for flow

* copy tweak

* tweaks after running it

* wire up status page

* rename toast

* use api lib

* rm temp code

* maybe fix otp error

* clear code on error/resend

* add 1s delay to verify success

* update package versions

* Delete SyncContactsFlow.web.tsx

* try and fix yarn.lock lint

* even woker

* fix uppercase friends

* surfdude feedback

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* rm log

* allow resend on invalid code

* Update GetContacts.tsx

* overwrite country code if possible

* fix Apple's Best Feature

* devenv latest

* disable bounces

* interactive keyboard dismiss

* copy changes

* national format

* allow resending immediately

* move success state down a bit

* Update FindContactsSettings.tsx

* [Contacts] More onboarding changes (#9491)

* integrate existing flow into onboarding

* refreshed onboarding styles, rm stepper

* center content on web

* Add back dismiss button for internal onboarding

* Import sort

---------

Co-authored-by: Eric Bailey <git@esb.lol>

* add matches query to shadow

* add clockwise arrow

* update status design, fix dismiss, fix queries

* add metrics

* add more comments

* Update metrics.ts

* refetch both queries on PTR

* fix shadow state in matches page

* reduce empty space at bottom

* show contact info on matches

* filter out contacts without numbers at an earlier stage

* Error handling 

* get notifs working

* filter out businesses

* rm log

* remove TODO from learn more links

* try and exclude from web bundle

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2025-12-12 10:32:06 -08:00
pfrazee d3a6db4594 Nightly source-language update 2025-12-12 02:44:56 +00:00
Eric Bailey d3923c1f2e Move Takendown and Deactivated screens out to the shell alongside AA (#9538) 2025-12-11 13:28:50 -06:00
Eric Bailey 8d5b1c83cc [AAv2] Drop regionCode if we can't get a short code on Android (#9542)
* Drop regionCode if we can't get a short code on Android

* Add a debug metric
2025-12-11 13:24:07 -06:00
Eric Bailey 37a73b1755 Don't overwrite more mod prefs than necessary (#9536) 2025-12-11 13:15:02 -06:00
Eric Bailey a3fc082148 Remove redundant disclaimer text (#9541) 2025-12-11 13:14:53 -06:00
Eric Bailey fcc4018971 Add a few aav2 metrics (#9540)
* Add a few aav2 metrics

* Eh
2025-12-11 13:14:43 -06:00
Samuel Newman 506bad83ba force esm version of unicode-segmenter on web (#9532) 2025-12-11 17:49:24 +02:00
Jim Calabro f7e61056f5 Sitemap Handlers for bsky.app (#9525)
* implement sitemap handlers for users

* ensure compressed payload is passed through

* improved handling

* reverse header order

* add the sitemap to robots.txt
2025-12-11 09:09:52 -05:00
Samuel Newman 1fded4e914 remove tel code select from storybook (#9531) 2025-12-11 03:29:45 -08:00
pfrazee a3e47dc189 Nightly source-language update 2025-12-11 02:44:11 +00:00
Eric Bailey 9b2999268b Copy update (#9522) 2025-12-10 17:14:42 -06:00
Samuel Newman e34ed14887 CAR dialog - add close button (#9470)
* car dialog add close button

* update toast import
2025-12-10 13:22:55 -08:00
Samuel Newman 6ccda945e5 Telephone country code select (#9473)
* add telephone code select

* add flags

* run svgo on flags

* get it somewhat working on web

* get web closed state working

* verify country code we get from geo

* trim down names to shorter common versions

* add labels to other selects

* make international tel codes a static object

* add component to storybook

* Update src/lib/international-telephone-codes.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* update to new geo hook

* use Intl.DisplayNames, add polyfill

* use in rather than keys().includes()

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-12-10 12:12:30 -08:00
Samuel Newman 07e1b3a0b6 update jest-expo (#9520) 2025-12-10 09:10:37 -08:00
Samuel Newman d5ff9c4380 build android from source in prod (#9517) 2025-12-10 08:56:29 -08:00
pfrazee a0906f6b8d Nightly source-language update 2025-12-10 02:43:24 +00:00
Eric Bailey b47f5f023e [APP-1674] Add bday fallback for app passwords (#9513)
* Add bday fallback for app passwords

* Update birthdate copy, add isAppPassword handling on NoAccessScreen

* Update copy

* Update usage

* Bump API package

* HmmMMMmmm

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* s/a/your

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Say hello

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-12-09 16:42:41 -06:00
Samuel Newman 4d50555e56 Update package.json (#9507) 2025-12-09 01:38:26 -08:00
pfrazee 2d8e855e25 Nightly source-language update 2025-12-09 02:41:44 +00:00
Eric Bailey 4407e59e15 Read from mergedGeolocation when setting mod authorities (#9509)
* Read from mergedGeolocation when setting mod authorities

* Add deprecation notice
2025-12-08 19:24:19 -06:00
Eric Bailey a0c4a6b307 Add handling for birthdate prefs write failure (#9508) 2025-12-08 17:43:38 -06:00
Alex Benzer 296d22d626 Large composer prompt image picker and camera icons (#9503) 2025-12-08 14:17:53 -06:00
Alex Benzer 214615df22 Fix issue where empty state message is not centered (#9501) 2025-12-08 14:16:07 -06:00
RetroSunstar 960df7bf6d Fixed an error found in #8969 for the Lists tab (#9502) 2025-12-07 03:07:41 -08:00
Eric Bailey b4e1fdfccf pull and extract (#9495) 2025-12-05 16:35:09 -06:00
Eric Bailey d16c8aedfb Prep v1.111.0 e2e (#9494)
* Add e2e debug support for AA

* Remove dup tap call

* Update dev-env
2025-12-05 16:34:08 -06:00
Samuel Newman c68e5e82af change dot-separated time style again (#9493) 2025-12-05 14:56:59 -06:00
Alex Benzer 8637ba7564 Make post composer prompt look less like a search field (#9492)
* Make post composer prompt look less like a search field

* change color on press

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-12-05 12:56:51 -08:00
estrattonbailey ad60be6c31 Nightly source-language update 2025-12-05 18:34:31 +00:00
Alex Benzer 9a0cb09d3a Fire the post:view client event in more places, anywhere a post can be seen (#9467)
* Fire the post:view client event in more places

* Fix bad import

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-12-05 12:32:19 -06:00
Eric Bailey db81cefb86 Fix birthday bug being perpetually snoozed (#9488) 2025-12-05 12:17:43 -06:00
Samuel Newman 89223d92d1 use FULL_SCREEN presentation (#9449) 2025-12-05 12:03:07 -06:00
Alex Benzer ef3a79495e Hook up suggestedUser:seen client events (#9468)
* Hook up suggestedUser:seen client events

* Fix crash when clicking "find people to follow"

* While we're at it, fix the position of the X button on the "find people to follow" modal

* Add suggestedDid and category attributes to suggestedUser client events

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-12-05 10:58:05 -06:00
Alex Benzer 6686ebc232 Add more client events to profile followers/following pages (#9466)
* Add more client events to profile followers/following pages

* Remove unneeded logContext attribute
2025-12-05 10:27:35 -06:00
Alex Benzer d3878bf0ac Clicking "see more" on user suggestions opens suggested users modal (#9482)
* Clicking "see more" on user suggestions now opens modal

* More conventional pattern

* Remove unneeded optional

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-12-05 09:25:24 -06:00
pfrazee fb3f67b1af Nightly source-language update 2025-12-05 02:42:40 +00:00
Samuel Newman cf6d8b060b fix nested link in repost reason (#9450) 2025-12-04 17:47:54 -06:00
Samuel Newman f985debeca Fix status bar color in video feed (#9434) 2025-12-04 17:47:13 -06:00
Samuel Newman 756cf0a2d5 patch speculative fix to RN (#9436) 2025-12-04 17:46:46 -06:00
Samuel Newman 732c7e59a8 patch expo-modules-core lifecycle fix (#9472) 2025-12-04 17:45:34 -06:00
Alex Benzer bc39b553f9 Adds a composer prompt on the home screen to invite users to post (#9464)
* Add a composer prompt on home

* Added image upload button

* Feed composer buttons

* Feed composer styles

* Add client events, auto-open gallery when button is pressed

* Add feature gate

* Move gate check to last

* Small style cleanups

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-12-04 17:39:56 -06:00
Samuel Newman 55eb6c5628 add shadow filter to post feeds (#9406) 2025-12-04 17:09:54 -06:00
estrattonbailey 051dbd289c Nightly source-language update 2025-12-04 22:41:47 +00:00
Eric Bailey e3494a4882 [AAv2] Fix for mod screen (#9483)
* Add derived flags, add back disabled adult content for users under 18

* Update copy
2025-12-04 16:39:31 -06:00
estrattonbailey 59aa2bd8b6 Nightly source-language update 2025-12-04 21:26:08 +00:00
Eric Bailey c4aef9f668 Age Assurance V2 (#9479)
* Age Assurance V2

* Tighten up test

* Add todos for sdk migration

* Align RQ versions

* Use useEffect for side effect

* Improve effects, memoize

* Standarize on birthdate

* Copy feedback

* Copilot

* Add support link

* Reove double ..

* Cleanup

* Remove redirect dialog

* Cleanup todos, add comments

* Update splash in main template too

* Mock some stuff

* Exhaustive checks

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* Exhaustive checks

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* Small fix to bday handling

* Add comment

* onboarding style tweak

sneaking this in sorry!

* rm unreachable breaks

* Put useIntentHandler back on web

* Remove misleading success set

* Align on birthdate

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-12-04 15:20:00 -06:00
Jim Calabro 7735183af4 Merge pull request #9475 from bluesky-social/jc/cache
Use FromCache Rather Than FromFile on Template Render
2025-12-03 16:47:46 -05:00
pfrazee f0c9e1ea5e Nightly source-language update 2025-12-03 02:41:44 +00:00
Samuel Newman 4d1b1bb2fd Catch crop cancelled errors (#9451) 2025-12-02 10:06:12 +02:00
pfrazee 507531e1db Nightly source-language update 2025-12-02 02:41:53 +00:00
Samuel Newman 0ba4edab8d add dot separated time style (#9455) 2025-12-01 17:52:19 +02:00
pfrazee 1eacf427b5 Nightly source-language update 2025-11-28 02:39:29 +00:00
Anastasiya Uraleva d0649e9a9e [APP-1403] Profile empty states (#8969)
* update: Empty state component

* update type error fixes

* add empty state icon

* update translations on labels

* update: lint error for empty state

* remove unused prompt

* update type errors

* fix lint errors and update profile followers and profile follows

* updated starterpack

* fix lint errors

* address feedback

* update icons to be a react element

* update icons

* update viewbox for icons

* optimize: icons and update profile lists

* optimize: icons and update profile lists

* lint error fix

* update iconSize from the rebase
2025-11-27 03:22:03 -08:00
pfrazee 2d056e5be6 Nightly source-language update 2025-11-27 02:40:10 +00:00
Samuel Newman 7f2d46b731 use contentFit prop (#9452) 2025-11-26 09:06:12 -08:00
bnewbold 6ab3751b5c update golang to v1.25 (and some containers do debian bookworm) (#9442)
* bskyweb: bump go to v1.25

* update docker images to go v1.25 and debian bookworm

* bump CI to go v1.25
2025-11-25 10:35:50 -08:00
pfrazee 8424083de9 Nightly source-language update 2025-11-23 02:47:44 +00:00
Samuel Newman 54af170448 Use new blue everywhere (#9435) 2025-11-23 00:20:37 +02:00
Samuel Newman 8b00b8f945 Split React Native patches into individual patches (#9429) 2025-11-22 23:49:57 +02:00
tomsqrd 9136be68b3 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 <tom.quinders@check24.de>
2025-11-22 03:03:30 -08:00
Samuel Newman af13c70444 bump version to v1.111 (#9431) 2025-11-21 22:56:49 +02:00
Samuel Newman 9330e21c6a patch in upstream expo updates fix (#9428) 2025-11-21 07:15:23 -08:00
Samuel Newman 5d220e49a0 [v1.110.1 release prep] Translations (#9426)
* `yarn intl:pull`

* `yarn intl:extract:all`
2025-11-20 10:23:36 -08:00
Samuel Newman 31fac4a62b Use macos-26-xlarge runner, update actions to resolve caching issues (#9411)
* use xlarge runner for macos build

* try and fix yarn cache

* update actions/cache for pods step

* use expo github action main rather than v8

* update all actions to the same

* use yarn cache where missing
2025-11-20 10:07:38 -08:00
Samuel Newman 13c4ef83f1 Add minimal header to profiles (#8936) 2025-11-20 18:31:41 +02:00
Samuel Newman dfe9f9fa07 use slightly more rounded repost icon (#9424) 2025-11-20 18:00:14 +02:00
Samuel Newman 2919a7da7f Search lists cleanup, pagninate actor search (#9009) 2025-11-20 17:59:20 +02:00
Samuel Newman 2792b4cef0 prevent webview from showing during device attest (#9425) 2025-11-20 17:54:02 +02:00
Samuel Newman f5a5eee32c handle share intents when app first launches (#9410) 2025-11-20 17:52:33 +02:00
Samuel Newman 9823bc98e9 fix android 2fa input not being paste-able (#9407) 2025-11-20 17:49:58 +02:00
Samuel Newman f57268e9b8 Use useConfirmEmail hook in deep link verification flow (#9413)
* use useConfirmEmail hook in deep link verification flow

* more straightforward logic
2025-11-20 07:48:13 -08:00
Alex Benzer 002a63b125 Post view client event (#9408)
* Adds post:view client event tracking in feeds

* Add post:view event on the post page itself

* Don't send post:view to statsig for now

* convert to non reactive callback to reduce rerenders

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-11-20 07:41:56 -08:00
Samuel Newman 2faf62c7f7 Update version to v1.110.1 (#9416) 2025-11-19 13:21:56 -08:00
Eric Bailey 7b99d8c7c3 Update Android build runner (#9404) 2025-11-17 16:36:03 -06:00
Samuel Newman c2979ffefa re-extract languages (#9402) 2025-11-17 11:00:06 -08:00
Samuel Newman bc62b3da76 Add metrics for composer threadgate (#9401)
* add metrics for composer threadgate

* add metrics to the in-thread version

* fix type error
2025-11-17 10:51:01 -08:00
Samuel Newman 53b3bd93a5 [1.110.0 release prep] Translations (#9400)
* `yarn intl:pull`

* `yarn intl:extract:all`
2025-11-17 08:37:07 -08:00
Samuel Newman 7197a064d7 [v1.110] Release prep (#9399)
* yml formatting whatever

* fix date input color

* fix up report dialog tests

* dumb fix to bypass save password popup

* remove tooltip in e2e

* Update index.e2e.tsx

* skip gate in e2e
2025-11-17 08:01:02 -08:00
Samuel Newman ef97a20c23 Fix password autofill on iOS (#9397)
* fix password autofill on iOS

* update autocomplete props, rm textContentType
2025-11-17 06:27:00 -08:00
Samuel Newman f53d5b6f27 add haptics to segmented control (#9398) 2025-11-17 05:23:28 -08:00
Alex Benzer 084f60c88f Profile follow client events (#9385)
* Add parameters to profile:follow

Track who was followed, whose profile generated the follow, and the position of the person who was followed in the list

* Add profileCard:seen event

* Don't send "profileCard:seen" event to Statsig

* Clean up

* prevent overzealous clearing

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-11-17 05:04:11 -08:00
Alex Benzer 2f678a3ccd Adds a "follow back" button to follow notifications (#9359)
* Adds a "follow back" button to follow notifications

* get shadowcache logic working, strip out manual optimistic update

* whoops, don't just stick any old profile in there

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-11-17 05:00:26 -08:00
Samuel Newman d464cde412 add transparency prop to tab bar (#9336) 2025-11-17 04:59:56 -08:00
surfdude29 a35a81a508 Change text on threadgate button from 'Anybody' to 'Anyone' (#9390) 2025-11-17 03:27:43 -08:00
surfdude29 4145878819 remove accessibilityHint and tweak labels (#9391) 2025-11-17 03:26:39 -08:00
Alex Benzer fb058afa54 Add client event for clicks on desktop feeds (#9386) 2025-11-17 03:23:56 -08:00
pfrazee 185fd39092 Nightly source-language update 2025-11-15 02:38:20 +00:00
Samuel Newman 92926a2417 SegmentedControl component (#8606)
* new segmented control

* fix type error

* convert server input, use CSS for web

* add segmented control to storybook

* use segmented control in embed dialog

* add to suggested text wrappers

* update change handle dialog

* update styles since button changes

* fix atom

* style updates to segmented control, add size prop

* update state in layout effect rather than in render

* set type = 'radio' as default

* prevent expansion in server dialog on iOS

* use non reactive callback in needsUpdate effect
2025-11-14 11:43:28 -08:00
Samuel Newman 7a8ab551e3 update crop tool to latest, adjust to API changes (#9389) 2025-11-14 11:05:31 -08:00
Samuel Newman 1caac024ab Fix video letterboxing issue (#9339)
* give video a black background on web

* Video crop on web tweaks (#9371)

* Remove video embed crop option to reduce confusion

* Improve default thumb and border on web

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-11-14 10:29:49 -08:00
Samuel Newman 24c96ac881 Image saving - fix extension, increase download timeout (#9388) 2025-11-14 17:46:39 +02:00
Samuel Newman c92ac4abc1 flatten may return undefined (#9387) 2025-11-14 17:46:20 +02:00
Samuel Newman b422765aed [Threadgate] Tweak threadgate buttons (#9173)
* tweak in-post threadgate button

* tweak composer threadgate button

* reduce date length slightly

* pressed styles

* make date length depend on breakpoint

* add chevron to label btn

* add tiny chevron, special-case button icon width

* [Threadgate] Add hint (#9350)

* get tooltip working on web

* add compatibility layer for working in iOS sheets

* add timeout to profile tooltip now that it appears instantly

* rm debug code

* Update ThreadgateBtn.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* remeasure when keyboard changes

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* fix types

* [Threadgate] Refresh dialog (#9342)

* wip new ui

* update threadgate dialog with new designs

* restore nobody option

* relayout android sheet when ratio changes

* fix ratio changing case in bottom sheet

* timebox reached, use setTimeout

* update panel styles

* missing imports

* extract out Panel

* tweak layout animation

* fix icon color

* use same color mechamism for icon as text

* restore the header

* refreshed toggle styles (#9343)

* [Threadgate] Persist settings (#9341)

* add persist toggle to threadgate dialog

* move state back down

* sort out spacing

* wire up query

* @surfdude29 tweaks

* use tiny chevron in WhoCanReply

* wait for prefetch before opening

* move Panel into the Toggle namespace

* default -> pref

* use medium date length

* rm hover state from web selects, fix border radius

* fix key issue in Selects

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-11-14 06:21:37 -08:00
Samuel Newman b56ee74cdb Tweak bg on follows you pill (#9384)
* tweak bg on follows you pill

* same for profile
2025-11-13 12:01:49 -08:00
Samuel Newman 554275957e update button spacing (#9383) 2025-11-13 09:24:27 -08:00
pfrazee 4884677826 Nightly source-language update 2025-11-13 02:41:07 +00:00
Samuel Newman e663e824b7 Add rectangular shape to button (#9382) 2025-11-13 00:35:34 +02:00
Samuel Newman 68a4d84450 tweak settings divider color (#9381) 2025-11-12 04:09:57 -08:00
pfrazee 9982961b8f Nightly source-language update 2025-11-12 02:40:28 +00:00
Eric Bailey 1711626493 Migrate remaining old report reasons, remove old unused file (#9378) 2025-11-11 14:13:11 -06:00
Samuel Newman cb2af3cd18 only round buttons if size is set (#9377) 2025-11-11 10:26:49 -06:00
Samuel Newman 59ffaa8a81 fix rounded notifs (#9374) 2025-11-11 03:18:43 -08:00
Samuel Newman a275e8999e restore flatten in emoji reaction picker (#9375) 2025-11-11 03:18:24 -08:00
pfrazee 8d2d45508d Nightly source-language update 2025-11-11 02:41:06 +00:00
Samuel Newman ddf82dcc44 Delete EmptyStateWithButton.tsx (#9348) 2025-11-10 18:02:52 -06:00
Samuel Newman 835a716eaf Try and guard against play/pause function being called after player is destroyed (#9364)
* try and guard play/pause against unmount

* add try/catch to avoid fatal crashes
2025-11-10 18:02:13 -06:00
Samuel Newman bb365856c9 fix react query error (#9365) 2025-11-10 18:02:01 -06:00
Samuel Newman bcd0e40192 Make the buttons round again (#9367)
* make the base button round

* some miscalleaneous tweaks
2025-11-10 18:01:41 -06:00
Samuel Newman 5208aa4a65 rm unused follow button (#9332) 2025-11-10 16:37:01 -06:00
surfdude29 1cdb105af5 tweak accessibility labels (#9347) 2025-11-10 16:31:08 -06:00
Samuel Newman ad91029f10 Select account redesign (#8905)
* new designs for select account

* tweak web styles

* add logged out indicator

* unify helper function

* move error, try catch
2025-11-10 06:02:53 -08:00
Alex Benzer 4791486aa7 Fixes a ts error caused by WelcomeModal styles on logged-out homepage (#9362)
* Fixes a ts error caused by welcomemodal styles on logged-out homepage

* use flatten util instead

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-11-10 03:18:31 -08:00
Samuel Newman df00ffa532 use feed module header bottom border on web (#9363) 2025-11-10 03:16:45 -08:00
pfrazee 70ccd82745 Nightly source-language update 2025-11-10 02:42:45 +00:00
Caidan 14604f735b fix: feed title line heights (#9346) 2025-11-09 18:24:12 +02:00
pfrazee 9583c310b9 Nightly source-language update 2025-11-07 02:40:28 +00:00
hailey d6ca9e6b41 [Reporting] Add new reporting categories and reasons (#9079)
* start adding new report reasons

* cleanup

* use updated types

* cleanup open/closed logic

* other fix

* state fix

* rename type

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/index.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/moderation/ReportDialog/utils/useReportOptions.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* add mapping

* Replace consts and maps using exported values

* Map to deprecated reason if necessary, send some reports only to Bluesky

* Use only new report reason types

* Cleanup

* Bump package, integrate new reasons

* Adjust sorting, return type, integrate feedback

* Just remove sort

* Finish 'other' handling

* Update descriptions

* Just invert filter logic, no functional change but feels more correct

* Clarify handling

* fix deep imports

* fix type error

* [Reporting] Integrate new `ReportDialog` into DMs (#9213)

* Update types, fork copy for convo vs message

* Integrate in remaining spots

* Replace DoneStep with separate dialog that opens after reporting

* Handle profile error state by just showing a success message

* Delete old dms ReportDialog

* Chats only go to bsky

* Only open block or delete dialog if submitted successfully

* make close button always large

* prevent expansion of blockordelete dialog

* Delete old report dialog (#9214)e

* Skip labeler selection for Bluesky-only cases

* Rename AfterReportDialog

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-11-06 15:40:13 -06:00
David Buchanan fd14bbfef9 move yt embed script to its own source file (#9337) 2025-11-06 10:15:49 -08:00
Samuel Newman 9f98e53541 Revert "push in post-post toast (#9252)" (#9344)
This reverts commit 54a388d132.
2025-11-06 09:40:31 -08:00
Eric Bailey 7bf00424c4 Clean up getPostThreadV2 settings/params in prep for future work (#9179)
* Deprecate prioritizeFollowedUsers

* Bump API package
2025-11-06 10:42:08 -06:00
Samuel Newman ec2c580aae Fix Android crash by try/catch dialog open (#9335) 2025-11-06 17:58:14 +02:00
pfrazee 215f97bad9 Nightly source-language update 2025-11-06 02:41:01 +00:00
Samuel Newman 531ff6c433 restore flatten to a place that is needed (#9334) 2025-11-05 02:07:01 -08:00
pfrazee 2077699a07 Nightly source-language update 2025-11-05 02:40:28 +00:00
Samuel Newman fb3f1c3936 always send #interactionReply (#9330) 2025-11-04 19:21:55 +02:00
Samuel Newman 78e20c4200 Prevent sparse arrays in snapToOffsets (#9329)
* prevent sparse arrays in snapToOffsets

* wait, sparse arrays don't work like that

* more readable check even if it's technically useless

* make the second check actually work
2025-11-04 09:08:43 -08:00
Eric Bailey d8e7e65a9d Post skele tweaks (#9328)
* feat: PostControlsSkeleton (#9205)

* feat: new PostControlsSkeleton component

* feat: integrate PostControlsSkeleton into other usages

* fix: shrink skele pill and circle sizes a bit

* Couple small tweaks

(cherry picked from commit f6a38ec42274bffc41b2898d8addb735791494fd)

---------

Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
2025-11-04 10:09:17 -06:00
Samuel Newman 16b14b9d13 Restore await to dismissBrowser in intent handler (#9326) 2025-11-04 16:57:52 +02:00
Samuel Newman fd5b1b3a59 add even more optional chaining to link thing (#9327) 2025-11-04 16:57:39 +02:00
Samuel Newman c9033dbc39 Avoid asking for read access to photo library when saving images on iOS (#9297)
* use saveToLibraryAsync on iOS

* use _(msg``) syntax
2025-11-04 06:33:30 -08:00
Samuel Newman 1b0fbd503e Remove use of flatten where possible (#9325)
* remove use of flatten where possible

* restore flatten where it says it's needed

* missing utils alpha
2025-11-04 05:43:08 -08:00
pfrazee 0bcde99025 Nightly source-language update 2025-11-04 02:40:47 +00:00
Alex Benzer 5a4e012fdc Adds client event for empty feed error (#9287)
* Adds client event for empty feed error

* Only log for discover

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-11-03 11:37:40 -06:00
Samuel Newman 6ccedd5e31 ship post follow follow suggestions (#9251) 2025-11-03 09:18:49 -08:00
Samuel Newman feab782ba9 Android lightbox minor perf improvement (#9274)
* minor perf improvement on android for lightbox

* Use correct `cachePolicy` when prefetching lightbox images (#9275)

* use `memory` cachePolicy when prefetching

* use `memory` cache policy on iOS lightbox images
2025-11-03 09:18:26 -08:00
Samuel Newman ca505fbbd2 chore: update caniuse (#9239) 2025-11-03 09:18:02 -08:00
Samuel Newman e5f3131644 fix right nav overflow (#9253) 2025-11-03 09:15:29 -08:00
Samuel Newman 54a388d132 push in post-post toast (#9252) 2025-11-03 09:15:12 -08:00
Samuel Newman b1f1b2050c add android ripple effect to images in feed (#9273) 2025-11-03 09:13:22 -08:00
Samuel Newman 9070fa9a8d Improve image download timeout handling (#9276) 2025-11-03 09:11:29 -08:00
Samuel Newman 55e9298ee8 disable wake-from-background OTA on Android (#9317) 2025-11-03 09:08:34 -08:00
Samuel Newman c6215065bd Update Android adaptive icon (#9298)
* remove adaptive icon gradient background

* try new foreground/monochrome assets

* adjust size back down
2025-11-03 09:05:18 -08:00
Samuel Newman bd3594ceea use 0.5px media border on high DPI screens on web (#9311) 2025-10-31 07:07:43 -07:00
Samuel Newman de6d2f1912 Update web dim <html> background color (#9307)
* update dim background color

* Update other css colors

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-10-30 11:44:22 -05:00
Jason Ericson faa49feec8 Fixed Apple Music song embeds. (#9220)
* Fixed Apple Music song embeds  when using a direct song link (vs playlist or album).

* Fixed song embed test.

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Jason Ericson <jasonmarkericson@gmail.com>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-30 09:25:42 -07:00
pfrazee 55b3474ad2 Nightly source-language update 2025-10-30 02:39:59 +00:00
Anastasiya Uraleva b0eb079ff8 [APP-1321]: Update brand embeds more clearly (#8955)
* Nightly source-language update

* run prettier

* wip

* feat: use local dev for bskyembed test.html

* feat: commit generated files which i'm not sure about

* Revert "feat: commit generated files which i'm not sure about"

This reverts commit b891efdaa1fd7ddd4417bfd5267e861a25a93b0e.

* chore: revert change to bskyembed/.eslintrc.cjs

* chore: remove generated file from bskyweb/static

* chore: revert messages.po changes

* Update bskyembed/test.html

* Nightly source-language update

* Update: Bluesky embeds

* update: embed colors for light and dark modes

* remove unused changes

* remove duplicate word

* update border radius and add cursor pointer

* add icons folder for dynamic icons

---------

Co-authored-by: Anastasiya Uraleva <anastasiya@Mac.localdomain>
Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Anastasiya Uraleva <anastasiya@Anastasiyas-MacBook-Pro.local>
2025-10-29 17:24:48 -07:00
Samuel Newman cfa2534ccb remove await on dismissBrowser (#9304) 2025-10-29 21:23:10 +02:00
Samuel Newman 2d626f7bbf Fix android icon file name (#9303) 2025-10-29 09:58:56 -07:00
Samuel Newman 5efae600dd Add dark/tinted icon variants (#9241)
* add tinted icon style

* new dark icon

* use icon composer file

* rename some icons, ensure default ios is still there

* use solid fill instead of auto gradient

* fix web build

* back to gradient

* add . for consistency

* rename `default_old` to `legacy`
2025-10-29 09:49:45 -07:00
Eric Bailey 339f3320c6 [TS-147] Add internal debug field display (#9302)
* Add internal debug field display

* Update title
2025-10-29 11:21:19 -05:00
Samuel Newman 3107efb449 Get rid of share menu fade edge effect (#9250) 2025-10-29 09:09:07 -07:00
Maxym Hyba faa389e060 rm clamp (#9271) 2025-10-29 08:46:21 -07:00
Samuel Newman f15a949ef8 more text elements missing emoji prop (#9301) 2025-10-29 08:44:52 -07:00
Samuel Newman bb908a5534 fix line height in hover card (#9281) 2025-10-29 08:44:17 -07:00
Samuel Newman a503fe27f5 add emoji prop to image alt text (#9278) 2025-10-29 08:43:53 -07:00
Chenyu d58c6c9ebc use admonition instead of toast for errors when appealing labels (#9272)
* use admonition instead of toast for errors when appealing labels

* address commments
2025-10-29 06:48:23 -07:00
Caidan bd5d102826 fix: prevent profile suggestions animation when no data available (#9277)
Prevents AccordionAnimation from animating open on web when suggestions array is empty by adding conditional rendering logic to AnimatedProfileHeaderSuggestedFollows component.
2025-10-29 02:43:18 -07:00
pfrazee 32bf6cf01f Nightly source-language update 2025-10-29 02:41:25 +00:00
Samuel Newman e3f5967407 Android - add fallbacks when saving image to gallery (#9293)
* add fallback paths when saving image to gallery

* `debug` -> `info`
2025-10-28 09:58:41 -07:00
Samuel Newman 900e569ef2 Override Reduce Motion on load-bearing animation (#9294) 2025-10-28 09:52:31 -07:00
Samuel Newman 1883f3fc7b Close IAB when it triggers an intent (#8454)
* Close IAB if it opens a link to the app

* native only

* await close
2025-10-28 08:52:09 -07:00
Samuel Newman 5cff45bdc8 Update expo and related dependencies (#9291)
* update expo + deps

* reanimated patch right version

* Update yarn.lock

* update other rn packages
2025-10-28 06:44:16 -07:00
Samuel Newman 0c6469f272 Change adaptive icon background color (#9286) 2025-10-28 00:26:52 -07:00
pfrazee b98350f927 Nightly source-language update 2025-10-28 02:38:50 +00:00
Samuel Newman 206f52fb13 Bump version to 1.110.0 (#9284) 2025-10-27 21:55:55 +02:00
Samuel Newman 78c8a6037f Remove feed:seen from statsig (#9261) 2025-10-27 13:23:38 -05:00
bnewbold 28e132ae03 clarify in content hider if label is on overall account (#9264)
* clarify in content hider if label is on overall account

* fix bool typo

* Update src/components/moderation/ContentHider.tsx

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* rename variable for clarity

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-10-27 10:37:47 -07:00
Samuel Newman 25a2a2c7f6 Revert "Disable Sentry sampling for now (#9262)" (#9282)
This reverts commit de68915bc0.
2025-10-27 11:12:27 -05:00
Eric Bailey 2a4b825637 Release 1.109.0 i18n take III (#9269) 2025-10-23 11:27:49 -05:00
Eric Bailey c00b3d1050 Don't log errors for known app password issues in chat (#9268) 2025-10-23 11:18:53 -05:00
Eric Bailey 74cb81b65f Add config to disable update overlay, disable it (#9267) 2025-10-23 11:16:55 -05:00
Samuel Newman e28aa7d1ab Patch out PerformanceMonitor component (#9266)
* patch out perf monitor component

* make PerformanceMonitor a noop

* rm debug stuff
2025-10-23 10:35:37 -05:00
Eric Bailey d4d5d6d8b9 intl:pull and intl:extract:all (#9263) 2025-10-22 15:51:19 -05:00
Eric Bailey de68915bc0 Disable Sentry sampling for now (#9262) 2025-10-22 14:08:25 -05:00
Samuel Newman ea00663e7f Android CI - Clear cache on second build (#9223)
* clear cache on second build

* alternative cache cleaning method
2025-10-22 10:05:00 -07:00
Samuel Newman 12e57378e8 fix android testflight ci (#9237) 2025-10-22 10:04:36 -07:00
Eric Bailey 24606dbcfc Don't need to be logging upstream errors (#9260) 2025-10-22 11:39:14 -05:00
Eric Bailey 6f31121e51 Check for network error before reporting push token issue (#9258) 2025-10-22 11:36:40 -05:00
Eric Bailey 1abc96314b Don't log network errors (#9257) 2025-10-22 11:36:32 -05:00
Eric Bailey 7cc897d096 Remove error log for Bluesky feed service issues (#9256) 2025-10-22 11:36:24 -05:00
Eric Bailey 6ed30213c8 Add 'Upstream service unreachable' to network errors (#9255) 2025-10-22 11:36:18 -05:00
Eric Bailey d7e8429753 Get iOS debug files into Sentry (#9242)
* Add buildArtifactPaths to iOS builds

* Update privacyManifests

* Revert changes to build configs

* Add --include-sources flag

* Add nativeCrash tester

* Sam's crash testbed

(cherry picked from commit b0a0cb7799cd900777570cae7dc10461cf811e0f)

* Output artifacts, tarball, extract and upload dSYM to Sentry

* Revert "Sam's crash testbed"

This reverts commit cc2c9828a0.

* Remove sources for other targets, include sources for main bundle

* Apply suggestion from @mozzius

* Apply suggestion from @mozzius

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-10-22 09:17:52 -05:00
Alex Benzer 6086bc5d5c Add a client event for "See more" link on suggested user interstitials (#9249) 2025-10-22 03:53:42 -07:00
Samuel Newman 199821d670 make gifs square again (#9236) 2025-10-20 07:15:01 -07:00
Eric Bailey 11dff765db Hook up post shadow to saved posts (#9225) 2025-10-20 03:05:49 -07:00
hailey 73639aa571 fix regex (#9234) 2025-10-19 09:20:53 -07:00
pfrazee f3b6d85913 Nightly source-language update 2025-10-17 02:36:59 +00:00
Samuel Newman 239d3cc535 [Release prep] 1.109.0 translations (#9218)
* intl:pull

* intl:extract:all
2025-10-16 10:08:15 -07:00
Samuel Newman d49d43f6eb update app icon (#9219) 2025-10-16 10:08:06 -07:00
Samuel Newman a482dae936 [Release prep] 1.109.0 E2E fixes (#9216)
* list tests

* fix create account

* get onboarding e2e tests working

* get curate list test working

* Update thread-muting.yml
2025-10-16 07:31:11 -07:00
Samuel Newman 25d44d8939 update xcode (#9215) 2025-10-16 07:26:52 -07:00
pfrazee e7801a0b76 Nightly source-language update 2025-10-16 02:37:46 +00:00
Eric Bailey 7861cd153d Remove notice in create account flow (#9209)
* Remove notice of policy updates

* Rm debug code
2025-10-15 13:56:29 -05:00
Samuel Newman be53a168ba Move interests clientside and add finance (#9176)
* move interests clientside

* add finance

* try and ensure there's always data for the "all" category

* add empty state for suggested accounts

* simplify error wording
2025-10-15 09:37:24 -07:00
Samuel Newman b56d0c419b add sort import suggestions plugin (#8335) 2025-10-15 09:37:07 -07:00
Samuel Newman 03adb4260f patch fractional font size issue (#9199) 2025-10-15 09:14:42 -07:00
Eric Bailey 27926f093c Fix computation of isLastSibling, isLastChild, and replyIndex (#9202)
* Fix computation of isLastSibling and isLastChild to account for muted or
otherwise hidden replies

* Update comments

* isLastSiblingByCounts isn't needed, should rely only on the count of replies seen

* The counters serve the same purpose, we only need to know the count of the actual replies rendered to the view in order to calculate the replyIndex

* Remove redundant check
2025-10-15 11:13:08 -05:00
Samuel Newman fe5a623b44 Haptic on profile buttons (#6034)
* play haptic on profile buttons

* change react import
2025-10-15 09:10:26 -07:00
Samuel Newman fc944841ce add large content viewer to tabs (#8394) 2025-10-15 11:02:47 -05:00
Samuel Newman 66ca3e34a4 fix invalid tweaking to date string (#8415) 2025-10-15 11:00:29 -05:00
Samuel Newman 4788106f32 change flatlist config for explore page (#9083) 2025-10-15 08:57:30 -07:00
Samuel Newman 6414bda252 delay toast after posting (#9208) 2025-10-15 08:56:35 -07:00
Samuel Newman 591fd262b3 make sure border radius matches inset border (#9207) 2025-10-15 08:55:46 -07:00
Samuel Newman ede10368d5 cache pages in explore feed previews (#9082) 2025-10-15 18:54:54 +03:00
Samuel Newman 1127e50248 [Onboarding] Add starterpacks step (#9007)
* add onboarding starterpacks step

* tweak starter pack cards

* fix web styling

* use new API

* add screen transitions to onboarding

* skip host account

* bump limit to 6

* tweak font weight

* rm commented out code

* fix yarn.lock

* limit starter packs experiment to english speakers
2025-10-15 07:32:38 -07:00
jim e4485da4ff Merge pull request #9189 from internet-development/binaryfiddler/hashtag
prompt user to log in on hashtag screen
2025-10-15 01:12:49 -07:00
Alex Benzer 6c7fd96528 Add metrics for when OPs click "hide reply for me" or "hide reply for everyone" (#9206) 2025-10-15 08:33:30 +01:00
pfrazee 6a1c0ff346 Nightly source-language update 2025-10-15 02:38:20 +00:00
Chenyu Huang ad18439148 use hasSession 2025-10-14 14:15:19 -07:00
Eric Bailey 7280e44ea2 Remove log (#9204) 2025-10-14 11:49:02 -05:00
Eric Bailey 7e6b23bd86 Fix ternary in moderation settings that caused a double title (#9198) 2025-10-14 09:17:34 -05:00
pfrazee d2bc22e9be Nightly source-language update 2025-10-14 02:36:22 +00:00
Eric Bailey 0b50e9f109 Remove remaining usages of old post thread query (#9184)
* Remove remaining usages of old post thread query

* Add PostThreadContext, cache mutator for threadgates on threads, pipe it through

* Replace getPostThread in threadgate query

* Replace in initQuote handling, which isn't even used rn...

* Missing import

* Revert ext change
2025-10-13 18:36:11 -05:00
Samuel Newman 0f6a99c8a5 enable numberOfLines on replyTo component (#9196) 2025-10-13 09:36:06 -07:00
Samuel Newman ea9986f127 fix label spacing (#9195) 2025-10-13 09:35:31 -07:00
Samuel Newman 5222a6e1c3 tidy up post reasons (#9194) 2025-10-13 08:24:02 -07:00
pfrazee b7f505ab00 Nightly source-language update 2025-10-11 02:32:55 +00:00
Chenyu Huang 34f2cc2322 prompt user to log in on hashtag screen 2025-10-10 14:17:57 -07:00
Eric Bailey 8a30131686 Combine SubtleWebHover and SubtleHover, default to web only for all cases (#9188) 2025-10-10 15:05:20 -05:00
Samuel Newman 69421d1f33 Change anchor text size to lg from xl (#9185) 2025-10-10 14:32:56 -05:00
Eric Bailey 995808e816 Bump alf package to include new colors (#9187) 2025-10-10 14:30:15 -05:00
Samuel Newman 508fa2aced Value prop screen - polish, convert to pager (#9133)
* turn value prop screen into a pager on native

* rm ts-ingore

* fix pager swipe on android

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-10-10 14:05:22 -05:00
Samuel Newman d528ae791f Fix add/edit moderation list form placeholder text (#9074)
* fix placeholder text of modlist dialog

* change header font weight

* fix string
2025-10-10 13:57:42 -05:00
Samuel Newman b15903e0cb move feed context on desktop (#9015) 2025-10-10 13:56:57 -05:00
Samuel Newman 9bea450803 Fix profile label section soft reset scroll (#9103)
* Fix profile label section scrollto

* revert back to headerHeight
2025-10-10 13:56:23 -05:00
Samuel Newman fb5d56422a fix border color of feed/list embeds (#9021) 2025-10-10 13:55:43 -05:00
Samuel Newman ad38d905e4 fix newline backspace behaviour (#9038) 2025-10-10 13:55:16 -05:00
Samuel Newman 2b34721876 fix android admonition flex collapse issue (#9120) 2025-10-10 11:43:23 -05:00
Samuel Newman c928d6b14a Keep the screen awake on the video feed (#9146) 2025-10-10 11:33:09 -05:00
Samuel Newman 0dd71fb087 Add accessibilityRole to single images (#9148) 2025-10-10 11:31:12 -05:00
Samuel Newman 54b8eacba1 Fix chat request buttons not moving with swipe gesture (#9155)
* portal in buttons so they move with swipe

* remove outline style buttons
2025-10-10 11:30:29 -05:00
Samuel Newman b7b47d30bf fix hider alignment in thread (#9168) 2025-10-10 11:26:48 -05:00
Samuel Newman 3561fc8112 move aspect ratio to atom (#9171) 2025-10-10 11:20:41 -05:00
Samuel Newman fe31cf4508 fix background colors (#9174) 2025-10-10 11:17:57 -05:00
Eric Bailey a9efd94983 Placeholder style tweaks (#9107)
* Align colors in loading placeholders

* Same for new skele components

* Increase opacity of disabled replies button slightly
2025-10-10 11:16:40 -05:00
Samuel Newman 6cd6a3447d Tweak greens (#9177)
* tweak greens

* undo test code
2025-10-10 09:15:48 -07:00
Samuel Newman ec8c36e614 add 10% sample rate to sentry (#9182) 2025-10-10 08:31:38 -07:00
Samuel Newman 84cae44cd2 Ship activation experiments (#9170)
* ship onboarding experiments

* delete logged out cta

* delete other loggedoutcta
2025-10-10 08:24:42 -07:00
Eric Bailey 5bf1141b55 Add validation to threadgate records, check for max hidden replies (#9178) 2025-10-10 10:03:47 -05:00
pfrazee e1ee85622d Nightly source-language update 2025-10-10 02:36:26 +00:00
easrng b1dc5179b6 reply button in feeds opens thread (#9143)
* the reply button should open the replies to a post, not present a text input for you to enter your Big Thought into. i think a lot of people don’t even realize that the point has already been written

* Feature gate, fix event

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-10-09 20:29:50 -05:00
Samuel Newman 96d77841e0 Fix language prompt text wrap issue (#9175) 2025-10-09 17:18:24 +03:00
Alex Benzer b38edc52b8 Auto-select search results tab (#9159)
When the user clicks the search button next to "Discover New Feeds" or "Suggested Accounts" on the Explore page, we'll auto-select the respective search results tab (feeds or users).
2025-10-09 05:02:38 -07:00
jim d68fc78e93 Merge pull request #9167 from internet-development/elijaharita/structured-data-name-fallback
fix: show both DisplayName and Handle in google structured data (or only Handle if DisplayName not set)
2025-10-08 14:38:07 -07:00
Elijah Seed-Arita 028ed2f8e2 fix: copy-paste mistake and more idiomatic structured data format 2025-10-08 10:45:30 -07:00
Elijah Seed-Arita 67049b98c9 fix: show both DisplayName and Handle in google structured data (or only Handle if DisplayName not set) 2025-10-08 10:29:44 -07:00
jim 07bcf7460a Merge pull request #9153 from bluesky-social/hailey/self-labels-check-embed
check for self labels when determining if we should hide embeds
2025-10-07 17:14:49 -07:00
Samuel Newman 54f70a576a [16KB] use 16kb-compatible fork of react-native-mmkv (#9150)
* use 16kb-compatible fork of react-native-mmkv

* avoid using package alias

* specify ndk version

* Revert "specify ndk version"

This reverts commit 577393518e.

* add compiler flags to mmkv build (bump version)

* move fork to bsky repo/npm org
2025-10-07 08:06:29 -07:00
Hailey 4a9185b0f5 nit 2025-10-06 20:41:04 -07:00
Hailey 1354bf987d check for self labels when determining if we should hide embeds 2025-10-06 20:39:43 -07:00
Elijah Seed-Arita 7f4e302b85 feat: hide embeds for moderated posts (#9152) 2025-10-06 19:34:26 -07:00
Samuel Newman 5e36992fba patch delete audio compression for 16kb compat (#9149) 2025-10-06 07:42:53 -07:00
Eduardo Rosendo 42a427cfd6 feat(link-meta): Tweaks getLinkMeta to whitelist trusted hostnames (#9139) 2025-10-06 16:36:33 +03:00
pfrazee 0c0c21a0aa Nightly source-language update 2025-10-04 02:30:44 +00:00
Samuel Newman f170313f70 patch sonner-native to remove exit animations (#9092) 2025-10-03 13:08:05 -07:00
Samuel Newman c8d0662690 remove gate (#9130) 2025-10-03 12:44:43 -07:00
Samuel Newman cf4cce2225 Embed testbed with tweaks (#9115)
* Nightly source-language update

* add: test embed page for bskyembeds

* run prettier

* wip

* feat: use local dev for bskyembed test.html

* feat: commit generated files which i'm not sure about

* chore: add basic readme to bskyembed

* Revert "feat: commit generated files which i'm not sure about"

This reverts commit b891efdaa1fd7ddd4417bfd5267e861a25a93b0e.

* chore: revert change to bskyembed/.eslintrc.cjs

* chore: remove generated file from bskyweb/static

* chore: revert messages.po changes

* add dev-snippet command, add dev router

* Update README.md

* Update bskyembed/test.html

* change IS_DEV check to allow localhost

---------

Co-authored-by: APiligrim <28320272+APiligrim@users.noreply.github.com>
Co-authored-by: Anastasiya Uraleva <anastasiya@Anastasiyas-MacBook-Pro.local>
Co-authored-by: Anastasiya Uraleva <anastasiya@Mac.localdomain>
Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
2025-10-03 12:15:26 -07:00
Samuel Newman 0e9e705d99 fix android onboarding dev crash (#9132) 2025-10-03 12:07:21 -07:00
Chenyu 12e09a9bd1 starter pack metrics (#9116)
* starter pack metrics

* emit starterpack:add/remove user event with starterpack uri in starter pack dialog

* rename metadata field
2025-10-03 10:17:59 -07:00
dan 885356256e [Fix Logouts] Persist accounts synchronously (#9109)
* Make persisting synchronous

* Initialize later so persisted is filled
2025-10-03 11:02:52 -05:00
pfrazee b68f80050c Nightly source-language update 2025-10-03 02:34:02 +00:00
dan 1354fd2661 [Fix Logouts] Remove buggy hackfix (#9108)
* Rip out the network hack in favor of bluesky-social/atproto#4238

* Bump api pkg

* Debug code

* Revert "Debug code"

This reverts commit 38445f31f4.

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-10-02 14:01:10 -05:00
Samuel Newman 77bf49f212 Tighten up eslint rule to catch unused const {_} = useLingui() (#9122)
* tighten eslint config to catch unused `useLingui`s

* fix now-invalid uses of _

* remove unused function that produces a ton of eslint warnings

* upgrade react compiler plugin
2025-10-02 09:59:05 -07:00
Eric Bailey 02b189a40e Language selection and suggestion UX improvements (#9067)
* feat: don't retain accepted language suggestion after finishing or exiting post (#8886)

* feat: don't retain accepted language suggestion after finishing or exiting post

* fix: rebase fixes

* fix: rebase fixes

* chore: lint

* Rename onChange for clarity

* Improve logic in composer

* Handle user override more explicitly

* Drill in onSelectLanguage callback into dialog too

* Fix typo

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Make text crystal clear

* Handle multiple languages

---------

Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-10-02 09:18:52 -05:00
Daniel Holmgren 5fd52b3d30 add patent pledge link to readme (#9118) 2025-10-01 11:49:06 -07:00
Samuel Newman 1e6a44f2e8 Fix feedfeedback metrics not distinguishing which feed it's from (#9099)
* fix feedfeedback metrics being sent for all feeds

* remove `discover:` metrics
2025-10-01 06:09:12 -07:00
pfrazee 144d61ef76 Nightly source-language update 2025-10-01 02:40:10 +00:00
Eric Bailey 381feacd26 Add StackedButton component (#9086) 2025-09-30 16:18:36 -05:00
dan 5df6036c2c [Web] Fix thread jumps (#9111)
* [Web] Fix thread jumps

* Comment formatting

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-09-30 10:46:31 -05:00
Eric Bailey 3e55e52858 Button tweaks (#9106)
* Tweak button colors

* Semi bold only for tiny buttons
2025-09-30 08:40:21 -05:00
Chenyu f82a6188e6 Update admonition component (#9068)
* update admonition component

* fix linting, adominition alighment

* design tweak

* edge cases for admonition, update storybook

* Update src/components/Admonition.tsx

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* fix mobile version

* change button style

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-09-30 05:27:19 -07:00
Samuel Newman c7ce827bfe fix gap on profile (#9081) 2025-09-30 07:28:50 +03:00
pfrazee 9e0f192546 Nightly source-language update 2025-09-30 02:34:39 +00:00
Samuel Newman d3dbb94689 Catch errors on geolocation request, reduce Sentry logs (#9098) 2025-09-29 23:12:50 +03:00
Samuel Newman 031fa95715 remove root sibling library (#9097) 2025-09-29 14:31:55 -05:00
Samuel Newman ae2c9a832f don't send some "activity no longer available" errors (#9100) 2025-09-29 14:15:38 -05:00
Samuel Newman 02a25d2aa2 Log OTA errors properly (#9101)
* Log OTA errors properly

* filter out network errors
2025-09-29 14:14:39 -05:00
Samuel Newman 2b32fff1d0 Fix link crash (#9102)
* fix link crash

* fix link crash
2025-09-29 14:14:13 -05:00
dan 22bb9c599f Send inferrable interactions to third-party feeds (#9094) 2025-09-29 14:07:21 -05:00
Samuel Newman 7f4e3091f7 patch react native screens (#9087) 2025-09-26 10:41:17 -07:00
jim 6114b33ce2 Merge pull request #8924 from internet-development/elijaharita/google-structured-data
feat: google structured data for profiles and posts
2025-09-26 09:27:39 -07:00
Elijah Seed-Arita 305ea8bdfb fix: remove escapejs and fix profile issues 2025-09-25 20:14:46 -07:00
Elijah Seed-Arita a322ae412a feat: profile.html escapejs 2025-09-25 20:14:46 -07:00
Elijah Seed-Arita caa7736035 feat: post.html structured content, wip 2025-09-25 20:14:46 -07:00
Elijah Seed-Arita 655964ec0b feat: profile.html structured content 2025-09-25 20:14:46 -07:00
Samuel Newman 66526a8e10 Fix extToMime function (#9084) 2025-09-25 10:26:25 -05:00
pfrazee 8cded435d1 Nightly source-language update 2025-09-25 02:36:36 +00:00
Eric Bailey bd17f04810 Migrate to @bsky.app/alf package (#9030)
* Add storybook shortcut in dev

* Migrate to alg pkg

* Migrate font_bold to new font_semi_bold

* Migrate font_heavy to font_bold

* Fix old theme refs

* Remove leading util

* Bump

* Revert "Add storybook shortcut in dev"

This reverts commit 7a86195c77fb5d449c7782e64ebabb6addfab919.

* Remove alf script

* Adjust font scale

* Bump

* Bump pkg

* Migrate values from conflicts

* Create default themes outside react

* Use built-in alf utils

* Migrate old font styles

* Remove unused tokens

* Move theme creation to more appropriate file

* Update button colors

* Adjust TextField colors, line heights
2025-09-24 11:47:08 -05:00
pfrazee bdc58045cf Nightly source-language update 2025-09-24 02:35:40 +00:00
Austin McKinley 0482e917b6 Merge pull request #9069 from bluesky-social/migrate-blink
Start migrating blink. Also add better shutdown handling for ogcard
2025-09-23 16:36:22 -07:00
Austin McKinley 0bc2355226 Start migrating blink. Also add better shutdown handling for ogcard 2025-09-23 15:17:49 -07:00
Samuel Newman 46a97fadcb Delete unused modals and invite code stuff (#8244)
* delete waitlist modal, which doesn't exist

* delete invite code modal

* rip out copied invites persisted state

* delete invite query

* delete unused modal implementations
2025-09-23 11:45:51 -07:00
Samuel Newman e90cfdc849 Modernise list create/edit dialog (#8223) 2025-09-23 20:11:21 +03:00
Samuel Newman 3bc906b911 fix profile feed liked by tablet offset (#9066) 2025-09-23 20:06:11 +03:00
Samuel Newman 7916c73b09 Better screen transitions for auth flow (#7803) 2025-09-23 20:04:22 +03:00
Samuel Newman 6d85fe05d1 Constraint video max height to 14/9 (#8611)
* constraint video max height to 14/9

* Apply new default to web video embed too

* Retain web handling

* Rename prop for clarity

* Align no-crop handling on native/web

* make it always constrained

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-09-23 07:24:31 -07:00
Samuel Newman be324432bd add sentry patch for vendoring metro import (#9065) 2025-09-23 07:16:19 -07:00
Eric Bailey 133bc2921e Fix incorrect usage of useAnimatedScrollHandler (#9063)
* Explicitly declare worklets for useAnimatedScrollHandler_FIXED.web.ts

* Delete unused web hook

* delete other platform split file, import directly

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-09-23 02:12:53 -07:00
pfrazee b90f807416 Nightly source-language update 2025-09-23 02:34:57 +00:00
Austin McKinley fbb85e109c Merge pull request #9064 from bluesky-social/migrate-ogcard
Normalize ogcard path metrics
2025-09-22 16:57:38 -07:00
Austin McKinley 9d6f51ff88 normalize ogcard metrics 2025-09-22 16:42:40 -07:00
Austin McKinley 7b10dcf249 Merge pull request #9061 from bluesky-social/migrate-ogcard
add metrics middleware to ogcard service
2025-09-22 15:12:36 -07:00
Austin McKinley 93f90bec97 fix metrics types 2025-09-22 11:56:57 -07:00
Austin McKinley 31eb41d21b remove bogus timeout 2025-09-22 11:45:02 -07:00
Austin McKinley 336e7b5372 update yarn.lock 2025-09-22 11:42:27 -07:00
Austin McKinley 9dcd8f81db update ogcard workflow to build and push new ECS images on PR creation 2025-09-22 11:38:10 -07:00
hailey cbcce8c960 improve og profile card (#9051) 2025-09-22 11:05:49 -07:00
Barry McGee 2c6752f24a Fix notification indicator appearing behind navigation text (#9035)
* Fix peeking notification indicator on web

* Remove relative positioning from LeftNav component
2025-09-22 10:49:16 -07:00
Austin McKinley 14ee7920f4 edit dockerfile to match 2025-09-22 10:28:17 -07:00
Austin McKinley 0ddd09eb9b add metrics middleware to ogcard service 2025-09-22 10:20:05 -07:00
Samuel Newman 5211b26903 Expo 54 (#8931)
* update deps

* update patches

* fix new arch optout

* build from source, disable new arch

* update to preview.14

* upgrade off of preview to release

* fix lockfile lint

* update patches

* add back expo-location

* downgrade reanimated

* downgrade pagerview

* use expo-file-system/legacy

* try and upgrade types/react-dom

* fix type of uint8array

* rm @types/react resolution from bad rebase

* more type errors

* fix mock

* bump rn-compressor

* add patch of https://github.com/bluesky-social/react-native-paste-input/pull/5

* delete NativeDropdown & remove Zeego

* `import React` in expo modules

* bump cocoapods

* rm unused picker lib

* add speculative react-native-mmkv patch

* revert patch, add temp debug info to error

* bring back speculative patch, patch built JS code instead of source

* revert patch, just do debugging part

* dep update

* update resolutions, dynamic-app-icon

* bump node version in eas.json

* update build instructions

* rm atob from docs

* Delete react-native-mmkv+2.12.2.patch

* bump expo which might include fix

* update expo patch version

* bump expo patch version

* wrong version oops

* update expo to latest

* update react-native-compressor, rm patch
2025-09-22 08:52:07 -07:00
Samuel Newman 6983efee7f iOS 26 with design compatibility mode (#9059)
* enable design compat mode

* patch compressor lib

https://github.com/numandev1/react-native-compressor/issues/367
2025-09-22 08:21:20 -07:00
Caidan ac71ea235f improve: enhance post OpenGraph metadata with engagement data and auth handling (#9046) 2025-09-17 14:30:10 -07:00
Samuel Newman 5e78c947a0 Add missing passive feed interactions (#9043) 2025-09-15 03:02:37 -07:00
pfrazee 952abc82f4 Nightly source-language update 2025-09-12 02:33:47 +00:00
surfdude29 b9a41f30a5 Generate separate strings for join messages in Newskie dialog (#8007)
* try again

* prettier

* prettier round 2

* Update src/components/NewskieDialog.tsx

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-09-11 12:08:30 -07:00
Samuel Newman 6a4c56dfa9 Log cleanup (#9029)
* change warn to log

* networkerror check on failed to check unread notifications

* rm both logs

* tweak imports
2025-09-11 11:23:16 -07:00
hailey 836d16fec9 ensure mod service header present for appeals (#9025) 2025-09-11 00:31:17 -07:00
pfrazee 58ffe365ae Nightly source-language update 2025-09-11 02:36:03 +00:00
jim 426f025940 Merge pull request #9023 from internet-development/caidanw/app-1040-feed-open-graph-tags
feat: add feed open graph tags
2025-09-10 14:19:15 -07:00
Samuel Newman 20ff3e3ba0 Ensure there is a thumbnail for videos on web (#9019) 2025-09-10 18:49:44 +03:00
Samuel Newman 5b8631d188 Fix profile lists/feeds/starterpacks tabs position issue (#8935) 2025-09-10 18:49:04 +03:00
Samuel Newman 5be753ecdf add prevent default to thread anchor checkmark (#9020) 2025-09-10 17:44:19 +03:00
Caidan Williams d7c180db0e style: remove trailing spaces 2025-09-09 20:35:14 -07:00
Caidan Williams f5079b8158 feat: add OpenGraph metadata for feed URLs in bskyweb
Enable rich link previews when feed URLs are shared in iMessage, Slack, and other social platforms. Adds feed title, description, creator info, and avatar images to improve sharing experience.
2025-09-09 20:03:50 -07:00
pfrazee c7591ef058 Nightly source-language update 2025-09-10 02:33:45 +00:00
Samuel Newman 372e20efa3 ALF saved feeds screen (#8844) 2025-09-09 22:40:25 +03:00
Samuel Newman 9e8bceec60 reduce checkmark size in thread anchor (#8942) 2025-09-09 10:27:16 -07:00
Samuel Newman 6432667f60 ALF lists screen (#8941)
* alf list screens

* relocate to `#/screens`, balkanize

* use useBreakpoints

* showCancel on subscribe menu

* fix typo
2025-09-09 10:20:33 -07:00
Samuel Newman 4a1b1f17f4 Clean up dialogs (#8934) 2025-09-09 18:45:36 +03:00
Samuel Newman 7574a745d1 Fix focus ring shapes (#9005)
* fix user avis being the wrong shape

* fix the fab being the wrong shape
2025-09-09 08:40:19 -07:00
Samuel Newman 53e43a957c run yarn lint --fix (#9013) 2025-09-09 08:38:21 -07:00
Samuel Newman bb30b592d7 Remove atob polyfill (#9000)
* remove atob polyfill

* remove base64-js as a dependency
2025-09-09 08:33:41 -07:00
Samuel Newman bbc55eb0d7 clean up language before suggesting (#9006) 2025-09-09 08:33:23 -07:00
Samuel Newman 3e2c181c40 Upgrade @types/react to 19 and run codemod (attempt 2) (#8918)
* update dependencies

* rm `import type React from 'react'`

* run codemods

* patch discord types

* update types/react-dom

* Update yarn.lock
2025-09-09 08:09:10 -07:00
pfrazee d496a22352 Nightly source-language update 2025-09-09 02:37:07 +00:00
Samuel Newman d8413b09f8 remove link from saved count (#9010) 2025-09-08 23:14:19 +03:00
Samuel Newman 5ec6db5297 bump version (#9008) 2025-09-08 11:31:14 -07:00
kindgracekind 2b4da7f536 Pass feed context to video feed post controls (#9004) 2025-09-08 02:24:07 -07:00
Eric Bailey 5cd4a3362d 1.108.0 Release Prep (#8993)
* Pull and extract

* Pull and extract part II
2025-09-05 13:14:20 -05:00
estrattonbailey 834486c97d Nightly source-language update 2025-09-05 16:28:09 +00:00
Eric Bailey e073bdac6e Remove region for AA call, actually not helpful (#8992) 2025-09-05 11:07:37 -05:00
Samuel Newman 73d72814c5 patch in unreleased upstream fix for jitter (#8952) 2025-09-05 08:39:55 -07:00
Samuel Newman daed047bb4 [Perf] Drawer gesture perf fix + related cleanup (#8953)
* split drawer layout into own component

* don't put props in dep array

* memoize pager view
2025-09-05 08:39:28 -07:00
Samuel Newman ee3e083938 Restore quick language select (#8981)
* restore quick language select

* rm showCancel

* rm margin from thread button

* alf composer icons

* stop hiding keyboard

* use trans
2025-09-05 08:34:00 -07:00
Eric Bailey 0f089060d2 Make logs more clear (#8991) 2025-09-05 10:25:42 -05:00
Samuel Newman 01ba0d0ed6 Revert "use comment instead of context (#8987)" (#8990)
This reverts commit c7f8da8f97.
2025-09-05 08:11:56 -07:00
Samuel Newman c7f8da8f97 use comment instead of context (#8987) 2025-09-05 18:03:29 +03:00
Eric Bailey 76cd645a40 Provide more precise data for age assurance (#8989) 2025-09-05 10:02:24 -05:00
Samuel Newman 124cfb57c7 only show bookmarks nux to existing users (#8988) 2025-09-05 09:49:34 -05:00
Samuel Newman ac0c4ef2d9 ensure headers are set when chat reporting (#8985) 2025-09-05 09:33:27 -05:00
Samuel Newman 917256713f require auth for bookmarks (#8983) 2025-09-05 09:31:25 -05:00
Samuel Newman c26906e15c add translation context for "saved" (#8982) 2025-09-05 07:29:57 -07:00
Samuel Newman 0c4b908020 Simplify post number formatting (#8978)
* revert number formatting change

* use formatPostStatCount in repost web
2025-09-05 09:29:10 -05:00
Samuel Newman 457cd3d0fb E2E fixes (#8980)
* update dev-env

* hide nux after onboarding

* use getter/setter for proxy header
2025-09-05 09:27:18 -05:00
estrattonbailey bc827dc97f Nightly source-language update 2025-09-05 00:40:16 +00:00
Eric Bailey c129108b78 108 fixes (#8977)
* Translation comment

* Fix error handling in starter pack generation

* Allow access to DM settings for age restricted users

* Leave post stat unit formatting up to translators
2025-09-04 19:36:23 -05:00
estrattonbailey 0b480bdaf8 Nightly source-language update 2025-09-04 22:33:00 +00:00
Eric Bailey 535d4d6cf7 📓 Bookmarks (#8976)
* Add button to controls, respace

* Hook up shadow and mutation

* Add Bookmarks screen

* Build out Bookmarks screen

* Handle removals via shadow

* Use truncateAndInvalidate strategy

* Add empty state

* Add toasts

* Add undo buttons to toasts

* Stage NUX, needs image

* Finesse post controls

* New reply icon

* Use curvier variant of repost icon

* Prevent layout shift with align_start

* Update api pkg

* Swap in new image

* Limit spacing on desktop

* Rm decimals over 10k

* Better optimistic adding/removing

* Add metrics

* Comment

* Remove unused code block

* Remove debug limit

* Fork shadow for web/native

* Tweak alt

* add preventExpansion: true

* Refine hitslop

* Add count to anchor

* Reduce space in compact mode

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-09-04 17:30:15 -05:00
estrattonbailey 04b869714e Nightly source-language update 2025-09-04 20:11:21 +00:00
surfdude29 9738f4858d Tweak location-related strings and labels (#8975)
* tweak string in BlockedGeoOverlay.tsx

* tweak string in AgeAssuranceAccountCard.tsx

* tweak string and labels in DeviceLocationRequestDialog.tsx

* prettier

* add missing `.` in DeviceLocationRequestDialog.tsx
2025-09-04 15:08:23 -05:00
estrattonbailey 0dafc2ccd6 Nightly source-language update 2025-09-04 16:11:27 +00:00
Eric Bailey f8ae0540a0 Provide geo-gated users optional GPS fallback for precise location data (#8973) 2025-09-04 11:07:12 -05:00
Alex Benzer 625b4e61db Welcome modal on logged-out homepage (#8944)
* Adds welcome modal to logged-out homepage

* Adds metrics and feature gate for welcome modal

* Slightly smaller text for mobile screens to avoid wrapping

* Remove unused SVG

* Adds text gradient and "X" close button

* Fix color on "Already have an account?" text

* tweak hooks, react import

* rm stylesheet

* use hardcoded colors

* add focus guards and scope

* no such thing as /home

* reduce spacign

* use css animations

* use session storage

* fix animation fill mode

* add a11y props

* Fix link/button color mismatch, reduce gap between buttons, show modal until user dismisses it

* Fix "Already have an account?" line left-aligning in small window sizes

* Adds "dismissed" and "presented" metric events

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-09-04 07:20:46 -07:00
Samuel Newman 0b02d9d9a7 bump version (#8970) 2025-09-04 07:16:52 -07:00
pfrazee 07d4ff4e8c Nightly source-language update 2025-09-04 02:34:11 +00:00
hailey 6c8e9fd8c9 add cursor constraint to safelink (#8966) 2025-09-03 08:55:09 -07:00
jim fd7b1292b8 Merge pull request #8923 from internet-development/@APiligrim/update-gif-select
Update: search on Gif select component to add small padding to match other search experiences
2025-09-02 22:21:16 -07:00
jim 135f37eae6 Merge pull request #8962 from internet-development/caidanw/app-1327-remove-pinned-post-from-replies-tab-on-profile
[APP-1327] Remove pinned post from replies tab on profiles
2025-09-02 22:19:15 -07:00
Eric Bailey 125191fc20 1.107.0 Prep Take 2 (#8964)
* Pull down latest translations

* Extract
2025-09-02 22:02:12 -05:00
Eric Bailey 566e869802 Use Automatic representation for all image pickers (#8963) 2025-09-02 21:43:33 -05:00
pfrazee c99500f5d3 Nightly source-language update 2025-09-03 02:33:35 +00:00
hailey bec0329774 enable link redirection in message (#8961) 2025-09-02 16:31:37 -07:00
Samuel Newman 670995a649 update bad token error message (#8954) 2025-09-02 18:27:52 -05:00
Caidan Williams b2ecaf9aa7 fix(feed): only include pins for author threads filter
Previously, pins were included for both 'posts_with_replies' and
'posts_and_author_threads' filters. This change restricts pin inclusion
to only the 'posts_and_author_threads' filter, ensuring correct feed
behavior and reducing unnecessary data in other filter modes.
2025-09-02 15:48:28 -07:00
hailey 01c466a213 fix safelink package.json (#8959) 2025-09-02 14:07:22 -07:00
Samuel Newman 75f0ee8a1e Tweaks to add to starter pack dialog (#8957) 2025-09-03 00:01:36 +03:00
hailey 5ce4aa5139 rm unknown fields (#8958) 2025-09-02 13:43:44 -07:00
hailey acdc509630 safelink (#8917)
Co-authored-by: hailey <me@haileyok.com>
Co-authored-by: Stanislas Signoud <signez@stanisoft.net>
Co-authored-by: will berry <wsb@wills-MBP.attlocal.net>
Co-authored-by: BlueSkiesAndGreenPastures <will@blueskyweb.xyz>
Co-authored-by: Chenyu Huang <itschenyu@gmail.com>
2025-09-02 13:36:20 -07:00
Samuel Newman b2258fb6cb Add QR code to github action (#8948) 2025-09-01 17:56:21 -07:00
Bartosz Kaszubowski 0bda727e8b Web: fix Suggested Accounts tabs end of scroll detection (#8939) 2025-09-01 03:23:41 -07:00
Anastasiya Uraleva 3601933ff6 move background to the parent and remove unused view 2025-08-29 17:40:41 -07:00
Samuel Newman 1c78f36a51 v1.107.0 release prep (#8938)
* yarn intl:pull

* yarn intl:extract:all
2025-08-29 08:24:43 -07:00
Samuel Newman d6dc52b6ea Improve e2e tests (#8927)
* get e2e image picker working

* verify create account actually reaches onboarding

* wait for image to actually be attached before posting

* wait until login finishes before moving on

* sign out before switch accounts then wait until logged in

* disable onboarding experiments in e2e

* add testId to handle availability checkmark

* fix too long username

* update thread muting test to reflect current behaviour

* hackfix for the british english translation

* unflake the onboarding tests

* fix curate list flow

* admit defeat on the most list one
2025-08-29 08:15:05 -07:00
Samuel Newman 541502c7ee prevent double border (#8937) 2025-08-29 07:02:28 -07:00
Samuel Newman 0114cfcfe1 fix hook being marked as async for no reason (#8932) 2025-08-29 10:36:20 +03:00
pfrazee 6172423714 Nightly source-language update 2025-08-29 02:36:45 +00:00
Samuel Newman 8a4398608a Close web mention suggestions popup on Escape (#8605)
* alf web typeahead

* fix type error

* fix escape behaviour

* change selection on hover

* rm React.

* undo random change
2025-08-28 17:03:12 -07:00
Samuel Newman 27c1058568 use Link instead of manual navigation (#8930) 2025-08-28 15:18:56 -07:00
Eric Bailey 2f2b542e5c Bump expo-image-picker to 17.0.5 (#8929)
* Bump picker, add patch for next version

* Revert "Bump picker, add patch for next version"

This reverts commit a4aab0bdcd.

* Update to latest picker@next
2025-08-28 15:14:28 -07:00
Eric Bailey 2a54781ce0 Update dev env (#8921)
* Update dev-env

* Integrate appviewDid value from dev-env

* Use correct env value to disable policy update overlay

* Remove log
2025-08-28 04:20:06 -07:00
Anastasiya Uraleva cc4acae758 Update search on Gif select component to add small padding to match other search experiences 2025-08-27 21:31:29 -07:00
APiligrim eeeeda3495 Nightly source-language update 2025-08-27 21:23:05 -07:00
pfrazee dcba5c4668 Nightly source-language update 2025-08-28 02:37:01 +00:00
Chenyu 7469e7306c Update birthday setting dialog (#8910)
* update birthday setting dialog

* Update src/components/dialogs/BirthDateSettings.tsx

Co-authored-by: Eric Bailey <git@esb.lol>

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-08-27 19:55:18 -05:00
surfdude29 58c2e68a24 Update FollowDialog.tsx (#8919) 2025-08-28 02:43:33 +03:00
surfdude29 01c20958c1 Add english-only-resource context and tweak labels (#8805)
* add context in VerificationsDialog.tsx

* add context in VerifierDialog.tsx

* add context in VerificationSettings.tsx

* add context in EditProfileDialog.tsx

* add context and tweak label in ChangeHandleDialog.tsx

* tweak label in ContentHider.tsx
2025-08-27 18:12:01 -05:00
jim 99722436b1 Merge pull request #8885 from internet-development/caidanw/app-1409-add-data-nosnippet-to-discover-feed
feat: prevent search engines from using Discover feed content as page descriptions
2025-08-27 14:56:40 -07:00
Caidan Williams 4a1f1efd76 refactor(feed): simplify isDiscoverFeed logic in FeedPage 2025-08-27 11:58:58 -07:00
Caidan Williams bd730db03e refactor(feed): remove NoSnippetWrapper from FeedPage in favor of dataSet attribute
Replaces NoSnippetWrapper with a dataSet prop on the root View to
control the nosnippet attribute for discover feeds. This simplifies the
component structure and improves maintainability by reducing unnecessary
wrappers.
2025-08-27 11:58:58 -07:00
Samuel Newman 8a22584a87 prevent android exposures to gate (#8916) 2025-08-27 10:12:09 -07:00
mozzius 17cbf75747 Nightly source-language update 2025-08-27 16:08:25 +00:00
Samuel Newman 8adebe6702 starter pack dialog tweaks (#8913) 2025-08-27 09:01:10 -07:00
Samuel Newman 39d460db51 Language select final tweaks (#8914)
* [APP-1303] Redesign/refactor post language select (#8884)

* Nightly source-language update

* Nightly source-language update

* [APP-1303] Redesign/refactor post language select

* update: stylesheets.create to use the latest structure

* update styles to modern structure

* update: dialog breakpoints on web and delete depricated language modals

* remove unused post languages settings dialog

* restructure Post languages dialog

* place the Dialog.Close inside the Dialog.ScrollableInner

* add: language search

* update search and language variables for clarity

* fix: memoize language state lists

* chore: add comments

* update proper colors to the background

* add back older error boundary

* add: tweaks to the mobile and web responsiveness

* add tweaks to center the container

* update labels

* update button and border

* added translation updates

* Update: text input to reuse search input

* remove unused file

* update: web breakpoints

* run eslint and prettier

---------

Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
Co-authored-by: Anastasiya Uraleva <anastasiya@Anastasiyas-MacBook-Pro.local>
Co-authored-by: Anastasiya Uraleva <anastasiya@Mac.localdomain>

* rm old file

* sort out styles, add FlatListFooter component

* rm cancel button in favor of search input X

* get dialog height working on iOS

* delete `DropdownButton`

* hide scroll indicators on android

* ios scroll indicator insets

* get footer sorta working on android

* change button color on press

* rm empty file

---------

Co-authored-by: Anastasiya Uraleva <anastasiyauraleva@gmail.com>
Co-authored-by: Elijah Seed-Arita <elijaharita@gmail.com>
Co-authored-by: Anastasiya Uraleva <anastasiya@Anastasiyas-MacBook-Pro.local>
Co-authored-by: Anastasiya Uraleva <anastasiya@Mac.localdomain>
2025-08-27 09:00:36 -07:00
Samuel Newman eac0290143 Add suggested follows experiment to onboarding (#8847)
* add new gated screen to onboarding

* add tab bar, adjust layout

* replace chevron with arrow

* get suggested accounts working on native

* tweaks for web

* add metrics to follow all

* rm non-functional link from card

* ensure selected interests are passed through to interests query

* fix logcontext

* followed all accounts! toast

* rm save interests function

* Update src/screens/Onboarding/StepSuggestedAccounts/index.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* use admonition

* rm comment

* Better interest tabs (#8879)

* make tabs draggable

* move tab component to own file

* rm focused state from tab, improve label

* add focus styles, remove focus when dragging

* rm log

* add arrows to tabs

* rename Tabs -> InterestTabs

* try and simplify approach

* rename ref

* Update InterestTabs.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/InterestTabs.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/ProgressGuide/FollowDialog.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/components/ProgressGuide/FollowDialog.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* add newline

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* fix flex problem

* Add value proposition screen experiment (#8898)

* add assets

* add value prop experiment

* add alt text

* add metrics

* add transitions

* add skip button

* tweak copy

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* add borderless variant for web

* rm pointer events

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Add slight delay, prevent layout shift

* Handle layout shift, add Let's Go! text

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2025-08-27 04:17:45 -07:00
APiligrim 349c70e413 Nightly source-language update 2025-08-26 20:21:22 -07:00
APiligrim 203ccbb1fb Nightly source-language update 2025-08-26 20:21:22 -07:00
pfrazee 0617fca5ef Nightly source-language update 2025-08-27 02:36:23 +00:00
hailey a1ed59e0ee use an env var for configurable proxy header (#8863) 2025-08-26 17:13:11 -07:00
surfdude29 39c6984c6e Mark label for translation in LoggedOutCTA.tsx (#8908)
* Mark label for translation in `LoggedOutCTA.tsx`

* Update LoggedOutCTA.tsx
2025-08-26 15:09:47 -07:00
Eric Bailey 9f7c920346 Fix toast type (#8909)
* Fix confusing toast API

* Provide all exports to e2e file

* Fix first usage in Composer

* Loosen type, add Trans tag
2025-08-26 16:54:43 -05:00
Caidan Williams 6ddc268b91 feat: prevent search engines from indexing Discover feed content as page descriptions 2025-08-26 13:01:36 -07:00
Caidan Williams 0517768cd3 feat: add data-nosnippet attribute to Discover feed for SEO control 2025-08-26 13:01:36 -07:00
Bartosz Kaszubowski 0555d3623c Fix RightNav elements focus outline on web (#8788) 2025-08-26 14:43:25 -05:00
Bartosz Kaszubowski 8dcf1825ec Web: fix Edit Profile discard warning when pressing backdrop (#8824)
* Web: fix Edit Profile discard warning

* cleanup imports
2025-08-26 14:38:59 -05:00
surfdude29 c12fd4482e Discover FeedsDiscover New Feeds (#8860) 2025-08-26 14:34:34 -05:00
kindgracekind 88e6dff484 Enable show less / more buttons for third party feeds (#8672)
Co-authored-by: hailey <hailey@blueskyweb.xyz>
Co-authored-by: Hailey <me@haileyok.com>
2025-08-26 12:16:50 -07:00
Samuel Newman 98d96bd28b Modernise change password dialog (#8269)
* alf change password dialog

* rm old modal

* move dialog

* fix buttons on native

* lowercase

* fix dupe import

* Apply suggestions from code review

Thanks @surfdude29 :)

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* use primary_subtle, change web layout

* move to into non-network err, warn -> error

* error -> safeMessage

* better message than token is invalid

* cancel button native only

* move close to end of focus priority

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-08-26 10:50:39 -07:00
Eric Bailey dd2830ba6c Fix bad copy pasta (#8907) 2025-08-26 12:33:43 -05:00
Eric Bailey 6a16ef83f6 Fix default opengraph (#8872)
* Fix default opengraph

* Add avatar back

* Remove default og images
2025-08-26 11:32:08 -05:00
Eric Bailey 8ec20026c0 Yeah toast (#8878)
* Split out into macro component

* Add Action component

* Add fallback

* add button to view post after sending

* Dismiss toast when clicking action button

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-08-26 11:20:04 -05:00
Alex Benzer acd7211b35 Adds signup CTA tests for logged-out visitors (#8906) 2025-08-26 08:52:38 -07:00
Samuel Newman b70e5b2f38 Add verification checkmarks to embed.bsky.app (#8644)
* update vite+typescript

* update atproto api to latest, split out utils

* add checkmark to post

* add checkie to embed

* revert change to example post

* fix ext link color
2025-08-26 08:24:46 -07:00
Inbestigator 5a074fa37a Add profile link to switcher menu (#8867)
* feat(leftnav): add profile link to switcher menu

* fix: close menu on navigate
2025-08-26 08:18:40 -07:00
Eric Bailey df20ae237e Threads v2 cleanup (#8902)
* Delete root PostThread component

* Remove PostThreadItem, migrate DebugMod to use new components

* Remove other unused components

* Move PostThreadFollowBtn to new home

* Move PostThreadComposePrompt to new home

* Remove gate

* Keep naming in DebugMod

* rm v1 prefs

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-08-26 09:54:19 -05:00
surfdude29 e91a683810 Tweak SelectMediaButton error string, accessibilityHint, and comments (#8870)
* remove isNative check from accessibilityHint

* tweak grammar in error string

* prettier

* tweak comment
2025-08-26 05:58:04 -07:00
jim bc8e3ba30b Merge pull request #8806 from internet-development/binaryfiddler/starter-pack-part2
Starter pack dialog implementations
2025-08-25 23:23:20 -07:00
jim e4c5fb7de5 Merge pull request #8901 from internet-development/caidanw/app-1358-final-card-refresh
feat(ui): redesign suggested profiles 'See more' card
2025-08-25 23:19:11 -07:00
jim d1aab56982 Merge pull request #8900 from internet-development/caidanw/app-1413-clean-up-canonical-urls
feat: implement canonical URL filter to clean parameters for SEO
2025-08-25 23:07:00 -07:00
pfrazee bb1eab41c6 Nightly source-language update 2025-08-26 02:38:40 +00:00
Caidan Williams eb45154823 refactor: rename canonical filter to canonicalize_url for better clarity
- Rename filter from 'canonical' to 'canonicalize_url' to follow Pongo2
naming conventions
- Update function name from filterCanonical to filterCanonicalizeURL
- Update template usage in post.html and profile.html
- Update test function name and all references
2025-08-25 17:18:15 -07:00
Caidan Williams 2b4d32bb09 feat(ui): redesign "See more" suggested profiles card
Refactored the "See more accounts you might like" card to use ButtonIcon
and ButtonText for improved consistency and accessibility. Updated
styles for better alignment, spacing, and visual hierarchy. Navigates to
the Explore page when pressed.
2025-08-25 16:57:33 -07:00
Caidan Williams b667e8b985 refactor(feed): rename Arrow to ArrowRight for clarity 2025-08-25 16:16:55 -07:00
Samuel Newman e8cd7ab131 Remove handle suggestion gate (#8899)
* remove handle suggestion gate

* rm from list of gates
2025-08-25 16:13:54 -07:00
Caidan Williams 685650b296 test: add comprehensive coverage for canonical URL filter
- Verify clean URL passthrough behavior
- Test query parameter removal functionality
- Test fragment removal functionality
- Test combined query params and fragments handling
- Ensure graceful degradation for malformed URLs
2025-08-25 16:04:45 -07:00
Caidan Williams f9118b2729 feat: apply canonical filter to profile template URLs for SEO
Use canonical filter on requestURI in canonical link tag while preserving
original URL with parameters for og:url metadata. This provides clean
canonical URLs for search engines while maintaining full Open Graph URLs.
2025-08-25 16:04:45 -07:00
Caidan Williams 5c04c9e3e3 feat: apply canonical filter to clean URLs in post template
Uses canonical filter for canonical link tags while preserving original URLs with parameters for og:url metadata, improving SEO through proper URL canonicalization
2025-08-25 16:04:45 -07:00
Caidan Williams 60a1be6de0 feat(seo): add canonical URL filter to remove query parameters
Addresses community feedback about canonical URLs being misleading
when they include UTM parameters. The new Pongo2 filter creates
clean canonical URLs while preserving tracking parameters for
social sharing.
2025-08-25 16:04:45 -07:00
Samuel Newman f3905c574b remove root sibling parent(s??) from composer (#8897) 2025-08-25 15:30:13 -07:00
Samuel Newman 27c591f031 Fix Gif Select dialog search bar scrolling away (#8874)
* fix flatlist dialogs on web

* tweak gif select dialog, add style prop to textfield
2025-08-25 09:37:12 -07:00
Samuel Newman 7771b56a43 fix searching for phrases by replacing smart quotes (#8865) 2025-08-25 19:25:28 +03:00
Samuel Newman 3810b29fb6 ALF log screen (#8845) 2025-08-25 19:25:02 +03:00
Samuel Newman 9d77b361fe add content hider padding (#8843) 2025-08-25 19:24:48 +03:00
Samuel Newman 54f7af12ca Update DM header to match new Layout style (#8846) 2025-08-25 19:23:08 +03:00
pfrazee ecb77a9b96 Nightly source-language update 2025-08-25 02:40:42 +00:00
Samuel Newman 45825dd005 Fix alt text in media preview (#8854) 2025-08-24 14:31:42 +03:00
Samuel Newman 5e07b0c77d Skip dirty git tree check in prebuild (#8853) 2025-08-24 14:31:25 +03:00
pfrazee dddea126f4 Nightly source-language update 2025-08-24 02:42:01 +00:00
Samuel Newman ce2604d0e9 Update @mozzius/expo-dynamic-app-icon (#8834) 2025-08-24 01:18:02 +03:00
Eric Bailey c28195067f Update origin (#8889) 2025-08-23 15:33:31 -05:00
Eric Bailey 3b7b93a411 Debug (#8888)
* Swap URL

* Add debug
2025-08-23 14:45:57 -05:00
jim 99d7570818 Merge pull request #8883 from internet-development/caidanw/app-1408-add-canonical-url
feat: add canonical URLs to improve SEO
2025-08-22 19:40:11 -07:00
pfrazee 7b9bc52720 Nightly source-language update 2025-08-23 02:36:29 +00:00
Chenyu Huang f84a756691 optimize for the web 2025-08-22 17:59:54 -07:00
jim 78e1e26a2c Merge pull request #8882 from internet-development/binaryfiddler/isnetwork
wrapp failed to send feed interactions inside isNetworkError
2025-08-22 16:10:53 -07:00
Caidan Williams d8c904d1d9 feat: add canonical URL to profile template for better SEO 2025-08-22 14:42:05 -07:00
Caidan Williams 560c503aa6 feat: add canonical URL to post template for better SEO 2025-08-22 14:40:57 -07:00
Caidan Williams 5120c037d1 feat: add canonical URL to home page for SEO optimization 2025-08-22 14:39:56 -07:00
Chenyu Huang 184df9cbfe wrapp failed to send feed interactions inside isNetworkError 2025-08-22 13:28:32 -07:00
Eric Bailey 912ab1bd9b [LEG-246] Geo overlay (#8881)
* Add AgeBlockedGeo

* Add MaxMind usage text

* Add geo overlay

---------

Co-authored-by: rafael <rafael@blueskyweb.xyz>
2025-08-22 14:55:16 -05:00
surfdude29 f038ac70da rearrange translation logic (#8880) 2025-08-22 12:00:00 -07:00
jim e404ddfbcd Merge pull request #8875 from internet-development/caidan/app-1406-follow-suggestions-card-to-show-follow-back
[APP-1406] follow suggestions card to show follow back
2025-08-21 22:15:07 -07:00
pfrazee 0baa5198e0 Nightly source-language update 2025-08-22 02:38:34 +00:00
Caidan Williams 7a1adfe67c refactor: all uses of "Follow Back" to "Follow back" 2025-08-21 15:55:01 -07:00
jim af55e578b2 Merge pull request #8876 from internet-development/caidanw/app-1399-trending-videos-icon-missing
[APP-1399] trending videos icon missing
2025-08-21 15:44:14 -07:00
Caidan Williams 994003e603 fix: capitalization of "Follow back" to "Follow Back" 2025-08-21 13:53:44 -07:00
Caidan Williams 8ab49da6da refactor: replace View with Button in ViewMoreCard for consistent colors across themes
Updated ViewMoreCard to use a Button component instead of a styled View
for the 'View more' action. This improves accessibility and consistency
with other interactive elements in TrendingVideos.
2025-08-21 13:23:53 -07:00
Caidan Williams c097f68a7d refactor: extract ViewMoreCard from VideoCards component
Moved the 'View more' card logic into a separate ViewMoreCard component
for better separation of concerns and readability.

Updated imports to use named React hooks instead of React namespace. To
modernise this old component per the new guidelines.
2025-08-21 12:53:35 -07:00
Caidan Williams b1ad229771 fix: show 'Follow back' label if user is followed by profile
Updated ProfileCard.FollowButton label to display 'Follow back' when the
current user is followed by the profile being viewed.
2025-08-21 12:29:08 -07:00
Caidan eabcd9150d [APP-1357] profile header follow recommendations (#8784) 2025-08-21 21:56:17 +03:00
Chenyu Huang 962654041c fix linting, minor ui tweaks 2025-08-21 11:49:08 -07:00
pfrazee d900d0b7a7 Nightly source-language update 2025-08-21 02:38:38 +00:00
Chenyu Huang 0474a3b6f7 address feedback 2025-08-20 15:00:06 -07:00
Eric Bailey 16701392b9 [APP-1398] Fix post shadow/like shadow state when replying (#8866)
* Add optimisticReplyCount to post shadow

* Add special util

* Fix subtle bug in query cache
2025-08-20 15:21:52 -05:00
Chenyu Huang f7c05c2df4 use Dialog.InnerFlatlist 2025-08-20 12:31:12 -07:00
cirx ef7c222e1b fix typo (#8869) 2025-08-20 11:11:02 -07:00
surfdude29 9835d0fb7b tweak plural formatting (#8871) 2025-08-20 11:10:34 -07:00
pfrazee bf6e01551e Nightly source-language update 2025-08-20 02:38:26 +00:00
Chenyu Huang 68e0a78f70 loading state 2025-08-19 16:37:49 -07:00
Chenyu Huang e32f280f47 clean up onSuccess callback 2025-08-19 15:59:12 -07:00
Chenyu Huang f42b5831bb parameterize the initial profile for starter pack profile select wizard screen 2025-08-19 15:28:37 -07:00
Eric Bailey ea7f984a40 Fix isPartOfLastBranchFromDepth assignment (#8856) 2025-08-19 11:33:46 -05:00
Ridley Combs 4923786927 [Lightbox] prevent browser-default escape key behavior (#8859)
Some browsers exit fullscreen when the escape key is pressed without `preventDefault()` being called; we don't want that when we're handling the press ourselves.
2025-08-19 06:25:42 -07:00
pfrazee 48baf7277d Nightly source-language update 2025-08-19 02:39:11 +00:00
Eric Bailey 92ad887e38 Add underage notice to Moderation screen (#8868)
* Add underage notice to Moderation screen

* Incorporate suggestion

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-08-18 19:24:54 -05:00
Eric Bailey 122a46891a [APP-1318] SelectMediaButton (#8828)
* Integrate Sonner for toasts

* Fix animation on iOS

* Refactor API

* Update e2e file

* [APP-1318] Post composer: combine image & video buttons  (#8710)

* add: select media btn

* udpate: compose post with combined image and video support

* add: video combine button with edge cases

* add select media btn

* test: select media btn

* add: media button update

* remove unused files and update toast on android

* update: make strings shorter

* add: ValidatedVideoAsset type

* update link comments and add toast support for native and web

* rebase latest toast and update toast structure

* remove unused prop

* fix types

* undo changes to yarn.lock

* remove: support for mkv files

* update: eslint and prettier

(cherry picked from commit f69779ee130f07e1c49219b53117e3bdd1a9f81b)

* Add missing props to launchImageLibraryAsync

(cherry picked from commit 2e80ae561fd66850f787cac0aae0fa5a6980f8f5)

* Rough out new approach

(cherry picked from commit 9add225160e7e407befc73e9cdd9743a30cdf1cd)

* Comments and cleanup

(cherry picked from commit e69bd186e7335372f440c446ae6643ed0fb15db9)

* Handle native case

(cherry picked from commit 74e38acdfd9181d0557426691fcbcbf0800481ca)

* Refactor

(cherry picked from commit 68aea496db8df54dba5f58da267ad962c28ef995)

* Rename

(cherry picked from commit 8609e59ad14219e7378ee6cb9514d633ce7efc27)

* Cleanup, comments

(cherry picked from commit 6c9c98648e37257285a9c8caeb1eadcc56c81402)

* Rename

(cherry picked from commit 66e3db539d5baa41436c9e49af06e87a78e9e7e1)

* Handle selectionLimit on Android

(cherry picked from commit 251f06dd5e65a7083b810bad3d81114b2fe9ab39)

* create composer images in parallel

(cherry picked from commit 70ea79d9d76d99e9c99a7d2296caed84c718650e)

* Update toast API usage

(cherry picked from commit e370018b8ed8cdfd7675c9634058c72cb59d39de)

* Ensure once one type of media is selected, you can only select more of that type

(cherry picked from commit 1a9e6e0cdb5234667f08e3dd9107ae598941fc23)

* Remove TODO and debug code

* Add more descriptive a11y label to button

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Add back post success toast

* Include mimeType in toast error

* Remove unneeded toast

* Clarify hint

* Typo

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* allow gifs on native, just treat as images

* disable haptic toast

* allow gifs on native, treat as videos

* only do keyboard dismiss on native

* tweak pasting logic

* hide web scrubber in certain situations

* Update MaxImages translation

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Add plural formatting to a11y hint translation

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* fix suggestion

* Protect against no valid assets selected

* Handle conversion of too-big assets on web

* Reorder

* Bump expo-image-picker to include bug/perf improvements

See https://github.com/expo/expo/blob/main/packages/expo-image-picker/CHANGELOG.md#1700--2025-08-13

* Handle edge case validations

* Ok actually bump expo-image-picker

* Comment

* HEIC support Android

* Fix handling for new picker version, improve size validation

* Remove getVideoMetadata handling, no longer needed

* Handle web video duration

* Update src/view/com/composer/SelectMediaButton.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

---------

Co-authored-by: Anastasiya Uraleva <anastasiyauraleva@gmail.com>
Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-08-18 18:28:01 -05:00
Chenyu Huang 7182cd3d5e starter pack dialog flow from profileMenu 2025-08-16 19:45:43 -07:00
pfrazee cced762a7f Nightly source-language update 2025-08-16 02:39:35 +00:00
Samuel Newman 314c380fc4 don't override backspace if alt or meta key (#8855) 2025-08-15 21:41:44 +03:00
Samuel Newman f2892779da Use medium font weight in a few places (#8848)
* medium font toasts

* medium font tabs

* medium font trending pill
2025-08-15 08:33:23 -07:00
Elijah Seed-Arita 5ca665467e feat: use OP's language as recommendation when replying (#8832)
* feat: use OP's language as recommendation when replying

* fix: address nits
2025-08-15 06:16:13 -07:00
pfrazee 4e0be91cff Nightly source-language update 2025-08-15 02:43:46 +00:00
Samuel Newman a761a2e260 Update Xcode in runner to 16.4 (#8842) 2025-08-14 23:21:42 +03:00
Bartosz Kaszubowski 9440068b69 Profile back button tweaks for web (#8795)
* Profile back button tweaks

* apply review feedback - remove StyleSheet

* Update src/screens/Profile/Header/Shell.tsx

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-08-14 10:54:27 -07:00
Eric Bailey 7b2e61bf4d Integrate Sonner for toasts (#8839)
* Integrate Sonner for toasts

* Fix animation on iOS

* Refactor API

* Update e2e file
2025-08-14 09:51:40 -05:00
Samuel Newman 221623f55a Improve "replied to a post" component (#8602)
* unify component

* change bottom padding from 2px to 4px
2025-08-14 03:14:18 -07:00
pfrazee f4dca5d230 Nightly source-language update 2025-08-14 02:42:45 +00:00
Eric Bailey 80ce71283b Bump version to 1.107.0 (#8840) 2025-08-13 17:42:11 -05:00
Samuel Newman 7a334362ae [Perf - part 1] Hoist service config query (#8812) 2025-08-14 01:13:51 +03:00
Samuel Newman b2c56cbd6d Add displayName to contexts (#8814) 2025-08-14 01:12:31 +03:00
Samuel Newman 275fece3e3 [Perf - part 3] Stop every dialog control in the entire app rerendering when opening a dialog (#8815) 2025-08-14 01:11:44 +03:00
Samuel Newman eef639ea54 Preconnect to go.bsky.app (#8825)
* preconnect to go.bsky.app

* other location why not
2025-08-13 17:00:27 -05:00
Samuel Newman 36b2a87a06 Skip intl:compile if not needed (#8837)
* skip intl compile if not needed

* add intl:compile to pull request ci

* compile -> build just to match others
2025-08-13 16:58:42 -05:00
Samuel Newman f001af2fe3 stop incorrectly using suffixtext (#8352) 2025-08-14 00:39:22 +03:00
Samuel Newman d5cc19f282 run lint-native:fix (#8836) 2025-08-13 22:15:08 +03:00
Samuel Newman edd205483d Fix chat button placeholder size on profile (#8827) 2025-08-13 17:20:23 +03:00
Elijah Seed-Arita 485f7ee95b fix: don't open user profile when clicking edit button in user list (#8831) 2025-08-13 01:52:21 -07:00
Arturo Fonseca bfcdb83536 Fix deletion of composed emojis in web composer (#8829) 2025-08-13 01:20:00 -07:00
pfrazee 6cd7dc0f9a Nightly source-language update 2025-08-13 02:42:56 +00:00
Samuel Newman 338fa4dfbe remove imports from @atproto/api internals (#8403) 2025-08-12 08:52:34 -07:00
Samuel Newman bf869d9185 remove unicode ltr chars and replace with css (#8826) 2025-08-12 05:59:03 -07:00
Eric Bailey 683d7bf5a7 Translations (#8823)
* Extract en

* Pull and extract

* Pull and extract
2025-08-11 20:54:31 -05:00
Eric Bailey 44cdf32c1f Update dates (#8822) 2025-08-11 19:01:01 -05:00
Samuel Newman 86b53e7bcc set maxwidth on feed context string (#8817) 2025-08-11 18:57:32 -05:00
Samuel Newman 3ce14b0c6f filter out muted/blocked convos from share menu (#8802) 2025-08-11 18:56:46 -05:00
Samuel Newman 9dfddd3c42 add bottom border to feed headers in explore on web (#8801) 2025-08-11 18:54:28 -05:00
Samuel Newman ef171e2892 Tweak small buttons (#8818)
* set size=small buttons to `text_sm`

* change to `leading_snug`

* add gap to repost buttons

* Add medium-weight font, use for buttons (#8819)

* add medium weight inter

* add medium font to buttons

* Adjust bold weights

* Fix ref

---------

Co-authored-by: Eric Bailey <git@esb.lol>

* Align with designs

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-08-11 18:04:45 -05:00
Samuel Newman 17c5cec356 make sure admonition text doesn't touch button (#8816) 2025-08-11 18:01:32 -05:00
surfdude29 f873f3b301 Add context and comments to button text, label and title in email verification dialog (#8810)
* add context and comment for translators to button text in email verification dialog

* shorten comment

* add comment for other string

* tweak comment

* tweak again
2025-08-11 18:01:10 -05:00
Eric Bailey a3bb8cca6e Fix policy state (#8821)
* Mark completedForDevice prior to creating an account

* Mark policies as completed after initial create account step
2025-08-11 15:51:08 -05:00
Samuel Newman bb949e4f44 Fix translations on Android using PROCESS_TEXT intent (#8486)
* use intents to translate text on android

* clean up config plugins

* restore day night plugin

just to be safe

* leave a comment for why we can't open translate directly

* add todo

* fix lockfile lint
2025-08-11 08:37:39 -07:00
pfrazee 2a6172cbaf Nightly source-language update 2025-08-10 02:54:10 +00:00
jim 4d1a03b99e Merge pull request #8766 from internet-development/binaryfiddler/starter-pack
Update starter pack wizard screen
2025-08-09 00:31:09 -07:00
Chenyu Huang 52637472e6 add missing import 2025-08-08 10:15:29 -07:00
Eric Bailey 23a797cfab Captcha fixes (#8803)
* Add env to scripts

* Update var name
2025-08-08 09:57:17 -05:00
Eric Bailey 22a8b63dcf Update links (#8800) 2025-08-07 15:40:12 -07:00
Eric Bailey 2ba2d9e5b5 Pull latest translations (#8799) 2025-08-07 15:24:55 -07:00
Samuel Newman 93c4719a21 Check handle as you type (#8601)
* check handle as you type

* metrics

* add metric types

* fix overflow

* only check reserved handles for bsky.social, fix test

* change validation check name

* tweak input

* move ghosttext component to textfield

* tweak styles to try and match latest

* add suggestions

* improvements, metrics

* share logic between typeahead and next button

* Apply suggestions from code review

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* update checks, disable button if unavailable

* convert to lowercase

* fix bug with checkHandleAvailability

* add gate

* move files around to make clearer

* fix bad import

* Fix flashing next button

* Enable for TF

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Hailey <me@haileyok.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2025-08-07 17:01:01 -05:00
Bartosz Kaszubowski f708e88410 Add cursor pointer to web select trigger (#8787) 2025-08-07 16:46:35 -05:00
Eric Bailey 88856b0ff7 Fix disabled primary button text color (#8796) 2025-08-07 16:44:19 -05:00
Eric Bailey 08a8324290 Fix e2e (#8794)
* Only enable policy update overlay once the actual Overlay mounts (after onboarding and all that)

* Disable policy overlay in e2e

* Add comments

* Add extra insurance

* Rm log

* Fix shared prefs test

* Fix login flows by optionally closing 'Remember password' system dialog

* Return missing testID

* Bump dev-env
2025-08-07 13:11:16 -07:00
Eric Bailey 11c9931fd2 Fix policy overlay logic (#8793)
* Only enable policy update overlay once the actual Overlay mounts (after onboarding and all that)

* Disable policy overlay in e2e

* Add comments

* Add extra insurance

* Rm log
2025-08-07 14:55:19 -05:00
hailey c0593e4979 Add device attestation to signup flow (#8757) 2025-08-07 12:33:38 -07:00
Samuel Newman 39e775a376 add border curve in neater way (#8792) 2025-08-07 11:30:49 -05:00
Bartosz Kaszubowski d84d54bae3 Fix web scrollable select unwanted overflow (#8786) 2025-08-07 09:23:01 -07:00
Samuel Newman 0a2b1fcfb8 add profile hover card to notif items (#8666) 2025-08-07 09:15:49 -07:00
Eric Bailey cb54082eda [APP-1310] Button refresh (#8758)
* Rm gradient buttons from Storybook

* TEMP move storybook button section

* Remove gradient_sky

* Remove actual defs for gradient_sky and gradient_primary

* Remove other gradient defs

* Remove gradient support entirely

* Deprecate 'variant' in favor of 'color'

* Fork base styles codepath to make variant deprecation more obvious

* Remove text styles for when no color is set, never been used

* Fork text styles codepath to make variant deprecation more obvious

* Revert temp storybook commit, remove deprecated values

* Replace remaining gradient button usage

* Update Buttons storybook section

* Update tiny styles

* Update small styles

* Update large sizes

* Ensure proper alignment of buttons in storybook

* Update button colors

* Rename negative_secondary to negative_subtle

* Remove unnecessary select()

* Update icon size and gap

* Update negative_subtle styles

* Custom button colors

* Add borderCurve
2025-08-07 11:08:31 -05:00
Samuel Newman 20ac2e2733 Only parse notifs with a reason (#8785)
* only parse notifs with a reason

* move error log to a warn, make it actually fire
2025-08-07 09:07:43 -07:00
Eric Bailey c103687d66 Toast tweaks (#8791)
* Tweak colors

* Fix e2e

* Color tweaks

* Fix alignment
2025-08-07 08:45:35 -05:00
pfrazee dbb9ff6918 Nightly source-language update 2025-08-07 02:52:42 +00:00
Anastasiya Uraleva 909ddc86e1 [APP-1365]: Ensure toast text meets a11y guidelines (#8779)
* update: toast colors for accessibility

* update: toast color codes from figma

* condense the colors to remove select calls that are unecessary

* remove unused select
2025-08-06 16:27:44 -05:00
Eric Bailey 75094f4860 [LEG-203] Add onboarding text for policy updates (#8783)
* Add onboarding text for policy updates

* Add gate, add to other case

* Update other UI cases to use Admonitions

* Th

* Update date
2025-08-06 15:16:08 -05:00
Eric Bailey 328aa2be94 [APP-1356] Policy update dialog (#8782)
* Add blocking announcement dialog feature

* WIP custom dialog

* Rework dialog and add native FocusScope

* Lock scroll on web, fix backdrop

* Add web FocusScope

* Create custom Outlet for these announcements

* Clean up FocusScope native impl

* Comments

* Some styling fixes

* Handle screen reader specifically

* Clean up state, remove Portal edits

* Reorg, rename

* Add syncing, tests

* Revert dialog updates

* Revert formatting

* Delete unused file

* Format

* Add FullWindowOverlay

* remove mmkv storage in debug btn

* Add debug code

* fix taps passing through on iOS

* Reorg

* Reorg, rename everything

* Complete policy update after signup

* Add logger

* Move context around, unmount portals on native

* Move a11y prop into FocusScope

* Remove useMemo

* Update dates

* Move debug to dev settings

* Unmount web portals until policy update completed

* UPdate dates

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-08-06 15:15:52 -05:00
Chenyu 9153474e59 Update src/screens/StarterPack/Wizard/index.tsx
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-08-06 11:41:28 -07:00
Chenyu Huang 4c8b30df19 left align header content 2025-08-06 11:24:04 -07:00
Arturo Fonseca fd37d92f85 Fix quality of first seconds of videos on web (#8761) (#8778) 2025-08-05 02:04:32 -07:00
pfrazee 53cf0b3b46 Nightly source-language update 2025-08-05 02:53:53 +00:00
Samuel Newman a5437ebbeb Fix web video ViewportObserver component (#8776)
* Revert "[APP-1083] bug fix: videos not accurately autoplaying on web (#8692)"

This reverts commit 9aa35e9fbb.

* fix overflow hidden breaking the video viewport observer
2025-08-04 10:24:53 -07:00
Samuel Newman 15bc77321b Fix android starting at notif screen (#8775)
* fix android launching at notif screen

* rm heuristic
2025-08-04 09:41:09 -07:00
Samuel Newman 7b5d11eb80 Fix video thumbnails on native (#8774) 2025-08-04 18:42:55 +03:00
kindgracekind b32568260f Add feed tuner to remove muted threads (#8773) 2025-08-04 10:27:27 -05:00
Anastasiya Uraleva 9aa35e9fbb [APP-1083] bug fix: videos not accurately autoplaying on web (#8692)
* update: auto play video on web with intersection position

* place back the threshold: 0.5

* update: optimize the intersection observer with a throttled scroll listener

---------

Co-authored-by: Anastasiya <anastasiya@Mac.localdomain>
Co-authored-by: Anastasiya <anastasiya@Anastasiyas-MacBook-Pro.local>
2025-08-04 06:17:50 -07:00
surfdude29 14e39c4aec Tweak accessibility label (#8767)
* tweak accessibility label

* change `alert` to `message` and add comment instead of context

* tweak comment
2025-08-04 03:49:35 -07:00
Chenyu Huang 73ce358052 update starter pack wizard layout 2025-08-01 11:32:14 -07:00
pfrazee 598641742e Nightly source-language update 2025-08-01 02:58:13 +00:00
jim f21478735c Merge pull request #8762 from JimmyCushnie/updates-readme-like-a-boss
Minor README improvements
2025-07-31 19:46:17 -07:00
jim 9eba567135 Merge pull request #8763 from internet-development/caidan/app-1364-fix-suggested-follows-small-web-view 2025-07-31 14:28:00 -07:00
Caidan Williams 79f365b21c fix(ui): small bug where on small web views the final card was not full height 2025-07-31 11:51:11 -07:00
Caidan Williams 8b344ca9fd fix(ui): adjust padding for ProfileGrid layout consistency
Fixes the issue of the shadow being cutoff by the overflow, now will
give proper spacing to the cards to display the shadow.
2025-07-31 11:51:11 -07:00
Jimmy Cushnie 648dda7541 README: fix verb form of CC
While both forms are used, CC'd is much more common and generally considered the correct form.
2025-07-31 13:59:29 -04:00
Jimmy Cushnie bf455f3e19 README: fix brand capitalization ("Github" -> "GitHub") 2025-07-31 13:55:13 -04:00
Jimmy Cushnie 91574f1f56 README: improve phrasing of packages mention 2025-07-31 13:52:49 -04:00
Jimmy Cushnie 3949747197 README: Use alert for the contributions note 2025-07-31 13:48:40 -04:00
Samuel Newman f4724e378d Don't animate images that will be posted as JPGs (#8760)
* don't play gifs that'll be png'd

* add media inset border

* fix unnecessary typecast

* Revert "fix unnecessary typecast"

This reverts commit 3a8bcc9277.
2025-07-31 09:47:22 -07:00
Eric Bailey e87555c481 [APP-1310] Button cleanup (#8754)
* Rm gradient buttons from Storybook

* TEMP move storybook button section

* Remove gradient_sky

* Remove actual defs for gradient_sky and gradient_primary

* Remove other gradient defs

* Remove gradient support entirely

* Deprecate 'variant' in favor of 'color'

* Fork base styles codepath to make variant deprecation more obvious

* Remove text styles for when no color is set, never been used

* Fork text styles codepath to make variant deprecation more obvious

* Revert temp storybook commit, remove deprecated values

* Replace remaining gradient button usage
2025-07-31 10:32:16 -05:00
Eric Bailey 3bcfcba6d8 Some toasts cleanup and reorg (#8748)
* Reorg

* Move animation into css file

* Update style comment

* Extract core component, use platform-specific wrappers

* Pull out platform specific styles

* Just move styles into Toast component itself

* Rename cleanup

* Update API

* Add duration optional prop

* Add some type docs

* add exp eased slide aniamtions

* Make toasts full width on mobile web

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-07-31 10:15:35 -05:00
surfdude29 33e0714948 tweak case of labels in SearchResults.tsx (#8759) 2025-07-31 06:40:39 -07:00
Eric Bailey b3d207c7b9 Make proper extension of Button more clearly defined (#8753)
* Remove unecessary color prop from SettingsList LinkItem

* Add UninheritableButtonProps to avoid misuse
2025-07-31 05:41:10 -07:00
pfrazee 85981deb31 Nightly source-language update 2025-07-31 02:51:14 +00:00
Jaz 045101286f Merge pull request #8755 from bluesky-social/echoprom_fix
fix echoprom config
2025-07-30 15:15:01 -07:00
Jaz Volpert b25677eb7f build 2025-07-30 21:42:56 +00:00
Jaz Volpert 4393a275ae fix echoprom config 2025-07-30 21:42:26 +00:00
Eric Bailey 3ff42f1595 Fix bad substitution (#8752) 2025-07-30 13:56:27 -05:00
Jaz 3dc6dcd9b9 Merge pull request #8749 from bluesky-social/go-124
Update golang toolchain to 1.24 and clean imports
2025-07-30 11:07:35 -07:00
Samuel Newman 25e60548c4 Mark old components as deprecated (#8747)
* mark a bunch of stuff as deprecated

* mark s as deprecated (serverence reference????)

* rm type import
2025-07-30 11:05:45 -07:00
hailey fade51e9eb Rework variable naming, logic for rendering chat requests (#8737) 2025-07-30 11:00:14 -07:00
Jaz Volpert 324ebdf2cb Cleanup workflows 2025-07-30 17:57:56 +00:00
Jaz Volpert ef167eaca0 build 2025-07-30 17:41:18 +00:00
Jaz Volpert 13499de325 Merge branch 'main' into go-124 2025-07-30 17:40:42 +00:00
Eric Bailey d4b23d3ab4 [APP-1173] Clean up env (#8701)
* Clean up env files

* Use new env in Sentry setup file

* Use new env in Bitdrift setup file

* Use new env in chat proxy header

* Prefix Bitdrift key with EXPO_PUBLIC

* Deprecate SENTRY_RELEASE since we use package.json now

* Use existing EXPO_PUBLIC_BUNDLE_IDENTIFIER short commit has as Sentry dist value

* Fix missing bundle identifier for Render deploys

* Deprecate SENTRY_DIST in favor of EXPO_PUBLIC_BUNDLE_IDENTIFIER

* Prefix SENTRY_DSN with EXPO_PUBLIC to match others

* Remove debugging field

* Replace NODE_ENV in places where its safe

* Self review

* Properly patch Sentry package

* Echo variables to .env in Dockerfile instead of passing to shell script

* Make sure EXPO_PUBLIC_ENV is set for web container builds

* Update IS_TESTFLIGHT to include testflight-android

* Slice bundle hash to match other platforms, needed for render.com deployments

* [APP-1331] Migrate `app-info` to new env (#8703)

* Move env files into directory with platform specific files

* Migrate usages of app-info to new env

* Fix bad import

* Update BUNDLE_DATE format comment

* Trim RENDER_GIT_COMMIT to first 7 to match --short sha

* Clarify build process env vars and ensure they are explicitly passed in

* Revert Sentry patch as a result of prev commit

* Update webpack Sentry dist value based on prev commits

* Add PACKAGE_VERSION and replace in statsig to fix conflict

* Fix render substitution syntax

* Remove invalid syntax

* Remove unnecessary testflight check

* Just use long commit hash

* Slice full hash for display in app

* Fix missing space in ios workflow

* Pass in sentry CLI env vars, align matching values

* Align on RELEASE_VERSION

* Add new env setup to missed OTA spot

* Update webpack to use same SENTRY_RELEASE var

* Just fallback to package version for Render deploys

* Remove TF check for BUNDLE_DATE

* Set EXPO_PUBLIC_ENV for bundle update

* Consistent naming "Env"

* Add comment

* Use RELEASE_VERSION instead of package.json

* Update PR comment CI
2025-07-30 12:33:40 -05:00
Austin McKinley 2d23d821d3 Update golang toolchain to 1.24 and clean imports 2025-07-30 10:28:03 -07:00
Samuel Newman db7bdae51a Convert old toast types to new ones, mark as deprecated (#8746)
* convert old types to new types

* add depreciation warning for old warnings

* rm as consts
2025-07-30 08:18:36 -07:00
Samuel Newman ee7f508717 Fix dataSet for noFeedback links (#8745)
* fix dataSet for noFeedback links

* rm memo

* rm useless spread
2025-07-30 08:17:57 -07:00
jim 7caf2922dd Merge pull request #8744 from internet-development/@APiligrim/update-toast
hot fix: imports for toast and alignment
2025-07-30 01:17:59 -07:00
Ana 18add1cff9 update type errors 2025-07-30 01:08:14 -07:00
Ana d141921abf add: prettier formating 2025-07-30 00:48:56 -07:00
Ana 315e7341bf update: lint fixes for toast.tsx 2025-07-30 00:40:34 -07:00
Ana f8781270e5 update: toast style after lint 2025-07-30 00:36:14 -07:00
Ana f472c7f540 update sorting 2025-07-30 00:25:17 -07:00
Ana 67ba92fa62 update: imports for toast 2025-07-30 00:02:03 -07:00
jim c2b8bdb33c Merge pull request #8743 from internet-development/@APiligrim/update-toast
[APP-1345] Hot fix: add toast.style file
2025-07-29 23:35:38 -07:00
Ana 61969e8dfa add: Toast.style 2025-07-29 23:28:10 -07:00
jim 658dd448d5 Merge pull request #8734 from internet-development/@APiligrim/update-toast
[APP-1345] Update Toast UI on the web and add to storybook
2025-07-29 22:51:16 -07:00
Ana 34ea6e8f34 update: toast styles that reuse consistent style 2025-07-29 22:12:36 -07:00
pfrazee 0a00e02c70 Nightly source-language update 2025-07-30 02:51:39 +00:00
Jaz 15c9835f1d Merge pull request #8740 from bluesky-social/embedr-metrics
Add metrics to embedr service
2025-07-29 18:05:15 -07:00
Austin McKinley 27c51401d2 git tidy 2025-07-29 17:54:11 -07:00
Austin McKinley 2b92697e3e switch to using DefaultServeMux, include go.mod and go.sum changes 2025-07-29 17:51:55 -07:00
jim c31b0338a1 Merge pull request #8733 from internet-development/caidan/app-1330-new-design-for-suggested-for-you-interstitial
feat: new design for "Suggested for you" interstitial
2025-07-29 17:42:30 -07:00
Caidan Williams 940e00c8cb feat(ui): add "See More Suggested Profiles" card 2025-07-29 17:37:01 -07:00
Caidan Williams 7b4ec21e3e refactor(ui): adjust border styles in ProfileGrid card 2025-07-29 17:37:01 -07:00
Caidan Williams e5457c946a feat(ui): improve suggested follow placeholder card
Now matches the same size and shape as the rendered card, which prevents
content layout shift.
2025-07-29 17:37:01 -07:00
Caidan Williams d83480cc64 refactor(ui): remove "Browse more accounts" card on mobile view 2025-07-29 17:37:01 -07:00
Caidan Williams 8dc074c477 fix(ui): profile name and description overflowing on web 2025-07-29 17:37:01 -07:00
Caidan Williams da47cd0d1b fix(ui): placeholder web size and flex grow 2025-07-29 17:37:01 -07:00
Caidan Williams ab5be5cb3f refactor(feed): wrap placeholder description placeholder in full-width view 2025-07-29 17:37:01 -07:00
Caidan Williams 22db8ed639 feat(feed): update suggested profiles link text 2025-07-29 17:37:01 -07:00
Caidan Williams 4c8d5db6a6 refactor(ui): web profile cards maxLength 4 -> 3 with flex grow 2025-07-29 17:37:01 -07:00
Caidan Williams b2fe27afe7 refactor(ui): remove "Browse more suggestions" on web in favor of "See all" 2025-07-29 17:37:01 -07:00
Caidan Williams f35dc19a48 feat(ui): update SuggestedFollowPlaceholder to match new design 2025-07-29 17:37:01 -07:00
Caidan Williams 4e507caa7c feat: update AvatarPlaceholder to take size prop 2025-07-29 17:37:01 -07:00
Caidan Williams 87f2bc5be3 feat: create NamePlaceholder component 2025-07-29 17:37:01 -07:00
Caidan Williams f58ad8e419 refactor: replace magic 6px with dynamic a.gap_md/2 2025-07-29 17:37:01 -07:00
Caidan Williams 2bf4ee5690 fix(ui): suggested profile card grid on web sm -> md 2025-07-29 17:37:01 -07:00
Caidan Williams 48f670f26a fix(ui): follow button should always be pushed to the bottom on the profile card 2025-07-29 17:37:01 -07:00
Caidan Williams 955a864245 refactor: update MOBILE_CARD_WIDTH instead of using inline width 2025-07-29 17:37:01 -07:00
Caidan Williams 0598d73617 refactor(ui): follow button and description to match design 2025-07-29 17:37:01 -07:00
Caidan Williams f478ebdeb5 refactor(ui): swap ProfileCard.NameAndHandle for ProfileCard.Name 2025-07-29 17:37:01 -07:00
Caidan Williams 205e7f0190 feat(ui): update ProfileCard.Avatar size 40 -> 88 2025-07-29 17:37:01 -07:00
Caidan Williams 3c89552e92 refactor(ui): replace ProfileCard.Header with custom View 2025-07-29 17:37:01 -07:00
Caidan Williams c93c36f6e5 feat(ui): force width on suggested profile card 2025-07-29 17:37:01 -07:00
Caidan Williams c6e7816fa7 feat(ui): update padding, border radius, and border on suggested profile card 2025-07-29 17:37:01 -07:00
Caidan Williams ff4eecc2e4 feat: update ProfileCard.Description to take style prop 2025-07-29 17:37:01 -07:00
Caidan Williams 2a6d04e6e2 feat: update ProfileCard.Avatar to take size prop 2025-07-29 17:37:01 -07:00
Caidan Williams e465c9e461 feat(ui): add dropshadow to suggested profile card 2025-07-29 17:37:01 -07:00
Caidan Williams b8a257a1c7 feat(ui): replace suggested profiles interstital icon with link "See all" 2025-07-29 17:37:01 -07:00
Caidan Williams 92e0119734 feat(ui): updated suggested profiles interstitial "Suggested for you" text color 2025-07-29 17:37:01 -07:00
Caidan Williams 287f5c0d42 feat(ui): update suggested profiles interstitial top padding 16 -> 12 2025-07-29 17:37:00 -07:00
Austin McKinley ea226da275 add metrics to embedr service 2025-07-29 17:36:58 -07:00
Elijah Seed-Arita 332dbc1bb4 fix: small profile followup fixes (#8735)
* fix: small profile followup fixes

* fix: change platform-specific compensation for profileHeaderDisplayName marginBottom to target all native

* fix: apply suggestion for consistent cross-platform profile username margin
2025-07-29 16:20:33 -05:00
Eric Bailey bc78fb224e Add comment (#8739) 2025-07-29 15:14:12 -05:00
Ana 890dee3eef update: web toast 2025-07-28 22:07:28 -07:00
Ana c13b1374d7 add: toasts to storybook 2025-07-28 20:24:57 -07:00
Eric Bailey 1504ce28e2 Fix parent read more occurring further up the tree (#8729) 2025-07-28 14:21:01 -05:00
Eric Bailey 6d0c859d8f Fix blur handling (#8730) 2025-07-28 14:20:55 -05:00
hailey 41998c59b5 Ensure preference overrides cause re-renders (#8724)
* make sure request is fetched before returning true

* Ensure preferences object skips equality checks if overridden

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-07-28 12:28:12 -05:00
pfrazee 872fe324a0 Nightly source-language update 2025-07-26 02:44:52 +00:00
hailey 810918b434 add web hook, action tweaks (#8723) 2025-07-25 12:39:43 -07:00
hailey 4d210e33cf fix type error (#8722) 2025-07-25 09:34:04 -07:00
hailey 15abdc67cf simplify logic for pull request OTAs (#8720)
* simplify logic for pull request OTAs

* just render deep link in the text

* dont download update until approved
2025-07-25 08:57:21 -07:00
hailey c6b578fe91 fix final final final (#8719) 2025-07-24 21:07:06 -07:00
pfrazee caeaff157c Nightly source-language update 2025-07-25 02:48:44 +00:00
hailey 5c2867d580 fix (#8718) 2025-07-24 17:48:54 -07:00
hailey 7f3835792e fix action (#8717) 2025-07-24 17:41:43 -07:00
hailey c37ab83823 fix action (#8716) 2025-07-24 17:21:58 -07:00
jim 26755445e3 Merge pull request #8714 from internet-development/c/app-1332-handle-autocomplete-broken-for-handles-with-hyphens
Fix some auto complete issues on mobile
2025-07-24 17:18:40 -07:00
hailey 101b3262b8 fix action (#8715) 2025-07-24 16:31:37 -07:00
hailey 1ee91d2c90 OTA deployments on PR comment action (#8713) 2025-07-24 16:23:17 -07:00
Chenyu Huang ead6862fc6 fix some auto complete issues 2025-07-24 15:58:24 -07:00
Chenyu 9e65f00c93 [APP-1157] disable searches for logged out users, prompt them to sign in (#8697) 2025-07-24 14:44:03 -07:00
jim c48f35d726 Merge pull request #8702 from internet-development/caidan/app-1328-new-trending-video-interstitial
feat(ui): new trending video design
2025-07-24 13:51:05 -07:00
rafael d1dbc4f852 Conditional workflows 2025-07-24 17:29:25 -03:00
rafael fc2fae42bd Add github workflow 2025-07-24 17:07:11 -03:00
Caidan Williams 742397bb1a fix(lint): remove unused import 2025-07-24 12:31:34 -07:00
Caidan Williams 269d70e66c feat(ui): increase the trending videos card size 2025-07-24 12:30:35 -07:00
Caidan Williams 0685de9b7f feat(ui): update TrendingVideos dismiss button style
Changed the TrendingVideos dismiss button to use solid variant and
square shape for improved visibility. Also set ButtonIcon size to "sm"
for better alignment with the new button style.
2025-07-24 12:30:35 -07:00
Caidan Williams c1d2aea885 feat(ui): remove the header icon
Replace the header's flex row with a single bold text element for
"Trending Videos", removing the Graph icon and extra container.
2025-07-24 12:30:35 -07:00
Caidan Williams 229f275246 fix(ui): adjust TrendingVideos padding and gap sizes
Reduced top padding from large to small and updated horizontal padding
handling for the TrendingVideos component. Increased card gap and snap
interval from small to medium.
2025-07-24 12:30:35 -07:00
Caidan Williams 66950a08cb feat(ui): add border to video post and trending cards
Added a border and low contrast border color to CompactVideoPostCard,
CompactVideoPostCardPlaceholder, and TrendingVideos card components for
improved visual separation.
2025-07-24 12:30:35 -07:00
Caidan Williams b89645a172 feat(ui): add shadow to video post trending cards
Added a small shadow (shadow_sm) to the CompactVideoPostCard and the
"View more" card in TrendingVideos for improved visual depth and
consistency. This enhances the card appearance and aligns with the
design system.
2025-07-24 12:30:35 -07:00
Caidan Williams 12e67f53dd fix(ui): overflow for TrendingVideos scroll container
Added overflow_hidden to the main container and set overflow_visible on
the FlatList to ensure proper display of horizontally scrolling cards.
This resolves clipping issues and improves the visual layout of trending
videos.
2025-07-24 12:30:35 -07:00
Caidan Williams ce02e4aa3d feat(atoms): add overflow_visible utility
Added the `overflow_visible` atom to the atoms utility object for
setting CSS overflow to 'visible'. This complements the existing
`overflow_hidden` atom and improves flexibility for layout styling.
2025-07-24 12:30:35 -07:00
Caidan Williams 605c50d6c7 style(ui): use larger border radius on video post card
Updated CompactVideoPostCard to use a larger border radius by replacing
rounded_md with rounded_lg.
2025-07-24 12:30:35 -07:00
Elijah Seed-Arita dff0332dd0 fix: general profile component layout fixes, and ability to disable the inset border for UserAvatar (#8711) 2025-07-24 11:22:19 -07:00
hailey f0b869aeeb fix moderation preferences for non-AA'd users (#8712) 2025-07-24 08:34:31 -07:00
jim 0610c822cf Merge pull request #8708 from internet-development/@APiligrim/chat-request-ui
[APP-1317] update: chat request ui to hide chat requests when there are no messages
2025-07-23 21:46:56 -07:00
Ana a3b188baec update: comment with a name 2025-07-23 20:01:03 -07:00
Eric Bailey 3775aeb146 If birth date is not set, ensure AA still shows (#8709) 2025-07-23 21:01:32 -05:00
Ana 8f1cd86115 update: chat request ui 2025-07-23 16:56:20 -07:00
Elijah Seed-Arita 6a7b8a279b [APP-1291] prevent GestureActionView from hijacking swipe in a direction which no actions are specified (#8705)
Co-authored-by: hailey <hailey@blueskyweb.xyz>
2025-07-23 15:19:48 -07:00
Eric Bailey 3ae3ed245b Clean up AA gate (#8707) 2025-07-23 14:32:19 -05:00
Samuel Newman 8fdcc3ee31 Replace resumeSession with getSession in the email check (#8670)
* replace resumeSession with getSession

* copy lil type tweak from the other PR

* Add partialRefreshSession to session API context, use session state to infer state further down tree

* Review

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-07-23 11:52:38 -05:00
Eric Bailey b4938bc9df Bump version (#8698) 2025-07-23 11:52:06 -05:00
Eric Bailey cf8d8b3bb9 Include app version in metrics (#8699) 2025-07-23 09:31:03 -05:00
pfrazee bbc022c0a6 Nightly source-language update 2025-07-23 02:49:16 +00:00
Caidan bbc39806fe feat(ui): remove like count from trending videos (#8689)
* feat(ui): add showLikeCount flag to CompactVideoPostCard

Introduced a showLikeCount flag to control the display of like count in
the CompactVideoPostCard component. The like count is now only shown if
both likeCount > 0 and showLikeCount are true. This allows for more
flexible UI configurations and easier toggling of like count visibility.

* fix(ui): hide gradient shadow when hiding like count

* fix(ui): increase trending video profile pic size from 20 -> 24

* fix(ui): add small drop shadow to trending video profile pic

* fix(ui): a.shadow_sm -> t.atoms.shadow_sm based on PR feedback
2025-07-22 19:16:07 -05:00
Paul Frazee 9e2b99e860 Release 1.105.0 (#8693)
* Tests fixes

* Pull latest translations
2025-07-21 20:15:29 -07:00
Chenyu fc4bf4e919 add margin between messages in the composer thread (#8691) 2025-07-21 19:49:59 -07:00
pfrazee 2a30a344b5 Nightly source-language update 2025-07-22 02:48:49 +00:00
surfdude29 4a853794dc bskyembed correct hashtag link (#8685) 2025-07-21 20:51:09 -05:00
Eric Bailey 7635a49001 introduce context for "Following" as a feed name. (#8262) (#8690)
"Following" has different translations as a name of a feed and the state of following someone in other languages like Turkish. This allows "Following" as a feed name translated correctly.

(cherry picked from commit d92a7f163ed9e28ee4ebab230758b1f00bdd9966)

Co-authored-by: Sedat Kapanoğlu <sedat@kapanoglu.com>
2025-07-21 20:49:49 -05:00
surfdude29 8ce9bdb27e tweak accessibility label (#8242) 2025-07-21 19:19:41 -05:00
surfdude29 e1a0beff7d add action context for Repost string in RepostButton.web.tsx (#8427) 2025-07-21 18:41:01 -05:00
surfdude29 e5d44923fb tweak app language names (#8436) 2025-07-21 18:40:25 -05:00
surfdude29 6d90d3c2fe remove title casing of Intl.DisplayNames language names (#8433) 2025-07-21 18:35:04 -05:00
Samuel Newman 9ebfbd0e40 Nicer error message for backend video too large error (#8596)
* nicer error message for backend video too large

* use same string for same error
2025-07-21 09:34:58 -05:00
Samuel Newman 74f7a44d71 Patch in upstream fix for video rotation on Android (#8635)
* patch in upstream fix

* build expo-image-picker from source so that patch takes
2025-07-21 09:33:59 -05:00
Samuel Newman 760b184d28 fix emoji popup scroll (#8636) 2025-07-21 09:22:35 -05:00
Samuel Newman 36fba20a01 Follow redirects for soundcloud shortlinks (#8614)
* follow redirects for soundcloud shortlinks

* clear timeout in `finally`
2025-07-21 09:18:33 -05:00
pfrazee ad16ed3096 Nightly source-language update 2025-07-19 02:43:42 +00:00
Eric Bailey 0995e81b58 Age assurance tweaks (#8671)
* Refetch state while in pending status

* Add success state to redirect, just have user close, nicer experience

* Stop refetching after pending
2025-07-18 14:21:23 -05:00
Eric Bailey 6a15679fb1 Handle missed error branch (#8663) 2025-07-18 10:19:56 -05:00
Eric Bailey 4dd9459cba Update copy (#8664) 2025-07-18 10:09:59 -05:00
Jordan Harband 95ab4fa0a1 show precise count in label/hover text (#6164) 2025-07-17 22:11:34 -07:00
Sedat Kapanoğlu cfaf741647 rename file names with colons to the common notation (#8264)
The colons in file names break Windows compatibility and prevent Bluesky from being developed on Windows. (Regression: Bluesky Git repository always shows missing files on Windows #8263)
2025-07-17 21:59:23 -07:00
pfrazee f4909e5e05 Nightly source-language update 2025-07-18 02:49:23 +00:00
Samuel Newman 08a1a806ef Fix checkmark overflow in profile card (#8612) 2025-07-17 23:03:55 +03:00
Eric Bailey 964eed54ea Age assurance fast-follows (#8656)
* Add feed banner

* Comment

* Update nux name

* Handle did error

* Hide mod settings if underage or age restricted

* Add metrics

* Remove DEV override

* Copy suggestion

* Small copy edits

* useState

* Fix bug

* Update src/components/ageAssurance/useAgeAssuranceCopy.ts

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Get rid of debug button

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
2025-07-17 14:32:58 -05:00
Eric Bailey 00b017804b Fix bug where replying to grandparents re-orders thread (#8662)
* Fix bug where optimistic replies were inserted above the root post

* Rename variables for clarity
2025-07-17 13:22:09 -05:00
Samuel Newman d13a2e5f69 use push to convo mechanism (#8653) 2025-07-17 21:18:32 +03:00
Samuel Newman 2c0c9bf803 avoid handling notifs if deep link (#8657) 2025-07-17 21:18:16 +03:00
Samuel Newman 2e16ef4384 fix whitespace collapse (#8659) 2025-07-17 21:17:57 +03:00
Eric Bailey 42bfee5d9d Update copy and link in reporting flow (#8583)
* Update copy and link

* fix prettier

* Update link

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-07-17 11:01:10 -05:00
pfrazee 94a3e5bbe1 Nightly source-language update 2025-07-17 02:47:36 +00:00
Eric Bailey 1dbc331314 UI for age assurance compliance (#8652)
* Add geo prop

* Add prelim fetch

* Add geo debug

* Pass in assurance state to notifications registration

* Comments

* Bump git index

* Add some component utils, no design, gate chat

* Disable mod prefs buttons, does not yet edit mod prefs

* Add initial prompt component

* Refine logic for showing prompt

* Add send email dialog

* Hook up dialog to fake mutation

* Fix geo debug bug

* Move provider inside query provider

* Slightly better screen gater

* Ok decent fallback with isExempt

* Reorg

* Wrap prompt in new logic

* Override mod prefs

* Use real endpoints, optimistic state

* Add persistent card, add time-ago, warning to dialog

* Add comment

* No undefined query values

* Fix case in import

* Wait for AA to load before registering push

* Override prefs in all locations

* Small refactor of notifications registration

* Register push after aa state

* Add retries

* Update blocked screens UI

* Strengthen email validation

* Add intent dialog

* Do service auth for init

* Rug refreshJwt

* Update copy

* Some mobile styles, add dev mode option

* Fix links on native

* Clean up intent dialog on native

* Don't mutate existing session, only copy

* Handle email validation error from server

* Clarity is better

* Moar clear

* Fixes

* Tweaks

* Add country code

* Gate it

* Refresh state after redirect

* Re-check on window focus

* Remove todo

* Enable in dev

* Check for did match on redirect

* Add blocked state

* Add appeal dialog

* Copy tweaks

* Inset in blue well

* Nux the prompt

* Copy updates

* Refetch just in case

* Uppercase country code

* Align copy, add notice to chat screens

* Tweak copy

* Add test code

* Add debug code

* Refactor AccountCard

* Big refactor

* Delay post-feed queries instead

* Debug code

* Clean up state

* Reorg

* Clean up copy

* Comments

* Reorg

* UPdate URL

* Cleanup

* Remove todo

* Update debug code

* revert unneeded changes

* UPdate nux name

* Revert unneeded change

* Updaet storage schema

* Checkpoint: cleanup

* Checkpoint: almost there

* isLoaded -> isReady

* Rename useAgeAssurance

* isUnderage -> isDeclaredUnderage

* Decompose, add docblocks

* Refactor

* UPdate debug

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Drop including Bluesky

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Apply suggestion from @surfdude29

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Remove todo

* Gate debug

* Revert unneeded change

* Fail closed

* Comments

* Comment

* Comment

* fix prettier

* rm viewheader

* bump sdk

* prevent overlap in admonition

* add age assurance intent route

* Just meow

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* Nix callback

* Fix spelling of dismissible lol

* Don't compare translated string

* Better KWS link labels

* Hide DMs send options in menu

* Add button

* Fix order

* Use only supported languages

* Rm button

* best-effort language mapping

* improve typing

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-07-16 13:58:07 -05:00
pfrazee 712c3ad421 Nightly source-language update 2025-07-16 02:47:16 +00:00
Samuel Newman 60c0689236 Fix navigation (#8648) 2025-07-15 15:53:52 +03:00
Samuel Newman 4ccbae7c30 Fix perf issue on web - restore pop behaviour to tabs (#8620) 2025-07-15 07:48:24 +03:00
pfrazee 1f82b1d557 Nightly source-language update 2025-07-15 02:49:31 +00:00
Jim Calabro c9c91fb113 omitempty on aa (#8647) 2025-07-14 16:22:41 -05:00
Jim Calabro 6375c54aa4 Merge pull request #8646 from bluesky-social/jc/aa
Fix Age Restriction Type
2025-07-14 16:24:53 -04:00
jcalabro 1da123b12b Fix Age Restriction Type 2025-07-14 16:21:06 -04:00
Samuel Newman b76f95c9bd bump version to v1.105 (#8616) 2025-07-14 10:03:28 -07:00
Samuel Newman 587c14bac8 fix who can reply icon (#8625) 2025-07-14 10:01:48 -07:00
Eric Bailey be75e00d21 Only show WhoCanReply on root post (#8645) 2025-07-14 11:37:23 -05:00
pfrazee 27d6de0b18 Nightly source-language update 2025-07-13 02:52:39 +00:00
Samuel Newman ff57e75b12 fix mention tab flicker (#8640) 2025-07-12 20:50:04 +03:00
Samuel Newman 0e3124a97e Filter activity notifs for muted words (#8637) 2025-07-11 08:49:59 -07:00
pfrazee 8f5a8f37af Nightly source-language update 2025-07-11 02:46:37 +00:00
Jim Calabro 3b329430ac Merge pull request #8634 from bluesky-social/jc/aaip
Detect Age Restricted Geos
2025-07-10 19:53:57 -04:00
Samuel Newman 377d80e21d Handle notifications on first load (#8629)
* add getInitialURL

* get deep linking working

* actually handle as push instead

* push to route instead of setting initial path

* pop to on top of notifications

* fix comment

* change chat-message handling

* add metrics

* don't reopen due to notif multiple times

* extract data from notification differently on android

* sorry sorry annoying naming nits, align logger

---------

Co-authored-by: Eric Bailey <git@esb.lol>
2025-07-10 16:36:53 -05:00
jcalabro c2a5b3efa8 Detect Age Restricted Geos 2025-07-10 12:41:15 -04:00
pfrazee 22bda086d0 Nightly source-language update 2025-07-10 02:44:40 +00:00
Samuel Newman 07b028ee66 Fix quote+list card padding (#8623)
* fix quote padding not being pressable

* fix list padding not being pressable

* Fix unnecessary loading of feeds (#8578)

* stop layout shifts in feed loading

* don't load feed data if we already have it

* adjust styles, alf stuff

* remove unused button, massively simplify

* fix layout shifting in notifs

* use feedcard for feed post embeds

* use bold text to match other style

* use Link component rather than jank Pressable

* prevent nested anchors in notifs

* match following text size

* add space between content hider

* Better dead feed handling (#8579)

* add space between content hider

* add handling for feeds that fail to load

* cleanError, in case of network funkiness

* handle deleted lists

* split out missingfeed
2025-07-09 00:14:30 -07:00
Samuel Newman 1fcd313424 Translation update (#8624)
* pull translations

* extract all
2025-07-08 08:35:16 -07:00
Samuel Newman 9adcf5a12e specify autocap (#8619) 2025-07-08 05:35:46 -07:00
hailey 34291131b4 bump video lib (#8604) 2025-07-03 22:22:59 -07:00
Samuel Newman a9469cc111 Move NUX date (#8603) 2025-07-03 16:30:24 -07:00
Samuel Newman 1ed019bd72 specify mcemojipicker version (#8600) 2025-07-03 10:17:36 -07:00
pfrazee 42af417e8c Nightly source-language update 2025-07-03 02:43:45 +00:00
Samuel Newman dbfb9dad2f fix label for activity notifs (#8599) 2025-07-02 10:52:40 -07:00
Paul Frazee 9d44673acb Release 1.104.0 (#8595)
* Fix to navigation action after saving feeds

* Test updates

* Intl pull
2025-07-01 17:56:27 -07:00
Samuel Newman bc072570d2 Activity notification settings (#8485)
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: hailey <me@haileyok.com>
2025-07-01 14:36:04 -07:00
Samuel Newman 8f9a8ddce0 enforce border radius on default avatar (#8577) 2025-07-01 13:24:20 -07:00
Samuel Newman 9fdd98d8b4 Improve post spacing (#8589) 2025-07-01 13:24:03 -07:00
pfrazee 5f291b5ca8 Nightly source-language update 2025-07-01 02:51:03 +00:00
hailey 806d3792a9 feat: use t.gifs cdn for tenor search results (#8574) 2025-06-30 13:24:53 -07:00
Samuel Newman 5e20d5ffab Reduce composer font size (#8591) 2025-06-30 19:13:14 +03:00
pfrazee 130f795dfb Nightly source-language update 2025-06-29 02:49:46 +00:00
surfdude29 7837c8f07d tweak string in ContentLanguagesSettings.tsx (#8582) 2025-06-28 10:35:14 -05:00
pfrazee 3e76a4725e Nightly source-language update 2025-06-28 02:40:00 +00:00
Samuel Newman 9b306598cc tweak who can reply dialog (#8573) 2025-06-28 00:03:22 +03:00
Samuel Newman bde3fdaa42 Fix video aspect ratio error - "Record/embed/aspectRatio/width cannot be less than 1" (#8571) 2025-06-28 00:02:59 +03:00
pfrazee 494758da11 Nightly source-language update 2025-06-27 02:42:24 +00:00
Samuel Newman ad54ec8ef9 android paper text input padding (#8570) 2025-06-26 17:26:40 +03:00
Samuel Newman e5f9377a69 Virtualise labeler list (#8566)
* use flatlist for labeler list

* use key extractor

* dedupe `labelValues`

* add comment
2025-06-25 23:39:34 -07:00
pfrazee 954e7d2a89 Nightly source-language update 2025-06-26 02:41:44 +00:00
Eric Bailey 92ffe66ae1 Notifications registration (#8564)
* Formatting nits

* Debounce push token registration by 100ms

* Comment

* Align handling across native devices

* Clean up

* Simplify

* Use hooks

* Update import

* Comment

* Put app view DIDs in constants

* Clarify comment
2025-06-25 21:32:51 -05:00
Eric Bailey bb760400fe A few perf params for threads v2 (#8567)
Co-authored-by: Hailey <me@haileyok.com>
2025-06-25 15:23:09 -07:00
Samuel Newman ab4148dc06 fix pager back gesture (#8565) 2025-06-25 15:22:26 -07:00
Eric Bailey 929393a77a useEmail doesn't need a low stale time (#8568) 2025-06-25 17:22:03 -05:00
Eric Bailey 4c1515169a Tooltip (#8555)
* Working overlay, WIP

* Ok working with no overlay and global gesture handler

* Ok pretty good on native

* Cleanup

* Cleanup

* add animation

* add transform origin to animation

* Some a11y

* Improve colors

* Explicitly wrap gesture handler

* Add easier abstraction

* Web

* Fix animation

* Cleanup and remove provider

* Include demo for now

* Ok diff interface to avoid collapsed views

* Use dimensions hook

* Adjust overlap, clarify intent of consts

* Revert testing edits

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
2025-06-24 22:03:23 -05:00
pfrazee cd820709b6 Nightly source-language update 2025-06-24 02:42:09 +00:00
hailey c894dda0bf disable new arch (#8561) 2025-06-23 10:11:17 -07:00
Samuel Newman c634cd9071 Upgrade prettier to 3.6 (#8558)
* upgrade prettier

* run prettier

* more files
2025-06-23 07:44:40 -07:00
pfrazee 3c92714e4e Nightly source-language update 2025-06-21 02:39:45 +00:00
Samuel Newman 25baf1f661 Allow disabling replies (#8537) 2025-06-20 22:44:53 +03:00
Samuel Newman dcbcd1bb80 simple heuristic for reducing footer height in thread (#8549) 2025-06-20 14:19:48 -05:00
Samuel Newman 92ee6260c1 Ignore common video errors (#8548) 2025-06-20 09:50:21 -07:00
Samuel Newman 9c7b330f92 Catch web browser errors (#8547)
* catch web browser errors

* use catch instead to ensure sheetWrapper works
2025-06-20 09:49:45 -07:00
Eric Bailey bc95c0e50c Don't send any debugs to Sentry (#8533)
* Don't send any debugs to Sentry

* Fix tests
2025-06-20 11:44:39 -05:00
Eric Bailey aeafb14fb4 Couple of Sentry cleanups (#8532)
* Temp ignore a couple logs

* Add debug for unknown notifications

* Nvm let's do this in Sentry

* Downgrade two DMs network related issues

* Check for network errors before sending in Convo

* Do the same for event bus

* Fix mistake
2025-06-20 09:30:52 -07:00
Samuel Newman 4c75b568df Android notification channels (#8539) 2025-06-20 11:01:55 +03:00
pfrazee 9702b210cc Nightly source-language update 2025-06-20 02:41:14 +00:00
Samuel Newman d53fdb0dda fix prefetch returning undefined (#8538) 2025-06-19 09:25:17 -07:00
pfrazee 9be3b0794c Nightly source-language update 2025-06-19 02:41:35 +00:00
Samuel Newman 77db98de65 bump keyboard dep (#8528) 2025-06-18 13:42:06 -07:00
Eric Bailey 51babe0164 Fix anchor text overflow in threads v2 (#8530) 2025-06-18 13:41:58 -07:00
Eric Bailey 04a2a227fc Revert "Move dialog outputs inside navigation context (#8511)" (#8531) 2025-06-18 13:39:58 -07:00
Samuel Newman 42510c0515 gate notification settings (#8527) 2025-06-18 13:36:37 -07:00
hailey f36776a91e switch mmkv version before android eas bundle (#8526) 2025-06-18 12:46:24 -07:00
Samuel Newman eb18b6a49a add scrollbars back on android (#8529) 2025-06-18 21:37:04 +03:00
Eric Bailey 3eaa2d9ddf Disable android new arch (#8525)
* Disable new arch in android for now

* Temporarily comment out mmkv script
2025-06-18 11:58:37 -05:00
Eric Bailey 066fd8cbf9 Fix select text color if system theme mismatches app theme (#8523) 2025-06-18 11:34:52 -05:00
Samuel Newman 06ebd2964a Fix linking to specific search results (#8520)
* fix linking to bsky.app/search?q=xyz

* add name to comment

* skip if notfound
2025-06-18 09:25:14 -07:00
Samuel Newman 3304cd0424 notif settings lexicon change (#8518) 2025-06-18 09:24:55 -07:00
Eric Bailey 32ba17a4f1 Fix anchor follow button alignment (#8522) 2025-06-18 09:24:27 -07:00
Eric Bailey f83335f110 Move dialog outputs inside navigation context (#8511)
* Move all dialogs within NavigationContent on native

* Ok leave old ModalsContainer alone for now

* Do the same on web

* Gate browser consent dialog just to be clear
2025-06-18 09:53:34 -05:00
Samuel Newman 4da86e5864 Modernise link warning dialog (#8243)
* add link warning dialog

* add copy for if sharing

* delete old modal

* get web working
2025-06-18 06:17:54 -07:00
Samuel Newman dd86402763 rearrange settings (#8519) 2025-06-18 05:19:42 -07:00
Frudrax Cheng 13d21692bf Mark translatable text in PreferenceControls.tsx (#8516)
* Update PreferenceControls.tsx

* Update PreferenceControls.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update PreferenceControls.tsx

Co-authored-by: Minseo Lee <itoupluk427@gmail.com>

* Update PreferenceControls.tsx

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Minseo Lee <itoupluk427@gmail.com>
2025-06-18 04:57:49 -07:00
Samuel Newman e672f43ec8 fix other case of promise.all misuse (#8505) 2025-06-18 04:08:44 -07:00
pfrazee afd3d2829f Nightly source-language update 2025-06-18 02:40:54 +00:00
Eric Bailey 619fa0d0bb Delete some old dialogs (#8512)
* Delete old EditProfile dialog

* Delete old email verification dialogs
2025-06-17 18:12:37 -05:00
Samuel Newman 9cf457acf8 copy tweak (#8506) 2025-06-18 00:12:59 +03:00
hailey f1f9ca9606 facepalm (#8510) 2025-06-17 13:19:07 -07:00
1822 changed files with 413665 additions and 208892 deletions
+48 -5
View File
@@ -1,8 +1,51 @@
# Copy this to `.env` and `.env.test` files
# The env the app is running in e.g. development, testflight, production
EXPO_PUBLIC_ENV=development
BITDRIFT_API_KEY=
SENTRY_AUTH_TOKEN=
EXPO_PUBLIC_LOG_LEVEL=debug
EXPO_PUBLIC_LOG_DEBUG=
# This is the semver release version of the app, pulled from package.json
EXPO_PUBLIC_RELEASE_VERSION=
# This is the commit hash that the current bundle was made from.
EXPO_PUBLIC_BUNDLE_IDENTIFIER=
# Should be formatted YYMMDDHH so that it increases for each build.
EXPO_PUBLIC_BUNDLE_DATE=0
# The log level for the app's logger transports
EXPO_PUBLIC_LOG_LEVEL=debug
# Enable debug logs for specific logger instances
EXPO_PUBLIC_LOG_DEBUG=session
# Bluesky appview DID
EXPO_PUBLIC_BLUESKY_PROXY_DID=
# Chat service DID
EXPO_PUBLIC_CHAT_PROXY_DID=
#
#
# Bluesky specific values
#
#
# Bluesky's metrics API
EXPO_PUBLIC_METRICS_API_HOST=
# Growthbook config
EXPO_PUBLIC_GROWTHBOOK_API_HOST=
EXPO_PUBLIC_GROWTHBOOK_CLIENT_KEY=
# Sentry DSN for telemetry
EXPO_PUBLIC_SENTRY_DSN=
# Bitdrift API key. If undefined, Bitdrift will be disabled.
EXPO_PUBLIC_BITDRIFT_API_KEY=
# geolocation web worker URL
GEOLOCATION_DEV_URL=
# live-events web worker URL
LIVE_EVENTS_DEV_URL=
# app-config web worker URL
APP_CONFIG_DEV_URL=
-120
View File
@@ -1,120 +0,0 @@
module.exports = {
root: true,
extends: [
'@react-native',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-native-a11y/ios',
'prettier',
],
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
'react',
'lingui',
'simple-import-sort',
'bsky-internal',
'eslint-plugin-react-compiler',
'import',
],
rules: {
'react/no-unescaped-entities': 0,
'react/prop-types': 0,
'react-native/no-inline-styles': 0,
'bsky-internal/avoid-unwrapped-text': [
'error',
{
impliedTextComponents: [
'H1',
'H2',
'H3',
'H4',
'H5',
'H6',
'P',
'Admonition',
'Admonition.Admonition',
'Span',
],
impliedTextProps: [],
suggestedTextWrappers: {
Button: 'ButtonText',
'ToggleButton.Button': 'ToggleButton.ButtonText',
},
},
],
'bsky-internal/use-exact-imports': 'error',
'bsky-internal/use-typed-gates': 'error',
'bsky-internal/use-prefixed-imports': 'error',
'simple-import-sort/imports': [
'error',
{
groups: [
// Side effect imports.
['^\\u0000'],
// Node.js builtins prefixed with `node:`.
['^node:'],
// Packages.
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
// React/React Native priortized, followed by expo
// Followed by all packages excluding unprefixed relative ones
[
'^(react\\/(.*)$)|^(react$)|^(react-native(.*)$)',
'^(expo(.*)$)|^(expo$)',
'^(?!(?:alf|components|lib|locale|logger|platform|screens|state|view)(?:$|\\/))@?\\w',
],
// Relative imports.
// Ideally, anything that starts with a dot or #
// due to unprefixed relative imports being used, we whitelist the relative paths we use
// (?:$|\\/) matches end of string or /
[
'^(?:#\\/)?(?:lib|state|logger|platform|locale)(?:$|\\/)',
'^(?:#\\/)?view(?:$|\\/)',
'^(?:#\\/)?screens(?:$|\\/)',
'^(?:#\\/)?alf(?:$|\\/)',
'^(?:#\\/)?components(?:$|\\/)',
'^#\\/',
'^\\.',
],
// anything else - hopefully we don't have any of these
['^'],
],
},
],
'simple-import-sort/exports': 'error',
'react-compiler/react-compiler': 'warn',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{argsIgnorePattern: '^_', varsIgnorePattern: '^_'},
],
'@typescript-eslint/consistent-type-imports': [
'warn',
{prefer: 'type-imports', fixStyle: 'inline-type-imports'},
],
'import/consistent-type-specifier-style': ['warn', 'prefer-inline'],
},
ignorePatterns: [
'**/__mocks__/*.ts',
'src/platform/polyfills.ts',
'src/third-party',
'ios',
'android',
'coverage',
'*.lock',
'.husky',
'patches',
'*.html',
'bskyweb',
'bskyembed',
'src/locale/locales/_build/',
'src/locale/locales/**/*.js',
],
settings: {
componentWrapperFunctions: ['observer'],
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 'latest',
},
}
+3 -2
View File
@@ -1,5 +1,5 @@
name: "Bug Report"
description: "Create a report for an issue you have experience in the app."
description: "Create a report for an issue you have experienced in the app."
labels: ["bug"]
body:
- type: markdown
@@ -19,13 +19,14 @@ body:
4. See error
validations:
required: true
- type: textarea
- type: upload
attributes:
label: Attachments
description: |
If possible, please provide any images or videos that may help us understand the issue you are experiencing.
validations:
required: false
accept: ".png,.jpg,.jpeg,.gif,.webp,.mp4,.mov,.webm"
- type: dropdown
attributes:
label: What platform(s) does this occur on?
+2 -1
View File
@@ -26,13 +26,14 @@ body:
4. See error
validations:
required: true
- type: textarea
- type: upload
attributes:
label: Attachments
description: |
If possible, please provide any images or videos that may help us understand the issue you are experiencing.
validations:
required: false
accept: ".png,.jpg,.jpeg,.gif,.webp,.mp4,.mov,.webm"
- type: dropdown
attributes:
label: What platform(s) does this occur on?
+2 -1
View File
@@ -15,7 +15,7 @@ body:
implement it in a timely manner.
validations:
required: true
- type: textarea
- type: upload
attributes:
label: Attachments
description: |
@@ -24,6 +24,7 @@ body:
in or is missing from.
validations:
required: false
accept: ".png,.jpg,.jpeg,.gif,.webp,.mp4,.mov,.webm"
- type: textarea
attributes:
label: Describe Alternatives
@@ -22,7 +22,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v1
@@ -43,12 +43,11 @@ jobs:
tags: |
type=sha,enable=true,priority=100,prefix=,suffix=,format=long
- name: Set outputs
id: vars
- name: Env
id: env
run: |
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Build and push Docker image
id: build-and-push
@@ -62,8 +61,8 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
EXPO_PUBLIC_BUNDLE_IDENTIFIER=${{ steps.vars.outputs.sha_short }}
SENTRY_DIST=${{ steps.vars.outputs.SENTRY_DIST }}
SENTRY_RELEASE=${{ steps.vars.outputs.SENTRY_RELEASE }}
EXPO_PUBLIC_ENV=production
EXPO_PUBLIC_RELEASE_VERSION=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
EXPO_PUBLIC_BUNDLE_IDENTIFIER=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v1
@@ -3,6 +3,7 @@ on:
push:
branches:
- main
- echoprom_fix
env:
REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }}
@@ -21,7 +22,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v1
@@ -1,6 +1,11 @@
name: build-and-push-link-aws
on:
workflow_dispatch:
pull_request:
paths:
- "bskylink/**"
- "Dockerfile.bskylink"
- ".github/workflows/build-and-push-link-aws.yaml"
env:
REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }}
@@ -19,7 +24,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v1
@@ -45,7 +50,7 @@ jobs:
uses: docker/build-push-action@v4
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
push: true
file: ./Dockerfile.bskylink
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
@@ -1,6 +1,11 @@
name: build-and-push-ogcard-aws
on:
workflow_dispatch:
pull_request:
paths:
- "bskyogcard/**"
- "Dockerfile.bskyogcard"
- ".github/workflows/build-and-push-ogcard-aws.yaml"
env:
REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }}
@@ -19,7 +24,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v1
@@ -45,7 +50,7 @@ jobs:
uses: docker/build-push-action@v4
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
push: true
file: ./Dockerfile.bskyogcard
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+49 -25
View File
@@ -13,8 +13,12 @@ on:
jobs:
build:
if: github.repository == 'bluesky-social/social-app'
name: Build and Submit Android
runs-on: ubuntu-latest
runs-on: Linux-x64-32core
concurrency:
group: android-build
cancel-in-progress: false
steps:
- name: Check for EXPO_TOKEN
run: >
@@ -29,7 +33,7 @@ jobs:
fetch-depth: 5
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
@@ -38,7 +42,7 @@ jobs:
uses: dcarbone/install-jq-action@v2
- name: 🔨 Setup EAS
uses: expo/expo-github-action@v8
uses: expo/expo-github-action@main
with:
expo-version: latest
eas-version: latest
@@ -49,15 +53,11 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: "Use upgraded MMKV for Fabric"
run: |
sed -i 's/"react-native-mmkv": "\^2\.12\.2"/"react-native-mmkv": "^3.3.0"/' filename.txt
distribution: "temurin"
java-version: "17"
- name: ⚙️ Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: 🔤 Compile translations
run: yarn intl:build 2>&1 | tee i18n.log
@@ -65,23 +65,33 @@ jobs:
- name: Check for i18n compilation errors
run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi
- name: ✏️ Write environment variables
# EXPO_PUBLIC_ENV is handled in eas.json
- name: Env
id: env
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
echo "$json" > google-services.json
- name: Setup Sentry vars for build-time injection
id: sentry
run: |
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
- name: 🏗️ EAS Build
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p android --profile ${{ inputs.profile || 'testflight-android' }} --local --output build.aab --non-interactive
env:
PROFILE: ${{ inputs.profile || 'testflight-android' }}
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p android
--profile $PROFILE
--local --output build.aab --non-interactive
- name: ✍️ Rename Testflight bundle
if: ${{ inputs.profile != 'production' }}
@@ -91,7 +101,7 @@ jobs:
id: timestamp
uses: nanzm/get-time-action@master
with:
format: 'MM-DD-HH-mm-ss'
format: "MM-DD-HH-mm-ss"
- name: 🚀 Upload Production Artifact
id: upload-artifact-production
@@ -141,9 +151,21 @@ jobs:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
- name: 🧹 Clear Metro cache
if: ${{ inputs.profile == 'production' }}
# https://github.com/expo/eas-cli/issues/2959#issuecomment-2749791326
run: rm -rf ${TMPDIR:-/tmp}/metro-cache
- name: 🏗️ Build Production APK
if: ${{ inputs.profile == 'production' }}
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p android --profile production-apk --local --output build.apk --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p android
--profile production-apk
--local --output build.apk --non-interactive
- name: 🚀 Upload Production APK Artifact
id: upload-artifact-production-apk
@@ -170,11 +192,13 @@ jobs:
- name: ⬇️ Restore Cache
id: get-base-commit
uses: actions/cache@v4
if: ${{ inputs.profile == 'testflight' }}
if: ${{ inputs.profile == 'testflight-android' }}
with:
path: most-recent-testflight-commit.txt
key: most-recent-testflight-commit
- name: ✏️ Write commit hash to cache
if: ${{ inputs.profile == 'testflight' }}
run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
if: ${{ inputs.profile == 'testflight-android' }}
env:
GITHUB_SHA: ${{ github.sha }}
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
+53 -18
View File
@@ -13,8 +13,12 @@ on:
jobs:
build:
if: github.repository == 'bluesky-social/social-app'
name: Build and Submit iOS
runs-on: macos-15
runs-on: macos-26-xlarge
concurrency:
group: ios-build
cancel-in-progress: false
steps:
- name: Check for EXPO_TOKEN
run: >
@@ -29,7 +33,7 @@ jobs:
fetch-depth: 5
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
@@ -38,7 +42,7 @@ jobs:
uses: dcarbone/install-jq-action@v2
- name: 🔨 Setup EAS
uses: expo/expo-github-action@v8
uses: expo/expo-github-action@main
with:
expo-version: latest
eas-version: latest
@@ -48,19 +52,19 @@ jobs:
run: yarn global add eas-cli-local-build-plugin
- name: ⚙️ Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '16.2'
xcode-version: "26.0"
- name: ☕️ Setup Cocoapods
uses: maxim-lobanov/setup-cocoapods@v1
with:
version: 1.14.3
version: 1.16.2
- name: 💾 Cache Pods
uses: actions/cache@v3
uses: actions/cache@v4
id: pods-cache
with:
path: ./ios/Pods
@@ -74,25 +78,54 @@ jobs:
- name: Check for i18n compilation errors
run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi
# EXPO_PUBLIC_ENV is handled in eas.json
- name: ✏️ Write environment variables
id: env
run: |
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
- name: Setup Sentry vars for build-time injection
id: sentry
run: |
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
- name: 🏗️ EAS Build
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p ios --profile ${{ inputs.profile || 'testflight' }} --local --output build.ipa --non-interactive
env:
PROFILE: ${{ inputs.profile || 'testflight' }}
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p ios
--profile $PROFILE
--local --output build.tar.gz --non-interactive
- name: 📂 Extract build artifact
run: |
if [ -f "build.tar.gz" ]; then
echo "Extracting build.tar.gz..."
mkdir ios-build
tar -xzf build.tar.gz -C ios-build
echo "Extraction completed successfully"
else
echo "Archive file not found!"
exit 1
fi
- name: 🚀 Deploy
run: eas submit -p ios --non-interactive --path build.ipa
run: eas submit -p ios --non-interactive --path ios-build/ios/build/Bluesky.ipa
- name: 🪲 Upload dSYM to Sentry
run: >
SENTRY_ORG=blueskyweb
SENTRY_PROJECT=app
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
yarn sentry-cli debug-files upload ios-build/ios/build/Bluesky.app.dSYM.zip --include-sources
- name: 📚 Get version from package.json
id: get-build-info
@@ -119,5 +152,7 @@ jobs:
key: most-recent-testflight-commit
- name: ✏️ Write commit hash to cache
env:
GITHUB_SHA: ${{ github.sha }}
if: ${{ inputs.profile == 'testflight' }}
run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
+87 -47
View File
@@ -20,6 +20,7 @@ on:
jobs:
bundleDeploy:
if: github.repository == 'bluesky-social/social-app'
name: Bundle and Deploy EAS Update
runs-on: ubuntu-latest
concurrency:
@@ -38,10 +39,12 @@ jobs:
# Validate the version if one is supplied. This should generally happen if the update is for a production client
- name: 🧐 Validate version
env:
RUNTIME_VERSION: ${{ inputs.runtimeVersion }}
if: ${{ inputs.runtimeVersion }}
run: |
if [ -z "${{ inputs.runtimeVersion }}" ]; then
[[ "${{ inputs.runtimeVersion }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "Version is valid" || exit 1
if [ -z "$RUNTIME_VERSION" ]; then
[[ "$RUNTIME_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && echo "Version is valid" || exit 1
fi
- name: ⬇️ Checkout
@@ -54,7 +57,7 @@ jobs:
run: git fetch origin main:main --depth 100
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
@@ -85,7 +88,7 @@ jobs:
run: yarn typecheck
- name: 🔨 Setup EAS
uses: expo/expo-github-action@v8
uses: expo/expo-github-action@main
if: ${{ !steps.fingerprint.outputs.includes-changes }}
with:
expo-version: latest
@@ -100,25 +103,34 @@ jobs:
if: ${{ !steps.fingerprint.outputs.includes-changes }}
uses: dcarbone/install-jq-action@v2
- name: ✏️ Write environment variables
# eas.json not used here, set EXPO_PUBLIC_ENV
- name: Env
env:
CHANNEL: ${{ inputs.channel || 'testflight' }}
GITHUB_SHA: ${{ github.sha }}
id: env
if: ${{ !steps.fingerprint.outputs.includes-changes }}
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_ENV=$CHANNEL" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
echo "$json" > google-services.json
- name: Setup Sentry vars for build-time injection
id: sentry
run: |
echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
- name: 🏗️ Create Bundle
if: ${{ !steps.fingerprint.outputs.includes-changes }}
run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} EXPO_PUBLIC_ENV="${{ inputs.channel || 'testflight' }}" yarn export
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn export
- name: 📦 Package Bundle and 🚀 Deploy
if: ${{ !steps.fingerprint.outputs.includes-changes }}
@@ -138,19 +150,19 @@ jobs:
- name: ✏️ Write commit hash to cache
if: ${{ !steps.fingerprint.outputs.includes-changes }}
run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
# GitHub actions are horrible so let's just copy paste this in
buildIfNecessaryIOS:
name: Build and Submit iOS
runs-on: macos-15
runs-on: macos-26
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-build-ios
cancel-in-progress: true
group: ios-build
cancel-in-progress: false
needs: [bundleDeploy]
# Gotta check if its NOT '[]' because any md5 hash in the outputs is detected as a possible secret and won't be
# available here
if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected }}
if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected && github.repository == 'bluesky-social/social-app' }}
steps:
- name: Check for EXPO_TOKEN
run: >
@@ -165,13 +177,13 @@ jobs:
fetch-depth: 5
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: 🔨 Setup EAS
uses: expo/expo-github-action@v8
uses: expo/expo-github-action@main
with:
expo-version: latest
eas-version: latest
@@ -181,19 +193,19 @@ jobs:
run: yarn global add eas-cli-local-build-plugin
- name: ⚙️ Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '16.2'
xcode-version: "26.0"
- name: ☕️ Setup Cocoapods
uses: maxim-lobanov/setup-cocoapods@v1
with:
version: 1.14.3
version: 1.16.2
- name: 💾 Cache Pods
uses: actions/cache@v3
uses: actions/cache@v4
id: pods-cache
with:
path: ./ios/Pods
@@ -204,16 +216,30 @@ jobs:
- name: 🔤 Compile translations
run: yarn intl:build
- name: ✏️ Write environment variables
# EXPO_PUBLIC_ENV is handled in eas.json
- name: Env
id: env
run: |
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
- name: 🏗️ EAS Build
run: yarn use-build-number-with-bump eas build -p ios --profile testflight --local --output build.ipa --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p ios
--profile testflight
--local --output build.ipa --non-interactive
- name: 🚀 Deploy
run: eas submit -p ios --non-interactive --path build.ipa
@@ -228,18 +254,20 @@ jobs:
- name: ✏️ Write commit hash to cache
if: ${{ inputs.channel == 'testflight' }}
run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
env:
GITHUB_SHA: ${{ github.sha }}
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
buildIfNecessaryAndroid:
name: Build and Submit Android
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-build-android
group: android-build
cancel-in-progress: false
needs: [bundleDeploy]
# Gotta check if its NOT '[]' because any md5 hash in the outputs is detected as a possible secret and won't be
# available here
if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected }}
if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected && github.repository == 'bluesky-social/social-app'}}
steps:
- name: Check for EXPO_TOKEN
@@ -255,13 +283,13 @@ jobs:
fetch-depth: 5
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: 🔨 Setup EAS
uses: expo/expo-github-action@v8
uses: expo/expo-github-action@main
with:
expo-version: latest
eas-version: latest
@@ -272,36 +300,46 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: "Use upgraded MMKV for Fabric"
run: |
sed -i 's/"react-native-mmkv": "\^2\.12\.2"/"react-native-mmkv": "^3.3.0"/' filename.txt
distribution: "temurin"
java-version: "17"
- name: ⚙️ Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: 🔤 Compile translations
run: yarn intl:build
- name: ✏️ Write environment variables
# EXPO_PUBLIC_ENV is handled in eas.json
- name: Env
id: env
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
echo "$json" > google-services.json
- name: 🏗️ EAS Build
run: yarn use-build-number-with-bump eas build -p android --profile testflight-android --local --output build.apk --non-interactive
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn use-build-number-with-bump
eas build -p android
--profile testflight-android
--local --output build.apk --non-interactive
- name: ⏰ Get a timestamp
id: timestamp
uses: nanzm/get-time-action@master
with:
format: 'MM-DD-HH-mm-ss'
format: "MM-DD-HH-mm-ss"
- name: 🚀 Upload Artifact
id: upload-artifact
@@ -332,5 +370,7 @@ jobs:
key: most-recent-testflight-commit
- name: ✏️ Write commit hash to cache
env:
GITHUB_SHA: ${{ github.sha }}
if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }}
run: echo ${{ github.sha }} > most-recent-testflight-commit.txt
run: echo $GITHUB_SHA > most-recent-testflight-commit.txt
+54
View File
@@ -0,0 +1,54 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'
# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'
# NOTE(sfn): we can add a custom system prompt here
claude_args: |
--model claude-opus-4-5-20251101
+7 -7
View File
@@ -7,7 +7,7 @@ on:
- main
concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
@@ -15,11 +15,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Git Checkout
uses: actions/checkout@v3
uses: actions/checkout@v5
- name: Set up Go tooling
uses: actions/setup-go@v3
uses: actions/setup-go@v6
with:
go-version: '1.23'
go-version-file: bskyweb/go.mod
- name: Dummy Static Files
run: touch bskyweb/static/js/blah.js && touch bskyweb/static/css/blah.txt && touch bskyweb/static/media/blah.txt
- name: Check
@@ -32,11 +32,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Git Checkout
uses: actions/checkout@v3
uses: actions/checkout@v5
- name: Set up Go tooling
uses: actions/setup-go@v3
uses: actions/setup-go@v6
with:
go-version: '1.23'
go-version-file: bskyweb/go.mod
- name: Dummy Static Files
run: touch bskyweb/static/js/blah.js && touch bskyweb/static/css/blah.txt && touch bskyweb/static/media/blah.txt
- name: Lint
+7 -5
View File
@@ -6,7 +6,7 @@ on:
branches:
- main
concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
@@ -15,11 +15,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: Yarn install
uses: Wandalen/wretry.action@master
with:
@@ -41,11 +42,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: Yarn install
uses: Wandalen/wretry.action@master
with:
@@ -1,7 +1,7 @@
name: Nightly Update Source Languages
on:
schedule:
- cron: '0 2 * * *' # run at 2 AM UTC
- cron: "0 2 * * *" # run at 2 AM UTC
workflow_dispatch:
jobs:
@@ -16,13 +16,14 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
ssh-key: ${{secrets.GH_ACTION_DEPLOY_KEY}}
- name: Install node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: Yarn install
uses: Wandalen/wretry.action@master
with:
@@ -46,4 +47,4 @@ jobs:
push_sources: false
create_pull_request: false
env:
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
+213
View File
@@ -0,0 +1,213 @@
---
name: PR Comment Trigger
on:
issue_comment:
types: [created]
# Permissiosn to make comments in the pull request
permissions:
pull-requests: write
actions: write
contents: read
jobs:
handle-comment:
if: github.event.issue.pull_request
runs-on: ubuntu-latest
outputs:
should-deploy: ${{ steps.check-org.outputs.result }}
steps:
- name: Check if bot is mentioned
id: check-mention
env:
COMMENT: ${{ github.event.comment.body }}
run: |
if [[ "$COMMENT" == *"@github-actions"* ]] || \
[[ "$COMMENT" == *"github-actions[bot]"* ]]; then
bot_mentioned=true
else
bot_mentioned=false
fi
if [[ "$COMMENT" == *"ota"* ]]; then
has_ota=true
else
has_ota=false
fi
if [[ "$bot_mentioned" == "true" ]] && [[ "$has_ota" == "true" ]]; then
echo "mentioned=true" >> $GITHUB_OUTPUT
else
echo "mentioned=false" >> $GITHUB_OUTPUT
fi
- name: Check organization membership
if: steps.check-mention.outputs.mentioned == 'true'
id: check-org
uses: actions/github-script@v7
with:
script: |
try {
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.payload.comment.user.login
});
const hasAccess = ['admin', 'write'].includes(perm.permission);
console.log(`User has ${perm.permission} access`);
return hasAccess;
} catch(error) {
console.log('User has no repository access');
return false;
}
bundle-deploy:
name: Bundle and Deploy EAS Update
runs-on: ubuntu-latest
needs: [handle-comment]
if: needs.handle-comment.outputs.should-deploy == 'true'
steps:
- name: Get PR HEAD SHA
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
id: pr-info
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: process.env.ISSUE_NUMBER,
});
console.log(`PR HEAD SHA: ${pr.data.head.sha}`);
console.log(`PR HEAD REF: ${pr.data.head.ref}`);
core.setOutput('head-sha', pr.data.head.sha);
core.setOutput('head-ref', pr.data.head.ref);
- name: 💬 Drop a comment
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pull-request-eas-build-${{ steps.pr-info.outputs.head-sha }}
number: ${{ github.event.issue.number }}
message: |
An OTA deployment has been requested and is now running for `${{ steps.pr-info.outputs.head-sha }}`.
[Here is some music to listen to while you wait...](https://www.youtube.com/watch?v=VBlFHuCzPgY)
---
*Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖*
- name: Check for EXPO_TOKEN
run: >
if [ -z "${{ secrets.EXPO_TOKEN }}" ]; then
echo "You must provide an EXPO_TOKEN secret linked to this project's Expo account in this repo's secrets. Learn more: https://docs.expo.dev/eas-update/github-actions"
exit 1
fi
- name: ⬇️ Checkout
uses: actions/checkout@v4
with:
ref: ${{ steps.pr-info.outputs.head-sha }}
- name: 🔧 Setup Node
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Lint check
run: yarn lint
- name: Lint lockfile
run: yarn lockfile-lint
- name: 🔤 Compile translations
run: yarn intl:build 2>&1 | tee i18n.log
- name: Check for i18n compilation errors
run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi
- name: Type check
run: yarn typecheck
- name: 🔨 Setup EAS
uses: expo/expo-github-action@main
with:
expo-version: latest
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- name: ⛏️ Setup Expo
run: yarn global add eas-cli-local-build-plugin
- name: 🪛 Setup jq
uses: dcarbone/install-jq-action@v2
- name: Env
id: env
run: |
export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}'
echo "${{ secrets.ENV_TOKEN }}" > .env
echo "EXPO_PUBLIC_ENV=testflight" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env
echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env
echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env
echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env
echo "EXPO_PUBLIC_GCP_PROJECT_ID=${{ secrets.EXPO_PUBLIC_GCP_PROJECT_ID }}" >> .env
echo "$json" > google-services.json
- name: 🏗️ Create Bundle
run: >
SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }}
SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }}
yarn export
- name: 📦 Package Bundle and 🚀 Deploy
run: yarn use-build-number bash scripts/bundleUpdate.sh
env:
DENIS_API_KEY: ${{ secrets.DENIS_API_KEY }}
CHANNEL_NAME: pull-request-${{ github.event.issue.number }}
RUNTIME_VERSION:
- name: 💬 Drop a comment
uses: marocchino/sticky-pull-request-comment@v2
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
with:
header: pull-request-eas-build-${{ steps.pr-info.outputs.head-sha }}
number: ${{ github.event.issue.number }}
message: |
Your requested OTA deployment was successful! You may now apply it by either scanning the QR code or opening the deep link below in your browser:
<img src="https://bsky-qr.vercel.app?channel=pull-request-$ISSUE_NUMBER" width=300 height=300>
`bluesky://intent/apply-ota?channel=pull-request-${{ github.event.issue.number }}`
---
*Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖*
- name: 💬 Drop a comment
uses: marocchino/sticky-pull-request-comment@v2
if: failure()
with:
header: pull-request-eas-build-${{ steps.pr-info.outputs.head-sha }}
number: ${{ github.event.issue.number }}
message: |
Your requested OTA deployment was unsuccessful. See action logs for more details.
---
*Generated by [PR labeler](https://github.com/expo/expo/actions/workflows/pr-labeler.yml) 🤖*
+18 -10
View File
@@ -29,27 +29,35 @@ jobs:
fetch-depth: 0
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
- name: Ensure tracking relevant branches and checkout base
env:
HEAD_REF: ${{ github.head_ref }}
BASE_REF: ${{ github.base_ref }}
run: |
git checkout ${{ github.head_ref }}
git checkout ${{ github.base_ref }}
git checkout $HEAD_REF
git checkout $BASE_REF
- name: Get the base commit
id: base-commit
run: echo base-commit=$(git log -n 1 ${{ github.base_ref }} --pretty=format:'%H') >> "$GITHUB_OUTPUT"
env:
BASE_REF: ${{ github.base_ref }}
run: echo base-commit=$(git log -n 1 $BASE_REF --pretty=format:'%H') >> "$GITHUB_OUTPUT"
- name: Merge PR commit
env:
HEAD_REF: ${{ github.head_ref }}
run: |
# Have to set a git config for the merge to work
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git merge --no-edit ${{ github.head_ref }}
git merge --no-edit $HEAD_REF
yarn install
yarn intl:build
- name: 🔦 Generate stats file for PR
run: |
@@ -73,6 +81,7 @@ jobs:
if: ${{ !steps.get-base-stats.outputs.cache-hit }}
run: |
yarn install
yarn intl:build
yarn generate-webpack-stats-file
mv stats.json stats-base.json
@@ -80,9 +89,9 @@ jobs:
id: get-diff
uses: NejcZdovc/bundle-size-diff@v1
with:
base_path: 'stats-base.json'
pr_path: '../stats-new.json'
excluded_assets: '(.+).chunk.js|(.+).js.map|(.+).json|(.+).png'
base_path: "stats-base.json"
pr_path: "../stats-new.json"
excluded_assets: "(.+).chunk.js|(.+).js.map|(.+).json|(.+).png|(.+).svg|(.+).webp|(.+).jpg|(.+).ico"
- name: 💬 Drop a comment
uses: marocchino/sticky-pull-request-comment@v2
@@ -108,7 +117,7 @@ jobs:
if: github.event_name == 'pull_request'
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
@@ -143,4 +152,3 @@ jobs:
with:
header: fingerprint-diff
delete: true
+31
View File
@@ -0,0 +1,31 @@
name: Sync to internal repo
on:
push:
branches: [main]
jobs:
sync:
runs-on: ubuntu-latest
if: github.repository == 'bluesky-social/social-app'
steps:
- name: Checkout public repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.SYNC_INTERNAL_APP_ID }}
private-key: ${{ secrets.SYNC_INTERNAL_PK }}
repositories: social-app-internal
- name: Push to internal repo
env:
TOKEN: ${{ steps.app-token.outputs.token }}
run: |
git config user.name "github-actions"
git config user.email "test@users.noreply.github.com"
git config --unset-all http.https://github.com/.extraheader
git remote add internal https://x-access-token:${TOKEN}@github.com/bluesky-social/social-app-internal.git
git push internal main --force
+9 -5
View File
@@ -3,7 +3,7 @@ name: Lockfile
on:
pull_request:
concurrency:
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
@@ -12,20 +12,24 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out PR HEAD
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch base branch
run: git fetch origin ${{ github.base_ref }} --depth=1
env:
BASE_REF: ${{ github.base_ref }}
run: git fetch origin $BASE_REF --depth=1
- name: Install node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
- name: Reset yarn.lock to base
run: git show "origin/${{ github.base_ref }}:yarn.lock" > yarn.lock
env:
BASE_REF: ${{ github.base_ref }}
run: git show "origin/$BASE_REF:yarn.lock" > yarn.lock
- name: Yarn install
uses: Wandalen/wretry.action@master
+10 -1
View File
@@ -58,6 +58,7 @@ buck-out/
# Ruby / CocoaPods
/ios/Pods/
/vendor/bundle/
Gemfile.lock
# Testing
coverage/
@@ -109,7 +110,9 @@ google-services.json
# i18n
src/locale/locales/_build/
src/locale/locales/**/*.js
src/locale/locales/**/messages.js
src/locale/locales/**/messages.mjs
src/locale/locales/**/messages.ts
# local builds
*.apk
@@ -118,3 +121,9 @@ src/locale/locales/**/*.js
# ogcard assets
bskyogcard/src/assets/fonts/noto-*
# bskyweb build output
bskyweb/static/media/*.webp
bskyweb/static/media/*.jpg
bskyweb/static/media/*.png
bskyweb/static/media/*.svg
+135
View File
@@ -0,0 +1,135 @@
/**
* Codemod to replace namespaced React calls with named imports
*
* Before:
* import React from 'react'
* React.useEffect(() => {}, [])
*
* After:
* import { useEffect } from 'react'
* useEffect(() => {}, [])
*
* Usage: jscodeshift -t .jscodeshift/react-import.js <file-path>
* Example: jscodeshift -t .jscodeshift/react-import.js src/App.native.tsx
*/
/* eslint-disable */
export const parser = 'tsx'
export default function transformer(file, api) {
const j = api.jscodeshift
const root = j(file.source)
// Find the React import
let reactImportPath = null
const reactMembers = new Set()
root.find(j.ImportDeclaration).forEach(path => {
const node = path.value
if (node.source.value === 'react') {
node.specifiers.forEach(spec => {
// Check if this is a default import of React
if (
spec.type === 'ImportDefaultSpecifier' &&
spec.local.name === 'React'
) {
reactImportPath = path
}
})
}
})
if (!reactImportPath) {
// No React import found, nothing to do
return file.source
}
// Find all React.* member expressions
root
.find(j.MemberExpression)
.filter(path => {
const node = path.value
return (
node.object.type === 'Identifier' &&
node.object.name === 'React' &&
node.property.type === 'Identifier'
)
})
.forEach(path => {
const propertyName = path.value.property.name
reactMembers.add(propertyName)
})
// Find all React.* JSX member expressions (e.g., <React.Fragment>)
root
.find(j.JSXMemberExpression)
.filter(path => {
const node = path.value
return node.object.name === 'React' && node.property.name
})
.forEach(path => {
const propertyName = path.value.property.name
reactMembers.add(propertyName)
})
// If no React members are used, remove the import
if (reactMembers.size === 0) {
reactImportPath.prune()
return root.toSource()
}
// Sort the members for consistent output
const sortedMembers = Array.from(reactMembers).sort()
// Create new import specifiers
const newSpecifiers = sortedMembers.map(name =>
j.importSpecifier(j.identifier(name), j.identifier(name)),
)
// Get the existing import specifiers
const sortedImports = Array.from(reactImportPath.value.specifiers).sort()
const existingSpecifiers = sortedImports.filter(
specifier => specifier.type !== 'ImportDefaultSpecifier',
)
const allSpecifiers = [
...new Map(
[...existingSpecifiers, ...newSpecifiers].map(item => [
item.imported.name,
item,
]),
).values(),
]
// Update the import declaration
reactImportPath.value.specifiers = allSpecifiers
// Replace all React.* member expressions with just the identifier
root
.find(j.MemberExpression)
.filter(path => {
const node = path.value
return (
node.object.type === 'Identifier' &&
node.object.name === 'React' &&
node.property.type === 'Identifier'
)
})
.replaceWith(path => {
return j.identifier(path.value.property.name)
})
// Replace all React.* JSX member expressions with just the identifier
root
.find(j.JSXMemberExpression)
.filter(path => {
const node = path.value
return node.object.name === 'React' && node.property.name
})
.replaceWith(path => {
return j.jsxIdentifier(path.value.property.name)
})
return root.toSource()
}
+106
View File
@@ -0,0 +1,106 @@
/**
* Codemod to replace namespaced React calls with named imports
*
* Before:
* import * as Toast from '#/view/com/util/Toast'
* Toast.show(message, 'xmark')
*
* After:
* import * as Toast from '#/components/Toast'
* Toast.show(message, {type: 'error'})
*
* Usage: jscodeshift -t .jscodeshift/toast-v2.js <file-path>
* Example: jscodeshift -t .jscodeshift/toast-v2.js src/App.native.tsx
*/
/* eslint-disable */
export const parser = 'tsx'
const OLD_IMPORT = '#/view/com/util/Toast'
const NEW_IMPORT = '#/components/Toast'
const convertLegacyToastType = type => {
switch (type) {
// these ones are fine
case 'default':
case 'success':
case 'error':
case 'warning':
case 'info':
return type
// legacy ones need conversion
case 'xmark':
return 'error'
case 'exclamation-circle':
return 'warning'
case 'check':
return 'success'
case 'clipboard-check':
return 'success'
case 'circle-exclamation':
case 'exclamation-circle':
return 'warning'
default:
return 'default'
}
}
export default function transformer(file, api) {
const j = api.jscodeshift
const root = j(file.source)
// Find Toast import declarations using the old path
const toastImports = root
.find(j.ImportDeclaration)
.filter(path => path.value.source.value === OLD_IMPORT)
if (toastImports.length === 0) {
return file.source
}
// Update import path
toastImports.forEach(path => {
path.value.source.value = NEW_IMPORT
})
// Collect all local names the Toast namespace is bound to
const toastLocalNames = new Set()
toastImports.forEach(path => {
path.value.specifiers.forEach(spec => {
if (spec.type === 'ImportNamespaceSpecifier') {
toastLocalNames.add(spec.local.name)
}
})
})
// Transform Toast.show(message, type) calls
root.find(j.CallExpression).forEach(path => {
const {callee, arguments: args} = path.value
// Match <ToastName>.show(...)
if (
callee.type !== 'MemberExpression' ||
callee.object.type !== 'Identifier' ||
!toastLocalNames.has(callee.object.name) ||
callee.property.name !== 'show'
) {
return
}
// Only transform 2-arg calls where the second arg is a string literal
if (args.length !== 2) return
const typeArg = args[1]
if (typeArg.type !== 'StringLiteral' && typeArg.type !== 'Literal') return
const legacyType = typeArg.value
const newType = convertLegacyToastType(legacyType)
// Replace the second argument with an options object: {type: 'newType'}
args[1] = j.objectExpression([
j.property('init', j.identifier('type'), j.stringLiteral(newType)),
])
})
return root.toSource()
}
+755
View File
@@ -0,0 +1,755 @@
# CLAUDE.md - Bluesky Social App Development Guide
This document provides guidance for working effectively in the Bluesky Social app codebase.
## Project Overview
Bluesky Social is a cross-platform social media application built with React Native and Expo. It runs on iOS, Android, and Web, connecting to the AT Protocol (atproto) decentralized social network.
**Tech Stack:**
- React Native 0.81 with Expo 54
- TypeScript
- React Navigation for routing
- TanStack Query (React Query) for data fetching
- Lingui for internationalization
- Custom design system called ALF (Application Layout Framework)
## Essential Commands
```bash
# Development
yarn start # Start Expo dev server
yarn web # Start web version
yarn android # Run on Android
yarn ios # Run on iOS
# Testing & Quality
# IMPORTANT: Always use these yarn scripts, never call the underlying tools directly
yarn test # Run Jest tests
yarn lint # Run ESLint
yarn typecheck # Run TypeScript type checking
# Internationalization
# DO NOT run these commands - extraction and compilation are handled by CI
yarn intl:extract # Extract translation strings (nightly CI job)
yarn intl:compile # Compile translations for runtime (nightly CI job)
# Build
yarn build-web # Build web version
yarn prebuild # Generate native projects
```
## Project Structure
```
src/
├── alf/ # Design system (ALF) - themes, atoms, tokens
├── components/ # Shared UI components (Button, Dialog, Menu, etc.)
├── screens/ # Full-page screen components (newer pattern)
├── features/ # Macro-features that bridge components/screens
├── view/
│ ├── screens/ # Full-page screens (legacy location)
│ ├── com/ # Reusable view components
│ └── shell/ # App shell (navigation bars, tabs)
├── state/
│ ├── queries/ # TanStack Query hooks
│ ├── preferences/ # User preferences (React Context)
│ ├── session/ # Authentication state
│ └── persisted/ # Persistent storage layer
├── lib/ # Utilities, constants, helpers
├── locale/ # i18n configuration and language files
└── Navigation.tsx # Main navigation configuration
```
### Project Structure in Depth
When building new things, follow these guidelines for where to put code.
#### Components vs Screens vs Features
**Components** are reusable UI elements that are not full screens. Should be
platform-agnostic when possible. Examples: Button, Dialog, Menu, TextField. Put
these in `/components` if they are shared across screens.
**Screens** are full-page components that represent a route in the app. They
often contain multiple components and handle layout for a page. New screens
should go in `/screens` (not `/view/screens`) to encourage better organization
and separation from legacy code.
For complex screens that have specific components or data needs that _are not
shared by other screens_, we encourage subdirectoreis within `/screens/<name>`
e.g. `/screens/ProfileScreen/ProfileScreen.tsx` and
`/screens/ProfileScreen/components/`.
**Features** are higher-level modules that may include context, data fetching,
components, and utilities related to a specific feature e.g.
`/features/liveNow`. They don't neatly fit into components or screens and often
span multiple screens. This is an optional pattern for organizing complex
features.
#### Legacy Directories
For the most part, avoid writing new files into the `/view` directory and
subdirectories. This is the older pattern for organizing screens and components,
and it has become a bit disorganized over time. New development should go into
`/screens`, `/components`, and `/features`.
#### State
The `/state` directory is where we've historically put all our data fetching and
state management logic. This is perfectly fine, but for new features, consider
organizing state logic closer to the components that use it, either within a
feature directory or co-located with a screen. The key is to keep related code
together and avoid having "god files" with too much unrelated logic.
#### Lib
The `/lib` directory is for utilities and helpers that don't fit into other
categories. This can include things like API clients, formatting functions,
constants, and other shared logic.
#### Top Level Directories
Avoid writing new top-level subdirectories within `/src`. We've done this for a
few things in the past that, but we have stronger patterns now. Examples:
`/logger` should probably have been written into `/lib`. And `ageAssurance` is
better classified within `/features`. We will probably migrate these things
eventually.
### File and Directory Naming Conventions
Typically JS style for variables, functions, etc. We use ProudCamelCase for
components, and camelCase directories and files.
When organizing new code, consider if it fits into a single file, or if it
should be broken down into multiple files. For "macro" component cases, or
things that live in `/features` or `/screens`, we often follow a pattern of
having an `index.tsx` for the main component, and then co-locating related
components, hooks, and utilities in the same directory. For example:
```
src
├── screens/
│ ├── ProfileScreen/
│ │ ├── index.tsx # Main screen component
│ │ ├── components/ # Sub-components used only by this screen
```
Similar patterns can be found in `/features` and `/components`. The idea here is
to keep related code together and make it easier to navigate.
You should ask yourself: if someone new was looking for the code related to this
feature or screen, where would they expect to find it? Organizing code in a way
that matches developer expectations can make the codebase much more
approachable. Being able to say "Live Now stuff lives in `/features/liveNow`" is
easier to understand than having it scattered across multiple directories.
No need to go overboard with this. If a component or feature fits into a single
file, there's no reason to have a `/Component/index.tsx` file when it could just
be `/Component.tsx`. Use your judgment based on the complexity and amount of
related code.
#### Platform Specific Files
We have conflicting patterns in the app for this. The preferred approach is to
group platform-specific files into a directory as much as possible. For example,
rather than having `Component.tsx`, `Component.web.tsx`, and
`Component.native.tsx` in the same directory, we prefer to have a `Component/`
directory with `index.tsx`, `index.web.tsx`, and `index.native.tsx`. This keeps
related code together and gives us a better visual cue that there are probably
other files contained within this "macro" feature, whereas `Component.tsx` on
its own looks more like a single component file.
### Documentation and Tests Within Features
For larger features or components, it's helpful to include a README.md file
within the directory that explains the purpose of the feature, how it works, and
any important implementation details. The `/Component/index.tsx` pattern lends
itself well to this, since the `index.tsx` can be the main component file, and
the `README.md` can provide documentation for the whole feature. This is
optional, but can be a nice way to keep documentation close to the code it
describes.
Similarly, if there are tests that are specific to a component or feature, it
can be helpful to include them in the same directory, either as
`Component.test.tsx` or in a `__tests__/` subdirectory. This keeps everything
related to the component or feature in one place and makes it easier to find and
maintain tests.
## Styling System (ALF)
ALF is the custom design system. It uses Tailwind-inspired naming with underscores instead of hyphens.
### Basic Usage
```tsx
import {atoms as a, useTheme} from '#/alf'
function MyComponent() {
const t = useTheme()
return (
<View style={[a.flex_row, a.gap_md, a.p_lg, t.atoms.bg]}>
<Text style={[a.text_md, a.font_bold, t.atoms.text]}>
Hello
</Text>
</View>
)
}
```
### Key Concepts
**Static Atoms** - Theme-independent styles imported from `atoms`:
```tsx
import {atoms as a} from '#/alf'
// a.flex_row, a.p_md, a.gap_sm, a.rounded_md, a.text_lg, etc.
```
**Theme Atoms** - Theme-dependent colors from `useTheme()`:
```tsx
const t = useTheme()
// t.atoms.bg, t.atoms.text, t.atoms.border_contrast_low, etc.
// t.palette.primary_500, t.palette.negative_400, etc.
```
**Platform Utilities** - For platform-specific styles:
```tsx
import {web, native, ios, android, platform} from '#/alf'
const styles = [
a.p_md,
web({cursor: 'pointer'}),
native({paddingBottom: 20}),
platform({ios: {...}, android: {...}, web: {...}}),
]
```
**Breakpoints** - Responsive design:
```tsx
import {useBreakpoints} from '#/alf'
const {gtPhone, gtMobile, gtTablet} = useBreakpoints()
if (gtMobile) {
// Tablet or desktop layout
}
```
### Naming Conventions
- Spacing: `2xs`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl` (t-shirt sizes)
- Text: `text_xs`, `text_sm`, `text_md`, `text_lg`, `text_xl`
- Gaps/Padding: `gap_sm`, `p_md`, `px_lg`, `py_xl`
- Flex: `flex_row`, `flex_1`, `align_center`, `justify_between`
- Borders: `border`, `border_t`, `rounded_md`, `rounded_full`
## Component Patterns
### Dialog Component
Dialogs use a bottom sheet on native and a modal on web. Use `useDialogControl()` hook to manage state.
```tsx
import * as Dialog from '#/components/Dialog'
function MyFeature() {
const control = Dialog.useDialogControl()
return (
<>
<Button label="Open" onPress={control.open}>
<ButtonText>Open Dialog</ButtonText>
</Button>
<Dialog.Outer control={control}>
{/* Typically the inner part is in its own component */}
<Dialog.Handle /> {/* Native-only drag handle */}
<Dialog.ScrollableInner label={_(msg`My Dialog`)}>
<Dialog.Header>
<Dialog.HeaderText>Title</Dialog.HeaderText>
</Dialog.Header>
<Text>Dialog content here</Text>
<Button label="Done" onPress={() => control.close()}>
<ButtonText>Done</ButtonText>
</Button>
<Dialog.Close /> {/* Web-only X button in top left */}
</Dialog.ScrollableInner>
</Dialog.Outer>
</>
)
}
```
### Menu Component
Menus render as a dropdown on web and a bottom sheet dialog on native.
```tsx
import * as Menu from '#/components/Menu'
function MyMenu() {
return (
<Menu.Root>
<Menu.Trigger label="Open menu">
{({props}) => (
<Button {...props} label="Menu">
<ButtonIcon icon={DotsHorizontal} />
</Button>
)}
</Menu.Trigger>
<Menu.Outer>
<Menu.Group>
<Menu.Item label="Edit" onPress={handleEdit}>
<Menu.ItemIcon icon={Pencil} />
<Menu.ItemText>Edit</Menu.ItemText>
</Menu.Item>
<Menu.Item label="Delete" onPress={handleDelete}>
<Menu.ItemIcon icon={Trash} />
<Menu.ItemText>Delete</Menu.ItemText>
</Menu.Item>
</Menu.Group>
</Menu.Outer>
</Menu.Root>
)
}
```
### Button Component
```tsx
import {Button, ButtonText, ButtonIcon} from '#/components/Button'
// Solid primary button (most common)
<Button label="Save" onPress={handleSave} color="primary" size="large">
<ButtonText>Save</ButtonText>
</Button>
// With icon
<Button label="Share" onPress={handleShare} color="secondary" size="small">
<ButtonIcon icon={Share} />
<ButtonText>Share</ButtonText>
</Button>
// Icon-only button
<Button label="Close" onPress={handleClose} color="secondary" size="small" shape="round">
<ButtonIcon icon={XIcon} />
</Button>
// Ghost variant (deprecated - use color prop)
<Button label="Cancel" variant="ghost" color="secondary" size="small">
<ButtonText>Cancel</ButtonText>
</Button>
```
**Button Props:**
- `color`: `'primary'` | `'secondary'` | `'negative'` | `'primary_subtle'` | `'negative_subtle'` | `'secondary_inverted'`
- `size`: `'tiny'` | `'small'` | `'large'`
- `shape`: `'default'` (pill) | `'round'` | `'square'` | `'rectangular'`
- `variant`: `'solid'` | `'outline'` | `'ghost'` (deprecated, use `color`)
### Typography
```tsx
import {Text, H1, H2, P} from '#/components/Typography'
<H1 style={[a.text_xl, a.font_bold]}>Heading</H1>
<P>Paragraph text with default styling.</P>
<Text style={[a.text_sm, t.atoms.text_contrast_medium]}>Custom text</Text>
// For text with emoji, add the emoji prop
<Text emoji>Hello! 👋</Text>
```
### TextField
```tsx
import * as TextField from '#/components/forms/TextField'
<TextField.LabelText>Email</TextField.LabelText>
<TextField.Root>
<TextField.Icon icon={AtSign} />
<TextField.Input
label="Email address"
placeholder="you@example.com"
defaultValue={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
</TextField.Root>
```
## Internationalization (i18n)
All user-facing strings must be wrapped for translation using Lingui.
```tsx
import {msg, plural} from '@lingui/core/macro'
import {Trans} from '@lingui/react/macro'
import {useLingui} from '@lingui/react'
function MyComponent() {
const {_} = useLingui()
// Simple strings - use msg() with _() function
const title = _(msg`Settings`)
const errorMessage = _(msg`Something went wrong`)
// Strings with variables
const greeting = _(msg`Hello, ${name}!`)
// Pluralization
const countLabel = _(plural(count, {
one: '# item',
other: '# items',
}))
// JSX content - use Trans component
return (
<Text>
<Trans>Welcome to <Text style={a.font_bold}>Bluesky</Text></Trans>
</Text>
)
}
```
**Commands:**
```bash
# DO NOT run these commands - extraction and compilation are handled by a nightly CI job
yarn intl:extract # Extract new strings to locale files
yarn intl:compile # Compile translations for runtime
```
## State Management
### TanStack Query (Data Fetching)
```tsx
// src/state/queries/profile.ts
import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query'
// Query key pattern
const RQKEY_ROOT = 'profile'
export const RQKEY = (did: string) => [RQKEY_ROOT, did]
// Query hook
export function useProfileQuery({did}: {did: string}) {
const agent = useAgent()
return useQuery({
queryKey: RQKEY(did),
queryFn: async () => {
const res = await agent.getProfile({actor: did})
return res.data
},
staleTime: STALE.MINUTES.FIVE,
enabled: !!did,
})
}
// Mutation hook
export function useUpdateProfile() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (data) => {
// Update logic
},
onSuccess: (_, variables) => {
queryClient.invalidateQueries({queryKey: RQKEY(variables.did)})
},
onError: (error) => {
if (isNetworkError(error)) {
// don't log, but inform user
} else if (error instanceof AppBskyExampleProcedure.ExampleError) {
// XRPC APIs often have typed errors, allows nicer handling
} else {
// Log unexpected errors to Sentry
logger.error('Error updating profile', {safeMessage: error})
}
}
})
}
```
**Stale Time Constants** (from `src/state/queries/index.ts`):
```tsx
STALE.SECONDS.FIFTEEN // 15 seconds
STALE.MINUTES.ONE // 1 minute
STALE.MINUTES.FIVE // 5 minutes
STALE.HOURS.ONE // 1 hour
STALE.INFINITY // Never stale
```
**Paginated APIs:** Many atproto APIs return paginated results with a `cursor`. Use `useInfiniteQuery` for these:
```tsx
export function useDraftsQuery() {
const agent = useAgent()
return useInfiniteQuery({
queryKey: ['drafts'],
queryFn: async ({pageParam}) => {
const res = await agent.app.bsky.draft.getDrafts({cursor: pageParam})
return res.data
},
initialPageParam: undefined as string | undefined,
getNextPageParam: page => page.cursor,
})
}
```
To get all items from pages: `data?.pages.flatMap(page => page.items) ?? []`
### Preferences (React Context)
```tsx
// Simple boolean preference pattern
import {useAutoplayDisabled, useSetAutoplayDisabled} from '#/state/preferences'
function SettingsScreen() {
const autoplayDisabled = useAutoplayDisabled()
const setAutoplayDisabled = useSetAutoplayDisabled()
return (
<Toggle
value={autoplayDisabled}
onValueChange={setAutoplayDisabled}
/>
)
}
```
### Session State
```tsx
import {useSession, useAgent} from '#/state/session'
function MyComponent() {
const {hasSession, currentAccount} = useSession()
const agent = useAgent()
if (!hasSession) {
return <LoginPrompt />
}
// Use agent for API calls
const response = await agent.getProfile({actor: currentAccount.did})
}
```
## Navigation
Navigation uses React Navigation with type-safe route parameters.
```tsx
// Screen component
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
import {type CommonNavigatorParams} from '#/lib/routes/types'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
export function ProfileScreen({route, navigation}: Props) {
const {name} = route.params // Type-safe params
return (
<Layout.Screen>
{/* Screen content */}
</Layout.Screen>
)
}
// Programmatic navigation
import {useNavigation} from '@react-navigation/native'
const navigation = useNavigation()
navigation.navigate('Profile', {name: 'alice.bsky.social'})
// Or use the navigate helper
import {navigate} from '#/Navigation'
navigate('Profile', {name: 'alice.bsky.social'})
```
## Platform-Specific Code
Use file extensions for platform-specific implementations:
```
Component.tsx # Shared/default
Component.web.tsx # Web-only
Component.native.tsx # iOS + Android
Component.ios.tsx # iOS-only
Component.android.tsx # Android-only
```
Example from Dialog:
- `src/components/Dialog/index.tsx` - Native (uses BottomSheet)
- `src/components/Dialog/index.web.tsx` - Web (uses modal with Radix primitives)
**Important:** The bundler automatically resolves platform-specific files. Just import normally:
```tsx
// CORRECT - bundler picks storage.ts or storage.web.ts automatically
import * as storage from '#/state/drafts/storage'
// WRONG - don't use require() or conditional imports for platform files
const storage = IS_NATIVE
? require('#/state/drafts/storage')
: require('#/state/drafts/storage.web')
```
Platform detection (for runtime logic, not imports):
```tsx
import {IS_WEB, IS_NATIVE, IS_IOS, IS_ANDROID} from '#/env'
if (IS_NATIVE) {
// Native-specific logic
}
```
## Import Aliases
Always use the `#/` alias for absolute imports:
```tsx
// Good
import {useSession} from '#/state/session'
import {atoms as a, useTheme} from '#/alf'
import {Button} from '#/components/Button'
// Avoid
import {useSession} from '../../../state/session'
```
## Footguns
Common pitfalls to avoid in this codebase:
### Dialog Close Callback (Critical)
**Always use `control.close(() => ...)` when performing actions after closing a dialog.** The callback ensures the action runs after the dialog's close animation completes. Failing to do this causes race conditions with React state updates.
```tsx
// WRONG - causes bugs with state updates, navigation, opening other dialogs
const onConfirm = () => {
control.close()
navigation.navigate('Home') // May race with dialog animation
}
// WRONG - same problem
const onConfirm = () => {
control.close()
otherDialogControl.open() // Will likely fail or cause visual glitches
}
// CORRECT - action runs after dialog fully closes
const onConfirm = () => {
control.close(() => {
navigation.navigate('Home')
})
}
// CORRECT - opening another dialog after close
const onConfirm = () => {
control.close(() => {
otherDialogControl.open()
})
}
// CORRECT - state updates after close
const onConfirm = () => {
control.close(() => {
setSomeState(newValue)
onCallback?.()
})
}
```
This applies to:
- Navigation (`navigation.navigate()`, `navigation.push()`)
- Opening other dialogs or menus
- State updates that affect UI (`setState`, `queryClient.invalidateQueries`)
- Callbacks passed from parent components
The Menu component on iOS specifically uses this pattern - see `src/components/Menu/index.tsx:151`.
### Controlled vs Uncontrolled Inputs
Prefer `defaultValue` over `value` for TextInput on the old architecture:
```tsx
// Preferred - uncontrolled
<TextField.Input
defaultValue={initialEmail}
onChangeText={setEmail}
/>
// Avoid when possible - controlled (can cause performance issues)
<TextField.Input
value={email}
onChangeText={setEmail}
/>
```
### Platform-Specific Behavior
Some components behave differently across platforms:
- `Dialog.Handle` - Only renders on native (drag handle for bottom sheet)
- `Dialog.Close` - Only renders on web (X button)
- `Menu.Divider` - Only renders on web
- `Menu.ContainerItem` - Only works on native
Always test on multiple platforms when using these components.
### React Compiler is Enabled
This codebase uses React Compiler, so **don't proactively add `useMemo` or `useCallback`**. The compiler handles memoization automatically.
```tsx
// UNNECESSARY - React Compiler handles this
const handlePress = useCallback(() => {
doSomething()
}, [doSomething])
// JUST WRITE THIS
const handlePress = () => {
doSomething()
}
```
Only use `useMemo`/`useCallback` when you have a specific reason, such as:
- The value is immediately used in an effect's dependency array
- You're passing a callback to a non-React library that needs referential stability
## Best Practices
1. **Accessibility**: Always provide `label` prop for interactive elements, use `accessibilityHint` where helpful
2. **Translations**: Wrap ALL user-facing strings with `msg()` or `<Trans>`
3. **Styling**: Combine static atoms with theme atoms, use platform utilities for platform-specific styles
4. **State**: Use TanStack Query for server state, React Context for UI preferences
5. **Components**: Check if a component exists in `#/components/` before creating new ones
6. **Types**: Define explicit types for props, use `NativeStackScreenProps` for screens
7. **Testing**: Components should have `testID` props for E2E testing
## Key Files Reference
| Purpose | Location |
|---------|----------|
| Theme definitions | `src/alf/themes.ts` |
| Design tokens | `src/alf/tokens.ts` |
| Static atoms | `src/alf/atoms.ts` (extends `@bsky.app/alf`) |
| Navigation config | `src/Navigation.tsx` |
| Route definitions | `src/routes.ts` |
| Route types | `src/lib/routes/types.ts` |
| Query hooks | `src/state/queries/*.ts` |
| Session state | `src/state/session/index.tsx` |
| i18n setup | `src/locale/i18n.ts` |
+18 -15
View File
@@ -1,4 +1,4 @@
FROM golang:1.23-bullseye AS build-env
FROM golang:1.25-bookworm AS build-env
WORKDIR /usr/src/social-app
@@ -19,28 +19,28 @@ ENV GOARCH="amd64"
ENV CGO_ENABLED=1
ENV GOEXPERIMENT="loopvar"
# The latest git hash of the preview branch on render.com
# https://render.com/docs/docker-secrets#environment-variables-in-docker-builds
ARG RENDER_GIT_COMMIT
#
# Expo
#
ARG EXPO_PUBLIC_ENV
ENV EXPO_PUBLIC_ENV=${EXPO_PUBLIC_ENV:-development}
ARG EXPO_PUBLIC_RELEASE_VERSION
ENV EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION
ARG EXPO_PUBLIC_BUNDLE_IDENTIFIER
ENV EXPO_PUBLIC_BUNDLE_IDENTIFIER=${EXPO_PUBLIC_BUNDLE_IDENTIFIER:-dev}
# The latest git hash of the preview branch on render.com
ARG RENDER_GIT_COMMIT
# If not set by GitHub workflows, we're probably in Render
ENV EXPO_PUBLIC_BUNDLE_IDENTIFIER=${EXPO_PUBLIC_BUNDLE_IDENTIFIER:-$RENDER_GIT_COMMIT}
#
# Sentry
#
ARG SENTRY_AUTH_TOKEN
ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN:-unknown}
# Will fall back to package.json#version, but this is handled elsewhere
ARG SENTRY_RELEASE
ENV SENTRY_RELEASE=$SENTRY_RELEASE
ARG SENTRY_DIST
# Default to RENDER_GIT_COMMIT if not set by GitHub workflows
ENV SENTRY_DIST=${SENTRY_DIST:-$RENDER_GIT_COMMIT}
ARG SENTRY_DSN
ENV SENTRY_DSN=$SENTRY_DSN
ARG EXPO_PUBLIC_SENTRY_DSN
ENV EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN
#
# Copy everything into the container
@@ -60,13 +60,16 @@ RUN \. "$NVM_DIR/nvm.sh" && \
nvm install $NODE_VERSION && \
nvm use $NODE_VERSION && \
echo "Using bundle identifier: $EXPO_PUBLIC_BUNDLE_IDENTIFIER" && \
echo "EXPO_PUBLIC_ENV=$EXPO_PUBLIC_ENV" >> .env && \
echo "EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION" >> .env && \
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER" >> .env && \
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env && \
echo "EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN" >> .env && \
npm install --global yarn && \
yarn && \
yarn intl:build 2>&1 | tee i18n.log && \
if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compile errors!\n\n"; fi && \
EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER EXPO_PUBLIC_BUNDLE_DATE=$() SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$SENTRY_RELEASE SENTRY_DIST=$SENTRY_DIST SENTRY_DSN=$SENTRY_DSN yarn build-web
SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$EXPO_PUBLIC_RELEASE_VERSION SENTRY_DIST=$EXPO_PUBLIC_BUNDLE_IDENTIFIER yarn build-web
# DEBUG
RUN find ./bskyweb/static && find ./web-build/static
@@ -86,7 +89,7 @@ RUN cd bskyweb/ && \
-o /bskyweb \
./cmd/bskyweb
FROM debian:bullseye-slim
FROM debian:bookworm-slim
ENV GODEBUG=netdns=go
ENV TZ=Etc/UTC
+2 -1
View File
@@ -26,8 +26,9 @@ COPY --from=build /app /app
RUN mkdir /app/data && chown node /app/data
VOLUME /app/data
EXPOSE 3000
EXPOSE 3000 3001
ENV CARD_PORT=3000
ENV CARD_METRICS_PORT=3001
ENV NODE_ENV=production
# potential perf issues w/ io_uring on this version of node
ENV UV_USE_IO_URING=0
+2 -2
View File
@@ -1,4 +1,4 @@
FROM golang:1.23-bullseye AS build-env
FROM golang:1.25-bookworm AS build-env
WORKDIR /usr/src/social-app
@@ -58,7 +58,7 @@ RUN cd bskyweb/ && \
-o /embedr \
./cmd/embedr
FROM debian:bullseye-slim
FROM debian:bookworm-slim
ENV GODEBUG=netdns=go
ENV TZ=Etc/UTC
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright 20232025 Bluesky Social PBC
Copyright 20232026 Bluesky Social PBC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+6 -3
View File
@@ -10,7 +10,7 @@ Get the app itself:
## Development Resources
This is a [React Native](https://reactnative.dev/) application, written in the TypeScript programming language. It builds on the `atproto` TypeScript packages (like [`@atproto/api`](https://www.npmjs.com/package/@atproto/api)), code for which is also open source, but in [a different git repository](https://github.com/bluesky-social/atproto).
This is a [React Native](https://reactnative.dev/) application, written in the TypeScript programming language. It builds on the `atproto` TypeScript packages (like [`@atproto/api`](https://www.npmjs.com/package/@atproto/api)), which are also open source, but in [a different git repository](https://github.com/bluesky-social/atproto).
There is a small amount of Go language source code (in `./bskyweb/`), for a web service that returns the React Native Web application.
@@ -19,7 +19,7 @@ The [Build Instructions](./docs/build.md) are a good place to get started with t
The Authenticated Transfer Protocol ("AT Protocol" or "atproto") is a decentralized social media protocol. You don't *need* to understand AT Protocol to work with this application, but it can help. Learn more at:
- [Overview and Guides](https://atproto.com/guides/overview)
- [Github Discussions](https://github.com/bluesky-social/atproto/discussions) 👈 Great place to ask questions
- [GitHub Discussions](https://github.com/bluesky-social/atproto/discussions) 👈 Great place to ask questions
- [Protocol Specifications](https://atproto.com/specs/atp)
- [Blogpost on self-authenticating data structures](https://bsky.social/about/blog/3-6-2022-a-self-authenticating-social-protocol)
@@ -27,6 +27,7 @@ The Bluesky Social application encompasses a set of schemas and APIs built in th
## Contributions
> [!NOTE]
> While we do accept contributions, we prioritize high quality issues and pull requests. Adhering to the below guidelines will ensure a more timely review.
**Rules:**
@@ -59,7 +60,7 @@ Please be sure to:
## Security disclosures
If you discover any security issues, please send an email to security@bsky.app. The email is automatically CCed to the entire team and we'll respond promptly.
If you discover any security issues, please send an email to security@bsky.app. The email is automatically CC'd to the entire team and we'll respond promptly.
## Are you a developer interested in building on atproto?
@@ -69,6 +70,8 @@ Bluesky is an open social network built on the AT Protocol, a flexible technolog
See [./LICENSE](./LICENSE) for the full license.
Bluesky Social PBC has committed to a software patent non-aggression pledge. For details see [the original announcement](https://bsky.social/about/blog/10-01-2025-patent-pledge).
## P.S.
We ❤️ you and all of the ways you support us. Thank you for making Bluesky a great place!
+9 -3
View File
@@ -3,20 +3,26 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: ?users
SERVER_PATH: ?users
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
# Post an image with the porn label
- assertVisible:
id: "composeFAB"
id: "composeFAB"
- tapOn:
id: "composeFAB"
- inputText: "Post with an image"
- tapOn:
id: "openGalleryBtn"
id: "openMediaBtn"
- extendedWaitUntil:
visible:
id: "selectedPhotosView"
- tapOn: "Content warnings"
- tapOn: "Porn"
- tapOn:
+18 -5
View File
@@ -3,13 +3,17 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: ?users
SERVER_PATH: ?users
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- assertVisible:
id: "composeFAB"
id: "composeFAB"
- tapOn:
id: "composeFAB"
- inputText: "Post text only"
@@ -21,7 +25,10 @@ appId: xyz.blueskyweb.app
id: "composeFAB"
- inputText: "Post with an image"
- tapOn:
id: "openGalleryBtn"
id: "openMediaBtn"
- extendedWaitUntil:
visible:
id: "selectedPhotosView"
- tapOn:
id: "composerPublishBtn"
- assertVisible:
@@ -46,7 +53,10 @@ appId: xyz.blueskyweb.app
id: "replyBtn"
- inputText: "Reply with an image"
- tapOn:
id: "openGalleryBtn"
id: "openMediaBtn"
- extendedWaitUntil:
visible:
id: "selectedPhotosView"
- tapOn:
id: "composerPublishBtn"
- assertVisible:
@@ -73,7 +83,10 @@ appId: xyz.blueskyweb.app
id: "quoteBtn"
- inputText: "QP with an image"
- tapOn:
id: "openGalleryBtn"
id: "openMediaBtn"
- extendedWaitUntil:
visible:
id: "selectedPhotosView"
- tapOn:
id: "composerPublishBtn"
- assertVisible:
+18 -4
View File
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: ""
SERVER_PATH: ""
- runFlow:
file: ../setupApp.yml
- tapOn:
@@ -25,11 +25,25 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "passwordInput"
- inputText: "hunter22"
- hideKeyboard
- tapOn:
# hideKeyboard on ios is borked
# https://docs.maestro.dev/troubleshooting/known-issues#hidekeyboard-command-is-flaky
text: "Your account"
- tapOn:
id: "nextBtn"
- tapOn: "Not now"
- waitForAnimationToEnd
- tapOn:
# save password thing no longer seems to be in hierarchy
# tap on something else instead
point: 20%,20%
repeat: 2
delay: 1000
- tapOn:
id: "handleInput"
- inputText: "e2e-test"
- extendedWaitUntil:
visible:
id: "handleAvailableCheck"
- tapOn:
id: "nextBtn"
- assertVisible: "Give your profile a face"
+27 -40
View File
@@ -3,95 +3,82 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users&follows&posts"
SERVER_PATH: "?users&follows&posts"
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
label: "Create a curate list"
id: "e2eGotoLists"
- tapOn:
id: "newUserListBtn"
- assertVisible:
id: "createOrEditListModal"
- waitForAnimationToEnd
- assertVisible: "Create user list"
- tapOn:
id: "editNameInput"
id: "editListNameInput"
- inputText: "Good Ppl"
- tapOn:
id: "editDescriptionInput"
id: "editListDescriptionInput"
- inputText: "They good"
- tapOn: "Save"
- tapOn: "Save"
- assertNotVisible:
id: "createOrEditListModal"
- assertNotVisible: "Create user list"
- tapOn: "People"
- assertVisible: "Good Ppl"
- assertVisible: "They good"
- tapOn:
label: "Edit display name and description via the edit curatelist modal"
point: "90%,9%"
id: "moreOptionsBtn"
- tapOn: "Edit list details"
- assertVisible:
id: "createOrEditListModal"
- assertVisible: "Edit user list"
- tapOn:
id: "editNameInput"
id: "editListNameInput"
- eraseText
- inputText: "Bad Ppl"
- hideKeyboard
- tapOn:
id: "editDescriptionInput"
id: "editListDescriptionInput"
- eraseText
- inputText: "They bad"
- tapOn: "Save"
- tapOn: "Save"
- assertNotVisible:
id: "createOrEditListModal"
- assertNotVisible: "Edit user list"
- assertVisible: Bad Ppl
- assertVisible: They bad
- tapOn:
label: "Remove description via the edit curatelist modal"
point: "90%,9%"
id: "moreOptionsBtn"
- tapOn: "Edit list details"
- assertVisible:
id: "createOrEditListModal"
- assertVisible: "Edit user list"
- tapOn:
id: "editDescriptionInput"
id: "editListDescriptionInput"
- eraseText
- tapOn: "Save"
- tapOn: "Save"
- assertNotVisible:
id: "createOrEditListModal"
- assertNotVisible: "Edit user list"
- assertNotVisible:
id: "listDescription"
- tapOn:
label: "Delete the curatelist"
point: "90%,9%"
id: "moreOptionsBtn"
- tapOn: "Delete List"
- tapOn:
id: "confirmBtn"
- tapOn:
label: "Create a new curatelist"
id: "e2eGotoLists"
- assertVisible:
id: "newUserListBtn"
- tapOn:
id: "newUserListBtn"
- assertVisible:
id: "createOrEditListModal"
- assertVisible: "Create user list"
- tapOn:
id: "editNameInput"
id: "editListNameInput"
- inputText: "Good Ppl"
- tapOn:
id: "editDescriptionInput"
id: "editListDescriptionInput"
- inputText: "They good"
- tapOn: "Save"
- tapOn: "Save"
- assertNotVisible:
id: "createOrEditListModal"
- assertNotVisible: "Create user list"
- tapOn: "People"
- assertVisible: "Good Ppl"
- assertVisible: "They good"
@@ -135,7 +122,7 @@ appId: xyz.blueskyweb.app
id: "e2eGotoLists"
- tapOn: "Good Ppl"
# - tapOn: "People"
- tapOn: "People"
- assertVisible: "View Bob's profile"
- tapOn:
point: "90%,43%"
@@ -146,7 +133,7 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "bottomBarSearchBtn"
- tapOn: "Search for posts, users, or feeds"
- tapOn: "Search for posts, users[,]? or feeds"
- inputText: "bob"
- tapOn:
id: "searchAutoCompleteResult-bob.test"
+12 -6
View File
@@ -35,9 +35,12 @@ appId: xyz.blueskyweb.app
id: "menuItemButton-Feeds"
- tapOn:
id: "editFeedsBtn"
- tapOn:
label: "Tap on down arrow"
id: "feed-timeline-moveDown"
- swipe:
label: "Drag feed down"
from:
id: "feed-drag-handle"
direction: "DOWN"
duration: 1000
- tapOn:
label: "Save button"
id: "saveChangesBtn"
@@ -55,9 +58,12 @@ appId: xyz.blueskyweb.app
id: "menuItemButton-Feeds"
- tapOn:
id: "editFeedsBtn"
- tapOn:
label: "Tap on down arrow"
id: "feed-feed-moveDown"
- swipe:
label: "Drag feed down"
from:
id: "feed-drag-handle"
direction: "DOWN"
duration: 1000
- tapOn:
label: "Save button"
id: "saveChangesBtn"
+3 -3
View File
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: ?users&follows&posts&feeds
SERVER_PATH: ?users&follows&posts&feeds
- runFlow:
file: ../setupApp.yml
- tapOn:
@@ -11,7 +11,7 @@ appId: xyz.blueskyweb.app
- extendedWaitUntil:
visible:
text: "Feeds ✨"
text: "Feeds ✨"
- tapOn:
label: "Can go to feeds page using feeds button in tab bar"
text: "Feeds ✨"
@@ -50,6 +50,6 @@ appId: xyz.blueskyweb.app
label: "Can delete posts"
id: "postDropdownBtn"
childOf:
id: "feedItem-by-alice.test"
id: "feedItem-by-alice.test"
- tapOn: "Delete post"
- tapOn: "Delete"
+8 -1
View File
@@ -15,6 +15,11 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "customServerTextInput"
- inputText: "http://localhost:3000"
- runFlow:
when:
platform: Android
commands:
- hideKeyboard
- tapOn: "Done"
- tapOn:
id: "loginUsernameInput"
@@ -23,5 +28,7 @@ appId: xyz.blueskyweb.app
id: "loginPasswordInput"
- inputText: "hunter2"
- pressKey: Enter
- tapOn: "Not now"
- tapOn:
text: "Not Now"
optional: true
- assertVisible: "Following"
+9 -13
View File
@@ -3,11 +3,14 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users&follows&labels"
SERVER_PATH: "?users&follows&labels"
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
# create a modlist
- tapOn:
@@ -16,32 +19,25 @@ appId: xyz.blueskyweb.app
id: "moderationlistsBtn"
- tapOn: "New list"
- tapOn:
id: "editNameInput"
id: "editListNameInput"
- inputText: "Muted Users"
- tapOn:
id: "editDescriptionInput"
id: "editListDescriptionInput"
- inputText: "Shhh"
- tapOn: "Save"
- tapOn: "Save"
# view modlist
- assertVisible: "Muted Users"
- assertVisible: "Shhh"
- tapOn:
label: "Dropdown"
point: "71%,9%"
- tapOn: "Subscribe to this list"
- tapOn: "Mute accounts"
- tapOn: "Mute list"
- tapOn: "Unmute"
- tapOn:
label: "Dropdown"
point: "71%,9%"
- tapOn: "Subscribe to this list"
- tapOn: "Block accounts"
- tapOn: "Block list"
- tapOn: "Unblock"
# the rest of the behaviors are tested in curate-lists.yml
# the rest of the behaviors are tested in curate-lists.yml
+23 -7
View File
@@ -3,11 +3,15 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users"
SERVER_PATH: "?users"
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "e2eStartOnboarding"
- tapOn: "Open avatar creator"
@@ -21,12 +25,24 @@ appId: xyz.blueskyweb.app
- tapOn: "Select the atom emoji as your avatar"
- tapOn: "Done"
- waitForAnimationToEnd
- tapOn: "Continue to next step"
- tapOn:
id: "onboardingContinue"
- assertVisible: "What are your interests?"
- tapOn:
label: "Tap on continue"
point: "50%,92%"
- assertVisible: "You're ready to go!"
id: "onboardingContinue"
- assertVisible: "Suggested for you"
# mock server doesn't have suggestions api
- tapOn: "Skip to next step"
- swipe:
direction: "LEFT"
- swipe:
direction: "LEFT"
- assertVisible: "Complete onboarding and start using your account"
- tapOn:
label: "Tap on Lets go"
point: "50%,92%"
id: "onboardingFinish"
- tapOn:
label: "NUX, if applicable"
text: "Close"
optional: true
- waitForAnimationToEnd
- assertVisible: "Following"
+25 -8
View File
@@ -3,27 +3,44 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users"
SERVER_PATH: "?users"
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "e2eStartOnboarding"
- tapOn: "Select an avatar"
- waitForAnimationToEnd
- assertVisible: "Search your library…"
- assertVisible: "Photos"
- assertVisible: "Collections"
- tapOn:
point: "50%,22%"
- waitForAnimationToEnd
- tapOn: "Done"
- waitForAnimationToEnd
- tapOn: "Continue to next step"
- tapOn:
id: "onboardingContinue"
- assertVisible: "What are your interests?"
- tapOn:
label: "Tap on continue"
point: "50%,92%"
- assertVisible: "You're ready to go!"
id: "onboardingContinue"
- assertVisible: "Suggested for you"
# mock server doesn't have suggestions api
- tapOn: "Skip to next step"
- swipe:
direction: "LEFT"
- swipe:
direction: "LEFT"
- assertVisible: "Complete onboarding and start using your account"
- tapOn:
label: "Tap on Lets go"
point: "50%,92%"
id: "onboardingFinish"
- tapOn:
label: "NUX, if applicable"
text: "Close"
optional: true
- waitForAnimationToEnd
- assertVisible: "Following"
+6 -2
View File
@@ -3,18 +3,22 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users&follows&posts"
SERVER_PATH: "?users&follows&posts"
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "postDropdownBtn"
index: 0
- tapOn:
id: "postDropdownReportBtn"
- tapOn: "Create report for Misleading Post"
- tapOn: "Create report for Misleading"
- tapOn: "Create report for Spam"
- tapOn: "Send report to Dev-env Moderation"
- tapOn:
point: "50%,90%"
+6 -4
View File
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users&posts&feeds"
SERVER_PATH: "?users&posts&feeds"
- runFlow:
file: ../setupApp.yml
- tapOn:
@@ -12,10 +12,10 @@ appId: xyz.blueskyweb.app
# Navigate to another user profile
- extendedWaitUntil:
visible:
id: "bottomBarSearchBtn"
id: "bottomBarSearchBtn"
- tapOn:
id: "bottomBarSearchBtn"
- tapOn: "Search for posts, users, or feeds"
- tapOn: "Search for posts, users[,]? or feeds"
- inputText: "b"
- tapOn:
id: "searchAutoCompleteResult-bob.test"
@@ -25,6 +25,8 @@ appId: xyz.blueskyweb.app
# Can follow/unfollow another user
- tapOn:
id: "followBtn"
- tapOn:
point: 65%,35% # dismiss the subscribe prompt
- tapOn:
id: "unfollowBtn"
@@ -36,4 +38,4 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "profileHeaderDropdownBtn"
- tapOn: "Unmute Account"
- assertNotVisible: "Account Muted"
- assertNotVisible: "Account Muted"
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../../setupServer.js
env:
SERVER_PATH: ?users&follows&posts&feeds
SERVER_PATH: ?users&follows&posts&feeds
- runFlow:
file: ../../setupApp.yml
- tapOn:
@@ -15,9 +15,11 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "profileHeaderDropdownReportBtn"
- tapOn:
id: "report:option:com.atproto.moderation.defs#reasonSpam"
id: "report:category:Misleading"
- tapOn:
id: "report:option:Spam"
- assertVisible:
id: "report:labeler:mod-authority.test"
text: "Send report to Dev-env Moderation"
- tapOn:
id: "report:submit"
- assertNotVisible:
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../../setupServer.js
env:
SERVER_PATH: ?users&follows&posts&feeds
SERVER_PATH: ?users&follows&posts&feeds
- runFlow:
file: ../../setupApp.yml
- tapOn:
@@ -15,9 +15,11 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "postDropdownReportBtn"
- tapOn:
id: "report:option:com.atproto.moderation.defs#reasonSpam"
id: "report:category:Misleading"
- tapOn:
id: "report:option:Spam"
- assertVisible:
id: "report:labeler:mod-authority.test"
text: "Send report to Dev-env Moderation"
- tapOn:
id: "report:submit"
- assertNotVisible:
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../../setupServer.js
env:
SERVER_PATH: ?users&follows&posts&feeds
SERVER_PATH: ?users&follows&posts&feeds
- runFlow:
file: ../../setupApp.yml
- tapOn:
@@ -15,20 +15,28 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "postDropdownReportBtn"
- tapOn:
id: "report:option:com.atproto.moderation.defs#reasonOther"
id: "report:category:Misleading"
- tapOn:
id: "report:option:Other misleading content"
- assertVisible:
id: "report:labeler:mod-authority.test"
text: Your report will be sent to Dev-env Moderation.*
# reason "other" defaults with details open
- assertVisible:
id: "report:details"
- tapOn:
id: "report:clearOption"
id: "report:clearReportOption"
- assertNotVisible:
id: "report:details"
- tapOn:
id: "report:option:com.atproto.moderation.defs#reasonSpam"
id: "report:clearCategory"
- assertNotVisible:
id: "report:option:Other misleading content"
- tapOn:
id: "report:category:Misleading"
- tapOn:
id: "report:option:Spam"
- assertVisible:
id: "report:labeler:mod-authority.test"
text: Your report will be sent to Dev-env Moderation.*
- tapOn:
id: "report:submit"
- assertNotVisible:
@@ -3,7 +3,7 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../../setupServer.js
env:
SERVER_PATH: ?users&follows&posts&feeds
SERVER_PATH: ?users&follows&posts&feeds
- runFlow:
file: ../../setupApp.yml
- tapOn:
@@ -15,15 +15,18 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "postDropdownReportBtn"
- tapOn:
id: "report:option:com.atproto.moderation.defs#reasonOther"
id: "report:category:Misleading"
- tapOn:
id: "report:option:Other misleading content"
- assertVisible:
id: "report:labeler:mod-authority.test"
text: "Send report to Dev-env Moderation"
# reason "other" defaults with details open
- assertVisible:
id: "report:details"
- tapOn:
id: "report:details"
- inputText: "This is a test report"
- hideKeyboard
- tapOn:
id: "report:submit"
- assertNotVisible:
+6 -4
View File
@@ -3,20 +3,22 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users"
SERVER_PATH: "?users"
- runFlow:
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
# Navigate to another user profile via autocomplete
- extendedWaitUntil:
visible:
id: "bottomBarSearchBtn"
- tapOn:
id: "bottomBarSearchBtn"
- assertVisible: "Search for posts, users, or feeds"
- tapOn: "Search for posts, users, or feeds"
- assertVisible: "Search for posts, users[,]? or feeds"
- tapOn: "Search for posts, users[,]? or feeds"
- inputText: "b"
- tapOn:
id: "searchAutoCompleteResult-bob.test"
- assertVisible:
id: "profileView"
+5 -1
View File
@@ -8,8 +8,12 @@ appId: xyz.blueskyweb.app
file: ../setupApp.yml
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- assertVisible:
id: "storybookBtn"
id: "storybookBtn"
- tapOn:
id: "storybookBtn"
- tapOn:
+38 -9
View File
@@ -3,13 +3,16 @@ appId: xyz.blueskyweb.app
- runScript:
file: ../setupServer.js
env:
SERVER_PATH: "?users&follows"
SERVER_PATH: "?users&follows"
- runFlow:
file: ../setupApp.yml
# Login, create a thread, and log out
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- assertVisible:
id: "composeFAB"
- tapOn:
@@ -19,8 +22,13 @@ appId: xyz.blueskyweb.app
id: "composerPublishBtn"
# Login, reply to the thread, and log out
- tapOn:
id: "e2eSignOut"
- tapOn:
id: "e2eSignInBob"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "replyBtn"
- inputText: "Reply 1"
@@ -28,8 +36,13 @@ appId: xyz.blueskyweb.app
id: "composerPublishBtn"
# Login, confirm notification exists, mute thread, and log out
- tapOn:
id: "e2eSignOut"
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "bottomBarNotificationsBtn"
- assertVisible:
@@ -39,12 +52,17 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "postDropdownBtn"
childOf:
id: "postThreadItem-by-bob.test"
id: "postThreadItem-by-bob.test"
- tapOn: "Mute thread"
# Login, reply to the thread twice, and log out
- tapOn:
id: "e2eSignOut"
- tapOn:
id: "e2eSignInBob"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "bottomBarProfileBtn"
- tapOn:
@@ -60,24 +78,35 @@ appId: xyz.blueskyweb.app
- tapOn:
id: "composerPublishBtn"
# Login, confirm notifications dont exist, unmute the thread, confirm notifications exist
# Login, confirm notifications dont exist, unmute the thread, ~~confirm notifications exist~~
# Mute thread behaviour no longer change old notifications after muting/unmuting a thread -sfn
- tapOn:
id: "e2eSignOut"
- tapOn:
id: "e2eSignInAlice"
- extendedWaitUntil:
visible:
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "bottomBarNotificationsBtn"
- assertNotVisible:
- assertVisible: ".*Reply 1.*"
- assertNotVisible: ".*Reply 2.*"
- assertNotVisible: ".*Reply 3.*"
- assertVisible:
id: "feedItem-by-bob.test"
- tapOn:
id: "bottomBarHomeBtn"
id: "feedItem-by-bob.test"
- tapOn:
id: "postDropdownBtn"
childOf:
id: "postThreadItem-by-bob.test"
- tapOn: "Unmute thread"
- tapOn:
id: "bottomBarNotificationsBtn"
- swipe:
from:
id: "notifsFeed"
id: "notifsFeed"
direction: DOWN
- assertVisible:
id: "feedItem-by-bob.test"
- assertVisible: ".*Reply 1.*"
- assertNotVisible: ".*Reply 2.*"
- assertNotVisible: ".*Reply 3.*"
-520
View File
@@ -1,520 +0,0 @@
import {createServer as createHTTPServer} from 'node:http'
import {parse} from 'node:url'
import {createServer, TestPDS} from '../jest/test-pds'
async function main() {
let server: TestPDS
createHTTPServer(async (req, res) => {
const url = parse(req.url || '/', true)
if (req.method !== 'POST') {
return res.writeHead(200).end()
}
try {
console.log('Closing old server')
await server?.close()
console.log('Starting new server')
const inviteRequired = url?.query && 'invite' in url.query
server = await createServer({inviteRequired})
console.log('Listening at', server.pdsUrl)
if (url?.query) {
if ('users' in url.query) {
console.log('Generating mock users')
await server.mocker.createUser('alice')
await server.mocker.createUser('bob')
await server.mocker.createUser('carla')
await server.mocker.users.alice.agent.upsertProfile(() => ({
displayName: 'Alice',
description: 'Test user 1',
}))
await server.mocker.users.bob.agent.upsertProfile(() => ({
displayName: 'Bob',
description: 'Test user 2',
}))
await server.mocker.users.carla.agent.upsertProfile(() => ({
displayName: 'Carla',
description: 'Test user 3',
}))
if (inviteRequired) {
await server.mocker.createInvite(server.mocker.users.alice.did)
}
}
if ('follows' in url.query) {
console.log('Generating mock follows')
await server.mocker.follow('alice', 'bob')
await server.mocker.follow('alice', 'carla')
await server.mocker.follow('bob', 'alice')
await server.mocker.follow('bob', 'carla')
await server.mocker.follow('carla', 'alice')
await server.mocker.follow('carla', 'bob')
}
if ('posts' in url.query) {
console.log('Generating mock posts')
for (let user in server.mocker.users) {
await server.mocker.users[user].agent.post({text: 'Post'})
}
}
if ('feeds' in url.query) {
console.log('Generating mock feed')
await server.mocker.createFeed('alice', 'alice-favs', [])
}
if ('thread' in url.query) {
console.log('Generating mock posts')
const res = await server.mocker.users.bob.agent.post({
text: 'Thread root',
})
await server.mocker.users.carla.agent.post({
text: 'Thread reply',
reply: {
parent: {cid: res.cid, uri: res.uri},
root: {cid: res.cid, uri: res.uri},
},
})
}
if ('mergefeed' in url.query) {
console.log('Generating mock users')
await server.mocker.createUser('alice')
await server.mocker.createUser('bob')
await server.mocker.createUser('carla')
await server.mocker.createUser('dan')
await server.mocker.users.alice.agent.upsertProfile(() => ({
displayName: 'Alice',
description: 'Test user 1',
}))
await server.mocker.users.bob.agent.upsertProfile(() => ({
displayName: 'Bob',
description: 'Test user 2',
}))
await server.mocker.users.carla.agent.upsertProfile(() => ({
displayName: 'Carla',
description: 'Test user 3',
}))
await server.mocker.users.dan.agent.upsertProfile(() => ({
displayName: 'Dan',
description: 'Test user 4',
}))
console.log('Generating mock follows')
await server.mocker.follow('alice', 'bob')
await server.mocker.follow('alice', 'carla')
console.log('Generating mock posts')
let posts: Record<string, any[]> = {
alice: [],
bob: [],
carla: [],
dan: [],
}
for (let i = 0; i < 10; i++) {
for (let user in server.mocker.users) {
if (user === 'alice') continue
posts[user].push(
await server.mocker.createPost(user, `Post ${i}`),
)
}
}
for (let i = 0; i < 10; i++) {
for (let user in server.mocker.users) {
if (user === 'alice') continue
if (i % 5 === 0) {
await server.mocker.createReply(user, 'Self reply', {
cid: posts[user][i].cid,
uri: posts[user][i].uri,
})
}
if (i % 5 === 1) {
await server.mocker.createReply(user, 'Reply to bob', {
cid: posts.bob[i].cid,
uri: posts.bob[i].uri,
})
}
if (i % 5 === 2) {
await server.mocker.createReply(user, 'Reply to dan', {
cid: posts.dan[i].cid,
uri: posts.dan[i].uri,
})
}
await server.mocker.users[user].agent.post({text: `Post ${i}`})
}
}
console.log('Generating mock feeds')
await server.mocker.createFeed(
'alice',
'alice-favs',
posts.dan.map(p => p.uri),
)
await server.mocker.createFeed(
'alice',
'alice-favs2',
posts.dan.map(p => p.uri),
)
}
if ('labels' in url.query) {
console.log('Generating naughty users with labels')
const anchorPost = await server.mocker.createPost(
'alice',
'Anchor post',
)
for (const user of [
'dmca-account',
'dmca-profile',
'dmca-posts',
'porn-account',
'porn-profile',
'porn-posts',
'nudity-account',
'nudity-profile',
'nudity-posts',
'scam-account',
'scam-profile',
'scam-posts',
'unknown-account',
'unknown-profile',
'unknown-posts',
'hide-account',
'hide-profile',
'hide-posts',
'no-promote-account',
'no-promote-profile',
'no-promote-posts',
'warn-account',
'warn-profile',
'warn-posts',
'muted-account',
'muted-by-list-account',
'blocking-account',
'blockedby-account',
'mutual-block-account',
]) {
await server.mocker.createUser(user)
await server.mocker.follow('alice', user)
await server.mocker.follow(user, 'alice')
await server.mocker.createPost(user, `Unlabeled post from ${user}`)
await server.mocker.createReply(
user,
`Unlabeled reply from ${user}`,
anchorPost,
)
await server.mocker.like(user, anchorPost)
}
await server.mocker.labelAccount('dmca-violation', 'dmca-account')
await server.mocker.labelProfile('dmca-violation', 'dmca-profile')
await server.mocker.labelPost(
'dmca-violation',
await server.mocker.createPost('dmca-posts', 'dmca post'),
)
await server.mocker.labelPost(
'dmca-violation',
await server.mocker.createQuotePost(
'dmca-posts',
'dmca quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'dmca-violation',
await server.mocker.createReply(
'dmca-posts',
'dmca reply',
anchorPost,
),
)
await server.mocker.labelAccount('porn', 'porn-account')
await server.mocker.labelProfile('porn', 'porn-profile')
await server.mocker.labelPost(
'porn',
await server.mocker.createImagePost('porn-posts', 'porn post'),
)
await server.mocker.labelPost(
'porn',
await server.mocker.createQuotePost(
'porn-posts',
'porn quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'porn',
await server.mocker.createReply(
'porn-posts',
'porn reply',
anchorPost,
),
)
await server.mocker.labelAccount('nudity', 'nudity-account')
await server.mocker.labelProfile('nudity', 'nudity-profile')
await server.mocker.labelPost(
'nudity',
await server.mocker.createImagePost('nudity-posts', 'nudity post'),
)
await server.mocker.labelPost(
'nudity',
await server.mocker.createQuotePost(
'nudity-posts',
'nudity quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'nudity',
await server.mocker.createReply(
'nudity-posts',
'nudity reply',
anchorPost,
),
)
await server.mocker.labelAccount('scam', 'scam-account')
await server.mocker.labelProfile('scam', 'scam-profile')
await server.mocker.labelPost(
'scam',
await server.mocker.createPost('scam-posts', 'scam post'),
)
await server.mocker.labelPost(
'scam',
await server.mocker.createQuotePost(
'scam-posts',
'scam quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'scam',
await server.mocker.createReply(
'scam-posts',
'scam reply',
anchorPost,
),
)
await server.mocker.labelAccount(
'not-a-real-label',
'unknown-account',
)
await server.mocker.labelProfile(
'not-a-real-label',
'unknown-profile',
)
await server.mocker.labelPost(
'not-a-real-label',
await server.mocker.createPost('unknown-posts', 'unknown post'),
)
await server.mocker.labelPost(
'not-a-real-label',
await server.mocker.createQuotePost(
'unknown-posts',
'unknown quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'not-a-real-label',
await server.mocker.createReply(
'unknown-posts',
'unknown reply',
anchorPost,
),
)
await server.mocker.labelAccount('!hide', 'hide-account')
await server.mocker.labelProfile('!hide', 'hide-profile')
await server.mocker.labelPost(
'!hide',
await server.mocker.createPost('hide-posts', 'hide post'),
)
await server.mocker.labelPost(
'!hide',
await server.mocker.createQuotePost(
'hide-posts',
'hide quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'!hide',
await server.mocker.createReply(
'hide-posts',
'hide reply',
anchorPost,
),
)
await server.mocker.labelAccount('!no-promote', 'no-promote-account')
await server.mocker.labelProfile('!no-promote', 'no-promote-profile')
await server.mocker.labelPost(
'!no-promote',
await server.mocker.createPost(
'no-promote-posts',
'no-promote post',
),
)
await server.mocker.labelPost(
'!no-promote',
await server.mocker.createQuotePost(
'no-promote-posts',
'no-promote quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'!no-promote',
await server.mocker.createReply(
'no-promote-posts',
'no-promote reply',
anchorPost,
),
)
await server.mocker.labelAccount('!warn', 'warn-account')
await server.mocker.labelProfile('!warn', 'warn-profile')
await server.mocker.labelPost(
'!warn',
await server.mocker.createPost('warn-posts', 'warn post'),
)
await server.mocker.labelPost(
'!warn',
await server.mocker.createQuotePost(
'warn-posts',
'warn quote post',
anchorPost,
),
)
await server.mocker.labelPost(
'!warn',
await server.mocker.createReply(
'warn-posts',
'warn reply',
anchorPost,
),
)
await server.mocker.users.alice.agent.mute('muted-account.test')
await server.mocker.createPost('muted-account', 'muted post')
await server.mocker.createQuotePost(
'muted-account',
'muted quote post',
anchorPost,
)
await server.mocker.createReply(
'muted-account',
'muted reply',
anchorPost,
)
const list = await server.mocker.createMuteList(
'alice',
'Muted Users',
)
await server.mocker.addToMuteList(
'alice',
list,
server.mocker.users['muted-by-list-account'].did,
)
await server.mocker.createPost('muted-by-list-account', 'muted post')
await server.mocker.createQuotePost(
'muted-by-list-account',
'account quote post',
anchorPost,
)
await server.mocker.createReply(
'muted-by-list-account',
'account reply',
anchorPost,
)
await server.mocker.createPost('blocking-account', 'blocking post')
await server.mocker.createQuotePost(
'blocking-account',
'blocking quote post',
anchorPost,
)
await server.mocker.createReply(
'blocking-account',
'blocking reply',
anchorPost,
)
await server.mocker.users.alice.agent.app.bsky.graph.block.create(
{
repo: server.mocker.users.alice.did,
},
{
subject: server.mocker.users['blocking-account'].did,
createdAt: new Date().toISOString(),
},
)
await server.mocker.createPost('blockedby-account', 'blockedby post')
await server.mocker.createQuotePost(
'blockedby-account',
'blockedby quote post',
anchorPost,
)
await server.mocker.createReply(
'blockedby-account',
'blockedby reply',
anchorPost,
)
await server.mocker.users[
'blockedby-account'
].agent.app.bsky.graph.block.create(
{
repo: server.mocker.users['blockedby-account'].did,
},
{
subject: server.mocker.users.alice.did,
createdAt: new Date().toISOString(),
},
)
await server.mocker.createPost(
'mutual-block-account',
'mutual-block post',
)
await server.mocker.createQuotePost(
'mutual-block-account',
'mutual-block quote post',
anchorPost,
)
await server.mocker.createReply(
'mutual-block-account',
'mutual-block reply',
anchorPost,
)
await server.mocker.users.alice.agent.app.bsky.graph.block.create(
{
repo: server.mocker.users.alice.did,
},
{
subject: server.mocker.users['mutual-block-account'].did,
createdAt: new Date().toISOString(),
},
)
await server.mocker.users[
'mutual-block-account'
].agent.app.bsky.graph.block.create(
{
repo: server.mocker.users['mutual-block-account'].did,
},
{
subject: server.mocker.users.alice.did,
createdAt: new Date().toISOString(),
},
)
// flush caches
await server.mocker.testNet.processAll()
}
}
console.log('Ready')
return res.writeHead(200).end(server.pdsUrl)
} catch (e) {
console.error('Error!', e)
return res.writeHead(500).end()
}
}).listen(1986)
console.log('Mock server manager listening on 1986')
}
main()
+1 -2
View File
@@ -1,4 +1,3 @@
# flow.yaml
appId: xyz.blueskyweb.app
@@ -33,7 +32,7 @@ appId: xyz.blueskyweb.app
direction: "LEFT"
- swipe:
direction: "LEFT"
- swipe:
- swipe:
direction: "LEFT"
- swipe:
direction: "RIGHT"
+29 -10
View File
@@ -1,13 +1,32 @@
appId: xyz.blueskyweb.app
---
- launchApp:
appId: "xyz.blueskyweb.app"
clearState: true
- waitForAnimationToEnd
- tapOn: "http://localhost:8081"
- waitForAnimationToEnd
- extendedWaitUntil:
visible: "Continue"
- swipe:
from: "Bluesky"
direction: DOWN
appId: "xyz.blueskyweb.app"
clearState: true
arguments:
"-EXDevMenuIsOnboardingFinished": true
- runFlow:
when:
platform: iOS
commands:
- openLink: "exp+bluesky://expo-development-client/?url=http%3A%2F%2Flocalhost%3A8081"
- runFlow:
when:
visible: 'Open in "Bluesky"'
commands:
- tapOn: Open
- runFlow:
when:
platform: Android
commands:
- tapOn: 'http://localhost:8081'
- runFlow:
label: "Dismiss Expo dev menu"
when:
visible: "Continue"
commands:
- back
- tapOn:
id: e2eProxyHeaderInput
- inputText: ${output.result}
- pressKey: Enter
+5 -2
View File
@@ -1,5 +1,8 @@
// eslint-disable-next-line
http.post('http://localhost:1986/' + SERVER_PATH, {
// eslint-disable-next-line no-undef
var res = http.post('http://localhost:1986/' + SERVER_PATH, {
headers: {'Content-Type': 'text/plain'},
body: '',
})
// eslint-disable-next-line no-undef
output.result = json(res.body).appviewDid
+6 -5
View File
@@ -1,7 +1,8 @@
import React, {ReactNode} from 'react'
import {View, ScrollView, Modal, FlatList, TextInput} from 'react-native'
import React, {type ReactNode} from 'react'
import {FlatList, Modal, ScrollView, TextInput, View} from 'react-native'
const BottomSheetModalContext = React.createContext(null)
BottomSheetModalContext.displayName = 'BottomSheetModalContext'
const BottomSheetModalProvider = (props: any) => {
return <BottomSheetModalContext.Provider {...props} value={{}} />
@@ -47,13 +48,13 @@ export {useBottomSheetInternal}
export {useBottomSheetDynamicSnapPoints}
export {
BottomSheetModalProvider,
BottomSheetBackdrop,
BottomSheetFlatList,
BottomSheetFooter,
BottomSheetHandle,
BottomSheetModal,
BottomSheetFooter,
BottomSheetModalProvider,
BottomSheetScrollView,
BottomSheetFlatList,
BottomSheetTextInput,
}
-6
View File
@@ -1,6 +0,0 @@
export default {
requestPermission: jest.fn(),
onForegroundEvent: jest.fn(),
setBadgeCount: jest.fn(),
displayNotification: jest.fn(),
}
@@ -1,9 +0,0 @@
export const CameraRoll = {
getPhotos: jest.fn().mockResolvedValue({
edges: [
{node: {image: {uri: 'path/to/image1.jpg'}}},
{node: {image: {uri: 'path/to/image2.jpg'}}},
{node: {image: {uri: 'path/to/image3.jpg'}}},
],
}),
}
@@ -1,4 +0,0 @@
export default {
configure: jest.fn().mockResolvedValue(0),
finish: jest.fn(),
}
-1
View File
@@ -1 +0,0 @@
export default {}
-10
View File
@@ -1,10 +0,0 @@
jest.mock('rn-fetch-blob', () => {
return {
__esModule: true,
default: {
fs: {
unlink: jest.fn(),
},
},
}
})
-2
View File
@@ -1,2 +0,0 @@
export const DropdownMenu = jest.fn().mockImplementation(() => {})
export const create = jest.fn().mockImplementation(() => {})
+1 -1
View File
@@ -1,4 +1,4 @@
import {createDownloadResumable, deleteAsync} from 'expo-file-system'
import {createDownloadResumable, deleteAsync} from 'expo-file-system/legacy'
import {manipulateAsync, SaveFormat} from 'expo-image-manipulator'
import {
+1 -1
View File
@@ -1,4 +1,4 @@
import {LikelyType, getLikelyType} from '../../src/lib/link-meta/link-meta'
import {getLikelyType, LikelyType} from '../../src/lib/link-meta/link-meta'
describe('getLikelyType', () => {
it('correctly handles non-parsed url', async () => {
+56 -4
View File
@@ -1,4 +1,5 @@
import {RichText} from '@atproto/api'
import {i18n} from '@lingui/core'
import {parseEmbedPlayerFromUrl} from '#/lib/strings/embed-player'
import {
@@ -6,6 +7,8 @@ import {
createStarterPackLinkFromAndroidReferrer,
parseStarterPackUri,
} from '#/lib/strings/starter-pack'
import {messages} from '#/locale/locales/en/messages'
import {tenorUrlToBskyGifUrl} from '#/state/queries/tenor'
import {cleanError} from '../../src/lib/strings/errors'
import {createFullHandle, makeValidHandle} from '../../src/lib/strings/handles'
import {enforceLen} from '../../src/lib/strings/helpers'
@@ -201,6 +204,9 @@ describe('enforceLen', () => {
})
describe('cleanError', () => {
// cleanError uses lingui
i18n.loadAndActivate({locale: 'en', messages})
const inputs = [
'TypeError: Network request failed',
'Error: Aborted',
@@ -326,6 +332,7 @@ describe('shortenLinks', () => {
expect(outputRT.text).toEqual(outputs[i][0])
expect(outputRT.facets?.length).toEqual(outputs[i][1].length)
for (let j = 0; j < outputs[i][1].length; j++) {
// @ts-expect-error whatever
expect(outputRT.facets![j].features[0].uri).toEqual(outputs[i][1][j])
}
}
@@ -377,6 +384,7 @@ describe('parseEmbedPlayerFromUrl', () => {
'https://music.apple.com/us/playlist/playlistName/playlistId',
'https://music.apple.com/us/album/albumName/albumId',
'https://music.apple.com/us/album/albumName/albumId?i=songId',
'https://music.apple.com/us/song/songName/songId',
'https://vimeo.com/videoId',
'https://vimeo.com/videoId?autoplay=0',
@@ -435,6 +443,13 @@ describe('parseEmbedPlayerFromUrl', () => {
'https://www.flickr.com/groups/898944@N23/',
'https://www.flickr.com/groups',
'https://maxblansjaar.bandcamp.com/album/false-comforts',
'https://grmnygrmny.bandcamp.com/track/fluid',
'https://sufjanstevens.bandcamp.com/',
'https://sufjanstevens.bandcamp.com',
'https://bandcamp.com/',
'https://bandcamp.com',
]
const outputs = [
@@ -603,6 +618,11 @@ describe('parseEmbedPlayerFromUrl', () => {
playerUri:
'https://embed.music.apple.com/us/album/albumName/albumId?i=songId',
},
{
type: 'apple_music_song',
source: 'appleMusic',
playerUri: 'https://embed.music.apple.com/us/song/songName/songId',
},
{
type: 'vimeo_video',
@@ -808,6 +828,23 @@ describe('parseEmbedPlayerFromUrl', () => {
undefined,
undefined,
{
type: 'bandcamp_album',
source: 'bandcamp',
playerUri:
'https://bandcamp.com/EmbeddedPlayer/url=https%3A%2F%2Fmaxblansjaar.bandcamp.com%2Falbum%2Ffalse-comforts/size=large/bgcol=ffffff/linkcol=0687f5/minimal=true/transparent=true/',
},
{
type: 'bandcamp_track',
source: 'bandcamp',
playerUri:
'https://bandcamp.com/EmbeddedPlayer/url=https%3A%2F%2Fgrmnygrmny.bandcamp.com%2Ftrack%2Ffluid/size=large/bgcol=ffffff/linkcol=0687f5/minimal=true/transparent=true/',
},
undefined,
undefined,
undefined,
undefined,
]
it('correctly grabs the correct id from uri', () => {
@@ -950,20 +987,20 @@ describe('parseStarterPackHttpUri', () => {
})
it('returns the at uri when the input is a valid starterpack at uri', () => {
const validAtUri = 'at://did:123/app.bsky.graph.starterpack/rkey'
const validAtUri = 'at://did:plc:123/app.bsky.graph.starterpack/rkey'
expect(parseStarterPackUri(validAtUri)).toEqual({
name: 'did:123',
name: 'did:plc:123',
rkey: 'rkey',
})
})
it('returns null when the at uri has no rkey', () => {
const validAtUri = 'at://did:123/app.bsky.graph.starterpack'
const validAtUri = 'at://did:plc:123/app.bsky.graph.starterpack'
expect(parseStarterPackUri(validAtUri)).toEqual(null)
})
it('returns null when the collection is not app.bsky.graph.starterpack', () => {
const validAtUri = 'at://did:123/app.bsky.graph.list/rkey'
const validAtUri = 'at://did:plc:123/app.bsky.graph.list/rkey'
expect(parseStarterPackUri(validAtUri)).toEqual(null)
})
@@ -997,3 +1034,18 @@ describe('createStarterPackGooglePlayUri', () => {
expect(createStarterPackGooglePlayUri(undefined, 'rkey')).toEqual(null)
})
})
describe('tenorUrlToBskyGifUrl', () => {
const inputs = [
'https://media.tenor.com/someID_AAAAC/someName.gif',
'https://media.tenor.com/someID/someName.gif',
]
it.each(inputs)(
'returns url with t.gifs.bsky.app as hostname for input url',
input => {
const out = tenorUrlToBskyGifUrl(input)
expect(out.startsWith('https://t.gifs.bsky.app/')).toEqual(true)
},
)
})
+5 -5
View File
@@ -1,4 +1,4 @@
import {IsValidHandle, validateServiceHandle} from '#/lib/strings/handles'
import {type IsValidHandle, validateServiceHandle} from '#/lib/strings/handles'
describe('handle validation', () => {
const valid = [
@@ -18,17 +18,17 @@ describe('handle validation', () => {
})
const invalid = [
['al', 'bsky.social', 'frontLength'],
['al', 'bsky.social', 'frontLengthNotTooShort'],
['-alice', 'bsky.social', 'hyphenStartOrEnd'],
['alice-', 'bsky.social', 'hyphenStartOrEnd'],
['%%%', 'bsky.social', 'handleChars'],
['1234567890123456789', 'bsky.social', 'frontLength'],
['1234567890123456789', 'bsky.social', 'frontLengthNotTooLong'],
[
'1234567890123456789',
'my-custom-pds-with-long-name.social',
'frontLength',
'frontLengthNotTooLong',
],
['al', 'my-custom-pds-with-long-name.social', 'frontLength'],
['al', 'my-custom-pds-with-long-name.social', 'frontLengthNotTooShort'],
['a'.repeat(300), 'toolong.com', 'totalLength'],
] satisfies [string, string, keyof IsValidHandle][]
it.each(invalid)(
@@ -32,6 +32,7 @@ describe('getMentionAt', () => {
['@alice hello', 7, undefined],
['alice@alice', 0, undefined],
['alice@alice', 6, undefined],
['hello @alice-com goodbye', 8, 'alice-com'],
]
it.each(cases)(
@@ -72,6 +73,7 @@ describe('insertMentionAt', () => {
['@alice hello', 7, '@alice hello'],
['alice@alice', 0, 'alice@alice'],
['alice@alice', 6, 'alice@alice'],
['hello @alice-com goodbye', 10, 'hello @alice.com goodbye'],
]
it.each(cases)(
+112 -49
View File
@@ -1,5 +1,10 @@
// @ts-check
const pkg = require('./package.json')
/**
* @param {import('@expo/config-types').ExpoConfig} _config
* @returns {{ expo: import('@expo/config-types').ExpoConfig }}
*/
module.exports = function (_config) {
/**
* App version number. Should be incremented as part of a release cycle.
@@ -11,11 +16,11 @@ module.exports = function (_config) {
*
* @see https://docs.expo.dev/build-reference/variables/#built-in-environment-variables
*/
const PLATFORM = process.env.EAS_BUILD_PLATFORM
const PLATFORM = process.env.EAS_BUILD_PLATFORM ?? 'web'
const IS_TESTFLIGHT = process.env.EXPO_PUBLIC_ENV === 'testflight'
const IS_PRODUCTION = process.env.EXPO_PUBLIC_ENV === 'production'
const IS_DEV = !IS_TESTFLIGHT || !IS_PRODUCTION
const IS_DEV = !IS_TESTFLIGHT && !IS_PRODUCTION
const ASSOCIATED_DOMAINS = [
'applinks:bsky.app',
@@ -26,15 +31,17 @@ module.exports = function (_config) {
...(IS_DEV || IS_TESTFLIGHT ? [] : []),
]
const UPDATES_CHANNEL = IS_TESTFLIGHT
? 'testflight'
: IS_PRODUCTION
? 'production'
: undefined
const UPDATES_ENABLED = !!UPDATES_CHANNEL
const UPDATES_ENABLED = IS_TESTFLIGHT || IS_PRODUCTION
const USE_SENTRY = Boolean(process.env.SENTRY_AUTH_TOKEN)
const IOS_ICON_FILE =
PLATFORM === 'web' // web build doesn't like .icon files
? './assets/app-icons/ios_icon_default_next.png'
: IS_TESTFLIGHT
? './assets/app-icons/ios_icon_testflight.icon'
: './assets/app-icons/ios_icon_default.icon'
return {
expo: {
version: VERSION,
@@ -45,15 +52,17 @@ module.exports = function (_config) {
runtimeVersion: {
policy: 'appVersion',
},
icon: './assets/app-icons/ios_icon_default_light.png',
icon: './assets/app-icons/ios_icon_default_next.png',
userInterfaceStyle: 'automatic',
primaryColor: '#1083fe',
newArchEnabled: false,
ios: {
supportsTablet: false,
bundleIdentifier: 'xyz.blueskyweb.app',
config: {
usesNonExemptEncryption: false,
},
icon: IOS_ICON_FILE,
infoPlist: {
UIBackgroundModes: ['remote-notification'],
NSCameraUsageDescription:
@@ -113,8 +122,37 @@ module.exports = function (_config) {
'com.apple.developer.kernel.increased-memory-limit': true,
'com.apple.developer.kernel.extended-virtual-addressing': true,
'com.apple.security.application-groups': 'group.app.bsky',
// 'com.apple.developer.device-information.user-assigned-device-name': true,
},
privacyManifests: {
NSPrivacyCollectedDataTypes: [
{
NSPrivacyCollectedDataType: 'NSPrivacyCollectedDataTypeCrashData',
NSPrivacyCollectedDataTypeLinked: false,
NSPrivacyCollectedDataTypeTracking: false,
NSPrivacyCollectedDataTypePurposes: [
'NSPrivacyCollectedDataTypePurposeAppFunctionality',
],
},
{
NSPrivacyCollectedDataType:
'NSPrivacyCollectedDataTypePerformanceData',
NSPrivacyCollectedDataTypeLinked: false,
NSPrivacyCollectedDataTypeTracking: false,
NSPrivacyCollectedDataTypePurposes: [
'NSPrivacyCollectedDataTypePurposeAppFunctionality',
],
},
{
NSPrivacyCollectedDataType:
'NSPrivacyCollectedDataTypeOtherDiagnosticData',
NSPrivacyCollectedDataTypeLinked: false,
NSPrivacyCollectedDataTypeTracking: false,
NSPrivacyCollectedDataTypePurposes: [
'NSPrivacyCollectedDataTypePurposeAppFunctionality',
],
},
],
NSPrivacyAccessedAPITypes: [
{
NSPrivacyAccessedAPIType:
@@ -146,12 +184,11 @@ module.exports = function (_config) {
barStyle: 'light-content',
},
android: {
icon: './assets/app-icons/android_icon_default_light.png',
icon: './assets/app-icons/android_icon_default_next.png',
adaptiveIcon: {
foregroundImage: './assets/icon-android-foreground.png',
monochromeImage: './assets/icon-android-foreground.png',
backgroundImage: './assets/icon-android-background.png',
backgroundColor: '#1185FE',
monochromeImage: './assets/icon-android-monochrome.png',
backgroundColor: '#006AFF',
},
googleServicesFile: './google-services.json',
package: 'xyz.blueskyweb.app',
@@ -164,10 +201,14 @@ module.exports = function (_config) {
scheme: 'https',
host: 'bsky.app',
},
IS_DEV && {
scheme: 'http',
host: 'localhost:19006',
},
...(IS_DEV
? [
{
scheme: 'http',
host: 'localhost:19006',
},
]
: []),
],
category: ['BROWSABLE', 'DEFAULT'],
},
@@ -190,7 +231,6 @@ module.exports = function (_config) {
}
: undefined,
checkAutomatically: 'NEVER',
channel: UPDATES_CHANNEL,
},
plugins: [
'expo-video',
@@ -200,26 +240,38 @@ module.exports = function (_config) {
'react-native-edge-to-edge',
{android: {enforceNavigationBarContrast: false}},
],
USE_SENTRY && [
'@sentry/react-native/expo',
{
organization: 'blueskyweb',
project: 'app',
url: 'https://sentry.io',
},
],
...(USE_SENTRY
? [
/** @type {[string, any]} */ ([
'@sentry/react-native/expo',
{
organization: 'blueskyweb',
project: 'app',
url: 'https://sentry.io',
},
]),
]
: []),
[
'expo-build-properties',
{
ios: {
deploymentTarget: '15.1',
newArchEnabled: false,
buildReactNativeFromSource: true,
ccacheEnabled: IS_DEV,
extraPods: [
{
name: 'MCEmojiPicker',
git: 'https://github.com/bluesky-social/MCEmojiPicker.git',
branch: 'main',
},
],
},
android: {
compileSdkVersion: 35,
compileSdkVersion: 36,
targetSdkVersion: 35,
buildToolsVersion: '35.0.0',
newArchEnabled: true,
buildReactNativeFromSource: IS_PRODUCTION,
},
},
],
@@ -240,8 +292,9 @@ module.exports = function (_config) {
],
'./plugins/starterPackAppClipExtension/withStarterPackAppClip.js',
'./plugins/withGradleJVMHeapSizeIncrease.js',
'./plugins/withAndroidManifestPlugin.js',
'./plugins/withAndroidManifestLargeHeapPlugin.js',
'./plugins/withAndroidManifestFCMIconPlugin.js',
'./plugins/withAndroidManifestIntentQueriesPlugin.js',
'./plugins/withAndroidStylesAccentColorPlugin.js',
'./plugins/withAndroidDayNightThemePlugin.js',
'./plugins/withAndroidNoJitpackPlugin.js',
@@ -256,10 +309,12 @@ module.exports = function (_config) {
// Android only
'./assets/fonts/inter/Inter-Regular.otf',
'./assets/fonts/inter/Inter-Italic.otf',
'./assets/fonts/inter/Inter-Medium.otf',
'./assets/fonts/inter/Inter-MediumItalic.otf',
'./assets/fonts/inter/Inter-SemiBold.otf',
'./assets/fonts/inter/Inter-SemiBoldItalic.otf',
'./assets/fonts/inter/Inter-ExtraBold.otf',
'./assets/fonts/inter/Inter-ExtraBoldItalic.otf',
'./assets/fonts/inter/Inter-Bold.otf',
'./assets/fonts/inter/Inter-BoldItalic.otf',
],
},
],
@@ -267,25 +322,25 @@ module.exports = function (_config) {
'expo-splash-screen',
{
ios: {
enableFullScreenImage_legacy: true,
backgroundColor: '#ffffff',
image: './assets/splash.png',
enableFullScreenImage_legacy: true, // iOS only
backgroundColor: '#006AFF', // primary_500
image: './assets/splash/splash.png',
resizeMode: 'cover',
dark: {
enableFullScreenImage_legacy: true,
backgroundColor: '#001429',
image: './assets/splash-dark.png',
enableFullScreenImage_legacy: true, // iOS only
backgroundColor: '#002861', // primary_900
image: './assets/splash/splash-dark.png',
resizeMode: 'cover',
},
},
android: {
backgroundColor: '#0c7cff',
image: './assets/splash-android-icon.png',
imageWidth: 150,
backgroundColor: '#006AFF', // primary_500
image: './assets/splash/android-splash-logo-white.png',
imageWidth: 102, // even division of 306px
dark: {
backgroundColor: '#0c2a49',
image: './assets/splash-android-icon-dark.png',
imageWidth: 150,
backgroundColor: '#002861', // primary_900
image: './assets/splash/android-splash-logo-white.png',
imageWidth: 102,
},
},
},
@@ -297,13 +352,13 @@ module.exports = function (_config) {
* Default set
*/
default_light: {
ios: './assets/app-icons/ios_icon_default_light.png',
android: './assets/app-icons/android_icon_default_light.png',
ios: './assets/app-icons/ios_icon_legacy_light.png',
android: './assets/app-icons/android_icon_legacy_light.png',
prerendered: true,
},
default_dark: {
ios: './assets/app-icons/ios_icon_default_dark.png',
android: './assets/app-icons/android_icon_default_dark.png',
ios: './assets/app-icons/ios_icon_legacy_dark.png',
android: './assets/app-icons/android_icon_legacy_dark.png',
prerendered: true,
},
@@ -358,7 +413,15 @@ module.exports = function (_config) {
},
],
['expo-screen-orientation', {initialOrientation: 'PORTRAIT_UP'}],
].filter(Boolean),
['expo-location'],
[
'expo-contacts',
{
contactsPermission:
'I agree to allow Bluesky to use my contacts for friend discovery until I opt out.',
},
],
],
extra: {
eas: {
build: {
Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

Before

Width:  |  Height:  |  Size: 467 KiB

After

Width:  |  Height:  |  Size: 467 KiB

Before

Width:  |  Height:  |  Size: 432 KiB

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

@@ -0,0 +1,31 @@
{
"fill" : {
"automatic-gradient" : "srgb:0.00000,0.41569,1.00000,1.00000"
},
"groups" : [
{
"layers" : [
{
"fill" : "none",
"glass" : false,
"image-name" : "iOS transparent.png",
"name" : "iOS transparent"
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Before

Width:  |  Height:  |  Size: 389 KiB

After

Width:  |  Height:  |  Size: 389 KiB

Before

Width:  |  Height:  |  Size: 321 KiB

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

@@ -0,0 +1,113 @@
{
"fill" : {
"automatic-gradient" : "srgb:1.00000,1.00000,1.00000,1.00000"
},
"groups" : [
{
"blend-mode-specializations" : [
{
"value" : "overlay"
},
{
"appearance" : "dark",
"value" : "screen"
},
{
"appearance" : "tinted",
"value" : "screen"
}
],
"blur-material-specializations" : [
{
"value" : 0.5
},
{
"appearance" : "dark",
"value" : 0.5
},
{
"appearance" : "tinted",
"value" : null
}
],
"hidden" : false,
"layers" : [
{
"image-name" : "TestFlight notice.png",
"name" : "TestFlight notice"
}
],
"lighting" : "individual",
"position" : {
"scale" : 0.4,
"translation-in-points" : [
0,
350
]
},
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"specular-specializations" : [
{
"value" : false
},
{
"appearance" : "dark",
"value" : false
},
{
"appearance" : "tinted",
"value" : false
}
],
"translucency-specializations" : [
{
"value" : {
"enabled" : true,
"value" : 0.5
}
},
{
"appearance" : "dark",
"value" : {
"enabled" : true,
"value" : 0.5
}
},
{
"appearance" : "tinted",
"value" : {
"enabled" : true,
"value" : 0.5
}
}
]
},
{
"layers" : [
{
"fill" : "none",
"glass" : false,
"image-name" : "iOS transparent.png",
"name" : "iOS transparent"
}
],
"shadow" : {
"kind" : "neutral",
"opacity" : 0.5
},
"translucency" : {
"enabled" : true,
"value" : 0.5
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M15.793 10.293a1 1 0 0 1 1.338-.068l.076.068 3.293 3.293a2 2 0 0 1 .138 2.677l-.138.151-3.293 3.293a1 1 0 1 1-1.414-1.414L18.086 16H8a5 5 0 0 1-5-5V5a1 1 0 0 1 2 0v6a3 3 0 0 0 3 3h10.086l-2.293-2.293-.068-.076a1 1 0 0 1 .068-1.338Z"/></svg>

After

Width:  |  Height:  |  Size: 334 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M2.972 12a9 9 0 0 1 9-9c1.726 0 3.165.423 4.448 1.21A10 10 0 0 1 18 5.428V4a1 1 0 1 1 2 0v4a1 1 0 0 1-1 1h-4a1 1 0 1 1 0-2h1.756a8.3 8.3 0 0 0-1.382-1.085C14.417 5.327 13.341 5 11.972 5a7 7 0 1 0 6.601 9.333A1 1 0 0 1 20.46 15a9 9 0 0 1-17.487-3Z"/></svg>

After

Width:  |  Height:  |  Size: 349 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M12 2a1 1 0 0 1 0 2 5.85 5.85 0 0 0-5.802 5.08L5.143 17h13.715l-.382-2.868-.01-.102a1 1 0 0 1 1.973-.262l.02.1.532 4a1 1 0 0 1-.99 1.132h-3.357c-.905 1.747-2.606 3-4.644 3s-3.74-1.253-4.643-3H4a1 1 0 0 1-.991-1.132l1.207-9.053A7.85 7.85 0 0 1 12 2ZM9.78 19c.61.637 1.397 1 2.22 1s1.611-.363 2.22-1H9.78ZM17 2.5a1 1 0 0 1 1 1V6h2.5a1 1 0 0 1 0 2H18v2.5a1 1 0 0 1-2 0V8h-2.5a1 1 0 1 1 0-2H16V3.5a1 1 0 0 1 1-1Z"/></svg>

After

Width:  |  Height:  |  Size: 511 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M12 2a7.854 7.854 0 0 1 7.784 6.815l1.207 9.053a1 1 0 0 1-.99 1.132h-3.354c-.904 1.748-2.608 3-4.647 3-2.038 0-3.742-1.252-4.646-3H4a1.002 1.002 0 0 1-.991-1.132l1.207-9.053A7.85 7.85 0 0 1 12 2ZM9.78 19c.608.637 1.398 1 2.221 1s1.613-.363 2.222-1H9.779ZM3.193 2.104a1 1 0 0 1 1.53 1.288A9.5 9.5 0 0 0 2.72 7.464a1 1 0 0 1-1.954-.427 11.46 11.46 0 0 1 2.428-4.933Zm16.205-.122a1 1 0 0 1 1.409.122 11.5 11.5 0 0 1 2.429 4.933 1 1 0 0 1-1.954.427 9.5 9.5 0 0 0-2.006-4.072 1 1 0 0 1 .122-1.41Z"/></svg>

After

Width:  |  Height:  |  Size: 594 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M9.7 16.895a4 4 0 0 1 4.6 0l3.7 2.6V6.5a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v12.995l3.7-2.6Zm10.3 2.6c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2 2 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v12.995Z"/></svg>

After

Width:  |  Height:  |  Size: 334 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#405168" d="M14.2 2.625c.834 0 1.482 0 2.001.042.523.043.949.131 1.331.326a3.38 3.38 0 0 1 1.475 1.475c.195.382.283.807.326 1.33.042.52.042 1.168.042 2.002v11.09c0 .495 0 .893-.027 1.199-.028.301-.087.585-.26.809-.249.323-.63.518-1.037.533-.282.01-.547-.107-.808-.26-.265-.154-.588-.385-.991-.673l-3.54-2.528c-.36-.258-.461-.322-.559-.347a.6.6 0 0 0-.306 0c-.098.025-.199.09-.559.347l-3.54 2.528c-.403.288-.726.519-.991.674-.261.152-.526.269-.808.259a1.38 1.38 0 0 1-1.038-.534c-.172-.223-.231-.507-.259-.808a7 7 0 0 1-.024-.528l-.003-.67V7.8c0-.834 0-1.482.042-2.001.043-.523.13-.949.325-1.331a3.38 3.38 0 0 1 1.476-1.475c.382-.195.808-.283 1.33-.326.52-.042 1.168-.042 2.002-.042h4.4Zm-4.4.75c-.846 0-1.458 0-1.94.04-.477.039-.792.114-1.051.246A2.63 2.63 0 0 0 5.66 4.81c-.132.259-.208.574-.247 1.051-.04.482-.039 1.094-.039 1.94v11.09l.003.658c.003.186.01.34.021.473.025.267.07.37.106.418a.63.63 0 0 0 .472.243c.059.002.168-.022.4-.158.23-.133.52-.34.935-.636l3.54-2.529c.308-.22.543-.396.81-.464.222-.056.454-.056.676 0 .267.068.5.244.81.464l3.54 2.529c.414.296.704.503.933.636.233.137.343.16.402.158a.63.63 0 0 0 .472-.243c.036-.048.081-.15.106-.419.024-.263.024-.62.024-1.13V7.8c0-.846 0-1.458-.04-1.94-.039-.477-.114-.792-.246-1.051A2.63 2.63 0 0 0 17.19 3.66c-.259-.132-.575-.207-1.051-.246-.482-.04-1.094-.04-1.94-.04H9.8Zm4.056 4.238a.375.375 0 0 1 .53.53L12.53 10l1.857 1.856a.375.375 0 0 1-.53.53L12 10.53l-1.856 1.857a.375.375 0 0 1-.53-.53L11.47 10 9.613 8.144a.375.375 0 0 1 .53-.53L12 9.47l1.856-1.857Z"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#006AFF" d="M16 2.5a4 4 0 0 1 4 4v12.995c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2 2 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8Z"/></svg>

After

Width:  |  Height:  |  Size: 250 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 0a2 2 0 0 1 1 3.73V5h4.2c1.68 0 2.52 0 3.162.327a3 3 0 0 1 1.31 1.31C22 7.28 22 8.12 22 9.8v.25a2.501 2.501 0 0 1 0 4.9V15c0 2.8 0 4.2-.545 5.27a5 5 0 0 1-2.185 2.185C18.2 23 16.8 23 14 23h-4c-2.8 0-4.2 0-5.27-.545a5 5 0 0 1-2.185-2.185C2 19.2 2 17.8 2 15v-.05a2.5 2.5 0 0 1 0-4.9V9.8c0-1.68 0-2.52.327-3.162a3 3 0 0 1 1.31-1.31C4.28 5 5.12 5 6.8 5H11V3.73A2 2 0 0 1 12 0M8 10a2 2 0 0 0-2 2v2a2 2 0 1 0 4 0v-2a2 2 0 0 0-2-2m8 0a2 2 0 0 0-2 2v2a2 2 0 1 0 4 0v-2a2 2 0 0 0-2-2" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 621 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M12 2a1 1 0 0 1 1 1v2h3.2l1.113.005c.975.015 1.568.077 2.05.322a3 3 0 0 1 1.31 1.31C21 7.28 21 8.12 21 9.8v.287a1.498 1.498 0 0 1-.005 2.827c-.006 2.204-.058 3.41-.54 4.356l-.093.174a5 5 0 0 1-2.092 2.011l-.205.096c-.766.33-1.72.417-3.21.44L13 20h-2l-1.854-.009c-1.49-.023-2.445-.11-3.211-.44l-.205-.096a5 5 0 0 1-2.185-2.185c-.409-.803-.51-1.79-.536-3.415l-.005-.94A1.498 1.498 0 0 1 3 10.086V9.8c0-1.575 0-2.412.27-3.04l.057-.122a3 3 0 0 1 1.105-1.196l.206-.115C5.279 5 6.12 5 7.8 5H11V3a1 1 0 0 1 1-1M7.8 7c-.873 0-1.408.002-1.808.034a3 3 0 0 0-.367.051l-.063.018-.016.006a1 1 0 0 0-.437.437l-.006.016-.018.063a3 3 0 0 0-.05.367C5.001 8.392 5 8.927 5 9.8V12c0 1.433.002 2.388.062 3.121.058.71.16 1.036.265 1.241a3 3 0 0 0 1.31 1.31c.207.106.532.209 1.242.267.733.06 1.688.061 3.121.061h2c1.433 0 2.388-.002 3.121-.061.71-.058 1.036-.161 1.241-.266a3 3 0 0 0 1.31-1.31c.106-.206.209-.532.267-1.242.06-.733.061-1.688.061-3.121V9.8c0-.873-.002-1.408-.034-1.808a2.5 2.5 0 0 0-.051-.367l-.017-.063-.007-.016a1 1 0 0 0-.437-.437l-.015-.006-.064-.018a3 3 0 0 0-.367-.05C17.608 7.001 17.073 7 16.2 7zM9 10a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1m6 0a1 1 0 0 1 1 1v2a1 1 0 1 1-2 0v-2a1 1 0 0 1 1-1"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 46 38"><path stroke="#405168" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M22.333 31.667H45M22.333 6.333H45m-33.333 0A5.333 5.333 0 1 1 1 6.333a5.333 5.333 0 0 1 10.667 0Zm0 25.334a5.333 5.333 0 1 1-10.667 0 5.333 5.333 0 0 1 10.667 0Z"/></svg>

After

Width:  |  Height:  |  Size: 333 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 62 53"><path fill="#405168" d="M28.173.231a5.653 5.653 0 0 1 7.018 3.83l2.66 9.046a20 20 0 0 1 3.986-.397c11.026 0 19.964 8.937 19.964 19.962l-.006.516c-.274 10.787-9.104 19.448-19.958 19.448l-.514-.007c-8.332-.21-15.394-5.528-18.178-12.938l-8.805 2.59a5.654 5.654 0 0 1-7.02-3.83L.232 14.34a5.654 5.654 0 0 1 3.83-7.018L28.172.23ZM41.838 14.71c-1.17 0-2.313.111-3.42.325l3.863 13.137a5.653 5.653 0 0 1-3.83 7.019L25.07 39.126c2.593 6.732 9.122 11.51 16.768 11.51 9.92 0 17.963-8.043 17.963-17.964S51.758 14.71 41.837 14.71ZM33.271 4.624a3.653 3.653 0 0 0-4.535-2.474L4.624 9.24a3.653 3.653 0 0 0-2.475 4.535l7.09 24.113a3.654 3.654 0 0 0 4.536 2.475l8.762-2.577a20 20 0 0 1-.662-5.114c0-8.961 5.905-16.544 14.037-19.069l-2.64-8.98Zm3.204 10.899c-7.302 2.28-12.601 9.096-12.601 17.15 0 1.571.203 3.095.582 4.548l13.431-3.948a3.654 3.654 0 0 0 2.474-4.536l-3.886-13.214Z"/></svg>

After

Width:  |  Height:  |  Size: 944 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M12 4a8 8 0 1 0 0 16 8 8 0 0 0 0-16ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 250 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M7 2a3 3 0 0 0-3 3v14.5A2.5 2.5 0 0 0 6.5 22H19a1 1 0 1 0 0-2H6.5a.5.5 0 0 1 0-1H19a1 1 0 0 0 1-1V4a2 2 0 0 0-2-2H7Zm5 5a1.75 1.75 0 1 0 0 3.5A1.75 1.75 0 0 0 12 7Zm0 4c-.894 0-1.57.188-2.068.512a2.07 2.07 0 0 0-.852 1.058c-.286.838.432 1.43 1.03 1.43h3.78c.598 0 1.316-.592 1.03-1.43a2.07 2.07 0 0 0-.852-1.058C13.57 11.189 12.894 11 12 11Z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 484 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M7 4a1 1 0 0 0-1 1v12.05q.243-.05.5-.05H18V4H7Zm5 7c.894 0 1.57.188 2.068.513a2.1 2.1 0 0 1 .806.937l.046.12c.285.836-.43 1.43-1.03 1.43h-3.78c-.6 0-1.315-.594-1.03-1.43l.046-.12a2.1 2.1 0 0 1 .806-.937C10.43 11.188 11.106 11 12 11Zm0-4a1.75 1.75 0 1 1 0 3.5A1.75 1.75 0 0 1 12 7Zm8 11a1 1 0 0 1-1 1H6.5a.5.5 0 0 0 0 1H19a1 1 0 1 1 0 2H6.5A2.5 2.5 0 0 1 4 19.5V5a3 3 0 0 1 3-3h11a2 2 0 0 1 2 2v14Z"/></svg>

After

Width:  |  Height:  |  Size: 500 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#000" d="M9 17a2 2 0 1 1 0 4 2 2 0 0 1 0-4Zm6 0a2 2 0 1 1 0 4 2 2 0 0 1 0-4Zm-6-7a2 2 0 1 1 0 4 2 2 0 0 1 0-4Zm6 0a2 2 0 1 1 0 4 2 2 0 0 1 0-4ZM9 3a2 2 0 1 1 0 4 2 2 0 0 1 0-4Zm6 0a2 2 0 1 1 0 4 2 2 0 0 1 0-4Z"/></svg>

After

Width:  |  Height:  |  Size: 303 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 48 48"><path fill="#405168" d="M19.667 4.458a1 1 0 1 0 0-2v2Zm25 23a1 1 0 0 0-2 0h2ZM3.912 45.543l.454-.891-.454.89Zm-2.33-2.33.89-.455h0l-.89.454Zm39.173 2.33-.454-.891h0l.454.89Zm2.33-2.33-.89-.455.89.454ZM1.581 6.37l-.89-.454h0l.89.454Zm2.331-2.331-.454-.891.454.89ZM14.333 32.79h-1a1 1 0 0 0 1 1v-1Zm.781-8.781.707.707-.707-.707ZM36.562 2.562l-.707-.707v0l.707.707Zm7.543 0-.707.707v0l.707-.707Zm.457.458.707-.707v0l-.707.707Zm0 7.542.707.707-.707-.707ZM23.114 32.01l.707.707-.707-.707Zm12.02 14.114v-1h-25.6v2h25.6v-1ZM1 37.591h1v-25.6H0v25.6h1ZM9.533 3.458v1h10.134v-2H9.533v1Zm34.134 24h-1V37.59h2V27.457h-1ZM9.533 46.124v-1c-1.51 0-2.582 0-3.421-.07-.828-.067-1.34-.195-1.746-.402l-.454.89-.454.892c.735.374 1.54.537 2.491.614.94.077 2.107.076 3.584.076v-1ZM1 37.591H0c0 1.477 0 2.645.076 3.584.078.951.24 1.756.614 2.491l.891-.454.891-.454c-.207-.406-.335-.918-.403-1.746C2.001 40.173 2 39.101 2 37.591H1Zm2.912 7.952.454-.891a4.33 4.33 0 0 1-1.894-1.894l-.89.454-.892.454a6.33 6.33 0 0 0 2.768 2.768l.454-.891Zm31.221.581v1c1.477 0 2.645.001 3.585-.076.95-.078 1.756-.24 2.49-.614l-.453-.891-.454-.891c-.406.207-.919.335-1.746.403-.84.068-1.912.07-3.422.07v1Zm8.534-8.533h-1c0 1.51-.001 2.582-.07 3.421-.067.828-.196 1.34-.403 1.746l.891.454.891.454c.375-.735.537-1.54.615-2.49.076-.94.076-2.108.076-3.585h-1Zm-2.912 7.952.454.89a6.33 6.33 0 0 0 2.767-2.767l-.89-.454-.892-.454a4.33 4.33 0 0 1-1.893 1.894l.454.89ZM1 11.99h1c0-1.51 0-2.582.07-3.422.067-.827.195-1.34.402-1.745l-.89-.454-.892-.454c-.374.734-.536 1.54-.614 2.49C-.001 9.345 0 10.513 0 11.99h1Zm8.533-8.533v-1c-1.477 0-2.645-.001-3.584.076-.951.077-1.756.24-2.49.614l.453.89.454.892c.406-.207.918-.336 1.746-.403.839-.069 1.911-.07 3.421-.07v-1ZM1.581 6.37l.891.454A4.33 4.33 0 0 1 4.366 4.93l-.454-.891-.454-.891A6.33 6.33 0 0 0 .69 5.916l.891.454Zm12.752 19.525h-1v6.896h2v-6.896h-1Zm0 6.896v1h6.896v-2h-6.896v1Zm.781-8.781.707.707L37.27 3.269l-.707-.707-.707-.707-21.448 21.448.707.707Zm28.99-21.448-.706.707.457.458.707-.707.707-.707-.457-.458-.707.707Zm.458 8-.707-.707-21.448 21.448.707.707.707.707L45.27 11.269l-.707-.707Zm0-7.542-.707.707a4.333 4.333 0 0 1 0 6.128l.707.707.707.707a6.333 6.333 0 0 0 0-8.956l-.707.707Zm-8-.458.707.707a4.333 4.333 0 0 1 6.129 0l.707-.707.707-.707a6.333 6.333 0 0 0-8.957 0l.707.707ZM21.23 32.791v1c.972 0 1.905-.386 2.593-1.074l-.708-.707-.707-.707a1.67 1.67 0 0 1-1.178.488v1Zm-6.896-6.896h1c0-.442.176-.866.489-1.178l-.708-.707-.707-.707a3.67 3.67 0 0 0-1.074 2.592h1Z"/></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#0052B4" d="M0 0h513v342H0z"/><path fill="#FFF" d="M440.1 181.1c-.1 39.2-6.4 81.4-57.4 101.5-51.1-20.1-57.3-62.3-57.4-101.5h114.8z"/><path fill="#29DBFF" d="M439.6 197.7c-2.8 34.9-12.4 67.4-57 85-44.4-17.6-54.5-51.2-56.9-84.9"/><path fill="#FFF" d="M437.8 214.1c-3.2 24.3-16.7 53.5-55.1 68.6-38.4-15.1-50.5-42.5-55.1-68.4"/><path fill="#29DBFF" d="M434.2 230.3c-5.7 17.7-19.3 39.4-51.3 52.8-32-12.6-45.2-33.8-51.4-53"/><path fill="#FFF" d="M426.7 246.9c-6.5 11.3-17.7 25.4-44 35.9-27.5-11.5-37.4-25.3-44-36.1"/><path fill="#29DBFF" d="M412.4 265.1c-8.1 7.2-12 11.2-29.6 17.9-20.1-7.9-22.6-11.6-29.2-17.5"/><path fill="#5CC85C" d="M383.3 231.6c-.2-.2-27.9 35.7-27.9 35.7-1.8-1.3-10-9.5-13.3-15l41.3-50.1 40.2 49.7c-3.9 6.5-11.4 13.6-13.2 15M382.6 85.3l-26.5 45h53z"/><ellipse cx="291.4" cy="225.7" fill="#F7A226" rx="48.7" ry="15.7" transform="rotate(-82.3 291.431 225.686)"/><ellipse cx="303.1" cy="164.7" fill="#DDC7AB" rx="11.7" ry="7.2" transform="rotate(-68.099 303.087 164.67)"/><ellipse cx="291.7" cy="271.7" fill="#DDC7AB" rx="11.4" ry="3.3" transform="rotate(-81.738 291.697 271.697)"/><ellipse cx="299.6" cy="269.4" fill="#DDC7AB" rx="3.3" ry="11" transform="matrix(.9986 -.05353 .05353 .9986 -13.992 16.424)"/><ellipse cx="314.5" cy="201.1" fill="#DDC7AB" rx="4.1" ry="13.7" transform="rotate(-21.518 314.54 201.06)"/><ellipse cx="317.5" cy="178.1" fill="#DDC7AB" rx="13.7" ry="4.1" transform="rotate(-21.518 317.511 178.077)"/><ellipse cx="473.6" cy="225.9" fill="#F7A226" rx="15.7" ry="48.7" transform="rotate(-7.7 473.781 225.857)"/><ellipse cx="462" cy="164.9" fill="#DDC7AB" rx="7.2" ry="11.7" transform="rotate(-21.901 462.057 164.866)"/><ellipse cx="473.4" cy="271.9" fill="#DDC7AB" rx="3.3" ry="11.4" transform="rotate(-8.27 473.27 271.908)"/><ellipse cx="465.5" cy="269.6" fill="#DDC7AB" rx="11" ry="3.3" transform="matrix(.05353 -.9986 .9986 .05353 171.34 719.998)"/><ellipse cx="450.6" cy="201.2" fill="#DDC7AB" rx="13.7" ry="4.1" transform="rotate(-68.482 450.552 201.247)"/><ellipse cx="447.6" cy="178.3" fill="#DDC7AB" rx="4.1" ry="13.7" transform="rotate(-68.482 447.58 178.265)"/><path fill="#B0C6CC" d="M373.3 130.3 356.1 155l17.8 26.1H396l4.7-25.4-5.4-25.4z"/><path fill="#FFF" d="M256 0v117.4h-46.1l46.1 30.7v22.6h-22.6L160 121.8v48.9H96v-48.9l-73.4 48.9H0v-22.6l46.1-30.7H0v-64h46.1L0 22.7V0h22.6L96 48.9V0h64v48.9L233.4 0z"/><path fill="#D80027" d="M144 0h-32v69.4H0v32h112v69.3h32v-69.3h112v-32H144z"/><path fill="#2E52B2" d="M256 22.7v30.7h-46.1z"/><path fill="#D80027" d="M0 170.7v-11l62.5-42.3h22.6L7.3 170.7zM7.3.1l77.8 53.2H62.5L0 11.1V.1zM256 .1v11l-62.5 42.3h-22.6L248.7.1zm-7.3 170.6-77.8-53.3h22.6l62.5 42.3v11z"/></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#FFDA44" d="M0 0h513v342H0z"/><path fill="#0052B4" d="M0 0h171v342H0z"/><path fill="#D80027" d="M342 0h171v342H342zM198.9 113.6H256v64.8h-57.1z"/><path stroke="#D80027" stroke-width="7" d="M267.6 113.6v64.7m16.6-64.7v64.7m16.6-64.7v64.7"/><path stroke="#D80027" stroke-width="5" d="M247.4 178.4v64.7m-13.3-64.7v64.7m-13.3-64.6v53.9m-13.7-53.9v47.1"/><path fill="#FFDA44" d="m199.9 146 27.6-32.4 28.5 32.3-28.1 32.4z"/><path fill="#BC8B00" d="M182.2 95.9v92.2c0 34.3 27.3 54.2 48.6 64.5-.8 1.4 25.1 8.3 25.1 8.3s25.9-6.9 25.1-8.3c21.4-10.3 48.6-30.1 48.6-64.5V95.9H182.2zm129.9 92.2c0 16.9-10 29.4-32.8 43.9-8.6 5.5-17.5 9-23.3 11-5.8-2-14.7-5.5-23.3-11-22.8-14.5-32.8-28-32.8-43.9v-74.5h112.2v74.5z"/><path fill="#D80027" d="M264.4 188.9h29.5v8.6h-29.5zm0 17.6h29.5v8.6h-29.5z"/></svg>

After

Width:  |  Height:  |  Size: 860 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#FFF" d="M0 0h513v342H0z"/><path fill="#009e49" d="M0 0h513v114H0z"/><path d="M0 228h513v114H0z"/><path fill="#ce1126" d="M0 0h171v342H0z"/></svg>

After

Width:  |  Height:  |  Size: 221 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#DB3E00" d="M0 0h513v342H0z"/><path fill="#479900" d="M331 0h182v342H331z"/><path d="M0 0h181.8v342H0z"/><path fill="#FFF" d="M256 126.7c-19.4 0-35.2 15.8-35.2 35.2v52.8h70.4v-52.8c0-19.5-15.8-35.2-35.2-35.2z"/><path fill="#FFF" d="M256 84.3c-47.7 0-86.4 38.7-86.4 86.4S208.3 257 256 257s86.4-38.7 86.4-86.4-38.7-86.3-86.4-86.3zm0 157.7c-39.4 0-71.4-32-71.4-71.4s32-71.4 71.4-71.4 71.4 32 71.4 71.4c0 39.5-32 71.4-71.4 71.4z"/></svg>

After

Width:  |  Height:  |  Size: 508 B

Some files were not shown because too many files have changed in this diff Show More