mirror of
https://github.com/ivabus/gui
synced 2025-06-08 00:00:27 +03:00
discover page styling (#511)
This commit is contained in:
parent
6278c023fe
commit
b19410f080
3 changed files with 131 additions and 106 deletions
|
@ -17,20 +17,20 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$: packages = $allPackages
|
$: packages = $allPackages
|
||||||
.filter((p) => p.categories.includes(SideMenuOptions.discover))
|
.filter((p) => p.categories.includes(SideMenuOptions.discover))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return a.manual_sorting - b.manual_sorting;
|
return a.manual_sorting - b.manual_sorting;
|
||||||
});
|
});
|
||||||
console.log("test",packages)
|
console.log("test", packages);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative h-full w-full">
|
<div class="relative h-full w-full">
|
||||||
<ul class="grid grid-cols-2 bg-black" on:scroll={onScroll}>
|
<ul class="flex flex-col items-stretch" on:scroll={onScroll}>
|
||||||
{#if packages.length > 0}
|
{#if packages.length > 0}
|
||||||
{#each packages as pkg}
|
{#each packages as pkg, idx}
|
||||||
<div class="z-1 p-1" class:col-span-2={["left", "right"].includes(pkg.card_layout)}>
|
<div class="z-1 p-1">
|
||||||
<Package tab={packageFilter} {pkg} layout="{pkg.card_layout}"/>
|
<Package tab={packageFilter} {pkg} layout={idx % 2 === 0 ? "left" : "right"} />
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
{#each Array(9) as _}
|
{#each Array(9) as _}
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
ul {
|
ul {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
padding-top: 80px;
|
padding-top: 80px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
height: calc(100vh - 49px);
|
height: calc(100vh - 49px);
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
|
@ -1,69 +1,77 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { GUIPackage } from "$libs/types";
|
import type { GUIPackage } from "$libs/types";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { packagesStore } from "$libs/stores";
|
import { packagesStore } from "$libs/stores";
|
||||||
|
|
||||||
let clazz = '';
|
let clazz = "";
|
||||||
export { clazz as class };
|
export { clazz as class };
|
||||||
|
|
||||||
export let layout: "bottom" | "right" | "left" | "none" = "bottom";
|
export let layout: "bottom" | "right" | "left" | "none" = "bottom";
|
||||||
|
|
||||||
export let pkg: GUIPackage;
|
export let pkg: GUIPackage;
|
||||||
|
|
||||||
const defaultImgUrl = "/images/default-thumb.jpg";
|
const defaultImgUrl = "/images/default-thumb.jpg";
|
||||||
let loadedImg = "";
|
$: loadedImg = "";
|
||||||
let loaded = false;
|
let loaded = false;
|
||||||
|
|
||||||
const loadImage = async (url:string): Promise<string> => {
|
const loadImage = async (url: string): Promise<string> => {
|
||||||
const image = new Image();
|
const image = new Image();
|
||||||
image.src = url;
|
image.src = url;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
image.onload = () => {
|
image.onload = () => {
|
||||||
loadedImg = url;
|
loadedImg = url;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loaded = true;
|
loaded = true;
|
||||||
}, 300);
|
}, 300);
|
||||||
resolve(url);
|
resolve(url);
|
||||||
};
|
};
|
||||||
image.onerror = () => {
|
image.onerror = () => {
|
||||||
reject(new Error(`file/url does not exist ${url}`));
|
reject(new Error(`file/url does not exist ${url}`));
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const recachePkg = async () => {
|
const recachePkg = async () => {
|
||||||
const url = await packagesStore.cachePkgImage(pkg)
|
const url = await packagesStore.cachePkgImage(pkg);
|
||||||
loadImage(url);
|
loadImage(url);
|
||||||
}
|
};
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (pkg.cached_image_url) {
|
if (pkg.cached_image_url) {
|
||||||
loadImage(pkg.cached_image_url)
|
loadImage(pkg.cached_image_url).catch(() => {
|
||||||
.catch(() => {
|
if (pkg.thumb_image_url) {
|
||||||
if (pkg.thumb_image_url) {
|
loadImage(pkg.thumb_image_url);
|
||||||
loadImage(pkg.thumb_image_url);
|
recachePkg();
|
||||||
recachePkg();
|
}
|
||||||
}
|
});
|
||||||
});
|
} else if (pkg.thumb_image_url) {
|
||||||
} else if (pkg.thumb_image_url) {
|
recachePkg();
|
||||||
recachePkg();
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="bg-black {clazz} {layout}">
|
<section class="bg-black {clazz} {layout}">
|
||||||
<i class="logo icon-tea-logo-iconasset-1 text-gray text-3xl animate-pulse {layout}"/>
|
<i class="logo icon-tea-logo-iconasset-1 text-gray animate-pulse text-3xl {layout}" />
|
||||||
<div class="bg-center transition-all opacity-0 duration-500" class:opacity-100={loaded} style="background-image: url({loadedImg})">
|
<div
|
||||||
<!-- dup image: save processing power instead of computing the blur across all the HTML layers -->
|
class="bg-center opacity-0 transition-all duration-500"
|
||||||
{#if layout !== "none"}
|
class:opacity-100={loaded}
|
||||||
<aside class="blur-sm {layout} transition-all opacity-0 duration-500" class:opacity-100={loaded}>
|
style="background-image: url({loadedImg})"
|
||||||
<figure class="bg-center" style="background-image: url({loadedImg})" />
|
>
|
||||||
</aside>
|
<!-- dup image: save processing power instead of computing the blur across all the HTML layers -->
|
||||||
{/if}
|
{#if layout !== "none"}
|
||||||
|
<!-- TODO: TALK TO NEIL -->
|
||||||
|
<aside
|
||||||
|
class="blur-sm {layout} opacity-0 transition-all duration-500"
|
||||||
|
class:opacity-100={loaded}
|
||||||
|
>
|
||||||
|
<figure class="bg-center" style="background-image: url({loadedImg})" />
|
||||||
|
</aside>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
section {
|
section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
@ -93,17 +101,17 @@
|
||||||
margin-top: -15px;
|
margin-top: -15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
aside {
|
aside {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -117,7 +125,7 @@
|
||||||
aside.left {
|
aside.left {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 40%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
aside.right {
|
aside.right {
|
||||||
|
@ -126,7 +134,7 @@
|
||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
figure {
|
figure {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -134,17 +142,22 @@
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
aside.bottom figure {
|
|
||||||
left: 0px;
|
aside.bottom figure {
|
||||||
}
|
|
||||||
aside.right figure {
|
|
||||||
height: 100%;
|
|
||||||
width: 150%;
|
|
||||||
right: 0px;
|
|
||||||
}
|
|
||||||
aside.left figure {
|
|
||||||
height: 100%;
|
|
||||||
width: 250%;
|
|
||||||
left: 0px;
|
left: 0px;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
aside.right figure {
|
||||||
|
height: 100%;
|
||||||
|
/* the overlay is 60% of the image, so we need to oversize the background image back to 100% */
|
||||||
|
width: 166.6666666%;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.left figure {
|
||||||
|
height: 100%;
|
||||||
|
/* the overlay is 60% of the image, so we need to oversize the background image back to 100% */
|
||||||
|
width: 166.66666666%;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<BgImage class="absolute top-0 left-0 h-full w-full" {layout} {pkg} />
|
<BgImage class="absolute top-0 left-0 h-full w-full" {layout} {pkg} />
|
||||||
|
|
||||||
<a href={link} on:mousedown={activate} on:mouseup={deactivate} on:mouseleave={deactivate}>
|
<a href={link} on:mousedown={activate} on:mouseup={deactivate} on:mouseleave={deactivate}>
|
||||||
<div class="package-card-content absolute h-full w-full flex-col justify-between">
|
<div class="package-card-content absolute h-full w-full flex-col justify-between">
|
||||||
<div class="hint-container">
|
<div class="hint-container">
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
<div class="line-clamp-1 text-xs">view more details</div>
|
<div class="line-clamp-1 text-xs">view more details</div>
|
||||||
|
@ -42,28 +42,31 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="content-container absolute bottom-0 w-full {layout}">
|
<div class="content-container absolute bottom-0 w-full {layout}">
|
||||||
<article class="card-thumb-label relative">
|
<article class="card-thumb-label relative">
|
||||||
<h3 class="text-bold font-mona line-clamp-1 text-2xl font-bold text-white">
|
{#if layout === "bottom"}
|
||||||
{fixPackageName(pkg.name)}
|
<h3 class="text-bold font-mona line-clamp-1 text-2xl font-bold text-white">
|
||||||
</h3>
|
{fixPackageName(pkg.name)}
|
||||||
<p class="line-clamp-2 h-[32px] text-xs font-thin lowercase">{pkg.desc ?? ""}</p>
|
</h3>
|
||||||
|
<p class="line-clamp-2 h-[32px] text-xs font-thin lowercase">{pkg.desc ?? ""}</p>
|
||||||
|
{:else}
|
||||||
|
<h3 class="text-bold font-mona line-clamp-1 mb-4 text-3xl font-bold text-white">
|
||||||
|
{fixPackageName(pkg.name)}
|
||||||
|
</h3>
|
||||||
|
<p class="line-clamp-10 h-[160px] text-xs font-thin lowercase">{pkg.desc ?? ""}</p>
|
||||||
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
<div class="relative mt-3.5 flex w-full">
|
<div class="relative mt-3.5 w-full">
|
||||||
<div class="install-button" on:mousedown={preventPropagation}>
|
<div class="install-button {layout}" on:mousedown={preventPropagation}>
|
||||||
{#if pkg.state === PackageStates.INSTALLED}
|
{#if pkg.state === PackageStates.INSTALLED}
|
||||||
<div>
|
<PackageInstalledBadge version={pkg.version} />
|
||||||
<PackageInstalledBadge version={pkg.version} />
|
|
||||||
</div>
|
|
||||||
{:else}
|
{:else}
|
||||||
<div on:mousedown={preventPropagation}>
|
<PackageInstallButton
|
||||||
<PackageInstallButton
|
{pkg}
|
||||||
{pkg}
|
onClick={(evt) => {
|
||||||
onClick={(evt) => {
|
// prevent default to prevent the link that this button is inside of from being followed
|
||||||
// prevent default to prevent the link that this button is inside of from being followed
|
evt?.preventDefault();
|
||||||
evt?.preventDefault();
|
onClickCTA();
|
||||||
onClickCTA();
|
}}
|
||||||
}}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,9 +99,6 @@
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
section.right {
|
|
||||||
height: 220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
section.active::before {
|
section.active::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -125,19 +125,23 @@
|
||||||
padding: 28px 14px;
|
padding: 28px 14px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-container.bottom {
|
.content-container.bottom {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-container.left {
|
.content-container.left {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 40%;
|
width: 60%;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
|
padding: 28px 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-container.right {
|
.content-container.right {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 60%;
|
width: 60%;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
|
padding: 28px 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hint-container {
|
.hint-container {
|
||||||
|
@ -172,8 +176,12 @@
|
||||||
color: #e1e1e1;
|
color: #e1e1e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.package-card {
|
.package-card.right {
|
||||||
background-size: cover;
|
min-width: 550px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-card.left {
|
||||||
|
min-width: 550px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.package-card:hover .hint {
|
.package-card:hover .hint {
|
||||||
|
@ -190,17 +198,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.install-button {
|
.install-button {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.install-button.bottom {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 650px) {
|
@media screen and (min-width: 650px) {
|
||||||
.install-button {
|
.install-button.bottom {
|
||||||
min-width: 60%;
|
min-width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1000px) {
|
@media screen and (min-width: 1000px) {
|
||||||
.install-button {
|
.install-button.bottom {
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue