@planningcenter/chat-react-native 4.2.1-qa-staging.0 → 4.2.1-qa-staging.1

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.
Files changed (50) hide show
  1. package/build/components/conversation/anchor_not_found_boundary.d.ts +18 -0
  2. package/build/components/conversation/anchor_not_found_boundary.d.ts.map +1 -0
  3. package/build/components/conversation/anchor_not_found_boundary.js +20 -0
  4. package/build/components/conversation/anchor_not_found_boundary.js.map +1 -0
  5. package/build/components/conversation/message_list.d.ts +3 -2
  6. package/build/components/conversation/message_list.d.ts.map +1 -1
  7. package/build/components/conversation/message_list.js +149 -66
  8. package/build/components/conversation/message_list.js.map +1 -1
  9. package/build/hooks/use_conversation_messages.d.ts +8 -2
  10. package/build/hooks/use_conversation_messages.d.ts.map +1 -1
  11. package/build/hooks/use_conversation_messages.js +77 -45
  12. package/build/hooks/use_conversation_messages.js.map +1 -1
  13. package/build/hooks/use_fetch_newer_on_foreground.d.ts +8 -0
  14. package/build/hooks/use_fetch_newer_on_foreground.d.ts.map +1 -0
  15. package/build/hooks/use_fetch_newer_on_foreground.js +41 -0
  16. package/build/hooks/use_fetch_newer_on_foreground.js.map +1 -0
  17. package/build/hooks/use_mark_latest_message_read.d.ts +2 -1
  18. package/build/hooks/use_mark_latest_message_read.d.ts.map +1 -1
  19. package/build/hooks/use_mark_latest_message_read.js +4 -3
  20. package/build/hooks/use_mark_latest_message_read.js.map +1 -1
  21. package/build/screens/conversation_screen.d.ts +1 -0
  22. package/build/screens/conversation_screen.d.ts.map +1 -1
  23. package/build/screens/conversation_screen.js +119 -48
  24. package/build/screens/conversation_screen.js.map +1 -1
  25. package/build/utils/generate_placeholder_ulid.d.ts +0 -6
  26. package/build/utils/generate_placeholder_ulid.d.ts.map +1 -1
  27. package/build/utils/generate_placeholder_ulid.js +2 -2
  28. package/build/utils/generate_placeholder_ulid.js.map +1 -1
  29. package/build/utils/request/get_messages.d.ts +18 -6
  30. package/build/utils/request/get_messages.d.ts.map +1 -1
  31. package/build/utils/request/get_messages.js +10 -12
  32. package/build/utils/request/get_messages.js.map +1 -1
  33. package/build/utils/ulid.d.ts +3 -0
  34. package/build/utils/ulid.d.ts.map +1 -0
  35. package/build/utils/ulid.js +7 -0
  36. package/build/utils/ulid.js.map +1 -0
  37. package/package.json +3 -3
  38. package/src/__tests__/utils/request/get_messages.test.ts +24 -0
  39. package/src/__tests__/utils/ulid.test.ts +15 -0
  40. package/src/components/conversation/__tests__/anchor_not_found_boundary.test.tsx +51 -0
  41. package/src/components/conversation/__tests__/message_list.test.tsx +42 -0
  42. package/src/components/conversation/anchor_not_found_boundary.tsx +21 -0
  43. package/src/components/conversation/message_list.tsx +50 -3
  44. package/src/hooks/use_conversation_messages.ts +43 -11
  45. package/src/hooks/use_fetch_newer_on_foreground.ts +25 -0
  46. package/src/hooks/use_mark_latest_message_read.ts +4 -3
  47. package/src/screens/conversation_screen.tsx +92 -21
  48. package/src/utils/generate_placeholder_ulid.ts +2 -2
  49. package/src/utils/request/get_messages.ts +12 -14
  50. package/src/utils/ulid.ts +11 -0
@@ -2,91 +2,123 @@ import { c as _c } from "react/compiler-runtime";
2
2
  import { useMemo } from 'react';
3
3
  import { replaceEqualById } from '../utils/replace_equal_by_id';
