mirror of
https://github.com/wukko/cobalt.git
synced 2024-11-15 12:50:01 +00:00
web: omnibox base with meowbalt
This commit is contained in:
parent
7cab37fc30
commit
e6ffa4864c
11 changed files with 286 additions and 16 deletions
6
web/package-lock.json
generated
6
web/package-lock.json
generated
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "CC-BY-NC-SA-4.0",
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fontsource-variable/noto-sans-mono": "^5.0.20",
|
||||||
"@fontsource/ibm-plex-mono": "^5.0.13",
|
"@fontsource/ibm-plex-mono": "^5.0.13",
|
||||||
"@tabler/icons-svelte": "^3.6.0"
|
"@tabler/icons-svelte": "^3.6.0"
|
||||||
},
|
},
|
||||||
|
@ -403,6 +404,11 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@fontsource-variable/noto-sans-mono": {
|
||||||
|
"version": "5.0.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz",
|
||||||
|
"integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw=="
|
||||||
|
},
|
||||||
"node_modules/@fontsource/ibm-plex-mono": {
|
"node_modules/@fontsource/ibm-plex-mono": {
|
||||||
"version": "5.0.13",
|
"version": "5.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz",
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"vite": "^5.0.3"
|
"vite": "^5.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fontsource-variable/noto-sans-mono": "^5.0.20",
|
||||||
"@fontsource/ibm-plex-mono": "^5.0.13",
|
"@fontsource/ibm-plex-mono": "^5.0.13",
|
||||||
"@tabler/icons-svelte": "^3.6.0"
|
"@tabler/icons-svelte": "^3.6.0"
|
||||||
}
|
}
|
||||||
|
|
111
web/src/components/save/Omnibox.svelte
Normal file
111
web/src/components/save/Omnibox.svelte
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { IconLink } from '@tabler/icons-svelte';
|
||||||
|
|
||||||
|
import DownloadButton from './buttons/DownloadButton.svelte';
|
||||||
|
import ClearButton from './buttons/ClearButton.svelte';
|
||||||
|
|
||||||
|
let link: string = "";
|
||||||
|
let isFocused = false;
|
||||||
|
|
||||||
|
const validLink = (link: string) => {
|
||||||
|
try {
|
||||||
|
return /^https:/i.test(new URL(link).protocol);
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="omnibox">
|
||||||
|
<div id="input-container" class:focused={isFocused} class:downloadable={validLink(link)}>
|
||||||
|
<IconLink id="input-link-icon" color="var(--gray)" size="18px" />
|
||||||
|
|
||||||
|
<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"
|
||||||
|
>
|
||||||
|
|
||||||
|
{#if link.length > 0}
|
||||||
|
<ClearButton click={() => link = ""} />
|
||||||
|
{/if}
|
||||||
|
{#if validLink(link)}
|
||||||
|
<DownloadButton />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#omnibox {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 640px;
|
||||||
|
width: 100%;
|
||||||
|
gap: var(--padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-container {
|
||||||
|
display: flex;
|
||||||
|
box-shadow: 0 0 0 1.5px var(--gray) inset;
|
||||||
|
border-radius: 11px;
|
||||||
|
padding: 0 12px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
flex: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-container.downloadable {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-container.focused {
|
||||||
|
box-shadow: 0 0 0 1.5px var(--secondary) inset;
|
||||||
|
outline: var(--secondary) 0.5px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-container.focused :global(#input-link-icon) {
|
||||||
|
stroke: var(--secondary);
|
||||||
|
}
|
||||||
|
#input-container.downloadable :global(#input-link-icon) {
|
||||||
|
stroke: var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-area {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 0;
|
||||||
|
height: 18px;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--secondary);
|
||||||
|
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
/* workaround for safari */
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-area::placeholder {
|
||||||
|
color: var(--gray)
|
||||||
|
}
|
||||||
|
</style>
|
15
web/src/components/save/buttons/ClearButton.svelte
Normal file
15
web/src/components/save/buttons/ClearButton.svelte
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<script>
|
||||||
|
export let click;
|
||||||
|
import IconX from '@tabler/icons-svelte/IconX.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button id="clear-button" on:click={click}>
|
||||||
|
<IconX color="var(--secondary)" size="16px"/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#clear-button {
|
||||||
|
padding: 3px;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
54
web/src/components/save/buttons/DownloadButton.svelte
Normal file
54
web/src/components/save/buttons/DownloadButton.svelte
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<script>
|
||||||
|
import '@fontsource-variable/noto-sans-mono';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button id="download-button">
|
||||||
|
<span id="download-state">>></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#download-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
min-width: 48px;
|
||||||
|
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0 12px;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
border-left: 1px var(--gray) solid;
|
||||||
|
border-top-right-radius: 11px;
|
||||||
|
border-bottom-right-radius: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#download-state {
|
||||||
|
font-size: 24px;
|
||||||
|
font-family: "Noto Sans Mono Variable", "Noto Sans Mono", "IBM Plex Mono", monospace;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
text-indent: -5px;
|
||||||
|
letter-spacing: -0.22em;
|
||||||
|
|
||||||
|
margin-bottom: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#download-button:hover {
|
||||||
|
background: var(--button-hover-transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#download-button:disabled {
|
||||||
|
cursor: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#download-button:disabled:hover {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(#input-container.focused) #download-button {
|
||||||
|
border-left: 2px var(--secondary) solid;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -10,7 +10,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: calc(var(--sidebar-padding) * 2 - 2px);
|
padding: calc(var(--padding) * 2 - 2px);
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 535px) {
|
@media screen and (max-width: 535px) {
|
||||||
#cobalt-logo {
|
#cobalt-logo {
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
background: black;
|
background: var(--secondary);
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
width: var(--sidebar-width);
|
width: var(--sidebar-width);
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
#sidebar-tabs {
|
#sidebar-tabs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding-bottom: var(--sidebar-padding);
|
padding-bottom: var(--padding);
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,8 @@
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: linear-gradient(90deg,
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
rgba(0, 0, 0, 0.9) 0%,
|
rgba(0, 0, 0, 0.9) 0%,
|
||||||
rgba(0, 0, 0, 0) 4%,
|
rgba(0, 0, 0, 0) 4%,
|
||||||
rgba(0, 0, 0, 0) 50%,
|
rgba(0, 0, 0, 0) 50%,
|
||||||
|
|
|
@ -24,15 +24,15 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
padding: var(--sidebar-padding) 5px;
|
padding: var(--padding) 5px;
|
||||||
color: var(--accent);
|
color: var(--primary);
|
||||||
font-size: var(--sidebar-font-size);
|
font-size: var(--sidebar-font-size);
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-tab.active {
|
.sidebar-tab.active {
|
||||||
color: var(--background);
|
color: var(--secondary);
|
||||||
background: var(--accent);
|
background: var(--primary);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
@media screen and (max-width: 535px) {
|
@media screen and (max-width: 535px) {
|
||||||
.sidebar-tab {
|
.sidebar-tab {
|
||||||
padding: 5px var(--sidebar-padding);
|
padding: 5px var(--padding);
|
||||||
min-width: calc(var(--sidebar-width) / 2);
|
min-width: calc(var(--sidebar-width) / 2);
|
||||||
}
|
}
|
||||||
.sidebar-tab.active {
|
.sidebar-tab.active {
|
||||||
|
|
|
@ -13,20 +13,32 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:global(:root) {
|
:global(:root) {
|
||||||
--accent: #ffffff;
|
--primary: #ffffff;
|
||||||
--background: #000000;
|
--secondary: #000000;
|
||||||
|
--gray: #8d8d95;
|
||||||
|
|
||||||
|
--button: #eeeeee;
|
||||||
|
--button-hover: rgb(215, 215, 215);
|
||||||
|
--button-hover-transparent: rgba(215, 215, 215, 0.5);
|
||||||
|
--button-stroke: rgba(0, 0, 0, 0.8);
|
||||||
|
|
||||||
|
--padding: 12px;
|
||||||
|
|
||||||
--sidebar-width: 80px;
|
--sidebar-width: 80px;
|
||||||
--sidebar-font-size: 11px;
|
--sidebar-font-size: 11px;
|
||||||
--sidebar-padding: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(html),
|
:global(html),
|
||||||
:global(body) {
|
:global(body) {
|
||||||
font-family: "IBM Plex Mono", "Noto Sans Mono", monospace;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
}
|
||||||
|
|
||||||
|
:global(*) {
|
||||||
|
font-family: "IBM Plex Mono", "Noto Sans Mono Variable", "Noto Sans Mono", monospace;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(a) {
|
:global(a) {
|
||||||
|
@ -34,6 +46,28 @@
|
||||||
text-decoration-line: none;
|
text-decoration-line: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(svg),
|
||||||
|
:global(img) {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(button) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 7px 13px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: var(--button);
|
||||||
|
color: var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(button:hover) {
|
||||||
|
background-color: var(--button-hover);
|
||||||
|
}
|
||||||
|
|
||||||
#cobalt {
|
#cobalt {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
|
@ -1,2 +1,50 @@
|
||||||
<!-- home (save) page -->
|
<script>
|
||||||
<div>home</div>
|
import Omnibox from "../components/save/Omnibox.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="cobalt-save-container">
|
||||||
|
<main id="cobalt-save">
|
||||||
|
<img
|
||||||
|
id="meowbalt-smile"
|
||||||
|
src="/meowbalt/smile.png"
|
||||||
|
height="152"
|
||||||
|
alt="black and white cat smiling and loafing"
|
||||||
|
/>
|
||||||
|
<Omnibox />
|
||||||
|
</main>
|
||||||
|
<div id="terms-note">
|
||||||
|
by continuing you agree to terms and ethics of use
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#cobalt-save-container {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: var(--padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cobalt-save {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#meowbalt-smile {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#terms-note {
|
||||||
|
bottom: 0;
|
||||||
|
color: var(--gray);
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: var(--padding);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
BIN
web/static/meowbalt/smile.png
Normal file
BIN
web/static/meowbalt/smile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in a new issue