From 4cb1ad77b8fc7685fb86ece825d4f986aa9a9305 Mon Sep 17 00:00:00 2001 From: James Acklin Date: Wed, 14 Aug 2024 15:41:00 -0400 Subject: [PATCH 01/33] webapp/sidebar: add Landscape icon + link --- .../src/components/Sidebar/AppNav.tsx | 20 +++++++++++++++++- .../src/components/icons/LandscapeIcon.tsx | 21 +++++++++++++++++++ apps/tlon-web/src/components/icons/index.tsx | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 apps/tlon-web/src/components/icons/LandscapeIcon.tsx diff --git a/apps/tlon-web/src/components/Sidebar/AppNav.tsx b/apps/tlon-web/src/components/Sidebar/AppNav.tsx index fa1f9d6f71..cea0c33f52 100644 --- a/apps/tlon-web/src/components/Sidebar/AppNav.tsx +++ b/apps/tlon-web/src/components/Sidebar/AppNav.tsx @@ -29,6 +29,7 @@ import NavTab, { import BellIcon from '../icons/BellIcon'; import CmdSmallIcon from '../icons/CmdSmallIcon'; import HomeIconMobileNav from '../icons/HomeIconMobileNav'; +import LandscapeIcon from '../icons/LandscapeIcon'; import MessagesIcon from '../icons/MessagesIcon'; import useActiveTab, { ActiveTab } from './util'; @@ -357,6 +358,20 @@ function ProfileTab(props: { isInactive: boolean }) { ); } +function LandscapeTab() { + return ( +
window.open('/apps/landscape', '_blank')} + > + +
+ ); +} + function LeapTab() { const { setIsOpen: setLeapOpen, isOpen } = useLeap(); @@ -449,7 +464,10 @@ export default function AppNav() { )} - +
+ + +
diff --git a/apps/tlon-web/src/components/icons/LandscapeIcon.tsx b/apps/tlon-web/src/components/icons/LandscapeIcon.tsx new file mode 100644 index 0000000000..be4e2c89fb --- /dev/null +++ b/apps/tlon-web/src/components/icons/LandscapeIcon.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import { IconProps } from './icon'; + +export default function LandscapeIcon({ className }: IconProps) { + return ( + + + + + + ); +} diff --git a/apps/tlon-web/src/components/icons/index.tsx b/apps/tlon-web/src/components/icons/index.tsx index 17b1518fc2..d961d503ad 100644 --- a/apps/tlon-web/src/components/icons/index.tsx +++ b/apps/tlon-web/src/components/icons/index.tsx @@ -53,6 +53,7 @@ import InviteIcon from './InviteIcon'; import InviteIcon16 from './InviteIcon16'; import ItalicIcon from './ItalicIcon'; import KeyIcon from './KeyIcon'; +import LandscapeIcon from './LandscapeIcon'; import LeaveIcon from './LeaveIcon'; import LinkIcon from './LinkIcon'; import LinkIcon16 from './LinkIcon16'; @@ -136,6 +137,7 @@ const icons: Record> = { InviteIcon, ItalicIcon, KeyIcon, + LandscapeIcon, LeaveIcon, LinkIcon, ListIcon, From 3f0bcca8f0972b46c2ae9d15e77ba9042fbc49f5 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Mon, 19 Aug 2024 11:31:59 -0500 Subject: [PATCH 02/33] activity: fix compiler isssue --- desk/app/activity.hoon | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index dfb885df44..42e04d821e 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -298,7 +298,8 @@ %. indices %~ uni by %- ~(run by indices:bak) - |= index + |= index:a + ^- index:a :_ [[floor.reads ~] bump] ?~ hed=(ram:on-event:a stream) *stream:a From 6060db75f032fbb363168a2bf8030bac978a4932 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Mon, 19 Aug 2024 11:32:27 -0500 Subject: [PATCH 03/33] channels: store logs so we can make changes work --- desk/app/channels.hoon | 1 + 1 file changed, 1 insertion(+) diff --git a/desk/app/channels.hoon b/desk/app/channels.hoon index 934ca27ff0..e7b98925b2 100644 --- a/desk/app/channels.hoon +++ b/desk/app/channels.hoon @@ -1304,6 +1304,7 @@ |= [=time =u-channel:c] ?> ca-from-host ^+ ca-core + =. log.channel (put:log-on:c log.channel time u-channel) ?- -.u-channel %create ?. =(0 rev.perm.channel) ca-core From 8e94cfe3d49099425c1d619d3f4dceb283dc8041 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Mon, 19 Aug 2024 15:43:17 -0500 Subject: [PATCH 04/33] channels: adding last-updated index --- desk/app/channels-server.hoon | 29 +++++++++++++++----- desk/app/channels.hoon | 50 +++++++++++++++++++++++++++++------ desk/sur/channels.hoon | 16 +++++++++++ 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/desk/app/channels-server.hoon b/desk/app/channels-server.hoon index 00f975f9ec..3276972a91 100644 --- a/desk/app/channels-server.hoon +++ b/desk/app/channels-server.hoon @@ -16,7 +16,7 @@ |% +$ card card:agent:gall +$ current-state - $: %5 + $: %6 =v-channels:c =pimp:imp == @@ -91,15 +91,32 @@ =? old ?=(%2 -.old) (state-2-to-3 old) =? old ?=(%3 -.old) (state-3-to-4 old) =? old ?=(%4 -.old) (state-4-to-5 old) - ?> ?=(%5 -.old) + =? old ?=(%5 -.old) (state-5-to-6 old) + ?> ?=(%6 -.old) =. state old inflate-io :: - +$ versioned-state $%(state-5 state-4 state-3 state-2 state-1 state-0) - +$ state-5 current-state + +$ versioned-state $%(state-6 state-5 state-4 state-3 state-2 state-1 state-0) + +$ state-6 current-state + +$ state-5 + $: %5 + =v-channels:v6:old:c + =pimp:imp + == + ++ state-5-to-6 + |= state-5 + ^- state-6 + [%6 (v-channels-5-to-6 v-channels) pimp] + ++ v-channels-5-to-6 + |= vc=v-channels:v6:old:c + ^- v-channels:c + %- ~(run by vc) + |= v=v-channel:v6:old:c + ^- v-channel:c + v(pending [pending.v *(map time id-post:c)]) +$ state-4 $: %4 - =v-channels:c + =v-channels:v6:old:c == ++ state-4-to-5 |= state-4 @@ -113,7 +130,7 @@ :: ++ v-channel-2-to-3 |= v=v-channel-2 - ^- v-channel:c + ^- v-channel:v6:old:c v(future [future.v *pending-messages:c]) ++ v-channels-2 (map nest:c v-channel-2) ++ v-channel-2 diff --git a/desk/app/channels.hoon b/desk/app/channels.hoon index e7b98925b2..457936c221 100644 --- a/desk/app/channels.hoon +++ b/desk/app/channels.hoon @@ -27,7 +27,7 @@ |% +$ card card:agent:gall +$ current-state - $: %6 + $: %7 =v-channels:c voc=(map [nest:c plan:c] (unit said:c)) hidden-posts=(set id-post:c) @@ -122,15 +122,48 @@ =? old ?=(%3 -.old) (state-3-to-4 old) =? old ?=(%4 -.old) (state-4-to-5 old) =? old ?=(%5 -.old) (state-5-to-6 old) - ?> ?=(%6 -.old) + =? old ?=(%6 -.old) (state-6-to-7 old) + ?> ?=(%7 -.old) =. state old inflate-io :: - +$ versioned-state $%(state-6 state-5 state-4 state-3 state-2 state-1 state-0) - +$ state-6 current-state + +$ versioned-state + $% state-7 + state-6 + state-5 + state-4 + state-3 + state-2 + state-1 + state-0 + == + +$ state-7 current-state + +$ state-6 + $: %6 + =v-channels:v6:old:c + voc=(map [nest:c plan:c] (unit said:c)) + hidden-posts=(set id-post:c) + :: + :: .pending-ref-edits: for migration, see also +poke %negotiate-notif + :: + pending-ref-edits=(jug ship [=kind:c name=term]) + :: delayed resubscribes + =^subs:s + =pimp:imp + == + ++ state-6-to-7 + |= s=state-6 + ^- state-7 + s(- %7, v-channels (v-channels-6-to-7 v-channels.s)) + ++ v-channels-6-to-7 + |= vc=v-channels:v6:old:c + ^- v-channels:c + %- ~(run by vc) + |= v=v-channel:v6:old:c + v(pending [pending.v *(map time id-post:c)]) +$ state-5 $: %5 - =v-channels:c + =v-channels:v6:old:c voc=(map [nest:c plan:c] (unit said:c)) hidden-posts=(set id-post:c) :: @@ -148,7 +181,7 @@ :: +$ state-4 $: %4 - =v-channels:c + =v-channels:v6:old:c voc=(map [nest:c plan:c] (unit said:c)) pins=(list nest:c) hidden-posts=(set id-post:c) @@ -261,7 +294,7 @@ == ++ v-channel-2-to-3 |= v=v-channel-2 - ^- v-channel:c + ^- v-channel:v6:old:c v(future [future.v *pending-messages:c]) ++ v-channel-1-to-2 |= v=v-channel-1 @@ -1304,7 +1337,8 @@ |= [=time =u-channel:c] ?> ca-from-host ^+ ca-core - =. log.channel (put:log-on:c log.channel time u-channel) + =? last-updated.channel ?=(%post -.u-channel) + (~(put by last-updated.channel) time id.u-channel) ?- -.u-channel %create ?. =(0 rev.perm.channel) ca-core diff --git a/desk/sur/channels.hoon b/desk/sur/channels.hoon index 793c65d6e7..313f2b8782 100644 --- a/desk/sur/channels.hoon +++ b/desk/sur/channels.hoon @@ -61,6 +61,7 @@ =window =future pending=pending-messages + last-updated=(map time id-post) == -- :: $v-post: a channel post @@ -526,6 +527,21 @@ ++ on-simple-replies ((on id-reply simple-reply) lte) ++ old |% + ++ v6 + |% + ++ v-channels (map nest v-channel) + ++ v-channel + |^ ,[global:^v-channel local] + +$ local + $: =net + =log + =remark + =window:^v-channel + =future:^v-channel + pending=pending-messages + == + -- + -- ++ v1 |% +$ post [seal [rev=@ud essay]] From 0e22abed685e1d956ea3a323484ca9665d4d00e1 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Mon, 19 Aug 2024 17:01:45 -0400 Subject: [PATCH 05/33] invalidate non active queries, fix unread state for subsequently returned to channels/threads --- packages/app/features/top/ChannelScreen.tsx | 15 ++++++++++++++- packages/app/features/top/PostScreen.tsx | 15 ++++++++++++++- packages/shared/src/db/queries.ts | 4 ++-- packages/shared/src/db/query.ts | 1 - packages/shared/src/store/dbHooks.ts | 6 +----- packages/ui/src/components/Channel/index.tsx | 19 ++++++++++--------- .../src/components/DetailView/DetailView.tsx | 10 +++++----- packages/ui/src/components/PostScreenView.tsx | 12 +++++++----- packages/ui/src/hooks/useStickyUnread.ts | 19 ------------------- 9 files changed, 53 insertions(+), 48 deletions(-) delete mode 100644 packages/ui/src/hooks/useStickyUnread.ts diff --git a/packages/app/features/top/ChannelScreen.tsx b/packages/app/features/top/ChannelScreen.tsx index 1c1ecc101e..b86fc33732 100644 --- a/packages/app/features/top/ChannelScreen.tsx +++ b/packages/app/features/top/ChannelScreen.tsx @@ -15,7 +15,7 @@ import { ChatOptionsProvider, INITIAL_POSTS_PER_PAGE, } from '@tloncorp/ui'; -import React, { useCallback, useEffect, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useChannelContext } from '../../hooks/useChannelContext'; import { useChatSettingsNavigation } from '../../hooks/useChatSettingsNavigation'; @@ -67,6 +67,18 @@ export default function ChannelScreen({ channelFromParams.id ); + // for the unread channel divider, we care about the unread state when you enter but don't want it to update over + // time + const [initialChannelUnread, setInitialChannelUnread] = + React.useState(null); + useEffect(() => { + async function initializeChannelUnread() { + const unread = await db.getChannelUnread({ channelId: currentChannelId }); + setInitialChannelUnread(unread ?? null); + } + initializeChannelUnread(); + }, []); + const { negotiationStatus, getDraft, @@ -251,6 +263,7 @@ export default function ChannelScreen({ (null); + useEffect(() => { + async function initializeChannelUnread() { + const unread = await db.getThreadUnreadState({ parentId: postParam.id }); + setInitialThreadUnread(unread ?? null); + } + initializeChannelUnread(); + }, []); + const { data: post } = store.usePostWithThreadUnreads({ id: postParam.id, }); @@ -109,6 +121,7 @@ export default function PostScreen({ parentPost={post} posts={posts} channel={channel} + initialThreadUnread={initialThreadUnread} goBack={goBack} sendReply={sendReply} groupMembers={group?.members ?? []} diff --git a/packages/shared/src/db/queries.ts b/packages/shared/src/db/queries.ts index 3b02ca2c23..c5e2db7925 100644 --- a/packages/shared/src/db/queries.ts +++ b/packages/shared/src/db/queries.ts @@ -97,7 +97,7 @@ import { VolumeSettings, } from './types'; -const logger = createDevLogger('queries', false); +const logger = createDevLogger('queries', true); const GROUP_META_COLUMNS = { id: true, @@ -1383,7 +1383,7 @@ export const getChannelWithRelations = createReadQuery( }); return returnNullIfUndefined(result); }, - ['channels', 'volumeSettings', 'pins', 'groups', 'contacts'] + ['channels', 'volumeSettings', 'pins', 'groups', 'contacts', 'channelUnreads'] ); export const getStaleChannels = createReadQuery( diff --git a/packages/shared/src/db/query.ts b/packages/shared/src/db/query.ts index 0544c15b04..54f2cda222 100644 --- a/packages/shared/src/db/query.ts +++ b/packages/shared/src/db/query.ts @@ -168,7 +168,6 @@ export async function withCtxOrDefault( const invalidated: string[] = []; queryClient.invalidateQueries({ fetchStatus: 'idle', - type: 'active', predicate: (query) => { const tableKey = query.queryKey[1]; const shouldInvalidate = diff --git a/packages/shared/src/store/dbHooks.ts b/packages/shared/src/store/dbHooks.ts index 7a5559d539..96967fd44b 100644 --- a/packages/shared/src/store/dbHooks.ts +++ b/packages/shared/src/store/dbHooks.ts @@ -8,11 +8,7 @@ import { useMemo } from 'react'; import * as api from '../api'; import * as db from '../db'; import * as ub from '../urbit'; -import { - getIsHosted, - hasCustomS3Creds, - hasHostingUploadCreds, -} from './storage'; +import { hasCustomS3Creds, hasHostingUploadCreds } from './storage'; import { syncPostReference } from './sync'; import { keyFromQueryDeps, useKeyFromQueryDeps } from './useKeyFromQueryDeps'; diff --git a/packages/ui/src/components/Channel/index.tsx b/packages/ui/src/components/Channel/index.tsx index a25508a9b5..5c44feb7e4 100644 --- a/packages/ui/src/components/Channel/index.tsx +++ b/packages/ui/src/components/Channel/index.tsx @@ -25,7 +25,6 @@ import { import { Attachment, AttachmentProvider } from '../../contexts/attachment'; import { RequestsProvider } from '../../contexts/requests'; import { ScrollContextProvider } from '../../contexts/scroll'; -import { useStickyUnread } from '../../hooks/useStickyUnread'; import * as utils from '../../utils'; import AddGalleryPost from '../AddGalleryPost'; import { BigInput } from '../BigInput'; @@ -51,6 +50,7 @@ const useApp = () => {}; export function Channel({ channel, + initialChannelUnread, currentUserId, posts, selectedPostId, @@ -92,6 +92,7 @@ export function Channel({ initialAttachments, }: { channel: db.Channel; + initialChannelUnread?: db.ChannelUnread | null; currentUserId: string; selectedPostId?: string | null; headerMode?: 'default' | 'next'; @@ -143,7 +144,6 @@ export function Channel({ const canWrite = utils.useCanWrite(channel, currentUserId); const isChatChannel = channel ? getIsChatChannel(channel) : true; - const channelUnread = useStickyUnread(channel.unread); const renderItem = isChatChannel ? ChatMessage : channel.type === 'notebook' @@ -186,13 +186,13 @@ export function Channel({ return { type: 'selected', postId: selectedPostId }; } else if ( channel.type !== 'gallery' && - channelUnread?.countWithoutThreads && - channelUnread.firstUnreadPostId + initialChannelUnread?.countWithoutThreads && + initialChannelUnread.firstUnreadPostId ) { - return { type: 'unread', postId: channelUnread.firstUnreadPostId }; + return { type: 'unread', postId: initialChannelUnread.firstUnreadPostId }; } return null; - }, [channel.type, selectedPostId, channelUnread]); + }, [channel.type, selectedPostId, initialChannelUnread]); const bigInputGoBack = () => { setShowBigInput(false); @@ -366,13 +366,14 @@ export function Channel({ channelType={channel.type} channelId={channel.id} firstUnreadId={ - channelUnread?.countWithoutThreads ?? + initialChannelUnread?.countWithoutThreads ?? 0 > 0 - ? channelUnread?.firstUnreadPostId + ? initialChannelUnread?.firstUnreadPostId : null } unreadCount={ - channelUnread?.countWithoutThreads ?? 0 + initialChannelUnread?.countWithoutThreads ?? + 0 } onPressPost={ isChatChannel ? undefined : goToPost diff --git a/packages/ui/src/components/DetailView/DetailView.tsx b/packages/ui/src/components/DetailView/DetailView.tsx index 273fd519b1..07ed52f673 100644 --- a/packages/ui/src/components/DetailView/DetailView.tsx +++ b/packages/ui/src/components/DetailView/DetailView.tsx @@ -13,7 +13,6 @@ import { withStaticProperties, } from 'tamagui'; -import { useStickyUnread } from '../../hooks/useStickyUnread'; import AuthorRow from '../AuthorRow'; import { BigInput } from '../BigInput'; import Scroller from '../Channel/Scroller'; @@ -23,6 +22,7 @@ import { DEFAULT_MESSAGE_INPUT_HEIGHT } from '../MessageInput/index.native'; export interface DetailViewProps { post: db.Post; + initialPostUnread?: db.ThreadUnreadState | null; children?: JSX.Element; editingPost?: db.Post; setEditingPost?: (post: db.Post | undefined) => void; @@ -100,6 +100,7 @@ const DetailViewHeaderComponentFrame = ({ const DetailViewFrameComponent = ({ post, + initialPostUnread, editingPost, setEditingPost, editPost, @@ -119,7 +120,6 @@ const DetailViewFrameComponent = ({ DEFAULT_MESSAGE_INPUT_HEIGHT ); const [activeMessage, setActiveMessage] = useState(null); - const threadUnread = useStickyUnread(post?.threadUnread); const [inputShouldBlur, setInputShouldBlur] = useState(false); const { bottom } = useSafeAreaInsets(); const isEditingParent = useMemo(() => { @@ -169,11 +169,11 @@ const DetailViewFrameComponent = ({ onPressRetry={onPressRetry} onPressDelete={onPressDelete} firstUnreadId={ - threadUnread?.count ?? 0 > 0 - ? threadUnread?.firstUnreadPostId + initialPostUnread?.count ?? 0 > 0 + ? initialPostUnread?.firstUnreadPostId : null } - unreadCount={threadUnread?.count ?? 0} + unreadCount={initialPostUnread?.count ?? 0} activeMessage={activeMessage} setActiveMessage={setActiveMessage} /> diff --git a/packages/ui/src/components/PostScreenView.tsx b/packages/ui/src/components/PostScreenView.tsx index 822055d917..dbe2da1e2b 100644 --- a/packages/ui/src/components/PostScreenView.tsx +++ b/packages/ui/src/components/PostScreenView.tsx @@ -9,7 +9,6 @@ import { Text, View, YStack } from 'tamagui'; import { AppDataContextProvider, CalmProvider, CalmState } from '../contexts'; import { AttachmentProvider } from '../contexts/attachment'; -import { useStickyUnread } from '../hooks/useStickyUnread'; import * as utils from '../utils'; import { ChannelFooter } from './Channel/ChannelFooter'; import { ChannelHeader } from './Channel/ChannelHeader'; @@ -24,6 +23,7 @@ export function PostScreenView({ currentUserId, contacts, channel, + initialThreadUnread, parentPost, posts, sendReply, @@ -49,6 +49,7 @@ export function PostScreenView({ calmSettings?: CalmState | null; contacts: db.Contact[] | null; channel: db.Channel; + initialThreadUnread?: db.ThreadUnreadState | null; group?: db.Group | null; parentPost: db.Post | null; posts: db.Post[] | null; @@ -79,7 +80,6 @@ export function PostScreenView({ const [inputShouldBlur, setInputShouldBlur] = useState(false); const canWrite = utils.useCanWrite(channel, currentUserId); const isChatChannel = channel ? getIsChatChannel(channel) : true; - const threadUnread = useStickyUnread(parentPost?.threadUnread); const postsWithoutParent = useMemo( () => posts?.filter((p) => p.id !== parentPost?.id) ?? [], [posts, parentPost] @@ -124,6 +124,7 @@ export function PostScreenView({ {parentPost && channel.type === 'gallery' && ( 0 - ? threadUnread?.firstUnreadPostId + initialThreadUnread?.count ?? 0 > 0 + ? initialThreadUnread?.firstUnreadPostId : null } - unreadCount={threadUnread?.count ?? 0} + unreadCount={initialThreadUnread?.count ?? 0} activeMessage={activeMessage} setActiveMessage={setActiveMessage} /> diff --git a/packages/ui/src/hooks/useStickyUnread.ts b/packages/ui/src/hooks/useStickyUnread.ts deleted file mode 100644 index 29b5f78874..0000000000 --- a/packages/ui/src/hooks/useStickyUnread.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as db from '@tloncorp/shared/dist/db'; -import { useMemo } from 'react'; - -type AnyUnread = db.ChannelUnread | db.ThreadUnreadState; -type UnreadInput = AnyUnread | null | undefined; - -// Once the channel is mounted, we want to preserve the initial unread state / -// banner unless cleared explicitly (which functionality doesn't yet exist). -export function useStickyUnread(unread: T): T { - return useMemo( - () => { - return unread; - }, - // we don't want this to change unless we're actually navigating to a - // different channel - // eslint-disable-next-line - [unread?.channelId] - ); -} From 947e101e03e2d801f63874f850cf6a7e08a3de57 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Mon, 19 Aug 2024 17:09:08 -0400 Subject: [PATCH 06/33] caught it this time --- packages/shared/src/db/queries.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/db/queries.ts b/packages/shared/src/db/queries.ts index c5e2db7925..b82e0709ed 100644 --- a/packages/shared/src/db/queries.ts +++ b/packages/shared/src/db/queries.ts @@ -97,7 +97,7 @@ import { VolumeSettings, } from './types'; -const logger = createDevLogger('queries', true); +const logger = createDevLogger('queries', false); const GROUP_META_COLUMNS = { id: true, From 2f1c894512c2adbe7a5dcdcb01a157d68f926d01 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Mon, 19 Aug 2024 17:17:48 -0400 Subject: [PATCH 07/33] use initial unread for cursor too --- packages/app/features/top/ChannelScreen.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/app/features/top/ChannelScreen.tsx b/packages/app/features/top/ChannelScreen.tsx index b86fc33732..33315bc8c6 100644 --- a/packages/app/features/top/ChannelScreen.tsx +++ b/packages/app/features/top/ChannelScreen.tsx @@ -122,16 +122,15 @@ export default function ChannelScreen({ if (!channel) { return undefined; } - const unread = channel?.unread; const firstUnreadId = - unread && - (unread.countWithoutThreads ?? 0) > 0 && - unread?.firstUnreadPostId; + initialChannelUnread && + (initialChannelUnread.countWithoutThreads ?? 0) > 0 && + initialChannelUnread?.firstUnreadPostId; return selectedPostId || firstUnreadId; // We only want this to rerun when the channel is loaded for the first time OR if // the selected post route param changes // eslint-disable-next-line - }, [!!channel, selectedPostId]); + }, [initialChannelUnread, selectedPostId]); useEffect(() => { if (channel?.id) { From 0c68b16fbd4cf7d3b3e9f91feb4d18f29ca58b66 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Mon, 19 Aug 2024 16:27:43 -0500 Subject: [PATCH 08/33] channels: new changes endpoint --- desk/app/channels-server.hoon | 2 +- desk/app/channels.hoon | 91 ++++++++++++++++++++--------------- desk/sur/channels.hoon | 4 +- 3 files changed, 55 insertions(+), 42 deletions(-) diff --git a/desk/app/channels-server.hoon b/desk/app/channels-server.hoon index 3276972a91..8ba00a11d6 100644 --- a/desk/app/channels-server.hoon +++ b/desk/app/channels-server.hoon @@ -113,7 +113,7 @@ %- ~(run by vc) |= v=v-channel:v6:old:c ^- v-channel:c - v(pending [pending.v *(map time id-post:c)]) + v(pending [pending.v *last-updated:c]) +$ state-4 $: %4 =v-channels:v6:old:c diff --git a/desk/app/channels.hoon b/desk/app/channels.hoon index 457936c221..893717ad78 100644 --- a/desk/app/channels.hoon +++ b/desk/app/channels.hoon @@ -15,6 +15,7 @@ :: performance, keep warm /+ channel-json :: +=/ verbose & %- %- agent:neg :+ notify=& [~.channels^%1 ~ ~] @@ -99,6 +100,11 @@ ++ emil |=(caz=(list card) cor(cards (welp (flop caz) cards))) ++ give |=(=gift:agent:gall (emit %give gift)) ++ server (cat 3 dap.bowl '-server') +++ log + |= msg=(trap tape) + ?. verbose same + (slog leaf+"%{(trip dap.bowl)} {(msg)}" ~) +:: :: :: does not overwite if wire and dock exist. maybe it should :: leave/rewatch if the path differs? @@ -160,7 +166,7 @@ ^- v-channels:c %- ~(run by vc) |= v=v-channel:v6:old:c - v(pending [pending.v *(map time id-post:c)]) + v(pending [pending.v *last-updated:c]) +$ state-5 $: %5 =v-channels:v6:old:c @@ -1338,7 +1344,15 @@ ?> ca-from-host ^+ ca-core =? last-updated.channel ?=(%post -.u-channel) - (~(put by last-updated.channel) time id.u-channel) + =/ id id.u-channel + =- (put:updated-on:c - time id.u-channel) + :: delete old entry so we don't have two entries for the same post + %+ gas:updated-on:c *last-updated:c + %+ murn + (tap:updated-on:c last-updated.channel) + |= [=^time =id-post:c] + ?: =(id id-post) ~ + `[time id-post] ?- -.u-channel %create ?. =(0 rev.perm.channel) ca-core @@ -1981,54 +1995,51 @@ %v2 give-posts-2 == :: - [%changes before=@ limit=@ ~] - =/ before=id-post:c - ?^ tim=(slaw %da before.pole) u.tim - (slav %ud before.pole) - =/ limit=@ud ::$@([%count @ud] [%time @da]) ::TODO support? - :: ?^ tim=(slaw %da limit.pole) [%time u.tim] - :: [%count (slav %ud limit.pole)] - (slav %ud limit.pole) - =; [older=(unit time) posts=v-posts:c] + [%changes start=@ end=@ after=@ ~] + =/ start=id-post:c + ?^ tim=(slaw %da start.pole) u.tim + (slav %ud start.pole) + =/ end=id-post:c + ?^ tim=(slaw %da end.pole) u.tim + (slav %ud end.pole) + =/ after=id-post:c + ?^ tim=(slaw %da after.pole) u.tim + (slav %ud after.pole) + =; posts=v-posts:c ?: ?=(%v2 version) =/ =paged-posts:c - [(uv-posts-2:utils posts) `before older (wyt:on-v-posts:c posts)] + [(uv-posts-2:utils posts) ~ ~ (wyt:on-v-posts:c posts)] ``channel-posts-2+!>(paged-posts) =/ =paged-posts:v1:old:c - [(uv-posts:utils posts) `before older (wyt:on-v-posts:c posts)] + [(uv-posts:utils posts) ~ ~ (wyt:on-v-posts:c posts)] ``channel-posts+!>(paged-posts) :: walk both posts and logs, in chronological order, newest-first, :: until we accumulate the desired amount of results :: ::NOTE would manually walk the tree, but logic gets rather confusing, :: so we just eat the conversion overhead here - =/ posts (bap:on-v-posts:c (lot:on-v-posts:c posts.channel ~ `before)) - =/ logs (bap:log-on:c (lot:log-on:c log.channel ~ `before)) - =| s=[=_limit older=_`(unit time)`(some before) out=v-posts:c] - =< [older out] - |- ^+ s - ?: =(0 limit.s) s - ?~ posts - :: cannot have logs if posts already empty ::REVIEW right? - :: - s(older ~) - =* pit key.i.posts - =/ lit ?~(logs pit key.i.logs) - ?: (gte pit lit) - :: post is newer than logs - :: - =? s !(has:on-v-posts:c out.s pit) - [(dec limit.s) `pit (put:on-v-posts:c out.s i.posts)] - $(posts t.posts) - :: log is newer than posts - :: - ?> ?=(^ logs) - ?. ?=(%post -.val.i.logs) $(logs t.logs) - =* id id.val.i.logs - =? s !(has:on-v-posts:c out.s id) - :+ (dec limit.s) `lit - (put:on-v-posts:c out.s id (got:on-v-posts:c posts.channel id)) - $(logs t.logs) + =/ posts (lot:on-v-posts:c posts.channel `(sub start 1) `(add end 1)) + =/ logs (tap:log-on:c (lot:log-on:c log.channel `after ~)) + =/ updated (tap:updated-on:c (lot:updated-on:c last-updated.channel `after ~)) + %- (log |.("posts: {<(lent posts)>}")) + %- (log |.("updated: {<(lent updated)>}")) + %- (log |.("start: {}")) + %- (log |.("end: {}")) + =| out=v-posts:c + |- ^+ out + :: no posts in this range + ?~ posts ~ + :: no changes after this point + ?~ updated out + =* changed val.i.updated + %- (log |.("changed post: {}")) + %- (log |.(" gte start: {<(gte changed start)>}")) + %- (log |.(" lte end: {<(lte changed end)>}")) + :: if the post is not in our subset, skip + ?~ post=(get:on-v-posts:c posts changed) + $(updated t.updated) + =. out (put:on-v-posts:c out changed u.post) + $(updated t.updated) :: [%post time=@ ~] =/ time (slav %ud time.pole) diff --git a/desk/sur/channels.hoon b/desk/sur/channels.hoon index 313f2b8782..23ebd37d77 100644 --- a/desk/sur/channels.hoon +++ b/desk/sur/channels.hoon @@ -61,9 +61,11 @@ =window =future pending=pending-messages - last-updated=(map time id-post) + =last-updated == -- ++$ last-updated ((mop time id-post) lte) +++ updated-on ((on time id-post) lte) :: $v-post: a channel post :: +$ v-post [v-seal (rev essay)] From 7cacaf7723b39209df75d4e72924ec85e957d5ee Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Mon, 19 Aug 2024 17:38:45 -0400 Subject: [PATCH 09/33] account for feature flagged channel switcher --- packages/app/features/top/ChannelScreen.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app/features/top/ChannelScreen.tsx b/packages/app/features/top/ChannelScreen.tsx index 33315bc8c6..aeee5439aa 100644 --- a/packages/app/features/top/ChannelScreen.tsx +++ b/packages/app/features/top/ChannelScreen.tsx @@ -15,7 +15,7 @@ import { ChatOptionsProvider, INITIAL_POSTS_PER_PAGE, } from '@tloncorp/ui'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import { useChannelContext } from '../../hooks/useChannelContext'; import { useChatSettingsNavigation } from '../../hooks/useChatSettingsNavigation'; @@ -77,7 +77,7 @@ export default function ChannelScreen({ setInitialChannelUnread(unread ?? null); } initializeChannelUnread(); - }, []); + }, [currentChannelId]); const { negotiationStatus, From 06d3442e35698e893ccc0a18c1c90e41b54fc1de Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Mon, 19 Aug 2024 16:40:04 -0500 Subject: [PATCH 10/33] channels: give cursors and turn off logs --- desk/app/channels.hoon | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/desk/app/channels.hoon b/desk/app/channels.hoon index 893717ad78..1bf7a7384d 100644 --- a/desk/app/channels.hoon +++ b/desk/app/channels.hoon @@ -15,7 +15,7 @@ :: performance, keep warm /+ channel-json :: -=/ verbose & +=/ verbose | %- %- agent:neg :+ notify=& [~.channels^%1 ~ ~] @@ -2008,7 +2008,15 @@ =; posts=v-posts:c ?: ?=(%v2 version) =/ =paged-posts:c - [(uv-posts-2:utils posts) ~ ~ (wyt:on-v-posts:c posts)] + :* (uv-posts-2:utils posts) + ?~ newer=(tab:on-v-posts:c posts.channel `end 1) + ~ + `key:(head newer) + ?~ older=(bat:mo-v-posts:c posts.channel `start 1) + ~ + `key:(head older) + (wyt:on-v-posts:c posts) + == ``channel-posts-2+!>(paged-posts) =/ =paged-posts:v1:old:c [(uv-posts:utils posts) ~ ~ (wyt:on-v-posts:c posts)] From fb379227c7b9057b4a653a2c8a5c3eb4d0beb42d Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 20 Aug 2024 15:16:58 +0000 Subject: [PATCH 11/33] update glob: [skip actions] --- desk/desk.docket-0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desk/desk.docket-0 b/desk/desk.docket-0 index abfa309f50..127d0c188e 100644 --- a/desk/desk.docket-0 +++ b/desk/desk.docket-0 @@ -2,7 +2,7 @@ info+'Start, host, and cultivate communities. Own your communications, organize your resources, and share documents. Tlon is a decentralized platform that offers a full, communal suite of tools for messaging, writing and sharing media with others.' color+0xde.dede image+'https://bootstrap.urbit.org/tlon.svg?v=1' - glob-http+['https://bootstrap.urbit.org/glob-0v2.mlvla.tg7kv.3srrv.71o2i.ad9oa.glob' 0v2.mlvla.tg7kv.3srrv.71o2i.ad9oa] + glob-http+['https://bootstrap.urbit.org/glob-0v3.nctdb.a4q27.vilgb.d7hmo.airq8.glob' 0v3.nctdb.a4q27.vilgb.d7hmo.airq8] base+'groups' version+[6 1 0] website+'https://tlon.io' From 35c012bbc9eb04139c8da7c24d71cf1fad054598 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Tue, 20 Aug 2024 12:00:39 -0500 Subject: [PATCH 12/33] app-nav: make link a link --- apps/tlon-web/src/components/Sidebar/AppNav.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/tlon-web/src/components/Sidebar/AppNav.tsx b/apps/tlon-web/src/components/Sidebar/AppNav.tsx index cea0c33f52..628464d8c4 100644 --- a/apps/tlon-web/src/components/Sidebar/AppNav.tsx +++ b/apps/tlon-web/src/components/Sidebar/AppNav.tsx @@ -360,15 +360,16 @@ function ProfileTab(props: { isInactive: boolean }) { function LandscapeTab() { return ( -
window.open('/apps/landscape', '_blank')} > -
+ ); } From 3d9971e5523bff8ff882de0eb4d3c601c20c4f40 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 20 Aug 2024 17:05:49 +0000 Subject: [PATCH 13/33] update glob: [skip actions] --- desk/desk.docket-0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desk/desk.docket-0 b/desk/desk.docket-0 index 127d0c188e..5225d20419 100644 --- a/desk/desk.docket-0 +++ b/desk/desk.docket-0 @@ -2,7 +2,7 @@ info+'Start, host, and cultivate communities. Own your communications, organize your resources, and share documents. Tlon is a decentralized platform that offers a full, communal suite of tools for messaging, writing and sharing media with others.' color+0xde.dede image+'https://bootstrap.urbit.org/tlon.svg?v=1' - glob-http+['https://bootstrap.urbit.org/glob-0v3.nctdb.a4q27.vilgb.d7hmo.airq8.glob' 0v3.nctdb.a4q27.vilgb.d7hmo.airq8] + glob-http+['https://bootstrap.urbit.org/glob-0v4.hirib.3mfdp.qdglf.e0kss.i2sgs.glob' 0v4.hirib.3mfdp.qdglf.e0kss.i2sgs] base+'groups' version+[6 1 0] website+'https://tlon.io' From 42598a4d0b1ac093a75af441c6c8782765638df3 Mon Sep 17 00:00:00 2001 From: David Lee Date: Mon, 19 Aug 2024 21:36:18 -0700 Subject: [PATCH 14/33] Prevent switches from getting shrunk --- packages/ui/src/components/FeatureFlagScreenView.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/FeatureFlagScreenView.tsx b/packages/ui/src/components/FeatureFlagScreenView.tsx index 6c6eaf3304..1605b6b253 100644 --- a/packages/ui/src/components/FeatureFlagScreenView.tsx +++ b/packages/ui/src/components/FeatureFlagScreenView.tsx @@ -35,8 +35,9 @@ export function FeatureFlagScreenView({ alignItems="center" padding="$l" > - {feature.label} + {feature.label} onFlagToggled(feature.name, enabled) From ae3c1fd657eb30ecb29c71e400e02d072a1d4970 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 09:43:50 -0700 Subject: [PATCH 15/33] Install Firebase performance monitoring plugin --- apps/tlon-mobile/app.config.ts | 1 + apps/tlon-mobile/firebase.json | 3 +- apps/tlon-mobile/ios/Podfile.lock | 47 ++++++++++++++++++++++++++++++- apps/tlon-mobile/package.json | 1 + 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/apps/tlon-mobile/app.config.ts b/apps/tlon-mobile/app.config.ts index 35c4b3cda8..97f909c678 100644 --- a/apps/tlon-mobile/app.config.ts +++ b/apps/tlon-mobile/app.config.ts @@ -56,6 +56,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ plugins: [ '@react-native-firebase/app', '@react-native-firebase/crashlytics', + '@react-native-firebase/perf', [ 'expo-image-picker', { diff --git a/apps/tlon-mobile/firebase.json b/apps/tlon-mobile/firebase.json index 719329b38b..1a76524a2f 100644 --- a/apps/tlon-mobile/firebase.json +++ b/apps/tlon-mobile/firebase.json @@ -1,5 +1,6 @@ { "react-native": { - "crashlytics_debug_enabled": false + "crashlytics_debug_enabled": false, + "perf_auto_collection_enabled": false } } diff --git a/apps/tlon-mobile/ios/Podfile.lock b/apps/tlon-mobile/ios/Podfile.lock index c87b70e3c2..43335525d4 100644 --- a/apps/tlon-mobile/ios/Podfile.lock +++ b/apps/tlon-mobile/ios/Podfile.lock @@ -162,6 +162,11 @@ PODS: - Firebase/Crashlytics (10.24.0): - Firebase/CoreOnly - FirebaseCrashlytics (~> 10.24.0) + - Firebase/Performance (10.24.0): + - Firebase/CoreOnly + - FirebasePerformance (~> 10.24.0) + - FirebaseABTesting (10.29.0): + - FirebaseCore (~> 10.0) - FirebaseCore (10.24.0): - FirebaseCoreInternal (~> 10.0) - GoogleUtilities/Environment (~> 7.12) @@ -184,6 +189,24 @@ PODS: - GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/UserDefaults (~> 7.8) - PromisesObjC (~> 2.1) + - FirebasePerformance (10.24.0): + - FirebaseCore (~> 10.5) + - FirebaseInstallations (~> 10.0) + - FirebaseRemoteConfig (~> 10.0) + - FirebaseSessions (~> 10.5) + - GoogleDataTransport (~> 9.2) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/ISASwizzler (~> 7.8) + - GoogleUtilities/MethodSwizzler (~> 7.8) + - nanopb (< 2.30911.0, >= 2.30908.0) + - FirebaseRemoteConfig (10.29.0): + - FirebaseABTesting (~> 10.0) + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - FirebaseRemoteConfigInterop (~> 10.23) + - FirebaseSharedSwift (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - "GoogleUtilities/NSData+zlib (~> 7.8)" - FirebaseRemoteConfigInterop (10.29.0) - FirebaseSessions (10.29.0): - FirebaseCore (~> 10.5) @@ -194,6 +217,7 @@ PODS: - GoogleUtilities/UserDefaults (~> 7.13) - nanopb (< 2.30911.0, >= 2.30908.0) - PromisesSwift (~> 2.1) + - FirebaseSharedSwift (10.29.0) - fmt (6.2.1) - glog (0.3.5) - GoogleDataTransport (9.4.1): @@ -203,9 +227,14 @@ PODS: - GoogleUtilities/Environment (7.13.3): - GoogleUtilities/Privacy - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/ISASwizzler (7.13.3): + - GoogleUtilities/Privacy - GoogleUtilities/Logger (7.13.3): - GoogleUtilities/Environment - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy - "GoogleUtilities/NSData+zlib (7.13.3)": - GoogleUtilities/Privacy - GoogleUtilities/Privacy (7.13.3) @@ -1323,6 +1352,10 @@ PODS: - FirebaseCoreExtension - React-Core - RNFBApp + - RNFBPerf (19.3.0): + - Firebase/Performance (= 10.24.0) + - React-Core + - RNFBApp - RNGestureHandler (2.18.1): - glog - RCT-Folly (= 2022.05.16.00) @@ -1457,6 +1490,7 @@ DEPENDENCIES: - RNDeviceInfo (from `../../../node_modules/react-native-device-info`) - "RNFBApp (from `../../../node_modules/@react-native-firebase/app`)" - "RNFBCrashlytics (from `../../../node_modules/@react-native-firebase/crashlytics`)" + - "RNFBPerf (from `../../../node_modules/@react-native-firebase/perf`)" - RNGestureHandler (from `../../../node_modules/react-native-gesture-handler`) - RNReanimated (from `../../../node_modules/react-native-reanimated`) - RNScreens (from `../../../node_modules/react-native-screens`) @@ -1469,13 +1503,17 @@ SPEC REPOS: trunk: - BranchSDK - Firebase + - FirebaseABTesting - FirebaseCore - FirebaseCoreExtension - FirebaseCoreInternal - FirebaseCrashlytics - FirebaseInstallations + - FirebasePerformance + - FirebaseRemoteConfig - FirebaseRemoteConfigInterop - FirebaseSessions + - FirebaseSharedSwift - fmt - GoogleDataTransport - GoogleUtilities @@ -1685,6 +1723,8 @@ EXTERNAL SOURCES: :path: "../../../node_modules/@react-native-firebase/app" RNFBCrashlytics: :path: "../../../node_modules/@react-native-firebase/crashlytics" + RNFBPerf: + :path: "../../../node_modules/@react-native-firebase/perf" RNGestureHandler: :path: "../../../node_modules/react-native-gesture-handler" RNReanimated: @@ -1740,13 +1780,17 @@ SPEC CHECKSUMS: FBLazyVector: 84f6edbe225f38aebd9deaf1540a4160b1f087d7 FBReactNativeSpec: 4b31c1954525bc2e3a5df4cbbd06fc7ae9191b11 Firebase: 91fefd38712feb9186ea8996af6cbdef41473442 + FirebaseABTesting: d87f56707159bae64e269757a6e963d490f2eebe FirebaseCore: 11dc8a16dfb7c5e3c3f45ba0e191a33ac4f50894 FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934 FirebaseCrashlytics: af38ea4adfa606f6e63fcc22091b61e7938fcf66 FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd + FirebasePerformance: 78fed7cf7907f67af3c1e9667d2d1881765f11e2 + FirebaseRemoteConfig: 48ef3f243742a8d72422ccfc9f986e19d7de53fd FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc + FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a @@ -1817,6 +1861,7 @@ SPEC CHECKSUMS: RNDeviceInfo: db5c64a060e66e5db3102d041ebe3ef307a85120 RNFBApp: 91311b27bc9a33e23b76a62825afd1635501018a RNFBCrashlytics: c3219ef7a0c779f2428236215781c38e7892f6f9 + RNFBPerf: 4206fb79bda0c795c07f50ee11047e10e5f6a50e RNGestureHandler: f42730cc5dc0b50e2b6409e259e8c238356ec0d0 RNReanimated: fb34efce9255966f5d71bd0fc65e14042c4b88a9 RNScreens: 2b73f5eb2ac5d94fbd61fa4be0bfebd345716825 @@ -1829,7 +1874,7 @@ SPEC CHECKSUMS: sqlite3: f163dbbb7aa3339ad8fc622782c2d9d7b72f7e9c tentap: fc7669734b4dea745d6e56f57f5c7dc4fc2977bc UMAppLoader: 5df85360d65cabaef544be5424ac64672e648482 - Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 + Yoga: 64cd2a583ead952b0315d5135bf39e053ae9be70 PODFILE CHECKSUM: 0cb7a78e5777e69c86c1bf4bb5135fd660376dbe diff --git a/apps/tlon-mobile/package.json b/apps/tlon-mobile/package.json index d6cd312c6a..7bfaa7349e 100644 --- a/apps/tlon-mobile/package.json +++ b/apps/tlon-mobile/package.json @@ -50,6 +50,7 @@ "@react-native-community/netinfo": "11.1.0", "@react-native-firebase/app": "^19.2.2", "@react-native-firebase/crashlytics": "^19.2.2", + "@react-native-firebase/perf": "^19.2.2", "@react-navigation/bottom-tabs": "^6.5.12", "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", From f402bcc9cadf451a29dea17ff07302901f9fc93a Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 09:48:37 -0700 Subject: [PATCH 16/33] Add instrumentation provider controlled by feature flag --- apps/tlon-mobile/src/App.main.tsx | 73 ++++++++--------- ...reFlagConnectedInstrumentationProvider.tsx | 18 +++++ packages/app/lib/featureFlags.ts | 4 + packages/shared/package.json | 4 +- packages/shared/src/index.ts | 1 + packages/shared/src/perf.ts | 78 +++++++++++++++++++ pnpm-lock.yaml | 21 +++++ 7 files changed, 163 insertions(+), 36 deletions(-) create mode 100644 apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx create mode 100644 packages/shared/src/perf.ts diff --git a/apps/tlon-mobile/src/App.main.tsx b/apps/tlon-mobile/src/App.main.tsx index 04d22c7cd6..38235c6983 100644 --- a/apps/tlon-mobile/src/App.main.tsx +++ b/apps/tlon-mobile/src/App.main.tsx @@ -30,6 +30,7 @@ import { SafeAreaProvider } from 'react-native-safe-area-context'; import { useTailwind } from 'tailwind-rn'; import AuthenticatedApp from './components/AuthenticatedApp'; +import { FeatureFlagConnectedInstrumentationProvider } from './components/FeatureFlagConnectedInstrumentationProvider'; import { LoadingSpinner } from './components/LoadingSpinner'; import { CheckVerifyScreen } from './screens/CheckVerifyScreen'; import { EULAScreen } from './screens/EULAScreen'; @@ -213,42 +214,44 @@ export default function ConnectedApp(props: Props) { return ( - - - - - - - - - - - - + + + + + + + + + + + + + - {__DEV__ && ( - - )} - - - - - - - - - + {__DEV__ && ( + + )} + + + + + + + + + + ); } diff --git a/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx b/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx new file mode 100644 index 0000000000..e9a30524a6 --- /dev/null +++ b/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx @@ -0,0 +1,18 @@ +import { useFeatureFlag } from '@tloncorp/app/lib/featureFlags'; +import { InstrumentationProvider } from '@tloncorp/shared/dist'; + +export function FeatureFlagConnectedInstrumentationProvider({ + children, +}: { + children: JSX.Element; +}) { + const [isPerformanceCollectionEnabled] = useFeatureFlag( + 'instrumentationEnabled' + ); + + return ( + + {children} + + ); +} diff --git a/packages/app/lib/featureFlags.ts b/packages/app/lib/featureFlags.ts index 80132b5ae6..08dabbab9e 100644 --- a/packages/app/lib/featureFlags.ts +++ b/packages/app/lib/featureFlags.ts @@ -9,6 +9,10 @@ export const featureMeta = { default: false, label: 'Experimental channel switcher', }, + instrumentationEnabled: { + default: false, + label: 'Enable collecting and reporting performance data', + }, } satisfies Record; export type FeatureName = keyof typeof featureMeta; diff --git a/packages/shared/package.json b/packages/shared/package.json index b7e2bdd816..4b0debbffd 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,13 +43,15 @@ "vitest": "^1.4.0" }, "peerDependencies": { + "@react-native-firebase/perf": "^19.2.2", "@tanstack/react-query": "^5.32.1", "@tiptap/core": "^2.0.3", "@tiptap/pm": "^2.0.3", "@tiptap/react": "^2.0.3", "@tiptap/suggestion": "^2.0.3", "drizzle-orm": "0.30.9", - "react": "^18.2.0" + "react": "^18.2.0", + "zustand": "^3.7.2" }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.9.5" diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 627c42ebaf..71a2bef1ae 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -16,3 +16,4 @@ export * as utils from './logic/utils'; export * as tiptap from './logic/tiptap'; export * as utilHooks from './logic/utilHooks'; export * from './debug'; +export * from './perf'; diff --git a/packages/shared/src/perf.ts b/packages/shared/src/perf.ts new file mode 100644 index 0000000000..c4de6e565b --- /dev/null +++ b/packages/shared/src/perf.ts @@ -0,0 +1,78 @@ +import { firebase } from '@react-native-firebase/perf'; +import { useEffect } from 'react'; +import create from 'zustand'; + +interface Trace { + putMetric(metricName: string, value: number): void; + stop(): Promise; +} + +type PerformanceMonitoringStore = { setEnabled: (enabled: boolean) => void } & ( + | { enabled: false } + | { enabled: true; startTrace(identifier: string): Promise } +); + +const usePerformanceMonitoringStore = create( + (set) => ({ + setEnabled: (enabled) => { + // instrumentationEnabled = automatic measurement of HTTP requests, other things? + firebase.perf().instrumentationEnabled = false; + + // dataCollectionEnabled = sending any data to server + firebase.perf().dataCollectionEnabled = enabled; + + set((prev) => ({ + ...prev, + enabled, + ...(enabled + ? { + startTrace(identifier) { + console.log(`Starting trace ${identifier}`); + return firebase.perf().startTrace(identifier); + }, + } + : {}), + })); + }, + enabled: false, + }) +); + +export function useStartTraceCallback(): + | undefined + | ((identifier: string) => Promise) { + return usePerformanceMonitoringStore((s) => + s.enabled ? s.startTrace : undefined + ); +} + +// For use outside of React +export function startTrace(identifier: string): Promise | null { + const store = usePerformanceMonitoringStore.getState(); + if (store.enabled) { + return store.startTrace(identifier); + } else { + return null; + } +} + +export function InstrumentationProvider({ + collectionEnabled, + children, +}: { + collectionEnabled: boolean; + children: JSX.Element; +}) { + const setMonitoringEnabled = usePerformanceMonitoringStore( + (s) => s.setEnabled + ); + + useEffect(() => { + console.log( + `Setting performance monitoring collection enabled to ${collectionEnabled}` + ); + setMonitoringEnabled(collectionEnabled); + }, [collectionEnabled, setMonitoringEnabled]); + + return children; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bdf14c97f4..2673af9eb1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,6 +126,9 @@ importers: '@react-native-firebase/crashlytics': specifier: ^19.2.2 version: 19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) + '@react-native-firebase/perf': + specifier: ^19.2.2 + version: 19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) '@react-navigation/bottom-tabs': specifier: ^6.5.12 version: 6.5.12(@react-navigation/native@6.1.10(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.9.0(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.29.0(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -944,6 +947,9 @@ importers: packages/app: dependencies: + '@react-native-firebase/perf': + specifier: ^19.2.2 + version: 19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) '@tloncorp/shared': specifier: workspace:* version: link:../shared @@ -4082,6 +4088,15 @@ packages: expo: optional: true + '@react-native-firebase/perf@19.3.0': + resolution: {integrity: sha512-d06aKTv/xqLZvjODiajpvIOL/eQzokOaJ///iJT7TkaAGiM7uWiqf5j3QGbg786b4RJclpLYUZpBiimX2T/Xug==} + peerDependencies: + '@react-native-firebase/app': 19.3.0 + expo: '>=47.0.0' + peerDependenciesMeta: + expo: + optional: true + '@react-native-mac/virtualized-lists@0.73.3': resolution: {integrity: sha512-7UcvjGYLIU0s2FzVLUPxHYo68tqtZV6x0AH8B0Hf9mkkpENGdRIKD7wDv0kjb/GkVn+qk94u3u0kQyMNRY9UkQ==} engines: {node: '>=18'} @@ -17460,6 +17475,12 @@ snapshots: optionalDependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) + '@react-native-firebase/perf@19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))': + dependencies: + '@react-native-firebase/app': 19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + optionalDependencies: + expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) + '@react-native-mac/virtualized-lists@0.73.3(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))': dependencies: invariant: 2.2.4 From e926cc6a287c1ca336bf6cc50a45330348f2d437 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 10:06:23 -0700 Subject: [PATCH 17/33] Fix new flags not getting defaults when overwritten by stored values --- packages/app/lib/featureFlags.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/app/lib/featureFlags.ts b/packages/app/lib/featureFlags.ts index 08dabbab9e..3e6ea6c5ec 100644 --- a/packages/app/lib/featureFlags.ts +++ b/packages/app/lib/featureFlags.ts @@ -63,7 +63,10 @@ async function loadInitialState() { if (state) { useFeatureFlagStore.setState((prev) => ({ ...prev, - flags: state, + flags: { + ...prev.flags, + state, + }, })); } } From 8f7bb90b3f29ab263f9ab40ffd8cb105731d10d7 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 10:14:00 -0700 Subject: [PATCH 18/33] Add custom FB perf trace for each query --- packages/shared/src/db/query.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/shared/src/db/query.ts b/packages/shared/src/db/query.ts index 0544c15b04..763792666a 100644 --- a/packages/shared/src/db/query.ts +++ b/packages/shared/src/db/query.ts @@ -2,6 +2,7 @@ import { sql } from 'drizzle-orm'; import { queryClient } from '../api'; import { createDevLogger, escapeLog, listDebugLabel, runIfDev } from '../debug'; +import { startTrace } from '../perf'; import * as changeListener from './changeListener'; import { AnySqliteDatabase, AnySqliteTransaction, client } from './client'; import { TableName } from './types'; @@ -86,6 +87,19 @@ export const createQuery = ( options?: TOptions, ctx?: QueryCtx ): Promise { + // No `awaits`! + // The performance tracing API is necessarily promise-based since we're + // talking to native code, but we don't want to block the query. + const queryTracePromise = + meta.label && startTrace(['query', meta.label].join('.')); + const completeQueryTraceIfPossible = () => { + if (queryTracePromise) { + queryTracePromise.then(async (trace) => { + await trace.stop(); + }); + } + }; + const startTime = Date.now(); // Resolve arguments based on parameter count of query function const [ctxArg, runQuery] = hasNoOptions(queryFn) @@ -102,6 +116,7 @@ export const createQuery = ( return withCtxOrDefault(meta, ctxArg, async (resolvedCtx) => { const result = await runQuery(resolvedCtx); logger.log(meta.label + ':end', Date.now() - startTime + 'ms'); + completeQueryTraceIfPossible(); // Pass pending table effects to query context if (meta?.tableEffects) { const effects = From d6afeb813a4bdb163021d25b74f0e3ee1a21bd0f Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 10:26:17 -0700 Subject: [PATCH 19/33] Remove console.logs --- packages/shared/src/perf.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/shared/src/perf.ts b/packages/shared/src/perf.ts index c4de6e565b..811fd4cf23 100644 --- a/packages/shared/src/perf.ts +++ b/packages/shared/src/perf.ts @@ -27,7 +27,6 @@ const usePerformanceMonitoringStore = create( ...(enabled ? { startTrace(identifier) { - console.log(`Starting trace ${identifier}`); return firebase.perf().startTrace(identifier); }, } @@ -68,9 +67,6 @@ export function InstrumentationProvider({ ); useEffect(() => { - console.log( - `Setting performance monitoring collection enabled to ${collectionEnabled}` - ); setMonitoringEnabled(collectionEnabled); }, [collectionEnabled, setMonitoringEnabled]); From 75b69e96df5911b9fe6fdc3fc8dd9dd8f57d0d77 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 10:32:06 -0700 Subject: [PATCH 20/33] Mock Firebase perf module in test --- packages/shared/src/test/setup.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/shared/src/test/setup.ts b/packages/shared/src/test/setup.ts index 5d598be501..be93d17082 100644 --- a/packages/shared/src/test/setup.ts +++ b/packages/shared/src/test/setup.ts @@ -19,6 +19,12 @@ vi.mock('@react-native-firebase/crashlytics', () => { }; }); +vi.mock('@react-native-firebase/perf', () => { + return { + firebase: vi.fn(), + }; +}); + vi.mock('@react-native-community/netinfo', () => { return { fetch: async () => ({ isConnected: true, type: 'wifi' }), From 38bbbe6663f85118bcf87ef75bf16e000c8efc9f Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 10:32:23 -0700 Subject: [PATCH 21/33] pnpm install --- pnpm-lock.yaml | 257 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 254 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2673af9eb1..4dd2f96249 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -947,9 +947,6 @@ importers: packages/app: dependencies: - '@react-native-firebase/perf': - specifier: ^19.2.2 - version: 19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) '@tloncorp/shared': specifier: workspace:* version: link:../shared @@ -1024,6 +1021,9 @@ importers: '@react-native-async-storage/async-storage': specifier: 1.21.0 version: 1.21.0(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)) + '@react-native-firebase/perf': + specifier: ^19.2.2 + version: 19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) '@tanstack/react-query': specifier: ^5.32.1 version: 5.32.1(react@18.2.0) @@ -1063,6 +1063,9 @@ importers: urbit-ob: specifier: ^5.0.1 version: 5.0.1 + zustand: + specifier: ^3.7.2 + version: 3.7.2(react@18.2.0) optionalDependencies: '@rollup/rollup-linux-x64-gnu': specifier: 4.9.5 @@ -13999,6 +14002,14 @@ snapshots: '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-proposal-decorators@7.23.9(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.25.2) + optional: true + '@babel/plugin-proposal-export-default-from@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -14138,6 +14149,12 @@ snapshots: '@babel/core': 7.23.7 '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.22.5 + optional: true + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -14821,6 +14838,12 @@ snapshots: '@babel/core': 7.23.7 '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.23.7) + '@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.25.2) + optional: true + '@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -14865,6 +14888,13 @@ snapshots: '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-transform-react-pure-annotations@7.23.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + optional: true + '@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -15228,6 +15258,17 @@ snapshots: '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.23.7) '@babel/plugin-transform-react-pure-annotations': 7.23.3(@babel/core@7.23.7) + '@babel/preset-react@7.23.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-transform-react-display-name': 7.23.3(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.25.2) + '@babel/plugin-transform-react-pure-annotations': 7.23.3(@babel/core@7.25.2) + optional: true + '@babel/preset-typescript@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -15772,6 +15813,94 @@ snapshots: - supports-color - utf-8-validate + '@expo/cli@0.17.5(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)(expo-modules-autolinking@1.10.3)': + dependencies: + '@babel/runtime': 7.23.8 + '@expo/code-signing-certificates': 0.0.5 + '@expo/config': 8.5.4 + '@expo/config-plugins': 7.8.4 + '@expo/devcert': 1.1.0 + '@expo/env': 0.2.1 + '@expo/image-utils': 0.4.1(encoding@0.1.13) + '@expo/json-file': 8.3.0 + '@expo/metro-config': 0.17.4(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))) + '@expo/osascript': 2.1.0 + '@expo/package-manager': 1.4.2 + '@expo/plist': 0.1.0 + '@expo/prebuild-config': 6.7.4(encoding@0.1.13)(expo-modules-autolinking@1.10.3) + '@expo/rudder-sdk-node': 1.1.1(encoding@0.1.13) + '@expo/spawn-async': 1.5.0 + '@expo/xcpretty': 4.3.1 + '@react-native/dev-middleware': 0.73.8(encoding@0.1.13) + '@urql/core': 2.3.6(graphql@15.8.0) + '@urql/exchange-retry': 0.3.0(graphql@15.8.0) + accepts: 1.3.8 + arg: 5.0.2 + better-opn: 3.0.2 + bplist-parser: 0.3.2 + cacache: 15.3.0 + chalk: 4.1.2 + ci-info: 3.9.0 + connect: 3.7.0 + debug: 4.3.4 + env-editor: 0.4.2 + find-yarn-workspace-root: 2.0.0 + form-data: 3.0.1 + freeport-async: 2.0.0 + fs-extra: 8.1.0 + getenv: 1.0.0 + glob: 7.2.3 + graphql: 15.8.0 + graphql-tag: 2.12.6(graphql@15.8.0) + https-proxy-agent: 5.0.1 + internal-ip: 4.3.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + js-yaml: 3.14.1 + json-schema-deref-sync: 0.13.0 + lodash.debounce: 4.0.8 + md5hex: 1.0.0 + minimatch: 3.1.2 + minipass: 3.3.6 + node-fetch: 2.6.12(encoding@0.1.13) + node-forge: 1.3.1 + npm-package-arg: 7.0.0 + open: 8.4.2 + ora: 3.4.0 + picomatch: 3.0.1 + pretty-bytes: 5.6.0 + progress: 2.0.3 + prompts: 2.4.2 + qrcode-terminal: 0.11.0 + require-from-string: 2.0.2 + requireg: 0.2.2 + resolve: 1.22.4 + resolve-from: 5.0.0 + resolve.exports: 2.0.2 + semver: 7.6.0 + send: 0.18.0 + slugify: 1.6.6 + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + structured-headers: 0.4.1 + tar: 6.2.0 + temp-dir: 2.0.0 + tempy: 0.7.1 + terminal-link: 2.1.1 + text-table: 0.2.0 + url-join: 4.0.0 + wrap-ansi: 7.0.0 + ws: 8.16.0 + transitivePeerDependencies: + - '@react-native/babel-preset' + - bluebird + - bufferutil + - encoding + - expo-modules-autolinking + - supports-color + - utf-8-validate + optional: true + '@expo/code-signing-certificates@0.0.5': dependencies: node-forge: 1.3.1 @@ -15904,6 +16033,33 @@ snapshots: transitivePeerDependencies: - supports-color + '@expo/metro-config@0.17.4(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))': + dependencies: + '@babel/core': 7.23.7 + '@babel/generator': 7.23.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.9 + '@expo/config': 8.5.4 + '@expo/env': 0.2.1 + '@expo/json-file': 8.3.0 + '@expo/spawn-async': 1.7.2 + '@react-native/babel-preset': 0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)) + babel-preset-fbjs: 3.4.0(@babel/core@7.23.7) + chalk: 4.1.2 + debug: 4.3.4 + find-yarn-workspace-root: 2.0.0 + fs-extra: 9.1.0 + getenv: 1.0.0 + glob: 7.2.3 + jsc-safe-url: 0.2.4 + lightningcss: 1.19.0 + postcss: 8.4.35 + resolve-from: 5.0.0 + sucrase: 3.34.0 + transitivePeerDependencies: + - supports-color + optional: true + '@expo/osascript@2.1.0': dependencies: '@expo/spawn-async': 1.7.2 @@ -17468,6 +17624,15 @@ snapshots: optionalDependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) + '@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': + dependencies: + opencollective-postinstall: 2.0.3 + react: 18.2.0 + react-native: 0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0) + superstruct: 0.6.2 + optionalDependencies: + expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) + '@react-native-firebase/crashlytics@19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))': dependencies: '@react-native-firebase/app': 19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -17481,6 +17646,12 @@ snapshots: optionalDependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) + '@react-native-firebase/perf@19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))': + dependencies: + '@react-native-firebase/app': 19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) + optionalDependencies: + expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) + '@react-native-mac/virtualized-lists@0.73.3(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))': dependencies: invariant: 2.2.4 @@ -20746,6 +20917,22 @@ snapshots: - '@babel/core' - supports-color + babel-preset-expo@10.0.1(@babel/core@7.25.2): + dependencies: + '@babel/plugin-proposal-decorators': 7.23.9(@babel/core@7.25.2) + '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.25.2) + '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.25.2) + '@babel/preset-env': 7.23.7(@babel/core@7.25.2) + '@babel/preset-react': 7.23.3(@babel/core@7.25.2) + '@react-native/babel-preset': 0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)) + babel-plugin-react-native-web: 0.18.12 + react-refresh: 0.14.0 + transitivePeerDependencies: + - '@babel/core' + - supports-color + optional: true + babel-preset-fbjs@3.4.0(@babel/core@7.23.7): dependencies: '@babel/core': 7.23.7 @@ -22427,6 +22614,19 @@ snapshots: - expo - supports-color + expo-asset@9.0.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): + dependencies: + '@react-native/assets-registry': 0.73.1 + blueimp-md5: 2.19.0 + expo-constants: 15.4.5(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) + expo-file-system: 16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) + invariant: 2.2.4 + md5-file: 3.2.3 + transitivePeerDependencies: + - expo + - supports-color + optional: true + expo-av@13.10.6(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22450,6 +22650,14 @@ snapshots: transitivePeerDependencies: - supports-color + expo-constants@15.4.5(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): + dependencies: + '@expo/config': 8.5.4 + expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) + transitivePeerDependencies: + - supports-color + optional: true + expo-dev-client@3.3.9(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22493,11 +22701,22 @@ snapshots: dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) + expo-file-system@16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): + dependencies: + expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) + optional: true + expo-font@11.10.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) fontfaceobserver: 2.3.0 + expo-font@11.10.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): + dependencies: + expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) + fontfaceobserver: 2.3.0 + optional: true + expo-haptics@12.8.1(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22527,6 +22746,11 @@ snapshots: dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) + expo-keep-awake@12.8.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): + dependencies: + expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) + optional: true + expo-linear-gradient@12.7.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22644,6 +22868,33 @@ snapshots: - supports-color - utf-8-validate + expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13): + dependencies: + '@babel/runtime': 7.23.8 + '@expo/cli': 0.17.5(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)(expo-modules-autolinking@1.10.3) + '@expo/config': 8.5.4 + '@expo/config-plugins': 7.8.4 + '@expo/metro-config': 0.17.4(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))) + '@expo/vector-icons': 14.0.0 + babel-preset-expo: 10.0.1(@babel/core@7.25.2) + expo-asset: 9.0.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) + expo-file-system: 16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) + expo-font: 11.10.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) + expo-keep-awake: 12.8.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) + expo-modules-autolinking: 1.10.3 + expo-modules-core: 1.11.8 + fbemitter: 3.0.0(encoding@0.1.13) + whatwg-url-without-unicode: 8.0.0-3 + transitivePeerDependencies: + - '@babel/core' + - '@react-native/babel-preset' + - bluebird + - bufferutil + - encoding + - supports-color + - utf-8-validate + optional: true + exponential-backoff@3.1.1: {} express@4.18.2: From 3284342febdd7fd6125710d930ae3173d4e482e4 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 10:33:54 -0700 Subject: [PATCH 22/33] Explicitly exclude @react-native-firebase/perf from shared bundle --- packages/shared/tsup.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/shared/tsup.config.ts b/packages/shared/tsup.config.ts index 8102813f0e..933323fc5e 100644 --- a/packages/shared/tsup.config.ts +++ b/packages/shared/tsup.config.ts @@ -23,6 +23,7 @@ export default defineConfig({ 'expo-image-picker', 'expo-file-system', '@react-native-firebase/crashlytics', + '@react-native-firebase/perf', '@react-native-community/netinfo', 'expo-battery', ], From 40f7bef8a0d4dd90a5c19d3a6a32f8699f99db27 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 15:32:24 -0700 Subject: [PATCH 23/33] Remove @tloncorp/shared dependency on Firebase perf --- ...reFlagConnectedInstrumentationProvider.tsx | 12 ++- packages/app/utils/perf.ts | 24 ++++++ packages/shared/src/perf.ts | 74 +++++++++++-------- packages/shared/src/test/setup.ts | 6 -- packages/shared/tsup.config.ts | 1 - 5 files changed, 80 insertions(+), 37 deletions(-) create mode 100644 packages/app/utils/perf.ts diff --git a/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx b/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx index e9a30524a6..196e7bfe69 100644 --- a/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx +++ b/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx @@ -1,5 +1,8 @@ +import { firebase } from '@react-native-firebase/perf'; import { useFeatureFlag } from '@tloncorp/app/lib/featureFlags'; +import { FirebasePerformanceMonitoringEndpoint } from '@tloncorp/app/utils/perf'; import { InstrumentationProvider } from '@tloncorp/shared/dist'; +import { useMemo } from 'react'; export function FeatureFlagConnectedInstrumentationProvider({ children, @@ -9,9 +12,16 @@ export function FeatureFlagConnectedInstrumentationProvider({ const [isPerformanceCollectionEnabled] = useFeatureFlag( 'instrumentationEnabled' ); + const endpoint = useMemo( + () => new FirebasePerformanceMonitoringEndpoint(firebase), + [] + ); return ( - + {children} ); diff --git a/packages/app/utils/perf.ts b/packages/app/utils/perf.ts new file mode 100644 index 0000000000..d02d9475cf --- /dev/null +++ b/packages/app/utils/perf.ts @@ -0,0 +1,24 @@ +import { firebase } from '@react-native-firebase/perf'; +import { PerformanceMonitoringEndpoint } from '@tloncorp/shared/dist/perf'; + +type Firebase = typeof firebase; + +export class FirebasePerformanceMonitoringEndpoint + implements PerformanceMonitoringEndpoint +{ + static shared = new FirebasePerformanceMonitoringEndpoint(firebase); + + constructor(private firebase: Firebase) { + // instrumentationEnabled = automatic measurement of HTTP requests, other stuff? + // Let's disable this until we need it to avoid overhead + this.firebase.perf().instrumentationEnabled = false; + } + + setEnabled(enabled: boolean) { + firebase.perf().dataCollectionEnabled = enabled; + } + + async startTrace(identifier: string) { + return firebase.perf().startTrace(identifier); + } +} diff --git a/packages/shared/src/perf.ts b/packages/shared/src/perf.ts index 811fd4cf23..8554469815 100644 --- a/packages/shared/src/perf.ts +++ b/packages/shared/src/perf.ts @@ -1,4 +1,3 @@ -import { firebase } from '@react-native-firebase/perf'; import { useEffect } from 'react'; import create from 'zustand'; @@ -7,42 +6,55 @@ interface Trace { stop(): Promise; } -type PerformanceMonitoringStore = { setEnabled: (enabled: boolean) => void } & ( - | { enabled: false } - | { enabled: true; startTrace(identifier: string): Promise } -); +export interface PerformanceMonitoringEndpoint { + setEnabled: (enabled: boolean) => void; + startTrace: (identifier: string) => Promise; +} + +type PerformanceMonitoringStore = { + enabled: boolean; + setEnabled: (enabled: boolean) => void; + endpoint: PerformanceMonitoringEndpoint | null; + setEndpoint: (e: PerformanceMonitoringEndpoint | null) => void; + startTrace(identifier: string): Promise | null; +}; const usePerformanceMonitoringStore = create( - (set) => ({ - setEnabled: (enabled) => { - // instrumentationEnabled = automatic measurement of HTTP requests, other things? - firebase.perf().instrumentationEnabled = false; + (set, getState) => ({ + endpoint: null, + setEndpoint: (e) => { + set({ endpoint: e }); + }, - // dataCollectionEnabled = sending any data to server - firebase.perf().dataCollectionEnabled = enabled; + setEnabled: (enabled) => { + const { endpoint } = getState(); + if (enabled && endpoint == null) { + throw new Error('Performance monitoring endpoint not set'); + } + endpoint?.setEnabled(enabled); set((prev) => ({ ...prev, enabled, - ...(enabled - ? { - startTrace(identifier) { - return firebase.perf().startTrace(identifier); - }, - } - : {}), })); }, + enabled: false, + + startTrace(identifier) { + const { enabled, endpoint } = getState(); + if (!enabled || endpoint == null) { + return null; + } + return endpoint.startTrace(identifier); + }, }) ); -export function useStartTraceCallback(): - | undefined - | ((identifier: string) => Promise) { - return usePerformanceMonitoringStore((s) => - s.enabled ? s.startTrace : undefined - ); +export function useStartTraceCallback(): ( + identifier: string +) => Promise | null { + return usePerformanceMonitoringStore((s) => s.startTrace); } // For use outside of React @@ -56,19 +68,23 @@ export function startTrace(identifier: string): Promise | null { } export function InstrumentationProvider({ + endpoint, collectionEnabled, children, }: { + endpoint: PerformanceMonitoringEndpoint | null; collectionEnabled: boolean; children: JSX.Element; }) { - const setMonitoringEnabled = usePerformanceMonitoringStore( - (s) => s.setEnabled - ); + const { setEndpoint, setEnabled } = usePerformanceMonitoringStore(); + + useEffect(() => { + setEnabled(collectionEnabled); + }, [collectionEnabled, setEnabled]); useEffect(() => { - setMonitoringEnabled(collectionEnabled); - }, [collectionEnabled, setMonitoringEnabled]); + setEndpoint(endpoint); + }, [setEndpoint, endpoint]); return children; } diff --git a/packages/shared/src/test/setup.ts b/packages/shared/src/test/setup.ts index be93d17082..5d598be501 100644 --- a/packages/shared/src/test/setup.ts +++ b/packages/shared/src/test/setup.ts @@ -19,12 +19,6 @@ vi.mock('@react-native-firebase/crashlytics', () => { }; }); -vi.mock('@react-native-firebase/perf', () => { - return { - firebase: vi.fn(), - }; -}); - vi.mock('@react-native-community/netinfo', () => { return { fetch: async () => ({ isConnected: true, type: 'wifi' }), diff --git a/packages/shared/tsup.config.ts b/packages/shared/tsup.config.ts index 933323fc5e..8102813f0e 100644 --- a/packages/shared/tsup.config.ts +++ b/packages/shared/tsup.config.ts @@ -23,7 +23,6 @@ export default defineConfig({ 'expo-image-picker', 'expo-file-system', '@react-native-firebase/crashlytics', - '@react-native-firebase/perf', '@react-native-community/netinfo', 'expo-battery', ], From 378791f9d0a41343dc4c8e3bc7a21a3558dae03f Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 15:56:30 -0700 Subject: [PATCH 24/33] Move FeatureFlagConnectedInstrumentationProvider to @tloncorp/app --- apps/tlon-mobile/src/App.main.tsx | 2 +- ...reFlagConnectedInstrumentationProvider.tsx | 28 ------------------ packages/app/package.json | 1 + packages/app/utils/{perf.ts => perf.tsx} | 29 ++++++++++++++++++- 4 files changed, 30 insertions(+), 30 deletions(-) delete mode 100644 apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx rename packages/app/utils/{perf.ts => perf.tsx} (51%) diff --git a/apps/tlon-mobile/src/App.main.tsx b/apps/tlon-mobile/src/App.main.tsx index 38235c6983..184db22243 100644 --- a/apps/tlon-mobile/src/App.main.tsx +++ b/apps/tlon-mobile/src/App.main.tsx @@ -17,6 +17,7 @@ import { useIsDarkMode } from '@tloncorp/app/hooks/useIsDarkMode'; import { useScreenOptions } from '@tloncorp/app/hooks/useScreenOptions'; import { useMigrations } from '@tloncorp/app/lib/nativeDb'; import { Provider as TamaguiProvider } from '@tloncorp/app/provider'; +import { FeatureFlagConnectedInstrumentationProvider } from '@tloncorp/app/utils/perf'; import { posthogAsync } from '@tloncorp/app/utils/posthog'; import { QueryClientProvider, queryClient } from '@tloncorp/shared/dist/api'; import { PortalProvider } from '@tloncorp/ui'; @@ -30,7 +31,6 @@ import { SafeAreaProvider } from 'react-native-safe-area-context'; import { useTailwind } from 'tailwind-rn'; import AuthenticatedApp from './components/AuthenticatedApp'; -import { FeatureFlagConnectedInstrumentationProvider } from './components/FeatureFlagConnectedInstrumentationProvider'; import { LoadingSpinner } from './components/LoadingSpinner'; import { CheckVerifyScreen } from './screens/CheckVerifyScreen'; import { EULAScreen } from './screens/EULAScreen'; diff --git a/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx b/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx deleted file mode 100644 index 196e7bfe69..0000000000 --- a/apps/tlon-mobile/src/components/FeatureFlagConnectedInstrumentationProvider.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { firebase } from '@react-native-firebase/perf'; -import { useFeatureFlag } from '@tloncorp/app/lib/featureFlags'; -import { FirebasePerformanceMonitoringEndpoint } from '@tloncorp/app/utils/perf'; -import { InstrumentationProvider } from '@tloncorp/shared/dist'; -import { useMemo } from 'react'; - -export function FeatureFlagConnectedInstrumentationProvider({ - children, -}: { - children: JSX.Element; -}) { - const [isPerformanceCollectionEnabled] = useFeatureFlag( - 'instrumentationEnabled' - ); - const endpoint = useMemo( - () => new FirebasePerformanceMonitoringEndpoint(firebase), - [] - ); - - return ( - - {children} - - ); -} diff --git a/packages/app/package.json b/packages/app/package.json index 26aa726a79..dbc56c5063 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -15,6 +15,7 @@ "@types/react-native": "0.73.0" }, "peerDependencies": { + "@react-native-firebase/perf": "^19.2.2", "lodash": "^4.17.21", "zustand": "^3.7.2" } diff --git a/packages/app/utils/perf.ts b/packages/app/utils/perf.tsx similarity index 51% rename from packages/app/utils/perf.ts rename to packages/app/utils/perf.tsx index d02d9475cf..0c41c9b868 100644 --- a/packages/app/utils/perf.ts +++ b/packages/app/utils/perf.tsx @@ -1,9 +1,13 @@ import { firebase } from '@react-native-firebase/perf'; +import { InstrumentationProvider } from '@tloncorp/shared/dist'; import { PerformanceMonitoringEndpoint } from '@tloncorp/shared/dist/perf'; +import { useMemo } from 'react'; + +import { useFeatureFlag } from '../lib/featureFlags'; type Firebase = typeof firebase; -export class FirebasePerformanceMonitoringEndpoint +class FirebasePerformanceMonitoringEndpoint implements PerformanceMonitoringEndpoint { static shared = new FirebasePerformanceMonitoringEndpoint(firebase); @@ -22,3 +26,26 @@ export class FirebasePerformanceMonitoringEndpoint return firebase.perf().startTrace(identifier); } } + +export function FeatureFlagConnectedInstrumentationProvider({ + children, +}: { + children: JSX.Element; +}) { + const [isPerformanceCollectionEnabled] = useFeatureFlag( + 'instrumentationEnabled' + ); + const endpoint = useMemo( + () => new FirebasePerformanceMonitoringEndpoint(firebase), + [] + ); + + return ( + + {children} + + ); +} From 9b07e62d2db969e44798b5cbed07d96746952e94 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 16:00:28 -0700 Subject: [PATCH 25/33] Remove unnecessary peerDependencies entry; pin version --- .../ios/Landscape.xcodeproj/project.pbxproj | 20 +- apps/tlon-mobile/ios/Podfile.lock | 4 +- apps/tlon-mobile/package.json | 2 +- packages/app/package.json | 2 +- packages/shared/package.json | 1 - pnpm-lock.yaml | 266 +----------------- 6 files changed, 31 insertions(+), 264 deletions(-) diff --git a/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj b/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj index 7744ffb5f3..6891178fad 100644 --- a/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj +++ b/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj @@ -917,11 +917,13 @@ "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCrashlytics/FirebaseCrashlytics_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", @@ -937,11 +939,13 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseABTesting_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCrashlytics_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseRemoteConfig_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", @@ -1021,11 +1025,13 @@ "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCrashlytics/FirebaseCrashlytics_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", @@ -1041,11 +1047,13 @@ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseABTesting_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCrashlytics_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseRemoteConfig_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", @@ -1841,7 +1849,11 @@ ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; @@ -1934,7 +1946,11 @@ MTL_ENABLE_DEBUG_INFO = NO; OTHER_CFLAGS = "$(inherited)"; OTHER_CPLUSPLUSFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-Wl", + "-ld_classic", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../../../node_modules/react-native"; SDKROOT = iphoneos; USE_HERMES = true; diff --git a/apps/tlon-mobile/ios/Podfile.lock b/apps/tlon-mobile/ios/Podfile.lock index 43335525d4..1a7e46abb3 100644 --- a/apps/tlon-mobile/ios/Podfile.lock +++ b/apps/tlon-mobile/ios/Podfile.lock @@ -1352,7 +1352,7 @@ PODS: - FirebaseCoreExtension - React-Core - RNFBApp - - RNFBPerf (19.3.0): + - RNFBPerf (19.2.2): - Firebase/Performance (= 10.24.0) - React-Core - RNFBApp @@ -1861,7 +1861,7 @@ SPEC CHECKSUMS: RNDeviceInfo: db5c64a060e66e5db3102d041ebe3ef307a85120 RNFBApp: 91311b27bc9a33e23b76a62825afd1635501018a RNFBCrashlytics: c3219ef7a0c779f2428236215781c38e7892f6f9 - RNFBPerf: 4206fb79bda0c795c07f50ee11047e10e5f6a50e + RNFBPerf: 2c926ff255c704a644dd53572008cba47c67ada0 RNGestureHandler: f42730cc5dc0b50e2b6409e259e8c238356ec0d0 RNReanimated: fb34efce9255966f5d71bd0fc65e14042c4b88a9 RNScreens: 2b73f5eb2ac5d94fbd61fa4be0bfebd345716825 diff --git a/apps/tlon-mobile/package.json b/apps/tlon-mobile/package.json index 7bfaa7349e..713d6c0853 100644 --- a/apps/tlon-mobile/package.json +++ b/apps/tlon-mobile/package.json @@ -50,7 +50,7 @@ "@react-native-community/netinfo": "11.1.0", "@react-native-firebase/app": "^19.2.2", "@react-native-firebase/crashlytics": "^19.2.2", - "@react-native-firebase/perf": "^19.2.2", + "@react-native-firebase/perf": "19.2.2", "@react-navigation/bottom-tabs": "^6.5.12", "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", diff --git a/packages/app/package.json b/packages/app/package.json index dbc56c5063..852828b5cd 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -15,7 +15,7 @@ "@types/react-native": "0.73.0" }, "peerDependencies": { - "@react-native-firebase/perf": "^19.2.2", + "@react-native-firebase/perf": "19.2.2", "lodash": "^4.17.21", "zustand": "^3.7.2" } diff --git a/packages/shared/package.json b/packages/shared/package.json index 4b0debbffd..a6b5db5b9a 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -43,7 +43,6 @@ "vitest": "^1.4.0" }, "peerDependencies": { - "@react-native-firebase/perf": "^19.2.2", "@tanstack/react-query": "^5.32.1", "@tiptap/core": "^2.0.3", "@tiptap/pm": "^2.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4dd2f96249..fa1a6bf918 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,8 +127,8 @@ importers: specifier: ^19.2.2 version: 19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) '@react-native-firebase/perf': - specifier: ^19.2.2 - version: 19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) + specifier: 19.2.2 + version: 19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) '@react-navigation/bottom-tabs': specifier: ^6.5.12 version: 6.5.12(@react-navigation/native@6.1.10(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-safe-area-context@4.9.0(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-screens@3.29.0(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -947,6 +947,9 @@ importers: packages/app: dependencies: + '@react-native-firebase/perf': + specifier: 19.2.2 + version: 19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)) '@tloncorp/shared': specifier: workspace:* version: link:../shared @@ -1021,9 +1024,6 @@ importers: '@react-native-async-storage/async-storage': specifier: 1.21.0 version: 1.21.0(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)) - '@react-native-firebase/perf': - specifier: ^19.2.2 - version: 19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) '@tanstack/react-query': specifier: ^5.32.1 version: 5.32.1(react@18.2.0) @@ -4091,10 +4091,10 @@ packages: expo: optional: true - '@react-native-firebase/perf@19.3.0': - resolution: {integrity: sha512-d06aKTv/xqLZvjODiajpvIOL/eQzokOaJ///iJT7TkaAGiM7uWiqf5j3QGbg786b4RJclpLYUZpBiimX2T/Xug==} + '@react-native-firebase/perf@19.2.2': + resolution: {integrity: sha512-4AZu+1AEYlwdFeop8o5Kac9iIfvd6frLHGa+U7xS+3pKdbVHZlUU2j7eiisOiILORVDaf/lkZ6yWzEDXqBeFjg==} peerDependencies: - '@react-native-firebase/app': 19.3.0 + '@react-native-firebase/app': 19.2.2 expo: '>=47.0.0' peerDependenciesMeta: expo: @@ -14002,14 +14002,6 @@ snapshots: '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.7) - '@babel/plugin-proposal-decorators@7.23.9(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.25.2) - optional: true - '@babel/plugin-proposal-export-default-from@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -14149,12 +14141,6 @@ snapshots: '@babel/core': 7.23.7 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -14838,12 +14824,6 @@ snapshots: '@babel/core': 7.23.7 '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.23.7) - '@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.25.2) - optional: true - '@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -14888,13 +14868,6 @@ snapshots: '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-transform-react-pure-annotations@7.23.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - optional: true - '@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -15258,17 +15231,6 @@ snapshots: '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.23.7) '@babel/plugin-transform-react-pure-annotations': 7.23.3(@babel/core@7.23.7) - '@babel/preset-react@7.23.3(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-transform-react-display-name': 7.23.3(@babel/core@7.25.2) - '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.25.2) - '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.25.2) - '@babel/plugin-transform-react-pure-annotations': 7.23.3(@babel/core@7.25.2) - optional: true - '@babel/preset-typescript@7.23.3(@babel/core@7.23.7)': dependencies: '@babel/core': 7.23.7 @@ -15813,94 +15775,6 @@ snapshots: - supports-color - utf-8-validate - '@expo/cli@0.17.5(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)(expo-modules-autolinking@1.10.3)': - dependencies: - '@babel/runtime': 7.23.8 - '@expo/code-signing-certificates': 0.0.5 - '@expo/config': 8.5.4 - '@expo/config-plugins': 7.8.4 - '@expo/devcert': 1.1.0 - '@expo/env': 0.2.1 - '@expo/image-utils': 0.4.1(encoding@0.1.13) - '@expo/json-file': 8.3.0 - '@expo/metro-config': 0.17.4(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))) - '@expo/osascript': 2.1.0 - '@expo/package-manager': 1.4.2 - '@expo/plist': 0.1.0 - '@expo/prebuild-config': 6.7.4(encoding@0.1.13)(expo-modules-autolinking@1.10.3) - '@expo/rudder-sdk-node': 1.1.1(encoding@0.1.13) - '@expo/spawn-async': 1.5.0 - '@expo/xcpretty': 4.3.1 - '@react-native/dev-middleware': 0.73.8(encoding@0.1.13) - '@urql/core': 2.3.6(graphql@15.8.0) - '@urql/exchange-retry': 0.3.0(graphql@15.8.0) - accepts: 1.3.8 - arg: 5.0.2 - better-opn: 3.0.2 - bplist-parser: 0.3.2 - cacache: 15.3.0 - chalk: 4.1.2 - ci-info: 3.9.0 - connect: 3.7.0 - debug: 4.3.4 - env-editor: 0.4.2 - find-yarn-workspace-root: 2.0.0 - form-data: 3.0.1 - freeport-async: 2.0.0 - fs-extra: 8.1.0 - getenv: 1.0.0 - glob: 7.2.3 - graphql: 15.8.0 - graphql-tag: 2.12.6(graphql@15.8.0) - https-proxy-agent: 5.0.1 - internal-ip: 4.3.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - js-yaml: 3.14.1 - json-schema-deref-sync: 0.13.0 - lodash.debounce: 4.0.8 - md5hex: 1.0.0 - minimatch: 3.1.2 - minipass: 3.3.6 - node-fetch: 2.6.12(encoding@0.1.13) - node-forge: 1.3.1 - npm-package-arg: 7.0.0 - open: 8.4.2 - ora: 3.4.0 - picomatch: 3.0.1 - pretty-bytes: 5.6.0 - progress: 2.0.3 - prompts: 2.4.2 - qrcode-terminal: 0.11.0 - require-from-string: 2.0.2 - requireg: 0.2.2 - resolve: 1.22.4 - resolve-from: 5.0.0 - resolve.exports: 2.0.2 - semver: 7.6.0 - send: 0.18.0 - slugify: 1.6.6 - source-map-support: 0.5.21 - stacktrace-parser: 0.1.10 - structured-headers: 0.4.1 - tar: 6.2.0 - temp-dir: 2.0.0 - tempy: 0.7.1 - terminal-link: 2.1.1 - text-table: 0.2.0 - url-join: 4.0.0 - wrap-ansi: 7.0.0 - ws: 8.16.0 - transitivePeerDependencies: - - '@react-native/babel-preset' - - bluebird - - bufferutil - - encoding - - expo-modules-autolinking - - supports-color - - utf-8-validate - optional: true - '@expo/code-signing-certificates@0.0.5': dependencies: node-forge: 1.3.1 @@ -16033,33 +15907,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/metro-config@0.17.4(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))': - dependencies: - '@babel/core': 7.23.7 - '@babel/generator': 7.23.6 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.9 - '@expo/config': 8.5.4 - '@expo/env': 0.2.1 - '@expo/json-file': 8.3.0 - '@expo/spawn-async': 1.7.2 - '@react-native/babel-preset': 0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)) - babel-preset-fbjs: 3.4.0(@babel/core@7.23.7) - chalk: 4.1.2 - debug: 4.3.4 - find-yarn-workspace-root: 2.0.0 - fs-extra: 9.1.0 - getenv: 1.0.0 - glob: 7.2.3 - jsc-safe-url: 0.2.4 - lightningcss: 1.19.0 - postcss: 8.4.35 - resolve-from: 5.0.0 - sucrase: 3.34.0 - transitivePeerDependencies: - - supports-color - optional: true - '@expo/osascript@2.1.0': dependencies: '@expo/spawn-async': 1.7.2 @@ -17624,15 +17471,6 @@ snapshots: optionalDependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) - '@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)': - dependencies: - opencollective-postinstall: 2.0.3 - react: 18.2.0 - react-native: 0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0) - superstruct: 0.6.2 - optionalDependencies: - expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) - '@react-native-firebase/crashlytics@19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))': dependencies: '@react-native-firebase/app': 19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -17640,18 +17478,12 @@ snapshots: optionalDependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) - '@react-native-firebase/perf@19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))': + '@react-native-firebase/perf@19.2.2(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))': dependencies: '@react-native-firebase/app': 19.2.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) optionalDependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) - '@react-native-firebase/perf@19.3.0(@react-native-firebase/app@19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))': - dependencies: - '@react-native-firebase/app': 19.2.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))(react-native@0.73.4(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0) - optionalDependencies: - expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) - '@react-native-mac/virtualized-lists@0.73.3(react-native@0.73.4(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7))(encoding@0.1.13)(react@18.2.0))': dependencies: invariant: 2.2.4 @@ -20917,22 +20749,6 @@ snapshots: - '@babel/core' - supports-color - babel-preset-expo@10.0.1(@babel/core@7.25.2): - dependencies: - '@babel/plugin-proposal-decorators': 7.23.9(@babel/core@7.25.2) - '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.25.2) - '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.25.2) - '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.25.2) - '@babel/preset-env': 7.23.7(@babel/core@7.25.2) - '@babel/preset-react': 7.23.3(@babel/core@7.25.2) - '@react-native/babel-preset': 0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)) - babel-plugin-react-native-web: 0.18.12 - react-refresh: 0.14.0 - transitivePeerDependencies: - - '@babel/core' - - supports-color - optional: true - babel-preset-fbjs@3.4.0(@babel/core@7.23.7): dependencies: '@babel/core': 7.23.7 @@ -22614,19 +22430,6 @@ snapshots: - expo - supports-color - expo-asset@9.0.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): - dependencies: - '@react-native/assets-registry': 0.73.1 - blueimp-md5: 2.19.0 - expo-constants: 15.4.5(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) - expo-file-system: 16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) - invariant: 2.2.4 - md5-file: 3.2.3 - transitivePeerDependencies: - - expo - - supports-color - optional: true - expo-av@13.10.6(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22650,14 +22453,6 @@ snapshots: transitivePeerDependencies: - supports-color - expo-constants@15.4.5(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): - dependencies: - '@expo/config': 8.5.4 - expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) - transitivePeerDependencies: - - supports-color - optional: true - expo-dev-client@3.3.9(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22701,22 +22496,11 @@ snapshots: dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) - expo-file-system@16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): - dependencies: - expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) - optional: true - expo-font@11.10.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) fontfaceobserver: 2.3.0 - expo-font@11.10.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): - dependencies: - expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) - fontfaceobserver: 2.3.0 - optional: true - expo-haptics@12.8.1(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22746,11 +22530,6 @@ snapshots: dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) - expo-keep-awake@12.8.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)): - dependencies: - expo: 50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13) - optional: true - expo-linear-gradient@12.7.2(expo@50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13)): dependencies: expo: 50.0.6(@babel/core@7.23.7)(@react-native/babel-preset@0.73.21(@babel/core@7.23.7)(@babel/preset-env@7.23.7(@babel/core@7.23.7)))(encoding@0.1.13) @@ -22868,33 +22647,6 @@ snapshots: - supports-color - utf-8-validate - expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13): - dependencies: - '@babel/runtime': 7.23.8 - '@expo/cli': 0.17.5(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)(expo-modules-autolinking@1.10.3) - '@expo/config': 8.5.4 - '@expo/config-plugins': 7.8.4 - '@expo/metro-config': 0.17.4(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))) - '@expo/vector-icons': 14.0.0 - babel-preset-expo: 10.0.1(@babel/core@7.25.2) - expo-asset: 9.0.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) - expo-file-system: 16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) - expo-font: 11.10.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) - expo-keep-awake: 12.8.2(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)) - expo-modules-autolinking: 1.10.3 - expo-modules-core: 1.11.8 - fbemitter: 3.0.0(encoding@0.1.13) - whatwg-url-without-unicode: 8.0.0-3 - transitivePeerDependencies: - - '@babel/core' - - '@react-native/babel-preset' - - bluebird - - bufferutil - - encoding - - supports-color - - utf-8-validate - optional: true - exponential-backoff@3.1.1: {} express@4.18.2: From 3949602f99aea4ef0668cb8792d6699146667865 Mon Sep 17 00:00:00 2001 From: David Lee Date: Tue, 20 Aug 2024 19:47:56 -0700 Subject: [PATCH 26/33] Fix feature flags load failing to unpack loaded state --- packages/app/lib/featureFlags.ts | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/app/lib/featureFlags.ts b/packages/app/lib/featureFlags.ts index 3e6ea6c5ec..0d4d6e49bb 100644 --- a/packages/app/lib/featureFlags.ts +++ b/packages/app/lib/featureFlags.ts @@ -61,18 +61,22 @@ async function loadInitialState() { // ignore } if (state) { - useFeatureFlagStore.setState((prev) => ({ - ...prev, - flags: { - ...prev.flags, - state, - }, - })); + Object.entries(state).forEach(([name, enabled]) => { + if (name in featureMeta) { + useFeatureFlagStore.getState().setEnabled(name as FeatureName, enabled); + } else { + console.warn('Unknown feature flag encountered in local storage', name); + } + }); } } -// Write to local storage on changes -useFeatureFlagStore.subscribe(async (state) => { - await storage.save({ key: storageKey, data: state.flags }); -}); -loadInitialState(); +async function setup() { + await loadInitialState(); + + // Write to local storage on changes, but only after initial load + useFeatureFlagStore.subscribe(async (state) => { + await storage.save({ key: storageKey, data: state.flags }); + }); +} +setup(); From 6d431fde4d60e1591350179337b33a4f4c692683 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Wed, 21 Aug 2024 10:36:54 -0400 Subject: [PATCH 27/33] always reset route stack when going to push, move notification listener into tlon-mobile --- .../src/components/AuthenticatedApp.tsx | 6 +-- .../src}/hooks/useNotificationListener.ts | 44 +++++++++++-------- 2 files changed, 28 insertions(+), 22 deletions(-) rename {packages/app => apps/tlon-mobile/src}/hooks/useNotificationListener.ts (85%) diff --git a/apps/tlon-mobile/src/components/AuthenticatedApp.tsx b/apps/tlon-mobile/src/components/AuthenticatedApp.tsx index 73079c8180..f5ccbb5209 100644 --- a/apps/tlon-mobile/src/components/AuthenticatedApp.tsx +++ b/apps/tlon-mobile/src/components/AuthenticatedApp.tsx @@ -5,9 +5,6 @@ import { useCurrentUserId } from '@tloncorp/app/hooks/useCurrentUser'; import { useDeepLinkListener } from '@tloncorp/app/hooks/useDeepLinkListener'; import { useNavigationLogging } from '@tloncorp/app/hooks/useNavigationLogger'; import { useNetworkLogger } from '@tloncorp/app/hooks/useNetworkLogger'; -import useNotificationListener, { - type Props as NotificationListenerProps, -} from '@tloncorp/app/hooks/useNotificationListener'; import { configureClient } from '@tloncorp/app/lib/api'; import { PlatformState } from '@tloncorp/app/lib/platformHelpers'; import { initializeCrashReporter, sync } from '@tloncorp/shared'; @@ -15,6 +12,9 @@ import * as store from '@tloncorp/shared/dist/store'; import { ZStack } from '@tloncorp/ui'; import { useEffect } from 'react'; +import useNotificationListener, { + type Props as NotificationListenerProps, +} from '../hooks/useNotificationListener'; import { RootStack } from '../navigation/RootStack'; export interface AuthenticatedAppProps { diff --git a/packages/app/hooks/useNotificationListener.ts b/apps/tlon-mobile/src/hooks/useNotificationListener.ts similarity index 85% rename from packages/app/hooks/useNotificationListener.ts rename to apps/tlon-mobile/src/hooks/useNotificationListener.ts index 02a616c150..f3e1e8a2c1 100644 --- a/packages/app/hooks/useNotificationListener.ts +++ b/apps/tlon-mobile/src/hooks/useNotificationListener.ts @@ -1,6 +1,8 @@ import crashlytics from '@react-native-firebase/crashlytics'; import type { NavigationProp } from '@react-navigation/native'; import { CommonActions, useNavigation } from '@react-navigation/native'; +import { connectNotifications } from '@tloncorp/app/lib/notifications'; +import * as posthog from '@tloncorp/app/utils/posthog'; import { syncDms, syncGroups } from '@tloncorp/shared'; import { markChatRead } from '@tloncorp/shared/dist/api'; import * as api from '@tloncorp/shared/dist/api'; @@ -10,10 +12,12 @@ import { whomIsDm, whomIsMultiDm } from '@tloncorp/shared/dist/urbit'; import { addNotificationResponseReceivedListener } from 'expo-notifications'; import { useEffect, useState } from 'react'; -import { connectNotifications } from '../lib/notifications'; -import * as posthog from '../utils/posthog'; +import { RootStackParamList } from '../types'; -// import type { RootStackParamList } from '../types'; +type RouteStack = { + name: keyof RootStackParamList; + params?: RootStackParamList[keyof RootStackParamList]; +}[]; interface NotificationData { channelId: string; @@ -29,7 +33,6 @@ export default function useNotificationListener({ notificationPath, notificationChannelId, }: Props) { - // @ts-expect-error - TODO: pass navigation handlers to this hook const navigation = useNavigation>(); const { data: isTlonEmployee } = store.useIsTlonEmployee(); @@ -106,11 +109,20 @@ export default function useNotificationListener({ useEffect(() => { if (channelId) { const goToChannel = async () => { - const channel = await db.getChannel({ id: channelId }); + const channel = await db.getChannelWithRelations({ id: channelId }); if (!channel) { return false; } + const routeStack: RouteStack = [{ name: 'ChatList' }]; + if (channel.group) { + routeStack.push({ + name: 'GroupChannels', + params: { group: channel.group }, + }); + } + routeStack.push({ name: 'Channel', params: { channel } }); + // if we have a post id, try to navigate to the thread if (postInfo) { let postToNavigateTo: { @@ -127,21 +139,15 @@ export default function useNotificationListener({ postToNavigateTo = { ...postInfo, channelId }; } - navigation.dispatch( - CommonActions.reset({ - index: 1, - routes: [ - { name: 'ChatList' }, - { name: 'Channel', params: { channel } }, - { name: 'Post', params: { post: postToNavigateTo } }, - ], - }) - ); - resetGotoData(); - return true; + routeStack.push({ name: 'Post', params: { post: postToNavigateTo } }); } - navigation.navigate('Channel', { channel }); + navigation.dispatch( + CommonActions.reset({ + index: 1, + routes: routeStack, + }) + ); resetGotoData(); return true; }; @@ -176,5 +182,5 @@ export default function useNotificationListener({ } })(); } - }, [channelId, postInfo, navigation, isDm]); + }, [channelId, postInfo, navigation, isDm, isTlonEmployee]); } From 6b4b16e125025f80d7c92fdad37baaafd1c8f167 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Wed, 21 Aug 2024 10:42:29 -0400 Subject: [PATCH 28/33] move over useDeepLinkListener --- apps/tlon-mobile/cosmos.imports.ts | 132 ++++++++++-------- .../src/components/AuthenticatedApp.tsx | 2 +- .../src}/hooks/useDeepLinkListener.ts | 12 +- 3 files changed, 79 insertions(+), 67 deletions(-) rename {packages/app => apps/tlon-mobile/src}/hooks/useDeepLinkListener.ts (83%) diff --git a/apps/tlon-mobile/cosmos.imports.ts b/apps/tlon-mobile/cosmos.imports.ts index 5ebbb8b7da..fc291c2f93 100644 --- a/apps/tlon-mobile/cosmos.imports.ts +++ b/apps/tlon-mobile/cosmos.imports.ts @@ -1,61 +1,59 @@ // This file is automatically generated by Cosmos. Add it to .gitignore and // only edit if you know what you're doing. - import { RendererConfig, UserModuleWrappers } from 'react-cosmos-core'; import * as fixture0 from './src/App.fixture'; -import * as fixture1 from './src/fixtures/VideoEmbed.fixture'; -import * as fixture2 from './src/fixtures/TrimmedText.fixture'; -import * as fixture3 from './src/fixtures/TlonButton.fixture'; -import * as fixture4 from './src/fixtures/SearchBar.fixture'; -import * as fixture5 from './src/fixtures/ScreenHeader.fixture'; -import * as fixture6 from './src/fixtures/ReferenceSkeleton.fixture'; -import * as fixture7 from './src/fixtures/ProfileWidget.fixture'; -import * as fixture8 from './src/fixtures/ProfileSheet.fixture'; -import * as fixture9 from './src/fixtures/ProfileBlock.fixture'; -import * as fixture10 from './src/fixtures/PostScreen.fixture'; -import * as fixture11 from './src/fixtures/PostReference.fixture'; -import * as fixture12 from './src/fixtures/OutsideEmbed.fixture'; -import * as fixture13 from './src/fixtures/MetaEditorScreen.fixture'; -import * as fixture14 from './src/fixtures/MessageInput.fixture'; -import * as fixture15 from './src/fixtures/MessageActions.fixture'; -import * as fixture16 from './src/fixtures/InputToolbar.fixture'; -import * as fixture17 from './src/fixtures/Input.fixture'; -import * as fixture18 from './src/fixtures/ImageViewer.fixture'; -import * as fixture19 from './src/fixtures/HeaderButton.fixture'; -import * as fixture20 from './src/fixtures/GroupListItem.fixture'; -import * as fixture21 from './src/fixtures/GroupList.fixture'; -import * as fixture22 from './src/fixtures/GalleryPost.fixture'; -import * as fixture23 from './src/fixtures/Form.fixture'; -import * as fixture24 from './src/fixtures/DetailView.fixture'; -import * as fixture25 from './src/fixtures/ContactList.fixture'; -import * as fixture26 from './src/fixtures/ChatMessage.fixture'; -import * as fixture27 from './src/fixtures/ChannelSwitcherSheet.fixture'; -import * as fixture28 from './src/fixtures/ChannelHeader.fixture'; -import * as fixture29 from './src/fixtures/ChannelDivider.fixture'; -import * as fixture30 from './src/fixtures/Channel.fixture'; -import * as fixture31 from './src/fixtures/Button.fixture'; -import * as fixture32 from './src/fixtures/BlockSectionList.fixture'; -import * as fixture33 from './src/fixtures/Avatar.fixture'; -import * as fixture34 from './src/fixtures/AudioEmbed.fixture'; -import * as fixture35 from './src/fixtures/AttachmentPreviewList.fixture'; -import * as fixture36 from './src/fixtures/ActionSheet/SendPostRetrySheet.fixture'; -import * as fixture37 from './src/fixtures/ActionSheet/ProfileSheet.fixture'; -import * as fixture38 from './src/fixtures/ActionSheet/GroupPreviewSheet.fixture'; -import * as fixture39 from './src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture'; -import * as fixture40 from './src/fixtures/ActionSheet/GenericActionSheet.fixture'; -import * as fixture41 from './src/fixtures/ActionSheet/EditSectionNameSheet.fixture'; -import * as fixture42 from './src/fixtures/ActionSheet/DeleteSheet.fixture'; -import * as fixture43 from './src/fixtures/ActionSheet/CreateChannelSheet.fixture'; -import * as fixture44 from './src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture'; -import * as fixture45 from './src/fixtures/ActionSheet/AttachmentSheet.fixture'; import * as fixture46 from './src/fixtures/ActionSheet/AddGalleryPostSheet.fixture'; - +import * as fixture45 from './src/fixtures/ActionSheet/AttachmentSheet.fixture'; +import * as fixture44 from './src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture'; +import * as fixture43 from './src/fixtures/ActionSheet/CreateChannelSheet.fixture'; +import * as fixture42 from './src/fixtures/ActionSheet/DeleteSheet.fixture'; +import * as fixture41 from './src/fixtures/ActionSheet/EditSectionNameSheet.fixture'; +import * as fixture40 from './src/fixtures/ActionSheet/GenericActionSheet.fixture'; +import * as fixture39 from './src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture'; +import * as fixture38 from './src/fixtures/ActionSheet/GroupPreviewSheet.fixture'; +import * as fixture37 from './src/fixtures/ActionSheet/ProfileSheet.fixture'; +import * as fixture36 from './src/fixtures/ActionSheet/SendPostRetrySheet.fixture'; +import * as fixture35 from './src/fixtures/AttachmentPreviewList.fixture'; +import * as fixture34 from './src/fixtures/AudioEmbed.fixture'; +import * as fixture33 from './src/fixtures/Avatar.fixture'; +import * as fixture32 from './src/fixtures/BlockSectionList.fixture'; +import * as fixture31 from './src/fixtures/Button.fixture'; +import * as fixture30 from './src/fixtures/Channel.fixture'; +import * as fixture29 from './src/fixtures/ChannelDivider.fixture'; +import * as fixture28 from './src/fixtures/ChannelHeader.fixture'; +import * as fixture27 from './src/fixtures/ChannelSwitcherSheet.fixture'; +import * as fixture26 from './src/fixtures/ChatMessage.fixture'; +import * as fixture25 from './src/fixtures/ContactList.fixture'; +import * as fixture24 from './src/fixtures/DetailView.fixture'; +import * as fixture23 from './src/fixtures/Form.fixture'; +import * as fixture22 from './src/fixtures/GalleryPost.fixture'; +import * as fixture21 from './src/fixtures/GroupList.fixture'; +import * as fixture20 from './src/fixtures/GroupListItem.fixture'; +import * as fixture19 from './src/fixtures/HeaderButton.fixture'; +import * as fixture18 from './src/fixtures/ImageViewer.fixture'; +import * as fixture17 from './src/fixtures/Input.fixture'; +import * as fixture16 from './src/fixtures/InputToolbar.fixture'; +import * as fixture15 from './src/fixtures/MessageActions.fixture'; +import * as fixture14 from './src/fixtures/MessageInput.fixture'; +import * as fixture13 from './src/fixtures/MetaEditorScreen.fixture'; +import * as fixture12 from './src/fixtures/OutsideEmbed.fixture'; +import * as fixture11 from './src/fixtures/PostReference.fixture'; +import * as fixture10 from './src/fixtures/PostScreen.fixture'; +import * as fixture9 from './src/fixtures/ProfileBlock.fixture'; +import * as fixture8 from './src/fixtures/ProfileSheet.fixture'; +import * as fixture7 from './src/fixtures/ProfileWidget.fixture'; +import * as fixture6 from './src/fixtures/ReferenceSkeleton.fixture'; +import * as fixture5 from './src/fixtures/ScreenHeader.fixture'; +import * as fixture4 from './src/fixtures/SearchBar.fixture'; +import * as fixture3 from './src/fixtures/TlonButton.fixture'; +import * as fixture2 from './src/fixtures/TrimmedText.fixture'; +import * as fixture1 from './src/fixtures/VideoEmbed.fixture'; import * as decorator0 from './src/fixtures/cosmos.decorator'; export const rendererConfig: RendererConfig = { - "playgroundUrl": "http://localhost:5001", - "rendererUrl": null + playgroundUrl: 'http://localhost:5001', + rendererUrl: null, }; const fixtures = { @@ -95,25 +93,41 @@ const fixtures = { 'src/fixtures/Avatar.fixture.tsx': { module: fixture33 }, 'src/fixtures/AudioEmbed.fixture.tsx': { module: fixture34 }, 'src/fixtures/AttachmentPreviewList.fixture.tsx': { module: fixture35 }, - 'src/fixtures/ActionSheet/SendPostRetrySheet.fixture.tsx': { module: fixture36 }, + 'src/fixtures/ActionSheet/SendPostRetrySheet.fixture.tsx': { + module: fixture36, + }, 'src/fixtures/ActionSheet/ProfileSheet.fixture.tsx': { module: fixture37 }, - 'src/fixtures/ActionSheet/GroupPreviewSheet.fixture.tsx': { module: fixture38 }, - 'src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture.tsx': { module: fixture39 }, - 'src/fixtures/ActionSheet/GenericActionSheet.fixture.tsx': { module: fixture40 }, - 'src/fixtures/ActionSheet/EditSectionNameSheet.fixture.tsx': { module: fixture41 }, + 'src/fixtures/ActionSheet/GroupPreviewSheet.fixture.tsx': { + module: fixture38, + }, + 'src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture.tsx': { + module: fixture39, + }, + 'src/fixtures/ActionSheet/GenericActionSheet.fixture.tsx': { + module: fixture40, + }, + 'src/fixtures/ActionSheet/EditSectionNameSheet.fixture.tsx': { + module: fixture41, + }, 'src/fixtures/ActionSheet/DeleteSheet.fixture.tsx': { module: fixture42 }, - 'src/fixtures/ActionSheet/CreateChannelSheet.fixture.tsx': { module: fixture43 }, - 'src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture.tsx': { module: fixture44 }, + 'src/fixtures/ActionSheet/CreateChannelSheet.fixture.tsx': { + module: fixture43, + }, + 'src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture.tsx': { + module: fixture44, + }, 'src/fixtures/ActionSheet/AttachmentSheet.fixture.tsx': { module: fixture45 }, - 'src/fixtures/ActionSheet/AddGalleryPostSheet.fixture.tsx': { module: fixture46 } + 'src/fixtures/ActionSheet/AddGalleryPostSheet.fixture.tsx': { + module: fixture46, + }, }; const decorators = { - 'src/fixtures/cosmos.decorator.tsx': { module: decorator0 } + 'src/fixtures/cosmos.decorator.tsx': { module: decorator0 }, }; export const moduleWrappers: UserModuleWrappers = { lazy: false, fixtures, - decorators + decorators, }; diff --git a/apps/tlon-mobile/src/components/AuthenticatedApp.tsx b/apps/tlon-mobile/src/components/AuthenticatedApp.tsx index f5ccbb5209..20835c2867 100644 --- a/apps/tlon-mobile/src/components/AuthenticatedApp.tsx +++ b/apps/tlon-mobile/src/components/AuthenticatedApp.tsx @@ -2,7 +2,6 @@ import crashlytics from '@react-native-firebase/crashlytics'; import { useShip } from '@tloncorp/app/contexts/ship'; import useAppForegrounded from '@tloncorp/app/hooks/useAppForegrounded'; import { useCurrentUserId } from '@tloncorp/app/hooks/useCurrentUser'; -import { useDeepLinkListener } from '@tloncorp/app/hooks/useDeepLinkListener'; import { useNavigationLogging } from '@tloncorp/app/hooks/useNavigationLogger'; import { useNetworkLogger } from '@tloncorp/app/hooks/useNetworkLogger'; import { configureClient } from '@tloncorp/app/lib/api'; @@ -12,6 +11,7 @@ import * as store from '@tloncorp/shared/dist/store'; import { ZStack } from '@tloncorp/ui'; import { useEffect } from 'react'; +import { useDeepLinkListener } from '../hooks/useDeepLinkListener'; import useNotificationListener, { type Props as NotificationListenerProps, } from '../hooks/useNotificationListener'; diff --git a/packages/app/hooks/useDeepLinkListener.ts b/apps/tlon-mobile/src/hooks/useDeepLinkListener.ts similarity index 83% rename from packages/app/hooks/useDeepLinkListener.ts rename to apps/tlon-mobile/src/hooks/useDeepLinkListener.ts index f09b7ebfa2..b476b6e022 100644 --- a/packages/app/hooks/useDeepLinkListener.ts +++ b/apps/tlon-mobile/src/hooks/useDeepLinkListener.ts @@ -1,17 +1,15 @@ import { useNavigation } from '@react-navigation/native'; import type { NavigationProp } from '@react-navigation/native'; -// import { parseActiveTab } from '@tloncorp/shared'; +import { useBranch } from '@tloncorp/app/contexts/branch'; +import { useShip } from '@tloncorp/app/contexts/ship'; +import { inviteShipWithLure } from '@tloncorp/app/lib/hostingApi'; +import { trackError } from '@tloncorp/app/utils/posthog'; import { useEffect } from 'react'; import { Alert } from 'react-native'; -import { useBranch } from '../contexts/branch'; -import { useShip } from '../contexts/ship'; -import { inviteShipWithLure } from '../lib/hostingApi'; -// import type { RootStackParamList } from '../types'; -import { trackError } from '../utils/posthog'; +import { RootStackParamList } from '../types'; export const useDeepLinkListener = () => { - // @ts-expect-error - TODO: pass navigation handler to hook const navigation = useNavigation>(); const { ship } = useShip(); const { lure, deepLinkPath, clearLure, clearDeepLink } = useBranch(); From e02695601f7780b93892d6531fe1f90c3a695dd1 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Wed, 21 Aug 2024 10:54:47 -0400 Subject: [PATCH 29/33] reset cosmos --- apps/tlon-mobile/cosmos.imports.ts | 132 +++++++++++++---------------- 1 file changed, 59 insertions(+), 73 deletions(-) diff --git a/apps/tlon-mobile/cosmos.imports.ts b/apps/tlon-mobile/cosmos.imports.ts index fc291c2f93..5ebbb8b7da 100644 --- a/apps/tlon-mobile/cosmos.imports.ts +++ b/apps/tlon-mobile/cosmos.imports.ts @@ -1,59 +1,61 @@ // This file is automatically generated by Cosmos. Add it to .gitignore and // only edit if you know what you're doing. + import { RendererConfig, UserModuleWrappers } from 'react-cosmos-core'; import * as fixture0 from './src/App.fixture'; -import * as fixture46 from './src/fixtures/ActionSheet/AddGalleryPostSheet.fixture'; -import * as fixture45 from './src/fixtures/ActionSheet/AttachmentSheet.fixture'; -import * as fixture44 from './src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture'; -import * as fixture43 from './src/fixtures/ActionSheet/CreateChannelSheet.fixture'; -import * as fixture42 from './src/fixtures/ActionSheet/DeleteSheet.fixture'; -import * as fixture41 from './src/fixtures/ActionSheet/EditSectionNameSheet.fixture'; -import * as fixture40 from './src/fixtures/ActionSheet/GenericActionSheet.fixture'; -import * as fixture39 from './src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture'; -import * as fixture38 from './src/fixtures/ActionSheet/GroupPreviewSheet.fixture'; -import * as fixture37 from './src/fixtures/ActionSheet/ProfileSheet.fixture'; -import * as fixture36 from './src/fixtures/ActionSheet/SendPostRetrySheet.fixture'; -import * as fixture35 from './src/fixtures/AttachmentPreviewList.fixture'; -import * as fixture34 from './src/fixtures/AudioEmbed.fixture'; -import * as fixture33 from './src/fixtures/Avatar.fixture'; -import * as fixture32 from './src/fixtures/BlockSectionList.fixture'; -import * as fixture31 from './src/fixtures/Button.fixture'; -import * as fixture30 from './src/fixtures/Channel.fixture'; -import * as fixture29 from './src/fixtures/ChannelDivider.fixture'; -import * as fixture28 from './src/fixtures/ChannelHeader.fixture'; -import * as fixture27 from './src/fixtures/ChannelSwitcherSheet.fixture'; -import * as fixture26 from './src/fixtures/ChatMessage.fixture'; -import * as fixture25 from './src/fixtures/ContactList.fixture'; -import * as fixture24 from './src/fixtures/DetailView.fixture'; -import * as fixture23 from './src/fixtures/Form.fixture'; -import * as fixture22 from './src/fixtures/GalleryPost.fixture'; -import * as fixture21 from './src/fixtures/GroupList.fixture'; -import * as fixture20 from './src/fixtures/GroupListItem.fixture'; -import * as fixture19 from './src/fixtures/HeaderButton.fixture'; -import * as fixture18 from './src/fixtures/ImageViewer.fixture'; -import * as fixture17 from './src/fixtures/Input.fixture'; -import * as fixture16 from './src/fixtures/InputToolbar.fixture'; -import * as fixture15 from './src/fixtures/MessageActions.fixture'; -import * as fixture14 from './src/fixtures/MessageInput.fixture'; -import * as fixture13 from './src/fixtures/MetaEditorScreen.fixture'; -import * as fixture12 from './src/fixtures/OutsideEmbed.fixture'; -import * as fixture11 from './src/fixtures/PostReference.fixture'; -import * as fixture10 from './src/fixtures/PostScreen.fixture'; -import * as fixture9 from './src/fixtures/ProfileBlock.fixture'; -import * as fixture8 from './src/fixtures/ProfileSheet.fixture'; -import * as fixture7 from './src/fixtures/ProfileWidget.fixture'; -import * as fixture6 from './src/fixtures/ReferenceSkeleton.fixture'; -import * as fixture5 from './src/fixtures/ScreenHeader.fixture'; -import * as fixture4 from './src/fixtures/SearchBar.fixture'; -import * as fixture3 from './src/fixtures/TlonButton.fixture'; -import * as fixture2 from './src/fixtures/TrimmedText.fixture'; import * as fixture1 from './src/fixtures/VideoEmbed.fixture'; +import * as fixture2 from './src/fixtures/TrimmedText.fixture'; +import * as fixture3 from './src/fixtures/TlonButton.fixture'; +import * as fixture4 from './src/fixtures/SearchBar.fixture'; +import * as fixture5 from './src/fixtures/ScreenHeader.fixture'; +import * as fixture6 from './src/fixtures/ReferenceSkeleton.fixture'; +import * as fixture7 from './src/fixtures/ProfileWidget.fixture'; +import * as fixture8 from './src/fixtures/ProfileSheet.fixture'; +import * as fixture9 from './src/fixtures/ProfileBlock.fixture'; +import * as fixture10 from './src/fixtures/PostScreen.fixture'; +import * as fixture11 from './src/fixtures/PostReference.fixture'; +import * as fixture12 from './src/fixtures/OutsideEmbed.fixture'; +import * as fixture13 from './src/fixtures/MetaEditorScreen.fixture'; +import * as fixture14 from './src/fixtures/MessageInput.fixture'; +import * as fixture15 from './src/fixtures/MessageActions.fixture'; +import * as fixture16 from './src/fixtures/InputToolbar.fixture'; +import * as fixture17 from './src/fixtures/Input.fixture'; +import * as fixture18 from './src/fixtures/ImageViewer.fixture'; +import * as fixture19 from './src/fixtures/HeaderButton.fixture'; +import * as fixture20 from './src/fixtures/GroupListItem.fixture'; +import * as fixture21 from './src/fixtures/GroupList.fixture'; +import * as fixture22 from './src/fixtures/GalleryPost.fixture'; +import * as fixture23 from './src/fixtures/Form.fixture'; +import * as fixture24 from './src/fixtures/DetailView.fixture'; +import * as fixture25 from './src/fixtures/ContactList.fixture'; +import * as fixture26 from './src/fixtures/ChatMessage.fixture'; +import * as fixture27 from './src/fixtures/ChannelSwitcherSheet.fixture'; +import * as fixture28 from './src/fixtures/ChannelHeader.fixture'; +import * as fixture29 from './src/fixtures/ChannelDivider.fixture'; +import * as fixture30 from './src/fixtures/Channel.fixture'; +import * as fixture31 from './src/fixtures/Button.fixture'; +import * as fixture32 from './src/fixtures/BlockSectionList.fixture'; +import * as fixture33 from './src/fixtures/Avatar.fixture'; +import * as fixture34 from './src/fixtures/AudioEmbed.fixture'; +import * as fixture35 from './src/fixtures/AttachmentPreviewList.fixture'; +import * as fixture36 from './src/fixtures/ActionSheet/SendPostRetrySheet.fixture'; +import * as fixture37 from './src/fixtures/ActionSheet/ProfileSheet.fixture'; +import * as fixture38 from './src/fixtures/ActionSheet/GroupPreviewSheet.fixture'; +import * as fixture39 from './src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture'; +import * as fixture40 from './src/fixtures/ActionSheet/GenericActionSheet.fixture'; +import * as fixture41 from './src/fixtures/ActionSheet/EditSectionNameSheet.fixture'; +import * as fixture42 from './src/fixtures/ActionSheet/DeleteSheet.fixture'; +import * as fixture43 from './src/fixtures/ActionSheet/CreateChannelSheet.fixture'; +import * as fixture44 from './src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture'; +import * as fixture45 from './src/fixtures/ActionSheet/AttachmentSheet.fixture'; +import * as fixture46 from './src/fixtures/ActionSheet/AddGalleryPostSheet.fixture'; + import * as decorator0 from './src/fixtures/cosmos.decorator'; export const rendererConfig: RendererConfig = { - playgroundUrl: 'http://localhost:5001', - rendererUrl: null, + "playgroundUrl": "http://localhost:5001", + "rendererUrl": null }; const fixtures = { @@ -93,41 +95,25 @@ const fixtures = { 'src/fixtures/Avatar.fixture.tsx': { module: fixture33 }, 'src/fixtures/AudioEmbed.fixture.tsx': { module: fixture34 }, 'src/fixtures/AttachmentPreviewList.fixture.tsx': { module: fixture35 }, - 'src/fixtures/ActionSheet/SendPostRetrySheet.fixture.tsx': { - module: fixture36, - }, + 'src/fixtures/ActionSheet/SendPostRetrySheet.fixture.tsx': { module: fixture36 }, 'src/fixtures/ActionSheet/ProfileSheet.fixture.tsx': { module: fixture37 }, - 'src/fixtures/ActionSheet/GroupPreviewSheet.fixture.tsx': { - module: fixture38, - }, - 'src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture.tsx': { - module: fixture39, - }, - 'src/fixtures/ActionSheet/GenericActionSheet.fixture.tsx': { - module: fixture40, - }, - 'src/fixtures/ActionSheet/EditSectionNameSheet.fixture.tsx': { - module: fixture41, - }, + 'src/fixtures/ActionSheet/GroupPreviewSheet.fixture.tsx': { module: fixture38 }, + 'src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture.tsx': { module: fixture39 }, + 'src/fixtures/ActionSheet/GenericActionSheet.fixture.tsx': { module: fixture40 }, + 'src/fixtures/ActionSheet/EditSectionNameSheet.fixture.tsx': { module: fixture41 }, 'src/fixtures/ActionSheet/DeleteSheet.fixture.tsx': { module: fixture42 }, - 'src/fixtures/ActionSheet/CreateChannelSheet.fixture.tsx': { - module: fixture43, - }, - 'src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture.tsx': { - module: fixture44, - }, + 'src/fixtures/ActionSheet/CreateChannelSheet.fixture.tsx': { module: fixture43 }, + 'src/fixtures/ActionSheet/ChannelSortActionsSheet.fixture.tsx': { module: fixture44 }, 'src/fixtures/ActionSheet/AttachmentSheet.fixture.tsx': { module: fixture45 }, - 'src/fixtures/ActionSheet/AddGalleryPostSheet.fixture.tsx': { - module: fixture46, - }, + 'src/fixtures/ActionSheet/AddGalleryPostSheet.fixture.tsx': { module: fixture46 } }; const decorators = { - 'src/fixtures/cosmos.decorator.tsx': { module: decorator0 }, + 'src/fixtures/cosmos.decorator.tsx': { module: decorator0 } }; export const moduleWrappers: UserModuleWrappers = { lazy: false, fixtures, - decorators, + decorators }; From f971b4e9588fcfd26a312c5526ce228da676bfc2 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Wed, 21 Aug 2024 11:05:21 -0400 Subject: [PATCH 30/33] account for channel switcher feature flag --- apps/tlon-mobile/src/hooks/useNotificationListener.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/tlon-mobile/src/hooks/useNotificationListener.ts b/apps/tlon-mobile/src/hooks/useNotificationListener.ts index f3e1e8a2c1..082659cf1b 100644 --- a/apps/tlon-mobile/src/hooks/useNotificationListener.ts +++ b/apps/tlon-mobile/src/hooks/useNotificationListener.ts @@ -1,6 +1,7 @@ import crashlytics from '@react-native-firebase/crashlytics'; import type { NavigationProp } from '@react-navigation/native'; import { CommonActions, useNavigation } from '@react-navigation/native'; +import { useFeatureFlag } from '@tloncorp/app/lib/featureFlags'; import { connectNotifications } from '@tloncorp/app/lib/notifications'; import * as posthog from '@tloncorp/app/utils/posthog'; import { syncDms, syncGroups } from '@tloncorp/shared'; @@ -35,6 +36,7 @@ export default function useNotificationListener({ }: Props) { const navigation = useNavigation>(); const { data: isTlonEmployee } = store.useIsTlonEmployee(); + const [channelSwitcherEnabled, _] = useFeatureFlag('channelSwitcher'); const [{ postInfo, channelId, isDm }, setGotoData] = useState<{ path?: string; @@ -115,7 +117,7 @@ export default function useNotificationListener({ } const routeStack: RouteStack = [{ name: 'ChatList' }]; - if (channel.group) { + if (channel.group && !channelSwitcherEnabled) { routeStack.push({ name: 'GroupChannels', params: { group: channel.group }, From 4b94306b1fb85cbbeced8743f7aff5b1c0d11c48 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Wed, 21 Aug 2024 10:38:50 -0500 Subject: [PATCH 31/33] activity: set allowed to all since we won't be using it --- desk/app/activity.hoon | 1 + 1 file changed, 1 insertion(+) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 42e04d821e..0e29281c07 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -139,6 +139,7 @@ =? old ?=(%5 -.old) (state-5-to-6 old) ?> ?=(%6 -.old) =. state old + =. allowed %all (emit %pass /fix-init-unreads %agent [our.bowl dap.bowl] %poke noun+!>(%fix-init-unreads)) +$ versioned-state $% state-6 From 18fc4b63097b668d428af1b1417596243066f56c Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 21 Aug 2024 16:32:24 +0000 Subject: [PATCH 32/33] update glob: [skip actions] --- desk/desk.docket-0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desk/desk.docket-0 b/desk/desk.docket-0 index 7a73ecff4f..9092fb0851 100644 --- a/desk/desk.docket-0 +++ b/desk/desk.docket-0 @@ -2,7 +2,7 @@ info+'Start, host, and cultivate communities. Own your communications, organize your resources, and share documents. Tlon is a decentralized platform that offers a full, communal suite of tools for messaging, writing and sharing media with others.' color+0xde.dede image+'https://bootstrap.urbit.org/tlon.svg?v=1' - glob-http+['https://bootstrap.urbit.org/glob-0v4.hirib.3mfdp.qdglf.e0kss.i2sgs.glob' 0v4.hirib.3mfdp.qdglf.e0kss.i2sgs] + glob-http+['https://bootstrap.urbit.org/glob-0v5.0v5ta.uubdh.ts772.avuoj.guen4.glob' 0v5.0v5ta.uubdh.ts772.avuoj.guen4] base+'groups' version+[6 2 0] website+'https://tlon.io' From ec11e8b584b08c36bb5d10663bfea5b097158f63 Mon Sep 17 00:00:00 2001 From: Hunter Miller Date: Wed, 21 Aug 2024 14:33:25 -0500 Subject: [PATCH 33/33] channels: make sure we give cursors for both and remove extraneous line --- desk/app/channels.hoon | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/desk/app/channels.hoon b/desk/app/channels.hoon index 1bf7a7384d..2f1dbf70f1 100644 --- a/desk/app/channels.hoon +++ b/desk/app/channels.hoon @@ -2006,20 +2006,20 @@ ?^ tim=(slaw %da after.pole) u.tim (slav %ud after.pole) =; posts=v-posts:c + =/ newer + ?~ newer=(tab:on-v-posts:c posts.channel `end 1) + ~ + `key:(head newer) + =/ older + ?~ older=(bat:mo-v-posts:c posts.channel `start 1) + ~ + `key:(head older) ?: ?=(%v2 version) =/ =paged-posts:c - :* (uv-posts-2:utils posts) - ?~ newer=(tab:on-v-posts:c posts.channel `end 1) - ~ - `key:(head newer) - ?~ older=(bat:mo-v-posts:c posts.channel `start 1) - ~ - `key:(head older) - (wyt:on-v-posts:c posts) - == + [(uv-posts-2:utils posts) newer older (wyt:on-v-posts:c posts)] ``channel-posts-2+!>(paged-posts) =/ =paged-posts:v1:old:c - [(uv-posts:utils posts) ~ ~ (wyt:on-v-posts:c posts)] + [(uv-posts:utils posts) newer older (wyt:on-v-posts:c posts)] ``channel-posts+!>(paged-posts) :: walk both posts and logs, in chronological order, newest-first, :: until we accumulate the desired amount of results @@ -2027,7 +2027,6 @@ ::NOTE would manually walk the tree, but logic gets rather confusing, :: so we just eat the conversion overhead here =/ posts (lot:on-v-posts:c posts.channel `(sub start 1) `(add end 1)) - =/ logs (tap:log-on:c (lot:log-on:c log.channel `after ~)) =/ updated (tap:updated-on:c (lot:updated-on:c last-updated.channel `after ~)) %- (log |.("posts: {<(lent posts)>}")) %- (log |.("updated: {<(lent updated)>}"))