stream-chat-react 12.8.0 → 12.8.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.
@@ -28,7 +28,7 @@ export const useChat = ({ client, defaultLanguage = 'en', i18nInstance, initialN
28
28
  if (!userAgent.includes('stream-chat-react')) {
29
29
  // result looks like: 'stream-chat-react-2.3.2-stream-chat-javascript-client-browser-2.2.2'
30
30
  // the upper-case text between double underscores is replaced with the actual semantic version of the library
31
- client.setUserAgent(`stream-chat-react-12.8.0-${userAgent}`);
31
+ client.setUserAgent(`stream-chat-react-12.8.1-${userAgent}`);
32
32
  }
33
33
  client.threads.registerSubscriptions();
34
34
  client.polls.registerSubscriptions();
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { StateStore } from 'stream-chat';
2
3
  export type GetOrCreateDialogParams = {
3
4
  id: DialogId;
@@ -8,6 +9,7 @@ export type Dialog = {
8
9
  id: DialogId;
9
10
  isOpen: boolean | undefined;
10
11
  open: (zIndex?: number) => void;
12
+ removalTimeout: NodeJS.Timeout | undefined;
11
13
  remove: () => void;
12
14
  toggle: (closeAll?: boolean) => void;
13
15
  };
@@ -39,5 +41,11 @@ export declare class DialogManager {
39
41
  closeAll(): void;
40
42
  toggle(params: GetOrCreateDialogParams, closeAll?: boolean): void;
41
43
  remove(id: DialogId): void;
44
+ /**
45
+ * Marks the dialog state as unused. If the dialog id is referenced again quickly,
46
+ * the state will not be removed. Otherwise, the state will be removed after
47
+ * a short timeout.
48
+ */
49
+ markForRemoval(id: DialogId): void;
42
50
  }
43
51
  export {};
@@ -35,6 +35,7 @@ export class DialogManager {
35
35
  open: () => {
36
36
  this.open({ id });
37
37
  },
38
+ removalTimeout: undefined,
38
39
  remove: () => {
39
40
  this.remove(id);
40
41
  },
@@ -47,6 +48,21 @@ export class DialogManager {
47
48
  ...{ dialogsById: { ...current.dialogsById, [id]: dialog } },
48
49
  }));
49
50
  }
51
+ if (dialog.removalTimeout) {
52
+ clearTimeout(dialog.removalTimeout);
53
+ this.state.next((current) => ({
54
+ ...current,
55
+ ...{
56
+ dialogsById: {
57
+ ...current.dialogsById,
58
+ [id]: {
59
+ ...dialog,
60
+ removalTimeout: undefined,
61
+ },
62
+ },
63
+ },
64
+ }));
65
+ }
50
66
  return dialog;
51
67
  }
52
68
  open(params, closeRest) {
@@ -86,6 +102,9 @@ export class DialogManager {
86
102
  const dialog = state.dialogsById[id];
87
103
  if (!dialog)
88
104
  return;
105
+ if (dialog.removalTimeout) {
106
+ clearTimeout(dialog.removalTimeout);
107
+ }
89
108
  this.state.next((current) => {
90
109
  const newDialogs = { ...current.dialogsById };
91
110
  delete newDialogs[id];
@@ -95,4 +114,27 @@ export class DialogManager {
95
114
  };
96
115
  });
97
116
  }
117
+ /**
118
+ * Marks the dialog state as unused. If the dialog id is referenced again quickly,
119
+ * the state will not be removed. Otherwise, the state will be removed after
120
+ * a short timeout.
121
+ */
122
+ markForRemoval(id) {
123
+ const dialog = this.state.getLatestValue().dialogsById[id];
124
+ if (!dialog) {
125
+ return;
126
+ }
127
+ this.state.next((current) => ({
128
+ ...current,
129
+ dialogsById: {
130
+ ...current.dialogsById,
131
+ [id]: {
132
+ ...dialog,
133
+ removalTimeout: setTimeout(() => {
134
+ this.remove(id);
135
+ }, 16),
136
+ },
137
+ },
138
+ }));
139
+ }
98
140
  }
@@ -4,7 +4,11 @@ import { useStateStore } from '../../../store';
4
4
  export const useDialog = ({ id }) => {
5
5
  const { dialogManager } = useDialogManager();
6
6
  useEffect(() => () => {
7
- dialogManager.remove(id);
7
+ // Since this cleanup can run even if the component is still mounted
8
+ // and dialog id is unchanged (e.g. in <StrictMode />), it's safer to
9
+ // mark state as unused and only remove it after a timeout, rather than
10
+ // to remove it immediately.
11
+ dialogManager.markForRemoval(id);
8
12
  }, [dialogManager, id]);
9
13
  return dialogManager.getOrCreate({ id });
10
14
  };
@@ -122,7 +122,7 @@ var useDialog = ({ id }) => {
122
122
  const { dialogManager } = useDialogManager();
123
123
  (0, import_react6.useEffect)(
124
124
  () => () => {
125
- dialogManager.remove(id);
125
+ dialogManager.markForRemoval(id);
126
126
  },
127
127
  [dialogManager, id]
128
128
  );