From 7113bf1a4d06df21bf65a8ff591fe6856f7e82e7 Mon Sep 17 00:00:00 2001 From: OFF0 Date: Mon, 1 May 2023 15:00:18 +0200 Subject: [PATCH] feed: visually improve threads styling CSS is a bit messy and should be redone, but threads are now styled a bit as branches. --- src/main.ts | 5 +- src/styles/cards.css | 130 ++++++++++++++++++++++++++++++++----------- src/styles/debug.css | 24 ++++++++ src/styles/main.css | 11 +++- src/styles/write.css | 4 +- src/ui.ts | 10 ++-- 6 files changed, 139 insertions(+), 45 deletions(-) create mode 100644 src/styles/debug.css diff --git a/src/main.ts b/src/main.ts index 487b5f4..e06506e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -89,10 +89,11 @@ const renderReply = (evt: EventWithNip19AndReplyTo) => { if (!parent) { // root article has not been rendered return; } - let replyContainer = parent.querySelector('.mobx-replies'); + let replyContainer = parent.querySelector('.mbox-replies'); if (!replyContainer) { - replyContainer = elem('div', {className: 'mobx-replies'}); + replyContainer = elem('div', {className: 'mbox-replies'}); parent.append(replyContainer); + parent.classList.add('mbox-has-replies'); } const reply = createTextNote(evt, eventRelayMap[evt.id][0]); replyContainer.append(reply); diff --git a/src/styles/cards.css b/src/styles/cards.css index b94c656..5be6ae4 100644 --- a/src/styles/cards.css +++ b/src/styles/cards.css @@ -5,16 +5,13 @@ flex-direction: row; flex-shrink: 0; flex-wrap: wrap; - margin-bottom: 1rem; + /* margin-bottom: 1rem; */ max-width: var(--content-width); - padding: 0 var(--gap-half); + padding: 0 0 0 var(--gap-half); } .mbox:last-child { margin-bottom: 0; } -.mbox .mbox { - padding: 0; -} .mbox-img { align-self: start; @@ -42,10 +39,14 @@ } .mbox-body { + flex-basis: 100%; flex-grow: 0; flex-shrink: 1; word-break: break-word; } +.mbox-body div a { + text-decoration: underline; +} .mbox-img + .mbox-body { flex-basis: calc(100% - var(--profileimg-size) - var(--gap-half)); } @@ -82,7 +83,9 @@ overflow: clip; } .mbox .mbox { + max-width: 100%; overflow: visible; + padding: 0; position: relative; } .mbox .buttons { @@ -95,32 +98,23 @@ .mbox button img + small { padding-left: .5rem; } -.mobx-replies { +.mbox-replies { + box-sizing: border-box; + flex-basis: 100%; flex-grow: 1; + flex-shrink: 0; position: relative; } -.mobx-replies .mobx-replies { +.mbox-replies .mbox-replies { --reply-padding: 3rem; margin-bottom: 2px; - padding: 0 1rem 0 var(--reply-padding); + padding: 0 0 0 var(--reply-padding); } -.mobx-replies .mobx-replies .mobx-replies { +.mbox-replies .mbox-replies .mbox-replies { --reply-padding: 0; } -.mbox .mbox::before, -.mobx-replies::before { - background-color: var(--bgcolor-inactive); - border: none; - content: ""; - display: block; - height: 200vh; - left: var(--profileimg-size-half); - margin-left: -.1rem; - position: absolute; - top: -200vh; - width: .2rem; -} -.mobx-replies .mbox .mbox::before { +/* direct replies */ +.mbox-replies .mbox-replies .mbox::before { background: none; border-color: var(--bgcolor-inactive);; border-style: solid; @@ -134,24 +128,76 @@ top: 0; width: .8rem; } -.mobx-replies .mbox .mbox::after { - background-color: var(--bgcolor-inactive); - border: none; +.mbox-replies .mbox-replies .mbox-replies .mbox::before { + content: none; + display: none; +} + +/* .mbox-replies .mbox-replies .mbox-replies .mbox::after, */ +.mbox-replies .mbox-replies .mbox-replies::before { + content: none; +} + +.mbox-body, +.mbox-has-replies:not(:last-child) { + position: relative; +} +.mbox-has-replies > .mbox-body::after, +.mbox-replies .mbox-has-replies:not(:last-child)::after, +.mbox-has-replies:not(:last-child) .mbox > .mbox-body::after, +.mbox-has-replies .mbox:not(:last-child) > .mbox-body::after { + bottom: 0; content: ""; display: block; - height: 100vh; - left: calc(-1 * var(--profileimg-size-quarter)); - margin-left: -.1rem; position: absolute; - top: -100vh; + top: .2rem; width: .2rem; } -/* support visualisation of 3 levels of thread nesting, rest render flat without line */ -.mbox .mobx-replies .mobx-replies::before, -.mobx-replies .mobx-replies .mbox .mbox::before { + +.mbox-body::after, +.mbox-has-replies::after { + background: var(--bgcolor-inactive); +} +.mbox-has-replies .mbox:not(:last-child) > .mbox-body::after { + left: -33px; +} +.mbox-has-replies .mbox-has-replies .mbox:not(:last-child) > .mbox-body::after { + left: -36px; +} +.mbox-has-replies > .mbox-body::after { + left: -33px; +} +.mbox-has-replies:not(:last-child) .mbox > .mbox-body::after { + left: -33px; +} +.mbox-has-replies:not(:last-child)::after { + left: 18px; +} + +.mbox-replies .mbox-has-replies:not(:last-child)::after { + left: 19px; +} +.mbox-replies .mbox-replies .mbox-has-replies:not(:last-child)::after { + left: -11px; +} + +.mbox-replies .mbox-replies .mbox-has-replies > .mbox-body::after { + left: -18px; +} +.mbox-has-replies .mbox-has-replies .mbox-has-replies .mbox:not(:last-child) > .mbox-body::after { + left: -18px; +} +.mbox-replies .mbox:not(.mbox-has-replies):last-child > .mbox-body::after { content: none; + display: none; } -.mobx-replies .mbox .mbox .mbox-img { + +.mbox-replies .mbox-replies .mbox-has-replies.mbox:not(:last-child) > .mbox-body::after { + left: -18px; +} + + +.mbox-replies .mbox .mbox .mbox-img { --profileimg-size: 2rem; left: -.2rem; margin-right: .5rem; @@ -159,6 +205,22 @@ position: relative; } +.mbox-replies .mbox .mbox .mbox-body { + display: flex; + flex-wrap: wrap; + font-size: var(--font-small); + padding-bottom: var(--gap-half); + padding-top: var(--gap-eight); +} +.mbox-replies .mbox .mbox .mbox-header a:last-of-type::after { + content: " "; + display: inline-block; + padding-right: var(--gap-half); +} +.mbox-replies .mbox .mbox .buttons { + display: none; +} + [data-append]::after { color: var(--color-accent); content: "…"; diff --git a/src/styles/debug.css b/src/styles/debug.css new file mode 100644 index 0000000..7ddcfda --- /dev/null +++ b/src/styles/debug.css @@ -0,0 +1,24 @@ + +.mbox-img { + opacity: .73; +} +.mbox-replies { + margin-bottom: 4px !important; + outline: 2px dashed rgba(0, 255, 0, 0.15); + outline-offset: -2px; +} +.mbox-replies .mbox-replies { + outline-color: rgba(0, 255, 0, .4); + outline-offset: -4px; +} +.mbox-replies .mbox-replies .mbox-replies { + outline-color: rgba(0, 255, 0, .7); + outline-offset: -6px; +} +.mbox-replies .mbox-replies .mbox-replies .mbox-replies { + outline-color: rgba(210, 255, 0, 1); + outline-offset: -8px; +} +.mbox-replies .mbox-replies .mbox-replies .mbox-replies .mbox-replies { + outline-color: rgb(187, 119, 9); +} diff --git a/src/styles/main.css b/src/styles/main.css index bd32aed..bb4e2b7 100644 --- a/src/styles/main.css +++ b/src/styles/main.css @@ -3,6 +3,7 @@ @import "form.css"; @import "write.css"; @import "error.css"; +/* @import "debug.css"; */ :root { --content-width: min(100% - 2.4rem, 96ch); @@ -17,6 +18,8 @@ --font-small: 1.2rem; --gap: 2.4rem; --gap-half: 1.2rem; + --gap-quarter: .6rem; + --gap-eight: .3rem; --profileimg-size: 4rem; --profileimg-size-half: 2rem; --profileimg-size-quarter: 1rem; @@ -56,7 +59,7 @@ --bgcolor-inactive: #434343; --bgcolor-textinput: #0e0e0e; --color: #e3e3e3; - --color-accent: #7b7b7b; + --color-accent: #828282; --color-danger: #e3e3e3; } @@ -78,7 +81,7 @@ body { background-color: var(--bgcolor); color: var(--color); font-size: 1.6rem; - line-height: 1.5; + line-height: 1.313; word-break: break-all; } @@ -101,6 +104,7 @@ textarea { small, time { font-size: var(--font-small); + line-height: 1.25; } canvas, @@ -118,6 +122,7 @@ img { a { color: var(--color-accent); + text-decoration: none; } a:focus { @@ -126,7 +131,7 @@ a:focus { outline-offset: 0; } a:visited { - color: darkslateblue; + color: #8377ce; } nav a:visited { color: inherit; diff --git a/src/styles/write.css b/src/styles/write.css index ab46ef4..3b3605b 100644 --- a/src/styles/write.css +++ b/src/styles/write.css @@ -2,11 +2,11 @@ background-color: darkmagenta; border-color: darkmagenta; border-radius: 10rem; - bottom: 8rem; + bottom: 5rem; height: 10rem; padding: 0; position: fixed; - right: 8rem; + right: 5rem; width: 10rem; z-index: 1; } diff --git a/src/ui.ts b/src/ui.ts index 862b5a6..9a3caf9 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -21,7 +21,9 @@ export const createTextNote = ( relay: string, ) => { const {host, img, name, time, userName} = getMetadata(evt, relay); - const replies = replyList.filter(({replyTo}) => replyTo === evt.id); + const replies = replyList.filter(({replyTo}) => replyTo === evt.id) + .sort(sortByCreatedAt) + .reverse(); // const isLongContent = evt.content.trimRight().length > 280; // const content = isLongContent ? evt.content.slice(0, 280) : evt.content; const reactions = getReactions(evt.id); @@ -44,7 +46,7 @@ export const createTextNote = ( if (localStorage.getItem('reply_to') === evt.id) { openWriteInput(buttons, evt.id); } - const replyFeed: Array = replies[0] ? replies.sort(sortByCreatedAt).map(e => setViewElem(e.id, createTextNote(e, relay))) : []; + const replyFeed: Array = replies[0] ? replies.map(e => setViewElem(e.id, createTextNote(e, relay))) : []; return elemArticle([ elem('div', {className: 'mbox-img'}, img), elem('div', {className: 'mbox-body'}, [ @@ -64,8 +66,8 @@ export const createTextNote = ( ]), buttons, ]), - ...(replies[0] ? [elem('div', {className: 'mobx-replies'}, replyFeed.reverse())] : []), - ], {data: {id: evt.id, pubkey: evt.pubkey, relay}}); + ...(replies[0] ? [elem('div', {className: 'mbox-replies'}, replyFeed)] : []), + ], {className: replies.length ? 'mbox-has-replies' : '', data: {id: evt.id, pubkey: evt.pubkey, relay}}); }; export const renderRecommendServer = (evt: Event, relay: string) => {