diff --git a/index.scss b/index.scss index c030f0a..2fe6c36 100644 --- a/index.scss +++ b/index.scss @@ -1,8 +1,11 @@ +// components @import '/src/component/PostGrid/$PostGrid'; @import '/src/component/PostTile/$PostTile'; @import '/src/component/Searchbar/$Searchbar'; @import '/src/component/IconButton/$IconButton'; +// routes @import '/src/route/post/$post_route'; +@import '/src/route/login/$login_route'; :root { --background-color: #1e1e2c; @@ -12,8 +15,12 @@ --primary-color-dark: #9696b3; --primary-color-darker: #72728d; --secondary-color: #aeaeec; - --secondary-color-dark: #424268; + --secondary-color-dark: #6d6da1; + --secondary-color-darker: #424268; + --border-radius-small: 0.4rem; + --border-radius-medium: 0.8rem; + --border-radius-large: 1.2rem; --nav-height: 50px; } html { @@ -65,7 +72,7 @@ nav { .app { display: flex; align-items: center; - border-radius: 0.4rem; + border-radius: var(--border-radius-small); // border: 1px solid var(--secondary-color); // padding: 0.2rem 0.4rem; margin: 0; @@ -74,7 +81,7 @@ nav { color: var(--background-color); background-color: var(--secondary-color); padding: 0.2em 0.4em; - border-radius: 0.4rem; + border-radius: var(--border-radius-small); font-size: 0.8rem; font-weight: bold; } @@ -90,7 +97,7 @@ nav { max-width: 500px; background-color: color-mix(in srgb, var(--background-color-light) 30%, transparent); border: 1px solid var(--primary-color-darker); - border-radius: 0.4rem; + border-radius: var(--border-radius-small); color: var(--primary-color-dark); transition: 0.3s all ease; cursor: pointer; @@ -114,6 +121,20 @@ nav { ion-icon.search { display: none; } + + div.account { + height: 2rem; + width: 2rem; + display: flex; + justify-content: center; + align-items: center; + border-radius: 2rem; + font-weight: bolder; + color: var(--secondary-color); + background-color: var(--secondary-color-darker); + user-select: none; + cursor: pointer; + } } @media (max-width: 800px) { @@ -139,12 +160,17 @@ router { } button { - background-color: var(--secondary-color-dark); + background-color: var(--secondary-color-darker); color: var(--secondary-color); padding: 0.8rem 1.2rem; border-radius: 1rem; border: none; cursor: pointer; + + &:hover { + background-color: var(--secondary-color-dark); + color: var(--primary-color); + } } ion-icon { @@ -160,4 +186,17 @@ ion-icon { a { color: var(--secondary-color); text-decoration: none; +} + +input { + background-color: var(--background-color-light); + border-radius: var(--border-radius-small); + border: 1px solid var(--background-color-lighter); + font-size: 0.9rem; + padding: 0.8rem 1.2rem; + color: var(--primary-color); + outline: none; + &:focus { + border-color: var(--secondary-color); + } } \ No newline at end of file diff --git a/src/component/IconButton/_$IconButton.scss b/src/component/IconButton/_$IconButton.scss index 5f66d60..583fd67 100644 --- a/src/component/IconButton/_$IconButton.scss +++ b/src/component/IconButton/_$IconButton.scss @@ -3,14 +3,10 @@ button.icon { justify-content: center; align-items: center; gap: 0.4rem; - padding: 0.4rem; - background-color: transparent; + padding: 0.8rem 1.2rem; ion-icon { - font-size: 1.5rem; - } - - &:hover { - background-color: var(--background-color-light); + font-size: 1.4rem; + color: inherit; } &.vertical { diff --git a/src/component/PostTile/_$PostTile.scss b/src/component/PostTile/_$PostTile.scss index c0baf32..6c61d0f 100644 --- a/src/component/PostTile/_$PostTile.scss +++ b/src/component/PostTile/_$PostTile.scss @@ -3,7 +3,7 @@ post-tile { transition: 0.3s all ease; position: relative; transition: all 0.3s ease; - border-radius: 10px; + border-radius: var(--border-radius-medium); overflow: hidden; -webkit-tap-highlight-color: transparent; user-select: none; @@ -31,7 +31,7 @@ post-tile { right: 0.3rem; padding: 0.2em 0.4em; height: 1rem; - border-radius: 4px; + border-radius: var(--border-radius-small); font-size: 12px; display: flex; align-items: center; diff --git a/src/component/Searchbar/_$Searchbar.scss b/src/component/Searchbar/_$Searchbar.scss index 4bd7dc8..828fdda 100644 --- a/src/component/Searchbar/_$Searchbar.scss +++ b/src/component/Searchbar/_$Searchbar.scss @@ -11,7 +11,7 @@ searchbar { div.input-container { margin-top: 0.4rem; background-color: color-mix(in srgb, var(--background-color-light) 100%, transparent); - border-radius: 0.4rem; + border-radius: var(--border-radius-small); font-size: 1rem; width: 500px; padding: 0.4rem 0.4rem; @@ -20,7 +20,7 @@ searchbar { z-index: 201; display: flex; align-items: center; - border: 1px solid var(--secondary-color-dark); + border: 1px solid var(--secondary-color-darker); &:focus-within { outline: none; @@ -39,16 +39,16 @@ searchbar { tag { display: inline-block; padding: 0.2rem 0.4rem; - background-color: var(--secondary-color-dark); + background-color: var(--secondary-color-darker); color: var(--secondary-color); - border-radius: 0.4rem; + border-radius: var(--border-radius-small); cursor: pointer; } } ion-icon { font-size: 20px; - color: var(--secondary-color-dark); + color: var(--secondary-color-darker); cursor: pointer; &:hover { color: var(--secondary-color); @@ -58,7 +58,7 @@ searchbar { div.selection-list-container { overflow: hidden; - border-radius: 0.4rem; + border-radius: var(--border-radius-small); background-color: var(--background-color); z-index: 201; max-width: calc(100% - 2rem); @@ -114,9 +114,9 @@ searchbar { } .tag-category, .user-level { padding: 0.1rem 0.4rem; - border-radius: 0.4rem; + border-radius: var(--border-radius-small); font-size: 0.9rem; - background-color: var(--secondary-color-dark); + background-color: var(--secondary-color-darker); color: var(--secondary-color); } @@ -138,7 +138,7 @@ searchbar { .input-wrapper { color: var(--primary-color); border: 1px solid var(--secondary-color); - border-radius: 0.4rem; + border-radius: var(--border-radius-small); position: relative; box-sizing: border-box; line-height: 1em; diff --git a/src/route/post/$post_route.ts b/src/route/post/$post_route.ts index a252b54..8a031d0 100644 --- a/src/route/post/$post_route.ts +++ b/src/route/post/$post_route.ts @@ -3,6 +3,7 @@ import { $Container, type $ContainerContentType } from "elexis"; import { Tag, TagCategory } from "../../structure/Tag"; import { ArtistCommentary } from "../../structure/Commentary"; import { Booru } from "../../structure/Booru"; +import type { $IonIcon } from "../../component/IonIcon/$IonIcon"; export const post_route = $('route').path('/posts/:id').id('post').builder(({$route, params}) => { if (!Number(params.id)) return $('h1').content('404: POST NOT FOUND'); @@ -46,43 +47,22 @@ export const post_route = $('route').path('/posts/:id').id('post').builder(({$ro new $Property('favorites').name('Favorites').content(post.favorites$), new $Property('score').name('Score').content(post.score$) ]), - new $Property('file-url').name('File').content($('a').href(post.file_url$).content(post.file_url$.convert((value) => value.replace('https://', ''))).target('_blank')), - new $Property('source-url').name('Source').content($('a').href(post.source$).content(post.source$.convert((value) => value.replace('https://', ''))).target('_blank')), - new $Property('booru-url').name(Booru.name$).content($('a').href(post.url$).content(post.url$.convert((value) => value.replace('https://', ''))).target('_blank')), + new $Property('file-url').name('File').content([ + $('a').href(post.file_url$).content(post.file_url$.convert((value) => value.replace('https://', ''))).target('_blank'), + $('ion-icon').name('clipboard').on('click', (e, $ion) => copyButtonHandler($ion, post.source)) + ]), + new $Property('source-url').name('Source').content([ + $('a').href(post.source$).content(post.source$.convert((value) => value.replace('https://', ''))).target('_blank'), + $('ion-icon').name('clipboard').on('click', (e, $ion) => copyButtonHandler($ion, post.source)) + ]), + new $Property('booru-url').name(Booru.name$).content([ + $('a').href(post.url$).content(post.url$.convert((value) => value.replace('https://', ''))).target('_blank'), + $('ion-icon').name('clipboard').on('click', (e, $ion) => copyButtonHandler($ion, post.source)) + ]), new $Property('booru-url').name('Webm').hide(true).self(async ($property) => { await post.ready; if (post.isUgoria) $property.content($('a').href(post.webm_url$).content(post.webm_url$.convert((value) => value.replace('https://', ''))).target('_blank')).hide(false); }), - // $('div').class('buttons').content([ - // $('icon-button').class('vertical').icon('link-outline').content(Booru.name$) - // .on('click', (e, $button) => { - // e.preventDefault(); - // navigator.clipboard.writeText(`${Booru.used.origin}${location.pathname}`); - // $button.content('Copied!'); - // setTimeout(() => { - // $button.content(Booru.name$) - // }, 2000); - // }), - // $('icon-button').class('vertical').icon('link-outline').content(`File`) - // .on('click', (e, $button) => { - // e.preventDefault(); - // navigator.clipboard.writeText(post.file_url); - // $button.content('Copied!'); - // setTimeout(() => { - // $button.content('File') - // }, 2000); - // }), - // $('icon-button').class('vertical').icon('link-outline').content(`Webm`) - // .on('click', (e, $button) => { - // e.preventDefault(); - // navigator.clipboard.writeText(post.previewURL); - // $button.content('Copied!'); - // setTimeout(() => { - // $button.content('Webm') - // }, 2000); - // }) - // .hide(true).self(async ($button) => { await post.ready; if (post.file_ext === 'zip') $button.hide(false) }) - // ]), ]), $('div').class('post-tags').content(async $tags => { const tags = await post.fetchTags(); @@ -117,6 +97,12 @@ export const post_route = $('route').path('/posts/:id').id('post').builder(({$ro ] }) +function copyButtonHandler($ion: $IonIcon, text: string) { + $ion.name('checkmark'); + navigator.clipboard.writeText(text); + setTimeout(() => $ion.name('clipboard'), 3000); +} + class $Property extends $Container { $name = $('span').class('property-name') $values = $('div').class('property-values') diff --git a/src/route/post/_$post_route.scss b/src/route/post/_$post_route.scss index d4d5143..f2f1a26 100644 --- a/src/route/post/_$post_route.scss +++ b/src/route/post/_$post_route.scss @@ -3,7 +3,7 @@ padding-top: var(--nav-height); section { background-color: #2f2f45; - border-radius: 20px; + border-radius: var(--border-radius-large); padding: 20px; } @@ -13,7 +13,7 @@ justify-content: center; align-items: center; background-color: #000000; - border-radius: 20px; + border-radius: var(--border-radius-large); overflow: hidden; width: calc(100vw - 300px - 4rem); margin: 1rem; @@ -85,7 +85,7 @@ overflow: scroll; overflow-x: hidden; height: calc(100vh - 2rem - var(--nav-height)); - border-radius: 20px; + border-radius: var(--border-radius-large); @media (max-width: 800px) { position: static; @@ -111,7 +111,7 @@ } .post-info { background-color: #2f2f45; - border-radius: 20px; + border-radius: var(--border-radius-large); padding: 20px; display: flex; flex-direction: column; @@ -136,15 +136,38 @@ div.property-values { display: flex; gap: 0.4rem; + width: 100%; overflow: hidden; span.property-value { - background-color: var(--secondary-color-dark); - color: var(--secondary-color); padding: 2px 4px; - border-radius: 4px; - text-overflow: ellipsis; - overflow: hidden; - text-wrap: nowrap; + background-color: var(--secondary-color-darker); + color: var(--secondary-color); + border-radius: var(--border-radius-small); + justify-content: space-between; + flex-shrink: 1; + + &:has(*) { + overflow: hidden; + padding: 0; + } + + &:has(ion-icon) { + flex-shrink: 0; + } + + * { + display: block; + padding: 2px 4px; + overflow: hidden; + text-wrap: nowrap; + text-overflow: ellipsis; + flex-shrink: 1; + } + ion-icon { + font-size: 1rem; + padding: 4px; + box-sizing: border-box; + } } } } @@ -164,10 +187,10 @@ text-decoration: none; } span.tag-post-count { - background-color: var(--secondary-color-dark); + background-color: var(--secondary-color-darker); color: var(--secondary-color); padding: 0px 4px; - border-radius: 4px; + border-radius: var(--border-radius-small); font-size: 12px; margin-left: 0.4rem; }