From 75e2c5487c9d7d6cbe303beb1a588db17bafa701 Mon Sep 17 00:00:00 2001 From: Hailey Date: Mon, 27 May 2024 22:21:25 -0700 Subject: [PATCH 01/55] bump iOS target to `14.0` (#4238) --- app.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.config.js b/app.config.js index 4ade9de31a..ffa6cf7dab 100644 --- a/app.config.js +++ b/app.config.js @@ -183,7 +183,7 @@ module.exports = function (config) { 'expo-build-properties', { ios: { - deploymentTarget: '13.4', + deploymentTarget: '14.0', newArchEnabled: false, }, android: { From 8a2f43c218c464e6165f331e482b6094b87eefc7 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 07:35:50 -0700 Subject: [PATCH 02/55] Bump 1.85.0 (#4237) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c79e29f91..0634a6cce9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bsky.app", - "version": "1.84.0", + "version": "1.85.0", "private": true, "engines": { "node": ">=18" From 9bd411c15159609803c4e8c3e352a9db32ea527c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 28 May 2024 16:37:51 +0100 Subject: [PATCH 03/55] Replace getAgent() with reading agent (#4243) * Replace getAgent() with agent * Replace {agent} with agent --- src/components/ReportDialog/SubmitView.tsx | 6 +- src/components/dms/ReportDialog.tsx | 4 +- src/components/hooks/useRichText.ts | 6 +- .../moderation/LabelsOnMeDialog.tsx | 4 +- src/lib/api/feed/author.ts | 12 +-- src/lib/api/feed/custom.ts | 14 ++-- src/lib/api/feed/following.ts | 10 +-- src/lib/api/feed/home.ts | 16 ++-- src/lib/api/feed/likes.ts | 12 +-- src/lib/api/feed/list.ts | 12 +-- src/lib/api/feed/merge.ts | 38 ++++----- src/lib/notifications/notifications.ts | 10 +-- src/screens/Deactivated.tsx | 10 +-- .../Messages/Conversation/ChatDisabled.tsx | 4 +- .../Messages/Conversation/MessagesList.tsx | 6 +- src/screens/Onboarding/StepFinished.tsx | 16 ++-- .../Onboarding/StepInterests/index.tsx | 5 +- src/screens/Onboarding/util.ts | 19 ++--- src/screens/Signup/index.tsx | 6 +- src/state/feed-feedback.tsx | 6 +- src/state/messages/convo/index.tsx | 4 +- src/state/messages/events/index.tsx | 4 +- src/state/queries/actor-autocomplete.ts | 10 +-- src/state/queries/actor-search.ts | 4 +- src/state/queries/app-passwords.ts | 12 +-- src/state/queries/feed.ts | 24 +++--- src/state/queries/handle.ts | 16 ++-- src/state/queries/invites.ts | 6 +- src/state/queries/labeler.ts | 18 ++--- src/state/queries/like.ts | 8 +- src/state/queries/list-members.ts | 4 +- src/state/queries/list-memberships.ts | 12 +-- src/state/queries/list.ts | 78 ++++++++----------- .../queries/messages/actor-declaration.ts | 8 +- src/state/queries/messages/conversation.ts | 8 +- .../queries/messages/get-convo-for-members.ts | 13 ++-- .../queries/messages/leave-conversation.ts | 4 +- .../queries/messages/list-converations.tsx | 4 +- .../queries/messages/mute-conversation.ts | 4 +- src/state/queries/my-blocked-accounts.ts | 4 +- src/state/queries/my-lists.ts | 14 ++-- src/state/queries/my-muted-accounts.ts | 4 +- src/state/queries/notifications/feed.ts | 4 +- src/state/queries/notifications/unread.tsx | 10 +-- src/state/queries/notifications/util.ts | 14 ++-- src/state/queries/post-feed.ts | 26 +++---- src/state/queries/post-liked-by.ts | 4 +- src/state/queries/post-reposted-by.ts | 4 +- src/state/queries/post-thread.ts | 4 +- src/state/queries/post.ts | 32 ++++---- src/state/queries/preferences/index.ts | 68 ++++++++-------- src/state/queries/profile-feedgens.ts | 4 +- src/state/queries/profile-followers.ts | 4 +- src/state/queries/profile-follows.ts | 4 +- src/state/queries/profile-lists.ts | 4 +- src/state/queries/profile.ts | 52 ++++++------- src/state/queries/resolve-uri.ts | 4 +- src/state/queries/search-posts.ts | 4 +- src/state/queries/suggested-feeds.ts | 4 +- src/state/queries/suggested-follows.ts | 8 +- src/state/session/index.tsx | 11 +-- src/view/com/composer/Composer.tsx | 4 +- .../com/composer/useExternalLinkFetch.e2e.ts | 6 +- src/view/com/composer/useExternalLinkFetch.ts | 10 +-- src/view/com/modals/ChangeEmail.tsx | 12 +-- src/view/com/modals/ChangeHandle.tsx | 10 +-- src/view/com/modals/ChangePassword.tsx | 3 +- src/view/com/modals/CreateOrEditList.tsx | 6 +- src/view/com/modals/DeleteAccount.tsx | 8 +- src/view/com/modals/VerifyEmail.tsx | 8 +- src/view/screens/Profile.tsx | 6 +- .../Settings/DisableEmail2FADialog.tsx | 8 +- src/view/screens/Settings/Email2FAToggle.tsx | 8 +- src/view/screens/Settings/ExportCarDialog.tsx | 5 +- 74 files changed, 400 insertions(+), 438 deletions(-) diff --git a/src/components/ReportDialog/SubmitView.tsx b/src/components/ReportDialog/SubmitView.tsx index e921d102a9..74ecf92e41 100644 --- a/src/components/ReportDialog/SubmitView.tsx +++ b/src/components/ReportDialog/SubmitView.tsx @@ -36,7 +36,7 @@ export function SubmitView({ }) { const t = useTheme() const {_} = useLingui() - const {getAgent} = useAgent() + const agent = useAgent() const [details, setDetails] = React.useState('') const [submitting, setSubmitting] = React.useState(false) const [selectedServices, setSelectedServices] = React.useState([ @@ -62,7 +62,7 @@ export function SubmitView({ } const results = await Promise.all( selectedServices.map(did => - getAgent() + agent .withProxy('atproto_labeler', did) .createModerationReport(report) .then( @@ -92,7 +92,7 @@ export function SubmitView({ selectedServices, onSubmitComplete, setError, - getAgent, + agent, ]) return ( diff --git a/src/components/dms/ReportDialog.tsx b/src/components/dms/ReportDialog.tsx index 63e4cd79e4..9c4ed2a0e9 100644 --- a/src/components/dms/ReportDialog.tsx +++ b/src/components/dms/ReportDialog.tsx @@ -102,7 +102,7 @@ function SubmitStep({ const t = useTheme() const [details, setDetails] = useState('') const control = Dialog.useDialogContext() - const {getAgent} = useAgent() + const agent = useAgent() const { mutate: submit, @@ -124,7 +124,7 @@ function SubmitStep({ reason: details, } satisfies ComAtprotoModerationCreateReport.InputSchema - await getAgent().createModerationReport(report) + await agent.createModerationReport(report) } }, onSuccess: () => { diff --git a/src/components/hooks/useRichText.ts b/src/components/hooks/useRichText.ts index 4329638ea6..caf6febc04 100644 --- a/src/components/hooks/useRichText.ts +++ b/src/components/hooks/useRichText.ts @@ -7,7 +7,7 @@ export function useRichText(text: string): [RichTextAPI, boolean] { const [prevText, setPrevText] = React.useState(text) const [rawRT, setRawRT] = React.useState(() => new RichTextAPI({text})) const [resolvedRT, setResolvedRT] = React.useState(null) - const {getAgent} = useAgent() + const agent = useAgent() if (text !== prevText) { setPrevText(text) setRawRT(new RichTextAPI({text})) @@ -19,7 +19,7 @@ export function useRichText(text: string): [RichTextAPI, boolean] { async function resolveRTFacets() { // new each time const resolvedRT = new RichTextAPI({text}) - await resolvedRT.detectFacets(getAgent()) + await resolvedRT.detectFacets(agent) if (!ignore) { setResolvedRT(resolvedRT) } @@ -28,7 +28,7 @@ export function useRichText(text: string): [RichTextAPI, boolean] { return () => { ignore = true } - }, [text, getAgent]) + }, [text, agent]) const isResolving = resolvedRT === null return [resolvedRT ?? rawRT, isResolving] } diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx index 2923981fd7..7c76269ac9 100644 --- a/src/components/moderation/LabelsOnMeDialog.tsx +++ b/src/components/moderation/LabelsOnMeDialog.tsx @@ -202,14 +202,14 @@ function AppealForm({ const {gtMobile} = useBreakpoints() const [details, setDetails] = React.useState('') const isAccountReport = 'did' in subject - const {getAgent} = useAgent() + const agent = useAgent() const {mutate, isPending} = useMutation({ mutationFn: async () => { const $type = !isAccountReport ? 'com.atproto.repo.strongRef' : 'com.atproto.admin.defs#repoRef' - await getAgent() + await agent .withProxy('atproto_labeler', label.src) .createModerationReport({ reasonType: ComAtprotoModerationDefs.REASONAPPEAL, diff --git a/src/lib/api/feed/author.ts b/src/lib/api/feed/author.ts index 85601d0683..56eff18816 100644 --- a/src/lib/api/feed/author.ts +++ b/src/lib/api/feed/author.ts @@ -7,22 +7,22 @@ import { import {FeedAPI, FeedAPIResponse} from './types' export class AuthorFeedAPI implements FeedAPI { - getAgent: () => BskyAgent + agent: BskyAgent params: GetAuthorFeed.QueryParams constructor({ - getAgent, + agent, feedParams, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedParams: GetAuthorFeed.QueryParams }) { - this.getAgent = getAgent + this.agent = agent this.params = feedParams } async peekLatest(): Promise { - const res = await this.getAgent().getAuthorFeed({ + const res = await this.agent.getAuthorFeed({ ...this.params, limit: 1, }) @@ -36,7 +36,7 @@ export class AuthorFeedAPI implements FeedAPI { cursor: string | undefined limit: number }): Promise { - const res = await this.getAgent().getAuthorFeed({ + const res = await this.agent.getAuthorFeed({ ...this.params, cursor, limit, diff --git a/src/lib/api/feed/custom.ts b/src/lib/api/feed/custom.ts index 87e45cebab..eb54dd29c1 100644 --- a/src/lib/api/feed/custom.ts +++ b/src/lib/api/feed/custom.ts @@ -10,27 +10,27 @@ import {FeedAPI, FeedAPIResponse} from './types' import {createBskyTopicsHeader, isBlueskyOwnedFeed} from './utils' export class CustomFeedAPI implements FeedAPI { - getAgent: () => BskyAgent + agent: BskyAgent params: GetCustomFeed.QueryParams userInterests?: string constructor({ - getAgent, + agent, feedParams, userInterests, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedParams: GetCustomFeed.QueryParams userInterests?: string }) { - this.getAgent = getAgent + this.agent = agent this.params = feedParams this.userInterests = userInterests } async peekLatest(): Promise { const contentLangs = getContentLanguages().join(',') - const res = await this.getAgent().app.bsky.feed.getFeed( + const res = await this.agent.app.bsky.feed.getFeed( { ...this.params, limit: 1, @@ -48,11 +48,11 @@ export class CustomFeedAPI implements FeedAPI { limit: number }): Promise { const contentLangs = getContentLanguages().join(',') - const agent = this.getAgent() + const agent = this.agent const isBlueskyOwned = isBlueskyOwnedFeed(this.params.feed) const res = agent.session - ? await this.getAgent().app.bsky.feed.getFeed( + ? await this.agent.app.bsky.feed.getFeed( { ...this.params, cursor, diff --git a/src/lib/api/feed/following.ts b/src/lib/api/feed/following.ts index 36c376554a..1004ccfb87 100644 --- a/src/lib/api/feed/following.ts +++ b/src/lib/api/feed/following.ts @@ -3,14 +3,14 @@ import {AppBskyFeedDefs, BskyAgent} from '@atproto/api' import {FeedAPI, FeedAPIResponse} from './types' export class FollowingFeedAPI implements FeedAPI { - getAgent: () => BskyAgent + agent: BskyAgent - constructor({getAgent}: {getAgent: () => BskyAgent}) { - this.getAgent = getAgent + constructor({agent}: {agent: BskyAgent}) { + this.agent = agent } async peekLatest(): Promise { - const res = await this.getAgent().getTimeline({ + const res = await this.agent.getTimeline({ limit: 1, }) return res.data.feed[0] @@ -23,7 +23,7 @@ export class FollowingFeedAPI implements FeedAPI { cursor: string | undefined limit: number }): Promise { - const res = await this.getAgent().getTimeline({ + const res = await this.agent.getTimeline({ cursor, limit, }) diff --git a/src/lib/api/feed/home.ts b/src/lib/api/feed/home.ts index 270f3aacb2..e6bc45bea0 100644 --- a/src/lib/api/feed/home.ts +++ b/src/lib/api/feed/home.ts @@ -27,7 +27,7 @@ export const FALLBACK_MARKER_POST: AppBskyFeedDefs.FeedViewPost = { } export class HomeFeedAPI implements FeedAPI { - getAgent: () => BskyAgent + agent: BskyAgent following: FollowingFeedAPI discover: CustomFeedAPI usingDiscover = false @@ -36,24 +36,24 @@ export class HomeFeedAPI implements FeedAPI { constructor({ userInterests, - getAgent, + agent, }: { userInterests?: string - getAgent: () => BskyAgent + agent: BskyAgent }) { - this.getAgent = getAgent - this.following = new FollowingFeedAPI({getAgent}) + this.agent = agent + this.following = new FollowingFeedAPI({agent}) this.discover = new CustomFeedAPI({ - getAgent, + agent, feedParams: {feed: PROD_DEFAULT_FEED('whats-hot')}, }) this.userInterests = userInterests } reset() { - this.following = new FollowingFeedAPI({getAgent: this.getAgent}) + this.following = new FollowingFeedAPI({agent: this.agent}) this.discover = new CustomFeedAPI({ - getAgent: this.getAgent, + agent: this.agent, feedParams: {feed: PROD_DEFAULT_FEED('whats-hot')}, userInterests: this.userInterests, }) diff --git a/src/lib/api/feed/likes.ts b/src/lib/api/feed/likes.ts index 1729ee05cf..a4e84d8f1f 100644 --- a/src/lib/api/feed/likes.ts +++ b/src/lib/api/feed/likes.ts @@ -7,22 +7,22 @@ import { import {FeedAPI, FeedAPIResponse} from './types' export class LikesFeedAPI implements FeedAPI { - getAgent: () => BskyAgent + agent: BskyAgent params: GetActorLikes.QueryParams constructor({ - getAgent, + agent, feedParams, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedParams: GetActorLikes.QueryParams }) { - this.getAgent = getAgent + this.agent = agent this.params = feedParams } async peekLatest(): Promise { - const res = await this.getAgent().getActorLikes({ + const res = await this.agent.getActorLikes({ ...this.params, limit: 1, }) @@ -36,7 +36,7 @@ export class LikesFeedAPI implements FeedAPI { cursor: string | undefined limit: number }): Promise { - const res = await this.getAgent().getActorLikes({ + const res = await this.agent.getActorLikes({ ...this.params, cursor, limit, diff --git a/src/lib/api/feed/list.ts b/src/lib/api/feed/list.ts index 004685b998..9744e3d4ce 100644 --- a/src/lib/api/feed/list.ts +++ b/src/lib/api/feed/list.ts @@ -7,22 +7,22 @@ import { import {FeedAPI, FeedAPIResponse} from './types' export class ListFeedAPI implements FeedAPI { - getAgent: () => BskyAgent + agent: BskyAgent params: GetListFeed.QueryParams constructor({ - getAgent, + agent, feedParams, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedParams: GetListFeed.QueryParams }) { - this.getAgent = getAgent + this.agent = agent this.params = feedParams } async peekLatest(): Promise { - const res = await this.getAgent().app.bsky.feed.getListFeed({ + const res = await this.agent.app.bsky.feed.getListFeed({ ...this.params, limit: 1, }) @@ -36,7 +36,7 @@ export class ListFeedAPI implements FeedAPI { cursor: string | undefined limit: number }): Promise { - const res = await this.getAgent().app.bsky.feed.getListFeed({ + const res = await this.agent.app.bsky.feed.getListFeed({ ...this.params, cursor, limit, diff --git a/src/lib/api/feed/merge.ts b/src/lib/api/feed/merge.ts index b7ac8bce1c..f551f5e4cc 100644 --- a/src/lib/api/feed/merge.ts +++ b/src/lib/api/feed/merge.ts @@ -16,7 +16,7 @@ const POST_AGE_CUTOFF = 60e3 * 60 * 24 // 24hours export class MergeFeedAPI implements FeedAPI { userInterests?: string - getAgent: () => BskyAgent + agent: BskyAgent params: FeedParams feedTuners: FeedTunerFn[] following: MergeFeedSource_Following @@ -26,29 +26,29 @@ export class MergeFeedAPI implements FeedAPI { sampleCursor = 0 constructor({ - getAgent, + agent, feedParams, feedTuners, userInterests, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedParams: FeedParams feedTuners: FeedTunerFn[] userInterests?: string }) { - this.getAgent = getAgent + this.agent = agent this.params = feedParams this.feedTuners = feedTuners this.userInterests = userInterests this.following = new MergeFeedSource_Following({ - getAgent: this.getAgent, + agent: this.agent, feedTuners: this.feedTuners, }) } reset() { this.following = new MergeFeedSource_Following({ - getAgent: this.getAgent, + agent: this.agent, feedTuners: this.feedTuners, }) this.customFeeds = [] @@ -60,7 +60,7 @@ export class MergeFeedAPI implements FeedAPI { this.params.mergeFeedSources.map( feedUri => new MergeFeedSource_Custom({ - getAgent: this.getAgent, + agent: this.agent, feedUri, feedTuners: this.feedTuners, userInterests: this.userInterests, @@ -73,7 +73,7 @@ export class MergeFeedAPI implements FeedAPI { } async peekLatest(): Promise { - const res = await this.getAgent().getTimeline({ + const res = await this.agent.getTimeline({ limit: 1, }) return res.data.feed[0] @@ -167,7 +167,7 @@ export class MergeFeedAPI implements FeedAPI { } class MergeFeedSource { - getAgent: () => BskyAgent + agent: BskyAgent feedTuners: FeedTunerFn[] sourceInfo: ReasonFeedSource | undefined cursor: string | undefined = undefined @@ -175,13 +175,13 @@ class MergeFeedSource { hasMore = true constructor({ - getAgent, + agent, feedTuners, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedTuners: FeedTunerFn[] }) { - this.getAgent = getAgent + this.agent = agent this.feedTuners = feedTuners } @@ -245,7 +245,7 @@ class MergeFeedSource_Following extends MergeFeedSource { cursor: string | undefined, limit: number, ): Promise { - const res = await this.getAgent().getTimeline({cursor, limit}) + const res = await this.agent.getTimeline({cursor, limit}) // run the tuner pre-emptively to ensure better mixing const slices = this.tuner.tune(res.data.feed, { dryRun: false, @@ -257,27 +257,27 @@ class MergeFeedSource_Following extends MergeFeedSource { } class MergeFeedSource_Custom extends MergeFeedSource { - getAgent: () => BskyAgent + agent: BskyAgent minDate: Date feedUri: string userInterests?: string constructor({ - getAgent, + agent, feedUri, feedTuners, userInterests, }: { - getAgent: () => BskyAgent + agent: BskyAgent feedUri: string feedTuners: FeedTunerFn[] userInterests?: string }) { super({ - getAgent, + agent, feedTuners, }) - this.getAgent = getAgent + this.agent = agent this.feedUri = feedUri this.userInterests = userInterests this.sourceInfo = { @@ -295,7 +295,7 @@ class MergeFeedSource_Custom extends MergeFeedSource { try { const contentLangs = getContentLanguages().join(',') const isBlueskyOwned = isBlueskyOwnedFeed(this.feedUri) - const res = await this.getAgent().app.bsky.feed.getFeed( + const res = await this.agent.app.bsky.feed.getFeed( { cursor, limit, diff --git a/src/lib/notifications/notifications.ts b/src/lib/notifications/notifications.ts index f9fbdb8bfa..f0667b0ccf 100644 --- a/src/lib/notifications/notifications.ts +++ b/src/lib/notifications/notifications.ts @@ -14,12 +14,12 @@ const SERVICE_DID = (serviceUrl?: string) => : 'did:web:api.bsky.app' async function registerPushToken( - getAgent: () => BskyAgent, + agent: BskyAgent, account: SessionAccount, token: Notifications.DevicePushToken, ) { try { - await getAgent().api.app.bsky.notification.registerPush({ + await agent.api.app.bsky.notification.registerPush({ serviceDid: SERVICE_DID(account.service), platform: devicePlatform, token: token.data, @@ -47,7 +47,7 @@ async function getPushToken(skipPermissionCheck = false) { } export function useNotificationsRegistration() { - const {getAgent} = useAgent() + const agent = useAgent() const {currentAccount} = useSession() React.useEffect(() => { @@ -60,13 +60,13 @@ export function useNotificationsRegistration() { // According to the Expo docs, there is a chance that the token will change while the app is open in some rare // cases. This will fire `registerPushToken` whenever that happens. const subscription = Notifications.addPushTokenListener(async newToken => { - registerPushToken(getAgent, currentAccount, newToken) + registerPushToken(agent, currentAccount, newToken) }) return () => { subscription.remove() } - }, [currentAccount, getAgent]) + }, [currentAccount, agent]) } export function useRequestNotificationsPermission() { diff --git a/src/screens/Deactivated.tsx b/src/screens/Deactivated.tsx index 08a2232df2..c9e9f95254 100644 --- a/src/screens/Deactivated.tsx +++ b/src/screens/Deactivated.tsx @@ -24,7 +24,7 @@ export function Deactivated() { const {gtMobile} = useBreakpoints() const onboardingDispatch = useOnboardingDispatch() const {logout} = useSessionApi() - const {getAgent} = useAgent() + const agent = useAgent() const [isProcessing, setProcessing] = React.useState(false) const [estimatedTime, setEstimatedTime] = React.useState( @@ -37,11 +37,11 @@ export function Deactivated() { const checkStatus = React.useCallback(async () => { setProcessing(true) try { - const res = await getAgent().com.atproto.temp.checkSignupQueue() + const res = await agent.com.atproto.temp.checkSignupQueue() if (res.data.activated) { // ready to go, exchange the access token for a usable one and kick off onboarding - await getAgent().refreshSession() - if (!isSessionDeactivated(getAgent().session?.accessJwt)) { + await agent.refreshSession() + if (!isSessionDeactivated(agent.session?.accessJwt)) { onboardingDispatch({type: 'start'}) } } else { @@ -61,7 +61,7 @@ export function Deactivated() { setEstimatedTime, setPlaceInQueue, onboardingDispatch, - getAgent, + agent, ]) React.useEffect(() => { diff --git a/src/screens/Messages/Conversation/ChatDisabled.tsx b/src/screens/Messages/Conversation/ChatDisabled.tsx index 6665dd1710..5c6e615863 100644 --- a/src/screens/Messages/Conversation/ChatDisabled.tsx +++ b/src/screens/Messages/Conversation/ChatDisabled.tsx @@ -66,14 +66,14 @@ function DialogInner() { const control = Dialog.useDialogContext() const [details, setDetails] = useState('') const {gtMobile} = useBreakpoints() - const {getAgent} = useAgent() + const agent = useAgent() const {currentAccount} = useSession() const {mutate, isPending} = useMutation({ mutationFn: async () => { if (!currentAccount) throw new Error('No current account, should be unreachable') - await getAgent().createModerationReport({ + await agent.createModerationReport({ reasonType: ComAtprotoModerationDefs.REASONAPPEAL, subject: { $type: 'com.atproto.admin.defs#repoRef', diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index a03d6bc034..bee7f6cd8f 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -79,7 +79,7 @@ export function MessagesList({ footer?: React.ReactNode }) { const convoState = useConvoActive() - const {getAgent} = useAgent() + const agent = useAgent() const flatListRef = useAnimatedRef() @@ -265,7 +265,7 @@ export function MessagesList({ const onSendMessage = useCallback( async (text: string) => { let rt = new RichText({text}, {cleanNewlines: true}) - await rt.detectFacets(getAgent()) + await rt.detectFacets(agent) rt = shortenLinks(rt) // filter out any mention facets that didn't map to a user @@ -288,7 +288,7 @@ export function MessagesList({ facets: rt.facets, }) }, - [convoState, getAgent, hasScrolled, setHasScrolled], + [convoState, agent, hasScrolled, setHasScrolled], ) // -- List layout changes (opening emoji keyboard, etc.) diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx index 855e12ed08..9658cfe15f 100644 --- a/src/screens/Onboarding/StepFinished.tsx +++ b/src/screens/Onboarding/StepFinished.tsx @@ -47,7 +47,7 @@ export function StepFinished() { const [saving, setSaving] = React.useState(false) const {mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation() const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() const gate = useGate() const finishOnboarding = React.useCallback(async () => { @@ -70,12 +70,12 @@ export function StepFinished() { try { await Promise.all([ bulkWriteFollows( - getAgent, + agent, suggestedAccountsStepResults.accountDids.concat(BSKY_APP_ACCOUNT_DID), ), // these must be serial (async () => { - await getAgent().setInterestsPref({tags: selectedInterests}) + await agent.setInterestsPref({tags: selectedInterests}) /* * In the reduced onboading experiment, we'll rely on the default @@ -98,7 +98,7 @@ export function StepFinished() { * (mimics old behavior) */ if ( - IS_PROD_SERVICE(getAgent().service.toString()) && + IS_PROD_SERVICE(agent.service.toString()) && !otherFeeds.length ) { otherFeeds.push({ @@ -124,8 +124,8 @@ export function StepFinished() { const {imageUri, imageMime} = profileStepResults if (imageUri && imageMime) { - const blobPromise = uploadBlob(getAgent(), imageUri, imageMime) - await getAgent().upsertProfile(async existing => { + const blobPromise = uploadBlob(agent, imageUri, imageMime) + await agent.upsertProfile(async existing => { existing = existing ?? {} const res = await blobPromise if (res.data.blob) { @@ -156,7 +156,7 @@ export function StepFinished() { queryKey: preferencesQueryKey, }), queryClient.invalidateQueries({ - queryKey: profileRQKey(getAgent().session?.did ?? ''), + queryKey: profileRQKey(agent.session?.did ?? ''), }), ]).catch(e => { logger.error(e) @@ -176,7 +176,7 @@ export function StepFinished() { setSaving, overwriteSavedFeeds, track, - getAgent, + agent, gate, queryClient, ]) diff --git a/src/screens/Onboarding/StepInterests/index.tsx b/src/screens/Onboarding/StepInterests/index.tsx index d95445d795..2589e66c2d 100644 --- a/src/screens/Onboarding/StepInterests/index.tsx +++ b/src/screens/Onboarding/StepInterests/index.tsx @@ -43,13 +43,12 @@ export function StepInterests() { state.interestsStepResults.selectedInterests.map(i => i), ) const onboardDispatch = useOnboardingDispatch() - const {getAgent} = useAgent() + const agent = useAgent() const {isLoading, isError, error, data, refetch, isFetching} = useQuery({ queryKey: ['interests'], queryFn: async () => { try { - const {data} = - await getAgent().app.bsky.unspecced.getTaggedSuggestions() + const {data} = await agent.app.bsky.unspecced.getTaggedSuggestions() return data.suggestions.reduce( (agg, s) => { const {tag, subject, subjectType} = s diff --git a/src/screens/Onboarding/util.ts b/src/screens/Onboarding/util.ts index fde4316e93..4174177075 100644 --- a/src/screens/Onboarding/util.ts +++ b/src/screens/Onboarding/util.ts @@ -66,11 +66,8 @@ export function aggregateInterestItems( return Array.from(new Set(results)).slice(0, 20) } -export async function bulkWriteFollows( - getAgent: () => BskyAgent, - dids: string[], -) { - const session = getAgent().session +export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) { + const session = agent.session if (!session) { throw new Error(`bulkWriteFollows failed: no session`) @@ -89,19 +86,15 @@ export async function bulkWriteFollows( value: r, })) - await getAgent().com.atproto.repo.applyWrites({ + await agent.com.atproto.repo.applyWrites({ repo: session.did, writes: followWrites, }) - await whenFollowsIndexed( - getAgent, - session.did, - res => !!res.data.follows.length, - ) + await whenFollowsIndexed(agent, session.did, res => !!res.data.follows.length) } async function whenFollowsIndexed( - getAgent: () => BskyAgent, + agent: BskyAgent, actor: string, fn: (res: AppBskyGraphGetFollows.Response) => boolean, ) { @@ -110,7 +103,7 @@ async function whenFollowsIndexed( 1e3, // 1s delay between tries fn, () => - getAgent().app.bsky.graph.getFollows({ + agent.app.bsky.graph.getFollows({ actor, limit: 1, }), diff --git a/src/screens/Signup/index.tsx b/src/screens/Signup/index.tsx index 3d8b505b91..2cc1bcab0b 100644 --- a/src/screens/Signup/index.tsx +++ b/src/screens/Signup/index.tsx @@ -36,7 +36,7 @@ export function Signup({onPressBack}: {onPressBack: () => void}) { const [state, dispatch] = React.useReducer(reducer, initialState) const submit = useSubmitSignup({state, dispatch}) const {gtMobile} = useBreakpoints() - const {getAgent} = useAgent() + const agent = useAgent() const { data: serviceInfo, @@ -77,7 +77,7 @@ export function Signup({onPressBack}: {onPressBack: () => void}) { try { dispatch({type: 'setIsLoading', value: true}) - const res = await getAgent().resolveHandle({ + const res = await agent.resolveHandle({ handle: createFullHandle(state.handle, state.userDomain), }) @@ -115,7 +115,7 @@ export function Signup({onPressBack}: {onPressBack: () => void}) { state.serviceDescription?.phoneVerificationRequired, state.userDomain, submit, - getAgent, + agent, ]) const onBackPress = React.useCallback(() => { diff --git a/src/state/feed-feedback.tsx b/src/state/feed-feedback.tsx index 5bfc77d0a5..64bdd4b893 100644 --- a/src/state/feed-feedback.tsx +++ b/src/state/feed-feedback.tsx @@ -25,7 +25,7 @@ const stateContext = React.createContext({ }) export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) { - const {getAgent} = useAgent() + const agent = useAgent() const enabled = isDiscoverFeed(feed) && hasSession const queue = React.useRef>(new Set()) const history = React.useRef< @@ -35,7 +35,7 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) { >(new WeakSet()) const sendToFeedNoDelay = React.useCallback(() => { - const proxyAgent = getAgent().withProxy( + const proxyAgent = agent.withProxy( // @ts-ignore TODO need to update withProxy() to support this key -prf 'bsky_fg', // TODO when we start sending to other feeds, we need to grab their DID -prf @@ -50,7 +50,7 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) { .catch((e: any) => { logger.warn('Failed to send feed interactions', {error: e}) }) - }, [getAgent]) + }, [agent]) const sendToFeed = React.useMemo( () => diff --git a/src/state/messages/convo/index.tsx b/src/state/messages/convo/index.tsx index 7ba337e454..78c513909c 100644 --- a/src/state/messages/convo/index.tsx +++ b/src/state/messages/convo/index.tsx @@ -58,13 +58,13 @@ export function ConvoProvider({ convoId, }: Pick & {children: React.ReactNode}) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() const events = useMessagesEventBus() const [convo] = useState( () => new Convo({ convoId, - agent: getAgent(), + agent, events, }), ) diff --git a/src/state/messages/events/index.tsx b/src/state/messages/events/index.tsx index d972c8c6a6..b3321df640 100644 --- a/src/state/messages/events/index.tsx +++ b/src/state/messages/events/index.tsx @@ -43,11 +43,11 @@ export function MessagesEventBusProviderInner({ }: { children: React.ReactNode }) { - const {getAgent} = useAgent() + const agent = useAgent() const [bus] = React.useState( () => new MessagesEventBus({ - agent: getAgent(), + agent, }), ) diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts index 17b00dc26e..7e997ea016 100644 --- a/src/state/queries/actor-autocomplete.ts +++ b/src/state/queries/actor-autocomplete.ts @@ -23,7 +23,7 @@ export function useActorAutocompleteQuery( limit?: number, ) { const moderationOpts = useModerationOpts() - const {getAgent} = useAgent() + const agent = useAgent() prefix = prefix.toLowerCase().trim() if (prefix.endsWith('.')) { @@ -36,7 +36,7 @@ export function useActorAutocompleteQuery( queryKey: RQKEY(prefix || ''), async queryFn() { const res = prefix - ? await getAgent().searchActorsTypeahead({ + ? await agent.searchActorsTypeahead({ q: prefix, limit: limit || 8, }) @@ -57,7 +57,7 @@ export type ActorAutocompleteFn = ReturnType export function useActorAutocompleteFn() { const queryClient = useQueryClient() const moderationOpts = useModerationOpts() - const {getAgent} = useAgent() + const agent = useAgent() return React.useCallback( async ({query, limit = 8}: {query: string; limit?: number}) => { @@ -69,7 +69,7 @@ export function useActorAutocompleteFn() { staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(query || ''), queryFn: () => - getAgent().searchActorsTypeahead({ + agent.searchActorsTypeahead({ q: query, limit, }), @@ -86,7 +86,7 @@ export function useActorAutocompleteFn() { moderationOpts || DEFAULT_MOD_OPTS, ) }, - [queryClient, moderationOpts, getAgent], + [queryClient, moderationOpts, agent], ) } diff --git a/src/state/queries/actor-search.ts b/src/state/queries/actor-search.ts index e50c68aacd..1e301a1bac 100644 --- a/src/state/queries/actor-search.ts +++ b/src/state/queries/actor-search.ts @@ -14,12 +14,12 @@ export function useActorSearch({ query: string enabled?: boolean }) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(query || ''), async queryFn() { - const res = await getAgent().searchActors({ + const res = await agent.searchActors({ q: query, }) return res.data.actors diff --git a/src/state/queries/app-passwords.ts b/src/state/queries/app-passwords.ts index 33009a3a4a..bbf2dea974 100644 --- a/src/state/queries/app-passwords.ts +++ b/src/state/queries/app-passwords.ts @@ -8,12 +8,12 @@ const RQKEY_ROOT = 'app-passwords' export const RQKEY = () => [RQKEY_ROOT] export function useAppPasswordsQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.FIVE, queryKey: RQKEY(), queryFn: async () => { - const res = await getAgent().com.atproto.server.listAppPasswords({}) + const res = await agent.com.atproto.server.listAppPasswords({}) return res.data.passwords }, }) @@ -21,7 +21,7 @@ export function useAppPasswordsQuery() { export function useAppPasswordCreateMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation< ComAtprotoServerCreateAppPassword.OutputSchema, Error, @@ -29,7 +29,7 @@ export function useAppPasswordCreateMutation() { >({ mutationFn: async ({name, privileged}) => { return ( - await getAgent().com.atproto.server.createAppPassword({ + await agent.com.atproto.server.createAppPassword({ name, privileged, }) @@ -45,10 +45,10 @@ export function useAppPasswordCreateMutation() { export function useAppPasswordDeleteMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({name}) => { - await getAgent().com.atproto.server.revokeAppPassword({ + await agent.com.atproto.server.revokeAppPassword({ name, }) }, diff --git a/src/state/queries/feed.ts b/src/state/queries/feed.ts index 19cded087b..b599ac1a0f 100644 --- a/src/state/queries/feed.ts +++ b/src/state/queries/feed.ts @@ -147,7 +147,7 @@ export function getAvatarTypeFromUri(uri: string) { export function useFeedSourceInfoQuery({uri}: {uri: string}) { const type = getFeedTypeFromUri(uri) - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.INFINITY, @@ -156,10 +156,10 @@ export function useFeedSourceInfoQuery({uri}: {uri: string}) { let view: FeedSourceInfo if (type === 'feed') { - const res = await getAgent().app.bsky.feed.getFeedGenerator({feed: uri}) + const res = await agent.app.bsky.feed.getFeedGenerator({feed: uri}) view = hydrateFeedGenerator(res.data.view) } else { - const res = await getAgent().app.bsky.graph.getList({ + const res = await agent.app.bsky.graph.getList({ list: uri, limit: 1, }) @@ -174,7 +174,7 @@ export function useFeedSourceInfoQuery({uri}: {uri: string}) { export const useGetPopularFeedsQueryKey = ['getPopularFeeds'] export function useGetPopularFeedsQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyUnspeccedGetPopularFeedGenerators.OutputSchema, Error, @@ -184,7 +184,7 @@ export function useGetPopularFeedsQuery() { >({ queryKey: useGetPopularFeedsQueryKey, queryFn: async ({pageParam}) => { - const res = await getAgent().app.bsky.unspecced.getPopularFeedGenerators({ + const res = await agent.app.bsky.unspecced.getPopularFeedGenerators({ limit: 10, cursor: pageParam, }) @@ -196,10 +196,10 @@ export function useGetPopularFeedsQuery() { } export function useSearchPopularFeedsMutation() { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async (query: string) => { - const res = await getAgent().app.bsky.unspecced.getPopularFeedGenerators({ + const res = await agent.app.bsky.unspecced.getPopularFeedGenerators({ limit: 10, query: query, }) @@ -241,7 +241,7 @@ const pinnedFeedInfosQueryKeyRoot = 'pinnedFeedsInfos' export function usePinnedFeedsInfos() { const {hasSession} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const {data: preferences, isLoading: isLoadingPrefs} = usePreferencesQuery() const pinnedItems = preferences?.savedFeeds.filter(feed => feed.pinned) ?? [] @@ -264,8 +264,8 @@ export function usePinnedFeedsInfos() { const pinnedFeeds = pinnedItems.filter(feed => feed.type === 'feed') let feedsPromise = Promise.resolve() if (pinnedFeeds.length > 0) { - feedsPromise = getAgent() - .app.bsky.feed.getFeedGenerators({ + feedsPromise = agent.app.bsky.feed + .getFeedGenerators({ feeds: pinnedFeeds.map(f => f.value), }) .then(res => { @@ -279,8 +279,8 @@ export function usePinnedFeedsInfos() { // Get all lists. This currently has to be done individually. const pinnedLists = pinnedItems.filter(feed => feed.type === 'list') const listsPromises = pinnedLists.map(list => - getAgent() - .app.bsky.graph.getList({ + agent.app.bsky.graph + .getList({ list: list.value, limit: 1, }) diff --git a/src/state/queries/handle.ts b/src/state/queries/handle.ts index 1ab275fcf7..d2d79e12d2 100644 --- a/src/state/queries/handle.ts +++ b/src/state/queries/handle.ts @@ -14,7 +14,7 @@ const fetchDidQueryKey = (handleOrDid: string) => [didQueryKeyRoot, handleOrDid] export function useFetchHandle() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return React.useCallback( async (handleOrDid: string) => { @@ -22,23 +22,23 @@ export function useFetchHandle() { const res = await queryClient.fetchQuery({ staleTime: STALE.MINUTES.FIVE, queryKey: fetchHandleQueryKey(handleOrDid), - queryFn: () => getAgent().getProfile({actor: handleOrDid}), + queryFn: () => agent.getProfile({actor: handleOrDid}), }) return res.data.handle } return handleOrDid }, - [queryClient, getAgent], + [queryClient, agent], ) } export function useUpdateHandleMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({handle}: {handle: string}) => { - await getAgent().updateHandle({handle}) + await agent.updateHandle({handle}) }, onSuccess(_data, variables) { queryClient.invalidateQueries({ @@ -50,7 +50,7 @@ export function useUpdateHandleMutation() { export function useFetchDid() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return React.useCallback( async (handleOrDid: string) => { @@ -60,13 +60,13 @@ export function useFetchDid() { queryFn: async () => { let identifier = handleOrDid if (!identifier.startsWith('did:')) { - const res = await getAgent().resolveHandle({handle: identifier}) + const res = await agent.resolveHandle({handle: identifier}) identifier = res.data.did } return identifier }, }) }, - [queryClient, getAgent], + [queryClient, agent], ) } diff --git a/src/state/queries/invites.ts b/src/state/queries/invites.ts index f9cf25c697..fdccac8cbd 100644 --- a/src/state/queries/invites.ts +++ b/src/state/queries/invites.ts @@ -16,13 +16,13 @@ export type InviteCodesQueryResponse = Exclude< undefined > export function useInviteCodesQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.FIVE, queryKey: [inviteCodesQueryKeyRoot], queryFn: async () => { - const res = await getAgent() - .com.atproto.server.getAccountInviteCodes({}) + const res = await agent.com.atproto.server + .getAccountInviteCodes({}) .catch(e => { if (cleanError(e) === 'Bad token scope') { return null diff --git a/src/state/queries/labeler.ts b/src/state/queries/labeler.ts index 359291636c..058e8fcdee 100644 --- a/src/state/queries/labeler.ts +++ b/src/state/queries/labeler.ts @@ -31,12 +31,12 @@ export function useLabelerInfoQuery({ did?: string enabled?: boolean }) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ enabled: !!did && enabled !== false, queryKey: labelerInfoQueryKey(did as string), queryFn: async () => { - const res = await getAgent().app.bsky.labeler.getServices({ + const res = await agent.app.bsky.labeler.getServices({ dids: [did as string], detailed: true, }) @@ -46,26 +46,26 @@ export function useLabelerInfoQuery({ } export function useLabelersInfoQuery({dids}: {dids: string[]}) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ enabled: !!dids.length, queryKey: labelersInfoQueryKey(dids), queryFn: async () => { - const res = await getAgent().app.bsky.labeler.getServices({dids}) + const res = await agent.app.bsky.labeler.getServices({dids}) return res.data.views as AppBskyLabelerDefs.LabelerView[] }, }) } export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ enabled: !!dids.length, queryKey: labelersDetailedInfoQueryKey(dids), gcTime: 1000 * 60 * 60 * 6, // 6 hours staleTime: STALE.MINUTES.ONE, queryFn: async () => { - const res = await getAgent().app.bsky.labeler.getServices({ + const res = await agent.app.bsky.labeler.getServices({ dids, detailed: true, }) @@ -76,7 +76,7 @@ export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { export function useLabelerSubscriptionMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) { @@ -87,9 +87,9 @@ export function useLabelerSubscriptionMutation() { }).parse({did, subscribe}) if (subscribe) { - await getAgent().addLabeler(did) + await agent.addLabeler(did) } else { - await getAgent().removeLabeler(did) + await agent.removeLabeler(did) } }, onSuccess() { diff --git a/src/state/queries/like.ts b/src/state/queries/like.ts index 75e93951a5..fa40300a40 100644 --- a/src/state/queries/like.ts +++ b/src/state/queries/like.ts @@ -3,20 +3,20 @@ import {useMutation} from '@tanstack/react-query' import {useAgent} from '#/state/session' export function useLikeMutation() { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({uri, cid}: {uri: string; cid: string}) => { - const res = await getAgent().like(uri, cid) + const res = await agent.like(uri, cid) return {uri: res.uri} }, }) } export function useUnlikeMutation() { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({uri}: {uri: string}) => { - await getAgent().deleteLike(uri) + await agent.deleteLike(uri) }, }) } diff --git a/src/state/queries/list-members.ts b/src/state/queries/list-members.ts index 6f87d53c0f..de9a36ab7f 100644 --- a/src/state/queries/list-members.ts +++ b/src/state/queries/list-members.ts @@ -16,7 +16,7 @@ const RQKEY_ROOT = 'list-members' export const RQKEY = (uri: string) => [RQKEY_ROOT, uri] export function useListMembersQuery(uri: string) { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyGraphGetList.OutputSchema, Error, @@ -27,7 +27,7 @@ export function useListMembersQuery(uri: string) { staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(uri), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.graph.getList({ + const res = await agent.app.bsky.graph.getList({ list: uri, limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/list-memberships.ts b/src/state/queries/list-memberships.ts index 46e6bdfc2c..83a2c2db13 100644 --- a/src/state/queries/list-memberships.ts +++ b/src/state/queries/list-memberships.ts @@ -40,7 +40,7 @@ export interface ListMembersip { */ export function useDangerousListMembershipsQuery() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.FIVE, queryKey: RQKEY(), @@ -51,7 +51,7 @@ export function useDangerousListMembershipsQuery() { let cursor let arr: ListMembersip[] = [] for (let i = 0; i < SANITY_PAGE_LIMIT; i++) { - const res = await getAgent().app.bsky.graph.listitem.list({ + const res = await agent.app.bsky.graph.listitem.list({ repo: currentAccount.did, limit: PAGE_SIZE, cursor, @@ -92,7 +92,7 @@ export function getMembership( export function useListMembershipAddMutation() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation< {uri: string; cid: string}, @@ -103,7 +103,7 @@ export function useListMembershipAddMutation() { if (!currentAccount) { throw new Error('Not logged in') } - const res = await getAgent().app.bsky.graph.listitem.create( + const res = await agent.app.bsky.graph.listitem.create( {repo: currentAccount.did}, { subject: actorDid, @@ -151,7 +151,7 @@ export function useListMembershipAddMutation() { export function useListMembershipRemoveMutation() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation< void, @@ -163,7 +163,7 @@ export function useListMembershipRemoveMutation() { throw new Error('Not logged in') } const membershipUrip = new AtUri(membershipUri) - await getAgent().app.bsky.graph.listitem.delete({ + await agent.app.bsky.graph.listitem.delete({ repo: currentAccount.did, rkey: membershipUrip.rkey, }) diff --git a/src/state/queries/list.ts b/src/state/queries/list.ts index dd2e21fb63..eeb9c3b381 100644 --- a/src/state/queries/list.ts +++ b/src/state/queries/list.ts @@ -21,7 +21,7 @@ const RQKEY_ROOT = 'list' export const RQKEY = (uri: string) => [RQKEY_ROOT, uri] export function useListQuery(uri?: string) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(uri || ''), @@ -29,7 +29,7 @@ export function useListQuery(uri?: string) { if (!uri) { throw new Error('URI not provided') } - const res = await getAgent().app.bsky.graph.getList({ + const res = await agent.app.bsky.graph.getList({ list: uri, limit: 1, }) @@ -49,7 +49,7 @@ export interface ListCreateMutateParams { export function useListCreateMutation() { const {currentAccount} = useSession() const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation<{uri: string; cid: string}, Error, ListCreateMutateParams>( { async mutationFn({ @@ -77,10 +77,10 @@ export function useListCreateMutation() { createdAt: new Date().toISOString(), } if (avatar) { - const blobRes = await uploadBlob(getAgent(), avatar.path, avatar.mime) + const blobRes = await uploadBlob(agent, avatar.path, avatar.mime) record.avatar = blobRes.data.blob } - const res = await getAgent().app.bsky.graph.list.create( + const res = await agent.app.bsky.graph.list.create( { repo: currentAccount.did, }, @@ -89,7 +89,7 @@ export function useListCreateMutation() { // wait for the appview to update await whenAppViewReady( - getAgent, + agent, res.uri, (v: AppBskyGraphGetList.Response) => { return typeof v?.data?.list.uri === 'string' @@ -116,7 +116,7 @@ export interface ListMetadataMutateParams { } export function useListMetadataMutation() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation< {uri: string; cid: string}, @@ -133,7 +133,7 @@ export function useListMetadataMutation() { } // get the current record - const {value: record} = await getAgent().app.bsky.graph.list.get({ + const {value: record} = await agent.app.bsky.graph.list.get({ repo: currentAccount.did, rkey, }) @@ -143,13 +143,13 @@ export function useListMetadataMutation() { record.description = description record.descriptionFacets = descriptionFacets if (avatar) { - const blobRes = await uploadBlob(getAgent(), avatar.path, avatar.mime) + const blobRes = await uploadBlob(agent, avatar.path, avatar.mime) record.avatar = blobRes.data.blob } else if (avatar === null) { record.avatar = undefined } const res = ( - await getAgent().com.atproto.repo.putRecord({ + await agent.com.atproto.repo.putRecord({ repo: currentAccount.did, collection: 'app.bsky.graph.list', rkey, @@ -159,7 +159,7 @@ export function useListMetadataMutation() { // wait for the appview to update await whenAppViewReady( - getAgent, + agent, res.uri, (v: AppBskyGraphGetList.Response) => { const list = v.data.list @@ -184,7 +184,7 @@ export function useListMetadataMutation() { export function useListDeleteMutation() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation({ mutationFn: async ({uri}) => { @@ -195,7 +195,7 @@ export function useListDeleteMutation() { let cursor let listitemRecordUris: string[] = [] for (let i = 0; i < 100; i++) { - const res = await getAgent().app.bsky.graph.listitem.list({ + const res = await agent.app.bsky.graph.listitem.list({ repo: currentAccount.did, cursor, limit: 100, @@ -226,20 +226,16 @@ export function useListDeleteMutation() { // apply in chunks for (const writesChunk of chunk(writes, 10)) { - await getAgent().com.atproto.repo.applyWrites({ + await agent.com.atproto.repo.applyWrites({ repo: currentAccount.did, writes: writesChunk, }) } // wait for the appview to update - await whenAppViewReady( - getAgent, - uri, - (v: AppBskyGraphGetList.Response) => { - return !v?.success - }, - ) + await whenAppViewReady(agent, uri, (v: AppBskyGraphGetList.Response) => { + return !v?.success + }) }, onSuccess() { invalidateMyLists(queryClient) @@ -253,22 +249,18 @@ export function useListDeleteMutation() { export function useListMuteMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({uri, mute}) => { if (mute) { - await getAgent().muteModList(uri) + await agent.muteModList(uri) } else { - await getAgent().unmuteModList(uri) + await agent.unmuteModList(uri) } - await whenAppViewReady( - getAgent, - uri, - (v: AppBskyGraphGetList.Response) => { - return Boolean(v?.data.list.viewer?.muted) === mute - }, - ) + await whenAppViewReady(agent, uri, (v: AppBskyGraphGetList.Response) => { + return Boolean(v?.data.list.viewer?.muted) === mute + }) }, onSuccess(data, variables) { queryClient.invalidateQueries({ @@ -280,24 +272,20 @@ export function useListMuteMutation() { export function useListBlockMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({uri, block}) => { if (block) { - await getAgent().blockModList(uri) + await agent.blockModList(uri) } else { - await getAgent().unblockModList(uri) + await agent.unblockModList(uri) } - await whenAppViewReady( - getAgent, - uri, - (v: AppBskyGraphGetList.Response) => { - return block - ? typeof v?.data.list.viewer?.blocked === 'string' - : !v?.data.list.viewer?.blocked - }, - ) + await whenAppViewReady(agent, uri, (v: AppBskyGraphGetList.Response) => { + return block + ? typeof v?.data.list.viewer?.blocked === 'string' + : !v?.data.list.viewer?.blocked + }) }, onSuccess(data, variables) { queryClient.invalidateQueries({ @@ -308,7 +296,7 @@ export function useListBlockMutation() { } async function whenAppViewReady( - getAgent: () => BskyAgent, + agent: BskyAgent, uri: string, fn: (res: AppBskyGraphGetList.Response) => boolean, ) { @@ -317,7 +305,7 @@ async function whenAppViewReady( 1e3, // 1s delay between tries fn, () => - getAgent().app.bsky.graph.getList({ + agent.app.bsky.graph.getList({ list: uri, limit: 1, }), diff --git a/src/state/queries/messages/actor-declaration.ts b/src/state/queries/messages/actor-declaration.ts index d6a86cf698..1105e2b3cb 100644 --- a/src/state/queries/messages/actor-declaration.ts +++ b/src/state/queries/messages/actor-declaration.ts @@ -14,12 +14,12 @@ export function useUpdateActorDeclaration({ }) { const queryClient = useQueryClient() const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async (allowIncoming: 'all' | 'none' | 'following') => { if (!currentAccount) throw new Error('Not logged in') - const result = await getAgent().api.com.atproto.repo.putRecord({ + const result = await agent.api.com.atproto.repo.putRecord({ repo: currentAccount.did, collection: 'chat.bsky.actor.declaration', rkey: 'self', @@ -64,13 +64,13 @@ export function useUpdateActorDeclaration({ // for use in the settings screen for testing export function useDeleteActorDeclaration() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async () => { if (!currentAccount) throw new Error('Not logged in') // TODO(sam): remove validate: false once PDSes have the new lexicon - const result = await getAgent().api.com.atproto.repo.deleteRecord({ + const result = await agent.api.com.atproto.repo.deleteRecord({ repo: currentAccount.did, collection: 'chat.bsky.actor.declaration', rkey: 'self', diff --git a/src/state/queries/messages/conversation.ts b/src/state/queries/messages/conversation.ts index baf69223a5..16ace3c5a8 100644 --- a/src/state/queries/messages/conversation.ts +++ b/src/state/queries/messages/conversation.ts @@ -11,12 +11,12 @@ const RQKEY_ROOT = 'convo' export const RQKEY = (convoId: string) => [RQKEY_ROOT, convoId] export function useConvoQuery(convo: ChatBskyConvoDefs.ConvoView) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ queryKey: RQKEY(convo.id), queryFn: async () => { - const {data} = await getAgent().api.chat.bsky.convo.getConvo( + const {data} = await agent.api.chat.bsky.convo.getConvo( {convoId: convo.id}, {headers: DM_SERVICE_HEADERS}, ) @@ -30,7 +30,7 @@ export function useConvoQuery(convo: ChatBskyConvoDefs.ConvoView) { export function useMarkAsReadMutation() { const optimisticUpdate = useOnMarkAsRead() const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({ @@ -42,7 +42,7 @@ export function useMarkAsReadMutation() { }) => { if (!convoId) throw new Error('No convoId provided') - await getAgent().api.chat.bsky.convo.updateRead( + await agent.api.chat.bsky.convo.updateRead( { convoId, messageId, diff --git a/src/state/queries/messages/get-convo-for-members.ts b/src/state/queries/messages/get-convo-for-members.ts index a260d54161..7979e06659 100644 --- a/src/state/queries/messages/get-convo-for-members.ts +++ b/src/state/queries/messages/get-convo-for-members.ts @@ -18,11 +18,11 @@ export function useGetConvoForMembers({ onError?: (error: Error) => void }) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async (members: string[]) => { - const {data} = await getAgent().api.chat.bsky.convo.getConvoForMembers( + const {data} = await agent.api.chat.bsky.convo.getConvoForMembers( {members: members}, {headers: DM_SERVICE_HEADERS}, ) @@ -44,16 +44,13 @@ export function useGetConvoForMembers({ * Gets the conversation ID for a given DID. Returns null if it's not possible to message them. */ export function useMaybeConvoForUser(did: string) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ queryKey: RQKEY(did), queryFn: async () => { - const convo = await getAgent() - .api.chat.bsky.convo.getConvoForMembers( - {members: [did]}, - {headers: DM_SERVICE_HEADERS}, - ) + const convo = await agent.api.chat.bsky.convo + .getConvoForMembers({members: [did]}, {headers: DM_SERVICE_HEADERS}) .catch(() => ({success: null})) if (convo.success) { diff --git a/src/state/queries/messages/leave-conversation.ts b/src/state/queries/messages/leave-conversation.ts index 9f45de5445..29c71a6066 100644 --- a/src/state/queries/messages/leave-conversation.ts +++ b/src/state/queries/messages/leave-conversation.ts @@ -17,13 +17,13 @@ export function useLeaveConvo( }, ) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async () => { if (!convoId) throw new Error('No convoId provided') - const {data} = await getAgent().api.chat.bsky.convo.leaveConvo( + const {data} = await agent.api.chat.bsky.convo.leaveConvo( {convoId}, {headers: DM_SERVICE_HEADERS, encoding: 'application/json'}, ) diff --git a/src/state/queries/messages/list-converations.tsx b/src/state/queries/messages/list-converations.tsx index 13a4a3bf21..46892f6aeb 100644 --- a/src/state/queries/messages/list-converations.tsx +++ b/src/state/queries/messages/list-converations.tsx @@ -27,12 +27,12 @@ export const RQKEY = ['convo-list'] type RQPageParam = string | undefined export function useListConvosQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery({ queryKey: RQKEY, queryFn: async ({pageParam}) => { - const {data} = await getAgent().api.chat.bsky.convo.listConvos( + const {data} = await agent.api.chat.bsky.convo.listConvos( {cursor: pageParam}, {headers: DM_SERVICE_HEADERS}, ) diff --git a/src/state/queries/messages/mute-conversation.ts b/src/state/queries/messages/mute-conversation.ts index fa760e00de..bc383fde11 100644 --- a/src/state/queries/messages/mute-conversation.ts +++ b/src/state/queries/messages/mute-conversation.ts @@ -21,13 +21,11 @@ export function useMuteConvo( }, ) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({mute}: {mute: boolean}) => { if (!convoId) throw new Error('No convoId provided') - - const agent = getAgent() if (mute) { const {data} = await agent.api.chat.bsky.convo.muteConvo( {convoId}, diff --git a/src/state/queries/my-blocked-accounts.ts b/src/state/queries/my-blocked-accounts.ts index 73e2890569..05a78825fa 100644 --- a/src/state/queries/my-blocked-accounts.ts +++ b/src/state/queries/my-blocked-accounts.ts @@ -13,7 +13,7 @@ export const RQKEY = () => [RQKEY_ROOT] type RQPageParam = string | undefined export function useMyBlockedAccountsQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyGraphGetBlocks.OutputSchema, Error, @@ -23,7 +23,7 @@ export function useMyBlockedAccountsQuery() { >({ queryKey: RQKEY(), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.graph.getBlocks({ + const res = await agent.app.bsky.graph.getBlocks({ limit: 30, cursor: pageParam, }) diff --git a/src/state/queries/my-lists.ts b/src/state/queries/my-lists.ts index 7fce8b68ea..0f8721c61a 100644 --- a/src/state/queries/my-lists.ts +++ b/src/state/queries/my-lists.ts @@ -16,7 +16,7 @@ export const RQKEY = (filter: MyListsFilter) => [RQKEY_ROOT, filter] export function useMyListsQuery(filter: MyListsFilter) { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(filter), @@ -24,8 +24,8 @@ export function useMyListsQuery(filter: MyListsFilter) { let lists: AppBskyGraphDefs.ListView[] = [] const promises = [ accumulate(cursor => - getAgent() - .app.bsky.graph.getLists({ + agent.app.bsky.graph + .getLists({ actor: currentAccount!.did, cursor, limit: 50, @@ -39,8 +39,8 @@ export function useMyListsQuery(filter: MyListsFilter) { if (filter === 'all-including-subscribed' || filter === 'mod') { promises.push( accumulate(cursor => - getAgent() - .app.bsky.graph.getListMutes({ + agent.app.bsky.graph + .getListMutes({ cursor, limit: 50, }) @@ -52,8 +52,8 @@ export function useMyListsQuery(filter: MyListsFilter) { ) promises.push( accumulate(cursor => - getAgent() - .app.bsky.graph.getListBlocks({ + agent.app.bsky.graph + .getListBlocks({ cursor, limit: 50, }) diff --git a/src/state/queries/my-muted-accounts.ts b/src/state/queries/my-muted-accounts.ts index 6eded3f83f..5fb0fa79b9 100644 --- a/src/state/queries/my-muted-accounts.ts +++ b/src/state/queries/my-muted-accounts.ts @@ -13,7 +13,7 @@ export const RQKEY = () => [RQKEY_ROOT] type RQPageParam = string | undefined export function useMyMutedAccountsQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyGraphGetMutes.OutputSchema, Error, @@ -23,7 +23,7 @@ export function useMyMutedAccountsQuery() { >({ queryKey: RQKEY(), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.graph.getMutes({ + const res = await agent.app.bsky.graph.getMutes({ limit: 30, cursor: pageParam, }) diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts index 80e5a4c472..523af28244 100644 --- a/src/state/queries/notifications/feed.ts +++ b/src/state/queries/notifications/feed.ts @@ -47,7 +47,7 @@ export function RQKEY() { } export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() const moderationOpts = useModerationOpts() const threadMutes = useMutedThreads() @@ -73,7 +73,7 @@ export function useNotificationFeedQuery(opts?: {enabled?: boolean}) { if (!page) { page = ( await fetchPage({ - getAgent, + agent, limit: PAGE_SIZE, cursor: pageParam, queryClient, diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx index acc68c360e..5f33cdf740 100644 --- a/src/state/queries/notifications/unread.tsx +++ b/src/state/queries/notifications/unread.tsx @@ -45,7 +45,7 @@ const apiContext = React.createContext({ export function Provider({children}: React.PropsWithChildren<{}>) { const {hasSession} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() const moderationOpts = useModerationOpts() const threadMutes = useMutedThreads() @@ -112,7 +112,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { return { async markAllRead() { // update server - await getAgent().updateSeenNotifications( + await agent.updateSeenNotifications( cacheRef.current.syncedAt.toISOString(), ) @@ -127,7 +127,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { isPoll, }: {invalidate?: boolean; isPoll?: boolean} = {}) { try { - if (!getAgent().session) return + if (!agent.session) return if (AppState.currentState !== 'active') { return } @@ -142,7 +142,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { // count const {page, indexedAt: lastIndexed} = await fetchPage({ - getAgent, + agent, cursor: undefined, limit: 40, queryClient, @@ -192,7 +192,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { } }, } - }, [setNumUnread, queryClient, moderationOpts, threadMutes, getAgent]) + }, [setNumUnread, queryClient, moderationOpts, threadMutes, agent]) checkUnreadRef.current = api.checkUnread return ( diff --git a/src/state/queries/notifications/util.ts b/src/state/queries/notifications/util.ts index 5029a33ccc..ebcdff6866 100644 --- a/src/state/queries/notifications/util.ts +++ b/src/state/queries/notifications/util.ts @@ -23,7 +23,7 @@ const MS_2DAY = MS_1HR * 48 // = export async function fetchPage({ - getAgent, + agent, cursor, limit, queryClient, @@ -31,7 +31,7 @@ export async function fetchPage({ threadMutes, fetchAdditionalData, }: { - getAgent: () => BskyAgent + agent: BskyAgent cursor: string | undefined limit: number queryClient: QueryClient @@ -39,7 +39,7 @@ export async function fetchPage({ threadMutes: string[] fetchAdditionalData: boolean }): Promise<{page: FeedPage; indexedAt: string | undefined}> { - const res = await getAgent().listNotifications({ + const res = await agent.listNotifications({ limit, cursor, }) @@ -56,7 +56,7 @@ export async function fetchPage({ // we fetch subjects of notifications (usually posts) now instead of lazily // in the UI to avoid relayouts if (fetchAdditionalData) { - const subjects = await fetchSubjects(getAgent, notifsGrouped) + const subjects = await fetchSubjects(agent, notifsGrouped) for (const notif of notifsGrouped) { if (notif.subjectUri) { notif.subject = subjects.get(notif.subjectUri) @@ -140,7 +140,7 @@ export function groupNotifications( } async function fetchSubjects( - getAgent: () => BskyAgent, + agent: BskyAgent, groupedNotifs: FeedNotification[], ): Promise> { const uris = new Set() @@ -152,9 +152,7 @@ async function fetchSubjects( const uriChunks = chunk(Array.from(uris), 25) const postsChunks = await Promise.all( uriChunks.map(uris => - getAgent() - .app.bsky.feed.getPosts({uris}) - .then(res => res.data.posts), + agent.app.bsky.feed.getPosts({uris}).then(res => res.data.posts), ), ) const map = new Map() diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts index 2851a0c2ac..eeec692c67 100644 --- a/src/state/queries/post-feed.ts +++ b/src/state/queries/post-feed.ts @@ -117,7 +117,7 @@ export function usePostFeedQuery( f => f.pinned && f.value === 'following', ) ?? -1 const enableFollowingToDiscoverFallback = followingPinnedIndex === 0 - const {getAgent} = useAgent() + const agent = useAgent() const lastRun = useRef<{ data: InfiniteData args: typeof selectArgs @@ -155,7 +155,7 @@ export function usePostFeedQuery( feedDesc, feedParams: params || {}, feedTuners, - getAgent, + agent, // Not in the query key because they don't change: userInterests, // Not in the query key. Reacting to it switching isn't important: @@ -173,7 +173,7 @@ export function usePostFeedQuery( * moderations happen later, which results in some posts being shown and * some not. */ - if (!getAgent().session) { + if (!agent.session) { assertSomePostsPassModeration(res.feed) } @@ -397,50 +397,50 @@ function createApi({ feedParams, feedTuners, userInterests, - getAgent, + agent, enableFollowingToDiscoverFallback, }: { feedDesc: FeedDescriptor feedParams: FeedParams feedTuners: FeedTunerFn[] userInterests?: string - getAgent: () => BskyAgent + agent: BskyAgent enableFollowingToDiscoverFallback: boolean }) { if (feedDesc === 'following') { if (feedParams.mergeFeedEnabled) { return new MergeFeedAPI({ - getAgent, + agent, feedParams, feedTuners, userInterests, }) } else { if (enableFollowingToDiscoverFallback) { - return new HomeFeedAPI({getAgent, userInterests}) + return new HomeFeedAPI({agent, userInterests}) } else { - return new FollowingFeedAPI({getAgent}) + return new FollowingFeedAPI({agent}) } } } else if (feedDesc.startsWith('author')) { const [_, actor, filter] = feedDesc.split('|') - return new AuthorFeedAPI({getAgent, feedParams: {actor, filter}}) + return new AuthorFeedAPI({agent, feedParams: {actor, filter}}) } else if (feedDesc.startsWith('likes')) { const [_, actor] = feedDesc.split('|') - return new LikesFeedAPI({getAgent, feedParams: {actor}}) + return new LikesFeedAPI({agent, feedParams: {actor}}) } else if (feedDesc.startsWith('feedgen')) { const [_, feed] = feedDesc.split('|') return new CustomFeedAPI({ - getAgent, + agent, feedParams: {feed}, userInterests, }) } else if (feedDesc.startsWith('list')) { const [_, list] = feedDesc.split('|') - return new ListFeedAPI({getAgent, feedParams: {list}}) + return new ListFeedAPI({agent, feedParams: {list}}) } else { // shouldnt happen - return new FollowingFeedAPI({getAgent}) + return new FollowingFeedAPI({agent}) } } diff --git a/src/state/queries/post-liked-by.ts b/src/state/queries/post-liked-by.ts index fdf6948609..ab9f5c7bba 100644 --- a/src/state/queries/post-liked-by.ts +++ b/src/state/queries/post-liked-by.ts @@ -16,7 +16,7 @@ const RQKEY_ROOT = 'liked-by' export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export function useLikedByQuery(resolvedUri: string | undefined) { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyFeedGetLikes.OutputSchema, Error, @@ -26,7 +26,7 @@ export function useLikedByQuery(resolvedUri: string | undefined) { >({ queryKey: RQKEY(resolvedUri || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().getLikes({ + const res = await agent.getLikes({ uri: resolvedUri || '', limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/post-reposted-by.ts b/src/state/queries/post-reposted-by.ts index 13643e98d2..a27f203dd9 100644 --- a/src/state/queries/post-reposted-by.ts +++ b/src/state/queries/post-reposted-by.ts @@ -16,7 +16,7 @@ const RQKEY_ROOT = 'post-reposted-by' export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export function usePostRepostedByQuery(resolvedUri: string | undefined) { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyFeedGetRepostedBy.OutputSchema, Error, @@ -26,7 +26,7 @@ export function usePostRepostedByQuery(resolvedUri: string | undefined) { >({ queryKey: RQKEY(resolvedUri || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().getRepostedBy({ + const res = await agent.getRepostedBy({ uri: resolvedUri || '', limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/post-thread.ts b/src/state/queries/post-thread.ts index 4ee0eb3f9e..6c70bbc5d7 100644 --- a/src/state/queries/post-thread.ts +++ b/src/state/queries/post-thread.ts @@ -68,12 +68,12 @@ export type ThreadModerationCache = WeakMap export function usePostThreadQuery(uri: string | undefined) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ gcTime: 0, queryKey: RQKEY(uri || ''), async queryFn() { - const res = await getAgent().getPostThread({uri: uri!}) + const res = await agent.getPostThread({uri: uri!}) if (res.success) { return responseToThreadNodes(res.data.thread) } diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts index d52c657134..f27628d696 100644 --- a/src/state/queries/post.ts +++ b/src/state/queries/post.ts @@ -14,11 +14,11 @@ const RQKEY_ROOT = 'post' export const RQKEY = (postUri: string) => [RQKEY_ROOT, postUri] export function usePostQuery(uri: string | undefined) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ queryKey: RQKEY(uri || ''), async queryFn() { - const res = await getAgent().getPosts({uris: [uri!]}) + const res = await agent.getPosts({uris: [uri!]}) if (res.success && res.data.posts[0]) { return res.data.posts[0] } @@ -31,7 +31,7 @@ export function usePostQuery(uri: string | undefined) { export function useGetPost() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useCallback( async ({uri}: {uri: string}) => { return queryClient.fetchQuery({ @@ -40,13 +40,13 @@ export function useGetPost() { const urip = new AtUri(uri) if (!urip.host.startsWith('did:')) { - const res = await getAgent().resolveHandle({ + const res = await agent.resolveHandle({ handle: urip.host, }) urip.host = res.data.did } - const res = await getAgent().getPosts({ + const res = await agent.getPosts({ uris: [urip.toString()!], }) @@ -58,7 +58,7 @@ export function useGetPost() { }, }) }, - [queryClient, getAgent], + [queryClient, agent], ) } @@ -127,7 +127,7 @@ function usePostLikeMutation( const {currentAccount} = useSession() const queryClient = useQueryClient() const postAuthor = post.author - const {getAgent} = useAgent() + const agent = useAgent() return useMutation< {uri: string}, // responds with the uri of the like Error, @@ -154,7 +154,7 @@ function usePostLikeMutation( ? toClout(post.likeCount + post.repostCount + post.replyCount) : undefined, }) - return getAgent().like(uri, cid) + return agent.like(uri, cid) }, onSuccess() { track('Post:Like') @@ -165,11 +165,11 @@ function usePostLikeMutation( function usePostUnlikeMutation( logContext: LogEvents['post:unlike']['logContext'], ) { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: ({likeUri}) => { logEvent('post:unlike', {logContext}) - return getAgent().deleteLike(likeUri) + return agent.deleteLike(likeUri) }, onSuccess() { track('Post:Unlike') @@ -238,7 +238,7 @@ export function usePostRepostMutationQueue( function usePostRepostMutation( logContext: LogEvents['post:repost']['logContext'], ) { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation< {uri: string}, // responds with the uri of the repost Error, @@ -246,7 +246,7 @@ function usePostRepostMutation( >({ mutationFn: post => { logEvent('post:repost', {logContext}) - return getAgent().repost(post.uri, post.cid) + return agent.repost(post.uri, post.cid) }, onSuccess() { track('Post:Repost') @@ -257,11 +257,11 @@ function usePostRepostMutation( function usePostUnrepostMutation( logContext: LogEvents['post:unrepost']['logContext'], ) { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: ({repostUri}) => { logEvent('post:unrepost', {logContext}) - return getAgent().deleteRepost(repostUri) + return agent.deleteRepost(repostUri) }, onSuccess() { track('Post:Unrepost') @@ -271,10 +271,10 @@ function usePostUnrepostMutation( export function usePostDeleteMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({uri}) => { - await getAgent().deletePost(uri) + await agent.deletePost(uri) }, onSuccess(data, variables) { updatePostShadow(queryClient, variables.uri, {isDeleted: true}) diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts index 555fd85a49..672abfcac5 100644 --- a/src/state/queries/preferences/index.ts +++ b/src/state/queries/preferences/index.ts @@ -30,15 +30,13 @@ const preferencesQueryKeyRoot = 'getPreferences' export const preferencesQueryKey = [preferencesQueryKeyRoot] export function usePreferencesQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.SECONDS.FIFTEEN, structuralSharing: replaceEqualDeep, refetchOnWindowFocus: true, queryKey: preferencesQueryKey, queryFn: async () => { - const agent = getAgent() - if (agent.session?.did === undefined) { return DEFAULT_LOGGED_OUT_PREFERENCES } else { @@ -75,11 +73,11 @@ export function usePreferencesQuery() { export function useClearPreferencesMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async () => { - await getAgent().app.bsky.actor.putPreferences({preferences: []}) + await agent.app.bsky.actor.putPreferences({preferences: []}) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -89,7 +87,7 @@ export function useClearPreferencesMutation() { } export function usePreferencesSetContentLabelMutation() { - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation< @@ -98,7 +96,7 @@ export function usePreferencesSetContentLabelMutation() { {label: string; visibility: LabelPreference; labelerDid: string | undefined} >({ mutationFn: async ({label, visibility, labelerDid}) => { - await getAgent().setContentLabelPref(label, visibility, labelerDid) + await agent.setContentLabelPref(label, visibility, labelerDid) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -109,7 +107,7 @@ export function usePreferencesSetContentLabelMutation() { export function useSetContentLabelMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({ @@ -121,7 +119,7 @@ export function useSetContentLabelMutation() { visibility: LabelPreference labelerDid?: string }) => { - await getAgent().setContentLabelPref(label, visibility, labelerDid) + await agent.setContentLabelPref(label, visibility, labelerDid) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -132,11 +130,11 @@ export function useSetContentLabelMutation() { export function usePreferencesSetAdultContentMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({enabled}) => { - await getAgent().setAdultContentEnabled(enabled) + await agent.setAdultContentEnabled(enabled) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -147,11 +145,11 @@ export function usePreferencesSetAdultContentMutation() { export function usePreferencesSetBirthDateMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({birthDate}: {birthDate: Date}) => { - await getAgent().setPersonalDetails({birthDate: birthDate.toISOString()}) + await agent.setPersonalDetails({birthDate: birthDate.toISOString()}) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -162,7 +160,7 @@ export function usePreferencesSetBirthDateMutation() { export function useSetFeedViewPreferencesMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation>({ mutationFn: async prefs => { @@ -170,7 +168,7 @@ export function useSetFeedViewPreferencesMutation() { * special handling here, merged into `feedViewPrefs` above, since * following was previously called `home` */ - await getAgent().setFeedViewPrefs('home', prefs) + await agent.setFeedViewPrefs('home', prefs) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -181,11 +179,11 @@ export function useSetFeedViewPreferencesMutation() { export function useSetThreadViewPreferencesMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation>({ mutationFn: async prefs => { - await getAgent().setThreadViewPrefs(prefs) + await agent.setThreadViewPrefs(prefs) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -196,11 +194,11 @@ export function useSetThreadViewPreferencesMutation() { export function useOverwriteSavedFeedsMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async savedFeeds => { - await getAgent().overwriteSavedFeeds(savedFeeds) + await agent.overwriteSavedFeeds(savedFeeds) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -211,7 +209,7 @@ export function useOverwriteSavedFeedsMutation() { export function useAddSavedFeedsMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation< void, @@ -219,7 +217,7 @@ export function useAddSavedFeedsMutation() { Pick[] >({ mutationFn: async savedFeeds => { - await getAgent().addSavedFeeds(savedFeeds) + await agent.addSavedFeeds(savedFeeds) track('CustomFeed:Save') // triggers a refetch await queryClient.invalidateQueries({ @@ -231,11 +229,11 @@ export function useAddSavedFeedsMutation() { export function useRemoveFeedMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation>({ mutationFn: async savedFeed => { - await getAgent().removeSavedFeeds([savedFeed.id]) + await agent.removeSavedFeeds([savedFeed.id]) track('CustomFeed:Unsave') // triggers a refetch await queryClient.invalidateQueries({ @@ -247,7 +245,7 @@ export function useRemoveFeedMutation() { export function useReplaceForYouWithDiscoverFeedMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({ @@ -258,10 +256,10 @@ export function useReplaceForYouWithDiscoverFeedMutation() { discoverFeedConfig: AppBskyActorDefs.SavedFeed | undefined }) => { if (forYouFeedConfig) { - await getAgent().removeSavedFeeds([forYouFeedConfig.id]) + await agent.removeSavedFeeds([forYouFeedConfig.id]) } if (!discoverFeedConfig) { - await getAgent().addSavedFeeds([ + await agent.addSavedFeeds([ { type: 'feed', value: PROD_DEFAULT_FEED('whats-hot'), @@ -269,7 +267,7 @@ export function useReplaceForYouWithDiscoverFeedMutation() { }, ]) } else { - await getAgent().updateSavedFeeds([ + await agent.updateSavedFeeds([ { ...discoverFeedConfig, pinned: true, @@ -286,11 +284,11 @@ export function useReplaceForYouWithDiscoverFeedMutation() { export function useUpdateSavedFeedsMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async feeds => { - await getAgent().updateSavedFeeds(feeds) + await agent.updateSavedFeeds(feeds) // triggers a refetch await queryClient.invalidateQueries({ @@ -302,11 +300,11 @@ export function useUpdateSavedFeedsMutation() { export function useUpsertMutedWordsMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => { - await getAgent().upsertMutedWords(mutedWords) + await agent.upsertMutedWords(mutedWords) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -317,11 +315,11 @@ export function useUpsertMutedWordsMutation() { export function useUpdateMutedWordMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { - await getAgent().updateMutedWord(mutedWord) + await agent.updateMutedWord(mutedWord) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, @@ -332,11 +330,11 @@ export function useUpdateMutedWordMutation() { export function useRemoveMutedWordMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { - await getAgent().removeMutedWord(mutedWord) + await agent.removeMutedWord(mutedWord) // triggers a refetch await queryClient.invalidateQueries({ queryKey: preferencesQueryKey, diff --git a/src/state/queries/profile-feedgens.ts b/src/state/queries/profile-feedgens.ts index 27f2d5aaab..e2508f994e 100644 --- a/src/state/queries/profile-feedgens.ts +++ b/src/state/queries/profile-feedgens.ts @@ -15,7 +15,7 @@ export function useProfileFeedgensQuery( opts?: {enabled?: boolean}, ) { const enabled = opts?.enabled !== false - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyFeedGetActorFeeds.OutputSchema, Error, @@ -25,7 +25,7 @@ export function useProfileFeedgensQuery( >({ queryKey: RQKEY(did), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.feed.getActorFeeds({ + const res = await agent.app.bsky.feed.getActorFeeds({ actor: did, limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/profile-followers.ts b/src/state/queries/profile-followers.ts index d0cbccaf57..131343cd10 100644 --- a/src/state/queries/profile-followers.ts +++ b/src/state/queries/profile-followers.ts @@ -15,7 +15,7 @@ const RQKEY_ROOT = 'profile-followers' export const RQKEY = (did: string) => [RQKEY_ROOT, did] export function useProfileFollowersQuery(did: string | undefined) { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyGraphGetFollowers.OutputSchema, Error, @@ -25,7 +25,7 @@ export function useProfileFollowersQuery(did: string | undefined) { >({ queryKey: RQKEY(did || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.graph.getFollowers({ + const res = await agent.app.bsky.graph.getFollowers({ actor: did || '', limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/profile-follows.ts b/src/state/queries/profile-follows.ts index 1919409c7f..6d832a8416 100644 --- a/src/state/queries/profile-follows.ts +++ b/src/state/queries/profile-follows.ts @@ -26,7 +26,7 @@ export function useProfileFollowsQuery( limit: PAGE_SIZE, }, ) { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyGraphGetFollows.OutputSchema, Error, @@ -37,7 +37,7 @@ export function useProfileFollowsQuery( staleTime: STALE.MINUTES.ONE, queryKey: RQKEY(did || ''), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.graph.getFollows({ + const res = await agent.app.bsky.graph.getFollows({ actor: did || '', limit: limit || PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/profile-lists.ts b/src/state/queries/profile-lists.ts index 543961d635..2bb5f4d28b 100644 --- a/src/state/queries/profile-lists.ts +++ b/src/state/queries/profile-lists.ts @@ -11,7 +11,7 @@ export const RQKEY = (did: string) => [RQKEY_ROOT, did] export function useProfileListsQuery(did: string, opts?: {enabled?: boolean}) { const enabled = opts?.enabled !== false - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyGraphGetLists.OutputSchema, Error, @@ -21,7 +21,7 @@ export function useProfileListsQuery(did: string, opts?: {enabled?: boolean}) { >({ queryKey: RQKEY(did), async queryFn({pageParam}: {pageParam: RQPageParam}) { - const res = await getAgent().app.bsky.graph.getLists({ + const res = await agent.app.bsky.graph.getLists({ actor: did, limit: PAGE_SIZE, cursor: pageParam, diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts index af8718c5e0..7cc9f69116 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -52,7 +52,7 @@ export function useProfileQuery({ staleTime?: number }) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ // WARNING // this staleTime is load-bearing @@ -62,7 +62,7 @@ export function useProfileQuery({ refetchOnWindowFocus: true, queryKey: RQKEY(did ?? ''), queryFn: async () => { - const res = await getAgent().getProfile({actor: did ?? ''}) + const res = await agent.getProfile({actor: did ?? ''}) return res.data }, placeholderData: () => { @@ -77,31 +77,31 @@ export function useProfileQuery({ } export function useProfilesQuery({handles}: {handles: string[]}) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.MINUTES.FIVE, queryKey: profilesQueryKey(handles), queryFn: async () => { - const res = await getAgent().getProfiles({actors: handles}) + const res = await agent.getProfiles({actors: handles}) return res.data }, }) } export function usePrefetchProfileQuery() { - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() const prefetchProfileQuery = useCallback( async (did: string) => { await queryClient.prefetchQuery({ queryKey: RQKEY(did), queryFn: async () => { - const res = await getAgent().getProfile({actor: did || ''}) + const res = await agent.getProfile({actor: did || ''}) return res.data }, }) }, - [queryClient, getAgent], + [queryClient, agent], ) return prefetchProfileQuery } @@ -117,7 +117,7 @@ interface ProfileUpdateParams { } export function useProfileUpdateMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({ profile, @@ -131,7 +131,7 @@ export function useProfileUpdateMutation() { | undefined if (newUserAvatar) { newUserAvatarPromise = uploadBlob( - getAgent(), + agent, newUserAvatar.path, newUserAvatar.mime, ) @@ -141,12 +141,12 @@ export function useProfileUpdateMutation() { | undefined if (newUserBanner) { newUserBannerPromise = uploadBlob( - getAgent(), + agent, newUserBanner.path, newUserBanner.mime, ) } - await getAgent().upsertProfile(async existing => { + await agent.upsertProfile(async existing => { existing = existing || {} if (typeof updates === 'function') { existing = updates(existing) @@ -169,7 +169,7 @@ export function useProfileUpdateMutation() { return existing }) await whenAppViewReady( - getAgent, + agent, profile.did, checkCommitted || (res => { @@ -271,7 +271,7 @@ function useProfileFollowMutation( profile: Shadow, ) { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation<{uri: string; cid: string}, Error, {did: string}>({ mutationFn: async ({did}) => { @@ -287,7 +287,7 @@ function useProfileFollowMutation( followeeClout: toClout(profile.followersCount), followerClout: toClout(ownProfile?.followersCount), }) - return await getAgent().follow(did) + return await agent.follow(did) }, onSuccess(data, variables) { track('Profile:Follow', {username: variables.did}) @@ -298,12 +298,12 @@ function useProfileFollowMutation( function useProfileUnfollowMutation( logContext: LogEvents['profile:unfollow']['logContext'], ) { - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({followUri}) => { logEvent('profile:unfollow', {logContext}) track('Profile:Unfollow', {username: followUri}) - return await getAgent().deleteFollow(followUri) + return await agent.deleteFollow(followUri) }, }) } @@ -359,10 +359,10 @@ export function useProfileMuteMutationQueue( function useProfileMuteMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({did}) => { - await getAgent().mute(did) + await agent.mute(did) }, onSuccess() { queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()}) @@ -372,10 +372,10 @@ function useProfileMuteMutation() { function useProfileUnmuteMutation() { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useMutation({ mutationFn: async ({did}) => { - await getAgent().unmute(did) + await agent.unmute(did) }, onSuccess() { queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()}) @@ -440,14 +440,14 @@ export function useProfileBlockMutationQueue( function useProfileBlockMutation() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation<{uri: string; cid: string}, Error, {did: string}>({ mutationFn: async ({did}) => { if (!currentAccount) { throw new Error('Not signed in') } - return await getAgent().app.bsky.graph.block.create( + return await agent.app.bsky.graph.block.create( {repo: currentAccount.did}, {subject: did, createdAt: new Date().toISOString()}, ) @@ -461,7 +461,7 @@ function useProfileBlockMutation() { function useProfileUnblockMutation() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const queryClient = useQueryClient() return useMutation({ mutationFn: async ({blockUri}) => { @@ -469,7 +469,7 @@ function useProfileUnblockMutation() { throw new Error('Not signed in') } const {rkey} = new AtUri(blockUri) - await getAgent().app.bsky.graph.block.delete({ + await agent.app.bsky.graph.block.delete({ repo: currentAccount.did, rkey, }) @@ -489,7 +489,7 @@ export function precacheProfile( } async function whenAppViewReady( - getAgent: () => BskyAgent, + agent: BskyAgent, actor: string, fn: (res: AppBskyActorGetProfile.Response) => boolean, ) { @@ -497,7 +497,7 @@ async function whenAppViewReady( 5, // 5 tries 1e3, // 1s delay between tries fn, - () => getAgent().app.bsky.actor.getProfile({actor}), + () => agent.app.bsky.actor.getProfile({actor}), ) } diff --git a/src/state/queries/resolve-uri.ts b/src/state/queries/resolve-uri.ts index b1980f07d1..7bd26435cf 100644 --- a/src/state/queries/resolve-uri.ts +++ b/src/state/queries/resolve-uri.ts @@ -24,7 +24,7 @@ export function useResolveUriQuery(uri: string | undefined): UriUseQueryResult { export function useResolveDidQuery(didOrHandle: string | undefined) { const queryClient = useQueryClient() - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ staleTime: STALE.HOURS.ONE, @@ -34,7 +34,7 @@ export function useResolveDidQuery(didOrHandle: string | undefined) { // Just return the did if it's already one if (didOrHandle.startsWith('did:')) return didOrHandle - const res = await getAgent().resolveHandle({handle: didOrHandle}) + const res = await agent.resolveHandle({handle: didOrHandle}) return res.data.did }, initialData: () => { diff --git a/src/state/queries/search-posts.ts b/src/state/queries/search-posts.ts index b0720af3c8..5bee96535f 100644 --- a/src/state/queries/search-posts.ts +++ b/src/state/queries/search-posts.ts @@ -25,7 +25,7 @@ export function useSearchPostsQuery({ sort?: 'top' | 'latest' enabled?: boolean }) { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyFeedSearchPosts.OutputSchema, Error, @@ -35,7 +35,7 @@ export function useSearchPostsQuery({ >({ queryKey: searchPostsQueryKey({query, sort}), queryFn: async ({pageParam}) => { - const res = await getAgent().app.bsky.feed.searchPosts({ + const res = await agent.app.bsky.feed.searchPosts({ q: query, limit: 25, cursor: pageParam, diff --git a/src/state/queries/suggested-feeds.ts b/src/state/queries/suggested-feeds.ts index c7751448e9..19614c2cb2 100644 --- a/src/state/queries/suggested-feeds.ts +++ b/src/state/queries/suggested-feeds.ts @@ -8,7 +8,7 @@ const suggestedFeedsQueryKeyRoot = 'suggestedFeeds' export const suggestedFeedsQueryKey = [suggestedFeedsQueryKeyRoot] export function useSuggestedFeedsQuery() { - const {getAgent} = useAgent() + const agent = useAgent() return useInfiniteQuery< AppBskyFeedGetSuggestedFeeds.OutputSchema, Error, @@ -19,7 +19,7 @@ export function useSuggestedFeedsQuery() { staleTime: STALE.HOURS.ONE, queryKey: suggestedFeedsQueryKey, queryFn: async ({pageParam}) => { - const res = await getAgent().app.bsky.feed.getSuggestedFeeds({ + const res = await agent.app.bsky.feed.getSuggestedFeeds({ limit: 10, cursor: pageParam, }) diff --git a/src/state/queries/suggested-follows.ts b/src/state/queries/suggested-follows.ts index 7740b1977c..59b8f7ed55 100644 --- a/src/state/queries/suggested-follows.ts +++ b/src/state/queries/suggested-follows.ts @@ -33,7 +33,7 @@ const suggestedFollowsByActorQueryKey = (did: string) => [ export function useSuggestedFollowsQuery() { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const moderationOpts = useModerationOpts() const {data: preferences} = usePreferencesQuery() @@ -49,7 +49,7 @@ export function useSuggestedFollowsQuery() { queryKey: suggestedFollowsQueryKey, queryFn: async ({pageParam}) => { const contentLangs = getContentLanguages().join(',') - const res = await getAgent().app.bsky.actor.getSuggestions( + const res = await agent.app.bsky.actor.getSuggestions( { limit: 25, cursor: pageParam, @@ -94,11 +94,11 @@ export function useSuggestedFollowsQuery() { } export function useSuggestedFollowsByActorQuery({did}: {did: string}) { - const {getAgent} = useAgent() + const agent = useAgent() return useQuery({ queryKey: suggestedFollowsByActorQueryKey(did), queryFn: async () => { - const res = await getAgent().app.bsky.graph.getSuggestedFollowsByActor({ + const res = await agent.app.bsky.graph.getSuggestedFollowsByActor({ actor: did, }) return res.data diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx index af8417f8d7..e38dd2bb55 100644 --- a/src/state/session/index.tsx +++ b/src/state/session/index.tsx @@ -268,17 +268,10 @@ export function useRequireAuth() { ) } -export function useAgent(): {getAgent: () => BskyAgent} { +export function useAgent(): BskyAgent { const agent = React.useContext(AgentContext) if (!agent) { throw Error('useAgent() must be below .') } - return React.useMemo( - () => ({ - getAgent() { - return agent - }, - }), - [agent], - ) + return agent } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 7b102c8236..12e57c411d 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -90,7 +90,7 @@ export const ComposePost = observer(function ComposePost({ imageUris: initImageUris, }: Props) { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const {data: currentProfile} = useProfileQuery({did: currentAccount!.did}) const {isModalActive} = useModals() const {closeComposer} = useComposerControls() @@ -260,7 +260,7 @@ export const ComposePost = observer(function ComposePost({ let postUri try { postUri = ( - await apilib.post(getAgent(), { + await apilib.post(agent, { rawText: richtext.text, replyTo: replyTo?.uri, images: gallery.images, diff --git a/src/view/com/composer/useExternalLinkFetch.e2e.ts b/src/view/com/composer/useExternalLinkFetch.e2e.ts index 65ecb866e7..257a3e8e52 100644 --- a/src/view/com/composer/useExternalLinkFetch.e2e.ts +++ b/src/view/com/composer/useExternalLinkFetch.e2e.ts @@ -8,7 +8,7 @@ import {ComposerOpts} from 'state/shell/composer' export function useExternalLinkFetch({}: { setQuote: (opts: ComposerOpts['quote']) => void }) { - const {getAgent} = useAgent() + const agent = useAgent() const [extLink, setExtLink] = useState( undefined, ) @@ -22,7 +22,7 @@ export function useExternalLinkFetch({}: { return cleanup } if (!extLink.meta) { - getLinkMeta(getAgent(), extLink.uri).then(meta => { + getLinkMeta(agent, extLink.uri).then(meta => { if (aborted) { return } @@ -41,7 +41,7 @@ export function useExternalLinkFetch({}: { }) } return cleanup - }, [extLink, getAgent]) + }, [extLink, agent]) return {extLink, setExtLink} } diff --git a/src/view/com/composer/useExternalLinkFetch.ts b/src/view/com/composer/useExternalLinkFetch.ts index d51dec42b1..2e0297a475 100644 --- a/src/view/com/composer/useExternalLinkFetch.ts +++ b/src/view/com/composer/useExternalLinkFetch.ts @@ -31,7 +31,7 @@ export function useExternalLinkFetch({ ) const getPost = useGetPost() const fetchDid = useFetchDid() - const {getAgent} = useAgent() + const agent = useAgent() useEffect(() => { let aborted = false @@ -59,7 +59,7 @@ export function useExternalLinkFetch({ }, ) } else if (isBskyCustomFeedUrl(extLink.uri)) { - getFeedAsEmbed(getAgent(), fetchDid, extLink.uri).then( + getFeedAsEmbed(agent, fetchDid, extLink.uri).then( ({embed, meta}) => { if (aborted) { return @@ -77,7 +77,7 @@ export function useExternalLinkFetch({ }, ) } else if (isBskyListUrl(extLink.uri)) { - getListAsEmbed(getAgent(), fetchDid, extLink.uri).then( + getListAsEmbed(agent, fetchDid, extLink.uri).then( ({embed, meta}) => { if (aborted) { return @@ -95,7 +95,7 @@ export function useExternalLinkFetch({ }, ) } else { - getLinkMeta(getAgent(), extLink.uri).then(meta => { + getLinkMeta(agent, extLink.uri).then(meta => { if (aborted) { return } @@ -137,7 +137,7 @@ export function useExternalLinkFetch({ }) } return cleanup - }, [extLink, setQuote, getPost, fetchDid, getAgent]) + }, [extLink, setQuote, getPost, fetchDid, agent]) return {extLink, setExtLink} } diff --git a/src/view/com/modals/ChangeEmail.tsx b/src/view/com/modals/ChangeEmail.tsx index b940b2d6dc..a214627e2d 100644 --- a/src/view/com/modals/ChangeEmail.tsx +++ b/src/view/com/modals/ChangeEmail.tsx @@ -27,7 +27,7 @@ export const snapPoints = ['90%'] export function Component() { const pal = usePalette('default') const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const {_} = useLingui() const [stage, setStage] = useState(Stages.InputEmail) const [email, setEmail] = useState(currentAccount?.email || '') @@ -45,12 +45,12 @@ export function Component() { setError('') setIsProcessing(true) try { - const res = await getAgent().com.atproto.server.requestEmailUpdate() + const res = await agent.com.atproto.server.requestEmailUpdate() if (res.data.tokenRequired) { setStage(Stages.ConfirmCode) } else { - await getAgent().com.atproto.server.updateEmail({email: email.trim()}) - await getAgent().resumeSession(getAgent().session!) + await agent.com.atproto.server.updateEmail({email: email.trim()}) + await agent.resumeSession(agent.session!) Toast.show(_(msg`Email updated`)) setStage(Stages.Done) } @@ -75,11 +75,11 @@ export function Component() { setError('') setIsProcessing(true) try { - await getAgent().com.atproto.server.updateEmail({ + await agent.com.atproto.server.updateEmail({ email: email.trim(), token: confirmationCode.trim(), }) - await getAgent().resumeSession(getAgent().session!) + await agent.resumeSession(agent.session!) Toast.show(_(msg`Email updated`)) setStage(Stages.Done) } catch (e) { diff --git a/src/view/com/modals/ChangeHandle.tsx b/src/view/com/modals/ChangeHandle.tsx index 52eb51031c..f2094ed75b 100644 --- a/src/view/com/modals/ChangeHandle.tsx +++ b/src/view/com/modals/ChangeHandle.tsx @@ -35,12 +35,12 @@ export type Props = {onChanged: () => void} export function Component(props: Props) { const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const { isLoading, data: serviceInfo, error: serviceInfoError, - } = useServiceQuery(getAgent().service.toString()) + } = useServiceQuery(agent.service.toString()) return isLoading || !currentAccount ? ( @@ -71,7 +71,7 @@ export function Inner({ const {closeModal} = useModalControls() const {mutateAsync: updateHandle, isPending: isUpdateHandlePending} = useUpdateHandleMutation() - const {getAgent} = useAgent() + const agent = useAgent() const [error, setError] = useState('') @@ -111,7 +111,7 @@ export function Inner({ await updateHandle({ handle: newHandle, }) - await getAgent().resumeSession(getAgent().session!) + await agent.resumeSession(agent.session!) closeModal() onChanged() } catch (err: any) { @@ -129,7 +129,7 @@ export function Inner({ closeModal, updateHandle, serviceInfo, - getAgent, + agent, ]) // rendering diff --git a/src/view/com/modals/ChangePassword.tsx b/src/view/com/modals/ChangePassword.tsx index 3ce7306b9d..196715b49f 100644 --- a/src/view/com/modals/ChangePassword.tsx +++ b/src/view/com/modals/ChangePassword.tsx @@ -37,7 +37,7 @@ export const snapPoints = isAndroid ? ['90%'] : ['45%'] export function Component() { const pal = usePalette('default') const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const {_} = useLingui() const [stage, setStage] = useState(Stages.RequestCode) const [isProcessing, setIsProcessing] = useState(false) @@ -46,7 +46,6 @@ export function Component() { const [error, setError] = useState('') const {isMobile} = useWebMediaQueries() const {closeModal} = useModalControls() - const agent = getAgent() const onRequestCode = async () => { if ( diff --git a/src/view/com/modals/CreateOrEditList.tsx b/src/view/com/modals/CreateOrEditList.tsx index 2dff636afc..2ea34e808b 100644 --- a/src/view/com/modals/CreateOrEditList.tsx +++ b/src/view/com/modals/CreateOrEditList.tsx @@ -62,7 +62,7 @@ export function Component({ const {_} = useLingui() const listCreateMutation = useListCreateMutation() const listMetadataMutation = useListMetadataMutation() - const {getAgent} = useAgent() + const agent = useAgent() const activePurpose = useMemo(() => { if (list?.purpose) { @@ -157,7 +157,7 @@ export function Component({ {cleanNewlines: true}, ) - await richText.detectFacets(getAgent()) + await richText.detectFacets(agent) richText = shortenLinks(richText) // filter out any mention facets that didn't map to a user @@ -229,7 +229,7 @@ export function Component({ listMetadataMutation, listCreateMutation, _, - getAgent, + agent, ]) return ( diff --git a/src/view/com/modals/DeleteAccount.tsx b/src/view/com/modals/DeleteAccount.tsx index cab5dc289c..06f1e111a0 100644 --- a/src/view/com/modals/DeleteAccount.tsx +++ b/src/view/com/modals/DeleteAccount.tsx @@ -31,7 +31,7 @@ export function Component({}: {}) { const pal = usePalette('default') const theme = useTheme() const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const {removeAccount} = useSessionApi() const {_} = useLingui() const {closeModal} = useModalControls() @@ -45,7 +45,7 @@ export function Component({}: {}) { setError('') setIsProcessing(true) try { - await getAgent().com.atproto.server.requestAccountDelete() + await agent.com.atproto.server.requestAccountDelete() setIsEmailSent(true) } catch (e: any) { setError(cleanError(e)) @@ -63,7 +63,7 @@ export function Component({}: {}) { try { // inform chat service of intent to delete account - const {success} = await getAgent().api.chat.bsky.actor.deleteAccount( + const {success} = await agent.api.chat.bsky.actor.deleteAccount( undefined, { headers: DM_SERVICE_HEADERS, @@ -72,7 +72,7 @@ export function Component({}: {}) { if (!success) { throw new Error('Failed to inform chat service of account deletion') } - await getAgent().com.atproto.server.deleteAccount({ + await agent.com.atproto.server.deleteAccount({ did: currentAccount.did, password, token, diff --git a/src/view/com/modals/VerifyEmail.tsx b/src/view/com/modals/VerifyEmail.tsx index 3fdde330d8..7c1146a016 100644 --- a/src/view/com/modals/VerifyEmail.tsx +++ b/src/view/com/modals/VerifyEmail.tsx @@ -41,7 +41,7 @@ export function Component({ onSuccess?: () => void }) { const pal = usePalette('default') - const {getAgent} = useAgent() + const agent = useAgent() const {currentAccount} = useSession() const {_} = useLingui() const [stage, setStage] = useState( @@ -64,7 +64,7 @@ export function Component({ setError('') setIsProcessing(true) try { - await getAgent().com.atproto.server.requestEmailConfirmation() + await agent.com.atproto.server.requestEmailConfirmation() setStage(Stages.ConfirmCode) } catch (e) { setError(cleanError(String(e))) @@ -77,11 +77,11 @@ export function Component({ setError('') setIsProcessing(true) try { - await getAgent().com.atproto.server.confirmEmail({ + await agent.com.atproto.server.confirmEmail({ email: (currentAccount?.email || '').trim(), token: confirmationCode.trim(), }) - await getAgent().resumeSession(getAgent().session!) + await agent.resumeSession(agent.session!) Toast.show(_(msg`Email verified`)) closeModal() onSuccess?.() diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index 4fa46a4cf1..734230c6c9 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -470,7 +470,7 @@ function ProfileScreenLoaded({ } function useRichText(text: string): [RichTextAPI, boolean] { - const {getAgent} = useAgent() + const agent = useAgent() const [prevText, setPrevText] = React.useState(text) const [rawRT, setRawRT] = React.useState(() => new RichTextAPI({text})) const [resolvedRT, setResolvedRT] = React.useState(null) @@ -485,7 +485,7 @@ function useRichText(text: string): [RichTextAPI, boolean] { async function resolveRTFacets() { // new each time const resolvedRT = new RichTextAPI({text}) - await resolvedRT.detectFacets(getAgent()) + await resolvedRT.detectFacets(agent) if (!ignore) { setResolvedRT(resolvedRT) } @@ -494,7 +494,7 @@ function useRichText(text: string): [RichTextAPI, boolean] { return () => { ignore = true } - }, [text, getAgent]) + }, [text, agent]) const isResolving = resolvedRT === null return [resolvedRT ?? rawRT, isResolving] } diff --git a/src/view/screens/Settings/DisableEmail2FADialog.tsx b/src/view/screens/Settings/DisableEmail2FADialog.tsx index b52dcc7a36..a27cff9a3e 100644 --- a/src/view/screens/Settings/DisableEmail2FADialog.tsx +++ b/src/view/screens/Settings/DisableEmail2FADialog.tsx @@ -30,7 +30,7 @@ export function DisableEmail2FADialog({ const t = useTheme() const {gtMobile} = useBreakpoints() const {currentAccount} = useSession() - const {getAgent} = useAgent() + const agent = useAgent() const [stage, setStage] = useState(Stages.Email) const [confirmationCode, setConfirmationCode] = useState('') @@ -41,7 +41,7 @@ export function DisableEmail2FADialog({ setError('') setIsProcessing(true) try { - await getAgent().com.atproto.server.requestEmailUpdate() + await agent.com.atproto.server.requestEmailUpdate() setStage(Stages.ConfirmCode) } catch (e) { setError(cleanError(String(e))) @@ -55,12 +55,12 @@ export function DisableEmail2FADialog({ setIsProcessing(true) try { if (currentAccount?.email) { - await getAgent().com.atproto.server.updateEmail({ + await agent.com.atproto.server.updateEmail({ email: currentAccount!.email, token: confirmationCode.trim(), emailAuthFactor: false, }) - await getAgent().resumeSession(getAgent().session!) + await agent.resumeSession(agent.session!) Toast.show(_(msg`Email 2FA disabled`)) } control.close() diff --git a/src/view/screens/Settings/Email2FAToggle.tsx b/src/view/screens/Settings/Email2FAToggle.tsx index efeb7e4d7c..b5e7adddb2 100644 --- a/src/view/screens/Settings/Email2FAToggle.tsx +++ b/src/view/screens/Settings/Email2FAToggle.tsx @@ -13,17 +13,17 @@ export function Email2FAToggle() { const {currentAccount} = useSession() const {openModal} = useModalControls() const disableDialogCtrl = useDialogControl() - const {getAgent} = useAgent() + const agent = useAgent() const enableEmailAuthFactor = React.useCallback(async () => { if (currentAccount?.email) { - await getAgent().com.atproto.server.updateEmail({ + await agent.com.atproto.server.updateEmail({ email: currentAccount.email, emailAuthFactor: true, }) - await getAgent().resumeSession(getAgent().session!) + await agent.resumeSession(agent.session!) } - }, [currentAccount, getAgent]) + }, [currentAccount, agent]) const onToggle = React.useCallback(() => { if (!currentAccount) { diff --git a/src/view/screens/Settings/ExportCarDialog.tsx b/src/view/screens/Settings/ExportCarDialog.tsx index af835cb620..72d943bcf0 100644 --- a/src/view/screens/Settings/ExportCarDialog.tsx +++ b/src/view/screens/Settings/ExportCarDialog.tsx @@ -21,11 +21,10 @@ export function ExportCarDialog({ }) { const {_} = useLingui() const t = useTheme() - const {getAgent} = useAgent() + const agent = useAgent() const [loading, setLoading] = React.useState(false) const download = React.useCallback(async () => { - const agent = getAgent() if (!agent.session) { return // shouldnt ever happen } @@ -49,7 +48,7 @@ export function ExportCarDialog({ setLoading(false) control.close() } - }, [_, control, getAgent]) + }, [_, control, agent]) return ( From adbbded003206f8005b680203c45bc1810be6537 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 28 May 2024 16:56:06 +0100 Subject: [PATCH 04/55] Remove old onboarding (#4224) * Hardcode onboarding_v2 to true, rm dead code * Rm initialState, use initialStateReduced * Rm dead code * Drop *reduced prefix in code * Prettier --- src/lib/statsig/gates.ts | 1 - .../Onboarding/StepAlgoFeeds/FeedCard.tsx | 378 ------------------ .../Onboarding/StepAlgoFeeds/index.tsx | 168 -------- src/screens/Onboarding/StepFinished.tsx | 95 +---- src/screens/Onboarding/StepFollowingFeed.tsx | 161 -------- .../Onboarding/StepInterests/index.tsx | 11 +- .../AdultContentEnabledPref.tsx | 131 ------ .../StepModeration/ModerationOption.tsx | 99 ----- .../Onboarding/StepModeration/index.tsx | 110 ----- src/screens/Onboarding/StepProfile/index.tsx | 6 +- .../SuggestedAccountCard.tsx | 188 --------- .../StepSuggestedAccounts/index.tsx | 210 ---------- src/screens/Onboarding/StepTopicalFeeds.tsx | 125 ------ src/screens/Onboarding/index.tsx | 30 +- src/screens/Onboarding/state.ts | 218 +--------- src/screens/Onboarding/util.ts | 76 ---- src/view/com/testing/TestCtrls.e2e.tsx | 6 - 17 files changed, 27 insertions(+), 1986 deletions(-) delete mode 100644 src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx delete mode 100644 src/screens/Onboarding/StepAlgoFeeds/index.tsx delete mode 100644 src/screens/Onboarding/StepFollowingFeed.tsx delete mode 100644 src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx delete mode 100644 src/screens/Onboarding/StepModeration/ModerationOption.tsx delete mode 100644 src/screens/Onboarding/StepModeration/index.tsx delete mode 100644 src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx delete mode 100644 src/screens/Onboarding/StepSuggestedAccounts/index.tsx delete mode 100644 src/screens/Onboarding/StepTopicalFeeds.tsx diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index 81e49e151b..c572c07211 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -1,5 +1,4 @@ export type Gate = // Keep this alphabetic please. - | 'reduced_onboarding_and_home_algo_v2' | 'request_notifications_permission_after_onboarding' | 'show_follow_back_label_v2' diff --git a/src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx b/src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx deleted file mode 100644 index 0aa063faa5..0000000000 --- a/src/screens/Onboarding/StepAlgoFeeds/FeedCard.tsx +++ /dev/null @@ -1,378 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {Image} from 'expo-image' -import {LinearGradient} from 'expo-linear-gradient' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {FeedSourceInfo, useFeedSourceInfoQuery} from '#/state/queries/feed' -import {FeedConfig} from '#/screens/Onboarding/StepAlgoFeeds' -import {atoms as a, useTheme} from '#/alf' -import * as Toggle from '#/components/forms/Toggle' -import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' -import {RichText} from '#/components/RichText' -import {Text} from '#/components/Typography' - -function PrimaryFeedCardInner({ - feed, - config, -}: { - feed: FeedSourceInfo - config: FeedConfig -}) { - const t = useTheme() - const ctx = Toggle.useItemContext() - - const styles = React.useMemo( - () => ({ - active: [t.atoms.bg_contrast_25], - selected: [ - a.shadow_md, - { - backgroundColor: - t.name === 'light' ? t.palette.primary_50 : t.palette.primary_950, - }, - ], - selectedHover: [ - { - backgroundColor: - t.name === 'light' ? t.palette.primary_25 : t.palette.primary_975, - }, - ], - textSelected: [{color: t.palette.white}], - checkboxSelected: [ - { - borderColor: t.palette.white, - }, - ], - }), - [t], - ) - - return ( - - {ctx.selected && config.gradient && ( - v[1])} - locations={config.gradient.values.map(v => v[0])} - start={{x: 0, y: 0}} - end={{x: 1, y: 1}} - style={[a.absolute, a.inset_0]} - /> - )} - - - - - - - - - {feed.displayName} - - - - by @{feed.creatorHandle} - - - - - {ctx.selected && } - - - - - - - - - - ) -} - -export function PrimaryFeedCard({config}: {config: FeedConfig}) { - const {_} = useLingui() - const {data: feed} = useFeedSourceInfoQuery({uri: config.uri}) - - return !feed ? ( - - ) : ( - - - - ) -} - -function FeedCardInner({feed}: {feed: FeedSourceInfo; config: FeedConfig}) { - const t = useTheme() - const ctx = Toggle.useItemContext() - - const styles = React.useMemo( - () => ({ - active: [t.atoms.bg_contrast_25], - selected: [ - { - backgroundColor: - t.name === 'light' ? t.palette.primary_50 : t.palette.primary_950, - }, - ], - selectedHover: [ - { - backgroundColor: - t.name === 'light' ? t.palette.primary_25 : t.palette.primary_975, - }, - ], - textSelected: [], - checkboxSelected: [ - { - backgroundColor: t.palette.primary_500, - }, - ], - }), - [t], - ) - - return ( - - - - - - - - - {feed.displayName} - - - @{feed.creatorHandle} - - - - - {ctx.selected && } - - - - - - - - - - ) -} - -export function FeedCard({config}: {config: FeedConfig}) { - const {_} = useLingui() - const {data: feed} = useFeedSourceInfoQuery({uri: config.uri}) - - return !feed ? ( - - ) : feed.avatar ? ( - - - - ) : null -} - -export function FeedCardPlaceholder({primary}: {primary?: boolean}) { - const t = useTheme() - return ( - - - - - - - - - - - - - - - - - ) -} diff --git a/src/screens/Onboarding/StepAlgoFeeds/index.tsx b/src/screens/Onboarding/StepAlgoFeeds/index.tsx deleted file mode 100644 index 19bb401046..0000000000 --- a/src/screens/Onboarding/StepAlgoFeeds/index.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useAnalytics} from '#/lib/analytics/analytics' -import {logEvent} from '#/lib/statsig/statsig' -import { - DescriptionText, - OnboardingControls, - TitleText, -} from '#/screens/Onboarding/Layout' -import {Context} from '#/screens/Onboarding/state' -import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard' -import {atoms as a, tokens, useTheme} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import * as Toggle from '#/components/forms/Toggle' -import {IconCircle} from '#/components/IconCircle' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' -import {ListSparkle_Stroke2_Corner0_Rounded as ListSparkle} from '#/components/icons/ListSparkle' -import {Loader} from '#/components/Loader' -import {Text} from '#/components/Typography' -import {IS_PROD} from '#/env' - -export type FeedConfig = { - default: boolean - uri: string - gradient?: typeof tokens.gradients.midnight | typeof tokens.gradients.nordic -} - -export const PRIMARY_FEEDS: FeedConfig[] = [ - { - default: IS_PROD, // these feeds are only available in prod - uri: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot', - gradient: tokens.gradients.midnight, - }, -] - -const SECONDARY_FEEDS: FeedConfig[] = [ - { - default: false, - uri: 'at://did:plc:vpkhqolt662uhesyj6nxm7ys/app.bsky.feed.generator/infreq', - }, - { - default: false, - uri: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/with-friends', - }, - { - default: false, - uri: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/best-of-follows', - }, - { - default: false, - uri: 'at://did:plc:tenurhgjptubkk5zf5qhi3og/app.bsky.feed.generator/catch-up', - }, - { - default: false, - uri: 'at://did:plc:q6gjnaw2blty4crticxkmujt/app.bsky.feed.generator/at-bangers', - }, -] - -export function StepAlgoFeeds() { - const {_} = useLingui() - const {track} = useAnalytics() - const t = useTheme() - const {state, dispatch} = React.useContext(Context) - const [primaryFeedUris, setPrimaryFeedUris] = React.useState( - PRIMARY_FEEDS.map(f => (f.default ? f.uri : '')).filter(Boolean), - ) - const [secondaryFeedUris, setSeconaryFeedUris] = React.useState([]) - const [saving, setSaving] = React.useState(false) - - const saveFeeds = React.useCallback(async () => { - setSaving(true) - - const uris = primaryFeedUris.concat(secondaryFeedUris) - dispatch({type: 'setAlgoFeedsStepResults', feedUris: uris}) - - setSaving(false) - dispatch({type: 'next'}) - track('OnboardingV2:StepAlgoFeeds:End', { - selectedPrimaryFeeds: primaryFeedUris, - selectedPrimaryFeedsLength: primaryFeedUris.length, - selectedSecondaryFeeds: secondaryFeedUris, - selectedSecondaryFeedsLength: secondaryFeedUris.length, - }) - logEvent('onboarding:algoFeeds:nextPressed', { - selectedPrimaryFeeds: primaryFeedUris, - selectedPrimaryFeedsLength: primaryFeedUris.length, - selectedSecondaryFeeds: secondaryFeedUris, - selectedSecondaryFeedsLength: secondaryFeedUris.length, - }) - }, [primaryFeedUris, secondaryFeedUris, dispatch, track]) - - React.useEffect(() => { - track('OnboardingV2:StepAlgoFeeds:Start') - }, [track]) - - return ( - - - - - Choose your main feeds - - - - Custom feeds built by the community bring you new experiences and help - you find the content you love. - - - - - - - We recommend our "Discover" feed: - - - - - - - There are many feeds to try: - - - {SECONDARY_FEEDS.map(config => ( - - ))} - - - - - - - - - ) -} diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx index 9658cfe15f..b8a21680bf 100644 --- a/src/screens/Onboarding/StepFinished.tsx +++ b/src/screens/Onboarding/StepFinished.tsx @@ -1,19 +1,14 @@ import React from 'react' import {View} from 'react-native' -import {TID} from '@atproto/common-web' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useQueryClient} from '@tanstack/react-query' import {useAnalytics} from '#/lib/analytics/analytics' -import {BSKY_APP_ACCOUNT_DID, IS_PROD_SERVICE} from '#/lib/constants' -import {DISCOVER_SAVED_FEED, TIMELINE_SAVED_FEED} from '#/lib/constants' -import {logEvent, useGate} from '#/lib/statsig/statsig' +import {BSKY_APP_ACCOUNT_DID} from '#/lib/constants' +import {logEvent} from '#/lib/statsig/statsig' import {logger} from '#/logger' -import { - preferencesQueryKey, - useOverwriteSavedFeedsMutation, -} from '#/state/queries/preferences' +import {preferencesQueryKey} from '#/state/queries/preferences' import {RQKEY as profileRQKey} from '#/state/queries/profile' import {useAgent} from '#/state/session' import {useOnboardingDispatch} from '#/state/shell' @@ -24,10 +19,7 @@ import { TitleText, } from '#/screens/Onboarding/Layout' import {Context} from '#/screens/Onboarding/state' -import { - bulkWriteFollows, - sortPrimaryAlgorithmFeeds, -} from '#/screens/Onboarding/util' +import {bulkWriteFollows} from '#/screens/Onboarding/util' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {IconCircle} from '#/components/IconCircle' @@ -45,83 +37,21 @@ export function StepFinished() { const {state, dispatch} = React.useContext(Context) const onboardDispatch = useOnboardingDispatch() const [saving, setSaving] = React.useState(false) - const {mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation() const queryClient = useQueryClient() const agent = useAgent() - const gate = useGate() const finishOnboarding = React.useCallback(async () => { setSaving(true) - // TODO uncomment - const { - interestsStepResults, - suggestedAccountsStepResults, - algoFeedsStepResults, - topicalFeedsStepResults, - profileStepResults, - } = state + const {interestsStepResults, profileStepResults} = state const {selectedInterests} = interestsStepResults - const selectedFeeds = [ - ...sortPrimaryAlgorithmFeeds(algoFeedsStepResults.feedUris), - ...topicalFeedsStepResults.feedUris, - ] - try { await Promise.all([ - bulkWriteFollows( - agent, - suggestedAccountsStepResults.accountDids.concat(BSKY_APP_ACCOUNT_DID), - ), - // these must be serial + bulkWriteFollows(agent, [BSKY_APP_ACCOUNT_DID]), (async () => { await agent.setInterestsPref({tags: selectedInterests}) - - /* - * In the reduced onboading experiment, we'll rely on the default - * feeds set in `createAgentAndCreateAccount`. No feeds will be - * selected in onboarding and therefore we don't need to run this - * code (which would overwrite the other feeds already set). - */ - if (!gate('reduced_onboarding_and_home_algo_v2')) { - const otherFeeds = selectedFeeds.length - ? selectedFeeds.map(f => ({ - type: 'feed', - value: f, - pinned: true, - id: TID.nextStr(), - })) - : [] - - /* - * If no selected feeds and we're in prod, add the discover feed - * (mimics old behavior) - */ - if ( - IS_PROD_SERVICE(agent.service.toString()) && - !otherFeeds.length - ) { - otherFeeds.push({ - ...DISCOVER_SAVED_FEED, - pinned: true, - id: TID.nextStr(), - }) - } - - await overwriteSavedFeeds([ - { - ...TIMELINE_SAVED_FEED, - pinned: true, - id: TID.nextStr(), - }, - ...otherFeeds, - ]) - } })(), - (async () => { - if (!gate('reduced_onboarding_and_home_algo_v2')) return - const {imageUri, imageMime} = profileStepResults if (imageUri && imageMime) { const blobPromise = uploadBlob(agent, imageUri, imageMime) @@ -134,7 +64,6 @@ export function StepFinished() { return existing }) } - logEvent('onboarding:finished:avatarResult', { avatarResult: profileStepResults.isCreatedAvatar ? 'created' @@ -169,17 +98,7 @@ export function StepFinished() { track('OnboardingV2:StepFinished:End') track('OnboardingV2:Complete') logEvent('onboarding:finished:nextPressed', {}) - }, [ - state, - dispatch, - onboardDispatch, - setSaving, - overwriteSavedFeeds, - track, - agent, - gate, - queryClient, - ]) + }, [state, dispatch, onboardDispatch, setSaving, track, agent, queryClient]) React.useEffect(() => { track('OnboardingV2:StepFinished:Start') diff --git a/src/screens/Onboarding/StepFollowingFeed.tsx b/src/screens/Onboarding/StepFollowingFeed.tsx deleted file mode 100644 index a1c7299f02..0000000000 --- a/src/screens/Onboarding/StepFollowingFeed.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useAnalytics} from '#/lib/analytics/analytics' -import {logEvent} from '#/lib/statsig/statsig' -import { - usePreferencesQuery, - useSetFeedViewPreferencesMutation, -} from 'state/queries/preferences' -import { - DescriptionText, - OnboardingControls, - TitleText, -} from '#/screens/Onboarding/Layout' -import {Context} from '#/screens/Onboarding/state' -import {atoms as a} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {Divider} from '#/components/Divider' -import * as Toggle from '#/components/forms/Toggle' -import {IconCircle} from '#/components/IconCircle' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' -import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline' -import {Text} from '#/components/Typography' - -export function StepFollowingFeed() { - const {_} = useLingui() - const {track} = useAnalytics() - const {dispatch} = React.useContext(Context) - - const {data: preferences} = usePreferencesQuery() - const {mutate: setFeedViewPref, variables} = - useSetFeedViewPreferencesMutation() - - const showReplies = !( - variables?.hideReplies ?? preferences?.feedViewPrefs.hideReplies - ) - const showReposts = !( - variables?.hideReposts ?? preferences?.feedViewPrefs.hideReposts - ) - const showQuotes = !( - variables?.hideQuotePosts ?? preferences?.feedViewPrefs.hideQuotePosts - ) - - const onContinue = React.useCallback(() => { - dispatch({type: 'next'}) - track('OnboardingV2:StepFollowingFeed:End') - logEvent('onboarding:followingFeed:nextPressed', {}) - }, [track, dispatch]) - - React.useEffect(() => { - track('OnboardingV2:StepFollowingFeed:Start') - }, [track]) - - return ( - // Hack for now to move the image container up - - - - - Your default feed is "Following" - - - It shows posts from the people you follow as they happen. - - - - { - setFeedViewPref({ - hideReplies: showReplies, - }) - }}> - - - Show replies in Following - - - - - - { - setFeedViewPref({ - hideReposts: showReposts, - }) - }}> - - - Show reposts in Following - - - - - - { - setFeedViewPref({ - hideQuotePosts: showQuotes, - }) - }}> - - - Show quotes in Following - - - - - - - - You can change these settings later. - - - - - - - ) -} diff --git a/src/screens/Onboarding/StepInterests/index.tsx b/src/screens/Onboarding/StepInterests/index.tsx index 2589e66c2d..866ea5c2f7 100644 --- a/src/screens/Onboarding/StepInterests/index.tsx +++ b/src/screens/Onboarding/StepInterests/index.tsx @@ -5,12 +5,11 @@ import {useLingui} from '@lingui/react' import {useQuery} from '@tanstack/react-query' import {useAnalytics} from '#/lib/analytics/analytics' -import {logEvent, useGate} from '#/lib/statsig/statsig' +import {logEvent} from '#/lib/statsig/statsig' import {capitalize} from '#/lib/strings/capitalize' import {logger} from '#/logger' import {useAgent} from '#/state/session' import {useOnboardingDispatch} from '#/state/shell' -import {useRequestNotificationsPermission} from 'lib/notifications/notifications' import { DescriptionText, OnboardingControls, @@ -34,8 +33,6 @@ export function StepInterests() { const t = useTheme() const {gtMobile} = useBreakpoints() const {track} = useAnalytics() - const gate = useGate() - const requestNotificationsPermission = useRequestNotificationsPermission() const {state, dispatch, interestsDisplayNames} = React.useContext(Context) const [saving, setSaving] = React.useState(false) @@ -132,12 +129,6 @@ export function StepInterests() { track('OnboardingV2:StepInterests:Start') }, [track]) - React.useEffect(() => { - if (!gate('reduced_onboarding_and_home_algo_v2')) { - requestNotificationsPermission('StartOnboarding') - } - }, [gate, requestNotificationsPermission]) - const title = isError ? ( Oh no! Something went wrong. ) : ( diff --git a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx b/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx deleted file mode 100644 index 7563bece10..0000000000 --- a/src/screens/Onboarding/StepModeration/AdultContentEnabledPref.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {UseMutateFunction} from '@tanstack/react-query' - -import {logger} from '#/logger' -import {isIOS} from '#/platform/detection' -import {usePreferencesQuery} from '#/state/queries/preferences' -import * as Toast from '#/view/com/util/Toast' -import {atoms as a, useTheme} from '#/alf' -import * as Toggle from '#/components/forms/Toggle' -import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' -import * as Prompt from '#/components/Prompt' -import {Text} from '#/components/Typography' - -function Card({children}: React.PropsWithChildren<{}>) { - const t = useTheme() - return ( - - {children} - - ) -} - -export function AdultContentEnabledPref({ - mutate, - variables, -}: { - mutate: UseMutateFunction - variables: {enabled: boolean} | undefined -}) { - const {_} = useLingui() - const t = useTheme() - const prompt = Prompt.usePromptControl() - - // Reuse logic here form ContentFilteringSettings.tsx - const {data: preferences} = usePreferencesQuery() - - const onToggleAdultContent = React.useCallback(async () => { - if (isIOS) { - prompt.open() - return - } - - try { - mutate({ - enabled: !( - variables?.enabled ?? preferences?.moderationPrefs.adultContentEnabled - ), - }) - } catch (e) { - Toast.show( - _(msg`There was an issue syncing your preferences with the server`), - ) - logger.error('Failed to update preferences with server', {error: e}) - } - }, [variables, preferences, mutate, _, prompt]) - - if (!preferences) return null - - return ( - <> - {preferences.userAge && preferences.userAge >= 18 ? ( - - - - - Enable Adult Content - - - - - - ) : ( - - - - You must be 18 years or older to enable adult content - - - )} - - - - Adult Content - - - - Due to Apple policies, adult content can only be enabled on the web - after completing sign up. - - - - prompt.close()} cta={_(msg`OK`)} /> - - - - ) -} diff --git a/src/screens/Onboarding/StepModeration/ModerationOption.tsx b/src/screens/Onboarding/StepModeration/ModerationOption.tsx deleted file mode 100644 index d6334e6bda..0000000000 --- a/src/screens/Onboarding/StepModeration/ModerationOption.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {InterpretedLabelValueDefinition, LabelPreference} from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings' -import { - usePreferencesQuery, - usePreferencesSetContentLabelMutation, -} from '#/state/queries/preferences' -import {atoms as a, useTheme} from '#/alf' -import * as ToggleButton from '#/components/forms/ToggleButton' -import {Text} from '#/components/Typography' - -export function ModerationOption({ - labelValueDefinition, - disabled, -}: { - labelValueDefinition: InterpretedLabelValueDefinition - disabled?: boolean -}) { - const {_} = useLingui() - const t = useTheme() - const {data: preferences} = usePreferencesQuery() - const {mutate, variables} = usePreferencesSetContentLabelMutation() - const label = labelValueDefinition.identifier - const visibility = - variables?.visibility ?? preferences?.moderationPrefs.labels?.[label] - - const allLabelStrings = useGlobalLabelStrings() - const labelStrings = - labelValueDefinition.identifier in allLabelStrings - ? allLabelStrings[labelValueDefinition.identifier] - : { - name: labelValueDefinition.identifier, - description: `Labeled "${labelValueDefinition.identifier}"`, - } - - const onChange = React.useCallback( - (vis: string[]) => { - mutate({ - label, - visibility: vis[0] as LabelPreference, - labelerDid: undefined, - }) - }, - [mutate, label], - ) - - const labels = { - hide: _(msg`Hide`), - warn: _(msg`Warn`), - show: _(msg`Show`), - } - - return ( - - - {labelStrings.name} - - {labelStrings.description} - - - - {disabled ? ( - - Hide - - ) : ( - - - {labels.show} - - - {labels.warn} - - - {labels.hide} - - - )} - - - ) -} diff --git a/src/screens/Onboarding/StepModeration/index.tsx b/src/screens/Onboarding/StepModeration/index.tsx deleted file mode 100644 index d494f48dd1..0000000000 --- a/src/screens/Onboarding/StepModeration/index.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {LABELS} from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useAnalytics} from '#/lib/analytics/analytics' -import {logEvent} from '#/lib/statsig/statsig' -import {usePreferencesQuery} from '#/state/queries/preferences' -import {usePreferencesSetAdultContentMutation} from 'state/queries/preferences' -import { - DescriptionText, - OnboardingControls, - TitleText, -} from '#/screens/Onboarding/Layout' -import {Context} from '#/screens/Onboarding/state' -import {AdultContentEnabledPref} from '#/screens/Onboarding/StepModeration/AdultContentEnabledPref' -import {ModerationOption} from '#/screens/Onboarding/StepModeration/ModerationOption' -import {atoms as a} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {IconCircle} from '#/components/IconCircle' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' -import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' -import {Loader} from '#/components/Loader' - -export function StepModeration() { - const {_} = useLingui() - const {track} = useAnalytics() - const {state, dispatch} = React.useContext(Context) - const {data: preferences} = usePreferencesQuery() - const {mutate, variables} = usePreferencesSetAdultContentMutation() - - // We need to know if the screen is mounted so we know if we want to run entering animations - // https://github.com/software-mansion/react-native-reanimated/discussions/2513 - const isMounted = React.useRef(false) - React.useLayoutEffect(() => { - isMounted.current = true - }, []) - - const adultContentEnabled = !!( - (variables && variables.enabled) || - (!variables && preferences?.moderationPrefs.adultContentEnabled) - ) - - const onContinue = React.useCallback(() => { - dispatch({type: 'next'}) - track('OnboardingV2:StepModeration:End') - logEvent('onboarding:moderation:nextPressed', {}) - }, [track, dispatch]) - - React.useEffect(() => { - track('OnboardingV2:StepModeration:Start') - }, [track]) - - return ( - - - - - You're in control - - - - Select what you want to see (or not see), and we’ll handle the rest. - - - - {!preferences ? ( - - - - ) : ( - <> - - - - - - - - - - )} - - - - - - ) -} diff --git a/src/screens/Onboarding/StepProfile/index.tsx b/src/screens/Onboarding/StepProfile/index.tsx index fc19d5bb34..e0a10419d6 100644 --- a/src/screens/Onboarding/StepProfile/index.tsx +++ b/src/screens/Onboarding/StepProfile/index.tsx @@ -92,11 +92,7 @@ export function StepProfile() { }, [track]) React.useEffect(() => { - // We have an experiment running for redueced onboarding, where this screen shows up as the first in onboarding. - // We only want to request permissions when that gate is actually active to prevent pollution - if (gate('reduced_onboarding_and_home_algo_v2')) { - requestNotificationsPermission('StartOnboarding') - } + requestNotificationsPermission('StartOnboarding') }, [gate, requestNotificationsPermission]) const openPicker = React.useCallback( diff --git a/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx b/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx deleted file mode 100644 index f0ba36e39f..0000000000 --- a/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import React from 'react' -import {View, ViewStyle} from 'react-native' -import {AppBskyActorDefs, moderateProfile} from '@atproto/api' - -import {useModerationOpts} from '#/state/preferences/moderation-opts' -import {UserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a, flatten, useTheme} from '#/alf' -import {useItemContext} from '#/components/forms/Toggle' -import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' -import {RichText} from '#/components/RichText' -import {Text} from '#/components/Typography' - -export function SuggestedAccountCard({ - profile, - moderationOpts, -}: { - profile: AppBskyActorDefs.ProfileViewDetailed - moderationOpts: ReturnType -}) { - const t = useTheme() - const ctx = useItemContext() - const moderation = moderateProfile(profile, moderationOpts!) - - const styles = React.useMemo(() => { - const light = t.name === 'light' - const base: ViewStyle[] = [t.atoms.bg_contrast_50] - const hover: ViewStyle[] = [t.atoms.bg_contrast_25] - const selected: ViewStyle[] = [ - { - backgroundColor: light ? t.palette.primary_50 : t.palette.primary_950, - }, - ] - const selectedHover: ViewStyle[] = [ - { - backgroundColor: light ? t.palette.primary_25 : t.palette.primary_975, - }, - ] - const checkboxBase: ViewStyle[] = [t.atoms.bg] - const checkboxSelected: ViewStyle[] = [ - { - backgroundColor: t.palette.primary_500, - }, - ] - const avatarBase: ViewStyle[] = [t.atoms.bg_contrast_100] - const avatarSelected: ViewStyle[] = [ - { - backgroundColor: light ? t.palette.primary_100 : t.palette.primary_900, - }, - ] - - return { - base, - hover: flatten(hover), - selected: flatten(selected), - selectedHover: flatten(selectedHover), - checkboxBase: flatten(checkboxBase), - checkboxSelected: flatten(checkboxSelected), - avatarBase: flatten(avatarBase), - avatarSelected: flatten(avatarSelected), - } - }, [t]) - - return ( - - - - - - - - - {profile.displayName} - - {profile.handle} - - - - - {ctx.selected && } - - - - {profile.description && ( - <> - - - - - )} - - ) -} - -export function SuggestedAccountCardPlaceholder() { - const t = useTheme() - return ( - - - - - - - - - - ) -} diff --git a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx deleted file mode 100644 index 774f2d3b01..0000000000 --- a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {AppBskyActorDefs} from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useAnalytics} from '#/lib/analytics/analytics' -import {logEvent} from '#/lib/statsig/statsig' -import {capitalize} from '#/lib/strings/capitalize' -import {useModerationOpts} from '#/state/preferences/moderation-opts' -import {useProfilesQuery} from '#/state/queries/profile' -import { - DescriptionText, - OnboardingControls, - TitleText, -} from '#/screens/Onboarding/Layout' -import {Context} from '#/screens/Onboarding/state' -import { - SuggestedAccountCard, - SuggestedAccountCardPlaceholder, -} from '#/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard' -import {aggregateInterestItems} from '#/screens/Onboarding/util' -import {atoms as a, useBreakpoints} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import * as Toggle from '#/components/forms/Toggle' -import {IconCircle} from '#/components/IconCircle' -import {At_Stroke2_Corner0_Rounded as At} from '#/components/icons/At' -import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' -import {Loader} from '#/components/Loader' -import {Text} from '#/components/Typography' - -export function Inner({ - profiles, - onSelect, - moderationOpts, -}: { - profiles: AppBskyActorDefs.ProfileViewDetailed[] - onSelect: (dids: string[]) => void - moderationOpts: ReturnType -}) { - const {_} = useLingui() - const [dids, setDids] = React.useState(profiles.map(p => p.did)) - - React.useEffect(() => { - onSelect(dids) - }, [dids, onSelect]) - - return ( - - - {profiles.map(profile => ( - - - - ))} - - - ) -} - -export function StepSuggestedAccounts() { - const {_} = useLingui() - const {gtMobile} = useBreakpoints() - const {track} = useAnalytics() - const {state, dispatch, interestsDisplayNames} = React.useContext(Context) - const suggestedDids = React.useMemo(() => { - return aggregateInterestItems( - state.interestsStepResults.selectedInterests, - state.interestsStepResults.apiResponse.suggestedAccountDids, - state.interestsStepResults.apiResponse.suggestedAccountDids.default || [], - ) - }, [state.interestsStepResults]) - const moderationOpts = useModerationOpts() - const { - isLoading: isProfilesLoading, - isError, - data, - error, - } = useProfilesQuery({ - handles: suggestedDids, - }) - const [dids, setDids] = React.useState([]) - const [saving, setSaving] = React.useState(false) - - const interestsText = React.useMemo(() => { - const i = state.interestsStepResults.selectedInterests.map( - i => interestsDisplayNames[i] || capitalize(i), - ) - return i.join(', ') - }, [state.interestsStepResults.selectedInterests, interestsDisplayNames]) - - const handleContinue = React.useCallback(async () => { - setSaving(true) - - if (dids.length) { - dispatch({type: 'setSuggestedAccountsStepResults', accountDids: dids}) - } - - setSaving(false) - dispatch({type: 'next'}) - track('OnboardingV2:StepSuggestedAccounts:End', { - selectedAccountsLength: dids.length, - }) - logEvent('onboarding:suggestedAccounts:nextPressed', { - selectedAccountsLength: dids.length, - skipped: false, - }) - }, [dids, setSaving, dispatch, track]) - - const handleSkip = React.useCallback(() => { - // if a user comes back and clicks skip, erase follows - dispatch({type: 'setSuggestedAccountsStepResults', accountDids: []}) - dispatch({type: 'next'}) - logEvent('onboarding:suggestedAccounts:nextPressed', { - selectedAccountsLength: 0, - skipped: true, - }) - }, [dispatch]) - - const isLoading = isProfilesLoading && moderationOpts - - React.useEffect(() => { - track('OnboardingV2:StepSuggestedAccounts:Start') - }, [track]) - - return ( - - - - - Here are some accounts for you to follow - - - {state.interestsStepResults.selectedInterests.length ? ( - Based on your interest in {interestsText} - ) : ( - These are popular accounts you might like: - )} - - - - {isLoading ? ( - - {Array(10) - .fill(0) - .map((_, i) => ( - - ))} - - ) : isError || !data ? ( - {error?.toString()} - ) : ( - - )} - - - - - - - - - - ) -} diff --git a/src/screens/Onboarding/StepTopicalFeeds.tsx b/src/screens/Onboarding/StepTopicalFeeds.tsx deleted file mode 100644 index bfc9e91d1b..0000000000 --- a/src/screens/Onboarding/StepTopicalFeeds.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useAnalytics} from '#/lib/analytics/analytics' -import {logEvent} from '#/lib/statsig/statsig' -import {capitalize} from '#/lib/strings/capitalize' -import {IS_TEST_USER} from 'lib/constants' -import {useSession} from 'state/session' -import { - DescriptionText, - OnboardingControls, - TitleText, -} from '#/screens/Onboarding/Layout' -import {Context} from '#/screens/Onboarding/state' -import {FeedCard} from '#/screens/Onboarding/StepAlgoFeeds/FeedCard' -import {aggregateInterestItems} from '#/screens/Onboarding/util' -import {atoms as a} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import * as Toggle from '#/components/forms/Toggle' -import {IconCircle} from '#/components/IconCircle' -import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' -import {ListMagnifyingGlass_Stroke2_Corner0_Rounded as ListMagnifyingGlass} from '#/components/icons/ListMagnifyingGlass' -import {Loader} from '#/components/Loader' - -export function StepTopicalFeeds() { - const {_} = useLingui() - const {track} = useAnalytics() - const {currentAccount} = useSession() - const {state, dispatch, interestsDisplayNames} = React.useContext(Context) - const [selectedFeedUris, setSelectedFeedUris] = React.useState([]) - const [saving, setSaving] = React.useState(false) - const suggestedFeedUris = React.useMemo(() => { - if (IS_TEST_USER(currentAccount?.handle)) return [] - return aggregateInterestItems( - state.interestsStepResults.selectedInterests, - state.interestsStepResults.apiResponse.suggestedFeedUris, - state.interestsStepResults.apiResponse.suggestedFeedUris.default || [], - ).slice(0, 10) - }, [ - currentAccount?.handle, - state.interestsStepResults.apiResponse.suggestedFeedUris, - state.interestsStepResults.selectedInterests, - ]) - - const interestsText = React.useMemo(() => { - const i = state.interestsStepResults.selectedInterests.map( - i => interestsDisplayNames[i] || capitalize(i), - ) - return i.join(', ') - }, [state.interestsStepResults.selectedInterests, interestsDisplayNames]) - - const saveFeeds = React.useCallback(async () => { - setSaving(true) - - dispatch({type: 'setTopicalFeedsStepResults', feedUris: selectedFeedUris}) - - setSaving(false) - dispatch({type: 'next'}) - track('OnboardingV2:StepTopicalFeeds:End', { - selectedFeeds: selectedFeedUris, - selectedFeedsLength: selectedFeedUris.length, - }) - logEvent('onboarding:topicalFeeds:nextPressed', { - selectedFeeds: selectedFeedUris, - selectedFeedsLength: selectedFeedUris.length, - }) - }, [selectedFeedUris, dispatch, track]) - - React.useEffect(() => { - track('OnboardingV2:StepTopicalFeeds:Start') - }, [track]) - - return ( - - - - - Feeds can be topical as well! - - - {state.interestsStepResults.selectedInterests.length ? ( - - Here are some topical feeds based on your interests: {interestsText} - . You can choose to follow as many as you like. - - ) : ( - - Here are some popular topical feeds. You can choose to follow as - many as you like. - - )} - - - - - - {suggestedFeedUris.map(uri => ( - - ))} - - - - - - - - - ) -} diff --git a/src/screens/Onboarding/index.tsx b/src/screens/Onboarding/index.tsx index 20271a4658..a5c423ca19 100644 --- a/src/screens/Onboarding/index.tsx +++ b/src/screens/Onboarding/index.tsx @@ -2,33 +2,18 @@ import React from 'react' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useGate} from '#/lib/statsig/statsig' import {Layout, OnboardingControls} from '#/screens/Onboarding/Layout' -import { - Context, - initialState, - initialStateReduced, - reducer, - reducerReduced, -} from '#/screens/Onboarding/state' -import {StepAlgoFeeds} from '#/screens/Onboarding/StepAlgoFeeds' +import {Context, initialState, reducer} from '#/screens/Onboarding/state' import {StepFinished} from '#/screens/Onboarding/StepFinished' -import {StepFollowingFeed} from '#/screens/Onboarding/StepFollowingFeed' import {StepInterests} from '#/screens/Onboarding/StepInterests' -import {StepModeration} from '#/screens/Onboarding/StepModeration' import {StepProfile} from '#/screens/Onboarding/StepProfile' -import {StepSuggestedAccounts} from '#/screens/Onboarding/StepSuggestedAccounts' -import {StepTopicalFeeds} from '#/screens/Onboarding/StepTopicalFeeds' import {Portal} from '#/components/Portal' export function Onboarding() { const {_} = useLingui() - const gate = useGate() - const isReducedOnboardingEnabled = gate('reduced_onboarding_and_home_algo_v2') - const [state, dispatch] = React.useReducer( - isReducedOnboardingEnabled ? reducerReduced : reducer, - isReducedOnboardingEnabled ? {...initialStateReduced} : {...initialState}, - ) + const [state, dispatch] = React.useReducer(reducer, { + ...initialState, + }) const interestsDisplayNames = React.useMemo(() => { return { @@ -68,13 +53,6 @@ export function Onboarding() { {state.activeStep === 'profile' && } {state.activeStep === 'interests' && } - {state.activeStep === 'suggestedAccounts' && ( - - )} - {state.activeStep === 'followingFeed' && } - {state.activeStep === 'algoFeeds' && } - {state.activeStep === 'topicalFeeds' && } - {state.activeStep === 'moderation' && } {state.activeStep === 'finished' && } diff --git a/src/screens/Onboarding/state.ts b/src/screens/Onboarding/state.ts index 50d815674c..8f61cb22eb 100644 --- a/src/screens/Onboarding/state.ts +++ b/src/screens/Onboarding/state.ts @@ -6,31 +6,13 @@ import {AvatarColor, Emoji} from '#/screens/Onboarding/StepProfile/types' export type OnboardingState = { hasPrev: boolean totalSteps: number - activeStep: - | 'profile' - | 'interests' - | 'suggestedAccounts' - | 'followingFeed' - | 'algoFeeds' - | 'topicalFeeds' - | 'moderation' - | 'profile' - | 'finished' + activeStep: 'profile' | 'interests' | 'finished' activeStepIndex: number interestsStepResults: { selectedInterests: string[] apiResponse: ApiResponseMap } - suggestedAccountsStepResults: { - accountDids: string[] - } - algoFeedsStepResults: { - feedUris: string[] - } - topicalFeedsStepResults: { - feedUris: string[] - } profileStepResults: { isCreatedAvatar: boolean image?: { @@ -64,18 +46,6 @@ export type OnboardingAction = selectedInterests: string[] apiResponse: ApiResponseMap } - | { - type: 'setSuggestedAccountsStepResults' - accountDids: string[] - } - | { - type: 'setAlgoFeedsStepResults' - feedUris: string[] - } - | { - type: 'setTopicalFeedsStepResults' - feedUris: string[] - } | { type: 'setProfileStepResults' isCreatedAvatar: boolean @@ -98,37 +68,6 @@ export type ApiResponseMap = { } } -export const initialState: OnboardingState = { - hasPrev: false, - totalSteps: 7, - activeStep: 'interests', - activeStepIndex: 1, - - interestsStepResults: { - selectedInterests: [], - apiResponse: { - interests: [], - suggestedAccountDids: {}, - suggestedFeedUris: {}, - }, - }, - suggestedAccountsStepResults: { - accountDids: [], - }, - algoFeedsStepResults: { - feedUris: [], - }, - topicalFeedsStepResults: { - feedUris: [], - }, - profileStepResults: { - isCreatedAvatar: false, - image: undefined, - imageUri: '', - imageMime: '', - }, -} - export const INTEREST_TO_DISPLAY_NAME_DEFAULTS: { [key: string]: string } = { @@ -156,125 +95,7 @@ export const INTEREST_TO_DISPLAY_NAME_DEFAULTS: { cooking: 'Cooking', } -export const Context = React.createContext<{ - state: OnboardingState - dispatch: React.Dispatch - interestsDisplayNames: {[key: string]: string} -}>({ - state: {...initialState}, - dispatch: () => {}, - interestsDisplayNames: INTEREST_TO_DISPLAY_NAME_DEFAULTS, -}) - -export function reducer( - s: OnboardingState, - a: OnboardingAction, -): OnboardingState { - let next = {...s} - - switch (a.type) { - case 'next': { - if (s.activeStep === 'interests') { - next.activeStep = 'suggestedAccounts' - next.activeStepIndex = 2 - } else if (s.activeStep === 'suggestedAccounts') { - next.activeStep = 'followingFeed' - next.activeStepIndex = 3 - } else if (s.activeStep === 'followingFeed') { - next.activeStep = 'algoFeeds' - next.activeStepIndex = 4 - } else if (s.activeStep === 'algoFeeds') { - next.activeStep = 'topicalFeeds' - next.activeStepIndex = 5 - } else if (s.activeStep === 'topicalFeeds') { - next.activeStep = 'moderation' - next.activeStepIndex = 6 - } else if (s.activeStep === 'moderation') { - next.activeStep = 'finished' - next.activeStepIndex = 7 - } - break - } - case 'prev': { - if (s.activeStep === 'suggestedAccounts') { - next.activeStep = 'interests' - next.activeStepIndex = 1 - } else if (s.activeStep === 'followingFeed') { - next.activeStep = 'suggestedAccounts' - next.activeStepIndex = 2 - } else if (s.activeStep === 'algoFeeds') { - next.activeStep = 'followingFeed' - next.activeStepIndex = 3 - } else if (s.activeStep === 'topicalFeeds') { - next.activeStep = 'algoFeeds' - next.activeStepIndex = 4 - } else if (s.activeStep === 'moderation') { - next.activeStep = 'topicalFeeds' - next.activeStepIndex = 5 - } else if (s.activeStep === 'finished') { - next.activeStep = 'moderation' - next.activeStepIndex = 6 - } - break - } - case 'finish': { - next = initialState - break - } - case 'setInterestsStepResults': { - next.interestsStepResults = { - selectedInterests: a.selectedInterests, - apiResponse: a.apiResponse, - } - break - } - case 'setSuggestedAccountsStepResults': { - next.suggestedAccountsStepResults = { - accountDids: next.suggestedAccountsStepResults.accountDids.concat( - a.accountDids, - ), - } - break - } - case 'setAlgoFeedsStepResults': { - next.algoFeedsStepResults = { - feedUris: a.feedUris, - } - break - } - case 'setTopicalFeedsStepResults': { - next.topicalFeedsStepResults = { - feedUris: next.topicalFeedsStepResults.feedUris.concat(a.feedUris), - } - break - } - } - - const state = { - ...next, - hasPrev: next.activeStep !== 'interests', - } - - logger.debug(`onboarding`, { - hasPrev: state.hasPrev, - activeStep: state.activeStep, - activeStepIndex: state.activeStepIndex, - interestsStepResults: { - selectedInterests: state.interestsStepResults.selectedInterests, - }, - suggestedAccountsStepResults: state.suggestedAccountsStepResults, - algoFeedsStepResults: state.algoFeedsStepResults, - topicalFeedsStepResults: state.topicalFeedsStepResults, - }) - - if (s.activeStep !== state.activeStep) { - logger.debug(`onboarding: step changed`, {activeStep: state.activeStep}) - } - - return state -} - -export const initialStateReduced: OnboardingState = { +export const initialState: OnboardingState = { hasPrev: false, totalSteps: 3, activeStep: 'profile', @@ -288,15 +109,6 @@ export const initialStateReduced: OnboardingState = { suggestedFeedUris: {}, }, }, - suggestedAccountsStepResults: { - accountDids: [], - }, - algoFeedsStepResults: { - feedUris: [], - }, - topicalFeedsStepResults: { - feedUris: [], - }, profileStepResults: { isCreatedAvatar: false, image: undefined, @@ -305,7 +117,17 @@ export const initialStateReduced: OnboardingState = { }, } -export function reducerReduced( +export const Context = React.createContext<{ + state: OnboardingState + dispatch: React.Dispatch + interestsDisplayNames: {[key: string]: string} +}>({ + state: {...initialState}, + dispatch: () => {}, + interestsDisplayNames: INTEREST_TO_DISPLAY_NAME_DEFAULTS, +}) + +export function reducer( s: OnboardingState, a: OnboardingAction, ): OnboardingState { @@ -333,7 +155,7 @@ export function reducerReduced( break } case 'finish': { - next = initialStateReduced + next = initialState break } case 'setInterestsStepResults': { @@ -343,15 +165,6 @@ export function reducerReduced( } break } - case 'setSuggestedAccountsStepResults': { - break - } - case 'setAlgoFeedsStepResults': { - break - } - case 'setTopicalFeedsStepResults': { - break - } case 'setProfileStepResults': { next.profileStepResults = { isCreatedAvatar: a.isCreatedAvatar, @@ -376,9 +189,6 @@ export function reducerReduced( interestsStepResults: { selectedInterests: state.interestsStepResults.selectedInterests, }, - suggestedAccountsStepResults: state.suggestedAccountsStepResults, - algoFeedsStepResults: state.algoFeedsStepResults, - topicalFeedsStepResults: state.topicalFeedsStepResults, profileStepResults: state.profileStepResults, }) diff --git a/src/screens/Onboarding/util.ts b/src/screens/Onboarding/util.ts index 4174177075..f3c800d053 100644 --- a/src/screens/Onboarding/util.ts +++ b/src/screens/Onboarding/util.ts @@ -5,66 +5,6 @@ import { } from '@atproto/api' import {until} from '#/lib/async/until' -import {PRIMARY_FEEDS} from './StepAlgoFeeds' - -function shuffle(array: any) { - let currentIndex = array.length, - randomIndex - - // While there remain elements to shuffle. - while (currentIndex > 0) { - // Pick a remaining element. - randomIndex = Math.floor(Math.random() * currentIndex) - currentIndex-- - - // And swap it with the current element. - ;[array[currentIndex], array[randomIndex]] = [ - array[randomIndex], - array[currentIndex], - ] - } - - return array -} - -export function aggregateInterestItems( - interests: string[], - map: {[key: string]: string[]}, - fallbackItems: string[], -) { - const selected = interests.length - const all = interests - .map(i => { - // suggestions from server - const rawSuggestions = map[i] - - // safeguard against a missing interest->suggestion mapping - if (!rawSuggestions || !rawSuggestions.length) { - return [] - } - - const suggestions = shuffle(rawSuggestions) - - if (selected === 1) { - return suggestions // return all - } else if (selected === 2) { - return suggestions.slice(0, 5) // return 5 - } else { - return suggestions.slice(0, 3) // return 3 - } - }) - .flat() - // dedupe suggestions - const results = Array.from(new Set(all)) - - // backfill - if (results.length < 20) { - results.push(...shuffle(fallbackItems)) - } - - // dedupe and return 20 - return Array.from(new Set(results)).slice(0, 20) -} export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) { const session = agent.session @@ -109,19 +49,3 @@ async function whenFollowsIndexed( }), ) } - -/** - * Kinda hacky, but we want Discover to appear as the first pinned - * feed after Following - */ -export function sortPrimaryAlgorithmFeeds(uris: string[]) { - return uris.sort((a, b) => { - if (a === PRIMARY_FEEDS[0]?.uri) { - return -1 - } - if (b === PRIMARY_FEEDS[0]?.uri) { - return 1 - } - return a.localeCompare(b) - }) -} diff --git a/src/view/com/testing/TestCtrls.e2e.tsx b/src/view/com/testing/TestCtrls.e2e.tsx index 31122f8388..1291165b3d 100644 --- a/src/view/com/testing/TestCtrls.e2e.tsx +++ b/src/view/com/testing/TestCtrls.e2e.tsx @@ -2,7 +2,6 @@ import React from 'react' import {LogBox, Pressable, View} from 'react-native' import {useQueryClient} from '@tanstack/react-query' -import {useDangerousSetGate} from '#/lib/statsig/statsig' import {useModalControls} from '#/state/modals' import {useSessionApi} from '#/state/session' import {useLoggedOutViewControls} from '#/state/shell/logged-out' @@ -25,7 +24,6 @@ export function TestCtrls() { const {openModal} = useModalControls() const onboardingDispatch = useOnboardingDispatch() const {setShowLoggedOut} = useLoggedOutViewControls() - const setGate = useDangerousSetGate() const onPressSignInAlice = async () => { await login( { @@ -117,8 +115,6 @@ export function TestCtrls() { { - // TODO remove when experiment is over - setGate('reduced_onboarding_and_home_algo_v2', true) onboardingDispatch({type: 'start'}) }} accessibilityRole="button" @@ -128,8 +124,6 @@ export function TestCtrls() { { - // TODO remove when experiment is over - setGate('reduced_onboarding_and_home_algo_v2', false) onboardingDispatch({type: 'start'}) }} accessibilityRole="button" From 5ceb440d4e46a69747316836626a6abcf7246ca1 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 16:38:24 -0700 Subject: [PATCH 05/55] use custom github action for fingerprinting (#4226) * use custom github action for fingerprinting * update pr workflow * update names of workflows * make a native change (testing) * adjust the action * Revert "make a native change (testing)" This reverts commit 8db98357330c24b4ac89b795dc73e3d84a29d9af. * update bundle-deploy script * test a prod build * crazy depth * manually set * use prod default * force prod * revert test changes * save cache after deploy * revert testing --- .github/workflows/build-submit-android.yml | 12 ++ .github/workflows/build-submit-ios.yml | 12 ++ .../workflows/bundle-deploy-eas-update.yml | 112 ++++++++---------- .github/workflows/pull-request-commit.yml | 35 ++---- 4 files changed, 84 insertions(+), 87 deletions(-) diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index e6ce20b86d..b039512d6e 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -119,3 +119,15 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: ⬇️ Restore Cache + id: get-base-commit + uses: actions/cache@v4 + if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + with: + path: most-recent-testflight-commit.txt + key: most-recent-testflight-commit + + - name: ✏️ Write commit hash to cache + if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + run: echo ${{ github.sha }} > most-recent-testflight-commit.txt diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index bfd0670956..0256e96878 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -76,3 +76,15 @@ jobs: - name: 🚀 Deploy run: eas submit -p ios --non-interactive --path build.ipa + + - name: ⬇️ Restore Cache + id: get-base-commit + uses: actions/cache@v4 + if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + with: + path: most-recent-testflight-commit.txt + key: most-recent-testflight-commit + + - name: ✏️ Write commit hash to cache + if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + run: echo ${{ github.sha }} > most-recent-testflight-commit.txt diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 3d49404677..192593b9b2 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -26,7 +26,7 @@ jobs: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-deploy cancel-in-progress: true outputs: - fingerprint-is-different: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different }} + changes-detected: ${{ steps.fingerprint.outputs.includes-changes }} steps: - name: Check for EXPO_TOKEN @@ -49,69 +49,22 @@ jobs: with: fetch-depth: 0 - - name: ⬇️ Get last successful deployment commit from the cache - id: get-base-commit - uses: actions/cache@v4 - with: - path: last-successful-commit-hash.txt - key: last-successful-deployment-commit-${{ github.ref_name }}-${{ github.sha }} - restore-keys: | - last-successful-deployment-commit-${{ github.ref_name }}- - - - name: Add the last successful deployment commit to the output - id: last-successful-commit - run: echo base-commit=$(cat last-successful-commit-hash.txt) >> "$GITHUB_OUTPUT" - - name: ⬇️ Fetch commits from base branch if: ${{ github.ref != 'refs/heads/main' }} run: git fetch origin main:main --depth 100 - # This should get the current production release's commit's hash to see if the update is compatible - - name: 🕵️ Get the base commit - id: base-commit - run: | - if ${{ inputs.channel == 'production' }}; then - echo base-commit=$(git show-ref -s ${{ inputs.runtimeVersion }}) >> "$GITHUB_OUTPUT" - else - echo base-commit=${{ steps.last-successful-commit.base-commit }} >> "$GITHUB_OUTPUT" - fi - - - name: ✓ Make sure we found a base commit - run: | - if [ -z "${{ steps.base-commit.outputs.base-commit }}" && ${{ inputs.channel == 'production' }} ]; then - echo "Could not find a base commit for this release. Exiting." - exit 1 - fi - - name: 🔧 Setup Node uses: actions/setup-node@v4 with: node-version-file: .nvmrc cache: yarn - - name: ⚙️ Install Dependencies - run: yarn install - - # Run the fingerprint - - name: 📷 Check fingerprint + - name: 📷 Check fingerprint and install dependencies id: fingerprint - uses: expo/expo-github-action/fingerprint@main + uses: bluesky-social/github-actions/fingerprint-native@main with: - previous-git-commit: ${{ steps.base-commit.outputs.base-commit }} - - - name: 👀 Debug fingerprint - id: fingerprint-debug - run: | - echo "previousGitCommit=${{ steps.fingerprint.outputs.previous-git-commit }} currentGitCommit=${{ steps.fingerprint.outputs.current-git-commit }}" - echo "isPreviousFingerprintEmpty=${{ steps.fingerprint.outputs.previous-fingerprint == '' }}" - - fingerprintDiff='$(echo "${{ steps.fingerprint.outputs.fingerprint-diff }}")' - - if [[ $fingerprintDiff =~ "bareRncliAutolinking" || $fingerprintDiff =~ "expoAutolinkingAndroid" || $fingerprintDiff =~ "expoAutolinkingIos" ]]; then - echo fingerprint-is-different="true" >> "$GITHUB_OUTPUT" - else - echo fingerprint-is-different="false" >> "$GITHUB_OUTPUT" - fi + profile: ${{ inputs.channel || 'testflight' }} + previous-commit-tag: ${{ inputs.runtimeVersion }} - name: Lint check run: yarn lint @@ -127,22 +80,22 @@ jobs: - name: 🔨 Setup EAS uses: expo/expo-github-action@v8 - if: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different == 'false'}} + if: ${{ !steps.fingerprint.outputs.includes-changes }} with: expo-version: latest eas-version: latest token: ${{ secrets.EXPO_TOKEN }} - name: ⛏️ Setup Expo - if: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different == 'false'}} + if: ${{ !steps.fingerprint.outputs.includes-changes }} run: yarn global add eas-cli-local-build-plugin - name: 🪛 Setup jq - if: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different == 'false'}} + if: ${{ !steps.fingerprint.outputs.includes-changes }} uses: dcarbone/install-jq-action@v2 - name: ✏️ Write environment variables - if: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different == 'false'}} + if: ${{ !steps.fingerprint.outputs.includes-changes }} run: | export json='${{ secrets.GOOGLE_SERVICES_TOKEN }}' echo "${{ secrets.ENV_TOKEN }}" > .env @@ -151,19 +104,28 @@ jobs: echo "$json" > google-services.json - name: 🏗️ Create Bundle - if: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different == 'false'}} + if: ${{ !steps.fingerprint.outputs.includes-changes }} run: EXPO_PUBLIC_ENV="${{ inputs.channel || 'testflight' }}" yarn export - name: 📦 Package Bundle and 🚀 Deploy - if: ${{ steps.fingerprint-debug.outputs.fingerprint-is-different == 'false'}} + if: ${{ !steps.fingerprint.outputs.includes-changes }} run: yarn use-build-number bash scripts/bundleUpdate.sh env: DENIS_API_KEY: ${{ secrets.DENIS_API_KEY }} RUNTIME_VERSION: ${{ inputs.runtimeVersion }} CHANNEL_NAME: ${{ inputs.channel || 'testflight' }} - - name: Save successful deployment commit hash - run: echo ${{ steps.fingerprint.outputs.current-git-commit }} > last-successful-commit-hash.txt + - name: ⬇️ Restore Cache + id: get-base-commit + uses: actions/cache@v4 + if: ${{ !steps.fingerprint.outputs.includes-changes }} + with: + path: most-recent-testflight-commit.txt + key: most-recent-testflight-commit + + - name: ✏️ Write commit hash to cache + if: ${{ !steps.fingerprint.outputs.includes-changes }} + run: echo ${{ github.sha }} > most-recent-testflight-commit.txt # GitHub actions are horrible so let's just copy paste this in buildIfNecessaryIOS: @@ -171,11 +133,11 @@ jobs: runs-on: macos-14 concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}-build-ios - cancel-in-progress: false + cancel-in-progress: true needs: [bundleDeploy] # Gotta check if its NOT '[]' because any md5 hash in the outputs is detected as a possible secret and won't be # available here - if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.fingerprint-is-different == 'true' }} + if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected }} steps: - name: Check for EXPO_TOKEN run: > @@ -238,6 +200,18 @@ jobs: - name: 🚀 Deploy run: eas submit -p ios --non-interactive --path build.ipa + - name: ⬇️ Restore Cache + id: get-base-commit + uses: actions/cache@v4 + if: ${{ inputs.channel == 'testflight' }} + with: + path: most-recent-testflight-commit.txt + key: most-recent-testflight-commit + + - name: ✏️ Write commit hash to cache + if: ${{ inputs.channel == 'testflight' }} + run: echo ${{ github.sha }} > most-recent-testflight-commit.txt + buildIfNecessaryAndroid: name: Build and Submit Android runs-on: ubuntu-latest @@ -247,7 +221,7 @@ jobs: needs: [ bundleDeploy ] # Gotta check if its NOT '[]' because any md5 hash in the outputs is detected as a possible secret and won't be # available here - if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.fingerprint-is-different == 'true' }} + if: ${{ inputs.channel != 'production' && needs.bundleDeploy.outputs.changes-detected }} steps: - name: Check for EXPO_TOKEN @@ -325,3 +299,15 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + - name: ⬇️ Restore Cache + id: get-base-commit + uses: actions/cache@v4 + if: ${{ inputs.channel == 'testflight' }} + with: + path: most-recent-testflight-commit.txt + key: most-recent-testflight-commit + + - name: ✏️ Write commit hash to cache + if: ${{ inputs.channel == 'testflight' }} + run: echo ${{ github.sha }} > most-recent-testflight-commit.txt diff --git a/.github/workflows/pull-request-commit.yml b/.github/workflows/pull-request-commit.yml index 6c796fd7c4..53e3cc9983 100644 --- a/.github/workflows/pull-request-commit.yml +++ b/.github/workflows/pull-request-commit.yml @@ -1,7 +1,7 @@ # Credit for fingerprint action https://github.com/expo/expo # https://github.com/expo/expo/blob/main/.github/workflows/pr-labeler.yml --- -name: PR labeler +name: PR Tests on: push: @@ -21,7 +21,7 @@ permissions: jobs: webpack-analyzer: runs-on: ubuntu-22.04 - if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.event_name == 'pull_request'}} steps: - name: ⬇️ Checkout uses: actions/checkout@v4 @@ -94,10 +94,9 @@ jobs: | ${{ steps.get-diff.outputs.base_file_string }} | ${{ steps.get-diff.outputs.pr_file_string }} | ${{ steps.get-diff.outputs.diff_file_string }} (${{ steps.get-diff.outputs.percent }}%) | --- - test-suite-fingerprint: + fingerprint-native: runs-on: ubuntu-22.04 - if: ${{ github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'push' }} - concurrency: fingerprint-${{ github.event_name != 'pull_request' && 'main' || github.run_id }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.event_name == 'pull_request'}} steps: - name: ⬇️ Checkout uses: actions/checkout@v4 @@ -114,35 +113,23 @@ jobs: node-version-file: .nvmrc cache: yarn - - name: ⚙️ Install Dependencies - run: yarn install - - - name: Get the base commit - id: base-commit - run: echo base-commit=$(git log -n 1 main --pretty=format:'%H') >> "$GITHUB_OUTPUT" - - - name: 📷 Check fingerprint + - name: 📷 Check fingerprint and install dependencies id: fingerprint - uses: expo/expo-github-action/fingerprint@main + uses: bluesky-social/github-actions/fingerprint-native@main with: - previous-git-commit: ${{ steps.base-commit.outputs.base-commit }} - - - name: 👀 Debug fingerprint - run: | - echo "previousGitCommit=${{ steps.fingerprint.outputs.previous-git-commit }} currentGitCommit=${{ steps.fingerprint.outputs.current-git-commit }}" - echo "isPreviousFingerprintEmpty=${{ steps.fingerprint.outputs.previous-fingerprint == '' }}" + profile: pull-request - name: 💬 Drop a comment uses: marocchino/sticky-pull-request-comment@v2 - if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff != '[]' }} + if: ${{ steps.fingerprint.outputs.includes-changes }} with: header: fingerprint-diff message: | - The Pull Request introduced fingerprint changes against the base commit: ${{ steps.fingerprint.outputs.previous-git-commit }} + The Pull Request introduced fingerprint changes against the base commit:
Fingerprint diff ```json - ${{ steps.fingerprint.outputs.fingerprint-diff }} + ${{ steps.fingerprint.outputs.diff }} ```
@@ -152,7 +139,7 @@ jobs: - name: 💬 Delete comment uses: marocchino/sticky-pull-request-comment@v2 - if: ${{ github.event_name == 'pull_request' && steps.fingerprint.outputs.fingerprint-diff == '[]' }} + if: ${{ !steps.fingerprint.outputs.includes-changes }} with: header: fingerprint-diff delete: true From 888bec7b4fbe1b924d788333ec44c916fd3e8676 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 18:15:35 -0700 Subject: [PATCH 06/55] Upgrade to Expo 51 and React Native 0.74 (#3980) * upgrade packages * remove `expo-image-picker` patch * remove old expo-updates patch * rename rn patch * downgrade crop picker * bump `ExpoGifView` `SDWebImage` version * apply config changes * update build docs for apple silicon * update build docs for apple silicon * update expo-updates patch * add back patch readme * bump `expo-dev-client` * bump `babel-preset` * update `babel.config.js` * update `react-native-paste-input` patch * remove old ota updates hook * update types * update types * downgrade pager-view * update animated ref type * fix web-only type * update `react-native-bottom-sheet` `BottomSheetTextInput` * add `expo-application` to jest mocks * remove reanimated patch * update notifications patch * update reanimated path * fix import * update yarn.lock * use `ItemT` instead of `any` * expo bump * Revert logic change, fix types * Fix JSON file --------- Co-authored-by: Dan Abramov --- app.config.js | 1 - babel.config.js | 3 - docs/build.md | 5 +- jest/jestSetup.js | 9 +- .../ios/ExpoBlueskyGifView.podspec | 4 +- package.json | 80 +- ...rmost+react-native-paste-input+0.6.4.patch | 3612 ----------------- ...rmost+react-native-paste-input+0.7.1.patch | 16 + patches/expo-image-picker+14.7.1.patch | 112 - patches/expo-image-picker+14.7.1.patch.md | 3 - ....patch => expo-notifications+0.28.1.patch} | 80 +- ....24.7.patch => expo-updates+0.25.11.patch} | 16 +- ...patch.md => expo-updates+0.25.11.patch.md} | 2 +- ...0.73.2.patch => react-native+0.74.1.patch} | 0 ....patch.md => react-native+0.74.1.patch.md} | 0 ...h => react-native-reanimated+3.11.0.patch} | 28 +- src/lib/hooks/useOTAUpdate.ts | 56 - src/view/com/pager/PagerWithHeader.tsx | 7 +- src/view/com/util/Views.web.tsx | 3 +- src/view/screens/LanguageSettings.tsx | 36 +- src/view/screens/Search/Search.tsx | 2 +- yarn.lock | 1891 +++++---- 22 files changed, 1172 insertions(+), 4794 deletions(-) delete mode 100644 patches/@mattermost+react-native-paste-input+0.6.4.patch create mode 100644 patches/@mattermost+react-native-paste-input+0.7.1.patch delete mode 100644 patches/expo-image-picker+14.7.1.patch delete mode 100644 patches/expo-image-picker+14.7.1.patch.md rename patches/{expo-notifications+0.27.6.patch => expo-notifications+0.28.1.patch} (88%) rename patches/{expo-updates+0.24.7.patch => expo-updates+0.25.11.patch} (60%) rename patches/{expo-updates+0.24.7.patch.md => expo-updates+0.25.11.patch.md} (96%) rename patches/{react-native+0.73.2.patch => react-native+0.74.1.patch} (100%) rename patches/{react-native+0.73.2.patch.md => react-native+0.74.1.patch.md} (100%) rename patches/{react-native-reanimated+3.6.0.patch => react-native-reanimated+3.11.0.patch} (57%) delete mode 100644 src/lib/hooks/useOTAUpdate.ts diff --git a/app.config.js b/app.config.js index ffa6cf7dab..eafacc6cc1 100644 --- a/app.config.js +++ b/app.config.js @@ -175,7 +175,6 @@ module.exports = function (config) { checkAutomatically: 'NEVER', channel: UPDATES_CHANNEL, }, - assetBundlePatterns: ['**/*'], plugins: [ 'expo-localization', Boolean(process.env.SENTRY_AUTH_TOKEN) && 'sentry-expo', diff --git a/babel.config.js b/babel.config.js index a54deca7cd..c976d04b67 100644 --- a/babel.config.js +++ b/babel.config.js @@ -8,9 +8,6 @@ module.exports = function (api) { { lazyImports: true, native: { - // We should be able to remove this after upgrading Expo - // to a version that includes https://github.com/expo/expo/pull/24672. - unstable_transformProfile: 'hermes-stable', // Disable ESM -> CJS compilation because Metro takes care of it. // However, we need it in Jest tests since those run without Metro. disableImportExportTransform: !isTestEnv, diff --git a/docs/build.md b/docs/build.md index 88733d3b09..dc710686e7 100644 --- a/docs/build.md +++ b/docs/build.md @@ -4,7 +4,10 @@ - Set up your environment [using the expo instructions](https://docs.expo.dev/guides/local-app-development/). - make sure that the JAVA_HOME points to the zulu-17 directory in your `.zshrc` or `.bashrc` file: `export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home`. DO NOT use another JDK or you will encounter build errors. -- If you're running macOS, make sure you are running the correct versions of Ruby and Cocoapods: +- If you're running macOS, make sure you are running the correct versions of Ruby and Cocoapods:- + - If you are using Apple Silicon and this is the first time you are building for RN 0.74+, you may need to run: + - `arch -arm64 brew install llvm` + - `sudo gem install ffi` - Check if you've installed Cocoapods through `homebrew`. If you have, remove it: - `brew info cocoapods` - If output says `Installed`: diff --git a/jest/jestSetup.js b/jest/jestSetup.js index e690e813a9..a6b7c24f69 100644 --- a/jest/jestSetup.js +++ b/jest/jestSetup.js @@ -1,10 +1,10 @@ /* global jest */ -import {configure} from '@testing-library/react-native' import 'react-native-gesture-handler/jestSetup' - // IMPORTANT: this is what's used in the native runtime import 'react-native-url-polyfill/auto' +import {configure} from '@testing-library/react-native' + configure({asyncUtilTimeout: 20000}) jest.mock('@react-native-async-storage/async-storage', () => @@ -90,3 +90,8 @@ jest.mock('sentry-expo', () => ({ })) jest.mock('crypto', () => ({})) + +jest.mock('expo-application', () => ({ + nativeApplicationVersion: '1.0.0', + nativeBuildVersion: '1', +})) diff --git a/modules/expo-bluesky-gif-view/ios/ExpoBlueskyGifView.podspec b/modules/expo-bluesky-gif-view/ios/ExpoBlueskyGifView.podspec index ddd0877b24..352812640b 100644 --- a/modules/expo-bluesky-gif-view/ios/ExpoBlueskyGifView.podspec +++ b/modules/expo-bluesky-gif-view/ios/ExpoBlueskyGifView.podspec @@ -10,8 +10,8 @@ Pod::Spec.new do |s| s.static_framework = true s.dependency 'ExpoModulesCore' - s.dependency 'SDWebImage', '~> 5.17.0' - s.dependency 'SDWebImageWebPCoder', '~> 0.13.0' + s.dependency 'SDWebImage', '~> 5.19.1' + s.dependency 'SDWebImageWebPCoder', '~> 0.14.6' # Swift/Objective-C compatibility s.pod_target_xcconfig = { diff --git a/package.json b/package.json index 0634a6cce9..5a936e3c1c 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@fortawesome/free-solid-svg-icons": "^6.1.1", "@fortawesome/react-native-fontawesome": "^0.3.0", "@lingui/react": "^4.5.0", - "@mattermost/react-native-paste-input": "^0.6.4", + "@mattermost/react-native-paste-input": "^0.7.1", "@miblanchard/react-native-slider": "^2.3.1", "@radix-ui/react-dropdown-menu": "^2.0.6", "@react-native-async-storage/async-storage": "1.23.1", @@ -107,35 +107,36 @@ "base64-js": "^1.5.1", "bcp-47-match": "^2.0.3", "date-fns": "^2.30.0", + "deprecated-react-native-prop-types": "^5.0.0", "email-validator": "^2.0.4", "emoji-mart": "^5.5.2", "eventemitter3": "^5.0.1", - "expo": "^50.0.17", - "expo-application": "^5.8.3", - "expo-build-properties": "^0.11.1", - "expo-camera": "~14.0.4", + "expo": "^51.0.8", + "expo-application": "^5.9.1", + "expo-build-properties": "^0.12.1", + "expo-camera": "~14.1.3", "expo-clipboard": "^5.0.1", - "expo-constants": "~15.4.5", - "expo-dev-client": "~3.3.8", + "expo-constants": "~15.4.6", + "expo-dev-client": "^4.0.14", "expo-device": "~5.9.3", "expo-file-system": "^16.0.9", "expo-haptics": "^12.8.1", - "expo-image": "~1.10.6", - "expo-image-manipulator": "^11.8.0", - "expo-image-picker": "~14.7.1", - "expo-linear-gradient": "^12.7.2", - "expo-linking": "^6.2.2", - "expo-localization": "~14.8.3", - "expo-media-library": "~15.9.1", - "expo-navigation-bar": "~2.8.1", - "expo-notifications": "~0.27.6", - "expo-sharing": "^11.10.0", - "expo-splash-screen": "~0.26.4", - "expo-status-bar": "~1.11.1", - "expo-system-ui": "~2.9.3", - "expo-task-manager": "~11.7.2", - "expo-updates": "~0.24.10", - "expo-web-browser": "~12.8.2", + "expo-image": "~1.12.9", + "expo-image-manipulator": "^12.0.3", + "expo-image-picker": "~15.0.4", + "expo-linear-gradient": "^13.0.2", + "expo-linking": "^6.3.1", + "expo-localization": "~15.0.3", + "expo-media-library": "~16.0.3", + "expo-navigation-bar": "~3.0.4", + "expo-notifications": "~0.28.1", + "expo-sharing": "^12.0.1", + "expo-splash-screen": "~0.27.4", + "expo-status-bar": "~1.12.1", + "expo-system-ui": "~3.0.4", + "expo-task-manager": "~11.8.1", + "expo-updates": "~0.25.11", + "expo-web-browser": "~13.0.3", "fast-text-encoding": "^1.0.6", "history": "^5.3.0", "js-sha256": "^0.9.0", @@ -164,30 +165,30 @@ "react-compiler-runtime": "file:./lib/react-compiler-runtime", "react-dom": "^18.2.0", "react-keyed-flatten-children": "^3.0.0", - "react-native": "0.73.2", - "react-native-date-picker": "^4.4.0", + "react-native": "0.74.1", + "react-native-date-picker": "^4.4.2", "react-native-drawer-layout": "^4.0.0-alpha.3", "react-native-fs": "^2.20.0", - "react-native-gesture-handler": "~2.14.0", + "react-native-gesture-handler": "~2.16.2", "react-native-get-random-values": "~1.11.0", - "react-native-image-crop-picker": "^0.38.1", + "react-native-image-crop-picker": "0.40.3", "react-native-ios-context-menu": "^1.15.3", "react-native-keyboard-controller": "^1.12.1", "react-native-pager-view": "6.2.3", - "react-native-picker-select": "^8.1.0", + "react-native-picker-select": "^9.1.3", "react-native-progress": "bluesky-social/react-native-progress", - "react-native-reanimated": "^3.6.0", + "react-native-reanimated": "^3.11.0", "react-native-root-siblings": "^4.1.1", - "react-native-safe-area-context": "4.8.2", - "react-native-screens": "~3.29.0", - "react-native-svg": "14.1.0", - "react-native-uitextview": "^1.1.6", + "react-native-safe-area-context": "4.10.1", + "react-native-screens": "~3.31.1", + "react-native-svg": "^15.2.0", + "react-native-uitextview": "^1.1.7", "react-native-url-polyfill": "^1.3.0", - "react-native-uuid": "^2.0.1", + "react-native-uuid": "^2.0.2", "react-native-view-shot": "^3.8.0", - "react-native-web": "~0.19.6", + "react-native-web": "~0.19.11", "react-native-web-webview": "^1.0.2", - "react-native-webview": "13.6.4", + "react-native-webview": "13.10.2", "react-responsive": "^9.0.2", "react-textarea-autosize": "^8.5.3", "rn-fetch-blob": "^0.12.0", @@ -210,7 +211,7 @@ "@lingui/macro": "^4.5.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@react-native-community/eslint-config": "^3.0.0", - "@react-native/typescript-config": "^0.74.0", + "@react-native/typescript-config": "^0.74.1", "@testing-library/jest-native": "^5.4.1", "@testing-library/react-native": "^11.5.2", "@tsconfig/react-native": "^2.0.3", @@ -254,7 +255,7 @@ "jest-expo": "^50.0.1", "jest-junit": "^15.0.0", "lint-staged": "^13.2.3", - "metro-react-native-babel-preset": "^0.73.7", + "metro-react-native-babel-preset": "^0.74.1", "prettier": "^2.8.3", "react-native-dotenv": "^3.3.1", "react-refresh": "^0.14.0", @@ -270,7 +271,8 @@ }, "resolutions": { "@types/react": "^18", - "**/zeed-dom": "0.10.9" + "**/zeed-dom": "0.10.9", + "@react-native/babel-preset": "0.74.1" }, "jest": { "preset": "jest-expo/ios", diff --git a/patches/@mattermost+react-native-paste-input+0.6.4.patch b/patches/@mattermost+react-native-paste-input+0.6.4.patch deleted file mode 100644 index 08413846ff..0000000000 --- a/patches/@mattermost+react-native-paste-input+0.6.4.patch +++ /dev/null @@ -1,3612 +0,0 @@ -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml -new file mode 100644 -index 0000000..0249d77 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml -@@ -0,0 +1,9 @@ -+ -+ -+ -+ -+ -+ -\ No newline at end of file -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json -new file mode 100644 -index 0000000..2aeca5f ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json -@@ -0,0 +1,18 @@ -+{ -+ "version": 3, -+ "artifactType": { -+ "type": "AAPT_FRIENDLY_MERGED_MANIFESTS", -+ "kind": "Directory" -+ }, -+ "applicationId": "com.mattermost.pasteinput", -+ "variantName": "debug", -+ "elements": [ -+ { -+ "type": "SINGLE", -+ "filters": [], -+ "attributes": [], -+ "outputFile": "AndroidManifest.xml" -+ } -+ ], -+ "elementType": "File" -+} -\ No newline at end of file -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aar_metadata/debug/aar-metadata.properties b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aar_metadata/debug/aar-metadata.properties -new file mode 100644 -index 0000000..8c9c699 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/aar_metadata/debug/aar-metadata.properties -@@ -0,0 +1,4 @@ -+aarFormatVersion=1.0 -+aarMetadataVersion=1.0 -+minCompileSdk=1 -+minAndroidGradlePluginVersion=1.0.0 -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/compile_r_class_jar/debug/R.jar b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/compile_r_class_jar/debug/R.jar -new file mode 100644 -index 0000000..e69de29 -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/compile_symbol_list/debug/R.txt b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/compile_symbol_list/debug/R.txt -new file mode 100644 -index 0000000..7c9d30e ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/compile_symbol_list/debug/R.txt -@@ -0,0 +1,1953 @@ -+int anim abc_fade_in 0x0 -+int anim abc_fade_out 0x0 -+int anim abc_grow_fade_in_from_bottom 0x0 -+int anim abc_popup_enter 0x0 -+int anim abc_popup_exit 0x0 -+int anim abc_shrink_fade_out_from_bottom 0x0 -+int anim abc_slide_in_bottom 0x0 -+int anim abc_slide_in_top 0x0 -+int anim abc_slide_out_bottom 0x0 -+int anim abc_slide_out_top 0x0 -+int anim abc_tooltip_enter 0x0 -+int anim abc_tooltip_exit 0x0 -+int anim btn_checkbox_to_checked_box_inner_merged_animation 0x0 -+int anim btn_checkbox_to_checked_box_outer_merged_animation 0x0 -+int anim btn_checkbox_to_checked_icon_null_animation 0x0 -+int anim btn_checkbox_to_unchecked_box_inner_merged_animation 0x0 -+int anim btn_checkbox_to_unchecked_check_path_merged_animation 0x0 -+int anim btn_checkbox_to_unchecked_icon_null_animation 0x0 -+int anim btn_radio_to_off_mtrl_dot_group_animation 0x0 -+int anim btn_radio_to_off_mtrl_ring_outer_animation 0x0 -+int anim btn_radio_to_off_mtrl_ring_outer_path_animation 0x0 -+int anim btn_radio_to_on_mtrl_dot_group_animation 0x0 -+int anim btn_radio_to_on_mtrl_ring_outer_animation 0x0 -+int anim btn_radio_to_on_mtrl_ring_outer_path_animation 0x0 -+int anim catalyst_fade_in 0x0 -+int anim catalyst_fade_out 0x0 -+int anim catalyst_push_up_in 0x0 -+int anim catalyst_push_up_out 0x0 -+int anim catalyst_slide_down 0x0 -+int anim catalyst_slide_up 0x0 -+int anim fragment_fast_out_extra_slow_in 0x0 -+int animator fragment_close_enter 0x0 -+int animator fragment_close_exit 0x0 -+int animator fragment_fade_enter 0x0 -+int animator fragment_fade_exit 0x0 -+int animator fragment_open_enter 0x0 -+int animator fragment_open_exit 0x0 -+int attr actionBarDivider 0x0 -+int attr actionBarItemBackground 0x0 -+int attr actionBarPopupTheme 0x0 -+int attr actionBarSize 0x0 -+int attr actionBarSplitStyle 0x0 -+int attr actionBarStyle 0x0 -+int attr actionBarTabBarStyle 0x0 -+int attr actionBarTabStyle 0x0 -+int attr actionBarTabTextStyle 0x0 -+int attr actionBarTheme 0x0 -+int attr actionBarWidgetTheme 0x0 -+int attr actionButtonStyle 0x0 -+int attr actionDropDownStyle 0x0 -+int attr actionLayout 0x0 -+int attr actionMenuTextAppearance 0x0 -+int attr actionMenuTextColor 0x0 -+int attr actionModeBackground 0x0 -+int attr actionModeCloseButtonStyle 0x0 -+int attr actionModeCloseContentDescription 0x0 -+int attr actionModeCloseDrawable 0x0 -+int attr actionModeCopyDrawable 0x0 -+int attr actionModeCutDrawable 0x0 -+int attr actionModeFindDrawable 0x0 -+int attr actionModePasteDrawable 0x0 -+int attr actionModePopupWindowStyle 0x0 -+int attr actionModeSelectAllDrawable 0x0 -+int attr actionModeShareDrawable 0x0 -+int attr actionModeSplitBackground 0x0 -+int attr actionModeStyle 0x0 -+int attr actionModeTheme 0x0 -+int attr actionModeWebSearchDrawable 0x0 -+int attr actionOverflowButtonStyle 0x0 -+int attr actionOverflowMenuStyle 0x0 -+int attr actionProviderClass 0x0 -+int attr actionViewClass 0x0 -+int attr activityChooserViewStyle 0x0 -+int attr actualImageResource 0x0 -+int attr actualImageScaleType 0x0 -+int attr actualImageUri 0x0 -+int attr alertDialogButtonGroupStyle 0x0 -+int attr alertDialogCenterButtons 0x0 -+int attr alertDialogStyle 0x0 -+int attr alertDialogTheme 0x0 -+int attr allowStacking 0x0 -+int attr alpha 0x0 -+int attr alphabeticModifiers 0x0 -+int attr arrowHeadLength 0x0 -+int attr arrowShaftLength 0x0 -+int attr autoCompleteTextViewStyle 0x0 -+int attr autoSizeMaxTextSize 0x0 -+int attr autoSizeMinTextSize 0x0 -+int attr autoSizePresetSizes 0x0 -+int attr autoSizeStepGranularity 0x0 -+int attr autoSizeTextType 0x0 -+int attr autofillInlineSuggestionChip 0x0 -+int attr autofillInlineSuggestionEndIconStyle 0x0 -+int attr autofillInlineSuggestionStartIconStyle 0x0 -+int attr autofillInlineSuggestionSubtitle 0x0 -+int attr autofillInlineSuggestionTitle 0x0 -+int attr background 0x0 -+int attr backgroundImage 0x0 -+int attr backgroundSplit 0x0 -+int attr backgroundStacked 0x0 -+int attr backgroundTint 0x0 -+int attr backgroundTintMode 0x0 -+int attr barLength 0x0 -+int attr borderlessButtonStyle 0x0 -+int attr buttonBarButtonStyle 0x0 -+int attr buttonBarNegativeButtonStyle 0x0 -+int attr buttonBarNeutralButtonStyle 0x0 -+int attr buttonBarPositiveButtonStyle 0x0 -+int attr buttonBarStyle 0x0 -+int attr buttonCompat 0x0 -+int attr buttonGravity 0x0 -+int attr buttonIconDimen 0x0 -+int attr buttonPanelSideLayout 0x0 -+int attr buttonStyle 0x0 -+int attr buttonStyleSmall 0x0 -+int attr buttonTint 0x0 -+int attr buttonTintMode 0x0 -+int attr checkMarkCompat 0x0 -+int attr checkMarkTint 0x0 -+int attr checkMarkTintMode 0x0 -+int attr checkboxStyle 0x0 -+int attr checkedTextViewStyle 0x0 -+int attr closeIcon 0x0 -+int attr closeItemLayout 0x0 -+int attr collapseContentDescription 0x0 -+int attr collapseIcon 0x0 -+int attr color 0x0 -+int attr colorAccent 0x0 -+int attr colorBackgroundFloating 0x0 -+int attr colorButtonNormal 0x0 -+int attr colorControlActivated 0x0 -+int attr colorControlHighlight 0x0 -+int attr colorControlNormal 0x0 -+int attr colorError 0x0 -+int attr colorPrimary 0x0 -+int attr colorPrimaryDark 0x0 -+int attr colorSwitchThumbNormal 0x0 -+int attr commitIcon 0x0 -+int attr contentDescription 0x0 -+int attr contentInsetEnd 0x0 -+int attr contentInsetEndWithActions 0x0 -+int attr contentInsetLeft 0x0 -+int attr contentInsetRight 0x0 -+int attr contentInsetStart 0x0 -+int attr contentInsetStartWithNavigation 0x0 -+int attr controlBackground 0x0 -+int attr customNavigationLayout 0x0 -+int attr defaultQueryHint 0x0 -+int attr dialogCornerRadius 0x0 -+int attr dialogPreferredPadding 0x0 -+int attr dialogTheme 0x0 -+int attr displayOptions 0x0 -+int attr divider 0x0 -+int attr dividerHorizontal 0x0 -+int attr dividerPadding 0x0 -+int attr dividerVertical 0x0 -+int attr drawableBottomCompat 0x0 -+int attr drawableEndCompat 0x0 -+int attr drawableLeftCompat 0x0 -+int attr drawableRightCompat 0x0 -+int attr drawableSize 0x0 -+int attr drawableStartCompat 0x0 -+int attr drawableTint 0x0 -+int attr drawableTintMode 0x0 -+int attr drawableTopCompat 0x0 -+int attr drawerArrowStyle 0x0 -+int attr dropDownListViewStyle 0x0 -+int attr dropdownListPreferredItemHeight 0x0 -+int attr editTextBackground 0x0 -+int attr editTextColor 0x0 -+int attr editTextStyle 0x0 -+int attr elevation 0x0 -+int attr emojiCompatEnabled 0x0 -+int attr expandActivityOverflowButtonDrawable 0x0 -+int attr fadeDuration 0x0 -+int attr failureImage 0x0 -+int attr failureImageScaleType 0x0 -+int attr firstBaselineToTopHeight 0x0 -+int attr font 0x0 -+int attr fontFamily 0x0 -+int attr fontProviderAuthority 0x0 -+int attr fontProviderCerts 0x0 -+int attr fontProviderFetchStrategy 0x0 -+int attr fontProviderFetchTimeout 0x0 -+int attr fontProviderPackage 0x0 -+int attr fontProviderQuery 0x0 -+int attr fontProviderSystemFontFamily 0x0 -+int attr fontStyle 0x0 -+int attr fontVariationSettings 0x0 -+int attr fontWeight 0x0 -+int attr gapBetweenBars 0x0 -+int attr goIcon 0x0 -+int attr height 0x0 -+int attr hideOnContentScroll 0x0 -+int attr homeAsUpIndicator 0x0 -+int attr homeLayout 0x0 -+int attr icon 0x0 -+int attr iconTint 0x0 -+int attr iconTintMode 0x0 -+int attr iconifiedByDefault 0x0 -+int attr imageButtonStyle 0x0 -+int attr indeterminateProgressStyle 0x0 -+int attr initialActivityCount 0x0 -+int attr isAutofillInlineSuggestionTheme 0x0 -+int attr isLightTheme 0x0 -+int attr itemPadding 0x0 -+int attr lStar 0x0 -+int attr lastBaselineToBottomHeight 0x0 -+int attr layout 0x0 -+int attr lineHeight 0x0 -+int attr listChoiceBackgroundIndicator 0x0 -+int attr listChoiceIndicatorMultipleAnimated 0x0 -+int attr listChoiceIndicatorSingleAnimated 0x0 -+int attr listDividerAlertDialog 0x0 -+int attr listItemLayout 0x0 -+int attr listLayout 0x0 -+int attr listMenuViewStyle 0x0 -+int attr listPopupWindowStyle 0x0 -+int attr listPreferredItemHeight 0x0 -+int attr listPreferredItemHeightLarge 0x0 -+int attr listPreferredItemHeightSmall 0x0 -+int attr listPreferredItemPaddingEnd 0x0 -+int attr listPreferredItemPaddingLeft 0x0 -+int attr listPreferredItemPaddingRight 0x0 -+int attr listPreferredItemPaddingStart 0x0 -+int attr logo 0x0 -+int attr logoDescription 0x0 -+int attr maxButtonHeight 0x0 -+int attr measureWithLargestChild 0x0 -+int attr menu 0x0 -+int attr multiChoiceItemLayout 0x0 -+int attr navigationContentDescription 0x0 -+int attr navigationIcon 0x0 -+int attr navigationMode 0x0 -+int attr nestedScrollViewStyle 0x0 -+int attr numericModifiers 0x0 -+int attr overlapAnchor 0x0 -+int attr overlayImage 0x0 -+int attr paddingBottomNoButtons 0x0 -+int attr paddingEnd 0x0 -+int attr paddingStart 0x0 -+int attr paddingTopNoTitle 0x0 -+int attr panelBackground 0x0 -+int attr panelMenuListTheme 0x0 -+int attr panelMenuListWidth 0x0 -+int attr placeholderImage 0x0 -+int attr placeholderImageScaleType 0x0 -+int attr popupMenuStyle 0x0 -+int attr popupTheme 0x0 -+int attr popupWindowStyle 0x0 -+int attr preserveIconSpacing 0x0 -+int attr pressedStateOverlayImage 0x0 -+int attr progressBarAutoRotateInterval 0x0 -+int attr progressBarImage 0x0 -+int attr progressBarImageScaleType 0x0 -+int attr progressBarPadding 0x0 -+int attr progressBarStyle 0x0 -+int attr queryBackground 0x0 -+int attr queryHint 0x0 -+int attr queryPatterns 0x0 -+int attr radioButtonStyle 0x0 -+int attr ratingBarStyle 0x0 -+int attr ratingBarStyleIndicator 0x0 -+int attr ratingBarStyleSmall 0x0 -+int attr retryImage 0x0 -+int attr retryImageScaleType 0x0 -+int attr roundAsCircle 0x0 -+int attr roundBottomEnd 0x0 -+int attr roundBottomLeft 0x0 -+int attr roundBottomRight 0x0 -+int attr roundBottomStart 0x0 -+int attr roundTopEnd 0x0 -+int attr roundTopLeft 0x0 -+int attr roundTopRight 0x0 -+int attr roundTopStart 0x0 -+int attr roundWithOverlayColor 0x0 -+int attr roundedCornerRadius 0x0 -+int attr roundingBorderColor 0x0 -+int attr roundingBorderPadding 0x0 -+int attr roundingBorderWidth 0x0 -+int attr searchHintIcon 0x0 -+int attr searchIcon 0x0 -+int attr searchViewStyle 0x0 -+int attr seekBarStyle 0x0 -+int attr selectableItemBackground 0x0 -+int attr selectableItemBackgroundBorderless 0x0 -+int attr shortcutMatchRequired 0x0 -+int attr showAsAction 0x0 -+int attr showDividers 0x0 -+int attr showText 0x0 -+int attr showTitle 0x0 -+int attr singleChoiceItemLayout 0x0 -+int attr spinBars 0x0 -+int attr spinnerDropDownItemStyle 0x0 -+int attr spinnerStyle 0x0 -+int attr splitTrack 0x0 -+int attr srcCompat 0x0 -+int attr state_above_anchor 0x0 -+int attr subMenuArrow 0x0 -+int attr submitBackground 0x0 -+int attr subtitle 0x0 -+int attr subtitleTextAppearance 0x0 -+int attr subtitleTextColor 0x0 -+int attr subtitleTextStyle 0x0 -+int attr suggestionRowLayout 0x0 -+int attr switchMinWidth 0x0 -+int attr switchPadding 0x0 -+int attr switchStyle 0x0 -+int attr switchTextAppearance 0x0 -+int attr textAllCaps 0x0 -+int attr textAppearanceLargePopupMenu 0x0 -+int attr textAppearanceListItem 0x0 -+int attr textAppearanceListItemSecondary 0x0 -+int attr textAppearanceListItemSmall 0x0 -+int attr textAppearancePopupMenuHeader 0x0 -+int attr textAppearanceSearchResultSubtitle 0x0 -+int attr textAppearanceSearchResultTitle 0x0 -+int attr textAppearanceSmallPopupMenu 0x0 -+int attr textColorAlertDialogListItem 0x0 -+int attr textColorSearchUrl 0x0 -+int attr textLocale 0x0 -+int attr theme 0x0 -+int attr thickness 0x0 -+int attr thumbTextPadding 0x0 -+int attr thumbTint 0x0 -+int attr thumbTintMode 0x0 -+int attr tickMark 0x0 -+int attr tickMarkTint 0x0 -+int attr tickMarkTintMode 0x0 -+int attr tint 0x0 -+int attr tintMode 0x0 -+int attr title 0x0 -+int attr titleMargin 0x0 -+int attr titleMarginBottom 0x0 -+int attr titleMarginEnd 0x0 -+int attr titleMarginStart 0x0 -+int attr titleMarginTop 0x0 -+int attr titleMargins 0x0 -+int attr titleTextAppearance 0x0 -+int attr titleTextColor 0x0 -+int attr titleTextStyle 0x0 -+int attr toolbarNavigationButtonStyle 0x0 -+int attr toolbarStyle 0x0 -+int attr tooltipForegroundColor 0x0 -+int attr tooltipFrameBackground 0x0 -+int attr tooltipText 0x0 -+int attr track 0x0 -+int attr trackTint 0x0 -+int attr trackTintMode 0x0 -+int attr ttcIndex 0x0 -+int attr viewAspectRatio 0x0 -+int attr viewInflaterClass 0x0 -+int attr voiceIcon 0x0 -+int attr windowActionBar 0x0 -+int attr windowActionBarOverlay 0x0 -+int attr windowActionModeOverlay 0x0 -+int attr windowFixedHeightMajor 0x0 -+int attr windowFixedHeightMinor 0x0 -+int attr windowFixedWidthMajor 0x0 -+int attr windowFixedWidthMinor 0x0 -+int attr windowMinWidthMajor 0x0 -+int attr windowMinWidthMinor 0x0 -+int attr windowNoTitle 0x0 -+int bool abc_action_bar_embed_tabs 0x0 -+int bool abc_config_actionMenuItemAllCaps 0x0 -+int color abc_background_cache_hint_selector_material_dark 0x0 -+int color abc_background_cache_hint_selector_material_light 0x0 -+int color abc_btn_colored_borderless_text_material 0x0 -+int color abc_btn_colored_text_material 0x0 -+int color abc_color_highlight_material 0x0 -+int color abc_decor_view_status_guard 0x0 -+int color abc_decor_view_status_guard_light 0x0 -+int color abc_hint_foreground_material_dark 0x0 -+int color abc_hint_foreground_material_light 0x0 -+int color abc_primary_text_disable_only_material_dark 0x0 -+int color abc_primary_text_disable_only_material_light 0x0 -+int color abc_primary_text_material_dark 0x0 -+int color abc_primary_text_material_light 0x0 -+int color abc_search_url_text 0x0 -+int color abc_search_url_text_normal 0x0 -+int color abc_search_url_text_pressed 0x0 -+int color abc_search_url_text_selected 0x0 -+int color abc_secondary_text_material_dark 0x0 -+int color abc_secondary_text_material_light 0x0 -+int color abc_tint_btn_checkable 0x0 -+int color abc_tint_default 0x0 -+int color abc_tint_edittext 0x0 -+int color abc_tint_seek_thumb 0x0 -+int color abc_tint_spinner 0x0 -+int color abc_tint_switch_track 0x0 -+int color accent_material_dark 0x0 -+int color accent_material_light 0x0 -+int color androidx_core_ripple_material_light 0x0 -+int color androidx_core_secondary_text_default_material_light 0x0 -+int color background_floating_material_dark 0x0 -+int color background_floating_material_light 0x0 -+int color background_material_dark 0x0 -+int color background_material_light 0x0 -+int color bright_foreground_disabled_material_dark 0x0 -+int color bright_foreground_disabled_material_light 0x0 -+int color bright_foreground_inverse_material_dark 0x0 -+int color bright_foreground_inverse_material_light 0x0 -+int color bright_foreground_material_dark 0x0 -+int color bright_foreground_material_light 0x0 -+int color button_material_dark 0x0 -+int color button_material_light 0x0 -+int color catalyst_logbox_background 0x0 -+int color catalyst_redbox_background 0x0 -+int color dim_foreground_disabled_material_dark 0x0 -+int color dim_foreground_disabled_material_light 0x0 -+int color dim_foreground_material_dark 0x0 -+int color dim_foreground_material_light 0x0 -+int color error_color_material_dark 0x0 -+int color error_color_material_light 0x0 -+int color foreground_material_dark 0x0 -+int color foreground_material_light 0x0 -+int color highlighted_text_material_dark 0x0 -+int color highlighted_text_material_light 0x0 -+int color material_blue_grey_800 0x0 -+int color material_blue_grey_900 0x0 -+int color material_blue_grey_950 0x0 -+int color material_deep_teal_200 0x0 -+int color material_deep_teal_500 0x0 -+int color material_grey_100 0x0 -+int color material_grey_300 0x0 -+int color material_grey_50 0x0 -+int color material_grey_600 0x0 -+int color material_grey_800 0x0 -+int color material_grey_850 0x0 -+int color material_grey_900 0x0 -+int color notification_action_color_filter 0x0 -+int color notification_icon_bg_color 0x0 -+int color primary_dark_material_dark 0x0 -+int color primary_dark_material_light 0x0 -+int color primary_material_dark 0x0 -+int color primary_material_light 0x0 -+int color primary_text_default_material_dark 0x0 -+int color primary_text_default_material_light 0x0 -+int color primary_text_disabled_material_dark 0x0 -+int color primary_text_disabled_material_light 0x0 -+int color ripple_material_dark 0x0 -+int color ripple_material_light 0x0 -+int color secondary_text_default_material_dark 0x0 -+int color secondary_text_default_material_light 0x0 -+int color secondary_text_disabled_material_dark 0x0 -+int color secondary_text_disabled_material_light 0x0 -+int color switch_thumb_disabled_material_dark 0x0 -+int color switch_thumb_disabled_material_light 0x0 -+int color switch_thumb_material_dark 0x0 -+int color switch_thumb_material_light 0x0 -+int color switch_thumb_normal_material_dark 0x0 -+int color switch_thumb_normal_material_light 0x0 -+int color tooltip_background_dark 0x0 -+int color tooltip_background_light 0x0 -+int dimen abc_action_bar_content_inset_material 0x0 -+int dimen abc_action_bar_content_inset_with_nav 0x0 -+int dimen abc_action_bar_default_height_material 0x0 -+int dimen abc_action_bar_default_padding_end_material 0x0 -+int dimen abc_action_bar_default_padding_start_material 0x0 -+int dimen abc_action_bar_elevation_material 0x0 -+int dimen abc_action_bar_icon_vertical_padding_material 0x0 -+int dimen abc_action_bar_overflow_padding_end_material 0x0 -+int dimen abc_action_bar_overflow_padding_start_material 0x0 -+int dimen abc_action_bar_stacked_max_height 0x0 -+int dimen abc_action_bar_stacked_tab_max_width 0x0 -+int dimen abc_action_bar_subtitle_bottom_margin_material 0x0 -+int dimen abc_action_bar_subtitle_top_margin_material 0x0 -+int dimen abc_action_button_min_height_material 0x0 -+int dimen abc_action_button_min_width_material 0x0 -+int dimen abc_action_button_min_width_overflow_material 0x0 -+int dimen abc_alert_dialog_button_bar_height 0x0 -+int dimen abc_alert_dialog_button_dimen 0x0 -+int dimen abc_button_inset_horizontal_material 0x0 -+int dimen abc_button_inset_vertical_material 0x0 -+int dimen abc_button_padding_horizontal_material 0x0 -+int dimen abc_button_padding_vertical_material 0x0 -+int dimen abc_cascading_menus_min_smallest_width 0x0 -+int dimen abc_config_prefDialogWidth 0x0 -+int dimen abc_control_corner_material 0x0 -+int dimen abc_control_inset_material 0x0 -+int dimen abc_control_padding_material 0x0 -+int dimen abc_dialog_corner_radius_material 0x0 -+int dimen abc_dialog_fixed_height_major 0x0 -+int dimen abc_dialog_fixed_height_minor 0x0 -+int dimen abc_dialog_fixed_width_major 0x0 -+int dimen abc_dialog_fixed_width_minor 0x0 -+int dimen abc_dialog_list_padding_bottom_no_buttons 0x0 -+int dimen abc_dialog_list_padding_top_no_title 0x0 -+int dimen abc_dialog_min_width_major 0x0 -+int dimen abc_dialog_min_width_minor 0x0 -+int dimen abc_dialog_padding_material 0x0 -+int dimen abc_dialog_padding_top_material 0x0 -+int dimen abc_dialog_title_divider_material 0x0 -+int dimen abc_disabled_alpha_material_dark 0x0 -+int dimen abc_disabled_alpha_material_light 0x0 -+int dimen abc_dropdownitem_icon_width 0x0 -+int dimen abc_dropdownitem_text_padding_left 0x0 -+int dimen abc_dropdownitem_text_padding_right 0x0 -+int dimen abc_edit_text_inset_bottom_material 0x0 -+int dimen abc_edit_text_inset_horizontal_material 0x0 -+int dimen abc_edit_text_inset_top_material 0x0 -+int dimen abc_floating_window_z 0x0 -+int dimen abc_list_item_height_large_material 0x0 -+int dimen abc_list_item_height_material 0x0 -+int dimen abc_list_item_height_small_material 0x0 -+int dimen abc_list_item_padding_horizontal_material 0x0 -+int dimen abc_panel_menu_list_width 0x0 -+int dimen abc_progress_bar_height_material 0x0 -+int dimen abc_search_view_preferred_height 0x0 -+int dimen abc_search_view_preferred_width 0x0 -+int dimen abc_seekbar_track_background_height_material 0x0 -+int dimen abc_seekbar_track_progress_height_material 0x0 -+int dimen abc_select_dialog_padding_start_material 0x0 -+int dimen abc_star_big 0x0 -+int dimen abc_star_medium 0x0 -+int dimen abc_star_small 0x0 -+int dimen abc_switch_padding 0x0 -+int dimen abc_text_size_body_1_material 0x0 -+int dimen abc_text_size_body_2_material 0x0 -+int dimen abc_text_size_button_material 0x0 -+int dimen abc_text_size_caption_material 0x0 -+int dimen abc_text_size_display_1_material 0x0 -+int dimen abc_text_size_display_2_material 0x0 -+int dimen abc_text_size_display_3_material 0x0 -+int dimen abc_text_size_display_4_material 0x0 -+int dimen abc_text_size_headline_material 0x0 -+int dimen abc_text_size_large_material 0x0 -+int dimen abc_text_size_medium_material 0x0 -+int dimen abc_text_size_menu_header_material 0x0 -+int dimen abc_text_size_menu_material 0x0 -+int dimen abc_text_size_small_material 0x0 -+int dimen abc_text_size_subhead_material 0x0 -+int dimen abc_text_size_subtitle_material_toolbar 0x0 -+int dimen abc_text_size_title_material 0x0 -+int dimen abc_text_size_title_material_toolbar 0x0 -+int dimen autofill_inline_suggestion_icon_size 0x0 -+int dimen compat_button_inset_horizontal_material 0x0 -+int dimen compat_button_inset_vertical_material 0x0 -+int dimen compat_button_padding_horizontal_material 0x0 -+int dimen compat_button_padding_vertical_material 0x0 -+int dimen compat_control_corner_material 0x0 -+int dimen compat_notification_large_icon_max_height 0x0 -+int dimen compat_notification_large_icon_max_width 0x0 -+int dimen disabled_alpha_material_dark 0x0 -+int dimen disabled_alpha_material_light 0x0 -+int dimen highlight_alpha_material_colored 0x0 -+int dimen highlight_alpha_material_dark 0x0 -+int dimen highlight_alpha_material_light 0x0 -+int dimen hint_alpha_material_dark 0x0 -+int dimen hint_alpha_material_light 0x0 -+int dimen hint_pressed_alpha_material_dark 0x0 -+int dimen hint_pressed_alpha_material_light 0x0 -+int dimen notification_action_icon_size 0x0 -+int dimen notification_action_text_size 0x0 -+int dimen notification_big_circle_margin 0x0 -+int dimen notification_content_margin_start 0x0 -+int dimen notification_large_icon_height 0x0 -+int dimen notification_large_icon_width 0x0 -+int dimen notification_main_column_padding_top 0x0 -+int dimen notification_media_narrow_margin 0x0 -+int dimen notification_right_icon_size 0x0 -+int dimen notification_right_side_padding_top 0x0 -+int dimen notification_small_icon_background_padding 0x0 -+int dimen notification_small_icon_size_as_large 0x0 -+int dimen notification_subtext_size 0x0 -+int dimen notification_top_pad 0x0 -+int dimen notification_top_pad_large_text 0x0 -+int dimen tooltip_corner_radius 0x0 -+int dimen tooltip_horizontal_padding 0x0 -+int dimen tooltip_margin 0x0 -+int dimen tooltip_precise_anchor_extra_offset 0x0 -+int dimen tooltip_precise_anchor_threshold 0x0 -+int dimen tooltip_vertical_padding 0x0 -+int dimen tooltip_y_offset_non_touch 0x0 -+int dimen tooltip_y_offset_touch 0x0 -+int drawable abc_ab_share_pack_mtrl_alpha 0x0 -+int drawable abc_action_bar_item_background_material 0x0 -+int drawable abc_btn_borderless_material 0x0 -+int drawable abc_btn_check_material 0x0 -+int drawable abc_btn_check_material_anim 0x0 -+int drawable abc_btn_check_to_on_mtrl_000 0x0 -+int drawable abc_btn_check_to_on_mtrl_015 0x0 -+int drawable abc_btn_colored_material 0x0 -+int drawable abc_btn_default_mtrl_shape 0x0 -+int drawable abc_btn_radio_material 0x0 -+int drawable abc_btn_radio_material_anim 0x0 -+int drawable abc_btn_radio_to_on_mtrl_000 0x0 -+int drawable abc_btn_radio_to_on_mtrl_015 0x0 -+int drawable abc_btn_switch_to_on_mtrl_00001 0x0 -+int drawable abc_btn_switch_to_on_mtrl_00012 0x0 -+int drawable abc_cab_background_internal_bg 0x0 -+int drawable abc_cab_background_top_material 0x0 -+int drawable abc_cab_background_top_mtrl_alpha 0x0 -+int drawable abc_control_background_material 0x0 -+int drawable abc_dialog_material_background 0x0 -+int drawable abc_edit_text_material 0x0 -+int drawable abc_ic_ab_back_material 0x0 -+int drawable abc_ic_arrow_drop_right_black_24dp 0x0 -+int drawable abc_ic_clear_material 0x0 -+int drawable abc_ic_commit_search_api_mtrl_alpha 0x0 -+int drawable abc_ic_go_search_api_material 0x0 -+int drawable abc_ic_menu_copy_mtrl_am_alpha 0x0 -+int drawable abc_ic_menu_cut_mtrl_alpha 0x0 -+int drawable abc_ic_menu_overflow_material 0x0 -+int drawable abc_ic_menu_paste_mtrl_am_alpha 0x0 -+int drawable abc_ic_menu_selectall_mtrl_alpha 0x0 -+int drawable abc_ic_menu_share_mtrl_alpha 0x0 -+int drawable abc_ic_search_api_material 0x0 -+int drawable abc_ic_voice_search_api_material 0x0 -+int drawable abc_item_background_holo_dark 0x0 -+int drawable abc_item_background_holo_light 0x0 -+int drawable abc_list_divider_material 0x0 -+int drawable abc_list_divider_mtrl_alpha 0x0 -+int drawable abc_list_focused_holo 0x0 -+int drawable abc_list_longpressed_holo 0x0 -+int drawable abc_list_pressed_holo_dark 0x0 -+int drawable abc_list_pressed_holo_light 0x0 -+int drawable abc_list_selector_background_transition_holo_dark 0x0 -+int drawable abc_list_selector_background_transition_holo_light 0x0 -+int drawable abc_list_selector_disabled_holo_dark 0x0 -+int drawable abc_list_selector_disabled_holo_light 0x0 -+int drawable abc_list_selector_holo_dark 0x0 -+int drawable abc_list_selector_holo_light 0x0 -+int drawable abc_menu_hardkey_panel_mtrl_mult 0x0 -+int drawable abc_popup_background_mtrl_mult 0x0 -+int drawable abc_ratingbar_indicator_material 0x0 -+int drawable abc_ratingbar_material 0x0 -+int drawable abc_ratingbar_small_material 0x0 -+int drawable abc_scrubber_control_off_mtrl_alpha 0x0 -+int drawable abc_scrubber_control_to_pressed_mtrl_000 0x0 -+int drawable abc_scrubber_control_to_pressed_mtrl_005 0x0 -+int drawable abc_scrubber_primary_mtrl_alpha 0x0 -+int drawable abc_scrubber_track_mtrl_alpha 0x0 -+int drawable abc_seekbar_thumb_material 0x0 -+int drawable abc_seekbar_tick_mark_material 0x0 -+int drawable abc_seekbar_track_material 0x0 -+int drawable abc_spinner_mtrl_am_alpha 0x0 -+int drawable abc_spinner_textfield_background_material 0x0 -+int drawable abc_star_black_48dp 0x0 -+int drawable abc_star_half_black_48dp 0x0 -+int drawable abc_switch_thumb_material 0x0 -+int drawable abc_switch_track_mtrl_alpha 0x0 -+int drawable abc_tab_indicator_material 0x0 -+int drawable abc_tab_indicator_mtrl_alpha 0x0 -+int drawable abc_text_cursor_material 0x0 -+int drawable abc_text_select_handle_left_mtrl 0x0 -+int drawable abc_text_select_handle_middle_mtrl 0x0 -+int drawable abc_text_select_handle_right_mtrl 0x0 -+int drawable abc_textfield_activated_mtrl_alpha 0x0 -+int drawable abc_textfield_default_mtrl_alpha 0x0 -+int drawable abc_textfield_search_activated_mtrl_alpha 0x0 -+int drawable abc_textfield_search_default_mtrl_alpha 0x0 -+int drawable abc_textfield_search_material 0x0 -+int drawable abc_vector_test 0x0 -+int drawable autofill_inline_suggestion_chip_background 0x0 -+int drawable btn_checkbox_checked_mtrl 0x0 -+int drawable btn_checkbox_checked_to_unchecked_mtrl_animation 0x0 -+int drawable btn_checkbox_unchecked_mtrl 0x0 -+int drawable btn_checkbox_unchecked_to_checked_mtrl_animation 0x0 -+int drawable btn_radio_off_mtrl 0x0 -+int drawable btn_radio_off_to_on_mtrl_animation 0x0 -+int drawable btn_radio_on_mtrl 0x0 -+int drawable btn_radio_on_to_off_mtrl_animation 0x0 -+int drawable notification_action_background 0x0 -+int drawable notification_bg 0x0 -+int drawable notification_bg_low 0x0 -+int drawable notification_bg_low_normal 0x0 -+int drawable notification_bg_low_pressed 0x0 -+int drawable notification_bg_normal 0x0 -+int drawable notification_bg_normal_pressed 0x0 -+int drawable notification_icon_background 0x0 -+int drawable notification_template_icon_bg 0x0 -+int drawable notification_template_icon_low_bg 0x0 -+int drawable notification_tile_bg 0x0 -+int drawable notify_panel_notification_icon_bg 0x0 -+int drawable redbox_top_border_background 0x0 -+int drawable test_level_drawable 0x0 -+int drawable tooltip_frame_dark 0x0 -+int drawable tooltip_frame_light 0x0 -+int id accessibility_action_clickable_span 0x0 -+int id accessibility_actions 0x0 -+int id accessibility_collection 0x0 -+int id accessibility_collection_item 0x0 -+int id accessibility_custom_action_0 0x0 -+int id accessibility_custom_action_1 0x0 -+int id accessibility_custom_action_10 0x0 -+int id accessibility_custom_action_11 0x0 -+int id accessibility_custom_action_12 0x0 -+int id accessibility_custom_action_13 0x0 -+int id accessibility_custom_action_14 0x0 -+int id accessibility_custom_action_15 0x0 -+int id accessibility_custom_action_16 0x0 -+int id accessibility_custom_action_17 0x0 -+int id accessibility_custom_action_18 0x0 -+int id accessibility_custom_action_19 0x0 -+int id accessibility_custom_action_2 0x0 -+int id accessibility_custom_action_20 0x0 -+int id accessibility_custom_action_21 0x0 -+int id accessibility_custom_action_22 0x0 -+int id accessibility_custom_action_23 0x0 -+int id accessibility_custom_action_24 0x0 -+int id accessibility_custom_action_25 0x0 -+int id accessibility_custom_action_26 0x0 -+int id accessibility_custom_action_27 0x0 -+int id accessibility_custom_action_28 0x0 -+int id accessibility_custom_action_29 0x0 -+int id accessibility_custom_action_3 0x0 -+int id accessibility_custom_action_30 0x0 -+int id accessibility_custom_action_31 0x0 -+int id accessibility_custom_action_4 0x0 -+int id accessibility_custom_action_5 0x0 -+int id accessibility_custom_action_6 0x0 -+int id accessibility_custom_action_7 0x0 -+int id accessibility_custom_action_8 0x0 -+int id accessibility_custom_action_9 0x0 -+int id accessibility_hint 0x0 -+int id accessibility_label 0x0 -+int id accessibility_links 0x0 -+int id accessibility_role 0x0 -+int id accessibility_state 0x0 -+int id accessibility_value 0x0 -+int id action_bar 0x0 -+int id action_bar_activity_content 0x0 -+int id action_bar_container 0x0 -+int id action_bar_root 0x0 -+int id action_bar_spinner 0x0 -+int id action_bar_subtitle 0x0 -+int id action_bar_title 0x0 -+int id action_container 0x0 -+int id action_context_bar 0x0 -+int id action_divider 0x0 -+int id action_image 0x0 -+int id action_menu_divider 0x0 -+int id action_menu_presenter 0x0 -+int id action_mode_bar 0x0 -+int id action_mode_bar_stub 0x0 -+int id action_mode_close_button 0x0 -+int id action_text 0x0 -+int id actions 0x0 -+int id activity_chooser_view_content 0x0 -+int id add 0x0 -+int id alertTitle 0x0 -+int id async 0x0 -+int id autofill_inline_suggestion_end_icon 0x0 -+int id autofill_inline_suggestion_start_icon 0x0 -+int id autofill_inline_suggestion_subtitle 0x0 -+int id autofill_inline_suggestion_title 0x0 -+int id blocking 0x0 -+int id buttonPanel 0x0 -+int id catalyst_redbox_title 0x0 -+int id center 0x0 -+int id centerCrop 0x0 -+int id centerInside 0x0 -+int id checkbox 0x0 -+int id checked 0x0 -+int id chronometer 0x0 -+int id content 0x0 -+int id contentPanel 0x0 -+int id custom 0x0 -+int id customPanel 0x0 -+int id decor_content_parent 0x0 -+int id default_activity_button 0x0 -+int id dialog_button 0x0 -+int id edit_query 0x0 -+int id expand_activities_button 0x0 -+int id expanded_menu 0x0 -+int id fitBottomStart 0x0 -+int id fitCenter 0x0 -+int id fitEnd 0x0 -+int id fitStart 0x0 -+int id fitXY 0x0 -+int id focusCrop 0x0 -+int id forever 0x0 -+int id fps_text 0x0 -+int id fragment_container_view_tag 0x0 -+int id group_divider 0x0 -+int id home 0x0 -+int id icon 0x0 -+int id icon_group 0x0 -+int id image 0x0 -+int id info 0x0 -+int id italic 0x0 -+int id item1 0x0 -+int id item2 0x0 -+int id item3 0x0 -+int id item4 0x0 -+int id labelled_by 0x0 -+int id line1 0x0 -+int id line3 0x0 -+int id listMode 0x0 -+int id list_item 0x0 -+int id message 0x0 -+int id multiply 0x0 -+int id none 0x0 -+int id normal 0x0 -+int id notification_background 0x0 -+int id notification_main_column 0x0 -+int id notification_main_column_container 0x0 -+int id off 0x0 -+int id on 0x0 -+int id parentPanel 0x0 -+int id pointer_events 0x0 -+int id progress_circular 0x0 -+int id progress_horizontal 0x0 -+int id radio 0x0 -+int id react_test_id 0x0 -+int id right_icon 0x0 -+int id right_side 0x0 -+int id rn_frame_file 0x0 -+int id rn_frame_method 0x0 -+int id rn_redbox_dismiss_button 0x0 -+int id rn_redbox_line_separator 0x0 -+int id rn_redbox_loading_indicator 0x0 -+int id rn_redbox_reload_button 0x0 -+int id rn_redbox_report_button 0x0 -+int id rn_redbox_report_label 0x0 -+int id rn_redbox_stack 0x0 -+int id screen 0x0 -+int id scrollIndicatorDown 0x0 -+int id scrollIndicatorUp 0x0 -+int id scrollView 0x0 -+int id search_badge 0x0 -+int id search_bar 0x0 -+int id search_button 0x0 -+int id search_close_btn 0x0 -+int id search_edit_frame 0x0 -+int id search_go_btn 0x0 -+int id search_mag_icon 0x0 -+int id search_plate 0x0 -+int id search_src_text 0x0 -+int id search_voice_btn 0x0 -+int id select_dialog_listview 0x0 -+int id shortcut 0x0 -+int id spacer 0x0 -+int id special_effects_controller_view_tag 0x0 -+int id split_action_bar 0x0 -+int id src_atop 0x0 -+int id src_in 0x0 -+int id src_over 0x0 -+int id submenuarrow 0x0 -+int id submit_area 0x0 -+int id tabMode 0x0 -+int id tag_accessibility_actions 0x0 -+int id tag_accessibility_clickable_spans 0x0 -+int id tag_accessibility_heading 0x0 -+int id tag_accessibility_pane_title 0x0 -+int id tag_on_apply_window_listener 0x0 -+int id tag_on_receive_content_listener 0x0 -+int id tag_on_receive_content_mime_types 0x0 -+int id tag_screen_reader_focusable 0x0 -+int id tag_state_description 0x0 -+int id tag_transition_group 0x0 -+int id tag_unhandled_key_event_manager 0x0 -+int id tag_unhandled_key_listeners 0x0 -+int id tag_window_insets_animation_callback 0x0 -+int id text 0x0 -+int id text2 0x0 -+int id textSpacerNoButtons 0x0 -+int id textSpacerNoTitle 0x0 -+int id time 0x0 -+int id title 0x0 -+int id titleDividerNoCustom 0x0 -+int id title_template 0x0 -+int id topPanel 0x0 -+int id unchecked 0x0 -+int id uniform 0x0 -+int id up 0x0 -+int id view_tag_instance_handle 0x0 -+int id view_tag_native_id 0x0 -+int id view_tree_lifecycle_owner 0x0 -+int id view_tree_saved_state_registry_owner 0x0 -+int id view_tree_view_model_store_owner 0x0 -+int id visible_removing_fragment_view_tag 0x0 -+int id wrap_content 0x0 -+int integer abc_config_activityDefaultDur 0x0 -+int integer abc_config_activityShortDur 0x0 -+int integer cancel_button_image_alpha 0x0 -+int integer config_tooltipAnimTime 0x0 -+int integer react_native_dev_server_port 0x0 -+int integer react_native_inspector_proxy_port 0x0 -+int integer status_bar_notification_info_maxnum 0x0 -+int interpolator btn_checkbox_checked_mtrl_animation_interpolator_0 0x0 -+int interpolator btn_checkbox_checked_mtrl_animation_interpolator_1 0x0 -+int interpolator btn_checkbox_unchecked_mtrl_animation_interpolator_0 0x0 -+int interpolator btn_checkbox_unchecked_mtrl_animation_interpolator_1 0x0 -+int interpolator btn_radio_to_off_mtrl_animation_interpolator_0 0x0 -+int interpolator btn_radio_to_on_mtrl_animation_interpolator_0 0x0 -+int interpolator fast_out_slow_in 0x0 -+int layout abc_action_bar_title_item 0x0 -+int layout abc_action_bar_up_container 0x0 -+int layout abc_action_menu_item_layout 0x0 -+int layout abc_action_menu_layout 0x0 -+int layout abc_action_mode_bar 0x0 -+int layout abc_action_mode_close_item_material 0x0 -+int layout abc_activity_chooser_view 0x0 -+int layout abc_activity_chooser_view_list_item 0x0 -+int layout abc_alert_dialog_button_bar_material 0x0 -+int layout abc_alert_dialog_material 0x0 -+int layout abc_alert_dialog_title_material 0x0 -+int layout abc_cascading_menu_item_layout 0x0 -+int layout abc_dialog_title_material 0x0 -+int layout abc_expanded_menu_layout 0x0 -+int layout abc_list_menu_item_checkbox 0x0 -+int layout abc_list_menu_item_icon 0x0 -+int layout abc_list_menu_item_layout 0x0 -+int layout abc_list_menu_item_radio 0x0 -+int layout abc_popup_menu_header_item_layout 0x0 -+int layout abc_popup_menu_item_layout 0x0 -+int layout abc_screen_content_include 0x0 -+int layout abc_screen_simple 0x0 -+int layout abc_screen_simple_overlay_action_mode 0x0 -+int layout abc_screen_toolbar 0x0 -+int layout abc_search_dropdown_item_icons_2line 0x0 -+int layout abc_search_view 0x0 -+int layout abc_select_dialog_material 0x0 -+int layout abc_tooltip 0x0 -+int layout autofill_inline_suggestion 0x0 -+int layout custom_dialog 0x0 -+int layout dev_loading_view 0x0 -+int layout fps_view 0x0 -+int layout notification_action 0x0 -+int layout notification_action_tombstone 0x0 -+int layout notification_template_custom_big 0x0 -+int layout notification_template_icon_group 0x0 -+int layout notification_template_part_chronometer 0x0 -+int layout notification_template_part_time 0x0 -+int layout redbox_item_frame 0x0 -+int layout redbox_item_title 0x0 -+int layout redbox_view 0x0 -+int layout select_dialog_item_material 0x0 -+int layout select_dialog_multichoice_material 0x0 -+int layout select_dialog_singlechoice_material 0x0 -+int layout support_simple_spinner_dropdown_item 0x0 -+int menu example_menu 0x0 -+int menu example_menu2 0x0 -+int string abc_action_bar_home_description 0x0 -+int string abc_action_bar_up_description 0x0 -+int string abc_action_menu_overflow_description 0x0 -+int string abc_action_mode_done 0x0 -+int string abc_activity_chooser_view_see_all 0x0 -+int string abc_activitychooserview_choose_application 0x0 -+int string abc_capital_off 0x0 -+int string abc_capital_on 0x0 -+int string abc_menu_alt_shortcut_label 0x0 -+int string abc_menu_ctrl_shortcut_label 0x0 -+int string abc_menu_delete_shortcut_label 0x0 -+int string abc_menu_enter_shortcut_label 0x0 -+int string abc_menu_function_shortcut_label 0x0 -+int string abc_menu_meta_shortcut_label 0x0 -+int string abc_menu_shift_shortcut_label 0x0 -+int string abc_menu_space_shortcut_label 0x0 -+int string abc_menu_sym_shortcut_label 0x0 -+int string abc_prepend_shortcut_label 0x0 -+int string abc_search_hint 0x0 -+int string abc_searchview_description_clear 0x0 -+int string abc_searchview_description_query 0x0 -+int string abc_searchview_description_search 0x0 -+int string abc_searchview_description_submit 0x0 -+int string abc_searchview_description_voice 0x0 -+int string abc_shareactionprovider_share_with 0x0 -+int string abc_shareactionprovider_share_with_application 0x0 -+int string abc_toolbar_collapse_description 0x0 -+int string alert_description 0x0 -+int string catalyst_change_bundle_location 0x0 -+int string catalyst_copy_button 0x0 -+int string catalyst_debug 0x0 -+int string catalyst_debug_chrome 0x0 -+int string catalyst_debug_chrome_stop 0x0 -+int string catalyst_debug_connecting 0x0 -+int string catalyst_debug_error 0x0 -+int string catalyst_debug_open 0x0 -+int string catalyst_debug_stop 0x0 -+int string catalyst_devtools_open 0x0 -+int string catalyst_dismiss_button 0x0 -+int string catalyst_heap_capture 0x0 -+int string catalyst_hot_reloading 0x0 -+int string catalyst_hot_reloading_auto_disable 0x0 -+int string catalyst_hot_reloading_auto_enable 0x0 -+int string catalyst_hot_reloading_stop 0x0 -+int string catalyst_inspector 0x0 -+int string catalyst_inspector_stop 0x0 -+int string catalyst_loading_from_url 0x0 -+int string catalyst_open_flipper_error 0x0 -+int string catalyst_perf_monitor 0x0 -+int string catalyst_perf_monitor_stop 0x0 -+int string catalyst_reload 0x0 -+int string catalyst_reload_button 0x0 -+int string catalyst_reload_error 0x0 -+int string catalyst_report_button 0x0 -+int string catalyst_sample_profiler_disable 0x0 -+int string catalyst_sample_profiler_enable 0x0 -+int string catalyst_settings 0x0 -+int string catalyst_settings_title 0x0 -+int string combobox_description 0x0 -+int string header_description 0x0 -+int string image_description 0x0 -+int string imagebutton_description 0x0 -+int string link_description 0x0 -+int string menu_description 0x0 -+int string menubar_description 0x0 -+int string menuitem_description 0x0 -+int string progressbar_description 0x0 -+int string radiogroup_description 0x0 -+int string rn_tab_description 0x0 -+int string scrollbar_description 0x0 -+int string search_menu_title 0x0 -+int string spinbutton_description 0x0 -+int string state_busy_description 0x0 -+int string state_collapsed_description 0x0 -+int string state_expanded_description 0x0 -+int string state_mixed_description 0x0 -+int string state_off_description 0x0 -+int string state_on_description 0x0 -+int string state_unselected_description 0x0 -+int string status_bar_notification_info_overflow 0x0 -+int string summary_description 0x0 -+int string tablist_description 0x0 -+int string timer_description 0x0 -+int string toolbar_description 0x0 -+int style AlertDialog_AppCompat 0x0 -+int style AlertDialog_AppCompat_Light 0x0 -+int style Animation_AppCompat_Dialog 0x0 -+int style Animation_AppCompat_DropDownUp 0x0 -+int style Animation_AppCompat_Tooltip 0x0 -+int style Animation_Catalyst_LogBox 0x0 -+int style Animation_Catalyst_RedBox 0x0 -+int style Base_AlertDialog_AppCompat 0x0 -+int style Base_AlertDialog_AppCompat_Light 0x0 -+int style Base_Animation_AppCompat_Dialog 0x0 -+int style Base_Animation_AppCompat_DropDownUp 0x0 -+int style Base_Animation_AppCompat_Tooltip 0x0 -+int style Base_DialogWindowTitleBackground_AppCompat 0x0 -+int style Base_DialogWindowTitle_AppCompat 0x0 -+int style Base_TextAppearance_AppCompat 0x0 -+int style Base_TextAppearance_AppCompat_Body1 0x0 -+int style Base_TextAppearance_AppCompat_Body2 0x0 -+int style Base_TextAppearance_AppCompat_Button 0x0 -+int style Base_TextAppearance_AppCompat_Caption 0x0 -+int style Base_TextAppearance_AppCompat_Display1 0x0 -+int style Base_TextAppearance_AppCompat_Display2 0x0 -+int style Base_TextAppearance_AppCompat_Display3 0x0 -+int style Base_TextAppearance_AppCompat_Display4 0x0 -+int style Base_TextAppearance_AppCompat_Headline 0x0 -+int style Base_TextAppearance_AppCompat_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Large 0x0 -+int style Base_TextAppearance_AppCompat_Large_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large 0x0 -+int style Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small 0x0 -+int style Base_TextAppearance_AppCompat_Medium 0x0 -+int style Base_TextAppearance_AppCompat_Medium_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Menu 0x0 -+int style Base_TextAppearance_AppCompat_SearchResult 0x0 -+int style Base_TextAppearance_AppCompat_SearchResult_Subtitle 0x0 -+int style Base_TextAppearance_AppCompat_SearchResult_Title 0x0 -+int style Base_TextAppearance_AppCompat_Small 0x0 -+int style Base_TextAppearance_AppCompat_Small_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Subhead 0x0 -+int style Base_TextAppearance_AppCompat_Subhead_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Title 0x0 -+int style Base_TextAppearance_AppCompat_Title_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Tooltip 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionBar_Menu 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionBar_Title 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle 0x0 -+int style Base_TextAppearance_AppCompat_Widget_ActionMode_Title 0x0 -+int style Base_TextAppearance_AppCompat_Widget_Button 0x0 -+int style Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored 0x0 -+int style Base_TextAppearance_AppCompat_Widget_Button_Colored 0x0 -+int style Base_TextAppearance_AppCompat_Widget_Button_Inverse 0x0 -+int style Base_TextAppearance_AppCompat_Widget_DropDownItem 0x0 -+int style Base_TextAppearance_AppCompat_Widget_PopupMenu_Header 0x0 -+int style Base_TextAppearance_AppCompat_Widget_PopupMenu_Large 0x0 -+int style Base_TextAppearance_AppCompat_Widget_PopupMenu_Small 0x0 -+int style Base_TextAppearance_AppCompat_Widget_Switch 0x0 -+int style Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem 0x0 -+int style Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item 0x0 -+int style Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle 0x0 -+int style Base_TextAppearance_Widget_AppCompat_Toolbar_Title 0x0 -+int style Base_ThemeOverlay_AppCompat 0x0 -+int style Base_ThemeOverlay_AppCompat_ActionBar 0x0 -+int style Base_ThemeOverlay_AppCompat_Dark 0x0 -+int style Base_ThemeOverlay_AppCompat_Dark_ActionBar 0x0 -+int style Base_ThemeOverlay_AppCompat_Dialog 0x0 -+int style Base_ThemeOverlay_AppCompat_Dialog_Alert 0x0 -+int style Base_ThemeOverlay_AppCompat_Light 0x0 -+int style Base_Theme_AppCompat 0x0 -+int style Base_Theme_AppCompat_CompactMenu 0x0 -+int style Base_Theme_AppCompat_Dialog 0x0 -+int style Base_Theme_AppCompat_DialogWhenLarge 0x0 -+int style Base_Theme_AppCompat_Dialog_Alert 0x0 -+int style Base_Theme_AppCompat_Dialog_FixedSize 0x0 -+int style Base_Theme_AppCompat_Dialog_MinWidth 0x0 -+int style Base_Theme_AppCompat_Light 0x0 -+int style Base_Theme_AppCompat_Light_DarkActionBar 0x0 -+int style Base_Theme_AppCompat_Light_Dialog 0x0 -+int style Base_Theme_AppCompat_Light_DialogWhenLarge 0x0 -+int style Base_Theme_AppCompat_Light_Dialog_Alert 0x0 -+int style Base_Theme_AppCompat_Light_Dialog_FixedSize 0x0 -+int style Base_Theme_AppCompat_Light_Dialog_MinWidth 0x0 -+int style Base_V21_ThemeOverlay_AppCompat_Dialog 0x0 -+int style Base_V21_Theme_AppCompat 0x0 -+int style Base_V21_Theme_AppCompat_Dialog 0x0 -+int style Base_V21_Theme_AppCompat_Light 0x0 -+int style Base_V21_Theme_AppCompat_Light_Dialog 0x0 -+int style Base_V22_Theme_AppCompat 0x0 -+int style Base_V22_Theme_AppCompat_Light 0x0 -+int style Base_V23_Theme_AppCompat 0x0 -+int style Base_V23_Theme_AppCompat_Light 0x0 -+int style Base_V26_Theme_AppCompat 0x0 -+int style Base_V26_Theme_AppCompat_Light 0x0 -+int style Base_V26_Widget_AppCompat_Toolbar 0x0 -+int style Base_V28_Theme_AppCompat 0x0 -+int style Base_V28_Theme_AppCompat_Light 0x0 -+int style Base_V7_ThemeOverlay_AppCompat_Dialog 0x0 -+int style Base_V7_Theme_AppCompat 0x0 -+int style Base_V7_Theme_AppCompat_Dialog 0x0 -+int style Base_V7_Theme_AppCompat_Light 0x0 -+int style Base_V7_Theme_AppCompat_Light_Dialog 0x0 -+int style Base_V7_Widget_AppCompat_AutoCompleteTextView 0x0 -+int style Base_V7_Widget_AppCompat_EditText 0x0 -+int style Base_V7_Widget_AppCompat_Toolbar 0x0 -+int style Base_Widget_AppCompat_ActionBar 0x0 -+int style Base_Widget_AppCompat_ActionBar_Solid 0x0 -+int style Base_Widget_AppCompat_ActionBar_TabBar 0x0 -+int style Base_Widget_AppCompat_ActionBar_TabText 0x0 -+int style Base_Widget_AppCompat_ActionBar_TabView 0x0 -+int style Base_Widget_AppCompat_ActionButton 0x0 -+int style Base_Widget_AppCompat_ActionButton_CloseMode 0x0 -+int style Base_Widget_AppCompat_ActionButton_Overflow 0x0 -+int style Base_Widget_AppCompat_ActionMode 0x0 -+int style Base_Widget_AppCompat_ActivityChooserView 0x0 -+int style Base_Widget_AppCompat_AutoCompleteTextView 0x0 -+int style Base_Widget_AppCompat_Button 0x0 -+int style Base_Widget_AppCompat_ButtonBar 0x0 -+int style Base_Widget_AppCompat_ButtonBar_AlertDialog 0x0 -+int style Base_Widget_AppCompat_Button_Borderless 0x0 -+int style Base_Widget_AppCompat_Button_Borderless_Colored 0x0 -+int style Base_Widget_AppCompat_Button_ButtonBar_AlertDialog 0x0 -+int style Base_Widget_AppCompat_Button_Colored 0x0 -+int style Base_Widget_AppCompat_Button_Small 0x0 -+int style Base_Widget_AppCompat_CompoundButton_CheckBox 0x0 -+int style Base_Widget_AppCompat_CompoundButton_RadioButton 0x0 -+int style Base_Widget_AppCompat_CompoundButton_Switch 0x0 -+int style Base_Widget_AppCompat_DrawerArrowToggle 0x0 -+int style Base_Widget_AppCompat_DrawerArrowToggle_Common 0x0 -+int style Base_Widget_AppCompat_DropDownItem_Spinner 0x0 -+int style Base_Widget_AppCompat_EditText 0x0 -+int style Base_Widget_AppCompat_ImageButton 0x0 -+int style Base_Widget_AppCompat_Light_ActionBar 0x0 -+int style Base_Widget_AppCompat_Light_ActionBar_Solid 0x0 -+int style Base_Widget_AppCompat_Light_ActionBar_TabBar 0x0 -+int style Base_Widget_AppCompat_Light_ActionBar_TabText 0x0 -+int style Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse 0x0 -+int style Base_Widget_AppCompat_Light_ActionBar_TabView 0x0 -+int style Base_Widget_AppCompat_Light_PopupMenu 0x0 -+int style Base_Widget_AppCompat_Light_PopupMenu_Overflow 0x0 -+int style Base_Widget_AppCompat_ListMenuView 0x0 -+int style Base_Widget_AppCompat_ListPopupWindow 0x0 -+int style Base_Widget_AppCompat_ListView 0x0 -+int style Base_Widget_AppCompat_ListView_DropDown 0x0 -+int style Base_Widget_AppCompat_ListView_Menu 0x0 -+int style Base_Widget_AppCompat_PopupMenu 0x0 -+int style Base_Widget_AppCompat_PopupMenu_Overflow 0x0 -+int style Base_Widget_AppCompat_PopupWindow 0x0 -+int style Base_Widget_AppCompat_ProgressBar 0x0 -+int style Base_Widget_AppCompat_ProgressBar_Horizontal 0x0 -+int style Base_Widget_AppCompat_RatingBar 0x0 -+int style Base_Widget_AppCompat_RatingBar_Indicator 0x0 -+int style Base_Widget_AppCompat_RatingBar_Small 0x0 -+int style Base_Widget_AppCompat_SearchView 0x0 -+int style Base_Widget_AppCompat_SearchView_ActionBar 0x0 -+int style Base_Widget_AppCompat_SeekBar 0x0 -+int style Base_Widget_AppCompat_SeekBar_Discrete 0x0 -+int style Base_Widget_AppCompat_Spinner 0x0 -+int style Base_Widget_AppCompat_Spinner_Underlined 0x0 -+int style Base_Widget_AppCompat_TextView 0x0 -+int style Base_Widget_AppCompat_TextView_SpinnerItem 0x0 -+int style Base_Widget_AppCompat_Toolbar 0x0 -+int style Base_Widget_AppCompat_Toolbar_Button_Navigation 0x0 -+int style CalendarDatePickerDialog 0x0 -+int style CalendarDatePickerStyle 0x0 -+int style DialogAnimationFade 0x0 -+int style DialogAnimationSlide 0x0 -+int style Platform_AppCompat 0x0 -+int style Platform_AppCompat_Light 0x0 -+int style Platform_ThemeOverlay_AppCompat 0x0 -+int style Platform_ThemeOverlay_AppCompat_Dark 0x0 -+int style Platform_ThemeOverlay_AppCompat_Light 0x0 -+int style Platform_V21_AppCompat 0x0 -+int style Platform_V21_AppCompat_Light 0x0 -+int style Platform_V25_AppCompat 0x0 -+int style Platform_V25_AppCompat_Light 0x0 -+int style Platform_Widget_AppCompat_Spinner 0x0 -+int style RtlOverlay_DialogWindowTitle_AppCompat 0x0 -+int style RtlOverlay_Widget_AppCompat_ActionBar_TitleItem 0x0 -+int style RtlOverlay_Widget_AppCompat_DialogTitle_Icon 0x0 -+int style RtlOverlay_Widget_AppCompat_PopupMenuItem 0x0 -+int style RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup 0x0 -+int style RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut 0x0 -+int style RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow 0x0 -+int style RtlOverlay_Widget_AppCompat_PopupMenuItem_Text 0x0 -+int style RtlOverlay_Widget_AppCompat_PopupMenuItem_Title 0x0 -+int style RtlOverlay_Widget_AppCompat_SearchView_MagIcon 0x0 -+int style RtlOverlay_Widget_AppCompat_Search_DropDown 0x0 -+int style RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1 0x0 -+int style RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2 0x0 -+int style RtlOverlay_Widget_AppCompat_Search_DropDown_Query 0x0 -+int style RtlOverlay_Widget_AppCompat_Search_DropDown_Text 0x0 -+int style RtlUnderlay_Widget_AppCompat_ActionButton 0x0 -+int style RtlUnderlay_Widget_AppCompat_ActionButton_Overflow 0x0 -+int style SpinnerDatePickerDialog 0x0 -+int style SpinnerDatePickerStyle 0x0 -+int style TextAppearance_AppCompat 0x0 -+int style TextAppearance_AppCompat_Body1 0x0 -+int style TextAppearance_AppCompat_Body2 0x0 -+int style TextAppearance_AppCompat_Button 0x0 -+int style TextAppearance_AppCompat_Caption 0x0 -+int style TextAppearance_AppCompat_Display1 0x0 -+int style TextAppearance_AppCompat_Display2 0x0 -+int style TextAppearance_AppCompat_Display3 0x0 -+int style TextAppearance_AppCompat_Display4 0x0 -+int style TextAppearance_AppCompat_Headline 0x0 -+int style TextAppearance_AppCompat_Inverse 0x0 -+int style TextAppearance_AppCompat_Large 0x0 -+int style TextAppearance_AppCompat_Large_Inverse 0x0 -+int style TextAppearance_AppCompat_Light_SearchResult_Subtitle 0x0 -+int style TextAppearance_AppCompat_Light_SearchResult_Title 0x0 -+int style TextAppearance_AppCompat_Light_Widget_PopupMenu_Large 0x0 -+int style TextAppearance_AppCompat_Light_Widget_PopupMenu_Small 0x0 -+int style TextAppearance_AppCompat_Medium 0x0 -+int style TextAppearance_AppCompat_Medium_Inverse 0x0 -+int style TextAppearance_AppCompat_Menu 0x0 -+int style TextAppearance_AppCompat_SearchResult_Subtitle 0x0 -+int style TextAppearance_AppCompat_SearchResult_Title 0x0 -+int style TextAppearance_AppCompat_Small 0x0 -+int style TextAppearance_AppCompat_Small_Inverse 0x0 -+int style TextAppearance_AppCompat_Subhead 0x0 -+int style TextAppearance_AppCompat_Subhead_Inverse 0x0 -+int style TextAppearance_AppCompat_Title 0x0 -+int style TextAppearance_AppCompat_Title_Inverse 0x0 -+int style TextAppearance_AppCompat_Tooltip 0x0 -+int style TextAppearance_AppCompat_Widget_ActionBar_Menu 0x0 -+int style TextAppearance_AppCompat_Widget_ActionBar_Subtitle 0x0 -+int style TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse 0x0 -+int style TextAppearance_AppCompat_Widget_ActionBar_Title 0x0 -+int style TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse 0x0 -+int style TextAppearance_AppCompat_Widget_ActionMode_Subtitle 0x0 -+int style TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse 0x0 -+int style TextAppearance_AppCompat_Widget_ActionMode_Title 0x0 -+int style TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse 0x0 -+int style TextAppearance_AppCompat_Widget_Button 0x0 -+int style TextAppearance_AppCompat_Widget_Button_Borderless_Colored 0x0 -+int style TextAppearance_AppCompat_Widget_Button_Colored 0x0 -+int style TextAppearance_AppCompat_Widget_Button_Inverse 0x0 -+int style TextAppearance_AppCompat_Widget_DropDownItem 0x0 -+int style TextAppearance_AppCompat_Widget_PopupMenu_Header 0x0 -+int style TextAppearance_AppCompat_Widget_PopupMenu_Large 0x0 -+int style TextAppearance_AppCompat_Widget_PopupMenu_Small 0x0 -+int style TextAppearance_AppCompat_Widget_Switch 0x0 -+int style TextAppearance_AppCompat_Widget_TextView_SpinnerItem 0x0 -+int style TextAppearance_Compat_Notification 0x0 -+int style TextAppearance_Compat_Notification_Info 0x0 -+int style TextAppearance_Compat_Notification_Line2 0x0 -+int style TextAppearance_Compat_Notification_Time 0x0 -+int style TextAppearance_Compat_Notification_Title 0x0 -+int style TextAppearance_Widget_AppCompat_ExpandedMenu_Item 0x0 -+int style TextAppearance_Widget_AppCompat_Toolbar_Subtitle 0x0 -+int style TextAppearance_Widget_AppCompat_Toolbar_Title 0x0 -+int style Theme 0x0 -+int style ThemeOverlay_AppCompat 0x0 -+int style ThemeOverlay_AppCompat_ActionBar 0x0 -+int style ThemeOverlay_AppCompat_Dark 0x0 -+int style ThemeOverlay_AppCompat_Dark_ActionBar 0x0 -+int style ThemeOverlay_AppCompat_DayNight 0x0 -+int style ThemeOverlay_AppCompat_DayNight_ActionBar 0x0 -+int style ThemeOverlay_AppCompat_Dialog 0x0 -+int style ThemeOverlay_AppCompat_Dialog_Alert 0x0 -+int style ThemeOverlay_AppCompat_Light 0x0 -+int style Theme_AppCompat 0x0 -+int style Theme_AppCompat_CompactMenu 0x0 -+int style Theme_AppCompat_DayNight 0x0 -+int style Theme_AppCompat_DayNight_DarkActionBar 0x0 -+int style Theme_AppCompat_DayNight_Dialog 0x0 -+int style Theme_AppCompat_DayNight_DialogWhenLarge 0x0 -+int style Theme_AppCompat_DayNight_Dialog_Alert 0x0 -+int style Theme_AppCompat_DayNight_Dialog_MinWidth 0x0 -+int style Theme_AppCompat_DayNight_NoActionBar 0x0 -+int style Theme_AppCompat_Dialog 0x0 -+int style Theme_AppCompat_DialogWhenLarge 0x0 -+int style Theme_AppCompat_Dialog_Alert 0x0 -+int style Theme_AppCompat_Dialog_MinWidth 0x0 -+int style Theme_AppCompat_Empty 0x0 -+int style Theme_AppCompat_Light 0x0 -+int style Theme_AppCompat_Light_DarkActionBar 0x0 -+int style Theme_AppCompat_Light_Dialog 0x0 -+int style Theme_AppCompat_Light_DialogWhenLarge 0x0 -+int style Theme_AppCompat_Light_Dialog_Alert 0x0 -+int style Theme_AppCompat_Light_Dialog_MinWidth 0x0 -+int style Theme_AppCompat_Light_NoActionBar 0x0 -+int style Theme_AppCompat_NoActionBar 0x0 -+int style Theme_AutofillInlineSuggestion 0x0 -+int style Theme_Catalyst 0x0 -+int style Theme_Catalyst_LogBox 0x0 -+int style Theme_Catalyst_RedBox 0x0 -+int style Theme_FullScreenDialog 0x0 -+int style Theme_FullScreenDialogAnimatedFade 0x0 -+int style Theme_FullScreenDialogAnimatedSlide 0x0 -+int style Theme_ReactNative_AppCompat_Light 0x0 -+int style Theme_ReactNative_AppCompat_Light_NoActionBar_FullScreen 0x0 -+int style Widget_AppCompat_ActionBar 0x0 -+int style Widget_AppCompat_ActionBar_Solid 0x0 -+int style Widget_AppCompat_ActionBar_TabBar 0x0 -+int style Widget_AppCompat_ActionBar_TabText 0x0 -+int style Widget_AppCompat_ActionBar_TabView 0x0 -+int style Widget_AppCompat_ActionButton 0x0 -+int style Widget_AppCompat_ActionButton_CloseMode 0x0 -+int style Widget_AppCompat_ActionButton_Overflow 0x0 -+int style Widget_AppCompat_ActionMode 0x0 -+int style Widget_AppCompat_ActivityChooserView 0x0 -+int style Widget_AppCompat_AutoCompleteTextView 0x0 -+int style Widget_AppCompat_Button 0x0 -+int style Widget_AppCompat_ButtonBar 0x0 -+int style Widget_AppCompat_ButtonBar_AlertDialog 0x0 -+int style Widget_AppCompat_Button_Borderless 0x0 -+int style Widget_AppCompat_Button_Borderless_Colored 0x0 -+int style Widget_AppCompat_Button_ButtonBar_AlertDialog 0x0 -+int style Widget_AppCompat_Button_Colored 0x0 -+int style Widget_AppCompat_Button_Small 0x0 -+int style Widget_AppCompat_CompoundButton_CheckBox 0x0 -+int style Widget_AppCompat_CompoundButton_RadioButton 0x0 -+int style Widget_AppCompat_CompoundButton_Switch 0x0 -+int style Widget_AppCompat_DrawerArrowToggle 0x0 -+int style Widget_AppCompat_DropDownItem_Spinner 0x0 -+int style Widget_AppCompat_EditText 0x0 -+int style Widget_AppCompat_ImageButton 0x0 -+int style Widget_AppCompat_Light_ActionBar 0x0 -+int style Widget_AppCompat_Light_ActionBar_Solid 0x0 -+int style Widget_AppCompat_Light_ActionBar_Solid_Inverse 0x0 -+int style Widget_AppCompat_Light_ActionBar_TabBar 0x0 -+int style Widget_AppCompat_Light_ActionBar_TabBar_Inverse 0x0 -+int style Widget_AppCompat_Light_ActionBar_TabText 0x0 -+int style Widget_AppCompat_Light_ActionBar_TabText_Inverse 0x0 -+int style Widget_AppCompat_Light_ActionBar_TabView 0x0 -+int style Widget_AppCompat_Light_ActionBar_TabView_Inverse 0x0 -+int style Widget_AppCompat_Light_ActionButton 0x0 -+int style Widget_AppCompat_Light_ActionButton_CloseMode 0x0 -+int style Widget_AppCompat_Light_ActionButton_Overflow 0x0 -+int style Widget_AppCompat_Light_ActionMode_Inverse 0x0 -+int style Widget_AppCompat_Light_ActivityChooserView 0x0 -+int style Widget_AppCompat_Light_AutoCompleteTextView 0x0 -+int style Widget_AppCompat_Light_DropDownItem_Spinner 0x0 -+int style Widget_AppCompat_Light_ListPopupWindow 0x0 -+int style Widget_AppCompat_Light_ListView_DropDown 0x0 -+int style Widget_AppCompat_Light_PopupMenu 0x0 -+int style Widget_AppCompat_Light_PopupMenu_Overflow 0x0 -+int style Widget_AppCompat_Light_SearchView 0x0 -+int style Widget_AppCompat_Light_Spinner_DropDown_ActionBar 0x0 -+int style Widget_AppCompat_ListMenuView 0x0 -+int style Widget_AppCompat_ListPopupWindow 0x0 -+int style Widget_AppCompat_ListView 0x0 -+int style Widget_AppCompat_ListView_DropDown 0x0 -+int style Widget_AppCompat_ListView_Menu 0x0 -+int style Widget_AppCompat_PopupMenu 0x0 -+int style Widget_AppCompat_PopupMenu_Overflow 0x0 -+int style Widget_AppCompat_PopupWindow 0x0 -+int style Widget_AppCompat_ProgressBar 0x0 -+int style Widget_AppCompat_ProgressBar_Horizontal 0x0 -+int style Widget_AppCompat_RatingBar 0x0 -+int style Widget_AppCompat_RatingBar_Indicator 0x0 -+int style Widget_AppCompat_RatingBar_Small 0x0 -+int style Widget_AppCompat_SearchView 0x0 -+int style Widget_AppCompat_SearchView_ActionBar 0x0 -+int style Widget_AppCompat_SeekBar 0x0 -+int style Widget_AppCompat_SeekBar_Discrete 0x0 -+int style Widget_AppCompat_Spinner 0x0 -+int style Widget_AppCompat_Spinner_DropDown 0x0 -+int style Widget_AppCompat_Spinner_DropDown_ActionBar 0x0 -+int style Widget_AppCompat_Spinner_Underlined 0x0 -+int style Widget_AppCompat_TextView 0x0 -+int style Widget_AppCompat_TextView_SpinnerItem 0x0 -+int style Widget_AppCompat_Toolbar 0x0 -+int style Widget_AppCompat_Toolbar_Button_Navigation 0x0 -+int style Widget_Autofill 0x0 -+int style Widget_Autofill_InlineSuggestionChip 0x0 -+int style Widget_Autofill_InlineSuggestionEndIconStyle 0x0 -+int style Widget_Autofill_InlineSuggestionStartIconStyle 0x0 -+int style Widget_Autofill_InlineSuggestionSubtitle 0x0 -+int style Widget_Autofill_InlineSuggestionTitle 0x0 -+int style Widget_Compat_NotificationActionContainer 0x0 -+int style Widget_Compat_NotificationActionText 0x0 -+int style redboxButton 0x0 -+int[] styleable ActionBar { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable ActionBar_background 0 -+int styleable ActionBar_backgroundSplit 1 -+int styleable ActionBar_backgroundStacked 2 -+int styleable ActionBar_contentInsetEnd 3 -+int styleable ActionBar_contentInsetEndWithActions 4 -+int styleable ActionBar_contentInsetLeft 5 -+int styleable ActionBar_contentInsetRight 6 -+int styleable ActionBar_contentInsetStart 7 -+int styleable ActionBar_contentInsetStartWithNavigation 8 -+int styleable ActionBar_customNavigationLayout 9 -+int styleable ActionBar_displayOptions 10 -+int styleable ActionBar_divider 11 -+int styleable ActionBar_elevation 12 -+int styleable ActionBar_height 13 -+int styleable ActionBar_hideOnContentScroll 14 -+int styleable ActionBar_homeAsUpIndicator 15 -+int styleable ActionBar_homeLayout 16 -+int styleable ActionBar_icon 17 -+int styleable ActionBar_indeterminateProgressStyle 18 -+int styleable ActionBar_itemPadding 19 -+int styleable ActionBar_logo 20 -+int styleable ActionBar_navigationMode 21 -+int styleable ActionBar_popupTheme 22 -+int styleable ActionBar_progressBarPadding 23 -+int styleable ActionBar_progressBarStyle 24 -+int styleable ActionBar_subtitle 25 -+int styleable ActionBar_subtitleTextStyle 26 -+int styleable ActionBar_title 27 -+int styleable ActionBar_titleTextStyle 28 -+int[] styleable ActionBarLayout { 0x10100b3 } -+int styleable ActionBarLayout_android_layout_gravity 0 -+int[] styleable ActionMenuItemView { 0x101013f } -+int styleable ActionMenuItemView_android_minWidth 0 -+int[] styleable ActionMenuView { } -+int[] styleable ActionMode { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable ActionMode_background 0 -+int styleable ActionMode_backgroundSplit 1 -+int styleable ActionMode_closeItemLayout 2 -+int styleable ActionMode_height 3 -+int styleable ActionMode_subtitleTextStyle 4 -+int styleable ActionMode_titleTextStyle 5 -+int[] styleable ActivityChooserView { 0x0, 0x0 } -+int styleable ActivityChooserView_expandActivityOverflowButtonDrawable 0 -+int styleable ActivityChooserView_initialActivityCount 1 -+int[] styleable AlertDialog { 0x10100f2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable AlertDialog_android_layout 0 -+int styleable AlertDialog_buttonIconDimen 1 -+int styleable AlertDialog_buttonPanelSideLayout 2 -+int styleable AlertDialog_listItemLayout 3 -+int styleable AlertDialog_listLayout 4 -+int styleable AlertDialog_multiChoiceItemLayout 5 -+int styleable AlertDialog_showTitle 6 -+int styleable AlertDialog_singleChoiceItemLayout 7 -+int[] styleable AnimatedStateListDrawableCompat { 0x1010196, 0x101011c, 0x101030c, 0x101030d, 0x1010195, 0x1010194 } -+int styleable AnimatedStateListDrawableCompat_android_constantSize 0 -+int styleable AnimatedStateListDrawableCompat_android_dither 1 -+int styleable AnimatedStateListDrawableCompat_android_enterFadeDuration 2 -+int styleable AnimatedStateListDrawableCompat_android_exitFadeDuration 3 -+int styleable AnimatedStateListDrawableCompat_android_variablePadding 4 -+int styleable AnimatedStateListDrawableCompat_android_visible 5 -+int[] styleable AnimatedStateListDrawableItem { 0x1010199, 0x10100d0 } -+int styleable AnimatedStateListDrawableItem_android_drawable 0 -+int styleable AnimatedStateListDrawableItem_android_id 1 -+int[] styleable AnimatedStateListDrawableTransition { 0x1010199, 0x101044a, 0x101044b, 0x1010449 } -+int styleable AnimatedStateListDrawableTransition_android_drawable 0 -+int styleable AnimatedStateListDrawableTransition_android_fromId 1 -+int styleable AnimatedStateListDrawableTransition_android_reversible 2 -+int styleable AnimatedStateListDrawableTransition_android_toId 3 -+int[] styleable AppCompatEmojiHelper { } -+int[] styleable AppCompatImageView { 0x1010119, 0x0, 0x0, 0x0 } -+int styleable AppCompatImageView_android_src 0 -+int styleable AppCompatImageView_srcCompat 1 -+int styleable AppCompatImageView_tint 2 -+int styleable AppCompatImageView_tintMode 3 -+int[] styleable AppCompatSeekBar { 0x1010142, 0x0, 0x0, 0x0 } -+int styleable AppCompatSeekBar_android_thumb 0 -+int styleable AppCompatSeekBar_tickMark 1 -+int styleable AppCompatSeekBar_tickMarkTint 2 -+int styleable AppCompatSeekBar_tickMarkTintMode 3 -+int[] styleable AppCompatTextHelper { 0x101016e, 0x1010393, 0x101016f, 0x1010170, 0x1010392, 0x101016d, 0x1010034 } -+int styleable AppCompatTextHelper_android_drawableBottom 0 -+int styleable AppCompatTextHelper_android_drawableEnd 1 -+int styleable AppCompatTextHelper_android_drawableLeft 2 -+int styleable AppCompatTextHelper_android_drawableRight 3 -+int styleable AppCompatTextHelper_android_drawableStart 4 -+int styleable AppCompatTextHelper_android_drawableTop 5 -+int styleable AppCompatTextHelper_android_textAppearance 6 -+int[] styleable AppCompatTextView { 0x1010034, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable AppCompatTextView_android_textAppearance 0 -+int styleable AppCompatTextView_autoSizeMaxTextSize 1 -+int styleable AppCompatTextView_autoSizeMinTextSize 2 -+int styleable AppCompatTextView_autoSizePresetSizes 3 -+int styleable AppCompatTextView_autoSizeStepGranularity 4 -+int styleable AppCompatTextView_autoSizeTextType 5 -+int styleable AppCompatTextView_drawableBottomCompat 6 -+int styleable AppCompatTextView_drawableEndCompat 7 -+int styleable AppCompatTextView_drawableLeftCompat 8 -+int styleable AppCompatTextView_drawableRightCompat 9 -+int styleable AppCompatTextView_drawableStartCompat 10 -+int styleable AppCompatTextView_drawableTint 11 -+int styleable AppCompatTextView_drawableTintMode 12 -+int styleable AppCompatTextView_drawableTopCompat 13 -+int styleable AppCompatTextView_emojiCompatEnabled 14 -+int styleable AppCompatTextView_firstBaselineToTopHeight 15 -+int styleable AppCompatTextView_fontFamily 16 -+int styleable AppCompatTextView_fontVariationSettings 17 -+int styleable AppCompatTextView_lastBaselineToBottomHeight 18 -+int styleable AppCompatTextView_lineHeight 19 -+int styleable AppCompatTextView_textAllCaps 20 -+int styleable AppCompatTextView_textLocale 21 -+int[] styleable AppCompatTheme { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10100ae, 0x1010057, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable AppCompatTheme_actionBarDivider 0 -+int styleable AppCompatTheme_actionBarItemBackground 1 -+int styleable AppCompatTheme_actionBarPopupTheme 2 -+int styleable AppCompatTheme_actionBarSize 3 -+int styleable AppCompatTheme_actionBarSplitStyle 4 -+int styleable AppCompatTheme_actionBarStyle 5 -+int styleable AppCompatTheme_actionBarTabBarStyle 6 -+int styleable AppCompatTheme_actionBarTabStyle 7 -+int styleable AppCompatTheme_actionBarTabTextStyle 8 -+int styleable AppCompatTheme_actionBarTheme 9 -+int styleable AppCompatTheme_actionBarWidgetTheme 10 -+int styleable AppCompatTheme_actionButtonStyle 11 -+int styleable AppCompatTheme_actionDropDownStyle 12 -+int styleable AppCompatTheme_actionMenuTextAppearance 13 -+int styleable AppCompatTheme_actionMenuTextColor 14 -+int styleable AppCompatTheme_actionModeBackground 15 -+int styleable AppCompatTheme_actionModeCloseButtonStyle 16 -+int styleable AppCompatTheme_actionModeCloseContentDescription 17 -+int styleable AppCompatTheme_actionModeCloseDrawable 18 -+int styleable AppCompatTheme_actionModeCopyDrawable 19 -+int styleable AppCompatTheme_actionModeCutDrawable 20 -+int styleable AppCompatTheme_actionModeFindDrawable 21 -+int styleable AppCompatTheme_actionModePasteDrawable 22 -+int styleable AppCompatTheme_actionModePopupWindowStyle 23 -+int styleable AppCompatTheme_actionModeSelectAllDrawable 24 -+int styleable AppCompatTheme_actionModeShareDrawable 25 -+int styleable AppCompatTheme_actionModeSplitBackground 26 -+int styleable AppCompatTheme_actionModeStyle 27 -+int styleable AppCompatTheme_actionModeTheme 28 -+int styleable AppCompatTheme_actionModeWebSearchDrawable 29 -+int styleable AppCompatTheme_actionOverflowButtonStyle 30 -+int styleable AppCompatTheme_actionOverflowMenuStyle 31 -+int styleable AppCompatTheme_activityChooserViewStyle 32 -+int styleable AppCompatTheme_alertDialogButtonGroupStyle 33 -+int styleable AppCompatTheme_alertDialogCenterButtons 34 -+int styleable AppCompatTheme_alertDialogStyle 35 -+int styleable AppCompatTheme_alertDialogTheme 36 -+int styleable AppCompatTheme_android_windowAnimationStyle 37 -+int styleable AppCompatTheme_android_windowIsFloating 38 -+int styleable AppCompatTheme_autoCompleteTextViewStyle 39 -+int styleable AppCompatTheme_borderlessButtonStyle 40 -+int styleable AppCompatTheme_buttonBarButtonStyle 41 -+int styleable AppCompatTheme_buttonBarNegativeButtonStyle 42 -+int styleable AppCompatTheme_buttonBarNeutralButtonStyle 43 -+int styleable AppCompatTheme_buttonBarPositiveButtonStyle 44 -+int styleable AppCompatTheme_buttonBarStyle 45 -+int styleable AppCompatTheme_buttonStyle 46 -+int styleable AppCompatTheme_buttonStyleSmall 47 -+int styleable AppCompatTheme_checkboxStyle 48 -+int styleable AppCompatTheme_checkedTextViewStyle 49 -+int styleable AppCompatTheme_colorAccent 50 -+int styleable AppCompatTheme_colorBackgroundFloating 51 -+int styleable AppCompatTheme_colorButtonNormal 52 -+int styleable AppCompatTheme_colorControlActivated 53 -+int styleable AppCompatTheme_colorControlHighlight 54 -+int styleable AppCompatTheme_colorControlNormal 55 -+int styleable AppCompatTheme_colorError 56 -+int styleable AppCompatTheme_colorPrimary 57 -+int styleable AppCompatTheme_colorPrimaryDark 58 -+int styleable AppCompatTheme_colorSwitchThumbNormal 59 -+int styleable AppCompatTheme_controlBackground 60 -+int styleable AppCompatTheme_dialogCornerRadius 61 -+int styleable AppCompatTheme_dialogPreferredPadding 62 -+int styleable AppCompatTheme_dialogTheme 63 -+int styleable AppCompatTheme_dividerHorizontal 64 -+int styleable AppCompatTheme_dividerVertical 65 -+int styleable AppCompatTheme_dropDownListViewStyle 66 -+int styleable AppCompatTheme_dropdownListPreferredItemHeight 67 -+int styleable AppCompatTheme_editTextBackground 68 -+int styleable AppCompatTheme_editTextColor 69 -+int styleable AppCompatTheme_editTextStyle 70 -+int styleable AppCompatTheme_homeAsUpIndicator 71 -+int styleable AppCompatTheme_imageButtonStyle 72 -+int styleable AppCompatTheme_listChoiceBackgroundIndicator 73 -+int styleable AppCompatTheme_listChoiceIndicatorMultipleAnimated 74 -+int styleable AppCompatTheme_listChoiceIndicatorSingleAnimated 75 -+int styleable AppCompatTheme_listDividerAlertDialog 76 -+int styleable AppCompatTheme_listMenuViewStyle 77 -+int styleable AppCompatTheme_listPopupWindowStyle 78 -+int styleable AppCompatTheme_listPreferredItemHeight 79 -+int styleable AppCompatTheme_listPreferredItemHeightLarge 80 -+int styleable AppCompatTheme_listPreferredItemHeightSmall 81 -+int styleable AppCompatTheme_listPreferredItemPaddingEnd 82 -+int styleable AppCompatTheme_listPreferredItemPaddingLeft 83 -+int styleable AppCompatTheme_listPreferredItemPaddingRight 84 -+int styleable AppCompatTheme_listPreferredItemPaddingStart 85 -+int styleable AppCompatTheme_panelBackground 86 -+int styleable AppCompatTheme_panelMenuListTheme 87 -+int styleable AppCompatTheme_panelMenuListWidth 88 -+int styleable AppCompatTheme_popupMenuStyle 89 -+int styleable AppCompatTheme_popupWindowStyle 90 -+int styleable AppCompatTheme_radioButtonStyle 91 -+int styleable AppCompatTheme_ratingBarStyle 92 -+int styleable AppCompatTheme_ratingBarStyleIndicator 93 -+int styleable AppCompatTheme_ratingBarStyleSmall 94 -+int styleable AppCompatTheme_searchViewStyle 95 -+int styleable AppCompatTheme_seekBarStyle 96 -+int styleable AppCompatTheme_selectableItemBackground 97 -+int styleable AppCompatTheme_selectableItemBackgroundBorderless 98 -+int styleable AppCompatTheme_spinnerDropDownItemStyle 99 -+int styleable AppCompatTheme_spinnerStyle 100 -+int styleable AppCompatTheme_switchStyle 101 -+int styleable AppCompatTheme_textAppearanceLargePopupMenu 102 -+int styleable AppCompatTheme_textAppearanceListItem 103 -+int styleable AppCompatTheme_textAppearanceListItemSecondary 104 -+int styleable AppCompatTheme_textAppearanceListItemSmall 105 -+int styleable AppCompatTheme_textAppearancePopupMenuHeader 106 -+int styleable AppCompatTheme_textAppearanceSearchResultSubtitle 107 -+int styleable AppCompatTheme_textAppearanceSearchResultTitle 108 -+int styleable AppCompatTheme_textAppearanceSmallPopupMenu 109 -+int styleable AppCompatTheme_textColorAlertDialogListItem 110 -+int styleable AppCompatTheme_textColorSearchUrl 111 -+int styleable AppCompatTheme_toolbarNavigationButtonStyle 112 -+int styleable AppCompatTheme_toolbarStyle 113 -+int styleable AppCompatTheme_tooltipForegroundColor 114 -+int styleable AppCompatTheme_tooltipFrameBackground 115 -+int styleable AppCompatTheme_viewInflaterClass 116 -+int styleable AppCompatTheme_windowActionBar 117 -+int styleable AppCompatTheme_windowActionBarOverlay 118 -+int styleable AppCompatTheme_windowActionModeOverlay 119 -+int styleable AppCompatTheme_windowFixedHeightMajor 120 -+int styleable AppCompatTheme_windowFixedHeightMinor 121 -+int styleable AppCompatTheme_windowFixedWidthMajor 122 -+int styleable AppCompatTheme_windowFixedWidthMinor 123 -+int styleable AppCompatTheme_windowMinWidthMajor 124 -+int styleable AppCompatTheme_windowMinWidthMinor 125 -+int styleable AppCompatTheme_windowNoTitle 126 -+int[] styleable Autofill_InlineSuggestion { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable Autofill_InlineSuggestion_autofillInlineSuggestionChip 0 -+int styleable Autofill_InlineSuggestion_autofillInlineSuggestionEndIconStyle 1 -+int styleable Autofill_InlineSuggestion_autofillInlineSuggestionStartIconStyle 2 -+int styleable Autofill_InlineSuggestion_autofillInlineSuggestionSubtitle 3 -+int styleable Autofill_InlineSuggestion_autofillInlineSuggestionTitle 4 -+int styleable Autofill_InlineSuggestion_isAutofillInlineSuggestionTheme 5 -+int[] styleable ButtonBarLayout { 0x0 } -+int styleable ButtonBarLayout_allowStacking 0 -+int[] styleable Capability { 0x0, 0x0 } -+int styleable Capability_queryPatterns 0 -+int styleable Capability_shortcutMatchRequired 1 -+int[] styleable CheckedTextView { 0x1010108, 0x0, 0x0, 0x0 } -+int styleable CheckedTextView_android_checkMark 0 -+int styleable CheckedTextView_checkMarkCompat 1 -+int styleable CheckedTextView_checkMarkTint 2 -+int styleable CheckedTextView_checkMarkTintMode 3 -+int[] styleable ColorStateListItem { 0x0, 0x101031f, 0x10101a5, 0x1010647, 0x0 } -+int styleable ColorStateListItem_alpha 0 -+int styleable ColorStateListItem_android_alpha 1 -+int styleable ColorStateListItem_android_color 2 -+int styleable ColorStateListItem_android_lStar 3 -+int styleable ColorStateListItem_lStar 4 -+int[] styleable CompoundButton { 0x1010107, 0x0, 0x0, 0x0 } -+int styleable CompoundButton_android_button 0 -+int styleable CompoundButton_buttonCompat 1 -+int styleable CompoundButton_buttonTint 2 -+int styleable CompoundButton_buttonTintMode 3 -+int[] styleable DrawerArrowToggle { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable DrawerArrowToggle_arrowHeadLength 0 -+int styleable DrawerArrowToggle_arrowShaftLength 1 -+int styleable DrawerArrowToggle_barLength 2 -+int styleable DrawerArrowToggle_color 3 -+int styleable DrawerArrowToggle_drawableSize 4 -+int styleable DrawerArrowToggle_gapBetweenBars 5 -+int styleable DrawerArrowToggle_spinBars 6 -+int styleable DrawerArrowToggle_thickness 7 -+int[] styleable FontFamily { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable FontFamily_fontProviderAuthority 0 -+int styleable FontFamily_fontProviderCerts 1 -+int styleable FontFamily_fontProviderFetchStrategy 2 -+int styleable FontFamily_fontProviderFetchTimeout 3 -+int styleable FontFamily_fontProviderPackage 4 -+int styleable FontFamily_fontProviderQuery 5 -+int styleable FontFamily_fontProviderSystemFontFamily 6 -+int[] styleable FontFamilyFont { 0x1010532, 0x101053f, 0x1010570, 0x1010533, 0x101056f, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable FontFamilyFont_android_font 0 -+int styleable FontFamilyFont_android_fontStyle 1 -+int styleable FontFamilyFont_android_fontVariationSettings 2 -+int styleable FontFamilyFont_android_fontWeight 3 -+int styleable FontFamilyFont_android_ttcIndex 4 -+int styleable FontFamilyFont_font 5 -+int styleable FontFamilyFont_fontStyle 6 -+int styleable FontFamilyFont_fontVariationSettings 7 -+int styleable FontFamilyFont_fontWeight 8 -+int styleable FontFamilyFont_ttcIndex 9 -+int[] styleable Fragment { 0x10100d0, 0x1010003, 0x10100d1 } -+int styleable Fragment_android_id 0 -+int styleable Fragment_android_name 1 -+int styleable Fragment_android_tag 2 -+int[] styleable FragmentContainerView { 0x1010003, 0x10100d1 } -+int styleable FragmentContainerView_android_name 0 -+int styleable FragmentContainerView_android_tag 1 -+int[] styleable GenericDraweeHierarchy { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable GenericDraweeHierarchy_actualImageScaleType 0 -+int styleable GenericDraweeHierarchy_backgroundImage 1 -+int styleable GenericDraweeHierarchy_fadeDuration 2 -+int styleable GenericDraweeHierarchy_failureImage 3 -+int styleable GenericDraweeHierarchy_failureImageScaleType 4 -+int styleable GenericDraweeHierarchy_overlayImage 5 -+int styleable GenericDraweeHierarchy_placeholderImage 6 -+int styleable GenericDraweeHierarchy_placeholderImageScaleType 7 -+int styleable GenericDraweeHierarchy_pressedStateOverlayImage 8 -+int styleable GenericDraweeHierarchy_progressBarAutoRotateInterval 9 -+int styleable GenericDraweeHierarchy_progressBarImage 10 -+int styleable GenericDraweeHierarchy_progressBarImageScaleType 11 -+int styleable GenericDraweeHierarchy_retryImage 12 -+int styleable GenericDraweeHierarchy_retryImageScaleType 13 -+int styleable GenericDraweeHierarchy_roundAsCircle 14 -+int styleable GenericDraweeHierarchy_roundBottomEnd 15 -+int styleable GenericDraweeHierarchy_roundBottomLeft 16 -+int styleable GenericDraweeHierarchy_roundBottomRight 17 -+int styleable GenericDraweeHierarchy_roundBottomStart 18 -+int styleable GenericDraweeHierarchy_roundTopEnd 19 -+int styleable GenericDraweeHierarchy_roundTopLeft 20 -+int styleable GenericDraweeHierarchy_roundTopRight 21 -+int styleable GenericDraweeHierarchy_roundTopStart 22 -+int styleable GenericDraweeHierarchy_roundWithOverlayColor 23 -+int styleable GenericDraweeHierarchy_roundedCornerRadius 24 -+int styleable GenericDraweeHierarchy_roundingBorderColor 25 -+int styleable GenericDraweeHierarchy_roundingBorderPadding 26 -+int styleable GenericDraweeHierarchy_roundingBorderWidth 27 -+int styleable GenericDraweeHierarchy_viewAspectRatio 28 -+int[] styleable GradientColor { 0x101020b, 0x10101a2, 0x10101a3, 0x101019e, 0x1010512, 0x1010513, 0x10101a4, 0x101019d, 0x1010510, 0x1010511, 0x1010201, 0x10101a1 } -+int styleable GradientColor_android_centerColor 0 -+int styleable GradientColor_android_centerX 1 -+int styleable GradientColor_android_centerY 2 -+int styleable GradientColor_android_endColor 3 -+int styleable GradientColor_android_endX 4 -+int styleable GradientColor_android_endY 5 -+int styleable GradientColor_android_gradientRadius 6 -+int styleable GradientColor_android_startColor 7 -+int styleable GradientColor_android_startX 8 -+int styleable GradientColor_android_startY 9 -+int styleable GradientColor_android_tileMode 10 -+int styleable GradientColor_android_type 11 -+int[] styleable GradientColorItem { 0x10101a5, 0x1010514 } -+int styleable GradientColorItem_android_color 0 -+int styleable GradientColorItem_android_offset 1 -+int[] styleable LinearLayoutCompat { 0x1010126, 0x1010127, 0x10100af, 0x10100c4, 0x1010128, 0x0, 0x0, 0x0, 0x0 } -+int styleable LinearLayoutCompat_android_baselineAligned 0 -+int styleable LinearLayoutCompat_android_baselineAlignedChildIndex 1 -+int styleable LinearLayoutCompat_android_gravity 2 -+int styleable LinearLayoutCompat_android_orientation 3 -+int styleable LinearLayoutCompat_android_weightSum 4 -+int styleable LinearLayoutCompat_divider 5 -+int styleable LinearLayoutCompat_dividerPadding 6 -+int styleable LinearLayoutCompat_measureWithLargestChild 7 -+int styleable LinearLayoutCompat_showDividers 8 -+int[] styleable LinearLayoutCompat_Layout { 0x10100b3, 0x10100f5, 0x1010181, 0x10100f4 } -+int styleable LinearLayoutCompat_Layout_android_layout_gravity 0 -+int styleable LinearLayoutCompat_Layout_android_layout_height 1 -+int styleable LinearLayoutCompat_Layout_android_layout_weight 2 -+int styleable LinearLayoutCompat_Layout_android_layout_width 3 -+int[] styleable ListPopupWindow { 0x10102ac, 0x10102ad } -+int styleable ListPopupWindow_android_dropDownHorizontalOffset 0 -+int styleable ListPopupWindow_android_dropDownVerticalOffset 1 -+int[] styleable MenuGroup { 0x10101e0, 0x101000e, 0x10100d0, 0x10101de, 0x10101df, 0x1010194 } -+int styleable MenuGroup_android_checkableBehavior 0 -+int styleable MenuGroup_android_enabled 1 -+int styleable MenuGroup_android_id 2 -+int styleable MenuGroup_android_menuCategory 3 -+int styleable MenuGroup_android_orderInCategory 4 -+int styleable MenuGroup_android_visible 5 -+int[] styleable MenuItem { 0x0, 0x0, 0x0, 0x0, 0x10101e3, 0x10101e5, 0x1010106, 0x101000e, 0x1010002, 0x10100d0, 0x10101de, 0x10101e4, 0x101026f, 0x10101df, 0x10101e1, 0x10101e2, 0x1010194, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable MenuItem_actionLayout 0 -+int styleable MenuItem_actionProviderClass 1 -+int styleable MenuItem_actionViewClass 2 -+int styleable MenuItem_alphabeticModifiers 3 -+int styleable MenuItem_android_alphabeticShortcut 4 -+int styleable MenuItem_android_checkable 5 -+int styleable MenuItem_android_checked 6 -+int styleable MenuItem_android_enabled 7 -+int styleable MenuItem_android_icon 8 -+int styleable MenuItem_android_id 9 -+int styleable MenuItem_android_menuCategory 10 -+int styleable MenuItem_android_numericShortcut 11 -+int styleable MenuItem_android_onClick 12 -+int styleable MenuItem_android_orderInCategory 13 -+int styleable MenuItem_android_title 14 -+int styleable MenuItem_android_titleCondensed 15 -+int styleable MenuItem_android_visible 16 -+int styleable MenuItem_contentDescription 17 -+int styleable MenuItem_iconTint 18 -+int styleable MenuItem_iconTintMode 19 -+int styleable MenuItem_numericModifiers 20 -+int styleable MenuItem_showAsAction 21 -+int styleable MenuItem_tooltipText 22 -+int[] styleable MenuView { 0x101012f, 0x101012d, 0x1010130, 0x1010131, 0x101012c, 0x101012e, 0x10100ae, 0x0, 0x0 } -+int styleable MenuView_android_headerBackground 0 -+int styleable MenuView_android_horizontalDivider 1 -+int styleable MenuView_android_itemBackground 2 -+int styleable MenuView_android_itemIconDisabledAlpha 3 -+int styleable MenuView_android_itemTextAppearance 4 -+int styleable MenuView_android_verticalDivider 5 -+int styleable MenuView_android_windowAnimationStyle 6 -+int styleable MenuView_preserveIconSpacing 7 -+int styleable MenuView_subMenuArrow 8 -+int[] styleable PopupWindow { 0x10102c9, 0x1010176, 0x0 } -+int styleable PopupWindow_android_popupAnimationStyle 0 -+int styleable PopupWindow_android_popupBackground 1 -+int styleable PopupWindow_overlapAnchor 2 -+int[] styleable PopupWindowBackgroundState { 0x0 } -+int styleable PopupWindowBackgroundState_state_above_anchor 0 -+int[] styleable RecycleListView { 0x0, 0x0 } -+int styleable RecycleListView_paddingBottomNoButtons 0 -+int styleable RecycleListView_paddingTopNoTitle 1 -+int[] styleable SearchView { 0x10100da, 0x1010264, 0x1010220, 0x101011f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable SearchView_android_focusable 0 -+int styleable SearchView_android_imeOptions 1 -+int styleable SearchView_android_inputType 2 -+int styleable SearchView_android_maxWidth 3 -+int styleable SearchView_closeIcon 4 -+int styleable SearchView_commitIcon 5 -+int styleable SearchView_defaultQueryHint 6 -+int styleable SearchView_goIcon 7 -+int styleable SearchView_iconifiedByDefault 8 -+int styleable SearchView_layout 9 -+int styleable SearchView_queryBackground 10 -+int styleable SearchView_queryHint 11 -+int styleable SearchView_searchHintIcon 12 -+int styleable SearchView_searchIcon 13 -+int styleable SearchView_submitBackground 14 -+int styleable SearchView_suggestionRowLayout 15 -+int styleable SearchView_voiceIcon 16 -+int[] styleable SimpleDraweeView { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable SimpleDraweeView_actualImageResource 0 -+int styleable SimpleDraweeView_actualImageScaleType 1 -+int styleable SimpleDraweeView_actualImageUri 2 -+int styleable SimpleDraweeView_backgroundImage 3 -+int styleable SimpleDraweeView_fadeDuration 4 -+int styleable SimpleDraweeView_failureImage 5 -+int styleable SimpleDraweeView_failureImageScaleType 6 -+int styleable SimpleDraweeView_overlayImage 7 -+int styleable SimpleDraweeView_placeholderImage 8 -+int styleable SimpleDraweeView_placeholderImageScaleType 9 -+int styleable SimpleDraweeView_pressedStateOverlayImage 10 -+int styleable SimpleDraweeView_progressBarAutoRotateInterval 11 -+int styleable SimpleDraweeView_progressBarImage 12 -+int styleable SimpleDraweeView_progressBarImageScaleType 13 -+int styleable SimpleDraweeView_retryImage 14 -+int styleable SimpleDraweeView_retryImageScaleType 15 -+int styleable SimpleDraweeView_roundAsCircle 16 -+int styleable SimpleDraweeView_roundBottomEnd 17 -+int styleable SimpleDraweeView_roundBottomLeft 18 -+int styleable SimpleDraweeView_roundBottomRight 19 -+int styleable SimpleDraweeView_roundBottomStart 20 -+int styleable SimpleDraweeView_roundTopEnd 21 -+int styleable SimpleDraweeView_roundTopLeft 22 -+int styleable SimpleDraweeView_roundTopRight 23 -+int styleable SimpleDraweeView_roundTopStart 24 -+int styleable SimpleDraweeView_roundWithOverlayColor 25 -+int styleable SimpleDraweeView_roundedCornerRadius 26 -+int styleable SimpleDraweeView_roundingBorderColor 27 -+int styleable SimpleDraweeView_roundingBorderPadding 28 -+int styleable SimpleDraweeView_roundingBorderWidth 29 -+int styleable SimpleDraweeView_viewAspectRatio 30 -+int[] styleable Spinner { 0x1010262, 0x10100b2, 0x1010176, 0x101017b, 0x0 } -+int styleable Spinner_android_dropDownWidth 0 -+int styleable Spinner_android_entries 1 -+int styleable Spinner_android_popupBackground 2 -+int styleable Spinner_android_prompt 3 -+int styleable Spinner_popupTheme 4 -+int[] styleable StateListDrawable { 0x1010196, 0x101011c, 0x101030c, 0x101030d, 0x1010195, 0x1010194 } -+int styleable StateListDrawable_android_constantSize 0 -+int styleable StateListDrawable_android_dither 1 -+int styleable StateListDrawable_android_enterFadeDuration 2 -+int styleable StateListDrawable_android_exitFadeDuration 3 -+int styleable StateListDrawable_android_variablePadding 4 -+int styleable StateListDrawable_android_visible 5 -+int[] styleable StateListDrawableItem { 0x1010199 } -+int styleable StateListDrawableItem_android_drawable 0 -+int[] styleable SwitchCompat { 0x1010125, 0x1010124, 0x1010142, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable SwitchCompat_android_textOff 0 -+int styleable SwitchCompat_android_textOn 1 -+int styleable SwitchCompat_android_thumb 2 -+int styleable SwitchCompat_showText 3 -+int styleable SwitchCompat_splitTrack 4 -+int styleable SwitchCompat_switchMinWidth 5 -+int styleable SwitchCompat_switchPadding 6 -+int styleable SwitchCompat_switchTextAppearance 7 -+int styleable SwitchCompat_thumbTextPadding 8 -+int styleable SwitchCompat_thumbTint 9 -+int styleable SwitchCompat_thumbTintMode 10 -+int styleable SwitchCompat_track 11 -+int styleable SwitchCompat_trackTint 12 -+int styleable SwitchCompat_trackTintMode 13 -+int[] styleable TextAppearance { 0x10103ac, 0x1010161, 0x1010162, 0x1010163, 0x1010164, 0x1010098, 0x101009a, 0x101009b, 0x1010585, 0x1010095, 0x1010097, 0x1010096, 0x0, 0x0, 0x0, 0x0 } -+int styleable TextAppearance_android_fontFamily 0 -+int styleable TextAppearance_android_shadowColor 1 -+int styleable TextAppearance_android_shadowDx 2 -+int styleable TextAppearance_android_shadowDy 3 -+int styleable TextAppearance_android_shadowRadius 4 -+int styleable TextAppearance_android_textColor 5 -+int styleable TextAppearance_android_textColorHint 6 -+int styleable TextAppearance_android_textColorLink 7 -+int styleable TextAppearance_android_textFontWeight 8 -+int styleable TextAppearance_android_textSize 9 -+int styleable TextAppearance_android_textStyle 10 -+int styleable TextAppearance_android_typeface 11 -+int styleable TextAppearance_fontFamily 12 -+int styleable TextAppearance_fontVariationSettings 13 -+int styleable TextAppearance_textAllCaps 14 -+int styleable TextAppearance_textLocale 15 -+int[] styleable Toolbar { 0x10100af, 0x1010140, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -+int styleable Toolbar_android_gravity 0 -+int styleable Toolbar_android_minHeight 1 -+int styleable Toolbar_buttonGravity 2 -+int styleable Toolbar_collapseContentDescription 3 -+int styleable Toolbar_collapseIcon 4 -+int styleable Toolbar_contentInsetEnd 5 -+int styleable Toolbar_contentInsetEndWithActions 6 -+int styleable Toolbar_contentInsetLeft 7 -+int styleable Toolbar_contentInsetRight 8 -+int styleable Toolbar_contentInsetStart 9 -+int styleable Toolbar_contentInsetStartWithNavigation 10 -+int styleable Toolbar_logo 11 -+int styleable Toolbar_logoDescription 12 -+int styleable Toolbar_maxButtonHeight 13 -+int styleable Toolbar_menu 14 -+int styleable Toolbar_navigationContentDescription 15 -+int styleable Toolbar_navigationIcon 16 -+int styleable Toolbar_popupTheme 17 -+int styleable Toolbar_subtitle 18 -+int styleable Toolbar_subtitleTextAppearance 19 -+int styleable Toolbar_subtitleTextColor 20 -+int styleable Toolbar_title 21 -+int styleable Toolbar_titleMargin 22 -+int styleable Toolbar_titleMarginBottom 23 -+int styleable Toolbar_titleMarginEnd 24 -+int styleable Toolbar_titleMarginStart 25 -+int styleable Toolbar_titleMarginTop 26 -+int styleable Toolbar_titleMargins 27 -+int styleable Toolbar_titleTextAppearance 28 -+int styleable Toolbar_titleTextColor 29 -+int[] styleable View { 0x10100da, 0x1010000, 0x0, 0x0, 0x0 } -+int styleable View_android_focusable 0 -+int styleable View_android_theme 1 -+int styleable View_paddingEnd 2 -+int styleable View_paddingStart 3 -+int styleable View_theme 4 -+int[] styleable ViewBackgroundHelper { 0x10100d4, 0x0, 0x0 } -+int styleable ViewBackgroundHelper_android_background 0 -+int styleable ViewBackgroundHelper_backgroundTint 1 -+int styleable ViewBackgroundHelper_backgroundTintMode 2 -+int[] styleable ViewStubCompat { 0x10100d0, 0x10100f3, 0x10100f2 } -+int styleable ViewStubCompat_android_id 0 -+int styleable ViewStubCompat_android_inflatedId 1 -+int styleable ViewStubCompat_android_layout 2 -+int xml rn_dev_preferences 0x0 -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties -new file mode 100644 -index 0000000..47e2add ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties -@@ -0,0 +1 @@ -+#Sun Apr 02 19:35:28 CDT 2023 -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml -new file mode 100644 -index 0000000..b5f25a5 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml -@@ -0,0 +1,2 @@ -+ -+ -\ No newline at end of file -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/local_only_symbol_list/debug/R-def.txt b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/local_only_symbol_list/debug/R-def.txt -new file mode 100644 -index 0000000..78ac5b8 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/local_only_symbol_list/debug/R-def.txt -@@ -0,0 +1,2 @@ -+R_DEF: Internal format may change without notice -+local -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt -new file mode 100644 -index 0000000..127829f ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt -@@ -0,0 +1,11 @@ -+1 -+2 -+4 -+5 /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+7 android:targetSdkVersion="33" /> -+7-->/Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+8 -+9 -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml -new file mode 100644 -index 0000000..0249d77 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml -@@ -0,0 +1,9 @@ -+ -+ -+ -+ -+ -+ -\ No newline at end of file -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/navigation_json/debug/navigation.json b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/navigation_json/debug/navigation.json -new file mode 100644 -index 0000000..0637a08 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/navigation_json/debug/navigation.json -@@ -0,0 +1 @@ -+[] -\ No newline at end of file -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/packaged_manifests/debug/output-metadata.json b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/packaged_manifests/debug/output-metadata.json -new file mode 100644 -index 0000000..3640409 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/packaged_manifests/debug/output-metadata.json -@@ -0,0 +1,18 @@ -+{ -+ "version": 3, -+ "artifactType": { -+ "type": "PACKAGED_MANIFESTS", -+ "kind": "Directory" -+ }, -+ "applicationId": "com.mattermost.pasteinput", -+ "variantName": "debug", -+ "elements": [ -+ { -+ "type": "SINGLE", -+ "filters": [], -+ "attributes": [], -+ "outputFile": "../../merged_manifest/debug/AndroidManifest.xml" -+ } -+ ], -+ "elementType": "File" -+} -\ No newline at end of file -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt -new file mode 100644 -index 0000000..7009825 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt -@@ -0,0 +1,1446 @@ -+com.mattermost.pasteinput -+anim abc_fade_in -+anim abc_fade_out -+anim abc_grow_fade_in_from_bottom -+anim abc_popup_enter -+anim abc_popup_exit -+anim abc_shrink_fade_out_from_bottom -+anim abc_slide_in_bottom -+anim abc_slide_in_top -+anim abc_slide_out_bottom -+anim abc_slide_out_top -+anim abc_tooltip_enter -+anim abc_tooltip_exit -+anim btn_checkbox_to_checked_box_inner_merged_animation -+anim btn_checkbox_to_checked_box_outer_merged_animation -+anim btn_checkbox_to_checked_icon_null_animation -+anim btn_checkbox_to_unchecked_box_inner_merged_animation -+anim btn_checkbox_to_unchecked_check_path_merged_animation -+anim btn_checkbox_to_unchecked_icon_null_animation -+anim btn_radio_to_off_mtrl_dot_group_animation -+anim btn_radio_to_off_mtrl_ring_outer_animation -+anim btn_radio_to_off_mtrl_ring_outer_path_animation -+anim btn_radio_to_on_mtrl_dot_group_animation -+anim btn_radio_to_on_mtrl_ring_outer_animation -+anim btn_radio_to_on_mtrl_ring_outer_path_animation -+anim catalyst_fade_in -+anim catalyst_fade_out -+anim catalyst_push_up_in -+anim catalyst_push_up_out -+anim catalyst_slide_down -+anim catalyst_slide_up -+anim fragment_fast_out_extra_slow_in -+animator fragment_close_enter -+animator fragment_close_exit -+animator fragment_fade_enter -+animator fragment_fade_exit -+animator fragment_open_enter -+animator fragment_open_exit -+attr actionBarDivider -+attr actionBarItemBackground -+attr actionBarPopupTheme -+attr actionBarSize -+attr actionBarSplitStyle -+attr actionBarStyle -+attr actionBarTabBarStyle -+attr actionBarTabStyle -+attr actionBarTabTextStyle -+attr actionBarTheme -+attr actionBarWidgetTheme -+attr actionButtonStyle -+attr actionDropDownStyle -+attr actionLayout -+attr actionMenuTextAppearance -+attr actionMenuTextColor -+attr actionModeBackground -+attr actionModeCloseButtonStyle -+attr actionModeCloseContentDescription -+attr actionModeCloseDrawable -+attr actionModeCopyDrawable -+attr actionModeCutDrawable -+attr actionModeFindDrawable -+attr actionModePasteDrawable -+attr actionModePopupWindowStyle -+attr actionModeSelectAllDrawable -+attr actionModeShareDrawable -+attr actionModeSplitBackground -+attr actionModeStyle -+attr actionModeTheme -+attr actionModeWebSearchDrawable -+attr actionOverflowButtonStyle -+attr actionOverflowMenuStyle -+attr actionProviderClass -+attr actionViewClass -+attr activityChooserViewStyle -+attr actualImageResource -+attr actualImageScaleType -+attr actualImageUri -+attr alertDialogButtonGroupStyle -+attr alertDialogCenterButtons -+attr alertDialogStyle -+attr alertDialogTheme -+attr allowStacking -+attr alpha -+attr alphabeticModifiers -+attr arrowHeadLength -+attr arrowShaftLength -+attr autoCompleteTextViewStyle -+attr autoSizeMaxTextSize -+attr autoSizeMinTextSize -+attr autoSizePresetSizes -+attr autoSizeStepGranularity -+attr autoSizeTextType -+attr autofillInlineSuggestionChip -+attr autofillInlineSuggestionEndIconStyle -+attr autofillInlineSuggestionStartIconStyle -+attr autofillInlineSuggestionSubtitle -+attr autofillInlineSuggestionTitle -+attr background -+attr backgroundImage -+attr backgroundSplit -+attr backgroundStacked -+attr backgroundTint -+attr backgroundTintMode -+attr barLength -+attr borderlessButtonStyle -+attr buttonBarButtonStyle -+attr buttonBarNegativeButtonStyle -+attr buttonBarNeutralButtonStyle -+attr buttonBarPositiveButtonStyle -+attr buttonBarStyle -+attr buttonCompat -+attr buttonGravity -+attr buttonIconDimen -+attr buttonPanelSideLayout -+attr buttonStyle -+attr buttonStyleSmall -+attr buttonTint -+attr buttonTintMode -+attr checkMarkCompat -+attr checkMarkTint -+attr checkMarkTintMode -+attr checkboxStyle -+attr checkedTextViewStyle -+attr closeIcon -+attr closeItemLayout -+attr collapseContentDescription -+attr collapseIcon -+attr color -+attr colorAccent -+attr colorBackgroundFloating -+attr colorButtonNormal -+attr colorControlActivated -+attr colorControlHighlight -+attr colorControlNormal -+attr colorError -+attr colorPrimary -+attr colorPrimaryDark -+attr colorSwitchThumbNormal -+attr commitIcon -+attr contentDescription -+attr contentInsetEnd -+attr contentInsetEndWithActions -+attr contentInsetLeft -+attr contentInsetRight -+attr contentInsetStart -+attr contentInsetStartWithNavigation -+attr controlBackground -+attr customNavigationLayout -+attr defaultQueryHint -+attr dialogCornerRadius -+attr dialogPreferredPadding -+attr dialogTheme -+attr displayOptions -+attr divider -+attr dividerHorizontal -+attr dividerPadding -+attr dividerVertical -+attr drawableBottomCompat -+attr drawableEndCompat -+attr drawableLeftCompat -+attr drawableRightCompat -+attr drawableSize -+attr drawableStartCompat -+attr drawableTint -+attr drawableTintMode -+attr drawableTopCompat -+attr drawerArrowStyle -+attr dropDownListViewStyle -+attr dropdownListPreferredItemHeight -+attr editTextBackground -+attr editTextColor -+attr editTextStyle -+attr elevation -+attr emojiCompatEnabled -+attr expandActivityOverflowButtonDrawable -+attr fadeDuration -+attr failureImage -+attr failureImageScaleType -+attr firstBaselineToTopHeight -+attr font -+attr fontFamily -+attr fontProviderAuthority -+attr fontProviderCerts -+attr fontProviderFetchStrategy -+attr fontProviderFetchTimeout -+attr fontProviderPackage -+attr fontProviderQuery -+attr fontProviderSystemFontFamily -+attr fontStyle -+attr fontVariationSettings -+attr fontWeight -+attr gapBetweenBars -+attr goIcon -+attr height -+attr hideOnContentScroll -+attr homeAsUpIndicator -+attr homeLayout -+attr icon -+attr iconTint -+attr iconTintMode -+attr iconifiedByDefault -+attr imageButtonStyle -+attr indeterminateProgressStyle -+attr initialActivityCount -+attr isAutofillInlineSuggestionTheme -+attr isLightTheme -+attr itemPadding -+attr lStar -+attr lastBaselineToBottomHeight -+attr layout -+attr lineHeight -+attr listChoiceBackgroundIndicator -+attr listChoiceIndicatorMultipleAnimated -+attr listChoiceIndicatorSingleAnimated -+attr listDividerAlertDialog -+attr listItemLayout -+attr listLayout -+attr listMenuViewStyle -+attr listPopupWindowStyle -+attr listPreferredItemHeight -+attr listPreferredItemHeightLarge -+attr listPreferredItemHeightSmall -+attr listPreferredItemPaddingEnd -+attr listPreferredItemPaddingLeft -+attr listPreferredItemPaddingRight -+attr listPreferredItemPaddingStart -+attr logo -+attr logoDescription -+attr maxButtonHeight -+attr measureWithLargestChild -+attr menu -+attr multiChoiceItemLayout -+attr navigationContentDescription -+attr navigationIcon -+attr navigationMode -+attr nestedScrollViewStyle -+attr numericModifiers -+attr overlapAnchor -+attr overlayImage -+attr paddingBottomNoButtons -+attr paddingEnd -+attr paddingStart -+attr paddingTopNoTitle -+attr panelBackground -+attr panelMenuListTheme -+attr panelMenuListWidth -+attr placeholderImage -+attr placeholderImageScaleType -+attr popupMenuStyle -+attr popupTheme -+attr popupWindowStyle -+attr preserveIconSpacing -+attr pressedStateOverlayImage -+attr progressBarAutoRotateInterval -+attr progressBarImage -+attr progressBarImageScaleType -+attr progressBarPadding -+attr progressBarStyle -+attr queryBackground -+attr queryHint -+attr queryPatterns -+attr radioButtonStyle -+attr ratingBarStyle -+attr ratingBarStyleIndicator -+attr ratingBarStyleSmall -+attr retryImage -+attr retryImageScaleType -+attr roundAsCircle -+attr roundBottomEnd -+attr roundBottomLeft -+attr roundBottomRight -+attr roundBottomStart -+attr roundTopEnd -+attr roundTopLeft -+attr roundTopRight -+attr roundTopStart -+attr roundWithOverlayColor -+attr roundedCornerRadius -+attr roundingBorderColor -+attr roundingBorderPadding -+attr roundingBorderWidth -+attr searchHintIcon -+attr searchIcon -+attr searchViewStyle -+attr seekBarStyle -+attr selectableItemBackground -+attr selectableItemBackgroundBorderless -+attr shortcutMatchRequired -+attr showAsAction -+attr showDividers -+attr showText -+attr showTitle -+attr singleChoiceItemLayout -+attr spinBars -+attr spinnerDropDownItemStyle -+attr spinnerStyle -+attr splitTrack -+attr srcCompat -+attr state_above_anchor -+attr subMenuArrow -+attr submitBackground -+attr subtitle -+attr subtitleTextAppearance -+attr subtitleTextColor -+attr subtitleTextStyle -+attr suggestionRowLayout -+attr switchMinWidth -+attr switchPadding -+attr switchStyle -+attr switchTextAppearance -+attr textAllCaps -+attr textAppearanceLargePopupMenu -+attr textAppearanceListItem -+attr textAppearanceListItemSecondary -+attr textAppearanceListItemSmall -+attr textAppearancePopupMenuHeader -+attr textAppearanceSearchResultSubtitle -+attr textAppearanceSearchResultTitle -+attr textAppearanceSmallPopupMenu -+attr textColorAlertDialogListItem -+attr textColorSearchUrl -+attr textLocale -+attr theme -+attr thickness -+attr thumbTextPadding -+attr thumbTint -+attr thumbTintMode -+attr tickMark -+attr tickMarkTint -+attr tickMarkTintMode -+attr tint -+attr tintMode -+attr title -+attr titleMargin -+attr titleMarginBottom -+attr titleMarginEnd -+attr titleMarginStart -+attr titleMarginTop -+attr titleMargins -+attr titleTextAppearance -+attr titleTextColor -+attr titleTextStyle -+attr toolbarNavigationButtonStyle -+attr toolbarStyle -+attr tooltipForegroundColor -+attr tooltipFrameBackground -+attr tooltipText -+attr track -+attr trackTint -+attr trackTintMode -+attr ttcIndex -+attr viewAspectRatio -+attr viewInflaterClass -+attr voiceIcon -+attr windowActionBar -+attr windowActionBarOverlay -+attr windowActionModeOverlay -+attr windowFixedHeightMajor -+attr windowFixedHeightMinor -+attr windowFixedWidthMajor -+attr windowFixedWidthMinor -+attr windowMinWidthMajor -+attr windowMinWidthMinor -+attr windowNoTitle -+bool abc_action_bar_embed_tabs -+bool abc_config_actionMenuItemAllCaps -+color abc_background_cache_hint_selector_material_dark -+color abc_background_cache_hint_selector_material_light -+color abc_btn_colored_borderless_text_material -+color abc_btn_colored_text_material -+color abc_color_highlight_material -+color abc_decor_view_status_guard -+color abc_decor_view_status_guard_light -+color abc_hint_foreground_material_dark -+color abc_hint_foreground_material_light -+color abc_primary_text_disable_only_material_dark -+color abc_primary_text_disable_only_material_light -+color abc_primary_text_material_dark -+color abc_primary_text_material_light -+color abc_search_url_text -+color abc_search_url_text_normal -+color abc_search_url_text_pressed -+color abc_search_url_text_selected -+color abc_secondary_text_material_dark -+color abc_secondary_text_material_light -+color abc_tint_btn_checkable -+color abc_tint_default -+color abc_tint_edittext -+color abc_tint_seek_thumb -+color abc_tint_spinner -+color abc_tint_switch_track -+color accent_material_dark -+color accent_material_light -+color androidx_core_ripple_material_light -+color androidx_core_secondary_text_default_material_light -+color background_floating_material_dark -+color background_floating_material_light -+color background_material_dark -+color background_material_light -+color bright_foreground_disabled_material_dark -+color bright_foreground_disabled_material_light -+color bright_foreground_inverse_material_dark -+color bright_foreground_inverse_material_light -+color bright_foreground_material_dark -+color bright_foreground_material_light -+color button_material_dark -+color button_material_light -+color catalyst_logbox_background -+color catalyst_redbox_background -+color dim_foreground_disabled_material_dark -+color dim_foreground_disabled_material_light -+color dim_foreground_material_dark -+color dim_foreground_material_light -+color error_color_material_dark -+color error_color_material_light -+color foreground_material_dark -+color foreground_material_light -+color highlighted_text_material_dark -+color highlighted_text_material_light -+color material_blue_grey_800 -+color material_blue_grey_900 -+color material_blue_grey_950 -+color material_deep_teal_200 -+color material_deep_teal_500 -+color material_grey_100 -+color material_grey_300 -+color material_grey_50 -+color material_grey_600 -+color material_grey_800 -+color material_grey_850 -+color material_grey_900 -+color notification_action_color_filter -+color notification_icon_bg_color -+color primary_dark_material_dark -+color primary_dark_material_light -+color primary_material_dark -+color primary_material_light -+color primary_text_default_material_dark -+color primary_text_default_material_light -+color primary_text_disabled_material_dark -+color primary_text_disabled_material_light -+color ripple_material_dark -+color ripple_material_light -+color secondary_text_default_material_dark -+color secondary_text_default_material_light -+color secondary_text_disabled_material_dark -+color secondary_text_disabled_material_light -+color switch_thumb_disabled_material_dark -+color switch_thumb_disabled_material_light -+color switch_thumb_material_dark -+color switch_thumb_material_light -+color switch_thumb_normal_material_dark -+color switch_thumb_normal_material_light -+color tooltip_background_dark -+color tooltip_background_light -+dimen abc_action_bar_content_inset_material -+dimen abc_action_bar_content_inset_with_nav -+dimen abc_action_bar_default_height_material -+dimen abc_action_bar_default_padding_end_material -+dimen abc_action_bar_default_padding_start_material -+dimen abc_action_bar_elevation_material -+dimen abc_action_bar_icon_vertical_padding_material -+dimen abc_action_bar_overflow_padding_end_material -+dimen abc_action_bar_overflow_padding_start_material -+dimen abc_action_bar_stacked_max_height -+dimen abc_action_bar_stacked_tab_max_width -+dimen abc_action_bar_subtitle_bottom_margin_material -+dimen abc_action_bar_subtitle_top_margin_material -+dimen abc_action_button_min_height_material -+dimen abc_action_button_min_width_material -+dimen abc_action_button_min_width_overflow_material -+dimen abc_alert_dialog_button_bar_height -+dimen abc_alert_dialog_button_dimen -+dimen abc_button_inset_horizontal_material -+dimen abc_button_inset_vertical_material -+dimen abc_button_padding_horizontal_material -+dimen abc_button_padding_vertical_material -+dimen abc_cascading_menus_min_smallest_width -+dimen abc_config_prefDialogWidth -+dimen abc_control_corner_material -+dimen abc_control_inset_material -+dimen abc_control_padding_material -+dimen abc_dialog_corner_radius_material -+dimen abc_dialog_fixed_height_major -+dimen abc_dialog_fixed_height_minor -+dimen abc_dialog_fixed_width_major -+dimen abc_dialog_fixed_width_minor -+dimen abc_dialog_list_padding_bottom_no_buttons -+dimen abc_dialog_list_padding_top_no_title -+dimen abc_dialog_min_width_major -+dimen abc_dialog_min_width_minor -+dimen abc_dialog_padding_material -+dimen abc_dialog_padding_top_material -+dimen abc_dialog_title_divider_material -+dimen abc_disabled_alpha_material_dark -+dimen abc_disabled_alpha_material_light -+dimen abc_dropdownitem_icon_width -+dimen abc_dropdownitem_text_padding_left -+dimen abc_dropdownitem_text_padding_right -+dimen abc_edit_text_inset_bottom_material -+dimen abc_edit_text_inset_horizontal_material -+dimen abc_edit_text_inset_top_material -+dimen abc_floating_window_z -+dimen abc_list_item_height_large_material -+dimen abc_list_item_height_material -+dimen abc_list_item_height_small_material -+dimen abc_list_item_padding_horizontal_material -+dimen abc_panel_menu_list_width -+dimen abc_progress_bar_height_material -+dimen abc_search_view_preferred_height -+dimen abc_search_view_preferred_width -+dimen abc_seekbar_track_background_height_material -+dimen abc_seekbar_track_progress_height_material -+dimen abc_select_dialog_padding_start_material -+dimen abc_star_big -+dimen abc_star_medium -+dimen abc_star_small -+dimen abc_switch_padding -+dimen abc_text_size_body_1_material -+dimen abc_text_size_body_2_material -+dimen abc_text_size_button_material -+dimen abc_text_size_caption_material -+dimen abc_text_size_display_1_material -+dimen abc_text_size_display_2_material -+dimen abc_text_size_display_3_material -+dimen abc_text_size_display_4_material -+dimen abc_text_size_headline_material -+dimen abc_text_size_large_material -+dimen abc_text_size_medium_material -+dimen abc_text_size_menu_header_material -+dimen abc_text_size_menu_material -+dimen abc_text_size_small_material -+dimen abc_text_size_subhead_material -+dimen abc_text_size_subtitle_material_toolbar -+dimen abc_text_size_title_material -+dimen abc_text_size_title_material_toolbar -+dimen autofill_inline_suggestion_icon_size -+dimen compat_button_inset_horizontal_material -+dimen compat_button_inset_vertical_material -+dimen compat_button_padding_horizontal_material -+dimen compat_button_padding_vertical_material -+dimen compat_control_corner_material -+dimen compat_notification_large_icon_max_height -+dimen compat_notification_large_icon_max_width -+dimen disabled_alpha_material_dark -+dimen disabled_alpha_material_light -+dimen highlight_alpha_material_colored -+dimen highlight_alpha_material_dark -+dimen highlight_alpha_material_light -+dimen hint_alpha_material_dark -+dimen hint_alpha_material_light -+dimen hint_pressed_alpha_material_dark -+dimen hint_pressed_alpha_material_light -+dimen notification_action_icon_size -+dimen notification_action_text_size -+dimen notification_big_circle_margin -+dimen notification_content_margin_start -+dimen notification_large_icon_height -+dimen notification_large_icon_width -+dimen notification_main_column_padding_top -+dimen notification_media_narrow_margin -+dimen notification_right_icon_size -+dimen notification_right_side_padding_top -+dimen notification_small_icon_background_padding -+dimen notification_small_icon_size_as_large -+dimen notification_subtext_size -+dimen notification_top_pad -+dimen notification_top_pad_large_text -+dimen tooltip_corner_radius -+dimen tooltip_horizontal_padding -+dimen tooltip_margin -+dimen tooltip_precise_anchor_extra_offset -+dimen tooltip_precise_anchor_threshold -+dimen tooltip_vertical_padding -+dimen tooltip_y_offset_non_touch -+dimen tooltip_y_offset_touch -+drawable abc_ab_share_pack_mtrl_alpha -+drawable abc_action_bar_item_background_material -+drawable abc_btn_borderless_material -+drawable abc_btn_check_material -+drawable abc_btn_check_material_anim -+drawable abc_btn_check_to_on_mtrl_000 -+drawable abc_btn_check_to_on_mtrl_015 -+drawable abc_btn_colored_material -+drawable abc_btn_default_mtrl_shape -+drawable abc_btn_radio_material -+drawable abc_btn_radio_material_anim -+drawable abc_btn_radio_to_on_mtrl_000 -+drawable abc_btn_radio_to_on_mtrl_015 -+drawable abc_btn_switch_to_on_mtrl_00001 -+drawable abc_btn_switch_to_on_mtrl_00012 -+drawable abc_cab_background_internal_bg -+drawable abc_cab_background_top_material -+drawable abc_cab_background_top_mtrl_alpha -+drawable abc_control_background_material -+drawable abc_dialog_material_background -+drawable abc_edit_text_material -+drawable abc_ic_ab_back_material -+drawable abc_ic_arrow_drop_right_black_24dp -+drawable abc_ic_clear_material -+drawable abc_ic_commit_search_api_mtrl_alpha -+drawable abc_ic_go_search_api_material -+drawable abc_ic_menu_copy_mtrl_am_alpha -+drawable abc_ic_menu_cut_mtrl_alpha -+drawable abc_ic_menu_overflow_material -+drawable abc_ic_menu_paste_mtrl_am_alpha -+drawable abc_ic_menu_selectall_mtrl_alpha -+drawable abc_ic_menu_share_mtrl_alpha -+drawable abc_ic_search_api_material -+drawable abc_ic_voice_search_api_material -+drawable abc_item_background_holo_dark -+drawable abc_item_background_holo_light -+drawable abc_list_divider_material -+drawable abc_list_divider_mtrl_alpha -+drawable abc_list_focused_holo -+drawable abc_list_longpressed_holo -+drawable abc_list_pressed_holo_dark -+drawable abc_list_pressed_holo_light -+drawable abc_list_selector_background_transition_holo_dark -+drawable abc_list_selector_background_transition_holo_light -+drawable abc_list_selector_disabled_holo_dark -+drawable abc_list_selector_disabled_holo_light -+drawable abc_list_selector_holo_dark -+drawable abc_list_selector_holo_light -+drawable abc_menu_hardkey_panel_mtrl_mult -+drawable abc_popup_background_mtrl_mult -+drawable abc_ratingbar_indicator_material -+drawable abc_ratingbar_material -+drawable abc_ratingbar_small_material -+drawable abc_scrubber_control_off_mtrl_alpha -+drawable abc_scrubber_control_to_pressed_mtrl_000 -+drawable abc_scrubber_control_to_pressed_mtrl_005 -+drawable abc_scrubber_primary_mtrl_alpha -+drawable abc_scrubber_track_mtrl_alpha -+drawable abc_seekbar_thumb_material -+drawable abc_seekbar_tick_mark_material -+drawable abc_seekbar_track_material -+drawable abc_spinner_mtrl_am_alpha -+drawable abc_spinner_textfield_background_material -+drawable abc_star_black_48dp -+drawable abc_star_half_black_48dp -+drawable abc_switch_thumb_material -+drawable abc_switch_track_mtrl_alpha -+drawable abc_tab_indicator_material -+drawable abc_tab_indicator_mtrl_alpha -+drawable abc_text_cursor_material -+drawable abc_text_select_handle_left_mtrl -+drawable abc_text_select_handle_middle_mtrl -+drawable abc_text_select_handle_right_mtrl -+drawable abc_textfield_activated_mtrl_alpha -+drawable abc_textfield_default_mtrl_alpha -+drawable abc_textfield_search_activated_mtrl_alpha -+drawable abc_textfield_search_default_mtrl_alpha -+drawable abc_textfield_search_material -+drawable abc_vector_test -+drawable autofill_inline_suggestion_chip_background -+drawable btn_checkbox_checked_mtrl -+drawable btn_checkbox_checked_to_unchecked_mtrl_animation -+drawable btn_checkbox_unchecked_mtrl -+drawable btn_checkbox_unchecked_to_checked_mtrl_animation -+drawable btn_radio_off_mtrl -+drawable btn_radio_off_to_on_mtrl_animation -+drawable btn_radio_on_mtrl -+drawable btn_radio_on_to_off_mtrl_animation -+drawable notification_action_background -+drawable notification_bg -+drawable notification_bg_low -+drawable notification_bg_low_normal -+drawable notification_bg_low_pressed -+drawable notification_bg_normal -+drawable notification_bg_normal_pressed -+drawable notification_icon_background -+drawable notification_template_icon_bg -+drawable notification_template_icon_low_bg -+drawable notification_tile_bg -+drawable notify_panel_notification_icon_bg -+drawable redbox_top_border_background -+drawable test_level_drawable -+drawable tooltip_frame_dark -+drawable tooltip_frame_light -+id accessibility_action_clickable_span -+id accessibility_actions -+id accessibility_collection -+id accessibility_collection_item -+id accessibility_custom_action_0 -+id accessibility_custom_action_1 -+id accessibility_custom_action_10 -+id accessibility_custom_action_11 -+id accessibility_custom_action_12 -+id accessibility_custom_action_13 -+id accessibility_custom_action_14 -+id accessibility_custom_action_15 -+id accessibility_custom_action_16 -+id accessibility_custom_action_17 -+id accessibility_custom_action_18 -+id accessibility_custom_action_19 -+id accessibility_custom_action_2 -+id accessibility_custom_action_20 -+id accessibility_custom_action_21 -+id accessibility_custom_action_22 -+id accessibility_custom_action_23 -+id accessibility_custom_action_24 -+id accessibility_custom_action_25 -+id accessibility_custom_action_26 -+id accessibility_custom_action_27 -+id accessibility_custom_action_28 -+id accessibility_custom_action_29 -+id accessibility_custom_action_3 -+id accessibility_custom_action_30 -+id accessibility_custom_action_31 -+id accessibility_custom_action_4 -+id accessibility_custom_action_5 -+id accessibility_custom_action_6 -+id accessibility_custom_action_7 -+id accessibility_custom_action_8 -+id accessibility_custom_action_9 -+id accessibility_hint -+id accessibility_label -+id accessibility_links -+id accessibility_role -+id accessibility_state -+id accessibility_value -+id action_bar -+id action_bar_activity_content -+id action_bar_container -+id action_bar_root -+id action_bar_spinner -+id action_bar_subtitle -+id action_bar_title -+id action_container -+id action_context_bar -+id action_divider -+id action_image -+id action_menu_divider -+id action_menu_presenter -+id action_mode_bar -+id action_mode_bar_stub -+id action_mode_close_button -+id action_text -+id actions -+id activity_chooser_view_content -+id add -+id alertTitle -+id async -+id autofill_inline_suggestion_end_icon -+id autofill_inline_suggestion_start_icon -+id autofill_inline_suggestion_subtitle -+id autofill_inline_suggestion_title -+id blocking -+id buttonPanel -+id catalyst_redbox_title -+id center -+id centerCrop -+id centerInside -+id checkbox -+id checked -+id chronometer -+id content -+id contentPanel -+id custom -+id customPanel -+id decor_content_parent -+id default_activity_button -+id dialog_button -+id edit_query -+id expand_activities_button -+id expanded_menu -+id fitBottomStart -+id fitCenter -+id fitEnd -+id fitStart -+id fitXY -+id focusCrop -+id forever -+id fps_text -+id fragment_container_view_tag -+id group_divider -+id home -+id icon -+id icon_group -+id image -+id info -+id italic -+id item1 -+id item2 -+id item3 -+id item4 -+id labelled_by -+id line1 -+id line3 -+id listMode -+id list_item -+id message -+id multiply -+id none -+id normal -+id notification_background -+id notification_main_column -+id notification_main_column_container -+id off -+id on -+id parentPanel -+id pointer_events -+id progress_circular -+id progress_horizontal -+id radio -+id react_test_id -+id right_icon -+id right_side -+id rn_frame_file -+id rn_frame_method -+id rn_redbox_dismiss_button -+id rn_redbox_line_separator -+id rn_redbox_loading_indicator -+id rn_redbox_reload_button -+id rn_redbox_report_button -+id rn_redbox_report_label -+id rn_redbox_stack -+id screen -+id scrollIndicatorDown -+id scrollIndicatorUp -+id scrollView -+id search_badge -+id search_bar -+id search_button -+id search_close_btn -+id search_edit_frame -+id search_go_btn -+id search_mag_icon -+id search_plate -+id search_src_text -+id search_voice_btn -+id select_dialog_listview -+id shortcut -+id spacer -+id special_effects_controller_view_tag -+id split_action_bar -+id src_atop -+id src_in -+id src_over -+id submenuarrow -+id submit_area -+id tabMode -+id tag_accessibility_actions -+id tag_accessibility_clickable_spans -+id tag_accessibility_heading -+id tag_accessibility_pane_title -+id tag_on_apply_window_listener -+id tag_on_receive_content_listener -+id tag_on_receive_content_mime_types -+id tag_screen_reader_focusable -+id tag_state_description -+id tag_transition_group -+id tag_unhandled_key_event_manager -+id tag_unhandled_key_listeners -+id tag_window_insets_animation_callback -+id text -+id text2 -+id textSpacerNoButtons -+id textSpacerNoTitle -+id time -+id title -+id titleDividerNoCustom -+id title_template -+id topPanel -+id unchecked -+id uniform -+id up -+id view_tag_instance_handle -+id view_tag_native_id -+id view_tree_lifecycle_owner -+id view_tree_saved_state_registry_owner -+id view_tree_view_model_store_owner -+id visible_removing_fragment_view_tag -+id wrap_content -+integer abc_config_activityDefaultDur -+integer abc_config_activityShortDur -+integer cancel_button_image_alpha -+integer config_tooltipAnimTime -+integer react_native_dev_server_port -+integer react_native_inspector_proxy_port -+integer status_bar_notification_info_maxnum -+interpolator btn_checkbox_checked_mtrl_animation_interpolator_0 -+interpolator btn_checkbox_checked_mtrl_animation_interpolator_1 -+interpolator btn_checkbox_unchecked_mtrl_animation_interpolator_0 -+interpolator btn_checkbox_unchecked_mtrl_animation_interpolator_1 -+interpolator btn_radio_to_off_mtrl_animation_interpolator_0 -+interpolator btn_radio_to_on_mtrl_animation_interpolator_0 -+interpolator fast_out_slow_in -+layout abc_action_bar_title_item -+layout abc_action_bar_up_container -+layout abc_action_menu_item_layout -+layout abc_action_menu_layout -+layout abc_action_mode_bar -+layout abc_action_mode_close_item_material -+layout abc_activity_chooser_view -+layout abc_activity_chooser_view_list_item -+layout abc_alert_dialog_button_bar_material -+layout abc_alert_dialog_material -+layout abc_alert_dialog_title_material -+layout abc_cascading_menu_item_layout -+layout abc_dialog_title_material -+layout abc_expanded_menu_layout -+layout abc_list_menu_item_checkbox -+layout abc_list_menu_item_icon -+layout abc_list_menu_item_layout -+layout abc_list_menu_item_radio -+layout abc_popup_menu_header_item_layout -+layout abc_popup_menu_item_layout -+layout abc_screen_content_include -+layout abc_screen_simple -+layout abc_screen_simple_overlay_action_mode -+layout abc_screen_toolbar -+layout abc_search_dropdown_item_icons_2line -+layout abc_search_view -+layout abc_select_dialog_material -+layout abc_tooltip -+layout autofill_inline_suggestion -+layout custom_dialog -+layout dev_loading_view -+layout fps_view -+layout notification_action -+layout notification_action_tombstone -+layout notification_template_custom_big -+layout notification_template_icon_group -+layout notification_template_part_chronometer -+layout notification_template_part_time -+layout redbox_item_frame -+layout redbox_item_title -+layout redbox_view -+layout select_dialog_item_material -+layout select_dialog_multichoice_material -+layout select_dialog_singlechoice_material -+layout support_simple_spinner_dropdown_item -+menu example_menu -+menu example_menu2 -+string abc_action_bar_home_description -+string abc_action_bar_up_description -+string abc_action_menu_overflow_description -+string abc_action_mode_done -+string abc_activity_chooser_view_see_all -+string abc_activitychooserview_choose_application -+string abc_capital_off -+string abc_capital_on -+string abc_menu_alt_shortcut_label -+string abc_menu_ctrl_shortcut_label -+string abc_menu_delete_shortcut_label -+string abc_menu_enter_shortcut_label -+string abc_menu_function_shortcut_label -+string abc_menu_meta_shortcut_label -+string abc_menu_shift_shortcut_label -+string abc_menu_space_shortcut_label -+string abc_menu_sym_shortcut_label -+string abc_prepend_shortcut_label -+string abc_search_hint -+string abc_searchview_description_clear -+string abc_searchview_description_query -+string abc_searchview_description_search -+string abc_searchview_description_submit -+string abc_searchview_description_voice -+string abc_shareactionprovider_share_with -+string abc_shareactionprovider_share_with_application -+string abc_toolbar_collapse_description -+string alert_description -+string catalyst_change_bundle_location -+string catalyst_copy_button -+string catalyst_debug -+string catalyst_debug_chrome -+string catalyst_debug_chrome_stop -+string catalyst_debug_connecting -+string catalyst_debug_error -+string catalyst_debug_open -+string catalyst_debug_stop -+string catalyst_devtools_open -+string catalyst_dismiss_button -+string catalyst_heap_capture -+string catalyst_hot_reloading -+string catalyst_hot_reloading_auto_disable -+string catalyst_hot_reloading_auto_enable -+string catalyst_hot_reloading_stop -+string catalyst_inspector -+string catalyst_inspector_stop -+string catalyst_loading_from_url -+string catalyst_open_flipper_error -+string catalyst_perf_monitor -+string catalyst_perf_monitor_stop -+string catalyst_reload -+string catalyst_reload_button -+string catalyst_reload_error -+string catalyst_report_button -+string catalyst_sample_profiler_disable -+string catalyst_sample_profiler_enable -+string catalyst_settings -+string catalyst_settings_title -+string combobox_description -+string header_description -+string image_description -+string imagebutton_description -+string link_description -+string menu_description -+string menubar_description -+string menuitem_description -+string progressbar_description -+string radiogroup_description -+string rn_tab_description -+string scrollbar_description -+string search_menu_title -+string spinbutton_description -+string state_busy_description -+string state_collapsed_description -+string state_expanded_description -+string state_mixed_description -+string state_off_description -+string state_on_description -+string state_unselected_description -+string status_bar_notification_info_overflow -+string summary_description -+string tablist_description -+string timer_description -+string toolbar_description -+style AlertDialog_AppCompat -+style AlertDialog_AppCompat_Light -+style Animation_AppCompat_Dialog -+style Animation_AppCompat_DropDownUp -+style Animation_AppCompat_Tooltip -+style Animation_Catalyst_LogBox -+style Animation_Catalyst_RedBox -+style Base_AlertDialog_AppCompat -+style Base_AlertDialog_AppCompat_Light -+style Base_Animation_AppCompat_Dialog -+style Base_Animation_AppCompat_DropDownUp -+style Base_Animation_AppCompat_Tooltip -+style Base_DialogWindowTitleBackground_AppCompat -+style Base_DialogWindowTitle_AppCompat -+style Base_TextAppearance_AppCompat -+style Base_TextAppearance_AppCompat_Body1 -+style Base_TextAppearance_AppCompat_Body2 -+style Base_TextAppearance_AppCompat_Button -+style Base_TextAppearance_AppCompat_Caption -+style Base_TextAppearance_AppCompat_Display1 -+style Base_TextAppearance_AppCompat_Display2 -+style Base_TextAppearance_AppCompat_Display3 -+style Base_TextAppearance_AppCompat_Display4 -+style Base_TextAppearance_AppCompat_Headline -+style Base_TextAppearance_AppCompat_Inverse -+style Base_TextAppearance_AppCompat_Large -+style Base_TextAppearance_AppCompat_Large_Inverse -+style Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Large -+style Base_TextAppearance_AppCompat_Light_Widget_PopupMenu_Small -+style Base_TextAppearance_AppCompat_Medium -+style Base_TextAppearance_AppCompat_Medium_Inverse -+style Base_TextAppearance_AppCompat_Menu -+style Base_TextAppearance_AppCompat_SearchResult -+style Base_TextAppearance_AppCompat_SearchResult_Subtitle -+style Base_TextAppearance_AppCompat_SearchResult_Title -+style Base_TextAppearance_AppCompat_Small -+style Base_TextAppearance_AppCompat_Small_Inverse -+style Base_TextAppearance_AppCompat_Subhead -+style Base_TextAppearance_AppCompat_Subhead_Inverse -+style Base_TextAppearance_AppCompat_Title -+style Base_TextAppearance_AppCompat_Title_Inverse -+style Base_TextAppearance_AppCompat_Tooltip -+style Base_TextAppearance_AppCompat_Widget_ActionBar_Menu -+style Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle -+style Base_TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse -+style Base_TextAppearance_AppCompat_Widget_ActionBar_Title -+style Base_TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse -+style Base_TextAppearance_AppCompat_Widget_ActionMode_Subtitle -+style Base_TextAppearance_AppCompat_Widget_ActionMode_Title -+style Base_TextAppearance_AppCompat_Widget_Button -+style Base_TextAppearance_AppCompat_Widget_Button_Borderless_Colored -+style Base_TextAppearance_AppCompat_Widget_Button_Colored -+style Base_TextAppearance_AppCompat_Widget_Button_Inverse -+style Base_TextAppearance_AppCompat_Widget_DropDownItem -+style Base_TextAppearance_AppCompat_Widget_PopupMenu_Header -+style Base_TextAppearance_AppCompat_Widget_PopupMenu_Large -+style Base_TextAppearance_AppCompat_Widget_PopupMenu_Small -+style Base_TextAppearance_AppCompat_Widget_Switch -+style Base_TextAppearance_AppCompat_Widget_TextView_SpinnerItem -+style Base_TextAppearance_Widget_AppCompat_ExpandedMenu_Item -+style Base_TextAppearance_Widget_AppCompat_Toolbar_Subtitle -+style Base_TextAppearance_Widget_AppCompat_Toolbar_Title -+style Base_ThemeOverlay_AppCompat -+style Base_ThemeOverlay_AppCompat_ActionBar -+style Base_ThemeOverlay_AppCompat_Dark -+style Base_ThemeOverlay_AppCompat_Dark_ActionBar -+style Base_ThemeOverlay_AppCompat_Dialog -+style Base_ThemeOverlay_AppCompat_Dialog_Alert -+style Base_ThemeOverlay_AppCompat_Light -+style Base_Theme_AppCompat -+style Base_Theme_AppCompat_CompactMenu -+style Base_Theme_AppCompat_Dialog -+style Base_Theme_AppCompat_DialogWhenLarge -+style Base_Theme_AppCompat_Dialog_Alert -+style Base_Theme_AppCompat_Dialog_FixedSize -+style Base_Theme_AppCompat_Dialog_MinWidth -+style Base_Theme_AppCompat_Light -+style Base_Theme_AppCompat_Light_DarkActionBar -+style Base_Theme_AppCompat_Light_Dialog -+style Base_Theme_AppCompat_Light_DialogWhenLarge -+style Base_Theme_AppCompat_Light_Dialog_Alert -+style Base_Theme_AppCompat_Light_Dialog_FixedSize -+style Base_Theme_AppCompat_Light_Dialog_MinWidth -+style Base_V21_ThemeOverlay_AppCompat_Dialog -+style Base_V21_Theme_AppCompat -+style Base_V21_Theme_AppCompat_Dialog -+style Base_V21_Theme_AppCompat_Light -+style Base_V21_Theme_AppCompat_Light_Dialog -+style Base_V22_Theme_AppCompat -+style Base_V22_Theme_AppCompat_Light -+style Base_V23_Theme_AppCompat -+style Base_V23_Theme_AppCompat_Light -+style Base_V26_Theme_AppCompat -+style Base_V26_Theme_AppCompat_Light -+style Base_V26_Widget_AppCompat_Toolbar -+style Base_V28_Theme_AppCompat -+style Base_V28_Theme_AppCompat_Light -+style Base_V7_ThemeOverlay_AppCompat_Dialog -+style Base_V7_Theme_AppCompat -+style Base_V7_Theme_AppCompat_Dialog -+style Base_V7_Theme_AppCompat_Light -+style Base_V7_Theme_AppCompat_Light_Dialog -+style Base_V7_Widget_AppCompat_AutoCompleteTextView -+style Base_V7_Widget_AppCompat_EditText -+style Base_V7_Widget_AppCompat_Toolbar -+style Base_Widget_AppCompat_ActionBar -+style Base_Widget_AppCompat_ActionBar_Solid -+style Base_Widget_AppCompat_ActionBar_TabBar -+style Base_Widget_AppCompat_ActionBar_TabText -+style Base_Widget_AppCompat_ActionBar_TabView -+style Base_Widget_AppCompat_ActionButton -+style Base_Widget_AppCompat_ActionButton_CloseMode -+style Base_Widget_AppCompat_ActionButton_Overflow -+style Base_Widget_AppCompat_ActionMode -+style Base_Widget_AppCompat_ActivityChooserView -+style Base_Widget_AppCompat_AutoCompleteTextView -+style Base_Widget_AppCompat_Button -+style Base_Widget_AppCompat_ButtonBar -+style Base_Widget_AppCompat_ButtonBar_AlertDialog -+style Base_Widget_AppCompat_Button_Borderless -+style Base_Widget_AppCompat_Button_Borderless_Colored -+style Base_Widget_AppCompat_Button_ButtonBar_AlertDialog -+style Base_Widget_AppCompat_Button_Colored -+style Base_Widget_AppCompat_Button_Small -+style Base_Widget_AppCompat_CompoundButton_CheckBox -+style Base_Widget_AppCompat_CompoundButton_RadioButton -+style Base_Widget_AppCompat_CompoundButton_Switch -+style Base_Widget_AppCompat_DrawerArrowToggle -+style Base_Widget_AppCompat_DrawerArrowToggle_Common -+style Base_Widget_AppCompat_DropDownItem_Spinner -+style Base_Widget_AppCompat_EditText -+style Base_Widget_AppCompat_ImageButton -+style Base_Widget_AppCompat_Light_ActionBar -+style Base_Widget_AppCompat_Light_ActionBar_Solid -+style Base_Widget_AppCompat_Light_ActionBar_TabBar -+style Base_Widget_AppCompat_Light_ActionBar_TabText -+style Base_Widget_AppCompat_Light_ActionBar_TabText_Inverse -+style Base_Widget_AppCompat_Light_ActionBar_TabView -+style Base_Widget_AppCompat_Light_PopupMenu -+style Base_Widget_AppCompat_Light_PopupMenu_Overflow -+style Base_Widget_AppCompat_ListMenuView -+style Base_Widget_AppCompat_ListPopupWindow -+style Base_Widget_AppCompat_ListView -+style Base_Widget_AppCompat_ListView_DropDown -+style Base_Widget_AppCompat_ListView_Menu -+style Base_Widget_AppCompat_PopupMenu -+style Base_Widget_AppCompat_PopupMenu_Overflow -+style Base_Widget_AppCompat_PopupWindow -+style Base_Widget_AppCompat_ProgressBar -+style Base_Widget_AppCompat_ProgressBar_Horizontal -+style Base_Widget_AppCompat_RatingBar -+style Base_Widget_AppCompat_RatingBar_Indicator -+style Base_Widget_AppCompat_RatingBar_Small -+style Base_Widget_AppCompat_SearchView -+style Base_Widget_AppCompat_SearchView_ActionBar -+style Base_Widget_AppCompat_SeekBar -+style Base_Widget_AppCompat_SeekBar_Discrete -+style Base_Widget_AppCompat_Spinner -+style Base_Widget_AppCompat_Spinner_Underlined -+style Base_Widget_AppCompat_TextView -+style Base_Widget_AppCompat_TextView_SpinnerItem -+style Base_Widget_AppCompat_Toolbar -+style Base_Widget_AppCompat_Toolbar_Button_Navigation -+style CalendarDatePickerDialog -+style CalendarDatePickerStyle -+style DialogAnimationFade -+style DialogAnimationSlide -+style Platform_AppCompat -+style Platform_AppCompat_Light -+style Platform_ThemeOverlay_AppCompat -+style Platform_ThemeOverlay_AppCompat_Dark -+style Platform_ThemeOverlay_AppCompat_Light -+style Platform_V21_AppCompat -+style Platform_V21_AppCompat_Light -+style Platform_V25_AppCompat -+style Platform_V25_AppCompat_Light -+style Platform_Widget_AppCompat_Spinner -+style RtlOverlay_DialogWindowTitle_AppCompat -+style RtlOverlay_Widget_AppCompat_ActionBar_TitleItem -+style RtlOverlay_Widget_AppCompat_DialogTitle_Icon -+style RtlOverlay_Widget_AppCompat_PopupMenuItem -+style RtlOverlay_Widget_AppCompat_PopupMenuItem_InternalGroup -+style RtlOverlay_Widget_AppCompat_PopupMenuItem_Shortcut -+style RtlOverlay_Widget_AppCompat_PopupMenuItem_SubmenuArrow -+style RtlOverlay_Widget_AppCompat_PopupMenuItem_Text -+style RtlOverlay_Widget_AppCompat_PopupMenuItem_Title -+style RtlOverlay_Widget_AppCompat_SearchView_MagIcon -+style RtlOverlay_Widget_AppCompat_Search_DropDown -+style RtlOverlay_Widget_AppCompat_Search_DropDown_Icon1 -+style RtlOverlay_Widget_AppCompat_Search_DropDown_Icon2 -+style RtlOverlay_Widget_AppCompat_Search_DropDown_Query -+style RtlOverlay_Widget_AppCompat_Search_DropDown_Text -+style RtlUnderlay_Widget_AppCompat_ActionButton -+style RtlUnderlay_Widget_AppCompat_ActionButton_Overflow -+style SpinnerDatePickerDialog -+style SpinnerDatePickerStyle -+style TextAppearance_AppCompat -+style TextAppearance_AppCompat_Body1 -+style TextAppearance_AppCompat_Body2 -+style TextAppearance_AppCompat_Button -+style TextAppearance_AppCompat_Caption -+style TextAppearance_AppCompat_Display1 -+style TextAppearance_AppCompat_Display2 -+style TextAppearance_AppCompat_Display3 -+style TextAppearance_AppCompat_Display4 -+style TextAppearance_AppCompat_Headline -+style TextAppearance_AppCompat_Inverse -+style TextAppearance_AppCompat_Large -+style TextAppearance_AppCompat_Large_Inverse -+style TextAppearance_AppCompat_Light_SearchResult_Subtitle -+style TextAppearance_AppCompat_Light_SearchResult_Title -+style TextAppearance_AppCompat_Light_Widget_PopupMenu_Large -+style TextAppearance_AppCompat_Light_Widget_PopupMenu_Small -+style TextAppearance_AppCompat_Medium -+style TextAppearance_AppCompat_Medium_Inverse -+style TextAppearance_AppCompat_Menu -+style TextAppearance_AppCompat_SearchResult_Subtitle -+style TextAppearance_AppCompat_SearchResult_Title -+style TextAppearance_AppCompat_Small -+style TextAppearance_AppCompat_Small_Inverse -+style TextAppearance_AppCompat_Subhead -+style TextAppearance_AppCompat_Subhead_Inverse -+style TextAppearance_AppCompat_Title -+style TextAppearance_AppCompat_Title_Inverse -+style TextAppearance_AppCompat_Tooltip -+style TextAppearance_AppCompat_Widget_ActionBar_Menu -+style TextAppearance_AppCompat_Widget_ActionBar_Subtitle -+style TextAppearance_AppCompat_Widget_ActionBar_Subtitle_Inverse -+style TextAppearance_AppCompat_Widget_ActionBar_Title -+style TextAppearance_AppCompat_Widget_ActionBar_Title_Inverse -+style TextAppearance_AppCompat_Widget_ActionMode_Subtitle -+style TextAppearance_AppCompat_Widget_ActionMode_Subtitle_Inverse -+style TextAppearance_AppCompat_Widget_ActionMode_Title -+style TextAppearance_AppCompat_Widget_ActionMode_Title_Inverse -+style TextAppearance_AppCompat_Widget_Button -+style TextAppearance_AppCompat_Widget_Button_Borderless_Colored -+style TextAppearance_AppCompat_Widget_Button_Colored -+style TextAppearance_AppCompat_Widget_Button_Inverse -+style TextAppearance_AppCompat_Widget_DropDownItem -+style TextAppearance_AppCompat_Widget_PopupMenu_Header -+style TextAppearance_AppCompat_Widget_PopupMenu_Large -+style TextAppearance_AppCompat_Widget_PopupMenu_Small -+style TextAppearance_AppCompat_Widget_Switch -+style TextAppearance_AppCompat_Widget_TextView_SpinnerItem -+style TextAppearance_Compat_Notification -+style TextAppearance_Compat_Notification_Info -+style TextAppearance_Compat_Notification_Line2 -+style TextAppearance_Compat_Notification_Time -+style TextAppearance_Compat_Notification_Title -+style TextAppearance_Widget_AppCompat_ExpandedMenu_Item -+style TextAppearance_Widget_AppCompat_Toolbar_Subtitle -+style TextAppearance_Widget_AppCompat_Toolbar_Title -+style Theme -+style ThemeOverlay_AppCompat -+style ThemeOverlay_AppCompat_ActionBar -+style ThemeOverlay_AppCompat_Dark -+style ThemeOverlay_AppCompat_Dark_ActionBar -+style ThemeOverlay_AppCompat_DayNight -+style ThemeOverlay_AppCompat_DayNight_ActionBar -+style ThemeOverlay_AppCompat_Dialog -+style ThemeOverlay_AppCompat_Dialog_Alert -+style ThemeOverlay_AppCompat_Light -+style Theme_AppCompat -+style Theme_AppCompat_CompactMenu -+style Theme_AppCompat_DayNight -+style Theme_AppCompat_DayNight_DarkActionBar -+style Theme_AppCompat_DayNight_Dialog -+style Theme_AppCompat_DayNight_DialogWhenLarge -+style Theme_AppCompat_DayNight_Dialog_Alert -+style Theme_AppCompat_DayNight_Dialog_MinWidth -+style Theme_AppCompat_DayNight_NoActionBar -+style Theme_AppCompat_Dialog -+style Theme_AppCompat_DialogWhenLarge -+style Theme_AppCompat_Dialog_Alert -+style Theme_AppCompat_Dialog_MinWidth -+style Theme_AppCompat_Empty -+style Theme_AppCompat_Light -+style Theme_AppCompat_Light_DarkActionBar -+style Theme_AppCompat_Light_Dialog -+style Theme_AppCompat_Light_DialogWhenLarge -+style Theme_AppCompat_Light_Dialog_Alert -+style Theme_AppCompat_Light_Dialog_MinWidth -+style Theme_AppCompat_Light_NoActionBar -+style Theme_AppCompat_NoActionBar -+style Theme_AutofillInlineSuggestion -+style Theme_Catalyst -+style Theme_Catalyst_LogBox -+style Theme_Catalyst_RedBox -+style Theme_FullScreenDialog -+style Theme_FullScreenDialogAnimatedFade -+style Theme_FullScreenDialogAnimatedSlide -+style Theme_ReactNative_AppCompat_Light -+style Theme_ReactNative_AppCompat_Light_NoActionBar_FullScreen -+style Widget_AppCompat_ActionBar -+style Widget_AppCompat_ActionBar_Solid -+style Widget_AppCompat_ActionBar_TabBar -+style Widget_AppCompat_ActionBar_TabText -+style Widget_AppCompat_ActionBar_TabView -+style Widget_AppCompat_ActionButton -+style Widget_AppCompat_ActionButton_CloseMode -+style Widget_AppCompat_ActionButton_Overflow -+style Widget_AppCompat_ActionMode -+style Widget_AppCompat_ActivityChooserView -+style Widget_AppCompat_AutoCompleteTextView -+style Widget_AppCompat_Button -+style Widget_AppCompat_ButtonBar -+style Widget_AppCompat_ButtonBar_AlertDialog -+style Widget_AppCompat_Button_Borderless -+style Widget_AppCompat_Button_Borderless_Colored -+style Widget_AppCompat_Button_ButtonBar_AlertDialog -+style Widget_AppCompat_Button_Colored -+style Widget_AppCompat_Button_Small -+style Widget_AppCompat_CompoundButton_CheckBox -+style Widget_AppCompat_CompoundButton_RadioButton -+style Widget_AppCompat_CompoundButton_Switch -+style Widget_AppCompat_DrawerArrowToggle -+style Widget_AppCompat_DropDownItem_Spinner -+style Widget_AppCompat_EditText -+style Widget_AppCompat_ImageButton -+style Widget_AppCompat_Light_ActionBar -+style Widget_AppCompat_Light_ActionBar_Solid -+style Widget_AppCompat_Light_ActionBar_Solid_Inverse -+style Widget_AppCompat_Light_ActionBar_TabBar -+style Widget_AppCompat_Light_ActionBar_TabBar_Inverse -+style Widget_AppCompat_Light_ActionBar_TabText -+style Widget_AppCompat_Light_ActionBar_TabText_Inverse -+style Widget_AppCompat_Light_ActionBar_TabView -+style Widget_AppCompat_Light_ActionBar_TabView_Inverse -+style Widget_AppCompat_Light_ActionButton -+style Widget_AppCompat_Light_ActionButton_CloseMode -+style Widget_AppCompat_Light_ActionButton_Overflow -+style Widget_AppCompat_Light_ActionMode_Inverse -+style Widget_AppCompat_Light_ActivityChooserView -+style Widget_AppCompat_Light_AutoCompleteTextView -+style Widget_AppCompat_Light_DropDownItem_Spinner -+style Widget_AppCompat_Light_ListPopupWindow -+style Widget_AppCompat_Light_ListView_DropDown -+style Widget_AppCompat_Light_PopupMenu -+style Widget_AppCompat_Light_PopupMenu_Overflow -+style Widget_AppCompat_Light_SearchView -+style Widget_AppCompat_Light_Spinner_DropDown_ActionBar -+style Widget_AppCompat_ListMenuView -+style Widget_AppCompat_ListPopupWindow -+style Widget_AppCompat_ListView -+style Widget_AppCompat_ListView_DropDown -+style Widget_AppCompat_ListView_Menu -+style Widget_AppCompat_PopupMenu -+style Widget_AppCompat_PopupMenu_Overflow -+style Widget_AppCompat_PopupWindow -+style Widget_AppCompat_ProgressBar -+style Widget_AppCompat_ProgressBar_Horizontal -+style Widget_AppCompat_RatingBar -+style Widget_AppCompat_RatingBar_Indicator -+style Widget_AppCompat_RatingBar_Small -+style Widget_AppCompat_SearchView -+style Widget_AppCompat_SearchView_ActionBar -+style Widget_AppCompat_SeekBar -+style Widget_AppCompat_SeekBar_Discrete -+style Widget_AppCompat_Spinner -+style Widget_AppCompat_Spinner_DropDown -+style Widget_AppCompat_Spinner_DropDown_ActionBar -+style Widget_AppCompat_Spinner_Underlined -+style Widget_AppCompat_TextView -+style Widget_AppCompat_TextView_SpinnerItem -+style Widget_AppCompat_Toolbar -+style Widget_AppCompat_Toolbar_Button_Navigation -+style Widget_Autofill -+style Widget_Autofill_InlineSuggestionChip -+style Widget_Autofill_InlineSuggestionEndIconStyle -+style Widget_Autofill_InlineSuggestionStartIconStyle -+style Widget_Autofill_InlineSuggestionSubtitle -+style Widget_Autofill_InlineSuggestionTitle -+style Widget_Compat_NotificationActionContainer -+style Widget_Compat_NotificationActionText -+style redboxButton -+styleable ActionBar background backgroundSplit backgroundStacked contentInsetEnd contentInsetEndWithActions contentInsetLeft contentInsetRight contentInsetStart contentInsetStartWithNavigation customNavigationLayout displayOptions divider elevation height hideOnContentScroll homeAsUpIndicator homeLayout icon indeterminateProgressStyle itemPadding logo navigationMode popupTheme progressBarPadding progressBarStyle subtitle subtitleTextStyle title titleTextStyle -+styleable ActionBarLayout android_layout_gravity -+styleable ActionMenuItemView android_minWidth -+styleable ActionMenuView -+styleable ActionMode background backgroundSplit closeItemLayout height subtitleTextStyle titleTextStyle -+styleable ActivityChooserView expandActivityOverflowButtonDrawable initialActivityCount -+styleable AlertDialog android_layout buttonIconDimen buttonPanelSideLayout listItemLayout listLayout multiChoiceItemLayout showTitle singleChoiceItemLayout -+styleable AnimatedStateListDrawableCompat android_constantSize android_dither android_enterFadeDuration android_exitFadeDuration android_variablePadding android_visible -+styleable AnimatedStateListDrawableItem android_drawable android_id -+styleable AnimatedStateListDrawableTransition android_drawable android_fromId android_reversible android_toId -+styleable AppCompatEmojiHelper -+styleable AppCompatImageView android_src srcCompat tint tintMode -+styleable AppCompatSeekBar android_thumb tickMark tickMarkTint tickMarkTintMode -+styleable AppCompatTextHelper android_drawableBottom android_drawableEnd android_drawableLeft android_drawableRight android_drawableStart android_drawableTop android_textAppearance -+styleable AppCompatTextView android_textAppearance autoSizeMaxTextSize autoSizeMinTextSize autoSizePresetSizes autoSizeStepGranularity autoSizeTextType drawableBottomCompat drawableEndCompat drawableLeftCompat drawableRightCompat drawableStartCompat drawableTint drawableTintMode drawableTopCompat emojiCompatEnabled firstBaselineToTopHeight fontFamily fontVariationSettings lastBaselineToBottomHeight lineHeight textAllCaps textLocale -+styleable AppCompatTheme actionBarDivider actionBarItemBackground actionBarPopupTheme actionBarSize actionBarSplitStyle actionBarStyle actionBarTabBarStyle actionBarTabStyle actionBarTabTextStyle actionBarTheme actionBarWidgetTheme actionButtonStyle actionDropDownStyle actionMenuTextAppearance actionMenuTextColor actionModeBackground actionModeCloseButtonStyle actionModeCloseContentDescription actionModeCloseDrawable actionModeCopyDrawable actionModeCutDrawable actionModeFindDrawable actionModePasteDrawable actionModePopupWindowStyle actionModeSelectAllDrawable actionModeShareDrawable actionModeSplitBackground actionModeStyle actionModeTheme actionModeWebSearchDrawable actionOverflowButtonStyle actionOverflowMenuStyle activityChooserViewStyle alertDialogButtonGroupStyle alertDialogCenterButtons alertDialogStyle alertDialogTheme android_windowAnimationStyle android_windowIsFloating autoCompleteTextViewStyle borderlessButtonStyle buttonBarButtonStyle buttonBarNegativeButtonStyle buttonBarNeutralButtonStyle buttonBarPositiveButtonStyle buttonBarStyle buttonStyle buttonStyleSmall checkboxStyle checkedTextViewStyle colorAccent colorBackgroundFloating colorButtonNormal colorControlActivated colorControlHighlight colorControlNormal colorError colorPrimary colorPrimaryDark colorSwitchThumbNormal controlBackground dialogCornerRadius dialogPreferredPadding dialogTheme dividerHorizontal dividerVertical dropDownListViewStyle dropdownListPreferredItemHeight editTextBackground editTextColor editTextStyle homeAsUpIndicator imageButtonStyle listChoiceBackgroundIndicator listChoiceIndicatorMultipleAnimated listChoiceIndicatorSingleAnimated listDividerAlertDialog listMenuViewStyle listPopupWindowStyle listPreferredItemHeight listPreferredItemHeightLarge listPreferredItemHeightSmall listPreferredItemPaddingEnd listPreferredItemPaddingLeft listPreferredItemPaddingRight listPreferredItemPaddingStart panelBackground panelMenuListTheme panelMenuListWidth popupMenuStyle popupWindowStyle radioButtonStyle ratingBarStyle ratingBarStyleIndicator ratingBarStyleSmall searchViewStyle seekBarStyle selectableItemBackground selectableItemBackgroundBorderless spinnerDropDownItemStyle spinnerStyle switchStyle textAppearanceLargePopupMenu textAppearanceListItem textAppearanceListItemSecondary textAppearanceListItemSmall textAppearancePopupMenuHeader textAppearanceSearchResultSubtitle textAppearanceSearchResultTitle textAppearanceSmallPopupMenu textColorAlertDialogListItem textColorSearchUrl toolbarNavigationButtonStyle toolbarStyle tooltipForegroundColor tooltipFrameBackground viewInflaterClass windowActionBar windowActionBarOverlay windowActionModeOverlay windowFixedHeightMajor windowFixedHeightMinor windowFixedWidthMajor windowFixedWidthMinor windowMinWidthMajor windowMinWidthMinor windowNoTitle -+styleable Autofill_InlineSuggestion autofillInlineSuggestionChip autofillInlineSuggestionEndIconStyle autofillInlineSuggestionStartIconStyle autofillInlineSuggestionSubtitle autofillInlineSuggestionTitle isAutofillInlineSuggestionTheme -+styleable ButtonBarLayout allowStacking -+styleable Capability queryPatterns shortcutMatchRequired -+styleable CheckedTextView android_checkMark checkMarkCompat checkMarkTint checkMarkTintMode -+styleable ColorStateListItem alpha android_alpha android_color android_lStar lStar -+styleable CompoundButton android_button buttonCompat buttonTint buttonTintMode -+styleable DrawerArrowToggle arrowHeadLength arrowShaftLength barLength color drawableSize gapBetweenBars spinBars thickness -+styleable FontFamily fontProviderAuthority fontProviderCerts fontProviderFetchStrategy fontProviderFetchTimeout fontProviderPackage fontProviderQuery fontProviderSystemFontFamily -+styleable FontFamilyFont android_font android_fontStyle android_fontVariationSettings android_fontWeight android_ttcIndex font fontStyle fontVariationSettings fontWeight ttcIndex -+styleable Fragment android_id android_name android_tag -+styleable FragmentContainerView android_name android_tag -+styleable GenericDraweeHierarchy actualImageScaleType backgroundImage fadeDuration failureImage failureImageScaleType overlayImage placeholderImage placeholderImageScaleType pressedStateOverlayImage progressBarAutoRotateInterval progressBarImage progressBarImageScaleType retryImage retryImageScaleType roundAsCircle roundBottomEnd roundBottomLeft roundBottomRight roundBottomStart roundTopEnd roundTopLeft roundTopRight roundTopStart roundWithOverlayColor roundedCornerRadius roundingBorderColor roundingBorderPadding roundingBorderWidth viewAspectRatio -+styleable GradientColor android_centerColor android_centerX android_centerY android_endColor android_endX android_endY android_gradientRadius android_startColor android_startX android_startY android_tileMode android_type -+styleable GradientColorItem android_color android_offset -+styleable LinearLayoutCompat android_baselineAligned android_baselineAlignedChildIndex android_gravity android_orientation android_weightSum divider dividerPadding measureWithLargestChild showDividers -+styleable LinearLayoutCompat_Layout android_layout_gravity android_layout_height android_layout_weight android_layout_width -+styleable ListPopupWindow android_dropDownHorizontalOffset android_dropDownVerticalOffset -+styleable MenuGroup android_checkableBehavior android_enabled android_id android_menuCategory android_orderInCategory android_visible -+styleable MenuItem actionLayout actionProviderClass actionViewClass alphabeticModifiers android_alphabeticShortcut android_checkable android_checked android_enabled android_icon android_id android_menuCategory android_numericShortcut android_onClick android_orderInCategory android_title android_titleCondensed android_visible contentDescription iconTint iconTintMode numericModifiers showAsAction tooltipText -+styleable MenuView android_headerBackground android_horizontalDivider android_itemBackground android_itemIconDisabledAlpha android_itemTextAppearance android_verticalDivider android_windowAnimationStyle preserveIconSpacing subMenuArrow -+styleable PopupWindow android_popupAnimationStyle android_popupBackground overlapAnchor -+styleable PopupWindowBackgroundState state_above_anchor -+styleable RecycleListView paddingBottomNoButtons paddingTopNoTitle -+styleable SearchView android_focusable android_imeOptions android_inputType android_maxWidth closeIcon commitIcon defaultQueryHint goIcon iconifiedByDefault layout queryBackground queryHint searchHintIcon searchIcon submitBackground suggestionRowLayout voiceIcon -+styleable SimpleDraweeView actualImageResource actualImageScaleType actualImageUri backgroundImage fadeDuration failureImage failureImageScaleType overlayImage placeholderImage placeholderImageScaleType pressedStateOverlayImage progressBarAutoRotateInterval progressBarImage progressBarImageScaleType retryImage retryImageScaleType roundAsCircle roundBottomEnd roundBottomLeft roundBottomRight roundBottomStart roundTopEnd roundTopLeft roundTopRight roundTopStart roundWithOverlayColor roundedCornerRadius roundingBorderColor roundingBorderPadding roundingBorderWidth viewAspectRatio -+styleable Spinner android_dropDownWidth android_entries android_popupBackground android_prompt popupTheme -+styleable StateListDrawable android_constantSize android_dither android_enterFadeDuration android_exitFadeDuration android_variablePadding android_visible -+styleable StateListDrawableItem android_drawable -+styleable SwitchCompat android_textOff android_textOn android_thumb showText splitTrack switchMinWidth switchPadding switchTextAppearance thumbTextPadding thumbTint thumbTintMode track trackTint trackTintMode -+styleable TextAppearance android_fontFamily android_shadowColor android_shadowDx android_shadowDy android_shadowRadius android_textColor android_textColorHint android_textColorLink android_textFontWeight android_textSize android_textStyle android_typeface fontFamily fontVariationSettings textAllCaps textLocale -+styleable Toolbar android_gravity android_minHeight buttonGravity collapseContentDescription collapseIcon contentInsetEnd contentInsetEndWithActions contentInsetLeft contentInsetRight contentInsetStart contentInsetStartWithNavigation logo logoDescription maxButtonHeight menu navigationContentDescription navigationIcon popupTheme subtitle subtitleTextAppearance subtitleTextColor title titleMargin titleMarginBottom titleMarginEnd titleMarginStart titleMarginTop titleMargins titleTextAppearance titleTextColor -+styleable View android_focusable android_theme paddingEnd paddingStart theme -+styleable ViewBackgroundHelper android_background backgroundTint backgroundTintMode -+styleable ViewStubCompat android_id android_inflatedId android_layout -+xml rn_dev_preferences -diff --git a/node_modules/@mattermost/react-native-paste-input/android/build/outputs/logs/manifest-merger-debug-report.txt b/node_modules/@mattermost/react-native-paste-input/android/build/outputs/logs/manifest-merger-debug-report.txt -new file mode 100644 -index 0000000..f153aa0 ---- /dev/null -+++ b/node_modules/@mattermost/react-native-paste-input/android/build/outputs/logs/manifest-merger-debug-report.txt -@@ -0,0 +1,25 @@ -+-- Merging decision tree log --- -+manifest -+ADDED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml:1:1-4:12 -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml:1:1-4:12 -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml:1:1-4:12 -+ package -+ ADDED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml:2:11-46 -+ INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ xmlns:android -+ ADDED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml:1:11-69 -+uses-sdk -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml reason: use-sdk injection requested -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ android:targetSdkVersion -+ INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ ADDED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ android:minSdkVersion -+ INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ ADDED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -+ INJECTED from /Users/john/projects/professional/bluesky/social-app/node_modules/@mattermost/react-native-paste-input/android/src/main/AndroidManifest.xml -diff --git a/node_modules/@mattermost/react-native-paste-input/android/gradle.properties b/node_modules/@mattermost/react-native-paste-input/android/gradle.properties -index 19b61ff..04a9951 100644 ---- a/node_modules/@mattermost/react-native-paste-input/android/gradle.properties -+++ b/node_modules/@mattermost/react-native-paste-input/android/gradle.properties -@@ -1,4 +1,4 @@ --PasteInput_kotlinVersion=1.3.50 -+PasteInput_kotlinVersion=1.5.20 - PasteInput_compileSdkVersion=30 - PasteInput_buildToolsVersion=30.0.2 - PasteInput_targetSdkVersion=30 -diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m b/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m -index e916023..0564d97 100644 ---- a/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m -+++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m -@@ -22,6 +22,11 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge - _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _backedTextInputView.textInputDelegate = self; - -+ // Disable inline predictions to prevent jank in the composer -+ if (@available(iOS 17.0, *)) { -+ _backedTextInputView.inlinePredictionType = UITextInlinePredictionTypeNo; -+ } -+ - [self addSubview:_backedTextInputView]; - } - diff --git a/patches/@mattermost+react-native-paste-input+0.7.1.patch b/patches/@mattermost+react-native-paste-input+0.7.1.patch new file mode 100644 index 0000000000..dbf55b0959 --- /dev/null +++ b/patches/@mattermost+react-native-paste-input+0.7.1.patch @@ -0,0 +1,16 @@ +diff --git a/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m b/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m +index e916023..0564d97 100644 +--- a/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m ++++ b/node_modules/@mattermost/react-native-paste-input/ios/PasteInputView.m +@@ -22,6 +22,11 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge + _backedTextInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _backedTextInputView.textInputDelegate = self; + ++ // Disable inline predictions to prevent jank in the composer ++ if (@available(iOS 17.0, *)) { ++ _backedTextInputView.inlinePredictionType = UITextInlinePredictionTypeNo; ++ } ++ + [self addSubview:_backedTextInputView]; + } + diff --git a/patches/expo-image-picker+14.7.1.patch b/patches/expo-image-picker+14.7.1.patch deleted file mode 100644 index 046eb4f4f3..0000000000 --- a/patches/expo-image-picker+14.7.1.patch +++ /dev/null @@ -1,112 +0,0 @@ -diff --git a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt -index 3f50f8c..ee47fa1 100644 ---- a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt -+++ b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/ImagePickerModule.kt -@@ -33,7 +33,9 @@ import kotlin.coroutines.resumeWithException - // TODO(@bbarthec): rename to ExpoImagePicker - private const val moduleName = "ExponentImagePicker" - -+ - class ImagePickerModule : Module() { -+ private var isPickerOpen = false - - override fun definition() = ModuleDefinition { - Name(moduleName) -@@ -129,6 +131,11 @@ class ImagePickerModule : Module() { - options: ImagePickerOptions - ): Any { - return try { -+ if(isPickerOpen) { -+ return ImagePickerResponse(canceled = true) -+ } -+ -+ isPickerOpen = true - var result = launchPicker(pickerLauncher) - if ( - !options.allowsMultipleSelection && -@@ -143,6 +150,8 @@ class ImagePickerModule : Module() { - mediaHandler.readExtras(result.data, options) - } catch (cause: OperationCanceledException) { - return ImagePickerResponse(canceled = true) -+ } finally { -+ isPickerOpen = false - } - } - -diff --git a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt -index ff15c91..9763012 100644 ---- a/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt -+++ b/node_modules/expo-image-picker/android/src/main/java/expo/modules/imagepicker/contracts/ImageLibraryContract.kt -@@ -5,12 +5,7 @@ import android.content.ContentResolver - import android.content.Context - import android.content.Intent - import android.net.Uri --import androidx.activity.result.PickVisualMediaRequest --import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia --import androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia - import expo.modules.imagepicker.ImagePickerOptions --import expo.modules.imagepicker.MediaTypes --import expo.modules.imagepicker.UNLIMITED_SELECTION - import expo.modules.imagepicker.getAllDataUris - import expo.modules.imagepicker.toMediaType - import expo.modules.kotlin.activityresult.AppContextActivityResultContract -@@ -26,51 +21,26 @@ import java.io.Serializable - * @see [androidx.activity.result.contract.ActivityResultContracts.GetMultipleContents] - */ - internal class ImageLibraryContract( -- private val appContextProvider: AppContextProvider -+ private val appContextProvider: AppContextProvider, - ) : AppContextActivityResultContract { - private val contentResolver: ContentResolver - get() = appContextProvider.appContext.reactContext?.contentResolver - ?: throw Exceptions.ReactContextLost() - - override fun createIntent(context: Context, input: ImageLibraryContractOptions): Intent { -- val request = PickVisualMediaRequest.Builder() -- .setMediaType( -- when (input.options.mediaTypes) { -- MediaTypes.VIDEOS -> { -- PickVisualMedia.VideoOnly -- } -- -- MediaTypes.IMAGES -> { -- PickVisualMedia.ImageOnly -- } -- -- else -> { -- PickVisualMedia.ImageAndVideo -- } -- } -- ) -- .build() -+ val intent = Intent(Intent.ACTION_GET_CONTENT) -+ .addCategory(Intent.CATEGORY_OPENABLE) -+ .setType("image/*") - - if (input.options.allowsMultipleSelection) { -- val selectionLimit = input.options.selectionLimit -- -- if (selectionLimit == 1) { -- // If multiple selection is allowed but the limit is 1, we should ignore -- // the multiple selection flag and just treat it as a single selection. -- return PickVisualMedia().createIntent(context, request) -+ if(input.options.selectionLimit == 1) { -+ return intent - } - -- if (selectionLimit > 1) { -- return PickMultipleVisualMedia(selectionLimit).createIntent(context, request) -- } -- -- // If the selection limit is 0, it is the same as unlimited selection. -- if (selectionLimit == UNLIMITED_SELECTION) { -- return PickMultipleVisualMedia().createIntent(context, request) -- } -+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) - } - -- return PickVisualMedia().createIntent(context, request) -+ return intent - } - - override fun parseResult(input: ImageLibraryContractOptions, resultCode: Int, intent: Intent?) = diff --git a/patches/expo-image-picker+14.7.1.patch.md b/patches/expo-image-picker+14.7.1.patch.md deleted file mode 100644 index 47c0daed5d..0000000000 --- a/patches/expo-image-picker+14.7.1.patch.md +++ /dev/null @@ -1,3 +0,0 @@ -added by https://github.com/bluesky-social/social-app/pull/2384#pullrequestreview-1800985521 - -hackfixes the image picker on android so that the user can select from their typical image sources \ No newline at end of file diff --git a/patches/expo-notifications+0.27.6.patch b/patches/expo-notifications+0.28.1.patch similarity index 88% rename from patches/expo-notifications+0.27.6.patch rename to patches/expo-notifications+0.28.1.patch index ba196eca05..41e91446e6 100644 --- a/patches/expo-notifications+0.27.6.patch +++ b/patches/expo-notifications+0.28.1.patch @@ -1,13 +1,13 @@ diff --git a/node_modules/expo-notifications/android/build.gradle b/node_modules/expo-notifications/android/build.gradle -index 97bf4f4..6e9d427 100644 +index d233e1f..cc2f856 100644 --- a/node_modules/expo-notifications/android/build.gradle +++ b/node_modules/expo-notifications/android/build.gradle -@@ -118,6 +118,7 @@ dependencies { +@@ -32,6 +32,7 @@ dependencies { api 'com.google.firebase:firebase-messaging:22.0.0' - + api 'me.leolin:ShortcutBadger:1.1.22@aar' + implementation project(':expo-background-notification-handler') - + if (project.findProject(':expo-modules-test-core')) { testImplementation project(':expo-modules-test-core') diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/JSONNotificationContentBuilder.java b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/JSONNotificationContentBuilder.java @@ -16,14 +16,14 @@ index 0af7fe0..8f2c8d8 100644 +++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/JSONNotificationContentBuilder.java @@ -14,6 +14,7 @@ import expo.modules.notifications.notifications.enums.NotificationPriority; import expo.modules.notifications.notifications.model.NotificationContent; - + public class JSONNotificationContentBuilder extends NotificationContent.Builder { + private static final String CHANNEL_ID_KEY = "channelId"; private static final String TITLE_KEY = "title"; private static final String TEXT_KEY = "message"; private static final String SUBTITLE_KEY = "subtitle"; @@ -36,6 +37,7 @@ public class JSONNotificationContentBuilder extends NotificationContent.Builder - + public NotificationContent.Builder setPayload(JSONObject payload) { this.setTitle(getTitle(payload)) + .setChannelId(getChannelId(payload)) @@ -33,7 +33,7 @@ index 0af7fe0..8f2c8d8 100644 @@ -60,6 +62,14 @@ public class JSONNotificationContentBuilder extends NotificationContent.Builder return this; } - + + protected String getChannelId(JSONObject payload) { + try { + return payload.getString(CHANNEL_ID_KEY); @@ -46,71 +46,73 @@ index 0af7fe0..8f2c8d8 100644 try { return payload.getString(TITLE_KEY); diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java -index f1fed19..1619f59 100644 +index f1fed19..166b34f 100644 --- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java +++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java @@ -20,6 +20,7 @@ import expo.modules.notifications.notifications.enums.NotificationPriority; * should be created using {@link NotificationContent.Builder}. */ public class NotificationContent implements Parcelable, Serializable { -+ private String mChannelId; ++ private string mChannelId; private String mTitle; private String mText; private String mSubtitle; -@@ -50,6 +51,9 @@ public class NotificationContent implements Parcelable, Serializable { +@@ -50,6 +51,11 @@ public class NotificationContent implements Parcelable, Serializable { } }; - + + @Nullable -+ public String getChannelId() { return mChannelId; } ++ public String getChannelId() { ++ return mTitle; ++ } + @Nullable public String getTitle() { return mTitle; -@@ -121,6 +125,7 @@ public class NotificationContent implements Parcelable, Serializable { +@@ -121,6 +127,7 @@ public class NotificationContent implements Parcelable, Serializable { } - + protected NotificationContent(Parcel in) { + mChannelId = in.readString(); mTitle = in.readString(); mText = in.readString(); mSubtitle = in.readString(); -@@ -146,6 +151,7 @@ public class NotificationContent implements Parcelable, Serializable { - +@@ -146,6 +153,7 @@ public class NotificationContent implements Parcelable, Serializable { + @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mChannelId); dest.writeString(mTitle); dest.writeString(mText); dest.writeString(mSubtitle); -@@ -166,6 +172,7 @@ public class NotificationContent implements Parcelable, Serializable { +@@ -166,6 +174,7 @@ public class NotificationContent implements Parcelable, Serializable { private static final long serialVersionUID = 397666843266836802L; - + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + out.writeObject(mChannelId); out.writeObject(mTitle); out.writeObject(mText); out.writeObject(mSubtitle); -@@ -190,6 +197,7 @@ public class NotificationContent implements Parcelable, Serializable { +@@ -190,6 +199,7 @@ public class NotificationContent implements Parcelable, Serializable { } - + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + mChannelId = (String) in.readObject(); mTitle = (String) in.readObject(); mText = (String) in.readObject(); mSubtitle = (String) in.readObject(); -@@ -240,6 +248,7 @@ public class NotificationContent implements Parcelable, Serializable { +@@ -240,6 +250,7 @@ public class NotificationContent implements Parcelable, Serializable { } - + public static class Builder { -+ private String mChannelId; ++ private string mChannelId; private String mTitle; private String mText; private String mSubtitle; -@@ -260,6 +269,11 @@ public class NotificationContent implements Parcelable, Serializable { +@@ -260,6 +271,11 @@ public class NotificationContent implements Parcelable, Serializable { useDefaultVibrationPattern(); } - + + public Builder setChannelId(String channelId) { + mChannelId = channelId; + return this; @@ -119,8 +121,8 @@ index f1fed19..1619f59 100644 public Builder setTitle(String title) { mTitle = title; return this; -@@ -336,6 +350,7 @@ public class NotificationContent implements Parcelable, Serializable { - +@@ -336,6 +352,7 @@ public class NotificationContent implements Parcelable, Serializable { + public NotificationContent build() { NotificationContent content = new NotificationContent(); + content.mChannelId = mChannelId; @@ -128,28 +130,20 @@ index f1fed19..1619f59 100644 content.mSubtitle = mSubtitle; content.mText = mText; diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java -index 6bd9928..aab71ea 100644 +index 6bd9928..ee93d70 100644 --- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java +++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java -@@ -7,7 +7,6 @@ import android.content.pm.PackageManager; - import android.content.res.Resources; - import android.graphics.Bitmap; - import android.graphics.BitmapFactory; --import android.os.Build; - import android.os.Bundle; - import android.os.Parcel; - import android.provider.Settings; -@@ -48,6 +47,10 @@ public class ExpoNotificationBuilder extends ChannelAwareNotificationBuilder { - +@@ -48,6 +48,10 @@ public class ExpoNotificationBuilder extends ChannelAwareNotificationBuilder { + NotificationContent content = getNotificationContent(); - + + if (content.getChannelId() != null) { + builder.setChannelId(content.getChannelId()); + } + builder.setAutoCancel(content.isAutoDismiss()); builder.setOngoing(content.isSticky()); - + diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt index 55b3a8d..1b99d5b 100644 --- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt @@ -164,7 +158,7 @@ index 55b3a8d..1b99d5b 100644 import org.json.JSONObject import java.lang.ref.WeakReference import java.util.* - + -open class FirebaseMessagingDelegate(protected val context: Context) : FirebaseMessagingDelegate { +open class FirebaseMessagingDelegate(protected val context: Context) : FirebaseMessagingDelegate, BackgroundNotificationHandlerInterface { companion object { @@ -172,7 +166,7 @@ index 55b3a8d..1b99d5b 100644 // than by static properties. Fortunately, using weak references we can @@ -89,12 +92,21 @@ open class FirebaseMessagingDelegate(protected val context: Context) : FirebaseM fun getBackgroundTasks() = sBackgroundTaskConsumerReferences.values.mapNotNull { it.get() } - + override fun onMessageReceived(remoteMessage: RemoteMessage) { - NotificationsService.receive(context, createNotification(remoteMessage)) - getBackgroundTasks().forEach { @@ -187,7 +181,7 @@ index 55b3a8d..1b99d5b 100644 + } } } - + + override fun showMessage(remoteMessage: RemoteMessage) { + NotificationsService.receive(context, createNotification(remoteMessage)) + } diff --git a/patches/expo-updates+0.24.7.patch b/patches/expo-updates+0.25.11.patch similarity index 60% rename from patches/expo-updates+0.24.7.patch rename to patches/expo-updates+0.25.11.patch index 603ae32ef8..5f9eceef48 100644 --- a/patches/expo-updates+0.24.7.patch +++ b/patches/expo-updates+0.25.11.patch @@ -1,11 +1,11 @@ -diff --git a/node_modules/expo-updates/ios/EXUpdates/Update/NewUpdate.swift b/node_modules/expo-updates/ios/EXUpdates/Update/NewUpdate.swift -index 189a5f5..8d5b8e6 100644 ---- a/node_modules/expo-updates/ios/EXUpdates/Update/NewUpdate.swift -+++ b/node_modules/expo-updates/ios/EXUpdates/Update/NewUpdate.swift -@@ -68,13 +68,20 @@ public final class NewUpdate: Update { - processedAssets.append(asset) +diff --git a/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift b/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift +index b85291e..07a5d3c 100644 +--- a/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift ++++ b/node_modules/expo-updates/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift +@@ -78,13 +78,20 @@ public final class ExpoUpdatesUpdate: Update { + status = UpdateStatus.StatusPending } - + + // Instead of relying on various hacks to get the correct format for the specific + // platform on the backend, we can just add this little patch.. + let dateFormatter = DateFormatter() @@ -23,4 +23,4 @@ index 189a5f5..8d5b8e6 100644 + commitTime: date, runtimeVersion: runtimeVersion, keep: true, - status: UpdateStatus.StatusPending, + status: status, diff --git a/patches/expo-updates+0.24.7.patch.md b/patches/expo-updates+0.25.11.patch.md similarity index 96% rename from patches/expo-updates+0.24.7.patch.md rename to patches/expo-updates+0.25.11.patch.md index 8a8848127e..6d5d7093df 100644 --- a/patches/expo-updates+0.24.7.patch.md +++ b/patches/expo-updates+0.25.11.patch.md @@ -4,4 +4,4 @@ This is a small patch to convert timestamp formats that are returned from the ba backend to return the correct format for a specific format (the format required on Android is not the same as on iOS) we can just add this conversion in. -Don't remove unless we make changes on the backend to support both platforms. \ No newline at end of file +Don't remove unless we make changes on the backend to support both platforms. diff --git a/patches/react-native+0.73.2.patch b/patches/react-native+0.74.1.patch similarity index 100% rename from patches/react-native+0.73.2.patch rename to patches/react-native+0.74.1.patch diff --git a/patches/react-native+0.73.2.patch.md b/patches/react-native+0.74.1.patch.md similarity index 100% rename from patches/react-native+0.73.2.patch.md rename to patches/react-native+0.74.1.patch.md diff --git a/patches/react-native-reanimated+3.6.0.patch b/patches/react-native-reanimated+3.11.0.patch similarity index 57% rename from patches/react-native-reanimated+3.6.0.patch rename to patches/react-native-reanimated+3.11.0.patch index 093d83e411..f189853859 100644 --- a/patches/react-native-reanimated+3.6.0.patch +++ b/patches/react-native-reanimated+3.11.0.patch @@ -1,30 +1,28 @@ diff --git a/node_modules/react-native-reanimated/lib/module/reanimated2/index.js b/node_modules/react-native-reanimated/lib/module/reanimated2/index.js -index 91e49f4..c10d3fc 100644 +index ac9be5d..86d4605 100644 --- a/node_modules/react-native-reanimated/lib/module/reanimated2/index.js +++ b/node_modules/react-native-reanimated/lib/module/reanimated2/index.js -@@ -45,4 +45,5 @@ export { getUseOfValueInStyleWarning } from './pluginUtils'; - export { withReanimatedTimer, advanceAnimationByTime, advanceAnimationByFrame, setUpTests, getAnimatedStyle } from './jestUtils'; - export { LayoutAnimationConfig } from './component/LayoutAnimationConfig'; +@@ -47,4 +47,5 @@ export { LayoutAnimationConfig } from './component/LayoutAnimationConfig'; + export { PerformanceMonitor } from './component/PerformanceMonitor'; export { startMapper, stopMapper } from './mappers'; + export { startScreenTransition, finishScreenTransition, ScreenTransition } from './screenTransition'; +export { isReducedMotion } from './PlatformChecker'; //# sourceMappingURL=index.js.map -\ No newline at end of file diff --git a/node_modules/react-native-reanimated/lib/typescript/reanimated2/index.d.ts b/node_modules/react-native-reanimated/lib/typescript/reanimated2/index.d.ts -index 96bd913..ad63a09 100644 +index f01dc57..161ef22 100644 --- a/node_modules/react-native-reanimated/lib/typescript/reanimated2/index.d.ts +++ b/node_modules/react-native-reanimated/lib/typescript/reanimated2/index.d.ts -@@ -33,3 +33,4 @@ export type { Adaptable, AdaptTransforms, AnimateProps, AnimatedProps, AnimatedT - export type { AnimatedScrollViewProps } from './component/ScrollView'; - export type { FlatListPropsWithLayout } from './component/FlatList'; +@@ -36,3 +36,4 @@ export type { FlatListPropsWithLayout } from './component/FlatList'; export { startMapper, stopMapper } from './mappers'; + export { startScreenTransition, finishScreenTransition, ScreenTransition, } from './screenTransition'; + export type { AnimatedScreenTransition, GoBackGesture, ScreenTransitionConfig, } from './screenTransition'; +export { isReducedMotion } from './PlatformChecker'; diff --git a/node_modules/react-native-reanimated/src/reanimated2/index.ts b/node_modules/react-native-reanimated/src/reanimated2/index.ts -index 096dc05..38fc01d 100644 +index 5885fa1..a3c693f 100644 --- a/node_modules/react-native-reanimated/src/reanimated2/index.ts +++ b/node_modules/react-native-reanimated/src/reanimated2/index.ts -@@ -271,3 +271,4 @@ export type { - export type { AnimatedScrollViewProps } from './component/ScrollView'; - export type { FlatListPropsWithLayout } from './component/FlatList'; - export { startMapper, stopMapper } from './mappers'; +@@ -284,3 +284,4 @@ export type { + GoBackGesture, + ScreenTransitionConfig, + } from './screenTransition'; +export { isReducedMotion } from './PlatformChecker'; -\ No newline at end of file diff --git a/src/lib/hooks/useOTAUpdate.ts b/src/lib/hooks/useOTAUpdate.ts deleted file mode 100644 index d35179256d..0000000000 --- a/src/lib/hooks/useOTAUpdate.ts +++ /dev/null @@ -1,56 +0,0 @@ -import * as Updates from 'expo-updates' -import {useCallback, useEffect} from 'react' -import {AppState} from 'react-native' -import {logger} from '#/logger' - -export function useOTAUpdate() { - // HELPER FUNCTIONS - const checkForUpdate = useCallback(async () => { - logger.debug('useOTAUpdate: Checking for update...') - try { - // Check if new OTA update is available - const update = await Updates.checkForUpdateAsync() - // If updates aren't available stop the function execution - if (!update.isAvailable) { - return - } - // Otherwise fetch the update in the background, so even if the user rejects switching to latest version it will be done automatically on next relaunch. - await Updates.fetchUpdateAsync() - } catch (e) { - logger.error('useOTAUpdate: Error while checking for update', { - message: e, - }) - } - }, []) - const updateEventListener = useCallback((event: Updates.UpdateEvent) => { - logger.debug('useOTAUpdate: Listening for update...') - if (event.type === Updates.UpdateEventType.ERROR) { - logger.error('useOTAUpdate: Error while listening for update', { - message: event.message, - }) - } else if (event.type === Updates.UpdateEventType.NO_UPDATE_AVAILABLE) { - // Handle no update available - // do nothing - } else if (event.type === Updates.UpdateEventType.UPDATE_AVAILABLE) { - // Handle update available - // open modal, ask for user confirmation, and reload the app - } - }, []) - - useEffect(() => { - // ADD EVENT LISTENERS - const updateEventSubscription = Updates.addListener(updateEventListener) - const appStateSubscription = AppState.addEventListener('change', state => { - if (state === 'active' && !__DEV__) { - checkForUpdate() - } - }) - - // REMOVE EVENT LISTENERS (CLEANUP) - return () => { - updateEventSubscription.remove() - appStateSubscription.remove() - } - }, []) // eslint-disable-line react-hooks/exhaustive-deps - // disable exhaustive deps because we don't want to run this effect again -} diff --git a/src/view/com/pager/PagerWithHeader.tsx b/src/view/com/pager/PagerWithHeader.tsx index 2d604d104e..61e2a4096d 100644 --- a/src/view/com/pager/PagerWithHeader.tsx +++ b/src/view/com/pager/PagerWithHeader.tsx @@ -109,7 +109,7 @@ export const PagerWithHeader = React.forwardRef( ], ) - const scrollRefs = useSharedValue[]>([]) + const scrollRefs = useSharedValue | null>>([]) const registerRef = React.useCallback( (scrollRef: AnimatedRef | null, atIndex: number) => { scrollRefs.modify(refs => { @@ -130,8 +130,9 @@ export const PagerWithHeader = React.forwardRef( lastForcedScrollY.value = forcedScrollY const refs = scrollRefs.value for (let i = 0; i < refs.length; i++) { - if (i !== currentPage && refs[i] != null) { - scrollTo(refs[i], 0, forcedScrollY, false) + const scollRef = refs[i] + if (i !== currentPage && scollRef != null) { + scrollTo(scollRef, 0, forcedScrollY, false) } } } diff --git a/src/view/com/util/Views.web.tsx b/src/view/com/util/Views.web.tsx index 04891806c4..792ace140e 100644 --- a/src/view/com/util/Views.web.tsx +++ b/src/view/com/util/Views.web.tsx @@ -14,6 +14,7 @@ import React from 'react' import { + FlatList, FlatListProps, ScrollViewProps, StyleSheet, @@ -67,7 +68,7 @@ export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl( desktopFixedHeight, ...props }: React.PropsWithChildren & AddedProps>, - ref: React.Ref>, + ref: React.Ref>, ) { const pal = usePalette('default') const {isMobile} = useWebMediaQueries() diff --git a/src/view/screens/LanguageSettings.tsx b/src/view/screens/LanguageSettings.tsx index b86cd46e1c..390d2807b0 100644 --- a/src/view/screens/LanguageSettings.tsx +++ b/src/view/screens/LanguageSettings.tsx @@ -1,27 +1,28 @@ import React from 'react' import {StyleSheet, View} from 'react-native' -import {Text} from '../com/util/text/Text' -import {s} from 'lib/styles' -import {usePalette} from 'lib/hooks/usePalette' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' -import {ViewHeader} from 'view/com/util/ViewHeader' -import {CenteredView} from 'view/com/util/Views' -import {Button} from 'view/com/util/forms/Button' +import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select' import { FontAwesomeIcon, FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {useAnalytics} from 'lib/analytics/analytics' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' -import {APP_LANGUAGES, LANGUAGES} from 'lib/../locale/languages' -import RNPickerSelect, {PickerSelectProps} from 'react-native-picker-select' -import {useSetMinimalShellMode} from '#/state/shell' + +import {sanitizeAppLanguageSetting} from '#/locale/helpers' import {useModalControls} from '#/state/modals' import {useLanguagePrefs, useLanguagePrefsApi} from '#/state/preferences' -import {Trans, msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {sanitizeAppLanguageSetting} from '#/locale/helpers' +import {useSetMinimalShellMode} from '#/state/shell' +import {APP_LANGUAGES, LANGUAGES} from 'lib/../locale/languages' +import {useAnalytics} from 'lib/analytics/analytics' +import {usePalette} from 'lib/hooks/usePalette' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' +import {s} from 'lib/styles' +import {Button} from 'view/com/util/forms/Button' +import {ViewHeader} from 'view/com/util/ViewHeader' +import {CenteredView} from 'view/com/util/Views' +import {Text} from '../com/util/text/Text' type Props = NativeStackScreenProps @@ -132,9 +133,10 @@ export function LanguageSettingsScreen(_props: Props) { paddingVertical: 8, borderRadius: 24, }, + inputWeb: { - // @ts-ignore web only cursor: 'pointer', + // @ts-ignore web only '-moz-appearance': 'none', '-webkit-appearance': 'none', appearance: 'none', @@ -224,8 +226,8 @@ export function LanguageSettingsScreen(_props: Props) { borderRadius: 24, }, inputWeb: { - // @ts-ignore web only cursor: 'pointer', + // @ts-ignore web only '-moz-appearance': 'none', '-webkit-appearance': 'none', appearance: 'none', diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx index 9dd1c397f3..b6680176bf 100644 --- a/src/view/screens/Search/Search.tsx +++ b/src/view/screens/Search/Search.tsx @@ -739,8 +739,8 @@ let SearchInputBox = ({ style={[ {backgroundColor: pal.colors.backgroundLight}, styles.headerSearchContainer, + // @ts-expect-error web only isWeb && { - // @ts-ignore web only cursor: 'default', }, ]} diff --git a/yarn.lock b/yarn.lock index 96bd60b7ff..07e2f73c2d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1278,6 +1278,21 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz#7d19da92c7e0cd8d11c09af2ce1b8e7512a6e723" + integrity sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.24.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.24.5" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" @@ -1308,6 +1323,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== +"@babel/helper-environment-visitor@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz#ac7ad5517821641550f6698dd5468f8cef78620d" + integrity sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g== + "@babel/helper-function-name@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" @@ -1345,6 +1365,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-member-expression-to-functions@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz#5981e131d5c7003c7d1fa1ad49e86c9b097ec475" + integrity sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA== + dependencies: + "@babel/types" "^7.24.5" + "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" @@ -1366,6 +1393,13 @@ dependencies: "@babel/types" "^7.24.0" +"@babel/helper-module-imports@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz#65e54ffceed6a268dc4ce11f0433b82cfff57852" + integrity sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g== + dependencies: + "@babel/types" "^7.24.6" + "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" @@ -1388,6 +1422,17 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.20" +"@babel/helper-module-transforms@^7.23.3": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz#22346ed9df44ce84dee850d7433c5b73fab1fe4e" + integrity sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA== + dependencies: + "@babel/helper-environment-visitor" "^7.24.6" + "@babel/helper-module-imports" "^7.24.6" + "@babel/helper-simple-access" "^7.24.6" + "@babel/helper-split-export-declaration" "^7.24.6" + "@babel/helper-validator-identifier" "^7.24.6" + "@babel/helper-module-transforms@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz#ea6c5e33f7b262a0ae762fd5986355c45f54a545" @@ -1411,6 +1456,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== +"@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a" + integrity sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ== + "@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" @@ -1438,6 +1488,15 @@ "@babel/helper-member-expression-to-functions" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" +"@babel/helper-replace-supers@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" + integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-simple-access@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" @@ -1452,6 +1511,13 @@ dependencies: "@babel/types" "^7.24.5" +"@babel/helper-simple-access@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz#1d6e04d468bba4fc963b4906f6dac6286cfedff1" + integrity sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g== + dependencies: + "@babel/types" "^7.24.6" + "@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" @@ -1473,6 +1539,13 @@ dependencies: "@babel/types" "^7.24.5" +"@babel/helper-split-export-declaration@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz#e830068f7ba8861c53b7421c284da30ae656d7a3" + integrity sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw== + dependencies: + "@babel/types" "^7.24.6" + "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" @@ -1488,6 +1561,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== +"@babel/helper-string-parser@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz#28583c28b15f2a3339cfafafeaad42f9a0e828df" + integrity sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q== + "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" @@ -1503,6 +1581,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== +"@babel/helper-validator-identifier@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz#08bb6612b11bdec78f3feed3db196da682454a5e" + integrity sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw== + "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -1650,6 +1733,14 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-default-from" "^7.22.5" +"@babel/plugin-proposal-logical-assignment-operators@^7.18.0": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz#dfbcaa8f7b4d37b51e8bfb46d94a5aea2bb89d83" + integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" @@ -1721,7 +1812,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.0.0", "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -1763,7 +1854,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.22.5": +"@babel/plugin-syntax-flow@^7.12.1", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== @@ -1798,7 +1889,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.7.2": +"@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.7.2": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== @@ -1812,6 +1903,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-syntax-jsx@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz#3f6ca04b8c841811dbc3c5c5f837934e0d626c10" + integrity sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -1833,7 +1931,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -1875,6 +1973,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-syntax-typescript@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz#b3bcc51f396d15f3591683f90239de143c076844" + integrity sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" @@ -1890,6 +1995,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-arrow-functions@^7.0.0-0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz#2bf263617060c9cc45bcdbf492b8cc805082bf27" + integrity sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-transform-async-generator-functions@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.10.tgz#45946cd17f915b10e65c29b8ed18a0a50fc648c8" @@ -1909,7 +2021,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-remap-async-to-generator" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.22.5": +"@babel/plugin-transform-block-scoped-functions@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== @@ -2025,7 +2137,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-flow" "^7.22.5" -"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.22.5": +"@babel/plugin-transform-for-of@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== @@ -2064,7 +2176,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.22.5": +"@babel/plugin-transform-member-expression-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== @@ -2088,6 +2200,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" +"@babel/plugin-transform-modules-commonjs@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz#e71ba1d0d69e049a22bf90b3867e263823d3f1b9" + integrity sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-simple-access" "^7.22.5" + "@babel/plugin-transform-modules-systemjs@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" @@ -2121,6 +2242,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-nullish-coalescing-operator@^7.0.0-0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz#0cd494bb97cb07d428bd651632cb9d4140513988" + integrity sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-transform-nullish-coalescing-operator@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz#f8872c65776e0b552e0849d7596cddd416c3e381" @@ -2137,13 +2266,6 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-assign@^7.16.7": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.22.5.tgz#290c1b9555dcea48bb2c29ad94237777600d04f9" - integrity sha512-iDhx9ARkXq4vhZ2CYOSnQXkmxkDgosLi3J8Z17mKz7LyzthtkdVchLD7WZ3aXeCuvJDOW3+1I5TpJmwIbF9MKQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-object-rest-spread@^7.12.13": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" @@ -2166,7 +2288,7 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.22.5" -"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.22.5": +"@babel/plugin-transform-object-super@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== @@ -2182,6 +2304,15 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-transform-optional-chaining@^7.0.0-0": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz#a6334bebd7f9dd3df37447880d0bd64b778e600f" + integrity sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-transform-optional-chaining@^7.22.10", "@babel/plugin-transform-optional-chaining@^7.22.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz#076d28a7e074392e840d4ae587d83445bac0372a" @@ -2233,7 +2364,7 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.22.5": +"@babel/plugin-transform-property-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== @@ -2354,6 +2485,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-shorthand-properties@^7.0.0-0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz#ba9a09144cf55d35ec6b93a32253becad8ee5b55" + integrity sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" @@ -2369,7 +2507,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.22.5": +"@babel/plugin-transform-template-literals@^7.0.0-0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz#15e2166873a30d8617e3e2ccadb86643d327aab7" + integrity sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-template-literals@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== @@ -2393,6 +2538,16 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-typescript" "^7.22.5" +"@babel/plugin-transform-typescript@^7.24.1": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz#bcba979e462120dc06a75bd34c473a04781931b8" + integrity sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.5" + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/plugin-syntax-typescript" "^7.24.1" + "@babel/plugin-transform-unicode-escapes@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" @@ -2563,6 +2718,17 @@ "@babel/plugin-transform-modules-commonjs" "^7.22.5" "@babel/plugin-transform-typescript" "^7.22.5" +"@babel/preset-typescript@^7.23.0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz#89bdf13a3149a17b3b2a2c9c62547f06db8845ec" + integrity sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-syntax-jsx" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-typescript" "^7.24.1" + "@babel/register@^7.13.16": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.5.tgz#e4d8d0f615ea3233a27b5c6ada6750ee59559939" @@ -2704,6 +2870,15 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@babel/types@^7.24.6": + version "7.24.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.6.tgz#ba4e1f59870c10dc2fa95a274ac4feec23b21912" + integrity sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ== + dependencies: + "@babel/helper-string-parser" "^7.24.6" + "@babel/helper-validator-identifier" "^7.24.6" + to-fast-properties "^2.0.0" + "@bam.tech/react-native-image-resizer@^3.0.4": version "3.0.5" resolved "https://registry.yarnpkg.com/@bam.tech/react-native-image-resizer/-/react-native-image-resizer-3.0.5.tgz#6661ba020de156268f73bdc92fbb93ef86f88a13" @@ -2938,7 +3113,7 @@ "@discord/bottom-sheet@bluesky-social/react-native-bottom-sheet": version "4.6.1" - resolved "https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/2b3f77e04a25c454e70d893a2692e8c03aced06b" + resolved "https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/3232c7cd9b966dd977c849a360fa853f88dcf3ca" dependencies: "@gorhom/portal" "1.0.14" invariant "^2.2.4" @@ -3117,40 +3292,41 @@ mv "~2" safe-json-stringify "~1" -"@expo/cli@0.17.10": - version "0.17.10" - resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.17.10.tgz#7dd5e2b4a01f5d29698c431729a19878fbd806f5" - integrity sha512-Jw2wY+lsavP9GRqwwLqF/SvB7w2GZ4sWBMcBKTZ8F0lWjwmLGAUt4WYquf20agdmnY/oZUHvWNkrz/t3SflhnA== +"@expo/cli@0.18.13": + version "0.18.13" + resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.18.13.tgz#b3a6aa1d4cfa78720ba86f73ded7c2c93f4805a9" + integrity sha512-ZO1fpDK8z6mLeQGuFP6e3cZyCHV55ohZY7/tEyhpft3bwysS680eyFg5SFe+tWNFesnziFrbtI8JaUyhyjqovA== dependencies: "@babel/runtime" "^7.20.0" "@expo/code-signing-certificates" "0.0.5" - "@expo/config" "~8.5.0" - "@expo/config-plugins" "~7.9.0" - "@expo/devcert" "^1.0.0" - "@expo/env" "~0.2.2" - "@expo/image-utils" "^0.4.0" - "@expo/json-file" "^8.2.37" - "@expo/metro-config" "~0.17.0" + "@expo/config" "~9.0.0" + "@expo/config-plugins" "~8.0.0" + "@expo/devcert" "^1.1.2" + "@expo/env" "~0.3.0" + "@expo/image-utils" "^0.5.0" + "@expo/json-file" "^8.3.0" + "@expo/metro-config" "~0.18.0" "@expo/osascript" "^2.0.31" - "@expo/package-manager" "^1.1.1" + "@expo/package-manager" "^1.5.0" "@expo/plist" "^0.1.0" - "@expo/prebuild-config" "6.8.1" + "@expo/prebuild-config" "7.0.4" "@expo/rudder-sdk-node" "1.1.1" - "@expo/spawn-async" "1.5.0" + "@expo/spawn-async" "^1.7.2" "@expo/xcpretty" "^4.3.0" - "@react-native/dev-middleware" "^0.73.6" + "@react-native/dev-middleware" "~0.74.75" "@urql/core" "2.3.6" "@urql/exchange-retry" "0.3.0" accepts "^1.3.8" arg "5.0.2" better-opn "~3.0.2" bplist-parser "^0.3.1" - cacache "^15.3.0" + cacache "^18.0.2" chalk "^4.0.0" ci-info "^3.3.0" connect "^3.7.0" debug "^4.3.4" env-editor "^0.4.1" + fast-glob "^3.3.2" find-yarn-workspace-root "~2.0.0" form-data "^3.0.1" freeport-async "2.0.0" @@ -3168,7 +3344,6 @@ lodash.debounce "^4.0.8" md5hex "^1.0.0" minimatch "^3.0.4" - minipass "3.3.6" node-fetch "^2.6.7" node-forge "^1.3.1" npm-package-arg "^7.0.0" @@ -3184,7 +3359,7 @@ resolve "^1.22.2" resolve-from "^5.0.0" resolve.exports "^2.0.2" - semver "^7.5.3" + semver "^7.6.0" send "^0.18.0" slugify "^1.3.4" source-map-support "~0.5.21" @@ -3229,24 +3404,22 @@ xcode "^3.0.1" xml2js "0.6.0" -"@expo/config-plugins@7.9.1", "@expo/config-plugins@~7.9.0": - version "7.9.1" - resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-7.9.1.tgz#fe4f7e4f9d4e87f2dcf2344ffdc59eb466dd5d2e" - integrity sha512-ICt6Jed1J0tPYMQrJ8K5Qusgih2I6pZ2PU4VSvxsN3T4n97L13XpYV1vyq1Uc/HMl3UhOwldipmgpEbCfeDqsQ== +"@expo/config-plugins@8.0.4", "@expo/config-plugins@~8.0.0", "@expo/config-plugins@~8.0.0-beta.0": + version "8.0.4" + resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-8.0.4.tgz#1e781cd971fab27409ed2f8d621db6d29cce3036" + integrity sha512-Hi+xuyNWE2LT4LVbGttHJgl9brnsdWAhEB42gWKb5+8ae86Nr/KwUBQJsJppirBYTeLjj5ZlY0glYnAkDa2jqw== dependencies: - "@expo/config-types" "^50.0.0-alpha.1" - "@expo/fingerprint" "^0.6.0" + "@expo/config-types" "^51.0.0-unreleased" "@expo/json-file" "~8.3.0" "@expo/plist" "^0.1.0" "@expo/sdk-runtime-versions" "^1.0.0" - "@react-native/normalize-color" "^2.0.0" chalk "^4.1.2" debug "^4.3.1" find-up "~5.0.0" getenv "^1.0.0" glob "7.1.6" resolve-from "^5.0.0" - semver "^7.5.3" + semver "^7.5.4" slash "^3.0.0" slugify "^1.6.6" xcode "^3.0.1" @@ -3278,25 +3451,30 @@ resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-47.0.0.tgz#99eeabe0bba7a776e0f252b78beb0c574692c38d" integrity sha512-r0pWfuhkv7KIcXMUiNACJmJKKwlTBGMw9VZHNdppS8/0Nve8HZMTkNRFQzTHW1uH3pBj8jEXpyw/2vSWDHex9g== -"@expo/config-types@^50.0.0", "@expo/config-types@^50.0.0-alpha.1": +"@expo/config-types@^50.0.0-alpha.1": version "50.0.0" resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-50.0.0.tgz#b534d3ec997ec60f8af24f6ad56244c8afc71a0b" integrity sha512-0kkhIwXRT6EdFDwn+zTg9R2MZIAEYGn1MVkyRohAd+C9cXOb5RA8WLQi7vuxKF9m1SMtNAUrf0pO+ENK0+/KSw== -"@expo/config@8.5.6": - version "8.5.6" - resolved "https://registry.yarnpkg.com/@expo/config/-/config-8.5.6.tgz#e37ba437a1718ed4629e1dd130a7aace25312b89" - integrity sha512-wF5awSg6MNn1cb1lIgjnhOn5ov2TEUTnkAVCsOl0QqDwcP+YIerteSFwjn9V52UZvg58L+LKxpCuGbw5IHavbg== +"@expo/config-types@^51.0.0-unreleased": + version "51.0.0" + resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-51.0.0.tgz#f5df238cd1237d7e4d9cc8217cdef3383c2a00cf" + integrity sha512-acn03/u8mQvBhdTQtA7CNhevMltUhbSrpI01FYBJwpVntufkU++ncQujWKlgY/OwIajcfygk1AY4xcNZ5ImkRA== + +"@expo/config@9.0.2", "@expo/config@~9.0.0": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@expo/config/-/config-9.0.2.tgz#112b93436dbca8aa3da73a46329e5b58fdd435d2" + integrity sha512-BKQ4/qBf3OLT8hHp5kjObk2vxwoRQ1yYQBbG/OM9Jdz32yYtrU8opTbKRAxfZEWH5i3ZHdLrPdC1rO0I6WxtTw== dependencies: "@babel/code-frame" "~7.10.4" - "@expo/config-plugins" "~7.9.0" - "@expo/config-types" "^50.0.0" - "@expo/json-file" "^8.2.37" + "@expo/config-plugins" "~8.0.0" + "@expo/config-types" "^51.0.0-unreleased" + "@expo/json-file" "^8.3.0" getenv "^1.0.0" glob "7.1.6" require-from-string "^2.0.2" resolve-from "^5.0.0" - semver "7.5.3" + semver "^7.6.0" slugify "^1.3.4" sucrase "3.34.0" @@ -3334,10 +3512,27 @@ slugify "^1.3.4" sucrase "^3.20.0" -"@expo/devcert@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@expo/devcert/-/devcert-1.1.0.tgz#d148eb9180db6753c438192e73a123fb13b662ac" - integrity sha512-ghUVhNJQOCTdQckSGTHctNp/0jzvVoMMkVh+6SHn+TZj8sU15U/npXIDt8NtQp0HedlPaCgkVdMu8Sacne0aEA== +"@expo/config@~9.0.0-beta.0": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@expo/config/-/config-9.0.1.tgz#e7b79de5af29d5ab2a98a62c3cda31f03bd75827" + integrity sha512-0tjaXBstTbXmD4z+UMFBkh2SZFwilizSQhW6DlaTMnPG5ezuw93zSFEWAuEC3YzkpVtNQTmYzxAYjxwh6seOGg== + dependencies: + "@babel/code-frame" "~7.10.4" + "@expo/config-plugins" "~8.0.0-beta.0" + "@expo/config-types" "^51.0.0-unreleased" + "@expo/json-file" "^8.3.0" + getenv "^1.0.0" + glob "7.1.6" + require-from-string "^2.0.2" + resolve-from "^5.0.0" + semver "^7.6.0" + slugify "^1.3.4" + sucrase "3.34.0" + +"@expo/devcert@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@expo/devcert/-/devcert-1.1.2.tgz#a4923b8ea5b34fde31d6e006a40d0f594096a0ed" + integrity sha512-FyWghLu7rUaZEZSTLt/XNRukm0c9GFfwP0iFaswoDWpV6alvVg+zRAfCLdIVQEz1SVcQ3zo1hMZFDrnKGvkCuQ== dependencies: application-config-path "^0.1.0" command-exists "^1.2.4" @@ -3345,7 +3540,7 @@ eol "^0.9.1" get-port "^3.2.0" glob "^7.1.2" - lodash "^4.17.4" + lodash "^4.17.21" mkdirp "^0.5.1" password-prompt "^1.0.4" rimraf "^2.6.2" @@ -3353,26 +3548,15 @@ tmp "^0.0.33" tslib "^2.4.0" -"@expo/env@~0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@expo/env/-/env-0.2.0.tgz#59964a52b92e0582cc8dd0e87bcd8967d019c809" - integrity sha512-NgcU8oxWCL0xEoOmFc6bHmKq0/sYma7AUARgas8X9wbXz4tfH9SmKrRntDdez33Yw2tarBsQ14MjZD2iJLj7xA== +"@expo/env@~0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@expo/env/-/env-0.3.0.tgz#a66064e5656e0e48197525f47f3398034fdf579e" + integrity sha512-OtB9XVHWaXidLbHvrVDeeXa09yvTl3+IQN884sO6PhIi2/StXfgSH/9zC7IvzrDB8kW3EBJ1PPLuCUJ2hxAT7Q== dependencies: chalk "^4.0.0" debug "^4.3.4" - dotenv "~16.0.3" - dotenv-expand "~10.0.0" - getenv "^1.0.0" - -"@expo/env@~0.2.2": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@expo/env/-/env-0.2.2.tgz#49f589f32e9bae279a6509d7a02218c0f4e32a60" - integrity sha512-m9nGuaSpzdvMzevQ1H60FWgf4PG5s4J0dfKUzdAGnDu7sMUerY/yUeDaA4+OBo3vBwGVQ+UHcQS9vPSMBNaPcg== - dependencies: - chalk "^4.0.0" - debug "^4.3.4" - dotenv "~16.0.3" - dotenv-expand "~10.0.0" + dotenv "~16.4.5" + dotenv-expand "~11.0.6" getenv "^1.0.0" "@expo/fingerprint@^0.6.0": @@ -3388,6 +3572,20 @@ p-limit "^3.1.0" resolve-from "^5.0.0" +"@expo/fingerprint@^0.7.0": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.7.1.tgz#5778c79f6be2471b4c703381e26e9ee0691fa8c6" + integrity sha512-lbTwFiIk0lOm9zzPRvnC45GfPqXqPB3w4hDDKVma+8FDAbPCWhNN42ltLhx/ekwcHFQxURmg0fHm59k0Vy+jtw== + dependencies: + "@expo/spawn-async" "^1.7.2" + chalk "^4.1.2" + debug "^4.3.4" + find-up "^5.0.0" + minimatch "^3.0.4" + p-limit "^3.1.0" + resolve-from "^5.0.0" + semver "^7.6.0" + "@expo/html-elements@^0.4.2": version "0.4.3" resolved "https://registry.yarnpkg.com/@expo/html-elements/-/html-elements-0.4.3.tgz#32b4ca05dd13582164ed1be34ae87e22adfd1d5b" @@ -3427,6 +3625,22 @@ semver "7.3.2" tempy "0.3.0" +"@expo/image-utils@^0.5.0": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.5.1.tgz#06fade141facebcd8431355923d30f3839309942" + integrity sha512-U/GsFfFox88lXULmFJ9Shfl2aQGcwoKPF7fawSCLixIKtMCpsI+1r0h+5i0nQnmt9tHuzXZDL8+Dg1z6OhkI9A== + dependencies: + "@expo/spawn-async" "^1.7.2" + chalk "^4.0.0" + fs-extra "9.0.0" + getenv "^1.0.0" + jimp-compact "0.16.1" + node-fetch "^2.6.0" + parse-png "^2.1.0" + resolve-from "^5.0.0" + semver "^7.6.0" + tempy "0.3.0" + "@expo/json-file@8.2.36": version "8.2.36" resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.36.tgz#62a505cb7f30a34d097386476794680a3f7385ff" @@ -3445,6 +3659,15 @@ json5 "^2.2.2" write-file-atomic "^2.3.0" +"@expo/json-file@^8.3.0": + version "8.3.3" + resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.3.3.tgz#7926e3592f76030ce63d6b1308ac8f5d4d9341f4" + integrity sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A== + dependencies: + "@babel/code-frame" "~7.10.4" + json5 "^2.2.2" + write-file-atomic "^2.3.0" + "@expo/json-file@~8.3.0": version "8.3.0" resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.3.0.tgz#fc84af77b532a4e9bfb5beafd0e3b7f692b6bd7e" @@ -3454,20 +3677,19 @@ json5 "^2.2.2" write-file-atomic "^2.3.0" -"@expo/metro-config@0.17.7": - version "0.17.7" - resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.17.7.tgz#c877a9558f3b97447cc9cf382971403834d84b46" - integrity sha512-3vAdinAjMeRwdhGWWLX6PziZdAPvnyJ6KVYqnJErHHqH0cA6dgAENT3Vq6PEM1H2HgczKr2d5yG9AMgwy848ow== +"@expo/metro-config@0.18.4": + version "0.18.4" + resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.18.4.tgz#bc298e21637a3007f3c31c238525d3bef17e823b" + integrity sha512-vh9WDf/SzE+NYCn6gqbzLKiXtENFlFZdAqyj9nI38RvQ4jw6TJIQ8+ExcdLDT3MOG36Ytg44XX9Zb3OWF6LVxw== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.5" "@babel/parser" "^7.20.0" "@babel/types" "^7.20.0" - "@expo/config" "~8.5.0" - "@expo/env" "~0.2.2" + "@expo/config" "~9.0.0" + "@expo/env" "~0.3.0" "@expo/json-file" "~8.3.0" "@expo/spawn-async" "^1.7.2" - babel-preset-fbjs "^3.4.0" chalk "^4.1.0" debug "^4.3.2" find-yarn-workspace-root "~2.0.0" @@ -3478,22 +3700,20 @@ lightningcss "~1.19.0" postcss "~8.4.32" resolve-from "^5.0.0" - sucrase "3.34.0" -"@expo/metro-config@~0.17.0": - version "0.17.1" - resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.17.1.tgz#8e1cd7b9f63ea84cc18696807cf23560d010e5d8" - integrity sha512-ZOE0Jx0YTZyPpsGiiE09orGEFgZ5sMrOOFSgOe8zrns925g/uCuEbowyNq38IfQt//3xSl5mW3z0l4rxgi7hHQ== +"@expo/metro-config@~0.18.0": + version "0.18.3" + resolved "https://registry.yarnpkg.com/@expo/metro-config/-/metro-config-0.18.3.tgz#fa198b9bf806df44fd7684f1df9af2535c107aa8" + integrity sha512-E4iW+VT/xHPPv+t68dViOsW7egtGIr+sRElcym0iGpC4goLz9WBux/xGzWgxvgvvHEWa21uSZQPM0jWla0OZXg== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.5" "@babel/parser" "^7.20.0" "@babel/types" "^7.20.0" - "@expo/config" "~8.5.0" - "@expo/env" "~0.2.0" + "@expo/config" "~9.0.0-beta.0" + "@expo/env" "~0.3.0" "@expo/json-file" "~8.3.0" "@expo/spawn-async" "^1.7.2" - babel-preset-fbjs "^3.4.0" chalk "^4.1.0" debug "^4.3.2" find-yarn-workspace-root "~2.0.0" @@ -3502,9 +3722,8 @@ glob "^7.2.3" jsc-safe-url "^0.2.4" lightningcss "~1.19.0" - postcss "~8.4.21" + postcss "~8.4.32" resolve-from "^5.0.0" - sucrase "^3.20.0" "@expo/osascript@^2.0.31": version "2.0.33" @@ -3514,13 +3733,13 @@ "@expo/spawn-async" "^1.5.0" exec-async "^2.2.0" -"@expo/package-manager@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.1.2.tgz#e58c9bed4cbb829ebf2cbb80b8542600a6609bd1" - integrity sha512-JI9XzrxB0QVXysyuJ996FPCJGDCYRkbUvgG4QmMTTMFA1T+mv8YzazC3T9C1pHQUAAveVCre1+Pqv0nZXN24Xg== +"@expo/package-manager@^1.5.0": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.5.2.tgz#6015963669977a188bbbac930aa0dc103162ee73" + integrity sha512-IuA9XtGBilce0q8cyxtWINqbzMB1Fia0Yrug/O53HNuRSwQguV/iqjV68bsa4z8mYerePhcFgtvISWLAlNEbUA== dependencies: - "@expo/json-file" "^8.2.37" - "@expo/spawn-async" "^1.5.0" + "@expo/json-file" "^8.3.0" + "@expo/spawn-async" "^1.7.2" ansi-regex "^5.0.0" chalk "^4.0.0" find-up "^5.0.0" @@ -3528,6 +3747,7 @@ js-yaml "^3.13.1" micromatch "^4.0.2" npm-package-arg "^7.0.0" + ora "^3.4.0" split "^1.0.1" sudo-prompt "9.1.1" @@ -3565,36 +3785,38 @@ semver "7.5.3" xml2js "0.6.0" -"@expo/prebuild-config@6.7.4": - version "6.7.4" - resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-6.7.4.tgz#b3e4c8545d7a101bf1fc263c5b7290abc4635e69" - integrity sha512-x8EUdCa8DTMZ/dtEXjHAdlP+ljf6oSeSKNzhycXiHhpMSMG9jEhV28ocCwc6cKsjK5GziweEiHwvrj6+vsBlhA== +"@expo/prebuild-config@7.0.3": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-7.0.3.tgz#d7f66745de6f0b17b15ed2f1417f91c6ba0b591b" + integrity sha512-Kvxy/oQzkxwXLvAmwb+ygxuRn4xUUN2+mVJj3KDe4bRVCNyDPs7wlgdokF3twnWjzRZssUzseMkhp+yHPjAEhA== dependencies: - "@expo/config" "~8.5.0" - "@expo/config-plugins" "~7.8.0" - "@expo/config-types" "^50.0.0-alpha.1" - "@expo/image-utils" "^0.4.0" - "@expo/json-file" "^8.2.37" + "@expo/config" "~9.0.0-beta.0" + "@expo/config-plugins" "~8.0.0-beta.0" + "@expo/config-types" "^51.0.0-unreleased" + "@expo/image-utils" "^0.5.0" + "@expo/json-file" "^8.3.0" + "@react-native/normalize-colors" "~0.74.83" debug "^4.3.1" fs-extra "^9.0.0" resolve-from "^5.0.0" - semver "7.5.3" + semver "^7.6.0" xml2js "0.6.0" -"@expo/prebuild-config@6.8.1": - version "6.8.1" - resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-6.8.1.tgz#5d562b1d6b2e5e4727a3c61acf1a4ed6117b94d8" - integrity sha512-ptK9e0dcj1eYlAWV+fG+QkuAWcLAT1AmtEbj++tn7ZjEj8+LkXRM73LCOEGaF0Er8i8ZWNnaVsgGW4vjgP5ZsA== +"@expo/prebuild-config@7.0.4": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-7.0.4.tgz#cf2d001792d69e652ad4cec9830c8bd4905f0e7a" + integrity sha512-E2n3QbwgV8Qa0CBw7BHrWBDWD7l8yw+N/yjvXpSPFFtoZLMSKyegdkJFACh2u+UIRKUSZm8zQwHeZR0rqAxV9g== dependencies: - "@expo/config" "~8.5.0" - "@expo/config-plugins" "~7.9.0" - "@expo/config-types" "^50.0.0-alpha.1" - "@expo/image-utils" "^0.4.0" - "@expo/json-file" "^8.2.37" + "@expo/config" "~9.0.0" + "@expo/config-plugins" "~8.0.0" + "@expo/config-types" "^51.0.0-unreleased" + "@expo/image-utils" "^0.5.0" + "@expo/json-file" "^8.3.0" + "@react-native/normalize-colors" "~0.74.83" debug "^4.3.1" fs-extra "^9.0.0" resolve-from "^5.0.0" - semver "7.5.3" + semver "^7.6.0" xml2js "0.6.0" "@expo/rudder-sdk-node@1.1.1": @@ -3818,11 +4040,6 @@ humps "^2.0.1" prop-types "^15.7.2" -"@gar/promisify@^1.0.1": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - "@gorhom/portal@1.0.14": version "1.0.14" resolved "https://registry.yarnpkg.com/@gorhom/portal/-/portal-1.0.14.tgz#1953edb76aaba80fb24021dc774550194a18e111" @@ -4618,12 +4835,12 @@ dependencies: "@lukeed/csprng" "^1.1.0" -"@mattermost/react-native-paste-input@^0.6.4": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@mattermost/react-native-paste-input/-/react-native-paste-input-0.6.4.tgz#0b51dacc525849c3f8350d43bf7057d17724b9b5" - integrity sha512-EJ/CTm97pe7u1GnrUFaVaP5j6i57GHPFpnUDdc+r7tLYa2T4LN0oR09KYbr1INcTMz//MqVMz4GYUVFMMN0Xmw== +"@mattermost/react-native-paste-input@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@mattermost/react-native-paste-input/-/react-native-paste-input-0.7.1.tgz#f14585030b992cf7c9bbd0921225eefa501756ba" + integrity sha512-kY8LKtqRX2T/rtn/HNrzTitijuATvyzd6yl5WNWOsszmyzNcssKStjjCTBup04CyMxfwutUU1CWrYUb3hQO7oA== dependencies: - semver "7.5.4" + semver "7.6.0" "@messageformat/parser@^5.0.0": version "5.1.0" @@ -4682,22 +4899,13 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== +"@npmcli/fs@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.1.tgz#59cdaa5adca95d135fc00f2bb53f5771575ce726" + integrity sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg== dependencies: - "@gar/promisify" "^1.0.1" semver "^7.3.5" -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -5090,50 +5298,51 @@ dependencies: merge-options "^3.0.4" -"@react-native-community/cli-clean@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-12.3.0.tgz#667b32daa58b4d11d5b5ab9eb0a2e216d500c90b" - integrity sha512-iAgLCOWYRGh9ukr+eVQnhkV/OqN3V2EGd/in33Ggn/Mj4uO6+oUncXFwB+yjlyaUNz6FfjudhIz09yYGSF+9sg== +"@react-native-community/cli-clean@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-13.6.6.tgz#87c7ad8746c38dab0fe7b3c6ff89d44351d5d943" + integrity sha512-cBwJTwl0NyeA4nyMxbhkWZhxtILYkbU3TW3k8AXLg+iGphe0zikYMGB3T+haTvTc6alTyEFwPbimk9bGIqkjAQ== dependencies: - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-tools" "13.6.6" chalk "^4.1.2" execa "^5.0.0" + fast-glob "^3.3.2" -"@react-native-community/cli-config@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-12.3.0.tgz#255b4e5391878937a25888f452f50a968d053e3e" - integrity sha512-BrTn5ndFD9uOxO8kxBQ32EpbtOvAsQExGPI7SokdI4Zlve70FziLtTq91LTlTUgMq1InVZn/jJb3VIDk6BTInQ== +"@react-native-community/cli-config@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-13.6.6.tgz#69f590694b3a079c74f781baab3b762db74f5dbd" + integrity sha512-mbG425zCKr8JZhv/j11382arezwS/70juWMsn8j2lmrGTrP1cUdW0MF15CCIFtJsqyK3Qs+FTmqttRpq81QfSg== dependencies: - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-tools" "13.6.6" chalk "^4.1.2" cosmiconfig "^5.1.0" deepmerge "^4.3.0" - glob "^7.1.3" + fast-glob "^3.3.2" joi "^17.2.1" -"@react-native-community/cli-debugger-ui@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-12.3.0.tgz#75bbb2082a369b3559e0dffa8bfeebf2a9107e3e" - integrity sha512-w3b0iwjQlk47GhZWHaeTG8kKH09NCMUJO729xSdMBXE8rlbm4kHpKbxQY9qKb6NlfWSJN4noGY+FkNZS2rRwnQ== +"@react-native-community/cli-debugger-ui@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-13.6.6.tgz#ac021ebd795b0fd66fb52a8987d1d41c5a4b8cb3" + integrity sha512-Vv9u6eS4vKSDAvdhA0OiQHoA7y39fiPIgJ6biT32tN4avHDtxlc6TWZGiqv7g98SBvDWvoVAmdPLcRf3kU+c8g== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-doctor@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-12.3.0.tgz#420eb4e80d482f16d431c4df33fbc203862508af" - integrity sha512-BPCwNNesoQMkKsxB08Ayy6URgGQ8Kndv6mMhIvJSNdST3J1+x3ehBHXzG9B9Vfi+DrTKRb8lmEl/b/7VkDlPkA== +"@react-native-community/cli-doctor@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-13.6.6.tgz#ac0febff05601d9b86af3e03460e1a6b0a1d33a5" + integrity sha512-TWZb5g6EmQe2Ua2TEWNmyaEayvlWH4GmdD9ZC+p8EpKFpB1NpDGMK6sXbpb42TDvwZg5s4TDRplK0PBEA/SVDg== dependencies: - "@react-native-community/cli-config" "12.3.0" - "@react-native-community/cli-platform-android" "12.3.0" - "@react-native-community/cli-platform-ios" "12.3.0" - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-config" "13.6.6" + "@react-native-community/cli-platform-android" "13.6.6" + "@react-native-community/cli-platform-apple" "13.6.6" + "@react-native-community/cli-platform-ios" "13.6.6" + "@react-native-community/cli-tools" "13.6.6" chalk "^4.1.2" command-exists "^1.2.8" deepmerge "^4.3.0" envinfo "^7.10.0" execa "^5.0.0" hermes-profile-transformer "^0.0.6" - ip "^1.1.5" node-stream-zip "^1.9.1" ora "^5.4.1" semver "^7.5.2" @@ -5141,68 +5350,70 @@ wcwidth "^1.0.1" yaml "^2.2.1" -"@react-native-community/cli-hermes@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-12.3.0.tgz#c302acbfb07e1f4e73e76e3150c32f0e4f54e9ed" - integrity sha512-G6FxpeZBO4AimKZwtWR3dpXRqTvsmEqlIkkxgwthdzn3LbVjDVIXKpVYU9PkR5cnT+KuAUxO0WwthrJ6Nmrrlg== +"@react-native-community/cli-hermes@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-13.6.6.tgz#590f55f151fec23b55498228f92d100a0e71d474" + integrity sha512-La5Ie+NGaRl3klei6WxKoOxmCUSGGxpOk6vU5pEGf0/O7ky+Ay0io+zXYUZqlNMi/cGpO7ZUijakBYOB/uyuFg== dependencies: - "@react-native-community/cli-platform-android" "12.3.0" - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-platform-android" "13.6.6" + "@react-native-community/cli-tools" "13.6.6" chalk "^4.1.2" hermes-profile-transformer "^0.0.6" - ip "^1.1.5" -"@react-native-community/cli-platform-android@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-12.3.0.tgz#eafa5fb12ebc25f716aea18cd55039c19fbedca6" - integrity sha512-VU1NZw63+GLU2TnyQ919bEMThpHQ/oMFju9MCfrd3pyPJz4Sn+vc3NfnTDUVA5Z5yfLijFOkHIHr4vo/C9bjnw== +"@react-native-community/cli-platform-android@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-13.6.6.tgz#9e3863cb092709021f11848890bff0fc16fc1609" + integrity sha512-/tMwkBeNxh84syiSwNlYtmUz/Ppc+HfKtdopL/5RB+fd3SV1/5/NPNjMlyLNgFKnpxvKCInQ7dnl6jGHJjeHjg== dependencies: - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-tools" "13.6.6" chalk "^4.1.2" execa "^5.0.0" + fast-glob "^3.3.2" fast-xml-parser "^4.2.4" - glob "^7.1.3" logkitty "^0.7.1" -"@react-native-community/cli-platform-ios@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-12.3.0.tgz#42a9185bb51f35a7eb9c5818b2f0072846945ef5" - integrity sha512-H95Sgt3wT7L8V75V0syFJDtv4YgqK5zbu69ko4yrXGv8dv2EBi6qZP0VMmkqXDamoPm9/U7tDTdbcf26ctnLfg== +"@react-native-community/cli-platform-apple@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-13.6.6.tgz#d445fd6ed02c5ae2f43f9c45501e04fee53a2790" + integrity sha512-bOmSSwoqNNT3AmCRZXEMYKz1Jf1l2F86Nhs7qBcXdY/sGiJ+Flng564LOqvdAlVLTbkgz47KjNKCS2pP4Jg0Mg== dependencies: - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-tools" "13.6.6" chalk "^4.1.2" execa "^5.0.0" + fast-glob "^3.3.2" fast-xml-parser "^4.0.12" - glob "^7.1.3" ora "^5.4.1" -"@react-native-community/cli-plugin-metro@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-12.3.0.tgz#b4ea8da691d294aee98ccfcd1162bcd958cae834" - integrity sha512-tYNHIYnNmxrBcsqbE2dAnLMzlKI3Cp1p1xUgTrNaOMsGPDN1epzNfa34n6Nps3iwKElSL7Js91CzYNqgTalucA== - -"@react-native-community/cli-server-api@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-12.3.0.tgz#0460472d44c121d1db8a98ad1df811200c074fb3" - integrity sha512-Rode8NrdyByC+lBKHHn+/W8Zu0c+DajJvLmOWbe2WY/ECvnwcd9MHHbu92hlT2EQaJ9LbLhGrSbQE3cQy9EOCw== +"@react-native-community/cli-platform-ios@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-13.6.6.tgz#0cd700f36483ca37dda7ec044377f8a926b1df1f" + integrity sha512-vjDnRwhlSN5ryqKTas6/DPkxuouuyFBAqAROH4FR1cspTbn6v78JTZKDmtQy9JMMo7N5vZj1kASU5vbFep9IOQ== dependencies: - "@react-native-community/cli-debugger-ui" "12.3.0" - "@react-native-community/cli-tools" "12.3.0" + "@react-native-community/cli-platform-apple" "13.6.6" + +"@react-native-community/cli-server-api@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-13.6.6.tgz#467993006ef82361cdf7a9817999d5a09e85ca6a" + integrity sha512-ZtCXxoFlM7oDv3iZ3wsrT3SamhtUJuIkX2WePLPlN5bcbq7zimbPm2lHyicNJtpcGQ5ymsgpUWPCNZsWQhXBqQ== + dependencies: + "@react-native-community/cli-debugger-ui" "13.6.6" + "@react-native-community/cli-tools" "13.6.6" compression "^1.7.1" connect "^3.6.5" errorhandler "^1.5.1" nocache "^3.0.1" pretty-format "^26.6.2" serve-static "^1.13.1" - ws "^7.5.1" + ws "^6.2.2" -"@react-native-community/cli-tools@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-12.3.0.tgz#d459a116e1a95034d3c9a6385069c9e2049fb2a6" - integrity sha512-2GafnCr8D88VdClwnm9KZfkEb+lzVoFdr/7ybqhdeYM0Vnt/tr2N+fM1EQzwI1DpzXiBzTYemw8GjRq+Utcz2Q== +"@react-native-community/cli-tools@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-13.6.6.tgz#55c40cbabafbfc56cfb95a4d5fbf73ef60ec3cbc" + integrity sha512-ptOnn4AJczY5njvbdK91k4hcYazDnGtEPrqIwEI+k/CTBHNdb27Rsm2OZ7ye6f7otLBqF8gj/hK6QzJs8CEMgw== dependencies: appdirsjs "^1.2.4" chalk "^4.1.2" + execa "^5.0.0" find-up "^5.0.0" mime "^2.4.1" node-fetch "^2.6.0" @@ -5212,27 +5423,26 @@ shell-quote "^1.7.3" sudo-prompt "^9.0.0" -"@react-native-community/cli-types@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-12.3.0.tgz#2d21a1f93aefbdb34a04311d68097aef0388704f" - integrity sha512-MgOkmrXH4zsGxhte4YqKL7d+N8ZNEd3w1wo56MZlhu5WabwCJh87wYpU5T8vyfujFLYOFuFK5jjlcbs8F4/WDw== +"@react-native-community/cli-types@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-13.6.6.tgz#b45af119d61888fea1074a7c32ddb093e3f119a9" + integrity sha512-733iaYzlmvNK7XYbnWlMjdE+2k0hlTBJW071af/xb6Bs+hbJqBP9c03FZuYH2hFFwDDntwj05bkri/P7VgSxug== dependencies: joi "^17.2.1" -"@react-native-community/cli@12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-12.3.0.tgz#c89aacc3973943bf24002255d7d0859b511d88a1" - integrity sha512-XeQohi2E+S2+MMSz97QcEZ/bWpi8sfKiQg35XuYeJkc32Til2g0b97jRpn0/+fV0BInHoG1CQYWwHA7opMsrHg== +"@react-native-community/cli@13.6.6": + version "13.6.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-13.6.6.tgz#b929c8668e88344c03a46a3e635cb382dba16773" + integrity sha512-IqclB7VQ84ye8Fcs89HOpOscY4284VZg2pojHNl8H0Lzd4DadXJWQoxC7zWm8v2f8eyeX2kdhxp2ETD5tceIgA== dependencies: - "@react-native-community/cli-clean" "12.3.0" - "@react-native-community/cli-config" "12.3.0" - "@react-native-community/cli-debugger-ui" "12.3.0" - "@react-native-community/cli-doctor" "12.3.0" - "@react-native-community/cli-hermes" "12.3.0" - "@react-native-community/cli-plugin-metro" "12.3.0" - "@react-native-community/cli-server-api" "12.3.0" - "@react-native-community/cli-tools" "12.3.0" - "@react-native-community/cli-types" "12.3.0" + "@react-native-community/cli-clean" "13.6.6" + "@react-native-community/cli-config" "13.6.6" + "@react-native-community/cli-debugger-ui" "13.6.6" + "@react-native-community/cli-doctor" "13.6.6" + "@react-native-community/cli-hermes" "13.6.6" + "@react-native-community/cli-server-api" "13.6.6" + "@react-native-community/cli-tools" "13.6.6" + "@react-native-community/cli-types" "13.6.6" chalk "^4.1.2" commander "^9.4.1" deepmerge "^4.3.0" @@ -5282,39 +5492,28 @@ resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.6.1.tgz#3b20ddd1385fab0487db103dc6519570f8892e6d" integrity sha512-oJftvmLOj6Y6/bF4kPcK6L83yNBALGmqNYugf94BzP0FQGpHBwimVN2ygqkQ2Sn2ZU3pGUZMs0jV6+Gku2GyYg== -"@react-native-picker/picker@^1.8.3": - version "1.16.8" - resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-1.16.8.tgz#2126ca54d4a5a3e9ea5e3f39ad1e6643f8e4b3d4" - integrity sha512-pacdQDX6V6EmjF+HoiIh6u++qx4mTK0WnhgUHRc01B+Qt5eoeUwseBqmqfTSXTx/aHDEd6PiIw7UGvKgFoqgFQ== +"@react-native/assets-registry@0.74.83", "@react-native/assets-registry@~0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.83.tgz#c1815dc10f9e1075e0d03b4c8a9619145969522e" + integrity sha512-2vkLMVnp+YTZYTNSDIBZojSsjz8sl5PscP3j4GcV6idD8V978SZfwFlk8K0ti0BzRs11mzL0Pj17km597S/eTQ== -"@react-native/assets-registry@0.73.1", "@react-native/assets-registry@~0.73.1": - version "0.73.1" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.73.1.tgz#e2a6b73b16c183a270f338dc69c36039b3946e85" - integrity sha512-2FgAbU7uKM5SbbW9QptPPZx8N9Ke2L7bsHb+EhAanZjFZunA9PaYtyjUQ1s7HD+zDVqOQIvjkpXSv7Kejd2tqg== - -"@react-native/babel-plugin-codegen@*": - version "0.74.0" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.0.tgz#01ba90840e23c6d1fbf739f75cce1d0f5be97bfa" - integrity sha512-xAM/eVSb5LBkKue3bDZgt76bdsGGzKeF/iEzUNbDTwRQrB3Q5GoceGNM/zVlF+z1xGAkr3jhL+ZyITZGSoIlgw== +"@react-native/babel-plugin-codegen@0.74.1": + version "0.74.1" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.1.tgz#b8dfd2aac48241a2bb1db4a4fb6921eaabb2d2f8" + integrity sha512-v8T79fEn49cuDVCyUNXsgXZ/ydN8s6ydAruasVCh0VyMzaPVJvuOQhaLW6JL+ysDTN/CnjraTv0oqYnaKoZgvQ== dependencies: - "@react-native/codegen" "*" + "@react-native/codegen" "0.74.1" -"@react-native/babel-plugin-codegen@0.73.2": - version "0.73.2" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.73.2.tgz#447656cde437b71dc3ef0af3f8a5b215653d5d07" - integrity sha512-PadyFZWVaWXIBP7Q5dgEL7eAd7tnsgsLjoHJB1hIRZZuVUg1Zqe3nULwC7RFAqOtr5Qx7KXChkFFcKQ3WnZzGw== - dependencies: - "@react-native/codegen" "0.73.2" - -"@react-native/babel-preset@0.73.19": - version "0.73.19" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.73.19.tgz#a6c0587651804f8f01d6f3b7729f1d4a2d469691" - integrity sha512-ujon01uMOREZecIltQxPDmJ6xlVqAUFGI/JCSpeVYdxyXBoBH5dBb0ihj7h6LKH1q1jsnO9z4MxfddtypKkIbg== +"@react-native/babel-preset@0.74.1", "@react-native/babel-preset@0.74.83", "@react-native/babel-preset@^0.73.18", "@react-native/babel-preset@~0.74.83": + version "0.74.1" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.1.tgz#96813549cac768b5ff59c9b74f51acf80909e707" + integrity sha512-c7xbLs0/fjDmORYs86xz3syTFiJhtRb6JzXpGes04ZNdY7NWdz7aqEfeleyBJbmCfDOr16WZJRy4JcPLvNKjZg== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.18.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.0" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0" "@babel/plugin-proposal-numeric-separator" "^7.0.0" "@babel/plugin-proposal-object-rest-spread" "^7.20.0" @@ -5350,164 +5549,122 @@ "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - "@react-native/babel-plugin-codegen" "0.73.2" + "@react-native/babel-plugin-codegen" "0.74.1" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" -"@react-native/babel-preset@^0.73.18": - version "0.73.18" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.73.18.tgz#0ff24ba35102d9ac071de8ab10706ccaee5e3e6f" - integrity sha512-FzPasmazoX9WZnmwotk6SK9ydiExdqS4Xt5VaukPoY9u8u3AUUODzqjTsWSOxjFD9eRF3Knyg5H8JMDe6pj5wQ== - dependencies: - "@babel/core" "^7.20.0" - "@babel/plugin-proposal-async-generator-functions" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.18.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0" - "@babel/plugin-proposal-numeric-separator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.20.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.0" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.18.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.20.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.20.0" - "@babel/plugin-transform-flow-strip-types" "^7.20.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.11" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-self" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.5.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - "@react-native/babel-plugin-codegen" "*" - babel-plugin-transform-flow-enums "^0.0.2" - react-refresh "^0.14.0" - -"@react-native/codegen@*", "@react-native/codegen@0.73.2": - version "0.73.2" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.73.2.tgz#58af4e4c3098f0e6338e88ec64412c014dd51519" - integrity sha512-lfy8S7umhE3QLQG5ViC4wg5N1Z+E6RnaeIw8w1voroQsXXGPB72IBozh8dAHR3+ceTxIU0KX3A8OpJI8e1+HpQ== +"@react-native/codegen@0.74.1": + version "0.74.1" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.1.tgz#d20d0a8cd612fd927604fd1bfc8d18f2a231c270" + integrity sha512-Wup76wd01GnHvnyW8DGTOQDbbw6W4xBkqfzdTyCSue6cGpCasqNQAf4okuDJKwcSbgpVkNcJdbGuGtz4RTA65Q== dependencies: "@babel/parser" "^7.20.0" - flow-parser "^0.206.0" glob "^7.1.1" + hermes-parser "0.19.1" invariant "^2.2.4" jscodeshift "^0.14.0" mkdirp "^0.5.1" nullthrows "^1.1.1" -"@react-native/community-cli-plugin@0.73.12": - version "0.73.12" - resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.73.12.tgz#3a72a8cbae839a0382d1a194a7067d4ffa0da04c" - integrity sha512-xWU06OkC1cX++Duh/cD/Wv+oZ0oSY3yqbtxAqQA2H3Q+MQltNNJM6MqIHt1VOZSabRf/LVlR1JL6U9TXJirkaw== +"@react-native/codegen@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.83.tgz#7c56a82fe7603f0867f0d80ff29db3757b71be55" + integrity sha512-GgvgHS3Aa2J8/mp1uC/zU8HuTh8ZT5jz7a4mVMWPw7+rGyv70Ba8uOVBq6UH2Q08o617IATYc+0HfyzAfm4n0w== dependencies: - "@react-native-community/cli-server-api" "12.3.0" - "@react-native-community/cli-tools" "12.3.0" - "@react-native/dev-middleware" "0.73.7" - "@react-native/metro-babel-transformer" "0.73.13" + "@babel/parser" "^7.20.0" + glob "^7.1.1" + hermes-parser "0.19.1" + invariant "^2.2.4" + jscodeshift "^0.14.0" + mkdirp "^0.5.1" + nullthrows "^1.1.1" + +"@react-native/community-cli-plugin@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.83.tgz#58808a58a5288895627548338731e72ebb5b507c" + integrity sha512-7GAFjFOg1mFSj8bnFNQS4u8u7+QtrEeflUIDVZGEfBZQ3wMNI5ycBzbBGycsZYiq00Xvoc6eKFC7kvIaqeJpUQ== + dependencies: + "@react-native-community/cli-server-api" "13.6.6" + "@react-native-community/cli-tools" "13.6.6" + "@react-native/dev-middleware" "0.74.83" + "@react-native/metro-babel-transformer" "0.74.83" chalk "^4.0.0" execa "^5.1.1" metro "^0.80.3" metro-config "^0.80.3" metro-core "^0.80.3" node-fetch "^2.2.0" + querystring "^0.2.1" readline "^1.3.0" -"@react-native/debugger-frontend@0.73.3", "@react-native/debugger-frontend@^0.73.3": - version "0.73.3" - resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.73.3.tgz#033757614d2ada994c68a1deae78c1dd2ad33c2b" - integrity sha512-RgEKnWuoo54dh7gQhV7kvzKhXZEhpF9LlMdZolyhGxHsBqZ2gXdibfDlfcARFFifPIiaZ3lXuOVVa4ei+uPgTw== +"@react-native/debugger-frontend@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.83.tgz#48050afa4e086438073b95f041c0cc84fe3f20de" + integrity sha512-RGQlVUegBRxAUF9c1ss1ssaHZh6CO+7awgtI9sDeU0PzDZY/40ImoPD5m0o0SI6nXoVzbPtcMGzU+VO590pRfA== -"@react-native/dev-middleware@0.73.7": - version "0.73.7" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.73.7.tgz#61d2bf08973d9a537fa3f2a42deeb13530d721ae" - integrity sha512-BZXpn+qKp/dNdr4+TkZxXDttfx8YobDh8MFHsMk9usouLm22pKgFIPkGBV0X8Do4LBkFNPGtrnsKkWk/yuUXKg== +"@react-native/dev-middleware@0.74.83", "@react-native/dev-middleware@~0.74.75": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.83.tgz#9d09cfdb763e8ef81c003b0f99ae4ed1a3539639" + integrity sha512-UH8iriqnf7N4Hpi20D7M2FdvSANwTVStwFCSD7VMU9agJX88Yk0D1T6Meh2RMhUu4kY2bv8sTkNRm7LmxvZqgA== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.73.3" + "@react-native/debugger-frontend" "0.74.83" + "@rnx-kit/chromium-edge-launcher" "^1.0.0" chrome-launcher "^0.15.2" - chromium-edge-launcher "^1.0.0" connect "^3.6.5" debug "^2.2.0" node-fetch "^2.2.0" + nullthrows "^1.1.1" open "^7.0.3" + selfsigned "^2.4.1" serve-static "^1.13.1" temp-dir "^2.0.0" + ws "^6.2.2" -"@react-native/dev-middleware@^0.73.6": - version "0.73.6" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.73.6.tgz#19ee210fddc3abb8eeb3da5f98711719ad032323" - integrity sha512-9SD7gIso+hO1Jy1Y/Glbd+JWQwyH7Xjnwebtkxdm5TMB51LQPjaGtMcwEigbIZyAtvoaDGmhWmudwbKpDlS+gA== - dependencies: - "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "^0.73.3" - chrome-launcher "^0.15.2" - chromium-edge-launcher "^1.0.0" - connect "^3.6.5" - debug "^2.2.0" - node-fetch "^2.2.0" - open "^7.0.3" - serve-static "^1.13.1" - temp-dir "^2.0.0" +"@react-native/gradle-plugin@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.83.tgz#4ac60a6d6295d5b920173cbf184ee32e53690810" + integrity sha512-Pw2BWVyOHoBuJVKxGVYF6/GSZRf6+v1Ygc+ULGz5t20N8qzRWPa2fRZWqoxsN7TkNLPsECYY8gooOl7okOcPAQ== -"@react-native/gradle-plugin@0.73.4": - version "0.73.4" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.73.4.tgz#aa55784a8c2b471aa89934db38c090d331baf23b" - integrity sha512-PMDnbsZa+tD55Ug+W8CfqXiGoGneSSyrBZCMb5JfiB3AFST3Uj5e6lw8SgI/B6SKZF7lG0BhZ6YHZsRZ5MlXmg== +"@react-native/js-polyfills@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.83.tgz#0e189ce3ab0efecd00223f3bfc53663ce08ba013" + integrity sha512-/t74n8r6wFhw4JEoOj3bN71N1NDLqaawB75uKAsSjeCwIR9AfCxlzZG0etsXtOexkY9KMeZIQ7YwRPqUdNXuqw== -"@react-native/js-polyfills@0.73.1": - version "0.73.1" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.73.1.tgz#730b0a7aaab947ae6f8e5aa9d995e788977191ed" - integrity sha512-ewMwGcumrilnF87H4jjrnvGZEaPFCAC4ebraEK+CurDDmwST/bIicI4hrOAv+0Z0F7DEK4O4H7r8q9vH7IbN4g== - -"@react-native/metro-babel-transformer@0.73.13": - version "0.73.13" - resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.73.13.tgz#81cb6dd8d5140c57f5595183fd6857feb8b7f5d7" - integrity sha512-k9AQifogQfgUXPlqQSoMtX2KUhniw4XvJl+nZ4hphCH7qiMDAwuP8OmkJbz5E/N+Ro9OFuLE7ax4GlwxaTsAWg== +"@react-native/metro-babel-transformer@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.83.tgz#ba87c3cf041f4c0d2b991231af1a6b4a216e9b5d" + integrity sha512-hGdx5N8diu8y+GW/ED39vTZa9Jx1di2ZZ0aapbhH4egN1agIAusj5jXTccfNBwwWF93aJ5oVbRzfteZgjbutKg== dependencies: "@babel/core" "^7.20.0" - "@react-native/babel-preset" "0.73.19" - hermes-parser "0.15.0" + "@react-native/babel-preset" "0.74.83" + hermes-parser "0.19.1" nullthrows "^1.1.1" -"@react-native/normalize-color@^2.0.0", "@react-native/normalize-color@^2.1.0": +"@react-native/normalize-color@^2.0.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== -"@react-native/normalize-colors@0.73.2", "@react-native/normalize-colors@^0.73.0": +"@react-native/normalize-colors@0.74.83", "@react-native/normalize-colors@^0.74.1", "@react-native/normalize-colors@~0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.83.tgz#86ef925bacf219d74df115bcfb615f62d8142e85" + integrity sha512-jhCY95gRDE44qYawWVvhTjTplW1g+JtKTKM3f8xYT1dJtJ8QWv+gqEtKcfmOHfDkSDaMKG0AGBaDTSK8GXLH8Q== + +"@react-native/normalize-colors@^0.73.0": version "0.73.2" resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.73.2.tgz#cc8e48fbae2bbfff53e12f209369e8d2e4cf34ec" integrity sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w== -"@react-native/typescript-config@^0.74.0": - version "0.74.0" - resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.74.0.tgz#cb2cb58e4e424593c4ff5859e50d24dd54b14a63" - integrity sha512-Nt7AkbuLXIfoWmUrlTp06UTUj6LrMhwJhf/ReEHVpiaVJRjuqfjmwelvW/6dGSJjPFtYvziC+iaLLeyv2oBV7w== +"@react-native/typescript-config@^0.74.1": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.74.83.tgz#7a25567f565cf582419df7d2c038c8d2bd321b33" + integrity sha512-UTcZZYkSD+vv2O67bL/wu0GCGJP3BCbIxXd9ZewNkJmiWl5BbfoNl23+EjmDwM2V66gu24VB/RsSMn0TdmFs8Q== -"@react-native/virtualized-lists@0.73.4": - version "0.73.4" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.73.4.tgz#640e594775806f63685435b5d9c3d05c378ccd8c" - integrity sha512-HpmLg1FrEiDtrtAbXiwCgXFYyloK/dOIPIuWW3fsqukwJEWAiTzm1nXGJ7xPU5XTHiWZ4sKup5Ebaj8z7iyWog== +"@react-native/virtualized-lists@0.74.83": + version "0.74.83" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.83.tgz#5595d6aefd9679d1295c56a1d1653b1fb261bd62" + integrity sha512-rmaLeE34rj7py4FxTod7iMTC7BAsm+HrGA8WxYmEJeyTV7WSaxAkosKoYBz8038mOiwnG9VwA/7FrB6bEQvn1A== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -5603,6 +5760,18 @@ dependencies: type-fest "^2.19.0" +"@rnx-kit/chromium-edge-launcher@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@rnx-kit/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz#c0df8ea00a902c7a417cd9655aab06de398b939c" + integrity sha512-lzD84av1ZQhYUS+jsGqJiCMaJO2dn9u+RTT9n9q6D3SaKVwWqv+7AoRKqBu19bkwyE+iFRl1ymr40QS90jVFYg== + dependencies: + "@types/node" "^18.0.0" + escape-string-regexp "^4.0.0" + is-wsl "^2.2.0" + lighthouse-logger "^1.0.0" + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@rollup/plugin-babel@^5.2.0": version "5.3.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" @@ -7949,11 +8118,25 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + "@types/node@*": version "20.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" integrity sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg== +"@types/node@^18.0.0": + version "18.19.33" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.33.tgz#98cd286a1b8a5e11aa06623210240bcc28e95c48" + integrity sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A== + dependencies: + undici-types "~5.26.4" + "@types/node@^18.16.2": version "18.17.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.17.6.tgz#0296e9a30b22d2a8fcaa48d3c45afe51474ca55b" @@ -9171,10 +9354,10 @@ babel-plugin-react-native-web@^0.18.12, babel-plugin-react-native-web@~0.18.10: resolved "https://registry.yarnpkg.com/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.18.12.tgz#3e9764484492ea612a16b40135b07c2d05b7969d" integrity sha512-4djr9G6fMdwQoD6LQ7hOKAm39+y12flWgovAqS1k5O8f42YQ3A1FFMyV5kKfetZuGhZO5BmNmOdRRZQ1TixtDw== -babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: - version "7.0.0-beta.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" - integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== +babel-plugin-react-native-web@~0.19.10: + version "0.19.11" + resolved "https://registry.yarnpkg.com/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.19.11.tgz#32316f51de0053bba6815f6522bf7b17c483bf17" + integrity sha512-0sHf8GgDhsRZxGwlwHHdfL3U8wImFaLw4haEa60U9M3EiO3bg6u3BJ+1vXhwgrevqSq76rMb5j1HJs+dNvMj5g== babel-plugin-transform-flow-enums@^0.0.2: version "0.0.2" @@ -9226,53 +9409,20 @@ babel-preset-expo@^10.0.0: babel-plugin-react-native-web "~0.18.10" react-refresh "0.14.0" -babel-preset-expo@~10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/babel-preset-expo/-/babel-preset-expo-10.0.2.tgz#5aae992b8c85dce6cf98334c9991d3052c567950" - integrity sha512-hg06qdSTK7MjKmFXSiq6cFoIbI3n3uT8a3NI2EZoISWhu+tedCj4DQduwi+3adFuRuYvAwECI0IYn/5iGh5zWQ== +babel-preset-expo@~11.0.6: + version "11.0.6" + resolved "https://registry.yarnpkg.com/babel-preset-expo/-/babel-preset-expo-11.0.6.tgz#b1ea2bd9f13338a9f7ca8d7089b5d6d6c7c03f79" + integrity sha512-jRi9I5/jT+dnIiNJDjDg+I/pV+AlxrIW/DNbdqYoRWPZA/LHDqD6IJnJXLxbuTcQ+llp+0LWcU7f/kC/PgGpkw== dependencies: "@babel/plugin-proposal-decorators" "^7.12.9" "@babel/plugin-transform-export-namespace-from" "^7.22.11" "@babel/plugin-transform-object-rest-spread" "^7.12.13" "@babel/plugin-transform-parameters" "^7.22.15" - "@babel/preset-env" "^7.20.0" "@babel/preset-react" "^7.22.15" - "@react-native/babel-preset" "^0.73.18" - babel-plugin-react-native-web "~0.18.10" - react-refresh "0.14.0" - -babel-preset-fbjs@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz#38a14e5a7a3b285a3f3a86552d650dca5cf6111c" - integrity sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-member-expression-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-property-literals" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" + "@babel/preset-typescript" "^7.23.0" + "@react-native/babel-preset" "~0.74.83" + babel-plugin-react-native-web "~0.19.10" + react-refresh "^0.14.2" babel-preset-jest@^27.5.1: version "27.5.1" @@ -9408,11 +9558,6 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -blueimp-md5@^2.10.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0" - integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w== - bn.js@^4.0.0, bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -9613,29 +9758,23 @@ bytes@3.1.2, bytes@^3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^15.3.0: - version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== +cacache@^18.0.2: + version "18.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.3.tgz#864e2c18414e1e141ae8763f31e46c2cb96d1b21" + integrity sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg== dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^10.0.1" + minipass "^7.0.3" + minipass-collect "^2.0.1" minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" + minipass-pipeline "^1.2.4" p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" @@ -9858,18 +9997,6 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -chromium-edge-launcher@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/chromium-edge-launcher/-/chromium-edge-launcher-1.0.0.tgz#0443083074715a13c669530b35df7bfea33b1509" - integrity sha512-pgtgjNKZ7i5U++1g1PWv75umkHvhVTDOQIZ+sjeUX9483S7Y6MUvO0lrd7ShGlQlFHMN4SwKTCq/X8hWrbv2KA== - dependencies: - "@types/node" "*" - escape-string-regexp "^4.0.0" - is-wsl "^2.2.0" - lighthouse-logger "^1.0.0" - mkdirp "^1.0.4" - rimraf "^3.0.2" - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -10147,13 +10274,6 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== -compare-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-urls/-/compare-urls-2.0.0.tgz#9b378c4abd43980a8700fffec9afb85de4df9075" - integrity sha512-eCJcWn2OYFEIqbm70ta7LQowJOOZZqq1a2YbbFCFI1uwSvj+TWMwXVn7vPR1ceFNcAIt5RSTDbwdlX82gYLTkA== - dependencies: - normalize-url "^2.0.1" - component-type@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-type/-/component-type-1.2.1.tgz#8a47901700238e4fc32269771230226f24b415a9" @@ -10691,7 +10811,7 @@ decimal.js@^10.2.1, decimal.js@^10.4.2: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: +decode-uri-component@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== @@ -11054,10 +11174,12 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -dotenv-expand@~10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" - integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== +dotenv-expand@~11.0.6: + version "11.0.6" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-11.0.6.tgz#f2c840fd924d7c77a94eff98f153331d876882d3" + integrity sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g== + dependencies: + dotenv "^16.4.4" dotenv@^10.0.0: version "10.0.0" @@ -11069,10 +11191,10 @@ dotenv@^16.0.3, dotenv@^16.3.1: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== -dotenv@~16.0.3: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== +dotenv@^16.4.4, dotenv@~16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== dset@^3.1.1, dset@^3.1.2: version "3.1.2" @@ -11918,40 +12040,33 @@ expect@^29.7.0: jest-message-util "^29.7.0" jest-util "^29.7.0" -expo-application@^5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/expo-application/-/expo-application-5.8.3.tgz#43991bd81d05c987b07b2f430c036cda1572bc62" - integrity sha512-IISxzpPX+Xe4ynnwX8yY52T6dm1g9sME1GCj4lvUlrdc5xeTPM6U35x7Wj82V7lLWBaVGe+/Tg9EeKqfylCEwA== +expo-application@^5.9.1, expo-application@~5.9.0: + version "5.9.1" + resolved "https://registry.yarnpkg.com/expo-application/-/expo-application-5.9.1.tgz#a12e0cf2741b6f084cc49cd0121ad0a70c770459" + integrity sha512-uAfLBNZNahnDZLRU41ZFmNSKtetHUT9Ua557/q189ua0AWV7pQjoVAx49E4953feuvqc9swtU3ScZ/hN1XO/FQ== -expo-application@~5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/expo-application/-/expo-application-5.8.0.tgz#b82cb98a08f91d61f047f6578e883e0deb9661f2" - integrity sha512-nNQ/ayC4P1ue0ZQSmUlG/K2ZHTPwHyYGsb0QtEmCFUCitsjPKIx4coNvAreZMuELvY7pD1zKr+pdtN/ULnljBA== - -expo-asset@~9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-9.0.2.tgz#e8a6b6da356d5fc97955599d2fa49af78c7f0bfd" - integrity sha512-PzYKME1MgUOoUvwtdzhAyXkjXOXGiSYqGKG/MsXwWr0Ef5wlBaBm2DCO9V6KYbng5tBPFu6hTjoRNil1tBOSow== +expo-asset@~10.0.6: + version "10.0.6" + resolved "https://registry.yarnpkg.com/expo-asset/-/expo-asset-10.0.6.tgz#0894c4e824ce90e130852e6eecaba386e9f2e5aa" + integrity sha512-waP73/ccn/HZNNcGM4/s3X3icKjSSbEQ9mwc6tX34oYNg+XE5WdwOuZ9wgVVFrU7wZMitq22lQXd2/O0db8bxg== dependencies: - "@react-native/assets-registry" "~0.73.1" - blueimp-md5 "^2.10.0" - expo-constants "~15.4.0" - expo-file-system "~16.0.0" + "@react-native/assets-registry" "~0.74.83" + expo-constants "~16.0.0" invariant "^2.2.4" md5-file "^3.2.3" -expo-build-properties@^0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/expo-build-properties/-/expo-build-properties-0.11.1.tgz#dc9ab9fb1ac989b97da500b3ec75139c961d8b26" - integrity sha512-m4j4aEjFaDuBE6KWYMxDhWgLzzSmpE7uHKAwtvXyNmRK+6JKF0gjiXi0sXgI5ngNppDQpsyPFMvqG7uQpRuCuw== +expo-build-properties@^0.12.1: + version "0.12.1" + resolved "https://registry.yarnpkg.com/expo-build-properties/-/expo-build-properties-0.12.1.tgz#8d11759b8f382e4654e2482ddcec4f9ad4530aad" + integrity sha512-gn8sngNmOHkbJ5Kt3mKcKg+Wl6+d0m70gg9OllRIVeDkvZqCObKfnSM4tAQWiJhm62sHnL8udfYnuArnKhQd/g== dependencies: ajv "^8.11.0" - semver "^7.5.3" + semver "^7.6.0" -expo-camera@~14.0.4: - version "14.0.6" - resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-14.0.6.tgz#4d02ae2c7d734b2256111fa17a3b2c46fa712c78" - integrity sha512-PBkbAR0g/rFO9A01CmOoPHknXBBfJ1rXFm75XQY6kmMNH9BHJ89yAtlOaYJy/fw5xVxJkyVG+6uVGgbBeu7dyw== +expo-camera@~14.1.3: + version "14.1.3" + resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-14.1.3.tgz#c3b36c7ed28613e7423b6c4df192549f4f9ee0dd" + integrity sha512-JodpVjOY8JDuSp/RkphS8Bxqaj/gwg0h0UbQB9MLr1LoxbL9brvJt7IZnmTf7+ON8jRKUx9E5o/F02pRNbmSbQ== dependencies: invariant "^2.2.4" @@ -11968,61 +12083,54 @@ expo-constants@^13.0.2: "@expo/config" "~7.0.0" uuid "^3.3.2" -expo-constants@~15.4.0: - version "15.4.1" - resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-15.4.1.tgz#f76f347cf687b6630e1e3b9a385a4e42771671a4" - integrity sha512-aLAN7HOMRFQ5dVduDLPxSlAhsA5OubDxFeM1uo3CHQoaXZfxyJv6g64zjLsOBzVSEIRmNQZl7+1mc5rujZDU2w== +expo-constants@~15.4.6: + version "15.4.6" + resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-15.4.6.tgz#d4e9b21b70c5602457962700f2e90a75356b487b" + integrity sha512-vizE69dww2Vl0PTWWvDmK0Jo2/J+WzdcMZlA05YEnEYofQuhKxTVsiuipf79mSOmFavt4UQYC1UnzptzKyfmiQ== dependencies: "@expo/config" "~8.5.0" -expo-constants@~15.4.3: - version "15.4.3" - resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-15.4.3.tgz#e6080323e3651e98c1433ba0d06d1352cfbd2203" - integrity sha512-iOLIB0ckJFSzsH68FoYp9f8FB0CjKViuLnRID+OhiF3IGL1ja9IZdfvtZgkGJ27Az79yThX/9ktlw77+5ejGbA== +expo-constants@~16.0.0: + version "16.0.1" + resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-16.0.1.tgz#1285e29c85513c6e88e118289e2baab72596d3f7" + integrity sha512-s6aTHtglp926EsugWtxN7KnpSsE9FCEjb7CgEjQQ78Gpu4btj4wB+IXot2tlqNwqv+x7xFe5veoPGfJDGF/kVg== dependencies: - "@expo/config" "~8.5.0" + "@expo/config" "~9.0.0-beta.0" -expo-constants@~15.4.5: - version "15.4.5" - resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-15.4.5.tgz#81756a4c4e1c020f840a419cd86a124a6d1fb35b" - integrity sha512-1pVVjwk733hbbIjtQcvUFCme540v4gFemdNlaxM2UXKbfRCOh2hzgKN5joHMOysoXQe736TTUrRj7UaZI5Yyhg== +expo-dev-client@^4.0.14: + version "4.0.14" + resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-4.0.14.tgz#73d2f8b6f173d01f07af3e01cf8d5acdc6e05c01" + integrity sha512-s5/FZZdgvoxBGA35QgNet61Dc1jh+8u375uaYkH9pUvfKFXURd9PDDAWvtAnOo+QYg9WwgiHPo7dKeCdN6pOPA== dependencies: - "@expo/config" "~8.5.0" + expo-dev-launcher "4.0.15" + expo-dev-menu "5.0.14" + expo-dev-menu-interface "1.8.3" + expo-manifests "~0.14.0" + expo-updates-interface "~0.16.2" -expo-dev-client@~3.3.8: - version "3.3.11" - resolved "https://registry.yarnpkg.com/expo-dev-client/-/expo-dev-client-3.3.11.tgz#f2541ccbcfc2ba32bcea47293bc9beae4e10db60" - integrity sha512-9nhhbfbskfmjp/tlRS5KvDpCoW0BREJBxpu2GyjKu7nDB33W8fJLL0wXgNhP+QEb93r37o3uezKmUm2kibOvTw== - dependencies: - expo-dev-launcher "3.6.9" - expo-dev-menu "4.5.8" - expo-dev-menu-interface "1.7.2" - expo-manifests "~0.13.0" - expo-updates-interface "~0.15.1" - -expo-dev-launcher@3.6.9: - version "3.6.9" - resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-3.6.9.tgz#5e104e0533a46f3614c1691673da3351092e8d1d" - integrity sha512-MBDMAqjCMVYt1Zv47u2dJTp4d8gCZMfM4GWAFhfQy3G6XzkUlFtewaQefAqy93FcYOv6BYdC9yZOLOb06tqTfA== +expo-dev-launcher@4.0.15: + version "4.0.15" + resolved "https://registry.yarnpkg.com/expo-dev-launcher/-/expo-dev-launcher-4.0.15.tgz#cd36f10b7e534e5caa176a5718381ccfa73b0b8c" + integrity sha512-avl4NTwFwalZjojFAXvINPgxAlcAxfdwy9PSsAq5KAkl9Vv+Vr8O2gI3nfrPwtqAA0iOIES/EKN0YFCiQuuvvg== dependencies: ajv "8.11.0" - expo-dev-menu "4.5.8" - expo-manifests "~0.13.0" + expo-dev-menu "5.0.14" + expo-manifests "~0.14.0" resolve-from "^5.0.0" - semver "^7.5.3" + semver "^7.6.0" -expo-dev-menu-interface@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/expo-dev-menu-interface/-/expo-dev-menu-interface-1.7.2.tgz#772fb97c6b0a44c27965cdfcfa078f316b0930ca" - integrity sha512-V/geSB9rW0IPTR+d7E5CcvkV0uVUCE7SMHZqE/J0/dH06Wo8AahB16fimXeh5/hTL2Qztq8CQ41xpFUBoA9TEw== +expo-dev-menu-interface@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/expo-dev-menu-interface/-/expo-dev-menu-interface-1.8.3.tgz#8c1262e29e0124fc5932a129c95b36de56656b20" + integrity sha512-QM0LRozeFT5Ek0N7XpV93M+HMdEKRLEOXn0aW5M3uoUlnqC1+PLtF3HMy3k3hMKTTE/kJ1y1Z7akH07T0lunCQ== -expo-dev-menu@4.5.8: - version "4.5.8" - resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-4.5.8.tgz#21940385124c7d2745066bbcb42185ebd35f66bc" - integrity sha512-GXfI0CmYlqjOqyFjtplXO9PSoJQoy89+50lbUSNZykDsGyvzCPzl4txdQcdHHSglKYr7lWV7aeMVeehuSct60w== +expo-dev-menu@5.0.14: + version "5.0.14" + resolved "https://registry.yarnpkg.com/expo-dev-menu/-/expo-dev-menu-5.0.14.tgz#7d54fc51b42217588cb9c5f2049bcf857d6e0b3d" + integrity sha512-zPXBMCyjptn4Aw7D2Z8FEqndED33g1ryChN0nyTA1zHzckDNwnGuLdTWTsNFrqmFqyqjRJgG5xFVJmnsDO8WyQ== dependencies: - expo-dev-menu-interface "1.7.2" - semver "^7.5.3" + expo-dev-menu-interface "1.8.3" + semver "^7.5.4" expo-device@~4.1.1: version "4.1.1" @@ -12032,31 +12140,31 @@ expo-device@~4.1.1: ua-parser-js "^0.7.19" expo-device@~5.9.3: - version "5.9.3" - resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-5.9.3.tgz#0ad61da681424aa682fa03001d0344394c01f8a1" - integrity sha512-azH5rz8krDZUJb/arqkcA6oZGaX2T5s4aaXIMFsDDzvq8TW0CttZZy2HFp6itmFdiKGdRpFX3/Gj0n6ZmPoJ/w== + version "5.9.4" + resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-5.9.4.tgz#7dc8ba3695e1c0891bbc840a255faac479310c08" + integrity sha512-nleq3GghLWWJrj4YH8HiCumnTF/gy4zRd3jedCkO8lMKQg6R1yn3v0ch8NtgPDci749FkNzOtXx/vmFImQalwg== dependencies: ua-parser-js "^0.7.33" -expo-eas-client@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/expo-eas-client/-/expo-eas-client-0.11.0.tgz#0f25aa497849cade7ebef55c0631093a87e58b07" - integrity sha512-99W0MUGe3U4/MY1E9UeJ4uKNI39mN8/sOGA0Le8XC47MTbwbLoVegHR3C5y2fXLwLn7EpfNxAn5nlxYjY3gD2A== +expo-eas-client@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/expo-eas-client/-/expo-eas-client-0.12.0.tgz#e8b6f7d33873e6f630f37f7bfc41646ae7b0b2a9" + integrity sha512-Jkww9Cwpv0z7DdLYiRX0r4fqBEcI9cKqTn7cHx63S09JaZ2rcwEE4zYHgrXwjahO+tU2VW8zqH+AJl6RhhW4zA== -expo-file-system@^16.0.9, expo-file-system@~16.0.9: +expo-file-system@^16.0.9: version "16.0.9" resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-16.0.9.tgz#cbd6c4b228b60a6b6c71fd1b91fe57299fb24da7" integrity sha512-3gRPvKVv7/Y7AdD9eHMIdfg5YbUn2zbwKofjsloTI5sEC57SLUFJtbLvUCz9Pk63DaSQ7WIE1JM0EASyvuPbuw== -expo-file-system@~16.0.0: - version "16.0.1" - resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-16.0.1.tgz#326b7c2f6e53e1a0eaafc9769578aafb3f9c9f43" - integrity sha512-/U6ufN2wRPgg4m2a9sqbL3dThqQsysT022qulEXWnUTmNaqnzYSk9ihjDWqoqjXLi9slQLsyok5t6CNzhM7HPw== +expo-file-system@~17.0.1: + version "17.0.1" + resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-17.0.1.tgz#b9f8af8c1c06ec71d96fd7a0d2567fa9e1c88f15" + integrity sha512-dYpnZJqTGj6HCYJyXAgpFkQWsiCH3HY1ek2cFZVHFoEc5tLz9gmdEgTF6nFHurvmvfmXqxi7a5CXyVm0aFYJBw== -expo-font@~11.10.3: - version "11.10.3" - resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-11.10.3.tgz#a3115ebda8e09bd7cb8052619a4bbe606f0c17f4" - integrity sha512-q1Td2zUvmLbCA9GV4OG4nLPw5gJuNY1VrPycsnemN1m8XWTzzs8nyECQQqrcBhgulCgcKZZJJ6U0kC2iuSoQHQ== +expo-font@~12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/expo-font/-/expo-font-12.0.5.tgz#3451c2bd3f98859b127a6484d3474a292889b93f" + integrity sha512-h/VkN4jlHYDJ6T6pPgOYTVoDEfBY0CTKQe4pxnPDGQiE6H+DFdDgk+qWVABGpRMH0+zXoHB+AEi3OoQjXIynFA== dependencies: fontfaceobserver "^2.1.0" @@ -12065,114 +12173,113 @@ expo-haptics@^12.8.1: resolved "https://registry.yarnpkg.com/expo-haptics/-/expo-haptics-12.8.1.tgz#42b996763be33d661bd33bbc3b3958c3f2734b9d" integrity sha512-ntLsHkfle8K8w9MW8pZEw92ZN3sguaGUSSIxv30fPKNeQFu7Cq/h47Qv3tONv2MO3wU48N9FbKnant6XlfptpA== -expo-image-loader@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-4.6.0.tgz#ca7d4fdf53125bff2091d3a2c34a3155f10df147" - integrity sha512-RHQTDak7/KyhWUxikn2yNzXL7i2cs16cMp6gEAgkHOjVhoCJQoOJ0Ljrt4cKQ3IowxgCuOrAgSUzGkqs7omj8Q== +expo-image-loader@~4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-4.7.0.tgz#d403106822de80bda12d644c82b7a3b7983c0f0b" + integrity sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g== -expo-image-manipulator@^11.8.0: - version "11.8.0" - resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-11.8.0.tgz#e52351728619e534c949ae4b394af2c7c5d16702" - integrity sha512-ZWVrHnYmwJq6h7auk+ropsxcNi+LyZcPFKQc8oy+JA0SaJosfShvkCm7RADWAunHmfPCmjHrhwPGEu/rs7WG/A== +expo-image-manipulator@^12.0.3: + version "12.0.3" + resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-12.0.3.tgz#797fda98f606a65c6be9d2c0f53256f3fb3f798c" + integrity sha512-gosW32roHbXRKPiBVbQDFpxaZf8sjOJ9aaqbe085Qfcenvvr1lNFMx9M9BFYhAoKd23oEWlyvNHDnAayV4gAFA== dependencies: - expo-image-loader "~4.6.0" + expo-image-loader "~4.7.0" -expo-image-picker@~14.7.1: - version "14.7.1" - resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-14.7.1.tgz#c51faff3a3fbffc6ae93d7155370beb1a2d2baea" - integrity sha512-ILQVOJgI3aEzrDmCFGDPtpAepYkn8mot8G7vfQ51BfFdQbzL6N3Wm1fS/ofdWlAZJl/qT2DwaIh5xYmf3SyGZA== +expo-image-picker@~15.0.4: + version "15.0.4" + resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-15.0.4.tgz#b01121b26c88ee14bf49133160e408c1e7972b4d" + integrity sha512-Jo78o3DQfqpYC4fsnayxTEVGDFSbaNMwx5gQ2PPlEYMK5AmD5qexQjxhlxM1mZ0e1xkJKJfN7XEdcf53jW9vIg== dependencies: - expo-image-loader "~4.6.0" + expo-image-loader "~4.7.0" -expo-image@~1.10.6: - version "1.10.6" - resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-1.10.6.tgz#b0e54d31d97742505296c076a5f18d094ba9a8cc" - integrity sha512-vcnAIym1eU8vQgV1re1E7rVQZStJimBa4aPDhjFfzMzbddAF7heJuagyewiUkTzbZUwYzPaZAie6VJPyWx9Ueg== +expo-image@~1.12.9: + version "1.12.9" + resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-1.12.9.tgz#b6354ab1dcff65df596399a538e6985c44aacc0b" + integrity sha512-WnC3Z3vsOTJLWE9FGB0a0GANmkpfBCqTf9bSLXXl50hEYiRcfwrAYZ/87oswAhggMGbJqOuLKZxt5rtuij1xcQ== dependencies: - "@react-native/assets-registry" "~0.73.1" + "@react-native/assets-registry" "~0.74.83" -expo-json-utils@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/expo-json-utils/-/expo-json-utils-0.12.0.tgz#15ad797e9518a6a47eae9b95599e6373e641f8f2" - integrity sha512-xsUsPUZcXZWoT4RY3FhEPYGYvr2iThMNNU5drdmkC/vmkePvqy5kK4aIqlIKzQboXxj7k1dXoNSSLg5mKy8uKg== +expo-json-utils@~0.13.0: + version "0.13.1" + resolved "https://registry.yarnpkg.com/expo-json-utils/-/expo-json-utils-0.13.1.tgz#e49b697198e11c573d346f08ab91c467095934a9" + integrity sha512-mlfaSArGVb+oJmUcR22jEONlgPp0wj4iNIHfQ2je9Q8WTOqMc0Ws9tUciz3JdJnhffdHqo/k8fpvf0IRmN5HPA== -expo-keep-awake@~12.8.2: - version "12.8.2" - resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-12.8.2.tgz#6cfdf8ad02b5fa130f99d4a1eb98e459d5b4332e" - integrity sha512-uiQdGbSX24Pt8nGbnmBtrKq6xL/Tm3+DuDRGBk/3ZE/HlizzNosGRIufIMJ/4B4FRw4dw8KU81h2RLuTjbay6g== +expo-keep-awake@~13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz#5ef31311a339671eec9921b934fdd90ab9652b0e" + integrity sha512-kKiwkVg/bY0AJ5q1Pxnm/GvpeB6hbNJhcFsoOWDh2NlpibhCLaHL826KHUM+WsnJRbVRxJ+K9vbPRHEMvFpVyw== -expo-linear-gradient@^12.7.2: - version "12.7.2" - resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-12.7.2.tgz#2ff9593eae8448ac5630be1a36ce6133c4a6f074" - integrity sha512-Wwb2EF18ywgrlTodcXJ6Yt/UEcKitRMdXPNyP/IokmeKh4emoq9DxZJpZdkXm3HUTLlbRpi6/t32jrFVqXB9AQ== +expo-linear-gradient@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/expo-linear-gradient/-/expo-linear-gradient-13.0.2.tgz#21bd7bc7c71ef4f7c089521daa16db729d2aec5f" + integrity sha512-EDcILUjRKu4P1rtWcwciN6CSyGtH7Bq4ll3oTRV7h3h8oSzSilH1g6z7kTAMlacPBKvMnkkWOGzW6KtgMKEiTg== -expo-linking@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-6.2.2.tgz#b7e148068ae49fd9ad814428c16fdf7a236e8aca" - integrity sha512-FEe6lP4f7xFT/vjoHRG+tt6EPVtkEGaWNK1smpaUevmNdyCJKqW0PDB8o8sfG6y7fly8ULe8qg3HhKh5J7aqUQ== +expo-linking@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-6.3.1.tgz#05aef8a42bd310391d0b00644be40d80ece038d9" + integrity sha512-xuZCntSBGWCD/95iZ+mTUGTwHdy8Sx+immCqbUBxdvZ2TN61P02kKg7SaLS8A4a/hLrSCwrg5tMMwu5wfKr35g== dependencies: - expo-constants "~15.4.3" + expo-constants "~16.0.0" invariant "^2.2.4" -expo-localization@~14.8.3: - version "14.8.3" - resolved "https://registry.yarnpkg.com/expo-localization/-/expo-localization-14.8.3.tgz#c1efa8a314b6bfe38425bbc6bcce9cf9b84a802d" - integrity sha512-leg1e+7ocUgfNWa7Men/g16waXtdSpBMR9tCdv3CG4wztmFU8C+87VAnnVkvHi4CCUkTLzhP3y0FcE6KIWTwdw== +expo-localization@~15.0.3: + version "15.0.3" + resolved "https://registry.yarnpkg.com/expo-localization/-/expo-localization-15.0.3.tgz#772c89b3ab9c925b7eca6911a11ca33980c2b674" + integrity sha512-IfcmlKuKRlowR9qIzL0e+nGHBeNoF7l2GQaOJstc7HZiPjNJ4J1R4D53ZNf483dt7JSkTRJBihdTadOtOEjRdg== dependencies: rtl-detect "^1.0.2" -expo-manifests@~0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/expo-manifests/-/expo-manifests-0.13.0.tgz#20f163f84a414c6c50b8079e5fd0685d7c5b8ce2" - integrity sha512-N3adl3edSga3jdatLXjXiltdSwQkB1rOI5uyGEE5OwR/bpxc/5OUgHdRZjJgY6jJmVY4BCAiw0RXFoVRBbgE0Q== +expo-manifests@~0.14.0: + version "0.14.2" + resolved "https://registry.yarnpkg.com/expo-manifests/-/expo-manifests-0.14.2.tgz#431a235f21ca667ea8f8642819fbc414a8473174" + integrity sha512-hFrwIGr76/zGVhZ+vcjDZpOePd7uYNB6yCaiJcm7/bcrt2ne7cHyKQ8l+3n26/v1OuXfBfjxNH+PHIpkClszoQ== dependencies: - "@expo/config" "~8.5.0" - expo-json-utils "~0.12.0" + "@expo/config" "~9.0.0-beta.0" + expo-json-utils "~0.13.0" -expo-media-library@~15.9.1: - version "15.9.1" - resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-15.9.1.tgz#1eaf5a0c8f51669f6f86d385a8fa411226042216" - integrity sha512-Y29uKFJ3qWwNejIrjoCppXp3OgIFs/RYHWXkF9xey6evpNrUlHoP1WHG2jYAMSrss6aIRVt3tO7EtYUCZxz50Q== +expo-media-library@~16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/expo-media-library/-/expo-media-library-16.0.3.tgz#789277a827b9c04e59eef84aa11f4edcf5f1cfce" + integrity sha512-E++h+ZyVOXhGOKddeg/wjoEFH+JAGazcAsMpjAOT+/F69nrIEl27Fymi9XVAzooazp38dKrDBNeOJuWoXUdUAw== -expo-modules-autolinking@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-1.10.3.tgz#19f349884a90f3f27ec9d64e8f2fa6be609558c5" - integrity sha512-pn4n2Dl4iRh/zUeiChjRIe1C7EqOw1qhccr85viQV7W6l5vgRpY0osE51ij5LKg/kJmGRcJfs12+PwbdTplbKw== +expo-modules-autolinking@1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/expo-modules-autolinking/-/expo-modules-autolinking-1.11.1.tgz#4a867f727d9dfde07de8dde14b333a3cbf82ce3c" + integrity sha512-2dy3lTz76adOl7QUvbreMCrXyzUiF8lygI7iFJLjgIQIVH+43KnFWE5zBumpPbkiaq0f0uaFpN9U0RGQbnKiMw== dependencies: - "@expo/config" "~8.5.0" chalk "^4.1.0" commander "^7.2.0" fast-glob "^3.2.5" find-up "^5.0.0" fs-extra "^9.1.0" -expo-modules-core@1.11.13: - version "1.11.13" - resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-1.11.13.tgz#a8e63ad844e966dce78dea40b50839af6c3bc518" - integrity sha512-2H5qrGUvmLzmJNPDOnovH1Pfk5H/S/V0BifBmOQyDc9aUh9LaDwkqnChZGIXv8ZHDW8JRlUW0QqyWxTggkbw1A== +expo-modules-core@1.12.11: + version "1.12.11" + resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-1.12.11.tgz#71d7efb2f6a2a4d3b96defad52fc799b9804f829" + integrity sha512-CF5G6hZo/6uIUz6tj4dNRlvE5L4lakYukXPqz5ZHQ+6fLk1NQVZbRdpHjMkxO/QSBQcKUzG/ngeytpoJus7poQ== dependencies: invariant "^2.2.4" -expo-navigation-bar@~2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/expo-navigation-bar/-/expo-navigation-bar-2.8.1.tgz#c4152f878d9fb6ca74c90b80e934af76c29b5377" - integrity sha512-aT5G+7SUsXDVPsRwp8fF940ycka1ABb4g3QKvTZN3YP6kMWvsiYEmRqMIJVy0zUr/i6bxBG1ZergkXimWrFt3w== +expo-navigation-bar@~3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/expo-navigation-bar/-/expo-navigation-bar-3.0.4.tgz#c122194f720f0fb03430fa8a34c15980fc0a169f" + integrity sha512-hlnYnoFX3L1hHZxcnTVwAQW3AM5xf3clWYjqB2UMSIfTxCaE2PU8aHtAztLBQANrQhEvnbiwNcrkzfnWU2WWCQ== dependencies: - "@react-native/normalize-color" "^2.0.0" + "@react-native/normalize-colors" "~0.74.83" debug "^4.3.2" -expo-notifications@~0.27.6: - version "0.27.6" - resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.27.6.tgz#ef7c95504034ac8b5fa360e13f5b037c5bf7e80d" - integrity sha512-F2iu/lzsrvfMyHA5BfnbZfE8fVLV8aQmNLk3NPztZ0g7911QEriZzH7BK/NKOZ5UHhJYI+hhYvcZCq2nFm1NLA== +expo-notifications@~0.28.1: + version "0.28.1" + resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.28.1.tgz#9152cb17100ce72b66f2bf642fb097c3ae2d2019" + integrity sha512-qBVcq3lc+FIvcYt/8M+JB1c60g0hVuyGY4MVGTY56ciU6nMOCiBiz4XPc3DeiZA16jVtfriooWA26wqBkQfkHg== dependencies: - "@expo/image-utils" "^0.4.0" + "@expo/image-utils" "^0.5.0" "@ide/backoff" "^1.0.0" abort-controller "^3.0.0" assert "^2.0.0" badgin "^1.1.5" - expo-application "~5.8.0" - expo-constants "~15.4.0" + expo-application "~5.9.0" + expo-constants "~16.0.0" fs-extra "^9.1.0" expo-pwa@0.0.127: @@ -12185,91 +12292,92 @@ expo-pwa@0.0.127: commander "2.20.0" update-check "1.5.3" -expo-sharing@^11.10.0: - version "11.10.0" - resolved "https://registry.yarnpkg.com/expo-sharing/-/expo-sharing-11.10.0.tgz#0e85197ee4d2634b00fe201e571fbdc64cf83eef" - integrity sha512-/64RyyKlZ25WfnMXa87HbPXhIIqWwNbIku/RaIYAq4SE0XTRC+KTH3v0XFkfDa+SCG/jKsAr1pJ3vQvsNo1sCQ== +expo-sharing@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/expo-sharing/-/expo-sharing-12.0.1.tgz#6c4d951beda47dac47112e679d60fc06c233b7aa" + integrity sha512-wBT+WeXwapj/9NWuLJO01vi9bdlchYu/Q/xD8slL/Ls4vVYku8CPqzkTtDFcjLrjtlJqyeHsdQXwKLvORmBIew== -expo-splash-screen@~0.26.4: - version "0.26.4" - resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.26.4.tgz#bc1fb226c6eae03ee351a3ebe5521a37f868cbc7" - integrity sha512-2DwofTQ0FFQCsvDysm/msENsbyNsJiAJwK3qK/oXeizECAPqD7bK19J4z9kuEbr7ORPX9MLnTQYKl6kmX3keUg== +expo-splash-screen@~0.27.4: + version "0.27.4" + resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.27.4.tgz#d7a86a2a1a87824ed47388aa8836e91b61268c62" + integrity sha512-JwepK1FjbwiOK2nwIFanfzj9s7UXYnpTwLX8A9v7Ec3K4V28yu8HooSc9X60cftBw9UZrs8Gwj4PgTpQabBS9A== dependencies: - "@expo/prebuild-config" "6.7.4" + "@expo/prebuild-config" "7.0.3" -expo-status-bar@~1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-1.11.1.tgz#a11318741d361048c11db2b16c4364a79a74af30" - integrity sha512-ddQEtCOgYHTLlFUe/yH67dDBIoct5VIULthyT3LRJbEwdpzAgueKsX2FYK02ldh440V87PWKCamh7R9evk1rrg== +expo-status-bar@~1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/expo-status-bar/-/expo-status-bar-1.12.1.tgz#52ce594aab5064a0511d14375364d718ab78aa66" + integrity sha512-/t3xdbS8KB0prj5KG5w7z+wZPFlPtkgs95BsmrP/E7Q0xHXTcDcQ6Cu2FkFuRM+PKTb17cJDnLkawyS5vDLxMA== -expo-structured-headers@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/expo-structured-headers/-/expo-structured-headers-3.7.0.tgz#69b752cf43515535eccd30513da428688634a7ec" - integrity sha512-uGcU65gzP4trfmVtntAg3rU/pytTGpCUXN+hQmCwCCvQb9qK1aoCXvVlqlW5zP8SZ04tzF1WXKR+P8RSEn5rSw== +expo-structured-headers@~3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/expo-structured-headers/-/expo-structured-headers-3.8.0.tgz#11797a4c3a7a6770b21126cecffcda148030e361" + integrity sha512-R+gFGn0x5CWl4OVlk2j1bJTJIz4KO8mPoCHpRHmfqMjmrMvrOM0qQSY3V5NHXwp1yT/L2v8aUmFQsBRIdvi1XA== -expo-system-ui@~2.9.3: - version "2.9.3" - resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-2.9.3.tgz#845c7615a6ede9d959dff1719df3d9392a43c080" - integrity sha512-RNFNBLJ9lhnjOGrHhtfDc15Ry/lF+SA4kwulmHzYGqaTeYvsL9q0K0+m9qmxuDdrbKJkuurvzvjVylDNnKNFVg== +expo-system-ui@~3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/expo-system-ui/-/expo-system-ui-3.0.4.tgz#5ace49d38eb03c09a8041b3b82c581a6b974741a" + integrity sha512-v1n6hBO30k9qw6RE8/au4yNoovs71ExGuXizJUlR5KSo4Ruogpb+0/2q3uRZMDIYWWCANvms8L0UOh6fQJ5TXg== dependencies: - "@react-native/normalize-color" "^2.0.0" + "@react-native/normalize-colors" "~0.74.83" debug "^4.3.2" -expo-task-manager@~11.7.2: - version "11.7.2" - resolved "https://registry.yarnpkg.com/expo-task-manager/-/expo-task-manager-11.7.2.tgz#db09ee5ed4adf1ea586c131a60196cb387a7eb4a" - integrity sha512-cmn7xg8+mGP7gX6deYZhvrCkKMkoBRJ+E4o5aL17Z/4ihXMfo/PFcQsrpuSYRLXzgidEw0kpppxhmYm21Jswwg== +expo-task-manager@~11.8.1: + version "11.8.1" + resolved "https://registry.yarnpkg.com/expo-task-manager/-/expo-task-manager-11.8.1.tgz#33089e78ee3fbd83327fb403bce12d69baf7d21b" + integrity sha512-oGOUI8Cz9us1xFvWFftbMEvFGOIFYLa2xVguSGL7G+6ys0f+ozlkgT42KgG5qSwtDoqQ6+LMh9TJLLJUg1sVZw== dependencies: - unimodules-app-loader "~4.5.0" + unimodules-app-loader "~4.6.0" -expo-updates-interface@~0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/expo-updates-interface/-/expo-updates-interface-0.15.1.tgz#b0242fa7ba05768ada2f0faf83b90aa8b8fa65d7" - integrity sha512-B42oOB0pw4TaPoOGE/yzt9ggwNNxo3PEJRU0kIOurQ8hW5UEUC8cAbGQDYWGbTyNGp8gLBG+T2MCg+YYaCYJUw== +expo-updates-interface@~0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/expo-updates-interface/-/expo-updates-interface-0.16.2.tgz#ad1ac2ca8ee5a8cc84052ea3c18a11da64da569b" + integrity sha512-929XBU70q5ELxkKADj1xL0UIm3HvhYhNAOZv5DSk7rrKvLo7QDdPyl+JVnwZm9LrkNbH4wuE2rLoKu1KMgZ+9A== -expo-updates@~0.24.10: - version "0.24.12" - resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.24.12.tgz#17a708f52f999d0a7dcbf3d4401b5a481ab12730" - integrity sha512-35ZpAMSqHIyVGT5mEptaZJBxytu0mv4PIG28i3BQe+GG4ifQtY94aCOCrUwZe8Myzaf4dNVGEUXWTPo+JPCgcw== +expo-updates@~0.25.11: + version "0.25.11" + resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.25.11.tgz#a477139cfd5f67c7b5fdf41eba3f6dad471eeb14" + integrity sha512-ZO+e6bLsEBMz+JdEOlJXGf+3w606si7zKKEEzkwDQWJWP20W0WQAG+MDYgTEgxQboc+jTC+T0MvvOvkVb8cFIQ== dependencies: "@expo/code-signing-certificates" "0.0.5" - "@expo/config" "~8.5.0" - "@expo/config-plugins" "~7.8.0" + "@expo/config" "~9.0.0-beta.0" + "@expo/config-plugins" "~8.0.0-beta.0" + "@expo/fingerprint" "^0.7.0" + "@expo/spawn-async" "^1.7.2" arg "4.1.0" chalk "^4.1.2" - expo-eas-client "~0.11.0" - expo-manifests "~0.13.0" - expo-structured-headers "~3.7.0" - expo-updates-interface "~0.15.1" + expo-eas-client "~0.12.0" + expo-manifests "~0.14.0" + expo-structured-headers "~3.8.0" + expo-updates-interface "~0.16.2" + fast-glob "^3.3.2" fbemitter "^3.0.0" + ignore "^5.3.1" resolve-from "^5.0.0" -expo-web-browser@~12.8.2: - version "12.8.2" - resolved "https://registry.yarnpkg.com/expo-web-browser/-/expo-web-browser-12.8.2.tgz#f34fb85c80031e0dddd4f9b9efd03cb60333b089" - integrity sha512-Mw8WoFMSADecNjtC4PZVsVj1/lYdxIAH1jOVV+F8v8SEWYxORWofoShfXg7oUxRLu0iUG8JETfO5y4m8+fOgdg== - dependencies: - compare-urls "^2.0.0" - url "^0.11.0" +expo-web-browser@~13.0.3: + version "13.0.3" + resolved "https://registry.yarnpkg.com/expo-web-browser/-/expo-web-browser-13.0.3.tgz#dceb05dbc187b498ca937b02adf385b0232a4e92" + integrity sha512-HXb7y82ApVJtqk8tManyudtTrCtx8xcUnVzmJECeHCB0SsWSQ+penVLZxJkcyATWoJOsFMnfVSVdrTcpKKGszQ== -expo@^50.0.17: - version "50.0.17" - resolved "https://registry.yarnpkg.com/expo/-/expo-50.0.17.tgz#ab0998d7e7c18e8d12efd9091f9688978b0e89ed" - integrity sha512-eD8Nh10BgVwecU7EVyogx7X314ajxVpJdFwkXhi341AD61S2WPX31NMHW82XGXas6dbDjdbgtaOMo5H/vylB7Q== +expo@^51.0.8: + version "51.0.8" + resolved "https://registry.yarnpkg.com/expo/-/expo-51.0.8.tgz#a7981e86ee20eac4b847c7c8cc5799d9c6b1508d" + integrity sha512-bdTOiMb1f3PChtuqEZ9czUm2gMTmS0r1+H+Pkm2O3PsuLnOgxfIBzL6S37+J4cUocLBaENrmx9SOGKpzhBqXpg== dependencies: "@babel/runtime" "^7.20.0" - "@expo/cli" "0.17.10" - "@expo/config" "8.5.6" - "@expo/config-plugins" "7.9.1" - "@expo/metro-config" "0.17.7" + "@expo/cli" "0.18.13" + "@expo/config" "9.0.2" + "@expo/config-plugins" "8.0.4" + "@expo/metro-config" "0.18.4" "@expo/vector-icons" "^14.0.0" - babel-preset-expo "~10.0.2" - expo-asset "~9.0.2" - expo-file-system "~16.0.9" - expo-font "~11.10.3" - expo-keep-awake "~12.8.2" - expo-modules-autolinking "1.10.3" - expo-modules-core "1.11.13" + babel-preset-expo "~11.0.6" + expo-asset "~10.0.6" + expo-file-system "~17.0.1" + expo-font "~12.0.5" + expo-keep-awake "~13.0.2" + expo-modules-autolinking "1.11.1" + expo-modules-core "1.12.11" fbemitter "^3.0.0" whatwg-url-without-unicode "8.0.0-3" @@ -12355,6 +12463,17 @@ fast-glob@^3.2.12, fast-glob@^3.2.5, fast-glob@^3.2.7, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -12662,11 +12781,6 @@ flow-parser@0.*: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.215.0.tgz#9b153fa27ab238bcc0bb1ff73b63bdb15d3f277d" integrity sha512-8bjwzy8vi+fNDy8YoTBNtQUSZa53i7UWJJTunJojOtjab9cMNhOCwohionuMgDQUU0y21QTTtPOX6OQEOQT72A== -flow-parser@^0.206.0: - version "0.206.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.206.0.tgz#f4f794f8026535278393308e01ea72f31000bfef" - integrity sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w== - follow-redirects@^1.0.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" @@ -12804,6 +12918,13 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" +fs-minipass@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== + dependencies: + minipass "^7.0.3" + fs-monkey@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.4.tgz#ee8c1b53d3fe8bb7e5d2c5c5dfc0168afdd2f747" @@ -12967,6 +13088,17 @@ glob@7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.2.2: + version "10.4.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.1.tgz#0cfb01ab6a6b438177bfe6a58e2576f6efe909c2" + integrity sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + path-scurry "^1.11.1" + glob@^10.3.10: version "10.3.12" resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" @@ -13199,28 +13331,21 @@ he@1.2.0, he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-estree@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.15.0.tgz#e32f6210ab18c7b705bdcb375f7700f2db15d6ba" - integrity sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ== - hermes-estree@0.18.2: version "0.18.2" resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.18.2.tgz#fd450fa1659cf074ceaa2ddeeb21674f3b2342f3" integrity sha512-KoLsoWXJ5o81nit1wSyEZnWUGy9cBna9iYMZBR7skKh7okYAYKqQ9/OczwpMHn/cH0hKDyblulGsJ7FknlfVxQ== +hermes-estree@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.19.1.tgz#d5924f5fac2bf0532547ae9f506d6db8f3c96392" + integrity sha512-daLGV3Q2MKk8w4evNMKwS8zBE/rcpA800nu1Q5kM08IKijoSnPe9Uo1iIxzPKRkn95IxxsgBMPeYHt3VG4ej2g== + hermes-estree@0.20.1: version "0.20.1" resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.20.1.tgz#0b9a544cf883a779a8e1444b915fa365bef7f72d" integrity sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg== -hermes-parser@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.15.0.tgz#f611a297c2a2dbbfbce8af8543242254f604c382" - integrity sha512-Q1uks5rjZlE9RjMMjSUCkGrEIPI5pKJILeCtK1VmTj7U4pf3wVPoo+cxfu+s4cBAPy2JzikIIdCZgBoR6x7U1Q== - dependencies: - hermes-estree "0.15.0" - hermes-parser@0.18.2: version "0.18.2" resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.18.2.tgz#50f15e2fcd559a48c68cd7af259d4292298bd14d" @@ -13228,6 +13353,13 @@ hermes-parser@0.18.2: dependencies: hermes-estree "0.18.2" +hermes-parser@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.19.1.tgz#1044348097165b7c93dc198a80b04ed5130d6b1a" + integrity sha512-Vp+bXzxYJWrpEuJ/vXxUsLnt0+y4q9zyi4zUlkLqD8FKv4LjIfOvP69R/9Lty3dCyKh0E2BU7Eypqr63/rKT/A== + dependencies: + hermes-estree "0.19.1" + hermes-parser@^0.20.1: version "0.20.1" resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.20.1.tgz#ad10597b99f718b91e283f81cbe636c50c3cff92" @@ -13516,6 +13648,11 @@ ignore@^5.0.5, ignore@^5.1.9, ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +ignore@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + image-size@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.2.tgz#d778b6d0ab75b2737c1556dd631652eb963bc486" @@ -13567,11 +13704,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -13671,11 +13803,6 @@ ip-regex@^2.1.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== -ip@^1.1.5: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" - integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== - ipaddr.js@1.9.1, ipaddr.js@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -13931,11 +14058,6 @@ is-path-inside@^3.0.2, is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -14176,6 +14298,15 @@ jackspeak@^2.3.6: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" +jackspeak@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.1.2.tgz#eada67ea949c6b71de50f1b09c92a961897b90ab" + integrity sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: version "10.8.7" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" @@ -15769,6 +15900,11 @@ lodash.isequal@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== +lodash.isobject@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" + integrity sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA== + lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -15824,7 +15960,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -15878,6 +16014,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^10.0.1: + version "10.2.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" + integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== + lru-cache@^10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" @@ -16128,16 +16269,17 @@ metro-minify-terser@0.80.4: dependencies: terser "^5.15.0" -metro-react-native-babel-preset@^0.73.7: - version "0.73.10" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.10.tgz#304b24bb391537d2c987732cc0a9774be227d3f6" - integrity sha512-1/dnH4EHwFb2RKEKx34vVDpUS3urt2WEeR8FYim+ogqALg4sTpG7yeQPxWpbgKATezt4rNfqAANpIyH19MS4BQ== +metro-react-native-babel-preset@^0.74.1: + version "0.74.1" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.74.1.tgz#81c1c30f13f543c5848049e46e1afbc81df87de6" + integrity sha512-DjsG9nqm5C7cjB2SlgbcNJOn9y5MBUd3bRlCfnoj8CxAeGTGkS+yXd183lHR3C1bhmQNjuUE0abzzpE1CFh6JQ== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-numeric-separator" "^7.0.0" "@babel/plugin-proposal-object-rest-spread" "^7.0.0" "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" "@babel/plugin-proposal-optional-chaining" "^7.0.0" @@ -16166,7 +16308,6 @@ metro-react-native-babel-preset@^0.73.7: "@babel/plugin-transform-shorthand-properties" "^7.0.0" "@babel/plugin-transform-spread" "^7.0.0" "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" @@ -16382,7 +16523,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.1: +minimatch@^9.0.1, minimatch@^9.0.4: version "9.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== @@ -16394,12 +16535,12 @@ minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== +minipass-collect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" + integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== dependencies: - minipass "^3.0.0" + minipass "^7.0.3" minipass-flush@^1.0.5: version "1.0.5" @@ -16408,14 +16549,14 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-pipeline@^1.2.2: +minipass-pipeline@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== dependencies: minipass "^3.0.0" -minipass@3.3.6, minipass@^3.0.0, minipass@^3.1.1: +minipass@^3.0.0: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -16432,6 +16573,11 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== +minipass@^7.0.3, minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -16699,15 +16845,6 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== -normalize-url@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" - integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== - dependencies: - prepend-http "^2.0.0" - query-string "^5.0.1" - sort-keys "^2.0.0" - normalize-url@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" @@ -16994,7 +17131,7 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" -ora@3.4.0: +ora@3.4.0, ora@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== @@ -17296,6 +17433,14 @@ path-scurry@^1.10.2: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -18100,15 +18245,6 @@ postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@~8.4.21: - version "8.4.29" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" - integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - postcss@~8.4.32: version "8.4.38" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" @@ -18168,11 +18304,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== - prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -18275,11 +18406,6 @@ progress@2.0.3, progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -18498,11 +18624,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - punycode@^2.1.0, punycode@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" @@ -18530,22 +18651,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" -qs@^6.11.2, qs@^6.5.1: +qs@^6.5.1: version "6.11.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: side-channel "^1.0.4" -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - query-string@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" @@ -18556,6 +18668,11 @@ query-string@^7.1.3: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" +querystring@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" @@ -18686,10 +18803,10 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-devtools-core@^4.27.7: - version "4.28.5" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.28.5.tgz#c8442b91f068cdf0c899c543907f7f27d79c2508" - integrity sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA== +react-devtools-core@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-5.2.0.tgz#072ecd2d84d3653817cc11e4b16f60a3c2b705f9" + integrity sha512-vZK+/gvxxsieAoAyYaiRIVFxlajb7KXhgBDV7OsoMzaAE+IqGpoxusBjIgq5ibqA2IloKu0p9n7tE68z1xs18A== dependencies: shell-quote "^1.6.1" ws "^7" @@ -18734,10 +18851,10 @@ react-keyed-flatten-children@^3.0.0: dependencies: react-is "^18.2.0" -react-native-date-picker@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/react-native-date-picker/-/react-native-date-picker-4.4.0.tgz#fe5b6eb8d85a4a30b2991ada5169a30ce5023ead" - integrity sha512-Axx3byihwwhKRLRVjPAr/UaEysapkRcKmjjM8/05UaVm4Q0xDn2RFUcRdy1QAahhRcjLjlVYhepxvU5bdgy7ZQ== +react-native-date-picker@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/react-native-date-picker/-/react-native-date-picker-4.4.2.tgz#f7bb9daa8559237e08bd30f907ee8487a6e2a6ec" + integrity sha512-wYKN8nYWhETVHJV/+Im30JOdzkFRwYRrDlEOyyYesOjt+1JTFJh9M7K5CqePLOIB4Nxlf2f2lRSI0VoUyFIovA== react-native-dotenv@^3.3.1: version "3.4.9" @@ -18761,10 +18878,10 @@ react-native-fs@^2.20.0: base-64 "^0.1.0" utf8 "^3.0.0" -react-native-gesture-handler@~2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.14.0.tgz#d6aec0d8b2e55c67557fd6107e828c0a1a248be8" - integrity sha512-cOmdaqbpzjWrOLUpX3hdSjsMby5wq3PIEdMq7okJeg9DmCzanysHSrktw1cXWNc/B5MAgxAn9J7Km0/4UIqKAQ== +react-native-gesture-handler@~2.16.2: + version "2.16.2" + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.16.2.tgz#032bd2a07334292d7f6cff1dc9d1ec928f72e26d" + integrity sha512-vGFlrDKlmyI+BT+FemqVxmvO7nqxU33cgXVsn6IKAFishvlG3oV2Ds67D5nPkHMea8T+s1IcuMm0bF8ntZtAyg== dependencies: "@egjs/hammerjs" "^2.0.17" hoist-non-react-statics "^3.3.0" @@ -18786,10 +18903,10 @@ react-native-get-random-values@~1.11.0: dependencies: fast-base64-decode "^1.0.0" -react-native-image-crop-picker@^0.38.1: - version "0.38.1" - resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.38.1.tgz#5973b4a8b55835b987e6be2064de411e849ac005" - integrity sha512-cF5UQnWplzHCeiCO+aiGS/0VomWaLmFf3nSsgTMPfY+8+99h8N/eHQvVdSF7RsGw50B8394wGeGyqHjjp8YRWw== +react-native-image-crop-picker@0.40.3: + version "0.40.3" + resolved "https://registry.yarnpkg.com/react-native-image-crop-picker/-/react-native-image-crop-picker-0.40.3.tgz#a6b135cd1218a33ad126c1a148ec5a1bd01737ff" + integrity sha512-45PKcTnsnLS+E36YwoXutllQdRSOuOsMN0IRcAcwsFXOuAQIOtugXlAuGGL28JHKb/ATaSSPvqCSrdG65Jv3GA== react-native-ios-context-menu@^1.15.3: version "1.15.3" @@ -18808,13 +18925,13 @@ react-native-pager-view@6.2.3: resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.2.3.tgz#698f6387fdf06cecc3d8d4792604419cb89cb775" integrity sha512-dqVpXWFtPNfD3D2QQQr8BP+ullS5MhjRJuF8Z/qml4QTILcrWaW8F5iAxKkQR3Jl0ikcEryG/+SQlNcwlo0Ggg== -react-native-picker-select@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/react-native-picker-select/-/react-native-picker-select-8.1.0.tgz#667a5442f783f4bcfd3f65880c6926155fd2c39c" - integrity sha512-iLsLv2OEWpXnQMDYJS6du5Cl1HTHy887n60Yp5OOiMny0TDB9w5CfxTUYWtpsvJJrUa/Yrv+1NMQiJy7IA4ETw== +react-native-picker-select@^9.1.3: + version "9.1.3" + resolved "https://registry.yarnpkg.com/react-native-picker-select/-/react-native-picker-select-9.1.3.tgz#eaa052c483a7935def8fb28e5ffdf1537b37ded2" + integrity sha512-O2EmlY4Mg5fZWxECTQJBDhO61as6RDbPYYiNoryaa0gmIkWxhANLsZI+ElEVru1h0Fp9UlCFtBDI5MwhHR9AxA== dependencies: - "@react-native-picker/picker" "^1.8.3" lodash.isequal "^4.5.0" + lodash.isobject "^3.0.2" react-native-progress@bluesky-social/react-native-progress: version "5.0.0" @@ -18822,12 +18939,16 @@ react-native-progress@bluesky-social/react-native-progress: dependencies: prop-types "^15.7.2" -react-native-reanimated@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.6.0.tgz#d2ca5f4c234f592af3d63bc749806e36d6e0a755" - integrity sha512-eDdhZTRYofrIqFB/Z5xLTWxcB7wDj4ifrNm+gZ2xHSZPjAQ747ukDdH9rglPyPmi+GcmDH7Wff411Xsw5fm45Q== +react-native-reanimated@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-3.11.0.tgz#d4265d4e0232623f5958ed60e1686ca884fc3452" + integrity sha512-BNw/XDgUfs8UhfY1X6IniU8kWpnotWGyt8qmQviaHisTi5lvwnaOdXQKfN1KGONx6ekdFRHRP5EFwLi0UajwKA== dependencies: - "@babel/plugin-transform-object-assign" "^7.16.7" + "@babel/plugin-transform-arrow-functions" "^7.0.0-0" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.0.0-0" + "@babel/plugin-transform-optional-chaining" "^7.0.0-0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0-0" + "@babel/plugin-transform-template-literals" "^7.0.0-0" "@babel/preset-typescript" "^7.16.7" convert-source-map "^2.0.0" invariant "^2.2.4" @@ -18837,31 +18958,31 @@ react-native-root-siblings@^4.1.1: resolved "https://registry.yarnpkg.com/react-native-root-siblings/-/react-native-root-siblings-4.1.1.tgz#b7742db7634a87f507eb99a5fd699c4f10c46ab0" integrity sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA== -react-native-safe-area-context@4.8.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.8.2.tgz#e6b3d8acf3c6afcb4b5db03a97f9c37df7668f65" - integrity sha512-ffUOv8BJQ6RqO3nLml5gxJ6ab3EestPiyWekxdzO/1MQ7NF8fW1Mzh1C5QE9yq573Xefnc7FuzGXjtesZGv7cQ== +react-native-safe-area-context@4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.10.1.tgz#29fb27395ff7dfa2fa38788a27226330d73a81cc" + integrity sha512-w8tCuowDorUkPoWPXmhqosovBr33YsukkwYCDERZFHAxIkx6qBadYxfeoaJ91nCQKjkNzGrK5qhoNOeSIcYSpA== -react-native-screens@~3.29.0: - version "3.29.0" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.29.0.tgz#1dee0326defbc1d4ef4e68287abb32a8e6b76b29" - integrity sha512-yB1GoAMamFAcYf4ku94uBPn0/ani9QG7NdI98beJ5cet2YFESYYzuEIuU+kt+CNRcO8qqKeugxlfgAa3HyTqlg== +react-native-screens@~3.31.1: + version "3.31.1" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.31.1.tgz#909a890f669e32b0fb1b1410278b71ad2f8238f6" + integrity sha512-8fRW362pfZ9y4rS8KY5P3DFScrmwo/vu1RrRMMx0PNHbeC9TLq0Kw1ubD83591yz64gLNHFLTVkTJmWeWCXKtQ== dependencies: react-freeze "^1.0.0" warn-once "^0.1.0" -react-native-svg@14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-14.1.0.tgz#7903bddd3c71bf3a8a503918253c839e6edaa724" - integrity sha512-HeseElmEk+AXGwFZl3h56s0LtYD9HyGdrpg8yd9QM26X+d7kjETrRQ9vCjtxuT5dCZEIQ5uggU1dQhzasnsCWA== +react-native-svg@^15.2.0: + version "15.2.0" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.2.0.tgz#9561a6b3bd6b44689f437ba13182afee33bd5557" + integrity sha512-R0E6IhcJfVLsL0lRmnUSm72QO+mTqcAOM5Jb8FVGxJqX3NfJMlMP0YyvcajZiaRR8CqQUpEoqrY25eyZb006kw== dependencies: css-select "^5.1.0" css-tree "^1.1.3" -react-native-uitextview@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/react-native-uitextview/-/react-native-uitextview-1.1.6.tgz#a70d039f415158445c90de8e8e546a7c3b251d6d" - integrity sha512-OTGTw4Y2DDn4dHTwN7aKOndXP6NoS/AS35Rj/Rsss+KRsGHToiv2g3ZdzQ0ZhZabhwl1u+Oht+wSU/FU+SoJ+Q== +react-native-uitextview@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/react-native-uitextview/-/react-native-uitextview-1.1.7.tgz#ee60ca279b0f4d081451f0df707b0ceac4580de1" + integrity sha512-7NaeizflafRvdsuomR6F4UxGV3XY8ilgntX0npLkE3YyH0YJTikBAHunrRWEPtj1vjybYN2DuThMYRELcVqyuA== react-native-url-polyfill@^1.3.0: version "1.3.0" @@ -18870,10 +18991,10 @@ react-native-url-polyfill@^1.3.0: dependencies: whatwg-url-without-unicode "8.0.0-3" -react-native-uuid@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/react-native-uuid/-/react-native-uuid-2.0.1.tgz#ed4e2dfb1683eddb66967eb5dca140dfe1abddb9" - integrity sha512-cptnoIbL53GTCrWlb/+jrDC6tvb7ypIyzbXNJcpR3Vab0mkeaaVd5qnB3f0whXYzS+SMoSQLcUUB0gEWqkPC0g== +react-native-uuid@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/react-native-uuid/-/react-native-uuid-2.0.2.tgz#3da192e342ef35ee95a7def676ab41c1256dfd66" + integrity sha512-5ypj/hV58P+6VREdjkW0EudSibsH3WdqDERoHKnD9syFWjF+NfRWWrJb2sa3LIwI5zpzMvUiabs+DX40WHpEMw== react-native-view-shot@^3.8.0: version "3.8.0" @@ -18889,13 +19010,13 @@ react-native-web-webview@^1.0.2: dependencies: qs "^6.5.1" -react-native-web@~0.19.6: - version "0.19.8" - resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.19.8.tgz#46127f8b310148fde11e4fef67fe625603599d47" - integrity sha512-anqGGHowJdfkYqRxzoQj6DeetJf5hyBlahN6rwksw54gXxgjbsUOe4/PyxqvjwxYafgbVo0oow23BwpsRFdrpw== +react-native-web@~0.19.11: + version "0.19.11" + resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.19.11.tgz#1b96ac3cea9af4e1280fd5fa3b606b471f66edc3" + integrity sha512-51Qcjr0AtIgskwLqLsBByUMPs2nAWZ+6QF7x/siC72svNPcJ1/daXoPTNuHR2fX4oOrDATC4Vmc/SXOYPH19rw== dependencies: "@babel/runtime" "^7.18.6" - "@react-native/normalize-color" "^2.1.0" + "@react-native/normalize-colors" "^0.74.1" fbjs "^3.0.4" inline-style-prefixer "^6.0.1" memoize-one "^6.0.0" @@ -18903,35 +19024,35 @@ react-native-web@~0.19.6: postcss-value-parser "^4.2.0" styleq "^0.1.3" -react-native-webview@13.6.4: - version "13.6.4" - resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.6.4.tgz#6ef66db9dd78b2a2ae1b4fe79e1e3597aa29186e" - integrity sha512-AdgmaMBHPcyERTvng9eSGgHX6AleyUlSusWAxngSOSdiYGgHW81T6C5A8j/ImJAF9oZg0bQDxp43Hu56tzENZQ== +react-native-webview@13.10.2: + version "13.10.2" + resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-13.10.2.tgz#0f9b84ab38cca022d5b1c4e77c100f4d9591e7af" + integrity sha512-rjrTuPBtpHbI3owoyvSR+bRJqHfsdo5V3nVfU+G65CotkSLewEcGfA9cq7Qv3nzm5t0KEDIt0G/n7hQFjsXihQ== dependencies: escape-string-regexp "2.0.0" invariant "2.2.4" -react-native@0.73.2: - version "0.73.2" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.73.2.tgz#74ee163c8189660d41d1da6560411da7ce41a608" - integrity sha512-7zj9tcUYpJUBdOdXY6cM8RcXYWkyql4kMyGZflW99E5EuFPoC7Ti+ZQSl7LP9ZPzGD0vMfslwyDW0I4tPWUCFw== +react-native@0.74.1: + version "0.74.1" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.1.tgz#8f5f59636242eb1b90ff675d9fcc7f5b8b1c9913" + integrity sha512-0H2XpmghwOtfPpM2LKqHIN7gxy+7G/r1hwJHKLV6uoyXGC/gCojRtoo5NqyKrWpFC8cqyT6wTYCLuG7CxEKilg== dependencies: "@jest/create-cache-key-function" "^29.6.3" - "@react-native-community/cli" "12.3.0" - "@react-native-community/cli-platform-android" "12.3.0" - "@react-native-community/cli-platform-ios" "12.3.0" - "@react-native/assets-registry" "0.73.1" - "@react-native/codegen" "0.73.2" - "@react-native/community-cli-plugin" "0.73.12" - "@react-native/gradle-plugin" "0.73.4" - "@react-native/js-polyfills" "0.73.1" - "@react-native/normalize-colors" "0.73.2" - "@react-native/virtualized-lists" "0.73.4" + "@react-native-community/cli" "13.6.6" + "@react-native-community/cli-platform-android" "13.6.6" + "@react-native-community/cli-platform-ios" "13.6.6" + "@react-native/assets-registry" "0.74.83" + "@react-native/codegen" "0.74.83" + "@react-native/community-cli-plugin" "0.74.83" + "@react-native/gradle-plugin" "0.74.83" + "@react-native/js-polyfills" "0.74.83" + "@react-native/normalize-colors" "0.74.83" + "@react-native/virtualized-lists" "0.74.83" abort-controller "^3.0.0" anser "^1.4.9" ansi-regex "^5.0.0" base64-js "^1.5.1" - deprecated-react-native-prop-types "^5.0.0" + chalk "^4.0.0" event-target-shim "^5.0.1" flow-enums-runtime "^0.0.6" invariant "^2.2.4" @@ -18944,7 +19065,7 @@ react-native@0.73.2: nullthrows "^1.1.1" pretty-format "^26.5.2" promise "^8.3.0" - react-devtools-core "^4.27.7" + react-devtools-core "^5.0.0" react-refresh "^0.14.0" react-shallow-renderer "^16.15.0" regenerator-runtime "^0.13.2" @@ -18964,6 +19085,11 @@ react-refresh@^0.11.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== +react-refresh@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== + react-refresh@^0.4.0: version "0.4.3" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" @@ -19720,6 +19846,14 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" +selfsigned@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -19737,10 +19871,10 @@ semver@7.5.3: dependencies: lru-cache "^6.0.0" -semver@7.5.4, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== +semver@7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" @@ -19754,6 +19888,18 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +semver@^7.6.0: + version "7.6.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== + semver@~7.3.2: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" @@ -20055,13 +20201,6 @@ sonic-boom@^3.1.0: dependencies: atomic-sleep "^1.0.0" -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== - dependencies: - is-plain-obj "^1.0.0" - source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -20184,12 +20323,12 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== +ssri@^10.0.0: + version "10.0.6" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.6.tgz#a8aade2de60ba2bce8688e3fa349bad05c7dc1e5" + integrity sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ== dependencies: - minipass "^3.1.1" + minipass "^7.0.3" stable@^0.1.8: version "0.1.8" @@ -20303,11 +20442,6 @@ streamx@^2.15.0: fast-fifo "^1.1.0" queue-tick "^1.0.1" -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== - strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" @@ -20738,7 +20872,7 @@ tar-stream@^3.1.5: fast-fifo "^1.2.0" streamx "^2.15.0" -tar@^6.0.2, tar@^6.0.5: +tar@^6.0.5: version "6.1.15" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== @@ -20750,6 +20884,18 @@ tar@^6.0.2, tar@^6.0.5: mkdirp "^1.0.3" yallist "^4.0.0" +tar@^6.1.11: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" @@ -21234,6 +21380,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + undici@^5.28.2: version "5.28.2" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.2.tgz#fea200eac65fc7ecaff80a023d1a0543423b4c91" @@ -21274,22 +21425,22 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -unimodules-app-loader@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/unimodules-app-loader/-/unimodules-app-loader-4.5.0.tgz#5ec66088d740bd17dc5c94b88c91f21249d9f0ba" - integrity sha512-q/Xug4K6/20876Xac+tjOLOOAeHEu2zF66LNN/5c8EV4WPEe/+RYZEljN/woQt17KPIB2eyel9dc+d6qUMjUOg== +unimodules-app-loader@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/unimodules-app-loader/-/unimodules-app-loader-4.6.0.tgz#8836040b3acbf605fc4c2c6f6feb6dd9084ea0d4" + integrity sha512-FRNIlx7sLBDVPG117JnEBhnzZkTIgZTEwYW2rzrY9HdvLBTpRN+k0dxY50U/CAhFHW3zMD0OP5JAlnSQRhx5HA== -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== +unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== dependencies: - unique-slug "^2.0.0" + unique-slug "^4.0.0" -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== +unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== dependencies: imurmurhash "^0.1.4" @@ -21400,14 +21551,6 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -url@^0.11.0: - version "0.11.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" - integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== - dependencies: - punycode "^1.4.1" - qs "^6.11.2" - use-callback-ref@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.0.tgz#772199899b9c9a50526fedc4993fc7fa1f7e32d5" From 8f8af476cca54ad26b214e56af022b392d8f9389 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 18:38:52 -0700 Subject: [PATCH 07/55] Bump `react-navigation` (#4216) * bump and rm patch * fix types * use `Home` default --------- Co-authored-by: Dan Abramov --- package.json | 8 +-- patches/@react-navigation+native+6.1.7.patch | 56 ----------------- .../@react-navigation+native+6.1.7.patch.md | 5 -- src/lib/routes/helpers.ts | 9 ++- src/view/com/feeds/FeedPage.tsx | 5 +- yarn.lock | 63 +++++++++---------- 6 files changed, 43 insertions(+), 103 deletions(-) delete mode 100644 patches/@react-navigation+native+6.1.7.patch delete mode 100644 patches/@react-navigation+native+6.1.7.patch.md diff --git a/package.json b/package.json index 5a936e3c1c..af3cb99997 100644 --- a/package.json +++ b/package.json @@ -72,10 +72,10 @@ "@react-native-masked-view/masked-view": "0.3.0", "@react-native-menu/menu": "^0.8.0", "@react-native-picker/picker": "2.6.1", - "@react-navigation/bottom-tabs": "^6.5.7", - "@react-navigation/drawer": "^6.6.2", - "@react-navigation/native": "^6.1.6", - "@react-navigation/native-stack": "^6.9.12", + "@react-navigation/bottom-tabs": "^6.5.20", + "@react-navigation/drawer": "^6.6.15", + "@react-navigation/native": "^6.1.17", + "@react-navigation/native-stack": "^6.9.26", "@segment/analytics-next": "^1.51.3", "@segment/analytics-react": "^1.0.0-rc1", "@segment/analytics-react-native": "^2.10.1", diff --git a/patches/@react-navigation+native+6.1.7.patch b/patches/@react-navigation+native+6.1.7.patch deleted file mode 100644 index b604e2c1aa..0000000000 --- a/patches/@react-navigation+native+6.1.7.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff --git a/node_modules/@react-navigation/native/lib/commonjs/useLinking.js b/node_modules/@react-navigation/native/lib/commonjs/useLinking.js -index ef4f368..2b0da35 100644 ---- a/node_modules/@react-navigation/native/lib/commonjs/useLinking.js -+++ b/node_modules/@react-navigation/native/lib/commonjs/useLinking.js -@@ -273,8 +273,12 @@ function useLinking(ref, _ref) { - }); - const currentIndex = history.index; - try { -- if (nextIndex !== -1 && nextIndex < currentIndex) { -- // An existing entry for this path exists and it's less than current index, go back to that -+ if ( -+ nextIndex !== -1 && -+ nextIndex < currentIndex && -+ // We should only go back if the entry exists and it's less than current index -+ history.get(nextIndex - currentIndex) -+ ) { // An existing entry for this path exists and it's less than current index, go back to that - await history.go(nextIndex - currentIndex); - } else { - // We couldn't find an existing entry to go back to, so we'll go back by the delta -diff --git a/node_modules/@react-navigation/native/lib/module/useLinking.js b/node_modules/@react-navigation/native/lib/module/useLinking.js -index 62a3b43..11a5a28 100644 ---- a/node_modules/@react-navigation/native/lib/module/useLinking.js -+++ b/node_modules/@react-navigation/native/lib/module/useLinking.js -@@ -264,8 +264,12 @@ export default function useLinking(ref, _ref) { - }); - const currentIndex = history.index; - try { -- if (nextIndex !== -1 && nextIndex < currentIndex) { -- // An existing entry for this path exists and it's less than current index, go back to that -+ if ( -+ nextIndex !== -1 && -+ nextIndex < currentIndex && -+ // We should only go back if the entry exists and it's less than current index -+ history.get(nextIndex - currentIndex) -+ ) { // An existing entry for this path exists and it's less than current index, go back to that - await history.go(nextIndex - currentIndex); - } else { - // We couldn't find an existing entry to go back to, so we'll go back by the delta -diff --git a/node_modules/@react-navigation/native/src/useLinking.tsx b/node_modules/@react-navigation/native/src/useLinking.tsx -index 3db40b7..9ba4ecd 100644 ---- a/node_modules/@react-navigation/native/src/useLinking.tsx -+++ b/node_modules/@react-navigation/native/src/useLinking.tsx -@@ -381,7 +381,12 @@ export default function useLinking( - const currentIndex = history.index; - - try { -- if (nextIndex !== -1 && nextIndex < currentIndex) { -+ if ( -+ nextIndex !== -1 && -+ nextIndex < currentIndex && -+ // We should only go back if the entry exists and it's less than current index -+ history.get(nextIndex - currentIndex) -+ ) { - // An existing entry for this path exists and it's less than current index, go back to that - await history.go(nextIndex - currentIndex); - } else { diff --git a/patches/@react-navigation+native+6.1.7.patch.md b/patches/@react-navigation+native+6.1.7.patch.md deleted file mode 100644 index 60b0d4e140..0000000000 --- a/patches/@react-navigation+native+6.1.7.patch.md +++ /dev/null @@ -1,5 +0,0 @@ -# React Navigation history bug patch - -This patches react-navigation to fix the issues in https://github.com/bluesky-social/social-app/issues/710. - -This is based on the PR found at https://github.com/react-navigation/react-navigation/pull/11833 diff --git a/src/lib/routes/helpers.ts b/src/lib/routes/helpers.ts index 0da8850433..603b6f71b6 100644 --- a/src/lib/routes/helpers.ts +++ b/src/lib/routes/helpers.ts @@ -1,5 +1,6 @@ import {NavigationProp} from '@react-navigation/native' -import {State, RouteParams} from './types' + +import {RouteParams, State} from './types' export function getRootNavigation( nav: NavigationProp, @@ -10,7 +11,11 @@ export function getRootNavigation( return nav } -export function getCurrentRoute(state: State) { +export function getCurrentRoute(state?: State) { + if (!state) { + return {name: 'Home'} + } + let node = state.routes[state.index || 0] while (node.state?.routes && typeof node.state?.index === 'number') { node = node.state?.routes[node.state?.index] diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx index f0a7c62381..c80740b769 100644 --- a/src/view/com/feeds/FeedPage.tsx +++ b/src/view/com/feeds/FeedPage.tsx @@ -3,7 +3,7 @@ import {View} from 'react-native' import {AppBskyActorDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useNavigation} from '@react-navigation/native' +import {NavigationProp, useNavigation} from '@react-navigation/native' import {useQueryClient} from '@tanstack/react-query' import {getRootNavigation, getTabState, TabState} from '#/lib/routes/helpers' @@ -19,6 +19,7 @@ import {useSetMinimalShellMode} from '#/state/shell' import {useComposerControls} from '#/state/shell/composer' import {useAnalytics} from 'lib/analytics/analytics' import {ComposeIcon2} from 'lib/icons' +import {AllNavigatorParams} from 'lib/routes/types' import {s} from 'lib/styles' import {useHeaderOffset} from '#/components/hooks/useHeaderOffset' import {Feed} from '../posts/Feed' @@ -48,7 +49,7 @@ export function FeedPage({ }) { const {hasSession} = useSession() const {_} = useLingui() - const navigation = useNavigation() + const navigation = useNavigation>() const queryClient = useQueryClient() const {openComposer} = useComposerControls() const [isScrolledDown, setIsScrolledDown] = React.useState(false) diff --git a/yarn.lock b/yarn.lock index 07e2f73c2d..75a15a8ee7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5669,55 +5669,55 @@ invariant "^2.2.4" nullthrows "^1.1.1" -"@react-navigation/bottom-tabs@^6.5.7": - version "6.5.8" - resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz#9536c6e45154abc183c363d07c94991e10b14856" - integrity sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg== +"@react-navigation/bottom-tabs@^6.5.20": + version "6.5.20" + resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.20.tgz#5335e75b02c527ef0569bd97d4f9185d65616e49" + integrity sha512-ow6Z06iS4VqBO8d7FP+HsGjJLWt2xTWIvuWjpoCvsM/uQXzCRDIjBv9HaKcXbF0yTW7IMir0oDAbU5PFzEDdgA== dependencies: - "@react-navigation/elements" "^1.3.18" + "@react-navigation/elements" "^1.3.30" color "^4.2.3" warn-once "^0.1.0" -"@react-navigation/core@^6.4.9": - version "6.4.9" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-6.4.9.tgz#aa09ce534f5393427cb993cf242abdbd848fb2c7" - integrity sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g== +"@react-navigation/core@^6.4.16": + version "6.4.16" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-6.4.16.tgz#f9369a134805174536b9aa0f0f483b930511caf9" + integrity sha512-UDTJBsHxnzgFETR3ZxhctP+RWr4SkyeZpbhpkQoIGOuwSCkt1SE0qjU48/u6r6w6XlX8OqVudn1Ab0QFXTHxuQ== dependencies: "@react-navigation/routers" "^6.1.9" escape-string-regexp "^4.0.0" nanoid "^3.1.23" query-string "^7.1.3" react-is "^16.13.0" - use-latest-callback "^0.1.5" + use-latest-callback "^0.1.9" -"@react-navigation/drawer@^6.6.2": - version "6.6.3" - resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-6.6.3.tgz#ad48b3e0a2d2771e7fc8bc46a8b269ef2ae11e54" - integrity sha512-oQzHqH6svtSIun6+rikQtku6ye2CyyxT4xf3RQLVsBvK7+g4tDdKKLcjgoJmuT1zBZC3SSu3wNeqp8cg4cr2PQ== +"@react-navigation/drawer@^6.6.15": + version "6.6.15" + resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-6.6.15.tgz#fcedba68f735103dbc035911f5959ce926081d62" + integrity sha512-GLkFQNxjtmxB/qXSHmu1DfoB89jCzW64tmX68iPndth+9U+0IP27GcCCaMZxQfwj+nI8Kn2zlTlXAZDIIHE+DQ== dependencies: - "@react-navigation/elements" "^1.3.18" + "@react-navigation/elements" "^1.3.30" color "^4.2.3" warn-once "^0.1.0" -"@react-navigation/elements@^1.3.18": - version "1.3.18" - resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.18.tgz#d8364b40276f3efb9c229c39da3b8b465f18f0a2" - integrity sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q== +"@react-navigation/elements@^1.3.30": + version "1.3.30" + resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.30.tgz#a81371f599af1070b12014f05d6c09b1a611fd9a" + integrity sha512-plhc8UvCZs0UkV+sI+3bisIyn78wz9O/BiWZXpounu72k/R/Sj5PuZYFJ1fi6psvriUveMCGh4LeZckAZu2qiQ== -"@react-navigation/native-stack@^6.9.12": - version "6.9.13" - resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.13.tgz#f308c398ee18fcd45de8ec7c04fe0641735feb31" - integrity sha512-ejlepMrvFneewL+XlXHHhn+6y3lwvavM4/R7XwBV0XJxCymujexK+7Vkg7UcvJ1lx4CRhOcyBSNfGmdNIHREyQ== +"@react-navigation/native-stack@^6.9.26": + version "6.9.26" + resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.26.tgz#90facf7783c9927f094bc9f01c613af75b6c241e" + integrity sha512-++dueQ+FDj2XkZ902DVrK79ub1vp19nSdAZWxKRgd6+Bc0Niiesua6rMCqymYOVaYh+dagwkA9r00bpt/U5WLw== dependencies: - "@react-navigation/elements" "^1.3.18" + "@react-navigation/elements" "^1.3.30" warn-once "^0.1.0" -"@react-navigation/native@^6.1.6": - version "6.1.7" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.1.7.tgz#968ef85b76d35f63111890668836fe2f125bbf90" - integrity sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw== +"@react-navigation/native@^6.1.17": + version "6.1.17" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.1.17.tgz#439f15a99809d26ea4682d2a3766081cf2ca31cf" + integrity sha512-mer3OvfwWOHoUSMJyLa4vnBH3zpFmCwuzrBPlw7feXklurr/ZDiLjLxUScOot6jLRMz/67GyilEYMmP99LL0RQ== dependencies: - "@react-navigation/core" "^6.4.9" + "@react-navigation/core" "^6.4.16" escape-string-regexp "^4.0.0" fast-deep-equal "^3.1.3" nanoid "^3.1.23" @@ -21568,11 +21568,6 @@ use-isomorphic-layout-effect@^1.1.1: resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== -use-latest-callback@^0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.1.6.tgz#3fa6e7babbb5f9bfa24b5094b22939e1e92ebcf6" - integrity sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg== - use-latest-callback@^0.1.9: version "0.1.9" resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.1.9.tgz#10191dc54257e65a8e52322127643a8940271e2a" From eb0859bffb419dd14d41522d1dcd427ce9e0bc8d Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 19:12:56 -0700 Subject: [PATCH 08/55] Fix `hitSlop` type (#4248) --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 75a15a8ee7..e363cc0a4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3113,7 +3113,7 @@ "@discord/bottom-sheet@bluesky-social/react-native-bottom-sheet": version "4.6.1" - resolved "https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/3232c7cd9b966dd977c849a360fa853f88dcf3ca" + resolved "https://codeload.github.com/bluesky-social/react-native-bottom-sheet/tar.gz/28a87d1bb55e10fc355fa1455545a30734995908" dependencies: "@gorhom/portal" "1.0.14" invariant "^2.2.4" From 19ee89caf363c2b1c7f9ea35325501304619e879 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 19:55:10 -0700 Subject: [PATCH 09/55] upgrade `react-native-svg` to `15.3.0` (#4249) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index af3cb99997..5ba1856327 100644 --- a/package.json +++ b/package.json @@ -181,7 +181,7 @@ "react-native-root-siblings": "^4.1.1", "react-native-safe-area-context": "4.10.1", "react-native-screens": "~3.31.1", - "react-native-svg": "^15.2.0", + "react-native-svg": "^15.3.0", "react-native-uitextview": "^1.1.7", "react-native-url-polyfill": "^1.3.0", "react-native-uuid": "^2.0.2", diff --git a/yarn.lock b/yarn.lock index e363cc0a4a..f8a3824a04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18971,10 +18971,10 @@ react-native-screens@~3.31.1: react-freeze "^1.0.0" warn-once "^0.1.0" -react-native-svg@^15.2.0: - version "15.2.0" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.2.0.tgz#9561a6b3bd6b44689f437ba13182afee33bd5557" - integrity sha512-R0E6IhcJfVLsL0lRmnUSm72QO+mTqcAOM5Jb8FVGxJqX3NfJMlMP0YyvcajZiaRR8CqQUpEoqrY25eyZb006kw== +react-native-svg@^15.3.0: + version "15.3.0" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.3.0.tgz#e24b833fe330714c99f1dd894bb0da52ad859a4c" + integrity sha512-mBHu/fdlzUbpGX8SZFxgbKvK/sgqLfDLP8uh8G7Us+zJgdjO8OSEeqHQs+kPRdQmdLJQiqPJX2WXgCl7ToTWqw== dependencies: css-select "^5.1.0" css-tree "^1.1.3" From efdfb7f57a6de487330cd1a24c3bc4955bb8c74d Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 28 May 2024 20:58:40 -0700 Subject: [PATCH 10/55] Alt text followups -- SLIGHTLY larger, and update gifs (#4252) * Bump up the alt text indicator's text size just a smidge * Update the GIF alt indicator to match images (right side, visually smaller on mobile) --- src/view/com/util/images/Gallery.tsx | 2 +- src/view/com/util/post-embeds/GifEmbed.tsx | 12 ++++++------ src/view/com/util/post-embeds/index.tsx | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx index f0b7ac15e7..8d23d258f5 100644 --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -79,7 +79,7 @@ const styles = StyleSheet.create({ }, alt: { color: 'white', - fontSize: 6, + fontSize: 7, fontWeight: 'bold', }, }) diff --git a/src/view/com/util/post-embeds/GifEmbed.tsx b/src/view/com/util/post-embeds/GifEmbed.tsx index deb82655b5..1c0cf3d39d 100644 --- a/src/view/com/util/post-embeds/GifEmbed.tsx +++ b/src/view/com/util/post-embeds/GifEmbed.tsx @@ -5,7 +5,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {HITSLOP_10} from '#/lib/constants' +import {HITSLOP_20} from '#/lib/constants' import {parseAltFromGIFDescription} from '#/lib/gif-alt-text' import {isWeb} from '#/platform/detection' import {EmbedPlayerParams} from 'lib/strings/embed-player' @@ -166,7 +166,7 @@ function AltText({text}: {text: string}) { accessibilityRole="button" accessibilityLabel={_(msg`Show alt text`)} accessibilityHint="" - hitSlop={HITSLOP_10} + hitSlop={HITSLOP_20} onPress={control.open} style={styles.altContainer}> @@ -195,18 +195,18 @@ const styles = StyleSheet.create({ altContainer: { backgroundColor: 'rgba(0, 0, 0, 0.75)', borderRadius: 6, - paddingHorizontal: 6, - paddingVertical: 3, + paddingHorizontal: isWeb ? 8 : 6, + paddingVertical: isWeb ? 6 : 3, position: 'absolute', // Related to margin/gap hack. This keeps the alt label in the same position // on all platforms - left: isWeb ? 8 : 5, + right: isWeb ? 8 : 5, bottom: isWeb ? 8 : 5, zIndex: 2, }, alt: { color: 'white', - fontSize: 10, + fontSize: isWeb ? 10 : 7, fontWeight: 'bold', }, }) diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index 8aa9919ca8..0fc8296252 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -183,7 +183,7 @@ const styles = StyleSheet.create({ }, alt: { color: 'white', - fontSize: 6, + fontSize: 7, fontWeight: 'bold', }, customFeedOuter: { From ff6a044f66e0babeaf559880735362fa69590f7e Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 29 May 2024 05:02:49 +0100 Subject: [PATCH 11/55] Bump more Expo libs (#4251) * Bump more Expo libs * Use legacy camera API * fix `expo-notifications` patch * bump `menu` * change patch name * patch reanimated * Revert "patch reanimated" This reverts commit dad822d8ea04c71a609784114d60f2e67b78290b. * Use nightly reanimated * Revert "Use nightly reanimated" This reverts commit 6687c7182883feb889cbf2c67dd14890e06bc501. * Revert "Revert "patch reanimated"" This reverts commit c30abd6732f559ca04dc59698411e1058800d63e. --------- Co-authored-by: Hailey --- package.json | 22 +- ....patch => expo-notifications+0.28.3.patch} | 44 ++-- ....md => expo-notifications-0.28.3.patch.md} | 0 patches/react-native-reanimated+3.11.0.patch | 209 ++++++++++++++++++ src/lib/hooks/usePermissions.ts | 5 +- yarn.lock | 102 ++++----- 6 files changed, 290 insertions(+), 92 deletions(-) rename patches/{expo-notifications+0.28.1.patch => expo-notifications+0.28.3.patch} (98%) rename patches/{expo-notifications-0.27.6.patch.md => expo-notifications-0.28.3.patch.md} (100%) diff --git a/package.json b/package.json index 5ba1856327..38c450c348 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@radix-ui/react-dropdown-menu": "^2.0.6", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-masked-view/masked-view": "0.3.0", - "@react-native-menu/menu": "^0.8.0", + "@react-native-menu/menu": "^1.1.0", "@react-native-picker/picker": "2.6.1", "@react-navigation/bottom-tabs": "^6.5.20", "@react-navigation/drawer": "^6.6.15", @@ -114,28 +114,28 @@ "expo": "^51.0.8", "expo-application": "^5.9.1", "expo-build-properties": "^0.12.1", - "expo-camera": "~14.1.3", - "expo-clipboard": "^5.0.1", - "expo-constants": "~15.4.6", + "expo-camera": "~15.0.9", + "expo-clipboard": "^6.0.3", + "expo-constants": "~16.0.1", "expo-dev-client": "^4.0.14", - "expo-device": "~5.9.3", - "expo-file-system": "^16.0.9", - "expo-haptics": "^12.8.1", + "expo-device": "~6.0.2", + "expo-file-system": "^17.0.1", + "expo-haptics": "^13.0.1", "expo-image": "~1.12.9", - "expo-image-manipulator": "^12.0.3", - "expo-image-picker": "~15.0.4", + "expo-image-manipulator": "^12.0.5", + "expo-image-picker": "~15.0.5", "expo-linear-gradient": "^13.0.2", "expo-linking": "^6.3.1", "expo-localization": "~15.0.3", "expo-media-library": "~16.0.3", "expo-navigation-bar": "~3.0.4", - "expo-notifications": "~0.28.1", + "expo-notifications": "~0.28.3", "expo-sharing": "^12.0.1", "expo-splash-screen": "~0.27.4", "expo-status-bar": "~1.12.1", "expo-system-ui": "~3.0.4", "expo-task-manager": "~11.8.1", - "expo-updates": "~0.25.11", + "expo-updates": "~0.25.14", "expo-web-browser": "~13.0.3", "fast-text-encoding": "^1.0.6", "history": "^5.3.0", diff --git a/patches/expo-notifications+0.28.1.patch b/patches/expo-notifications+0.28.3.patch similarity index 98% rename from patches/expo-notifications+0.28.1.patch rename to patches/expo-notifications+0.28.3.patch index 41e91446e6..3a9985c7b0 100644 --- a/patches/expo-notifications+0.28.1.patch +++ b/patches/expo-notifications+0.28.3.patch @@ -4,10 +4,10 @@ index d233e1f..cc2f856 100644 +++ b/node_modules/expo-notifications/android/build.gradle @@ -32,6 +32,7 @@ dependencies { api 'com.google.firebase:firebase-messaging:22.0.0' - + api 'me.leolin:ShortcutBadger:1.1.22@aar' + implementation project(':expo-background-notification-handler') - + if (project.findProject(':expo-modules-test-core')) { testImplementation project(':expo-modules-test-core') diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/JSONNotificationContentBuilder.java b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/JSONNotificationContentBuilder.java @@ -16,14 +16,14 @@ index 0af7fe0..8f2c8d8 100644 +++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/JSONNotificationContentBuilder.java @@ -14,6 +14,7 @@ import expo.modules.notifications.notifications.enums.NotificationPriority; import expo.modules.notifications.notifications.model.NotificationContent; - + public class JSONNotificationContentBuilder extends NotificationContent.Builder { + private static final String CHANNEL_ID_KEY = "channelId"; private static final String TITLE_KEY = "title"; private static final String TEXT_KEY = "message"; private static final String SUBTITLE_KEY = "subtitle"; @@ -36,6 +37,7 @@ public class JSONNotificationContentBuilder extends NotificationContent.Builder - + public NotificationContent.Builder setPayload(JSONObject payload) { this.setTitle(getTitle(payload)) + .setChannelId(getChannelId(payload)) @@ -33,7 +33,7 @@ index 0af7fe0..8f2c8d8 100644 @@ -60,6 +62,14 @@ public class JSONNotificationContentBuilder extends NotificationContent.Builder return this; } - + + protected String getChannelId(JSONObject payload) { + try { + return payload.getString(CHANNEL_ID_KEY); @@ -46,21 +46,21 @@ index 0af7fe0..8f2c8d8 100644 try { return payload.getString(TITLE_KEY); diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java -index f1fed19..166b34f 100644 +index f1fed19..80afe9e 100644 --- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java +++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/model/NotificationContent.java @@ -20,6 +20,7 @@ import expo.modules.notifications.notifications.enums.NotificationPriority; * should be created using {@link NotificationContent.Builder}. */ public class NotificationContent implements Parcelable, Serializable { -+ private string mChannelId; ++ private String mChannelId; private String mTitle; private String mText; private String mSubtitle; @@ -50,6 +51,11 @@ public class NotificationContent implements Parcelable, Serializable { } }; - + + @Nullable + public String getChannelId() { + return mTitle; @@ -71,14 +71,14 @@ index f1fed19..166b34f 100644 return mTitle; @@ -121,6 +127,7 @@ public class NotificationContent implements Parcelable, Serializable { } - + protected NotificationContent(Parcel in) { + mChannelId = in.readString(); mTitle = in.readString(); mText = in.readString(); mSubtitle = in.readString(); @@ -146,6 +153,7 @@ public class NotificationContent implements Parcelable, Serializable { - + @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mChannelId); @@ -87,7 +87,7 @@ index f1fed19..166b34f 100644 dest.writeString(mSubtitle); @@ -166,6 +174,7 @@ public class NotificationContent implements Parcelable, Serializable { private static final long serialVersionUID = 397666843266836802L; - + private void writeObject(java.io.ObjectOutputStream out) throws IOException { + out.writeObject(mChannelId); out.writeObject(mTitle); @@ -95,7 +95,7 @@ index f1fed19..166b34f 100644 out.writeObject(mSubtitle); @@ -190,6 +199,7 @@ public class NotificationContent implements Parcelable, Serializable { } - + private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { + mChannelId = (String) in.readObject(); mTitle = (String) in.readObject(); @@ -103,16 +103,16 @@ index f1fed19..166b34f 100644 mSubtitle = (String) in.readObject(); @@ -240,6 +250,7 @@ public class NotificationContent implements Parcelable, Serializable { } - + public static class Builder { -+ private string mChannelId; ++ private String mChannelId; private String mTitle; private String mText; private String mSubtitle; @@ -260,6 +271,11 @@ public class NotificationContent implements Parcelable, Serializable { useDefaultVibrationPattern(); } - + + public Builder setChannelId(String channelId) { + mChannelId = channelId; + return this; @@ -122,7 +122,7 @@ index f1fed19..166b34f 100644 mTitle = title; return this; @@ -336,6 +352,7 @@ public class NotificationContent implements Parcelable, Serializable { - + public NotificationContent build() { NotificationContent content = new NotificationContent(); + content.mChannelId = mChannelId; @@ -134,16 +134,16 @@ index 6bd9928..ee93d70 100644 --- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java +++ b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/notifications/presentation/builders/ExpoNotificationBuilder.java @@ -48,6 +48,10 @@ public class ExpoNotificationBuilder extends ChannelAwareNotificationBuilder { - + NotificationContent content = getNotificationContent(); - + + if (content.getChannelId() != null) { + builder.setChannelId(content.getChannelId()); + } + builder.setAutoCancel(content.isAutoDismiss()); builder.setOngoing(content.isSticky()); - + diff --git a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt b/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt index 55b3a8d..1b99d5b 100644 --- a/node_modules/expo-notifications/android/src/main/java/expo/modules/notifications/service/delegates/FirebaseMessagingDelegate.kt @@ -158,7 +158,7 @@ index 55b3a8d..1b99d5b 100644 import org.json.JSONObject import java.lang.ref.WeakReference import java.util.* - + -open class FirebaseMessagingDelegate(protected val context: Context) : FirebaseMessagingDelegate { +open class FirebaseMessagingDelegate(protected val context: Context) : FirebaseMessagingDelegate, BackgroundNotificationHandlerInterface { companion object { @@ -166,7 +166,7 @@ index 55b3a8d..1b99d5b 100644 // than by static properties. Fortunately, using weak references we can @@ -89,12 +92,21 @@ open class FirebaseMessagingDelegate(protected val context: Context) : FirebaseM fun getBackgroundTasks() = sBackgroundTaskConsumerReferences.values.mapNotNull { it.get() } - + override fun onMessageReceived(remoteMessage: RemoteMessage) { - NotificationsService.receive(context, createNotification(remoteMessage)) - getBackgroundTasks().forEach { @@ -181,7 +181,7 @@ index 55b3a8d..1b99d5b 100644 + } } } - + + override fun showMessage(remoteMessage: RemoteMessage) { + NotificationsService.receive(context, createNotification(remoteMessage)) + } diff --git a/patches/expo-notifications-0.27.6.patch.md b/patches/expo-notifications-0.28.3.patch.md similarity index 100% rename from patches/expo-notifications-0.27.6.patch.md rename to patches/expo-notifications-0.28.3.patch.md diff --git a/patches/react-native-reanimated+3.11.0.patch b/patches/react-native-reanimated+3.11.0.patch index f189853859..9147cf08ef 100644 --- a/patches/react-native-reanimated+3.11.0.patch +++ b/patches/react-native-reanimated+3.11.0.patch @@ -1,3 +1,212 @@ +diff --git a/node_modules/react-native-reanimated/src/createAnimatedComponent/commonTypes.ts b/node_modules/react-native-reanimated/src/createAnimatedComponent/commonTypes.ts +index 92ebe62..5f8207e 100644 +--- a/node_modules/react-native-reanimated/src/createAnimatedComponent/commonTypes.ts ++++ b/node_modules/react-native-reanimated/src/createAnimatedComponent/commonTypes.ts +@@ -96,7 +96,8 @@ export interface AnimatedComponentRef extends Component { + export interface IAnimatedComponentInternal { + _styles: StyleProps[] | null; + _animatedProps?: Partial>; +- _viewTag: number; ++ _componentViewTag: number; ++ _eventViewTag: number; + _isFirstRender: boolean; + jestAnimatedStyle: { value: StyleProps }; + _component: AnimatedComponentRef | HTMLElement | null; +diff --git a/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx b/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx +index 88b3fdf..2488ebc 100644 +--- a/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx ++++ b/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx +@@ -122,7 +122,8 @@ export function createAnimatedComponent( + { + _styles: StyleProps[] | null = null; + _animatedProps?: Partial>; +- _viewTag = -1; ++ _componentViewTag = -1; ++ _eventViewTag = -1; + _isFirstRender = true; + jestAnimatedStyle: { value: StyleProps } = { value: {} }; + _component: AnimatedComponentRef | HTMLElement | null = null; +@@ -143,7 +144,8 @@ export function createAnimatedComponent( + } + + componentDidMount() { +- this._viewTag = this._getViewInfo().viewTag as number; ++ this._setComponentViewTag(); ++ this._setEventViewTag(); + this._attachNativeEvents(); + this._jsPropsUpdater.addOnJSPropsChangeListener(this); + this._attachAnimatedStyles(); +@@ -185,7 +187,10 @@ export function createAnimatedComponent( + if (this.props.sharedTransitionTag) { + this._configureSharedTransition(true); + } +- this._sharedElementTransition?.unregisterTransition(this._viewTag, true); ++ this._sharedElementTransition?.unregisterTransition( ++ this._componentViewTag, ++ true ++ ); + + const exiting = this.props.exiting; + if ( +@@ -209,7 +214,7 @@ export function createAnimatedComponent( + : getReduceMotionFromConfig(); + if (!reduceMotionInExiting) { + updateLayoutAnimations( +- this._viewTag, ++ this._componentViewTag, + LayoutAnimationType.EXITING, + maybeBuild( + exiting, +@@ -221,12 +226,22 @@ export function createAnimatedComponent( + } + } + +- _getEventViewRef() { +- // Make sure to get the scrollable node for components that implement +- // `ScrollResponder.Mixin`. +- return (this._component as AnimatedComponentRef)?.getScrollableNode +- ? (this._component as AnimatedComponentRef).getScrollableNode?.() +- : this._component; ++ _setComponentViewTag() { ++ this._componentViewTag = this._getViewInfo().viewTag as number; ++ } ++ ++ _setEventViewTag() { ++ // Setting the tag for registering events - since the event emitting view can be nested inside the main component ++ const componentAnimatedRef = this._component as AnimatedComponentRef; ++ if (componentAnimatedRef.getScrollableNode) { ++ const scrollableNode = componentAnimatedRef.getScrollableNode(); ++ this._eventViewTag = findNodeHandle(scrollableNode) ?? -1; ++ } else { ++ this._eventViewTag = ++ findNodeHandle( ++ options?.setNativeProps ? this : componentAnimatedRef ++ ) ?? -1; ++ } + } + + _attachNativeEvents() { +@@ -236,7 +251,7 @@ export function createAnimatedComponent( + has('workletEventHandler', prop) && + prop.workletEventHandler instanceof WorkletEventHandler + ) { +- prop.workletEventHandler.registerForEvents(this._viewTag, key); ++ prop.workletEventHandler.registerForEvents(this._eventViewTag, key); + } + } + } +@@ -248,7 +263,7 @@ export function createAnimatedComponent( + has('workletEventHandler', prop) && + prop.workletEventHandler instanceof WorkletEventHandler + ) { +- prop.workletEventHandler.unregisterFromEvents(this._viewTag); ++ prop.workletEventHandler.unregisterFromEvents(this._eventViewTag); + } + } + } +@@ -258,15 +273,17 @@ export function createAnimatedComponent( + for (const style of this._styles) { + style.viewsRef.remove(this); + } +- } else if (this._viewTag !== -1 && this._styles !== null) { ++ } else if (this._componentViewTag !== -1 && this._styles !== null) { + for (const style of this._styles) { +- style.viewDescriptors.remove(this._viewTag); ++ style.viewDescriptors.remove(this._componentViewTag); + } + if (this.props.animatedProps?.viewDescriptors) { +- this.props.animatedProps.viewDescriptors.remove(this._viewTag); ++ this.props.animatedProps.viewDescriptors.remove( ++ this._componentViewTag ++ ); + } + if (isFabric()) { +- removeFromPropsRegistry(this._viewTag); ++ removeFromPropsRegistry(this._componentViewTag); + } + } + } +@@ -283,15 +300,19 @@ export function createAnimatedComponent( + const newProp = this.props[key]; + if (!newProp) { + // Prop got deleted +- prevProp.workletEventHandler.unregisterFromEvents(this._viewTag); ++ prevProp.workletEventHandler.unregisterFromEvents( ++ this._eventViewTag ++ ); + } else if ( + has('workletEventHandler', newProp) && + newProp.workletEventHandler instanceof WorkletEventHandler && + newProp.workletEventHandler !== prevProp.workletEventHandler + ) { + // Prop got changed +- prevProp.workletEventHandler.unregisterFromEvents(this._viewTag); +- newProp.workletEventHandler.registerForEvents(this._viewTag); ++ prevProp.workletEventHandler.unregisterFromEvents( ++ this._eventViewTag ++ ); ++ newProp.workletEventHandler.registerForEvents(this._eventViewTag); + } + } + } +@@ -304,7 +325,7 @@ export function createAnimatedComponent( + !prevProps[key] + ) { + // Prop got added +- newProp.workletEventHandler.registerForEvents(this._viewTag); ++ newProp.workletEventHandler.registerForEvents(this._eventViewTag); + } + } + } +@@ -381,7 +402,7 @@ export function createAnimatedComponent( + adaptViewConfig(viewConfig); + } + +- this._viewTag = viewTag as number; ++ this._componentViewTag = viewTag as number; + + // remove old styles + if (prevStyles) { +@@ -487,7 +508,11 @@ export function createAnimatedComponent( + AnimatedComponent.displayName + ) + : undefined; +- updateLayoutAnimations(this._viewTag, LayoutAnimationType.LAYOUT, layout); ++ updateLayoutAnimations( ++ this._componentViewTag, ++ LayoutAnimationType.LAYOUT, ++ layout ++ ); + } + + _configureSharedTransition(isUnmounting = false) { +@@ -497,7 +522,7 @@ export function createAnimatedComponent( + const { sharedTransitionTag } = this.props; + if (!sharedTransitionTag) { + this._sharedElementTransition?.unregisterTransition( +- this._viewTag, ++ this._componentViewTag, + isUnmounting + ); + this._sharedElementTransition = null; +@@ -508,7 +533,7 @@ export function createAnimatedComponent( + this._sharedElementTransition ?? + new SharedTransition(); + sharedElementTransition.registerTransition( +- this._viewTag, ++ this._componentViewTag, + sharedTransitionTag, + isUnmounting + ); +@@ -527,7 +552,7 @@ export function createAnimatedComponent( + ? (ref as HTMLElement) + : findNodeHandle(ref as Component); + +- this._viewTag = tag as number; ++ this._componentViewTag = tag as number; + + const { layout, entering, exiting, sharedTransitionTag } = this.props; + if ( diff --git a/node_modules/react-native-reanimated/lib/module/reanimated2/index.js b/node_modules/react-native-reanimated/lib/module/reanimated2/index.js index ac9be5d..86d4605 100644 --- a/node_modules/react-native-reanimated/lib/module/reanimated2/index.js diff --git a/src/lib/hooks/usePermissions.ts b/src/lib/hooks/usePermissions.ts index 138f3eacab..baf9f7b8af 100644 --- a/src/lib/hooks/usePermissions.ts +++ b/src/lib/hooks/usePermissions.ts @@ -1,6 +1,7 @@ -import {Camera} from 'expo-camera' -import * as MediaLibrary from 'expo-media-library' import {Linking} from 'react-native' +import {Camera} from 'expo-camera/legacy' // TODO: Migrate to the new one. +import * as MediaLibrary from 'expo-media-library' + import {isWeb} from 'platform/detection' import {Alert} from 'view/com/util/Alert' diff --git a/yarn.lock b/yarn.lock index f8a3824a04..2b105f00ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3572,10 +3572,10 @@ p-limit "^3.1.0" resolve-from "^5.0.0" -"@expo/fingerprint@^0.7.0": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.7.1.tgz#5778c79f6be2471b4c703381e26e9ee0691fa8c6" - integrity sha512-lbTwFiIk0lOm9zzPRvnC45GfPqXqPB3w4hDDKVma+8FDAbPCWhNN42ltLhx/ekwcHFQxURmg0fHm59k0Vy+jtw== +"@expo/fingerprint@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.8.0.tgz#631a64c5db23e121228546502ae6a0eeab19aaf7" + integrity sha512-LBNweJnpG16p7SbvFGINF5Q44bDErIcm1li9SuvYQgrrSey3ErIPmZsiMsNBxlvVie6eTp4wmFO6IFmeaqEhbg== dependencies: "@expo/spawn-async" "^1.7.2" chalk "^4.1.2" @@ -5482,10 +5482,10 @@ resolved "https://registry.yarnpkg.com/@react-native-masked-view/masked-view/-/masked-view-0.3.0.tgz#bd29fae18d148a685331910a3c7b766ce87eafcc" integrity sha512-qLyoObcjzrkpNcoJjXquUePXfL1dXjHtuv+yX0zZ0Q4kG5yvVqd620+tSh7WbRoHkjpXhFBfLwvGhcWB2I0Lpw== -"@react-native-menu/menu@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@react-native-menu/menu/-/menu-0.8.0.tgz#dbf227c2081e5ffd3d2073ee68ecc84cf8639727" - integrity sha512-kxiT6ySZsDbBvNWovrKVAfs4AQvAytKIf0f8KQLkVO6eNYMUmONBQPzi6onTTbVujXtZHambo7qr/PcedaR8Tg== +"@react-native-menu/menu@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@react-native-menu/menu/-/menu-1.1.0.tgz#e89c0850f7e5aa4c671c44a9c10edafadb23c35a" + integrity sha512-vf9zp0M4nbAFnSKz5NJYKUPM5UzXWmLyGcjtuPaKWYxxloz9C0Pp6XdZRJnoOSlfRShE8NksX3bVY8W4wGnlCQ== "@react-native-picker/picker@2.6.1": version "2.6.1" @@ -12063,17 +12063,17 @@ expo-build-properties@^0.12.1: ajv "^8.11.0" semver "^7.6.0" -expo-camera@~14.1.3: - version "14.1.3" - resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-14.1.3.tgz#c3b36c7ed28613e7423b6c4df192549f4f9ee0dd" - integrity sha512-JodpVjOY8JDuSp/RkphS8Bxqaj/gwg0h0UbQB9MLr1LoxbL9brvJt7IZnmTf7+ON8jRKUx9E5o/F02pRNbmSbQ== +expo-camera@~15.0.9: + version "15.0.9" + resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-15.0.9.tgz#a6a175638bdd9914aca061c6090001452329fcea" + integrity sha512-xH+y8gA/3rNLostIw+z4kDGA+AYzsI9+QYb7G1uCFyxr3SxUGhapz+oMBFDU++vmyo9G7Ax0n52nghqIrNBJxQ== dependencies: invariant "^2.2.4" -expo-clipboard@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/expo-clipboard/-/expo-clipboard-5.0.1.tgz#a62a021a9444740d180d60f915cca8242a323716" - integrity sha512-JH853QJPr5W3h87If3aDTnMK+ESSIrwzU2TdfZrqZttVDY2pMIf/w37mVHHNYodXM4ATHXadtOkjKbAa0DWwUg== +expo-clipboard@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/expo-clipboard/-/expo-clipboard-6.0.3.tgz#dfea74d4a004dce59ecefd063d6fb9f1c356a03f" + integrity sha512-RIKDsuHkYfaspifbFpVC8sBVFKR05L7Pj7mU2/XkbrW9m01OBNvdpGraXEMsTFCx97xMGsZpEw9pPquL4j4xVg== expo-constants@^13.0.2: version "13.2.4" @@ -12083,14 +12083,7 @@ expo-constants@^13.0.2: "@expo/config" "~7.0.0" uuid "^3.3.2" -expo-constants@~15.4.6: - version "15.4.6" - resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-15.4.6.tgz#d4e9b21b70c5602457962700f2e90a75356b487b" - integrity sha512-vizE69dww2Vl0PTWWvDmK0Jo2/J+WzdcMZlA05YEnEYofQuhKxTVsiuipf79mSOmFavt4UQYC1UnzptzKyfmiQ== - dependencies: - "@expo/config" "~8.5.0" - -expo-constants@~16.0.0: +expo-constants@~16.0.0, expo-constants@~16.0.1: version "16.0.1" resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-16.0.1.tgz#1285e29c85513c6e88e118289e2baab72596d3f7" integrity sha512-s6aTHtglp926EsugWtxN7KnpSsE9FCEjb7CgEjQQ78Gpu4btj4wB+IXot2tlqNwqv+x7xFe5veoPGfJDGF/kVg== @@ -12139,10 +12132,10 @@ expo-device@~4.1.1: dependencies: ua-parser-js "^0.7.19" -expo-device@~5.9.3: - version "5.9.4" - resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-5.9.4.tgz#7dc8ba3695e1c0891bbc840a255faac479310c08" - integrity sha512-nleq3GghLWWJrj4YH8HiCumnTF/gy4zRd3jedCkO8lMKQg6R1yn3v0ch8NtgPDci749FkNzOtXx/vmFImQalwg== +expo-device@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/expo-device/-/expo-device-6.0.2.tgz#9bc3eccd16509c2819c225cc2ca8f7c3e3bdd11e" + integrity sha512-sCt91CuTmAuMXX4SlFOn4lIos2UIr8vb0jDstDDZXys6kErcj0uynC7bQAMreU5uRUTKMAl4MAMpKt9ufCXPBw== dependencies: ua-parser-js "^0.7.33" @@ -12151,12 +12144,7 @@ expo-eas-client@~0.12.0: resolved "https://registry.yarnpkg.com/expo-eas-client/-/expo-eas-client-0.12.0.tgz#e8b6f7d33873e6f630f37f7bfc41646ae7b0b2a9" integrity sha512-Jkww9Cwpv0z7DdLYiRX0r4fqBEcI9cKqTn7cHx63S09JaZ2rcwEE4zYHgrXwjahO+tU2VW8zqH+AJl6RhhW4zA== -expo-file-system@^16.0.9: - version "16.0.9" - resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-16.0.9.tgz#cbd6c4b228b60a6b6c71fd1b91fe57299fb24da7" - integrity sha512-3gRPvKVv7/Y7AdD9eHMIdfg5YbUn2zbwKofjsloTI5sEC57SLUFJtbLvUCz9Pk63DaSQ7WIE1JM0EASyvuPbuw== - -expo-file-system@~17.0.1: +expo-file-system@^17.0.1, expo-file-system@~17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/expo-file-system/-/expo-file-system-17.0.1.tgz#b9f8af8c1c06ec71d96fd7a0d2567fa9e1c88f15" integrity sha512-dYpnZJqTGj6HCYJyXAgpFkQWsiCH3HY1ek2cFZVHFoEc5tLz9gmdEgTF6nFHurvmvfmXqxi7a5CXyVm0aFYJBw== @@ -12168,27 +12156,27 @@ expo-font@~12.0.5: dependencies: fontfaceobserver "^2.1.0" -expo-haptics@^12.8.1: - version "12.8.1" - resolved "https://registry.yarnpkg.com/expo-haptics/-/expo-haptics-12.8.1.tgz#42b996763be33d661bd33bbc3b3958c3f2734b9d" - integrity sha512-ntLsHkfle8K8w9MW8pZEw92ZN3sguaGUSSIxv30fPKNeQFu7Cq/h47Qv3tONv2MO3wU48N9FbKnant6XlfptpA== +expo-haptics@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/expo-haptics/-/expo-haptics-13.0.1.tgz#35679c7fde4ae1c21ae3bc2d2cb34c266049dc2c" + integrity sha512-qG0EOLDE4bROVT3DtUSyV9g3iB3YFu9j3711X7SNNEnBDXc+2/p3wGDPTnJvPW0ao6HG3/McAOrBQA5hVSdWng== expo-image-loader@~4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/expo-image-loader/-/expo-image-loader-4.7.0.tgz#d403106822de80bda12d644c82b7a3b7983c0f0b" integrity sha512-cx+MxxsAMGl9AiWnQUzrkJMJH4eNOGlu7XkLGnAXSJrRoIiciGaKqzeaD326IyCTV+Z1fXvIliSgNW+DscvD8g== -expo-image-manipulator@^12.0.3: - version "12.0.3" - resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-12.0.3.tgz#797fda98f606a65c6be9d2c0f53256f3fb3f798c" - integrity sha512-gosW32roHbXRKPiBVbQDFpxaZf8sjOJ9aaqbe085Qfcenvvr1lNFMx9M9BFYhAoKd23oEWlyvNHDnAayV4gAFA== +expo-image-manipulator@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/expo-image-manipulator/-/expo-image-manipulator-12.0.5.tgz#e3dd2810d27025705f73523cd4ba47b0d091a662" + integrity sha512-zJ8yINjckYw/yfoSuICt4yJ9xr112+W9e5QVXwK3nCAHr7sv45RQ5sxte0qppf594TPl+UoV6Tjim7WpoKipRQ== dependencies: expo-image-loader "~4.7.0" -expo-image-picker@~15.0.4: - version "15.0.4" - resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-15.0.4.tgz#b01121b26c88ee14bf49133160e408c1e7972b4d" - integrity sha512-Jo78o3DQfqpYC4fsnayxTEVGDFSbaNMwx5gQ2PPlEYMK5AmD5qexQjxhlxM1mZ0e1xkJKJfN7XEdcf53jW9vIg== +expo-image-picker@~15.0.5: + version "15.0.5" + resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-15.0.5.tgz#8a3d4c3ecdb5bcf58f09e024597dd69edf7baa9c" + integrity sha512-Qqp16udsadx/YpNcNaWzfbmO0tbMxyX9bS1aFiDVC+Zffh8LY8S4HJJcnWqSC2TeuAl+9SxUwTloJagvPeMBBw== dependencies: expo-image-loader "~4.7.0" @@ -12268,10 +12256,10 @@ expo-navigation-bar@~3.0.4: "@react-native/normalize-colors" "~0.74.83" debug "^4.3.2" -expo-notifications@~0.28.1: - version "0.28.1" - resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.28.1.tgz#9152cb17100ce72b66f2bf642fb097c3ae2d2019" - integrity sha512-qBVcq3lc+FIvcYt/8M+JB1c60g0hVuyGY4MVGTY56ciU6nMOCiBiz4XPc3DeiZA16jVtfriooWA26wqBkQfkHg== +expo-notifications@~0.28.3: + version "0.28.3" + resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.28.3.tgz#9076c2bd69c3de3338a2e2161c8bd5f18cb440cb" + integrity sha512-Xaj82eQUJzJXa8+giZr708ih86GGtkGS8N01epoiDkTKC8Z9783UJ8Pf8+PSFSfHsY3Sd8TJpQrD9n7QnGHwGQ== dependencies: "@expo/image-utils" "^0.5.0" "@ide/backoff" "^1.0.0" @@ -12334,15 +12322,15 @@ expo-updates-interface@~0.16.2: resolved "https://registry.yarnpkg.com/expo-updates-interface/-/expo-updates-interface-0.16.2.tgz#ad1ac2ca8ee5a8cc84052ea3c18a11da64da569b" integrity sha512-929XBU70q5ELxkKADj1xL0UIm3HvhYhNAOZv5DSk7rrKvLo7QDdPyl+JVnwZm9LrkNbH4wuE2rLoKu1KMgZ+9A== -expo-updates@~0.25.11: - version "0.25.11" - resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.25.11.tgz#a477139cfd5f67c7b5fdf41eba3f6dad471eeb14" - integrity sha512-ZO+e6bLsEBMz+JdEOlJXGf+3w606si7zKKEEzkwDQWJWP20W0WQAG+MDYgTEgxQboc+jTC+T0MvvOvkVb8cFIQ== +expo-updates@~0.25.14: + version "0.25.14" + resolved "https://registry.yarnpkg.com/expo-updates/-/expo-updates-0.25.14.tgz#d0838780d0fa91558df72ca0f8b25b02466da11c" + integrity sha512-taYa6Q/882MxPaMZEoU0Tr4Ivtq0B0XUmCgj7GcKv0pDDhB7vuQ4uxXhWYn5udX+nJM0KH+dtEVFNVyeucVArg== dependencies: "@expo/code-signing-certificates" "0.0.5" - "@expo/config" "~9.0.0-beta.0" - "@expo/config-plugins" "~8.0.0-beta.0" - "@expo/fingerprint" "^0.7.0" + "@expo/config" "~9.0.0" + "@expo/config-plugins" "~8.0.0" + "@expo/fingerprint" "^0.8.0" "@expo/spawn-async" "^1.7.2" arg "4.1.0" chalk "^4.1.2" From a60f9933d8c5734391b9f5b14c1bdb0d17ac0468 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 28 May 2024 21:04:56 -0700 Subject: [PATCH 12/55] Enable navigation animations on Android, decrease animation speed (#4207) * bump and rm patch * use the better settings * fix types * remove animation duration * try it with full screen * thanks mozz - use `ios` only on android * maybe a little duration * slightly faster duration * Revert "fix types" This reverts commit d15d4b7a9b59da6d45211bfc4b526c5701db83c6. * Revert "bump and rm patch" This reverts commit 571f85f9e5b7e1381ac9477db6e551dff65e80ce. --------- Co-authored-by: Dan Abramov --- src/Navigation.tsx | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 23cf5f59dd..18801bf645 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -353,11 +353,11 @@ function HomeTabNavigator() { return ( HomeScreen} /> @@ -371,11 +371,11 @@ function SearchTabNavigator() { return ( SearchScreen} /> @@ -389,11 +389,11 @@ function FeedsTabNavigator() { return ( FeedsScreen} /> @@ -407,11 +407,11 @@ function NotificationsTabNavigator() { return ( { Date: Wed, 29 May 2024 07:08:46 +0300 Subject: [PATCH 13/55] Native translation expo module (#4098) * translation expo module * add `onClose` and `onReplacementAction` * rm onReplacementAction * make all props published * make translation api available globally w/o wrapper (#4110) * conditionally import the translation module * only use native translation if language is probably supported * open native translation via dropdown menu --------- Co-authored-by: Hailey Co-authored-by: Dan Abramov --- .../expo-module.config.json | 6 +++ modules/expo-bluesky-translate/index.ts | 6 +++ .../Common/UIHostingControllerCompat.swift | 20 ++++++++ .../ios/ExpoBlueskyTranslate.podspec | 21 ++++++++ .../ios/ExpoBlueskyTranslateModule.swift | 18 +++++++ .../ios/ExpoBlueskyTranslateView.swift | 22 +++++++++ .../ios/TranslateView.swift | 31 ++++++++++++ .../src/ExpoBlueskyTranslate.types.ts | 3 ++ .../src/ExpoBlueskyTranslateView.ios.tsx | 48 +++++++++++++++++++ .../src/ExpoBlueskyTranslateView.tsx | 13 +++++ .../src/ExpoScrollForwarderView.tsx | 2 + src/view/com/post-thread/PostThreadItem.tsx | 27 +++++++++-- src/view/com/util/forms/PostDropdownBtn.tsx | 21 ++++++-- src/view/shell/index.tsx | 2 + 14 files changed, 232 insertions(+), 8 deletions(-) create mode 100644 modules/expo-bluesky-translate/expo-module.config.json create mode 100644 modules/expo-bluesky-translate/index.ts create mode 100644 modules/expo-bluesky-translate/ios/Common/UIHostingControllerCompat.swift create mode 100644 modules/expo-bluesky-translate/ios/ExpoBlueskyTranslate.podspec create mode 100644 modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateModule.swift create mode 100644 modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateView.swift create mode 100644 modules/expo-bluesky-translate/ios/TranslateView.swift create mode 100644 modules/expo-bluesky-translate/src/ExpoBlueskyTranslate.types.ts create mode 100644 modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx create mode 100644 modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.tsx diff --git a/modules/expo-bluesky-translate/expo-module.config.json b/modules/expo-bluesky-translate/expo-module.config.json new file mode 100644 index 0000000000..28c5dd878d --- /dev/null +++ b/modules/expo-bluesky-translate/expo-module.config.json @@ -0,0 +1,6 @@ +{ + "platforms": ["ios"], + "ios": { + "modules": ["ExpoBlueskyTranslateModule"] + } +} diff --git a/modules/expo-bluesky-translate/index.ts b/modules/expo-bluesky-translate/index.ts new file mode 100644 index 0000000000..f3e1d3b113 --- /dev/null +++ b/modules/expo-bluesky-translate/index.ts @@ -0,0 +1,6 @@ +export { + isAvailable, + isLanguageSupported, + NativeTranslationModule, + NativeTranslationView, +} from './src/ExpoBlueskyTranslateView' diff --git a/modules/expo-bluesky-translate/ios/Common/UIHostingControllerCompat.swift b/modules/expo-bluesky-translate/ios/Common/UIHostingControllerCompat.swift new file mode 100644 index 0000000000..c8ca3e0273 --- /dev/null +++ b/modules/expo-bluesky-translate/ios/Common/UIHostingControllerCompat.swift @@ -0,0 +1,20 @@ +import ExpoModulesCore +import SwiftUI + +// Thanks to Andrew Levy for this code snippet +// https://github.com/andrew-levy/swiftui-react-native/blob/d3fbb2abf07601ff0d4b83055e7717bb980910d6/ios/Common/ExpoView%2BUIHostingController.swift + +extension ExpoView { + func setupHostingController(_ hostingController: UIHostingController) { + hostingController.view.translatesAutoresizingMaskIntoConstraints = false + hostingController.view.backgroundColor = .clear + + addSubview(hostingController.view) + NSLayoutConstraint.activate([ + hostingController.view.topAnchor.constraint(equalTo: self.topAnchor), + hostingController.view.bottomAnchor.constraint(equalTo: self.bottomAnchor), + hostingController.view.leftAnchor.constraint(equalTo: self.leftAnchor), + hostingController.view.rightAnchor.constraint(equalTo: self.rightAnchor), + ]) + } +} diff --git a/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslate.podspec b/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslate.podspec new file mode 100644 index 0000000000..45f86a6056 --- /dev/null +++ b/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslate.podspec @@ -0,0 +1,21 @@ +Pod::Spec.new do |s| + s.name = 'ExpoBlueskyTranslate' + s.version = '1.0.0' + s.summary = 'Uses SwiftUI translation to translate text.' + s.description = 'Uses SwiftUI translation to translate text.' + s.author = '' + s.homepage = 'https://docs.expo.dev/modules/' + s.platforms = { :ios => '13.4' } + s.source = { git: '' } + s.static_framework = true + + s.dependency 'ExpoModulesCore' + + # Swift/Objective-C compatibility + s.pod_target_xcconfig = { + 'DEFINES_MODULE' => 'YES', + 'SWIFT_COMPILATION_MODE' => 'wholemodule' + } + + s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}" +end diff --git a/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateModule.swift b/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateModule.swift new file mode 100644 index 0000000000..afa8137229 --- /dev/null +++ b/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateModule.swift @@ -0,0 +1,18 @@ +import ExpoModulesCore +import Foundation +import SwiftUI + +public class ExpoBlueskyTranslateModule: Module { + public func definition() -> ModuleDefinition { + Name("ExpoBlueskyTranslate") + + AsyncFunction("presentAsync") { (text: String) in + DispatchQueue.main.async { [weak state = TranslateViewState.shared] in + state?.isPresented = true + state?.text = text + } + } + + View(ExpoBlueskyTranslateView.self) {} + } +} diff --git a/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateView.swift b/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateView.swift new file mode 100644 index 0000000000..ca6e3be69c --- /dev/null +++ b/modules/expo-bluesky-translate/ios/ExpoBlueskyTranslateView.swift @@ -0,0 +1,22 @@ +import ExpoModulesCore +import Foundation +import SwiftUI + +class TranslateViewState: ObservableObject { + static var shared = TranslateViewState() + + @Published var isPresented = false + @Published var text = "" +} + +class ExpoBlueskyTranslateView: ExpoView { + required init(appContext: AppContext? = nil) { + if #available(iOS 14.0, *) { + let hostingController = UIHostingController(rootView: TranslateView()) + super.init(appContext: appContext) + setupHostingController(hostingController) + } else { + super.init(appContext: appContext) + } + } +} diff --git a/modules/expo-bluesky-translate/ios/TranslateView.swift b/modules/expo-bluesky-translate/ios/TranslateView.swift new file mode 100644 index 0000000000..e2886dc844 --- /dev/null +++ b/modules/expo-bluesky-translate/ios/TranslateView.swift @@ -0,0 +1,31 @@ +import SwiftUI +// conditionally import the Translation module +#if canImport(Translation) +import Translation +#endif + +struct TranslateView: View { + @ObservedObject var state = TranslateViewState.shared + + var body: some View { + if #available(iOS 17.4, *) { + VStack { + UIViewRepresentableWrapper(view: UIView(frame: .zero)) + } + .translationPresentation( + isPresented: $state.isPresented, + text: state.text + ) + } + } +} + +struct UIViewRepresentableWrapper: UIViewRepresentable { + let view: UIView + + func makeUIView(context: Context) -> UIView { + return view + } + + func updateUIView(_ uiView: UIView, context: Context) {} +} diff --git a/modules/expo-bluesky-translate/src/ExpoBlueskyTranslate.types.ts b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslate.types.ts new file mode 100644 index 0000000000..a01d4d479d --- /dev/null +++ b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslate.types.ts @@ -0,0 +1,3 @@ +export type ExpoBlueskyTranslateModule = { + presentAsync: (text: string) => Promise +} diff --git a/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx new file mode 100644 index 0000000000..daddfa0286 --- /dev/null +++ b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx @@ -0,0 +1,48 @@ +import React from 'react' +import {Platform} from 'react-native' +import {requireNativeModule, requireNativeViewManager} from 'expo-modules-core' + +import {ExpoBlueskyTranslateModule} from './ExpoBlueskyTranslate.types' + +export const NativeTranslationModule = + requireNativeModule('ExpoBlueskyTranslate') + +const NativeView: React.ComponentType = requireNativeViewManager( + 'ExpoBlueskyTranslate', +) + +export function NativeTranslationView() { + return +} + +export const isAvailable = Number(Platform.Version) >= 17.4 + +// https://en.wikipedia.org/wiki/Translate_(Apple)#Languages +const SUPPORTED_LANGUAGES = [ + 'ar', + 'zh', + 'zh', + 'nl', + 'en', + 'en', + 'fr', + 'de', + 'id', + 'it', + 'ja', + 'ko', + 'pl', + 'pt', + 'ru', + 'es', + 'th', + 'tr', + 'uk', + 'vi', +] + +export function isLanguageSupported(lang?: string) { + // If the language is not provided, we assume it is supported + if (!lang) return true + return SUPPORTED_LANGUAGES.includes(lang) +} diff --git a/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.tsx b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.tsx new file mode 100644 index 0000000000..16ff9d6004 --- /dev/null +++ b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.tsx @@ -0,0 +1,13 @@ +export const NativeTranslationModule = { + presentAsync: async (_: string) => {}, +} + +export function NativeTranslationView() { + return null +} + +export const isAvailable = false + +export function isLanguageSupported(_lang?: string) { + return false +} diff --git a/modules/expo-scroll-forwarder/src/ExpoScrollForwarderView.tsx b/modules/expo-scroll-forwarder/src/ExpoScrollForwarderView.tsx index 93e69333fd..0f5d01c130 100644 --- a/modules/expo-scroll-forwarder/src/ExpoScrollForwarderView.tsx +++ b/modules/expo-scroll-forwarder/src/ExpoScrollForwarderView.tsx @@ -1,5 +1,7 @@ import React from 'react' + import {ExpoScrollForwarderViewProps} from './ExpoScrollForwarder.types' + export function ExpoScrollForwarderView({ children, }: React.PropsWithChildren) { diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index c44875b376..548b73af6c 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -30,6 +30,11 @@ import {useSession} from 'state/session' import {PostThreadFollowBtn} from 'view/com/post-thread/PostThreadFollowBtn' import {atoms as a} from '#/alf' import {RichText} from '#/components/RichText' +import { + isAvailable as isNativeTranslationAvailable, + isLanguageSupported, + NativeTranslationModule, +} from '../../../../modules/expo-bluesky-translate' import {ContentHider} from '../../../components/moderation/ContentHider' import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' import {PostAlerts} from '../../../components/moderation/PostAlerts' @@ -317,6 +322,7 @@ let PostThreadItemLoaded = ({ @@ -620,26 +626,39 @@ function PostOuterWrapper({ function ExpandedPostDetails({ post, + record, needsTranslation, translatorUrl, }: { post: AppBskyFeedDefs.PostView + record?: AppBskyFeedPost.Record needsTranslation: boolean translatorUrl: string }) { const pal = usePalette('default') const {_} = useLingui() const openLink = useOpenLink() - const onTranslatePress = React.useCallback( - () => openLink(translatorUrl), - [openLink, translatorUrl], - ) + + const text = record?.text || '' + + const onTranslatePress = React.useCallback(() => { + if ( + isNativeTranslationAvailable && + isLanguageSupported(record?.langs?.at(0)) + ) { + NativeTranslationModule.presentAsync(text) + } else { + openLink(translatorUrl) + } + }, [openLink, text, translatorUrl, record]) + return ( {niceDate(post.indexedAt)} {needsTranslation && ( <> · + { - openLink(translatorUrl) - }, [openLink, translatorUrl]) + const onPressTranslate = React.useCallback(() => { + if ( + isNativeTranslationAvailable && + isLanguageSupported(record?.langs?.at(0)) + ) { + const text = richTextToString(richText, true) + NativeTranslationModule.presentAsync(text) + } else { + openLink(translatorUrl) + } + }, [openLink, record?.langs, richText, translatorUrl]) const onHidePost = React.useCallback(() => { hidePost({uri: postUri}) @@ -246,7 +259,7 @@ let PostDropdownBtn = ({ + onPress={onPressTranslate}> {_(msg`Translate`)} diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 7d080e57b1..317ac0bde4 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -33,6 +33,7 @@ import {ErrorBoundary} from 'view/com/util/ErrorBoundary' import {MutedWordsDialog} from '#/components/dialogs/MutedWords' import {SigninDialog} from '#/components/dialogs/Signin' import {Outlet as PortalOutlet} from '#/components/Portal' +import {NativeTranslationView} from '../../../modules/expo-bluesky-translate' import {RoutesContainer, TabsNavigator} from '../../Navigation' import {Composer} from './Composer' import {DrawerContent} from './Drawer' @@ -93,6 +94,7 @@ function ShellInner() { + From 211eff3d32760695faeb986d6c51de5dd5379411 Mon Sep 17 00:00:00 2001 From: Eiichi Yoshikawa Date: Wed, 29 May 2024 13:13:36 +0900 Subject: [PATCH 14/55] Add statusBarTranslucent prop (= true) to KeyboardProvider in App.native.tsx (#4208) --- src/App.native.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.native.tsx b/src/App.native.tsx index 7c60d1624b..b359ad911d 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -143,7 +143,7 @@ function App() { * that is set up in the InnerApp component above. */ return ( - + From 613884a3d388b814244fc620c7a06c4742851585 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 29 May 2024 01:50:06 -0700 Subject: [PATCH 15/55] use xcode 15.3 (#4253) * use xcode 15.3 * tweak cache update --- .github/workflows/build-submit-android.yml | 4 ++-- .github/workflows/build-submit-ios.yml | 8 ++++++-- .github/workflows/bundle-deploy-eas-update.yml | 4 ++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-submit-android.yml b/.github/workflows/build-submit-android.yml index b039512d6e..c487c2ab8a 100644 --- a/.github/workflows/build-submit-android.yml +++ b/.github/workflows/build-submit-android.yml @@ -123,11 +123,11 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit uses: actions/cache@v4 - if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + if: ${{ inputs.profile == 'testflight' }} with: path: most-recent-testflight-commit.txt key: most-recent-testflight-commit - name: ✏️ Write commit hash to cache - if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + if: ${{ inputs.profile == 'testflight' }} run: echo ${{ github.sha }} > most-recent-testflight-commit.txt diff --git a/.github/workflows/build-submit-ios.yml b/.github/workflows/build-submit-ios.yml index 0256e96878..c1693b814d 100644 --- a/.github/workflows/build-submit-ios.yml +++ b/.github/workflows/build-submit-ios.yml @@ -47,6 +47,10 @@ jobs: - name: ⚙️ Install dependencies run: yarn install + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '15.3' + - name: ☕️ Setup Cocoapods uses: maxim-lobanov/setup-cocoapods@v1 with: @@ -80,11 +84,11 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit uses: actions/cache@v4 - if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + if: ${{ inputs.profile == 'testflight' }} with: path: most-recent-testflight-commit.txt key: most-recent-testflight-commit - name: ✏️ Write commit hash to cache - if: ${{ inputs.profile == 'testflight' && github.ref == 'refs/heads/main' }} + if: ${{ inputs.profile == 'testflight' }} run: echo ${{ github.sha }} > most-recent-testflight-commit.txt diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 192593b9b2..039b4150a2 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -170,6 +170,10 @@ jobs: - name: ⚙️ Install dependencies run: yarn install + - uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '15.3' + - name: ☕️ Setup Cocoapods uses: maxim-lobanov/setup-cocoapods@v1 with: From 33de856c32711b2b5a83d5b27583eec0cc6e1248 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 29 May 2024 12:00:15 +0300 Subject: [PATCH 16/55] match web version exports (#4257) --- src/lib/app-info.web.ts | 2 ++ src/lib/media/manip.web.ts | 4 ++++ src/view/com/util/images/Image.web.tsx | 12 ++---------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/lib/app-info.web.ts b/src/lib/app-info.web.ts index fe2bc5fff8..7227e28632 100644 --- a/src/lib/app-info.web.ts +++ b/src/lib/app-info.web.ts @@ -1,6 +1,8 @@ import {version} from '../../package.json' +export const BUILD_ENV = process.env.EXPO_PUBLIC_ENV export const IS_DEV = process.env.EXPO_PUBLIC_ENV === 'development' +export const IS_TESTFLIGHT = false // 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. diff --git a/src/lib/media/manip.web.ts b/src/lib/media/manip.web.ts index 25315ebbd8..4761f2fe0d 100644 --- a/src/lib/media/manip.web.ts +++ b/src/lib/media/manip.web.ts @@ -159,3 +159,7 @@ async function downloadUrl(href: string, filename: string) { a.download = filename a.click() } + +export async function safeDeleteAsync() { + // no-op +} diff --git a/src/view/com/util/images/Image.web.tsx b/src/view/com/util/images/Image.web.tsx index ecd9d730ab..a5200b3ea2 100644 --- a/src/view/com/util/images/Image.web.tsx +++ b/src/view/com/util/images/Image.web.tsx @@ -1,11 +1,3 @@ -import { - Image, - NativeSyntheticEvent, - ImageLoadEventData, - ImageSourcePropType, -} from 'react-native' -export default Image +import {Image} from 'react-native' + export const HighPriorityImage = Image -export type OnLoadEvent = NativeSyntheticEvent -export type Source = ImageSourcePropType -export type {ImageStyle} from 'react-native' From 65ad16e394d0525d68e6fc8cd9508de4675c88d5 Mon Sep 17 00:00:00 2001 From: Nick Manos Date: Wed, 29 May 2024 05:56:36 -0400 Subject: [PATCH 17/55] Change Android's MainActivity launchMode to singleTop (#4255) * Add build config plugin to set .MainActivity launchMode * Change android:launchMode to standard * Revert "Change android:launchMode to standard" This reverts commit fddbc4e1b512ff9a55009e227f1f44e99ddabaf3. * adjust --------- Co-authored-by: Hailey --- .github/workflows/bundle-deploy-eas-update.yml | 4 ++-- app.config.js | 1 + plugins/withAndroidManifestLaunchModePlugin.js | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 plugins/withAndroidManifestLaunchModePlugin.js diff --git a/.github/workflows/bundle-deploy-eas-update.yml b/.github/workflows/bundle-deploy-eas-update.yml index 039b4150a2..a684f525fd 100644 --- a/.github/workflows/bundle-deploy-eas-update.yml +++ b/.github/workflows/bundle-deploy-eas-update.yml @@ -307,11 +307,11 @@ jobs: - name: ⬇️ Restore Cache id: get-base-commit uses: actions/cache@v4 - if: ${{ inputs.channel == 'testflight' }} + if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }} with: path: most-recent-testflight-commit.txt key: most-recent-testflight-commit - name: ✏️ Write commit hash to cache - if: ${{ inputs.channel == 'testflight' }} + if: ${{ inputs.channel != 'testflight' && inputs.channel != 'production' }} run: echo ${{ github.sha }} > most-recent-testflight-commit.txt diff --git a/app.config.js b/app.config.js index eafacc6cc1..0c3588c67f 100644 --- a/app.config.js +++ b/app.config.js @@ -204,6 +204,7 @@ module.exports = function (config) { ], './plugins/withAndroidManifestPlugin.js', './plugins/withAndroidManifestFCMIconPlugin.js', + './plugins/withAndroidManifestLaunchModePlugin.js', './plugins/withAndroidStylesWindowBackgroundPlugin.js', './plugins/withAndroidStylesAccentColorPlugin.js', './plugins/withAndroidSplashScreenStatusBarTranslucentPlugin.js', diff --git a/plugins/withAndroidManifestLaunchModePlugin.js b/plugins/withAndroidManifestLaunchModePlugin.js new file mode 100644 index 0000000000..45ab9aeb76 --- /dev/null +++ b/plugins/withAndroidManifestLaunchModePlugin.js @@ -0,0 +1,17 @@ +const {withAndroidManifest} = require('expo/config-plugins') + +module.exports = function withAndroidManifestLaunchModePlugin(appConfig) { + return withAndroidManifest(appConfig, function (decoratedAppConfig) { + try { + const mainApplication = + decoratedAppConfig.modResults.manifest.application[0] + const mainActivity = mainApplication.activity.find( + elem => elem.$['android:name'] === '.MainActivity', + ) + mainActivity.$['android:launchMode'] = 'singleTop' + } catch (e) { + console.error(`withAndroidManifestLaunchModePlugin failed`, e) + } + return decoratedAppConfig + }) +} From 4d39ef2e19632eddc1a31a5b41078f6e40b92fbc Mon Sep 17 00:00:00 2001 From: Mary <148872143+mary-ext@users.noreply.github.com> Date: Thu, 30 May 2024 01:50:13 +0700 Subject: [PATCH 18/55] fix: don't round up count, truncate (#4261) --- src/view/com/util/numeric/format.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/view/com/util/numeric/format.ts b/src/view/com/util/numeric/format.ts index 7aa5a4f4df..71d8d73e04 100644 --- a/src/view/com/util/numeric/format.ts +++ b/src/view/com/util/numeric/format.ts @@ -2,6 +2,10 @@ export const formatCount = (num: number) => Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 1, + // `1,953` shouldn't be rounded up to 2k, it should be truncated. + // @ts-expect-error: `roundingMode` doesn't seem to be in the typings yet + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#roundingmode + roundingMode: 'trunc', }).format(num) export function formatCountShortOnly(num: number): string { From 165feedb866034452807eb87b39efe3ba780184f Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 03:25:11 +0300 Subject: [PATCH 19/55] Use ALF for post controls (#3400) * alf the repost dropdown on web + import icons * alf like icon * convert other post controls * add missing padding to share button * refine buttons and use better icons * revert buttonicon changes * remove ButtonIcon and ButtonText from repost dialog * use 15px font size when not big * reduce size and use contrast_25 * add hover state to logged out view * add `userSelect: 'none'` to buttons * use width rather than height * fix quote close behaviour * prettier * Fix Esc on repost * Use new icons for placeholder * Fix placeholder --------- Co-authored-by: Dan Abramov --- ...seQuote_filled_stroke2_corner0_rounded.svg | 1 + .../closeQuote_stroke2_corner0_rounded.svg | 1 + .../closeQuote_stroke2_corner1_rounded.svg | 1 + ...enQuote_filled_stroke2_corner0_rounded.svg | 1 + .../openQuote_stroke2_corner0_rounded.svg | 1 + .../icons/repost_stroke2_corner0_rounded.svg | 1 + .../icons/repost_stroke2_corner3_rounded.svg | 1 + src/alf/atoms.ts | 11 +- src/components/Button.tsx | 6 +- src/components/icons/Quote.tsx | 21 ++ src/components/icons/Repost.tsx | 13 ++ src/view/com/post-thread/PostThreadItem.tsx | 4 +- src/view/com/util/LoadingPlaceholder.tsx | 64 +++--- src/view/com/util/forms/PostDropdownBtn.tsx | 20 +- src/view/com/util/post-ctrls/PostCtrls.tsx | 147 +++++++------ src/view/com/util/post-ctrls/RepostButton.tsx | 174 +++++++++------- .../com/util/post-ctrls/RepostButton.web.tsx | 194 +++++++++--------- 17 files changed, 376 insertions(+), 285 deletions(-) create mode 100644 assets/icons/closeQuote_filled_stroke2_corner0_rounded.svg create mode 100644 assets/icons/closeQuote_stroke2_corner0_rounded.svg create mode 100644 assets/icons/closeQuote_stroke2_corner1_rounded.svg create mode 100644 assets/icons/openQuote_filled_stroke2_corner0_rounded.svg create mode 100644 assets/icons/openQuote_stroke2_corner0_rounded.svg create mode 100644 assets/icons/repost_stroke2_corner0_rounded.svg create mode 100644 assets/icons/repost_stroke2_corner3_rounded.svg create mode 100644 src/components/icons/Quote.tsx create mode 100644 src/components/icons/Repost.tsx diff --git a/assets/icons/closeQuote_filled_stroke2_corner0_rounded.svg b/assets/icons/closeQuote_filled_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..41e75887c0 --- /dev/null +++ b/assets/icons/closeQuote_filled_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/closeQuote_stroke2_corner0_rounded.svg b/assets/icons/closeQuote_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..3c76c73920 --- /dev/null +++ b/assets/icons/closeQuote_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/closeQuote_stroke2_corner1_rounded.svg b/assets/icons/closeQuote_stroke2_corner1_rounded.svg new file mode 100644 index 0000000000..b27eb94f23 --- /dev/null +++ b/assets/icons/closeQuote_stroke2_corner1_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/openQuote_filled_stroke2_corner0_rounded.svg b/assets/icons/openQuote_filled_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..e8141a1128 --- /dev/null +++ b/assets/icons/openQuote_filled_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/openQuote_stroke2_corner0_rounded.svg b/assets/icons/openQuote_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..eee6344cee --- /dev/null +++ b/assets/icons/openQuote_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/repost_stroke2_corner0_rounded.svg b/assets/icons/repost_stroke2_corner0_rounded.svg new file mode 100644 index 0000000000..a3cff9c62d --- /dev/null +++ b/assets/icons/repost_stroke2_corner0_rounded.svg @@ -0,0 +1 @@ + diff --git a/assets/icons/repost_stroke2_corner3_rounded.svg b/assets/icons/repost_stroke2_corner3_rounded.svg new file mode 100644 index 0000000000..8aa7f727bd --- /dev/null +++ b/assets/icons/repost_stroke2_corner3_rounded.svg @@ -0,0 +1 @@ + diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index 3e5ddf049b..158bb6ec5b 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -841,7 +841,7 @@ export const atoms = { marginRight: 'auto', }, /* - * Pointer events + * Pointer events & user select */ pointer_events_none: { pointerEvents: 'none', @@ -849,6 +849,15 @@ export const atoms = { pointer_events_auto: { pointerEvents: 'auto', }, + user_select_none: { + userSelect: 'none', + }, + user_select_text: { + userSelect: 'text', + }, + user_select_all: { + userSelect: 'all', + }, /* * Text decoration */ diff --git a/src/components/Button.tsx b/src/components/Button.tsx index a008c8605c..3db8033997 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -71,6 +71,7 @@ export type ButtonProps = Pick< testID?: string label: string style?: StyleProp + hoverStyle?: StyleProp children: NonTextElements | ((context: ButtonContext) => NonTextElements) } @@ -96,6 +97,7 @@ export function Button({ label, disabled = false, style, + hoverStyle: hoverStyleProp, ...rest }: ButtonProps) { const t = useTheme() @@ -374,7 +376,9 @@ export function Button({ a.align_center, a.justify_center, flattenedBaseStyles, - ...(state.hovered || state.pressed ? hoverStyles : []), + ...(state.hovered || state.pressed + ? [hoverStyles, flatten(hoverStyleProp)] + : []), flatten(style), ]} onPressIn={onPressIn} diff --git a/src/components/icons/Quote.tsx b/src/components/icons/Quote.tsx new file mode 100644 index 0000000000..ec53cfc460 --- /dev/null +++ b/src/components/icons/Quote.tsx @@ -0,0 +1,21 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const OpenQuote_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M7.574 4.178a1 1 0 0 1 .43.822v5h2a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8c0-2.585 1.162-4.335 2.316-5.417a8.163 8.163 0 0 1 1.569-1.15 7.029 7.029 0 0 1 .738-.36l.016-.005.005-.003h.003v-.001c.001 0 .002 0 .353.936l-.351-.936a1 1 0 0 1 .92.114Zm-1.57 2.588a5.99 5.99 0 0 0-.316.276C4.842 7.835 4.004 9.085 4.004 11v7h5v-6h-2a1 1 0 0 1-1-1V6.766Zm12.57-2.588a1 1 0 0 1 .43.822v5h2a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-8c0-2.585 1.162-4.335 2.316-5.417a8.166 8.166 0 0 1 1.569-1.15 7.038 7.038 0 0 1 .738-.36l.016-.005.005-.003h.003v-.001c.001 0 .002 0 .353.936l-.351-.936a1 1 0 0 1 .92.114Zm-1.57 2.588c-.105.085-.21.177-.316.276-.846.793-1.684 2.043-1.684 3.958v7h5v-6h-2a1 1 0 0 1-1-1V6.766Z', +}) + +export const OpenQuote_Filled_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M8.004 5a1 1 0 0 0-.43-.822c-.57-.395-1.176-.031-1.685.255-.428.24-.998.614-1.569 1.15C3.166 6.665 2.004 8.415 2.004 11v8a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2V5ZM19.004 5a1 1 0 0 0-.43-.822c-.57-.395-1.176-.031-1.685.255-.428.24-.998.614-1.569 1.15-1.154 1.082-2.316 2.832-2.316 5.417v8a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1v-8a1 1 0 0 0-1-1h-2V5Z', +}) + +export const CloseQuote_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M2.004 5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v8c0 2.585-1.162 4.335-2.316 5.417-.571.536-1.14.91-1.569 1.15a7.01 7.01 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001L6.004 19l.351.936A1 1 0 0 1 5.004 19v-5h-2a1 1 0 0 1-1-1V5Zm5 12.234c.104-.085.21-.177.316-.276.846-.793 1.684-2.043 1.684-3.958V6h-5v6h2a1 1 0 0 1 1 1v4.234Zm6-12.234a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v8c0 2.585-1.162 4.335-2.316 5.417-.571.536-1.14.91-1.569 1.15a7.018 7.018 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001-.352-.936.351.936A1 1 0 0 1 16.004 19v-5h-2a1 1 0 0 1-1-1V5Zm5 12.234V13a1 1 0 0 0-1-1h-2V6h5v7c0 1.915-.838 3.165-1.684 3.958-.106.1-.212.191-.316.276Z', +}) + +export const CloseQuote_Stroke2_Corner1_Rounded = createSinglePathSVG({ + path: 'M2.003 5.999a2 2 0 0 1 2-1.999h5c1.104 0 2 .893 2 1.999V13c0 2.585-1.16 4.335-2.315 5.417-.571.536-1.14.91-1.569 1.15a7.01 7.01 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001L6.004 19l.351.936a1 1 0 0 1-1.351-.935L5 14H4a2 2 0 0 1-2-2.001l.002-6Zm5 11.236L7 12.999A1 1 0 0 0 6 12H4l.003-6h5v7c0 1.915-.837 3.165-1.683 3.958-.106.1-.213.192-.317.277Zm6-11.235a2 2 0 0 1 2-2h5c1.104 0 2 .893 2 1.999V13c0 2.585-1.16 4.335-2.315 5.417-.571.536-1.14.91-1.569 1.15a7.018 7.018 0 0 1-.738.36l-.016.006-.006.002h-.002l-.001.001-.352-.936.351.936A1 1 0 0 1 16.004 19v-5h-1a2 2 0 0 1-2-2V6Zm7 0h-5v6h2a1 1 0 0 1 1 1v4.234c.105-.085.211-.177.317-.276.846-.793 1.684-2.043 1.684-3.958V6Z', +}) + +export const CloseQuote_Filled_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M3.004 4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2v5a1 1 0 0 0 .43.822c.57.395 1.176.031 1.685-.255.428-.24.998-.614 1.569-1.15 1.154-1.082 2.316-2.832 2.316-5.417V5a1 1 0 0 0-1-1h-7ZM14.004 4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h2v5a1 1 0 0 0 .43.822c.57.395 1.176.031 1.685-.255.428-.24.998-.614 1.569-1.15 1.154-1.082 2.316-2.832 2.316-5.417V5a1 1 0 0 0-1-1h-7Z', +}) diff --git a/src/components/icons/Repost.tsx b/src/components/icons/Repost.tsx new file mode 100644 index 0000000000..01214bca71 --- /dev/null +++ b/src/components/icons/Repost.tsx @@ -0,0 +1,13 @@ +import {createSinglePathSVG} from './TEMPLATE' + +export const Repost_Stroke2_Corner0_Rounded = createSinglePathSVG({ + path: 'M16.293 2.293a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1 0 1.414l-3 3a1 1 0 0 1-1.414-1.414L17.586 7H5v4a1 1 0 1 1-2 0V6a1 1 0 0 1 1-1h13.586l-1.293-1.293a1 1 0 0 1 0-1.414ZM21 13v5a1 1 0 0 1-1 1H6.414l1.293 1.293a1 1 0 1 1-1.414 1.414l-3-3a1 1 0 0 1 0-1.414l3-3a1 1 0 0 1 1.414 1.414L6.414 17H19v-4a1 1 0 1 1 2 0Z', +}) + +export const Repost_Stroke2_Corner2_Rounded = createSinglePathSVG({ + path: 'M17.957 2.293a1 1 0 1 0-1.414 1.414L17.836 5H6a3 3 0 0 0-3 3v3a1 1 0 1 0 2 0V8a1 1 0 0 1 1-1h11.836l-1.293 1.293a1 1 0 0 0 1.414 1.414l2.47-2.47a1.75 1.75 0 0 0 0-2.474l-2.47-2.47ZM20 12a1 1 0 0 1 1 1v3a3 3 0 0 1-3 3H6.164l1.293 1.293a1 1 0 1 1-1.414 1.414l-2.47-2.47a1.75 1.75 0 0 1 0-2.474l2.47-2.47a1 1 0 0 1 1.414 1.414L6.164 17H18a1 1 0 0 0 1-1v-3a1 1 0 0 1 1-1Z', +}) + +export const Repost_Stroke2_Corner3_Rounded = createSinglePathSVG({ + path: 'M16.793 2.293a1 1 0 0 1 1.414 0L20.5 4.586a2 2 0 0 1 0 2.828l-2.293 2.293a1 1 0 0 1-1.414-1.414L18.086 7H7a2 2 0 0 0-2 2v2a1 1 0 1 1-2 0V9a4 4 0 0 1 4-4h11.086l-1.293-1.293a1 1 0 0 1 0-1.414ZM20 12a1 1 0 0 1 1 1v2a4 4 0 0 1-4 4H5.914l1.293 1.293a1 1 0 1 1-1.414 1.414L3.5 19.414a2 2 0 0 1 0-2.828l2.293-2.293a1 1 0 0 1 1.414 1.414L5.914 17H17a2 2 0 0 0 2-2v-2a1 1 0 0 1 1-1Z', +}) diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 548b73af6c..0ff040b9c8 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -367,7 +367,7 @@ let PostThreadItemLoaded = ({ ) : null} ) : null} - + }) { - const theme = useTheme() + const t = useTheme_NEW() const pal = usePalette('default') return ( @@ -67,35 +67,47 @@ export function PostLoadingPlaceholder({ - - - + + - - - + @@ -290,10 +302,10 @@ const styles = StyleSheet.create({ flex: 1, }, postBtn: { - padding: 5, flex: 1, flexDirection: 'row', alignItems: 'center', + padding: 5, }, avatar: { borderRadius: 26, diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx index 50677ee8a6..cd82ec98f0 100644 --- a/src/view/com/util/forms/PostDropdownBtn.tsx +++ b/src/view/com/util/forms/PostDropdownBtn.tsx @@ -1,5 +1,10 @@ import React, {memo} from 'react' -import {Pressable, PressableProps, StyleProp, ViewStyle} from 'react-native' +import { + Pressable, + type PressableProps, + type StyleProp, + type ViewStyle, +} from 'react-native' import * as Clipboard from 'expo-clipboard' import { AppBskyActorDefs, @@ -7,7 +12,6 @@ import { AtUri, RichText as RichTextAPI, } from '@atproto/api' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' @@ -37,6 +41,7 @@ import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons import {BubbleQuestion_Stroke2_Corner0_Rounded as Translate} from '#/components/icons/Bubble' import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard' import {CodeBrackets_Stroke2_Corner0_Rounded as CodeBrackets} from '#/components/icons/CodeBrackets' +import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid' import { EmojiSad_Stroke2_Corner0_Rounded as EmojiSad, EmojiSmile_Stroke2_Corner0_Rounded as EmojiSmile, @@ -68,6 +73,7 @@ let PostDropdownBtn = ({ richText, style, hitSlop, + size, timestamp, }: { testID: string @@ -79,6 +85,7 @@ let PostDropdownBtn = ({ richText: RichTextAPI style?: StyleProp hitSlop?: PressableProps['hitSlop'] + size?: 'lg' | 'md' | 'sm' timestamp: string }): React.ReactNode => { const {hasSession, currentAccount} = useSession() @@ -238,14 +245,13 @@ let PostDropdownBtn = ({ style, a.rounded_full, (state.hovered || state.pressed) && [ - alf.atoms.bg_contrast_50, + alf.atoms.bg_contrast_25, ], ]}> -
) diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index b6c07d5735..2b0220842e 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -1,10 +1,10 @@ import React, {memo, useCallback} from 'react' import { - StyleProp, - StyleSheet, - TouchableOpacity, + Pressable, + type PressableStateCallbackType, + type StyleProp, View, - ViewStyle, + type ViewStyle, } from 'react-native' import { AppBskyFeedDefs, @@ -16,12 +16,11 @@ import {msg, plural} from '@lingui/macro' import {useLingui} from '@lingui/react' import {HITSLOP_10, HITSLOP_20} from '#/lib/constants' -import {CommentBottomArrow, HeartIcon, HeartIconSolid} from '#/lib/icons' +import {useHaptics} from '#/lib/haptics' import {makeProfileLink} from '#/lib/routes/links' import {shareUrl} from '#/lib/sharing' import {toShareUrl} from '#/lib/strings/url-helpers' import {s} from '#/lib/styles' -import {useTheme} from '#/lib/ThemeContext' import {Shadow} from '#/state/cache/types' import {useFeedFeedbackContext} from '#/state/feed-feedback' import {useModalControls} from '#/state/modals' @@ -31,9 +30,14 @@ import { } from '#/state/queries/post' import {useRequireAuth} from '#/state/session' import {useComposerControls} from '#/state/shell/composer' -import {useHaptics} from 'lib/haptics' +import {atoms as a, useTheme} from '#/alf' import {useDialogControl} from '#/components/Dialog' import {ArrowOutOfBox_Stroke2_Corner0_Rounded as ArrowOutOfBox} from '#/components/icons/ArrowOutOfBox' +import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '#/components/icons/Bubble' +import { + Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled, + Heart2_Stroke2_Corner0_Rounded as HeartIconOutline, +} from '#/components/icons/Heart2' import * as Prompt from '#/components/Prompt' import {PostDropdownBtn} from '../forms/PostDropdownBtn' import {Text} from '../text/Text' @@ -58,7 +62,7 @@ let PostCtrls = ({ onPressReply: () => void logContext: 'FeedItem' | 'PostThreadItem' | 'Post' }): React.ReactNode => { - const theme = useTheme() + const t = useTheme() const {_} = useLingui() const {openComposer} = useComposerControls() const {closeModal} = useModalControls() @@ -80,9 +84,9 @@ let PostCtrls = ({ const defaultCtrlColor = React.useMemo( () => ({ - color: theme.palette.default.postCtrl, + color: t.palette.contrast_500, }), - [theme], + [t], ) as StyleProp const onPressToggleLike = React.useCallback(async () => { @@ -185,57 +189,70 @@ let PostCtrls = ({ }) }, [post.uri, post.author, sendInteraction, feedContext]) + const btnStyle = React.useCallback( + ({pressed, hovered}: PressableStateCallbackType) => [ + a.gap_xs, + a.rounded_full, + a.flex_row, + a.align_center, + a.justify_center, + {padding: 5}, + (pressed || hovered) && t.atoms.bg_contrast_25, + ], + [t.atoms.bg_contrast_25], + ) + return ( - + - { if (!post.viewer?.replyDisabled) { requireAuth(() => onPressReply()) } }} - accessibilityRole="button" accessibilityLabel={plural(post.replyCount || 0, { one: 'Reply (# reply)', other: 'Reply (# replies)', })} accessibilityHint="" hitSlop={big ? HITSLOP_20 : HITSLOP_10}> - {typeof post.replyCount !== 'undefined' && post.replyCount > 0 ? ( - + {post.replyCount} ) : undefined} - +
- + - - + { - requireAuth(() => onPressToggleLike()) - }} - accessibilityRole="button" + style={btnStyle} + onPress={() => requireAuth(() => onPressToggleLike())} accessibilityLabel={ post.viewer?.like ? plural(post.likeCount || 0, { @@ -250,33 +267,36 @@ let PostCtrls = ({ accessibilityHint="" hitSlop={big ? HITSLOP_20 : HITSLOP_10}> {post.viewer?.like ? ( - + ) : ( - )} {typeof post.likeCount !== 'undefined' && post.likeCount > 0 ? ( + style={[ + [ + big ? a.text_md : {fontSize: 15}, + a.user_select_none, + post.viewer?.like + ? [a.font_bold, s.likeColor] + : defaultCtrlColor, + ], + ]}> {post.likeCount} ) : undefined} - + {big && ( <> - - + { if (shouldShowLoggedOutWarning) { loggedOutWarningPromptControl.open() @@ -284,15 +304,14 @@ let PostCtrls = ({ onShare() } }} - accessibilityRole="button" - accessibilityLabel={`${_(msg`Share`)}`} + accessibilityLabel={_(msg`Share`)} accessibilityHint="" hitSlop={big ? HITSLOP_20 : HITSLOP_10}> - + )} - + @@ -324,31 +343,3 @@ let PostCtrls = ({ } PostCtrls = memo(PostCtrls) export {PostCtrls} - -const styles = StyleSheet.create({ - ctrls: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }, - ctrl: { - flex: 1, - alignItems: 'flex-start', - }, - ctrlBig: { - alignItems: 'center', - }, - btn: { - flexDirection: 'row', - alignItems: 'center', - }, - btnPad: { - paddingTop: 5, - paddingBottom: 5, - paddingLeft: 5, - paddingRight: 5, - }, - mt1: { - marginTop: 1, - }, -}) diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx index f584178874..1124cb4059 100644 --- a/src/view/com/util/post-ctrls/RepostButton.tsx +++ b/src/view/com/util/post-ctrls/RepostButton.tsx @@ -1,108 +1,132 @@ import React, {memo, useCallback} from 'react' -import {StyleProp, StyleSheet, TouchableOpacity, ViewStyle} from 'react-native' +import {View} from 'react-native' import {msg, plural} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useModalControls} from '#/state/modals' import {useRequireAuth} from '#/state/session' -import {HITSLOP_10, HITSLOP_20} from 'lib/constants' -import {RepostIcon} from 'lib/icons' -import {colors, s} from 'lib/styles' -import {useTheme} from 'lib/ThemeContext' -import {Text} from '../text/Text' +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote' +import {Repost_Stroke2_Corner2_Rounded as Repost} from '#/components/icons/Repost' +import {Text} from '#/components/Typography' interface Props { isReposted: boolean repostCount?: number - big?: boolean onRepost: () => void onQuote: () => void + big?: boolean } let RepostButton = ({ isReposted, repostCount, - big, onRepost, onQuote, + big, }: Props): React.ReactNode => { - const theme = useTheme() + const t = useTheme() const {_} = useLingui() - const {openModal} = useModalControls() const requireAuth = useRequireAuth() + const dialogControl = Dialog.useDialogControl() - const defaultControlColor = React.useMemo( + const color = React.useMemo( () => ({ - color: theme.palette.default.postCtrl, + color: isReposted ? t.palette.positive_600 : t.palette.contrast_500, }), - [theme], + [t, isReposted], ) - const onPressToggleRepostWrapper = useCallback(() => { - openModal({ - name: 'repost', - onRepost: onRepost, - onQuote: onQuote, - isReposted, - }) - }, [onRepost, onQuote, isReposted, openModal]) + const close = useCallback(() => dialogControl.close(), [dialogControl]) return ( - { - requireAuth(() => onPressToggleRepostWrapper()) - }} - style={[styles.btn, !big && styles.btnPad]} - accessibilityRole="button" - accessibilityLabel={`${ - isReposted - ? _(msg`Undo repost`) - : _(msg({message: 'Repost', context: 'action'})) - } (${plural(repostCount || 0, {one: '# repost', other: '# reposts'})})`} - accessibilityHint="" - hitSlop={big ? HITSLOP_20 : HITSLOP_10}> - + + + + + + + + + + + + + + ) } RepostButton = memo(RepostButton) export {RepostButton} - -const styles = StyleSheet.create({ - btn: { - flexDirection: 'row', - alignItems: 'center', - }, - btnPad: { - paddingTop: 5, - paddingBottom: 5, - paddingLeft: 5, - paddingRight: 5, - }, - reposted: { - color: colors.green3, - }, - repostCount: { - color: 'currentColor', - }, -}) diff --git a/src/view/com/util/post-ctrls/RepostButton.web.tsx b/src/view/com/util/post-ctrls/RepostButton.web.tsx index bbe5869feb..0898981419 100644 --- a/src/view/com/util/post-ctrls/RepostButton.web.tsx +++ b/src/view/com/util/post-ctrls/RepostButton.web.tsx @@ -1,130 +1,134 @@ import React from 'react' -import {StyleProp, StyleSheet, View, ViewStyle, Pressable} from 'react-native' -import {RepostIcon} from 'lib/icons' -import {colors} from 'lib/styles' -import {useTheme} from 'lib/ThemeContext' -import {Text} from '../text/Text' - -import { - NativeDropdown, - DropdownItem as NativeDropdownItem, -} from '../forms/NativeDropdown' -import {EventStopper} from '../EventStopper' -import {useLingui} from '@lingui/react' +import {Pressable, View} from 'react-native' import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + import {useRequireAuth} from '#/state/session' import {useSession} from '#/state/session' +import {atoms as a, useTheme} from '#/alf' +import {Button} from '#/components/Button' +import {CloseQuote_Stroke2_Corner1_Rounded as Quote} from '#/components/icons/Quote' +import {Repost_Stroke2_Corner2_Rounded as Repost} from '#/components/icons/Repost' +import * as Menu from '#/components/Menu' +import {Text} from '#/components/Typography' +import {EventStopper} from '../EventStopper' interface Props { isReposted: boolean repostCount?: number - big?: boolean onRepost: () => void onQuote: () => void - style?: StyleProp + big?: boolean } export const RepostButton = ({ isReposted, repostCount, - big, onRepost, onQuote, + big, }: Props) => { - const theme = useTheme() + const t = useTheme() const {_} = useLingui() const {hasSession} = useSession() const requireAuth = useRequireAuth() - const defaultControlColor = React.useMemo( + const color = React.useMemo( () => ({ - color: theme.palette.default.postCtrl, + color: isReposted ? t.palette.positive_600 : t.palette.contrast_500, }), - [theme], - ) - - const dropdownItems: NativeDropdownItem[] = [ - { - label: isReposted ? _(msg`Undo repost`) : _(msg`Repost`), - testID: 'repostDropdownRepostBtn', - icon: { - ios: {name: 'repeat'}, - android: '', - web: 'retweet', - }, - onPress: onRepost, - }, - { - label: _(msg`Quote post`), - testID: 'repostDropdownQuoteBtn', - icon: { - ios: {name: 'quote.bubble'}, - android: '', - web: 'quote-left', - }, - onPress: onQuote, - }, - ] - - const inner = ( - , - ]}> - - {typeof repostCount !== 'undefined' && repostCount > 0 ? ( - - {repostCount} - - ) : undefined} - + [t, isReposted], ) return hasSession ? ( - - - {inner} - + + + + {({props, state}) => { + return ( + + + + ) + }} + + + + + {isReposted ? _(msg`Undo repost`) : _(msg`Repost`)} + + + + + {_(msg`Quote post`)} + + + + ) : ( - { requireAuth(() => {}) }} - accessibilityLabel={_(msg`Repost or quote post`)} - accessibilityHint=""> - {inner} - + label={_(msg`Repost or quote post`)} + style={{padding: 0}} + hoverStyle={t.atoms.bg_contrast_25} + shape="round" + variant="ghost" + color="secondary"> + + ) } -const styles = StyleSheet.create({ - btn: { - flexDirection: 'row', - alignItems: 'center', - gap: 4, - }, - btnPad: { - paddingTop: 5, - paddingBottom: 5, - paddingLeft: 5, - paddingRight: 5, - }, - reposted: { - color: colors.green3, - }, - repostCount: { - color: 'currentColor', - }, -}) +const RepostInner = ({ + isReposted, + color, + repostCount, + big, +}: { + isReposted: boolean + color: {color: string} + repostCount?: number + big?: boolean +}) => ( + + + {typeof repostCount !== 'undefined' && repostCount > 0 ? ( + + {repostCount} + + ) : undefined} + +) From eb6f44853d91083c7f6015952f1fe6cbe0395631 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 29 May 2024 18:42:12 -0700 Subject: [PATCH 20/55] adjust notifications experiment by removing `canAskAgain` (#4271) * adjust notifications experiment by removing `canAskAgain` * move to `StepFinished` for after onboarding --- src/lib/notifications/notifications.ts | 67 ++++++++++++------------- src/lib/statsig/gates.ts | 2 +- src/screens/Onboarding/StepFinished.tsx | 13 ++++- src/view/screens/Home.tsx | 7 --- 4 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/lib/notifications/notifications.ts b/src/lib/notifications/notifications.ts index f0667b0ccf..705d90c564 100644 --- a/src/lib/notifications/notifications.ts +++ b/src/lib/notifications/notifications.ts @@ -71,46 +71,41 @@ export function useNotificationsRegistration() { export function useRequestNotificationsPermission() { const gate = useGate() - const {currentAccount} = useSession() - return React.useCallback( - async (context: 'StartOnboarding' | 'AfterOnboarding' | 'Login') => { - const permissions = await Notifications.getPermissionsAsync() + return async (context: 'StartOnboarding' | 'AfterOnboarding' | 'Login') => { + const permissions = await Notifications.getPermissionsAsync() - if ( - !currentAccount || - !isNative || - permissions?.status === 'granted' || - (permissions?.status === 'denied' && !permissions?.canAskAgain) - ) { - return - } - if ( - context === 'StartOnboarding' && - gate('request_notifications_permission_after_onboarding') - ) { - return - } - if ( - context === 'AfterOnboarding' && - !gate('request_notifications_permission_after_onboarding') - ) { - return - } + if ( + !isNative || + permissions?.status === 'granted' || + permissions?.status === 'denied' + ) { + return + } + if ( + context === 'StartOnboarding' && + gate('request_notifications_permission_after_onboarding_v2') + ) { + return + } + if ( + context === 'AfterOnboarding' && + !gate('request_notifications_permission_after_onboarding_v2') + ) { + return + } - const res = await Notifications.requestPermissionsAsync() - logEvent('notifications:request', { - context: context, - status: res.status, - }) + const res = await Notifications.requestPermissionsAsync() + logEvent('notifications:request', { + context: context, + status: res.status, + }) - if (res.granted) { - // This will fire a pushTokenEvent, which will handle registration of the token - getPushToken(true) - } - }, - [gate, currentAccount], - ) + if (res.granted) { + // This will fire a pushTokenEvent, which will handle registration of the token + getPushToken(true) + } + } } export async function decrementBadgeCount(by: number | 'reset' = 1) { diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index c572c07211..2721871f35 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -1,4 +1,4 @@ export type Gate = // Keep this alphabetic please. - | 'request_notifications_permission_after_onboarding' + | 'request_notifications_permission_after_onboarding_v2' | 'show_follow_back_label_v2' diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx index b8a21680bf..c75dd4fa74 100644 --- a/src/screens/Onboarding/StepFinished.tsx +++ b/src/screens/Onboarding/StepFinished.tsx @@ -13,6 +13,7 @@ import {RQKEY as profileRQKey} from '#/state/queries/profile' import {useAgent} from '#/state/session' import {useOnboardingDispatch} from '#/state/shell' import {uploadBlob} from 'lib/api' +import {useRequestNotificationsPermission} from 'lib/notifications/notifications' import { DescriptionText, OnboardingControls, @@ -39,6 +40,7 @@ export function StepFinished() { const [saving, setSaving] = React.useState(false) const queryClient = useQueryClient() const agent = useAgent() + const requestNotificationsPermission = useRequestNotificationsPermission() const finishOnboarding = React.useCallback(async () => { setSaving(true) @@ -72,6 +74,7 @@ export function StepFinished() { : 'default', }) })(), + requestNotificationsPermission('AfterOnboarding'), ]) } catch (e: any) { logger.info(`onboarding: bulk save failed`) @@ -98,7 +101,15 @@ export function StepFinished() { track('OnboardingV2:StepFinished:End') track('OnboardingV2:Complete') logEvent('onboarding:finished:nextPressed', {}) - }, [state, dispatch, onboardDispatch, setSaving, track, agent, queryClient]) + }, [ + state, + queryClient, + agent, + dispatch, + onboardDispatch, + track, + requestNotificationsPermission, + ]) React.useEffect(() => { track('OnboardingV2:StepFinished:Start') diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 1744c6651c..829cd94e48 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -20,7 +20,6 @@ import { } from '#/state/shell' import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed' import {useOTAUpdates} from 'lib/hooks/useOTAUpdates' -import {useRequestNotificationsPermission} from 'lib/notifications/notifications' import {HomeTabNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' import {FeedPage} from 'view/com/feeds/FeedPage' import {Pager, PagerRef, RenderTabBarFnProps} from 'view/com/pager/Pager' @@ -59,8 +58,6 @@ function HomeScreenReady({ preferences: UsePreferencesQueryResponse pinnedFeedInfos: SavedFeedSourceInfo[] }) { - const requestNotificationsPermission = useRequestNotificationsPermission() - const allFeeds = React.useMemo( () => pinnedFeedInfos.map(f => f.feedDescriptor), [pinnedFeedInfos], @@ -74,10 +71,6 @@ function HomeScreenReady({ useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName) useOTAUpdates() - React.useEffect(() => { - requestNotificationsPermission('AfterOnboarding') - }, [requestNotificationsPermission]) - const pagerRef = React.useRef(null) const lastPagerReportedIndexRef = React.useRef(selectedIndex) React.useLayoutEffect(() => { From 9628070e52c4f50e2f381a3f4ad1f3932743d011 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 29 May 2024 20:09:24 -0700 Subject: [PATCH 21/55] add prop to ListImpl for disabling `content-visibility` style (#4236) * add prop to `ListImpl` for `content-visibility` style * change to `disableContentVisibility` * lint * tweaks * Keep the fix more general * Clarify ambiguity --------- Co-authored-by: Dan Abramov --- .../Messages/Conversation/MessagesList.tsx | 3 +++ src/view/com/util/List.tsx | 2 ++ src/view/com/util/List.web.tsx | 20 +++++++++++++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index bee7f6cd8f..583c408526 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -328,6 +328,9 @@ export function MessagesList({ renderItem={renderItem} keyExtractor={keyExtractor} containWeb={true} + // Prevents wrong position in Firefox when sending a message + // as well as scroll getting stuck on Chome when scrolling upwards. + disableContentVisibility={true} disableVirtualization={true} style={animatedListStyle} // The extra two items account for the header and the footer components diff --git a/src/view/com/util/List.tsx b/src/view/com/util/List.tsx index c271481a90..22d0949129 100644 --- a/src/view/com/util/List.tsx +++ b/src/view/com/util/List.tsx @@ -26,6 +26,8 @@ export type ListProps = Omit< onItemSeen?: (item: ItemT) => void containWeb?: boolean sideBorders?: boolean + // Web only prop to disable a perf optimization (which would otherwise be on). + disableContentVisibility?: boolean } export type ListRef = React.MutableRefObject diff --git a/src/view/com/util/List.web.tsx b/src/view/com/util/List.web.tsx index 9d8ddedaa3..d4bd1b0039 100644 --- a/src/view/com/util/List.web.tsx +++ b/src/view/com/util/List.web.tsx @@ -5,7 +5,7 @@ import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/rean import {batchedUpdates} from '#/lib/batchedUpdates' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useScrollHandlers} from '#/lib/ScrollContext' -import {isFirefox, isSafari} from 'lib/browser' +import {isSafari} from 'lib/browser' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {addStyle} from 'lib/styles' @@ -25,6 +25,7 @@ export type ListProps = Omit< desktopFixedHeight: any // TODO: Better types. containWeb?: boolean sideBorders?: boolean + disableContentVisibility?: boolean } export type ListRef = React.MutableRefObject // TODO: Better types. @@ -56,6 +57,7 @@ function ListImpl( extraData, style, sideBorders = true, + disableContentVisibility, ...props }: ListProps, ref: React.Ref, @@ -339,6 +341,7 @@ function ListImpl( renderItem={renderItem} extraData={extraData} onItemSeen={onItemSeen} + disableContentVisibility={disableContentVisibility} /> ) })} @@ -387,6 +390,7 @@ let Row = function RowImpl({ renderItem, extraData: _unused, onItemSeen, + disableContentVisibility, }: { item: ItemT index: number @@ -396,6 +400,7 @@ let Row = function RowImpl({ | ((data: {index: number; item: any; separators: any}) => React.ReactNode) extraData: any onItemSeen: ((item: any) => void) | undefined + disableContentVisibility?: boolean }): React.ReactNode { const rowRef = React.useRef(null) const intersectionTimeout = React.useRef(undefined) @@ -444,8 +449,15 @@ let Row = function RowImpl({ return null } + const shouldDisableContentVisibility = disableContentVisibility || isSafari return ( - + {renderItem({item, index, separators: null as any})} ) @@ -516,9 +528,9 @@ const styles = StyleSheet.create({ marginLeft: 'auto', marginRight: 'auto', }, - row: { + contentVisibilityAuto: { // @ts-ignore web only - contentVisibility: isSafari || isFirefox ? '' : 'auto', // Safari support for this is buggy. + contentVisibility: 'auto', }, minHeightViewport: { // @ts-ignore web only From 9edb4879494b348616caca6999ee89658f439c49 Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 29 May 2024 20:28:32 -0700 Subject: [PATCH 22/55] Always show the header on post threads on native (#4254) * always show header on native * ALF ALF ALF * rm offset for top border * wrap in a `CenteredView` * use `CenteredView`'s side borders * account for loading state on web * move `isTabletOrMobile` * hide top border on first post in list * show border if parents are loading * don't show top border for deleted or blocked posts * hide top border for hidden replies * Rm root post top border --------- Co-authored-by: Dan Abramov --- src/view/com/post-thread/PostThread.tsx | 337 ++++++++---------- src/view/com/post-thread/PostThreadItem.tsx | 43 ++- .../PostThreadShowHiddenReplies.tsx | 4 +- 3 files changed, 194 insertions(+), 190 deletions(-) diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 4f7d0d3c62..1212f992da 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useRef} from 'react' -import {StyleSheet, useWindowDimensions, View} from 'react-native' +import {useWindowDimensions, View} from 'react-native' import {runOnJS} from 'react-native-reanimated' import {AppBskyFeedDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' @@ -22,15 +22,16 @@ import { import {usePreferencesQuery} from '#/state/queries/preferences' import {useSession} from '#/state/session' import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' -import {usePalette} from 'lib/hooks/usePalette' import {useSetTitle} from 'lib/hooks/useSetTitle' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {sanitizeDisplayName} from 'lib/strings/display-names' import {cleanError} from 'lib/strings/errors' +import {CenteredView} from 'view/com/util/Views' +import {atoms as a, useTheme} from '#/alf' import {ListFooter, ListMaybePlaceholder} from '#/components/Lists' +import {Text} from '#/components/Typography' import {ComposePrompt} from '../composer/Prompt' import {List, ListMethods} from '../util/List' -import {Text} from '../util/text/Text' import {ViewHeader} from '../util/ViewHeader' import {PostThreadItem} from './PostThreadItem' import {PostThreadShowHiddenReplies} from './PostThreadShowHiddenReplies' @@ -45,7 +46,6 @@ const MAINTAIN_VISIBLE_CONTENT_POSITION = { minIndexForVisible: 0, } -const TOP_COMPONENT = {_reactKey: '__top_component__'} const REPLY_PROMPT = {_reactKey: '__reply__'} const LOAD_MORE = {_reactKey: '__load_more__'} const SHOW_HIDDEN_REPLIES = {_reactKey: '__show_hidden_replies__'} @@ -66,7 +66,6 @@ type YieldedItem = type RowItem = | YieldedItem // TODO: TS doesn't actually enforce it's one of these, it only enforces matching shape. - | typeof TOP_COMPONENT | typeof REPLY_PROMPT | typeof LOAD_MORE @@ -91,7 +90,7 @@ export function PostThread({ }) { const {hasSession} = useSession() const {_} = useLingui() - const pal = usePalette('default') + const t = useTheme() const {isMobile, isTabletOrMobile} = useWebMediaQueries() const initialNumToRender = useInitialNumToRender() const {height: windowHeight} = useWindowDimensions() @@ -224,32 +223,21 @@ export function PostThread({ const {parents, highlightedPost, replies} = skeleton let arr: RowItem[] = [] if (highlightedPost.type === 'post') { - const isRoot = - !highlightedPost.parent && !highlightedPost.ctx.isParentLoading - if (isRoot) { - // No parents to load. - arr.push(TOP_COMPONENT) - } else { - if (highlightedPost.ctx.isParentLoading || deferParents) { - // We're loading parents of the highlighted post. - // In this case, we don't render anything above the post. - // If you add something here, you'll need to update both - // maintainVisibleContentPosition and onContentSizeChange - // to "hold onto" the correct row instead of the first one. - } else { - // Everything is loaded - let startIndex = Math.max(0, parents.length - maxParents) - if (startIndex === 0) { - arr.push(TOP_COMPONENT) - } else { - // When progressively revealing parents, rendering a placeholder - // here will cause scrolling jumps. Don't add it unless you test it. - // QT'ing this thread is a great way to test all the scrolling hacks: - // https://bsky.app/profile/www.mozzius.dev/post/3kjqhblh6qk2o - } - for (let i = startIndex; i < parents.length; i++) { - arr.push(parents[i]) - } + // We want to wait for parents to load before rendering. + // If you add something here, you'll need to update both + // maintainVisibleContentPosition and onContentSizeChange + // to "hold onto" the correct row instead of the first one. + + if (!highlightedPost.ctx.isParentLoading && !deferParents) { + // When progressively revealing parents, rendering a placeholder + // here will cause scrolling jumps. Don't add it unless you test it. + // QT'ing this thread is a great way to test all the scrolling hacks: + // https://bsky.app/profile/www.mozzius.dev/post/3kjqhblh6qk2o + + // Everything is loaded + let startIndex = Math.max(0, parents.length - maxParents) + for (let i = startIndex; i < parents.length; i++) { + arr.push(parents[i]) } } arr.push(highlightedPost) @@ -323,117 +311,100 @@ export function PostThread({ setMaxReplies(prev => prev + 50) }, [isFetching, maxReplies, posts.length]) - const renderItem = React.useCallback( - ({item, index}: {item: RowItem; index: number}) => { - if (item === TOP_COMPONENT) { - return isTabletOrMobile ? ( - - ) : null - } else if (item === REPLY_PROMPT && hasSession) { - return ( - - {!isMobile && } - - ) - } else if (item === SHOW_HIDDEN_REPLIES) { - return ( - - setHiddenRepliesState(HiddenRepliesState.ShowAndOverridePostHider) + const hasParents = + skeleton?.highlightedPost?.type === 'post' && + (skeleton.highlightedPost.ctx.isParentLoading || + Boolean(skeleton?.parents && skeleton.parents.length > 0)) + const showHeader = + isNative || (isTabletOrMobile && (!hasParents || !isFetching)) + + const renderItem = ({item, index}: {item: RowItem; index: number}) => { + if (item === REPLY_PROMPT && hasSession) { + return ( + + {!isMobile && } + + ) + } else if (item === SHOW_HIDDEN_REPLIES || item === SHOW_MUTED_REPLIES) { + return ( + + setHiddenRepliesState(HiddenRepliesState.ShowAndOverridePostHider) + } + hideTopBorder={index === 0} + /> + ) + } else if (isThreadNotFound(item)) { + return ( + + + Deleted post. + + + ) + } else if (isThreadBlocked(item)) { + return ( + + + Blocked post. + + + ) + } else if (isThreadPost(item)) { + const prev = isThreadPost(posts[index - 1]) + ? (posts[index - 1] as ThreadPost) + : undefined + const next = isThreadPost(posts[index + 1]) + ? (posts[index + 1] as ThreadPost) + : undefined + const showChildReplyLine = (next?.ctx.depth || 0) > item.ctx.depth + const showParentReplyLine = + (item.ctx.depth < 0 && !!item.parent) || item.ctx.depth > 1 + const hasUnrevealedParents = + index === 0 && skeleton?.parents && maxParents < skeleton.parents.length + return ( + setDeferParents(false) : undefined}> + 0 } + onPostReply={refetch} + hideTopBorder={index === 0 && !item.ctx.isParentLoading} /> - ) - } else if (item === SHOW_MUTED_REPLIES) { - return ( - - setHiddenRepliesState(HiddenRepliesState.ShowAndOverridePostHider) - } - /> - ) - } else if (isThreadNotFound(item)) { - return ( - - - Deleted post. - - - ) - } else if (isThreadBlocked(item)) { - return ( - - - Blocked post. - - - ) - } else if (isThreadPost(item)) { - const prev = isThreadPost(posts[index - 1]) - ? (posts[index - 1] as ThreadPost) - : undefined - const next = isThreadPost(posts[index + 1]) - ? (posts[index + 1] as ThreadPost) - : undefined - const showChildReplyLine = (next?.ctx.depth || 0) > item.ctx.depth - const showParentReplyLine = - (item.ctx.depth < 0 && !!item.parent) || item.ctx.depth > 1 - const hasUnrevealedParents = - index === 0 && - skeleton?.parents && - maxParents < skeleton.parents.length - return ( - setDeferParents(false) : undefined}> - 0 - } - onPostReply={refetch} - /> - - ) - } - return null - }, - [ - hasSession, - isTabletOrMobile, - _, - isMobile, - onPressReply, - pal.border, - pal.viewLight, - pal.textLight, - posts, - skeleton?.parents, - maxParents, - deferParents, - treeView, - refetch, - threadModerationCache, - hiddenRepliesState, - setHiddenRepliesState, - ], - ) + + ) + } + return null + } if (!thread || !preferences || error) { return ( @@ -449,39 +420,49 @@ export function PostThread({ } return ( - - - } - initialNumToRender={initialNumToRender} - windowSize={11} - /> - + + {showHeader && ( + + )} + + + + } + initialNumToRender={initialNumToRender} + windowSize={11} + sideBorders={false} + /> + + ) } @@ -630,11 +611,3 @@ function hasBranchingReplies(node?: ThreadNode) { } return true } - -const styles = StyleSheet.create({ - itemContainer: { - borderTopWidth: 1, - paddingHorizontal: 18, - paddingVertical: 18, - }, -}) diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 0ff040b9c8..99fbda6d28 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -65,6 +65,7 @@ export function PostThreadItem({ hasPrecedingItem, overrideBlur, onPostReply, + hideTopBorder, }: { post: AppBskyFeedDefs.PostView record: AppBskyFeedPost.Record @@ -80,6 +81,7 @@ export function PostThreadItem({ hasPrecedingItem: boolean overrideBlur: boolean onPostReply: () => void + hideTopBorder?: boolean }) { const postShadowed = usePostShadow(post) const richText = useMemo( @@ -91,7 +93,7 @@ export function PostThreadItem({ [record], ) if (postShadowed === POST_TOMBSTONE) { - return + return } if (richText && moderation) { return ( @@ -113,16 +115,25 @@ export function PostThreadItem({ hasPrecedingItem={hasPrecedingItem} overrideBlur={overrideBlur} onPostReply={onPostReply} + hideTopBorder={hideTopBorder} /> ) } return null } -function PostThreadItemDeleted() { +function PostThreadItemDeleted({hideTopBorder}: {hideTopBorder?: boolean}) { const pal = usePalette('default') return ( - + This post has been deleted. @@ -147,6 +158,7 @@ let PostThreadItemLoaded = ({ hasPrecedingItem, overrideBlur, onPostReply, + hideTopBorder, }: { post: Shadow record: AppBskyFeedPost.Record @@ -163,6 +175,7 @@ let PostThreadItemLoaded = ({ hasPrecedingItem: boolean overrideBlur: boolean onPostReply: () => void + hideTopBorder?: boolean }): React.ReactNode => { const pal = usePalette('default') const {_} = useLingui() @@ -237,7 +250,7 @@ let PostThreadItemLoaded = ({ styles.replyLine, { flexGrow: 1, - backgroundColor: pal.colors.border, + backgroundColor: pal.colors.replyLine, }, ]} /> @@ -247,7 +260,14 @@ let PostThreadItemLoaded = ({ @@ -395,7 +415,8 @@ let PostThreadItemLoaded = ({ depth={depth} showParentReplyLine={!!showParentReplyLine} treeView={treeView} - hasPrecedingItem={hasPrecedingItem}> + hasPrecedingItem={hasPrecedingItem} + hideTopBorder={hideTopBorder}> ) { const {isMobile} = useWebMediaQueries() const pal = usePalette('default') @@ -617,6 +640,7 @@ function PostOuterWrapper({ styles.outer, pal.border, showParentReplyLine && hasPrecedingItem && styles.noTopBorder, + hideTopBorder && styles.noTopBorder, styles.cursor, ]}> {children} @@ -677,10 +701,15 @@ const styles = StyleSheet.create({ paddingLeft: 8, }, outerHighlighted: { - paddingTop: 16, + borderTopWidth: 0, + paddingTop: 4, paddingLeft: 8, paddingRight: 8, }, + outerHighlightedRoot: { + borderTopWidth: 1, + paddingTop: 16, + }, noTopBorder: { borderTopWidth: 0, }, diff --git a/src/view/com/post-thread/PostThreadShowHiddenReplies.tsx b/src/view/com/post-thread/PostThreadShowHiddenReplies.tsx index 998906524a..7c021d88b7 100644 --- a/src/view/com/post-thread/PostThreadShowHiddenReplies.tsx +++ b/src/view/com/post-thread/PostThreadShowHiddenReplies.tsx @@ -11,9 +11,11 @@ import {Text} from '#/components/Typography' export function PostThreadShowHiddenReplies({ type, onPress, + hideTopBorder, }: { type: 'hidden' | 'muted' onPress: () => void + hideTopBorder?: boolean }) { const {_} = useLingui() const t = useTheme() @@ -31,7 +33,7 @@ export function PostThreadShowHiddenReplies({ a.gap_sm, a.py_lg, a.px_xl, - a.border_t, + !hideTopBorder && a.border_t, t.atoms.border_contrast_low, hovered || pressed ? t.atoms.bg_contrast_25 : t.atoms.bg, ]}> From 4cc55f05c2f8dda903733e5a7bb1442a107d116d Mon Sep 17 00:00:00 2001 From: Hailey Date: Wed, 29 May 2024 20:37:45 -0700 Subject: [PATCH 23/55] =?UTF-8?q?Use=20a=20margin=20of=20-6=20instead=20of?= =?UTF-8?q?=20-5=20for=20PostCtrls=20=F0=9F=98=B5=E2=80=8D=F0=9F=92=AB=20(?= =?UTF-8?q?#4272)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * -6 instead of -5 😵‍💫 * same here --- src/view/com/util/LoadingPlaceholder.tsx | 2 +- src/view/com/util/post-ctrls/PostCtrls.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/view/com/util/LoadingPlaceholder.tsx b/src/view/com/util/LoadingPlaceholder.tsx index 882f7216b0..33a59be6dc 100644 --- a/src/view/com/util/LoadingPlaceholder.tsx +++ b/src/view/com/util/LoadingPlaceholder.tsx @@ -67,7 +67,7 @@ export function PostLoadingPlaceholder({ - + Date: Wed, 29 May 2024 21:33:18 -0700 Subject: [PATCH 24/55] Improve the visual clarity of labels on profiles and posts (#4262) * Update PostAlerts rendering to show the avi of the labeler rather than the display name; also add size variations * Update ProfileHeaderAlerts to match PostAlerts behavior --- src/components/moderation/PostAlerts.tsx | 53 ++++++++++++++----- .../moderation/ProfileHeaderAlerts.tsx | 15 ++++-- .../useModerationCauseDescription.ts | 18 ++++--- src/view/com/post-thread/PostThreadItem.tsx | 3 +- src/view/com/posts/FeedItem.tsx | 2 +- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/components/moderation/PostAlerts.tsx b/src/components/moderation/PostAlerts.tsx index c59aa2655e..5a33bbc80f 100644 --- a/src/components/moderation/PostAlerts.tsx +++ b/src/components/moderation/PostAlerts.tsx @@ -1,9 +1,10 @@ import React from 'react' import {StyleProp, View, ViewStyle} from 'react-native' -import {ModerationCause, ModerationUI} from '@atproto/api' +import {BSKY_LABELER_DID, ModerationCause, ModerationUI} from '@atproto/api' import {getModerationCauseKey} from '#/lib/moderation' import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' +import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme} from '#/alf' import {Button} from '#/components/Button' import { @@ -14,9 +15,11 @@ import {Text} from '#/components/Typography' export function PostAlerts({ modui, + size, style, }: { modui: ModerationUI + size?: 'medium' | 'large' includeMute?: boolean style?: StyleProp }) { @@ -28,17 +31,31 @@ export function PostAlerts({ {modui.alerts.map(cause => ( - + ))} {modui.informs.map(cause => ( - + ))} ) } -function PostLabel({cause}: {cause: ModerationCause}) { +function PostLabel({ + cause, + size, +}: { + cause: ModerationCause + size?: 'medium' | 'large' +}) { const control = useModerationDetailsDialogControl() const desc = useModerationCauseDescription(cause) const t = useTheme() @@ -55,24 +72,36 @@ function PostLabel({cause}: {cause: ModerationCause}) { style={[ a.flex_row, a.align_center, - {paddingLeft: 4, paddingRight: 6, paddingVertical: 1}, a.gap_xs, a.rounded_sm, hovered || pressed - ? t.atoms.bg_contrast_50 - : t.atoms.bg_contrast_25, + ? size === 'large' + ? t.atoms.bg_contrast_50 + : t.atoms.bg_contrast_25 + : size === 'large' + ? t.atoms.bg_contrast_25 + : undefined, + size === 'large' + ? {paddingLeft: 4, paddingRight: 6, paddingVertical: 2} + : {paddingRight: 4, paddingVertical: 1}, ]}> - + {desc.sourceType === 'labeler' && + desc.sourceDid !== BSKY_LABELER_DID ? ( + + ) : ( + + )} {desc.name} - {desc.source ? ` – ${desc.source}` : ''} )} diff --git a/src/components/moderation/ProfileHeaderAlerts.tsx b/src/components/moderation/ProfileHeaderAlerts.tsx index 3fa24b9385..287a0bddec 100644 --- a/src/components/moderation/ProfileHeaderAlerts.tsx +++ b/src/components/moderation/ProfileHeaderAlerts.tsx @@ -1,9 +1,14 @@ import React from 'react' import {StyleProp, View, ViewStyle} from 'react-native' -import {ModerationCause, ModerationDecision} from '@atproto/api' +import { + BSKY_LABELER_DID, + ModerationCause, + ModerationDecision, +} from '@atproto/api' import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription' import {getModerationCauseKey} from 'lib/moderation' +import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme} from '#/alf' import {Button} from '#/components/Button' import { @@ -62,7 +67,12 @@ function ProfileLabel({cause}: {cause: ModerationCause}) { ? t.atoms.bg_contrast_50 : t.atoms.bg_contrast_25, ]}> - + {desc.sourceType === 'labeler' && + desc.sourceDid !== BSKY_LABELER_DID ? ( + + ) : ( + + )} {desc.name} - {desc.source ? ` – ${desc.source}` : ''} )} diff --git a/src/lib/moderation/useModerationCauseDescription.ts b/src/lib/moderation/useModerationCauseDescription.ts index 57b50d7779..be9014029c 100644 --- a/src/lib/moderation/useModerationCauseDescription.ts +++ b/src/lib/moderation/useModerationCauseDescription.ts @@ -6,15 +6,15 @@ import { } from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {getDefinition, getLabelStrings} from './useLabelInfo' -import {useLabelDefinitions} from '#/state/preferences' -import {useGlobalLabelStrings} from './useGlobalLabelStrings' -import {Props as SVGIconProps} from '#/components/icons/common' -import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' -import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' -import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' +import {useLabelDefinitions} from '#/state/preferences' import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import {Props as SVGIconProps} from '#/components/icons/common' +import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' +import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' +import {useGlobalLabelStrings} from './useGlobalLabelStrings' +import {getDefinition, getLabelStrings} from './useLabelInfo' export interface ModerationCauseDescription { icon: React.ComponentType @@ -22,6 +22,8 @@ export interface ModerationCauseDescription { description: string source?: string sourceType?: ModerationCauseSource['type'] + sourceAvi?: string + sourceDid?: string } export function useModerationCauseDescription( @@ -138,6 +140,8 @@ export function useModerationCauseDescription( description: strings.description, source, sourceType: cause.source.type, + sourceAvi: labeler?.creator.avatar, + sourceDid: cause.label.src, } } // should never happen diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 99fbda6d28..5451a67dd8 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -316,6 +316,7 @@ let PostThreadItemLoaded = ({ childContainerStyle={styles.contentHiderChild}> @@ -517,7 +518,7 @@ let PostThreadItemLoaded = ({ {richText?.text ? ( diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 1a5f954e32..70f63427dc 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -368,7 +368,7 @@ let PostContent = ({ modui={moderation.ui('contentList')} ignoreMute childContainerStyle={styles.contentHiderChild}> - + {richText.text ? ( Date: Wed, 29 May 2024 21:34:47 -0700 Subject: [PATCH 25/55] Interpret 'hide' setting as ALWAYS hiding from thread replies (#4263) --- src/components/moderation/PostHider.tsx | 5 ++++- src/view/com/post-thread/PostThread.tsx | 4 ++-- src/view/com/post-thread/PostThreadItem.tsx | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/moderation/PostHider.tsx b/src/components/moderation/PostHider.tsx index 177104f932..8a64742978 100644 --- a/src/components/moderation/PostHider.tsx +++ b/src/components/moderation/PostHider.tsx @@ -23,6 +23,7 @@ interface Props extends ComponentProps { iconStyles: StyleProp modui: ModerationUI profile: AppBskyActorDefs.ProfileViewBasic + interpretFilterAsBlur?: boolean } export function PostHider({ @@ -35,6 +36,7 @@ export function PostHider({ iconSize, iconStyles, profile, + interpretFilterAsBlur, ...props }: Props) { const queryClient = useQueryClient() @@ -42,7 +44,8 @@ export function PostHider({ const {_} = useLingui() const [override, setOverride] = React.useState(false) const control = useModerationDetailsDialogControl() - const blur = modui.blurs[0] + const blur = + modui.blurs[0] || (interpretFilterAsBlur ? modui.filters[0] : undefined) const desc = useModerationCauseDescription(blur) const onBeforePress = React.useCallback(() => { diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 1212f992da..64ff9cb0fd 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -543,9 +543,9 @@ function* flattenThreadReplies( // handle blurred items if (node.ctx.depth > 0) { const modui = modCache.get(node)?.ui('contentList') - if (modui?.blur) { + if (modui?.blur || modui?.filter) { if (!showHiddenReplies || node.ctx.depth > 1) { - if (modui.blurs[0].type === 'muted') { + if ((modui.blurs[0] || modui.filters[0]).type === 'muted') { return HiddenReplyType.Muted } return HiddenReplyType.Hidden diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 5451a67dd8..9d2985f155 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -430,7 +430,8 @@ let PostThreadItemLoaded = ({ ? {marginRight: 4} : {marginLeft: 2, marginRight: 2} } - profile={post.author}> + profile={post.author} + interpretFilterAsBlur> Date: Thu, 30 May 2024 07:36:07 +0300 Subject: [PATCH 26/55] scale down FAB on press (#4259) --- src/view/com/util/fab/FABInner.tsx | 50 ++++++++++++++++++------------ 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/view/com/util/fab/FABInner.tsx b/src/view/com/util/fab/FABInner.tsx index a01756da06..ccf2f31dbf 100644 --- a/src/view/com/util/fab/FABInner.tsx +++ b/src/view/com/util/fab/FABInner.tsx @@ -1,6 +1,6 @@ import React, {ComponentProps} from 'react' import {StyleSheet, TouchableWithoutFeedback} from 'react-native' -import Animated from 'react-native-reanimated' +import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {LinearGradient} from 'expo-linear-gradient' @@ -9,6 +9,7 @@ import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {clamp} from 'lib/numbers' import {gradients} from 'lib/styles' +import {useInteractionState} from '#/components/hooks/useInteractionState' export interface FABProps extends ComponentProps { @@ -20,21 +21,28 @@ export function FABInner({testID, icon, ...props}: FABProps) { const insets = useSafeAreaInsets() const {isMobile, isTablet} = useWebMediaQueries() const {fabMinimalShellTransform} = useMinimalShellMode() + const { + state: pressed, + onIn: onPressIn, + onOut: onPressOut, + } = useInteractionState() - const size = React.useMemo(() => { - return isTablet ? styles.sizeLarge : styles.sizeRegular - }, [isTablet]) - const tabletSpacing = React.useMemo(() => { - return isTablet - ? {right: 50, bottom: 50} - : { - right: 24, - bottom: clamp(insets.bottom, 15, 60) + 15, - } - }, [insets.bottom, isTablet]) + const size = isTablet ? styles.sizeLarge : styles.sizeRegular + + const tabletSpacing = isTablet + ? {right: 50, bottom: 50} + : {right: 24, bottom: clamp(insets.bottom, 15, 60) + 15} + + const scale = useAnimatedStyle(() => ({ + transform: [{scale: withTiming(pressed ? 0.95 : 1)}], + })) return ( - + - - {icon} - + + + {icon} + + ) From c4abaa1abcde54f15133b2e2b546f0d54a3a1d07 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 07:44:20 +0300 Subject: [PATCH 27/55] Use `` for Composer (#3588) * use to display composer * trigger `onPressCancel` on modal cancel * remove android top padding * use light statusbar on ios * use KeyboardStickyView from r-n-keyboard-controller * make extra bottom padding ios-only * make cancelRef optional * scope legacy modals * don't change bg color on ios * use fullScreen instead of formSheet * adjust padding on keyboardaccessory to account for new buttons * Revert "use KeyboardStickyView from r-n-keyboard-controller" This reverts commit 426c812904f427bdd08107cffc32e4be1d9b83bc. * fix insets * tweaks and merge * revert 89f51c72 * nit * import keyboard provider --------- Co-authored-by: Hailey Co-authored-by: Dan Abramov --- src/alf/util/useColorModeTheme.ts | 8 +- src/view/com/composer/Composer.tsx | 51 +++++----- src/view/com/composer/KeyboardAccessory.tsx | 34 +++++++ src/view/shell/Composer.tsx | 106 +++++++------------- 4 files changed, 101 insertions(+), 98 deletions(-) create mode 100644 src/view/com/composer/KeyboardAccessory.tsx diff --git a/src/alf/util/useColorModeTheme.ts b/src/alf/util/useColorModeTheme.ts index 4f8921bf9b..301c993dd4 100644 --- a/src/alf/util/useColorModeTheme.ts +++ b/src/alf/util/useColorModeTheme.ts @@ -1,11 +1,11 @@ import React from 'react' import {ColorSchemeName, useColorScheme} from 'react-native' - -import {useThemePrefs} from 'state/shell' -import {isWeb} from 'platform/detection' -import {ThemeName, light, dark, dim} from '#/alf/themes' import * as SystemUI from 'expo-system-ui' +import {isWeb} from 'platform/detection' +import {useThemePrefs} from 'state/shell' +import {dark, dim, light, ThemeName} from '#/alf/themes' + export function useColorModeTheme(): ThemeName { const colorScheme = useColorScheme() const {colorMode, darkTheme} = useThemePrefs() diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 12e57c411d..5746454c28 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -1,7 +1,13 @@ -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react' +import React, { + useCallback, + useEffect, + useImperativeHandle, + useMemo, + useRef, + useState, +} from 'react' import { ActivityIndicator, - BackHandler, Keyboard, ScrollView, StyleSheet, @@ -79,6 +85,10 @@ import {TextInput, TextInputRef} from './text-input/TextInput' import {ThreadgateBtn} from './threadgate/ThreadgateBtn' import {useExternalLinkFetch} from './useExternalLinkFetch' +type CancelRef = { + onPressCancel: () => void +} + type Props = ComposerOpts export const ComposePost = observer(function ComposePost({ replyTo, @@ -88,7 +98,10 @@ export const ComposePost = observer(function ComposePost({ openPicker, text: initText, imageUris: initImageUris, -}: Props) { + cancelRef, +}: Props & { + cancelRef?: React.RefObject +}) { const {currentAccount} = useSession() const agent = useAgent() const {data: currentProfile} = useProfileQuery({did: currentAccount!.did}) @@ -145,7 +158,7 @@ export const ComposePost = observer(function ComposePost({ () => ({ paddingBottom: isAndroid || (isIOS && !isKeyboardVisible) ? insets.bottom : 0, - paddingTop: isAndroid ? insets.top : isMobile ? 15 : 0, + paddingTop: isMobile && isWeb ? 15 : insets.top, }), [insets, isKeyboardVisible, isMobile], ) @@ -167,23 +180,8 @@ export const ComposePost = observer(function ComposePost({ discardPromptControl, onClose, ]) - // android back button - useEffect(() => { - if (!isAndroid) { - return - } - const backHandler = BackHandler.addEventListener( - 'hardwareBackPress', - () => { - onPressCancel() - return true - }, - ) - return () => { - backHandler.remove() - } - }, [onPressCancel]) + useImperativeHandle(cancelRef, () => ({onPressCancel})) // listen to escape key on desktop web const onEscape = useCallback( @@ -583,19 +581,18 @@ export const ComposePost = observer(function ComposePost({ ) }) +export function useComposerCancelRef() { + return useRef(null) +} + const styles = StyleSheet.create({ - outer: { - flexDirection: 'column', - flex: 1, - height: '100%', - }, topbar: { flexDirection: 'row', alignItems: 'center', - paddingTop: 6, + marginTop: -14, paddingBottom: 4, paddingHorizontal: 20, - height: 55, + height: 50, gap: 4, }, topbarDesktop: { diff --git a/src/view/com/composer/KeyboardAccessory.tsx b/src/view/com/composer/KeyboardAccessory.tsx new file mode 100644 index 0000000000..983a87dae9 --- /dev/null +++ b/src/view/com/composer/KeyboardAccessory.tsx @@ -0,0 +1,34 @@ +import React from 'react' +import {View} from 'react-native' +import {KeyboardStickyView} from 'react-native-keyboard-controller' +import {useSafeAreaInsets} from 'react-native-safe-area-context' + +import {isWeb} from '#/platform/detection' +import {atoms as a, useTheme} from '#/alf' + +export function KeyboardAccessory({children}: {children: React.ReactNode}) { + const t = useTheme() + const {bottom} = useSafeAreaInsets() + + const style = [ + a.flex_row, + a.py_xs, + a.pl_sm, + a.pr_xl, + a.align_center, + a.border_t, + t.atoms.border_contrast_medium, + t.atoms.bg, + ] + + // todo: when iPad support is added, it should also not use the KeyboardStickyView + if (isWeb) { + return {children} + } + + return ( + + {children} + + ) +} diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx index 1937fcb6ea..17348a30ca 100644 --- a/src/view/shell/Composer.tsx +++ b/src/view/shell/Composer.tsx @@ -1,77 +1,49 @@ -import React, {useEffect} from 'react' +import React from 'react' +import {Modal, View} from 'react-native' import {observer} from 'mobx-react-lite' -import {Animated, Easing, Platform, StyleSheet, View} from 'react-native' -import {ComposePost} from '../com/composer/Composer' -import {useComposerState} from 'state/shell/composer' -import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' -import {usePalette} from 'lib/hooks/usePalette' -export const Composer = observer(function ComposerImpl({ - winHeight, -}: { +import {Provider as LegacyModalProvider} from '#/state/modals' +import {useComposerState} from 'state/shell/composer' +import {ModalsContainer as LegacyModalsContainer} from '#/view/com/modals/Modal' +import {useTheme} from '#/alf' +import { + Outlet as PortalOutlet, + Provider as PortalProvider, +} from '#/components/Portal' +import {ComposePost, useComposerCancelRef} from '../com/composer/Composer' + +export const Composer = observer(function ComposerImpl({}: { winHeight: number }) { + const t = useTheme() const state = useComposerState() - const pal = usePalette('default') - const initInterp = useAnimatedValue(0) - - useEffect(() => { - if (state) { - Animated.timing(initInterp, { - toValue: 1, - duration: 300, - easing: Easing.out(Easing.exp), - useNativeDriver: true, - }).start() - } else { - initInterp.setValue(0) - } - }, [initInterp, state]) - const wrapperAnimStyle = { - transform: [ - { - translateY: initInterp.interpolate({ - inputRange: [0, 1], - outputRange: [winHeight, 0], - }), - }, - ], - } - - // rendering - // = - - if (!state) { - return - } + const ref = useComposerCancelRef() return ( - - - + accessibilityViewIsModal + visible={!!state} + presentationStyle="overFullScreen" + animationType="slide" + onRequestClose={() => ref.current?.onPressCancel()}> + + + + + + + + + + ) }) - -const styles = StyleSheet.create({ - wrapper: { - position: 'absolute', - top: 0, - bottom: 0, - width: '100%', - ...Platform.select({ - ios: { - paddingTop: 24, - }, - }), - }, -}) From d92036f2c576d33964b1141ac63888bdc2fb1ca4 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 09:44:49 +0300 Subject: [PATCH 28/55] Post controls update followup (#4276) * rm legacy repost modal * make repost button transparent * reduce gap between post and ctrls * remove old repost modal on web --- src/alf/atoms.ts | 7 + src/components/Button.tsx | 2 +- src/state/modals/index.tsx | 8 -- src/view/com/modals/Modal.tsx | 4 - src/view/com/modals/Modal.web.tsx | 3 - src/view/com/modals/Repost.tsx | 129 ------------------ src/view/com/posts/FeedItem.tsx | 4 +- src/view/com/util/post-ctrls/RepostButton.tsx | 8 +- 8 files changed, 17 insertions(+), 148 deletions(-) delete mode 100644 src/view/com/modals/Repost.tsx diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index 158bb6ec5b..eb130f3ae9 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -55,6 +55,13 @@ export const atoms = { height: '100vh', }), + /* + * Theme-independent bg colors + */ + bg_transparent: { + backgroundColor: 'transparent', + }, + /* * Border radius */ diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 3db8033997..c543cbba5f 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -376,10 +376,10 @@ export function Button({ a.align_center, a.justify_center, flattenedBaseStyles, + flatten(style), ...(state.hovered || state.pressed ? [hoverStyles, flatten(hoverStyleProp)] : []), - flatten(style), ]} onPressIn={onPressIn} onPressOut={onPressOut} diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index cf82bcd075..f8a64dc2d3 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -60,13 +60,6 @@ export interface DeleteAccountModal { name: 'delete-account' } -export interface RepostModal { - name: 'repost' - onRepost: () => void - onQuote: () => void - isReposted: boolean -} - export interface SelfLabelModal { name: 'self-label' labels: string[] @@ -154,7 +147,6 @@ export type Modal = | AltTextImageModal | CropImageModal | EditImageModal - | RepostModal | SelfLabelModal | ThreadgateModal diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index d82975b5e8..3491b94e34 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -22,7 +22,6 @@ import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguages import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' import * as LinkWarningModal from './LinkWarning' import * as ListAddUserModal from './ListAddRemoveUsers' -import * as RepostModal from './Repost' import * as SelfLabelModal from './SelfLabel' import * as ThreadgateModal from './Threadgate' import * as UserAddRemoveListsModal from './UserAddRemoveLists' @@ -74,9 +73,6 @@ export function ModalsContainer() { } else if (activeModal?.name === 'delete-account') { snapPoints = DeleteAccountModal.snapPoints element = - } else if (activeModal?.name === 'repost') { - snapPoints = RepostModal.snapPoints - element = } else if (activeModal?.name === 'self-label') { snapPoints = SelfLabelModal.snapPoints element = diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index f95c748111..14ee99e576 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -22,7 +22,6 @@ import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguages import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' import * as LinkWarningModal from './LinkWarning' import * as ListAddUserModal from './ListAddRemoveUsers' -import * as RepostModal from './Repost' import * as SelfLabelModal from './SelfLabel' import * as ThreadgateModal from './Threadgate' import * as UserAddRemoveLists from './UserAddRemoveLists' @@ -83,8 +82,6 @@ function Modal({modal}: {modal: ModalIface}) { element = } else if (modal.name === 'delete-account') { element = - } else if (modal.name === 'repost') { - element = } else if (modal.name === 'self-label') { element = } else if (modal.name === 'threadgate') { diff --git a/src/view/com/modals/Repost.tsx b/src/view/com/modals/Repost.tsx deleted file mode 100644 index 5dedee832b..0000000000 --- a/src/view/com/modals/Repost.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React from 'react' -import {StyleSheet, TouchableOpacity, View} from 'react-native' -import {LinearGradient} from 'expo-linear-gradient' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useModalControls} from '#/state/modals' -import {usePalette} from 'lib/hooks/usePalette' -import {RepostIcon} from 'lib/icons' -import {colors, gradients, s} from 'lib/styles' -import {Text} from '../util/text/Text' - -export const snapPoints = [250] - -export function Component({ - onRepost, - onQuote, - isReposted, -}: { - onRepost: () => void - onQuote: () => void - isReposted: boolean - // TODO: Add author into component -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {closeModal} = useModalControls() - const onPress = async () => { - closeModal() - } - - return ( - - - - - - {!isReposted ? ( - Repost - ) : ( - Undo repost - )} - - - - - - Quote Post - - - - - - - Cancel - - - - - ) -} - -const styles = StyleSheet.create({ - container: { - paddingHorizontal: 30, - }, - title: { - textAlign: 'center', - fontWeight: 'bold', - fontSize: 24, - marginBottom: 12, - }, - description: { - textAlign: 'center', - fontSize: 17, - paddingHorizontal: 22, - marginBottom: 10, - }, - btn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - width: '100%', - borderRadius: 32, - padding: 14, - backgroundColor: colors.gray1, - }, - actionBtn: { - flexDirection: 'row', - alignItems: 'center', - }, - actionBtnLabel: { - paddingHorizontal: 14, - paddingVertical: 16, - }, -}) diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 70f63427dc..8077c29683 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -390,7 +390,7 @@ let PostContent = ({ /> ) : undefined} {postEmbed ? ( - + { requireAuth(() => dialogControl.open()) }} - style={[a.flex_row, a.align_center, a.gap_xs, {padding: 5}]} + style={[ + a.flex_row, + a.align_center, + a.gap_xs, + a.bg_transparent, + {padding: 5}, + ]} hoverStyle={t.atoms.bg_contrast_25} label={`${ isReposted From cd497a3974ad1ee2266cb5d220c4406614adc2f9 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 10:45:35 +0300 Subject: [PATCH 29/55] only show divider when scrolled (#4275) --- src/view/com/composer/Composer.tsx | 61 +++++++++++++++++----- src/view/com/composer/labels/LabelsBtn.tsx | 12 +++-- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 5746454c28..00dbcb591e 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -9,7 +9,6 @@ import React, { import { ActivityIndicator, Keyboard, - ScrollView, StyleSheet, TouchableOpacity, View, @@ -18,6 +17,12 @@ import { KeyboardAvoidingView, KeyboardStickyView, } from 'react-native-keyboard-controller' +import Animated, { + interpolateColor, + useAnimatedStyle, + useSharedValue, + withTiming, +} from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {LinearGradient} from 'expo-linear-gradient' import {RichText} from '@atproto/api' @@ -30,6 +35,7 @@ import { createGIFDescription, parseAltFromGIFDescription, } from '#/lib/gif-alt-text' +import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED' import {LikelyType} from '#/lib/link-meta/link-meta' import {logEvent} from '#/lib/statsig/statsig' import {logger} from '#/logger' @@ -61,7 +67,7 @@ import {useDialogStateControlContext} from 'state/dialogs' import {GalleryModel} from 'state/models/media/gallery' import {ComposerOpts} from 'state/shell/composer' import {ComposerReplyTo} from 'view/com/composer/ComposerReplyTo' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' import {Button} from '#/components/Button' import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji' import * as Prompt from '#/components/Prompt' @@ -109,7 +115,7 @@ export const ComposePost = observer(function ComposePost({ const {closeComposer} = useComposerControls() const {track} = useAnalytics() const pal = usePalette('default') - const {isDesktop, isMobile} = useWebMediaQueries() + const {isTabletOrDesktop, isMobile} = useWebMediaQueries() const {_} = useLingui() const requireAltTextEnabled = useRequireAltTextEnabled() const langPrefs = useLanguagePrefs() @@ -117,6 +123,7 @@ export const ComposePost = observer(function ComposePost({ const textInput = useRef(null) const discardPromptControl = Prompt.usePromptControl() const {closeAllDialogs} = useDialogStateControlContext() + const t = useTheme() const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true}) const [isProcessing, setIsProcessing] = useState(false) @@ -163,6 +170,25 @@ export const ComposePost = observer(function ComposePost({ [insets, isKeyboardVisible, isMobile], ) + const hasScrolled = useSharedValue(0) + const scrollHandler = useAnimatedScrollHandler({ + onScroll: event => { + hasScrolled.value = withTiming(event.contentOffset.y > 0 ? 1 : 0) + }, + }) + const topBarAnimatedStyle = useAnimatedStyle(() => { + return { + borderColor: interpolateColor( + hasScrolled.value, + [0, 1], + [ + 'transparent', + isWeb ? t.palette.contrast_100 : t.palette.contrast_400, + ], + ), + } + }) + const onPressCancel = useCallback(() => { if (graphemeLength > 0 || !gallery.isEmpty) { closeAllDialogs() @@ -380,7 +406,12 @@ export const ComposePost = observer(function ComposePost({ style={s.flex1} keyboardVerticalOffset={replyTo ? 60 : isAndroid ? 120 : 100}> - + )} - + {isAltTextRequiredAndMissing && ( @@ -471,14 +502,14 @@ export const ComposePost = observer(function ComposePost({ {error} )} - {replyTo ? : undefined} @@ -533,7 +564,7 @@ export const ComposePost = observer(function ComposePost({ )} ) : undefined} - + @@ -589,15 +620,18 @@ const styles = StyleSheet.create({ topbar: { flexDirection: 'row', alignItems: 'center', - marginTop: -14, - paddingBottom: 4, - paddingHorizontal: 20, - height: 50, + marginTop: -10, + paddingHorizontal: 4, + marginHorizontal: 16, + height: 44, gap: 4, + borderBottomWidth: StyleSheet.hairlineWidth, }, topbarDesktop: { paddingTop: 10, paddingBottom: 10, + height: 50, + marginTop: 0, }, postBtn: { borderRadius: 20, @@ -636,11 +670,10 @@ const styles = StyleSheet.create({ }, scrollView: { flex: 1, - paddingHorizontal: 15, + paddingHorizontal: 16, }, textInputLayout: { flexDirection: 'row', - borderTopWidth: 1, paddingTop: 16, }, textInputLayoutMobile: { diff --git a/src/view/com/composer/labels/LabelsBtn.tsx b/src/view/com/composer/labels/LabelsBtn.tsx index b880dd3306..27e3813dc2 100644 --- a/src/view/com/composer/labels/LabelsBtn.tsx +++ b/src/view/com/composer/labels/LabelsBtn.tsx @@ -1,14 +1,15 @@ import React from 'react' import {Keyboard, StyleSheet} from 'react-native' -import {Button} from 'view/com/util/forms/Button' -import {usePalette} from 'lib/hooks/usePalette' -import {ShieldExclamation} from 'lib/icons' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIconStyle} from '@fortawesome/react-native-fontawesome' -import {isNative} from 'platform/detection' -import {useLingui} from '@lingui/react' import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + import {useModalControls} from '#/state/modals' +import {usePalette} from 'lib/hooks/usePalette' +import {ShieldExclamation} from 'lib/icons' +import {isNative} from 'platform/detection' +import {Button} from 'view/com/util/forms/Button' export function LabelsBtn({ labels, @@ -54,6 +55,7 @@ const styles = StyleSheet.create({ button: { flexDirection: 'row', alignItems: 'center', + paddingVertical: 2, paddingHorizontal: 6, }, dimmed: { From a72f55a11fcc45440314d30656c9d563181a0001 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 14:34:30 +0300 Subject: [PATCH 30/55] Composer - fix divider when replying to someone (#4279) * move replyto border to beneath * use hairline width for consistency * fix border colors --- src/view/com/composer/Composer.tsx | 4 +++- src/view/com/composer/ComposerReplyTo.tsx | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 00dbcb591e..4911adf2c4 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -183,7 +183,9 @@ export const ComposePost = observer(function ComposePost({ [0, 1], [ 'transparent', - isWeb ? t.palette.contrast_100 : t.palette.contrast_400, + isWeb + ? t.atoms.border_contrast_low.borderColor + : t.atoms.border_contrast_high.borderColor, ], ), } diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 7dc17fd4a7..1bb4a5c21f 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -10,16 +10,17 @@ import { import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from 'lib/hooks/usePalette' +import {isWeb} from '#/platform/detection' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {ComposerOptsPostRef} from 'state/shell/composer' import {QuoteEmbed} from 'view/com/util/post-embeds/QuoteEmbed' import {Text} from 'view/com/util/text/Text' import {PreviewableUserAvatar} from 'view/com/util/UserAvatar' +import {useTheme} from '#/alf' export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { - const pal = usePalette('default') + const t = useTheme() const {_} = useLingui() const {embed} = replyTo @@ -75,7 +76,10 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { return ( - + {sanitizeDisplayName( replyTo.author.displayName || sanitizeHandle(replyTo.author.handle), )} @@ -100,7 +104,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { {replyTo.text} @@ -218,7 +222,7 @@ const styles = StyleSheet.create({ replyToLayout: { flexDirection: 'row', alignItems: 'flex-start', - borderTopWidth: 1, + borderBottomWidth: StyleSheet.hairlineWidth, paddingTop: 16, paddingBottom: 16, }, From 13c08f56ba372c5c7f631c9771a215b82979eb20 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 14:35:38 +0300 Subject: [PATCH 31/55] Fix native translations on iOS 17.5.1 (#4282) * enable translations on iOS 17.5.1 * add comment --- .../src/ExpoBlueskyTranslateView.ios.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx index daddfa0286..290fabd30d 100644 --- a/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx +++ b/modules/expo-bluesky-translate/src/ExpoBlueskyTranslateView.ios.tsx @@ -15,7 +15,10 @@ export function NativeTranslationView() { return } -export const isAvailable = Number(Platform.Version) >= 17.4 +// can be something like "17.5.1", so just take the first two parts +const version = String(Platform.Version).split('.').slice(0, 2).join('.') + +export const isAvailable = Number(version) >= 17.4 // https://en.wikipedia.org/wiki/Translate_(Apple)#Languages const SUPPORTED_LANGUAGES = [ From 76f860dad2c55b17fcbd4caf4d4a9297261b64e3 Mon Sep 17 00:00:00 2001 From: Hailey Date: Thu, 30 May 2024 04:36:40 -0700 Subject: [PATCH 32/55] don't maintain position whenever there are no parents (#4277) --- src/view/com/post-thread/PostThread.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 64ff9cb0fd..35028334c6 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -440,7 +440,9 @@ export function PostThread({ onEndReachedThreshold={2} onScrollToTop={onScrollToTop} maintainVisibleContentPosition={ - isNative ? MAINTAIN_VISIBLE_CONTENT_POSITION : undefined + isNative && hasParents + ? MAINTAIN_VISIBLE_CONTENT_POSITION + : undefined } // @ts-ignore our .web version only -prf desktopFixedHeight From 3bdceac2fb0a835d1709ad4558c9dcc2dfee6f25 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 14:39:36 +0300 Subject: [PATCH 33/55] Composer - Use sheet presentation on iOS (#4278) * use sheet presentation + tweak spacing * line up elements + add hitslop to cancel * fixing spacing on replies --- src/alf/util/useColorModeTheme.ts | 24 +++++++------- src/view/com/composer/Composer.tsx | 15 ++++----- src/view/com/composer/ComposerReplyTo.tsx | 3 +- src/view/shell/Composer.tsx | 38 +++++++++++++++++++---- 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/alf/util/useColorModeTheme.ts b/src/alf/util/useColorModeTheme.ts index 301c993dd4..ce15587478 100644 --- a/src/alf/util/useColorModeTheme.ts +++ b/src/alf/util/useColorModeTheme.ts @@ -7,19 +7,21 @@ import {useThemePrefs} from 'state/shell' import {dark, dim, light, ThemeName} from '#/alf/themes' export function useColorModeTheme(): ThemeName { + const theme = useThemeName() + + React.useLayoutEffect(() => { + updateDocument(theme) + SystemUI.setBackgroundColorAsync(getBackgroundColor(theme)) + }, [theme]) + + return theme +} + +export function useThemeName(): ThemeName { const colorScheme = useColorScheme() const {colorMode, darkTheme} = useThemePrefs() - React.useLayoutEffect(() => { - const theme = getThemeName(colorScheme, colorMode, darkTheme) - updateDocument(theme) - SystemUI.setBackgroundColorAsync(getBackgroundColor(theme)) - }, [colorMode, colorScheme, darkTheme]) - - return React.useMemo( - () => getThemeName(colorScheme, colorMode, darkTheme), - [colorScheme, colorMode, darkTheme], - ) + return getThemeName(colorScheme, colorMode, darkTheme) } function getThemeName( @@ -53,7 +55,7 @@ function updateDocument(theme: ThemeName) { } } -function getBackgroundColor(theme: ThemeName): string { +export function getBackgroundColor(theme: ThemeName): string { switch (theme) { case 'light': return light.atoms.bg.backgroundColor diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 4911adf2c4..2618c51a3d 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -54,7 +54,7 @@ import {useAgent, useSession} from '#/state/session' import {useComposerControls} from '#/state/shell/composer' import {useAnalytics} from 'lib/analytics/analytics' import * as apilib from 'lib/api/index' -import {MAX_GRAPHEME_LENGTH} from 'lib/constants' +import {HITSLOP_10, MAX_GRAPHEME_LENGTH} from 'lib/constants' import {useIsKeyboardVisible} from 'lib/hooks/useIsKeyboardVisible' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' @@ -165,9 +165,8 @@ export const ComposePost = observer(function ComposePost({ () => ({ paddingBottom: isAndroid || (isIOS && !isKeyboardVisible) ? insets.bottom : 0, - paddingTop: isMobile && isWeb ? 15 : insets.top, }), - [insets, isKeyboardVisible, isMobile], + [insets, isKeyboardVisible], ) const hasScrolled = useSharedValue(0) @@ -422,7 +421,8 @@ export const ComposePost = observer(function ComposePost({ accessibilityLabel={_(msg`Cancel`)} accessibilityHint={_( msg`Closes post composer and discards post draft`, - )}> + )} + hitSlop={HITSLOP_10}> Cancel @@ -622,10 +622,8 @@ const styles = StyleSheet.create({ topbar: { flexDirection: 'row', alignItems: 'center', - marginTop: -10, - paddingHorizontal: 4, marginHorizontal: 16, - height: 44, + height: 54, gap: 4, borderBottomWidth: StyleSheet.hairlineWidth, }, @@ -633,7 +631,6 @@ const styles = StyleSheet.create({ paddingTop: 10, paddingBottom: 10, height: 50, - marginTop: 0, }, postBtn: { borderRadius: 20, @@ -676,7 +673,7 @@ const styles = StyleSheet.create({ }, textInputLayout: { flexDirection: 'row', - paddingTop: 16, + paddingTop: 4, }, textInputLayoutMobile: { flex: 1, diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 1bb4a5c21f..902d60a460 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -223,8 +223,9 @@ const styles = StyleSheet.create({ flexDirection: 'row', alignItems: 'flex-start', borderBottomWidth: StyleSheet.hairlineWidth, - paddingTop: 16, + paddingTop: 4, paddingBottom: 16, + marginBottom: 12, }, replyToPost: { flex: 1, diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx index 17348a30ca..ce53ffc01d 100644 --- a/src/view/shell/Composer.tsx +++ b/src/view/shell/Composer.tsx @@ -1,11 +1,15 @@ -import React from 'react' +import React, {useLayoutEffect} from 'react' import {Modal, View} from 'react-native' +import {StatusBar} from 'expo-status-bar' +import * as SystemUI from 'expo-system-ui' import {observer} from 'mobx-react-lite' +import {isIOS} from '#/platform/detection' import {Provider as LegacyModalProvider} from '#/state/modals' -import {useComposerState} from 'state/shell/composer' +import {useComposerState} from '#/state/shell/composer' import {ModalsContainer as LegacyModalsContainer} from '#/view/com/modals/Modal' -import {useTheme} from '#/alf' +import {atoms as a, useTheme} from '#/alf' +import {getBackgroundColor, useThemeName} from '#/alf/util/useColorModeTheme' import { Outlet as PortalOutlet, Provider as PortalProvider, @@ -19,15 +23,17 @@ export const Composer = observer(function ComposerImpl({}: { const state = useComposerState() const ref = useComposerCancelRef() + const open = !!state + return ( ref.current?.onPressCancel()}> - + + {isIOS && } ) }) + +// Generally, the backdrop of the app is the theme color, but when this is open +// we want it to be black due to the modal being a form sheet. +function IOSModalBackground({active}: {active: boolean}) { + const theme = useThemeName() + + useLayoutEffect(() => { + SystemUI.setBackgroundColorAsync('black') + + return () => { + SystemUI.setBackgroundColorAsync(getBackgroundColor(theme)) + } + }, [theme]) + + // Set the status bar to light - however, only if the modal is active + // If we rely on this component being mounted to set this, + // there'll be a delay before it switches back to default. + return active ? : null +} From b077cbe399c32907e40d790e988a94ada47779a7 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 14:40:22 +0300 Subject: [PATCH 34/55] match loadmore position to fab (#4280) --- src/view/com/util/fab/FABInner.tsx | 8 +++--- .../com/util/load-latest/LoadLatestBtn.tsx | 27 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/view/com/util/fab/FABInner.tsx b/src/view/com/util/fab/FABInner.tsx index ccf2f31dbf..c9443127b8 100644 --- a/src/view/com/util/fab/FABInner.tsx +++ b/src/view/com/util/fab/FABInner.tsx @@ -4,11 +4,11 @@ import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated' import {useSafeAreaInsets} from 'react-native-safe-area-context' import {LinearGradient} from 'expo-linear-gradient' +import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' +import {clamp} from '#/lib/numbers' +import {gradients} from '#/lib/styles' import {isWeb} from '#/platform/detection' -import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {clamp} from 'lib/numbers' -import {gradients} from 'lib/styles' import {useInteractionState} from '#/components/hooks/useInteractionState' export interface FABProps diff --git a/src/view/com/util/load-latest/LoadLatestBtn.tsx b/src/view/com/util/load-latest/LoadLatestBtn.tsx index f02e4a2bd7..7e85e670f4 100644 --- a/src/view/com/util/load-latest/LoadLatestBtn.tsx +++ b/src/view/com/util/load-latest/LoadLatestBtn.tsx @@ -1,17 +1,21 @@ import React from 'react' import {StyleSheet, TouchableOpacity, View} from 'react-native' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import Animated from 'react-native-reanimated' +import {useSafeAreaInsets} from 'react-native-safe-area-context' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {useMediaQuery} from 'react-responsive' -import {usePalette} from 'lib/hooks/usePalette' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {colors} from 'lib/styles' -import {HITSLOP_20} from 'lib/constants' -import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' + +import {HITSLOP_20} from '#/lib/constants' +import {useMinimalShellMode} from '#/lib/hooks/useMinimalShellMode' +import {usePalette} from '#/lib/hooks/usePalette' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' +import {clamp} from '#/lib/numbers' +import {colors} from '#/lib/styles' +import {isWeb} from '#/platform/detection' +import {useSession} from '#/state/session' + const AnimatedTouchableOpacity = Animated.createAnimatedComponent(TouchableOpacity) -import {isWeb} from 'platform/detection' -import {useSession} from 'state/session' export function LoadLatestBtn({ onPress, @@ -26,6 +30,7 @@ export function LoadLatestBtn({ const {hasSession} = useSession() const {isDesktop, isTablet, isMobile, isTabletOrMobile} = useWebMediaQueries() const {fabMinimalShellTransform} = useMinimalShellMode() + const insets = useSafeAreaInsets() // move button inline if it starts overlapping the left nav const isTallViewport = useMediaQuery({minHeight: 700}) @@ -34,6 +39,10 @@ export function LoadLatestBtn({ // it on both tablet and mobile since we are showing the bottom bar (see createNativeStackNavigatorWithAuth) const showBottomBar = hasSession ? isMobile : isTabletOrMobile + const bottomPosition = isTablet + ? {bottom: 50} + : {bottom: clamp(insets.bottom, 15, 60) + 15} + return ( Date: Thu, 30 May 2024 15:46:26 +0300 Subject: [PATCH 35/55] play haptics before closing modal (#4283) --- src/view/com/util/post-ctrls/PostCtrls.tsx | 10 ---------- src/view/com/util/post-ctrls/RepostButton.tsx | 10 ++++++++-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index c90a723a0b..d42590e905 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -23,7 +23,6 @@ import {toShareUrl} from '#/lib/strings/url-helpers' import {s} from '#/lib/styles' import {Shadow} from '#/state/cache/types' import {useFeedFeedbackContext} from '#/state/feed-feedback' -import {useModalControls} from '#/state/modals' import { usePostLikeMutationQueue, usePostRepostMutationQueue, @@ -65,7 +64,6 @@ let PostCtrls = ({ const t = useTheme() const {_} = useLingui() const {openComposer} = useComposerControls() - const {closeModal} = useModalControls() const [queueLike, queueUnlike] = usePostLikeMutationQueue(post, logContext) const [queueRepost, queueUnrepost] = usePostRepostMutationQueue( post, @@ -118,10 +116,8 @@ let PostCtrls = ({ ]) const onRepost = useCallback(async () => { - closeModal() try { if (!post.viewer?.repost) { - playHaptic() sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#interactionRepost', @@ -137,10 +133,8 @@ let PostCtrls = ({ } } }, [ - closeModal, post.uri, post.viewer?.repost, - playHaptic, queueRepost, queueUnrepost, sendInteraction, @@ -148,7 +142,6 @@ let PostCtrls = ({ ]) const onQuote = useCallback(() => { - closeModal() sendInteraction({ item: post.uri, event: 'app.bsky.feed.defs#interactionQuote', @@ -163,16 +156,13 @@ let PostCtrls = ({ indexedAt: post.indexedAt, }, }) - playHaptic() }, [ - closeModal, openComposer, post.uri, post.cid, post.author, post.indexedAt, record.text, - playHaptic, sendInteraction, feedContext, ]) diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx index ebf3357f31..b1fe73d5b3 100644 --- a/src/view/com/util/post-ctrls/RepostButton.tsx +++ b/src/view/com/util/post-ctrls/RepostButton.tsx @@ -3,6 +3,7 @@ import {View} from 'react-native' import {msg, plural} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useHaptics} from '#/lib/haptics' import {useRequireAuth} from '#/state/session' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' @@ -30,6 +31,7 @@ let RepostButton = ({ const {_} = useLingui() const requireAuth = useRequireAuth() const dialogControl = Dialog.useDialogControl() + const playHaptic = useHaptics() const color = React.useMemo( () => ({ @@ -89,8 +91,11 @@ let RepostButton = ({ : _(msg({message: `Repost`, context: 'action'})) } onPress={() => { - dialogControl.close() - onRepost() + if (!isReposted) playHaptic() + + dialogControl.close(() => { + onRepost() + }) }} size="large" variant="ghost" @@ -106,6 +111,7 @@ let RepostButton = ({ style={[a.justify_start, a.px_md]} label={_(msg`Quote post`)} onPress={() => { + playHaptic() dialogControl.close(() => { onQuote() }) From 8feb2ab449fb31c1a5a6bd25dea8c01f97fa5231 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Thu, 30 May 2024 16:06:59 +0300 Subject: [PATCH 36/55] put dropdown in fullscreenoverlay on iOS (#4284) --- .../select-language/SelectLangBtn.tsx | 27 +++++++++-------- src/view/com/util/forms/DropdownButton.tsx | 30 ++++++++++++------- src/view/shell/Composer.web.tsx | 7 +++-- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/view/com/composer/select-language/SelectLangBtn.tsx b/src/view/com/composer/select-language/SelectLangBtn.tsx index 7856222259..7a086789ac 100644 --- a/src/view/com/composer/select-language/SelectLangBtn.tsx +++ b/src/view/com/composer/select-language/SelectLangBtn.tsx @@ -1,27 +1,28 @@ import React, {useCallback, useMemo} from 'react' -import {StyleSheet, Keyboard} from 'react-native' +import {Keyboard, StyleSheet} from 'react-native' import { FontAwesomeIcon, FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {Text} from 'view/com/util/text/Text' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useModalControls} from '#/state/modals' +import { + hasPostLanguage, + toPostLanguages, + useLanguagePrefs, + useLanguagePrefsApi, +} from '#/state/preferences/languages' +import {usePalette} from 'lib/hooks/usePalette' +import {isNative} from 'platform/detection' import { DropdownButton, DropdownItem, DropdownItemButton, } from 'view/com/util/forms/DropdownButton' -import {usePalette} from 'lib/hooks/usePalette' -import {isNative} from 'platform/detection' +import {Text} from 'view/com/util/text/Text' import {codeToLanguageName} from '../../../../locale/helpers' -import {useModalControls} from '#/state/modals' -import { - useLanguagePrefs, - useLanguagePrefsApi, - toPostLanguages, - hasPostLanguage, -} from '#/state/preferences/languages' -import {msg} from '@lingui/macro' -import {useLingui} from '@lingui/react' export function SelectLangBtn() { const pal = usePalette('default') diff --git a/src/view/com/util/forms/DropdownButton.tsx b/src/view/com/util/forms/DropdownButton.tsx index 2285b0615a..14b97161da 100644 --- a/src/view/com/util/forms/DropdownButton.tsx +++ b/src/view/com/util/forms/DropdownButton.tsx @@ -2,6 +2,7 @@ import React, {PropsWithChildren, useMemo, useRef} from 'react' import { Dimensions, GestureResponderEvent, + Platform, StyleProp, StyleSheet, TouchableOpacity, @@ -10,18 +11,20 @@ import { View, ViewStyle, } from 'react-native' -import {IconProp} from '@fortawesome/fontawesome-svg-core' import RootSiblings from 'react-native-root-siblings' +import {FullWindowOverlay} from 'react-native-screens' +import {IconProp} from '@fortawesome/fontawesome-svg-core' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {HITSLOP_10} from 'lib/constants' +import {usePalette} from 'lib/hooks/usePalette' +import {colors} from 'lib/styles' +import {useTheme} from 'lib/ThemeContext' +import {isWeb} from 'platform/detection' import {Text} from '../text/Text' import {Button, ButtonType} from './Button' -import {colors} from 'lib/styles' -import {usePalette} from 'lib/hooks/usePalette' -import {useTheme} from 'lib/ThemeContext' -import {HITSLOP_10} from 'lib/constants' -import {useLingui} from '@lingui/react' -import {msg} from '@lingui/macro' -import {isWeb} from 'platform/detection' const ESTIMATED_BTN_HEIGHT = 50 const ESTIMATED_SEP_HEIGHT = 16 @@ -239,7 +242,7 @@ const DropdownItems = ({ // - (On mobile) be buttons by default, accept `label` and `nativeID` // props, and always have an explicit label return ( - <> + {/* This TouchableWithoutFeedback renders the background so if the user clicks outside, the dropdown closes */} - + ) } +// on iOS, due to formSheet presentation style, we need to render the overlay +// as a full screen overlay +const Wrapper = Platform.select({ + ios: FullWindowOverlay, + default: ({children}) => <>{children}, +}) + function isSep(item: DropdownItem): item is DropdownItemSeparator { return 'sep' in item && item.sep } diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx index 00233f66af..c9c604f114 100644 --- a/src/view/shell/Composer.web.tsx +++ b/src/view/shell/Composer.web.tsx @@ -1,15 +1,16 @@ import React from 'react' import {StyleSheet, View} from 'react-native' import Animated, {FadeIn, FadeInDown, FadeOut} from 'react-native-reanimated' -import {ComposePost} from '../com/composer/Composer' -import {useComposerState} from 'state/shell/composer' + +import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' +import {useComposerState} from 'state/shell/composer' import { EmojiPicker, EmojiPickerState, } from 'view/com/composer/text-input/web/EmojiPicker.web' +import {ComposePost} from '../com/composer/Composer' const BOTTOM_BAR_HEIGHT = 61 From 8de028387c939999708e521203541fceea5543d4 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 30 May 2024 15:57:03 +0100 Subject: [PATCH 37/55] Reduce Threadgate button size (#4287) --- src/components/Button.tsx | 6 +++++- src/view/com/composer/threadgate/ThreadgateBtn.tsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index c543cbba5f..e22faa060c 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -28,7 +28,7 @@ export type ButtonColor = | 'gradient_sunset' | 'gradient_nordic' | 'gradient_bonfire' -export type ButtonSize = 'tiny' | 'small' | 'medium' | 'large' +export type ButtonSize = 'tiny' | 'xsmall' | 'small' | 'medium' | 'large' export type ButtonShape = 'round' | 'square' | 'default' export type VariantProps = { /** @@ -283,6 +283,8 @@ export function Button({ baseStyles.push({paddingVertical: 12}, a.px_2xl, a.rounded_sm, a.gap_md) } else if (size === 'small') { baseStyles.push({paddingVertical: 9}, a.px_lg, a.rounded_sm, a.gap_sm) + } else if (size === 'xsmall') { + baseStyles.push({paddingVertical: 6}, a.px_sm, a.rounded_sm, a.gap_sm) } else if (size === 'tiny') { baseStyles.push({paddingVertical: 4}, a.px_sm, a.rounded_xs, a.gap_xs) } @@ -295,6 +297,8 @@ export function Button({ } } else if (size === 'small') { baseStyles.push({height: 34, width: 34}) + } else if (size === 'xsmall') { + baseStyles.push({height: 28, width: 28}) } else if (size === 'tiny') { baseStyles.push({height: 20, width: 20}) } diff --git a/src/view/com/composer/threadgate/ThreadgateBtn.tsx b/src/view/com/composer/threadgate/ThreadgateBtn.tsx index c43f00676b..df2a31e2b9 100644 --- a/src/view/com/composer/threadgate/ThreadgateBtn.tsx +++ b/src/view/com/composer/threadgate/ThreadgateBtn.tsx @@ -49,7 +49,7 @@ export function ThreadgateBtn({ + )} + + ) : ( + children + ) +} diff --git a/src/view/com/posts/AviFollowButton.web.tsx b/src/view/com/posts/AviFollowButton.web.tsx new file mode 100644 index 0000000000..6ad3c9f1fd --- /dev/null +++ b/src/view/com/posts/AviFollowButton.web.tsx @@ -0,0 +1 @@ +export {Fragment as AviFollowButton} from 'react' diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx index 8077c29683..b10ffe19fa 100644 --- a/src/view/com/posts/FeedItem.tsx +++ b/src/view/com/posts/FeedItem.tsx @@ -41,6 +41,7 @@ import {PostEmbeds} from '../util/post-embeds' import {PostMeta} from '../util/PostMeta' import {Text} from '../util/text/Text' import {PreviewableUserAvatar} from '../util/UserAvatar' +import {AviFollowButton} from './AviFollowButton' interface FeedItemProps { record: AppBskyFeedPost.Record @@ -284,13 +285,15 @@ let FeedItemInner = ({ - + + + {isThreadParent && ( Date: Thu, 30 May 2024 21:32:54 -0700 Subject: [PATCH 44/55] Change many border widths from `1` to `hairlineWidth` (#4294) * feed items * update some more * moar * profile card * composer and notifications * settings screen * remove border from first item in feeds * remove border from first item in feeds * more removal of top border * fix flatlist rendering * oops * scroll to top fab * a.border * centeredview/list * placeholder * web sidebar * search posts * feeds list * user lists * list header * account list width 1 * hide top border feedgens * same for lists * fix tab bar web desktop * wait... * show the border on desktop web * fix lists * fix lists * round --- src/alf/atoms.ts | 13 ++--- src/components/AccountList.tsx | 4 +- src/view/com/composer/Composer.tsx | 5 +- src/view/com/composer/Prompt.tsx | 16 +++--- src/view/com/feeds/FeedSourceCard.tsx | 16 ++++-- src/view/com/feeds/ProfileFeedgens.tsx | 4 +- src/view/com/lists/ListCard.tsx | 22 ++++---- src/view/com/lists/MyLists.tsx | 18 ++++--- src/view/com/lists/ProfileLists.tsx | 8 +-- src/view/com/notifications/Feed.tsx | 33 ++++++++---- src/view/com/notifications/FeedItem.tsx | 5 +- src/view/com/pager/PagerWithHeader.tsx | 4 +- src/view/com/pager/TabBar.tsx | 3 +- src/view/com/post-thread/PostThreadItem.tsx | 11 ++-- src/view/com/post/Post.tsx | 3 +- src/view/com/posts/Feed.tsx | 21 +++++--- src/view/com/posts/FeedItem.tsx | 11 ++-- src/view/com/posts/FeedSlice.tsx | 10 +++- src/view/com/profile/ProfileCard.tsx | 3 +- src/view/com/profile/ProfileSubpageHeader.tsx | 28 +++++----- src/view/com/util/LoadingPlaceholder.tsx | 3 +- src/view/com/util/ViewHeader.tsx | 5 +- src/view/com/util/Views.web.tsx | 9 ++-- .../com/util/load-latest/LoadLatestBtn.tsx | 3 +- src/view/com/util/post-embeds/QuoteEmbed.tsx | 5 +- src/view/com/util/post-embeds/index.tsx | 3 +- src/view/screens/Feeds.tsx | 5 +- src/view/screens/Lists.tsx | 31 ++++++----- src/view/screens/Notifications.tsx | 53 ++++++++++--------- src/view/screens/ProfileList.tsx | 5 +- src/view/screens/Settings/index.tsx | 3 +- src/view/shell/bottom-bar/BottomBarStyles.tsx | 3 +- src/view/shell/desktop/RightNav.tsx | 5 +- 33 files changed, 227 insertions(+), 144 deletions(-) diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts index eb130f3ae9..1ccb0460c4 100644 --- a/src/alf/atoms.ts +++ b/src/alf/atoms.ts @@ -1,7 +1,8 @@ -import {Platform} from 'react-native' +import {Platform, StyleSheet} from 'react-native' import * as tokens from '#/alf/tokens' import {native, web} from '#/alf/util/platform' +import hairlineWidth = StyleSheet.hairlineWidth export const atoms = { /* @@ -277,19 +278,19 @@ export const atoms = { borderWidth: 0, }, border: { - borderWidth: 1, + borderWidth: hairlineWidth, }, border_t: { - borderTopWidth: 1, + borderTopWidth: hairlineWidth, }, border_b: { - borderBottomWidth: 1, + borderBottomWidth: hairlineWidth, }, border_l: { - borderLeftWidth: 1, + borderLeftWidth: hairlineWidth, }, border_r: { - borderRightWidth: 1, + borderRightWidth: hairlineWidth, }, /* diff --git a/src/components/AccountList.tsx b/src/components/AccountList.tsx index 7d696801ed..883c06c144 100644 --- a/src/components/AccountList.tsx +++ b/src/components/AccountList.tsx @@ -37,7 +37,7 @@ export function AccountList({ style={[ a.rounded_md, a.overflow_hidden, - a.border, + {borderWidth: 1}, t.atoms.border_contrast_low, ]}> {accounts.map(account => ( @@ -48,7 +48,7 @@ export function AccountList({ isCurrentAccount={account.did === currentAccount?.did} isPendingAccount={account.did === pendingDid} /> - + ))} ) : null} - + @@ -621,11 +627,6 @@ export function useComposerCancelRef() { const styles = StyleSheet.create({ topbar: { - flexDirection: 'row', - alignItems: 'center', - marginHorizontal: 16, - height: 54, - gap: 4, borderBottomWidth: StyleSheet.hairlineWidth, }, topbarDesktop: { @@ -633,6 +634,13 @@ const styles = StyleSheet.create({ paddingBottom: 10, height: 50, }, + topbarInner: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 16, + height: 54, + gap: 4, + }, postBtn: { borderRadius: 20, paddingHorizontal: 20, @@ -643,19 +651,19 @@ const styles = StyleSheet.create({ flexDirection: 'row', backgroundColor: colors.red1, borderRadius: 6, - marginHorizontal: 15, + marginHorizontal: 16, paddingHorizontal: 8, paddingVertical: 6, - marginVertical: 6, + marginBottom: 8, }, reminderLine: { flexDirection: 'row', alignItems: 'center', borderRadius: 6, - marginHorizontal: 15, + marginHorizontal: 16, paddingHorizontal: 8, paddingVertical: 6, - marginBottom: 6, + marginBottom: 8, }, errorIcon: { borderWidth: hairlineWidth, @@ -690,8 +698,8 @@ const styles = StyleSheet.create({ bottomBar: { flexDirection: 'row', paddingVertical: 4, - paddingLeft: 15, - paddingRight: 20, + paddingLeft: 8, + paddingRight: 16, alignItems: 'center', borderTopWidth: hairlineWidth, }, diff --git a/src/view/com/composer/ComposerReplyTo.tsx b/src/view/com/composer/ComposerReplyTo.tsx index 902d60a460..6b38caff03 100644 --- a/src/view/com/composer/ComposerReplyTo.tsx +++ b/src/view/com/composer/ComposerReplyTo.tsx @@ -10,7 +10,6 @@ import { import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {isWeb} from '#/platform/detection' import {sanitizeDisplayName} from 'lib/strings/display-names' import {sanitizeHandle} from 'lib/strings/handles' import {ComposerOptsPostRef} from 'state/shell/composer' @@ -76,10 +75,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) { return ( { @@ -45,7 +46,7 @@ export function ThreadgateBtn({ : _(msg`Some people can reply`) return ( - + + + {title} + + + + + { + setSearchText(text) + listRef.current?.scrollToOffset({offset: 0, animated: false}) + }} + onEscape={control.close} + /> + + + ) + }, [ + t.atoms.border_contrast_low, + t.atoms.bg, + t.atoms.text_contrast_high, + t.palette.contrast_500, + _, + title, + searchText, + control, + ]) + + return ( + item.key} + style={[ + web([a.py_0, {height: '100vh', maxHeight: 600}, a.px_0]), + native({ + height: '100%', + paddingHorizontal: 0, + marginTop: 0, + paddingTop: 0, + borderTopLeftRadius: 40, + borderTopRightRadius: 40, + }), + ]} + webInnerStyle={[a.py_0, {maxWidth: 500, minWidth: 200}]} + keyboardDismissMode="on-drag" + /> ) } @@ -293,217 +461,3 @@ function SearchInput({ ) } - -function SearchablePeopleList({ - onCreateChat, -}: { - onCreateChat: (did: string) => void -}) { - const t = useTheme() - const {_} = useLingui() - const moderationOpts = useModerationOpts() - const control = Dialog.useDialogContext() - const listRef = useRef(null) - const {currentAccount} = useSession() - const inputRef = useRef(null) - - const [searchText, setSearchText] = useState('') - - const { - data: results, - isError, - isFetching, - } = useActorAutocompleteQuery(searchText, true, 12) - const {data: follows} = useProfileFollowsQuery(currentAccount?.did) - - const items = useMemo(() => { - let _items: Item[] = [] - - if (isError) { - _items.push({ - type: 'empty', - key: 'empty', - message: _(msg`We're having network issues, try again`), - }) - } else if (searchText.length) { - if (results?.length) { - for (const profile of results) { - if (profile.did === currentAccount?.did) continue - _items.push({ - type: 'profile', - key: profile.did, - enabled: canBeMessaged(profile), - profile, - }) - } - - _items = _items.sort(a => { - // @ts-ignore - return a.enabled ? -1 : 1 - }) - } - } else { - if (follows) { - for (const page of follows.pages) { - for (const profile of page.follows) { - _items.push({ - type: 'profile', - key: profile.did, - enabled: canBeMessaged(profile), - profile, - }) - } - } - - _items = _items.sort(a => { - // @ts-ignore - return a.enabled ? -1 : 1 - }) - } else { - Array(10) - .fill(0) - .forEach((_, i) => { - _items.push({ - type: 'placeholder', - key: i + '', - }) - }) - } - } - - return _items - }, [_, searchText, results, isError, currentAccount?.did, follows]) - - if (searchText && !isFetching && !items.length && !isError) { - items.push({type: 'empty', key: 'empty', message: _(msg`No results`)}) - } - - const renderItems = useCallback( - ({item}: {item: Item}) => { - switch (item.type) { - case 'profile': { - return ( - - ) - } - case 'placeholder': { - return - } - case 'empty': { - return - } - default: - return null - } - }, - [moderationOpts, onCreateChat], - ) - - useLayoutEffect(() => { - if (isWeb) { - setImmediate(() => { - inputRef?.current?.focus() - }) - } - }, []) - - const listHeader = useMemo(() => { - return ( - - - - - Start a new chat - - - - - { - setSearchText(text) - listRef.current?.scrollToOffset({offset: 0, animated: false}) - }} - onEscape={control.close} - /> - - - ) - }, [t, _, control, searchText]) - - return ( - item.key} - style={[ - web([a.py_0, {height: '100vh', maxHeight: 600}, a.px_0]), - native({ - height: '100%', - paddingHorizontal: 0, - marginTop: 0, - paddingTop: 0, - borderTopLeftRadius: 40, - borderTopRightRadius: 40, - }), - ]} - webInnerStyle={[a.py_0, {maxWidth: 500, minWidth: 200}]} - keyboardDismissMode="on-drag" - /> - ) -} diff --git a/src/components/dms/dialogs/ShareViaChatDialog.tsx b/src/components/dms/dialogs/ShareViaChatDialog.tsx new file mode 100644 index 0000000000..ac475f7c99 --- /dev/null +++ b/src/components/dms/dialogs/ShareViaChatDialog.tsx @@ -0,0 +1,52 @@ +import React, {useCallback} from 'react' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members' +import {logEvent} from 'lib/statsig/statsig' +import * as Toast from '#/view/com/util/Toast' +import * as Dialog from '#/components/Dialog' +import {SearchablePeopleList} from './SearchablePeopleList' + +export function SendViaChatDialog({ + control, + onSelectChat, +}: { + control: Dialog.DialogControlProps + onSelectChat: (chatId: string) => void +}) { + const {_} = useLingui() + + const {mutate: createChat} = useGetConvoForMembers({ + onSuccess: data => { + onSelectChat(data.convo.id) + + if (!data.convo.lastMessage) { + logEvent('chat:create', {logContext: 'SendViaChatDialog'}) + } + logEvent('chat:open', {logContext: 'SendViaChatDialog'}) + }, + onError: error => { + Toast.show(error.message) + }, + }) + + const onCreateChat = useCallback( + (did: string) => { + control.close(() => createChat([did])) + }, + [control, createChat], + ) + + return ( + + + + ) +} diff --git a/src/components/dms/NewChatDialog/TextInput.tsx b/src/components/dms/dialogs/TextInput.tsx similarity index 100% rename from src/components/dms/NewChatDialog/TextInput.tsx rename to src/components/dms/dialogs/TextInput.tsx diff --git a/src/components/dms/NewChatDialog/TextInput.web.tsx b/src/components/dms/dialogs/TextInput.web.tsx similarity index 100% rename from src/components/dms/NewChatDialog/TextInput.web.tsx rename to src/components/dms/dialogs/TextInput.web.tsx diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index 5011aafd79..7504cd83a0 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -38,7 +38,7 @@ export type CommonNavigatorParams = { AccessibilitySettings: undefined Search: {q?: string} Hashtag: {tag: string; author?: string} - MessagesConversation: {conversation: string} + MessagesConversation: {conversation: string; embed?: string} MessagesSettings: undefined } diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts index 00444c18c4..48651b3d96 100644 --- a/src/lib/statsig/events.ts +++ b/src/lib/statsig/events.ts @@ -130,10 +130,14 @@ export type LogEvents = { | 'AvatarButton' } 'chat:create': { - logContext: 'ProfileHeader' | 'NewChatDialog' + logContext: 'ProfileHeader' | 'NewChatDialog' | 'SendViaChatDialog' } 'chat:open': { - logContext: 'ProfileHeader' | 'NewChatDialog' | 'ChatsList' + logContext: + | 'ProfileHeader' + | 'NewChatDialog' + | 'ChatsList' + | 'SendViaChatDialog' } 'test:all:always': {} diff --git a/src/screens/Messages/Conversation/MessageInput.tsx b/src/screens/Messages/Conversation/MessageInput.tsx index 1491886846..c8229f95dc 100644 --- a/src/screens/Messages/Conversation/MessageInput.tsx +++ b/src/screens/Messages/Conversation/MessageInput.tsx @@ -27,13 +27,20 @@ import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {useSharedInputStyles} from '#/components/forms/TextField' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane' +import {useExtractEmbedFromFacets} from './MessageInputEmbed' const AnimatedTextInput = Animated.createAnimatedComponent(TextInput) export function MessageInput({ onSendMessage, + hasEmbed, + setEmbed, + children, }: { onSendMessage: (message: string) => void + hasEmbed: boolean + setEmbed: (embedUrl: string | undefined) => void + children?: React.ReactNode }) { const {_} = useLingui() const t = useTheme() @@ -53,9 +60,10 @@ export function MessageInput({ const inputRef = useAnimatedRef() useSaveMessageDraft(message) + useExtractEmbedFromFacets(message, setEmbed) const onSubmit = React.useCallback(() => { - if (message.trim() === '') { + if (!hasEmbed && message.trim() === '') { return } if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) { @@ -66,13 +74,23 @@ export function MessageInput({ onSendMessage(message) playHaptic() setMessage('') + setEmbed(undefined) // Pressing the send button causes the text input to lose focus, so we need to // re-focus it after sending setTimeout(() => { inputRef.current?.focus() }, 100) - }, [message, clearDraft, onSendMessage, playHaptic, _, inputRef]) + }, [ + hasEmbed, + message, + clearDraft, + onSendMessage, + playHaptic, + setEmbed, + _, + inputRef, + ]) useFocusedInputHandler( { @@ -101,6 +119,7 @@ export function MessageInput({ return ( + {children} void + hasEmbed: boolean + setEmbed: (embedUrl: string | undefined) => void + children?: React.ReactNode }) { const {isTabletOrDesktop} = useWebMediaQueries() const {_} = useLingui() @@ -35,7 +42,7 @@ export function MessageInput({ const [textAreaHeight, setTextAreaHeight] = React.useState(38) const onSubmit = React.useCallback(() => { - if (message.trim() === '') { + if (!hasEmbed && message.trim() === '') { return } if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) { @@ -45,7 +52,8 @@ export function MessageInput({ clearDraft() onSendMessage(message) setMessage('') - }, [message, onSendMessage, _, clearDraft]) + setEmbed(undefined) + }, [message, onSendMessage, _, clearDraft, hasEmbed, setEmbed]) const onKeyDown = React.useCallback( (e: React.KeyboardEvent) => { @@ -87,9 +95,11 @@ export function MessageInput({ ) useSaveMessageDraft(message) + useExtractEmbedFromFacets(message, setEmbed) return ( + {children} >() + const navigation = useNavigation() + const embedFromParams = route.params.embed + + const [embedUri, setEmbed] = useState(embedFromParams) + + if (embedFromParams && embedUri !== embedFromParams) { + setEmbed(embedFromParams) + } + + return { + embedUri, + setEmbed: useCallback( + (embedUrl: string | undefined) => { + if (!embedUrl) { + navigation.setParams({embed: ''}) + setEmbed(undefined) + return + } + + if (embedFromParams) return + + const url = convertBskyAppUrlIfNeeded(embedUrl) + const [_0, user, _1, rkey] = url.split('/').filter(Boolean) + const uri = makeRecordUri(user, 'app.bsky.feed.post', rkey) + + setEmbed(uri) + }, + [embedFromParams, navigation], + ), + } +} + +export function useExtractEmbedFromFacets( + message: string, + setEmbed: (embedUrl: string | undefined) => void, +) { + const rt = new RichTextAPI({text: message}) + rt.detectFacetsWithoutResolution() + + let uriFromFacet: string | undefined + + for (const facet of rt.facets ?? []) { + for (const feature of facet.features) { + if (AppBskyRichtextFacet.isLink(feature) && isBskyPostUrl(feature.uri)) { + uriFromFacet = feature.uri + break + } + } + } + + useEffect(() => { + if (uriFromFacet) { + setEmbed(uriFromFacet) + } + }, [uriFromFacet, setEmbed]) +} + +export function MessageInputEmbed({ + embedUri, + setEmbed, +}: { + embedUri: string | undefined + setEmbed: (embedUrl: string | undefined) => void +}) { + const t = useTheme() + const {_} = useLingui() + + const {data: post, status} = usePostQuery(embedUri) + + const moderationOpts = useModerationOpts() + const moderation = useMemo( + () => + moderationOpts && post ? moderatePost(post, moderationOpts) : undefined, + [moderationOpts, post], + ) + + const {rt, record} = useMemo(() => { + if ( + post && + AppBskyFeedPost.isRecord(post.record) && + AppBskyFeedPost.validateRecord(post.record).success + ) { + return { + rt: new RichTextAPI({ + text: post.record.text, + facets: post.record.facets, + }), + record: post.record, + } + } + + return {rt: undefined, record: undefined} + }, [post]) + + if (!embedUri) { + return null + } + + let content = null + switch (status) { + case 'pending': + content = ( + + + + ) + break + case 'error': + content = ( + + Could not fetch post + + ) + break + case 'success': + const itemUrip = new AtUri(post.uri) + const itemHref = makeProfileLink(post.author, 'post', itemUrip.rkey) + + if (!post || !moderation || !rt || !record) { + return null + } + + const images = AppBskyEmbedImages.isView(post.embed) + ? post.embed.images + : AppBskyEmbedRecordWithMedia.isView(post.embed) && + AppBskyEmbedImages.isView(post.embed.media) + ? post.embed.media.images + : undefined + + content = ( + + + + + {rt.text && ( + + + + )} + {images && images?.length > 0 && ( + + )} + + + ) + break + } + + return ( + + {content} + + + ) +} diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index d6aa06a1ce..e6f657b497 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -15,9 +15,11 @@ import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/rean import {useSafeAreaInsets} from 'react-native-safe-area-context' import {AppBskyEmbedRecord, AppBskyRichtextFacet, RichText} from '@atproto/api' -import {getPostAsQuote} from '#/lib/link-meta/bsky' import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip' -import {isBskyPostUrl} from '#/lib/strings/url-helpers' +import { + convertBskyAppUrlIfNeeded, + isBskyPostUrl, +} from '#/lib/strings/url-helpers' import {logger} from '#/logger' import {isNative} from '#/platform/detection' import {isConvoActive, useConvoActive} from '#/state/messages/convo' @@ -36,6 +38,7 @@ import {MessageItem} from '#/components/dms/MessageItem' import {NewMessagesPill} from '#/components/dms/NewMessagesPill' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' +import {MessageInputEmbed, useMessageEmbed} from './MessageInputEmbed' function MaybeLoader({isLoading}: {isLoading: boolean}) { return ( @@ -85,6 +88,7 @@ export function MessagesList({ const convoState = useConvoActive() const agent = useAgent() const getPost = useGetPost() + const {embedUri, setEmbed} = useMessageEmbed() const flatListRef = useAnimatedRef() @@ -277,25 +281,10 @@ export function MessagesList({ rt.detectFacetsWithoutResolution() let embed: AppBskyEmbedRecord.Main | undefined - // find the first link facet that is a link to a post - const postLinkFacet = rt.facets?.find(facet => { - return facet.features.find(feature => { - if (AppBskyRichtextFacet.isLink(feature)) { - return isBskyPostUrl(feature.uri) - } - return false - }) - }) - - // if we found a post link, get the post and embed it - if (postLinkFacet) { - const postLink = postLinkFacet.features.find( - AppBskyRichtextFacet.isLink, - ) - if (!postLink) return + if (embedUri) { try { - const post = await getPostAsQuote(getPost, postLink.uri) + const post = await getPost({uri: embedUri}) if (post) { embed = { $type: 'app.bsky.embed.record', @@ -305,24 +294,43 @@ export function MessagesList({ }, } - // remove the post link from the text - rt.delete( - postLinkFacet.index.byteStart, - postLinkFacet.index.byteEnd, - ) + // look for the embed uri in the facets, so we can remove it from the text + const postLinkFacet = rt.facets?.find(facet => { + return facet.features.find(feature => { + if (AppBskyRichtextFacet.isLink(feature)) { + if (isBskyPostUrl(feature.uri)) { + const url = convertBskyAppUrlIfNeeded(feature.uri) + const [_0, _1, _2, rkey] = url.split('/').filter(Boolean) - // re-trim the text, now that we've removed the post link - // - // if the post link is at the start of the text, we don't want to leave a leading space - // so trim on both sides - if (postLinkFacet.index.byteStart === 0) { - rt = new RichText({text: rt.text.trim()}, {cleanNewlines: true}) - } else { - // otherwise just trim the end - rt = new RichText( - {text: rt.text.trimEnd()}, - {cleanNewlines: true}, + // this might have a handle instead of a DID + // so just compare the rkey - not particularly dangerous + return post.uri.endsWith(rkey) + } + } + return false + }) + }) + + if (postLinkFacet) { + // remove the post link from the text + rt.delete( + postLinkFacet.index.byteStart, + postLinkFacet.index.byteEnd, ) + + // re-trim the text, now that we've removed the post link + // + // if the post link is at the start of the text, we don't want to leave a leading space + // so trim on both sides + if (postLinkFacet.index.byteStart === 0) { + rt = new RichText({text: rt.text.trim()}, {cleanNewlines: true}) + } else { + // otherwise just trim the end + rt = new RichText( + {text: rt.text.trimEnd()}, + {cleanNewlines: true}, + ) + } } } } catch (error) { @@ -345,7 +353,7 @@ export function MessagesList({ embed, }) }, - [agent, convoState, getPost, hasScrolled, setHasScrolled], + [agent, convoState, embedUri, getPost, hasScrolled, setHasScrolled], ) // -- List layout changes (opening emoji keyboard, etc.) @@ -420,7 +428,12 @@ export function MessagesList({ {isConvoActive(convoState) && !convoState.isFetchingHistory && convoState.items.length === 0 && } - + + + )} diff --git a/src/screens/Messages/List/index.tsx b/src/screens/Messages/List/index.tsx index 7c67c59d3f..0b1fe2a958 100644 --- a/src/screens/Messages/List/index.tsx +++ b/src/screens/Messages/List/index.tsx @@ -21,8 +21,8 @@ import {CenteredView} from '#/view/com/util/Views' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {DialogControlProps, useDialogControl} from '#/components/Dialog' +import {NewChat} from '#/components/dms/dialogs/NewChatDialog' import {MessagesNUX} from '#/components/dms/MessagesNUX' -import {NewChat} from '#/components/dms/NewChatDialog' import {useRefreshOnFocus} from '#/components/hooks/useRefreshOnFocus' import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Retry} from '#/components/icons/ArrowRotateCounterClockwise' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' diff --git a/src/state/messages/convo/agent.ts b/src/state/messages/convo/agent.ts index 9850124c90..de2605b5ad 100644 --- a/src/state/messages/convo/agent.ts +++ b/src/state/messages/convo/agent.ts @@ -1018,6 +1018,7 @@ export class Convo { key: m.id, message: { ...m.message, + embed: undefined, $type: 'chat.bsky.convo.defs#messageView', id: nanoid(), rev: '__fake__', diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts index f27628d696..794f48eb1b 100644 --- a/src/state/queries/post.ts +++ b/src/state/queries/post.ts @@ -18,7 +18,16 @@ export function usePostQuery(uri: string | undefined) { return useQuery({ queryKey: RQKEY(uri || ''), async queryFn() { - const res = await agent.getPosts({uris: [uri!]}) + const urip = new AtUri(uri!) + + if (!urip.host.startsWith('did:')) { + const res = await agent.resolveHandle({ + handle: urip.host, + }) + urip.host = res.data.did + } + + const res = await agent.getPosts({uris: [urip.toString()]}) if (res.success && res.data.posts[0]) { return res.data.posts[0] } @@ -47,7 +56,7 @@ export function useGetPost() { } const res = await agent.getPosts({ - uris: [urip.toString()!], + uris: [urip.toString()], }) if (res.success && res.data.posts[0]) { diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index a5cc60fd81..4b50946a41 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -451,7 +451,7 @@ function AdditionalPostText({post}: {post?: AppBskyFeedDefs.PostView}) { return ( <> {text?.length > 0 && {text}} - {images && images?.length > 0 && ( + {images && images.length > 0 && ( )} diff --git a/src/view/com/util/forms/PostDropdownBtn.tsx b/src/view/com/util/forms/PostDropdownBtn.tsx index cd82ec98f0..945cf5e596 100644 --- a/src/view/com/util/forms/PostDropdownBtn.tsx +++ b/src/view/com/util/forms/PostDropdownBtn.tsx @@ -12,12 +12,12 @@ import { AtUri, RichText as RichTextAPI, } from '@atproto/api' -import {msg} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {makeProfileLink} from '#/lib/routes/links' -import {CommonNavigatorParams} from '#/lib/routes/types' +import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types' import {richTextToString} from '#/lib/strings/rich-text-helpers' import {getTranslatorLink} from '#/locale/helpers' import {logger} from '#/logger' @@ -37,6 +37,7 @@ import {atoms as a, useBreakpoints, useTheme as useAlf} from '#/alf' import {useDialogControl} from '#/components/Dialog' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' import {EmbedDialog} from '#/components/dialogs/Embed' +import {SendViaChatDialog} from '#/components/dms/dialogs/ShareViaChatDialog' import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox' import {BubbleQuestion_Stroke2_Corner0_Rounded as Translate} from '#/components/icons/Bubble' import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard' @@ -49,6 +50,7 @@ import { import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter' import {Mute_Stroke2_Corner0_Rounded as Mute} from '#/components/icons/Mute' +import {PaperPlane_Stroke2_Corner0_Rounded as Send} from '#/components/icons/PaperPlane' import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as Unmute} from '#/components/icons/Speaker' import {Trash_Stroke2_Corner0_Rounded as Trash} from '#/components/icons/Trash' import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/Warning' @@ -102,13 +104,14 @@ let PostDropdownBtn = ({ const {hidePost} = useHiddenPostsApi() const feedFeedback = useFeedFeedbackContext() const openLink = useOpenLink() - const navigation = useNavigation() + const navigation = useNavigation() const {mutedWordsDialogControl} = useGlobalDialogsControlContext() const reportDialogControl = useReportDialogControl() const deletePromptControl = useDialogControl() const hidePromptControl = useDialogControl() const loggedOutWarningPromptControl = useDialogControl() const embedPostControl = useDialogControl() + const sendViaChatControl = useDialogControl() const rootUri = record.reply?.root?.uri || postUri const isThreadMuted = mutedThreads.includes(rootUri) @@ -229,6 +232,16 @@ let PostDropdownBtn = ({ Toast.show('Feedback sent!') }, [feedFeedback, postUri, postFeedContext]) + const onSelectChatToShareTo = React.useCallback( + (conversation: string) => { + navigation.navigate('MessagesConversation', { + conversation, + embed: postUri, + }) + }, + [navigation, postUri], + ) + const canEmbed = isWeb && gtMobile && !hideInPWI return ( @@ -280,6 +293,18 @@ let PostDropdownBtn = ({ )} + {hasSession && ( + + + Send via direct message + + + + )} + )} + + ) } diff --git a/src/view/com/util/images/ImageHorzList.tsx b/src/view/com/util/images/ImageHorzList.tsx index e37f8af1b7..12eef14f73 100644 --- a/src/view/com/util/images/ImageHorzList.tsx +++ b/src/view/com/util/images/ImageHorzList.tsx @@ -27,11 +27,14 @@ export function ImageHorzList({images, style}: Props) { } const styles = StyleSheet.create({ - flexRow: {flexDirection: 'row'}, + flexRow: { + flexDirection: 'row', + gap: 5, + }, image: { - width: 100, - height: 100, + maxWidth: 100, + aspectRatio: 1, + flex: 1, borderRadius: 4, - marginRight: 5, }, }) diff --git a/yarn.lock b/yarn.lock index 3e1246d92c..ae18bfbec6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,10 +34,10 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@atproto/api@^0.12.13": - version "0.12.13" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.13.tgz#269d6c57ea894e23f20b28bd3cbfed944bd28528" - integrity sha512-pRSID6w8AUiZJoCxgctMPRTSGVFHq7wphAnxEbRLBP3OQ1g+BRZUcqFw+e+17Pd3wrc8VImjiD4HCWtCJvCx3w== +"@atproto/api@^0.12.14": + version "0.12.14" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.14.tgz#81252fd166ec8fe950056531e690d563437720fa" + integrity sha512-ZPh/afoRjFEQDQgMZW2FQiG5CDUifY7SxBqI0zVJUwed8Zi6fqYzGYM8fcDvD8yJfflRCqRxUE72g5fKiA1zAQ== dependencies: "@atproto/common-web" "^0.3.0" "@atproto/lexicon" "^0.4.0" @@ -22564,12 +22564,12 @@ zod-validation-error@^3.0.3: resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-3.3.0.tgz#2cfe81b62d044e0453d1aa3ae7c32a2f36dde9af" integrity sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw== -zod@^3.14.2, zod@^3.20.2, zod@^3.21.4: +zod@^3.14.2, zod@^3.20.2: version "3.22.2" resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.2.tgz#3add8c682b7077c05ac6f979fea6998b573e157b" integrity sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg== -zod@^3.22.4: +zod@^3.21.4, zod@^3.22.4: version "3.23.8" resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== From 2bb36948198b9a0787544258bde72b4d3c6d78b0 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 31 May 2024 12:14:11 -0500 Subject: [PATCH 51/55] =?UTF-8?q?[=F0=9F=90=B4]=20Add=20labels=20to=20chat?= =?UTF-8?q?s=20(#4293)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add labels to chat list * Add to convo header * Prevent click through on PostAlert buttons * Fix space * Fix alignment --- src/components/dms/MessagesListHeader.tsx | 107 ++++++++++++--------- src/components/moderation/PostAlerts.tsx | 4 +- src/screens/Messages/List/ChatListItem.tsx | 7 ++ 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/src/components/dms/MessagesListHeader.tsx b/src/components/dms/MessagesListHeader.tsx index 0a0cd20da1..0aeac36286 100644 --- a/src/components/dms/MessagesListHeader.tsx +++ b/src/components/dms/MessagesListHeader.tsx @@ -22,6 +22,7 @@ import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {ConvoMenu} from '#/components/dms/ConvoMenu' import {Bell2Off_Filled_Corner0_Rounded as BellStroke} from '#/components/icons/Bell2' import {Link} from '#/components/Link' +import {PostAlerts} from '#/components/moderation/PostAlerts' import {Text} from '#/components/Typography' const PFP_SIZE = isWeb ? 40 : 34 @@ -58,7 +59,7 @@ export let MessagesListHeader = ({ t.atoms.border_contrast_low, a.border_b, a.flex_row, - a.align_center, + a.align_start, a.gap_sm, gtTablet ? a.pl_lg : a.pl_xl, a.pr_lg, @@ -69,7 +70,7 @@ export let MessagesListHeader = ({ testID="conversationHeaderBackBtn" onPress={onPressBack} hitSlop={BACK_HITSLOP} - style={{width: 30, height: 30}} + style={{width: 30, height: 30, marginTop: isWeb ? 6 : 4}} accessibilityRole="button" accessibilityLabel={_(msg`Back`)} accessibilityHint=""> @@ -152,51 +153,71 @@ function HeaderReady({ ) return ( - <> - - - - - {displayName} - - {!isDeletedAccount && ( + + + + + + + - @{profile.handle} - {convoState.convo?.muted && ( - <> - {' '} - ·{' '} - - - )} + {displayName} - )} - - + {!isDeletedAccount && ( + + @{profile.handle} + {convoState.convo?.muted && ( + <> + {' '} + ·{' '} + + + )} + + )} + + - {isConvoActive(convoState) && ( - + )} + + + + - )} - + + ) } diff --git a/src/components/moderation/PostAlerts.tsx b/src/components/moderation/PostAlerts.tsx index 5a33bbc80f..0b48b51d1d 100644 --- a/src/components/moderation/PostAlerts.tsx +++ b/src/components/moderation/PostAlerts.tsx @@ -64,7 +64,9 @@ function PostLabel({ <> )} From b51640fbc099a1e9df1430b5a05bf913495008b7 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Fri, 31 May 2024 22:57:42 +0300 Subject: [PATCH 54/55] =?UTF-8?q?[=F0=9F=90=B4]=20add=20emoji=20multiplier?= =?UTF-8?q?=20prop=20to=20RichText=20and=20bump=20it=20up=20for=20DMs=20(#?= =?UTF-8?q?4229)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add emoji multiplier prop to RichText and bump it up for DMs * remove background if only emoji * Handle more emoji * Adjust emoji regex and length * Fix bad merge conflict res * Fix logic * Revert to emoji specific regex --------- Co-authored-by: Eric Bailey --- src/components/RichText.tsx | 20 +++++++++----- src/components/dms/MessageItem.tsx | 44 ++++++++++++++++-------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/components/RichText.tsx b/src/components/RichText.tsx index ed69c199ad..9ba44eabe4 100644 --- a/src/components/RichText.tsx +++ b/src/components/RichText.tsx @@ -28,6 +28,7 @@ export function RichText({ authorHandle, onLinkPress, interactiveStyle, + emojiMultiplier = 1.85, }: TextStyleProp & Pick & { value: RichTextAPI | string @@ -38,6 +39,7 @@ export function RichText({ authorHandle?: string onLinkPress?: LinkProps['onPress'] interactiveStyle?: TextStyle + emojiMultiplier?: number }) { const richText = React.useMemo( () => @@ -57,17 +59,14 @@ export function RichText({ const {text, facets} = richText if (!facets?.length) { - if (text.length <= 5 && /^\p{Extended_Pictographic}+$/u.test(text)) { + if (isOnlyEmoji(text)) { + const fontSize = + (flattenedStyle.fontSize ?? a.text_sm.fontSize) * emojiMultiplier return ( {text} @@ -247,3 +246,10 @@ function RichTextTag({ ) } + +export function isOnlyEmoji(text: string) { + return ( + text.length <= 15 && + /^[\p{Emoji_Presentation}\p{Extended_Pictographic}]+$/u.test(text) + ) +} diff --git a/src/components/dms/MessageItem.tsx b/src/components/dms/MessageItem.tsx index 772fcb1b11..61358c9893 100644 --- a/src/components/dms/MessageItem.tsx +++ b/src/components/dms/MessageItem.tsx @@ -21,7 +21,7 @@ import {atoms as a, useTheme} from '#/alf' import {ActionsWrapper} from '#/components/dms/ActionsWrapper' import {InlineLinkText} from '#/components/Link' import {Text} from '#/components/Typography' -import {RichText} from '../RichText' +import {isOnlyEmoji, RichText} from '../RichText' import {MessageItemEmbed} from './MessageItemEmbed' let MessageItem = ({ @@ -87,36 +87,38 @@ let MessageItem = ({ )} {rt.text.length > 0 && ( + style={ + !isOnlyEmoji(message.text) && [ + a.py_sm, + a.my_2xs, + a.rounded_md, + { + paddingLeft: 14, + paddingRight: 14, + backgroundColor: isFromSelf + ? isPending + ? pendingColor + : t.palette.primary_500 + : t.palette.contrast_50, + borderRadius: 17, + }, + isFromSelf ? a.self_end : a.self_start, + isFromSelf + ? {borderBottomRightRadius: isLastInGroup ? 2 : 17} + : {borderBottomLeftRadius: isLastInGroup ? 2 : 17}, + ] + }> )} From 708a80e7a7ca1199247a8c3ff4552d3957ea1c7b Mon Sep 17 00:00:00 2001 From: Hailey Date: Fri, 31 May 2024 13:02:18 -0700 Subject: [PATCH 55/55] fix accessibility label in notifications (#4305) * fix accessibility label in notifications * add accessibility options to expand post * inherit from outside, but always include `activate` * include option to disable label/hint on previewable avatar * fix hidden elements still being read on voiceover * make it work for followers too * extract variable * fix hint * update wording elsewhere --- src/view/com/notifications/FeedItem.tsx | 118 ++++++++++++++---------- src/view/com/util/Link.tsx | 15 +++ src/view/com/util/UserAvatar.tsx | 9 +- 3 files changed, 93 insertions(+), 49 deletions(-) diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 4b50946a41..22ebf8271c 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -194,10 +194,36 @@ let FeedItem = ({ ]} href={itemHref} noFeedback - accessible={ - (item.type === 'post-like' && authors.length === 1) || - item.type === 'repost' + accessible={!isAuthorsExpanded} + accessibilityActions={ + authors.length > 1 + ? [ + { + name: 'toggleAuthorsExpanded', + label: isAuthorsExpanded + ? _(msg`Collapse list of users`) + : _(msg`Expand list of users`), + }, + ] + : [ + { + name: 'viewProfile', + label: _( + msg`View ${ + authors[0].profile.displayName || authors[0].profile.handle + }'s profile`, + ), + }, + ] } + onAccessibilityAction={e => { + if (e.nativeEvent.actionName === 'activate') { + onBeforePress() + } + if (e.nativeEvent.actionName === 'toggleAuthorsExpanded') { + onToggleAuthorsExpanded() + } + }} onBeforePress={onBeforePress}> {/* TODO: Prevent conditional rendering and move toward composable @@ -332,16 +358,14 @@ function CondensedAuthorsList({ profile={authors[0].profile} moderation={authors[0].moderation.ui('avatar')} type={authors[0].profile.associated?.labeler ? 'labeler' : 'user'} + accessible={false} /> ) } return ( {authors.slice(0, MAX_AUTHORS).map(author => ( @@ -351,6 +375,7 @@ function CondensedAuthorsList({ profile={author.profile} moderation={author.moderation.ui('avatar')} type={author.profile.associated?.labeler ? 'labeler' : 'user'} + accessible={false} /> ))} @@ -392,48 +417,45 @@ function ExpandedAuthorsList({ }, [heightInterp, visible]) return ( - - {authors.map(author => ( - - - - - - - - - {sanitizeDisplayName( - author.profile.displayName || author.profile.handle, - )} -   - - {sanitizeHandle(author.profile.handle)} + + {visible && + authors.map(author => ( + + + + + + + + + {sanitizeDisplayName( + author.profile.displayName || author.profile.handle, + )} +   + + {sanitizeHandle(author.profile.handle)} + - - - - ))} + + + ))} ) } diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 865be45520..ab6fd200fc 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -64,6 +64,8 @@ export const Link = memo(function Link({ anchorNoUnderline, navigationAction, onBeforePress, + accessibilityActions, + onAccessibilityAction, ...props }: Props) { const t = useTheme() @@ -89,6 +91,11 @@ export const Link = memo(function Link({ [closeModal, navigation, navigationAction, href, openLink, onBeforePress], ) + const accessibilityActionsWithActivate = [ + ...(accessibilityActions || []), + {name: 'activate', label: title}, + ] + if (noFeedback) { return ( @@ -97,6 +104,14 @@ export const Link = memo(function Link({ onPress={onPress} accessible={accessible} accessibilityRole="link" + accessibilityActions={accessibilityActionsWithActivate} + onAccessibilityAction={e => { + if (e.nativeEvent.actionName === 'activate') { + onPress() + } else { + onAccessibilityAction?.(e) + } + }} {...props} android_ripple={{ color: t.atoms.bg_contrast_25.backgroundColor, diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index f23f4f7a5d..587b466a3c 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -53,6 +53,7 @@ interface PreviewableUserAvatarProps extends BaseUserAvatarProps { profile: AppBskyActorDefs.ProfileViewBasic disableHoverCard?: boolean onBeforePress?: () => void + accessible?: boolean } const BLUR_AMOUNT = isWeb ? 5 : 100 @@ -386,6 +387,7 @@ let PreviewableUserAvatar = ({ profile, disableHoverCard, onBeforePress, + accessible = true, ...rest }: PreviewableUserAvatarProps): React.ReactNode => { const {_} = useLingui() @@ -399,7 +401,12 @@ let PreviewableUserAvatar = ({ return (