Upgrade web assets (#219)

* Update assets

* Upgrade linting and other improvments

* Correct linting

* Correction and type check improvements

* Correct type check lib

* Fix lint pathing for VSCode

* Remove duplicate babel config

* Remove editorconfig root attribute from web subdir

* Use double quotes around message

* Simplify ESLint config

* Update web assets

* Allow AMD loader in WebPack

* Bump web dependencies

* Only include FA icons in-use
This commit is contained in:
Tyler Vigario
2020-11-25 06:08:12 -08:00
committed by GitHub
parent c79d4cf977
commit ff5b1cb1ee
17 changed files with 8517 additions and 5744 deletions

42
web/js/lib/text.mjs Normal file
View File

@ -0,0 +1,42 @@
import {validateString, validateNumber} from './type.mjs';
/**
* Truncate string length by characters.
*
* @param {string} text String to format.
* @param {number} limit Maximum number of characters in resulting string.
* @param {string} ending Ending to use if string is trucated.
*
* @returns {string} Formatted string.
*/
export function limitChars(text, limit = 50, ending = '...') {
validateString(text);
validateNumber(limit);
validateString(ending);
// Check if string is already below limit
if (text.length <= limit) {
return text;
}
// Limit string length by characters
return text.substring(0, limit - ending.length) + ending;
}
/**
* Truncate string length by words.
*
* @param {string} text String to format.
* @param {number} limit Maximum number of words in resulting string.
* @param {string} ending Ending to use if string is trucated.
*
* @returns {string} Formatted string.
*/
export function limitWords(text, limit = 10, ending = '...') {
validateString(text);
validateNumber(limit);
validateString(ending);
// Limit string length by words
return text.split(' ').splice(0, limit).join(' ') + ending;
}

42
web/js/lib/theme.mjs Normal file
View File

@ -0,0 +1,42 @@
export default class {
/**
* @property {boolean} dark Interal state for dark theme activation.
* @private
*/
static #dark = false;
/**
* Inialize the theme class.
*/
static init() {
// Check LocalStorage for dark theme selection
if (localStorage.getItem('darkTheme') === 'true') {
// Update page theme
this.set(true);
}
}
/**
* Set page theme and update local storage variable.
*
* @param {boolean} dark Whether to activate dark theme.
*/
static set(dark = false) {
// Swap CSS to selected theme
document.getElementById('pagestyle')
.setAttribute('href', 'static/css/' + (dark ? 'dark' : 'main') + '.css');
// Update local storage
localStorage.setItem('darkTheme', dark);
// Update internal state
this.#dark = dark;
}
/**
* Swap page theme.
*/
static swap() {
this.set(!this.#dark);
}
}

65
web/js/lib/type.mjs Normal file
View File

@ -0,0 +1,65 @@
/**
* Checks if `value` is the type `Object` excluding `Function` and `null`
*
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, otherwise `false`.
*/
export function isObject(value) {
return (Object.prototype.toString.call(value) === '[object Object]');
}
/**
* Checks if `value` is the type `string`
*
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a string, otherwise `false`.
*/
export function isString(value) {
return (typeof value === 'string');
}
/**
* Checks if `value` is the type `number`
*
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a number, otherwise `false`.
*/
export function isNumber(value) {
return (typeof value === 'number');
}
/**
* Validate parameter is of type object.
*
* @param {string} value Variable to validate.
* @throws Error if not an object.
*/
export function validateObject(value) {
if (!isObject(value)) {
throw new TypeError('Parameter "value" must be of type object.');
}
}
/**
* Validate parameter is of type string.
*
* @param {string} value Variable to validate.
* @throws Error if not an string.
*/
export function validateString(value) {
if (!isString(value)) {
throw new TypeError('Parameter "value" must be of type string.');
}
}
/**
* Validate parameter is of type number.
*
* @param {number} value Variable to validate.
* @throws Error if not an number.
*/
export function validateNumber(value) {
if (!isNumber(value)) {
throw new TypeError('Parameter "value" must be of type number.');
}
}

55
web/js/lib/util.mjs Normal file
View File

@ -0,0 +1,55 @@
export function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
export function hash(string) {
if (typeof string != 'string') return 0;
let hash = 0;
if (string.length === 0) {
return hash;
}
for (let i = 0; i < string.length; i++) {
const char = string.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
export function getColor(string) {
const num = hash(string) % 8;
switch (num) {
case 0:
return 'primary';
case 1:
return 'secondary';
case 2:
return 'success';
case 3:
return 'danger';
case 4:
return 'warning';
case 5:
return 'info';
case 6:
return 'light';
case 7:
return 'dark';
}
}
export function setProgressBar(bar, progress, text = '') {
const progPos = (-1 * (1 - progress) * bar.scrollWidth).toString();
const progStr = (progress * 100).toString();
bar.setAttribute('aria-valuenow', progStr);
bar.style.transform = 'translateX(' + progPos + 'px)';
bar.textContent = text;
}
export function secondsToStr(seconds) {
seconds = Math.floor(seconds);
const mins = Math.floor(seconds / 60);
const secs = seconds % 60;
return ('00' + mins).slice(-2) + ':' + ('00' + secs).slice(-2);
}