From 051023226f97d538f7025332547447ad8783b8c4 Mon Sep 17 00:00:00 2001 From: Tanner Heffner Date: Mon, 18 Mar 2024 22:42:33 -0700 Subject: [PATCH 1/3] run prettier --- .eslintrc.cjs | 5 ++ src/lib/rehype-wrap-img.js | 1 - src/routes/(main)/+page.server.js | 30 ++++---- src/routes/(main)/blog/fuzzySearch.js | 102 ++++++++++++++++++++++++++ tailwind.config.cjs | 2 +- 5 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 src/routes/(main)/blog/fuzzySearch.js diff --git a/.eslintrc.cjs b/.eslintrc.cjs index f89e492..7d98f3e 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -16,6 +16,11 @@ module.exports = { sourceType: 'module', ecmaVersion: 2019, }, + rules: { + 'no-unused-expressions': 'warn', + 'no-constant-binary-expression': 'warn', + 'no-sequences': 'warn', + }, env: { browser: true, es2017: true, diff --git a/src/lib/rehype-wrap-img.js b/src/lib/rehype-wrap-img.js index 6ce6471..c80f825 100644 --- a/src/lib/rehype-wrap-img.js +++ b/src/lib/rehype-wrap-img.js @@ -10,7 +10,6 @@ export default function rehypeZoomImages(options = { selector: 'img' }) { const label = fromSelector('label') const checkbox = fromSelector('input[type="checkbox"]') - node.properties.loading = 'lazy' // add class for bg color before loading node.properties.class = 'lazy-image' diff --git a/src/routes/(main)/+page.server.js b/src/routes/(main)/+page.server.js index ab77348..106d7a5 100644 --- a/src/routes/(main)/+page.server.js +++ b/src/routes/(main)/+page.server.js @@ -1,32 +1,36 @@ import { LASTFM_API_KEY, STEAM_API_KEY } from '$env/static/private' -import { LASTFM_ID, LETTERBOXD_ID, STEAM_ID} from '$lib/siteConfig' +import { LASTFM_ID, LETTERBOXD_ID, STEAM_ID } from '$lib/siteConfig' import letterboxd from 'letterboxd' - /** @type {import('./$types').PageServerLoad} */ export async function load({ fetch, params }) { // Fetch recently played songs from last.fm - const lastfm_res = await fetch(`http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${LASTFM_ID}&api_key=${LASTFM_API_KEY}&format=json`) + const lastfm_res = await fetch( + `http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${LASTFM_ID}&api_key=${LASTFM_API_KEY}&format=json` + ) const lastfm_json = await lastfm_res.json() const recentlyListened = lastfm_json.recenttracks.track.slice(0, 5) // Fetch recently watched movies from letterboxd. scrapes rss feed let recentlyWatched = [] - await letterboxd(LETTERBOXD_ID).then(function (items) { - recentlyWatched = items.slice(0, 5) - }) - .catch(function (error) { - console.log(error); - }); + await letterboxd(LETTERBOXD_ID) + .then(function (items) { + recentlyWatched = items.slice(0, 5) + }) + .catch(function (error) { + console.log(error) + }) // Fetched recently played games from Steam. - const steam_res = await fetch(`http://api.steampowered.com/IPlayerService/GetRecentlyPlayedGames/v1/?key=${STEAM_API_KEY}&steamid=${STEAM_ID}`) + const steam_res = await fetch( + `http://api.steampowered.com/IPlayerService/GetRecentlyPlayedGames/v1/?key=${STEAM_API_KEY}&steamid=${STEAM_ID}` + ) const steam_json = await steam_res.json() const recentlyPlayed = steam_json.response return { - recentlyListened, + recentlyListened, recentlyWatched, - recentlyPlayed - }; + recentlyPlayed, + } } diff --git a/src/routes/(main)/blog/fuzzySearch.js b/src/routes/(main)/blog/fuzzySearch.js new file mode 100644 index 0000000..eb7f904 --- /dev/null +++ b/src/routes/(main)/blog/fuzzySearch.js @@ -0,0 +1,102 @@ +import uFuzzy from '@leeoniya/ufuzzy' + +// https://github.com/leeoniya/uFuzzy#options +export let isSearchExact = false +export function setIsSearchExact(value = !isSearchExact) { + isSearchExact = value +} +let u = new uFuzzy({ intraMode: 1 }) + +export function changeSearchMode() { + isSearchExact = !isSearchExact + if (isSearchExact) { + u = new uFuzzy({ intraMode: 0, interLft: 1, interRgt: 1 }) + } else { + u = new uFuzzy({ intraMode: 1, interLft: 0, interRgt: 0 }) + } +} + +// debounce async function returning a promise +// https://dev.to/gabe_ragland/debouncing-with-async-await-in-js-26ci +function debounce(func, wait) { + let timeout + return (...args) => { + const context = this + return new Promise((resolve, reject) => { + const later = () => { + timeout = null + resolve(func.apply(context, args)) + } + const callNow = !timeout + clearTimeout(timeout) + timeout = setTimeout(later, wait) + if (callNow) resolve(func.apply(context, args)) + }) + } +} + +/** + * @param {import('$lib/types').ContentItem[]} items + * @param {string[]} selectedCategories + * @param {string} search + * @return {Object[]} + */ +function _fuzzySearch(items, selectedCategories, search) { + const filteredItems = items.filter((item) => { + if (selectedCategories?.length < 1) return true + return selectedCategories + .map((element) => { + return element.toLowerCase() + }) + .includes(item.category.toLowerCase()) + }) + if (search) { + const haystack = filteredItems.map((v) => + [ + v.title, + v.subtitle, + v.tags.map((tag) => 'hashtag-' + tag), // add #tag so as to enable tag search + v.content, + v.description, + ].join(' ') + ) + const idxs = u.filter(haystack, search) + const info = u.info(idxs, haystack, search) + const order = u.sort(info, haystack, search) + const mark = (part, matched) => + matched ? '' + part + '' : part + const list = order.map((i) => { + const x = filteredItems[info.idx[order[i]]] + const hl = uFuzzy + .highlight( + haystack[info.idx[order[i]]] + // sanitize html as we dont actually want to render it + .replaceAll('<', ' ') + .replaceAll('/>', ' ') + .replaceAll('>', ' '), + info.ranges[order[i]], + mark + ) + // highlight whats left + .slice( + Math.max(info.ranges[order[i]][0] - 200, 0), + Math.min( + info.ranges[order[i]][1] + 200, + haystack[info.idx[order[i]]].length + ) + ) + // slice clean words + .split(' ') + .slice(1, -1) + .join(' ') + return { ...x, highlightedResults: hl } + }) + return list + } else { + return filteredItems + } +} + +export function fuzzySearch(items, selectedCategories, search) { + return debounce(_fuzzySearch, 100)(items, selectedCategories, search) +} diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 5d035f0..78da5a3 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -13,7 +13,7 @@ module.exports = { secondary: 'var(--brand-secondary)', }, gridTemplateColumns: { - 'currently': '50px 1fr' + currently: '50px 1fr', }, typography: (theme) => ({ DEFAULT: { From 5a896b48efd3e6980fe8256e1c30417525aa1e12 Mon Sep 17 00:00:00 2001 From: Tanner Heffner Date: Mon, 18 Mar 2024 23:03:29 -0700 Subject: [PATCH 2/3] update eslint stuff --- .eslintrc.cjs | 29 +- package-lock.json | 828 +++++++++------------------------------------- package.json | 6 +- 3 files changed, 176 insertions(+), 687 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7d98f3e..c95b224 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,25 +1,24 @@ module.exports = { root: true, parser: '@typescript-eslint/parser', - extends: [ - 'eslint:recommended', - // 'plugin:@typescript-eslint/recommended', // todo: https://stackoverflow.com/questions/57597142/how-to-run-typescript-eslint-on-ts-files-and-eslint-on-js-files-in-the-same-pr - 'prettier', - ], - plugins: ['svelte3', '@typescript-eslint'], + extends: ['eslint:recommended', 'plugin:svelte/recommended', 'prettier'], + plugins: ['@typescript-eslint'], ignorePatterns: ['*.cjs'], - overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], - settings: { - 'svelte3/typescript': () => require('typescript'), - }, + overrides: [ + { + files: ['*.svelte'], + parser: 'svelte-eslint-parser', + // Parse the `