| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- import {rawEmojis} from "./emojis";
- import beep from "../sounds/beep.mp3";
- import juntos from "../sounds/juntos.mp3";
- import pristine from "../sounds/pristine.mp3";
- import ding from "../sounds/ding.mp3";
- import dadum from "../sounds/dadum.mp3";
- import pop from "../sounds/pop.mp3";
- import popSwoosh from "../sounds/pop-swoosh.mp3";
- import config from "./config";
- import {Base64} from 'js-base64';
- export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`;
- export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws`
- .replaceAll("https://", "wss://")
- .replaceAll("http://", "ws://");
- export const topicUrlJson = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/json`;
- export const topicUrlJsonPoll = (baseUrl, topic) => `${topicUrlJson(baseUrl, topic)}?poll=1`;
- export const topicUrlJsonPollWithSince = (baseUrl, topic, since) => `${topicUrlJson(baseUrl, topic)}?poll=1&since=${since}`;
- export const topicUrlAuth = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/auth`;
- export const topicShortUrl = (baseUrl, topic) => shortUrl(topicUrl(baseUrl, topic));
- export const userStatsUrl = (baseUrl) => `${baseUrl}/user/stats`;
- export const shortUrl = (url) => url.replaceAll(/https?:\/\//g, "");
- export const expandUrl = (url) => [`https://${url}`, `http://${url}`];
- export const expandSecureUrl = (url) => `https://${url}`;
- export const validUrl = (url) => {
- return url.match(/^https?:\/\//);
- }
- export const validTopic = (topic) => {
- if (disallowedTopic(topic)) {
- return false;
- }
- return topic.match(/^([-_a-zA-Z0-9]{1,64})$/); // Regex must match Go & Android app!
- }
- export const disallowedTopic = (topic) => {
- return config.disallowedTopics.includes(topic);
- }
- // Format emojis (see emoji.js)
- const emojis = {};
- rawEmojis.forEach(emoji => {
- emoji.aliases.forEach(alias => {
- emojis[alias] = emoji.emoji;
- });
- });
- const toEmojis = (tags) => {
- if (!tags) return [];
- else return tags.filter(tag => tag in emojis).map(tag => emojis[tag]);
- }
- export const formatTitleWithDefault = (m, fallback) => {
- if (m.title) {
- return formatTitle(m);
- }
- return fallback;
- };
- export const formatTitle = (m) => {
- const emojiList = toEmojis(m.tags);
- if (emojiList.length > 0) {
- return `${emojiList.join(" ")} ${m.title}`;
- } else {
- return m.title;
- }
- };
- export const formatMessage = (m) => {
- if (m.title) {
- return m.message;
- } else {
- const emojiList = toEmojis(m.tags);
- if (emojiList.length > 0) {
- return `${emojiList.join(" ")} ${m.message}`;
- } else {
- return m.message;
- }
- }
- };
- export const unmatchedTags = (tags) => {
- if (!tags) return [];
- else return tags.filter(tag => !(tag in emojis));
- }
- export const maybeWithBasicAuth = (headers, user) => {
- if (user) {
- headers['Authorization'] = `Basic ${encodeBase64(`${user.username}:${user.password}`)}`;
- }
- return headers;
- }
- export const basicAuth = (username, password) => {
- return `Basic ${encodeBase64(`${username}:${password}`)}`;
- }
- export const encodeBase64 = (s) => {
- return Base64.encode(s);
- }
- export const encodeBase64Url = (s) => {
- return Base64.encodeURI(s);
- }
- export const shuffle = (arr) => {
- let j, x;
- for (let index = arr.length - 1; index > 0; index--) {
- j = Math.floor(Math.random() * (index + 1));
- x = arr[index];
- arr[index] = arr[j];
- arr[j] = x;
- }
- return arr;
- }
- export const splitNoEmpty = (s, delimiter) => {
- return s
- .split(delimiter)
- .map(x => x.trim())
- .filter(x => x !== "");
- }
- /** Non-cryptographic hash function, see https://stackoverflow.com/a/8831937/1440785 */
- export const hashCode = async (s) => {
- let hash = 0;
- for (let i = 0; i < s.length; i++) {
- const char = s.charCodeAt(i);
- hash = ((hash<<5)-hash)+char;
- hash = hash & hash; // Convert to 32bit integer
- }
- return hash;
- }
- export const formatShortDateTime = (timestamp) => {
- return new Intl.DateTimeFormat('default', {dateStyle: 'short', timeStyle: 'short'})
- .format(new Date(timestamp * 1000));
- }
- export const formatBytes = (bytes, decimals = 2) => {
- if (bytes === 0) return '0 bytes';
- const k = 1024;
- const dm = decimals < 0 ? 0 : decimals;
- const sizes = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
- const i = Math.floor(Math.log(bytes) / Math.log(k));
- return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
- }
- export const openUrl = (url) => {
- window.open(url, "_blank", "noopener,noreferrer");
- };
- export const sounds = {
- "beep": beep,
- "juntos": juntos,
- "pristine": pristine,
- "ding": ding,
- "dadum": dadum,
- "pop": pop,
- "pop-swoosh": popSwoosh
- };
- export const playSound = async (sound) => {
- const audio = new Audio(sounds[sound]);
- return audio.play();
- };
- // From: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
- export async function* fetchLinesIterator(fileURL, headers) {
- const utf8Decoder = new TextDecoder('utf-8');
- const response = await fetch(fileURL, {
- headers: headers
- });
- const reader = response.body.getReader();
- let { value: chunk, done: readerDone } = await reader.read();
- chunk = chunk ? utf8Decoder.decode(chunk) : '';
- const re = /\n|\r|\r\n/gm;
- let startIndex = 0;
- for (;;) {
- let result = re.exec(chunk);
- if (!result) {
- if (readerDone) {
- break;
- }
- let remainder = chunk.substr(startIndex);
- ({ value: chunk, done: readerDone } = await reader.read());
- chunk = remainder + (chunk ? utf8Decoder.decode(chunk) : '');
- startIndex = re.lastIndex = 0;
- continue;
- }
- yield chunk.substring(startIndex, result.index);
- startIndex = re.lastIndex;
- }
- if (startIndex < chunk.length) {
- yield chunk.substr(startIndex); // last line didn't end in a newline char
- }
- }
|