Skip to content

Commit

Permalink
Start working on showcase
Browse files Browse the repository at this point in the history
  • Loading branch information
rianadon committed Jul 14, 2024
1 parent 0ea881c commit 8abfee4
Show file tree
Hide file tree
Showing 22 changed files with 323 additions and 23 deletions.
26 changes: 24 additions & 2 deletions src/compress-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,32 @@ function main() {
addIfModified(pool, image, '.webp', () => compressWebp(image))
addIfModified(pool, image, '.avif', () => compressAvif(image))
}
for (const image of fg.sync('src/routes/showcase/assets/kbd-*.jpg')) {
addIfModified(pool, image, '.thumb.jpg', () => compressThumbJpg(image, preprocessKeyboard(false)))
// addIfModified(pool, image, '.thumb.webp', () => compressThumbWebp(image, preprocessKeyboard(false)))
// addIfModified(pool, image, '.thumb.avif', () => compressThumbAvif(image, preprocessKeyboard(false)))
addIfModified(pool, image, '.jpg', () => compressJpg(image, preprocessKeyboard(true)))
// addIfModified(pool, image, '.webp', () => compressWebp(image, preprocessKeyboard(true)))
// addIfModified(pool, image, '.avif', () => compressAvif(image, preprocessKeyboard(true)))
}
for (const video of fg.sync('docs/assets/*.(mp4)')) {
addIfModified(pool, video, '.mp4', () => compressMp4(video))
addIfModified(pool, video, '.webm', () => compressWebm(video))
}
pool.run().then(() => console.log('Done optimizing!'))
}

/** Fit keyboard to 19:10 aspect ratio and reduce size */
function preprocessKeyboard(large: boolean) {
return (img: sharp.Sharp) => {
const [width, height] = large ? [1900, 1000] : [668, 352]
return img.resize(width, height, {
fit: 'cover',
withoutEnlargement: true,
})
}
}

