PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Launch / hooks / useTelemetry.js

useTelemetry.js in Extendify 3.1.5, at src/Launch/hooks/useTelemetry.js

194 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { INSIGHTS_HOST } from '@constants';
2 import { useGlobalStore } from '@launch/state/Global';
3 import { usePagesStore } from '@launch/state/Pages';
4 import { usePagesSelectionStore } from '@launch/state/pages-selections';
5 import { useUserSelectionStore } from '@launch/state/user-selections';
6 import { useEffect, useRef, useState } from '@wordpress/element';
7
8 // Dev note: This entire section is opt-in only when partnerID is set as a constant
9 export const useTelemetry = () => {
10 const {
11 sitePlugins,
12 siteStructure,
13 variation,
14 siteProfile,
15 siteObjective,
16 siteQA,
17 attempt,
18 urlParameters,
19 } = useUserSelectionStore();
20 const { pages: selectedPages, style: selectedStyle } =
21 usePagesSelectionStore();
22 const { generating } = useGlobalStore();
23 const { pages, currentPageIndex, preselectedPages } = usePagesStore();
24 const [stepProgress, setStepProgress] = useState([]);
25 const [viewedStyles, setViewedStyles] = useState(new Set());
26 const running = useRef(false);
27 const firstRun = useRef(true);
28
29 useEffect(() => {
30 const p = [...pages].map((p) => p[0]);
31 // Add pages as they move around
32 setStepProgress((progress) => {
33 const withoutSkipped = progress.filter((p) => !preselectedPages.has(p));
34 // Return early if launched, or on the same page
35 if ([p[currentPageIndex], 'launched'].includes(progress?.at(-1))) {
36 return withoutSkipped;
37 }
38 return [...withoutSkipped, p[currentPageIndex]];
39 });
40 }, [currentPageIndex, pages, preselectedPages]);
41
42 useEffect(() => {
43 if (!generating) return;
44 // They pressed Launch
45 setStepProgress((progress) => [...progress, 'launched']);
46 }, [generating]);
47
48 useEffect(() => {
49 if (!Object.keys(selectedStyle ?? {})?.length) return;
50 // Add selectedStyle to the set
51 setViewedStyles((styles) => {
52 const newStyles = new Set(styles);
53 newStyles.add(selectedStyle);
54 return newStyles;
55 });
56 }, [selectedStyle]);
57
58 useEffect(() => {
59 let id = 0;
60 let innerId = 0;
61 const timeout = firstRun.current
62 ? // Send the first request immediately,
63 0
64 : // if on page 0, wait 2s
65 currentPageIndex === 0
66 ? 2000
67 : // Every other request will be 1s
68 1000;
69 firstRun.current = false;
70 id = window.setTimeout(() => {
71 if (running.current) return;
72 running.current = true;
73 const controller = new AbortController();
74 innerId = window.setTimeout(() => {
75 running.current = false;
76 controller.abort();
77 }, 900);
78
79 fetch(`${INSIGHTS_HOST}/api/v1/launch`, {
80 method: 'POST',
81 headers: {
82 'Content-type': 'application/json',
83 Accept: 'application/json',
84 'X-Extendify': 'true',
85 },
86 signal: controller.signal,
87 body: JSON.stringify({
88 siteType: siteProfile?.aiSiteType,
89 siteCategory: siteProfile?.aiSiteCategory,
90 siteCreatedAt: window.extSharedData?.siteCreatedAt,
91 style: variation?.title,
92 siteStructure,
93 siteObjective,
94 pages: selectedPages?.map((p) => p.slug),
95 sitePlugins: sitePlugins?.map((p) => p?.name),
96 lastCompletedStep: stepProgress?.at(-1),
97 progress: stepProgress,
98 preSelect: [...preselectedPages],
99 stylesViewed: [...viewedStyles]
100 .filter((s) => s?.variation)
101 .map((s) => s.variation.title),
102 insightsId: window.extSharedData?.siteId,
103 activeTests:
104 window.extOnbData?.activeTests?.length > 0
105 ? JSON.stringify(window.extOnbData?.activeTests)
106 : undefined,
107 hostPartner: window.extSharedData?.partnerId,
108 language: window.extSharedData?.wpLanguage,
109 siteURL: window.extSharedData?.homeUrl,
110 siteQuestions: siteQA?.questions.map((q) => ({
111 id: q?.id,
112 question: q?.question,
113 answerUser: q?.answerUser || null,
114 answerAI: q?.answerAI || null,
115 group: q?.group || null,
116 extraFields: q?.extraFields
117 ? q?.extraFields.map((ef) => ({
118 question: ef?.id,
119 answer: ef?.answer || null,
120 }))
121 : null,
122 })),
123 showHiddenQuestions: Boolean(siteQA?.showHidden),
124 attempt,
125 enabledFeatures: window.extSharedData?.showSiteQuestions
126 ? ['site-questions']
127 : [],
128 urlParameters: Object.fromEntries(
129 Object.entries(urlParameters)
130 .map(([key, value]) => {
131 if (key === 'tone' && Array.isArray(value)) {
132 return [key, value.map((t) => t.value)];
133 }
134 if (key === 'skip' && Array.isArray(value)) {
135 return [key, value];
136 }
137 return [key, value];
138 })
139 .filter(
140 ([_, value]) =>
141 value !== null &&
142 value !== '' &&
143 (!Array.isArray(value) || value.length > 0),
144 ),
145 ),
146 extra: {
147 userAgent: window?.navigator?.userAgent,
148 vendor: window?.navigator?.vendor || 'unknown',
149 platform:
150 window?.navigator?.userAgentData?.platform ||
151 window?.navigator?.platform ||
152 'unknown',
153 mobile: window?.navigator?.userAgentData?.mobile,
154 width: window.innerWidth,
155 height: window.innerHeight,
156 screenHeight: window.screen.height,
157 screenWidth: window.screen.width,
158 orientation: window.screen.orientation?.type,
159 touchSupport:
160 'ontouchstart' in window || navigator.maxTouchPoints > 0,
161 },
162 }),
163 })
164 .catch(() => undefined)
165 .finally(() => {
166 running.current = false;
167 });
168 }, timeout);
169 return () => {
170 running.current = false;
171 [id, innerId].forEach((i) => {
172 window.clearTimeout(i);
173 });
174 };
175 }, [
176 selectedPages,
177 selectedStyle,
178 pages,
179 stepProgress,
180 viewedStyles,
181 currentPageIndex,
182 sitePlugins,
183 siteProfile?.aiSiteType,
184 siteProfile?.aiSiteCategory,
185 siteStructure,
186 siteObjective,
187 variation,
188 preselectedPages,
189 siteQA,
190 attempt,
191 urlParameters,
192 ]);
193 };
194