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:
Neil 2023-03-10 12:28:37 +08:00 committed by GitHub
parent 73984ac4d8
commit 64aa63a8c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 51 deletions

View file

@ -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>&#x2022; {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>

View file

@ -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>

View file

@ -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>

View file

@ -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>