upload, string extensions, lgres
This commit is contained in:
@ -1,10 +1,20 @@
|
||||
import { getCookie, setCookie, deleteCookie } from "./utility/cookie";
|
||||
import { get, post } from "./utility/request";
|
||||
import { init, r, lang } from "./utility/lgres";
|
||||
import { get, post, upload } from "./utility/request";
|
||||
import { nullOrEmpty, contains, endsWith, padStart } from "./utility/strings";
|
||||
|
||||
export {
|
||||
getCookie,
|
||||
setCookie,
|
||||
deleteCookie,
|
||||
init,
|
||||
r,
|
||||
lang,
|
||||
get,
|
||||
post
|
||||
post,
|
||||
upload,
|
||||
nullOrEmpty,
|
||||
contains,
|
||||
endsWith,
|
||||
padStart
|
||||
}
|
7
lib/utility/lgres.d.ts
vendored
Normal file
7
lib/utility/lgres.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export function init(dom?: HTMLElement, ahead?: | { callback?: (result: any) => void }): Promise<any>
|
||||
export function r(key: string, defaultValue?: any): any
|
||||
export const lang: {
|
||||
get current(): string,
|
||||
get unknownError(): string,
|
||||
get savedSuccessfully(): string
|
||||
}
|
167
lib/utility/lgres.js
Normal file
167
lib/utility/lgres.js
Normal file
@ -0,0 +1,167 @@
|
||||
import { getCookie } from "./cookie";
|
||||
import { get } from "./request";
|
||||
import { nullOrEmpty } from "./strings";
|
||||
|
||||
let cache;
|
||||
|
||||
function getCurrentLgId() {
|
||||
let lgid;
|
||||
if (typeof consts !== 'undefined') {
|
||||
lgid = consts.cookie != null && getCookie(consts.cookie.lang);
|
||||
if (nullOrEmpty(lgid)) {
|
||||
lgid = consts.user && consts.user.language;
|
||||
}
|
||||
}
|
||||
if (nullOrEmpty(lgid)) {
|
||||
lgid = getCookie('lgid');
|
||||
}
|
||||
if (nullOrEmpty(lgid)) {
|
||||
lgid = navigator.language || 'en-us';
|
||||
}
|
||||
lgid = lgid.toLowerCase().replace(/-/g, '_');
|
||||
if (nullOrEmpty(lgid)) {
|
||||
lgid = 'en';
|
||||
}
|
||||
switch (lgid) {
|
||||
case 'en':
|
||||
case 'en_au':
|
||||
case 'fr':
|
||||
case 'zh_cn':
|
||||
return lgid;
|
||||
}
|
||||
const lang = lgid.split('_')[0];
|
||||
switch (lang) {
|
||||
case 'en':
|
||||
case 'fr':
|
||||
return lang;
|
||||
}
|
||||
return 'en';
|
||||
}
|
||||
|
||||
function getStorageKey(lgid) {
|
||||
if (typeof consts !== 'undefined') {
|
||||
return (consts.prefix || '') + `res_${lgid}`;
|
||||
}
|
||||
return `res_${lgid}`;
|
||||
}
|
||||
|
||||
async function doRefreshLgres() {
|
||||
const lgid = getCurrentLgId();
|
||||
const r = await get(`language/${lgid}/res.json`);
|
||||
const dict = await r.json();
|
||||
localStorage.setItem(getStorageKey(lgid), JSON.stringify(dict));
|
||||
cache = dict;
|
||||
return dict;
|
||||
}
|
||||
|
||||
async function refreshLgres(lgres) {
|
||||
if (lgres == null || typeof consts === 'undefined') {
|
||||
return await doRefreshLgres();
|
||||
}
|
||||
const ver = Number(consts.resver);
|
||||
if (isNaN(lgres.ver) || isNaN(ver) || ver > lgres.ver) {
|
||||
console.log(`found new language res version: ${lgres.ver} => ${ver}`);
|
||||
return await doRefreshLgres();
|
||||
}
|
||||
cache = lgres;
|
||||
return lgres;
|
||||
}
|
||||
|
||||
function getLanguage(lgres, key, defaultValue) {
|
||||
let value = lgres[key];
|
||||
if (value == null) {
|
||||
value = defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function applyLanguage(dom, result) {
|
||||
if (dom == null) {
|
||||
dom = document.body;
|
||||
}
|
||||
for (let text of dom.querySelectorAll('[data-lgid]')) {
|
||||
const key = text.getAttribute('data-lgid');
|
||||
if (text.tagName === 'INPUT') {
|
||||
text.value = getLanguage(result, key, text.value);
|
||||
} else {
|
||||
text.innerText = getLanguage(result, key, text.innerText);
|
||||
}
|
||||
}
|
||||
for (let title of dom.querySelectorAll('[data-title-lgid]')) {
|
||||
const key = title.getAttribute('data-title-lgid');
|
||||
title.setAttribute('title', getLanguage(result, key, title.getAttribute('title')));
|
||||
}
|
||||
for (let holder of dom.querySelectorAll('[data-placeholder-lgid]')) {
|
||||
const key = holder.getAttribute('data-placeholder-lgid');
|
||||
holder.setAttribute('placeholder', getLanguage(result, key, holder.getAttribute('placeholder')));
|
||||
}
|
||||
}
|
||||
|
||||
async function init(dom, ahead) {
|
||||
const lgid = getCurrentLgId();
|
||||
let lgres = localStorage.getItem(getStorageKey(lgid));
|
||||
let result;
|
||||
if (lgres != null) {
|
||||
try {
|
||||
lgres = JSON.parse(lgres);
|
||||
result = await refreshLgres(lgres);
|
||||
} catch (e) {
|
||||
console.error('error while parsing lgres, try refresh ...', e);
|
||||
result = await refreshLgres();
|
||||
}
|
||||
} else {
|
||||
result = await refreshLgres();
|
||||
}
|
||||
|
||||
try {
|
||||
if (ahead != null) {
|
||||
// not in defer mode
|
||||
if (document.readyState === 'loading') {
|
||||
return await new Promise((resolve, reject) => {
|
||||
let tid = setTimeout(() => reject('timeout'), 30000);
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
clearTimeout(tid);
|
||||
tid = void 0;
|
||||
if (typeof ahead.callback === 'function') {
|
||||
ahead.callback(result);
|
||||
}
|
||||
applyLanguage(dom, result);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
if (typeof ahead.callback === 'function') {
|
||||
ahead.callback(result);
|
||||
}
|
||||
}
|
||||
applyLanguage(dom, result);
|
||||
return result;
|
||||
} catch (err) {
|
||||
console.error('error while loading language res ...', err);
|
||||
}
|
||||
}
|
||||
|
||||
function r(key, defaultValue) {
|
||||
if (cache != null) {
|
||||
return getLanguage(cache, key, defaultValue);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
const lang = {
|
||||
get current() {
|
||||
return getCurrentLgId();
|
||||
},
|
||||
get unknownError() {
|
||||
return r('unknownError', 'An unknown error occurred, please contact the administrator.');
|
||||
},
|
||||
get savedSuccessfully() {
|
||||
return r('savedSuccessfully', 'Saved successfully.');
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
init,
|
||||
r,
|
||||
lang
|
||||
}
|
5
lib/utility/request.d.ts
vendored
5
lib/utility/request.d.ts
vendored
@ -1,9 +1,12 @@
|
||||
interface RequestOptions {
|
||||
method?: string;
|
||||
accept?: string;
|
||||
contentType?: string;
|
||||
customerHeaders?: { [key: string]: string };
|
||||
signal?: AbortSignal | null;
|
||||
progress?: (this: XMLHttpRequestUpload, ev: ProgressEvent<XMLHttpRequestEventTarget>) => any
|
||||
}
|
||||
|
||||
export function get(url: string, options?: RequestOptions): Promise<Response>
|
||||
export function post(url: string, data?: BodyInit | null, options?: RequestOptions): Promise<Response>
|
||||
export function post(url: string, data?: BodyInit | null, options?: RequestOptions): Promise<Response>
|
||||
export function upload(url: string, data: FormData, options?: RequestOptions): Promise<Response>
|
@ -1,4 +1,7 @@
|
||||
function combineUrl(url) {
|
||||
if (/^(https?|wss?|ftp):/.test(url)) {
|
||||
return url;
|
||||
}
|
||||
if (typeof consts === 'undefined') {
|
||||
return url;
|
||||
}
|
||||
@ -11,7 +14,7 @@ function get(url, options) {
|
||||
method: options.method || 'GET',
|
||||
headers: {
|
||||
...options.customerHeaders,
|
||||
'Content-Type': options.contentType || 'application/json'
|
||||
'Accept': options.accept || 'application/json'
|
||||
},
|
||||
signal: options.signal,
|
||||
cache: 'default'
|
||||
@ -20,19 +23,62 @@ function get(url, options) {
|
||||
|
||||
function post(url, data, options) {
|
||||
options ??= {};
|
||||
// let contentType;
|
||||
if (data instanceof FormData) {
|
||||
// contentType = 'multipart/form-data';
|
||||
} else {
|
||||
if (typeof data !== 'string') {
|
||||
data = JSON.stringify(data);
|
||||
}
|
||||
// contentType = 'application/json';
|
||||
if (options.customerHeaders == null) {
|
||||
options.customerHeaders = {};
|
||||
}
|
||||
if (options.customerHeaders['Content-Type'] == null) {
|
||||
options.customerHeaders['Content-Type'] = 'application/json';
|
||||
}
|
||||
}
|
||||
return fetch(combineUrl(url), {
|
||||
method: options.method || 'POST',
|
||||
headers: {
|
||||
...options.customerHeaders,
|
||||
'Content-Type': options.contentType || 'application/json'
|
||||
},
|
||||
headers: options.customerHeaders,
|
||||
body: data,
|
||||
signal: options.signal,
|
||||
cache: 'no-cache'
|
||||
});
|
||||
}
|
||||
|
||||
function upload(url, data, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.onreadystatechange = function () {
|
||||
if (this.readyState === XMLHttpRequest.DONE) {
|
||||
if (this.status === 200) {
|
||||
resolve(this);
|
||||
} else {
|
||||
reject(`${this.status} ${this.statusText}: ${this.responseText}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
options ??= {};
|
||||
if (typeof options.progress === 'function') {
|
||||
request.upload.addEventListener('progress', function (ev) {
|
||||
if (ev.lengthComputable) {
|
||||
options.progress.call(this, ev);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
request.open('POST', combineUrl(url));
|
||||
if (options.customerHeaders != null) {
|
||||
for (let header of Object.entries(options.customerHeaders)) {
|
||||
request.setRequestHeader(header[0], header[1]);
|
||||
}
|
||||
}
|
||||
request.send(data);
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
get,
|
||||
post
|
||||
post,
|
||||
upload
|
||||
}
|
4
lib/utility/strings.d.ts
vendored
Normal file
4
lib/utility/strings.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
export function nullOrEmpty(s?: string | any | null): boolean
|
||||
export function contains(s: string, key: string | any, ignoreCase?: boolean): boolean
|
||||
export function endsWith(s: string, suffix: string): boolean
|
||||
export function padStart(s: string, num: Number, char: string): boolean
|
40
lib/utility/strings.js
Normal file
40
lib/utility/strings.js
Normal file
@ -0,0 +1,40 @@
|
||||
function nullOrEmpty(s) {
|
||||
return s == null || typeof s !== 'string' || s.length === 0;
|
||||
}
|
||||
|
||||
function contains(s, key, ignoreCase) {
|
||||
if (nullOrEmpty(s) || key == null) {
|
||||
return false;
|
||||
}
|
||||
if (typeof key !== 'string') {
|
||||
key = String(key);
|
||||
}
|
||||
if (ignoreCase) {
|
||||
return s.toLowerCase().indexOf(key.toLowerCase()) >= 0;
|
||||
}
|
||||
return s.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
function endsWith(s, suffix) {
|
||||
if (nullOrEmpty(s) || nullOrEmpty(suffix)) {
|
||||
return false;
|
||||
}
|
||||
return s.indexOf(suffix) === s.length - suffix.length;
|
||||
}
|
||||
|
||||
function padStart(s, num, char) {
|
||||
if (nullOrEmpty(s) || isNaN(num) || num <= s.length) {
|
||||
return s;
|
||||
}
|
||||
if (char == null) {
|
||||
char = ' ';
|
||||
}
|
||||
return char.repeat(num - s.length);
|
||||
}
|
||||
|
||||
export {
|
||||
nullOrEmpty,
|
||||
contains,
|
||||
endsWith,
|
||||
padStart
|
||||
}
|
Reference in New Issue
Block a user