diff --git a/packages/gui/package.json b/packages/gui/package.json index 187132a..77b5824 100644 --- a/packages/gui/package.json +++ b/packages/gui/package.json @@ -43,6 +43,8 @@ "@tauri-apps/api": "^1.2.0", "buffer": "^6.0.3", "fuse.js": "^6.6.2", + "lodash": "^4.17.21", + "lorem-ipsum": "^2.0.8", "svelte-watch-resize": "^1.0.3" }, "pnpm": { diff --git a/packages/gui/src/components/PackageReviews/PackageReviews.svelte b/packages/gui/src/components/PackageReviews/PackageReviews.svelte index 9833d7c..1d6b7f7 100644 --- a/packages/gui/src/components/PackageReviews/PackageReviews.svelte +++ b/packages/gui/src/components/PackageReviews/PackageReviews.svelte @@ -1,38 +1,47 @@ -
REVIEWS (31)
-
-
- +
REVIEWS ({reviews.length})
+
+
+ {#each col1 as review} + +
+ {/each}
-
- +
+ {#each col2 as review} + +
+ {/each}
-
- +
+ {#each col3 as review} + +
+ {/each}
diff --git a/packages/gui/src/components/SearchPackages/SearchPackages.svelte b/packages/gui/src/components/SearchPackages/SearchPackages.svelte index a83c5fe..5396224 100644 --- a/packages/gui/src/components/SearchPackages/SearchPackages.svelte +++ b/packages/gui/src/components/SearchPackages/SearchPackages.svelte @@ -19,6 +19,7 @@ const searchLimit = 5; const setPackages = (pkgs: Package[]) => { + console.log('pkgs sub', pkgs); packages = pkgs.sort((a, b) => { if (sortBy === 'popularity') { const aPop = +a.dl_count + a.installs; @@ -36,9 +37,12 @@ packagesStore.subscribe((v) => { allPackages = v; setPackages(allPackages); - packagesIndex = new Fuse(allPackages, { - keys: ['name', 'full_name', 'desc'] - }); + if (!packagesIndex) { + // dont remove or this can get crazy + packagesIndex = new Fuse(allPackages, { + keys: ['name', 'full_name', 'desc'] + }); + } }); onMount(async () => { diff --git a/packages/gui/src/libs/api/mock.ts b/packages/gui/src/libs/api/mock.ts index 5831955..70482d2 100644 --- a/packages/gui/src/libs/api/mock.ts +++ b/packages/gui/src/libs/api/mock.ts @@ -5,7 +5,10 @@ * TODO: * * make cors work with api.tea.xyz/v1 */ -import type { Package } from '../types'; +import type { Package, Review } from '@tea/ui/types'; +import { loremIpsum } from 'lorem-ipsum'; +import _ from 'lodash'; + const packages: Package[] = [ { slug: 'mesonbuild_com', @@ -156,3 +159,41 @@ export async function getPackages(): Promise { export async function getFeaturedPackages(): Promise { return packages.slice(0, 4); } + +export async function getPackageReviews(full_name: string): Promise { + console.log(`generating reviews for ${full_name}`); + + const reviewCount = _.random(7, 21); + const reviews: Review[] = []; + + for (let i = 0; i < reviewCount; i++) { + const title = loremIpsum({ + count: _.random(2, 5), + format: 'plain', + paragraphLowerBound: 3, + paragraphUpperBound: 7, + random: Math.random, + sentenceLowerBound: 5, + sentenceUpperBound: 15, + units: 'words' + }); + const comment = loremIpsum({ + count: 2, + format: 'plain', + paragraphLowerBound: 3, + paragraphUpperBound: 7, + random: Math.random, + sentenceLowerBound: 5, + sentenceUpperBound: 15, + units: 'sentences' + }); + const rating = _.random(0, 5); + reviews.push({ + title, + comment, + rating + }); + } + + return reviews; +} diff --git a/packages/gui/src/libs/api/tauri.ts b/packages/gui/src/libs/api/tauri.ts index 5d9f920..60bc07d 100644 --- a/packages/gui/src/libs/api/tauri.ts +++ b/packages/gui/src/libs/api/tauri.ts @@ -12,7 +12,7 @@ */ import { getClient } from '@tauri-apps/api/http'; import { Buffer } from 'buffer'; -import type { Package } from '../types'; +import type { Package, Review } from '../types'; import * as mock from './mock'; const username = 'user'; @@ -55,3 +55,10 @@ export async function getFeaturedPackages(): Promise { const packages = await mock.getFeaturedPackages(); return packages; } + +export async function getPackageReviews(full_name: string): Promise { + console.log(`getting reviews for ${full_name}`); + const reviews: Review[] = await mock.getPackageReviews(full_name); + + return reviews; +} diff --git a/packages/gui/src/libs/stores.ts b/packages/gui/src/libs/stores.ts index cb85595..4869c80 100644 --- a/packages/gui/src/libs/stores.ts +++ b/packages/gui/src/libs/stores.ts @@ -1,7 +1,9 @@ import { writable } from 'svelte/store'; -import type { Package } from './types'; +import type { Package, Review } from '@tea/ui/types'; -import { getPackages, getFeaturedPackages } from '@api'; +// TODO: figure out a better structure for managing states maybe turn them into models? + +import { getPackages, getFeaturedPackages, getPackageReviews } from '@api'; export const backLink = writable('/'); @@ -10,11 +12,51 @@ export const packages = writable([]); export const featuredPackages = writable([]); export const initializePackages = async () => { + console.log('initialize packages'); const newPackages = await getPackages(); packages.set(newPackages); }; export const initializeFeaturedPackages = async () => { + console.log('initialzie featured packages'); const packages = await getFeaturedPackages(); featuredPackages.set(packages); }; + +interface PackagesReview { + [full_name: string]: Review[]; +} + +function initPackagesReviewStore() { + const { set, update, subscribe } = writable({}); + + let packagesReviews: PackagesReview = {}; + + subscribe((v) => (packagesReviews = v)); + + const getSetPackageReviews = async (full_name: string) => { + if (full_name && !packagesReviews[full_name]) { + console.log('getting reviews for', full_name); + const reviews = await getPackageReviews(full_name); + update((v) => { + return { + ...v, + [full_name]: reviews + }; + }); + } + }; + + return { + subscribe: (full_name: string, reset: (reviews: Review[]) => void) => { + getSetPackageReviews(full_name); + return subscribe((value) => { + if (value[full_name]) { + reset(value[full_name]); + } + }); + } + }; +} + +export const packagesReviewStore = initPackagesReviewStore(); diff --git a/packages/gui/src/routes/packages/[slug]/+page.svelte b/packages/gui/src/routes/packages/[slug]/+page.svelte index d02fee2..65bd403 100644 --- a/packages/gui/src/routes/packages/[slug]/+page.svelte +++ b/packages/gui/src/routes/packages/[slug]/+page.svelte @@ -9,17 +9,24 @@ /** @type {import('./$types').PageData} */ export let data; - import { packages, featuredPackages } from '$libs/stores'; + import { packages, featuredPackages, packagesReviewStore } from '$libs/stores'; - import type { Package } from '@tea/ui/types'; + import type { Package, Review } from '@tea/ui/types'; let pkg: Package; + let reviews: Review[]; + const setPkg = (pkgs: Package[]) => { const foundPackage = pkgs.find(({ slug }) => slug === data?.slug) as Package; if (!pkg && foundPackage) { pkg = foundPackage; } + if (!reviews && pkg) { + packagesReviewStore.subscribe(pkg.full_name, (updatedReviews) => { + reviews = updatedReviews; + }); + } }; packages.subscribe(setPkg); @@ -32,6 +39,6 @@
- +
diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts index fed9a83..25415fd 100644 --- a/packages/ui/src/types.ts +++ b/packages/ui/src/types.ts @@ -1,3 +1,9 @@ +export interface Review { + title: string; + comment: string; + rating: number; + created_at?: Date | string; +} export interface Package { slug: string; version: string; @@ -11,11 +17,5 @@ export interface Package { desc: string; dl_count: number; installs: number; -} - -export interface Review { - title: string; - comment: string; - rating: number; - created_at?: Date | string; + reviews?: Review[]; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 376ddb4..0321477 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,8 @@ importers: eslint-config-prettier: ^8.3.0 eslint-plugin-svelte3: ^4.0.0 fuse.js: ^6.6.2 + lodash: ^4.17.21 + lorem-ipsum: ^2.0.8 postcss: ^8.4.19 prettier: ^2.6.2 prettier-plugin-svelte: ^2.7.0 @@ -38,12 +40,14 @@ importers: '@tauri-apps/api': 1.2.0 buffer: 6.0.3 fuse.js: 6.6.2 + lodash: 4.17.21 + lorem-ipsum: 2.0.8 svelte-watch-resize: 1.0.3 devDependencies: '@playwright/test': 1.25.0 '@sveltejs/adapter-auto': 1.0.0-next.90 '@sveltejs/adapter-static': 1.0.0-next.48 - '@sveltejs/kit': 1.0.0-next.567_svelte@3.53.1+vite@3.2.4 + '@sveltejs/kit': 1.0.0-next.570_svelte@3.53.1+vite@3.2.4 '@tauri-apps/cli': 1.2.0 '@tea/ui': link:../ui '@typescript-eslint/eslint-plugin': 5.43.0_wze2rj5tow7zwqpgbdx2buoy3m @@ -3206,34 +3210,6 @@ packages: resolution: {integrity: sha512-Z5Z+QZOav6D0KDeU3ReksGERJg/sX1k5OKWWXyQ11OwGErEEwSXHYRUyjaBmZEPeGzpVVGwwMUK8YWJlG/MKeA==} dev: true - /@sveltejs/kit/1.0.0-next.567_svelte@3.53.1+vite@3.2.4: - resolution: {integrity: sha512-4Q74HPLZb9Rr60n7EJANXH2Ng3d7wwrz67TuXxVfYuxARigWO9YzjcLHxG2IVMwRZIeT+LlwOKkg9vYYdBiezQ==} - engines: {node: '>=16.14'} - hasBin: true - requiresBuild: true - peerDependencies: - svelte: ^3.44.0 - vite: ^3.2.0 - dependencies: - '@sveltejs/vite-plugin-svelte': 1.3.1_svelte@3.53.1+vite@3.2.4 - '@types/cookie': 0.5.1 - cookie: 0.5.0 - devalue: 4.2.0 - kleur: 4.1.5 - magic-string: 0.26.7 - mime: 3.0.0 - sade: 1.8.1 - set-cookie-parser: 2.5.1 - sirv: 2.0.2 - svelte: 3.53.1 - tiny-glob: 0.2.9 - undici: 5.13.0 - vite: 3.2.4 - transitivePeerDependencies: - - diff-match-patch - - supports-color - dev: true - /@sveltejs/kit/1.0.0-next.570_svelte@3.53.1+vite@3.2.4: resolution: {integrity: sha512-7CUoYidoWlKdTGxL/5RsPPkgGTb36TwFBnhSZmspHFeiIST5qQEXyzqicFk8+4M5qQhxvOZ0NuP8uy7Pc+xf/Q==} engines: {node: '>=16.14'} @@ -4634,6 +4610,11 @@ packages: engines: {node: '>= 6'} dev: true + /commander/9.4.1: + resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} + engines: {node: ^12.20.0 || >=14} + dev: false + /commondir/1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: true @@ -7341,7 +7322,6 @@ packages: /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true /longest-streak/3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -7354,6 +7334,14 @@ packages: js-tokens: 4.0.0 dev: true + /lorem-ipsum/2.0.8: + resolution: {integrity: sha512-5RIwHuCb979RASgCJH0VKERn9cQo/+NcAi2BMe9ddj+gp7hujl6BI+qdOG4nVsLDpwWEJwTVYXNKP6BGgbcoGA==} + engines: {node: '>= 8.x', npm: '>= 5.x'} + hasBin: true + dependencies: + commander: 9.4.1 + dev: false + /lower-case/2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: