added quote rating

This commit is contained in:
Jack 2021-08-27 20:09:47 +01:00
parent 166b6c10e7
commit db3d25c7ef
7 changed files with 422 additions and 2 deletions

View file

@ -129,6 +129,7 @@ const refactoredSrc = [
"./src/js/popups/custom-text-popup.js",
"./src/js/popups/quote-search-popup.js",
"./src/js/popups/rate-quote-popup.js",
"./src/js/popups/version-popup.js",
"./src/js/popups/support-popup.js",
"./src/js/popups/custom-word-amount-popup.js",

View file

@ -54,6 +54,7 @@ export async function initSnapshot() {
started: 0,
completed: 0,
},
quoteRatings: undefined,
};
let snap = defaultSnap;
try {
@ -70,6 +71,7 @@ export async function initSnapshot() {
started: userData.startedTests,
completed: userData.completedTests,
};
snap.quoteRatings = userData.quoteRatings;
snap.favouriteThemes =
userData.favouriteThemes === undefined ? [] : userData.favouriteThemes;
try {

View file

@ -0,0 +1,203 @@
import * as DB from "./db";
import * as Loader from "./loader";
import * as Notifications from "./notifications";
import axiosInstance from "./axios-instance";
let rating = 0;
let currentQuote = null;
let quoteStats = null;
function reset() {
$(`#rateQuotePopup .quote .text`).text("-");
$(`#rateQuotePopup .quote .source .val`).text("-");
$(`#rateQuotePopup .quote .id .val`).text("-");
$(`#rateQuotePopup .quote .length .val`).text("-");
$("#rateQuotePopup .ratingCount .val").text("-");
$("#rateQuotePopup .ratingAverage .val").text("-");
}
export function show(quote) {
if ($("#rateQuotePopupWrapper").hasClass("hidden")) {
reset();
currentQuote = quote;
rating = 0;
let alreadyRated = DB.getSnapshot().quoteRatings?.[currentQuote.language]?.[
currentQuote.id
];
if (alreadyRated) {
rating = alreadyRated;
}
refreshStars();
updateData();
$("#rateQuotePopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 125);
}
}
function hide() {
if (!$("#rateQuotePopupWrapper").hasClass("hidden")) {
$("#rateQuotePopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
(e) => {
$("#rateQuotePopupWrapper").addClass("hidden");
}
);
}
}
function refreshStars(force) {
let limit = force ? parseInt(force) : rating;
$(`#rateQuotePopup .star`).removeClass("active");
for (let i = 1; i <= limit; i++) {
$(`#rateQuotePopup .star[rating=${i}]`).addClass("active");
}
}
function updateData() {
let lengthDesc;
if (currentQuote.group == 0) {
lengthDesc = "short";
} else if (currentQuote.group == 1) {
lengthDesc = "medium";
} else if (currentQuote.group == 2) {
lengthDesc = "long";
} else if (currentQuote.group == 3) {
lengthDesc = "thicc";
}
$(`#rateQuotePopup .quote .text`).text(currentQuote.text);
$(`#rateQuotePopup .quote .source .val`).text(currentQuote.source);
$(`#rateQuotePopup .quote .id .val`).text(currentQuote.id);
$(`#rateQuotePopup .quote .length .val`).text(lengthDesc);
updateRatingStats();
}
export async function getQuoteStats(quote) {
if (quote) currentQuote = quote;
let response;
try {
response = await axiosInstance.get("/quote-ratings/get", {
params: { quoteId: currentQuote.id, language: currentQuote.language },
});
} catch (e) {
Loader.hide();
let msg = e?.response?.data?.message ?? e.message;
Notifications.add("Failed to get quote ratings: " + msg, -1);
return;
}
Loader.hide();
if (response.status !== 200) {
Notifications.add(response.data.message);
} else {
quoteStats = response.data;
if (quoteStats) {
quoteStats.average = (
Math.round((quoteStats.totalRating / quoteStats.ratings) * 10) / 10
).toFixed(1);
}
return response.data;
}
}
export function clearQuoteStats() {
quoteStats = undefined;
}
async function updateRatingStats() {
if (quoteStats === null) await getQuoteStats();
if (quoteStats === undefined) {
$("#rateQuotePopup .ratingCount .val").text("0");
$("#rateQuotePopup .ratingAverage .val").text("-");
} else {
$("#rateQuotePopup .ratingCount .val").text(quoteStats.ratings);
$("#rateQuotePopup .ratingAverage .val").text(quoteStats.average);
}
}
async function submit() {
if (rating == 0) {
Notifications.add("Please select a rating");
return;
}
hide();
let response;
try {
response = await axiosInstance.post("/quote-ratings/submit", {
quoteId: currentQuote.id,
rating: rating,
language: currentQuote.language,
});
} catch (e) {
Loader.hide();
let msg = e?.response?.data?.message ?? e.message;
Notifications.add("Failed to submit quote rating: " + msg, -1);
return;
}
Loader.hide();
if (response.status !== 200) {
Notifications.add(response.data.message);
} else {
let quoteRatings = DB.getSnapshot().quoteRatings;
if (quoteRatings?.[currentQuote.language]?.[currentQuote.id]) {
let oldRating = quoteRatings[currentQuote.language][currentQuote.id];
let diff = rating - oldRating;
quoteStats.totalRating += diff;
quoteRatings[currentQuote.language][currentQuote.id] = rating;
Notifications.add("Rating updated", 1);
} else {
if (quoteRatings === undefined) quoteRatings = {};
if (quoteRatings[currentQuote.language] === undefined)
quoteRatings[currentQuote.language] = {};
if (quoteRatings[currentQuote.language][currentQuote.id] == undefined)
quoteRatings[currentQuote.language][currentQuote.id] = undefined;
quoteRatings[currentQuote.language][currentQuote.id] = rating;
quoteStats = {
ratings: 1,
totalRating: parseInt(rating),
quoteId: currentQuote.id,
language: currentQuote.language,
};
Notifications.add("Rating submitted", 1);
}
quoteStats.average = (
Math.round((quoteStats.totalRating / quoteStats.ratings) * 10) / 10
).toFixed(1);
$(".pageTest #result #rateQuoteButton .rating").text(quoteStats.average);
}
}
$("#rateQuotePopupWrapper").click((e) => {
if ($(e.target).attr("id") === "rateQuotePopupWrapper") {
hide();
}
});
$("#rateQuotePopup .stars .star").hover((e) => {
let ratingHover = $(e.currentTarget).attr("rating");
refreshStars(ratingHover);
});
$("#rateQuotePopup .stars .star").click((e) => {
let ratingHover = $(e.currentTarget).attr("rating");
rating = ratingHover;
});
$("#rateQuotePopup .stars .star").mouseout((e) => {
$(`#rateQuotePopup .star`).removeClass("active");
refreshStars();
});
$("#rateQuotePopup .submitButton").click((e) => {
submit();
});

View file

@ -35,6 +35,7 @@ import * as TodayTracker from "./today-tracker";
import * as WeakSpot from "./weak-spot";
import * as Wordset from "./wordset";
import * as ChallengeContoller from "./challenge-controller";
import * as RateQuotePopup from "./rate-quote-popup";
let glarsesMode = false;
@ -707,6 +708,7 @@ export async function init() {
rq.text = rq.text.replace(/( *(\r\n|\r|\n) *)/g, "\n ");
rq.text = rq.text.replace(/…/g, "...");
rq.text = rq.text.trim();
rq.language = Config.language.replace(/_\d*k$/g, "");
setRandomQuote(rq);
@ -849,6 +851,7 @@ export function restart(
$("#showWordHistoryButton").removeClass("loaded");
TestUI.focusWords();
Funbox.resetMemoryTimer();
RateQuotePopup.clearQuoteStats();
TestUI.reset();
@ -1586,6 +1589,17 @@ export async function finish(difficultyFailed = false) {
) {
if (firebase.auth().currentUser != null) {
completedEvent.uid = firebase.auth().currentUser.uid;
let quoteStats = await RateQuotePopup.getQuoteStats(randomQuote);
if (quoteStats !== null) {
$(".pageTest #result #rateQuoteButton .rating").text(
quoteStats.average
);
} else {
$(".pageTest #result #rateQuoteButton .rating").text("");
}
$(".pageTest #result #rateQuoteButton").removeClass("hidden");
//check local pb
AccountButton.loading(true);
let dontShowCrown = false;
@ -1857,6 +1871,7 @@ export async function finish(difficultyFailed = false) {
});
});
} else {
$(".pageTest #result #rateQuoteButton").addClass("hidden");
try {
firebase.analytics().logEvent("testCompletedNoLogin", completedEvent);
} catch (e) {

View file

@ -18,6 +18,7 @@ import * as TestStats from "./test-stats";
import * as Misc from "./misc";
import * as TestUI from "./test-ui";
import * as ChallengeController from "./challenge-controller";
import * as RateQuotePopup from "./rate-quote-popup";
export let currentWordElementIndex = 0;
export let resultVisible = false;
@ -934,6 +935,10 @@ $(".pageTest #copyWordsListButton").click(async (event) => {
}
});
$(".pageTest #rateQuoteButton").click(async (event) => {
RateQuotePopup.show(TestLogic.randomQuote);
});
$(".pageTest #toggleBurstHeatmap").click(async (event) => {
UpdateConfig.setBurstHeatmap(!Config.burstHeatmap);
});

View file

@ -713,6 +713,114 @@ label.checkbox {
}
}
#rateQuotePopupWrapper {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
position: fixed;
left: 0;
top: 0;
z-index: 1000;
display: grid;
justify-content: center;
align-items: center;
padding: 5rem 0;
#rateQuotePopup {
color: var(--sub-color);
background: var(--bg-color);
border-radius: var(--roundness);
padding: 2rem;
display: grid;
gap: 2rem;
width: 1000px;
display: grid;
grid-template-areas: "ratingStats ratingStats submitButton" "spacer spacer spacer" "quote quote quote";
grid-template-columns: auto 1fr;
color: var(--text-color);
.spacer {
grid-area: spacer;
grid-column: 1/4;
width: 100%;
height: 0.1rem;
border-radius: var(--roundness);
background: var(--sub-color);
opacity: 0.25;
}
.submitButton {
font-size: 2rem;
grid-area: submitButton;
color: var(--sub-color);
&:hover {
color: var(--text-color);
}
}
.top {
color: var(--sub-color);
font-size: 0.8rem;
}
.ratingStats {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 1rem;
grid-area: ratingStats;
.top {
font-size: 1rem;
}
.val {
font-size: 2rem;
}
}
.quote {
display: grid;
grid-area: quote;
gap: 1rem;
grid-template-areas:
"text text text"
"id length source";
grid-template-columns: 1fr 1fr 3fr;
.text {
grid-area: text;
}
.id {
grid-area: id;
}
.length {
grid-area: length;
}
.source {
grid-area: source;
}
}
.stars {
display: grid;
color: var(--sub-color);
font-size: 2rem;
grid-template-columns: auto auto auto auto auto;
justify-content: flex-start;
align-items: center;
cursor: pointer;
}
.star {
transition: 0.125s;
}
i {
pointer-events: none;
}
.star.active {
color: var(--text-color);
}
}
}
#simplePopupWrapper {
width: 100%;
height: 100%;
@ -2129,6 +2237,7 @@ key {
color: var(--sub-color);
font-size: 1rem;
line-height: 1rem;
margin-bottom: 0.25rem;
}
.bottom {
@ -2146,6 +2255,10 @@ key {
margin-left: 0.2rem;
}
}
&.source #rateQuoteButton {
padding: 0 0.5rem;
}
}
// .infoAndTags {

View file

@ -137,6 +137,75 @@
</div>
</div>
<div id="rateQuotePopupWrapper" class="hidden">
<div id="rateQuotePopup" quoteId="">
<div class="quote">
<div class="text">-</div>
<div class="id">
<div class="top">id</div>
<div class="val">-</div>
</div>
<div class="length">
<div class="top">length</div>
<div class="val">-</div>
</div>
<div class="source">
<div class="top">source</div>
<div class="val">-</div>
</div>
</div>
<div class="spacer"></div>
<div class="ratingStats">
<div class="ratingCount">
<div class="top">ratings</div>
<div class="val">-</div>
</div>
<div class="ratingAverage">
<div class="top">average</div>
<div class="val">-</div>
</div>
<div class="starsWrapper">
<div class="top">your rating</div>
<div class="stars">
<div class="star active" rating="1">
<i class="fas fa-fw fa-star"></i>
</div>
<div class="star active" rating="2">
<i class="fas fa-fw fa-star"></i>
</div>
<div class="star active" rating="3">
<i class="fas fa-fw fa-star"></i>
</div>
<div class="star" rating="4">
<i class="fas fa-fw fa-star"></i>
</div>
<div class="star" rating="5">
<i class="fas fa-fw fa-star"></i>
</div>
</div>
</div>
</div>
<!-- <div class="button rate1">
<i class="fas fa-star"></i>
<i class="far fa-star"></i>
<i class="far fa-star"></i>
</div>
<div class="button rate2">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="far fa-star"></i>
</div>
<div class="button rate3">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
</div> -->
<div class="icon-button submitButton">
<i class="fas fa-chevron-right"></i>
</div>
</div>
</div>
<div id="settingsImportWrapper" class="hidden">
<div id="settingsImport" action="">
<input type="text" />
@ -1498,7 +1567,7 @@
<div class="group flat consistency">
<div class="top">consistency</div>
<div class="bottom" aria-label="" data-balloon-pos="up">
-
2 -
</div>
</div>
<div class="group time">
@ -1512,7 +1581,19 @@
<!-- </div> -->
<div class="group source hidden">
<div class="top">source</div>
<div class="top">
source
<span
id="rateQuoteButton"
class="icon-button hidden"
aria-label="Rate quote"
data-balloon-pos="up"
style="display: inline-block"
>
<i class="far fa-star"></i>
<span class="rating"></span>
</span>
</div>
<div class="bottom">-</div>
</div>