/** Only add the task if the input file was modified after the last optimization */
function addIfModified(pool: PromisePool, filename: string, ext: string, task: () => Promise<string>) {
const out = target(filename, ext)
Expand All @@ -55,17 +74,20 @@ const formatSize = (begin: number, end: number) => inKB(begin) + ' ⭢ ' + inKB

/** Compress images using the sharp library */
function compressSharp(fn: (inp: sharp.Sharp) => sharp.Sharp, ext: string) {
return async (image: string) => {
return async (image: string, preprocess?: (inp: sharp.Sharp) => sharp.Sharp) => {
const input = sharp(await sharp(image).toBuffer())
const meta = await input.metadata()
const output = await fn(input).toFile(target(image, ext))
const output = await fn(preprocess ? preprocess(input) : input).toFile(target(image, ext))
return formatSize(meta.size!, output.size)
}
}

const compressJpg = compressSharp(img => img.jpeg({ mozjpeg: true, quality: 90 }), '.jpg')
const compressWebp = compressSharp(img => img.webp({ quality: 90, effort: 6 }), '.webp')
const compressAvif = compressSharp(img => img.avif({ quality: 90, effort: 6 }), '.avif')
const compressThumbJpg = compressSharp(img => img.jpeg({ mozjpeg: true, quality: 90 }), '.thumb.jpg')
const compressThumbWebp = compressSharp(img => img.webp({ quality: 90, effort: 6 }), '.thumb.webp')
const compressThumbAvif = compressSharp(img => img.avif({ quality: 90, effort: 6 }), '.thumb.avif')

const run = promisify(execFile)
/** Compress videos using the ffmpeg process */
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<a
href="{base}/beta"
class="text-black bg-brand-amber rounded-0.8 px-2 py-0.5 font-semibold <md:hidden transition hover:shadow-lg shadow-amber/30"
on:click={join}>Try the beta</a
on:click={join}>Try the Beta</a
>
</div>
</header>
Expand Down
8 changes: 6 additions & 2 deletions src/lib/telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { hasPro } from '@pro'

async function post(url: string, body: any) {
try {
await (await fetch('https://analytics.ryanis.cool' + url, {
Expand All @@ -9,15 +11,17 @@ async function post(url: string, body: any) {
}
}

export function trackPageView() {
export function trackPageView(referrer?: string) {
if (!hasPro) return
return post('/', {
url: window.location.href,
language: window.navigator.language,
referrer: document.referrer,
referrer: referrer || document.referrer,
})
}

export function trackEvent(event: string, keys: Record<string, string | number>) {
if (!hasPro) return
const entries = Object.entries(keys)
return post('/event', {
url: window.location.href,
Expand Down
7 changes: 7 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
import '@unocss/reset/tailwind.css'
import '$lib/fonts.css'
import { browser } from '$app/environment'
import { afterNavigate } from '$app/navigation'
import { trackPageView } from '$lib/telemetry'
afterNavigate(({ to, from }) => {
if (from && from.url) {
trackPageView(from.url.pathname)
}
})
if (browser) trackPageView()
</script>

Expand Down
96 changes: 92 additions & 4 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import Dialog from '$lib/presentation/Dialog.svelte'
import { discordMsg } from '$lib/store'
import Header from '$lib/Header.svelte'
import { keyboards } from './showcase/showcase'
import { browser } from '$app/environment'
const discord = 'https://discord.gg/nXjqkfgtGy'
const discordUsers = fetch('https://cosmos.ryanis.cool/discord/members', { method: 'POST' }).then(
Expand Down Expand Up @@ -68,10 +70,50 @@
class="text-black bg-brand-green font-semibold sm:pt-1 sm:px-10 rounded sm:border-b-6 border-[#f57aec] inline-flex items-center gap-30 cta sm:text-xl my-4 sm:pb-0.5 px-6 border-b-4"
on:click={join}
>
Try the beta
Try the Beta
<Icon path={mdiChevronRight} size="100%" class="w-[28px] sm:w-[32px]" />
</a>
</section>
<section class="mt-6 mb-24 px-8">
<div class="w-full carousel-container max-w-525 mx-auto overflow-hidden">
<div class="flex w-600 md:w-1050 carousel py-2">
{#each keyboards.concat(keyboards) as kbd}
<a
class="block bg-[#2e272d]/50 w-full rounded-2 overflow-hidden mx-2 transition-transform hover:scale-105 citem"
href="{base}/showcase/{kbd.key}"
tabindex="-1"
>
{#if browser}
<div class="w-full aspect-[1.9/1] vignette">
<img
src={kbd.image}
alt="Image of {kbd.author}'s keyboard"
class="w-full h-full object-cover"
/>
</div>
<div class="flex gap-4 mx-2 my-2 items-center">
<img
src={kbd.authorImage}
alt="Profile icon for {kbd.author}"
class="h-6 w-6 rounded-full"
/>
{kbd.author}
</div>
{:else}
<div class="w-full aspect-[1.9/1] bg-slate-800" />
<div class="my-2 h-6" />
{/if}
</a>
{/each}
</div>
</div>
<p class="text-center opacity-50 hover:underline">
<a href="{base}/showcase" class="inline-flex items-center gap-1">
See more keyboards in the showcase
<Icon path={mdiChevronRight} size="20px" />
</a>
</p>
</section>
<section class="section">
<img src="{base}/hand.svg" class="<sm:mx-auto sm:float-right w-72 ml-6 mb-6 mt--6" alt="" />
<h2 class="heading">Scan Your Hand, Build a Keyboard</h2>
Expand Down Expand Up @@ -214,7 +256,7 @@
class="text-black bg-brand-pink font-semibold sm:pt-1 sm:px-10 rounded sm:border-b-6 border-brand-green inline-flex items-center gap-30 cta sm:text-xl my-4 sm:pb-0.5 px-6 border-b-4"
on:click={join}
>
Try the beta
Try the Beta
<Icon path={mdiChevronRight} size="100%" class="w-[28px] sm:w-[32px]" />
</a>
<p class="mt-6 max-w-prose mx-auto px-6 text-gray-200">
Expand All @@ -232,7 +274,7 @@
<span slot="title" class="font-urbanist">Before you leave…</span>
<div slot="content" class="text-center text-white font-urbanist">
<p class="font-system">
Don't miss out on updates! The generator is in constant flux during the beta, and joining the
Don't miss out on updates! The generator is in constant flux during the Beta, and joining the
Discord server will keep you up to date with the changes.
</p>
<div class="bg-gray-700 inline-flex my-6 py-2 px-4 rounded items-center gap-4">
Expand Down Expand Up @@ -260,7 +302,7 @@
<a
href="beta"
class="inline-block text-black bg-brand-pink rounded px-2 py-0.5 font-semibold mt-6"
on:click={subbed}>Just take me to the beta already</a
on:click={subbed}>Just take me to the Beta already</a
>
</div>
</Dialog>
Expand Down Expand Up @@ -330,6 +372,39 @@
animation: rotate-slow 4s ease-in-out alternate infinite;
}
.vignette {
position: relative;
}
.vignette::after {
content: ' ';
position: absolute;
inset: 0;
background: radial-gradient(circle at center, transparent 60%, rgba(46, 39, 45, 0.4) 100%);
}
.carousel {
animation: carousel 50s linear infinite;
}
.carousel-container {
position: relative;
}
.carousel-container::before {
content: '';
position: absolute;
z-index: 1;
inset: 0;
pointer-events: none;
background: linear-gradient(
to right,
#17171d 0%,
rgba(23, 23, 29, 0) 20%,
rgba(23, 23, 29, 0) 80%,
#17171d 100%
);
}
@keyframes bounce-slow {
100% {
transform: translateY(-6%);
Expand All @@ -347,4 +422,17 @@
transform: rotate(1deg);
}
}
@keyframes carousel {
100% {
transform: translateZ(0) translateX(-50%);
}
0% {
transform: translateZ(0) translateX(0);
}
}
.citem:hover > .vignette > img {
filter: brightness(1.3);
}
</style>
50 changes: 36 additions & 14 deletions src/routes/showcase/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,29 +1,51 @@
<script lang="ts">
import { browser } from '$app/environment'
import { base } from '$app/paths'
import Header from '$lib/Header.svelte'
import { keyboards } from './showcase'
</script>

<svelte:head>
<title>Cosmos Keyboard</title>
<title>Showcase • Cosmos Keyboard</title>
<link rel="canonical" href="https://ryanis.cool/cosmos/showcase" />
<link rel="icon" href="{base}/favicon.png" />
</svelte:head>

<svelte:body class="bg-brand-dark" />
<svelte:body class="bg-brand-dark font-urbanist text-white" />

<Header />

<div class="font-urbanist text-center text-white">
<p class="mt-20">
There's nothing here yet. In the meantime, you can view some keyboards <a
class="s-link"
href="https://www.youtube.com/watch?v=dQw4w9WgXcQ">here</a
>.
</p>
<p class="mt-2">
If you're interested in posting your keyboard here when the page goes live, ping me on Discord!
</p>
<h1 class="uppercase text-xl sm:text-3xl text-[#68e4a9] font-medium text-center mt-10">
Keyboards from the Community
</h1>
<p class="text-center mt-2">You can click on any keyboard to view more information.</p>
<p class="text-center mt-2 opacity-50">
n.b. most of these will have bugs when you import them. I'll fix the models once V3 is publicly
released.
</p>
<div
class="mx-8 my-6 grid sm:grid-cols-[repeat(2,18rem)] md:grid-cols-[repeat(2,21rem)] gap-2 justify-center"
>
{#each keyboards as kbd}
<a class="block bg-[#2e272d]/50 rounded-2 overflow-hidden citem" href="{base}/showcase/{kbd.key}">
{#if browser}
<div class="w-full aspect-[1.9/1] vignette">
<img
src={kbd.image}
alt="Image of {kbd.author}'s keyboard"
class="w-full h-full object-cover"
/>
</div>
<div class="flex gap-4 mx-2 my-2 items-center">
<img src={kbd.authorImage} alt="Profile icon for {kbd.author}" class="h-6 w-6 rounded-full" />
{kbd.author}
</div>
{:else}
<div class="w-full aspect-[1.9/1] bg-slate-800" />
<div class="my-2 h-6" />
{/if}
</a>
{/each}
</div>

<style>
</style>
<p class="text-center opacity-50 mb-6">The order of keyboards is shuffled daily.</p>
14 changes: 14 additions & 0 deletions src/routes/showcase/[slug]/+page.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { error } from '@sveltejs/kit'
import { keyboards } from '../showcase.js'

export const load = ({ params }) => {
const keyboard = keyboards.find(k => k.key == params.slug)

if (!keyboard) {
error(404, {
message: 'Not found',
})
}

return { keyboard }
}
58 changes: 58 additions & 0 deletions src/routes/showcase/[slug]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<script lang="ts">
import { base } from '$app/paths'
import Header from '$lib/Header.svelte'
import Icon from '$lib/presentation/Icon.svelte'
import { mdiChevronRight } from '@mdi/js'
import type { keyboards } from '../showcase'
export let data: { keyboard: (typeof keyboards)[number] }
$: kbd = data.keyboard
</script>

<svelte:head>
<title>{kbd.name} • Showcase • Cosmos Keyboard</title>
<link rel="canonical" href="https://ryanis.cool/cosmos/showcase" />
<link rel="icon" href="{base}/favicon.png" />
</svelte:head>

<svelte:body class="bg-brand-dark font-urbanist text-white" />

<Header />

<div class="mx-auto container max-w-[calc(190vh-21rem)]">
<div class="w-full aspect-[1.9/1]">
<img
src={kbd.largeImage}
alt="Image of {kbd.author}'s keyboard"
class="w-full h-full object-cover"
/>
</div>
<div class="flex mt-2 mx-2">
<div class="w-full">
<h1 class="uppercase text-xl sm:text-3xl text-[#68e4a9] font-medium">
{kbd.name}
</h1>
<div class="flex gap-4 mx-0.5 my-2 items-center">
<img src={kbd.authorImage} alt="Profile icon for {kbd.author}" class="h-6 w-6 rounded-full" />
{kbd.author}
</div>
{#if kbd.details}
<p class="mt-2 mb-4">{kbd.details}</p>
{/if}
</div>
<div class="flex-none">
{#if kbd.config}
<a
href="{base}/beta{kbd.config}"
class="text-black font-semibold rounded inline-flex items-center gap-16 my-4 pl-6 pr-4 bg-brand-green <sm:ml-6 transition hover:shadow-lg shadow-teal/30"
>
Fit, Edit and Download
<Icon path={mdiChevronRight} size="100%" class="w-[28px] sm:w-[32px]" />
</a>
{/if}
</div>
</div>
</div>

<style>
</style>
Binary file added src/routes/showcase/assets/author-fata1err0r.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/author-jonas_h.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/author-lily.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/author-spidermo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/author-thebigskree.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/author-umang.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/kbd-fata1err0r.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/kbd-jonas_h.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/kbd-lily.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/kbd-spidermo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/kbd-thebigskree.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/routes/showcase/assets/kbd-umang.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 8abfee4

Please sign in to comment.