@planningcenter/chat-react-native 4.4.1-qa-staging.10 → 4.4.1-qa-staging.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"api_provider.d.ts","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAIZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAgCxC,eAAO,MAAM,eAAe,aAO1B,CAAA;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,2CA6BlD;AAcD,wBAAgB,eAAe,WAQ9B"}
1
+ {"version":3,"file":"api_provider.d.ts","sourceRoot":"","sources":["../../src/contexts/api_provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAIZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAiCxC,eAAO,MAAM,eAAe,aAO1B,CAAA;AAEF,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,2CA8BlD;AAoBD,wBAAgB,eAAe,WAQ9B"}
@@ -5,6 +5,7 @@ import { useApiClient } from '../hooks/use_api_client';
5
5
  import { useAppState } from '../hooks/use_app_state';
6
6
  import { appGrantsQueryOptions } from '../hooks/use_chat_permissions';
7
7
  import { featuresQueryOptions } from '../hooks/use_features';
8
+ import { useJoltForegroundPing } from '../hooks/use_jolt';
8
9
  import { emitAuthRefresh } from '../utils/auth_events';
9
10
  import { ResponseError } from '../utils/response_error';
10
11
  import { ChatContext } from './chat_context';
@@ -39,7 +40,7 @@ export const chatQueryClient = new QueryClient({
39
40
  }
40
41
  });
