feathermost/js/util.js
Midgard f7344dc63f
Improve when time is shown and improve post UI
This commit introduces a heuristic for when to show time, introduces a
date separator and tweaks the margins of posts.
2022-06-11 18:15:31 +02:00

144 lines
3.6 KiB
JavaScript

/**
* Return an endpoint URL that has a protocol, domain and path
*/
function normalizedEndpoint(endpoint) {
let matches = endpoint.match(/^(https?:\/\/)?([^\/]+)(\/.*)?$/i);
if (!matches) throw Error("Invalid endpoint URL");
let protocol = matches[1] || "https://";
let domain = matches[2];
let path = matches[3] || "/api/v4";
return `${protocol}${domain}${path}`;
}
/**
* Return the endpoint as it should be shown to the user
*/
function humanReadableEndpoint(endpoint) {
let matches = endpoint.match(/^(https?:\/\/.+)\/api\/v4$/i);
if (!matches) throw Error("Invalid endpoint URL");
return matches[1];
}
/**
* Shorthand for document.getElementById
*/
function byId(id, nullOk=false) {
const el = document.getElementById(id);
if (!el && !nullOk) {
console.error(`No element #${id}`);
}
return el;
}
function removeClass(el, className) {
el.className = el.className.split(" ").filter(x => x !== className).join(" ");
}
function addClass(el, className) {
el.className = el.className.split(" ").filter(x => x !== className).join(" ") + ` ${className}`;
}
/**
* Wrap a function so that it receives `this` as first argument
*/
function thisToArg(f) {
return function(...rest) {
return f(this, ...rest);
}
}
/**
* Extend an object in-place with own properties of a second one
*/
function extend(obj1, obj2) {
for (let key in Object.getOwnPropertyNames(obj1)) {
obj1[key] = obj2[key];
}
}
function arrayToHashmap(array, key) {
let result = Object.create(null);
for (let x of array) {
result[x[key]] = x;
}
return result;
}
function startsWith(string, start) {
return string.slice(0, start.length) == start;
}
function padLeft(input, width, padding=" ") {
text = input + "";
while (text.length < width) {
text = padding + text;
}
return text;
}
function toTimeZone(date, timezoneString) {
// https://stackoverflow.com/questions/10087819/convert-date-to-another-timezone-in-javascript
return new Date(date.toLocaleString("en-US", {timeZone: timezoneString}));
}
function formatYyyyMmDdWeekday(date) {
const weekday = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"][date.getDay()];
return `${date.getFullYear()}-${padLeft(date.getMonth() + 1, 2, "0")}-${padLeft(date.getDate(), 2, "0")}, ${weekday}`;
}
function formatHhMm(date) {
return `${padLeft(date.getHours(), 2, "0")}:${padLeft(date.getMinutes(), 2, "0")}`;
}
const DATE_SIMILARITY = {
none: 0,
year: 1,
month: 2,
date: 3,
hours: 4,
minutes: 5,
seconds: 6
}
function dateSimilarity(d1, d2) {
if (!d1 || !d2) return DATE_SIMILARITY.none;
if (d1.getFullYear() != d2.getFullYear()) return DATE_SIMILARITY.none;
if (d1.getMonth() != d2.getMonth()) return DATE_SIMILARITY.year;
if (d1.getDate() != d2.getDate()) return DATE_SIMILARITY.month;
if (d1.getHours() != d2.getHours()) return DATE_SIMILARITY.date;
if (d1.getMinutes() != d2.getMinutes()) return DATE_SIMILARITY.hours;
if (d1.getSeconds() != d2.getSeconds()) return DATE_SIMILARITY.minutes;
return DATE_SIMILARITY.seconds;
}
class AssertionError extends Error {}
/**
* Throw an AssertionError if the first argument is not true
*/
function assert(condition, message) {
if (!condition) {
if (message) {
throw new AssertionError(`Assertion failed: ${message}`);
} else {
throw new AssertionError("Assertion failed");
}
}
}
const MATTERMOST_ID_REGEXP = /^[a-z0-9]{26}$/;
function assertIsMattermostId(string, name="") {
assert(MATTERMOST_ID_REGEXP.test(string), `${name} has the form of a Mattermost ID`);
}
function assertIsNullOrMattermostId(string, name="") {
assert(string === null || MATTERMOST_ID_REGEXP.test(string), `${name} is null or has the form of a Mattermost ID`);
}