mirror of
https://github.com/ivabus/gui
synced 2025-06-07 15:50:27 +03:00
New image format (#675)
* use new image loading strategy: infer from gui.tea.xyz/stage/pkgFullname/dimension.webp
This commit is contained in:
parent
0dc057af8d
commit
53224e21b9
10 changed files with 88 additions and 106 deletions
|
@ -3,10 +3,12 @@ import { mkdirp } from "mkdirp";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import log from "./logger";
|
import log from "./logger";
|
||||||
import { getTeaPath } from "./tea-dir";
|
import { getTeaPath } from "./tea-dir";
|
||||||
import { Packages } from "../../src/libs/types";
|
import { GUIPackage, Packages } from "../../src/libs/types";
|
||||||
|
import { isDev } from "./auto-updater";
|
||||||
|
|
||||||
const pkgsFilePath = path.join(getTeaPath(), "tea.xyz/gui/pkgs.json");
|
const pkgsFilePath = path.join(getTeaPath(), "tea.xyz/gui/pkgs.json");
|
||||||
const pkgsFolder = path.join(getTeaPath(), "tea.xyz/gui");
|
const pkgsFolder = path.join(getTeaPath(), "tea.xyz/gui");
|
||||||
|
const dev = isDev();
|
||||||
|
|
||||||
export async function writePackageCache(pkgs: Packages) {
|
export async function writePackageCache(pkgs: Packages) {
|
||||||
try {
|
try {
|
||||||
|
@ -29,13 +31,19 @@ export async function loadPackageCache(): Promise<Packages> {
|
||||||
log.info(`loading package cache from ${pkgsFilePath}`);
|
log.info(`loading package cache from ${pkgsFilePath}`);
|
||||||
const pkgData = fs.readFileSync(pkgsFilePath);
|
const pkgData = fs.readFileSync(pkgsFilePath);
|
||||||
const pkgs = JSON.parse(pkgData.toString()) as Packages;
|
const pkgs = JSON.parse(pkgData.toString()) as Packages;
|
||||||
|
|
||||||
if (pkgs?.packages) {
|
if (pkgs?.packages) {
|
||||||
// Remove any temporary properties that may have been added to the package (like installation progress)
|
// Remove any temporary properties that may have been added to the package (like installation progress)
|
||||||
for (const [key, value] of Object.entries(pkgs.packages)) {
|
for (const [key, value] of Object.entries(pkgs.packages)) {
|
||||||
const { install_progress_percentage, isUninstalling, synced, displayState, ...rest } =
|
const { install_progress_percentage, isUninstalling, synced, displayState, ...rest } =
|
||||||
value;
|
value;
|
||||||
pkgs.packages[key] = rest;
|
pkgs.packages[key] = rest as GUIPackage;
|
||||||
|
// possible user deletes cache files
|
||||||
|
delete pkgs.packages[key].cached_image_url;
|
||||||
|
if (rest.image_added_at) {
|
||||||
|
const prefix = `https://gui.tea.xyz/${dev ? "dev" : "prod"}/${rest.full_name}`;
|
||||||
|
pkgs.packages[key].image_128_url = `${prefix}/128x128.webp`;
|
||||||
|
pkgs.packages[key].image_512_url = `${prefix}/512x512.webp`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pkgs;
|
return pkgs;
|
||||||
|
|
|
@ -163,18 +163,24 @@ async function downloadImage(url: string, imagePath: string): Promise<void> {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const fileStream = fs.createWriteStream(imagePath);
|
const fileStream = fs.createWriteStream(imagePath);
|
||||||
|
if (response.status == 200) {
|
||||||
response.body.pipe(fileStream);
|
response.body.pipe(fileStream);
|
||||||
fileStream.on("finish", () => resolve());
|
fileStream.on("finish", () => resolve());
|
||||||
fileStream.on("error", (error) => reject(error));
|
fileStream.on("error", (error) => reject(error));
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Failed to download image: ${url}`));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cacheImage(url: string): Promise<string> {
|
export async function cacheImage(url: string): Promise<string> {
|
||||||
const imageFolder = path.join(getGuiPath(), "cached_images");
|
const imageFolder = path.join(getGuiPath(), "cached_images");
|
||||||
const imageName = path.basename(url);
|
const pkgFilePath = url.split("gui.tea.xyz")[1];
|
||||||
const imagePath = path.join(imageFolder, imageName);
|
const imagePath = path.join(imageFolder, pkgFilePath);
|
||||||
|
const fileName = path.basename(imagePath);
|
||||||
await mkdirp(imageFolder);
|
const folderPath = imagePath.replace(fileName, "");
|
||||||
|
log.info("creating folder:", folderPath);
|
||||||
|
await mkdirp(folderPath);
|
||||||
|
|
||||||
if (!fs.existsSync(imagePath)) {
|
if (!fs.existsSync(imagePath)) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "tea",
|
"name": "tea",
|
||||||
"version": "0.2.27",
|
"version": "0.2.28",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "tea gui app",
|
"description": "tea gui app",
|
||||||
"author": "tea.xyz",
|
"author": "tea.xyz",
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import "$appcss";
|
|
||||||
import { onMount } from "svelte";
|
|
||||||
import type { Package } from "@tea/ui/types";
|
|
||||||
|
|
||||||
import Gallery from "@tea/ui/gallery/gallery.svelte";
|
|
||||||
import {
|
|
||||||
featuredPackages as featuredPackagesStore,
|
|
||||||
initializeFeaturedPackages
|
|
||||||
} from "$libs/stores";
|
|
||||||
|
|
||||||
let featuredPackages: Package[] = [];
|
|
||||||
|
|
||||||
featuredPackagesStore.subscribe((v) => {
|
|
||||||
featuredPackages = v;
|
|
||||||
});
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (!featuredPackages.length) {
|
|
||||||
initializeFeaturedPackages();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Gallery
|
|
||||||
title="FEATURED PACKAGES"
|
|
||||||
items={featuredPackages.map((pkg) => ({
|
|
||||||
title: pkg.full_name,
|
|
||||||
subTitle: pkg.maintainer || "",
|
|
||||||
imageUrl: pkg.thumb_image_url,
|
|
||||||
link: `/packages/${pkg.slug}`
|
|
||||||
}))}
|
|
||||||
/>
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { GUIPackage } from "$libs/types";
|
import type { GUIPackage } from "$libs/types";
|
||||||
import { onMount } from "svelte";
|
|
||||||
import { packagesStore } from "$libs/stores";
|
import { packagesStore } from "$libs/stores";
|
||||||
|
|
||||||
let clazz = "";
|
let clazz = "";
|
||||||
|
@ -15,8 +14,8 @@
|
||||||
let loaded = false;
|
let loaded = false;
|
||||||
let lastProcessedPkg: GUIPackage | null = null;
|
let lastProcessedPkg: GUIPackage | null = null;
|
||||||
|
|
||||||
const loadImage = async (url: string): Promise<string> => {
|
const loadImage = async (url: string, force = false): Promise<string> => {
|
||||||
if (url.includes("cached_images")) {
|
if (url.includes("cached_images") || force) {
|
||||||
loadedImg = url;
|
loadedImg = url;
|
||||||
loaded = true;
|
loaded = true;
|
||||||
return url;
|
return url;
|
||||||
|
@ -38,21 +37,12 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const recachePkg = async () => {
|
|
||||||
const url = await packagesStore.cachePkgImage(pkg);
|
|
||||||
loadImage(url);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getCache = async () => {
|
const getCache = async () => {
|
||||||
if (pkg.cached_image_url) {
|
if (pkg.image_512_url) {
|
||||||
loadImage(pkg.cached_image_url).catch(() => {
|
loadImage(pkg.image_512_url, true).finally(async () => {
|
||||||
if (pkg.thumb_image_url) {
|
const nextImage = await packagesStore.cachePkgImage(pkg);
|
||||||
loadImage(pkg.thumb_image_url);
|
loadImage(nextImage, true);
|
||||||
recachePkg();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else if (pkg.thumb_image_url) {
|
|
||||||
recachePkg();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,7 +59,7 @@
|
||||||
<section class="overflow-hidden bg-black {clazz} {layout}">
|
<section class="overflow-hidden bg-black {clazz} {layout}">
|
||||||
<i
|
<i
|
||||||
class="logo icon-tea-logo-iconasset-1 text-3xl text-gray {layout}"
|
class="logo icon-tea-logo-iconasset-1 text-3xl text-gray {layout}"
|
||||||
class:animate-pulse={!pkg.thumb_image_url}
|
class:animate-pulse={!pkg.image_added_at}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="opacity-0 transition-all duration-500 {layout}"
|
class="opacity-0 transition-all duration-500 {layout}"
|
||||||
|
|
|
@ -24,9 +24,7 @@
|
||||||
<ImgLoader
|
<ImgLoader
|
||||||
on:click={() => gotoPackagePage()}
|
on:click={() => gotoPackagePage()}
|
||||||
class="pkg-image h-16 w-16 object-cover"
|
class="pkg-image h-16 w-16 object-cover"
|
||||||
src={!pkg.thumb_image_url.includes("https://tea.xyz")
|
src={pkg.image_128_url || "/images/default-thumb.jpg"}
|
||||||
? "/images/default-thumb.jpg"
|
|
||||||
: pkg.thumb_image_url}
|
|
||||||
alt={pkg.name}
|
alt={pkg.name}
|
||||||
/>
|
/>
|
||||||
<header data-testid="card-result-{pkg.slug}" class="flex-grow" on:click={() => gotoPackagePage()}>
|
<header data-testid="card-result-{pkg.slug}" class="flex-grow" on:click={() => gotoPackagePage()}>
|
||||||
|
|
|
@ -20,15 +20,14 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-06T15:45:08.000Z",
|
last_modified: "2022-10-06T15:45:08.000Z",
|
||||||
full_name: "mesonbuild.com",
|
full_name: "mesonbuild.com",
|
||||||
dl_count: 270745,
|
dl_count: 270745,
|
||||||
thumb_image_name: "mesonbuild_com_option 1.jpg ",
|
|
||||||
maintainer: "",
|
maintainer: "",
|
||||||
desc: "Fast and user friendly build system",
|
desc: "Fast and user friendly build system",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/mesonbuild_com.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["foundation_essentials"],
|
categories: ["foundation_essentials"],
|
||||||
created: "2022-10-06T15:45:08.000Z",
|
created: "2022-10-06T15:45:08.000Z",
|
||||||
manual_sorting: 0,
|
manual_sorting: 0,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "pixman_org",
|
slug: "pixman_org",
|
||||||
|
@ -39,14 +38,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-09-26T19:37:47.000Z",
|
last_modified: "2022-09-26T19:37:47.000Z",
|
||||||
full_name: "pixman.org",
|
full_name: "pixman.org",
|
||||||
dl_count: 0,
|
dl_count: 0,
|
||||||
thumb_image_name: "pixman_org_option 1.jpg ",
|
|
||||||
desc: "Pixman is a library that provides low-level pixel manipulation features such as image compositing and trapezoid rasterization.",
|
desc: "Pixman is a library that provides low-level pixel manipulation features such as image compositing and trapezoid rasterization.",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/pixman_org.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["foundation_essentials"],
|
categories: ["foundation_essentials"],
|
||||||
created: "2022-09-26T19:37:47.000Z",
|
created: "2022-09-26T19:37:47.000Z",
|
||||||
manual_sorting: 1,
|
manual_sorting: 1,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "freedesktop_org_pkg_config",
|
slug: "freedesktop_org_pkg_config",
|
||||||
|
@ -57,14 +55,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-20T01:32:15.000Z",
|
last_modified: "2022-10-20T01:32:15.000Z",
|
||||||
full_name: "freedesktop.org/pkg-config",
|
full_name: "freedesktop.org/pkg-config",
|
||||||
dl_count: 2661501,
|
dl_count: 2661501,
|
||||||
thumb_image_name: "freedecktop_org_pkg_config option 1.jpg ",
|
|
||||||
desc: "Manage compile and link flags for libraries",
|
desc: "Manage compile and link flags for libraries",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/freedesktop_org_pkg_config.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["foundation_essentials"],
|
categories: ["foundation_essentials"],
|
||||||
created: "2022-10-20T01:32:15.000Z",
|
created: "2022-10-20T01:32:15.000Z",
|
||||||
manual_sorting: 2,
|
manual_sorting: 2,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "gnu_org_gettext",
|
slug: "gnu_org_gettext",
|
||||||
|
@ -75,14 +72,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-20T01:23:46.000Z",
|
last_modified: "2022-10-20T01:23:46.000Z",
|
||||||
full_name: "gnu.org/gettext",
|
full_name: "gnu.org/gettext",
|
||||||
dl_count: 3715970,
|
dl_count: 3715970,
|
||||||
thumb_image_name: "gnu_org_gettext_option 1.jpg ",
|
|
||||||
desc: "GNU internationalization (i18n) and localization (l10n) library",
|
desc: "GNU internationalization (i18n) and localization (l10n) library",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/gnu_org_gettext.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["foundation_essentials"],
|
categories: ["foundation_essentials"],
|
||||||
created: "2022-10-20T01:23:46.000Z",
|
created: "2022-10-20T01:23:46.000Z",
|
||||||
manual_sorting: 3,
|
manual_sorting: 3,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "ipfs_tech",
|
slug: "ipfs_tech",
|
||||||
|
@ -92,15 +88,14 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-19T21:36:52.000Z",
|
last_modified: "2022-10-19T21:36:52.000Z",
|
||||||
full_name: "ipfs.tech",
|
full_name: "ipfs.tech",
|
||||||
dl_count: 14457,
|
dl_count: 14457,
|
||||||
thumb_image_name: "ipfs_tech_option 2.jpg ",
|
|
||||||
maintainer: "",
|
maintainer: "",
|
||||||
desc: "Peer-to-peer hypermedia protocol",
|
desc: "Peer-to-peer hypermedia protocol",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/ipfs_tech.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["foundation_essentials"],
|
categories: ["foundation_essentials"],
|
||||||
created: "2022-10-19T21:36:52.000Z",
|
created: "2022-10-19T21:36:52.000Z",
|
||||||
manual_sorting: 4,
|
manual_sorting: 4,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "nixos_org_patchelf",
|
slug: "nixos_org_patchelf",
|
||||||
|
@ -111,14 +106,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-09-27T04:50:44.000Z",
|
last_modified: "2022-09-27T04:50:44.000Z",
|
||||||
full_name: "nixos.org/patchelf",
|
full_name: "nixos.org/patchelf",
|
||||||
dl_count: 0,
|
dl_count: 0,
|
||||||
thumb_image_name: "nixos_org_patchelf_option 1.jpg ",
|
|
||||||
desc: "PatchELF is a simple utility for modifying existing ELF executables and libraries.",
|
desc: "PatchELF is a simple utility for modifying existing ELF executables and libraries.",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/nixos_org_patchelf.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["top_packages", "foundation_essentials"],
|
categories: ["top_packages", "foundation_essentials"],
|
||||||
created: "2022-09-27T04:50:44.000Z",
|
created: "2022-09-27T04:50:44.000Z",
|
||||||
manual_sorting: 5,
|
manual_sorting: 5,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "tea_xyz",
|
slug: "tea_xyz",
|
||||||
|
@ -129,14 +123,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-19T19:13:51.000Z",
|
last_modified: "2022-10-19T19:13:51.000Z",
|
||||||
full_name: "tea.xyz",
|
full_name: "tea.xyz",
|
||||||
dl_count: 0,
|
dl_count: 0,
|
||||||
thumb_image_name: "tea_xyz_option 2.jpg ",
|
|
||||||
desc: "Website of tea.xyz",
|
desc: "Website of tea.xyz",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/tea_xyz.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["top_packages", "foundation_essentials"],
|
categories: ["top_packages", "foundation_essentials"],
|
||||||
created: "2022-10-19T19:13:51.000Z",
|
created: "2022-10-19T19:13:51.000Z",
|
||||||
manual_sorting: 6,
|
manual_sorting: 6,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "charm_sh_gum",
|
slug: "charm_sh_gum",
|
||||||
|
@ -147,14 +140,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-21T02:15:16.000Z",
|
last_modified: "2022-10-21T02:15:16.000Z",
|
||||||
full_name: "charm.sh/gum",
|
full_name: "charm.sh/gum",
|
||||||
dl_count: 0,
|
dl_count: 0,
|
||||||
thumb_image_name: "charm_sh_gum.jpg ",
|
|
||||||
desc: "",
|
desc: "",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/charm_sh_gum.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["top_packages", "foundation_essentials"],
|
categories: ["top_packages", "foundation_essentials"],
|
||||||
created: "2022-10-21T02:15:16.000Z",
|
created: "2022-10-21T02:15:16.000Z",
|
||||||
manual_sorting: 7,
|
manual_sorting: 7,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "pyyaml_org",
|
slug: "pyyaml_org",
|
||||||
|
@ -164,15 +156,14 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-03T15:35:14.000Z",
|
last_modified: "2022-10-03T15:35:14.000Z",
|
||||||
full_name: "pyyaml.org",
|
full_name: "pyyaml.org",
|
||||||
dl_count: 107505,
|
dl_count: 107505,
|
||||||
thumb_image_name: "pyyaml_org_option 1.jpg ",
|
|
||||||
maintainer: "",
|
maintainer: "",
|
||||||
desc: "YAML framework for Python",
|
desc: "YAML framework for Python",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/pyyaml_org.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["top_packages", "foundation_essentials"],
|
categories: ["top_packages", "foundation_essentials"],
|
||||||
created: "2022-10-03T15:35:14.000Z",
|
created: "2022-10-03T15:35:14.000Z",
|
||||||
manual_sorting: 8,
|
manual_sorting: 8,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
slug: "tea_xyz_gx_cc",
|
slug: "tea_xyz_gx_cc",
|
||||||
|
@ -183,14 +174,13 @@ const packages: Package[] = [
|
||||||
last_modified: "2022-10-19T16:47:44.000Z",
|
last_modified: "2022-10-19T16:47:44.000Z",
|
||||||
full_name: "tea.xyz/gx/cc",
|
full_name: "tea.xyz/gx/cc",
|
||||||
dl_count: 0,
|
dl_count: 0,
|
||||||
thumb_image_name: "tea_xyz_gx.jpg ",
|
|
||||||
desc: "",
|
desc: "",
|
||||||
thumb_image_url: "https://tea.xyz/Images/packages/tea_xyz_gx_cc.jpg",
|
|
||||||
installs: 0,
|
installs: 0,
|
||||||
categories: ["top_packages", "foundation_essentials"],
|
categories: ["top_packages", "foundation_essentials"],
|
||||||
created: "2022-10-19T16:47:44.000Z",
|
created: "2022-10-19T16:47:44.000Z",
|
||||||
manual_sorting: 9,
|
manual_sorting: 9,
|
||||||
card_layout: "bottom"
|
card_layout: "bottom",
|
||||||
|
image_added_at: new Date()
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ import {
|
||||||
listenToChannel,
|
listenToChannel,
|
||||||
getInstalledVersionsForPackage,
|
getInstalledVersionsForPackage,
|
||||||
monitorTeaDir,
|
monitorTeaDir,
|
||||||
stopMonitoringTeaDir
|
stopMonitoringTeaDir,
|
||||||
|
isDev
|
||||||
} from "@native";
|
} from "@native";
|
||||||
|
|
||||||
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
||||||
|
@ -38,6 +39,8 @@ let initialized = false;
|
||||||
let isDestroyed = false;
|
let isDestroyed = false;
|
||||||
let refreshTimeoutId: ReturnType<typeof setTimeout> | null = null;
|
let refreshTimeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
|
const dev = isDev();
|
||||||
|
|
||||||
const packageMap = writable<Packages>({ version: "0", packages: {} });
|
const packageMap = writable<Packages>({ version: "0", packages: {} });
|
||||||
const packageList = derived(packageMap, ($packages) =>
|
const packageList = derived(packageMap, ($packages) =>
|
||||||
Object.values($packages.packages).sort((a, b) => {
|
Object.values($packages.packages).sort((a, b) => {
|
||||||
|
@ -162,12 +165,22 @@ const refreshPackages = async () => {
|
||||||
if (isDestroyed) return;
|
if (isDestroyed) return;
|
||||||
|
|
||||||
log.info("packages store: refreshing...");
|
log.info("packages store: refreshing...");
|
||||||
|
const isDev = await dev;
|
||||||
const pkgs = await getDistPackages();
|
const pkgs = await getDistPackages();
|
||||||
const guiPkgs: GUIPackage[] = pkgs.map((p) => ({
|
|
||||||
|
const guiPkgs: GUIPackage[] = pkgs.map((p) => {
|
||||||
|
const prefix = `https://gui.tea.xyz/${isDev ? "dev" : "prod"}/${p.full_name}`;
|
||||||
|
return {
|
||||||
...p,
|
...p,
|
||||||
state: PackageStates.AVAILABLE
|
state: PackageStates.AVAILABLE,
|
||||||
}));
|
...(p.image_added_at
|
||||||
|
? {
|
||||||
|
image_512_url: `${prefix}/512x512.webp`,
|
||||||
|
image_128_url: `${prefix}/128x128.webp`
|
||||||
|
}
|
||||||
|
: {})
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
// set packages data so that i can render something in the UI already
|
// set packages data so that i can render something in the UI already
|
||||||
|
@ -291,8 +304,8 @@ packageMap.subscribe(async (pkgs) => {
|
||||||
const cachePkgImage = async (pkg: GUIPackage): Promise<string> => {
|
const cachePkgImage = async (pkg: GUIPackage): Promise<string> => {
|
||||||
let cacheFileURL = "";
|
let cacheFileURL = "";
|
||||||
updatePackage(pkg.full_name, { cached_image_url: "" });
|
updatePackage(pkg.full_name, { cached_image_url: "" });
|
||||||
if (pkg.thumb_image_url && !pkg.thumb_image_url.includes("package-thumb-nolabel4.jpg")) {
|
if (pkg.image_added_at && pkg.image_512_url) {
|
||||||
const result = await cacheImageURL(pkg.thumb_image_url);
|
const result = await cacheImageURL(pkg.image_512_url);
|
||||||
if (result) {
|
if (result) {
|
||||||
cacheFileURL = result;
|
cacheFileURL = result;
|
||||||
updatePackage(pkg.full_name, { cached_image_url: cacheFileURL });
|
updatePackage(pkg.full_name, { cached_image_url: cacheFileURL });
|
||||||
|
@ -301,6 +314,15 @@ const cachePkgImage = async (pkg: GUIPackage): Promise<string> => {
|
||||||
return cacheFileURL;
|
return cacheFileURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getPackageImageURL = async (
|
||||||
|
pkg: GUIPackage,
|
||||||
|
size: 512 | 1024 | 128
|
||||||
|
): Promise<string> => {
|
||||||
|
if (!pkg.image_added_at) return "";
|
||||||
|
const isDev = await dev;
|
||||||
|
return `https://gui.tea.xyz/${isDev ? "dev" : "prod"}/${pkg.full_name}/${size}x${size}.webp`;
|
||||||
|
};
|
||||||
|
|
||||||
listenToChannel("install-progress", ({ full_name, progress }: any) => {
|
listenToChannel("install-progress", ({ full_name, progress }: any) => {
|
||||||
if (!full_name) {
|
if (!full_name) {
|
||||||
return;
|
return;
|
||||||
|
@ -387,5 +409,6 @@ export default {
|
||||||
destroy,
|
destroy,
|
||||||
cachePkgImage,
|
cachePkgImage,
|
||||||
resetPackageDisplayState,
|
resetPackageDisplayState,
|
||||||
resetAllPackagesUpdatedState
|
resetAllPackagesUpdatedState,
|
||||||
|
getPackageImageURL
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,8 @@ export type GUIPackage = Package & {
|
||||||
install_progress_percentage?: number;
|
install_progress_percentage?: number;
|
||||||
isUninstalling?: boolean;
|
isUninstalling?: boolean;
|
||||||
cached_image_url?: string;
|
cached_image_url?: string;
|
||||||
|
image_512_url?: string;
|
||||||
|
image_128_url?: string;
|
||||||
displayState?: PackageDisplayState | null;
|
displayState?: PackageDisplayState | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,6 @@ export interface Package {
|
||||||
homepage: string;
|
homepage: string;
|
||||||
last_modified: Date | string;
|
last_modified: Date | string;
|
||||||
created: Date | string;
|
created: Date | string;
|
||||||
thumb_image_url: string;
|
|
||||||
thumb_image_name: string;
|
|
||||||
desc: string;
|
desc: string;
|
||||||
dl_count: number;
|
dl_count: number;
|
||||||
installs: number;
|
installs: number;
|
||||||
|
@ -37,6 +35,7 @@ export interface Package {
|
||||||
};
|
};
|
||||||
manual_sorting: number;
|
manual_sorting: number;
|
||||||
card_layout: "bottom" | "right" | "left";
|
card_layout: "bottom" | "right" | "left";
|
||||||
|
image_added_at: Date | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AirtablePost = {
|
export type AirtablePost = {
|
||||||
|
|
Loading…
Reference in a new issue