refactor Utils package
This commit is contained in:
@@ -0,0 +1,114 @@
|
|||||||
|
const epsilon = 0.1;
|
||||||
|
|
||||||
|
const Utils = {
|
||||||
|
blobToBase64: blob => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
return new Promise(resolve => {
|
||||||
|
reader.onloadend = () => {
|
||||||
|
resolve(reader.result);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
adjustMinMax(r){
|
||||||
|
return {
|
||||||
|
x1: Math.min(r.x1, r.x2), x2: Math.max(r.x1, r.x2),
|
||||||
|
y1: Math.min(r.y1, r.y2), y2: Math.max(r.y1, r.y2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
intersectPointRect(p, r){
|
||||||
|
//r = this.adjustMinMax(r);
|
||||||
|
return p[0] >= r.x1 && p[0] <= r.x2 && p[1] >= r.y1 && p[1] <= r.y2;
|
||||||
|
},
|
||||||
|
|
||||||
|
intersectPointLine(p, l){
|
||||||
|
//l = this.adjustMinMax(l);
|
||||||
|
let dx = l.x2 - l.x1, dy = l.y2 - l.y1;
|
||||||
|
let c = dy / dx;
|
||||||
|
return this.intersectPointRect(p, l) && c * p[0] - p[1] <= epsilon
|
||||||
|
},
|
||||||
|
|
||||||
|
intersectLineRect(l, r){
|
||||||
|
return this.intersectPointRect([l.x1, l.y1], r) ||
|
||||||
|
this.intersectPointRect([l.x2, l.y2], r);
|
||||||
|
},
|
||||||
|
|
||||||
|
intersectRectRect(r1, r2){
|
||||||
|
return this.intersectPointRect([r1.x1, r1.y1], r2) ||
|
||||||
|
this.intersectPointRect([r1.x1, r1.y2], r2) ||
|
||||||
|
this.intersectPointRect([r1.x2, r1.y1], r2) ||
|
||||||
|
this.intersectPointRect([r1.x2, r1.y2], r2);
|
||||||
|
},
|
||||||
|
|
||||||
|
round(n, p = 2){
|
||||||
|
let pp = Math.pow(10, p);
|
||||||
|
return Math.round(n*pp)/pp;
|
||||||
|
},
|
||||||
|
|
||||||
|
deg2rad(deg){
|
||||||
|
return deg * (Math.PI / 180);
|
||||||
|
},
|
||||||
|
|
||||||
|
rad2deg(rad){
|
||||||
|
return rad * 180 / Math.PI;
|
||||||
|
},
|
||||||
|
|
||||||
|
shuffleArray(arr){
|
||||||
|
return arr.map(value => ({ value, sort: Math.random() }))
|
||||||
|
.sort((a, b) => a.sort - b.sort).map(({ value }) => value)
|
||||||
|
},
|
||||||
|
|
||||||
|
deepMerge(target, source, transformFn) {
|
||||||
|
Object.entries(source).forEach(([key, value]) => {
|
||||||
|
if (transformFn){
|
||||||
|
value = transformFn(key, value)
|
||||||
|
}
|
||||||
|
if (value && typeof value === 'object') {
|
||||||
|
let dflt = Array.isArray(value) ? [] : {};
|
||||||
|
this.deepMerge(target[key] = target[key] || dflt, value, transformFn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target[key] = value;
|
||||||
|
});
|
||||||
|
return target;
|
||||||
|
},
|
||||||
|
|
||||||
|
drawOnCanvas(svg, width, height){
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
let url = URL.createObjectURL(new Blob([svg],{ type:"image/svg+xml;charset=utf-8" }));
|
||||||
|
let img = new Image();
|
||||||
|
let canvas = document.createElement('canvas');
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
img.addEventListener('load', function () {
|
||||||
|
ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
resolve(canvas);
|
||||||
|
}, { once: true })
|
||||||
|
|
||||||
|
img.src = url;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
async wait(ms){
|
||||||
|
await new Promise((resolve, reject)=>{
|
||||||
|
setTimeout(resolve, ms)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
async waitFor(expFn){
|
||||||
|
while (!expFn()){
|
||||||
|
await Utils.wait(200);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
escapeRegExp(string) {
|
||||||
|
return string && string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Utils;
|
||||||
@@ -5,6 +5,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import { Strategy as LocalStrategy } from 'passport-local';
|
import { Strategy as LocalStrategy } from 'passport-local';
|
||||||
import { Strategy as FacebookStrategy } from 'passport-facebook';
|
import { Strategy as FacebookStrategy } from 'passport-facebook';
|
||||||
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
|
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
|
||||||
|
import Utils from '../Utils.js';
|
||||||
|
|
||||||
const collection = 'users';
|
const collection = 'users';
|
||||||
const emailRegexp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
const emailRegexp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
||||||
@@ -31,16 +32,16 @@ class UserManager {
|
|||||||
|
|
||||||
passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' },
|
passport.use(new LocalStrategy({ usernameField: 'email', passwordField: 'password' },
|
||||||
async function (email, password, done) {
|
async function (email, password, done) {
|
||||||
let user = await db.get(collection, { email: { $regex: `^${global.JsUtils.escapeRegExp(email)}$`, $options: 'i' } });
|
let user = await db.get(collection, { email: { $regex: `^${Utils.escapeRegExp(email)}$`, $options: 'i' } });
|
||||||
if (user) {
|
if (user) {
|
||||||
if (md5(md5(password) + config.am.salt) == user.password) {
|
if (md5(md5(password) + config.am.salt) == user.password) {
|
||||||
return done(null, am.getUserProfile(user));
|
return done(null, am.getUserProfile(user));
|
||||||
} else {
|
} else {
|
||||||
await global.JsUtils.wait(3000);
|
await Utils.wait(3000);
|
||||||
return done(null, false, { message: 'invalidPassword' });
|
return done(null, false, { message: 'invalidPassword' });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await global.JsUtils.wait(3000);
|
await Utils.wait(3000);
|
||||||
return done(null, false, { message: 'invalidUsername' });
|
return done(null, false, { message: 'invalidUsername' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +131,7 @@ class UserManager {
|
|||||||
if (!emailRegexp.test(data.email)) {
|
if (!emailRegexp.test(data.email)) {
|
||||||
return reject(new Error('invalidEmail'));
|
return reject(new Error('invalidEmail'));
|
||||||
}
|
}
|
||||||
let exists = await db.get(collection, { email: { $regex: `^${global.JsUtils.escapeRegExp(data.email)}$`, $options: 'i' } });
|
let exists = await db.get(collection, { email: { $regex: `^${Utils.escapeRegExp(data.email)}$`, $options: 'i' } });
|
||||||
if (exists) {
|
if (exists) {
|
||||||
return reject(new Error('emailExists'))
|
return reject(new Error('emailExists'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import svgCaptcha from 'svg-captcha';
|
import svgCaptcha from 'svg-captcha';
|
||||||
|
import Utils from '../../app/Utils.js';
|
||||||
|
|
||||||
const collection = 'users';
|
const collection = 'users';
|
||||||
|
|
||||||
@@ -138,7 +139,7 @@ class UsersController {
|
|||||||
limit: req.body.limit || 12, skip: req.body.skip || 0
|
limit: req.body.limit || 12, skip: req.body.skip || 0
|
||||||
};
|
};
|
||||||
if (req.body.email) {
|
if (req.body.email) {
|
||||||
q.query.email = { $regex: global.JsUtils.escapeRegExp(req.body.email), $options: 'i' }
|
q.query.email = { $regex: Utils.escapeRegExp(req.body.email), $options: 'i' }
|
||||||
}
|
}
|
||||||
let list = await db.list(collection, q);
|
let list = await db.list(collection, q);
|
||||||
res.json(list);
|
res.json(list);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { MazeObject } from "./MazeObject";
|
import { MazeObject } from "./MazeObject";
|
||||||
import Utils from "@/lib/Utils";
|
import Utils from "#/app/Utils";
|
||||||
import { EventManager } from '@/lib/EventManager';
|
import { EventManager } from '@/lib/EventManager';
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { BoxGeometry, Mesh, MeshStandardMaterial, Group, Vector3, CatmullRomCurv
|
|||||||
import { LineMaterial, LineGeometry, Line2 } from 'three/examples/jsm/Addons.js';
|
import { LineMaterial, LineGeometry, Line2 } from 'three/examples/jsm/Addons.js';
|
||||||
import { centerOrigin } from '@/lib/MeshUtils';
|
import { centerOrigin } from '@/lib/MeshUtils';
|
||||||
import { EventManager } from '@/lib/EventManager';
|
import { EventManager } from '@/lib/EventManager';
|
||||||
import Utils from '@/lib/Utils';
|
import Utils from '#/app/Utils';
|
||||||
|
|
||||||
class PairMatchingGame extends EventManager {
|
class PairMatchingGame extends EventManager {
|
||||||
emits = ['finish', 'interaction']
|
emits = ['finish', 'interaction']
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Group, Color } from 'three';
|
|||||||
import { centerOrigin } from '@/lib/MeshUtils';
|
import { centerOrigin } from '@/lib/MeshUtils';
|
||||||
import { EventManager } from '@/lib/EventManager';
|
import { EventManager } from '@/lib/EventManager';
|
||||||
import { TextObject } from './TextObject';
|
import { TextObject } from './TextObject';
|
||||||
import Utils from '@/lib/Utils';
|
import Utils from '#/app/Utils';
|
||||||
|
|
||||||
class SingleQuestion extends EventManager {
|
class SingleQuestion extends EventManager {
|
||||||
emits = ['finish']
|
emits = ['finish']
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SvgIcon from './SvgIcon.vue';
|
import SvgIcon from './SvgIcon.vue';
|
||||||
import Utils from '@/lib/Utils';
|
import Utils from '#/app/Utils';
|
||||||
import AssetSelector from '../AssetsManagement/AssetSelector.vue';
|
import AssetSelector from '../AssetsManagement/AssetSelector.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
import GameObject from './GameObject.vue';
|
import GameObject from './GameObject.vue';
|
||||||
import Scene from './Scene.vue';
|
import Scene from './Scene.vue';
|
||||||
import SvgRectangle from './SvgRectangle.vue';
|
import SvgRectangle from './SvgRectangle.vue';
|
||||||
import Utils from '@/lib/Utils';
|
import Utils from '#/app/Utils';
|
||||||
import AssetSelector from '../AssetsManagement/AssetSelector.vue';
|
import AssetSelector from '../AssetsManagement/AssetSelector.vue';
|
||||||
import Task from './Task.vue';
|
import Task from './Task.vue';
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import AnnotationPoint from './AnnotationPoint.vue';
|
import AnnotationPoint from './AnnotationPoint.vue';
|
||||||
import Utils from '@/lib/Utils';
|
import Utils from '#/app/Utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { AnnotationPoint },
|
components: { AnnotationPoint },
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SvgIcon from './SvgIcon.vue';
|
import SvgIcon from './SvgIcon.vue';
|
||||||
import Utils from '@/lib/Utils';
|
import Utils from '#/app/Utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits:['target', 'preview'],
|
emits:['target', 'preview'],
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
|
|
||||||
import { Text } from "troika-three-text";
|
import { Text } from "troika-three-text";
|
||||||
import { EventManager } from "./EventManager";
|
import { EventManager } from "./EventManager";
|
||||||
import Utils from "./Utils";
|
import Utils from "#/app/Utils";
|
||||||
class DashBoard extends EventManager {
|
class DashBoard extends EventManager {
|
||||||
#points = 0;
|
#points = 0;
|
||||||
constructor(engine) {
|
constructor(engine) {
|
||||||
|
|||||||
+2
-1
@@ -54,7 +54,8 @@ export default defineConfig({
|
|||||||
define: { 'process.env': {} },
|
define: { 'process.env': {} },
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||||
|
'#': fileURLToPath(new URL('./backend', import.meta.url))
|
||||||
},
|
},
|
||||||
extensions: [
|
extensions: [
|
||||||
'.js',
|
'.js',
|
||||||
|
|||||||
Reference in New Issue
Block a user