From c13b1374d7ff25b913405b96cc568dce6c929be0 Mon Sep 17 00:00:00 2001 From: Ana Date: Mon, 28 Jul 2025 20:22:58 -0700 Subject: [PATCH 01/45] add: toasts to storybook --- src/view/screens/Storybook/Toasts.tsx | 69 +++++++++++++++++++++++++++ src/view/screens/Storybook/index.tsx | 2 + 2 files changed, 71 insertions(+) create mode 100644 src/view/screens/Storybook/Toasts.tsx diff --git a/src/view/screens/Storybook/Toasts.tsx b/src/view/screens/Storybook/Toasts.tsx new file mode 100644 index 0000000000..714afdfbdd --- /dev/null +++ b/src/view/screens/Storybook/Toasts.tsx @@ -0,0 +1,69 @@ +import {View} from 'react-native' + +import {atoms as a} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import {H1} from '#/components/Typography' +import * as Toast from '#/view/com/util/Toast' +import * as ToastHelpers from '#/view/com/util/ToastHelpers' + +export function Toasts() { + return ( + +

Toasts

+ + + + + + + + + + + + +
+ ) +} diff --git a/src/view/screens/Storybook/index.tsx b/src/view/screens/Storybook/index.tsx index a6c2ecdde3..afcc1c4e73 100644 --- a/src/view/screens/Storybook/index.tsx +++ b/src/view/screens/Storybook/index.tsx @@ -20,6 +20,7 @@ import {Settings} from './Settings' import {Shadows} from './Shadows' import {Spacing} from './Spacing' import {Theming} from './Theming' +import {Toasts} from './Toasts' import {Typography} from './Typography' export function Storybook() { @@ -122,6 +123,7 @@ function StorybookInner() { + From e5457c946a5bf56fafde790ced9014e1cb73cd34 Mon Sep 17 00:00:00 2001 From: Caidan Williams Date: Tue, 29 Jul 2025 17:04:47 -0700 Subject: [PATCH 29/45] feat(ui): improve suggested follow placeholder card Now matches the same size and shape as the rendered card, which prevents content layout shift. --- src/components/FeedInterstitials.tsx | 31 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index aab54b7df7..e4419838dd 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -25,7 +25,7 @@ import { type ViewStyleProp, web, } from '#/alf' -import {Button} from '#/components/Button' +import {Button, ButtonText} from '#/components/Button' import * as FeedCard from '#/components/FeedCard' import {ArrowRight_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow' import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' @@ -64,15 +64,30 @@ function CardOuter({ export function SuggestedFollowPlaceholder() { const t = useTheme() + return ( - - - - - - + + + + + + + + - + + + ) } From 7b4ec21e3e60cb25197fb277f3ba54fa627e4e1e Mon Sep 17 00:00:00 2001 From: Caidan Williams Date: Tue, 29 Jul 2025 17:05:13 -0700 Subject: [PATCH 30/45] refactor(ui): adjust border styles in ProfileGrid card --- src/components/FeedInterstitials.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index e4419838dd..9bdfcbc5ed 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -308,10 +308,8 @@ export function ProfileGrid({ Date: Tue, 29 Jul 2025 17:29:22 -0700 Subject: [PATCH 31/45] feat(ui): add "See More Suggested Profiles" card --- src/components/FeedInterstitials.tsx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index 9bdfcbc5ed..2a3a00ba7d 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -415,6 +415,8 @@ export function ProfileGrid({ style={[a.overflow_visible]}> {content} + + @@ -424,6 +426,32 @@ export function ProfileGrid({ ) } +function SeeMoreSuggestedProfilesCard() { + const navigation = useNavigation() + const t = useTheme() + const {_} = useLingui() + + return ( + + ) +} + export function SuggestedFeeds() { const numFeedsToDisplay = 3 const t = useTheme() From 2b92697e3ec67c058119e88c4779e04a3cb952ce Mon Sep 17 00:00:00 2001 From: Austin McKinley Date: Tue, 29 Jul 2025 17:51:55 -0700 Subject: [PATCH 32/45] switch to using DefaultServeMux, include go.mod and go.sum changes --- bskyweb/cmd/embedr/server.go | 4 +++- bskyweb/go.mod | 41 +++++++++++++++++++----------------- bskyweb/go.sum | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/bskyweb/cmd/embedr/server.go b/bskyweb/cmd/embedr/server.go index 07c25afad7..d8df4276f2 100644 --- a/bskyweb/cmd/embedr/server.go +++ b/bskyweb/cmd/embedr/server.go @@ -13,6 +13,8 @@ import ( "syscall" "time" + _ "net/http/pprof" + "github.com/bluesky-social/indigo/atproto/identity" "github.com/bluesky-social/indigo/util/cliutil" "github.com/bluesky-social/indigo/xrpc" @@ -70,7 +72,7 @@ func serve(cctx *cli.Context) error { return err } - metricsMux := http.NewServeMux() + metricsMux := http.DefaultServeMux metricsMux.Handle("/metrics", promhttp.Handler()) metricsHttpd := &http.Server{ diff --git a/bskyweb/go.mod b/bskyweb/go.mod index 630d5d256b..af0c5c6fc3 100644 --- a/bskyweb/go.mod +++ b/bskyweb/go.mod @@ -1,24 +1,26 @@ module github.com/bluesky-social/social-app/bskyweb -go 1.23 +go 1.24 -toolchain go1.23.4 +toolchain go1.24.5 require ( - github.com/bluesky-social/indigo v0.0.0-20250605010711-db9bb60025dc + github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a github.com/flosch/pongo2/v6 v6.0.0 github.com/ipfs/go-log v1.0.5 github.com/joho/godotenv v1.5.1 - github.com/klauspost/compress v1.17.3 - github.com/labstack/echo/v4 v4.11.3 + github.com/klauspost/compress v1.18.0 + github.com/labstack/echo/v4 v4.13.3 github.com/urfave/cli/v2 v2.25.7 ) +require github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect github.com/carlmjohnson/versioninfo v0.22.5 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -52,14 +54,15 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect - github.com/labstack/gommon v0.4.1 // indirect + github.com/labstack/echo-contrib v0.17.4 + github.com/labstack/gommon v0.4.2 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc v1.0.4 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/jwx/v2 v2.0.12 // indirect github.com/lestrrat-go/option v1.0.1 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect @@ -73,10 +76,10 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/orandin/slog-gorm v1.3.2 // indirect github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect - github.com/prometheus/client_golang v1.17.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -94,14 +97,14 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sync v0.14.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect + golang.org/x/time v0.11.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.36.6 // indirect gorm.io/driver/postgres v1.5.7 // indirect gorm.io/driver/sqlite v1.5.5 // indirect gorm.io/gorm v1.25.9 // indirect diff --git a/bskyweb/go.sum b/bskyweb/go.sum index c0ba4f6cc1..cbd815ebed 100644 --- a/bskyweb/go.sum +++ b/bskyweb/go.sum @@ -4,12 +4,16 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bluesky-social/indigo v0.0.0-20250605010711-db9bb60025dc h1:chbGD59Cn1mw07kbq9Uvb8WUFIr1dcoL5TOhT+I9bV4= github.com/bluesky-social/indigo v0.0.0-20250605010711-db9bb60025dc/go.mod h1:ovyxp8AMO1Hoe838vMJUbqHTZaAR8ABM3g3TXu+A5Ng= +github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a h1:S12KN45uIkRglMHC8PqD/Vsz0+u3KbIaBF/6rit8/Pg= +github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a/go.mod h1:0XUyOCRtL4/OiyeqMTmr6RlVHQMDgw3LS7CfibuZR5Q= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc= github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -104,6 +108,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -113,10 +119,16 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo-contrib v0.17.4 h1:g5mfsrJfJTKv+F5uNKCyrjLK7js+ZW6HTjg4FnDxxgk= +github.com/labstack/echo-contrib v0.17.4/go.mod h1:9O7ZPAHUeMGTOAfg80YqQduHzt0CzLak36PZRldYrZ0= github.com/labstack/echo/v4 v4.11.3 h1:Upyu3olaqSHkCjs1EJJwQ3WId8b8b1hxbogyommKktM= github.com/labstack/echo/v4 v4.11.3/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws= +github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= +github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= github.com/labstack/gommon v0.4.1 h1:gqEff0p/hTENGMABzezPoPSRtIh1Cvw0ueMOe0/dfOk= github.com/labstack/gommon v0.4.1/go.mod h1:TyTrpPqxR5KMk8LKVtLmfMjeQ5FEkBYdxLYPw/WfrOM= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= @@ -132,6 +144,8 @@ github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNB github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -154,6 +168,8 @@ github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7B github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/orandin/slog-gorm v1.3.2 h1:C0lKDQPAx/pF+8K2HL7bdShPwOEJpPM0Bn80zTzxU1g= @@ -165,12 +181,20 @@ github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4 github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -254,6 +278,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -273,6 +299,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -281,6 +309,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -299,6 +329,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -312,8 +344,12 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -334,6 +370,8 @@ golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSm golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From 27c51401d2d828db5a52c99dd9b73a700ba65368 Mon Sep 17 00:00:00 2001 From: Austin McKinley Date: Tue, 29 Jul 2025 17:54:11 -0700 Subject: [PATCH 33/45] git tidy --- bskyweb/go.mod | 4 +--- bskyweb/go.sum | 50 ++++++-------------------------------------------- 2 files changed, 7 insertions(+), 47 deletions(-) diff --git a/bskyweb/go.mod b/bskyweb/go.mod index af0c5c6fc3..f4689af5ae 100644 --- a/bskyweb/go.mod +++ b/bskyweb/go.mod @@ -28,7 +28,6 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/google/uuid v1.4.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect @@ -65,7 +64,6 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -76,7 +74,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/orandin/slog-gorm v1.3.2 // indirect github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect - github.com/prometheus/client_golang v1.22.0 // indirect + github.com/prometheus/client_golang v1.22.0 github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.63.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect diff --git a/bskyweb/go.sum b/bskyweb/go.sum index cbd815ebed..144ad7cfa3 100644 --- a/bskyweb/go.sum +++ b/bskyweb/go.sum @@ -2,16 +2,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bluesky-social/indigo v0.0.0-20250605010711-db9bb60025dc h1:chbGD59Cn1mw07kbq9Uvb8WUFIr1dcoL5TOhT+I9bV4= -github.com/bluesky-social/indigo v0.0.0-20250605010711-db9bb60025dc/go.mod h1:ovyxp8AMO1Hoe838vMJUbqHTZaAR8ABM3g3TXu+A5Ng= github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a h1:S12KN45uIkRglMHC8PqD/Vsz0+u3KbIaBF/6rit8/Pg= github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a/go.mod h1:0XUyOCRtL4/OiyeqMTmr6RlVHQMDgw3LS7CfibuZR5Q= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc= github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -37,10 +33,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -106,8 +100,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= @@ -119,14 +111,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo-contrib v0.17.4 h1:g5mfsrJfJTKv+F5uNKCyrjLK7js+ZW6HTjg4FnDxxgk= github.com/labstack/echo-contrib v0.17.4/go.mod h1:9O7ZPAHUeMGTOAfg80YqQduHzt0CzLak36PZRldYrZ0= -github.com/labstack/echo/v4 v4.11.3 h1:Upyu3olaqSHkCjs1EJJwQ3WId8b8b1hxbogyommKktM= -github.com/labstack/echo/v4 v4.11.3/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= -github.com/labstack/gommon v0.4.1 h1:gqEff0p/hTENGMABzezPoPSRtIh1Cvw0ueMOe0/dfOk= -github.com/labstack/gommon v0.4.1/go.mod h1:TyTrpPqxR5KMk8LKVtLmfMjeQ5FEkBYdxLYPw/WfrOM= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= @@ -142,18 +132,13 @@ github.com/lestrrat-go/jwx/v2 v2.0.12/go.mod h1:Mq4KN1mM7bp+5z/W5HS8aCNs5RKZ911G github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -179,20 +164,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4TCkEuWIckKvdHFeJH/huIFJ9/cXOB0= github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -221,8 +198,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= @@ -276,8 +253,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -297,8 +272,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -307,8 +280,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -322,13 +293,10 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -342,12 +310,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -368,8 +332,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 0a00e02c701aee2151b8f708e9b53af81a41d44e Mon Sep 17 00:00:00 2001 From: pfrazee <1270099+pfrazee@users.noreply.github.com> Date: Wed, 30 Jul 2025 02:51:39 +0000 Subject: [PATCH 34/45] Nightly source-language update --- src/locale/locales/en/messages.po | 53 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index 69532591c3..3a5480a5cd 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -966,8 +966,8 @@ msgstr "" #: src/components/hooks/useFollowMethods.ts:35 #: src/components/hooks/useFollowMethods.ts:50 -#: src/components/ProfileCard.tsx:457 -#: src/components/ProfileCard.tsx:478 +#: src/components/ProfileCard.tsx:484 +#: src/components/ProfileCard.tsx:505 #: src/view/com/profile/FollowButton.tsx:38 #: src/view/com/profile/FollowButton.tsx:48 msgid "An issue occurred, please try again." @@ -1262,7 +1262,7 @@ msgid "Birthday" msgstr "" #: src/components/PostControls/PostMenu/PostMenuItems.tsx:757 -#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:319 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:320 #: src/view/com/profile/ProfileMenu.tsx:473 msgid "Block" msgstr "" @@ -1423,23 +1423,20 @@ msgstr "" msgid "Books" msgstr "" -#: src/components/FeedInterstitials.tsx:379 +#: src/components/FeedInterstitials.tsx:436 msgid "Browse more accounts on the Explore page" msgstr "" -#: src/components/FeedInterstitials.tsx:517 +#: src/components/FeedInterstitials.tsx:566 msgid "Browse more feeds on the Explore page" msgstr "" -#: src/components/FeedInterstitials.tsx:359 -#: src/components/FeedInterstitials.tsx:362 -#: src/components/FeedInterstitials.tsx:498 -#: src/components/FeedInterstitials.tsx:501 +#: src/components/FeedInterstitials.tsx:547 +#: src/components/FeedInterstitials.tsx:550 msgid "Browse more suggestions" msgstr "" -#: src/components/FeedInterstitials.tsx:387 -#: src/components/FeedInterstitials.tsx:526 +#: src/components/FeedInterstitials.tsx:575 msgid "Browse more suggestions on the Explore page" msgstr "" @@ -3618,7 +3615,7 @@ msgid "Flexible" msgstr "" #. User is not following this account, click to follow -#: src/components/ProfileCard.tsx:490 +#: src/components/ProfileCard.tsx:517 #: src/components/ProfileHoverCard/index.web.tsx:494 #: src/components/ProfileHoverCard/index.web.tsx:505 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:245 @@ -3696,7 +3693,7 @@ msgid "Followers you know" msgstr "" #. User is following this account, click to unfollow -#: src/components/ProfileCard.tsx:484 +#: src/components/ProfileCard.tsx:511 #: src/components/ProfileHoverCard/index.web.tsx:493 #: src/components/ProfileHoverCard/index.web.tsx:504 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:241 @@ -3711,7 +3708,7 @@ msgctxt "feed-name" msgid "Following" msgstr "" -#: src/components/ProfileCard.tsx:447 +#: src/components/ProfileCard.tsx:474 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:89 msgid "Following {0}" msgstr "" @@ -5459,7 +5456,7 @@ msgstr "" msgid "No likes yet" msgstr "" -#: src/components/ProfileCard.tsx:469 +#: src/components/ProfileCard.tsx:496 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:110 msgid "No longer following {0}" msgstr "" @@ -7398,6 +7395,18 @@ msgstr "" msgid "See jobs at Bluesky" msgstr "" +#: src/components/FeedInterstitials.tsx:397 +msgid "See more" +msgstr "" + +#: src/components/FeedInterstitials.tsx:444 +msgid "See more accounts you might like" +msgstr "" + +#: src/components/FeedInterstitials.tsx:395 +msgid "See more suggested profiles on the Explore page" +msgstr "" + #: src/view/screens/SavedFeeds.tsx:213 msgid "See this guide" msgstr "" @@ -7975,7 +7984,7 @@ msgstr "" msgid "Signed in as @{0}" msgstr "" -#: src/components/FeedInterstitials.tsx:343 +#: src/components/FeedInterstitials.tsx:389 msgid "Similar accounts" msgstr "" @@ -8005,7 +8014,7 @@ msgstr "" msgid "Some of your verifications are invalid." msgstr "" -#: src/components/FeedInterstitials.tsx:480 +#: src/components/FeedInterstitials.tsx:529 msgid "Some other feeds you might like" msgstr "" @@ -8237,7 +8246,7 @@ msgstr "" msgid "Suggested Accounts" msgstr "" -#: src/components/FeedInterstitials.tsx:345 +#: src/components/FeedInterstitials.tsx:391 msgid "Suggested for you" msgstr "" @@ -8421,7 +8430,7 @@ msgstr "" msgid "That's everything!" msgstr "" -#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:315 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:316 #: src/view/com/profile/ProfileMenu.tsx:461 msgid "The account will be able to interact with you after unblocking." msgstr "" @@ -9046,7 +9055,7 @@ msgstr "" #: src/components/dms/MessagesListBlockedFooter.tsx:112 #: src/components/dms/MessagesListBlockedFooter.tsx:119 #: src/screens/Profile/Header/ProfileHeaderStandard.tsx:203 -#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:319 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:320 #: src/view/com/profile/ProfileMenu.tsx:473 #: src/view/screens/ProfileList.tsx:723 msgid "Unblock" @@ -9064,7 +9073,7 @@ msgstr "" msgid "Unblock account" msgstr "" -#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:313 +#: src/screens/Profile/Header/ProfileHeaderStandard.tsx:314 #: src/view/com/profile/ProfileMenu.tsx:455 msgid "Unblock Account?" msgstr "" @@ -9571,7 +9580,7 @@ msgstr "" msgid "View {0}'s avatar" msgstr "" -#: src/components/ProfileCard.tsx:118 +#: src/components/ProfileCard.tsx:124 #: src/screens/Profile/components/ProfileFeedHeader.tsx:454 #: src/screens/Search/components/SearchProfileCard.tsx:36 #: src/screens/VideoFeed/index.tsx:790 From 34ea6e8f3499eeeb1013dfbf7c4dcd3bdcf149a3 Mon Sep 17 00:00:00 2001 From: Ana Date: Tue, 29 Jul 2025 18:15:32 -0700 Subject: [PATCH 35/45] update: toast styles that reuse consistent style --- src/view/com/util/Toast.tsx | 182 +++++++++----------------- src/view/com/util/Toast.web.tsx | 146 ++++++++++----------- src/view/screens/Storybook/Toasts.tsx | 139 ++++++++++++-------- 3 files changed, 215 insertions(+), 252 deletions(-) diff --git a/src/view/com/util/Toast.tsx b/src/view/com/util/Toast.tsx index fc9bdf6727..2f8888bef4 100644 --- a/src/view/com/util/Toast.tsx +++ b/src/view/com/util/Toast.tsx @@ -6,8 +6,8 @@ import { GestureHandlerRootView, } from 'react-native-gesture-handler' import Animated, { - FadeInUp, - FadeOutUp, + FadeIn, + FadeOut, runOnJS, useAnimatedReaction, useAnimatedStyle, @@ -17,53 +17,36 @@ import Animated, { } from 'react-native-reanimated' import RootSiblings from 'react-native-root-siblings' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import { - FontAwesomeIcon, - type Props as FontAwesomeProps, -} from '@fortawesome/react-native-fontawesome' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' -import {isWeb} from '#/platform/detection' import {atoms as a, useTheme} from '#/alf' import {Text} from '#/components/Typography' +import { + type ToastType, + TOAST_TYPE_TO_ICON, + getToastTypeStyles, + TOAST_ANIMATION_CONFIG, +} from './Toast.style' const TIMEOUT = 2e3 -export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' - -const TOAST_TYPE_TO_ICON: Record = { - default: 'check', - success: 'check', - error: 'exclamation', - warning: 'circle-exclamation', - info: 'info', -} - -export function show( - message: string, - type: ToastType | FontAwesomeProps['icon'] = 'default', -) { +export function show(message: string, type: ToastType = 'default') { if (process.env.NODE_ENV === 'test') { return } - const icon = - typeof type === 'string' && type in TOAST_TYPE_TO_ICON - ? TOAST_TYPE_TO_ICON[type as ToastType] - : (type as FontAwesomeProps['icon']) - AccessibilityInfo.announceForAccessibility(message) const item = new RootSiblings( - item.destroy()} />, + item.destroy()} />, ) } function Toast({ message, - icon, + type, destroy, }: { message: string - icon: FontAwesomeProps['icon'] + type: ToastType destroy: () => void }) { const t = useTheme() @@ -72,6 +55,10 @@ function Toast({ const dismissSwipeTranslateY = useSharedValue(0) const [cardHeight, setCardHeight] = useState(0) + const toastStyles = getToastTypeStyles(t) + const colors = toastStyles[type] + const IconComponent = TOAST_TYPE_TO_ICON[type] + // for the exit animation to work on iOS the animated component // must not be the root component // so we need to wrap it in a view and unmount the toast ahead of time @@ -169,103 +156,58 @@ function Toast({ } }) - // Web-specific styles for better compatibility - const webContainerStyle = isWeb - ? { - position: 'absolute' as const, - top: topOffset, - left: 16, - right: 16, - zIndex: 9999, - pointerEvents: 'auto' as const, - } - : {} - - const webToastStyle = isWeb - ? { - backgroundColor: - t.name === 'dark' ? t.palette.contrast_25 : t.palette.white, - shadowColor: '#000', - shadowOffset: {width: 0, height: 10}, - shadowOpacity: 0.1, - shadowRadius: 15, - elevation: 10, - borderColor: t.palette.contrast_300, - borderWidth: 1, - borderRadius: 8, - minHeight: 60, - } - : {} - return ( {alive && ( - setCardHeight(evt.nativeEvent.layout.height)} - accessibilityRole="alert" - accessible={true} - accessibilityLabel={message} - accessibilityHint="" - onAccessibilityEscape={hideAndDestroyImmediately} - style={[ - a.flex_1, - isWeb - ? webToastStyle - : [ - t.name === 'dark' ? t.atoms.bg_contrast_25 : t.atoms.bg, - a.shadow_lg, - t.atoms.border_contrast_medium, - a.rounded_sm, - a.border, - ], - !isWeb && animatedStyle, - ]}> - - - - - - - - {message} - - + entering={FadeIn.duration(TOAST_ANIMATION_CONFIG.duration)} + exiting={FadeOut.duration(TOAST_ANIMATION_CONFIG.duration * 0.7)} + onLayout={evt => setCardHeight(evt.nativeEvent.layout.height)} + accessibilityRole="alert" + accessible={true} + accessibilityLabel={message} + accessibilityHint="" + onAccessibilityEscape={hideAndDestroyImmediately} + style={[ + a.flex_1, + {backgroundColor: colors.backgroundColor}, + a.shadow_sm, + {borderColor: colors.borderColor, borderWidth: 1}, + a.rounded_sm, + animatedStyle, + ]}> + + + + - - + + + {message} + + + + )} diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx index 949dce7ef6..331a8b5398 100644 --- a/src/view/com/util/Toast.web.tsx +++ b/src/view/com/util/Toast.web.tsx @@ -4,28 +4,19 @@ import {useEffect, useState} from 'react' import {Pressable, StyleSheet, Text, View} from 'react-native' +import {atoms as a, useTheme} from '#/alf' import { - FontAwesomeIcon, - type FontAwesomeIconStyle, - type Props as FontAwesomeProps, -} from '@fortawesome/react-native-fontawesome' -import {atoms as a, useBreakpoints, useTheme} from '#/alf' + type ToastType, + TOAST_TYPE_TO_ICON, + getToastTypeStyles, + getToastWebAnimationStyles, + TOAST_WEB_KEYFRAMES, +} from './Toast.style' -const DURATION = 60000 - -export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' - -const TOAST_TYPE_TO_ICON: Record = { - default: 'check', - success: 'check', - error: 'exclamation', - warning: 'circle-exclamation', - info: 'info', -} +const DURATION = 3500 interface ActiveToast { text: string - icon: FontAwesomeProps['icon'] type: ToastType } type GlobalSetActiveToast = (_activeToast: ActiveToast | undefined) => void @@ -40,50 +31,45 @@ let toastTimeout: NodeJS.Timeout | undefined type ToastContainerProps = {} export const ToastContainer: React.FC = ({}) => { const [activeToast, setActiveToast] = useState() + const [isExiting, setIsExiting] = useState(false) + useEffect(() => { globalSetActiveToast = (t: ActiveToast | undefined) => { - setActiveToast(t) + if (!t && activeToast) { + setIsExiting(true) + setTimeout(() => { + setActiveToast(t) + setIsExiting(false) + }, 200) + } else { + setActiveToast(t) + setIsExiting(false) + } } - }) + }, [activeToast]) + + useEffect(() => { + const styleId = 'toast-animations' + if (!document.getElementById(styleId)) { + const style = document.createElement('style') + style.id = styleId + style.textContent = TOAST_WEB_KEYFRAMES + document.head.appendChild(style) + } + }, []) const t = useTheme() - const TOAST_TYPE_TO_STYLES = { - default: { - backgroundColor: t.atoms.text_contrast_low.color, - borderColor: t.atoms.border_contrast_medium.borderColor, - iconColor: '#fff', - textColor: '#fff', - }, - success: { - backgroundColor: '#059669', - borderColor: '#047857', - iconColor: '#fff', - textColor: '#fff', - }, - error: { - backgroundColor: t.palette.negative_100, - borderColor: t.palette.negative_400, - iconColor: t.palette.negative_600, - textColor: t.palette.negative_600, - }, - warning: { - backgroundColor: t.palette.negative_500, - borderColor: t.palette.negative_600, - iconColor: '#fff', - textColor: '#fff', - }, - info: { - backgroundColor: t.atoms.text_contrast_low.color, - borderColor: t.atoms.border_contrast_medium.borderColor, - iconColor: '#fff', - textColor: '#fff', - }, - } - + const toastTypeStyles = getToastTypeStyles(t) const toastStyles = activeToast - ? TOAST_TYPE_TO_STYLES[activeToast.type] - : TOAST_TYPE_TO_STYLES.default + ? toastTypeStyles[activeToast.type] + : toastTypeStyles.default + + const IconComponent = activeToast + ? TOAST_TYPE_TO_ICON[activeToast.type] + : TOAST_TYPE_TO_ICON.default + + const animationStyles = getToastWebAnimationStyles() return ( <> @@ -94,18 +80,24 @@ export const ToastContainer: React.FC = ({}) => { { backgroundColor: toastStyles.backgroundColor, borderColor: toastStyles.borderColor, + ...(isExiting + ? animationStyles.exiting + : animationStyles.entering), }, ]}> - + + + = ({}) => { // methods // = -export function show( - text: string, - type: ToastType | FontAwesomeProps['icon'] = 'default', -) { +export function show(text: string, type: ToastType = 'default') { if (toastTimeout) { clearTimeout(toastTimeout) } - // Determine if type is a semantic type or direct icon - const isSemanticType = typeof type === 'string' && type in TOAST_TYPE_TO_ICON - const icon = isSemanticType - ? TOAST_TYPE_TO_ICON[type as ToastType] - : (type as FontAwesomeProps['icon']) - const toastType = isSemanticType ? (type as ToastType) : 'default' - - globalSetActiveToast?.({text, icon, type: toastType}) + globalSetActiveToast?.({text, type}) toastTimeout = setTimeout(() => { globalSetActiveToast?.(undefined) }, DURATION) @@ -161,10 +143,10 @@ const styles = StyleSheet.create({ bottom: 20, // @ts-ignore web only width: 'calc(100% - 40px)', - maxWidth: 350, + maxWidth: 380, padding: 20, flexDirection: 'row', - alignItems: 'center', + alignItems: 'flex-start', borderRadius: 10, borderWidth: 1, }, @@ -175,6 +157,14 @@ const styles = StyleSheet.create({ bottom: 0, right: 0, }, + iconContainer: { + width: 32, + height: 32, + borderRadius: 16, + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + }, icon: { flexShrink: 0, }, diff --git a/src/view/screens/Storybook/Toasts.tsx b/src/view/screens/Storybook/Toasts.tsx index 714afdfbdd..5197ec2f4c 100644 --- a/src/view/screens/Storybook/Toasts.tsx +++ b/src/view/screens/Storybook/Toasts.tsx @@ -1,68 +1,99 @@ -import {View} from 'react-native' +import {View, Pressable} from 'react-native' -import {atoms as a} from '#/alf' -import {Button, ButtonText} from '#/components/Button' -import {H1} from '#/components/Typography' +import {atoms as a, useTheme} from '#/alf' +import {Text, H1} from '#/components/Typography' +import { + type ToastType, + TOAST_TYPE_TO_ICON, + getToastTypeStyles, +} from '#/view/com/util/Toast.style' import * as Toast from '#/view/com/util/Toast' -import * as ToastHelpers from '#/view/com/util/ToastHelpers' + +function ToastPreview({message, type}: {message: string; type: ToastType}) { + const t = useTheme() + const toastStyles = getToastTypeStyles(t) + const colors = toastStyles[type] + const IconComponent = TOAST_TYPE_TO_ICON[type] + + return ( + Toast.show(message, type)} + style={[ + {backgroundColor: colors.backgroundColor}, + a.shadow_sm, + {borderColor: colors.borderColor}, + a.rounded_sm, + a.border, + a.px_sm, + a.py_sm, + a.flex_row, + a.gap_sm, + a.align_center, + ]}> + + + + + + {message} + + + + ) +} export function Toasts() { return ( -

Toasts

+

Toast Examples

- - + + + + - + + + - + + + - + + + - + + + + + + + ) From 61969e8dfa92fb200b83f13f691093ccaab2a031 Mon Sep 17 00:00:00 2001 From: Ana Date: Tue, 29 Jul 2025 23:28:10 -0700 Subject: [PATCH 36/45] add: Toast.style --- src/view/com/util/Toast.style.tsx | 167 ++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 src/view/com/util/Toast.style.tsx diff --git a/src/view/com/util/Toast.style.tsx b/src/view/com/util/Toast.style.tsx new file mode 100644 index 0000000000..9a7e6b82d1 --- /dev/null +++ b/src/view/com/util/Toast.style.tsx @@ -0,0 +1,167 @@ +import {type Theme, select} from '#/alf' +import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' +import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' +import {Check_Stroke2_Corner0_Rounded as SuccessIcon} from '#/components/icons/Check' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' + +export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' + +export const TOAST_ANIMATION_CONFIG = { + duration: 300, + damping: 15, + stiffness: 150, + mass: 0.8, + overshootClamping: false, + restSpeedThreshold: 0.01, + restDisplacementThreshold: 0.01, +} + +export const TOAST_TYPE_TO_ICON = { + default: SuccessIcon, + success: SuccessIcon, + error: ErrorIcon, + warning: WarningIcon, + info: CircleInfo, +} + +export const getToastTypeStyles = (t: Theme) => ({ + default: { + backgroundColor: select(t.name, { + light: t.atoms.bg_contrast_25.backgroundColor, + dim: t.atoms.bg_contrast_100.backgroundColor, + dark: t.atoms.bg_contrast_100.backgroundColor, + }), + borderColor: select(t.name, { + light: t.atoms.border_contrast_low.borderColor, + dim: t.atoms.border_contrast_high.borderColor, + dark: t.atoms.border_contrast_high.borderColor, + }), + iconColor: select(t.name, { + light: t.atoms.text_contrast_medium.color, + dim: t.atoms.text_contrast_medium.color, + dark: t.atoms.text_contrast_medium.color, + }), + textColor: select(t.name, { + light: t.atoms.text_contrast_medium.color, + dim: t.atoms.text_contrast_medium.color, + dark: t.atoms.text_contrast_medium.color, + }), + }, + success: { + backgroundColor: select(t.name, { + light: t.palette.primary_100, + dim: t.palette.primary_100, + dark: t.palette.primary_50, + }), + borderColor: select(t.name, { + light: t.palette.primary_500, + dim: t.palette.primary_500, + dark: t.palette.primary_500, + }), + iconColor: select(t.name, { + light: t.palette.primary_500, + dim: t.palette.primary_600, + dark: t.palette.primary_600, + }), + textColor: select(t.name, { + light: t.palette.primary_500, + dim: t.palette.primary_600, + dark: t.palette.primary_600, + }), + }, + error: { + backgroundColor: select(t.name, { + light: t.palette.negative_200, + dim: t.palette.negative_25, + dark: t.palette.negative_25, + }), + borderColor: select(t.name, { + light: t.palette.negative_300, + dim: t.palette.negative_300, + dark: t.palette.negative_300, + }), + iconColor: select(t.name, { + light: t.palette.negative_600, + dim: t.palette.negative_600, + dark: t.palette.negative_600, + }), + textColor: select(t.name, { + light: t.palette.negative_600, + dim: t.palette.negative_600, + dark: t.palette.negative_600, + }), + }, + warning: { + backgroundColor: select(t.name, { + light: t.atoms.bg_contrast_25.backgroundColor, + dim: t.atoms.bg_contrast_100.backgroundColor, + dark: t.atoms.bg_contrast_100.backgroundColor, + }), + borderColor: select(t.name, { + light: t.atoms.border_contrast_low.borderColor, + dim: t.atoms.border_contrast_high.borderColor, + dark: t.atoms.border_contrast_high.borderColor, + }), + iconColor: select(t.name, { + light: t.atoms.text_contrast_medium.color, + dim: t.atoms.text_contrast_medium.color, + dark: t.atoms.text_contrast_medium.color, + }), + textColor: select(t.name, { + light: t.atoms.text_contrast_medium.color, + dim: t.atoms.text_contrast_medium.color, + dark: t.atoms.text_contrast_medium.color, + }), + }, + info: { + backgroundColor: select(t.name, { + light: t.atoms.bg_contrast_25.backgroundColor, + dim: t.atoms.bg_contrast_100.backgroundColor, + dark: t.atoms.bg_contrast_100.backgroundColor, + }), + borderColor: select(t.name, { + light: t.atoms.border_contrast_low.borderColor, + dim: t.atoms.border_contrast_high.borderColor, + dark: t.atoms.border_contrast_high.borderColor, + }), + iconColor: select(t.name, { + light: t.atoms.text_contrast_medium.color, + dim: t.atoms.text_contrast_medium.color, + dark: t.atoms.text_contrast_medium.color, + }), + textColor: select(t.name, { + light: t.atoms.text_contrast_medium.color, + dim: t.atoms.text_contrast_medium.color, + dark: t.atoms.text_contrast_medium.color, + }), + }, +}) + +export const getToastWebAnimationStyles = () => ({ + entering: { + animation: 'toastFadeIn 0.3s ease-out forwards', + }, + exiting: { + animation: 'toastFadeOut 0.2s ease-in forwards', + }, +}) + +export const TOAST_WEB_KEYFRAMES = ` + @keyframes toastFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + + @keyframes toastFadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } + } +` From 67ba92fa624f8edb2878fe65ac19439dff042c29 Mon Sep 17 00:00:00 2001 From: Ana Date: Wed, 30 Jul 2025 00:02:03 -0700 Subject: [PATCH 37/45] update: imports for toast --- src/view/com/util/Toast.tsx | 2 +- src/view/com/util/Toast.web.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/view/com/util/Toast.tsx b/src/view/com/util/Toast.tsx index 2f8888bef4..9c20e56be8 100644 --- a/src/view/com/util/Toast.tsx +++ b/src/view/com/util/Toast.tsx @@ -25,7 +25,7 @@ import { TOAST_TYPE_TO_ICON, getToastTypeStyles, TOAST_ANIMATION_CONFIG, -} from './Toast.style' +} from '#/view/com/util/Toast.style' const TIMEOUT = 2e3 diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx index 331a8b5398..fbe31528e3 100644 --- a/src/view/com/util/Toast.web.tsx +++ b/src/view/com/util/Toast.web.tsx @@ -11,7 +11,7 @@ import { getToastTypeStyles, getToastWebAnimationStyles, TOAST_WEB_KEYFRAMES, -} from './Toast.style' +} from '#/view/com/util/Toast.style' const DURATION = 3500 @@ -146,7 +146,7 @@ const styles = StyleSheet.create({ maxWidth: 380, padding: 20, flexDirection: 'row', - alignItems: 'flex-start', + alignItems: 'center', borderRadius: 10, borderWidth: 1, }, From f472c7f540840df7d98af22719742944e70ccfa2 Mon Sep 17 00:00:00 2001 From: Ana Date: Wed, 30 Jul 2025 00:14:28 -0700 Subject: [PATCH 38/45] update sorting --- src/view/com/util/Toast.style.tsx | 6 +++--- src/view/com/util/Toast.tsx | 18 +++++++++--------- src/view/com/util/Toast.web.tsx | 7 ++++--- src/view/screens/Storybook/Toasts.tsx | 18 +++++++++--------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/view/com/util/Toast.style.tsx b/src/view/com/util/Toast.style.tsx index 9a7e6b82d1..6bfb12bc1c 100644 --- a/src/view/com/util/Toast.style.tsx +++ b/src/view/com/util/Toast.style.tsx @@ -1,8 +1,8 @@ -import {type Theme, select} from '#/alf' -import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' -import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' import {Check_Stroke2_Corner0_Rounded as SuccessIcon} from '#/components/icons/Check' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' +import {type Theme, select} from '#/alf' +import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' diff --git a/src/view/com/util/Toast.tsx b/src/view/com/util/Toast.tsx index 9c20e56be8..6fe04f793f 100644 --- a/src/view/com/util/Toast.tsx +++ b/src/view/com/util/Toast.tsx @@ -1,3 +1,12 @@ +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' +import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' +import { + type ToastType, + getToastTypeStyles, + TOAST_ANIMATION_CONFIG, + TOAST_TYPE_TO_ICON, +} from '#/view/com/util/Toast.style' import {useEffect, useMemo, useRef, useState} from 'react' import {AccessibilityInfo, View} from 'react-native' import { @@ -17,15 +26,6 @@ import Animated, { } from 'react-native-reanimated' import RootSiblings from 'react-native-root-siblings' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' -import {atoms as a, useTheme} from '#/alf' -import {Text} from '#/components/Typography' -import { - type ToastType, - TOAST_TYPE_TO_ICON, - getToastTypeStyles, - TOAST_ANIMATION_CONFIG, -} from '#/view/com/util/Toast.style' const TIMEOUT = 2e3 diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx index fbe31528e3..9ed1f03975 100644 --- a/src/view/com/util/Toast.web.tsx +++ b/src/view/com/util/Toast.web.tsx @@ -4,14 +4,15 @@ import {useEffect, useState} from 'react' import {Pressable, StyleSheet, Text, View} from 'react-native' -import {atoms as a, useTheme} from '#/alf' + import { - type ToastType, - TOAST_TYPE_TO_ICON, getToastTypeStyles, getToastWebAnimationStyles, + TOAST_TYPE_TO_ICON, TOAST_WEB_KEYFRAMES, + type ToastType, } from '#/view/com/util/Toast.style' +import {atoms as a, useTheme} from '#/alf' const DURATION = 3500 diff --git a/src/view/screens/Storybook/Toasts.tsx b/src/view/screens/Storybook/Toasts.tsx index 5197ec2f4c..da0f1c416e 100644 --- a/src/view/screens/Storybook/Toasts.tsx +++ b/src/view/screens/Storybook/Toasts.tsx @@ -1,13 +1,13 @@ -import {View, Pressable} from 'react-native' +import {Pressable,View} from 'react-native' -import {atoms as a, useTheme} from '#/alf' -import {Text, H1} from '#/components/Typography' -import { - type ToastType, - TOAST_TYPE_TO_ICON, - getToastTypeStyles, -} from '#/view/com/util/Toast.style' import * as Toast from '#/view/com/util/Toast' +import { + getToastTypeStyles, + TOAST_TYPE_TO_ICON, + type ToastType, +} from '#/view/com/util/Toast.style' +import {atoms as a, useTheme} from '#/alf' +import {H1,Text} from '#/components/Typography' function ToastPreview({message, type}: {message: string; type: ToastType}) { const t = useTheme() @@ -16,7 +16,7 @@ function ToastPreview({message, type}: {message: string; type: ToastType}) { const IconComponent = TOAST_TYPE_TO_ICON[type] return ( - Toast.show(message, type)} style={[ {backgroundColor: colors.backgroundColor}, From f8781270e5df1d3730192ac463331845af028b4b Mon Sep 17 00:00:00 2001 From: Ana Date: Wed, 30 Jul 2025 00:36:14 -0700 Subject: [PATCH 39/45] update: toast style after lint --- src/view/com/util/Toast.style.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/com/util/Toast.style.tsx b/src/view/com/util/Toast.style.tsx index 6bfb12bc1c..dfa4f4fd63 100644 --- a/src/view/com/util/Toast.style.tsx +++ b/src/view/com/util/Toast.style.tsx @@ -1,7 +1,7 @@ +import {select, type Theme} from '#/alf' import {Check_Stroke2_Corner0_Rounded as SuccessIcon} from '#/components/icons/Check' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' -import {type Theme, select} from '#/alf' import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' From 315e7341bf99243bb0249567f62ca20d147e7b53 Mon Sep 17 00:00:00 2001 From: Ana Date: Wed, 30 Jul 2025 00:40:34 -0700 Subject: [PATCH 40/45] update: lint fixes for toast.tsx --- src/view/com/util/Toast.tsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/view/com/util/Toast.tsx b/src/view/com/util/Toast.tsx index 6fe04f793f..7258eac9d8 100644 --- a/src/view/com/util/Toast.tsx +++ b/src/view/com/util/Toast.tsx @@ -1,12 +1,3 @@ -import {atoms as a, useTheme} from '#/alf' -import {Text} from '#/components/Typography' -import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' -import { - type ToastType, - getToastTypeStyles, - TOAST_ANIMATION_CONFIG, - TOAST_TYPE_TO_ICON, -} from '#/view/com/util/Toast.style' import {useEffect, useMemo, useRef, useState} from 'react' import {AccessibilityInfo, View} from 'react-native' import { @@ -27,6 +18,16 @@ import Animated, { import RootSiblings from 'react-native-root-siblings' import {useSafeAreaInsets} from 'react-native-safe-area-context' +import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' +import { + getToastTypeStyles, + TOAST_ANIMATION_CONFIG, + TOAST_TYPE_TO_ICON, + type ToastType, +} from '#/view/com/util/Toast.style' +import {atoms as a, useTheme} from '#/alf' +import {Text} from '#/components/Typography' + const TIMEOUT = 2e3 export function show(message: string, type: ToastType = 'default') { From d141921abf23d0694ce399615e70011492434e69 Mon Sep 17 00:00:00 2001 From: Ana Date: Wed, 30 Jul 2025 00:48:56 -0700 Subject: [PATCH 41/45] add: prettier formating --- src/view/screens/Storybook/Toasts.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/view/screens/Storybook/Toasts.tsx b/src/view/screens/Storybook/Toasts.tsx index da0f1c416e..54735f7bbd 100644 --- a/src/view/screens/Storybook/Toasts.tsx +++ b/src/view/screens/Storybook/Toasts.tsx @@ -1,4 +1,4 @@ -import {Pressable,View} from 'react-native' +import {Pressable, View} from 'react-native' import * as Toast from '#/view/com/util/Toast' import { @@ -7,7 +7,7 @@ import { type ToastType, } from '#/view/com/util/Toast.style' import {atoms as a, useTheme} from '#/alf' -import {H1,Text} from '#/components/Typography' +import {H1, Text} from '#/components/Typography' function ToastPreview({message, type}: {message: string; type: ToastType}) { const t = useTheme() @@ -16,7 +16,8 @@ function ToastPreview({message, type}: {message: string; type: ToastType}) { const IconComponent = TOAST_TYPE_TO_ICON[type] return ( - Toast.show(message, type)} style={[ {backgroundColor: colors.backgroundColor}, From 18add1cff9eb36568439d8ea80180c36c1a30260 Mon Sep 17 00:00:00 2001 From: Ana Date: Wed, 30 Jul 2025 01:08:14 -0700 Subject: [PATCH 42/45] update type errors --- src/view/com/util/Toast.style.tsx | 12 +++++++++++- src/view/com/util/Toast.tsx | 5 +++-- src/view/com/util/Toast.web.tsx | 4 ++-- src/view/screens/Storybook/Toasts.tsx | 5 +++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/view/com/util/Toast.style.tsx b/src/view/com/util/Toast.style.tsx index dfa4f4fd63..8b952fd00b 100644 --- a/src/view/com/util/Toast.style.tsx +++ b/src/view/com/util/Toast.style.tsx @@ -4,7 +4,17 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' -export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' +export type ToastType = + | 'default' + | 'success' + | 'error' + | 'warning' + | 'info' + | 'xmark' + | 'exclamation-circle' + | 'check' + | 'clipboard-check' + | 'circle-exclamation' export const TOAST_ANIMATION_CONFIG = { duration: 300, diff --git a/src/view/com/util/Toast.tsx b/src/view/com/util/Toast.tsx index 7258eac9d8..4c999ca2a4 100644 --- a/src/view/com/util/Toast.tsx +++ b/src/view/com/util/Toast.tsx @@ -57,8 +57,9 @@ function Toast({ const [cardHeight, setCardHeight] = useState(0) const toastStyles = getToastTypeStyles(t) - const colors = toastStyles[type] - const IconComponent = TOAST_TYPE_TO_ICON[type] + const colors = toastStyles[type as keyof typeof toastStyles] + const IconComponent = + TOAST_TYPE_TO_ICON[type as keyof typeof TOAST_TYPE_TO_ICON] // for the exit animation to work on iOS the animated component // must not be the root component diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx index 9ed1f03975..1abbaa0031 100644 --- a/src/view/com/util/Toast.web.tsx +++ b/src/view/com/util/Toast.web.tsx @@ -63,11 +63,11 @@ export const ToastContainer: React.FC = ({}) => { const toastTypeStyles = getToastTypeStyles(t) const toastStyles = activeToast - ? toastTypeStyles[activeToast.type] + ? toastTypeStyles[activeToast.type as keyof typeof toastTypeStyles] : toastTypeStyles.default const IconComponent = activeToast - ? TOAST_TYPE_TO_ICON[activeToast.type] + ? TOAST_TYPE_TO_ICON[activeToast.type as keyof typeof TOAST_TYPE_TO_ICON] : TOAST_TYPE_TO_ICON.default const animationStyles = getToastWebAnimationStyles() diff --git a/src/view/screens/Storybook/Toasts.tsx b/src/view/screens/Storybook/Toasts.tsx index 54735f7bbd..4c17f1c332 100644 --- a/src/view/screens/Storybook/Toasts.tsx +++ b/src/view/screens/Storybook/Toasts.tsx @@ -12,8 +12,9 @@ import {H1, Text} from '#/components/Typography' function ToastPreview({message, type}: {message: string; type: ToastType}) { const t = useTheme() const toastStyles = getToastTypeStyles(t) - const colors = toastStyles[type] - const IconComponent = TOAST_TYPE_TO_ICON[type] + const colors = toastStyles[type as keyof typeof toastStyles] + const IconComponent = + TOAST_TYPE_TO_ICON[type as keyof typeof TOAST_TYPE_TO_ICON] return ( Date: Wed, 30 Jul 2025 18:17:57 +0300 Subject: [PATCH 43/45] Fix dataSet for noFeedback links (#8745) * fix dataSet for noFeedback links * rm memo * rm useless spread --- src/view/com/util/Link.tsx | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 6a931d9a40..496b771821 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -101,13 +101,9 @@ export const Link = memo(function Link({ {name: 'activate', label: title}, ] - const dataSet = useMemo(() => { - const ds = {...dataSetProp} - if (anchorNoUnderline) { - ds.noUnderline = 1 - } - return ds - }, [dataSetProp, anchorNoUnderline]) + const dataSet = anchorNoUnderline + ? {...dataSetProp, noUnderline: 1} + : dataSetProp if (noFeedback) { return ( @@ -125,6 +121,8 @@ export const Link = memo(function Link({ onAccessibilityAction?.(e) } }} + // @ts-ignore web only -sfn + dataSet={dataSet} {...props} android_ripple={{ color: t.atoms.bg_contrast_25.backgroundColor, @@ -198,13 +196,9 @@ export const TextLink = memo(function TextLink({ console.error('Unable to detect mismatching label') } - const dataSet = useMemo(() => { - const ds = {...dataSetProp} - if (anchorNoUnderline) { - ds.noUnderline = 1 - } - return ds - }, [dataSetProp, anchorNoUnderline]) + const dataSet = anchorNoUnderline + ? {...dataSetProp, noUnderline: 1} + : dataSetProp const onPress = useCallback( (e?: Event) => { From db7bdae51a1a06e67856b887e4e63a183fa5f479 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 30 Jul 2025 18:18:36 +0300 Subject: [PATCH 44/45] Convert old toast types to new ones, mark as deprecated (#8746) * convert old types to new types * add depreciation warning for old warnings * rm as consts --- src/view/com/util/Toast.style.tsx | 38 +++++++++++++++++++++++++------ src/view/com/util/Toast.tsx | 27 ++++++++++++++++++---- src/view/com/util/Toast.web.tsx | 13 +++++++---- 3 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/view/com/util/Toast.style.tsx b/src/view/com/util/Toast.style.tsx index 8b952fd00b..3869e6890b 100644 --- a/src/view/com/util/Toast.style.tsx +++ b/src/view/com/util/Toast.style.tsx @@ -4,18 +4,42 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/ico import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' -export type ToastType = - | 'default' - | 'success' - | 'error' - | 'warning' - | 'info' +export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info' + +export type LegacyToastType = | 'xmark' | 'exclamation-circle' | 'check' | 'clipboard-check' | 'circle-exclamation' +export const convertLegacyToastType = ( + type: ToastType | LegacyToastType, +): ToastType => { + switch (type) { + // these ones are fine + case 'default': + case 'success': + case 'error': + case 'warning': + case 'info': + return type + // legacy ones need conversion + case 'xmark': + return 'error' + case 'exclamation-circle': + return 'warning' + case 'check': + return 'success' + case 'clipboard-check': + return 'success' + case 'circle-exclamation': + return 'warning' + default: + return 'default' + } +} + export const TOAST_ANIMATION_CONFIG = { duration: 300, damping: 15, @@ -165,7 +189,7 @@ export const TOAST_WEB_KEYFRAMES = ` opacity: 1; } } - + @keyframes toastFadeOut { from { opacity: 1; diff --git a/src/view/com/util/Toast.tsx b/src/view/com/util/Toast.tsx index 4c999ca2a4..54ef7042d2 100644 --- a/src/view/com/util/Toast.tsx +++ b/src/view/com/util/Toast.tsx @@ -20,7 +20,9 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import { + convertLegacyToastType, getToastTypeStyles, + type LegacyToastType, TOAST_ANIMATION_CONFIG, TOAST_TYPE_TO_ICON, type ToastType, @@ -30,14 +32,30 @@ import {Text} from '#/components/Typography' const TIMEOUT = 2e3 -export function show(message: string, type: ToastType = 'default') { +// Use type overloading to mark certain types as deprecated -sfn +// https://stackoverflow.com/a/78325851/13325987 +export function show(message: string, type?: ToastType): void +/** + * @deprecated type is deprecated - use one of `'default' | 'success' | 'error' | 'warning' | 'info'` + */ +export function show(message: string, type?: LegacyToastType): void +export function show( + message: string, + type: ToastType | LegacyToastType = 'default', +): void { if (process.env.NODE_ENV === 'test') { return } AccessibilityInfo.announceForAccessibility(message) const item = new RootSiblings( - item.destroy()} />, + ( + item.destroy()} + /> + ), ) } @@ -57,9 +75,8 @@ function Toast({ const [cardHeight, setCardHeight] = useState(0) const toastStyles = getToastTypeStyles(t) - const colors = toastStyles[type as keyof typeof toastStyles] - const IconComponent = - TOAST_TYPE_TO_ICON[type as keyof typeof TOAST_TYPE_TO_ICON] + const colors = toastStyles[type] + const IconComponent = TOAST_TYPE_TO_ICON[type] // for the exit animation to work on iOS the animated component // must not be the root component diff --git a/src/view/com/util/Toast.web.tsx b/src/view/com/util/Toast.web.tsx index 1abbaa0031..6b99b30bf3 100644 --- a/src/view/com/util/Toast.web.tsx +++ b/src/view/com/util/Toast.web.tsx @@ -6,8 +6,10 @@ import {useEffect, useState} from 'react' import {Pressable, StyleSheet, Text, View} from 'react-native' import { + convertLegacyToastType, getToastTypeStyles, getToastWebAnimationStyles, + type LegacyToastType, TOAST_TYPE_TO_ICON, TOAST_WEB_KEYFRAMES, type ToastType, @@ -63,11 +65,11 @@ export const ToastContainer: React.FC = ({}) => { const toastTypeStyles = getToastTypeStyles(t) const toastStyles = activeToast - ? toastTypeStyles[activeToast.type as keyof typeof toastTypeStyles] + ? toastTypeStyles[activeToast.type] : toastTypeStyles.default const IconComponent = activeToast - ? TOAST_TYPE_TO_ICON[activeToast.type as keyof typeof TOAST_TYPE_TO_ICON] + ? TOAST_TYPE_TO_ICON[activeToast.type] : TOAST_TYPE_TO_ICON.default const animationStyles = getToastWebAnimationStyles() @@ -125,12 +127,15 @@ export const ToastContainer: React.FC = ({}) => { // methods // = -export function show(text: string, type: ToastType = 'default') { +export function show( + text: string, + type: ToastType | LegacyToastType = 'default', +) { if (toastTimeout) { clearTimeout(toastTimeout) } - globalSetActiveToast?.({text, type}) + globalSetActiveToast?.({text, type: convertLegacyToastType(type)}) toastTimeout = setTimeout(() => { globalSetActiveToast?.(undefined) }, DURATION) From d4b23d3ab4e8448321fecc7bd46b6531ada80348 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Wed, 30 Jul 2025 12:33:40 -0500 Subject: [PATCH 45/45] [APP-1173] Clean up env (#8701) * Clean up env files * Use new env in Sentry setup file * Use new env in Bitdrift setup file * Use new env in chat proxy header * Prefix Bitdrift key with EXPO_PUBLIC * Deprecate SENTRY_RELEASE since we use package.json now * Use existing EXPO_PUBLIC_BUNDLE_IDENTIFIER short commit has as Sentry dist value * Fix missing bundle identifier for Render deploys * Deprecate SENTRY_DIST in favor of EXPO_PUBLIC_BUNDLE_IDENTIFIER * Prefix SENTRY_DSN with EXPO_PUBLIC to match others * Remove debugging field * Replace NODE_ENV in places where its safe * Self review * Properly patch Sentry package * Echo variables to .env in Dockerfile instead of passing to shell script * Make sure EXPO_PUBLIC_ENV is set for web container builds * Update IS_TESTFLIGHT to include testflight-android * Slice bundle hash to match other platforms, needed for render.com deployments * [APP-1331] Migrate `app-info` to new env (#8703) * Move env files into directory with platform specific files * Migrate usages of app-info to new env * Fix bad import * Update BUNDLE_DATE format comment * Trim RENDER_GIT_COMMIT to first 7 to match --short sha * Clarify build process env vars and ensure they are explicitly passed in * Revert Sentry patch as a result of prev commit * Update webpack Sentry dist value based on prev commits * Add PACKAGE_VERSION and replace in statsig to fix conflict * Fix render substitution syntax * Remove invalid syntax * Remove unnecessary testflight check * Just use long commit hash * Slice full hash for display in app * Fix missing space in ios workflow * Pass in sentry CLI env vars, align matching values * Align on RELEASE_VERSION * Add new env setup to missed OTA spot * Update webpack to use same SENTRY_RELEASE var * Just fallback to package version for Render deploys * Remove TF check for BUNDLE_DATE * Set EXPO_PUBLIC_ENV for bundle update * Consistent naming "Env" * Add comment * Use RELEASE_VERSION instead of package.json * Update PR comment CI --- .env.example | 34 ++++++-- .../workflows/build-and-push-bskyweb-aws.yaml | 17 ++-- .github/workflows/build-submit-android.yml | 36 ++++++--- .github/workflows/build-submit-ios.yml | 25 +++--- .../workflows/bundle-deploy-eas-update.yml | 67 +++++++++++----- .github/workflows/pull-request-comment.yml | 24 +++--- Dockerfile | 29 ++++--- docs/build.md | 4 +- src/components/PostControls/DiscoverDebug.tsx | 2 +- .../PostControls/PostMenu/PostMenuItems.tsx | 2 +- src/env.ts | 6 -- src/env/common.ts | 79 +++++++++++++++++++ src/env/index.ts | 19 +++++ src/env/index.web.ts | 15 ++++ src/lib/app-info.ts | 18 ----- src/lib/app-info.web.ts | 18 ----- src/lib/hooks/useOTAUpdates.ts | 2 +- src/lib/statsig/statsig.tsx | 20 +++-- src/logger/bitdrift/setup/index.ts | 3 +- src/logger/index.ts | 3 +- src/logger/sentry/setup/index.ts | 29 ++----- src/screens/Settings/AboutSettings.tsx | 10 +-- .../Settings/AppIconSettings/index.tsx | 8 +- src/screens/Settings/AppearanceSettings.tsx | 2 +- src/screens/Settings/Settings.tsx | 2 +- src/state/queries/messages/const.ts | 4 +- src/state/session/logging.ts | 10 +-- webpack.config.js | 2 +- 28 files changed, 313 insertions(+), 177 deletions(-) delete mode 100644 src/env.ts create mode 100644 src/env/common.ts create mode 100644 src/env/index.ts create mode 100644 src/env/index.web.ts delete mode 100644 src/lib/app-info.ts delete mode 100644 src/lib/app-info.web.ts diff --git a/.env.example b/.env.example index a4d21ac332..e18cda4e55 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,32 @@ -# Copy this to `.env` and `.env.test` files +# The env the app is running in e.g. development, testflight, production +EXPO_PUBLIC_ENV=development -BITDRIFT_API_KEY= -SENTRY_AUTH_TOKEN= -EXPO_PUBLIC_LOG_LEVEL=debug -EXPO_PUBLIC_LOG_DEBUG= +# This is the semver release version of the app, pulled from package.json +EXPO_PUBLIC_RELEASE_VERSION= + +# This is the commit hash that the current bundle was made from. EXPO_PUBLIC_BUNDLE_IDENTIFIER= + +# Should be formatted YYMMDDHH so that it increases for each build. EXPO_PUBLIC_BUNDLE_DATE=0 + +# The log level for the app's logger transports +EXPO_PUBLIC_LOG_LEVEL=debug + +# Enable debug logs for specific logger instances +EXPO_PUBLIC_LOG_DEBUG=session + +# Chat service DID +EXPO_PUBLIC_CHAT_PROXY_DID= + +# +# +# Bluesky specific values +# +# + +# Sentry DSN for telemetry +EXPO_PUBLIC_SENTRY_DSN= + +# Bitdrift API key. If undefined, Bitdrift will be disabled. +EXPO_PUBLIC_BITDRIFT_API_KEY= diff --git a/.github/workflows/build-and-push-bskyweb-aws.yaml b/.github/workflows/build-and-push-bskyweb-aws.yaml index 399e8669f0..6d573b0f71 100644 --- a/.github/workflows/build-and-push-bskyweb-aws.yaml +++ b/.github/workflows/build-and-push-bskyweb-aws.yaml @@ -43,12 +43,11 @@ jobs: tags: | type=sha,enable=true,priority=100,prefix=,suffix=,format=long - - name: Set outputs - id: vars + - name: Env + id: env run: | - echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - name: Build and push Docker image id: build-and-push @@ -62,8 +61,8 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max build-args: | - EXPO_PUBLIC_BUNDLE_IDENTIFIER=${{ steps.vars.outputs.sha_short }} - SENTRY_DIST=${{ steps.vars.outputs.SENTRY_DIST }} - SENTRY_RELEASE=${{ steps.vars.outputs.SENTRY_RELEASE }} + EXPO_PUBLIC_ENV=production + EXPO_PUBLIC_RELEASE_VERSION=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} + EXPO_PUBLIC_BUNDLE_IDENTIFIER=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} + EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_DSN=${{ secrets.SENTRY_DSN }} diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index e862a701fd..f1e75f87e5 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -62,23 +62,30 @@ jobs: - name: Check for i18n compilation errors run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi - - name: ✏️ Write environment variables + # EXPO_PUBLIC_ENV is handled in eas.json + - name: Env + id: env run: | export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env - echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env + echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env + echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env echo "$json" > google-services.json - - name: Setup Sentry vars for build-time injection - id: sentry - run: | - echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT - - name: 🏗️ EAS Build - run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p android --profile ${{ inputs.profile || 'testflight-android' }} --local --output build.aab --non-interactive + 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' }} + --local --output build.aab --non-interactive - name: ✍️ Rename Testflight bundle if: ${{ inputs.profile != 'production' }} @@ -140,7 +147,14 @@ jobs: - name: 🏗️ Build Production APK if: ${{ inputs.profile == 'production' }} - run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p android --profile production-apk --local --output build.apk --non-interactive + run: > + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} + SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} + yarn use-build-number-with-bump + eas build -p android + --profile production-apk + --local --output build.apk --non-interactive - name: 🚀 Upload Production APK Artifact id: upload-artifact-production-apk diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index a197695db7..f3759d0dd4 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -75,22 +75,29 @@ jobs: - name: Check for i18n compilation errors run: if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compilation errors!\n\n"; fi + # EXPO_PUBLIC_ENV is handled in eas.json - name: ✏️ Write environment variables + id: env run: | echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env - echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env + echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env + echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json - - name: Setup Sentry vars for build-time injection - id: sentry - run: | - echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT - - name: 🏗️ EAS Build - run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} yarn use-build-number-with-bump eas build -p ios --profile ${{ inputs.profile || 'testflight' }} --local --output build.ipa --non-interactive + 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 - name: 🚀 Deploy run: eas submit -p ios --non-interactive --path build.ipa diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 475bc087f1..1bd0b71c47 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -101,25 +101,30 @@ jobs: if: ${{ !steps.fingerprint.outputs.includes-changes }} uses: dcarbone/install-jq-action@v2 - - name: ✏️ Write environment variables + # eas.json not used here, set EXPO_PUBLIC_ENV + - name: Env + id: env if: ${{ !steps.fingerprint.outputs.includes-changes }} run: | export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env + echo "EXPO_PUBLIC_ENV=${{ inputs.channel || 'testflight' }}" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env - echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env + echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env + echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env echo "$json" > google-services.json - - name: Setup Sentry vars for build-time injection - id: sentry - run: | - echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT - - name: 🏗️ Create Bundle if: ${{ !steps.fingerprint.outputs.includes-changes }} - run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} EXPO_PUBLIC_ENV="${{ inputs.channel || 'testflight' }}" yarn export + run: > + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} + SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} + yarn export - name: 📦 Package Bundle and 🚀 Deploy if: ${{ !steps.fingerprint.outputs.includes-changes }} @@ -205,16 +210,29 @@ jobs: - name: 🔤 Compile translations run: yarn intl:build - - name: ✏️ Write environment variables + # EXPO_PUBLIC_ENV is handled in eas.json + - name: Env + id: env run: | echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env - echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env + echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env + echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env echo "${{ secrets.GOOGLE_SERVICES_TOKEN }}" > google-services.json - name: 🏗️ EAS Build - run: yarn use-build-number-with-bump eas build -p ios --profile testflight --local --output build.ipa --non-interactive + run: > + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} + SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} + yarn use-build-number-with-bump + eas build -p ios + --profile testflight + --local --output build.ipa --non-interactive - name: 🚀 Deploy run: eas submit -p ios --non-interactive --path build.ipa @@ -282,17 +300,30 @@ jobs: - name: 🔤 Compile translations run: yarn intl:build - - name: ✏️ Write environment variables + # EXPO_PUBLIC_ENV is handled in eas.json + - name: Env + id: env run: | export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env - echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env + echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env + echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env echo "$json" > google-services.json - name: 🏗️ EAS Build - run: yarn use-build-number-with-bump eas build -p android --profile testflight-android --local --output build.apk --non-interactive + run: > + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} + SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} + yarn use-build-number-with-bump + eas build -p android + --profile testflight-android + --local --output build.apk --non-interactive - name: ⏰ Get a timestamp id: timestamp diff --git a/.github/workflows/pull-request-comment.yml b/.github/workflows/pull-request-comment.yml index e40eff6c7d..d043010027 100644 --- a/.github/workflows/pull-request-comment.yml +++ b/.github/workflows/pull-request-comment.yml @@ -152,23 +152,27 @@ jobs: - name: 🪛 Setup jq uses: dcarbone/install-jq-action@v2 - - name: ✏️ Write environment variables + - name: Env + id: env run: | export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env - echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse --short HEAD)" >> .env + echo "EXPO_PUBLIC_ENV=testflight" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> .env + echo "EXPO_PUBLIC_RELEASE_VERSION=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> .env + echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env - echo "BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env + echo "EXPO_PUBLIC_SENTRY_DSN=${{ secrets.SENTRY_DSN }}" >> .env + echo "EXPO_PUBLIC_BITDRIFT_API_KEY=${{ secrets.BITDRIFT_API_KEY }}" >> .env echo "$json" > google-services.json - - name: Setup Sentry vars for build-time injection - id: sentry - run: | - echo "SENTRY_DIST=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT - echo "SENTRY_RELEASE=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT - - name: 🏗️ Create Bundle - run: SENTRY_DIST=${{ steps.sentry.outputs.SENTRY_DIST }} SENTRY_RELEASE=${{ steps.sentry.outputs.SENTRY_RELEASE }} SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_DSN=${{ secrets.SENTRY_DSN }} EXPO_PUBLIC_ENV="testflight" yarn export + run: > + SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_RELEASE=${{ steps.env.outputs.EXPO_PUBLIC_RELEASE_VERSION }} + SENTRY_DIST=${{ steps.env.outputs.EXPO_PUBLIC_BUNDLE_IDENTIFIER }} + yarn export - name: 📦 Package Bundle and 🚀 Deploy run: yarn use-build-number bash scripts/bundleUpdate.sh diff --git a/Dockerfile b/Dockerfile index 50dc28b4b3..43d7f4eb48 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,28 +19,28 @@ ENV GOARCH="amd64" ENV CGO_ENABLED=1 ENV GOEXPERIMENT="loopvar" +# The latest git hash of the preview branch on render.com +# https://render.com/docs/docker-secrets#environment-variables-in-docker-builds +ARG RENDER_GIT_COMMIT + # # Expo # +ARG EXPO_PUBLIC_ENV +ENV EXPO_PUBLIC_ENV=${EXPO_PUBLIC_ENV:-development} +ARG EXPO_PUBLIC_RELEASE_VERSION +ENV EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION ARG EXPO_PUBLIC_BUNDLE_IDENTIFIER -ENV EXPO_PUBLIC_BUNDLE_IDENTIFIER=${EXPO_PUBLIC_BUNDLE_IDENTIFIER:-dev} - -# The latest git hash of the preview branch on render.com -ARG RENDER_GIT_COMMIT +# If not set by GitHub workflows, we're probably in Render +ENV EXPO_PUBLIC_BUNDLE_IDENTIFIER=${EXPO_PUBLIC_BUNDLE_IDENTIFIER:-$RENDER_GIT_COMMIT} # # Sentry # ARG SENTRY_AUTH_TOKEN ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN:-unknown} -# Will fall back to package.json#version, but this is handled elsewhere -ARG SENTRY_RELEASE -ENV SENTRY_RELEASE=$SENTRY_RELEASE -ARG SENTRY_DIST -# Default to RENDER_GIT_COMMIT if not set by GitHub workflows -ENV SENTRY_DIST=${SENTRY_DIST:-$RENDER_GIT_COMMIT} -ARG SENTRY_DSN -ENV SENTRY_DSN=$SENTRY_DSN +ARG EXPO_PUBLIC_SENTRY_DSN +ENV EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN # # Copy everything into the container @@ -60,13 +60,16 @@ RUN \. "$NVM_DIR/nvm.sh" && \ nvm install $NODE_VERSION && \ nvm use $NODE_VERSION && \ echo "Using bundle identifier: $EXPO_PUBLIC_BUNDLE_IDENTIFIER" && \ + echo "EXPO_PUBLIC_ENV=$EXPO_PUBLIC_ENV" >> .env && \ + echo "EXPO_PUBLIC_RELEASE_VERSION=$EXPO_PUBLIC_RELEASE_VERSION" >> .env && \ echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER" >> .env && \ echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env && \ + echo "EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN" >> .env && \ npm install --global yarn && \ yarn && \ yarn intl:build 2>&1 | tee i18n.log && \ if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compile errors!\n\n"; fi && \ - EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER EXPO_PUBLIC_BUNDLE_DATE=$() SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$SENTRY_RELEASE SENTRY_DIST=$SENTRY_DIST SENTRY_DSN=$SENTRY_DSN yarn build-web + SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$EXPO_PUBLIC_RELEASE_VERSION SENTRY_DIST=$EXPO_PUBLIC_BUNDLE_IDENTIFIER yarn build-web # DEBUG RUN find ./bskyweb/static && find ./web-build/static diff --git a/docs/build.md b/docs/build.md index 7817dd0957..87b653bdb9 100644 --- a/docs/build.md +++ b/docs/build.md @@ -89,9 +89,9 @@ If you change `SENTRY_AUTH_TOKEN`, you need to do `yarn prebuild` before running ### Adding bitdrift -Adding bitdirft is NOT required. You can keep `BITDRIFT_API_KEY=` in `.env` which will avoid initializing bitdrift during startup. +Adding bitdrift is NOT required. You can keep `EXPO_PUBLIC_BITDRIFT_API_KEY=` in `.env` which will avoid initializing bitdrift during startup. -However, if you're a part of the Bluesky team and want to enable bitdrift, fill in `BITDRIFT_API_KEY` in your `.env` to enable bitdrift. +However, if you're a part of the Bluesky team and want to enable bitdrift, fill in `EXPO_PUBLIC_BITDRIFT_API_KEY` in your `.env` to enable bitdrift. ### Adding and Updating Locales diff --git a/src/components/PostControls/DiscoverDebug.tsx b/src/components/PostControls/DiscoverDebug.tsx index 796981f0c2..403b50ccab 100644 --- a/src/components/PostControls/DiscoverDebug.tsx +++ b/src/components/PostControls/DiscoverDebug.tsx @@ -2,13 +2,13 @@ import {Pressable} from 'react-native' import * as Clipboard from 'expo-clipboard' import {t} from '@lingui/macro' -import {IS_INTERNAL} from '#/lib/app-info' import {DISCOVER_DEBUG_DIDS} from '#/lib/constants' import {useGate} from '#/lib/statsig/statsig' import {useSession} from '#/state/session' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Text} from '#/components/Typography' +import {IS_INTERNAL} from '#/env' export function DiscoverDebug({ feedContext, diff --git a/src/components/PostControls/PostMenu/PostMenuItems.tsx b/src/components/PostControls/PostMenu/PostMenuItems.tsx index f0ef9ed055..ecc3d01741 100644 --- a/src/components/PostControls/PostMenu/PostMenuItems.tsx +++ b/src/components/PostControls/PostMenu/PostMenuItems.tsx @@ -17,7 +17,6 @@ import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {IS_INTERNAL} from '#/lib/app-info' import {DISCOVER_DEBUG_DIDS} from '#/lib/constants' import {useOpenLink} from '#/lib/hooks/useOpenLink' import {getCurrentRoute} from '#/lib/routes/helpers' @@ -83,6 +82,7 @@ import { useReportDialogControl, } from '#/components/moderation/ReportDialog' import * as Prompt from '#/components/Prompt' +import {IS_INTERNAL} from '#/env' import * as bsky from '#/types/bsky' let PostMenuItems = ({ diff --git a/src/env.ts b/src/env.ts deleted file mode 100644 index 32ce70670b..0000000000 --- a/src/env.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const LOG_DEBUG = process.env.EXPO_PUBLIC_LOG_DEBUG || '' -export const LOG_LEVEL = (process.env.EXPO_PUBLIC_LOG_LEVEL || 'info') as - | 'debug' - | 'info' - | 'warn' - | 'error' diff --git a/src/env/common.ts b/src/env/common.ts new file mode 100644 index 0000000000..e68e9fab80 --- /dev/null +++ b/src/env/common.ts @@ -0,0 +1,79 @@ +import {type Did} from '@atproto/api' + +import packageJson from '#/../package.json' + +/** + * The semver version of the app, as defined in `package.json.` + * + * N.B. The fallback is needed for Render.com deployments + */ +export const RELEASE_VERSION: string = + process.env.EXPO_PUBLIC_RELEASE_VERSION || packageJson.version + +/** + * The env the app is running in e.g. development, testflight, production + */ +export const ENV: string = process.env.EXPO_PUBLIC_ENV + +/** + * Indicates whether the app is running in TestFlight + */ +export const IS_TESTFLIGHT = ENV === 'testflight' + +/** + * Indicates whether the app is __DEV__ + */ +export const IS_DEV = __DEV__ + +/** + * Indicates whether the app is __DEV__ or TestFlight + */ +export const IS_INTERNAL = IS_DEV || IS_TESTFLIGHT + +/** + * The commit hash that the current bundle was made from. The user can + * see the commit hash in the app's settings along with the other version info. + * Useful for debugging/reporting. + */ +export const BUNDLE_IDENTIFIER: string = + process.env.EXPO_PUBLIC_BUNDLE_IDENTIFIER || 'dev' + +/** + * This will always be in the format of YYMMDDHH, so that it always increases + * for each build. This should only be used for StatSig reporting and shouldn't + * be used to identify a specific bundle. + */ +export const BUNDLE_DATE: number = !process.env.EXPO_PUBLIC_BUNDLE_DATE + ? 0 + : Number(process.env.EXPO_PUBLIC_BUNDLE_DATE) + +/** + * The log level for the app. + */ +export const LOG_LEVEL = (process.env.EXPO_PUBLIC_LOG_LEVEL || 'info') as + | 'debug' + | 'info' + | 'warn' + | 'error' + +/** + * Enable debug logs for specific logger instances + */ +export const LOG_DEBUG: string = process.env.EXPO_PUBLIC_LOG_DEBUG || '' + +/** + * The DID of the chat service to proxy to + */ +export const CHAT_PROXY_DID: Did = + process.env.EXPO_PUBLIC_CHAT_PROXY_DID || 'did:web:api.bsky.chat' + +/** + * Sentry DSN for telemetry + */ +export const SENTRY_DSN: string | undefined = process.env.EXPO_PUBLIC_SENTRY_DSN + +/** + * Bitdrift API key. If undefined, Bitdrift should be disabled. + */ +export const BITDRIFT_API_KEY: string | undefined = + process.env.EXPO_PUBLIC_BITDRIFT_API_KEY diff --git a/src/env/index.ts b/src/env/index.ts new file mode 100644 index 0000000000..8558c55b5d --- /dev/null +++ b/src/env/index.ts @@ -0,0 +1,19 @@ +import {nativeBuildVersion} from 'expo-application' + +import {BUNDLE_IDENTIFIER, IS_TESTFLIGHT, RELEASE_VERSION} from '#/env/common' + +export * from '#/env/common' + +/** + * The semver version of the app, specified in our `package.json`.file. On + * iOs/Android, the native build version is appended to the semver version, so + * that it can be used to identify a specific build. + */ +export const APP_VERSION = `${RELEASE_VERSION}.${nativeBuildVersion}` + +/** + * The short commit hash and environment of the current bundle. + */ +export const APP_METADATA = `${BUNDLE_IDENTIFIER.slice(0, 7)} (${ + __DEV__ ? 'dev' : IS_TESTFLIGHT ? 'tf' : 'prod' +})` diff --git a/src/env/index.web.ts b/src/env/index.web.ts new file mode 100644 index 0000000000..66087749b7 --- /dev/null +++ b/src/env/index.web.ts @@ -0,0 +1,15 @@ +import {BUNDLE_IDENTIFIER, RELEASE_VERSION} from '#/env/common' + +export * from '#/env/common' + +/** + * The semver version of the app, specified in our `package.json`.file. On + * iOs/Android, the native build version is appended to the semver version, so + * that it can be used to identify a specific build. + */ +export const APP_VERSION = RELEASE_VERSION + +/** + * The short commit hash and environment of the current bundle. + */ +export const APP_METADATA = `${BUNDLE_IDENTIFIER.slice(0, 7)} (${__DEV__ ? 'dev' : 'prod'})` diff --git a/src/lib/app-info.ts b/src/lib/app-info.ts deleted file mode 100644 index 0749087eae..0000000000 --- a/src/lib/app-info.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {nativeApplicationVersion, nativeBuildVersion} from 'expo-application' - -export const IS_TESTFLIGHT = process.env.EXPO_PUBLIC_ENV === 'testflight' -export const IS_INTERNAL = __DEV__ || IS_TESTFLIGHT - -// This is the commit hash that the current bundle was made from. The user can see the commit hash in the app's settings -// along with the other version info. Useful for debugging/reporting. -export const BUNDLE_IDENTIFIER = process.env.EXPO_PUBLIC_BUNDLE_IDENTIFIER ?? '' - -// This will always be in the format of YYMMDD, so that it always increases for each build. This should only be used -// for Statsig reporting and shouldn't be used to identify a specific bundle. -export const BUNDLE_DATE = - IS_TESTFLIGHT || __DEV__ ? 0 : Number(process.env.EXPO_PUBLIC_BUNDLE_DATE) - -export const appVersion = `${nativeApplicationVersion}.${nativeBuildVersion}` -export const bundleInfo = `${BUNDLE_IDENTIFIER} (${ - __DEV__ ? 'dev' : IS_TESTFLIGHT ? 'tf' : 'prod' -})` diff --git a/src/lib/app-info.web.ts b/src/lib/app-info.web.ts deleted file mode 100644 index 1530d99769..0000000000 --- a/src/lib/app-info.web.ts +++ /dev/null @@ -1,18 +0,0 @@ -import packageDotJson from '../../package.json' - -export const IS_TESTFLIGHT = false -export const IS_INTERNAL = __DEV__ - -// This is the commit hash that the current bundle was made from. The user can see the commit hash in the app's settings -// along with the other version info. Useful for debugging/reporting. -export const BUNDLE_IDENTIFIER = - process.env.EXPO_PUBLIC_BUNDLE_IDENTIFIER ?? 'dev' - -// This will always be in the format of YYMMDD, so that it always increases for each build. This should only be used -// for Statsig reporting and shouldn't be used to identify a specific bundle. -export const BUNDLE_DATE = __DEV__ - ? 0 - : Number(process.env.EXPO_PUBLIC_BUNDLE_DATE) - -export const appVersion = packageDotJson.version -export const bundleInfo = `${BUNDLE_IDENTIFIER} (${__DEV__ ? 'dev' : 'prod'})` diff --git a/src/lib/hooks/useOTAUpdates.ts b/src/lib/hooks/useOTAUpdates.ts index 864d5d6970..ba46b60552 100644 --- a/src/lib/hooks/useOTAUpdates.ts +++ b/src/lib/hooks/useOTAUpdates.ts @@ -10,9 +10,9 @@ import { useUpdates, } from 'expo-updates' -import {IS_TESTFLIGHT} from '#/lib/app-info' import {logger} from '#/logger' import {isIOS} from '#/platform/detection' +import {IS_TESTFLIGHT} from '#/env' const MINIMUM_MINIMIZE_TIME = 15 * 60e3 diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx index f2d3ffca9b..1091c82e04 100644 --- a/src/lib/statsig/statsig.tsx +++ b/src/lib/statsig/statsig.tsx @@ -3,12 +3,11 @@ import {Platform} from 'react-native' import {AppState, type AppStateStatus} from 'react-native' import {Statsig, StatsigProvider} from 'statsig-react-native-expo' -import {BUNDLE_DATE, BUNDLE_IDENTIFIER, IS_TESTFLIGHT} from '#/lib/app-info' import {logger} from '#/logger' import {type MetricEvents} from '#/logger/metrics' import {isWeb} from '#/platform/detection' import * as persisted from '#/state/persisted' -import packageDotJson from '../../../package.json' +import * as env from '#/env' import {useSession} from '../../state/session' import {timeout} from '../async/timeout' import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback' @@ -49,12 +48,11 @@ export type {MetricEvents as LogEvents} function createStatsigOptions(prefetchUsers: StatsigUser[]) { return { environment: { - tier: - process.env.NODE_ENV === 'development' - ? 'development' - : IS_TESTFLIGHT - ? 'staging' - : 'production', + tier: env.IS_DEV + ? 'development' + : env.IS_TESTFLIGHT + ? 'staging' + : 'production', }, // Don't block on waiting for network. The fetched config will kick in on next load. // This ensures the UI is always consistent and doesn't update mid-session. @@ -212,9 +210,9 @@ function toStatsigUser(did: string | undefined): StatsigUser { refSrc, refUrl, platform: Platform.OS as 'ios' | 'android' | 'web', - appVersion: packageDotJson.version, - bundleIdentifier: BUNDLE_IDENTIFIER, - bundleDate: BUNDLE_DATE, + appVersion: env.RELEASE_VERSION, + bundleIdentifier: env.BUNDLE_IDENTIFIER, + bundleDate: env.BUNDLE_DATE, appLanguage: languagePrefs.appLanguage, contentLanguages: languagePrefs.contentLanguages, }, diff --git a/src/logger/bitdrift/setup/index.ts b/src/logger/bitdrift/setup/index.ts index d6af3fe24b..dd2560acc6 100644 --- a/src/logger/bitdrift/setup/index.ts +++ b/src/logger/bitdrift/setup/index.ts @@ -2,8 +2,7 @@ import {init, SessionStrategy} from '@bitdrift/react-native' import {Statsig} from 'statsig-react-native-expo' import {initPromise} from '#/lib/statsig/statsig' - -const BITDRIFT_API_KEY = process.env.BITDRIFT_API_KEY +import {BITDRIFT_API_KEY} from '#/env' initPromise.then(() => { let isEnabled = false diff --git a/src/logger/index.ts b/src/logger/index.ts index e7aaf666a0..998d025818 100644 --- a/src/logger/index.ts +++ b/src/logger/index.ts @@ -14,9 +14,10 @@ import { } from '#/logger/types' import {enabledLogLevels} from '#/logger/util' import {isNative} from '#/platform/detection' +import {ENV} from '#/env' const TRANSPORTS: Transport[] = (function configureTransports() { - switch (process.env.NODE_ENV) { + switch (ENV) { case 'production': { return [sentryTransport, isNative && bitdriftTransport].filter( Boolean, diff --git a/src/logger/sentry/setup/index.ts b/src/logger/sentry/setup/index.ts index f05a7fc833..d062f05d2b 100644 --- a/src/logger/sentry/setup/index.ts +++ b/src/logger/sentry/setup/index.ts @@ -1,32 +1,15 @@ -/** - * Importing these separately from `platform/detection` and `lib/app-info` to - * avoid future conflicts and/or circular deps - */ - import {init} from '@sentry/react-native' -import pkgJson from '#/../package.json' - -/** - * Examples: - * - `dev` - * - `1.99.0` - */ -const release = process.env.SENTRY_RELEASE || pkgJson.version - -/** - * The latest deployed commit hash - */ -const dist = process.env.SENTRY_DIST || 'dev' +import * as env from '#/env' init({ - enabled: !__DEV__ && !!process.env.SENTRY_DSN, + enabled: !env.IS_DEV && !!env.SENTRY_DSN, autoSessionTracking: false, - dsn: process.env.SENTRY_DSN, + dsn: env.SENTRY_DSN, debug: false, // If `true`, Sentry will try to print out useful debugging information if something goes wrong with sending the event. Set it to `false` in production - environment: process.env.NODE_ENV, - dist, - release, + environment: env.ENV, + dist: env.BUNDLE_IDENTIFIER, + release: env.RELEASE_VERSION, ignoreErrors: [ /* * Unknown internals errors diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx index 0ce127ff3f..e48841d9f0 100644 --- a/src/screens/Settings/AboutSettings.tsx +++ b/src/screens/Settings/AboutSettings.tsx @@ -9,7 +9,6 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack' import {useMutation} from '@tanstack/react-query' import {Statsig} from 'statsig-react-native-expo' -import {appVersion, BUNDLE_DATE, bundleInfo} from '#/lib/app-info' import {STATUS_PAGE_URL} from '#/lib/constants' import {type CommonNavigatorParams} from '#/lib/routes/types' import {isAndroid, isIOS, isNative} from '#/platform/detection' @@ -23,6 +22,7 @@ import {Newspaper_Stroke2_Corner2_Rounded as NewspaperIcon} from '#/components/i import {Wrench_Stroke2_Corner2_Rounded as WrenchIcon} from '#/components/icons/Wrench' import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' +import * as env from '#/env' import {useDemoMode} from '#/storage/hooks/demo-mode' import {useDevMode} from '#/storage/hooks/dev-mode' import {OTAInfo} from './components/OTAInfo' @@ -123,7 +123,7 @@ export function AboutSettingsScreen({}: Props) { )} { const newDevModeEnabled = !devModeEnabled @@ -146,15 +146,15 @@ export function AboutSettingsScreen({}: Props) { }} onPress={() => { setStringAsync( - `Build version: ${appVersion}; Bundle info: ${bundleInfo}; Bundle date: ${BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}; Anonymous ID: ${stableID}`, + `Build version: ${env.APP_VERSION}; Bundle info: ${env.APP_METADATA}; Bundle date: ${env.BUNDLE_DATE}; Platform: ${Platform.OS}; Platform version: ${Platform.Version}; Anonymous ID: ${stableID}`, ) Toast.show(_(msg`Copied build version to clipboard`)) }}> - Version {appVersion} + Version {env.APP_VERSION} - {bundleInfo} + {env.APP_METADATA} {devModeEnabled && ( <> diff --git a/src/screens/Settings/AppIconSettings/index.tsx b/src/screens/Settings/AppIconSettings/index.tsx index 954bac68a5..799873c2d9 100644 --- a/src/screens/Settings/AppIconSettings/index.tsx +++ b/src/screens/Settings/AppIconSettings/index.tsx @@ -3,20 +3,20 @@ import {Alert, View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import * as DynamicAppIcon from '@mozzius/expo-dynamic-app-icon' -import {NativeStackScreenProps} from '@react-navigation/native-stack' +import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {IS_INTERNAL} from '#/lib/app-info' import {PressableScale} from '#/lib/custom-animations/PressableScale' -import {CommonNavigatorParams} from '#/lib/routes/types' +import {type CommonNavigatorParams} from '#/lib/routes/types' import {useGate} from '#/lib/statsig/statsig' import {isAndroid} from '#/platform/detection' import {AppIconImage} from '#/screens/Settings/AppIconSettings/AppIconImage' -import {AppIconSet} from '#/screens/Settings/AppIconSettings/types' +import {type AppIconSet} from '#/screens/Settings/AppIconSettings/types' import {useAppIconSets} from '#/screens/Settings/AppIconSettings/useAppIconSets' import {atoms as a, useTheme} from '#/alf' import * as Toggle from '#/components/forms/Toggle' import * as Layout from '#/components/Layout' import {Text} from '#/components/Typography' +import {IS_INTERNAL} from '#/env' type Props = NativeStackScreenProps export function AppIconSettingsScreen({}: Props) { diff --git a/src/screens/Settings/AppearanceSettings.tsx b/src/screens/Settings/AppearanceSettings.tsx index d0158aaa84..492d6d172b 100644 --- a/src/screens/Settings/AppearanceSettings.tsx +++ b/src/screens/Settings/AppearanceSettings.tsx @@ -8,7 +8,6 @@ import Animated, { import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {IS_INTERNAL} from '#/lib/app-info' import { type CommonNavigatorParams, type NativeStackScreenProps, @@ -26,6 +25,7 @@ import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/T import {TitleCase_Stroke2_Corner0_Rounded as Aa} from '#/components/icons/TitleCase' import * as Layout from '#/components/Layout' import {Text} from '#/components/Typography' +import {IS_INTERNAL} from '#/env' import * as SettingsList from './components/SettingsList' type Props = NativeStackScreenProps diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index b712c054cb..719bbf9a29 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -9,7 +9,6 @@ import {useNavigation} from '@react-navigation/native' import {type NativeStackScreenProps} from '@react-navigation/native-stack' import {useActorStatus} from '#/lib/actor-status' -import {IS_INTERNAL} from '#/lib/app-info' import {HELP_DESK_URL} from '#/lib/constants' import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher' import {useApplyPullRequestOTAUpdate} from '#/lib/hooks/useOTAUpdates' @@ -66,6 +65,7 @@ import { shouldShowVerificationCheckButton, VerificationCheckButton, } from '#/components/verification/VerificationCheckButton' +import {IS_INTERNAL} from '#/env' import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged' type Props = NativeStackScreenProps diff --git a/src/state/queries/messages/const.ts b/src/state/queries/messages/const.ts index 7642c5d7b2..1c5519a633 100644 --- a/src/state/queries/messages/const.ts +++ b/src/state/queries/messages/const.ts @@ -1,3 +1,5 @@ +import {CHAT_PROXY_DID} from '#/env' + export const DM_SERVICE_HEADERS = { - 'atproto-proxy': 'did:web:api.bsky.chat#bsky_chat', + 'atproto-proxy': `${CHAT_PROXY_DID}#bsky_chat`, } diff --git a/src/state/session/logging.ts b/src/state/session/logging.ts index 98de5a3964..bf847f08f5 100644 --- a/src/state/session/logging.ts +++ b/src/state/session/logging.ts @@ -1,11 +1,11 @@ -import {AtpSessionData, AtpSessionEvent} from '@atproto/api' +import {type AtpSessionData, type AtpSessionEvent} from '@atproto/api' import {sha256} from 'js-sha256' import {Statsig} from 'statsig-react-native-expo' -import {IS_INTERNAL} from '#/lib/app-info' -import {Schema} from '../persisted' -import {Action, State} from './reducer' -import {SessionAccount} from './types' +import {IS_INTERNAL} from '#/env' +import {type Schema} from '../persisted' +import {type Action, type State} from './reducer' +import {type SessionAccount} from './types' type Reducer = (state: State, action: Action) => State diff --git a/webpack.config.js b/webpack.config.js index 9a238e5493..7f58a7448a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -53,7 +53,7 @@ module.exports = async function (env, argv) { project: 'app', authToken: process.env.SENTRY_AUTH_TOKEN, release: { - // env is undefined for Render.com builds, fall back + // fallback needed for Render.com deployments name: process.env.SENTRY_RELEASE || version, dist: process.env.SENTRY_DIST, },