Skip to content

Commit 2cde9eb

Browse files
committed
fix: Panels not being destroyed properly on component unmount
1 parent 5253bb7 commit 2cde9eb

File tree

5 files changed

+34
-61
lines changed

5 files changed

+34
-61
lines changed

example/App.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ function App() {
107107
const [panelHeight, setPanelHeight] = useState(100);
108108
const [panelVisible, setPanelVisible] = useState(true);
109109

110-
const [panel, setPanel] = useState(false);
110+
const [renderPanel, setPanel] = useState(false);
111111

112112
if (typeof import.meta.env.VITE_APP_ID !== "string") {
113113
return (
@@ -156,7 +156,7 @@ function App() {
156156
{...(blur ? { onBlur } : {})}
157157
style={{ width: 500, height: 600 }}
158158
>
159-
{panel && (
159+
{renderPanel && (
160160
<HtmlPanel
161161
url="example/panel.html"
162162
height={panelHeight}
@@ -174,8 +174,13 @@ function App() {
174174
</Chatbox>
175175
</Session>
176176

177-
<button onClick={() => setPanel((x) => !x)}>
178-
toggle panel to {String(!panel)}
177+
<button
178+
onClick={() => {
179+
setPanel((x) => !x);
180+
setPanelVisible(true);
181+
}}
182+
>
183+
{renderPanel ? "Unmount" : "Mount"} HTML panel
179184
</button>
180185
<button onClick={otherMe}>switch user (new session)</button>
181186
<br />

example/main.tsx

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,3 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
88
<App />
99
</React.StrictMode>,
1010
);
11-
12-
// import Talk from "talkjs";
13-
14-
// await Talk.ready;
15-
16-
// const me = new Talk.User({ id: "alice", name: "Alice" });
17-
// const session = new Talk.Session({ appId: "Hku1c4Pt", me });
18-
// const chatbox = session.createChatbox();
19-
// const conversation = session.getOrCreateConversation("abc");
20-
// conversation.setParticipant(me);
21-
22-
// chatbox.select(conversation);
23-
// chatbox.mount(document.getElementById("root")!);
24-
25-
// chatbox.createHtmlPanel({ url: "./example/panel.html" });
26-
27-
// document.getElementById("root")!.style.height = "100vh";

example/panel.html

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,5 @@
1515
}
1616
</style>
1717
</head>
18-
<body>
19-
Default content here
20-
</body>
18+
<body></body>
2119
</html>

lib/HtmlPanel.tsx

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useContext, useEffect, useRef, useState } from "react";
1+
import { useContext, useEffect, useState } from "react";
22
import { createPortal } from "react-dom";
33
import Talk from "talkjs";
44
import { BoxContext } from "./MountedBox";
@@ -31,47 +31,38 @@ export function HtmlPanel({
3131
conversationId,
3232
children,
3333
}: HtmlPanelProps) {
34-
const panelPromise = useRef<undefined | Promise<Talk.HtmlPanel>>(undefined);
3534
const [panel, setPanel] = useState<undefined | Talk.HtmlPanel>(undefined);
3635
const box = useContext(BoxContext);
3736

3837
useEffect(() => {
39-
function run() {
40-
console.log("@@trying");
41-
if (!box || panelPromise.current) return;
42-
console.log("@@initializing");
38+
async function run() {
39+
if (!box || panel) return Promise.resolve(panel);
4340

44-
// const old = await panelPromise;
45-
// old?.destroy();
41+
const newPanel = await box.createHtmlPanel({
42+
url,
43+
conversation: conversationId,
44+
height,
45+
show: false,
46+
});
4647

47-
const panel = box
48-
.createHtmlPanel({ url, conversation: conversationId, height, show })
49-
.then(async (panel) => {
50-
await panel.windowLoadedPromise;
51-
console.log("@@window loaded");
52-
// setPanel(panel);
53-
return panel;
54-
});
48+
await newPanel.DOMContentLoadedPromise;
49+
if (show) {
50+
newPanel.show();
51+
}
5552

56-
panelPromise.current = panel;
53+
setPanel(newPanel);
54+
return newPanel;
5755
}
5856

59-
run();
57+
const panelPromise = run();
6058

61-
// return () => {
62-
// console.log("@@cleanup", panelPromise);
63-
// if (panelPromise) {
64-
// panelPromise.current?.then((panel) => {
65-
// panelPromise.current = undefined;
66-
// panel.destroy().then(() => {
67-
// console.log("@@deleted");
68-
// setPanel(undefined);
69-
// });
70-
// });
71-
// } else {
72-
// setPanel(undefined);
73-
// }
74-
// };
59+
return () => {
60+
panelPromise.then((panel) => {
61+
panel?.destroy().then(() => {
62+
setPanel(undefined);
63+
});
64+
});
65+
};
7566
// We intentionally exclude `height` and `show` from the dependency array so
7667
// that we update them later via methods instead of by re-creating the
7768
// entire panel from scratch each time.
@@ -91,6 +82,5 @@ export function HtmlPanel({
9182
}
9283
}, [panel, show]);
9384

94-
// return <>{panel && createPortal(children, panel.window.document.body)}</>;
95-
return null;
85+
return <>{panel && createPortal(children, panel.window.document.body)}</>;
9686
}

lib/hooks.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,11 @@ export function useUIBox<
8484
if (session?.isAlive) {
8585
const uibox = session[create](options) as R;
8686
setBox(uibox);
87-
(window as any).ui = uibox;
88-
console.log("@@create");
8987
if (ref) {
9088
ref.current = uibox;
9189
}
9290

9391
return () => {
94-
console.log("@@destroy");
9592
uibox.destroy();
9693
setBox(undefined);
9794
};

0 commit comments

Comments
 (0)