mirror of
https://github.com/ivabus/gui
synced 2025-04-23 14:07:14 +03:00
suggest package update (#253)
* #246 prepare pkg shape detect if needs to update * #246 optimize package card usage --------- Co-authored-by: neil <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
ba7be4230d
commit
0c467b08aa
9 changed files with 74 additions and 59 deletions
28
modules/desktop/src/components/packages/package.svelte
Normal file
28
modules/desktop/src/components/packages/package.svelte
Normal file
|
@ -0,0 +1,28 @@
|
|||
<script lang="ts">
|
||||
import '$appcss';
|
||||
import PackageCard from '@tea/ui/package-card/package-card.svelte';
|
||||
import { t } from '$libs/translations';
|
||||
import type { GUIPackage } from '$libs/types';
|
||||
import { PackageStates } from '$libs/types';
|
||||
|
||||
|
||||
export let pkg: GUIPackage;
|
||||
export let onClick: () => void;
|
||||
|
||||
const getCTALabel = (state: PackageStates): string => {
|
||||
return {
|
||||
[PackageStates.AVAILABLE]: $t("package.install-label").toUpperCase(),
|
||||
[PackageStates.INSTALLED]: $t("package.installed-label").toUpperCase(),
|
||||
[PackageStates.INSTALLING]: $t("package.installing-label").toUpperCase(),
|
||||
[PackageStates.UNINSTALLED]: $t("package.reinstall-label").toUpperCase(),
|
||||
[PackageStates.NEEDS_UPDATE]: $t("package.needs-update-label").toUpperCase(),
|
||||
}[state];
|
||||
};
|
||||
</script>
|
||||
|
||||
<PackageCard
|
||||
{pkg}
|
||||
link={`/packages/${pkg.slug}`}
|
||||
ctaLabel={getCTALabel(pkg.state)}
|
||||
onClickCTA={onClick}
|
||||
/>
|
|
@ -4,7 +4,7 @@
|
|||
import type { GUIPackage } from '$libs/types';
|
||||
import { PackageStates } from '$libs/types';
|
||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
||||
import PackageCard from '@tea/ui/package-card/package-card.svelte';
|
||||
import Package from "./package.svelte";
|
||||
import { packagesStore } from '$libs/stores';
|
||||
|
||||
import { installPackage } from '@native';
|
||||
|
@ -15,15 +15,6 @@
|
|||
|
||||
let packages: GUIPackage[] = [];
|
||||
|
||||
const getCTALabel = (state: PackageStates): string => {
|
||||
return {
|
||||
[PackageStates.AVAILABLE]: $t("package.install-label").toUpperCase(),
|
||||
[PackageStates.INSTALLED]: $t("package.installed-label").toUpperCase(),
|
||||
[PackageStates.INSTALLING]: $t("package.installing-label").toUpperCase(),
|
||||
[PackageStates.UNINSTALLED]: $t("package.reinstall-label").toUpperCase(),
|
||||
}[state];
|
||||
};
|
||||
|
||||
packagesStore.subscribe((ps) => {
|
||||
packages = category ?
|
||||
ps.filter((p) => (p.categories || []).includes(category)) :
|
||||
|
@ -39,11 +30,9 @@
|
|||
{#if packages.length > 0}
|
||||
{#each packages as pkg}
|
||||
<div class={pkg.state === PackageStates.INSTALLING ? 'animate-pulse' : ''}>
|
||||
<PackageCard
|
||||
<Package
|
||||
{pkg}
|
||||
link={`/packages/${pkg.slug}`}
|
||||
ctaLabel={getCTALabel(pkg.state)}
|
||||
onClickCTA={async () => {
|
||||
onClick={async () => {
|
||||
try {
|
||||
pkg.state = PackageStates.INSTALLING;
|
||||
await installPackage(pkg.full_name);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
import SortingButtons from './sorting-buttons.svelte';
|
||||
import type { GUIPackage } from '$libs/types';
|
||||
import { PackageStates } from '$libs/types';
|
||||
import PackageCard from '@tea/ui/package-card/package-card.svelte';
|
||||
import Package from "$components/packages/package.svelte";
|
||||
import SearchInput from '@tea/ui/search-input/search-input.svelte';
|
||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
||||
|
||||
|
@ -50,15 +50,6 @@
|
|||
setPackages(packages);
|
||||
};
|
||||
|
||||
const getCTALabel = (state: PackageStates): string => {
|
||||
return {
|
||||
[PackageStates.AVAILABLE]: $t("package.install-label").toUpperCase(),
|
||||
[PackageStates.INSTALLED]: $t("package.installed-label").toUpperCase(),
|
||||
[PackageStates.INSTALLING]: $t("package.installing-label").toUpperCase(),
|
||||
[PackageStates.UNINSTALLED]: $t("package.reinstall-label").toUpperCase(),
|
||||
}[state];
|
||||
};
|
||||
|
||||
packagesStore.subscribe(setPackages);
|
||||
</script>
|
||||
|
||||
|
@ -77,11 +68,9 @@
|
|||
{#if packages.length > 0}
|
||||
{#each packages as pkg}
|
||||
<div class={pkg.state === PackageStates.INSTALLING ? 'animate-pulse' : ''}>
|
||||
<PackageCard
|
||||
<Package
|
||||
{pkg}
|
||||
link={`/packages/${pkg.slug}`}
|
||||
ctaLabel={getCTALabel(pkg.state)}
|
||||
onClickCTA={async () => {
|
||||
onClick={async () => {
|
||||
try {
|
||||
pkg.state = PackageStates.INSTALLING;
|
||||
await installPackage(pkg.full_name);
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { searchStore } from '$libs/stores';
|
||||
import { t } from '$libs/translations';
|
||||
import type { GUIPackage } from '$libs/types';
|
||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
||||
import PackageCard from '@tea/ui/package-card/package-card.svelte';
|
||||
import Package from "$components/packages/package.svelte";
|
||||
import { PackageStates } from '$libs/types';
|
||||
import Posts from '@tea/ui/posts/posts.svelte';
|
||||
|
||||
|
@ -39,15 +38,6 @@
|
|||
|
||||
searchStore.searching.subscribe((v) => (loading = v));
|
||||
|
||||
const getCTALabel = (state: PackageStates): string => {
|
||||
return {
|
||||
[PackageStates.AVAILABLE]: $t("package.install-label").toUpperCase(),
|
||||
[PackageStates.INSTALLED]: $t("package.installed-label").toUpperCase(),
|
||||
[PackageStates.INSTALLING]: $t("package.installing-label").toUpperCase(),
|
||||
[PackageStates.UNINSTALLED]: $t("package.reinstall-label").toUpperCase(),
|
||||
}[state];
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
term = '';
|
||||
};
|
||||
|
@ -74,11 +64,9 @@
|
|||
{#if packages.length > 0}
|
||||
{#each packages as pkg}
|
||||
<div class={pkg.state === PackageStates.INSTALLING ? 'animate-pulse' : ''}>
|
||||
<PackageCard
|
||||
<Package
|
||||
{pkg}
|
||||
link={`/packages/${pkg.slug}`}
|
||||
ctaLabel={getCTALabel(pkg.state)}
|
||||
onClickCTA={async () => {
|
||||
onClick={async () => {
|
||||
try {
|
||||
pkg.state = PackageStates.INSTALLING;
|
||||
await installPackage(pkg.full_name);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<script lang="ts">
|
||||
import '$appcss';
|
||||
import { t } from '$libs/translations';
|
||||
import type { GUIPackage } from '$libs/types';
|
||||
import type { Package } from '@tea/ui/types';
|
||||
import { PackageStates } from '$libs/types';
|
||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
||||
import PackageCard from '@tea/ui/package-card/package-card.svelte';
|
||||
import PackageCard from "$components/packages/package.svelte";
|
||||
import { onMount } from 'svelte';
|
||||
import { installPackage } from '@native';
|
||||
import { packagesStore } from '$libs/stores';
|
||||
|
@ -14,15 +13,6 @@
|
|||
|
||||
let packages: GUIPackage[] = [];
|
||||
|
||||
const getCTALabel = (state: PackageStates): string => {
|
||||
return {
|
||||
[PackageStates.AVAILABLE]: $t("package.install-label").toUpperCase(),
|
||||
[PackageStates.INSTALLED]: $t("package.installed-label").toUpperCase(),
|
||||
[PackageStates.INSTALLING]: $t("package.installing-label").toUpperCase(),
|
||||
[PackageStates.UNINSTALLED]: $t("package.reinstall-label").toUpperCase(),
|
||||
}[state];
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
if (!packages.length) {
|
||||
const matches = await packagesStore.search(pkg.desc, 4);
|
||||
|
@ -40,9 +30,7 @@
|
|||
<div class={pkg.state === PackageStates.INSTALLING ? 'animate-pulse' : ''}>
|
||||
<PackageCard
|
||||
{pkg}
|
||||
link={`/packages/${pkg.slug}`}
|
||||
ctaLabel={getCTALabel(pkg.state)}
|
||||
onClickCTA={async () => {
|
||||
onClick={async () => {
|
||||
try {
|
||||
pkg.state = PackageStates.INSTALLING;
|
||||
await installPackage(pkg.full_name);
|
||||
|
|
|
@ -32,6 +32,9 @@ export async function getPackages(): Promise<GUIPackage[]> {
|
|||
// sorts all packages from highest -> lowest
|
||||
installedPackages.sort((a, b) => semverCompare(b.version, a.version));
|
||||
|
||||
// NOTE: its not ideal to get bottles or set package states here maybe do it async in the package store init
|
||||
// --- it has noticeable slowness
|
||||
|
||||
return (packages || []).map((pkg) => {
|
||||
const installedVersions = installedPackages
|
||||
.filter((p) => p.full_name === pkg.full_name)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { writable } from "svelte/store";
|
||||
import type { GUIPackage } from "../types";
|
||||
import { PackageStates } from "../types";
|
||||
import { getPackages } from "@native";
|
||||
import Fuse from "fuse.js";
|
||||
import { getPackage } from "@native";
|
||||
import { getPackage, getPackageBottles } from "@native";
|
||||
|
||||
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
||||
import semverCompare from "semver/functions/compare";
|
||||
|
||||
export default function initPackagesStore() {
|
||||
let initialized = false;
|
||||
|
@ -19,6 +21,12 @@ export default function initPackagesStore() {
|
|||
packagesIndex = new Fuse(pkgs, {
|
||||
keys: ["name", "full_name", "desc", "categories"]
|
||||
});
|
||||
|
||||
pkgs.forEach((pkg) => {
|
||||
if (pkg.state === PackageStates.INSTALLED) {
|
||||
syncPackageBottlesAndState(pkg.full_name);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -67,6 +75,25 @@ To read more about this package go to [${guiPkg.homepage}](${guiPkg.homepage}).
|
|||
updatePackageProp(guiPkg.full_name!, updatedPackage);
|
||||
};
|
||||
|
||||
const syncPackageBottlesAndState = async (pkgName: string) => {
|
||||
const bottles = await getPackageBottles(pkgName);
|
||||
const pkg = packages.find((p) => p.full_name === pkgName);
|
||||
|
||||
const availableVersions = bottles
|
||||
.map(({ version }) => version)
|
||||
.sort((a, b) => semverCompare(b, a));
|
||||
|
||||
const installedVersions = pkg?.installed_versions?.sort((a, b) => semverCompare(b, a)) || [];
|
||||
|
||||
updatePackageProp(pkgName, {
|
||||
available_versions: availableVersions,
|
||||
state:
|
||||
availableVersions[0] === installedVersions[0]
|
||||
? PackageStates.INSTALLED
|
||||
: PackageStates.NEEDS_UPDATE
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
packages,
|
||||
subscribe,
|
||||
|
|
|
@ -258,6 +258,7 @@
|
|||
"installed-label": "installed",
|
||||
"installing-label": "installing",
|
||||
"reinstall-label": "re-install",
|
||||
"needs-update-label": "update",
|
||||
"my-installs-title": "my installs",
|
||||
"check-for-updates": "check for updates",
|
||||
"details": "details"
|
||||
|
|
|
@ -9,13 +9,15 @@ export enum PackageStates {
|
|||
AVAILABLE,
|
||||
INSTALLED,
|
||||
INSTALLING,
|
||||
UNINSTALLED
|
||||
UNINSTALLED,
|
||||
NEEDS_UPDATE
|
||||
}
|
||||
|
||||
export type GUIPackage = Package & {
|
||||
state: PackageStates;
|
||||
installed_versions?: string[];
|
||||
synced?: boolean;
|
||||
available_versions?: string[];
|
||||
};
|
||||
|
||||
export type Course = {
|
||||
|
|
Loading…
Reference in a new issue