generated from CodeYourFuture/Module-Template
-
-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathbloom.mjs
More file actions
88 lines (74 loc) · 2.4 KB
/
bloom.mjs
File metadata and controls
88 lines (74 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* Create a bloom component
* @param {string} template - The ID of the template to clone
* @param {Object} bloom - The bloom data
* @returns {DocumentFragment} - The bloom fragment of UI, for items in the Timeline
* btw a bloom object is composed thus
* {"id": Number,
* "sender": username,
* "content": "string from textarea",
* "sent_timestamp": "datetime as ISO 8601 formatted string"}
*/
const createBloom = (template, bloom) => {
if (!bloom) return;
const bloomFrag = document.getElementById(template).content.cloneNode(true);
const bloomParser = new DOMParser();
const bloomArticle = bloomFrag.querySelector("[data-bloom]");
const bloomUsername = bloomFrag.querySelector("[data-username]");
const bloomTime = bloomFrag.querySelector("[data-time]");
const bloomTimeLink = bloomFrag.querySelector("a:has(> [data-time])");
const bloomContent = bloomFrag.querySelector("[data-content]");
bloomArticle.setAttribute("data-bloom-id", bloom.id);
bloomUsername.setAttribute("href", `/profile/${bloom.sender}`);
bloomUsername.textContent = bloom.sender;
bloomTime.textContent = _formatTimestamp(bloom.sent_timestamp);
bloomTimeLink.setAttribute("href", `/bloom/${bloom.id}`);
bloomContent.replaceChildren(
...bloomParser.parseFromString(_formatHashtags(bloom.content), "text/html")
.body.childNodes
);
return bloomFrag;
};
function _formatHashtags(text) {
if (!text) return text;
return text.replace(
/\B#[a-zA-Z0-9_]+/g,
(match) => `<a href="/hashtag/${match.slice(1)}">${match}</a>`
);
}
function _formatTimestamp(timestamp) {
if (!timestamp) return "";
try {
const date = new Date(timestamp);
const now = new Date();
const diffSeconds = Math.floor((now - date) / 1000);
// Less than a minute
if (diffSeconds < 60) {
return `${diffSeconds}s`;
}
// Less than an hour
const diffMinutes = Math.floor(diffSeconds / 60);
if (diffMinutes < 60) {
return `${diffMinutes}m`;
}
// Less than a day
const diffHours = Math.floor(diffMinutes / 60);
if (diffHours < 24) {
return `${diffHours}h`;
}
// Less than a week
const diffDays = Math.floor(diffHours / 24);
if (diffDays < 7) {
return `${diffDays}d`;
}
// Format as month and day for older dates
return new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
}).format(date);
} catch (error) {
console.error("Failed to format timestamp:", error);
return "";
}
}
export { createBloom };