41
42
  export function ApiProvider(t0) {
42
- const $ = _c(14);
43
+ const $ = _c(15);
43
44
  const {
44
45
  children
45
46
  } = t0;
@@ -109,18 +110,25 @@ export function ApiProvider(t0) {
109
110
  t6 = $[10];
110
111
  }
111
112
  let t7;
112
- if ($[11] !== children || $[12] !== t6) {
113
- t7 = /*#__PURE__*/_jsxs(QueryClientProvider, {
113
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
114
+ t7 = /*#__PURE__*/_jsx(JoltForegroundPing, {});
115
+ $[11] = t7;
116
+ } else {
117
+ t7 = $[11];
118
+ }
119
+ let t8;
120
+ if ($[12] !== children || $[13] !== t6) {
121
+ t8 = /*#__PURE__*/_jsxs(QueryClientProvider, {
114
122
  client: chatQueryClient,
115
- children: [t6, children]
123
+ children: [t6, t7, children]
116
124
  });
117
- $[11] = children;
118
- $[12] = t6;
119
- $[13] = t7;
125
+ $[12] = children;
126
+ $[13] = t6;
127
+ $[14] = t8;
120
128
  } else {
121
- t7 = $[13];
129
+ t8 = $[14];
122
130
  }
123
- return t7;
131
+ return t8;
124
132
  }
125
133
 
126
134
  // Component to prefetch queries when the app is focused
@@ -152,6 +160,10 @@ const PrefetchQueries = () => {
152
160
  usePrefetchQuery(t1);
153
161
  return null;
154
162
  };
163
+ const JoltForegroundPing = () => {
164
+ useJoltForegroundPing();
165
+ return null;
166
+ };
155
167
  export function useFocusManager() {
156
168
  const $ = _c(3);
157
169
  const appState = useAppState();
@@ -1 +1 @@
1
- {"version":3,"file":"api_provider.js","names":["focusManager","QueryClient","QueryClientProvider","usePrefetchQuery","React","useContext","useEffect","useRef","useApiClient","useAppState","appGrantsQueryOptions","featuresQueryOptions","emitAuthRefresh","ResponseError","ChatContext","jsx","_jsx","jsxs","_jsxs","apiClient","defaultQueryFn","queryKey","Error","url","data","headers","app","get","configuredRetry","failureCount","error","is429Error","status","chatQueryClient","defaultOptions","queries","queryFn","retry","ApiProvider","t0","$","_c","children","token","env","session","t1","sessionChanged","useSessionChanged","client","t2","t3","isFetching","cancelQueries","then","_temp","clear","t4","t5","t6","isAuthenticated","PrefetchQueries","t7","invalidateQueries","useFocusManager","appState","setFocused","value","newToken","newEnv","prevToken","prevEnv","usePrevious","isInitialLogin","tokenChanged","Boolean","access_token","envChanged","ref","current"],"sources":["../../src/contexts/api_provider.tsx"],"sourcesContent":["import {\n focusManager,\n QueryClient,\n QueryClientProvider,\n QueryKey,\n usePrefetchQuery,\n} from '@tanstack/react-query'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { ViewProps } from 'react-native'\nimport { ApiClient, useApiClient } from '../hooks/use_api_client'\nimport { useAppState } from '../hooks/use_app_state'\nimport { appGrantsQueryOptions } from '../hooks/use_chat_permissions'\nimport { featuresQueryOptions } from '../hooks/use_features'\nimport { RequestQueryKey } from '../hooks/use_suspense_api'\nimport { emitAuthRefresh } from '../utils/auth_events'\nimport { ResponseError } from '../utils/response_error'\nimport { ChatContext, ChatContextValue } from './chat_context'\n\nlet apiClient: ApiClient | undefined\n\nconst defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {\n if (!apiClient) {\n throw new Error('No token present')\n }\n\n const [url, data, headers, app = 'chat'] = queryKey as RequestQueryKey\n\n return apiClient[app].get({ url, data, headers })\n}\n\nconst configuredRetry = (failureCount: number, error: any) => {\n if (is429Error(error)) return false\n\n return failureCount < 3\n}\n\nconst is429Error = (error: any): boolean => {\n return error instanceof ResponseError && error.status === 429\n}\n\nexport const chatQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n queryFn: defaultQueryFn,\n retry: configuredRetry,\n },\n },\n})\n\nexport function ApiProvider({ children }: ViewProps) {\n const { token, env, session } = useContext(ChatContext)\n const sessionChanged = useSessionChanged({ token, env })\n\n const client = useApiClient()\n\n useEffect(() => {\n if (!sessionChanged) return\n\n emitAuthRefresh()\n\n if (chatQueryClient.isFetching()) {\n chatQueryClient.cancelQueries().then(() => chatQueryClient.invalidateQueries())\n return\n }\n\n chatQueryClient.clear()\n }, [sessionChanged])\n\n useEffect(() => {\n apiClient = client\n }, [client])\n\n return (\n <QueryClientProvider client={chatQueryClient}>\n {session.isAuthenticated && <PrefetchQueries />}\n {children}\n </QueryClientProvider>\n )\n}\n\n// Component to prefetch queries when the app is focused\n// This needs to live in the provider so that it can access the api client\n// and the chat query client\nconst PrefetchQueries = () => {\n const client = useApiClient()\n\n usePrefetchQuery(appGrantsQueryOptions(client))\n usePrefetchQuery(featuresQueryOptions(client))\n\n return null\n}\n\nexport function useFocusManager() {\n const appState = useAppState()\n\n useEffect(() => {\n focusManager.setFocused(appState === 'active')\n }, [appState])\n\n return appState\n}\n\nfunction useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {\n const { token: newToken, env: newEnv } = value\n const { token: prevToken, env: prevEnv } = usePrevious<typeof value>(value)\n\n const isInitialLogin = !prevToken && !!newToken\n if (isInitialLogin) return false\n\n const tokenChanged = Boolean(\n prevToken?.access_token && newToken?.access_token !== prevToken?.access_token\n )\n\n const envChanged = Boolean(prevEnv && newEnv !== prevEnv)\n\n return tokenChanged || envChanged\n}\n\nfunction usePrevious<T>(value: T): T {\n const ref = useRef<T>(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"api_provider.js","names":["focusManager","QueryClient","QueryClientProvider","usePrefetchQuery","React","useContext","useEffect","useRef","useApiClient","useAppState","appGrantsQueryOptions","featuresQueryOptions","useJoltForegroundPing","emitAuthRefresh","ResponseError","ChatContext","jsx","_jsx","jsxs","_jsxs","apiClient","defaultQueryFn","queryKey","Error","url","data","headers","app","get","configuredRetry","failureCount","error","is429Error","status","chatQueryClient","defaultOptions","queries","queryFn","retry","ApiProvider","t0","$","_c","children","token","env","session","t1","sessionChanged","useSessionChanged","client","t2","t3","isFetching","cancelQueries","then","_temp","clear","t4","t5","t6","isAuthenticated","PrefetchQueries","t7","Symbol","for","JoltForegroundPing","t8","invalidateQueries","useFocusManager","appState","setFocused","value","newToken","newEnv","prevToken","prevEnv","usePrevious","isInitialLogin","tokenChanged","Boolean","access_token","envChanged","ref","current"],"sources":["../../src/contexts/api_provider.tsx"],"sourcesContent":["import {\n focusManager,\n QueryClient,\n QueryClientProvider,\n QueryKey,\n usePrefetchQuery,\n} from '@tanstack/react-query'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { ViewProps } from 'react-native'\nimport { ApiClient, useApiClient } from '../hooks/use_api_client'\nimport { useAppState } from '../hooks/use_app_state'\nimport { appGrantsQueryOptions } from '../hooks/use_chat_permissions'\nimport { featuresQueryOptions } from '../hooks/use_features'\nimport { useJoltForegroundPing } from '../hooks/use_jolt'\nimport { RequestQueryKey } from '../hooks/use_suspense_api'\nimport { emitAuthRefresh } from '../utils/auth_events'\nimport { ResponseError } from '../utils/response_error'\nimport { ChatContext, ChatContextValue } from './chat_context'\n\nlet apiClient: ApiClient | undefined\n\nconst defaultQueryFn = ({ queryKey }: { queryKey: QueryKey }) => {\n if (!apiClient) {\n throw new Error('No token present')\n }\n\n const [url, data, headers, app = 'chat'] = queryKey as RequestQueryKey\n\n return apiClient[app].get({ url, data, headers })\n}\n\nconst configuredRetry = (failureCount: number, error: any) => {\n if (is429Error(error)) return false\n\n return failureCount < 3\n}\n\nconst is429Error = (error: any): boolean => {\n return error instanceof ResponseError && error.status === 429\n}\n\nexport const chatQueryClient = new QueryClient({\n defaultOptions: {\n queries: {\n queryFn: defaultQueryFn,\n retry: configuredRetry,\n },\n },\n})\n\nexport function ApiProvider({ children }: ViewProps) {\n const { token, env, session } = useContext(ChatContext)\n const sessionChanged = useSessionChanged({ token, env })\n\n const client = useApiClient()\n\n useEffect(() => {\n if (!sessionChanged) return\n\n emitAuthRefresh()\n\n if (chatQueryClient.isFetching()) {\n chatQueryClient.cancelQueries().then(() => chatQueryClient.invalidateQueries())\n return\n }\n\n chatQueryClient.clear()\n }, [sessionChanged])\n\n useEffect(() => {\n apiClient = client\n }, [client])\n\n return (\n <QueryClientProvider client={chatQueryClient}>\n {session.isAuthenticated && <PrefetchQueries />}\n <JoltForegroundPing />\n {children}\n </QueryClientProvider>\n )\n}\n\n// Component to prefetch queries when the app is focused\n// This needs to live in the provider so that it can access the api client\n// and the chat query client\nconst PrefetchQueries = () => {\n const client = useApiClient()\n\n usePrefetchQuery(appGrantsQueryOptions(client))\n usePrefetchQuery(featuresQueryOptions(client))\n\n return null\n}\n\nconst JoltForegroundPing = () => {\n useJoltForegroundPing()\n\n return null\n}\n\nexport function useFocusManager() {\n const appState = useAppState()\n\n useEffect(() => {\n focusManager.setFocused(appState === 'active')\n }, [appState])\n\n return appState\n}\n\nfunction useSessionChanged(value: Pick<ChatContextValue, 'token' | 'env'>): boolean {\n const { token: newToken, env: newEnv } = value\n const { token: prevToken, env: prevEnv } = usePrevious<typeof value>(value)\n\n const isInitialLogin = !prevToken && !!newToken\n if (isInitialLogin) return false\n\n const tokenChanged = Boolean(\n prevToken?.access_token && newToken?.access_token !== prevToken?.access_token\n )\n\n const envChanged = Boolean(prevEnv && newEnv !== prevEnv)\n\n return tokenChanged || envChanged\n}\n\nfunction usePrevious<T>(value: T): T {\n const ref = useRef<T>(value)\n\n useEffect(() => {\n ref.current = value\n }, [value])\n\n return ref.current\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"use_conversation_messages.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAazD,OAAO,EAAE,wBAAwB,EAAwB,MAAM,oBAAoB,CAAA;AAEnF,KAAK,aAAa,GAAG;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAC/E,KAAK,OAAO,GAAG,aAAa,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEzD,eAAO,MAAM,uBAAuB,GAClC,4CAA4C,OAAO,EACnD,OAAO,wBAAwB;;;;;;;;;;CA0EhC,CAAA;AAiBD,eAAO,MAAM,0BAA0B,GAAI,SAAS,aAAa,SAIhE,CAAA"}
1
+ {"version":3,"file":"use_conversation_messages.d.ts","sourceRoot":"","sources":["../../src/hooks/use_conversation_messages.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAazD,OAAO,EAAE,wBAAwB,EAAwB,MAAM,oBAAoB,CAAA;AAEnF,KAAK,aAAa,GAAG;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAC/E,KAAK,OAAO,GAAG,aAAa,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEzD,eAAO,MAAM,uBAAuB,GAClC,4CAA4C,OAAO,EACnD,OAAO,wBAAwB;;;;;;;;;;CA0EhC,CAAA;AAmBD,eAAO,MAAM,0BAA0B,GAAI,SAAS,aAAa,SAIhE,CAAA"}
@@ -148,40 +148,40 @@ export const useConversationMessages = (t0, opts) => {
148
148
  }
149
149
  const messages = t9;
150
150
  let t10;
151
- let t11;
152
- if ($[26] !== infiniteData || $[27] !== queryClient || $[28] !== queryKey) {
153
- t10 = () => {
154
- const settled = markLiveIfCaughtUp(infiniteData);
155
- if (settled !== infiniteData) {
156
- queryClient.setQueryData(queryKey, settled);
157
- }
151
+ if ($[26] !== anchor || $[27] !== conversation_id || $[28] !== reply_root_id) {
152
+ t10 = {
153
+ conversation_id,
154
+ reply_root_id,
155
+ anchor
158
156
  };
159
- t11 = [infiniteData, queryClient, queryKey];
160
- $[26] = infiniteData;
161
- $[27] = queryClient;
162
- $[28] = queryKey;
157
+ $[26] = anchor;
158
+ $[27] = conversation_id;
159
+ $[28] = reply_root_id;
163
160
  $[29] = t10;
164
- $[30] = t11;
165
161
  } else {
166
162
  t10 = $[29];
167
- t11 = $[30];
168
163
  }
169
- useEffect(t10, t11);
164
+ useEnsureWindowOpenedAtAnchor(t10);
165
+ let t11;
170
166
  let t12;
171
- if ($[31] !== anchor || $[32] !== conversation_id || $[33] !== reply_root_id) {
172
- t12 = {
173
- conversation_id,
174
- reply_root_id,
175
- anchor
167
+ if ($[30] !== infiniteData || $[31] !== queryClient || $[32] !== queryKey) {
168
+ t11 = () => {
169
+ const settled = markLiveIfCaughtUp(infiniteData);
170
+ if (settled !== infiniteData) {
171
+ queryClient.setQueryData(queryKey, settled);
172
+ }
176
173
  };
177
- $[31] = anchor;
178
- $[32] = conversation_id;
179
- $[33] = reply_root_id;
174
+ t12 = [infiniteData, queryClient, queryKey];
175
+ $[30] = infiniteData;
176
+ $[31] = queryClient;
177
+ $[32] = queryKey;
178
+ $[33] = t11;
180
179
  $[34] = t12;
181
180
  } else {
181
+ t11 = $[33];
182
182
  t12 = $[34];
183
183
  }
184
- useEnsureWindowHoldsAnchor(t12);
184
+ useEffect(t11, t12);
185
185
  let t13;
186
186
  if ($[35] !== behind || $[36] !== fetchLiveWindow || $[37] !== fetchNewer || $[38] !== fetchOlder || $[39] !== hasNextPage || $[40] !== isRefetching || $[41] !== messages || $[42] !== queryKey || $[43] !== refetch) {
187
187
  t13 = {
@@ -210,7 +210,7 @@ export const useConversationMessages = (t0, opts) => {
210
210
  }
211
211
  return t13;
212
212
  };
213
- const useEnsureWindowHoldsAnchor = t0 => {
213
+ const useEnsureWindowOpenedAtAnchor = t0 => {
214
214
  const $ = _c(6);
215
215
  const {
216
216
  conversation_id,
@@ -230,8 +230,11 @@ const useEnsureWindowHoldsAnchor = t0 => {
230
230
  reply_root_id
231
231
  });
232
232
  const cached = queryClient.getQueryData(queryKey);
233
- const holdsAnchor = cached?.pages.some(page => page.data.some(m => m.id === anchor));
234
- if (cached && !holdsAnchor) {
233
+ if (!cached) {
234
+ return;
235
+ }
236
+ const openedAtAnchor = cached.pageParams[0]?.where?.id_around === anchor;
237
+ if (!openedAtAnchor) {
235
238
  queryClient.resetQueries({
236
239
  queryKey,
237
240
  exact: true
@@ -1 +1 @@
1
- {"version":3,"file":"use_conversation_messages.js","names":["useQueryClient","useEffect","useMemo","chatQueryClient","anchoredPageParam","isBehindLiveEdge","livePageParam","markLiveIfCaughtUp","newerPageParam","newestFirst","replaceEqualById","getMessagesQueryKey","getMessagesRequestArgs","useApiClient","useSuspensePaginator","useConversationMessages","t0","opts","$","_c","conversation_id","reply_root_id","anchor","queryClient","apiClient","t1","queryKey","t2","requestArgs","t3","t4","structuralSharing","initialPageParam","getPreviousPageParam","transformPage","data","infiniteData","refetch","isRefetching","fetchNextPage","fetchPreviousPage","hasNextPage","hasPreviousPage","t5","behind","t6","cancelRefetch","fetchOlder","t7","fetchNewer","t8","page","chat","get","cancelQueries","exact","setQueryData","pages","pageParams","fetchLiveWindow","t9","filter","_temp","sort","_temp2","messages","t10","t11","settled","t12","useEnsureWindowHoldsAnchor","t13","cached","getQueryData","holdsAnchor","some","m","id","resetQueries","dropMessagesWindowIfBehind","options","removeQueries","message","deletedAt","attachments","length","text","a","b","localeCompare"],"sources":["../../src/hooks/use_conversation_messages.ts"],"sourcesContent":["import { useQueryClient } from '@tanstack/react-query'\nimport { useEffect, useMemo } from 'react'\nimport { chatQueryClient } from '../contexts/api_provider'\nimport { ApiCollection, MessageResource } from '../types'\nimport {\n anchoredPageParam,\n isBehindLiveEdge,\n livePageParam,\n markLiveIfCaughtUp,\n MessagesWindow,\n newerPageParam,\n newestFirst,\n} from '../utils/cache/messages_window'\nimport { replaceEqualById } from '../utils/replace_equal_by_id'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { useApiClient } from './use_api_client'\nimport { SuspensePaginatorOptions, useSuspensePaginator } from './use_suspense_api'\n\ntype WindowOptions = { conversation_id: number; reply_root_id?: string | null }\ntype Options = WindowOptions & { anchor?: string | null }\n\nexport const useConversationMessages = (\n { conversation_id, reply_root_id, anchor }: Options,\n opts?: SuspensePaginatorOptions\n) => {\n const queryClient = useQueryClient()\n const apiClient = useApiClient()\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })\n const requestArgs = getMessagesRequestArgs({ conversation_id, reply_root_id })\n const {\n data,\n infiniteData,\n refetch,\n isRefetching,\n fetchNextPage,\n fetchPreviousPage,\n hasNextPage,\n hasPreviousPage,\n } = useSuspensePaginator<MessageResource>(requestArgs, {\n structuralSharing: replaceEqualById,\n initialPageParam: anchor ? anchoredPageParam(anchor) : livePageParam,\n getPreviousPageParam: newerPageParam,\n transformPage: newestFirst,\n ...opts,\n })\n const behind = isBehindLiveEdge(infiniteData)\n\n const fetchOlder = () => fetchNextPage({ cancelRefetch: false })\n\n const fetchNewer = async () => {\n if (!hasPreviousPage) return\n\n await fetchPreviousPage({ cancelRefetch: false })\n }\n\n const fetchLiveWindow = async () => {\n if (!behind) return\n\n const page = await apiClient.chat.get<ApiCollection<MessageResource>>(requestArgs)\n await queryClient.cancelQueries({ queryKey, exact: true })\n queryClient.setQueryData<MessagesWindow>(queryKey, {\n pages: [page],\n pageParams: [livePageParam],\n })\n }\n\n const messages = useMemo(\n () =>\n data\n .filter(message => message.deletedAt || message.attachments?.length || message.text?.length)\n .sort((a, b) => -a.id.localeCompare(b.id)),\n [data]\n )\n\n // Once nothing newer remains, the top of the window is the live edge. Without this,\n // a refetch would replay from the anchor and drop rows Jolt has added since.\n useEffect(() => {\n const settled = markLiveIfCaughtUp(infiniteData)\n\n if (settled !== infiniteData) {\n queryClient.setQueryData(queryKey, settled)\n }\n }, [infiniteData, queryClient, queryKey])\n\n useEnsureWindowHoldsAnchor({ conversation_id, reply_root_id, anchor })\n\n return {\n messages,\n behind,\n refetch,\n isRefetching,\n fetchNextPage: fetchOlder,\n fetchNewer,\n fetchLiveWindow,\n hasNextPage,\n queryKey,\n }\n}\n\nconst useEnsureWindowHoldsAnchor = ({ conversation_id, reply_root_id, anchor }: Options) => {\n const queryClient = useQueryClient()\n\n useEffect(() => {\n if (!anchor) return\n\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })\n const cached = queryClient.getQueryData<MessagesWindow>(queryKey)\n const holdsAnchor = cached?.pages.some(page => page.data.some(m => m.id === anchor))\n if (cached && !holdsAnchor) {\n queryClient.resetQueries({ queryKey, exact: true })\n }\n }, [anchor, conversation_id, reply_root_id, queryClient])\n}\n\nexport const dropMessagesWindowIfBehind = (options: WindowOptions) => {\n const queryKey = getMessagesQueryKey(options)\n const cached = chatQueryClient.getQueryData<MessagesWindow>(queryKey)\n if (isBehindLiveEdge(cached)) chatQueryClient.removeQueries({ queryKey, exact: true })\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"use_conversation_messages.js","names":["useQueryClient","useEffect","useMemo","chatQueryClient","anchoredPageParam","isBehindLiveEdge","livePageParam","markLiveIfCaughtUp","newerPageParam","newestFirst","replaceEqualById","getMessagesQueryKey","getMessagesRequestArgs","useApiClient","useSuspensePaginator","useConversationMessages","t0","opts","$","_c","conversation_id","reply_root_id","anchor","queryClient","apiClient","t1","queryKey","t2","requestArgs","t3","t4","structuralSharing","initialPageParam","getPreviousPageParam","transformPage","data","infiniteData","refetch","isRefetching","fetchNextPage","fetchPreviousPage","hasNextPage","hasPreviousPage","t5","behind","t6","cancelRefetch","fetchOlder","t7","fetchNewer","t8","page","chat","get","cancelQueries","exact","setQueryData","pages","pageParams","fetchLiveWindow","t9","filter","_temp","sort","_temp2","messages","t10","useEnsureWindowOpenedAtAnchor","t11","t12","settled","t13","cached","getQueryData","openedAtAnchor","where","id_around","resetQueries","dropMessagesWindowIfBehind","options","removeQueries","message","deletedAt","attachments","length","text","a","b","id","localeCompare"],"sources":["../../src/hooks/use_conversation_messages.ts"],"sourcesContent":["import { useQueryClient } from '@tanstack/react-query'\nimport { useEffect, useMemo } from 'react'\nimport { chatQueryClient } from '../contexts/api_provider'\nimport { ApiCollection, MessageResource } from '../types'\nimport {\n anchoredPageParam,\n isBehindLiveEdge,\n livePageParam,\n markLiveIfCaughtUp,\n MessagesWindow,\n newerPageParam,\n newestFirst,\n} from '../utils/cache/messages_window'\nimport { replaceEqualById } from '../utils/replace_equal_by_id'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { useApiClient } from './use_api_client'\nimport { SuspensePaginatorOptions, useSuspensePaginator } from './use_suspense_api'\n\ntype WindowOptions = { conversation_id: number; reply_root_id?: string | null }\ntype Options = WindowOptions & { anchor?: string | null }\n\nexport const useConversationMessages = (\n { conversation_id, reply_root_id, anchor }: Options,\n opts?: SuspensePaginatorOptions\n) => {\n const queryClient = useQueryClient()\n const apiClient = useApiClient()\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })\n const requestArgs = getMessagesRequestArgs({ conversation_id, reply_root_id })\n const {\n data,\n infiniteData,\n refetch,\n isRefetching,\n fetchNextPage,\n fetchPreviousPage,\n hasNextPage,\n hasPreviousPage,\n } = useSuspensePaginator<MessageResource>(requestArgs, {\n structuralSharing: replaceEqualById,\n initialPageParam: anchor ? anchoredPageParam(anchor) : livePageParam,\n getPreviousPageParam: newerPageParam,\n transformPage: newestFirst,\n ...opts,\n })\n const behind = isBehindLiveEdge(infiniteData)\n\n const fetchOlder = () => fetchNextPage({ cancelRefetch: false })\n\n const fetchNewer = async () => {\n if (!hasPreviousPage) return\n\n await fetchPreviousPage({ cancelRefetch: false })\n }\n\n const fetchLiveWindow = async () => {\n if (!behind) return\n\n const page = await apiClient.chat.get<ApiCollection<MessageResource>>(requestArgs)\n await queryClient.cancelQueries({ queryKey, exact: true })\n queryClient.setQueryData<MessagesWindow>(queryKey, {\n pages: [page],\n pageParams: [livePageParam],\n })\n }\n\n const messages = useMemo(\n () =>\n data\n .filter(message => message.deletedAt || message.attachments?.length || message.text?.length)\n .sort((a, b) => -a.id.localeCompare(b.id)),\n [data]\n )\n\n useEnsureWindowOpenedAtAnchor({ conversation_id, reply_root_id, anchor })\n\n // Once nothing newer remains, the top of the window is the live edge. Without this,\n // a refetch would replay from the anchor and drop rows Jolt has added since.\n useEffect(() => {\n const settled = markLiveIfCaughtUp(infiniteData)\n\n if (settled !== infiniteData) {\n queryClient.setQueryData(queryKey, settled)\n }\n }, [infiniteData, queryClient, queryKey])\n\n return {\n messages,\n behind,\n refetch,\n isRefetching,\n fetchNextPage: fetchOlder,\n fetchNewer,\n fetchLiveWindow,\n hasNextPage,\n queryKey,\n }\n}\n\nconst useEnsureWindowOpenedAtAnchor = ({ conversation_id, reply_root_id, anchor }: Options) => {\n const queryClient = useQueryClient()\n\n useEffect(() => {\n if (!anchor) return\n\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })\n const cached = queryClient.getQueryData<MessagesWindow>(queryKey)\n if (!cached) return\n\n const openedAtAnchor = cached.pageParams[0]?.where?.id_around === anchor\n if (!openedAtAnchor) {\n queryClient.resetQueries({ queryKey, exact: true })\n }\n }, [anchor, conversation_id, reply_root_id, queryClient])\n}\n\nexport const dropMessagesWindowIfBehind = (options: WindowOptions) => {\n const queryKey = getMessagesQueryKey(options)\n const cached = chatQueryClient.getQueryData<MessagesWindow>(queryKey)\n if (isBehindLiveEdge(cached)) chatQueryClient.removeQueries({ queryKey, exact: true })\n}\n"],"mappings":"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","ignoreList":[]}
@@ -3,6 +3,7 @@ import { CustomMessage } from '@planningcenter/jolt-client/dist/types/JoltConnec
3
3
  import { JoltSubscription } from '@planningcenter/jolt-client/dist/types/JoltSubscription';
4
4
  import type { JoltSubscriptionPattern } from '../types/jolt_events';
5
5
  export declare const useJoltClient: () => JoltClient | undefined;
6
+ export declare const useJoltForegroundPing: () => void;
6
7
  export declare function useJoltChannel(channelName: string, enabled?: boolean): JoltSubscription | undefined | null;
7
8
  type UserCallbackFn<T> = (_event: T) => void;
8
9
  export declare function useJoltEvent<T extends CustomMessage>(channel: JoltSubscription | undefined | null, eventName: JoltSubscriptionPattern, callback: UserCallbackFn<T>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"use_jolt.d.ts","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,6BAA6B,CAAA;AACpD,OAAO,EACL,aAAa,EAEd,MAAM,uDAAuD,CAAA;AAC9D,OAAO,EAEL,gBAAgB,EACjB,MAAM,yDAAyD,CAAA;AAKhE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAWnE,eAAO,MAAM,aAAa,QAAO,UAAU,GAAG,SAqG7C,CAAA;AAED,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAc,GACtB,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAoCrC;AAED,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;AAE5C,wBAAgB,YAAY,CAAC,CAAC,SAAS,aAAa,EAClD,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,EAC5C,SAAS,EAAE,uBAAuB,EAClC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAO5B"}
1
+ {"version":3,"file":"use_jolt.d.ts","sourceRoot":"","sources":["../../src/hooks/use_jolt.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,6BAA6B,CAAA;AACpD,OAAO,EACL,aAAa,EAEd,MAAM,uDAAuD,CAAA;AAC9D,OAAO,EAEL,gBAAgB,EACjB,MAAM,yDAAyD,CAAA;AAMhE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAWnE,eAAO,MAAM,aAAa,QAAO,UAAU,GAAG,SAqG7C,CAAA;AAgBD,eAAO,MAAM,qBAAqB,YAcjC,CAAA;AAED,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAc,GACtB,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAoCrC;AAED,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;AAE5C,wBAAgB,YAAY,CAAC,CAAC,SAAS,aAAa,EAClD,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,EAC5C,SAAS,EAAE,uBAAuB,EAClC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,QAO5B"}
@@ -2,6 +2,7 @@ import { c as _c } from "react/compiler-runtime";
2
2
  import JoltClient from '@planningcenter/jolt-client';
3
3
  import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
4
4
  import { useCallback, useEffect, useMemo } from 'react';
5
+ import { AppState } from 'react-native';
5
6
  import { useChatContext } from '../contexts/chat_context';
6
7
  import { Client, Uri } from '../utils';
7
8
  import { throwResponseError } from '../utils/response_error';
@@ -181,6 +182,43 @@ export const useJoltClient = () => {
181
182
  } = useQuery(t11);
182
183
  return joltClient;
183
184
  };
185
+ const pingSubscribedJoltClients = queryClient => {
186
+ queryClient.getQueryCache().findAll({
187
+ queryKey: ['jolt-client']
188
+ }).forEach(query => {
189
+ const joltClient = query.state.data;
190
+ if (!joltClient || joltClient.subscriptions.length === 0) return;
191
+ try {
192
+ joltClient.ping();
193
+ } catch {}
194
+ });
195
+ };
196
+ export const useJoltForegroundPing = () => {
197
+ const $ = _c(3);
198
+ const queryClient = useQueryClient();
199
+ let t0;
200
+ let t1;
201
+ if ($[0] !== queryClient) {
202
+ t0 = () => {
203
+ let previousState = AppState.currentState;
204
+ const subscription = AppState.addEventListener("change", nextState => {
205
+ if (nextState === "active" && previousState !== "active") {
206
+ pingSubscribedJoltClients(queryClient);
207
+ }
208
+ previousState = nextState;
209
+ });
210
+ return () => subscription.remove();
211
+ };
212
+ t1 = [queryClient];
213
+ $[0] = queryClient;
214
+ $[1] = t0;
215
+ $[2] = t1;
216
+ } else {
217
+ t0 = $[1];
218
+ t1 = $[2];
219
+ }
220
+ useEffect(t0, t1);
221
+ };
184
222
  export function useJoltChannel(channelName, t0) {
185
223
  const $ = _c(16);
186
224
  const enabled = t0 === undefined ? true : t0;
@@ -1 +1 @@
1
- {"version":3,"file":"use_jolt.js","names":["JoltClient","useQuery","useQueryClient","useSuspenseQuery","useCallback","useEffect","useMemo","useChatContext","Client","Uri","throwResponseError","FIVE_SECONDS","useJoltClient","$","_c","session","sessionAccessToken","token","access_token","queryClient","t0","uri","t1","root","api","defaultHeaders","headers","version","apiClient","t2","fetchQuery","queryKey","queryFn","post","url","data","type","attributes","catch","staleTime","fetchJoltToken","t3","Symbol","for","t4","then","_temp","Infinity","gcTime","refetchOnWindowFocus","wssUrl","t5","_temp2","fetchAuthTokenFn","t6","channel","connectionId","cid","_temp3","_temp4","fetchSubscribeToken","t7","channel_0","connectionId_0","options","fetchSubscribeTokenFn","t8","Boolean","t9","t10","logToConsole","t11","enabled","joltClient","useJoltChannel","channelName","undefined","jolt","ready","alreadySubscribed","subscriptions","find","c","subscribe","handleSubscribe","subscription","removeQueries","exact","unsubscribe","handleUnsubscribe","useJoltEvent","eventName","callback","_temp5","bind","e","res","res_0","id","res_1","res_2","console","error"],"sources":["../../src/hooks/use_jolt.ts"],"sourcesContent":["import JoltClient from '@planningcenter/jolt-client'\nimport {\n CustomMessage,\n FetchAuthToken,\n} from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport {\n FetchSubscribeToken,\n JoltSubscription,\n} from '@planningcenter/jolt-client/dist/types/JoltSubscription'\nimport { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo } from 'react'\nimport { useChatContext } from '../contexts/chat_context'\nimport { ApiResource } from '../types'\nimport type { JoltSubscriptionPattern } from '../types/jolt_events'\nimport { Client, Uri } from '../utils'\nimport { throwResponseError } from '../utils/response_error'\nimport { FIVE_SECONDS } from '../utils/time'\n\ninterface JoltResponse {\n type: 'JoltToken'\n id: string\n wssUrl: string\n}\n\nexport const useJoltClient = (): JoltClient | undefined => {\n const { session } = useChatContext()\n const sessionAccessToken = session.token?.access_token\n const queryClient = useQueryClient()\n const uri = useMemo(() => new Uri({ session }), [session])\n const apiClient = useMemo(\n () =>\n new Client({\n root: uri.api(`/chat/v2`),\n defaultHeaders: uri.headers,\n version: '2018-11-01',\n }),\n [uri]\n )\n\n const fetchJoltToken = async () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-token'],\n queryFn: () => {\n return apiClient\n .post<ApiResource<JoltResponse>>({\n url: '/me/jolt_authorize',\n data: {\n data: {\n type: 'JoltToken',\n attributes: {},\n },\n },\n })\n .catch(throwResponseError)\n },\n staleTime: FIVE_SECONDS,\n })\n }\n\n /** The wssUrl is static and doesn't change so we can cache it to infinity and beyond */\n const { data: wssUrl } = useSuspenseQuery<string>({\n queryKey: ['wss-url'],\n queryFn: () => fetchJoltToken().then(res => res.data.wssUrl),\n staleTime: Infinity,\n gcTime: Infinity,\n refetchOnWindowFocus: false,\n })\n\n const fetchAuthTokenFn: FetchAuthToken = () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-auth-token'],\n queryFn: () => fetchJoltToken().then(res => res.data.id),\n })\n }\n\n const fetchSubscribeToken: FetchSubscribeToken = (channel: string, connectionId: string) => {\n return apiClient\n .post<ApiResource<JoltResponse>>({\n url: '/me/jolt_subscribe',\n data: {\n data: {\n type: 'JoltSubscribeToken',\n attributes: { channel, cid: connectionId },\n },\n },\n })\n .then(res => res.data.id)\n .catch((res: unknown) => {\n console.error('failed to subscribe to Jolt channel', res)\n return ''\n })\n }\n\n const fetchSubscribeTokenFn: FetchSubscribeToken = (\n channel: string,\n connectionId: string,\n options\n ) => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-subscribe-token', channel, connectionId],\n queryFn: () => fetchSubscribeToken(channel, connectionId, options),\n })\n }\n\n const { data: joltClient } = useQuery({\n enabled: Boolean(wssUrl),\n queryKey: ['jolt-client', wssUrl, sessionAccessToken],\n queryFn: async () => {\n if (!wssUrl) return undefined\n\n return new JoltClient(\n wssUrl,\n {\n fetchAuthTokenFn,\n fetchSubscribeTokenFn,\n },\n { logToConsole: false }\n )\n },\n refetchOnWindowFocus: false,\n staleTime: Infinity,\n gcTime: Infinity,\n })\n\n return joltClient\n}\n\nexport function useJoltChannel(\n channelName: string,\n enabled: boolean = true\n): JoltSubscription | undefined | null {\n const jolt = useJoltClient()\n const queryClient = useQueryClient()\n const ready = Boolean(jolt) && enabled\n\n const handleSubscribe = useCallback(async () => {\n if (!jolt) return null\n\n // If the subscription already exists, we don't need to subscribe again\n const alreadySubscribed = jolt.subscriptions.find(c => c.channel === channelName)\n if (alreadySubscribed) return alreadySubscribed\n\n return jolt.subscribe(channelName)\n }, [channelName, jolt])\n\n const { data: subscription } = useQuery<JoltSubscription | null>({\n queryKey: ['jolt-subscription', channelName],\n queryFn: handleSubscribe,\n refetchOnWindowFocus: false,\n enabled: ready,\n })\n\n const handleUnsubscribe = useCallback(() => {\n queryClient.removeQueries({\n queryKey: ['jolt-subscription', channelName],\n exact: true,\n })\n\n jolt?.unsubscribe(channelName)\n }, [queryClient, channelName, jolt])\n\n useEffect(() => {\n return handleUnsubscribe\n }, [handleUnsubscribe])\n\n return subscription\n}\n\ntype UserCallbackFn<T> = (_event: T) => void\n\nexport function useJoltEvent<T extends CustomMessage>(\n channel: JoltSubscription | undefined | null,\n eventName: JoltSubscriptionPattern,\n callback: UserCallbackFn<T>\n) {\n useEffect(() => {\n if (!channel) return () => {}\n\n return channel.bind(eventName, e => callback(e as T))\n }, [channel, eventName, callback])\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"use_jolt.js","names":["JoltClient","useQuery","useQueryClient","useSuspenseQuery","useCallback","useEffect","useMemo","AppState","useChatContext","Client","Uri","throwResponseError","FIVE_SECONDS","useJoltClient","$","_c","session","sessionAccessToken","token","access_token","queryClient","t0","uri","t1","root","api","defaultHeaders","headers","version","apiClient","t2","fetchQuery","queryKey","queryFn","post","url","data","type","attributes","catch","staleTime","fetchJoltToken","t3","Symbol","for","t4","then","_temp","Infinity","gcTime","refetchOnWindowFocus","wssUrl","t5","_temp2","fetchAuthTokenFn","t6","channel","connectionId","cid","_temp3","_temp4","fetchSubscribeToken","t7","channel_0","connectionId_0","options","fetchSubscribeTokenFn","t8","Boolean","t9","t10","logToConsole","t11","enabled","joltClient","pingSubscribedJoltClients","getQueryCache","findAll","forEach","query","state","subscriptions","length","ping","useJoltForegroundPing","previousState","currentState","subscription","addEventListener","nextState","remove","useJoltChannel","channelName","undefined","jolt","ready","alreadySubscribed","find","c","subscribe","handleSubscribe","removeQueries","exact","unsubscribe","handleUnsubscribe","useJoltEvent","eventName","callback","_temp5","bind","e","res","res_0","id","res_1","res_2","console","error"],"sources":["../../src/hooks/use_jolt.ts"],"sourcesContent":["import JoltClient from '@planningcenter/jolt-client'\nimport {\n CustomMessage,\n FetchAuthToken,\n} from '@planningcenter/jolt-client/dist/types/JoltConnection'\nimport {\n FetchSubscribeToken,\n JoltSubscription,\n} from '@planningcenter/jolt-client/dist/types/JoltSubscription'\nimport { QueryClient, useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo } from 'react'\nimport { AppState, AppStateStatus } from 'react-native'\nimport { useChatContext } from '../contexts/chat_context'\nimport { ApiResource } from '../types'\nimport type { JoltSubscriptionPattern } from '../types/jolt_events'\nimport { Client, Uri } from '../utils'\nimport { throwResponseError } from '../utils/response_error'\nimport { FIVE_SECONDS } from '../utils/time'\n\ninterface JoltResponse {\n type: 'JoltToken'\n id: string\n wssUrl: string\n}\n\nexport const useJoltClient = (): JoltClient | undefined => {\n const { session } = useChatContext()\n const sessionAccessToken = session.token?.access_token\n const queryClient = useQueryClient()\n const uri = useMemo(() => new Uri({ session }), [session])\n const apiClient = useMemo(\n () =>\n new Client({\n root: uri.api(`/chat/v2`),\n defaultHeaders: uri.headers,\n version: '2018-11-01',\n }),\n [uri]\n )\n\n const fetchJoltToken = async () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-token'],\n queryFn: () => {\n return apiClient\n .post<ApiResource<JoltResponse>>({\n url: '/me/jolt_authorize',\n data: {\n data: {\n type: 'JoltToken',\n attributes: {},\n },\n },\n })\n .catch(throwResponseError)\n },\n staleTime: FIVE_SECONDS,\n })\n }\n\n /** The wssUrl is static and doesn't change so we can cache it to infinity and beyond */\n const { data: wssUrl } = useSuspenseQuery<string>({\n queryKey: ['wss-url'],\n queryFn: () => fetchJoltToken().then(res => res.data.wssUrl),\n staleTime: Infinity,\n gcTime: Infinity,\n refetchOnWindowFocus: false,\n })\n\n const fetchAuthTokenFn: FetchAuthToken = () => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-auth-token'],\n queryFn: () => fetchJoltToken().then(res => res.data.id),\n })\n }\n\n const fetchSubscribeToken: FetchSubscribeToken = (channel: string, connectionId: string) => {\n return apiClient\n .post<ApiResource<JoltResponse>>({\n url: '/me/jolt_subscribe',\n data: {\n data: {\n type: 'JoltSubscribeToken',\n attributes: { channel, cid: connectionId },\n },\n },\n })\n .then(res => res.data.id)\n .catch((res: unknown) => {\n console.error('failed to subscribe to Jolt channel', res)\n return ''\n })\n }\n\n const fetchSubscribeTokenFn: FetchSubscribeToken = (\n channel: string,\n connectionId: string,\n options\n ) => {\n return queryClient.fetchQuery({\n queryKey: ['jolt-subscribe-token', channel, connectionId],\n queryFn: () => fetchSubscribeToken(channel, connectionId, options),\n })\n }\n\n const { data: joltClient } = useQuery({\n enabled: Boolean(wssUrl),\n queryKey: ['jolt-client', wssUrl, sessionAccessToken],\n queryFn: async () => {\n if (!wssUrl) return undefined\n\n return new JoltClient(\n wssUrl,\n {\n fetchAuthTokenFn,\n fetchSubscribeTokenFn,\n },\n { logToConsole: false }\n )\n },\n refetchOnWindowFocus: false,\n staleTime: Infinity,\n gcTime: Infinity,\n })\n\n return joltClient\n}\n\nconst pingSubscribedJoltClients = (queryClient: QueryClient) => {\n queryClient\n .getQueryCache()\n .findAll({ queryKey: ['jolt-client'] })\n .forEach(query => {\n const joltClient = query.state.data as JoltClient | undefined\n if (!joltClient || joltClient.subscriptions.length === 0) return\n\n try {\n joltClient.ping()\n } catch {}\n })\n}\n\nexport const useJoltForegroundPing = () => {\n const queryClient = useQueryClient()\n\n useEffect(() => {\n let previousState: AppStateStatus = AppState.currentState\n const subscription = AppState.addEventListener('change', nextState => {\n if (nextState === 'active' && previousState !== 'active') {\n pingSubscribedJoltClients(queryClient)\n }\n previousState = nextState\n })\n\n return () => subscription.remove()\n }, [queryClient])\n}\n\nexport function useJoltChannel(\n channelName: string,\n enabled: boolean = true\n): JoltSubscription | undefined | null {\n const jolt = useJoltClient()\n const queryClient = useQueryClient()\n const ready = Boolean(jolt) && enabled\n\n const handleSubscribe = useCallback(async () => {\n if (!jolt) return null\n\n // If the subscription already exists, we don't need to subscribe again\n const alreadySubscribed = jolt.subscriptions.find(c => c.channel === channelName)\n if (alreadySubscribed) return alreadySubscribed\n\n return jolt.subscribe(channelName)\n }, [channelName, jolt])\n\n const { data: subscription } = useQuery<JoltSubscription | null>({\n queryKey: ['jolt-subscription', channelName],\n queryFn: handleSubscribe,\n refetchOnWindowFocus: false,\n enabled: ready,\n })\n\n const handleUnsubscribe = useCallback(() => {\n queryClient.removeQueries({\n queryKey: ['jolt-subscription', channelName],\n exact: true,\n })\n\n jolt?.unsubscribe(channelName)\n }, [queryClient, channelName, jolt])\n\n useEffect(() => {\n return handleUnsubscribe\n }, [handleUnsubscribe])\n\n return subscription\n}\n\ntype UserCallbackFn<T> = (_event: T) => void\n\nexport function useJoltEvent<T extends CustomMessage>(\n channel: JoltSubscription | undefined | null,\n eventName: JoltSubscriptionPattern,\n callback: UserCallbackFn<T>\n) {\n useEffect(() => {\n if (!channel) return () => {}\n\n return channel.bind(eventName, e => callback(e as T))\n }, [channel, eventName, callback])\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"use_mark_latest_message_read.d.ts","sourceRoot":"","sources":["../../src/hooks/use_mark_latest_message_read.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAIhE,UAAU,KAAK;IACb,YAAY,EAAE,oBAAoB,CAAA;IAClC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,wBAAwB,CAAC,EAAE,YAAY,EAAE,OAAc,EAAE,EAAE,KAAK,QAqB/E"}
1
+ {"version":3,"file":"use_mark_latest_message_read.d.ts","sourceRoot":"","sources":["../../src/hooks/use_mark_latest_message_read.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAIhE,UAAU,KAAK;IACb,YAAY,EAAE,oBAAoB,CAAA;IAClC,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,wBAAwB,CAAC,EAAE,YAAY,EAAE,OAAc,EAAE,EAAE,KAAK,QAsB/E"}
@@ -18,13 +18,13 @@ export function useMarkLatestMessageRead({
18
18
  }), [markRead]);
19
19
  const unreadCount = conversation.unreadCount;
20
20
  const unreadReaction = conversation.unreadReaction;
21
- const shouldMarkRead = Boolean(unreadCount >= 1 || unreadReaction || !firedOnce.current);
21
+ const shouldMarkRead = !firedOnce.current || enabled && Boolean(unreadCount >= 1 || unreadReaction);
22
22
  const appState = useAppState();
23
23
  const isActive = appState === 'active';
24
24
  useEffect(() => {
25
- if (!enabled || !isActive || !shouldMarkRead) return;
25
+ if (!isActive || !shouldMarkRead) return;
26
26
  firedOnce.current = true;
27
27
  debouncedMarkRead(true);
28
- }, [debouncedMarkRead, enabled, isActive, shouldMarkRead, unreadReaction]);
28
+ }, [debouncedMarkRead, isActive, shouldMarkRead, unreadReaction]);
29
29
  }
30
30
  //# sourceMappingURL=use_mark_latest_message_read.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use_mark_latest_message_read.js","names":["debounce","useEffect","useMemo","useRef","useAppState","useConversationsMarkRead","useMarkLatestMessageRead","conversation","enabled","firedOnce","markRead","debouncedMarkRead","leading","trailing","unreadCount","unreadReaction","shouldMarkRead","Boolean","current","appState","isActive"],"sources":["../../src/hooks/use_mark_latest_message_read.ts"],"sourcesContent":["import { debounce } from 'lodash'\nimport { useEffect, useMemo, useRef } from 'react'\nimport { ConversationResource, MessageResource } from '../types'\nimport { useAppState } from './use_app_state'\nimport { useConversationsMarkRead } from './use_conversations_actions'\n\ninterface Props {\n conversation: ConversationResource\n messages: MessageResource[]\n enabled?: boolean\n}\n\nexport function useMarkLatestMessageRead({ conversation, enabled = true }: Props) {\n const firedOnce = useRef<boolean>(false)\n const { markRead } = useConversationsMarkRead({ conversation })\n const debouncedMarkRead = useMemo(\n () => debounce(markRead, 1000, { leading: true, trailing: true }),\n [markRead]\n )\n const unreadCount = conversation.unreadCount\n const unreadReaction = conversation.unreadReaction\n\n const shouldMarkRead = Boolean(unreadCount >= 1 || unreadReaction || !firedOnce.current)\n const appState = useAppState()\n const isActive = appState === 'active'\n\n useEffect(() => {\n if (!enabled || !isActive || !shouldMarkRead) return\n\n firedOnce.current = true\n\n debouncedMarkRead(true)\n }, [debouncedMarkRead, enabled, isActive, shouldMarkRead, unreadReaction])\n}\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,QAAQ;AACjC,SAASC,SAAS,EAAEC,OAAO,EAAEC,MAAM,QAAQ,OAAO;AAElD,SAASC,WAAW,QAAQ,iBAAiB;AAC7C,SAASC,wBAAwB,QAAQ,6BAA6B;AAQtE,OAAO,SAASC,wBAAwBA,CAAC;EAAEC,YAAY;EAAEC,OAAO,GAAG;AAAY,CAAC,EAAE;EAChF,MAAMC,SAAS,GAAGN,MAAM,CAAU,KAAK,CAAC;EACxC,MAAM;IAAEO;EAAS,CAAC,GAAGL,wBAAwB,CAAC;IAAEE;EAAa,CAAC,CAAC;EAC/D,MAAMI,iBAAiB,GAAGT,OAAO,CAC/B,MAAMF,QAAQ,CAACU,QAAQ,EAAE,IAAI,EAAE;IAAEE,OAAO,EAAE,IAAI;IAAEC,QAAQ,EAAE;EAAK,CAAC,CAAC,EACjE,CAACH,QAAQ,CACX,CAAC;EACD,MAAMI,WAAW,GAAGP,YAAY,CAACO,WAAW;EAC5C,MAAMC,cAAc,GAAGR,YAAY,CAACQ,cAAc;EAElD,MAAMC,cAAc,GAAGC,OAAO,CAACH,WAAW,IAAI,CAAC,IAAIC,cAAc,IAAI,CAACN,SAAS,CAACS,OAAO,CAAC;EACxF,MAAMC,QAAQ,GAAGf,WAAW,CAAC,CAAC;EAC9B,MAAMgB,QAAQ,GAAGD,QAAQ,KAAK,QAAQ;EAEtClB,SAAS,CAAC,MAAM;IACd,IAAI,CAACO,OAAO,IAAI,CAACY,QAAQ,IAAI,CAACJ,cAAc,EAAE;IAE9CP,SAAS,CAACS,OAAO,GAAG,IAAI;IAExBP,iBAAiB,CAAC,IAAI,CAAC;EACzB,CAAC,EAAE,CAACA,iBAAiB,EAAEH,OAAO,EAAEY,QAAQ,EAAEJ,cAAc,EAAED,cAAc,CAAC,CAAC;AAC5E","ignoreList":[]}
1
+ {"version":3,"file":"use_mark_latest_message_read.js","names":["debounce","useEffect","useMemo","useRef","useAppState","useConversationsMarkRead","useMarkLatestMessageRead","conversation","enabled","firedOnce","markRead","debouncedMarkRead","leading","trailing","unreadCount","unreadReaction","shouldMarkRead","current","Boolean","appState","isActive"],"sources":["../../src/hooks/use_mark_latest_message_read.ts"],"sourcesContent":["import { debounce } from 'lodash'\nimport { useEffect, useMemo, useRef } from 'react'\nimport { ConversationResource, MessageResource } from '../types'\nimport { useAppState } from './use_app_state'\nimport { useConversationsMarkRead } from './use_conversations_actions'\n\ninterface Props {\n conversation: ConversationResource\n messages: MessageResource[]\n enabled?: boolean\n}\n\nexport function useMarkLatestMessageRead({ conversation, enabled = true }: Props) {\n const firedOnce = useRef<boolean>(false)\n const { markRead } = useConversationsMarkRead({ conversation })\n const debouncedMarkRead = useMemo(\n () => debounce(markRead, 1000, { leading: true, trailing: true }),\n [markRead]\n )\n const unreadCount = conversation.unreadCount\n const unreadReaction = conversation.unreadReaction\n\n const shouldMarkRead =\n !firedOnce.current || (enabled && Boolean(unreadCount >= 1 || unreadReaction))\n const appState = useAppState()\n const isActive = appState === 'active'\n\n useEffect(() => {\n if (!isActive || !shouldMarkRead) return\n\n firedOnce.current = true\n\n debouncedMarkRead(true)\n }, [debouncedMarkRead, isActive, shouldMarkRead, unreadReaction])\n}\n"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,QAAQ;AACjC,SAASC,SAAS,EAAEC,OAAO,EAAEC,MAAM,QAAQ,OAAO;AAElD,SAASC,WAAW,QAAQ,iBAAiB;AAC7C,SAASC,wBAAwB,QAAQ,6BAA6B;AAQtE,OAAO,SAASC,wBAAwBA,CAAC;EAAEC,YAAY;EAAEC,OAAO,GAAG;AAAY,CAAC,EAAE;EAChF,MAAMC,SAAS,GAAGN,MAAM,CAAU,KAAK,CAAC;EACxC,MAAM;IAAEO;EAAS,CAAC,GAAGL,wBAAwB,CAAC;IAAEE;EAAa,CAAC,CAAC;EAC/D,MAAMI,iBAAiB,GAAGT,OAAO,CAC/B,MAAMF,QAAQ,CAACU,QAAQ,EAAE,IAAI,EAAE;IAAEE,OAAO,EAAE,IAAI;IAAEC,QAAQ,EAAE;EAAK,CAAC,CAAC,EACjE,CAACH,QAAQ,CACX,CAAC;EACD,MAAMI,WAAW,GAAGP,YAAY,CAACO,WAAW;EAC5C,MAAMC,cAAc,GAAGR,YAAY,CAACQ,cAAc;EAElD,MAAMC,cAAc,GAClB,CAACP,SAAS,CAACQ,OAAO,IAAKT,OAAO,IAAIU,OAAO,CAACJ,WAAW,IAAI,CAAC,IAAIC,cAAc,CAAE;EAChF,MAAMI,QAAQ,GAAGf,WAAW,CAAC,CAAC;EAC9B,MAAMgB,QAAQ,GAAGD,QAAQ,KAAK,QAAQ;EAEtClB,SAAS,CAAC,MAAM;IACd,IAAI,CAACmB,QAAQ,IAAI,CAACJ,cAAc,EAAE;IAElCP,SAAS,CAACQ,OAAO,GAAG,IAAI;IAExBN,iBAAiB,CAAC,IAAI,CAAC;EACzB,CAAC,EAAE,CAACA,iBAAiB,EAAES,QAAQ,EAAEJ,cAAc,EAAED,cAAc,CAAC,CAAC;AACnE","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"search_screen.d.ts","sourceRoot":"","sources":["../../../src/screens/search/search_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAiB,MAAM,0BAA0B,CAAA;AACvE,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACvB,MAAM,gCAAgC,CAAA;AAevC,eAAO,MAAM,mBAAmB,GAAI,iBAEjC,sBAAsB,CAAC,aAAa,CAAC,KAAG,4BAIxC,CAAA;AAEH,wBAAgB,YAAY,4CAqD3B"}
1
+ {"version":3,"file":"search_screen.d.ts","sourceRoot":"","sources":["../../../src/screens/search/search_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAiB,MAAM,0BAA0B,CAAA;AACvE,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACvB,MAAM,gCAAgC,CAAA;AAevC,eAAO,MAAM,mBAAmB,GAAI,iBAEjC,sBAAsB,CAAC,aAAa,CAAC,KAAG,4BAIxC,CAAA;AAEH,wBAAgB,YAAY,4CAuD3B"}
@@ -1,7 +1,7 @@
1
1
  import { c as _c } from "react/compiler-runtime";
2
2
  import { useNavigation } from '@react-navigation/native';
3
3
  import React, { useRef, useState } from 'react';
4
- import { Keyboard, StyleSheet, View } from 'react-native';
4
+ import { Keyboard, ScrollView, StyleSheet, View } from 'react-native';
5
5
  import { KeyboardView } from '../../components';
6
6
  import { composeOptions, withMinimalBack } from '../../components/display/platform_modal_header_buttons';
7
7
  import { useDebouncedSearchTerm } from '../../hooks/use_debounced_search_term';
@@ -98,7 +98,11 @@ export function SearchScreen() {
98
98
  term: debouncedTerm,
99
99
  onSelect: openResult,
100
100
  onSettled: publishSearch
101
- }, debouncedTerm) : /*#__PURE__*/_jsx(SearchPromptBlankState, {});
101
+ }, debouncedTerm) : /*#__PURE__*/_jsx(ScrollView, {
102
+ contentContainerStyle: styles.prompt,
103
+ keyboardShouldPersistTaps: "handled",
104
+ children: /*#__PURE__*/_jsx(SearchPromptBlankState, {})
105
+ });
102
106
  $[8] = debouncedTerm;
103
107
  $[9] = openResult;
104
108
  $[10] = publishSearch;
@@ -126,6 +130,10 @@ export function SearchScreen() {
126
130
  const styles = StyleSheet.create({
127
131
  container: {
128
132
  flex: 1
133
+ },
134
+ prompt: {
135
+ flexGrow: 1,
136
+ justifyContent: 'center'
129
137
  }
130
138
  });
131
139
  //# sourceMappingURL=search_screen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"search_screen.js","names":["useNavigation","React","useRef","useState","Keyboard","StyleSheet","View","KeyboardView","composeOptions","withMinimalBack","useDebouncedSearchTerm","analyticsEvents","useProductAnalytics","SearchPromptBlankState","SearchField","SearchResultsList","jsx","_jsx","jsxs","_jsxs","SearchScreenOptions","navigation","title","animation","onPress","goBack","SearchScreen","$","_c","term","setTerm","debouncedTerm","publishEvent","t0","Symbol","for","Set","publishedTerms","t1","settledTerm","counts","current","has","add","search_performed","term_length","length","conversation_result_count","conversationResultCount","message_result_count","messageResultCount","publishSearch","t2","result","position","dismiss","search_result_opened","result_type","type","navigate","conversation_id","Number","id","extra","conversationId","initial_message_id","openResult","t3","t4","t5","children","style","styles","container","testID","create","flex"],"sources":["../../../src/screens/search/search_screen.tsx"],"sourcesContent":["import { ParamListBase, useNavigation } from '@react-navigation/native'\nimport {\n NativeStackNavigationOptions,\n NativeStackScreenProps,\n} from '@react-navigation/native-stack'\nimport React, { useRef, useState } from 'react'\nimport { Keyboard, StyleSheet, View } from 'react-native'\nimport { KeyboardView } from '../../components'\nimport {\n composeOptions,\n withMinimalBack,\n} from '../../components/display/platform_modal_header_buttons'\nimport { useDebouncedSearchTerm } from '../../hooks/use_debounced_search_term'\nimport { analyticsEvents, useProductAnalytics } from '../../hooks/use_product_analytics'\nimport type { SearchResultResource } from '../../types/resources/search_result'\nimport { SearchPromptBlankState } from './components/search_blank_states'\nimport { SearchField } from './components/search_field'\nimport { SearchResultsList, type SearchResultCounts } from './components/search_results_list'\n\nexport const SearchScreenOptions = ({\n navigation,\n}: NativeStackScreenProps<ParamListBase>): NativeStackNavigationOptions =>\n composeOptions(\n { title: 'Search', animation: 'fade' },\n withMinimalBack({ onPress: () => navigation.goBack() })\n )\n\nexport function SearchScreen() {\n const navigation = useNavigation()\n const [term, setTerm] = useState('')\n const debouncedTerm = useDebouncedSearchTerm(term)\n const { publishEvent } = useProductAnalytics()\n const publishedTerms = useRef(new Set<string>())\n\n const publishSearch = (settledTerm: string, counts: SearchResultCounts) => {\n if (publishedTerms.current.has(settledTerm)) return\n\n publishedTerms.current.add(settledTerm)\n publishEvent(analyticsEvents.search_performed, {\n term_length: settledTerm.length,\n conversation_result_count: counts.conversationResultCount,\n message_result_count: counts.messageResultCount,\n })\n }\n\n const openResult = (result: SearchResultResource, position: number) => {\n Keyboard.dismiss()\n publishEvent(analyticsEvents.search_result_opened, { result_type: result.type, position })\n\n if (result.type === 'conversation') {\n navigation.navigate('Conversation', {\n conversation_id: Number(result.id),\n title: result.title,\n })\n } else {\n navigation.navigate('Conversation', {\n conversation_id: result.extra.conversationId,\n initial_message_id: result.id,\n title: result.title,\n })\n }\n }\n\n return (\n <KeyboardView>\n <View style={styles.container} testID=\"search-screen\">\n <SearchField term={term} onChange={setTerm} />\n {debouncedTerm.length > 0 ? (\n <SearchResultsList\n key={debouncedTerm}\n term={debouncedTerm}\n onSelect={openResult}\n onSettled={publishSearch}\n />\n ) : (\n <SearchPromptBlankState />\n )}\n </View>\n </KeyboardView>\n )\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n})\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"search_screen.js","names":["useNavigation","React","useRef","useState","Keyboard","ScrollView","StyleSheet","View","KeyboardView","composeOptions","withMinimalBack","useDebouncedSearchTerm","analyticsEvents","useProductAnalytics","SearchPromptBlankState","SearchField","SearchResultsList","jsx","_jsx","jsxs","_jsxs","SearchScreenOptions","navigation","title","animation","onPress","goBack","SearchScreen","$","_c","term","setTerm","debouncedTerm","publishEvent","t0","Symbol","for","Set","publishedTerms","t1","settledTerm","counts","current","has","add","search_performed","term_length","length","conversation_result_count","conversationResultCount","message_result_count","messageResultCount","publishSearch","t2","result","position","dismiss","search_result_opened","result_type","type","navigate","conversation_id","Number","id","extra","conversationId","initial_message_id","openResult","t3","t4","contentContainerStyle","styles","prompt","keyboardShouldPersistTaps","children","t5","style","container","testID","create","flex","flexGrow","justifyContent"],"sources":["../../../src/screens/search/search_screen.tsx"],"sourcesContent":["import { ParamListBase, useNavigation } from '@react-navigation/native'\nimport {\n NativeStackNavigationOptions,\n NativeStackScreenProps,\n} from '@react-navigation/native-stack'\nimport React, { useRef, useState } from 'react'\nimport { Keyboard, ScrollView, StyleSheet, View } from 'react-native'\nimport { KeyboardView } from '../../components'\nimport {\n composeOptions,\n withMinimalBack,\n} from '../../components/display/platform_modal_header_buttons'\nimport { useDebouncedSearchTerm } from '../../hooks/use_debounced_search_term'\nimport { analyticsEvents, useProductAnalytics } from '../../hooks/use_product_analytics'\nimport type { SearchResultResource } from '../../types/resources/search_result'\nimport { SearchPromptBlankState } from './components/search_blank_states'\nimport { SearchField } from './components/search_field'\nimport { SearchResultsList, type SearchResultCounts } from './components/search_results_list'\n\nexport const SearchScreenOptions = ({\n navigation,\n}: NativeStackScreenProps<ParamListBase>): NativeStackNavigationOptions =>\n composeOptions(\n { title: 'Search', animation: 'fade' },\n withMinimalBack({ onPress: () => navigation.goBack() })\n )\n\nexport function SearchScreen() {\n const navigation = useNavigation()\n const [term, setTerm] = useState('')\n const debouncedTerm = useDebouncedSearchTerm(term)\n const { publishEvent } = useProductAnalytics()\n const publishedTerms = useRef(new Set<string>())\n\n const publishSearch = (settledTerm: string, counts: SearchResultCounts) => {\n if (publishedTerms.current.has(settledTerm)) return\n\n publishedTerms.current.add(settledTerm)\n publishEvent(analyticsEvents.search_performed, {\n term_length: settledTerm.length,\n conversation_result_count: counts.conversationResultCount,\n message_result_count: counts.messageResultCount,\n })\n }\n\n const openResult = (result: SearchResultResource, position: number) => {\n Keyboard.dismiss()\n publishEvent(analyticsEvents.search_result_opened, { result_type: result.type, position })\n\n if (result.type === 'conversation') {\n navigation.navigate('Conversation', {\n conversation_id: Number(result.id),\n title: result.title,\n })\n } else {\n navigation.navigate('Conversation', {\n conversation_id: result.extra.conversationId,\n initial_message_id: result.id,\n title: result.title,\n })\n }\n }\n\n return (\n <KeyboardView>\n <View style={styles.container} testID=\"search-screen\">\n <SearchField term={term} onChange={setTerm} />\n {debouncedTerm.length > 0 ? (\n <SearchResultsList\n key={debouncedTerm}\n term={debouncedTerm}\n onSelect={openResult}\n onSettled={publishSearch}\n />\n ) : (\n <ScrollView contentContainerStyle={styles.prompt} keyboardShouldPersistTaps=\"handled\">\n <SearchPromptBlankState />\n </ScrollView>\n )}\n </View>\n </KeyboardView>\n )\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n prompt: {\n flexGrow: 1,\n justifyContent: 'center',\n },\n})\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/chat-react-native",
3
- "version": "4.4.1-qa-staging.10",
3
+ "version": "4.4.1-qa-staging.12",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,13 +33,13 @@
33
33
  "dependencies": {
34
34
  "@fortawesome/fontawesome-svg-core": "^7.2.0",
35
35
  "@fortawesome/react-native-fontawesome": "^0.3.2",
36
- "@planningcenter/emoji-keyboard": "4.4.1-qa-staging.10",
36
+ "@planningcenter/emoji-keyboard": "4.4.1-qa-staging.12",
37
37
  "lodash-inflection": "^1.5.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@planningcenter/datetime-fmt": ">=2.0.0",
41
41
  "@planningcenter/icons": "^15.24.0",
42
- "@planningcenter/jolt-client": "^3.0.0",
42
+ "@planningcenter/jolt-client": "^3.2.1",
43
43
  "@react-native-community/datetimepicker": ">=7.6.2",
44
44
  "@react-navigation/elements": "*",
45
45
  "@react-navigation/native": ">=7.0.0",
@@ -84,5 +84,5 @@
84
84
  "sf-symbols-typescript": "^2.2.0",
85
85
  "typescript": "~6.0.3"
86
86
  },
87
- "gitHead": "1e3d2b7deafd780d4651c8da8adc7083ff348c3d"
87
+ "gitHead": "6f3c08cf78133011af4691c1af089c2811982829"
88
88
  }
@@ -11,6 +11,7 @@ import { ApiClient, useApiClient } from '../hooks/use_api_client'
11
11
  import { useAppState } from '../hooks/use_app_state'
12
12
  import { appGrantsQueryOptions } from '../hooks/use_chat_permissions'
13
13
  import { featuresQueryOptions } from '../hooks/use_features'
14
+ import { useJoltForegroundPing } from '../hooks/use_jolt'
14
15
  import { RequestQueryKey } from '../hooks/use_suspense_api'
15
16
  import { emitAuthRefresh } from '../utils/auth_events'
16
17
  import { ResponseError } from '../utils/response_error'
@@ -73,6 +74,7 @@ export function ApiProvider({ children }: ViewProps) {
73
74
  return (
74
75
  <QueryClientProvider client={chatQueryClient}>
75
76
  {session.isAuthenticated && <PrefetchQueries />}
77
+ <JoltForegroundPing />
76
78
  {children}
77
79
  </QueryClientProvider>
78
80
  )
@@ -90,6 +92,12 @@ const PrefetchQueries = () => {
90
92
  return null
91
93
  }
92
94
 
95
+ const JoltForegroundPing = () => {
96
+ useJoltForegroundPing()
97
+
98
+ return null
99
+ }
100
+
93
101
  export function useFocusManager() {
94
102
  const appState = useAppState()
95
103
 
@@ -101,8 +101,8 @@ describe('useConversationMessages', () => {
101
101
  await waitFor(() => expect(result.current.messages.map(m => m.id)).toContain(anchor))
102
102
  })
103
103
 
104
- it('reuses a cached window that already holds the anchor', async () => {
105
- seed(livePageParam, ['Z', anchor])
104
+ it('reuses a cached window that was opened at the anchor', async () => {
105
+ seed(anchoredPageParam(anchor), ['Z', anchor], behindMeta)
106
106
 
107
107
  const { result } = render({ conversation_id, anchor })
108
108
 
@@ -110,6 +110,14 @@ describe('useConversationMessages', () => {
110
110
  expect(mockGet).not.toHaveBeenCalled()
111
111
  })
112
112
 
113
+ it('refetches around the anchor when a live window still holds a stale copy of it', async () => {
114
+ seed(livePageParam, ['Z', anchor])
115
+
116
+ render({ conversation_id, anchor })
117
+
118
+ await waitFor(() => expect(requestedWhere()).toEqual([{ id_around: anchor }]))
119
+ })
120
+
113
121
  it('keeps a deleted anchor so the list can mark where it was', async () => {
114
122
  const deleted = {
115
123
  ...message(anchor),
@@ -1,12 +1,15 @@
1
+ import JoltClient from '@planningcenter/jolt-client'
2
+ import { JoltSubscription } from '@planningcenter/jolt-client/dist/types/JoltSubscription'
1
3
  import { QueryClientProvider } from '@tanstack/react-query'
2
4
  import { render, waitFor } from '@testing-library/react-native'
3
5
  import React, { PropsWithChildren, Suspense } from 'react'
6
+ import { AppState, AppStateStatus } from 'react-native'
4
7
  import { buildTestQueryClient } from '../../__utils__/query_client'
5
8
  import { ChatContext, ChatContextValue } from '../../contexts/chat_context'
6
9
  import { Session } from '../../utils'
7
10
  import { Client } from '../../utils/client'
8
11
  import { ResponseError } from '../../utils/response_error'
9
- import { useJoltClient } from '../use_jolt'
12
+ import { useJoltClient, useJoltForegroundPing } from '../use_jolt'
10
13
 
11
14
  let caught: unknown
12
15
 
@@ -68,3 +71,77 @@ describe('useJoltClient', () => {
68
71
  expect((caught as ResponseError).status).toBe(401)
69
72
  })
70
73
  })
74
+
75
+ describe('useJoltForegroundPing', () => {
76
+ const addEventListener = AppState.addEventListener as jest.Mock
77
+ const confirmedSubscription = {} as JoltSubscription
78
+
79
+ const PingProbe = () => {
80
+ useJoltForegroundPing()
81
+ return null
82
+ }
83
+
84
+ const renderForegroundPing = (joltClient: Partial<JoltClient>) => {
85
+ const queryClient = buildTestQueryClient({ defaultOptions: { queries: { gcTime: Infinity } } })
86
+ queryClient.setQueryData(['jolt-client', 'wss://jolt.test', 'a-real-token'], joltClient)
87
+
88
+ render(
89
+ <QueryClientProvider client={queryClient}>
90
+ <PingProbe />
91
+ </QueryClientProvider>
92
+ )
93
+
94
+ const [, onChange] = addEventListener.mock.calls.at(-1) as [
95
+ string,
96
+ (_state: AppStateStatus) => void,
97
+ ]
98
+
99
+ return onChange
100
+ }
101
+
102
+ beforeEach(() => {
103
+ addEventListener.mockClear()
104
+ })
105
+
106
+ it('pings the jolt client once when the app returns to the foreground', () => {
107
+ const ping = jest.fn()
108
+ const onChange = renderForegroundPing({ ping, subscriptions: [confirmedSubscription] })
109
+
110
+ onChange('background')
111
+ onChange('active')
112
+
113
+ expect(ping).toHaveBeenCalledTimes(1)
114
+ })
115
+
116
+ it('does not ping when there are no confirmed subscriptions', () => {
117
+ const ping = jest.fn()
118
+ const onChange = renderForegroundPing({ ping, subscriptions: [] })
119
+
120
+ onChange('background')
121
+ onChange('active')
122
+
123
+ expect(ping).not.toHaveBeenCalled()
124
+ })
125
+
126
+ it('does not ping when the app leaves the foreground', () => {
127
+ const ping = jest.fn()
128
+ const onChange = renderForegroundPing({ ping, subscriptions: [confirmedSubscription] })
129
+
130
+ onChange('inactive')
131
+ onChange('background')
132
+
133
+ expect(ping).not.toHaveBeenCalled()
134
+ })
135
+
136
+ it('swallows errors from pinging a closed socket', () => {
137
+ const ping = jest.fn(() => {
138
+ throw new Error('No WebSocket')
139
+ })
140
+ const onChange = renderForegroundPing({ ping, subscriptions: [confirmedSubscription] })
141
+
142
+ onChange('background')
143
+
144
+ expect(() => onChange('active')).not.toThrow()
145
+ expect(ping).toHaveBeenCalledTimes(1)
146
+ })
147
+ })
@@ -1,4 +1,4 @@
1
- import { renderHook } from '@testing-library/react-native'
1
+ import { act, renderHook } from '@testing-library/react-native'
2
2
  import type { ConversationResource } from '../../types'
3
3
  import { useMarkLatestMessageRead } from '../use_mark_latest_message_read'
4
4
 
@@ -19,15 +19,29 @@ describe('useMarkLatestMessageRead', () => {
19
19
  expect(mockMarkRead).toHaveBeenCalledTimes(1)
20
20
  })
21
21
 
22
- it('waits while disabled and marks read once enabled', () => {
23
- const { rerender } = renderHook<void, { enabled: boolean }>(
24
- ({ enabled }) => useMarkLatestMessageRead({ conversation, messages: [], enabled }),
25
- { initialProps: { enabled: false } }
22
+ it('marks read once on mount even while disabled', () => {
23
+ renderHook(() => useMarkLatestMessageRead({ conversation, messages: [], enabled: false }))
24
+
25
+ expect(mockMarkRead).toHaveBeenCalledTimes(1)
26
+ })
27
+
28
+ it('ignores unread bumps while disabled and marks read once enabled', () => {
29
+ jest.useFakeTimers()
30
+ const { rerender } = renderHook<void, { conversation: ConversationResource; enabled: boolean }>(
31
+ props => useMarkLatestMessageRead({ ...props, messages: [] }),
32
+ { initialProps: { conversation: { ...conversation, unreadCount: 0 }, enabled: false } }
26
33
  )
27
- expect(mockMarkRead).not.toHaveBeenCalled()
34
+ expect(mockMarkRead).toHaveBeenCalledTimes(1)
28
35
 
29
- rerender({ enabled: true })
36
+ rerender({ conversation: { ...conversation, unreadCount: 2 }, enabled: false })
37
+ act(() => jest.advanceTimersByTime(1000))
30
38
 
31
39
  expect(mockMarkRead).toHaveBeenCalledTimes(1)
40
+
41
+ rerender({ conversation: { ...conversation, unreadCount: 2 }, enabled: true })
42
+ act(() => jest.advanceTimersByTime(1000))
43
+
44
+ expect(mockMarkRead).toHaveBeenCalledTimes(2)
45
+ jest.useRealTimers()
32
46
  })
33
47
  })
@@ -72,6 +72,8 @@ export const useConversationMessages = (
72
72
  [data]
73
73
  )
74
74
 
75
+ useEnsureWindowOpenedAtAnchor({ conversation_id, reply_root_id, anchor })
76
+
75
77
  // Once nothing newer remains, the top of the window is the live edge. Without this,
76
78
  // a refetch would replay from the anchor and drop rows Jolt has added since.
77
79
  useEffect(() => {
@@ -82,8 +84,6 @@ export const useConversationMessages = (
82
84
  }
83
85
  }, [infiniteData, queryClient, queryKey])
84
86
 
85
- useEnsureWindowHoldsAnchor({ conversation_id, reply_root_id, anchor })
86
-
87
87
  return {
88
88
  messages,
89
89
  behind,
@@ -97,7 +97,7 @@ export const useConversationMessages = (
97
97
  }
98
98
  }
99
99
 
100
- const useEnsureWindowHoldsAnchor = ({ conversation_id, reply_root_id, anchor }: Options) => {
100
+ const useEnsureWindowOpenedAtAnchor = ({ conversation_id, reply_root_id, anchor }: Options) => {
101
101
  const queryClient = useQueryClient()
102
102
 
103
103
  useEffect(() => {
@@ -105,8 +105,10 @@ const useEnsureWindowHoldsAnchor = ({ conversation_id, reply_root_id, anchor }:
105
105
 
106
106
  const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })
107
107
  const cached = queryClient.getQueryData<MessagesWindow>(queryKey)
108
- const holdsAnchor = cached?.pages.some(page => page.data.some(m => m.id === anchor))
109
- if (cached && !holdsAnchor) {
108
+ if (!cached) return
109
+
110
+ const openedAtAnchor = cached.pageParams[0]?.where?.id_around === anchor
111
+ if (!openedAtAnchor) {
110
112
  queryClient.resetQueries({ queryKey, exact: true })
111
113
  }
112
114
  }, [anchor, conversation_id, reply_root_id, queryClient])
@@ -7,8 +7,9 @@ import {
7
7
  FetchSubscribeToken,
8
8
  JoltSubscription,
9
9
  } from '@planningcenter/jolt-client/dist/types/JoltSubscription'
10
- import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
10
+ import { QueryClient, useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
11
11
  import { useCallback, useEffect, useMemo } from 'react'
12
+ import { AppState, AppStateStatus } from 'react-native'
12
13
  import { useChatContext } from '../contexts/chat_context'
13
14
  import { ApiResource } from '../types'
14
15
  import type { JoltSubscriptionPattern } from '../types/jolt_events'
@@ -125,6 +126,36 @@ export const useJoltClient = (): JoltClient | undefined => {
125
126
  return joltClient
126
127
  }
127
128
 
129
+ const pingSubscribedJoltClients = (queryClient: QueryClient) => {
130
+ queryClient
131
+ .getQueryCache()
132
+ .findAll({ queryKey: ['jolt-client'] })
133
+ .forEach(query => {
134
+ const joltClient = query.state.data as JoltClient | undefined
135
+ if (!joltClient || joltClient.subscriptions.length === 0) return
136
+
137
+ try {
138
+ joltClient.ping()
139
+ } catch {}
140
+ })
141
+ }
142
+
143
+ export const useJoltForegroundPing = () => {
144
+ const queryClient = useQueryClient()
145
+
146
+ useEffect(() => {
147
+ let previousState: AppStateStatus = AppState.currentState
148
+ const subscription = AppState.addEventListener('change', nextState => {
149
+ if (nextState === 'active' && previousState !== 'active') {
150
+ pingSubscribedJoltClients(queryClient)
151
+ }
152
+ previousState = nextState
153
+ })
154
+
155
+ return () => subscription.remove()
156
+ }, [queryClient])
157
+ }
158
+
128
159
  export function useJoltChannel(
129
160
  channelName: string,
130
161
  enabled: boolean = true
@@ -20,15 +20,16 @@ export function useMarkLatestMessageRead({ conversation, enabled = true }: Props
20
20
  const unreadCount = conversation.unreadCount
21
21
  const unreadReaction = conversation.unreadReaction
22
22
 
23
- const shouldMarkRead = Boolean(unreadCount >= 1 || unreadReaction || !firedOnce.current)
23
+ const shouldMarkRead =
24
+ !firedOnce.current || (enabled && Boolean(unreadCount >= 1 || unreadReaction))
24
25
  const appState = useAppState()
25
26
  const isActive = appState === 'active'
26
27
 
27
28
  useEffect(() => {
28
- if (!enabled || !isActive || !shouldMarkRead) return
29
+ if (!isActive || !shouldMarkRead) return
29
30
 
30
31
  firedOnce.current = true
31
32
 
32
33
  debouncedMarkRead(true)
33
- }, [debouncedMarkRead, enabled, isActive, shouldMarkRead, unreadReaction])
34
+ }, [debouncedMarkRead, isActive, shouldMarkRead, unreadReaction])
34
35
  }
@@ -1,6 +1,6 @@
1
1
  import { act, fireEvent, render } from '@testing-library/react-native'
2
2
  import React from 'react'
3
- import { Keyboard } from 'react-native'
3
+ import { Keyboard, ScrollView } from 'react-native'
4
4
  import type { useSearchResults } from '../../../hooks/use_search_results'
5
5
  import type {
6
6
  ConversationSearchResultResource,
@@ -116,6 +116,18 @@ describe('SearchScreen', () => {
116
116
  expect(view.getByLabelText('Loading results')).toBeTruthy()
117
117
  })
118
118
 
119
+ it('lets the prompt scroll while taps still reach the field', () => {
120
+ const view = render(<SearchScreen />)
121
+
122
+ const scrollView = view.UNSAFE_getByType(ScrollView)
123
+ expect(scrollView.props.keyboardShouldPersistTaps).toBe('handled')
124
+ expect(scrollView.props.contentContainerStyle).toMatchObject({
125
+ flexGrow: 1,
126
+ justifyContent: 'center',
127
+ })
128
+ expect(view.getByText('Search chat')).toBeTruthy()
129
+ })
130
+
119
131
  it('returns to the prompt as soon as the term is cleared', () => {
120
132
  const view = render(<SearchScreen />)
121
133
  const input = view.getByLabelText(inputLabel)
@@ -4,7 +4,7 @@ import {
4
4
  NativeStackScreenProps,
5
5
  } from '@react-navigation/native-stack'
6
6
  import React, { useRef, useState } from 'react'
7
- import { Keyboard, StyleSheet, View } from 'react-native'
7
+ import { Keyboard, ScrollView, StyleSheet, View } from 'react-native'
8
8
  import { KeyboardView } from '../../components'
9
9
  import {
10
10
  composeOptions,
@@ -73,7 +73,9 @@ export function SearchScreen() {
73
73
  onSettled={publishSearch}
74
74
  />
75
75
  ) : (
76
- <SearchPromptBlankState />
76
+ <ScrollView contentContainerStyle={styles.prompt} keyboardShouldPersistTaps="handled">
77
+ <SearchPromptBlankState />
78
+ </ScrollView>
77
79
  )}
78
80
  </View>
79
81
  </KeyboardView>
@@ -84,4 +86,8 @@ const styles = StyleSheet.create({
84
86
  container: {
85
87
  flex: 1,
86
88
  },
89
+ prompt: {
90
+ flexGrow: 1,
91
+ justifyContent: 'center',
92
+ },
87
93
  })