4
4
  import { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages';
5
+ import { getNewerPageParam } from './paginator_meta';
5
6
  import { useSuspensePaginator } from './use_suspense_api';
6
7
  export const useConversationMessages = (t0, opts) => {
7
- const $ = _c(17);
8
+ const $ = _c(25);
8
9
  const {
9
10
  conversation_id,
10
- reply_root_id
11
+ reply_root_id,
12
+ anchor
11
13
  } = t0;
12
14
  let t1;
13
- if ($[0] !== conversation_id || $[1] !== reply_root_id) {
15
+ if ($[0] !== anchor || $[1] !== conversation_id || $[2] !== reply_root_id) {
14
16
  t1 = getMessagesRequestArgs({
15
17
  conversation_id,
16
- reply_root_id
18
+ reply_root_id,
19
+ anchor
17
20
  });
18
- $[0] = conversation_id;
19
- $[1] = reply_root_id;
20
- $[2] = t1;
21
+ $[0] = anchor;
22
+ $[1] = conversation_id;
23
+ $[2] = reply_root_id;
24
+ $[3] = t1;
21
25
  } else {
22
- t1 = $[2];
26
+ t1 = $[3];
23
27
  }
24
28
  let t2;
25
- if ($[3] !== opts) {
26
- t2 = {
29
+ if ($[4] !== anchor) {
30
+ t2 = anchor ? {
31
+ getPreviousPageParam: _temp,
32
+ gcTime: 0,
33
+ staleTime: Infinity
34
+ } : {};
35
+ $[4] = anchor;
36
+ $[5] = t2;
37
+ } else {
38
+ t2 = $[5];
39
+ }
40
+ let t3;
41
+ if ($[6] !== opts || $[7] !== t2) {
42
+ t3 = {
27
43
  structuralSharing: replaceEqualById,
44
+ ...t2,
28
45
  ...opts
29
46
  };
30
- $[3] = opts;
31
- $[4] = t2;
47
+ $[6] = opts;
48
+ $[7] = t2;
49
+ $[8] = t3;
32
50
  } else {
33
- t2 = $[4];
51
+ t3 = $[8];
34
52
  }
35
53
  const {
36
54
  data,
37
55
  refetch,
38
56
  isRefetching,
39
57
  fetchNextPage,
40
- hasNextPage
41
- } = useSuspensePaginator(t1, t2);
42
- let t3;
43
- if ($[5] !== conversation_id || $[6] !== reply_root_id) {
44
- t3 = getMessagesQueryKey({
58
+ hasNextPage,
59
+ fetchPreviousPage,
60
+ hasPreviousPage,
61
+ isFetchingPreviousPage
62
+ } = useSuspensePaginator(t1, t3);
63
+ let t4;
64
+ if ($[9] !== anchor || $[10] !== conversation_id || $[11] !== reply_root_id) {
65
+ t4 = getMessagesQueryKey({
45
66
  conversation_id,
46
- reply_root_id
67
+ reply_root_id,
68
+ anchor
47
69
  });
48
- $[5] = conversation_id;
49
- $[6] = reply_root_id;
50
- $[7] = t3;
70
+ $[9] = anchor;
71
+ $[10] = conversation_id;
72
+ $[11] = reply_root_id;
73
+ $[12] = t4;
51
74
  } else {
52
- t3 = $[7];
75
+ t4 = $[12];
53
76
  }
54
- const queryKey = t3;
55
- let t4;
56
- if ($[8] !== data) {
57
- t4 = data.filter(_temp).sort(_temp2);
58
- $[8] = data;
59
- $[9] = t4;
77
+ const queryKey = t4;
78
+ let t5;
79
+ if ($[13] !== data) {
80
+ t5 = data.filter(_temp2).sort(_temp3);
81
+ $[13] = data;
82
+ $[14] = t5;
60
83
  } else {
61
- t4 = $[9];
84
+ t5 = $[14];
62
85
  }
63
- const messages = t4;
64
- let t5;
65
- if ($[10] !== fetchNextPage || $[11] !== hasNextPage || $[12] !== isRefetching || $[13] !== messages || $[14] !== queryKey || $[15] !== refetch) {
66
- t5 = {
86
+ const messages = t5;
87
+ let t6;
88
+ if ($[15] !== fetchNextPage || $[16] !== fetchPreviousPage || $[17] !== hasNextPage || $[18] !== hasPreviousPage || $[19] !== isFetchingPreviousPage || $[20] !== isRefetching || $[21] !== messages || $[22] !== queryKey || $[23] !== refetch) {
89
+ t6 = {
67
90
  messages,
68
91
  refetch,
69
92
  isRefetching,
70
93
  fetchNextPage,
71
94
  hasNextPage,
95
+ fetchPreviousPage,
96
+ hasPreviousPage,
97
+ isFetchingPreviousPage,
72
98
  queryKey
73
99
  };
74
- $[10] = fetchNextPage;
75
- $[11] = hasNextPage;
76
- $[12] = isRefetching;
77
- $[13] = messages;
78
- $[14] = queryKey;
79
- $[15] = refetch;
80
- $[16] = t5;
100
+ $[15] = fetchNextPage;
101
+ $[16] = fetchPreviousPage;
102
+ $[17] = hasNextPage;
103
+ $[18] = hasPreviousPage;
104
+ $[19] = isFetchingPreviousPage;
105
+ $[20] = isRefetching;
106
+ $[21] = messages;
107
+ $[22] = queryKey;
108
+ $[23] = refetch;
109
+ $[24] = t6;
81
110
  } else {
82
- t5 = $[16];
111
+ t6 = $[24];
83
112
  }
84
- return t5;
113
+ return t6;
85
114
  };
86
- function _temp(message) {
115
+ function _temp(page, _pages, pageParam) {
116
+ return getNewerPageParam(page, pageParam);
117
+ }
118
+ function _temp2(message) {
87
119
  return (!message.deletedAt || message.replyRootId) && (message.attachments?.length || message.text?.length);
88
120
  }
89
- function _temp2(a, b) {
121
+ function _temp3(a, b) {
90
122
  return -a.id.localeCompare(b.id);
91
123
  }
92
124
  //# sourceMappingURL=use_conversation_messages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use_conversation_messages.js","names":["useMemo","replaceEqualById","getMessagesQueryKey","getMessagesRequestArgs","useSuspensePaginator","useConversationMessages","t0","opts","$","_c","conversation_id","reply_root_id","t1","t2","structuralSharing","data","refetch","isRefetching","fetchNextPage","hasNextPage","t3","queryKey","t4","filter","_temp","sort","_temp2","messages","t5","message","deletedAt","replyRootId","attachments","length","text","a","b","id","localeCompare"],"sources":["../../src/hooks/use_conversation_messages.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { MessageResource } from '../types'\nimport { replaceEqualById } from '../utils/replace_equal_by_id'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { SuspensePaginatorOptions, useSuspensePaginator } from './use_suspense_api'\n\nexport const useConversationMessages = (\n { conversation_id, reply_root_id }: { conversation_id: number; reply_root_id?: string | null },\n opts?: SuspensePaginatorOptions\n) => {\n const { data, refetch, isRefetching, fetchNextPage, hasNextPage } =\n useSuspensePaginator<MessageResource>(\n getMessagesRequestArgs({ conversation_id, reply_root_id }),\n {\n structuralSharing: replaceEqualById,\n ...opts,\n }\n )\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id })\n const messages = useMemo(\n () =>\n data\n .filter(\n message =>\n (!message.deletedAt || message.replyRootId) &&\n (message.attachments?.length || message.text?.length)\n )\n .sort((a, b) => -a.id.localeCompare(b.id)),\n [data]\n )\n\n return { messages, refetch, isRefetching, fetchNextPage, hasNextPage, queryKey }\n}\n"],"mappings":";AAAA,SAASA,OAAO,QAAQ,OAAO;AAE/B,SAASC,gBAAgB,QAAQ,8BAA8B;AAC/D,SAASC,mBAAmB,EAAEC,sBAAsB,QAAQ,+BAA+B;AAC3F,SAAmCC,oBAAoB,QAAQ,oBAAoB;AAEnF,OAAO,MAAMC,uBAAuB,GAAGA,CAAAC,EAAA,EAAAC,IAAA;EAAA,MAAAC,CAAA,GAAAC,EAAA;EACrC;IAAAC,eAAA;IAAAC;EAAA,IAAAL,EAA8F;EAAA,IAAAM,EAAA;EAAA,IAAAJ,CAAA,QAAAE,eAAA,IAAAF,CAAA,QAAAG,aAAA;IAK1FC,EAAA,GAAAT,sBAAsB,CAAC;MAAAO,eAAA;MAAAC;IAAiC,CAAC,CAAC;IAAAH,CAAA,MAAAE,eAAA;IAAAF,CAAA,MAAAG,aAAA;IAAAH,CAAA,MAAAI,EAAA;EAAA;IAAAA,EAAA,GAAAJ,CAAA;EAAA;EAAA,IAAAK,EAAA;EAAA,IAAAL,CAAA,QAAAD,IAAA;IAC1DM,EAAA;MAAAC,iBAAA,EACqBb,gBAAgB;MAAA,GAChCM;IACL,CAAC;IAAAC,CAAA,MAAAD,IAAA;IAAAC,CAAA,MAAAK,EAAA;EAAA;IAAAA,EAAA,GAAAL,CAAA;EAAA;EANL;IAAAO,IAAA;IAAAC,OAAA;IAAAC,YAAA;IAAAC,aAAA;IAAAC;EAAA,IACEf,oBAAoB,CAClBQ,EAA0D,EAC1DC,EAIF,CAAC;EAAA,IAAAO,EAAA;EAAA,IAAAZ,CAAA,QAAAE,eAAA,IAAAF,CAAA,QAAAG,aAAA;IACcS,EAAA,GAAAlB,mBAAmB,CAAC;MAAAQ,eAAA;MAAAC;IAAiC,CAAC,CAAC;IAAAH,CAAA,MAAAE,eAAA;IAAAF,CAAA,MAAAG,aAAA;IAAAH,CAAA,MAAAY,EAAA;EAAA;IAAAA,EAAA,GAAAZ,CAAA;EAAA;EAAxE,MAAAa,QAAA,GAAiBD,EAAuD;EAAA,IAAAE,EAAA;EAAA,IAAAd,CAAA,QAAAO,IAAA;IAGpEO,EAAA,GAAAP,IAAI,CAAAQ,MACK,CACLC,KAGF,CAAC,CAAAC,IACI,CAACC,MAAmC,CAAC;IAAAlB,CAAA,MAAAO,IAAA;IAAAP,CAAA,MAAAc,EAAA;EAAA;IAAAA,EAAA,GAAAd,CAAA;EAAA;EARhD,MAAAmB,QAAA,GAEIL,EAM4C;EAE/C,IAAAM,EAAA;EAAA,IAAApB,CAAA,SAAAU,aAAA,IAAAV,CAAA,SAAAW,WAAA,IAAAX,CAAA,SAAAS,YAAA,IAAAT,CAAA,SAAAmB,QAAA,IAAAnB,CAAA,SAAAa,QAAA,IAAAb,CAAA,SAAAQ,OAAA;IAEMY,EAAA;MAAAD,QAAA;MAAAX,OAAA;MAAAC,YAAA;MAAAC,aAAA;MAAAC,WAAA;MAAAE;IAAwE,CAAC;IAAAb,CAAA,OAAAU,aAAA;IAAAV,CAAA,OAAAW,WAAA;IAAAX,CAAA,OAAAS,YAAA;IAAAT,CAAA,OAAAmB,QAAA;IAAAnB,CAAA,OAAAa,QAAA;IAAAb,CAAA,OAAAQ,OAAA;IAAAR,CAAA,OAAAoB,EAAA;EAAA;IAAAA,EAAA,GAAApB,CAAA;EAAA;EAAA,OAAzEoB,EAAyE;AAAA,CACjF;AA1BsC,SAAAJ,MAAAK,OAAA;EAAA,OAkB3B,CAAC,CAACA,OAAO,CAAAC,SAAiC,IAAnBD,OAAO,CAAAE,WACuB,MAApDF,OAAO,CAAAG,WAAoB,EAAAC,MAAwB,IAApBJ,OAAO,CAAAK,IAAa,EAAAD,MAAC;AAAA;AAnB1B,SAAAP,OAAAS,CAAA,EAAAC,CAAA;EAAA,OAqBf,CAACD,CAAC,CAAAE,EAAG,CAAAC,aAAc,CAACF,CAAC,CAAAC,EAAG,CAAC;AAAA","ignoreList":[]}
1
+ {"version":3,"file":"use_conversation_messages.js","names":["useMemo","replaceEqualById","getMessagesQueryKey","getMessagesRequestArgs","getNewerPageParam","useSuspensePaginator","useConversationMessages","t0","opts","$","_c","conversation_id","reply_root_id","anchor","t1","t2","getPreviousPageParam","_temp","gcTime","staleTime","Infinity","t3","structuralSharing","data","refetch","isRefetching","fetchNextPage","hasNextPage","fetchPreviousPage","hasPreviousPage","isFetchingPreviousPage","t4","queryKey","t5","filter","_temp2","sort","_temp3","messages","t6","page","_pages","pageParam","message","deletedAt","replyRootId","attachments","length","text","a","b","id","localeCompare"],"sources":["../../src/hooks/use_conversation_messages.ts"],"sourcesContent":["import { useMemo } from 'react'\nimport { MessageResource } from '../types'\nimport { replaceEqualById } from '../utils/replace_equal_by_id'\nimport { getMessagesQueryKey, getMessagesRequestArgs } from '../utils/request/get_messages'\nimport { getNewerPageParam } from './paginator_meta'\nimport { SuspensePaginatorOptions, useSuspensePaginator } from './use_suspense_api'\n\ntype Options = {\n conversation_id: number\n reply_root_id?: string | null\n anchor?: string | null\n}\n\nexport const useConversationMessages = (\n { conversation_id, reply_root_id, anchor }: Options,\n opts?: SuspensePaginatorOptions\n) => {\n const {\n data,\n refetch,\n isRefetching,\n fetchNextPage,\n hasNextPage,\n fetchPreviousPage,\n hasPreviousPage,\n isFetchingPreviousPage,\n } = useSuspensePaginator<MessageResource>(\n getMessagesRequestArgs({ conversation_id, reply_root_id, anchor }),\n {\n structuralSharing: replaceEqualById,\n ...(anchor\n ? {\n getPreviousPageParam: (page, _pages, pageParam) => getNewerPageParam(page, pageParam),\n gcTime: 0,\n staleTime: Infinity,\n }\n : {}),\n ...opts,\n }\n )\n const queryKey = getMessagesQueryKey({ conversation_id, reply_root_id, anchor })\n const messages = useMemo(\n () =>\n data\n .filter(\n message =>\n (!message.deletedAt || message.replyRootId) &&\n (message.attachments?.length || message.text?.length)\n )\n .sort((a, b) => -a.id.localeCompare(b.id)),\n [data]\n )\n\n return {\n messages,\n refetch,\n isRefetching,\n fetchNextPage,\n hasNextPage,\n fetchPreviousPage,\n hasPreviousPage,\n isFetchingPreviousPage,\n queryKey,\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,8 @@
1
+ type Options = {
2
+ fetchNewer: (newestMessageId: string) => void;
3
+ newestMessageId?: string;
4
+ enabled: boolean;
5
+ };
6
+ export declare const useFetchNewerOnForeground: ({ fetchNewer, newestMessageId, enabled }: Options) => void;
7
+ export {};
8
+ //# sourceMappingURL=use_fetch_newer_on_foreground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_fetch_newer_on_foreground.d.ts","sourceRoot":"","sources":["../../src/hooks/use_fetch_newer_on_foreground.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG;IACb,UAAU,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,0CAA0C,OAAO,SAe1F,CAAA"}
@@ -0,0 +1,41 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useEffect, useRef } from 'react';
3
+ import { useAppState } from './use_app_state';
4
+ export const useFetchNewerOnForeground = t0 => {
5
+ const $ = _c(6);
6
+ const {
7
+ fetchNewer,
8
+ newestMessageId,
9
+ enabled
10
+ } = t0;
11
+ const appState = useAppState();
12
+ const wasInBackground = useRef(false);
13
+ let t1;
14
+ let t2;
15
+ if ($[0] !== appState || $[1] !== enabled || $[2] !== fetchNewer || $[3] !== newestMessageId) {
16
+ t1 = () => {
17
+ if (appState !== "active") {
18
+ wasInBackground.current = true;
19
+ return;
20
+ }
21
+ const returnedToForeground = wasInBackground.current;
22
+ wasInBackground.current = false;
23
+ if (!returnedToForeground || !enabled || !newestMessageId) {
24
+ return;
25
+ }
26
+ fetchNewer(newestMessageId);
27
+ };
28
+ t2 = [appState, enabled, fetchNewer, newestMessageId];
29
+ $[0] = appState;
30
+ $[1] = enabled;
31
+ $[2] = fetchNewer;
32
+ $[3] = newestMessageId;
33
+ $[4] = t1;
34
+ $[5] = t2;
35
+ } else {
36
+ t1 = $[4];
37
+ t2 = $[5];
38
+ }
39
+ useEffect(t1, t2);
40
+ };
41
+ //# sourceMappingURL=use_fetch_newer_on_foreground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_fetch_newer_on_foreground.js","names":["useEffect","useRef","useAppState","useFetchNewerOnForeground","t0","$","_c","fetchNewer","newestMessageId","enabled","appState","wasInBackground","t1","t2","current","returnedToForeground"],"sources":["../../src/hooks/use_fetch_newer_on_foreground.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { useAppState } from './use_app_state'\n\ntype Options = {\n fetchNewer: (newestMessageId: string) => void\n newestMessageId?: string\n enabled: boolean\n}\n\nexport const useFetchNewerOnForeground = ({ fetchNewer, newestMessageId, enabled }: Options) => {\n const appState = useAppState()\n const wasInBackground = useRef(false)\n\n useEffect(() => {\n if (appState !== 'active') {\n wasInBackground.current = true\n return\n }\n const returnedToForeground = wasInBackground.current\n wasInBackground.current = false\n if (!returnedToForeground || !enabled || !newestMessageId) return\n\n fetchNewer(newestMessageId)\n }, [appState, enabled, fetchNewer, newestMessageId])\n}\n"],"mappings":";AAAA,SAASA,SAAS,EAAEC,MAAM,QAAQ,OAAO;AACzC,SAASC,WAAW,QAAQ,iBAAiB;AAQ7C,OAAO,MAAMC,yBAAyB,GAAGC,EAAA;EAAA,MAAAC,CAAA,GAAAC,EAAA;EAAC;IAAAC,UAAA;IAAAC,eAAA;IAAAC;EAAA,IAAAL,EAAiD;EACzF,MAAAM,QAAA,GAAiBR,WAAW,CAAC,CAAC;EAC9B,MAAAS,eAAA,GAAwBV,MAAM,CAAC,KAAK,CAAC;EAAA,IAAAW,EAAA;EAAA,IAAAC,EAAA;EAAA,IAAAR,CAAA,QAAAK,QAAA,IAAAL,CAAA,QAAAI,OAAA,IAAAJ,CAAA,QAAAE,UAAA,IAAAF,CAAA,QAAAG,eAAA;IAE3BI,EAAA,GAAAA,CAAA;MACR,IAAIF,QAAQ,KAAK,QAAQ;QACvBC,eAAe,CAAAG,OAAA,GAAW,IAAH;QAAA;MAAA;MAGzB,MAAAC,oBAAA,GAA6BJ,eAAe,CAAAG,OAAQ;MACpDH,eAAe,CAAAG,OAAA,GAAW,KAAH;MACvB,IAAI,CAACC,oBAAgC,IAAjC,CAA0BN,OAA2B,IAArD,CAAsCD,eAAe;QAAA;MAAA;MAEzDD,UAAU,CAACC,eAAe,CAAC;IAAA,CAC5B;IAAEK,EAAA,IAACH,QAAQ,EAAED,OAAO,EAAEF,UAAU,EAAEC,eAAe,CAAC;IAAAH,CAAA,MAAAK,QAAA;IAAAL,CAAA,MAAAI,OAAA;IAAAJ,CAAA,MAAAE,UAAA;IAAAF,CAAA,MAAAG,eAAA;IAAAH,CAAA,MAAAO,EAAA;IAAAP,CAAA,MAAAQ,EAAA;EAAA;IAAAD,EAAA,GAAAP,CAAA;IAAAQ,EAAA,GAAAR,CAAA;EAAA;EAVnDL,SAAS,CAACY,EAUT,EAAEC,EAAgD,CAAC;AAAA,CACrD","ignoreList":[]}
@@ -2,7 +2,8 @@ import { ConversationResource, MessageResource } from '../types';
2
2
  interface Props {
3
3
  conversation: ConversationResource;
4
4
  messages: MessageResource[];
5
+ enabled?: boolean;
5
6
  }
6
- export declare function useMarkLatestMessageRead({ conversation }: Props): void;
7
+ export declare function useMarkLatestMessageRead({ conversation, enabled }: Props): void;
7
8
  export {};
8
9
  //# sourceMappingURL=use_mark_latest_message_read.d.ts.map
@@ -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;CAC5B;AAED,wBAAgB,wBAAwB,CAAC,EAAE,YAAY,EAAE,EAAE,KAAK,QAqB/D"}
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"}
@@ -3,7 +3,8 @@ import { useEffect, useMemo, useRef } from 'react';
3
3
  import { useAppState } from './use_app_state';
4
4
  import { useConversationsMarkRead } from './use_conversations_actions';
5
5
  export function useMarkLatestMessageRead({
6
- conversation
6
+ conversation,
7
+ enabled = true
7
8
  }) {
8
9
  const firedOnce = useRef(false);
9
10
  const {
@@ -21,9 +22,9 @@ export function useMarkLatestMessageRead({
21
22
  const appState = useAppState();
22
23
  const isActive = appState === 'active';
23
24
  useEffect(() => {
24
- if (!isActive || !shouldMarkRead) return;
25
+ if (!enabled || !isActive || !shouldMarkRead) return;
25
26
  firedOnce.current = true;
26
27
  debouncedMarkRead(true);
27
- }, [debouncedMarkRead, isActive, shouldMarkRead, unreadReaction]);
28
+ }, [debouncedMarkRead, enabled, isActive, shouldMarkRead, unreadReaction]);
28
29
  }
29
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","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}\n\nexport function useMarkLatestMessageRead({ conversation }: 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 (!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;AAOtE,OAAO,SAASC,wBAAwBA,CAAC;EAAEC;AAAoB,CAAC,EAAE;EAChE,MAAMC,SAAS,GAAGL,MAAM,CAAU,KAAK,CAAC;EACxC,MAAM;IAAEM;EAAS,CAAC,GAAGJ,wBAAwB,CAAC;IAAEE;EAAa,CAAC,CAAC;EAC/D,MAAMG,iBAAiB,GAAGR,OAAO,CAC/B,MAAMF,QAAQ,CAACS,QAAQ,EAAE,IAAI,EAAE;IAAEE,OAAO,EAAE,IAAI;IAAEC,QAAQ,EAAE;EAAK,CAAC,CAAC,EACjE,CAACH,QAAQ,CACX,CAAC;EACD,MAAMI,WAAW,GAAGN,YAAY,CAACM,WAAW;EAC5C,MAAMC,cAAc,GAAGP,YAAY,CAACO,cAAc;EAElD,MAAMC,cAAc,GAAGC,OAAO,CAACH,WAAW,IAAI,CAAC,IAAIC,cAAc,IAAI,CAACN,SAAS,CAACS,OAAO,CAAC;EACxF,MAAMC,QAAQ,GAAGd,WAAW,CAAC,CAAC;EAC9B,MAAMe,QAAQ,GAAGD,QAAQ,KAAK,QAAQ;EAEtCjB,SAAS,CAAC,MAAM;IACd,IAAI,CAACkB,QAAQ,IAAI,CAACJ,cAAc,EAAE;IAElCP,SAAS,CAACS,OAAO,GAAG,IAAI;IAExBP,iBAAiB,CAAC,IAAI,CAAC;EACzB,CAAC,EAAE,CAACA,iBAAiB,EAAES,QAAQ,EAAEJ,cAAc,EAAED,cAAc,CAAC,CAAC;AACnE","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","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":[]}
@@ -8,6 +8,7 @@ export type ConversationRouteProps = {
8
8
  chat_group_graph_id?: string;
9
9
  clear_input?: boolean;
10
10
  editing_message_id?: number | null;
11
+ initial_message_id?: string | null;
11
12
  title?: string;
12
13
  subtitle?: string;
13
14
  badge?: ConversationBadgeResource;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,gBAAgB,EAAqB,MAAM,4BAA4B,CAAA;AAC7F,OAAO,EAGL,iBAAiB,EAIlB,MAAM,0BAA0B,CAAA;AAkCjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;AAIjF,MAAM,MAAM,sBAAsB,GAAG;IACnC,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,yBAAyB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAA;AAE/E,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,2CAkBpE;AAyMD,UAAU,4BAA6B,SAAQ,gBAAgB;IAC7D,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,yBAAyB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,eAAO,MAAM,uBAAuB,GAAI,8DAOrC,4BAA4B,4CAqC9B,CAAA"}
1
+ {"version":3,"file":"conversation_screen.d.ts","sourceRoot":"","sources":["../../src/screens/conversation_screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,gBAAgB,EAAqB,MAAM,4BAA4B,CAAA;AAC7F,OAAO,EAGL,iBAAiB,EAIlB,MAAM,0BAA0B,CAAA;AAoCjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAA;AAKjF,MAAM,MAAM,sBAAsB,GAAG;IACnC,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,yBAAyB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,sBAAsB,CAAC,CAAA;AAE/E,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,2CAuCpE;AAuPD,UAAU,4BAA6B,SAAQ,gBAAgB;IAC7D,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,yBAAyB,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,eAAO,MAAM,uBAAuB,GAAI,8DAOrC,4BAA4B,4CAqC9B,CAAA"}
@@ -1,10 +1,11 @@
1
1
  import { c as _c } from "react/compiler-runtime";
2
2
  import { HeaderTitle, PlatformPressable } from '@react-navigation/elements';
3
3
  import { CommonActions, useNavigation, useTheme as useNavigationTheme, useRoute } from '@react-navigation/native';
4
- import React, { useCallback, useEffect, useRef, useState } from 'react';
4
+ import React, { startTransition, useCallback, useEffect, useRef, useState } from 'react';
5
5
  import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native';
6
6
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
7
7
  import { Badge, Icon } from '../components';
8
+ import { AnchorNotFoundBoundary } from '../components/conversation/anchor_not_found_boundary';
8
9
  import { ConversationStartBanner } from '../components/conversation/conversation_start_banner';
9
10
  import { JumpToBottomButton } from '../components/conversation/jump_to_bottom_button';
10
11
  import { MessageForm } from '../components/conversation/message_form';
@@ -21,20 +22,23 @@ import { useConversationJoltEvents } from '../hooks/use_conversation_jolt_events
21
22
  import { useConversationMessages } from '../hooks/use_conversation_messages';
22
23
  import { useConversationMessagesJoltEvents } from '../hooks/use_conversation_messages_jolt_events';
23
24
  import { useFetchNewerMessages } from '../hooks/use_fetch_newer_messages';
25
+ import { useFetchNewerOnForeground } from '../hooks/use_fetch_newer_on_foreground';
24
26
  import { useMarkLatestMessageRead } from '../hooks/use_mark_latest_message_read';
25
27
  import { analyticsEvents, normalizeAnalyticsMetadata, usePublishProductAnalyticsEvent } from '../hooks/use_product_analytics';
26
28
  import { useRestAwayFromDismissEdge } from '../hooks/use_rest_away_from_dismiss_edge';
27
29
  import { useVideoModerationJoltEvents } from '../hooks/use_video_moderation_jolt_events';
28
30
  import { gatedMessageCache } from '../utils/gated_message_cache';
31
+ import { decodeUlidTime } from '../utils/ulid';
29
32
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
30
33
  export function ConversationScreen(t0) {
31
- const $ = _c(13);
34
+ const $ = _c(19);
32
35
  const {
33
36
  route
34
37
  } = t0;
35
38
  const {
36
39
  conversation_id,
37
- reply_root_id
40
+ reply_root_id,
41
+ initial_message_id
38
42
  } = route.params;
39
43
  let t1;
40
44
  if ($[0] !== conversation_id) {
@@ -50,55 +54,93 @@ export function ConversationScreen(t0) {
50
54
  data: conversation
51
55
  } = useConversation(t1);
52
56
  let t2;
53
- if ($[2] !== conversation) {
54
- t2 = normalizeAnalyticsMetadata(conversation);
55
- $[2] = conversation;
56
- $[3] = t2;
57
+ if ($[2] !== conversation?.lastMessageCreatedAt || $[3] !== initial_message_id) {
58
+ t2 = () => isBeforeLatestMessage(initial_message_id, conversation?.lastMessageCreatedAt) ? initial_message_id : null;
59
+ $[2] = conversation?.lastMessageCreatedAt;
60
+ $[3] = initial_message_id;
61
+ $[4] = t2;
57
62
  } else {
58
- t2 = $[3];
63
+ t2 = $[4];
59
64
  }
65
+ const [anchor, setAnchor] = useState(t2);
60
66
  let t3;
61
- if ($[4] !== reply_root_id || $[5] !== t2) {
62
- t3 = {
63
- reply_root_id,
64
- ...t2
65
- };
66
- $[4] = reply_root_id;
67
- $[5] = t2;
68
- $[6] = t3;
67
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
68
+ t3 = () => startTransition(() => setAnchor(null));
69
+ $[5] = t3;
69
70
  } else {
70
- t3 = $[6];
71
+ t3 = $[5];
71
72
  }
72
- usePublishProductAnalyticsEvent(analyticsEvents.conversation_show_opened, t3);
73
- const t4 = reply_root_id ?? null;
73
+ const exitAnchoredMode = t3;
74
+ let t4;
75
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
76
+ t4 = () => setAnchor(null);
77
+ $[6] = t4;
78
+ } else {
79
+ t4 = $[6];
80
+ }
81
+ const dropAnchor = t4;
74
82
  let t5;
75
- if ($[7] !== route) {
76
- t5 = /*#__PURE__*/_jsx(ConversationScreenContent, {
77
- route: route
78
- });
79
- $[7] = route;
83
+ if ($[7] !== conversation) {
84
+ t5 = normalizeAnalyticsMetadata(conversation);
85
+ $[7] = conversation;
80
86
  $[8] = t5;
81
87
  } else {
82
88
  t5 = $[8];
83
89
  }
84
90
  let t6;
85
- if ($[9] !== conversation_id || $[10] !== t4 || $[11] !== t5) {
86
- t6 = /*#__PURE__*/_jsx(ConversationContextProvider, {
91
+ if ($[9] !== reply_root_id || $[10] !== t5) {
92
+ t6 = {
93
+ reply_root_id,
94
+ ...t5
95
+ };
96
+ $[9] = reply_root_id;
97
+ $[10] = t5;
98
+ $[11] = t6;
99
+ } else {
100
+ t6 = $[11];
101
+ }
102
+ usePublishProductAnalyticsEvent(analyticsEvents.conversation_show_opened, t6);
103
+ const t7 = reply_root_id ?? null;
104
+ let t8;
105
+ if ($[12] !== anchor || $[13] !== route) {
106
+ t8 = anchor ? /*#__PURE__*/_jsx(AnchorNotFoundBoundary, {
107
+ onAnchorNotFound: dropAnchor,
108
+ children: /*#__PURE__*/_jsx(ConversationScreenContent, {
109
+ route: route,
110
+ anchor: anchor,
111
+ onExitAnchoredMode: exitAnchoredMode
112
+ })
113
+ }) : /*#__PURE__*/_jsx(ConversationScreenContent, {
114
+ route: route,
115
+ anchor: null,
116
+ onExitAnchoredMode: exitAnchoredMode
117
+ });
118
+ $[12] = anchor;
119
+ $[13] = route;
120
+ $[14] = t8;
121
+ } else {
122
+ t8 = $[14];
123
+ }
124
+ let t9;
125
+ if ($[15] !== conversation_id || $[16] !== t7 || $[17] !== t8) {
126
+ t9 = /*#__PURE__*/_jsx(ConversationContextProvider, {
87
127
  conversationId: conversation_id,
88
- currentPageReplyRootId: t4,
89
- children: t5
128
+ currentPageReplyRootId: t7,
129
+ children: t8
90
130
  });
91
- $[9] = conversation_id;
92
- $[10] = t4;
93
- $[11] = t5;
94
- $[12] = t6;
131
+ $[15] = conversation_id;
132
+ $[16] = t7;
133
+ $[17] = t8;
134
+ $[18] = t9;
95
135
  } else {
96
- t6 = $[12];
136
+ t9 = $[18];
97
137
  }
98
- return t6;
138
+ return t9;
99
139
  }
100
140
  function ConversationScreenContent({
101
- route
141
+ route,
142
+ anchor,
143
+ onExitAnchoredMode
102
144
  }) {
103
145
  const styles = useStyles();
104
146
  const navigation = useNavigation();
@@ -111,21 +153,28 @@ function ConversationScreenContent({
111
153
  const {
112
154
  data: conversation
113
155
  } = useConversation(route.params);
156
+ const anchored = !!anchor;
114
157
  const {
115
158
  messages,
116
159
  fetchNextPage,
117
160
  hasNextPage,
161
+ fetchPreviousPage,
162
+ hasPreviousPage,
163
+ isFetchingPreviousPage,
118
164
  queryKey
119
165
  } = useConversationMessages({
120
166
  conversation_id,
121
- reply_root_id
167
+ reply_root_id,
168
+ anchor
122
169
  });
170
+ const behindLatest = anchored && hasPreviousPage;
171
+ const caughtUp = !hasPreviousPage;
123
172
  const [showJumpToBottomButton, setShowJumpToBottomButton] = useState(false);
124
173
  const readingHistory = showJumpToBottomButton;
125
174
  const skippedNewMessages = useRef(false);
126
175
  const messageCaches = [gatedMessageCache({
127
176
  queryKey,
128
- acceptNewMessages: !readingHistory,
177
+ acceptNewMessages: caughtUp && !readingHistory,
129
178
  onSkippedNewMessage: () => {
130
179
  skippedNewMessages.current = true;
131
180
  }
@@ -144,13 +193,19 @@ function ConversationScreenContent({
144
193
  useEnsureConversationsRouteExists();
145
194
  useMarkLatestMessageRead({
146
195
  conversation,
147
- messages
196
+ messages,
197
+ enabled: !behindLatest
148
198
  });
149
199
  const fetchNewer = useFetchNewerMessages({
150
200
  conversation_id,
151
201
  reply_root_id,
152
202
  queryKey
153
203
  });
204
+ useFetchNewerOnForeground({
205
+ fetchNewer,
206
+ newestMessageId,
207
+ enabled: anchored && caughtUp
208
+ });
154
209
  const noMessages = messages.length === 0;
155
210
  const {
156
211
  repliesDisabled,
@@ -166,10 +221,8 @@ function ConversationScreenContent({
166
221
  // Prefer the membership for optimistic updates.
167
222
  const muted = conversation.conversationMembership?.muted ?? conversation.muted;
168
223
  const listRef = useRef(null);
169
- const trackScroll = event => {
170
- const offsetY = event.nativeEvent.contentOffset.y;
171
- setShowJumpToBottomButton(offsetY > 200);
172
- };
224
+ const [hasDragged, setHasDragged] = useState(false);
225
+ const holdListPosition = behindLatest || readingHistory;
173
226
  const {
174
227
  restOffset,
175
228
  onLayout,
@@ -185,15 +238,28 @@ function ConversationScreenContent({
185
238
  offset: restOffset
186
239
  });
187
240
  }, [restOffset]);
241
+ const exitAnchoredMode = useCallback(() => {
242
+ onExitAnchoredMode();
243
+ handleReturnToBottom();
244
+ }, [handleReturnToBottom, onExitAnchoredMode]);
188
245
  const jumpToLatest = useCallback(() => {
189
246
  setShowJumpToBottomButton(false);
190
- handleReturnToBottom();
191
- }, [handleReturnToBottom]);
247
+ if (behindLatest) exitAnchoredMode();else handleReturnToBottom();
248
+ }, [behindLatest, exitAnchoredMode, handleReturnToBottom]);
249
+ const trackScroll = event => {
250
+ const offsetY = event.nativeEvent.contentOffset.y;
251
+ setShowJumpToBottomButton(offsetY > 200);
252
+ };
253
+ const loadNewerMessages = () => {
254
+ if (!hasPreviousPage || isFetchingPreviousPage) return;
255
+ setHasDragged(false);
256
+ fetchPreviousPage();
257
+ };
192
258
  useEffect(() => {
193
- if (readingHistory || !newestMessageId || !skippedNewMessages.current) return;
259
+ if (readingHistory || !caughtUp || !newestMessageId || !skippedNewMessages.current) return;
194
260
  skippedNewMessages.current = false;
195
261
  fetchNewer(newestMessageId);
196
- }, [fetchNewer, newestMessageId, readingHistory]);
262
+ }, [caughtUp, fetchNewer, newestMessageId, readingHistory]);
197
263
  useEffect(() => {
198
264
  if (reply_root_id) {
199
265
  navigation.setParams({
@@ -242,6 +308,7 @@ function ConversationScreenContent({
242
308
  conversationId: conversation_id,
243
309
  messages: messages,
244
310
  replyRootId: reply_root_id,
311
+ anchorMessageId: anchor,
245
312
  hasNextPage: hasNextPage,
246
313
  onEndReached: () => fetchNextPage(),
247
314
  onScroll: trackScroll,
@@ -249,12 +316,15 @@ function ConversationScreenContent({
249
316
  onContentSizeChange: onContentSizeChange,
250
317
  onScrollEndDrag: onScrollEndDrag,
251
318
  onMomentumScrollEnd: onMomentumScrollEnd,
252
- maintainVisibleContentPosition: readingHistory ? {
319
+ onScrollBeginDrag: anchored ? () => setHasDragged(true) : undefined,
320
+ onStartReached: anchored && hasDragged ? loadNewerMessages : undefined,
321
+ onStartReachedThreshold: anchored ? 0.5 : undefined,
322
+ maintainVisibleContentPosition: holdListPosition ? {
253
323
  minIndexForVisible: 0
254
324
  } : undefined
255
325
  }), /*#__PURE__*/_jsx(JumpToBottomButton, {
256
326
  onPress: jumpToLatest,
257
- visible: showJumpToBottomButton
327
+ visible: behindLatest || showJumpToBottomButton
258
328
  }), !noMessages && /*#__PURE__*/_jsx(TypingIndicator, {}), showLeaderDisabledReplyBanner && /*#__PURE__*/_jsx(LeaderMessagesDisabledBanner, {}), /*#__PURE__*/_jsx(ConversationBottomBar, {
259
329
  conversation: conversation,
260
330
  canReply: canReply,
@@ -349,6 +419,7 @@ function ConversationBottomBar(t0) {
349
419
  }
350
420
  return t6;
351
421
  }
422
+ const isBeforeLatestMessage = (anchor, latestMessageCreatedAt) => !!anchor && !!latestMessageCreatedAt && decodeUlidTime(anchor) < Date.parse(latestMessageCreatedAt);
352
423
  export const ConversationScreenTitle = t0 => {
353
424
  const $ = _c(29);
354
425
  const {