Compare commits

...

316 Commits

Author SHA1 Message Date
Eric Bailey ed5802a450 Remove some unused things 2026-01-16 17:21:19 -06: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
1040 changed files with 190812 additions and 137543 deletions
+4 -4
View File
@@ -34,8 +34,8 @@ EXPO_PUBLIC_SENTRY_DSN=
# Bitdrift API key. If undefined, Bitdrift will be disabled.
EXPO_PUBLIC_BITDRIFT_API_KEY=
# bapp-config web worker URL
BAPP_CONFIG_DEV_URL=
# geolocation web worker URL
GEOLOCATION_DEV_URL=
# Dev-only passthrough value for bapp-config web worker
BAPP_CONFIG_DEV_BYPASS_SECRET=
# live-events web worker URL
LIVE_EVENTS_DEV_URL=
-125
View File
@@ -1,125 +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',
'Toast.Action',
'AgeAssuranceAdmonition',
'Span',
'StackedButton',
],
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',
'*.e2e.ts',
'*.e2e.tsx',
],
settings: {
componentWrapperFunctions: ['observer'],
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 'latest',
},
}
@@ -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
@@ -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
@@ -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
@@ -3,9 +3,9 @@ on:
workflow_dispatch:
pull_request:
paths:
- 'bskylink/**'
- 'Dockerfile.bskylink'
- '.github/workflows/build-and-push-link-aws.yaml'
- "bskylink/**"
- "Dockerfile.bskylink"
- ".github/workflows/build-and-push-link-aws.yaml"
env:
REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }}
@@ -24,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
@@ -3,9 +3,9 @@ on:
workflow_dispatch:
pull_request:
paths:
- 'bskyogcard/**'
- 'Dockerfile.bskyogcard'
- '.github/workflows/build-and-push-ogcard-aws.yaml'
- "bskyogcard/**"
- "Dockerfile.bskyogcard"
- ".github/workflows/build-and-push-ogcard-aws.yaml"
env:
REGISTRY: ${{ secrets.AWS_ECR_REGISTRY_USEAST2_PACKAGES_REGISTRY }}
@@ -24,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
+23 -11
View File
@@ -15,7 +15,10 @@ 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: >
@@ -30,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
@@ -39,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
@@ -50,11 +53,11 @@ jobs:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
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
@@ -79,13 +82,15 @@ jobs:
echo "$json" > google-services.json
- name: 🏗️ EAS Build
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 ${{ inputs.profile || 'testflight-android' }}
--profile $PROFILE
--local --output build.aab --non-interactive
- name: ✍️ Rename Testflight bundle
@@ -96,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
@@ -146,6 +151,11 @@ 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: >
@@ -182,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
+36 -10
View File
@@ -15,7 +15,10 @@ 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: >
@@ -30,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
@@ -39,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,11 +52,11 @@ 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.4"
xcode-version: "26.0"
- name: ☕️ Setup Cocoapods
uses: maxim-lobanov/setup-cocoapods@v1
@@ -61,7 +64,7 @@ jobs:
version: 1.16.2
- name: 💾 Cache Pods
uses: actions/cache@v3
uses: actions/cache@v4
id: pods-cache
with:
path: ./ios/Pods
@@ -91,17 +94,38 @@ jobs:
echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json
- name: 🏗️ EAS Build
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 ${{ inputs.profile || 'testflight' }}
--local --output build.ipa --non-interactive
--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
@@ -128,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
+29 -20
View File
@@ -39,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
@@ -55,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
@@ -86,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
@@ -103,12 +105,15 @@ jobs:
# 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_ENV=${{ inputs.channel || 'testflight' }}" >> .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
@@ -145,15 +150,15 @@ 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
@@ -172,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
@@ -188,11 +193,11 @@ 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
@@ -200,7 +205,7 @@ jobs:
version: 1.16.2
- name: 💾 Cache Pods
uses: actions/cache@v3
uses: actions/cache@v4
id: pods-cache
with:
path: ./ios/Pods
@@ -249,13 +254,15 @@ 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
@@ -276,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
@@ -297,7 +304,7 @@ jobs:
java-version: "17"
- name: ⚙️ Install dependencies
run: yarn install
run: yarn install --frozen-lockfile
- name: 🔤 Compile translations
run: yarn intl:build
@@ -363,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
+5 -5
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@v4
- name: Set up Go tooling
uses: actions/setup-go@v3
with:
go-version: '1.23'
go-version: "1.25"
- 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@v4
- name: Set up Go tooling
uses: actions/setup-go@v3
with:
go-version: '1.23'
go-version: "1.25"
- 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 }}
+9 -5
View File
@@ -32,7 +32,7 @@ jobs:
fi
if [[ "${{ github.event.comment.body }}" == *"ota"* ]]; then
if [[ "$COMMENT" == *"ota"* ]]; then
has_ota=true
else
has_ota=false
@@ -75,6 +75,8 @@ jobs:
steps:
- name: Get PR HEAD SHA
env:
ISSUE_NUMBER: ${{ github.event.issue.number }}
id: pr-info
uses: actions/github-script@v7
with:
@@ -82,7 +84,7 @@ jobs:
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: ${{ github.event.issue.number }}
pull_number: process.env.ISSUE_NUMBER,
});
console.log(`PR HEAD SHA: ${pr.data.head.sha}`);
@@ -116,7 +118,7 @@ jobs:
ref: ${{ steps.pr-info.outputs.head-sha }}
- name: 🔧 Setup Node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: yarn
@@ -140,7 +142,7 @@ jobs:
run: yarn typecheck
- name: 🔨 Setup EAS
uses: expo/expo-github-action@v8
uses: expo/expo-github-action@main
with:
expo-version: latest
eas-version: latest
@@ -184,13 +186,15 @@ jobs:
- 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-${{ github.event.issue.number }}" width=300 height=300>
<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 }}`
---
+16 -9
View File
@@ -29,26 +29,33 @@ 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
@@ -82,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
@@ -110,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
+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
+6
View File
@@ -119,3 +119,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
+591
View File
@@ -0,0 +1,591 @@
# 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
yarn test # Run Jest tests
yarn lint # Run ESLint
yarn typecheck # Run TypeScript type checking
# Internationalization
yarn intl:extract # Extract translation strings
yarn intl:compile # Compile translations for runtime
# 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)
├── 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
```
## 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: `xxs`, `xs`, `sm`, `md`, `lg`, `xl`, `xxl` (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}>
<Dialog.Handle /> {/* Native drag handle */}
<Dialog.ScrollableInner label={_(msg`My Dialog`)}>
<Dialog.Header>
<Dialog.HeaderText>Title</Dialog.HeaderText>
</Dialog.Header>
<Text>Dialog content here</Text>
<Button label="Close" onPress={() => control.close()}>
<ButtonText>Close</ButtonText>
</Button>
</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={X} />
</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'`
- `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, Trans, plural} from '@lingui/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
yarn intl:extract # Extract new strings to locale files
yarn intl:compile # Compile for runtime (required after changes)
```
## 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)})
},
})
}
```
**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
```
### 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)
Platform detection:
```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` |
+2 -2
View File
@@ -1,4 +1,4 @@
FROM golang:1.24.5-bullseye AS build-env
FROM golang:1.25-bookworm AS build-env
WORKDIR /usr/src/social-app
@@ -89,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 -2
View File
@@ -1,4 +1,4 @@
FROM golang:1.24.5-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
+14 -5
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,16 +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"
- waitForAnimationToEnd
- tapOn:
text: "Not Now"
optional: true
# 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"
id: "handleAvailableCheck"
- tapOn:
id: "nextBtn"
- assertVisible: "Give your profile a face"
+19 -33
View File
@@ -17,63 +17,52 @@ appId: xyz.blueskyweb.app
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"
@@ -82,18 +71,15 @@ appId: xyz.blueskyweb.app
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"
+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"
+2 -6
View File
@@ -19,21 +19,17 @@ 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"
# DOES NOT WORK - THE BUTTON IS NOT ACCESSIBLE
# IGNORING FOR NOW, FIX THE COMPONENTS IN THE NEXT RELEASE
# BECAUSE THIS IS A LEGIT A11Y PROBLEM -sfn
- tapOn: "Subscribe to this list"
- tapOn: "Mute accounts"
- tapOn: "Mute list"
+8 -1
View File
@@ -30,7 +30,14 @@ appId: xyz.blueskyweb.app
- assertVisible: "What are your interests?"
- tapOn:
id: "onboardingContinue"
- assertVisible: "You're ready to go!"
- 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:
id: "onboardingFinish"
- tapOn:
+10 -2
View File
@@ -16,7 +16,8 @@ appId: xyz.blueskyweb.app
id: "e2eStartOnboarding"
- tapOn: "Select an avatar"
- waitForAnimationToEnd
- assertVisible: "Search your library…"
- assertVisible: "Photos"
- assertVisible: "Collections"
- tapOn:
point: "50%,22%"
- waitForAnimationToEnd
@@ -27,7 +28,14 @@ appId: xyz.blueskyweb.app
- assertVisible: "What are your interests?"
- tapOn:
id: "onboardingContinue"
- assertVisible: "You're ready to go!"
- 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:
id: "onboardingFinish"
- tapOn:
+2 -1
View File
@@ -17,7 +17,8 @@ appId: xyz.blueskyweb.app
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%"
@@ -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:
+5 -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:
@@ -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,9 +15,11 @@ 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"
+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"
+6 -6
View File
@@ -1,18 +1,18 @@
appId: xyz.blueskyweb.app
---
- launchApp:
appId: "xyz.blueskyweb.app"
clearState: true
appId: "xyz.blueskyweb.app"
clearState: true
- waitForAnimationToEnd
- tapOn: "http://localhost:8081"
- waitForAnimationToEnd
- extendedWaitUntil:
visible: "Continue"
- swipe:
from: "Bluesky"
direction: DOWN
from: "Bluesky"
direction: DOWN
duration: 100
- tapOn:
id: e2eProxyHeaderInput
id: e2eProxyHeaderInput
- inputText: ${output.result}
- pressKey: Enter
- hideKeyboard
+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 () => {
+10 -4
View File
@@ -378,6 +378,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',
@@ -604,6 +605,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',
@@ -951,20 +957,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)
})
+49 -15
View File
@@ -11,7 +11,7 @@ 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'
@@ -40,7 +40,7 @@ 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,
@@ -50,6 +50,10 @@ module.exports = function (_config) {
config: {
usesNonExemptEncryption: false,
},
icon:
PLATFORM === 'web' // web build doesn't like .icon files
? './assets/app-icons/ios_icon_default_next.png'
: './assets/app-icons/ios_icon_default.icon',
infoPlist: {
UIBackgroundModes: ['remote-notification'],
NSCameraUsageDescription:
@@ -112,6 +116,34 @@ module.exports = function (_config) {
'com.apple.security.application-groups': 'group.app.bsky',
},
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:
@@ -143,12 +175,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',
@@ -215,6 +246,7 @@ module.exports = function (_config) {
compileSdkVersion: 35,
targetSdkVersion: 35,
buildToolsVersion: '35.0.0',
buildReactNativeFromSource: IS_PRODUCTION,
},
},
],
@@ -295,18 +327,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',
prerendered: true,
},
next: {
ios: './assets/app-icons/icon_default_next.png',
android: './assets/app-icons/icon_default_next.png',
ios: './assets/app-icons/ios_icon_legacy_dark.png',
android: './assets/app-icons/android_icon_legacy_dark.png',
prerendered: true,
},
@@ -362,6 +389,13 @@ module.exports = function (_config) {
],
['expo-screen-orientation', {initialOrientation: 'PORTRAIT_UP'}],
['expo-location'],
[
'expo-contacts',
{
contactsPermission:
'I agree to allow Bluesky to use my contacts for friend discovery until I opt out.',
},
],
].filter(Boolean),
extra: {
eas: {
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.

Before

Width:  |  Height:  |  Size: 486 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.

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="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 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="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 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

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path d="M0 0h513v342H0z"/><path fill="#0072c6" d="M88.8 136.5c-2.2 12.9-3.4 26.2-3.4 39.8s1.2 27 3.4 39.8L256 228.3l167.2-12.1c2.2-12.9 3.4-26.2 3.4-39.8s-1.2-27-3.4-39.8"/><path fill="#FFF" d="M423.2 219H88.8c15.8 69.8 84.7 122.3 167.2 122.3S407.4 288.8 423.2 219z"/><path fill="#FFDA44" d="M365.9 136.5H146.1l44.9-21.1-23.9-43.5 48.8 9.4L222 32l34 36.2L290 32l6.1 49.3 48.8-9.4-23.9 43.5z"/><g fill="#ce1126"><path d="M256.5 342 0 0v342z"/><path d="M513 342V0L256 342z"/></g></svg>

After

Width:  |  Height:  |  Size: 547 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#00318b" d="M0 0h513v342H0z"/><path fill="#FFF" d="M454.8 265.38c7.94-10.93 13.24-24.27 13.24-40.42V104.89a59.75 59.75 0 0 1-36.02 12.01c-19.64 0-37.07-9.43-48.03-24.01-10.95 14.58-28.39 24.01-48.03 24.01-13.52 0-25.99-4.47-36.02-12v120.06c0 16.16 5.3 29.5 13.24 40.42H454.8z"/><path fill="#8DCCFF" d="M310.23 260.98C332.65 296.96 384 309 384 309s51.35-12.04 73.77-48.02H310.23z"/><path fill="#D87B00" d="M396.66 172.21c.32 1.42 8.72 10.17 17.56 20.15 1.39 1.57-8.74 12.63-6.91 12.59 4.75-.12 19.27-17.26 19.34 6.65.05 15.94-30 27.51-30 27.51h17.47l.65 14.96s4.97-13.34 7.59-16.57c8.1-9.97 20.18-30.07 34.59-27.1s-13.66-13.92-13.66-13.92-5.2-15.19-16.63-16.97c-10.06-1.57-14.29-2.51-26.64-7.3-1.68-.65-3.88-2.32-3.36 0z"/><path fill="#D87B00" d="M359.69 198.69c1.07-.99 4.46-12.63 8.69-25.28.67-1.99 15.31 1.27 14.35-.3-2.47-4.06-24.58-8.08-3.9-20.08 13.79-8 38.82 12.27 38.82 12.27l-8.72-15.14 12.64-8.03s-14.05 2.35-18.14 1.69c-12.68-2.04-36.13-2.48-40.75-16.45s-5.25 18.79-5.25 18.79-10.56 12.08-6.4 22.88c3.66 9.5 4.96 13.64 6.97 26.73.29 1.79-.06 4.53 1.69 2.92z"/><path fill="#D87B00" d="M395.67 219.87c-1.39-.43-13.16 2.49-26.22 5.18-2.06.42-6.59-13.88-7.47-12.26-2.27 4.17 5.36 25.31-15.41 13.45-13.84-7.91-8.89-39.73-8.89-39.73l-8.71 15.14-13.29-6.9s9.09 10.96 10.57 14.84c4.6 11.99 16 32.49 6.24 43.49-9.76 11.01 18.88-4.9 18.88-4.9s15.76 3.07 23-5.96c6.38-7.94 9.3-11.14 19.61-19.45 1.43-1.12 3.97-2.19 1.69-2.9z"/><path fill="#FFF" d="M256.5 0h-23.1L160 48.9V0H96v48.9L22.6 0H0v22.7l46.1 30.7H0v64h46.1L0 148.1V171h22.6L96 121.8V171h64v-49.2l73.4 49.2h23.1v-22.9l-46.6-30.7h46.6v-64h-46.6l46.6-30.7z"/><path fill="#D80027" d="M144 0h-32v69.4H0v32h112V171h32v-69.6h112.5v-32H144z"/><path fill="#D80027" d="M0 171v-11.3l62.5-42.3h22.6L7.3 171zM7.3.1l77.8 53.2H62.5L0 11.1V.1zm249.2 0v11l-63 42.3h-22.6L248.7.1zM248.7 171l-77.8-53.6h22.6l63 42.3V171z"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90 60"><path fill="#ED2024" d="M0 0h90v60H0z"/><path fill="#212121" d="M32.5 12.2v16l7.1 2.5-5 4.9 2.4 3 5.3-5.5 1.2 2.3-3 4.9 3.6 5.6-1.8 2.6 2.8 3.6 2.7-3.7-1.5-2.6 3-5.8-2.7-4.6 1.2-2.3 5.2 5.5 2.5-2.9-5.2-5.1 7.2-2.6V12.2l-5.2 1.9-.1 3.8-3.3.3v-2.6l1.7-2.3 5.6-2.2-2.3-.4 1.4-1.2.9.4-.8-1.4L54 9l-1-1.1L47.5 9l1.4 1.1-3.8 4.9-3.8-4.8 1.3-1.1-5-1.2L36.2 9l-1.5-.4-.8 1.4.9-.6 1.6 1.1-2.3.5 5.5 2 1.6 2.3v2.9l-3.3-.3v-3.6z"/><path fill="#212121" d="M26.2 25h6.4v2.5h-6.4zm0-4.1h6.4v2.7h-6.4zm0-4.2h6.4v2.6h-6.4zm0-4h6.4v2.5h-6.4zM57.4 25h6.4v2.5h-6.4zm0-4.1h6.4v2.7h-6.4zm0-4.2h6.4v2.6h-6.4zm0-4h6.4v2.5h-6.4zM53.4 36.1h6.4V38h-6.4zm-23.2 0h6.4V38h-6.4z"/></svg>

After

Width:  |  Height:  |  Size: 718 B

+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="#D80027" d="M0 0h513v114H0z"/><path fill="#FF9811" d="M0 228h513v114H0z"/></svg>

After

Width:  |  Height:  |  Size: 197 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path d="M0 171h513v171H0z"/><path fill="#D80027" d="M0 0h513v171H0z"/><g fill="#FFDA44"><path d="m332.7 135.6 17.5-8.6-7.4-19-18.7 6.2zm-45.6-56 5.5-18.8-19.1-7.2-8 18zm29.4 23.2 12.2-15.3-14.9-13.9-14.2 13.6zm19.4 68.9 19.5-.8v-21.3l-22.9.2zm-12.6 38.1 18.8 5.5 7.3-19-18-8zm-29 32.4 14.9 12.7 14.4-14.4-13.1-14.7zm-47-147.7 9.8 19.9 21.9 3.3-15.9 15.5 3.6 21.9-19.6-10.4-19.7 10.2 3.8-21.9-15.8-15.5 22-3.1z"/><path d="m250.8 61.3-2.7 18.3c43.1 3.2 77 39.2 77 83.1 0 46-37.3 82.9-83.4 83.4-29.2.3-51.3-14.8-67-33.7l-13.9 12.3c15 19 40.8 39.9 80.9 39.9 56.3 0 101.9-45.6 101.9-101.9.1-53.2-40.7-96.9-92.8-101.4z"/><path fill="#000" d="m291.9 223.4-11.8 14s51.9 38.9 53.6 40.4 5.2 2 9.1-2.7c3.7-4.5 2.8-8.1.9-9.7-2-1.5-51.8-42-51.8-42z"/><path d="M206.1 157.2c-7.7 10.3-7.5 23.1 2.8 30.9 0 0 135.2 101.5 136.9 103s5.2 2 9.1-2.7c3.7-4.5 2.8-8.1.9-9.7-1.9-1.5-149.7-121.5-149.7-121.5zm47.7 99.1 7.3 18.2 19.5-6-4.8-19.1zm-40.4-3.7-2 19.5 20.1 3.6 4.5-19.1zm-35.7-21.2L167.4 248l16.4 12.1 12.5-15.2z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 744 496"><path fill="#3A7DCE" d="M0 0h744v496H0V0z"/><path fill="#fff" d="m120 125 90 63 54-14 23-81 61-36 92 14 105 55 6 90 34 12v92l-65 115-78 24-72-17 18-30-8-32-10 9-162-25-49-85 20-46-49-62z"/></svg>

After

Width:  |  Height:  |  Size: 258 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 0h512v342H0z"/><path fill="#338AF3" d="M0 0h512v114H0zm0 228h512v114H0z"/><circle cx="256.5" cy="171" r="40" fill="#FFDA44" stroke="#d6ab00" stroke-width="5"/></svg>

After

Width:  |  Height:  |  Size: 252 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#10338c" d="M0 0h513v342H0z"/><path fill="#D80027" d="M513 33 95.3 171 513 310.76V342L0 171 513 0z"/><path fill="#FFF" d="M513 287.18v24.58L81.72 171 513 30v24.16"/><path fill="#A2001D" d="m476.98 140.21-21.89 10.68-3.18-15.32 31.19-29.77s-9.42-40.65-13.75-44.98l-112.32 55.82-6.84 36.76-31.9 28.59-.4 34.2 34.29-22.76 67.23-2.66-1.51 38.11h22.23l11.9-44.64 31.55-24.61-6.6-19.42z"/><path fill="#EFC100" stroke="#231F20" stroke-miterlimit="10" d="m317.89 238.41-22.24-11.11 22.24-11.11h144.46v22.22z"/></svg>

After

Width:  |  Height:  |  Size: 583 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 114h513v114H0z"/><path fill="#D80027" d="M0 0h513v114H0zm0 228h513v114H0z"/></svg>

After

Width:  |  Height:  |  Size: 169 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#10338c" d="M0 0h513v342H0z"/><g fill="#FFF"><path d="M222.2 170.7c.3-.3.5-.6.8-.9-.2.3-.5.6-.8.9zM188 212.6l11 22.9 24.7-5.7-11 22.8 19.9 15.8-24.8 5.6.1 25.4-19.9-15.9-19.8 15.9.1-25.4-24.8-5.6 19.9-15.8-11.1-22.8 24.8 5.7zm197.9 28.5 5.2 10.9 11.8-2.7-5.3 10.9 9.5 7.5-11.8 2.6v12.2l-9.4-7.6-9.5 7.6.1-12.2-11.8-2.6 9.5-7.5-5.3-10.9 11.8 2.7zm-48.6-116 5.2 10.9 11.8-2.7-5.3 10.9 9.5 7.5-11.8 2.7v12.1l-9.4-7.6-9.5 7.6.1-12.1-11.9-2.7 9.5-7.5-5.3-10.9L332 136zm48.6-66.2 5.2 10.9 11.8-2.7-5.3 10.9 9.5 7.5-11.8 2.7v12.1l-9.4-7.6-9.5 7.6.1-12.1-11.8-2.7 9.5-7.5-5.3-10.9 11.8 2.7zm42.5 49.7 5.2 10.9 11.8-2.7-5.3 10.9 9.5 7.5-11.8 2.6V150l-9.4-7.6-9.5 7.6v-12.2l-11.8-2.6 9.5-7.5-5.3-10.9 11.8 2.7zM398 166.5l4.1 12.7h13.3l-10.8 7.8 4.2 12.7-10.8-7.9-10.8 7.9 4.1-12.7-10.7-7.8h13.3z"/><path d="M254.8 0v30.6l-45.1 25.1h45.1V115h-59.1l59.1 32.8v22.9h-26.7l-73.5-40.9v40.9H99v-48.6l-87.4 48.6H-1.2v-30.6L44 115H-1.2V55.7h59.1L-1.2 22.8V0h26.7L99 40.8V0h55.6v48.6L242.1 0z"/></g><path fill="#D80027" d="M142.8 0h-32v69.3h-112v32h112v69.4h32v-69.4h112v-32h-112z"/><path fill="#0052B4" d="m154.6 115 100.2 55.7v-15.8L183 115z"/><path fill="#FFF" d="m154.6 115 100.2 55.7v-15.8L183 115z"/><path fill="#D80027" d="m154.6 115 100.2 55.7v-15.8L183 115zm-83.9 0-71.9 39.9v15.8L99 115z"/><path fill="#0052B4" d="M99 55.7-1.2 0v15.7l71.9 40z"/><path fill="#FFF" d="M99 55.7-1.2 0v15.7l71.9 40z"/><path fill="#D80027" d="M99 55.7-1.2 0v15.7l71.9 40zm84 0 71.8-40V0L154.6 55.7z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 363 242"><path fill="#338AF3" d="M0 0h363v242H0z"/><path fill="#FFF" d="M57 96.9 14.7 78.2 57 59.6l18.6-42.2 18.6 42.2 42.3 18.6-42.3 18.7-18.6 42.2z"/><path fill="#f30028" d="m75.6 40.6 11.5 26.1 26.1 11.5-26.1 11.5-11.5 26.1-11.5-26.1L38 78.2l26.1-11.5z"/><path fill="#FFDA44" d="M0 152.2h363v15.7H0zm0 31.4h363v15.7H0z"/></svg>

After

Width:  |  Height:  |  Size: 384 B

+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="#FFDA44" d="M513 210.9H202.2V342h-79.8V210.9H0v-79.8h122.4V0h79.8v131.1H513v61.2z"/><path fill="#D80027" d="M513 149.7v42.6H183.7V342H141V192.3H0v-42.6h141V0h42.7v149.7z"/></svg>

After

Width:  |  Height:  |  Size: 295 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#ef3340" d="M0 0h513v342H0z"/><path fill="#00b5e2" d="M0 0h513v114H0z"/><path fill="#509e2f" d="M0 228h513v114H0z"/><g fill="#FFF"><path d="M265.6 212.6c-23 0-41.6-18.6-41.6-41.6s18.6-41.6 41.6-41.6c7.2 0 13.9 1.8 19.8 5-9.2-9-21.9-14.6-35.8-14.6-28.3 0-51.2 22.9-51.2 51.2s22.9 51.2 51.2 51.2c13.9 0 26.6-5.6 35.8-14.6-5.9 3.2-12.6 5-19.8 5z"/><path d="m297.6 142.2 5.5 15.5 14.9-7.1-7.1 14.9 15.5 5.5-15.5 5.5 7.1 14.9-14.9-7.1-5.5 15.5-5.5-15.5-14.9 7.1 7.1-14.9-15.5-5.5 15.5-5.5-7.1-14.9 14.9 7.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 590 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#10338C" d="M0 0h513.1v342H0z"/><path fill="#F6C500" d="M99.9 0h342v342"/><g fill="#FFF"><path d="M19.9 21.1 40.3 6.2 60.9 21 54 0H26.7z"/><path d="M92.3 25.5 84.4 1.3l-7.8 24.2H51.3l20.5 14.8-7.8 24 20.4-14.8L105 64.3l-7.9-24 20.5-14.9z"/><path d="m136.3 69.2-7.8-24-7.8 24H95.5l20.4 14.9-7.8 24 20.4-14.8 20.6 14.8-7.8-24 20.4-14.9z"/><path d="m179.4 112.3-7.8-24.1-7.8 24.1h-25.3l20.5 14.9-7.8 24 20.4-14.8 20.6 14.8-7.9-24 20.5-15z"/><path d="m222.5 155.3-7.8-24-7.8 24h-25.4l20.6 15-7.8 24 20.4-14.9 20.4 14.9-7.8-24 20.6-15z"/><path d="m265.6 198.4-7.8-24-7.8 24h-25.4l20.6 14.9-7.8 24.1 20.4-14.9 20.4 14.9-7.8-24.2 20.5-14.8z"/><path d="m308.7 241.5-7.9-24-7.8 24h-25.3l20.5 14.8-7.9 24.2 20.6-14.9 20.4 14.8-7.8-24.1 20.5-14.8z"/><path d="m351.7 284.6-7.8-24.2-7.8 24.2h-25.3l20.4 14.8-7.8 24.1 20.5-14.9 20.5 14.9-7.8-24.1 20.4-14.8z"/><path d="m387 303.5-7.9 24.1-25.3.1 19.8 14.3h26.6l19.9-14.4h-25.3z"/></g></svg>

After

Width:  |  Height:  |  Size: 1001 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#ffc726" d="M0 0h513v342H0z"/><path fill="#00267f" d="M0 0h171v342H0zm342 0h171v342H342z"/><path d="m325.74 101.02-31.97 12.4c-.68 1.35-5.79 7.54-8.18 53.06h-17.05v-60.42L256 78.68l-12.54 27v60.8H226.4c-2.39-45.53-7.8-52.48-8.47-53.84l-31.68-11.63c.15.31 15.4 31.34 15.4 78.01v12.54h41.81v71.07h25.08v-71.07h41.81v-12.54c0-24.13 4.17-44.02 7.68-56.46 3.82-13.57 7.7-21.49 7.74-21.57l-.03.03z"/></svg>

After

Width:  |  Height:  |  Size: 475 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 85.333 513 342"><path fill="#2d6e41" d="M0 85.331h513v342H0z"/><circle cx="218.902" cy="256.5" r="115" fill="#F40B32"/></svg>

After

Width:  |  Height:  |  Size: 177 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#fdda25" d="M0 0h513v342H0z"/><path d="M0 0h171v342H0z"/><path fill="#ef3340" d="M342 0h171v342H342z"/></svg>

After

Width:  |  Height:  |  Size: 184 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#3d944f" d="M0 0h513v342H0z"/><path fill="#ef2b2d" d="M0 0h513v171H0z"/><path fill="#FFDA44" d="m256 102.6 16.9 52h54.7l-44.2 32.2 16.8 52-44.2-32.1-44.2 32.1 16.8-52-44.2-32.2h54.7z"/></svg>

After

Width:  |  Height:  |  Size: 266 B

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

After

Width:  |  Height:  |  Size: 194 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#D80027" d="M0 0h513v342H0z"/><path fill="#FFF" d="m222.8 34.3-85.2 34.2 85.2 34.1-85.2 34.1 85.2 34.1-85.2 34.1 85.2 34.1-85.2 34.1 85.2 34.1-85.2 34.8H0V0h137.6z"/></svg>

After

Width:  |  Height:  |  Size: 247 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#D80027" d="M0 0h513v342H0z"/><path fill="#47a644" d="M215.9 170.7 0 314.6V26.8zM513 26.8v287.8L297.1 170.7z"/><path fill="#0052B4" d="M513 26.8 296.1 170.7 513 314.6V342h-41.1L256 197.4 40.1 342H0v-27.4l215.9-143.9L0 26.8V0h40.1L256 143.9 471.9 0H513z"/><path fill="#FFF" d="M513 26.8 297.1 170.7 513 314.6V342h-40L256 197.4 39 342H0v-27.4l215.9-143.9L0 26.8V0h40.1L256 143.9 471.9 0H513z"/><circle cx="251.6" cy="170.7" r="100.2" fill="#FFF"/><path fill="#D80027" stroke="#47a644" stroke-width="3" d="m251.4 103.6 7.4 12.9h14.8l-7.4 12.8 7.4 12.8h-14.8l-7.4 12.9-7.4-12.9h-14.8l7.4-12.8-7.4-12.8H244zm38.8 66.7 7.4 12.9h14.8L305 196l7.4 12.8h-14.8l-7.4 12.9-7.4-12.9h-14.9l7.4-12.8-7.4-12.8h14.9zm-77.2 0 7.4 12.9h14.9l-7.4 12.8 7.4 12.8h-14.9l-7.4 12.9-7.4-12.9h-14.8l7.4-12.8-7.4-12.8h14.8z"/></svg>

After

Width:  |  Height:  |  Size: 878 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 85.333 513 342"><path fill="#008751" d="M0 85.333h513v342H0z"/><path fill="#fcd116" d="M196.666 85.333H513v171H196.666z"/><path fill="#e8112d" d="M196.666 256H513v171H196.666z"/></svg>

After

Width:  |  Height:  |  Size: 236 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="#E6BC00" d="M157.31 199.76s-9.04 43.93-19.31 40.39c-10.62-3.54-17.53-18.76-17.53-18.76l-14.52 21.24s38.18 8.48 41.01 5.47c1.22-1.14 8.21-15.1 10.34-26.05v-22.29zm-56.13 60.57s-2.48 20.18-1.06 22.66c1.24 2.3 39.48 11.33 39.48 11.33s-24.96 16.46-29.74 20.54L91.8 284.94l-.71-24.61h10.09zm11.33-165.69s39.65 41.6 40.36 45.5c.71 3.72-4.25 3.19-4.25 3.19s-44.79-37.53-49.92-41.07c-5.31-3.55 13.81-7.62 13.81-7.62z"/><path fill="#ADADAD" d="M99.41 104.73s16.99-.71 16.64-11.51c-.35-10.62-11.15-14.87-19.12-12.39-7.97 2.3-23.01 13.45-13.63 35.05 9.38 21.42 23.37 29.39 26.2 47.8 0 0-5.46 9.86-19.12.35-16.9-11.77-6.2-38.24-10.44-44.96-4.25-7.08-40.95-38.92-40.95-38.92s-30.24 39.37-18 74.92c16.95 49.21 51.74 31.98 64.61 36.76 0 0-42.13 61.96-49.57 67.09 0 0 24.08 8.32 47.8-18.76 0 0 5.84 9.74 7.08 20.18h10.27c4.78-26.2 51.51-64.26 49.92-82.32-1.77-21.25-49.21-49.39-51.69-73.29z"/><path fill="#E6BC00" d="M359.17 201.27s8.96 42.43 19.23 38.89c10.62-3.54 17.53-18.76 17.53-18.76l14.52 21.24s-37 8.48-39.83 5.47c-1.21-1.14-9.32-13.79-11.52-24.66l.07-22.18zm56.05 59.06s2.48 20.18 1.06 22.66c-1.24 2.3-39.48 11.33-39.48 11.33s24.96 16.46 29.74 20.54l18.06-29.92.71-24.61h-10.09zM403.89 94.64s-39.65 41.6-40.36 45.5c-.71 3.72 4.25 3.19 4.25 3.19s44.79-37.53 49.92-41.07c5.14-3.55-13.81-7.62-13.81-7.62z"/><path fill="#125ECC" d="M157.31 87.06H359.1v145.46c0 16.06-9.69 21.39-21.91 31.85l-45.92 39.41c-18.25 15.62-47.91 15.57-66.07 0l-46.01-39.43c-12.08-10.35-21.88-15.71-21.88-31.82V87.06z"/><path fill="#FFE600" d="M200.55 147.71c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41zm57.65-3c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41zm57.65 3c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41zM214.96 274.43c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41c.01 7.96-6.45 14.41-14.41 14.41zm43.24 14.42c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41c0 7.95-6.45 14.41-14.41 14.41zm43.24-14.42c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41z"/><path fill="#D60537" d="M157.31 175.36H359.1v57.65H157.31v-57.65z"/><path fill="#EACE00" d="M142.9 43.82s57.65-14.41 115.31-14.41 115.31 14.41 115.31 14.41l-14.41 57.65s-50.45-14.41-100.89-14.41-100.89 14.41-100.89 14.41L142.9 43.82z"/><path fill="#7A6920" d="M258.2 72.65c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41zm57.65 5c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41zm-115.3 0c-7.96 0-14.41-6.45-14.41-14.41s6.45-14.41 14.41-14.41 14.41 6.45 14.41 14.41-6.45 14.41-14.41 14.41z"/><path fill="#ADADAD" d="M365.08 178.02c-1.59 18.06 45.14 56.12 49.92 82.32h10.27c1.24-10.44 7.08-20.18 7.08-20.18 23.72 27.09 47.8 18.76 47.8 18.76-7.44-5.13-49.57-67.09-49.57-67.09 12.88-4.78 47.67 12.45 64.61-36.76 12.24-35.55-18-74.92-18-74.92s-36.7 31.84-40.95 38.92c-4.25 6.73 6.46 33.2-10.44 44.96-13.66 9.51-19.12-.35-19.12-.35 2.83-18.41 16.82-26.38 26.2-47.8 9.38-21.6-5.66-32.75-13.63-35.05-7.97-2.48-18.76 1.77-19.12 12.39-.35 10.8 16.64 11.51 16.64 11.51-2.48 23.9-49.92 52.04-51.69 73.29z"/><circle cx="258.2" cy="204.19" r="16.93" fill="#FFF"/></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#c8102e" d="M0 0h513v342H0z"/><path fill="#012169" d="M0 .1h256.5v171H0z"/><path fill="#FFF" d="M256 0h-22.6L160 48.9V0H96v48.9L22.6 0H0v22.7l46.1 30.7H0v64h46.1L0 148.1v22.6h22.6L96 121.8v48.9h64v-48.9l73.4 48.9H256v-22.6l-46.1-30.7H256v-64h-46.1L256 22.7z"/><path fill="#c8102e" d="M144 0h-32v69.4H0v32h112v69.3h32v-69.3h112v-32H144z"/><path fill="#c8102e" 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"/><g transform="translate(13 5)"><path fill="#fff" d="M303.9 94.94v99.69c0 59.81 79.75 99.69 79.75 99.69s79.75-39.88 79.75-99.69V94.94H303.9z"/><path fill="#2F8F22" d="M436.37 254.44H330.93c23.13 25.08 52.72 39.88 52.72 39.88s29.59-14.8 52.72-39.88z"/><circle cx="383.65" cy="214.56" r="39.88" fill="#65B5D2"/><circle cx="343.77" cy="194.63" r="19.94" fill="#c8102e"/><circle cx="423.52" cy="194.63" r="19.94" fill="#c8102e"/><circle cx="383.65" cy="154.75" r="19.94" fill="#c8102e"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 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 d="m0 193.74 513 127.19V214.26L0 97.08z"/><path fill="#FFF" d="M513 234.26v-86.67L0 20.41v86.67"/><g fill="#D80027" stroke="#231F20" stroke-miterlimit="10" stroke-width="3"><path d="M306.4 134.01a50.3 50.3 0 0 1 6.07 24.02c0 21.55-13.51 39.94-32.52 47.19v-59.51c5.7-1.19 10-6.37 10-12.59 6.9 0 12.5-5.75 12.5-12.85h-.42c6.9 0 12.91-5.75 12.91-12.85h-34.99V76.58l-14.99-27.71-15 27.71v30.84h-34.99c0 7.1 6.01 12.85 12.91 12.85h-.42c0 7.1 5.6 12.85 12.5 12.85 0 6.22 4.29 11.4 9.99 12.59v61.37c-22.09-5.39-38.48-25.3-38.48-49.05 0-8.7 2.2-16.88 6.07-24.02-10.96 11.21-17.72 26.53-17.72 43.44 0 34.32 27.82 62.15 62.15 62.15s62.15-27.83 62.15-62.15c0-16.91-6.77-32.24-17.72-43.44z"/><path d="M198.46 226.81s20.69 27.71 66.5 27.71 66.5-27.71 66.5-27.71l13.47 28.37s-21.03 27.71-79.97 27.71-79.97-27.71-79.97-27.71l13.47-28.37zm-69.22-93.63h20.88l24.93 27.26v73.45h-26.28v-68.37zm270.76 0h-20.88l-24.93 27.26v73.45h26.27v-68.37z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#d52b1e" d="M0 0h513v114H0z"/><path fill="#f9e300" d="M0 114h513v114H0z"/><path fill="#007934" d="M0 228h513v114H0z"/></svg>

After

Width:  |  Height:  |  Size: 199 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="#012a87" d="M0 342h513V0z"/><path fill="#f9d90f" d="M250.4 0H0v166.9z"/><path fill="#dc171d" d="m140.4 118.3 12.2 21.2h24.5l-12.3 21.1 12.3 21.2h-24.5L140.4 203l-12.2-21.2h-24.5l12.3-21.2-12.3-21.1h24.5z"/><circle cx="140.4" cy="160.6" r="57.7" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="9"/></svg>

After

Width:  |  Height:  |  Size: 432 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#DC171D" d="M512 342H0V.7h512V342z"/><path fill="#012A87" d="M512 342H0V171.3h512V342z"/><path fill="#FFF" d="M256 342 0 171.3 256 .7l256 170.7L256 342z"/><path fill="#F9D90F" d="m199.2 249.5 21.7-66.8-56.8-41.2h70.5L256 74.7l21.7 66.8h70.2l-56.8 41.2 21.7 66.8-56.8-41.3z"/></svg>

After

Width:  |  Height:  |  Size: 356 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600"><path fill="#dc171d" d="M0 0h900v600H0z"/><path fill="#fff" d="M450 168.787 215.691 300 450 431.213 684.309 300z"/><path fill="#dc171f" d="M281.477 336.852V376h69.961l290.727-52.4V376h-93.668z"/><path fill="#012a87" d="M188 288H20V20h418v128zm524 0h168V20H462v128zm-524 24H20v268h418V452zm524 0h168v268H462V452z"/><path fill="#f9d90f" d="m450 199.5 8.068 24.827h26.105l-21.12 15.346 8.067 24.827L450 249.157 428.88 264.5l8.066-24.827-21.119-15.345 26.105-.001z"/><path fill="#008830" d="M281.477 336.852c2.712-8.848 8.614-12.77 16.594-10.995 4.94-18.73 27.739-22.07 36.786-12.857l22.273 22.37c4.837 2.251 12.207 3.095 17.326 3.095 6.33.1 5.621 3.005 10.91 3.106 14.096.27 51.143.458 57.857 0 2.75-.187 64.134-67.857 64.134-67.857 5.12-6.31 18.453-8.333 25.714-3.214 6.786 6.429 13.929 7.143 18.929 2.857 4.405-6.547 14.392-7.309 20.714-3.571l69.45 53.815L548.497 376H351.438l-69.96-39.148z"/></svg>

After

Width:  |  Height:  |  Size: 961 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="#012a87" d="M0 342h513V0z"/><path fill="#f9d90f" d="M250.4 0H0v166.9z"/><path fill="#dc171d" d="m140.4 118.3 12.2 21.2h24.5l-12.3 21.1 12.3 21.2h-24.5L140.4 203l-12.2-21.2h-24.5l12.3-21.2-12.3-21.1h24.5z"/><circle cx="140.4" cy="160.6" r="57.7" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="9"/></svg>

After

Width:  |  Height:  |  Size: 432 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#009b3a" d="M0 0h513v342H0z"/><path fill="#fedf00" d="m256.5 19.3 204.9 151.4L256.5 322 50.6 170.7z"/><circle cx="256.5" cy="171" r="80.4" fill="#FFF"/><path fill="#002776" d="M215.9 165.7c-13.9 0-27.4 2.1-40.1 6 .6 43.9 36.3 79.3 80.3 79.3 27.2 0 51.3-13.6 65.8-34.3-24.9-31-63.2-51-106-51zm119 20.3c.9-5 1.5-10.1 1.5-15.4 0-44.4-36-80.4-80.4-80.4-33.1 0-61.5 20.1-73.9 48.6 10.9-2.2 22.1-3.4 33.6-3.4 46.8.1 89 19.5 119.2 50.6z"/></svg>

After

Width:  |  Height:  |  Size: 513 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#ffc72c" d="M0 0h513v342H0z"/><path fill="#00778b" d="M0 0h513v114H0zm0 228h513v114H0z"/><path d="M256 171 0 342V0z"/></svg>

After

Width:  |  Height:  |  Size: 199 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#FF7415" d="M0 0h513v342H0z"/><path fill="#FFDA44" d="M513 0H0v342"/><path fill="none" stroke="#FFF" stroke-miterlimit="10" stroke-width="42" d="M128.7 255.5s35 54 67.3 32.4c56.9-37.9-68.9-108.6-2.9-152.6 58.3-38.8 76.6 103.5 137.6 62.8 59-39.3-64.7-111.4-9.2-148.4 33.4-22.2 67.1 32.6 67.1 32.6"/></svg>

After

Width:  |  Height:  |  Size: 379 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 33.333 1100 733.333"><path fill="#ef2b2d" d="M0 0h1100v800H0z"/><path fill="#fff" d="M300 0h200v800H300z"/><path fill="#fff" d="M0 300h1100v200H0z"/><path fill="#002868" d="M350 0h100v800H350z"/><path fill="#002868" d="M0 350h1100v100H0z"/></svg>

After

Width:  |  Height:  |  Size: 298 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="#6da9d2" d="M0 238h513v104H0zM0 0h513v104H0z"/><path d="M0 125.5h513v89.656H0z"/></svg>

After

Width:  |  Height:  |  Size: 201 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#007C30" d="M0 0h513v342H0z"/><path fill="#CE1720" d="M0 230h513V0H0"/><path fill="#FFF" d="M100 230V0H0v342h513-413z"/><path fill="#CE1720" d="M28 159.6 8.6 128.2 28 97.4l19.3 30.8zm44.6 0-19.3-31.4 19.3-30.8L92 128.2zM28 241.2 8.6 209.8 28 179l19.3 30.8zm44.6 0-19.3-31.4L72.6 179 92 209.8z"/><path fill="none" stroke="#CE1720" stroke-width="7" d="m28 73.8-16.1-26L28 22.2l16 25.6zm44.6 0-16-26 16-25.6 16.1 25.6zM28 318l-16.1-26.1L28 266.3l16 25.6zm44.6 0-16-26.1 16-25.6 16.1 25.6z"/></svg>

After

Width:  |  Height:  |  Size: 569 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#003e87" d="M0 0h513v342H0z"/><circle cx="260.9" cy="170.9" r="118.9" fill="#FFF"/><circle cx="261.9" cy="173.1" r="94.5" fill="none" stroke="#6DA544" stroke-miterlimit="10" stroke-width="18"/><g stroke="#000"><path fill="#003e87" d="m261.9 151.5-50.6 23.4v20c0 11.8 6.1 22.8 16.2 28.9L262 239l34.5-15.2c10-6.2 16.2-17.1 16.2-28.9v-20l-50.8-23.4z"/><path fill="#FFDA44" d="M211.3 128.1h101.3v46.7H211.3z"/></g><path fill="#ce1127" d="M0 0h513v35H0zm0 306h513v35H0z"/></svg>

After

Width:  |  Height:  |  Size: 548 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="red" d="M0 0h142v342H0zm371 0h142v342H371zm-64.5 206 50.4-25.2-25.2-12.6V143l-50.4 25.2 25.2-50.4h-25.2L256.1 80l-25.2 37.8h-25.2l25.2 50.4-50.4-25.2v25.2l-25.2 12.6 50.4 25.2-12.6 25.2h50.4V269h25.2v-37.8h50.4z"/></svg>

After

Width:  |  Height:  |  Size: 334 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="green" d="M0 0h513v342H0z"/><path fill="#FFDA44" d="m422.7 252.4 6.2 12.8 13.8-3.2-6.2 12.8 11.2 8.8-13.9 3.2V301l-11.1-8.9-11.1 8.9v-14.2l-13.8-3.2 11.1-8.8-6.2-12.8 13.9 3.2zm-46.6-136.3 6.2 12.9 13.8-3.2-6.2 12.8 11.2 8.8-13.9 3.1v14.3l-11.1-8.9-11.1 8.9.1-14.3-13.9-3.1 11.1-8.8-6.2-12.8L370 129zm37-77.8 6.2 12.8 13.8-3.2-6.2 12.8 11.2 8.9-13.9 3.1v14.2L413.1 78 402 86.9l.1-14.2-13.9-3.1 11.1-8.9-6.2-12.8 13.9 3.2zm51.8 58.4 6.2 12.8 13.9-3.2-6.3 12.8 11.2 8.9-13.9 3.1.1 14.2-11.2-8.9-11.1 8.9.1-14.2L440 128l11.2-8.9-6.3-12.8 13.9 3.2zm-28 68.1 4.9 14.8h15.6l-12.6 9.2 4.8 14.9-12.7-9.2-12.6 9.2 4.8-14.9-12.6-9.2h15.6zM306.8 254.7c-49.2 0-89.1-39.9-89.1-89.1s39.9-89.1 89.1-89.1c15.3 0 29.8 3.9 42.4 10.7C329.4 67.9 302.3 56 272.5 56c-60.5 0-109.6 49.1-109.6 109.6S212 275.3 272.5 275.3c29.8 0 56.9-11.9 76.6-31.3-12.6 6.8-27 10.7-42.3 10.7zM140.4 59.5C129.7 41 109.7 28.6 86.8 28.6S44 41 33.3 59.5h107.1zm.2.4-53.8 53.8-53.7-53.8C28 68.9 25 79.3 25 90.5c0 34.2 27.7 61.9 61.9 61.9s61.9-27.7 61.9-61.9c-.1-11.2-3.1-21.6-8.2-30.6z"/><path fill="#A2001D" d="M71.4 98.2v52.2c4.9 1.3 10.1 1.9 15.5 1.9s10.5-.7 15.5-1.9V98.2h-31z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#338AF3" d="M0 0h513v342H0z"/><path fill="#FFDA44" d="M513 66.9V0H411.7L0 274.4V342h100.3z"/><path fill="#D80027" d="M513 0v40.1L60.2 342H0v-40.8L451.8 0z"/><path fill="#FFDA44" d="m93.6 31.2 16.3 50.4H163l-42.9 31.2 16.4 50.5-42.9-31.2-43 31.2L67 112.8 24.1 81.6h53.1z"/></svg>

After

Width:  |  Height:  |  Size: 353 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342"><path fill="#d21034" d="M0 0h513v342H0z"/><path fill="#3a9927" d="M0 171h211.5v85.3H0zm300.5 0H512v85.3H300.5z"/><path fill="#003082" d="M0 0v85.3h211.5V0h89v85.3H513V0z"/><path fill="#FFF" d="M300.5 85.3H512v85.3H300.5zM0 85.3h211.5v85.3H0z"/><path fill="#ffce00" d="M300.5 342h-89v-86H0v86h513v-86H300.5zM105.7 8.6l8.6 26.2h27.5L119.5 51l8.6 26.2L105.7 61 83.4 77.2 91.9 51 69.6 34.8h27.6z"/></svg>

After

Width:  |  Height:  |  Size: 463 B

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