mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-21 12:48:28 +00:00
web: basic pager layout + home banner
This commit is contained in:
parent
b7ce70bc6d
commit
ed39a13d57
@ -12,5 +12,10 @@
|
|||||||
"@sveltejs/vite-plugin-svelte": "^3.1.0",
|
"@sveltejs/vite-plugin-svelte": "^3.1.0",
|
||||||
"svelte": "^4.2.12",
|
"svelte": "^4.2.12",
|
||||||
"vite": "^5.2.0"
|
"vite": "^5.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fontsource-variable/noto-sans-mono": "^5.0.19",
|
||||||
|
"@fontsource/redaction-10": "^5.0.1",
|
||||||
|
"@tabler/icons-svelte": "^3.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
web/public/meowbalt/smile.png
Normal file
BIN
web/public/meowbalt/smile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -1,5 +1,17 @@
|
|||||||
html,
|
html,
|
||||||
body {
|
body,
|
||||||
|
#app {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: calc(100% + env(safe-area-inset-top)/2);
|
height: calc(100% + env(safe-area-inset-top)/2);
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
svg, img {
|
||||||
|
pointer-events: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--accent: #000000;
|
||||||
|
--gray: #6e6e6e;
|
||||||
}
|
}
|
@ -1,3 +1,27 @@
|
|||||||
|
<script>
|
||||||
|
import '@fontsource-variable/noto-sans-mono';
|
||||||
|
import '@fontsource/redaction-10';
|
||||||
|
|
||||||
|
import HomeBanner from "./components/HomeBanner/HomeBanner.svelte";
|
||||||
|
import Pager from "./components/Pager/Pager.svelte";
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
:global(*) {
|
||||||
|
font-family: 'Noto Sans Mono', monospace;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<main>
|
<main>
|
||||||
<h1>Hello Bro</h1>
|
<HomeBanner />
|
||||||
|
<Pager />
|
||||||
</main>
|
</main>
|
||||||
|
30
web/src/components/HomeBanner/HomeBanner.svelte
Normal file
30
web/src/components/HomeBanner/HomeBanner.svelte
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<style>
|
||||||
|
#home-banner {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding-bottom: 32px;
|
||||||
|
}
|
||||||
|
#meowbalt-smile {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#big-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 70px;
|
||||||
|
line-height: 85%;
|
||||||
|
letter-spacing: -0.07em;
|
||||||
|
font-family: 'Redaction 10', serif;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="home-banner">
|
||||||
|
<img id="meowbalt-smile"
|
||||||
|
src="/meowbalt/smile.png"
|
||||||
|
width="140"
|
||||||
|
alt="black and white cat smiling and loafing">
|
||||||
|
|
||||||
|
<h1 id="big-title">Save what<br>you love</h1>
|
||||||
|
</div>
|
117
web/src/components/Pager/Pager.svelte
Normal file
117
web/src/components/Pager/Pager.svelte
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<script>
|
||||||
|
import IconLink from '@tabler/icons-svelte/IconLink.svelte';
|
||||||
|
|
||||||
|
let inputContainer;
|
||||||
|
let link = "";
|
||||||
|
let isFocused = false;
|
||||||
|
|
||||||
|
const testLink = (/** @type {string} */ link) => {
|
||||||
|
try {
|
||||||
|
return /^https?:/i.test(new URL(link).protocol);
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const pasteClipboard = () => {
|
||||||
|
navigator.clipboard.readText().then(text => {
|
||||||
|
let matchLink = text.match(/https?:\/\/[^\s]+/g);
|
||||||
|
if (matchLink) {
|
||||||
|
link = matchLink[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#pager {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 585px;
|
||||||
|
width: 100%;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
#input-container {
|
||||||
|
display: flex;
|
||||||
|
border: var(--gray) 1px solid;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 0 10px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
flex: 1
|
||||||
|
}
|
||||||
|
:global(#input-container.focused) {
|
||||||
|
outline: var(--accent) 1px solid;
|
||||||
|
border: var(--accent) 1px solid;
|
||||||
|
}
|
||||||
|
:global(#input-container.focused) :global(#input-link-icon) {
|
||||||
|
stroke: var(--accent);
|
||||||
|
}
|
||||||
|
#link-area {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 0;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--accent);
|
||||||
|
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
#link-area::placeholder {
|
||||||
|
color: var(--gray);
|
||||||
|
}
|
||||||
|
#button-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="pager">
|
||||||
|
<div id="input-container" class:focused={isFocused} bind:this={inputContainer}>
|
||||||
|
<IconLink id="input-link-icon" color="var(--gray)" size="20px"/>
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y-autofocus -->
|
||||||
|
<input
|
||||||
|
id="link-area"
|
||||||
|
bind:value={link}
|
||||||
|
|
||||||
|
on:input={() => isFocused = true}
|
||||||
|
on:focus={() => isFocused = true}
|
||||||
|
on:blur={() => isFocused = false}
|
||||||
|
|
||||||
|
spellcheck="false"
|
||||||
|
autocomplete="off"
|
||||||
|
autocapitalize="off"
|
||||||
|
maxlength="256"
|
||||||
|
|
||||||
|
placeholder="paste the link here"
|
||||||
|
aria-label="link input area"
|
||||||
|
|
||||||
|
autofocus>
|
||||||
|
|
||||||
|
{#if link.length > 0}
|
||||||
|
<button id="clear-button" on:click={() => link = ""}>✕</button>
|
||||||
|
{/if}
|
||||||
|
{#if testLink(link)}
|
||||||
|
<input
|
||||||
|
id="download-button"
|
||||||
|
aria-label="download button"
|
||||||
|
type="submit"
|
||||||
|
value=">>">
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div id="button-container">
|
||||||
|
<div id="mode-switcher">
|
||||||
|
<button id="auto-mode-button">auto</button>
|
||||||
|
<button id="audio-mode-button">audio</button>
|
||||||
|
</div>
|
||||||
|
<button id="paste-button" on:click={pasteClipboard}>paste</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,7 +1,9 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite';
|
||||||
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [svelte()],
|
plugins: [
|
||||||
|
svelte()
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user