Skip to content

Commit c759c90

Browse files
authored
Merge pull request Next-Room#46 from Next-Room/fix/hide_channeltalk
fix: 다른 페이지에서 회원가입으로 이동 시 채널톡이 남아 있음
2 parents 1dd9706 + ab63281 commit c759c90

File tree

7 files changed

+231
-40
lines changed

7 files changed

+231
-40
lines changed

app/apis/ChannelTalk.tsx

Lines changed: 198 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,198 @@
1-
"use client";
2-
3-
import { isDevMode } from "@/consts/env";
4-
import { usePathname } from "next/navigation"
5-
import Script from "next/script";
6-
7-
function ChannelTalk() {
8-
const pathname = usePathname();
9-
10-
if (isDevMode) return null;
11-
if (pathname==="/signup") return null;
12-
console.log(pathname);
13-
14-
const channelIoScript = `
15-
(function(){var w=window;if(w.ChannelIO){return w.console.error("ChannelIO script included twice.");}var ch=function(){ch.c(arguments);};ch.q=[];ch.c=function(args){ch.q.push(args);};w.ChannelIO=ch;function l(){if(w.ChannelIOInitialized){return;}w.ChannelIOInitialized=true;var s=document.createElement("script");s.type="text/javascript";s.async=true;s.src="https://cdn.channel.io/plugin/ch-plugin-web.js";var x=document.getElementsByTagName("script")[0];if(x.parentNode){x.parentNode.insertBefore(s,x);}}if(document.readyState==="complete"){l();}else{w.addEventListener("DOMContentLoaded",l);w.addEventListener("load",l);}})();
16-
17-
ChannelIO('boot', {
18-
"pluginKey": "acb0febb-fe4a-45ac-aca1-e7d8c5ed746f"
19-
});
20-
`;
21-
// You can show in the console the GA_TRACKING_ID to confirm
22-
23-
return (
24-
<Script
25-
id="channel-talk-init"
26-
strategy="afterInteractive"
27-
dangerouslySetInnerHTML={{
28-
__html: channelIoScript,
29-
}}
30-
/>
31-
);
32-
}
33-
34-
export default ChannelTalk;
1+
/* eslint-disable */
2+
declare global {
3+
interface Window {
4+
ChannelIO?: IChannelIO;
5+
ChannelIOInitialized?: boolean;
6+
}
7+
}
8+
9+
interface IChannelIO {
10+
c?: (...args: any) => void;
11+
q?: [methodName: string, ...args: any[]][];
12+
(...args: any): void;
13+
}
14+
15+
interface BootOption {
16+
appearance?: string;
17+
customLauncherSelector?: string;
18+
hideChannelButtonOnBoot?: boolean;
19+
hidePopup?: boolean;
20+
language?: string;
21+
memberHash?: string;
22+
memberId?: string;
23+
pluginKey: string;
24+
profile?: Profile;
25+
trackDefaultEvent?: boolean;
26+
trackUtmSource?: boolean;
27+
unsubscribe?: boolean;
28+
unsubscribeEmail?: boolean;
29+
unsubscribeTexting?: boolean;
30+
zIndex?: number;
31+
}
32+
33+
interface Callback {
34+
(error: Error | null, user: CallbackUser | null): void;
35+
}
36+
37+
interface CallbackUser {
38+
alert: number;
39+
avatarUrl: string;
40+
id: string;
41+
language: string;
42+
memberId: string;
43+
name?: string;
44+
profile?: Profile | null;
45+
tags?: string[] | null;
46+
unsubscribeEmail: boolean;
47+
unsubscribeTexting: boolean;
48+
}
49+
50+
interface UpdateUserInfo {
51+
language?: string;
52+
profile?: Profile | null;
53+
profileOnce?: Profile;
54+
tags?: string[] | null;
55+
unsubscribeEmail?: boolean;
56+
unsubscribeTexting?: boolean;
57+
}
58+
59+
interface Profile {
60+
[key: string]: string | number | boolean | null | undefined;
61+
}
62+
63+
interface FollowUpProfile {
64+
name?: string | null;
65+
mobileNumber?: string | null;
66+
email?: string | null;
67+
}
68+
69+
interface EventProperty {
70+
[key: string]: string | number | boolean | null | undefined;
71+
}
72+
73+
type Appearance = "light" | "dark" | "system" | null;
74+
75+
class ChannelService {
76+
loadScript() {
77+
(function () {
78+
const w = window;
79+
if (w.ChannelIO) {
80+
return w.console.error("ChannelIO script included twice.");
81+
}
82+
const ch: IChannelIO = function () {
83+
ch.c?.(arguments);
84+
};
85+
ch.q = [];
86+
ch.c = function (args) {
87+
ch.q?.push(args);
88+
};
89+
w.ChannelIO = ch;
90+
function l() {
91+
if (w.ChannelIOInitialized) {
92+
return;
93+
}
94+
w.ChannelIOInitialized = true;
95+
const s = document.createElement("script");
96+
s.type = "text/javascript";
97+
s.async = true;
98+
s.src = "https://cdn.channel.io/plugin/ch-plugin-web.js";
99+
const x = document.getElementsByTagName("script")[0];
100+
if (x.parentNode) {
101+
x.parentNode.insertBefore(s, x);
102+
}
103+
}
104+
if (document.readyState === "complete") {
105+
l();
106+
} else {
107+
w.addEventListener("DOMContentLoaded", l);
108+
w.addEventListener("load", l);
109+
}
110+
})();
111+
}
112+
113+
boot(option: BootOption, callback?: Callback) {
114+
window.ChannelIO?.("boot", option, callback);
115+
}
116+
117+
shutdown() {
118+
window.ChannelIO?.("shutdown");
119+
}
120+
121+
showMessenger() {
122+
window.ChannelIO?.("showMessenger");
123+
}
124+
125+
hideMessenger() {
126+
window.ChannelIO?.("hideMessenger");
127+
}
128+
129+
openChat(chatId?: string | number, message?: string) {
130+
window.ChannelIO?.("openChat", chatId, message);
131+
}
132+
133+
track(eventName: string, eventProperty?: EventProperty) {
134+
window.ChannelIO?.("track", eventName, eventProperty);
135+
}
136+
137+
onShowMessenger(callback: () => void) {
138+
window.ChannelIO?.("onShowMessenger", callback);
139+
}
140+
141+
onHideMessenger(callback: () => void) {
142+
window.ChannelIO?.("onHideMessenger", callback);
143+
}
144+
145+
onBadgeChanged(callback: (unread: number, alert: number) => void) {
146+
window.ChannelIO?.("onBadgeChanged", callback);
147+
}
148+
149+
onChatCreated(callback: () => void) {
150+
window.ChannelIO?.("onChatCreated", callback);
151+
}
152+
153+
onFollowUpChanged(callback: (profile: FollowUpProfile) => void) {
154+
window.ChannelIO?.("onFollowUpChanged", callback);
155+
}
156+
157+
onUrlClicked(callback: (url: string) => void) {
158+
window.ChannelIO?.("onUrlClicked", callback);
159+
}
160+
161+
clearCallbacks() {
162+
window.ChannelIO?.("clearCallbacks");
163+
}
164+
165+
updateUser(userInfo: UpdateUserInfo, callback?: Callback) {
166+
window.ChannelIO?.("updateUser", userInfo, callback);
167+
}
168+
169+
addTags(tags: string[], callback?: Callback) {
170+
window.ChannelIO?.("addTags", tags, callback);
171+
}
172+
173+
removeTags(tags: string[], callback?: Callback) {
174+
window.ChannelIO?.("removeTags", tags, callback);
175+
}
176+
177+
setPage(page: string) {
178+
window.ChannelIO?.("setPage", page);
179+
}
180+
181+
resetPage() {
182+
window.ChannelIO?.("resetPage");
183+
}
184+
185+
showChannelButton() {
186+
window.ChannelIO?.("showChannelButton");
187+
}
188+
189+
hideChannelButton() {
190+
window.ChannelIO?.("hideChannelButton");
191+
}
192+
193+
setAppearance(appearance: Appearance) {
194+
window.ChannelIO?.("setAppearance", appearance);
195+
}
196+
}
197+
198+
export default ChannelService;

app/components/MakeThemePage/MakeThemePage.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useSelectedTheme } from "@/components/atoms/selectedTheme.atom";
88
import { useModalState } from "@/components/atoms/modals.atom";
99
import { useRouter } from "next/navigation";
1010
import { useGetThemeList } from "@/queries/getThemeList";
11+
import useChannelTalk from "@/hooks/useChannelTalk";
1112
import MakeThemeModalView from "./MakeThemePageView";
1213
import Dialog from "../common/Dialog/Dialog";
1314

@@ -22,6 +23,7 @@ function MakeThemePage() {
2223
const [modalState, setModalState] = useModalState();
2324
const { data: categories = [] } = useGetThemeList();
2425
const [open, setOpen] = useState<boolean>(false);
26+
useChannelTalk();
2527

2628
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2729
const [selectedTheme, setSelectedTheme] = useSelectedTheme();

app/home/Home.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ import useCheckSignIn from "@/hooks/useCheckSignIn";
66
import { useSnackBarInfo } from "@/components/atoms/snackBar.atom";
77
import SnackBar from "@/components/SnackBar/SnackBar";
88
import Loader from "@/components/Loader/Loader";
9+
import useChannelTalk from "@/hooks/useChannelTalk";
910
import HomeView from "./HomeView";
1011

1112
function Home() {
1213
const { data: categories = [] } = useGetThemeList();
1314
const [open, setOpen] = useState<boolean>(false);
1415
const [snackInfo, setSnackBarInfo] = useSnackBarInfo();
16+
useChannelTalk();
1517

1618
const handleDialog = () => {
1719
setOpen(!open);
1820
};
1921

2022
const isSignIn = useCheckSignIn();
21-
2223

2324
useEffect(() => {
2425
if (snackInfo.isOpen) {

app/hooks/useChannelTalk.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use client";
2+
3+
import ChannelTalk from "@/apis/ChannelTalk";
4+
import { isDevMode } from "@/consts/env";
5+
import { useEffect } from "react";
6+
7+
const useChannelTalk = () => {
8+
useEffect(() => {
9+
if (isDevMode) return () => null;
10+
const channelTalkInstance = new ChannelTalk();
11+
12+
channelTalkInstance.loadScript();
13+
channelTalkInstance.boot({
14+
pluginKey: "acb0febb-fe4a-45ac-aca1-e7d8c5ed746f",
15+
});
16+
17+
return () => {
18+
channelTalkInstance.shutdown();
19+
};
20+
}, []);
21+
};
22+
23+
export default useChannelTalk;

app/landing/Landing.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useIsLoggedInWrite } from "@/components/atoms/account.atom";
66
import { useAsPathStateWrite } from "@/components/atoms/signup.atom";
77
import { removeAccessToken } from "@/utils/localStorage";
88
import useCheckSignIn from "@/hooks/useCheckSignIn";
9+
import useChannelTalk from "@/hooks/useChannelTalk";
910
import LandingView from "./LandingView";
1011

1112
function Landing() {
@@ -21,10 +22,10 @@ function Landing() {
2122
setAsPathState(pathName);
2223
// document.cookie = `pathName =${pathName}`;
2324

25+
useChannelTalk();
26+
2427
const handleSignUpBtn = () => {
25-
const url = isSignIn
26-
? "/admin"
27-
: "/signup";
28+
const url = isSignIn ? "/admin" : "/signup";
2829

2930
router.push(url);
3031
};

app/layout.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import ReactQueryProvider from "@/lib/reactQueryProvider";
1010
import RequireAuth from "@/components/RequireAuth/RequireAuth";
1111

1212
import Analytics from "./apis/Analytics";
13-
import ChannelTalk from "./apis/ChannelTalk";
1413
import Clarity from "./apis/Clarity";
1514

1615
export const metadata: Metadata = {
@@ -35,7 +34,6 @@ export default function RootLayout({
3534
<body>
3635
<Suspense>
3736
<Analytics />
38-
<ChannelTalk />
3937
<Clarity />
4038
</Suspense>
4139
<Recoil>

app/login/Login.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useIsLoggedInValue } from "@/components/atoms/account.atom";
88
import { usePostLogin } from "@/mutations/postLogin";
99
import useCheckSignIn from "@/hooks/useCheckSignIn";
1010
import Loader from "@/components/Loader/Loader";
11+
import useChannelTalk from "@/hooks/useChannelTalk";
1112
import LoginView from "./LoginView";
1213

1314
interface FormValues {
@@ -34,6 +35,7 @@ function Login() {
3435
},
3536
});
3637
useCheckSignIn();
38+
useChannelTalk();
3739

3840
const onSubmit: SubmitHandler<FormValues> = (data) => {
3941
postLogin(data);

0 commit comments

Comments
 (0)