From 517b1ba23ddfdddcbd284dfc89800ef1eb9aae95 Mon Sep 17 00:00:00 2001 From: Max Richter Date: Tue, 29 Aug 2023 13:48:52 +0200 Subject: [PATCH] feat: sort by rating by default --- lib/crud.ts | 42 +++++++++++++++++++++++++++--------------- lib/helpers.ts | 7 +++++++ lib/types.ts | 1 + 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/crud.ts b/lib/crud.ts index bcf7971..3635dd5 100644 --- a/lib/crud.ts +++ b/lib/crud.ts @@ -6,18 +6,10 @@ import { } from "@lib/documents.ts"; import { Root } from "https://esm.sh/remark-frontmatter@4.0.1"; import { getThumbhash } from "@lib/cache/image.ts"; +import { GenericResource } from "@lib/types.ts"; +import { parseRating } from "@lib/helpers.ts"; -type Resource = { - name: string; - id: string; - meta: { - image?: string; - author?: string; - thumbnail?: string; - }; -}; - -export async function addThumbnailToResource( +export async function addThumbnailToResource( res: T, ): Promise { const imageUrl = res?.meta?.image; @@ -34,7 +26,27 @@ export async function addThumbnailToResource( }; } -export function createCrud( +type SortType = "rating" | "date" | "name" | "author"; + +function sortFunction(sortType: SortType) { + return (a: T, b: T) => { + switch (sortType) { + case "rating": + return parseRating(a.meta?.rating || 0) > + parseRating(b.meta?.rating || 0) + ? -1 + : 1; + case "date": + return (a.meta?.date || 0) > (b.meta?.date || 0) ? -1 : 1; + case "name": + return a.name.localeCompare(b.name); + case "author": + return a.meta?.author?.localeCompare(b.meta?.author || ""); + } + }; +} + +export function createCrud( { prefix, parse, render, hasThumbnails = false }: { prefix: string; hasThumbnails?: boolean; @@ -80,9 +92,9 @@ export function createCrud( await createDocument(path, newDoc); } - async function readAll() { + async function readAll({ sort = "rating" }: { sort?: SortType } = {}) { const allDocuments = await getDocuments(); - return Promise.all( + return (await Promise.all( allDocuments.filter((d) => { return d.name.startsWith(prefix) && d.contentType === "text/markdown" && @@ -91,7 +103,7 @@ export function createCrud( const id = doc.name.replace(prefix, "").replace(/\.md$/, ""); return read(id); }), - ); + )).sort(sortFunction(sort)); } return { diff --git a/lib/helpers.ts b/lib/helpers.ts index 35f8cad..a5d538a 100644 --- a/lib/helpers.ts +++ b/lib/helpers.ts @@ -88,3 +88,10 @@ export function debounce) => void>( timer = setTimeout(() => fn.apply(this, args), delay); }; } + +export function parseRating(rating: string | number) { + if (typeof rating === "string") { + return [...rating.matchAll(/⭐/)].length; + } + return rating; +} diff --git a/lib/types.ts b/lib/types.ts index 9c5e2ff..850609d 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -43,6 +43,7 @@ export type GenericResource = { author?: string; rating?: number; average?: string; + date?: Date | string; thumbnail?: string; }; };