mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-03 04:00:41 +08:00
added preset management functions
This commit is contained in:
parent
308d87d565
commit
b2b0634195
7 changed files with 266 additions and 239 deletions
|
@ -6,6 +6,11 @@ const tagSchema = new Schema({
|
|||
personalBests: { type: Schema.Types.Mixed },
|
||||
});
|
||||
|
||||
const presetSchema = new Schema({
|
||||
name: { type: String, required: true },
|
||||
config: { type: Schema.Types.Mixed }, //will be config schema after it's created
|
||||
});
|
||||
|
||||
const resultSchema = new Schema({
|
||||
wpm: { type: Number, required: true },
|
||||
rawWpm: { type: Number, required: true },
|
||||
|
@ -52,7 +57,7 @@ const userSchema = new Schema(
|
|||
zen: { type: Schema.Types.Mixed, default: {} },
|
||||
},
|
||||
name: { type: String, required: true },
|
||||
presets: [{ type: Schema.Types.Mixed, default: {} }],
|
||||
presets: [{ type: presetSchema, default: {} }],
|
||||
tags: [{ type: tagSchema, default: {} }],
|
||||
favouriteThemes: [],
|
||||
refactored: { type: Boolean, default: true },
|
||||
|
|
|
@ -500,6 +500,12 @@ async function incrementPublicTypingStats(started, completed, time) {
|
|||
*/
|
||||
}
|
||||
|
||||
function isTagPresetNameValid(name) {
|
||||
if (name === null || name === undefined || name === "") return false;
|
||||
if (name.length > 16) return false;
|
||||
return /^[0-9a-zA-Z_.-]+$/.test(name);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
app.post("/api/updateName", (req, res) => {
|
||||
|
@ -1081,6 +1087,160 @@ app.post("/api/saveConfig", authenticateToken, (req, res) => {
|
|||
}
|
||||
});
|
||||
|
||||
app.post("/api/addPreset", authenticateToken, (req, res) => {
|
||||
try {
|
||||
if (!isTagPresetNameValid(req.body.obj.name)) {
|
||||
return { resultCode: -1 };
|
||||
} else if (req.name === undefined || req.body.obj === undefined) {
|
||||
console.error(`error saving config for ${req.name} - missing input`);
|
||||
res.json({
|
||||
resultCode: -1,
|
||||
message: "Missing input",
|
||||
});
|
||||
} else {
|
||||
let config = req.body.obj.config;
|
||||
let errorMessage = "";
|
||||
let err = false;
|
||||
Object.keys(config).forEach((key) => {
|
||||
if (err) return;
|
||||
if (!isConfigKeyValid(key)) {
|
||||
err = true;
|
||||
console.error(`${key} failed regex check`);
|
||||
errorMessage = `${key} failed regex check`;
|
||||
}
|
||||
if (err) return;
|
||||
if (key === "resultFilters") return;
|
||||
if (key === "customBackground") return;
|
||||
let val = config[key];
|
||||
if (Array.isArray(val)) {
|
||||
val.forEach((valarr) => {
|
||||
if (!isConfigKeyValid(valarr)) {
|
||||
err = true;
|
||||
console.error(`${key}: ${valarr} failed regex check`);
|
||||
errorMessage = `${key}: ${valarr} failed regex check`;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!isConfigKeyValid(val)) {
|
||||
err = true;
|
||||
console.error(`${key}: ${val} failed regex check`);
|
||||
errorMessage = `${key}: ${val} failed regex check`;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (err) {
|
||||
console.error(
|
||||
`error adding preset for ${req.name} - bad input - ${JSON.stringify(
|
||||
req.body.obj
|
||||
)}`
|
||||
);
|
||||
res.json({
|
||||
resultCode: -1,
|
||||
message: "Bad input. " + errorMessage,
|
||||
});
|
||||
}
|
||||
|
||||
User.findOne({ name: req.name }, (err, user) => {
|
||||
if (user.presets.length >= 10) {
|
||||
res.json({
|
||||
resultCode: -2,
|
||||
message: "Preset limit",
|
||||
});
|
||||
} else {
|
||||
user.presets.push(req.body.obj);
|
||||
user.save();
|
||||
}
|
||||
})
|
||||
.then((updatedUser) => {
|
||||
res.json({
|
||||
resultCode: 1,
|
||||
message: "Saved",
|
||||
id: updatedUser.presets[updatedUser.presets.length - 1]._id,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error adding preset to DB for ${req.name} - ${e.message}`
|
||||
);
|
||||
res.json({
|
||||
resultCode: -1,
|
||||
message: e.message,
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`error adding preset for ${req.name} - ${e}`);
|
||||
res.json({
|
||||
resultCode: -999,
|
||||
message: e,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/editPreset", authenticateToken, (req, res) => {
|
||||
try {
|
||||
if (!isTagPresetNameValid(req.body.presetName)) {
|
||||
return { resultCode: -1 };
|
||||
} else {
|
||||
User.findOne({ name: req.name }, (err, user) => {
|
||||
for (i = 0; i < user.presets.length; i++) {
|
||||
if (user.presets[i]._id.toString() == req.body.presetid.toString()) {
|
||||
user.presets[i] = {
|
||||
config: req.body.config,
|
||||
name: req.body.presetName,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
user.save();
|
||||
})
|
||||
.then((e) => {
|
||||
console.log(
|
||||
`user ${req.name} updated a preset: ${req.body.presetName}`
|
||||
);
|
||||
res.send({
|
||||
resultCode: 1,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error while updating preset for user ${req.name}: ${e.message}`
|
||||
);
|
||||
res.send({ resultCode: -999, message: e.message });
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`error updating preset for ${request.uid} - ${e}`);
|
||||
return { resultCode: -999, message: e.message };
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/removePreset", authenticateToken, (req, res) => {
|
||||
try {
|
||||
User.findOne({ name: req.name }, (err, user) => {
|
||||
for (i = 0; i < user.presets.length; i++) {
|
||||
if (user.presets[i]._id.toString() == req.body.presetid.toString()) {
|
||||
user.presets.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
user.save();
|
||||
})
|
||||
.then((e) => {
|
||||
console.log(`user ${req.name} deleted a preset`);
|
||||
res.send({ resultCode: 1 });
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error deleting preset for user ${req.name}: ${e.message}`
|
||||
);
|
||||
res.send({ resultCode: -999 });
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`error deleting preset for ${req.name} - ${e}`);
|
||||
res.send({ resultCode: -999 });
|
||||
}
|
||||
});
|
||||
/*
|
||||
app.post("/api/checkLeaderboards", (req, res) => {
|
||||
//not sure if the allow origin and options are necessary
|
||||
|
|
|
@ -234,34 +234,6 @@ async function checkIfTagPB(uid, obj, userdata) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
exports.clearTagPb = functions.https.onCall((request, response) => {
|
||||
try {
|
||||
return db
|
||||
.collection(`users/${request.uid}/tags`)
|
||||
.doc(request.tagid)
|
||||
.update({
|
||||
pb: 0,
|
||||
})
|
||||
.then((e) => {
|
||||
return {
|
||||
resultCode: 1,
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error deleting tag pb for user ${request.uid}: ${e.message}`
|
||||
);
|
||||
return {
|
||||
resultCode: -999,
|
||||
message: e.message,
|
||||
};
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`error deleting tag pb for ${request.uid} - ${e}`);
|
||||
return { resultCode: -999 };
|
||||
}
|
||||
});
|
||||
|
||||
exports.verifyUser = functions.https.onRequest(async (request, response) => {
|
||||
response.set("Access-Control-Allow-Origin", origin);
|
||||
response.set("Access-Control-Allow-Headers", "*");
|
||||
|
@ -439,151 +411,6 @@ exports.updateResultTags = functions.https.onCall((request, response) => {
|
|||
}
|
||||
});
|
||||
|
||||
exports.addPreset = functions.https.onCall(async (request, response) => {
|
||||
try {
|
||||
if (!isTagPresetNameValid(request.obj.name)) {
|
||||
return { resultCode: -1 };
|
||||
} else if (request.uid === undefined || request.obj === undefined) {
|
||||
console.error(`error saving config for ${request.uid} - missing input`);
|
||||
return {
|
||||
resultCode: -1,
|
||||
message: "Missing input",
|
||||
};
|
||||
} else {
|
||||
let config = request.obj.config;
|
||||
let errorMessage = "";
|
||||
let err = false;
|
||||
Object.keys(config).forEach((key) => {
|
||||
if (err) return;
|
||||
if (!isConfigKeyValid(key)) {
|
||||
err = true;
|
||||
console.error(`${key} failed regex check`);
|
||||
errorMessage = `${key} failed regex check`;
|
||||
}
|
||||
if (err) return;
|
||||
if (key === "resultFilters") return;
|
||||
if (key === "customBackground") return;
|
||||
let val = config[key];
|
||||
if (Array.isArray(val)) {
|
||||
val.forEach((valarr) => {
|
||||
if (!isConfigKeyValid(valarr)) {
|
||||
err = true;
|
||||
console.error(`${key}: ${valarr} failed regex check`);
|
||||
errorMessage = `${key}: ${valarr} failed regex check`;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!isConfigKeyValid(val)) {
|
||||
err = true;
|
||||
console.error(`${key}: ${val} failed regex check`);
|
||||
errorMessage = `${key}: ${val} failed regex check`;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (err) {
|
||||
console.error(
|
||||
`error adding preset for ${
|
||||
request.uid
|
||||
} - bad input - ${JSON.stringify(request.obj)}`
|
||||
);
|
||||
return {
|
||||
resultCode: -1,
|
||||
message: "Bad input. " + errorMessage,
|
||||
};
|
||||
}
|
||||
|
||||
let presets = await db.collection(`users/${request.uid}/presets`).get();
|
||||
if (presets.docs.length >= 10) {
|
||||
return {
|
||||
resultCode: -2,
|
||||
message: "Preset limit",
|
||||
};
|
||||
}
|
||||
|
||||
return db
|
||||
.collection(`users/${request.uid}/presets`)
|
||||
.add(request.obj)
|
||||
.then((e) => {
|
||||
return {
|
||||
resultCode: 1,
|
||||
message: "Saved",
|
||||
id: e.id,
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error adding preset to DB for ${request.uid} - ${e.message}`
|
||||
);
|
||||
return {
|
||||
resultCode: -1,
|
||||
message: e.message,
|
||||
};
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`error adding preset for ${request.uid} - ${e}`);
|
||||
return {
|
||||
resultCode: -999,
|
||||
message: e,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
exports.editPreset = functions.https.onCall((request, response) => {
|
||||
try {
|
||||
if (!isTagPresetNameValid(request.name)) {
|
||||
return { resultCode: -1 };
|
||||
} else {
|
||||
return db
|
||||
.collection(`users/${request.uid}/presets`)
|
||||
.doc(request.presetid)
|
||||
.set({
|
||||
config: request.config,
|
||||
name: request.name,
|
||||
})
|
||||
.then((e) => {
|
||||
console.log(`user ${request.uid} updated a preset: ${request.name}`);
|
||||
return {
|
||||
resultCode: 1,
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error while updating preset for user ${request.uid}: ${e.message}`
|
||||
);
|
||||
return { resultCode: -999, message: e.message };
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`error updating preset for ${request.uid} - ${e}`);
|
||||
return { resultCode: -999, message: e.message };
|
||||
}
|
||||
});
|
||||
|
||||
exports.removePreset = functions.https.onCall((request, response) => {
|
||||
try {
|
||||
return db
|
||||
.collection(`users/${request.uid}/presets`)
|
||||
.doc(request.presetid)
|
||||
.delete()
|
||||
.then((e) => {
|
||||
console.log(`user ${request.uid} deleted a tag`);
|
||||
return {
|
||||
resultCode: 1,
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error deleting tag for user ${request.uid}: ${e.message}`
|
||||
);
|
||||
return { resultCode: -999 };
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`error deleting tag for ${request.uid} - ${e}`);
|
||||
return { resultCode: -999 };
|
||||
}
|
||||
});
|
||||
|
||||
class Leaderboard {
|
||||
constructor(size, mode, mode2, type, starting) {
|
||||
this.size = size;
|
||||
|
|
|
@ -39,6 +39,35 @@ exports.getPatreons = functions.https.onRequest(async (request, response) => {
|
|||
}
|
||||
});
|
||||
|
||||
exports.clearTagPb = functions.https.onCall((request, response) => {
|
||||
//It looks like this button is not used anymore
|
||||
try {
|
||||
return db
|
||||
.collection(`users/${request.uid}/tags`)
|
||||
.doc(request.tagid)
|
||||
.update({
|
||||
pb: 0,
|
||||
})
|
||||
.then((e) => {
|
||||
return {
|
||||
resultCode: 1,
|
||||
};
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(
|
||||
`error deleting tag pb for user ${request.uid}: ${e.message}`
|
||||
);
|
||||
return {
|
||||
resultCode: -999,
|
||||
message: e.message,
|
||||
};
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`error deleting tag pb for ${request.uid} - ${e}`);
|
||||
return { resultCode: -999 };
|
||||
}
|
||||
});
|
||||
|
||||
async function getAllNames() {
|
||||
// return admin
|
||||
// .auth()
|
||||
|
|
|
@ -4,6 +4,7 @@ import * as CloudFunctions from "./cloud-functions";
|
|||
import * as Notifications from "./notifications";
|
||||
import * as Settings from "./settings";
|
||||
import * as Config from "./config";
|
||||
import axiosInstance from "./axios-instance";
|
||||
|
||||
export function show(action, id, name) {
|
||||
if (action === "add") {
|
||||
|
@ -71,75 +72,80 @@ function apply() {
|
|||
hide();
|
||||
if (action === "add") {
|
||||
Loader.show();
|
||||
CloudFunctions.addPreset({
|
||||
uid: DB.currentUser().uid,
|
||||
obj: {
|
||||
name: inputVal,
|
||||
config: configChanges,
|
||||
},
|
||||
}).then((e) => {
|
||||
Loader.hide();
|
||||
let status = e.data.resultCode;
|
||||
if (status === 1) {
|
||||
Notifications.add("Preset added", 1, 2);
|
||||
DB.getSnapshot().presets.push({
|
||||
axiosInstance
|
||||
.post("/api/addPreset", {
|
||||
obj: {
|
||||
name: inputVal,
|
||||
config: configChanges,
|
||||
id: e.data.id,
|
||||
});
|
||||
Settings.update();
|
||||
} else if (status === -1) {
|
||||
Notifications.add("Invalid preset name", 0);
|
||||
} else if (status === -2) {
|
||||
Notifications.add("You can't add any more presets", 0);
|
||||
} else if (status < -1) {
|
||||
Notifications.add("Unknown error: " + e.data.message, -1);
|
||||
}
|
||||
});
|
||||
},
|
||||
})
|
||||
.then((e) => {
|
||||
console.log(e);
|
||||
console.log("Should be ready to go away");
|
||||
Loader.hide();
|
||||
let status = e.data.resultCode;
|
||||
if (status === 1) {
|
||||
Notifications.add("Preset added", 1, 2);
|
||||
DB.getSnapshot().presets.push({
|
||||
name: inputVal,
|
||||
config: configChanges,
|
||||
id: e.data.id,
|
||||
});
|
||||
Settings.update();
|
||||
} else if (status === -1) {
|
||||
Notifications.add("Invalid preset name", 0);
|
||||
} else if (status === -2) {
|
||||
Notifications.add("You can't add any more presets", 0);
|
||||
} else if (status < -1) {
|
||||
Notifications.add("Unknown error: " + e.data.message, -1);
|
||||
}
|
||||
});
|
||||
} else if (action === "edit") {
|
||||
Loader.show();
|
||||
CloudFunctions.editPreset({
|
||||
uid: DB.currentUser().uid,
|
||||
name: inputVal,
|
||||
presetid,
|
||||
config: configChanges,
|
||||
}).then((e) => {
|
||||
Loader.hide();
|
||||
let status = e.data.resultCode;
|
||||
if (status === 1) {
|
||||
Notifications.add("Preset updated", 1);
|
||||
let preset = DB.getSnapshot().presets.filter(
|
||||
(preset) => preset.id == presetid
|
||||
)[0];
|
||||
preset.name = inputVal;
|
||||
preset.config = configChanges;
|
||||
Settings.update();
|
||||
} else if (status === -1) {
|
||||
Notifications.add("Invalid preset name", 0);
|
||||
} else if (status < -1) {
|
||||
Notifications.add("Unknown error: " + e.data.message, -1);
|
||||
}
|
||||
});
|
||||
axiosInstance
|
||||
.post("/api/editPreset", {
|
||||
presetName: inputVal,
|
||||
presetid: presetid,
|
||||
config: configChanges,
|
||||
})
|
||||
.then((e) => {
|
||||
Loader.hide();
|
||||
let status = e.data.resultCode;
|
||||
if (status === 1) {
|
||||
Notifications.add("Preset updated", 1);
|
||||
let preset = DB.getSnapshot().presets.filter(
|
||||
(preset) => preset._id == presetid
|
||||
)[0];
|
||||
preset.name = inputVal;
|
||||
preset.config = configChanges;
|
||||
Settings.update();
|
||||
} else if (status === -1) {
|
||||
Notifications.add("Invalid preset name", 0);
|
||||
} else if (status < -1) {
|
||||
Notifications.add("Unknown error: " + e.data.message, -1);
|
||||
}
|
||||
});
|
||||
} else if (action === "remove") {
|
||||
Loader.show();
|
||||
CloudFunctions.removePreset({
|
||||
uid: DB.currentUser().uid,
|
||||
presetid,
|
||||
}).then((e) => {
|
||||
Loader.hide();
|
||||
let status = e.data.resultCode;
|
||||
if (status === 1) {
|
||||
Notifications.add("Preset removed", 1);
|
||||
DB.getSnapshot().presets.forEach((preset, index) => {
|
||||
if (preset.id === presetid) {
|
||||
DB.getSnapshot().presets.splice(index, 1);
|
||||
}
|
||||
});
|
||||
Settings.update();
|
||||
} else if (status < -1) {
|
||||
Notifications.add("Unknown error: " + e.data.message, -1);
|
||||
}
|
||||
});
|
||||
axiosInstance
|
||||
.post("/api/removePreset", {
|
||||
presetid,
|
||||
})
|
||||
.then((e) => {
|
||||
Loader.hide();
|
||||
let status = e.data.resultCode;
|
||||
if (status === 1) {
|
||||
Notifications.add("Preset removed", 1);
|
||||
DB.getSnapshot().presets.forEach((preset, index) => {
|
||||
if (preset._id === presetid) {
|
||||
DB.getSnapshot().presets.splice(index, 1);
|
||||
}
|
||||
});
|
||||
Settings.update();
|
||||
} else if (status < -1) {
|
||||
Notifications.add("Unknown error: " + e.data.message, -1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import * as Settings from "./settings";
|
|||
export function apply(id) {
|
||||
// console.log(DB.getSnapshot().presets);
|
||||
DB.getSnapshot().presets.forEach((preset) => {
|
||||
if (preset.id == id) {
|
||||
if (preset._id == id) {
|
||||
Config.apply(JSON.parse(JSON.stringify(preset.config)));
|
||||
Notifications.add("Preset applied", 1, 2);
|
||||
Config.saveToLocalStorage();
|
||||
|
|
|
@ -480,7 +480,7 @@ function refreshPresetsSettingsSection() {
|
|||
let presetsEl = $(".pageSettings .section.presets .presetsList").empty();
|
||||
DB.getSnapshot().presets.forEach((preset) => {
|
||||
presetsEl.append(`
|
||||
<div class="buttons preset" id="${preset.id}">
|
||||
<div class="buttons preset" id="${preset._id}">
|
||||
<div class="button presetButton">
|
||||
<div class="title">${preset.name}</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue