mirror of
https://github.com/ivabus/gui
synced 2025-04-23 14:07:14 +03:00
I18n cleanup (#382)
* #374 rm custom tea-cli notification * #370 apply i18n to several statements * #370 remove unused i18n and components --------- Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
3acce8ac0c
commit
5fec6e16f9
17 changed files with 65 additions and 546 deletions
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<PanelHeader {title} {ctaLabel} ctaLink="/" />
|
<PanelHeader {title} {ctaLabel} ctaLink="/" />
|
||||||
{#if courses.length}
|
{#if courses.length}
|
||||||
<Posts posts={courses} readMoreCta={$t("post.read-more-cta")} linkTarget="_blank" />
|
<Posts posts={courses} linkTarget="_blank" />
|
||||||
{:else}
|
{:else}
|
||||||
<section class="border-gray h-64 border bg-black p-4">
|
<section class="border-gray h-64 border bg-black p-4">
|
||||||
<Preloader />
|
<Preloader />
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import '$appcss';
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
import type { GUIPackage } from '$libs/types';
|
|
||||||
import { PackageStates } from '$libs/types';
|
|
||||||
import PanelHeader from '@tea/ui/panel-header/panel-header.svelte';
|
|
||||||
import { packagesStore } from '$libs/stores';
|
|
||||||
import MiniPackageCard from '@tea/ui/mini-package-card/mini-package-card.svelte';
|
|
||||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
|
||||||
let packages: GUIPackage[] = [];
|
|
||||||
|
|
||||||
packagesStore.subscribe((v) => {
|
|
||||||
packages = v.filter((p) => p.state === PackageStates.INSTALLED);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<PanelHeader title={$t("package.my-installs-title")} ctaLabel={`${$t("package.check-for-updates")} >`} ctaLink="#" />
|
|
||||||
|
|
||||||
<ul class="border-gray grid grid-cols-3 border border-r-0 bg-black">
|
|
||||||
{#if packages.length > 0}
|
|
||||||
{#each packages as pkg}
|
|
||||||
<div class="border-gray border border-t-0 border-l-0 p-4">
|
|
||||||
<MiniPackageCard
|
|
||||||
{pkg}
|
|
||||||
ctaLabel={$t("package.details").toUpperCase()}
|
|
||||||
onClickCTA={async () => {
|
|
||||||
console.log('do something with:', pkg.full_name);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
{:else}
|
|
||||||
{#each Array(12) as _}
|
|
||||||
<section class="h-50 border-gray border p-4">
|
|
||||||
<Preloader />
|
|
||||||
</section>
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
|
@ -12,7 +12,7 @@
|
||||||
postsStore.subscribeByTag('news', (posts) => (news = posts));
|
postsStore.subscribeByTag('news', (posts) => (news = posts));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<PanelHeader title={$t("home.os-news-title")} ctaLabel={`${$t("post.article-more-cta")} >`} ctaLink="/" />
|
<PanelHeader title="OPEN-SOURCE NEWS" ctaLabel="Read more articles" ctaLink="/" />
|
||||||
{#if news.length}
|
{#if news.length}
|
||||||
<Posts posts={news} linkTarget="_blank" />
|
<Posts posts={news} linkTarget="_blank" />
|
||||||
{:else}
|
{:else}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import "$appcss";
|
import "$appcss";
|
||||||
import "@tea/ui/icons/icons.css";
|
import "@tea/ui/icons/icons.css";
|
||||||
|
import { t } from '$libs/translations';
|
||||||
import Button from "@tea/ui/button/button.svelte";
|
import Button from "@tea/ui/button/button.svelte";
|
||||||
|
|
||||||
import { installPackage } from "@native";
|
import { installPackage } from "@native";
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
color="black"
|
color="black"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
shellOpenExternal(`https://github.com/${pkg.github}`);
|
shellOpenExternal(`https://github.com/${pkg.github}`);
|
||||||
}}>View on github</Button
|
}}>{$t("common.view-on-github")}</Button
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import '$appcss';
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
import { postsStore } from '$libs/stores';
|
|
||||||
import type { AirtablePost } from '@tea/ui/types';
|
|
||||||
import Posts from '@tea/ui/posts/posts.svelte';
|
|
||||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
|
||||||
|
|
||||||
let posts: AirtablePost[] = [];
|
|
||||||
|
|
||||||
let tab: "ALL" | "ARTICLE" | "WORKSHOP" = "ALL";
|
|
||||||
|
|
||||||
const setPosts = (newPosts: AirtablePost[]) => {
|
|
||||||
posts = tab === "ALL" ? newPosts : newPosts.filter((p) => p.tags.includes(tab));
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchTab = (nextTab: "ALL" | "ARTICLE" | "WORKSHOP") => {
|
|
||||||
tab = nextTab;
|
|
||||||
setPosts($postsStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
postsStore.subscribe(setPosts);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<header class="flex items-center justify-between border border-gray bg-black p-4 text-primary">
|
|
||||||
<div>{$t("home.resources")}</div>
|
|
||||||
|
|
||||||
<section class="border border-gray mr-2 rounded-sm h-10 text-gray font-thin flex">
|
|
||||||
<button on:click={() => switchTab("ALL")} class={`px-2 ${tab === "ALL" && "active"}`}>{$t("common.all")}</button>
|
|
||||||
<button on:click={() => switchTab("ARTICLE")} class={`px-2 ${tab === "ARTICLE" && "active"}`}>{$t("common.articles")}</button>
|
|
||||||
<button on:click={() => switchTab("WORKSHOP")} class={`px-2 ${tab === "WORKSHOP" && "active"}`}>{$t("common.workshops")}</button>
|
|
||||||
</section>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{#if posts.length}
|
|
||||||
<Posts {posts} linkTarget="_blank" />
|
|
||||||
{:else}
|
|
||||||
<section class="border-gray h-64 border bg-black p-4">
|
|
||||||
<Preloader />
|
|
||||||
</section>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
button {
|
|
||||||
height: 100%;
|
|
||||||
text-decoration: none;
|
|
||||||
min-width: 120px;
|
|
||||||
transition: 0.1s linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover, button.active {
|
|
||||||
color: white;
|
|
||||||
background-color: #8000ff;
|
|
||||||
box-shadow: inset 0vw 0vw 0vw 0.223vw #1a1a1a !important;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,93 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import '$appcss';
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
import { packagesStore } from '$libs/stores';
|
|
||||||
import SortingButtons from './sorting-buttons.svelte';
|
|
||||||
import type { GUIPackage } from '$libs/types';
|
|
||||||
import { PackageStates } from '$libs/types';
|
|
||||||
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';
|
|
||||||
|
|
||||||
import { installPackage } from '@native';
|
|
||||||
|
|
||||||
let packages: GUIPackage[] = [];
|
|
||||||
|
|
||||||
let sortBy = 'popularity';
|
|
||||||
let sortDirection: 'asc' | 'desc' = 'desc';
|
|
||||||
|
|
||||||
const searchLimit = 10;
|
|
||||||
|
|
||||||
const setPackages = (pkgs: GUIPackage[], isSearch?: boolean) => {
|
|
||||||
packages = isSearch
|
|
||||||
? pkgs
|
|
||||||
: pkgs.sort((a, b) => {
|
|
||||||
if (sortBy === 'popularity') {
|
|
||||||
const aPop = +a.dl_count + a.installs;
|
|
||||||
const bPop = +b.dl_count + b.installs;
|
|
||||||
return sortDirection === 'asc' ? aPop - bPop : bPop - aPop;
|
|
||||||
} else {
|
|
||||||
// most recent
|
|
||||||
const aDate = new Date(a.last_modified);
|
|
||||||
const bDate = new Date(b.last_modified);
|
|
||||||
return sortDirection === 'asc' ? +aDate - +bDate : +bDate - +aDate;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSearch = async (term: string) => {
|
|
||||||
if (term !== '' && term.length > 1) {
|
|
||||||
const matchingPackages: GUIPackage[] = await packagesStore.search(term, searchLimit);
|
|
||||||
setPackages(matchingPackages, true);
|
|
||||||
} else {
|
|
||||||
setPackages(packagesStore.packages, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSort = (opt: string, dir: 'asc' | 'desc') => {
|
|
||||||
sortBy = opt;
|
|
||||||
sortDirection = dir;
|
|
||||||
setPackages(packages);
|
|
||||||
};
|
|
||||||
|
|
||||||
packagesStore.subscribe(setPackages);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="border-gray border bg-black">
|
|
||||||
<section class="flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<SearchInput size="medium" {onSearch} placeholder={`${$t("search")}_`} />
|
|
||||||
</div>
|
|
||||||
<div class="pr-4">
|
|
||||||
<section class="border-gray h-12 w-48 border">
|
|
||||||
<SortingButtons {onSort} />
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<ul class="grid grid-cols-3">
|
|
||||||
{#if packages.length > 0}
|
|
||||||
{#each packages as pkg}
|
|
||||||
<div class={pkg.state === PackageStates.INSTALLING ? 'animate-pulse' : ''}>
|
|
||||||
<Package
|
|
||||||
{pkg}
|
|
||||||
onClick={async () => {
|
|
||||||
try {
|
|
||||||
pkg.state = PackageStates.INSTALLING;
|
|
||||||
await installPackage(pkg);
|
|
||||||
pkg.state = PackageStates.INSTALLED;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
{:else}
|
|
||||||
{#each Array(12) as _}
|
|
||||||
<section class="h-50 border-gray border p-4">
|
|
||||||
<Preloader />
|
|
||||||
</section>
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
|
@ -1,101 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
import Button from '@tea/ui/button/button.svelte';
|
|
||||||
import { openTerminal } from '@native';
|
|
||||||
import { packagesStore } from '$libs/stores';
|
|
||||||
import { PackageStates, type GUIPackage } from '$libs/types';
|
|
||||||
|
|
||||||
type CliUpdateState = 'unknown' | 'not_installed' | 'update_required' | 'up_to_date' | 'updated';
|
|
||||||
|
|
||||||
$: updateState = 'unknown' as CliUpdateState;
|
|
||||||
|
|
||||||
const getCliUpdateState = (pkg: GUIPackage | null): CliUpdateState => {
|
|
||||||
if (!pkg) {
|
|
||||||
return 'unknown';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkg.state != PackageStates.INSTALLED){
|
|
||||||
return 'not_installed';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pkg.installed_versions?.includes(pkg.version)) {
|
|
||||||
return 'update_required';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'up_to_date';
|
|
||||||
}
|
|
||||||
|
|
||||||
packagesStore.subscribeToPackage("tea_xyz", (pkg) => {
|
|
||||||
if (updateState !== 'updated' ) {
|
|
||||||
updateState = getCliUpdateState(pkg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const onOpenTerminal = async () => {
|
|
||||||
console.log("installing tea...")
|
|
||||||
try {
|
|
||||||
openTerminal(`sh <(curl https://tea.xyz)`);
|
|
||||||
} catch (error) {
|
|
||||||
console.log("install failed")
|
|
||||||
}
|
|
||||||
updateState = 'updated';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{#if updateState === 'not_installed'}
|
|
||||||
<div class="banner flex items-center justify-center text-primary">
|
|
||||||
<span class="text-white mr-4">{$t('package.install-tea-cli')}</span>
|
|
||||||
<button class="button" on:click={onOpenTerminal}>{$t("package.install-tea-label")}</button>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if updateState === 'update_required'}
|
|
||||||
<div class="banner flex items-center justify-center text-primary">
|
|
||||||
<span class="text-white mr-4">{$t('package.update-tea-cli')}</span>
|
|
||||||
<button class="button" on:click={onOpenTerminal}>{$t("package.update-tea-label")}</button>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.banner {
|
|
||||||
background-color: #FF4100;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 6px;
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
|
||||||
padding-top: 12px;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
color: white;
|
|
||||||
border: 1px solid white;
|
|
||||||
padding: 6px 24px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button::before {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
background: #e1e1e1;
|
|
||||||
transition-duration: 0.2s;
|
|
||||||
z-index: -1;
|
|
||||||
inset: 0px auto auto 0px;
|
|
||||||
width: 0px;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:hover::before {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:hover {
|
|
||||||
color: #1a1a1a;
|
|
||||||
background: #e1e1e1;
|
|
||||||
transition: color 0.3s ease 0s, background 0s ease 0.3s;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<!-- home / discover / welcome page -->
|
|
||||||
<script lang="ts">
|
|
||||||
import '$appcss';
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
import ListAction from '@tea/ui/list-action/list-action.svelte';
|
|
||||||
import type { ListActionItem } from '@tea/ui/types';
|
|
||||||
import { packagesStore } from '$libs/stores';
|
|
||||||
|
|
||||||
let items: ListActionItem[];
|
|
||||||
|
|
||||||
packagesStore.subscribe((ps) => {
|
|
||||||
items = ps
|
|
||||||
.filter((p) => (p.categories || []).includes('top_packages'))
|
|
||||||
.map((pkg) => ({
|
|
||||||
title: pkg.full_name,
|
|
||||||
sub_title: pkg.version,
|
|
||||||
action_label: $t("package.install-label").toUpperCase(),
|
|
||||||
image_url: pkg.thumb_image_url,
|
|
||||||
detail_url: `/packages/${pkg.slug}`
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSelectPackage = async (item:ListActionItem) => {
|
|
||||||
console.log(item);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ListAction
|
|
||||||
title={$t("package.top-list-title")}
|
|
||||||
mainCtaTitle={$t("package.view-all-cta").toUpperCase()}
|
|
||||||
items={items}
|
|
||||||
onSelectItem={onSelectPackage}
|
|
||||||
/>
|
|
|
@ -1,51 +0,0 @@
|
||||||
<!-- home / discover / welcome page -->
|
|
||||||
<script lang="ts">
|
|
||||||
import '$appcss';
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
import type { ListActionItem } from '@tea/ui/types';
|
|
||||||
import ListAction from '@tea/ui/list-action/list-action.svelte';
|
|
||||||
|
|
||||||
const action_label = $t("script.use-label");
|
|
||||||
const items: ListActionItem[] = [
|
|
||||||
{
|
|
||||||
title: 'Script A',
|
|
||||||
sub_title: 'v 0.0.1',
|
|
||||||
image_url: '/images/bored-ape.png',
|
|
||||||
action_label
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Script B',
|
|
||||||
sub_title: 'v 0.1.1',
|
|
||||||
image_url: '/images/bored-ape.png',
|
|
||||||
action_label
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Script C',
|
|
||||||
sub_title: 'v 2.0.1',
|
|
||||||
image_url: '/images/bored-ape.png',
|
|
||||||
action_label
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Script D',
|
|
||||||
sub_title: 'v 0.1.1',
|
|
||||||
image_url: '/images/bored-ape.png',
|
|
||||||
action_label
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Script E',
|
|
||||||
sub_title: 'v 0.1.1',
|
|
||||||
image_url: '/images/bored-ape.png',
|
|
||||||
action_label
|
|
||||||
},
|
|
||||||
];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<ListAction
|
|
||||||
title={$t("script.top-list-title")}
|
|
||||||
mainCtaTitle={$t("script.view-all-cta").toUpperCase()}
|
|
||||||
items={items}
|
|
||||||
onSelectItem={async (script) => {
|
|
||||||
console.log(script)
|
|
||||||
}}
|
|
||||||
/>
|
|
|
@ -5,29 +5,17 @@ import Fuse from "fuse.js";
|
||||||
import {
|
import {
|
||||||
getPackage,
|
getPackage,
|
||||||
getDistPackages,
|
getDistPackages,
|
||||||
openTerminal,
|
|
||||||
getInstalledPackages,
|
getInstalledPackages,
|
||||||
installPackage,
|
installPackage,
|
||||||
getPackageBottles
|
getPackageBottles
|
||||||
} from "@native";
|
} from "@native";
|
||||||
|
|
||||||
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
import { getReadme, getContributors, getRepoAsPackage } from "$libs/github";
|
||||||
import { notificationStore } from "../stores";
|
|
||||||
import { NotificationType } from "@tea/ui/types";
|
|
||||||
import type { Package } from "@tea/ui/types";
|
import type { Package } from "@tea/ui/types";
|
||||||
import { trackInstall, trackInstallFailed } from "$libs/analytics";
|
import { trackInstall, trackInstallFailed } from "$libs/analytics";
|
||||||
|
|
||||||
const log = window.require("electron-log");
|
const log = window.require("electron-log");
|
||||||
|
|
||||||
const installTea = async () => {
|
|
||||||
log.info("installing tea...");
|
|
||||||
try {
|
|
||||||
openTerminal(`sh <(curl https://tea.xyz)`);
|
|
||||||
} catch (error) {
|
|
||||||
log.error("install failed", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function initPackagesStore() {
|
export default function initPackagesStore() {
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
const syncProgress = writable<number>(0); // TODO: maybe use this in the UI someday
|
const syncProgress = writable<number>(0); // TODO: maybe use this in the UI someday
|
||||||
|
@ -49,8 +37,8 @@ export default function initPackagesStore() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const syncPackageData = async (guiPkg: Partial<GUIPackage>) => {
|
const syncPackageData = async (guiPkg: Partial<GUIPackage> | undefined) => {
|
||||||
if (guiPkg.synced) return;
|
if (!guiPkg || guiPkg.synced) return;
|
||||||
|
|
||||||
const pkg = await getPackage(guiPkg.full_name!); // ATM: pkg only bottles and github:string
|
const pkg = await getPackage(guiPkg.full_name!); // ATM: pkg only bottles and github:string
|
||||||
const readmeMd = `# ${guiPkg.full_name} #
|
const readmeMd = `# ${guiPkg.full_name} #
|
||||||
|
@ -87,16 +75,6 @@ To read more about this package go to [${guiPkg.homepage}](${guiPkg.homepage}).
|
||||||
|
|
||||||
const isUpToDate = teaPkg.version === installedPkg?.installed_versions[0];
|
const isUpToDate = teaPkg.version === installedPkg?.installed_versions[0];
|
||||||
log.info("check if Tea-CLI is up to date:", isUpToDate);
|
log.info("check if Tea-CLI is up to date:", isUpToDate);
|
||||||
//TODO: Is there where we handle the case of tea not being installed at all?
|
|
||||||
if (!isUpToDate) {
|
|
||||||
notificationStore.add({
|
|
||||||
message: "install cli",
|
|
||||||
i18n_key: "package.update-tea-cli",
|
|
||||||
type: NotificationType.ACTION_BANNER,
|
|
||||||
callback: installTea,
|
|
||||||
callback_label: "UPDATE"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const init = async function () {
|
const init = async function () {
|
||||||
|
@ -202,7 +180,8 @@ To read more about this package go to [${guiPkg.homepage}](${guiPkg.homepage}).
|
||||||
fetchPackageBottles,
|
fetchPackageBottles,
|
||||||
updatePackage,
|
updatePackage,
|
||||||
init,
|
init,
|
||||||
installPkg
|
installPkg,
|
||||||
|
syncPackageData
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,39 +3,9 @@
|
||||||
"lang": {
|
"lang": {
|
||||||
"en": "English"
|
"en": "English"
|
||||||
},
|
},
|
||||||
"cli": {
|
|
||||||
"install": "install tea"
|
|
||||||
},
|
|
||||||
"store-search-placeholder": "type to search",
|
"store-search-placeholder": "type to search",
|
||||||
"search": "search",
|
|
||||||
"home": {
|
|
||||||
"all-packages": "All packages",
|
|
||||||
"discover-title": "DISCOVER",
|
|
||||||
"asset-title": "ASSET TYPE",
|
|
||||||
"tutorials-title": "TUTORIALS",
|
|
||||||
"os-news-title": "OPEN-SOURCE NEWS",
|
|
||||||
"resources": "Resources"
|
|
||||||
},
|
|
||||||
"package": {
|
"package": {
|
||||||
"update-all": "UPDATE ALL",
|
"update-all": "UPDATE ALL",
|
||||||
"top-list-title": "Top packages this week",
|
|
||||||
"browse-cta": "Browse packages",
|
|
||||||
"what-title": "What are packages?",
|
|
||||||
"short-description": "Collections of files aggregated to form larger frameworks & functions. Think Python or Node.js.",
|
|
||||||
"foundation-essentials-title": "FOUNDATION ESSENTIALS",
|
|
||||||
"view-all-cta": "View all packages",
|
|
||||||
"install-label": "install",
|
|
||||||
"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",
|
|
||||||
"install-tea-label": "Install tea cli",
|
|
||||||
"update-tea-label": "Update now",
|
|
||||||
"install-tea-cli": "This app requires our command-line interface",
|
|
||||||
"update-tea-cli": "An update is available for tea cli",
|
|
||||||
"cta-AVAILABLE": "INSTALL",
|
"cta-AVAILABLE": "INSTALL",
|
||||||
"cta-INSTALLED": "INSTALLED",
|
"cta-INSTALLED": "INSTALLED",
|
||||||
"cta-INSTALLING": "INSTALLING",
|
"cta-INSTALLING": "INSTALLING",
|
||||||
|
@ -43,19 +13,6 @@
|
||||||
"cta-NEEDS_UPDATE": "UPDATE",
|
"cta-NEEDS_UPDATE": "UPDATE",
|
||||||
"cta-UPDATING": "UPDATING"
|
"cta-UPDATING": "UPDATING"
|
||||||
},
|
},
|
||||||
"script": {
|
|
||||||
"top-list-title": "Top scripts this week",
|
|
||||||
"view-all-cta": "View all scripts",
|
|
||||||
"use-label": "use",
|
|
||||||
"browse-cta": "Browse scripts",
|
|
||||||
"what-title": "What are scripts?",
|
|
||||||
"short-description": "Invisible applications that chain packages together in order to perform cool actions on your computer."
|
|
||||||
},
|
|
||||||
"post": {
|
|
||||||
"workshops-title": "workshops to get started",
|
|
||||||
"article-more-cta": "Read more articles",
|
|
||||||
"read-more-cta": "read more"
|
|
||||||
},
|
|
||||||
"footer": {
|
"footer": {
|
||||||
"quick-links-title": "quick links",
|
"quick-links-title": "quick links",
|
||||||
"about-tea-store": "about the tea store",
|
"about-tea-store": "about the tea store",
|
||||||
|
@ -79,7 +36,15 @@
|
||||||
"home": "home",
|
"home": "home",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"articles": "Articles",
|
"articles": "Articles",
|
||||||
"workshops": "Workshops"
|
"workshops": "Workshops",
|
||||||
|
"details": "details",
|
||||||
|
"versions": "versions",
|
||||||
|
"metadata": "Metadata",
|
||||||
|
"homepage": "Homepage",
|
||||||
|
"documentation": "Documentation",
|
||||||
|
"github-repository": "Github Repository",
|
||||||
|
"contributors": "Contributors",
|
||||||
|
"view-on-github": "View on github"
|
||||||
},
|
},
|
||||||
"notification": {
|
"notification": {
|
||||||
"gui-downloading": "A new tea gui({{version}}) is being downloaded. Please don't close the app.",
|
"gui-downloading": "A new tea gui({{version}}) is being downloaded. Please don't close the app.",
|
||||||
|
@ -99,6 +64,7 @@
|
||||||
},
|
},
|
||||||
"tags": {
|
"tags": {
|
||||||
"all": "all",
|
"all": "all",
|
||||||
|
"installed": "installed",
|
||||||
"updates_available": "Updates available",
|
"updates_available": "Updates available",
|
||||||
"recently_updated": "Recently updated",
|
"recently_updated": "Recently updated",
|
||||||
"new_packages": "New packages",
|
"new_packages": "New packages",
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<script>
|
|
||||||
import '$appcss';
|
|
||||||
import { t } from '$libs/translations';
|
|
||||||
|
|
||||||
import PageHeader from '$components/page-header/page-header.svelte';
|
|
||||||
import CliBanner from '$components/cli-banner/cli-banner.svelte';
|
|
||||||
import BigBlackSpace from '$components/big-black-space/big-black-space.svelte';
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<PageHeader>{$t('cli.install')}</PageHeader>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<CliBanner />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="mt-8">
|
|
||||||
<BigBlackSpace />
|
|
||||||
</section>
|
|
||||||
</div>
|
|
|
@ -1,10 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
import '$appcss';
|
import '$appcss';
|
||||||
import PageHeader from '$components/page-header/page-header.svelte';
|
import PageHeader from '$components/page-header/page-header.svelte';
|
||||||
import SearchPackages from '$components/search-packages/search-packages.svelte';
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<PageHeader>Packages</PageHeader>
|
<PageHeader>Packages</PageHeader>
|
||||||
<SearchPackages />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
// import PageHeader from '$components/page-header/page-header.svelte';
|
// import PageHeader from '$components/page-header/page-header.svelte';
|
||||||
import PackageBanner from '$components/package-banner/package-banner.svelte';
|
import PackageBanner from '$components/package-banner/package-banner.svelte';
|
||||||
import type { Bottle } from '@tea/ui/types';
|
|
||||||
// import SuggestedPackages from '$components/suggested-packages/suggested-packages.svelte';
|
// import SuggestedPackages from '$components/suggested-packages/suggested-packages.svelte';
|
||||||
import Tabs from '@tea/ui/tabs/tabs.svelte';
|
import Tabs from '@tea/ui/tabs/tabs.svelte';
|
||||||
import type { Tab } from '@tea/ui/types';
|
import type { Tab } from '@tea/ui/types';
|
||||||
|
@ -13,57 +12,45 @@
|
||||||
import PackageMetas from '@tea/ui/package-metas/package-metas.svelte';
|
import PackageMetas from '@tea/ui/package-metas/package-metas.svelte';
|
||||||
import Markdown from '@tea/ui/markdown/markdown.svelte';
|
import Markdown from '@tea/ui/markdown/markdown.svelte';
|
||||||
// import PackageSnippets from '@tea/ui/package-snippets/package-snippets.svelte';
|
// import PackageSnippets from '@tea/ui/package-snippets/package-snippets.svelte';
|
||||||
import type { GUIPackage } from '$libs/types';
|
|
||||||
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data: { slug:string, content:string, title:string };
|
export let data: { slug:string, content:string, title:string };
|
||||||
|
|
||||||
import { packagesStore } from '$libs/stores';
|
import { packagesStore } from '$libs/stores';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
let pkg: GUIPackage;
|
const { packages } = packagesStore;
|
||||||
|
|
||||||
|
$: pkg = $packages.find((p) => p.slug === data?.slug);
|
||||||
|
|
||||||
// let reviews: Review[];
|
// let reviews: Review[];
|
||||||
let bottles: Bottle[] = [];
|
$: bottles = pkg?.bottles || [];
|
||||||
let versions: string[] = [];
|
$: versions = [...new Set(bottles.map((b) => b.version))];
|
||||||
let readme: string;
|
$: readme = pkg?.readme_md || '';
|
||||||
|
|
||||||
let tabs: Tab[] = [];
|
$: tabs = [
|
||||||
|
readme !== '' && {
|
||||||
packagesStore.subscribeToPackage(data?.slug, (p) => {
|
label: $t("common.details"),
|
||||||
pkg = p;
|
component: Markdown,
|
||||||
|
props: { pkg, source: readme }
|
||||||
if (!bottles.length && pkg.bottles) {
|
},
|
||||||
const newVersion = pkg.bottles.map((b) => b.version);
|
bottles?.length && {
|
||||||
versions = [...new Set(newVersion)];
|
label: `${$t("common.versions")} (${versions.length || 0})`,
|
||||||
bottles.push(...pkg.bottles);
|
component: Bottles,
|
||||||
tabs = [
|
props: {
|
||||||
...tabs,
|
bottles
|
||||||
{
|
}
|
||||||
label: `versions (${versions.length || 0})`,
|
|
||||||
component: Bottles,
|
|
||||||
props: {
|
|
||||||
bottles
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
].filter((t) => t && t?.label) as unknown as Tab[];
|
||||||
|
|
||||||
if (!readme && pkg.readme_md) {
|
|
||||||
readme = pkg.readme_md;
|
|
||||||
tabs = [
|
|
||||||
{
|
|
||||||
label: 'details',
|
|
||||||
component: Markdown,
|
|
||||||
props: { pkg, source: readme }
|
|
||||||
},
|
|
||||||
...tabs,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const url = $page.url;
|
const url = $page.url;
|
||||||
|
|
||||||
const tab = url.searchParams.get("tab");
|
const tab = url.searchParams.get("tab");
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
packagesStore.syncPackageData(pkg);
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<header class="mx-16 py-5 mb-10 text-gray border border-x-0 border-t-0">
|
<header class="mx-16 py-5 mb-10 text-gray border border-x-0 border-t-0">
|
||||||
<a class="hover:text-white hover:opacity-80 cursor-default" href="/">{$t("common.home")}</a>
|
<a class="hover:text-white hover:opacity-80 cursor-default" href="/">{$t("common.home")}</a>
|
||||||
|
@ -72,7 +59,7 @@
|
||||||
<a class="hover:text-white hover:opacity-80 cursor-default" href={`/?tab=${tab || "all"}`}>{$t(`tags.${tab}`) || "all"}</a>
|
<a class="hover:text-white hover:opacity-80 cursor-default" href={`/?tab=${tab || "all"}`}>{$t(`tags.${tab}`) || "all"}</a>
|
||||||
>
|
>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-white">{pkg.full_name}</span>
|
<span class="text-white">{pkg?.full_name}</span>
|
||||||
</header>
|
</header>
|
||||||
{#if pkg}
|
{#if pkg}
|
||||||
<div class="px-16">
|
<div class="px-16">
|
||||||
|
@ -82,7 +69,7 @@
|
||||||
|
|
||||||
<section class="mt-8 flex gap-8">
|
<section class="mt-8 flex gap-8">
|
||||||
<div class="w-2/3">
|
<div class="w-2/3">
|
||||||
<Tabs {tabs} />
|
<Tabs {tabs} defaultTab={$t("common.details")} />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/3">
|
<div class="w-1/3">
|
||||||
{#if pkg}
|
{#if pkg}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<script>
|
|
||||||
import '$appcss';
|
|
||||||
import PageHeader from '$components/page-header/page-header.svelte';
|
|
||||||
import ProfileBanner from '$components/profile-banner/profile-banner.svelte';
|
|
||||||
import Preflight from '$components/preflight/preflight.svelte';
|
|
||||||
import Badges from '$components/badges/badges.svelte';
|
|
||||||
import InstalledPackages from '$components/installed-packages/installed-packages.svelte';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<PageHeader>PROFILE</PageHeader>
|
|
||||||
<section>
|
|
||||||
<ProfileBanner />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="mt-8 grid grid-cols-2 gap-8">
|
|
||||||
<div>
|
|
||||||
<Preflight />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Badges />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="mt-8">
|
|
||||||
<InstalledPackages />
|
|
||||||
</section>
|
|
||||||
</div>
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Package } from "../types";
|
import type { Package } from "../types";
|
||||||
|
import { t } from "$libs/translations";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import relativeTime from "dayjs/plugin/relativeTime";
|
import relativeTime from "dayjs/plugin/relativeTime";
|
||||||
import { shellOpenExternal } from "@native";
|
import { shellOpenExternal } from "@native";
|
||||||
|
@ -29,7 +30,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="bg-black pt-2">
|
<section class="bg-black pt-2">
|
||||||
<h1 class="text-primary">Metadata</h1>
|
<h1 class="text-primary">{$t("common.metadata")}</h1>
|
||||||
<ul class="mb-10 flex flex-col gap-2">
|
<ul class="mb-10 flex flex-col gap-2">
|
||||||
{#if pkg?.bottles}
|
{#if pkg?.bottles}
|
||||||
<li>
|
<li>
|
||||||
|
@ -47,7 +48,7 @@
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
<h1 class="text-primary">Homepage</h1>
|
<h1 class="text-primary">{$t("common.homepage")}</h1>
|
||||||
<ul class="mb-10 flex flex-col gap-2">
|
<ul class="mb-10 flex flex-col gap-2">
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<li on:click={() => shellOpenExternal(pkg.homepage)}>
|
<li on:click={() => shellOpenExternal(pkg.homepage)}>
|
||||||
|
@ -55,7 +56,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{#if pkg.documentation_url}
|
{#if pkg.documentation_url}
|
||||||
<h1 class="text-primary">Documentation</h1>
|
<h1 class="text-primary">{$t("common.documentation")}</h1>
|
||||||
<ul class="mb-10 flex flex-col gap-2">
|
<ul class="mb-10 flex flex-col gap-2">
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<li on:click={() => shellOpenExternal(pkg.documentation_url)}>
|
<li on:click={() => shellOpenExternal(pkg.documentation_url)}>
|
||||||
|
@ -64,7 +65,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
{/if}
|
{/if}
|
||||||
{#if pkg.github}
|
{#if pkg.github}
|
||||||
<h1 class="text-primary">Github Repository</h1>
|
<h1 class="text-primary">{$t("common.github-repository")}</h1>
|
||||||
<ul class="mb-10 flex flex-col gap-2">
|
<ul class="mb-10 flex flex-col gap-2">
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<li on:click={() => shellOpenExternal(`https://github.com/${pkg.github}`)}>
|
<li on:click={() => shellOpenExternal(`https://github.com/${pkg.github}`)}>
|
||||||
|
@ -73,7 +74,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
{/if}
|
{/if}
|
||||||
{#if pkg.contributors?.length}
|
{#if pkg.contributors?.length}
|
||||||
<h1 class="text-primary">Contributors</h1>
|
<h1 class="text-primary">{$t("common.contributors")}</h1>
|
||||||
<ul class="mb-10 flex flex-col gap-2">
|
<ul class="mb-10 flex flex-col gap-2">
|
||||||
{#each pkg.contributors as contributor}
|
{#each pkg.contributors as contributor}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
|
|
@ -9,12 +9,19 @@
|
||||||
import Button from "../button/button.svelte";
|
import Button from "../button/button.svelte";
|
||||||
|
|
||||||
export let tabs: Tab[] = [];
|
export let tabs: Tab[] = [];
|
||||||
|
export let defaultTab: string;
|
||||||
|
|
||||||
let active: string;
|
let active: string;
|
||||||
|
|
||||||
|
let dirty = false;
|
||||||
|
|
||||||
afterUpdate(() => {
|
afterUpdate(() => {
|
||||||
if (tabs.length && !active) {
|
if (tabs.length && !active) {
|
||||||
active = tabs[0].label;
|
if (!defaultTab) {
|
||||||
|
active = tabs[0].label;
|
||||||
|
} else if (!dirty) {
|
||||||
|
active = defaultTab;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -23,8 +30,13 @@
|
||||||
<menu class="flex gap-1">
|
<menu class="flex gap-1">
|
||||||
{#each tabs as tab}
|
{#each tabs as tab}
|
||||||
<div class="border border-x-0 border-t-0 border-gray text-white">
|
<div class="border border-x-0 border-t-0 border-gray text-white">
|
||||||
<Button onClick={() => (active = tab.label)}>
|
<Button
|
||||||
<span class={tab.label === active ? "text-white" : ""}>{tab.label}</span>
|
onClick={() => {
|
||||||
|
dirty = true;
|
||||||
|
active = tab.label;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span class:text-white={tab.label === active}>{tab.label}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
Loading…
Reference in a new issue