mirror of
https://github.com/mue/mue.git
synced 2026-07-22 16:27:32 +02:00
feat(dev): jsdoc and prop-types
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
const testImage =
|
||||
'AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAAFCbWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAFBETmF2aWYAAAAADnBpdG0AAAAAAAEAAAAsaWxvYwAAAABEAAACAAEAAAABAAACRgAAABgAAgAAAAEAAAFqAAAA3AAAAEFpaW5mAAAAAAACAAAAGmluZmUCAAAAAAEAAGF2MDFDb2xvcgAAAAAZaW5mZQIAAAEAAgAARXhpZkV4aWYAAAAAGmlyZWYAAAAAAAAADmNkc2MAAgABAAEAAAB5aXBycAAAAFlpcGNvAAAAFGlzcGUAAAAAAAAAAQAAAAEAAAAQcGFzcAAAAAEAAAABAAAADGF2MUOBABwAAAAADnBpeGkAAAAAAQgAAAATY29scm5jbHgAAQANAAGAAAAAGGlwbWEAAAAAAAAAAQABBQECg4SFAAAA/G1kYXQAAAAASUkqAAgAAAAGABIBAwABAAAAAQAAABoBBQABAAAAVgAAABsBBQABAAAAXgAAACgBAwABAAAAAgAAADEBAgARAAAAZgAAAGmHBAABAAAAeAAAAAAAAAABAAAAAQAAAAEAAAABAAAAcGFpbnQubmV0IDQuMy4xMgAABQAAkAcABAAAADAyMzABoAMAAQAAAAEAAAACoAQAAQAAAAEAAAADoAQAAQAAAAEAAAAFoAQAAQAAALoAAAAAAAAAAgABAAIABAAAAFI5OAACAAcABAAAADAxMDAAAAAAEgAKBxgABpgIaA0yCxJABBEAEADG1FkX';
|
||||
|
||||
/**
|
||||
* It creates a new image element, sets the source to a base64 encoded AVIF image, and then resolves
|
||||
* true if the image loads successfully, or false if it doesn't
|
||||
*/
|
||||
export const supportsAVIF = () => {
|
||||
new Promise((resolve) => {
|
||||
const image = new Image();
|
||||
|
||||
@@ -4,6 +4,11 @@ import setRgba from './setRgba';
|
||||
const hexRegexp = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)|(^#{0,1}[0-9A-F]{8}$)/i;
|
||||
const regexp = /([0-9A-F])([0-9A-F])([0-9A-F])/i;
|
||||
|
||||
/**
|
||||
* It takes a hex color code and returns an object with the color's RGB and HSV values
|
||||
* @param value - The hex value to convert to RGB.
|
||||
* @returns An object with the properties red, green, blue, alpha, hue, saturation, and value.
|
||||
*/
|
||||
export default function hexToRgb(value) {
|
||||
const valid = hexRegexp.test(value);
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* It takes three numbers, converts them to hexadecimal, and returns a string of the three hexadecimal
|
||||
* numbers concatenated together
|
||||
* @param red - The red value of the color (0-255)
|
||||
* @param green - 0
|
||||
* @param blue - 0
|
||||
* @returns a string of the hexadecimal value of the rgb values passed in.
|
||||
*/
|
||||
export default function rgbToHex(red, green, blue) {
|
||||
let r16 = red.toString(16);
|
||||
let g16 = green.toString(16);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* It converts RGB values to HSV values
|
||||
* @returns An object with the hue, saturation, and value of the color.
|
||||
* @param red - The red value of the color.
|
||||
* @param green - 0-255
|
||||
* @param blue - The blue value of the color.
|
||||
*/
|
||||
export default function rgbToHSv({ red, green, blue }) {
|
||||
let rr, gg, bb, h, s;
|
||||
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
/**
|
||||
* It returns true if the value is a number, not NaN, and between 0 and 255.
|
||||
* @param value - The value to check.
|
||||
* @returns A function that takes a value and returns a boolean.
|
||||
*/
|
||||
const isValidRGBValue = (value) => {
|
||||
return typeof value === 'number' && Number.isNaN(value) === false && value >= 0 && value <= 255;
|
||||
};
|
||||
|
||||
/**
|
||||
* "If the red, green, and blue values are valid, return an object with the red, green, and blue
|
||||
* values, and if the alpha value is valid, add it to the object."
|
||||
*
|
||||
* The function is a bit more complicated than that, but that's the gist of it
|
||||
* @param red - The red value of the color.
|
||||
* @param green - 0-255
|
||||
* @param blue - The blue value of the color.
|
||||
* @param alpha - The alpha value of the color.
|
||||
* @returns An object with the properties red, green, blue, and alpha.
|
||||
*/
|
||||
export default function setRGBA(red, green, blue, alpha) {
|
||||
if (isValidRGBValue(red) && isValidRGBValue(green) && isValidRGBValue(blue)) {
|
||||
const color = {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// since there is so much code in the component, we have moved it to a separate file
|
||||
import offlineImages from './offlineImages.json';
|
||||
|
||||
/**
|
||||
* If the URL starts with `data:video/` or ends with `.mp4`, `.webm`, or `.ogg`, then it's a video.
|
||||
* @param url - The URL of the file to be checked.
|
||||
* @returns A function that takes a url and returns a boolean.
|
||||
*/
|
||||
export function videoCheck(url) {
|
||||
return (
|
||||
url.startsWith('data:video/') ||
|
||||
@@ -10,8 +15,19 @@ export function videoCheck(url) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets a random photographer from the offlineImages.json file, then gets a random image from that
|
||||
* photographer, and returns an object with the image's URL, type, and photoInfo.
|
||||
* </code>
|
||||
* @param type - 'background' or 'thumbnail'
|
||||
* @returns An object with the following properties:
|
||||
* url: A string that is the path to the image.
|
||||
* type: A string that is the type of image.
|
||||
* photoInfo: An object with the following properties:
|
||||
* offline: A boolean that is true.
|
||||
* credit: A string that is the name of the photographer.
|
||||
*/
|
||||
export function offlineBackground(type) {
|
||||
// Get all photographers from the keys in offlineImages.json
|
||||
const photographers = Object.keys(offlineImages);
|
||||
const photographer = photographers[Math.floor(Math.random() * photographers.length)];
|
||||
|
||||
@@ -33,6 +49,10 @@ export function offlineBackground(type) {
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a gradient object and returns a style object
|
||||
* @returns An object with two properties: type and style.
|
||||
*/
|
||||
function gradientStyleBuilder({ type, angle, gradient }) {
|
||||
// Note: Append the gradient for additional browser support.
|
||||
const steps = gradient?.map((v) => `${v.colour} ${v.stop}%`);
|
||||
@@ -44,6 +64,10 @@ function gradientStyleBuilder({ type, angle, gradient }) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets the gradient settings from localStorage, parses it, and returns the gradient style.
|
||||
* @returns A string.
|
||||
*/
|
||||
export function getGradient() {
|
||||
const customBackgroundColour = localStorage.getItem('customBackgroundColour') || {
|
||||
angle: '180',
|
||||
@@ -72,6 +96,11 @@ export function getGradient() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns a random colour or random gradient as a style object
|
||||
* @param type - The type of the style. This is used to determine which style builder to use.
|
||||
* @returns An object with two properties: type and style.
|
||||
*/
|
||||
export function randomColourStyleBuilder(type) {
|
||||
// randomColour based on https://stackoverflow.com/a/5092872
|
||||
const randomColour = () =>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* If the number is between 3 and 20, return the number with the suffix "th". Otherwise, return the
|
||||
* number with the suffix "st", "nd", "rd", or "th" depending on the last digit of the number
|
||||
* @param d - The day of the month.
|
||||
* @returns the day of the month with the appropriate suffix.
|
||||
*/
|
||||
export function nth(d) {
|
||||
if (d > 3 && d < 21) {
|
||||
return d + 'th';
|
||||
@@ -15,6 +21,12 @@ export function nth(d) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a date and a timezone and returns a new date object with the timezone applied.
|
||||
* @param date - The date you want to convert.
|
||||
* @param tz - The timezone you want to convert to.
|
||||
* @returns A new Date object with the timezone set to the timezone passed in.
|
||||
*/
|
||||
export function convertTimezone(date, tz) {
|
||||
return new Date(
|
||||
(typeof date === 'string' ? new Date(date) : date).toLocaleString('en-US', {
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
// one day it might be a good idea to replace all this with redux, but it'd take
|
||||
// a lot of rewriting
|
||||
export default class EventBus {
|
||||
static listeners = {};
|
||||
|
||||
/**
|
||||
* The on function adds an event listener to the document, and then pushes the callback function into
|
||||
* the listeners array.
|
||||
* @param event - The event name
|
||||
* @param callback - The function to be called when the event is triggered.
|
||||
*/
|
||||
static on(event, callback) {
|
||||
document.addEventListener(event, (e) => {
|
||||
callback(e.detail);
|
||||
});
|
||||
if (!this.listeners[event]) {
|
||||
this.listeners[event] = [];
|
||||
}
|
||||
this.listeners[event].push(callback);
|
||||
}
|
||||
|
||||
static dispatch(event, data) {
|
||||
/**
|
||||
* It creates a new custom event, and dispatches it
|
||||
* @param event - The name of the event you want to emit.
|
||||
* @param data - The data you want to pass to the event.
|
||||
*/
|
||||
static emit(event, data) {
|
||||
document.dispatchEvent(
|
||||
new CustomEvent(event, {
|
||||
detail: data,
|
||||
@@ -15,7 +30,107 @@ export default class EventBus {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* It removes an event listener from the document and removes the callback from the listeners array
|
||||
* @param event - The event to listen for.
|
||||
* @param callback - The function to be called when the event is triggered.
|
||||
*/
|
||||
static off(event, callback) {
|
||||
document.removeEventListener(event, callback);
|
||||
if (this.listeners[event]) {
|
||||
this.listeners[event] = this.listeners[event].filter((listener) => listener !== callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The once function takes an event and a callback, and then adds a listener to the event that calls
|
||||
* the callback with the event's detail, and then removes the listener.
|
||||
* @param event - The event name
|
||||
* @param callback - The function to be called when the event is triggered.
|
||||
*/
|
||||
static once(event, callback) {
|
||||
const listener = (e) => {
|
||||
callback(e.detail);
|
||||
this.off(event, listener);
|
||||
};
|
||||
document.addEventListener(event, listener);
|
||||
if (!this.listeners[event]) {
|
||||
this.listeners[event] = [];
|
||||
}
|
||||
this.listeners[event].push({ callback, listener });
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds a listener to the beginning of the event listener queue.
|
||||
* @param event - The name of the event to listen for.
|
||||
* @param callback - The function to be called when the event is triggered.
|
||||
*/
|
||||
static prepend(event, callback) {
|
||||
const listener = (e) => {
|
||||
callback(e.detail);
|
||||
};
|
||||
document.addEventListener(
|
||||
event,
|
||||
listener,
|
||||
true, // set `useCapture` to `true` to insert the listener at the beginning
|
||||
);
|
||||
if (!this.listeners[event]) {
|
||||
this.listeners[event] = [];
|
||||
}
|
||||
this.listeners[event].unshift({ callback, listener });
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds an event listener to the document that will be called before any other event listeners for
|
||||
* the same event
|
||||
* @param event - The name of the event to listen for.
|
||||
* @param callback - The function to be called when the event is triggered.
|
||||
*/
|
||||
static prependOnce(event, callback) {
|
||||
const listener = (e) => {
|
||||
callback(e.detail);
|
||||
this.off(event, listener);
|
||||
};
|
||||
document.addEventListener(
|
||||
event,
|
||||
listener,
|
||||
true, // set `useCapture` to `true` to insert the listener at the beginning
|
||||
);
|
||||
if (!this.listeners[event]) {
|
||||
this.listeners[event] = [];
|
||||
}
|
||||
this.listeners[event].unshift({ callback, listener });
|
||||
}
|
||||
|
||||
/**
|
||||
* If the event exists, return the listeners for that event, otherwise return an empty array.
|
||||
* @param event - The event name.
|
||||
* @returns An array of listeners for the event.
|
||||
*/
|
||||
static getListeners(event) {
|
||||
if (this.listeners[event]) {
|
||||
return this.listeners[event];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array of all the event names that have listeners attached to them.
|
||||
* @returns An array of the keys of the listeners object.
|
||||
*/
|
||||
static eventNames() {
|
||||
return Object.keys(this.listeners);
|
||||
}
|
||||
|
||||
/**
|
||||
* It removes all event listeners from the document.
|
||||
*/
|
||||
static removeAllListeners() {
|
||||
Object.keys(this.listeners).forEach((event) => {
|
||||
this.listeners[event].forEach(({ listener }) => {
|
||||
document.removeEventListener(event, listener);
|
||||
});
|
||||
});
|
||||
this.listeners = {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export function install(type, input, sideload) {
|
||||
}
|
||||
localStorage.setItem('backgroundType', 'photo_pack');
|
||||
localStorage.removeItem('backgroundchange');
|
||||
EventBus.dispatch('refresh', 'background');
|
||||
EventBus.emit('refresh', 'background');
|
||||
// TODO: make this legitimately good and work without a reload - currently we just refresh
|
||||
sleep(4000);
|
||||
window.location.reload();
|
||||
@@ -66,7 +66,7 @@ export function install(type, input, sideload) {
|
||||
}
|
||||
localStorage.setItem('quoteType', 'quote_pack');
|
||||
localStorage.removeItem('quotechange');
|
||||
EventBus.dispatch('refresh', 'quote');
|
||||
EventBus.emit('refresh', 'quote');
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -121,7 +121,7 @@ export function uninstall(type, name) {
|
||||
localStorage.removeItem('quote_packs');
|
||||
}
|
||||
localStorage.removeItem('quotechange');
|
||||
EventBus.dispatch('refresh', 'marketplacequoteuninstall');
|
||||
EventBus.emit('refresh', 'marketplacequoteuninstall');
|
||||
break;
|
||||
|
||||
case 'photos':
|
||||
@@ -142,7 +142,7 @@ export function uninstall(type, name) {
|
||||
localStorage.removeItem('photo_packs');
|
||||
}
|
||||
localStorage.removeItem('backgroundchange');
|
||||
EventBus.dispatch('refresh', 'marketplacebackgrounduninstall');
|
||||
EventBus.emit('refresh', 'marketplacebackgrounduninstall');
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -4,6 +4,10 @@ import experimentalInit from '../experimental';
|
||||
import defaultSettings from 'modules/default_settings.json';
|
||||
import languages from 'modules/languages.json';
|
||||
|
||||
/**
|
||||
* It sets the default settings for the extension
|
||||
* @param reset - boolean
|
||||
*/
|
||||
export function setDefaultSettings(reset) {
|
||||
localStorage.clear();
|
||||
defaultSettings.forEach((element) => localStorage.setItem(element.name, element.value));
|
||||
@@ -31,6 +35,10 @@ export function setDefaultSettings(reset) {
|
||||
localStorage.setItem('firstRun', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* It loads the settings from localStorage and applies them to the page.
|
||||
* @param hotreload - boolean
|
||||
*/
|
||||
export function loadSettings(hotreload) {
|
||||
switch (localStorage.getItem('theme')) {
|
||||
case 'dark':
|
||||
@@ -157,8 +165,11 @@ export function loadSettings(hotreload) {
|
||||
`);
|
||||
}
|
||||
|
||||
// in a nutshell, this function saves all of the current settings, resets them, sets the defaults and then overrides
|
||||
// the new settings with the old saved messages where they exist
|
||||
/**
|
||||
* Saves all of the current settings, resets them, sets the defaults and then overrides
|
||||
* the new settings with the old saved messages where they exist.
|
||||
* @returns the result of the setDefaultSettings() function.
|
||||
*/
|
||||
export function moveSettings() {
|
||||
const currentSettings = Object.keys(localStorage);
|
||||
if (currentSettings.length === 0) {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import variables from 'modules/variables';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
/**
|
||||
* It creates a link to a file, and then clicks it
|
||||
* @param data - the data you want to save
|
||||
* @param [filename=file] - the name of the file to be saved
|
||||
* @param [type=text/json] - the type of file you want to save.
|
||||
*/
|
||||
export function saveFile(data, filename = 'file', type = 'text/json') {
|
||||
if (typeof data === 'object') {
|
||||
data = JSON.stringify(data, undefined, 4);
|
||||
@@ -36,6 +42,9 @@ export function saveFile(data, filename = 'file', type = 'text/json') {
|
||||
a.dispatchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes all the settings from localStorage and saves them to a file
|
||||
*/
|
||||
export function exportSettings() {
|
||||
const settings = {};
|
||||
|
||||
@@ -49,6 +58,11 @@ export function exportSettings() {
|
||||
variables.stats.postEvent('tab', 'Settings exported');
|
||||
}
|
||||
|
||||
/**
|
||||
* It takes a JSON file of Mue settings, parses it, and then sets the localStorage values to the values in the
|
||||
* file.
|
||||
* @param e - The JSON settings string to import
|
||||
*/
|
||||
export function importSettings(e) {
|
||||
const content = JSON.parse(e);
|
||||
|
||||
@@ -60,6 +74,11 @@ export function importSettings(e) {
|
||||
variables.stats.postEvent('tab', 'Settings imported');
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns an array of objects with a value and label property for the Mue sliders.
|
||||
* @param type - The type of slider you want to use.
|
||||
* @returns An object with keys of either zoom, toast, background or experimental.
|
||||
*/
|
||||
export function values(type) {
|
||||
const marks = {
|
||||
zoom: [
|
||||
@@ -98,5 +117,5 @@ export function values(type) {
|
||||
],
|
||||
};
|
||||
|
||||
return marks[type];
|
||||
return marks[type] || [];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
export default class Stats {
|
||||
/**
|
||||
* It takes two arguments, a type and a name, and then it increments the value of the name in the type
|
||||
* object in localStorage
|
||||
* @param type - The type of event you want to track. This can be anything you want, but I recommend
|
||||
* using something like "click" or "hover"
|
||||
* @param name - The name of the event.
|
||||
*/
|
||||
static async postEvent(type, name) {
|
||||
const value = name.toLowerCase().replaceAll(' ', '-');
|
||||
|
||||
@@ -19,6 +26,9 @@ export default class Stats {
|
||||
localStorage.setItem('statsData', JSON.stringify(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* It increments the value of the key 'tabs-opened' in the object stored in localStorage by 1.
|
||||
*/
|
||||
static async tabLoad() {
|
||||
const data = JSON.parse(localStorage.getItem('statsData'));
|
||||
data['tabs-opened'] = data['tabs-opened'] + 1 || 1;
|
||||
|
||||
@@ -1,34 +1,26 @@
|
||||
import I18n from '@eartharoid/i18n';
|
||||
|
||||
import * as de_DE from '../translations/de_DE.json';
|
||||
import * as en_GB from '../translations/en_GB.json';
|
||||
import * as en_US from '../translations/en_US.json';
|
||||
import * as es from '../translations/es.json';
|
||||
import * as es_419 from '../translations/es_419.json';
|
||||
import * as fr from '../translations/fr.json';
|
||||
import * as nl from '../translations/nl.json';
|
||||
import * as no from '../translations/no.json';
|
||||
import * as ru from '../translations/ru.json';
|
||||
import * as zh_CN from '../translations/zh_CN.json';
|
||||
import * as id_ID from '../translations/id_ID.json';
|
||||
import * as tr_TR from '../translations/tr_TR.json';
|
||||
import * as pt_BR from '../translations/pt_BR.json';
|
||||
|
||||
/**
|
||||
* Initialise the i18n object.
|
||||
* The i18n object is then returned.
|
||||
* @param locale - The locale to use.
|
||||
* @returns The i18n object.
|
||||
*/
|
||||
export default function initTranslations(locale) {
|
||||
const i18n = new I18n(locale, {
|
||||
de_DE,
|
||||
en_GB,
|
||||
en_US,
|
||||
es,
|
||||
es_419,
|
||||
fr,
|
||||
nl,
|
||||
no,
|
||||
ru,
|
||||
zh_CN,
|
||||
id_ID,
|
||||
tr_TR,
|
||||
pt_BR,
|
||||
de_DE: import('../translations/de_DE.json'),
|
||||
en_GB: import('../translations/en_GB.json'),
|
||||
en_US: import('../translations/en_US.json'),
|
||||
es: import('../translations/es.json'),
|
||||
es_419: import('../translations/es_419.json'),
|
||||
fr: import('../translations/fr.json'),
|
||||
nl: import('../translations/nl.json'),
|
||||
no: import('../translations/no.json'),
|
||||
ru: import('../translations/ru.json'),
|
||||
zh_CN: import('../translations/zh_CN.json'),
|
||||
id_ID: import('../translations/id_ID.json'),
|
||||
tr_TR: import('../translations/tr_TR.json'),
|
||||
pt_BR: import('../translations/pt_BR.json'),
|
||||
});
|
||||
|
||||
return i18n;
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import * as constants from 'modules/constants';
|
||||
import Stats from 'modules/helpers/stats';
|
||||
|
||||
const variables = {
|
||||
language: {},
|
||||
languagecode: '',
|
||||
stats: {
|
||||
tabLoad: () => '',
|
||||
postEvent: () => '',
|
||||
},
|
||||
stats: Stats,
|
||||
constants,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user