PluginProbe ʕ •ᴥ•ʔ
Presto Player / trunk
Presto Player vtrunk
4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / src / admin / dashboard / utils / formatters.js
presto-player / src / admin / dashboard / utils Last commit date
test 1 month ago analyticsApi.js 1 month ago classnames.js 1 month ago dateUtils.js 1 month ago formatters.js 1 month ago helpers.js 1 month ago icons.js 1 month ago index.js 1 month ago pluginUtils.js 1 month ago transformers.js 1 month ago viewportBoundary.js 1 month ago
formatters.js
151 lines
1 /**
2 * Utility functions for formatting text, HTML, and time values
3 */
4
5 /**
6 * Decodes HTML entities in text
7 * Useful for rendering WordPress content that may contain encoded entities
8 *
9 * @param {string} text - The text containing HTML entities
10 * @returns {string} The decoded text
11 *
12 * @example
13 * decodeHTMLEntities("John's Video") // Returns: "John's Video"
14 * decodeHTMLEntities("Sales & Marketing") // Returns: "Sales & Marketing"
15 */
16 export const decodeHTMLEntities = (text) => {
17 if (!text) return "";
18 const textArea = document.createElement("textarea");
19 textArea.innerHTML = text;
20 return textArea.value;
21 };
22
23 /**
24 * Converts seconds to a human-readable format
25 *
26 * @param {number} seconds - The number of seconds to format
27 * @returns {string} The formatted time string (e.g., "2h 30m 15s")
28 *
29 * @example
30 * humanSeconds(0) // Returns: "0s"
31 * humanSeconds(65) // Returns: "1m 5s"
32 * humanSeconds(3665) // Returns: "1h 1m 5s"
33 */
34 /**
35 * Formats seconds as HH:MM:SS
36 *
37 * @param {number} seconds - The number of seconds to format
38 * @returns {string} Formatted time string (e.g., "01:30:05")
39 */
40 export const formatHMS = (seconds) => {
41 const s = Math.round(seconds) || 0;
42 const h = Math.floor(s / 3600);
43 const m = Math.floor((s % 3600) / 60);
44 const sec = s % 60;
45 return [h, m, sec].map((v) => String(v).padStart(2, "0")).join(":");
46 };
47
48 export const humanSeconds = (seconds) => {
49 if (!seconds || seconds === 0) {
50 return "0s";
51 }
52
53 const hours = Math.floor(seconds / 3600);
54 const minutes = Math.floor((seconds % 3600) / 60);
55 const secs = Math.floor(seconds % 60);
56
57 const parts = [];
58 if (hours > 0) parts.push(`${hours}h`);
59 if (minutes > 0) parts.push(`${minutes}m`);
60 if (secs > 0 || parts.length === 0) parts.push(`${secs}s`);
61
62 return parts.join(" ");
63 };
64
65 /**
66 * Compact single-unit version of humanSeconds for chart axes / tight UI.
67 *
68 * Stays in seconds up to 90s (so a sub-minute Y-axis reads "0s, 30s, 60s, 90s"
69 * rather than mixing "45s, 1m") and similarly defers to minutes up to 90m.
70 *
71 * @param {number} seconds
72 * @returns {string} e.g. "6s", "60s", "2m", "1h"
73 */
74 export const humanSecondsCompact = (seconds) => {
75 const s = Math.round(Number(seconds) || 0);
76 if (s < 90) return `${s}s`;
77 if (s < 90 * 60) return `${Math.round(s / 60)}m`;
78 return `${Math.round(s / 3600)}h`;
79 };
80
81 /**
82 * Formats chart data for display in LineChart components
83 * Handles sorting, date formatting, and value transformations
84 *
85 * @param {Array} chartData - Array of chart data objects
86 * @param {string} dataKey - The key to extract the value from each data object
87 * @param {boolean} isWatchTime - Whether to convert seconds to minutes
88 * @param {Function} formatDate - Date formatting function
89 * @param {number} divisor - Number to divide values by (default: 60 for watch time)
90 * @param {number} decimalPlaces - Number of decimal places for watch time (default: 2)
91 * @returns {Array} Formatted chart data with 'month' and 'count' properties
92 *
93 * @example
94 * formatChartData(data, 'total', false, format) // For views
95 * formatChartData(data, 'total', true, format) // For watch time (converts seconds to minutes)
96 */
97 export const formatChartData = (
98 chartData,
99 dataKey,
100 isWatchTime = false,
101 formatDate,
102 divisor = 60,
103 decimalPlaces = 2
104 ) => {
105 if (!chartData || chartData.length === 0) {
106 return [];
107 }
108
109 const sortedChartData = [...chartData].sort(
110 (a, b) => new Date(a.date_time) - new Date(b.date_time)
111 );
112
113 return sortedChartData.map((data) => {
114 const value = parseInt(data[dataKey], 10) || 0;
115 return {
116 month: formatDate(new Date(data.date_time), "MMM dd, yyyy"),
117 count: isWatchTime
118 ? parseFloat((value / divisor).toFixed(decimalPlaces))
119 : value,
120 };
121 });
122 };
123
124 /**
125 * Fill missing days in a formatted chart series with zero entries so the
126 * chart line touches y=0 across gaps instead of interpolating between the
127 * non-zero days surrounding them.
128 *
129 * @param {Array} points Output of formatChartData (each item has `{ month, count }`).
130 * @param {Object} range `{ from: Date, to: Date }` — inclusive day bounds.
131 * @param {Function} formatDate Same date formatter used by formatChartData.
132 * @returns {Array} Continuous daily series across the range.
133 */
134 export const padDailyPoints = (points, range, formatDate) => {
135 if (!range?.from || !range?.to || !formatDate) return points;
136
137 const byDay = new Map((points || []).map((p) => [p.month, p.count]));
138 const result = [];
139 const cursor = new Date(range.from);
140 cursor.setHours(0, 0, 0, 0);
141 const end = new Date(range.to);
142 end.setHours(0, 0, 0, 0);
143
144 while (cursor <= end) {
145 const key = formatDate(cursor, "MMM dd, yyyy");
146 result.push({ month: key, count: byDay.get(key) ?? 0 });
147 cursor.setDate(cursor.getDate() + 1);
148 }
149 return result;
150 };
151