mirror of
https://github.com/ivabus/gui
synced 2025-06-06 23:30:26 +03:00
Package Progress install (#272)
* #263 fake progress for package installation --------- Co-authored-by: neil <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
78a6887374
commit
db84f9c7f1
4 changed files with 168 additions and 3 deletions
|
@ -1,14 +1,19 @@
|
|||
<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';
|
||||
import { getPackage } from '@native';
|
||||
import { inc } from 'semver';
|
||||
|
||||
|
||||
export let pkg: GUIPackage;
|
||||
export let onClick: () => void;
|
||||
|
||||
let fakeLoadingProgress = 0;
|
||||
|
||||
const getCTALabel = (state: PackageStates): string => {
|
||||
return {
|
||||
[PackageStates.AVAILABLE]: $t("package.install-label").toUpperCase(),
|
||||
|
@ -18,11 +23,39 @@
|
|||
[PackageStates.NEEDS_UPDATE]: $t("package.needs-update-label").toUpperCase(),
|
||||
}[state];
|
||||
};
|
||||
|
||||
let fakeTimer: NodeJS.Timer;
|
||||
|
||||
async function startFakeLoader() {
|
||||
let ms = 100;
|
||||
let assumedDlSpeedMb = 1024 * 1024 * 3; // 3mbps
|
||||
const p = await getPackage(pkg.full_name);
|
||||
const size = (p?.bottles?.length ? p.bottles[0].bytes : assumedDlSpeedMb*10);
|
||||
const eta = size / assumedDlSpeedMb;
|
||||
|
||||
const increment = (1 / eta)/10;
|
||||
|
||||
fakeTimer = setInterval(() => {
|
||||
const progressLeft = 100 - fakeLoadingProgress;
|
||||
const addProgress = progressLeft * increment;
|
||||
fakeLoadingProgress = fakeLoadingProgress + addProgress;
|
||||
}, ms);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<PackageCard
|
||||
{pkg}
|
||||
link={`/packages/${pkg.slug}`}
|
||||
ctaLabel={getCTALabel(pkg.state)}
|
||||
onClickCTA={onClick}
|
||||
progessLoading={+fakeLoadingProgress.toFixed(2)}
|
||||
onClickCTA={async () => {
|
||||
fakeLoadingProgress = 1;
|
||||
startFakeLoader();
|
||||
await onClick();
|
||||
setTimeout(() => {
|
||||
clearTimeout(fakeTimer);
|
||||
fakeLoadingProgress = 100;
|
||||
}, 1500);
|
||||
}}
|
||||
/>
|
|
@ -0,0 +1,61 @@
|
|||
<script lang="ts">
|
||||
export let value = 0;
|
||||
export let max = 100;
|
||||
$: progressPath = () => {
|
||||
if (value <= 0) {
|
||||
return "";
|
||||
} else if (value >= max) {
|
||||
return "M50,5A45 45 0 1 1 49.9999 5";
|
||||
} else {
|
||||
const angle = Math.PI * 2 * (value / max);
|
||||
const x = 50 + Math.cos(angle - Math.PI / 2) * 45;
|
||||
const y = 50 + Math.sin(angle - Math.PI / 2) * 45;
|
||||
let path = "M50,5";
|
||||
if (angle > Math.PI) {
|
||||
path += "A45 45 0 0 1 50 95";
|
||||
}
|
||||
path += `A45 45 0 0 1 ${x} ${y}`;
|
||||
return path;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
fill: var(--progress-fill, transparent);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
stroke-linecap: var(--progress-linecap, round);
|
||||
width: 100%;
|
||||
}
|
||||
path:first-child {
|
||||
stroke: var(--progress-trackcolor, grey);
|
||||
stroke-width: var(--progress-trackwidth, 9px);
|
||||
}
|
||||
path:last-child {
|
||||
stroke: var(--progress-color, lightgreen);
|
||||
stroke-width: var(--progress-width, 10px);
|
||||
}
|
||||
div {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
span {
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<svg viewBox="0 0 100 100">
|
||||
<path d="M50,5A45 45 0 1 1 49.9999 5" />
|
||||
<path d="{progressPath()}" />
|
||||
</svg>
|
||||
<div>
|
||||
<slot>
|
||||
<span>{value}</span>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
|
@ -2,19 +2,21 @@
|
|||
import "../app.css";
|
||||
import type { Package } from "../types";
|
||||
import ImgLoader from "../img-loader/img-loader.svelte";
|
||||
import ProgressCircle from "../progress-circle/progress-circle.svelte";
|
||||
|
||||
export let pkg: Package;
|
||||
export let link: string;
|
||||
export let ctaLabel: string;
|
||||
export let progessLoading = 0;
|
||||
|
||||
export let onClickCTA = () => {
|
||||
console.log("do nothing");
|
||||
};
|
||||
</script>
|
||||
|
||||
<section class="package-card border border-gray p-4">
|
||||
<section class="package-card relative h-auto border border-gray p-4">
|
||||
<a href={link}>
|
||||
<figure>
|
||||
<figure class="relative">
|
||||
<ImgLoader
|
||||
class="pkg-image"
|
||||
src={!pkg.thumb_image_url.includes("https://tea.xyz")
|
||||
|
@ -45,6 +47,13 @@
|
|||
</div>
|
||||
<button class="p-2 font-machina" on:click={onClickCTA}>{ctaLabel}</button>
|
||||
</footer>
|
||||
{#if progessLoading > 0 && progessLoading < 100}
|
||||
<div class="absolute top-0 left-0 h-full w-full bg-black bg-opacity-50">
|
||||
<div class="absolute left-0 right-0 top-1/2 m-auto -mt-12 h-24 w-24">
|
||||
<ProgressCircle value={progessLoading} />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<style>
|
||||
|
|
62
modules/ui/src/progress-circle/progress-circle.svelte
Normal file
62
modules/ui/src/progress-circle/progress-circle.svelte
Normal file
|
@ -0,0 +1,62 @@
|
|||
<script lang="ts">
|
||||
export let value = 0;
|
||||
export let max = 100;
|
||||
$: progressPath = () => {
|
||||
if (value <= 0) {
|
||||
return "";
|
||||
} else if (value >= max) {
|
||||
return "M50,5A45 45 0 1 1 49.9999 5";
|
||||
} else {
|
||||
const angle = Math.PI * 2 * (value / max);
|
||||
const x = 50 + Math.cos(angle - Math.PI / 2) * 45;
|
||||
const y = 50 + Math.sin(angle - Math.PI / 2) * 45;
|
||||
let path = "M50,5";
|
||||
if (angle > Math.PI) {
|
||||
path += "A45 45 0 0 1 50 95";
|
||||
}
|
||||
path += `A45 45 0 0 1 ${x} ${y}`;
|
||||
return path;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<svg viewBox="0 0 100 100">
|
||||
<path d="M50,5A45 45 0 1 1 49.9999 5" />
|
||||
<path d={progressPath()} />
|
||||
</svg>
|
||||
<div>
|
||||
<slot>
|
||||
<span>{value}%</span>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
fill: var(--progress-fill, transparent);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
stroke-linecap: var(--progress-linecap, round);
|
||||
width: 100%;
|
||||
}
|
||||
path:first-child {
|
||||
stroke: var(--progress-trackcolor, grey);
|
||||
stroke-width: var(--progress-trackwidth, 9px);
|
||||
}
|
||||
path:last-child {
|
||||
stroke: var(--progress-color, #00ffd0);
|
||||
stroke-width: var(--progress-width, 10px);
|
||||
}
|
||||
div {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
span {
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
Loading…
Reference in a new issue