Add favorite quotes mode (#2945) bruception

* Add favorite quotes mode

* Remove unnecessary repeated fn call

* resetting quote length to -1 when no favorites found

* fixed quote favoriting broken

* starting hidden

* showing/hiding button depending on login state

* added command to commandline

* removed comment

Co-authored-by: Miodec <bartnikjack@gmail.com>
This commit is contained in:
Bruce Berrios 2022-05-08 05:58:58 -04:00 committed by GitHub
parent c9bfb00008
commit 9026893571
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 123 additions and 44 deletions

View file

@ -1000,7 +1000,7 @@ export function setQuoteLength(
): boolean {
if (
!isConfigValueValid("quote length", len, [
[-2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3],
"numberArray",
])
) {
@ -1013,7 +1013,7 @@ export function setQuoteLength(
config.quoteLength = len;
} else {
if (!Array.isArray(config.quoteLength)) config.quoteLength = [];
if (len === null || isNaN(len) || len < -2 || len > 3) {
if (len === null || isNaN(len) || len < -3 || len > 3) {
len = 1;
}
len = parseInt(len.toString()) as MonkeyTypes.QuoteLength;

View file

@ -47,6 +47,10 @@ import { Auth } from "../firebase";
import differenceInDays from "date-fns/differenceInDays";
import { defaultSnap } from "../constants/default-snapshot";
import { dispatch as dispatchSignUpEvent } from "../observables/google-sign-up-event";
import {
hideFavoriteQuoteLength,
showFavoriteQuoteLength,
} from "../test/test-config";
export const gmailProvider = new GoogleAuthProvider();
@ -107,6 +111,7 @@ export async function getDataAndInit(): Promise<boolean> {
LoadingPage.updateText("Applying settings...");
const snapshot = DB.getSnapshot();
$("#menu .text-button.account .text").text(snapshot.name);
showFavoriteQuoteLength();
ResultFilters.loadTags(snapshot.tags);
@ -491,6 +496,7 @@ export function signOut(): void {
DB.setSnapshot(defaultSnap);
$(".pageLogin .button").removeClass("disabled");
$(".pageLogin input").prop("disabled", false);
hideFavoriteQuoteLength();
})
.catch(function (error) {
Notifications.add(error.message, -1);

View file

@ -1,5 +1,6 @@
import { shuffle } from "../utils/misc";
import { randomElementFromArray, shuffle } from "../utils/misc";
import { subscribe } from "../observables/config-event";
import * as DB from "../db";
interface Quote {
text: string;
@ -28,6 +29,10 @@ const defaultQuoteCollection: QuoteCollection = {
groups: [],
};
function normalizeLanguage(language: string): string {
return language.replace(/_\d*k$/g, "");
}
class QuotesController {
private quoteCollection: QuoteCollection = defaultQuoteCollection;
@ -38,7 +43,7 @@ class QuotesController {
language: string,
quoteLengths?: number[]
): Promise<QuoteCollection> {
const normalizedLanguage = language.replace(/_\d*k$/g, "");
const normalizedLanguage = normalizeLanguage(language);
if (this.quoteCollection.language !== normalizedLanguage) {
try {
@ -146,6 +151,54 @@ class QuotesController {
return this.quoteQueue[this.queueIndex];
}
getRandomFavoriteQuote(language: string): MonkeyTypes.Quote | null {
const snapshot = DB.getSnapshot();
if (!snapshot) {
return null;
}
const normalizedLanguage = normalizeLanguage(language);
const quoteIds: string[] = [];
const { favoriteQuotes } = snapshot;
Object.keys(favoriteQuotes).forEach((language) => {
if (normalizeLanguage(language) !== normalizedLanguage) {
return;
}
quoteIds.push(...favoriteQuotes[language]);
});
if (quoteIds.length === 0) {
return null;
}
const randomQuoteId = randomElementFromArray(quoteIds);
const randomQuote = this.getQuoteById(parseInt(randomQuoteId, 10));
return randomQuote ?? null;
}
isQuoteFavorite({ language: quoteLanguage, id }: MonkeyTypes.Quote): boolean {
const snapshot = DB.getSnapshot();
if (!snapshot) {
return false;
}
const { favoriteQuotes } = snapshot;
const normalizedQuoteLanguage = normalizeLanguage(quoteLanguage);
const matchedLanguage = Object.keys(favoriteQuotes).find((language) => {
if (normalizedQuoteLanguage !== normalizeLanguage(language)) {
return false;
}
return favoriteQuotes[language].includes(id.toString());
});
return matchedLanguage !== undefined;
}
}
const quoteController = new QuotesController();

View file

@ -2059,6 +2059,20 @@ const commandsQuoteLengthConfig: MonkeyTypes.CommandsGroup = {
TestLogic.restart();
},
},
{
id: "changeQuoteLengthFavorite",
display: "favorite",
configValue: -3,
configValueMode: "include",
available: (): boolean => {
return !!Auth.currentUser;
},
exec: (): void => {
UpdateConfig.setMode("quote");
UpdateConfig.setQuoteLength(-3);
TestLogic.restart();
},
},
],
};

View file

@ -16,7 +16,6 @@ import QuotesController from "../controllers/quotes-controller";
import { Auth } from "../firebase";
import { debounce } from "throttle-debounce";
import Ape from "../ape";
import { isQuoteFavorite } from "../utils/misc";
import * as Loader from "../elements/loader";
export let selectedId = 1;
@ -85,14 +84,10 @@ function applyQuoteFavFilter(quotes: MonkeyTypes.Quote[]): MonkeyTypes.Quote[] {
const filteredQuotes = quotes.filter((quote) => {
if (showFavOnly) {
return isQuoteFavorite(
DB.getSnapshot(),
quote.language,
quote.id.toString()
);
} else {
return true;
return QuotesController.isQuoteFavorite(quote);
}
return true;
});
return filteredQuotes;
@ -113,10 +108,8 @@ function buildQuoteSearchResult(
lengthDesc = "thicc";
}
const loggedIn = !Auth.currentUser;
const isFav =
!loggedIn &&
isQuoteFavorite(DB.getSnapshot(), quote.language, quote.id.toString());
const loggedOut = !Auth.currentUser;
const isFav = !loggedOut && QuotesController.isQuoteFavorite(quote);
return `
<div class="searchResult" id="${quote.id}">
@ -143,13 +136,13 @@ function buildQuoteSearchResult(
</div>
<div class="text-button report ${
loggedIn && "hidden"
loggedOut && "hidden"
}" aria-label="Report quote" data-balloon-pos="left">
<i class="fas fa-flag report"></i>
</div>
<div class="text-button favorite ${
loggedIn && "hidden"
loggedOut && "hidden"
}" aria-label="Favorite quote" data-balloon-pos="left">
<i class="${isFav ? "fas" : "far"} fa-heart favorite"></i>
</div>
@ -171,10 +164,9 @@ async function updateResults(searchText: string): Promise<void> {
const { results: matches, matchedQueryTerms } =
quoteSearchService.query(searchText);
let quotesToShow = [];
quotesToShow = applyQuoteLengthFilter(searchText === "" ? quotes : matches);
quotesToShow = applyQuoteFavFilter(quotesToShow);
const quotesToShow = applyQuoteLengthFilter(
applyQuoteFavFilter(searchText === "" ? quotes : matches)
);
const resultsList = $("#quoteSearchResults");
resultsList.empty();

View file

@ -13,6 +13,7 @@ import * as GlarsesMode from "../states/glarses-mode";
import * as TestInput from "./test-input";
import * as Notifications from "../elements/notifications";
import * as Loader from "../elements/loader";
import QuotesController from "../controllers/quotes-controller";
import { Chart } from "chart.js";
import { Auth } from "../firebase";
@ -581,17 +582,15 @@ function updateQuoteFavorite(randomQuote: MonkeyTypes.Quote): void {
quoteLang = Config.mode === "quote" ? randomQuote.language : "";
quoteId = Config.mode === "quote" ? randomQuote.id.toString() : "";
const $icon = $(".pageTest #result #favoriteQuoteButton .icon");
const icon = $(".pageTest #result #favoriteQuoteButton .icon");
if (Config.mode === "quote" && Auth.currentUser) {
const userFav = Misc.isQuoteFavorite(DB.getSnapshot(), quoteLang, quoteId);
const userFav = QuotesController.isQuoteFavorite(randomQuote);
$icon
.removeClass(userFav ? "far" : "fas")
.addClass(userFav ? "fas" : "far");
$icon.parent().removeClass("hidden");
icon.removeClass(userFav ? "far" : "fas").addClass(userFav ? "fas" : "far");
icon.parent().removeClass("hidden");
} else {
$icon.parent().addClass("hidden");
icon.parent().addClass("hidden");
}
}

View file

@ -160,6 +160,14 @@ export function update(
);
}
export function showFavoriteQuoteLength(): void {
$("#top .desktopConfig .group.quoteLength .favorite").removeClass("hidden");
}
export function hideFavoriteQuoteLength(): void {
$("#top .desktopConfig .group.quoteLength .favorite").addClass("hidden");
}
ConfigEvent.subscribe((eventKey, eventValue, _nosave, eventPreviousValue) => {
if (eventKey === "mode") {
update(

View file

@ -932,7 +932,7 @@ export async function init(): Promise<void> {
}
let rq: MonkeyTypes.Quote | undefined = undefined;
if (Config.quoteLength.includes(-2) && Config.quoteLength.length == 1) {
if (Config.quoteLength.includes(-2) && Config.quoteLength.length === 1) {
const targetQuote = QuotesController.getQuoteById(
QuoteSearchPopup.selectedId
);
@ -942,6 +942,19 @@ export async function init(): Promise<void> {
} else {
rq = targetQuote;
}
} else if (Config.quoteLength.includes(-3)) {
const randomQuote = QuotesController.getRandomFavoriteQuote(
Config.language
);
if (randomQuote === null) {
Notifications.add("No favorite quotes found", 0);
UpdateConfig.setQuoteLength(-1);
restart();
return;
}
rq = randomQuote;
} else {
const randomQuote = QuotesController.getRandomQuote();
if (randomQuote === null) {

View file

@ -33,7 +33,7 @@ declare namespace MonkeyTypes {
type QuoteModes = "short" | "medium" | "long" | "thicc";
type QuoteLength = -2 | -1 | 0 | 1 | 2 | 3;
type QuoteLength = -3 | -2 | -1 | 0 | 1 | 2 | 3;
type FontSize = "1" | "125" | "15" | "2" | "3" | "4";

View file

@ -1111,18 +1111,6 @@ export function createErrorMessage(error: unknown, message: string): string {
return message;
}
export function isQuoteFavorite(
snapshot: MonkeyTypes.Snapshot,
quoteLang: string,
quoteId: string
): boolean {
if (!snapshot) return false;
if (!Object.keys(snapshot.favoriteQuotes).includes(quoteLang)) return false;
return snapshot.favoriteQuotes[quoteLang].includes(quoteId);
}
export function isAnyPopupVisible(): boolean {
const popups = document.querySelectorAll(".popupWrapper");
let popupVisible = false;

View file

@ -155,7 +155,6 @@
style="display: inline-block"
>
<i class="icon far fa-heart"></i>
<span class="favorite"></span>
</span>
<span
id="rateQuoteButton"

View file

@ -187,6 +187,13 @@
</div>
<div class="text-button" quoteLength="2" tabindex="2">long</div>
<div class="text-button" quoteLength="3" tabindex="2">thicc</div>
<div
class="text-button hidden favorite"
quoteLength="-3"
tabindex="2"
>
<i class="fas fa-heart"></i>
</div>
<div class="text-button" quoteLength="-2" tabindex="2">
<i class="fas fa-search"></i>
</div>