mirror of
https://github.com/BradNut/boredgame
synced 2025-09-08 17:40:22 +00:00
Adding binary search and using in add sorted for stores.
This commit is contained in:
parent
416594c756
commit
0cabb2f466
8 changed files with 56 additions and 7 deletions
|
|
@ -11,6 +11,8 @@
|
||||||
import { addToCollection, removeFromCollection } from '$lib/util/manipulateCollection';
|
import { addToCollection, removeFromCollection } from '$lib/util/manipulateCollection';
|
||||||
import { addToWishlist } from '$lib/util/manipulateWishlist';
|
import { addToWishlist } from '$lib/util/manipulateWishlist';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
|
import { binarySearchOnStore } from '$root/lib/util/binarySearchOnStore';
|
||||||
|
import { convertToSavedGame } from '$root/lib/util/gameMapper';
|
||||||
|
|
||||||
export let game: GameType | SavedGameType;
|
export let game: GameType | SavedGameType;
|
||||||
export let detailed: boolean = false;
|
export let detailed: boolean = false;
|
||||||
|
|
@ -29,7 +31,8 @@
|
||||||
if (existsInCollection) {
|
if (existsInCollection) {
|
||||||
removeGameFromCollection();
|
removeGameFromCollection();
|
||||||
} else {
|
} else {
|
||||||
addToCollection(game);
|
let index = binarySearchOnStore($collectionStore, convertToSavedGame(game), 'en');
|
||||||
|
addToCollection(game, index);
|
||||||
if (browser) {
|
if (browser) {
|
||||||
localStorage.collection = JSON.stringify($collectionStore);
|
localStorage.collection = JSON.stringify($collectionStore);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,13 @@ const state = () => {
|
||||||
update((store) => [...store, game]);
|
update((store) => [...store, game]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addSorted(game: SavedGameType, index: number) {
|
||||||
|
update((store) => {
|
||||||
|
store.splice(index, 0, game);
|
||||||
|
return store;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function remove(id: string) {
|
function remove(id: string) {
|
||||||
update((store) => {
|
update((store) => {
|
||||||
const newStore = store.filter((item: SavedGameType) => item.id !== id);
|
const newStore = store.filter((item: SavedGameType) => item.id !== id);
|
||||||
|
|
@ -28,7 +35,7 @@ const state = () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { subscribe, set, update, add, addAll, remove, removeAll };
|
return { subscribe, set, update, add, addSorted, addAll, remove, removeAll };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const collectionStore = state();
|
export const collectionStore = state();
|
||||||
|
|
|
||||||
25
src/lib/util/binarySearchOnStore.ts
Normal file
25
src/lib/util/binarySearchOnStore.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import type { SavedGameType } from "../types";
|
||||||
|
|
||||||
|
export function binarySearchOnStore(inputArray: SavedGameType[], item: SavedGameType, locale = 'en') {
|
||||||
|
const collator = Intl.Collator(locale)
|
||||||
|
let low = 0;
|
||||||
|
let high = inputArray?.length - 1;
|
||||||
|
let mid;
|
||||||
|
let comparison;
|
||||||
|
|
||||||
|
while (low <= high) {
|
||||||
|
mid = (low + high) >>> 1; /* equivalent to Math.floor((low + hight) / 2) but faster */
|
||||||
|
const midValue = inputArray[mid];
|
||||||
|
comparison = collator.compare(midValue?.name, item?.name);
|
||||||
|
|
||||||
|
if (comparison < 0) {
|
||||||
|
low = mid + 1;
|
||||||
|
} else if (comparison > 0) {
|
||||||
|
high = mid - 1;
|
||||||
|
} else {
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return low;
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,15 @@ import { ToastType, type GameType, type SavedGameType } from '$lib/types';
|
||||||
import { convertToSavedGame } from './gameMapper';
|
import { convertToSavedGame } from './gameMapper';
|
||||||
import { saved_game_schema } from '../zodValidation';
|
import { saved_game_schema } from '../zodValidation';
|
||||||
|
|
||||||
export function addToCollection(game: GameType | SavedGameType) {
|
export function addToCollection(game: GameType | SavedGameType, index: number) {
|
||||||
try {
|
try {
|
||||||
console.log(`Saving game: ${JSON.stringify(game)}`);
|
console.log(`Saving game: ${JSON.stringify(game)}`);
|
||||||
saved_game_schema.parse(game);
|
saved_game_schema.parse(game);
|
||||||
collectionStore.add(convertToSavedGame(game));
|
if (index === -1) {
|
||||||
|
collectionStore.add(convertToSavedGame(game));
|
||||||
|
} else {
|
||||||
|
collectionStore.addSorted(convertToSavedGame(game), index);
|
||||||
|
}
|
||||||
toast.send('Added to collection', { duration: 3000, type: ToastType.INFO });
|
toast.send('Added to collection', { duration: 3000, type: ToastType.INFO });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,14 @@
|
||||||
$: isOpen = $boredState?.dialog?.isOpen;
|
$: isOpen = $boredState?.dialog?.isOpen;
|
||||||
|
|
||||||
if (browser) {
|
if (browser) {
|
||||||
|
const collator = new Intl.Collator('en');
|
||||||
|
|
||||||
let collectionEmpty = $collectionStore.length === 0 || false;
|
let collectionEmpty = $collectionStore.length === 0 || false;
|
||||||
let wishlistEmpty = $wishlistStore.length === 0 || false;
|
let wishlistEmpty = $wishlistStore.length === 0 || false;
|
||||||
if (wishlistEmpty && localStorage?.wishlist && localStorage?.wishlist?.length !== 0) {
|
if (wishlistEmpty && localStorage?.wishlist && localStorage?.wishlist?.length !== 0) {
|
||||||
const wishlist: SavedGameType[] = JSON.parse(localStorage.wishlist);
|
const wishlist: SavedGameType[] = JSON.parse(localStorage.wishlist);
|
||||||
if (wishlist?.length !== 0) {
|
if (wishlist?.length !== 0) {
|
||||||
|
wishlist.sort((a, b) => collator.compare(a.name, b.name));
|
||||||
for (const item of wishlist) {
|
for (const item of wishlist) {
|
||||||
if (!item?.searchTerms) {
|
if (!item?.searchTerms) {
|
||||||
item.searchTerms = `${item?.name?.toLowerCase()}`;
|
item.searchTerms = `${item?.name?.toLowerCase()}`;
|
||||||
|
|
@ -53,6 +56,7 @@
|
||||||
if (collectionEmpty && localStorage?.collection && localStorage?.collection?.length !== 0) {
|
if (collectionEmpty && localStorage?.collection && localStorage?.collection?.length !== 0) {
|
||||||
const collection: SavedGameType[] = JSON.parse(localStorage.collection);
|
const collection: SavedGameType[] = JSON.parse(localStorage.collection);
|
||||||
if (collection?.length !== 0) {
|
if (collection?.length !== 0) {
|
||||||
|
collection.sort((a, b) => collator.compare(a.name, b.name));
|
||||||
for (const item of collection) {
|
for (const item of collection) {
|
||||||
if (!item?.searchTerms) {
|
if (!item?.searchTerms) {
|
||||||
item.searchTerms = `${item?.name?.toLowerCase()}`;
|
item.searchTerms = `${item?.name?.toLowerCase()}`;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import type { PageServerLoad } from "../$types";
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ fetch, url }) => {
|
export const load: PageServerLoad = async ({ fetch, url }) => {
|
||||||
const searchParams = Object.fromEntries(url?.searchParams);
|
const searchParams = Object.fromEntries(url?.searchParams);
|
||||||
const q = searchParams?.q;
|
const q = searchParams?.q;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$: skip = (page - 1) * pageSize;
|
$: skip = (page - 1) * pageSize;
|
||||||
$: gamesShown = $searchStore.filtered.slice(skip, skip + pageSize);
|
$: gamesShown = $searchStore.data.slice(skip, skip + pageSize);
|
||||||
$: totalItems = $searchStore.search === '' ? $collectionStore.length : $searchStore.filtered.length;
|
$: totalItems = $searchStore.search === '' ? $collectionStore.length : $searchStore.filtered.length;
|
||||||
|
|
||||||
interface RemoveGameEvent extends Event {
|
interface RemoveGameEvent extends Event {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
import LinkWithIcon from '$root/lib/components/LinkWithIcon.svelte';
|
import LinkWithIcon from '$root/lib/components/LinkWithIcon.svelte';
|
||||||
import { addToWishlist } from '$root/lib/util/manipulateWishlist';
|
import { addToWishlist } from '$root/lib/util/manipulateWishlist';
|
||||||
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
|
||||||
|
import { binarySearchOnStore } from '$root/lib/util/binarySearchOnStore';
|
||||||
|
import { convertToSavedGame } from '$root/lib/util/gameMapper';
|
||||||
|
|
||||||
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
|
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
|
||||||
$: existsInWishlist = $wishlistStore.find((item: SavedGameType) => item.id === game.id);
|
$: existsInWishlist = $wishlistStore.find((item: SavedGameType) => item.id === game.id);
|
||||||
|
|
@ -41,11 +43,13 @@
|
||||||
firstParagraphEnd = game?.description?.indexOf('</ p>') + 5;
|
firstParagraphEnd = game?.description?.indexOf('</ p>') + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCollectionClick() {
|
function onCollectionClick() {
|
||||||
if (existsInCollection) {
|
if (existsInCollection) {
|
||||||
removeFromCollection();
|
removeFromCollection();
|
||||||
} else {
|
} else {
|
||||||
addToCollection(game);
|
let index = binarySearchOnStore($collectionStore, convertToSavedGame(game), 'en');
|
||||||
|
console.log(`Binary index: ${index}`)
|
||||||
|
addToCollection(game, index);
|
||||||
if (browser) {
|
if (browser) {
|
||||||
localStorage.collection = JSON.stringify($collectionStore);
|
localStorage.collection = JSON.stringify($collectionStore);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue