Skip to content

Commit 5add9f1

Browse files
dev: add block usage tracking
1 parent beb4619 commit 5add9f1

2 files changed

Lines changed: 109 additions & 0 deletions

File tree

js/FeedzyLoop/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import './extension';
1616
import metadata from './block.json';
1717
import variations from './variations';
1818
import edit from './edit';
19+
import './tracking';
1920

2021
const { name } = metadata;
2122

js/FeedzyLoop/tracking.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { subscribe, select } from '@wordpress/data';
2+
import { store as blockEditorStore } from '@wordpress/block-editor';
3+
import domReady from '@wordpress/dom-ready';
4+
5+
/**
6+
* Stores the current count of each watched block type.
7+
* @type {Object.<string, number>}
8+
*/
9+
let blockCounts = {};
10+
11+
/**
12+
* Flag to track if the initial block count has been established.
13+
* Used to skip logging on first load.
14+
* @type {boolean}
15+
*/
16+
let isInitialized = false;
17+
18+
/**
19+
* Array of block types to monitor for changes.
20+
* @type {string[]}
21+
* @constant
22+
*/
23+
const watchedBlockTypes = [
24+
'feedzy-rss-feeds/loop',
25+
'feedzy-rss-feeds/feedzy-block',
26+
'core/rss',
27+
];
28+
29+
/**
30+
* Recursively flattens the block tree to get all blocks including nested ones.
31+
*
32+
* @return {Object[]} Array of all blocks in the editor (flattened)
33+
*/
34+
function getAllBlocks() {
35+
function flattenBlocks(blocks) {
36+
let allBlocks = [];
37+
blocks.forEach((block) => {
38+
allBlocks.push(block);
39+
if (block.innerBlocks?.length > 0) {
40+
allBlocks = allBlocks.concat(flattenBlocks(block.innerBlocks));
41+
}
42+
});
43+
return allBlocks;
44+
}
45+
46+
return flattenBlocks(select(blockEditorStore).getBlocks());
47+
}
48+
49+
/**
50+
* Updates the block counts and tracks changes for analytics.
51+
* Skips logging during initial initialization to avoid false positives.
52+
*
53+
* @fires window.tiTrk.with - Sends analytics data when block counts change if telemetry is enabled.
54+
*/
55+
function updateBlockCounts() {
56+
const allBlocks = getAllBlocks();
57+
58+
// Reset counts.
59+
const newCounts = {};
60+
watchedBlockTypes.forEach((type) => {
61+
newCounts[type] = 0;
62+
});
63+
64+
const clientIds = [];
65+
66+
// Count blocks.
67+
allBlocks.forEach((block) => {
68+
if (watchedBlockTypes.includes(block.name)) {
69+
clientIds.push(block.clientId);
70+
newCounts[block.name]++;
71+
}
72+
});
73+
74+
if (isInitialized) {
75+
// Check for changes.
76+
watchedBlockTypes.forEach((blockType) => {
77+
const oldCount = blockCounts[blockType] || 0;
78+
const newCount = newCounts[blockType] || 0;
79+
80+
if (oldCount === newCount) {
81+
return;
82+
}
83+
84+
const change = newCount - oldCount;
85+
window?.tiTrk?.with('feedzy')?.set(`${blockType}:${Date()}`, {
86+
feature: 'block-usage',
87+
featureComponent: blockType,
88+
featureValue: change,
89+
});
90+
});
91+
} else {
92+
isInitialized = true;
93+
}
94+
95+
blockCounts = newCounts;
96+
}
97+
98+
domReady(() => {
99+
if (window.tiTrk) {
100+
window.tiTrk?.start();
101+
window.tiTrk.eventsLimit = 60 * 1000; // Check for events every minute.
102+
}
103+
104+
// Note: add a delay for a better initialization for existing blocks.
105+
setTimeout(() => {
106+
const unsubscribe = subscribe(updateBlockCounts, blockEditorStore);
107+
}, 1000);
108+
});

0 commit comments

Comments
 (0)