mirror of
https://github.com/ivabus/gui
synced 2025-04-23 14:07:14 +03:00
Package detail buttons (#284)
* remove footer * #281 show package state and cta in package detail page --------- Co-authored-by: neil <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
73984ac4d8
commit
64aa63a8c0
4 changed files with 71 additions and 51 deletions
|
@ -1,36 +1,19 @@
|
|||
<script lang="ts">
|
||||
import '$appcss';
|
||||
import '@tea/ui/icons/icons.css';
|
||||
import type { Package, Bottle } from '@tea/ui/types';
|
||||
import type { Bottle } from '@tea/ui/types';
|
||||
import Button from '@tea/ui/button/button.svelte';
|
||||
import StarRating from '@tea/ui/star-rating/star-rating.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { getPackageBottles } from '@native';
|
||||
import { openTerminal } from '@native';
|
||||
import { trackInstall, trackInstallFailed } from '$libs/analytics';
|
||||
|
||||
export let pkg: Package;
|
||||
import { installPackage } from '@native';
|
||||
import { PackageStates, type GUIPackage } from '$libs/types';
|
||||
import { packagesStore } from '$libs/stores';
|
||||
|
||||
export let pkg: GUIPackage;
|
||||
let bottles: Bottle[] = [];
|
||||
let packageRating = 0;
|
||||
let copyButtonText = 'COPY';
|
||||
const copyValue = `sh <(curl tea.xyz ) +${pkg.full_name}`;
|
||||
|
||||
const onCopy = () => {
|
||||
copyButtonText = 'COPIED!';
|
||||
navigator.clipboard.writeText(copyValue);
|
||||
};
|
||||
|
||||
const onOpenTerminal = () => {
|
||||
try {
|
||||
openTerminal(`sh <(curl tea.xyz) +${pkg.full_name}`);
|
||||
trackInstall(pkg.full_name);
|
||||
} catch (error) {
|
||||
let message = 'Unknown Error'
|
||||
if (error instanceof Error) message = error.message
|
||||
trackInstallFailed(pkg.full_name, message || "unknown");
|
||||
}
|
||||
}
|
||||
|
||||
let installing = false;
|
||||
onMount(async () => {
|
||||
try {
|
||||
bottles = await getPackageBottles(pkg.full_name);
|
||||
|
@ -38,6 +21,15 @@
|
|||
console.error(err);
|
||||
}
|
||||
});
|
||||
|
||||
const install = async () => {
|
||||
installing = true;
|
||||
await installPackage(pkg);
|
||||
installing = false;
|
||||
packagesStore.updatePackage(pkg.full_name, {
|
||||
state: PackageStates.INSTALLED,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="border-gray mt-4 border bg-black">
|
||||
|
@ -47,19 +39,33 @@
|
|||
</figure>
|
||||
<article class="w-2/3 p-4 pt-8">
|
||||
<h3 class="text-primary text-3xl">{pkg.full_name}</h3>
|
||||
<h3>• {pkg.maintainer || ''}{pkg.maintainer ? ' |' : ''} {bottles.length} bottles</h3>
|
||||
<div class="mt-4">
|
||||
<StarRating maxRating={5} rating={packageRating} />
|
||||
</div>
|
||||
{#if pkg.homepage}
|
||||
<a target="_blank" rel="noreferrer" href={pkg.homepage}>
|
||||
<span>{pkg.homepage}</span>
|
||||
</a>
|
||||
{/if}
|
||||
<p class="font-sono mt-4 text-sm">{pkg.desc}</p>
|
||||
<menu class="h-10 grid grid-cols-2 gap-4 mt-4 text-xs">
|
||||
{#if pkg.state === PackageStates.INSTALLED}
|
||||
<Button type="plain" color="primary">
|
||||
Latest version installed v{pkg.version}
|
||||
</Button>
|
||||
{:else if pkg.state === PackageStates.AVAILABLE}
|
||||
<Button type="plain" color="secondary" onClick={install} loading={installing}>
|
||||
{installing ? "Installing" : "Install"} v{pkg.version}
|
||||
</Button>
|
||||
{:else if pkg.state === PackageStates.NEEDS_UPDATE}
|
||||
<Button type="plain" color="secondary" onClick={install} loading={installing}>
|
||||
{installing ? "Updating" : "Update"} to v{pkg.version}
|
||||
</Button>
|
||||
{/if}
|
||||
{#if pkg.github}
|
||||
<a href={`https://github.com/${pkg.github}`} target="_blank" rel="noreferrer">
|
||||
<Button class="border border-gray h-10">View on github</Button>
|
||||
</a>
|
||||
{/if}
|
||||
</menu>
|
||||
</article>
|
||||
</header>
|
||||
|
||||
<footer class="border-gray flex h-20 border-t text-white">
|
||||
<input class="click-copy flex-grow bg-black pl-4" disabled value={copyValue} />
|
||||
<Button class="w-16 border-0 border-l-2 text-sm" onClick={onCopy}>{copyButtonText}</Button>
|
||||
<Button class="w-56 border-0 border-l-2 text-sm" onClick={onOpenTerminal}
|
||||
>OPEN IN TERMINAL</Button
|
||||
>
|
||||
</footer>
|
||||
</section>
|
||||
|
|
|
@ -39,9 +39,6 @@
|
|||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
<footer class="border-gray mt-8 w-full border border-r-0 bg-black">
|
||||
<FooterLinks />
|
||||
</footer>
|
||||
<SearchPopupResults />
|
||||
</section>
|
||||
</div>
|
||||
|
@ -83,8 +80,4 @@
|
|||
div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
footer {
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,15 +10,14 @@
|
|||
import PackageMetas from '@tea/ui/package-metas/package-metas.svelte';
|
||||
import Markdown from '@tea/ui/markdown/markdown.svelte';
|
||||
import PackageSnippets from '@tea/ui/package-snippets/package-snippets.svelte';
|
||||
import type { GUIPackage } from '$libs/types';
|
||||
|
||||
/** @type {import('./$types').PageData} */
|
||||
export let data;
|
||||
|
||||
import { packagesStore } from '$libs/stores';
|
||||
|
||||
import type { Package } from '@tea/ui/types';
|
||||
|
||||
let pkg: Package;
|
||||
let pkg: GUIPackage;
|
||||
|
||||
let reviews: Review[];
|
||||
let bottles: Bottle[] = [];
|
||||
|
@ -62,7 +61,6 @@
|
|||
</script>
|
||||
|
||||
<div>
|
||||
<PageHeader coverUrl={pkg.thumb_image_url}>{pkg.full_name}</PageHeader>
|
||||
<section>
|
||||
<PackageBanner {pkg} />
|
||||
</section>
|
||||
|
|
|
@ -6,11 +6,18 @@
|
|||
|
||||
export let onClick: undefined | (() => void) = undefined;
|
||||
export let active = false;
|
||||
|
||||
export let type: "ghost" | "plain" = "ghost";
|
||||
export let color: "primary" | "secondary" = "primary";
|
||||
|
||||
export let loading = false;
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class={`w-full p-2 font-machina text-gray ${clazz} ${active ? "active" : ""}`}
|
||||
class={`w-full p-2 font-machina text-gray ${clazz} ${active ? "active" : ""} ${type} ${color} ${
|
||||
loading ? "animate-pulse" : ""
|
||||
}`}
|
||||
on:click={() => onClick && onClick()}
|
||||
>
|
||||
<slot />
|
||||
|
@ -19,14 +26,30 @@
|
|||
<style>
|
||||
button {
|
||||
min-width: 100px;
|
||||
transition: 0.2s ease-in-out !important;
|
||||
transition: 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
button.plain.primary {
|
||||
color: black;
|
||||
background-color: #00ffd0;
|
||||
}
|
||||
|
||||
button.plain.secondary {
|
||||
color: white;
|
||||
background-color: #8000ff;
|
||||
}
|
||||
button.active {
|
||||
color: black;
|
||||
}
|
||||
button:hover {
|
||||
box-shadow: inset 0px 0px 0px 5px #1a1a1a !important;
|
||||
background-color: #00ffd0 !important;
|
||||
color: #1a1a1a !important;
|
||||
box-shadow: inset 0px 0px 0px 5px #1a1a1a;
|
||||
background-color: #00ffd0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
button.primary:hover {
|
||||
background-color: #00ffd0;
|
||||
}
|
||||
button.secondary:hover {
|
||||
background-color: #8000ff;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue