diff --git a/components.js b/components.js
index 6eb55d3..0e6e519 100644
--- a/components.js
+++ b/components.js
@@ -3665,7 +3665,7 @@ customElements.define('tags-input', class extends HTMLElement {
e.preventDefault()
}
if (e.target.value.trim() !== '') {
- if (e.key === 'Enter' || e.key === ',' || e.key === '/' || e.code === 'Space') {
+ if (e.key === 'Enter' || e.key === ',' || e.key === '/') {
const tagValue = e.target.value.trim()
if (this.tags.has(tagValue)) {
this.tagsWrapper.querySelector(`[data-value="${tagValue}"]`).animate([
diff --git a/css/main.css b/css/main.css
index 6ec416e..c9216b9 100644
--- a/css/main.css
+++ b/css/main.css
@@ -395,6 +395,7 @@ ul {
}
.logo {
+ position: absolute;
color: inherit;
display: grid;
align-items: center;
@@ -653,6 +654,7 @@ main {
}
theme-toggle {
+ margin-left: auto;
padding: 0 0.5rem;
}
@@ -669,7 +671,8 @@ theme-toggle {
font-size: 0.9rem;
}
-#latest_articles_list {
+#latest_articles_list,
+#query_results_list {
margin: 1rem 0;
gap: 1.6rem;
}
@@ -701,6 +704,10 @@ theme-toggle {
gap: 0.3rem;
}
+#explore {
+ padding-top: 1.5rem;
+}
+
#article {
gap: 2rem 0;
padding-bottom: 3rem;
@@ -713,6 +720,19 @@ theme-toggle {
padding-top: 1.5rem;
}
+#article_contributors {
+ flex-wrap: wrap;
+ gap: 0.3rem;
+ margin: 0.5rem 0 1rem 0;
+}
+
+.contributor {
+ font-size: 0.8rem;
+ background-color: rgba(var(--text-color), 0.06);
+ border-radius: 0.3rem;
+ padding: 0.3rem 0.5rem;
+}
+
#dashboard {
height: -webkit-max-content;
height: -moz-max-content;
diff --git a/css/main.min.css b/css/main.min.css
index 703a7d8..d279e98 100644
--- a/css/main.min.css
+++ b/css/main.min.css
@@ -1 +1 @@
-*{padding:0;margin:0;box-sizing:border-box;font-family:"Inter",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color), 1);background:rgba(var(--background-color), 1)}body,body *{--accent-color: #256eff;--text-color: 36, 36, 36;--background-color: 248, 248, 248;--foreground-color: rgb(255, 255, 255);--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #f3a600;scrollbar-width:thin}body[data-theme=dark],body[data-theme=dark] *{--accent-color: #86afff;--text-color: 230, 230, 230;--text-color-light: 170, 170, 170;--background-color: 10, 10, 10;--foreground-color: rgb(24, 24, 24);--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffd13a}body[data-theme=dark] sm-popup::part(popup){background-color:var(--foreground-color)}p,strong{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a{text-decoration:none}a:not([class]){color:var(--accent-color)}a:not([class]):focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}button,.button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;align-items:center;font-size:.9rem;font-weight:500}.button{white-space:nowrap;padding:.5rem .8rem;border-radius:.3rem;background-color:rgba(var(--text-color), 0.06);color:rgba(var(--text-color), 0.8);justify-content:center}.button--primary{background-color:var(--accent-color);color:rgba(var(--background-color), 1)}.icon-only{padding:.5rem;border-radius:.3rem}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}sm-input,sm-textarea,tags-input{font-size:.9rem;--border-radius: 0.3rem}sm-button{--padding: 0.5rem 0.8rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}sm-button.uppercase{letter-spacing:.05em}sm-button.danger{--background: var(--danger-color);color:rgba(var(--background-color), 1)}ul{list-style:none}.hide-completely{display:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/-1}.h1{font-size:1.5rem}.h2{font-size:1.2rem}.h3{font-size:1rem}.h4{font-size:.9rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:flex}.grid{display:grid}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.ripple{height:8rem;width:8rem;position:absolute;border-radius:50%;transform:scale(0);background:radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}.empty-state{display:grid;width:100%;padding:1.5rem 1rem}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)+.empty-state{display:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8);flex-shrink:0}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:rgba(var(--text-color), 0.1);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#prompt_message{margin-bottom:1.5rem}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem 0 .8rem;align-items:center;grid-template-columns:auto 1fr auto}.popup__header__close{padding:.5rem;cursor:pointer}.logo{color:inherit;display:grid;align-items:center;grid-template-columns:auto 1fr;gap:0 .2rem;justify-self:center}.logo h4{text-transform:capitalize;font-size:.9rem;letter-spacing:.03em}.logo .main-logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details summary{display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}details[open]>summary .down-arrow{transform:rotate(180deg)}sm-select,sm-option,strip-option{font-size:.9rem}strip-select{--gap: 0}strip-option{font-weight:500;--border-radius: 0.3rem;--active-option-color: var(--accent-color)}sm-menu{--background: var(--foreground-color)}menu-option{font-size:.9rem}sm-copy{font-size:.9rem;--button-border-radius: 0.2rem}.warning{background-color:khaki;color:rgba(0,0,0,.7);padding:1rem;border-radius:.5rem;line-height:1.5}.page{height:100%}.page-layout,#preview_page{display:grid;grid-template-columns:1rem minmax(0, 1fr) 1rem}.page-layout>*,#preview_page>*{grid-column:2/3}#landing{grid-template-rows:auto 1fr}#landing header{padding:1.5rem 0}#landing>section{align-items:center;text-align:center}#landing h1{margin-top:-2ch;font-size:clamp(2rem,5vw,5rem)}#landing p{max-width:100%}#sign_in,#sign_up{grid-template-rows:auto 1fr;align-items:center}#sign_in section,#sign_up section{margin-top:-6rem;justify-self:center;width:min(24rem,100%)}#sign_in sm-form,#sign_up sm-form{margin:2rem 0}#sign_in header,#sign_up header{padding:1.5rem 0}#sign_up .h2{margin-bottom:.5rem}#sign_up .card{margin:1.5rem 0}#sign_up h5{font-weight:500;color:rgba(var(--text-color), 0.8)}#sign_up .warning{margin-top:2rem}#loading{place-content:center;text-align:center}#loader_container{height:3rem;overflow:hidden;margin-bottom:1.5rem}#loader_container::after{content:"";position:absolute;height:100%;width:100%;left:0;background:linear-gradient(rgba(var(--foreground-color), 1), transparent 20%, transparent 80%, rgba(var(--foreground-color), 1))}#loader{height:6rem;width:6rem;-webkit-animation:scroll infinite 1s cubic-bezier(0.075, 0.82, 0.165, 1);animation:scroll infinite 1s cubic-bezier(0.075, 0.82, 0.165, 1);fill:rgba(var(--text-color), 0.2)}@-webkit-keyframes scroll{to{transform:translateY(-3rem)}}@keyframes scroll{to{transform:translateY(-3rem)}}.label{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-bottom:.2rem}.icon--success{fill:var(--green)}.icon--failure,.icon--error{fill:var(--danger-color)}main{display:grid;height:100%;grid-template-rows:auto 1fr;grid-template-columns:minmax(0, 1fr)}#main_header{position:-webkit-sticky;position:sticky;top:0;display:grid;gap:.5rem;padding:1rem;align-items:center;grid-column:1/-1;grid-template-columns:auto 1fr auto auto;background-color:rgba(var(--background-color), 1);z-index:2;border-bottom:thin solid rgba(var(--text-color), 0.2)}#expanding_search{position:absolute;display:grid;gap:.5rem;align-items:center;width:calc(100% - 2rem);margin:0 1rem;z-index:1;background-color:rgba(var(--background-color), 1);-webkit-clip-path:circle(0 at 1.5rem);clip-path:circle(0 at 1.5rem);transition:-webkit-clip-path .1s;transition:clip-path .1s;transition:clip-path .1s, -webkit-clip-path .1s}#expanding_search.expanded{transition:-webkit-clip-path .3s;transition:clip-path .3s;transition:clip-path .3s, -webkit-clip-path .3s;-webkit-clip-path:circle(200%);clip-path:circle(200%)}#expanding_search button{margin-right:.5rem}#search_suggestions{position:absolute;top:calc(100% + .5rem);background-color:var(--foreground-color);padding:.3rem;width:100%;border-radius:.3rem;box-shadow:0 .5rem 1.5rem rgba(0,0,0,.1)}.search-suggestion{font-size:.9rem;color:inherit;padding:1rem;border-radius:.3rem}#search_articles{--border-radius: 0.5em;width:100%}theme-toggle{padding:0 .5rem}#main_page{display:grid;padding:1rem;padding-top:0;gap:1.5rem}.category{padding:.5rem;color:inherit;font-size:.9rem}#latest_articles_list{margin:1rem 0;gap:1.6rem}.article-card{gap:.3rem}.article-card a{color:inherit}.article-card .article-link{gap:.5rem}.article-card__title{line-height:1.4}.article-card__category{background-color:rgba(var(--text-color), 0.1);border-radius:.3rem;font-size:.8rem;padding:.3rem .6rem;font-weight:700;color:rgba(var(--text-color), 0.6) !important;justify-self:flex-start;text-transform:capitalize}.article-card .flex{font-size:.8rem;gap:.3rem}#article{gap:2rem 0;padding-bottom:3rem}.hero-section{display:grid;gap:.5rem;grid-template-columns:minmax(0, 1fr);padding-top:1.5rem}#dashboard{height:-webkit-max-content;height:-moz-max-content;height:max-content;padding:1.5rem 0;grid-template-rows:auto 1fr}#publishing_requests{margin-top:2rem;align-content:flex-start}.request-card{display:grid;gap:.5rem;border-radius:.5rem;align-items:flex-start;grid-template-columns:1fr auto}.request-card__title{grid-area:2/1}.request-card__time{font-size:.8rem}.request-card .flex{grid-row:span 2}.request-card .publish-button{text-transform:uppercase;letter-spacing:.05em;font-size:.8rem;font-weight:700}#preview_popup h1,#article h1{font-size:1.4rem;margin-bottom:1rem}#preview_popup h3:not(:first-of-type),#article h3:not(:first-of-type){margin-top:2rem}#preview_popup h3,#article h3{margin-bottom:1rem}#preview_popup h3:not(:first-of-type),#article h3:not(:first-of-type){margin-top:1.5rem}#preview_popup p,#article p{font-family:"noto serif",serif;font-size:1rem;line-height:1.8}#preview_popup p>*,#article p>*{font-family:inherit}#preview_popup time,#preview_popup #reading_time,#article time,#article #reading_time{font-size:.8rem}@media screen and (max-width: 40rem){.hide-on-mobile{display:none}}@supports(-webkit-text-stroke: 1px black){#landing h1{-webkit-text-stroke:1px rgba(var(--text-color), 1);-webkit-text-fill-color:rgba(var(--background-color), 1)}}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}h1,.h1{font-size:2rem}.h2{font-size:1.8rem}.h3{font-size:1.3rem}.h4{font-size:1rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 .8rem}#confirmation_popup{--width: 24rem}.page-layout{grid-template-columns:1fr 90vw 1fr}.hide-on-desktop{display:none}#landing h1{-webkit-text-stroke-width:.1rem}#main_header{padding:1rem 1.5rem}#main_page{padding:1rem 6vw;grid-template-rows:auto 1fr;grid-template-columns:1fr 22rem}#main_page__header{grid-area:1/1/2/-1}#expanding_search{margin:1rem 1.5rem;left:0;width:20rem}#preview_popup h1,#article h1{font-size:2rem}#article{grid-template-columns:1fr 60ch 1fr}#preview_popup{--width: 60ch}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.interact,button:not(.button--primary){transition:background-color .3s}.interact:hover,button:not(.button--primary):hover{background-color:rgba(var(--text-color), 0.06)}.button--primary{transition:filter .3s}.button--primary:hover{filter:brightness(120%)}}
\ No newline at end of file
+*{padding:0;margin:0;box-sizing:border-box;font-family:"Inter",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color), 1);background:rgba(var(--background-color), 1)}body,body *{--accent-color: #256eff;--text-color: 36, 36, 36;--background-color: 248, 248, 248;--foreground-color: rgb(255, 255, 255);--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #f3a600;scrollbar-width:thin}body[data-theme=dark],body[data-theme=dark] *{--accent-color: #86afff;--text-color: 230, 230, 230;--text-color-light: 170, 170, 170;--background-color: 10, 10, 10;--foreground-color: rgb(24, 24, 24);--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffd13a}body[data-theme=dark] sm-popup::part(popup){background-color:var(--foreground-color)}p,strong{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type),strong:not(:last-of-type){margin-bottom:1.5rem}a{text-decoration:none}a:not([class]){color:var(--accent-color)}a:not([class]):focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}button,.button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;align-items:center;font-size:.9rem;font-weight:500}.button{white-space:nowrap;padding:.5rem .8rem;border-radius:.3rem;background-color:rgba(var(--text-color), 0.06);color:rgba(var(--text-color), 0.8);justify-content:center}.button--primary{background-color:var(--accent-color);color:rgba(var(--background-color), 1)}.icon-only{padding:.5rem;border-radius:.3rem}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}sm-input,sm-textarea,tags-input{font-size:.9rem;--border-radius: 0.3rem}sm-button{--padding: 0.5rem 0.8rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}sm-button.uppercase{letter-spacing:.05em}sm-button.danger{--background: var(--danger-color);color:rgba(var(--background-color), 1)}ul{list-style:none}.hide-completely{display:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/-1}.h1{font-size:1.5rem}.h2{font-size:1.2rem}.h3{font-size:1rem}.h4{font-size:.9rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:flex}.grid{display:grid}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.ripple{height:8rem;width:8rem;position:absolute;border-radius:50%;transform:scale(0);background:radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}.empty-state{display:grid;width:100%;padding:1.5rem 1rem}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)+.empty-state{display:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8);flex-shrink:0}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:rgba(var(--text-color), 0.1);height:-webkit-max-content;height:-moz-max-content;height:max-content}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#prompt_message{margin-bottom:1.5rem}.popup__header{display:grid;gap:.5rem;width:100%;padding:0 1.5rem 0 .8rem;align-items:center;grid-template-columns:auto 1fr auto}.popup__header__close{padding:.5rem;cursor:pointer}.logo{position:absolute;color:inherit;display:grid;align-items:center;grid-template-columns:auto 1fr;gap:0 .2rem;justify-self:center}.logo h4{text-transform:capitalize;font-size:.9rem;letter-spacing:.03em}.logo .main-logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details summary{display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}details[open]>summary .down-arrow{transform:rotate(180deg)}sm-select,sm-option,strip-option{font-size:.9rem}strip-select{--gap: 0}strip-option{font-weight:500;--border-radius: 0.3rem;--active-option-color: var(--accent-color)}sm-menu{--background: var(--foreground-color)}menu-option{font-size:.9rem}sm-copy{font-size:.9rem;--button-border-radius: 0.2rem}.warning{background-color:khaki;color:rgba(0,0,0,.7);padding:1rem;border-radius:.5rem;line-height:1.5}.page{height:100%}.page-layout,#preview_page{display:grid;grid-template-columns:1rem minmax(0, 1fr) 1rem}.page-layout>*,#preview_page>*{grid-column:2/3}#landing{grid-template-rows:auto 1fr}#landing header{padding:1.5rem 0}#landing>section{align-items:center;text-align:center}#landing h1{margin-top:-2ch;font-size:clamp(2rem,5vw,5rem)}#landing p{max-width:100%}#sign_in,#sign_up{grid-template-rows:auto 1fr;align-items:center}#sign_in section,#sign_up section{margin-top:-6rem;justify-self:center;width:min(24rem,100%)}#sign_in sm-form,#sign_up sm-form{margin:2rem 0}#sign_in header,#sign_up header{padding:1.5rem 0}#sign_up .h2{margin-bottom:.5rem}#sign_up .card{margin:1.5rem 0}#sign_up h5{font-weight:500;color:rgba(var(--text-color), 0.8)}#sign_up .warning{margin-top:2rem}#loading{place-content:center;text-align:center}#loader_container{height:3rem;overflow:hidden;margin-bottom:1.5rem}#loader_container::after{content:"";position:absolute;height:100%;width:100%;left:0;background:linear-gradient(rgba(var(--foreground-color), 1), transparent 20%, transparent 80%, rgba(var(--foreground-color), 1))}#loader{height:6rem;width:6rem;-webkit-animation:scroll infinite 1s cubic-bezier(0.075, 0.82, 0.165, 1);animation:scroll infinite 1s cubic-bezier(0.075, 0.82, 0.165, 1);fill:rgba(var(--text-color), 0.2)}@-webkit-keyframes scroll{to{transform:translateY(-3rem)}}@keyframes scroll{to{transform:translateY(-3rem)}}.label{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-bottom:.2rem}.icon--success{fill:var(--green)}.icon--failure,.icon--error{fill:var(--danger-color)}main{display:grid;height:100%;grid-template-rows:auto 1fr;grid-template-columns:minmax(0, 1fr)}#main_header{position:-webkit-sticky;position:sticky;top:0;display:grid;gap:.5rem;padding:1rem;align-items:center;grid-column:1/-1;grid-template-columns:auto 1fr auto auto;background-color:rgba(var(--background-color), 1);z-index:2;border-bottom:thin solid rgba(var(--text-color), 0.2)}#expanding_search{position:absolute;display:grid;gap:.5rem;align-items:center;width:calc(100% - 2rem);margin:0 1rem;z-index:1;background-color:rgba(var(--background-color), 1);-webkit-clip-path:circle(0 at 1.5rem);clip-path:circle(0 at 1.5rem);transition:-webkit-clip-path .1s;transition:clip-path .1s;transition:clip-path .1s, -webkit-clip-path .1s}#expanding_search.expanded{transition:-webkit-clip-path .3s;transition:clip-path .3s;transition:clip-path .3s, -webkit-clip-path .3s;-webkit-clip-path:circle(200%);clip-path:circle(200%)}#expanding_search button{margin-right:.5rem}#search_suggestions{position:absolute;top:calc(100% + .5rem);background-color:var(--foreground-color);padding:.3rem;width:100%;border-radius:.3rem;box-shadow:0 .5rem 1.5rem rgba(0,0,0,.1)}.search-suggestion{font-size:.9rem;color:inherit;padding:1rem;border-radius:.3rem}#search_articles{--border-radius: 0.5em;width:100%}theme-toggle{margin-left:auto;padding:0 .5rem}#main_page{display:grid;padding:1rem;padding-top:0;gap:1.5rem}.category{padding:.5rem;color:inherit;font-size:.9rem}#latest_articles_list,#query_results_list{margin:1rem 0;gap:1.6rem}.article-card{gap:.3rem}.article-card a{color:inherit}.article-card .article-link{gap:.5rem}.article-card__title{line-height:1.4}.article-card__category{background-color:rgba(var(--text-color), 0.1);border-radius:.3rem;font-size:.8rem;padding:.3rem .6rem;font-weight:700;color:rgba(var(--text-color), 0.6) !important;justify-self:flex-start;text-transform:capitalize}.article-card .flex{font-size:.8rem;gap:.3rem}#explore{padding-top:1.5rem}#article{gap:2rem 0;padding-bottom:3rem}.hero-section{display:grid;gap:.5rem;grid-template-columns:minmax(0, 1fr);padding-top:1.5rem}#article_contributors{flex-wrap:wrap;gap:.3rem;margin:.5rem 0 1rem 0}.contributor{font-size:.8rem;background-color:rgba(var(--text-color), 0.06);border-radius:.3rem;padding:.3rem .5rem}#dashboard{height:-webkit-max-content;height:-moz-max-content;height:max-content;padding:1.5rem 0;grid-template-rows:auto 1fr}#publishing_requests{margin-top:2rem;align-content:flex-start}.request-card{display:grid;gap:.5rem;border-radius:.5rem;align-items:flex-start;grid-template-columns:1fr auto}.request-card__title{grid-area:2/1}.request-card__time{font-size:.8rem}.request-card .flex{grid-row:span 2}.request-card .publish-button{text-transform:uppercase;letter-spacing:.05em;font-size:.8rem;font-weight:700}#preview_popup h1,#article h1{font-size:1.4rem;margin-bottom:1rem}#preview_popup h3:not(:first-of-type),#article h3:not(:first-of-type){margin-top:2rem}#preview_popup h3,#article h3{margin-bottom:1rem}#preview_popup h3:not(:first-of-type),#article h3:not(:first-of-type){margin-top:1.5rem}#preview_popup p,#article p{font-family:"noto serif",serif;font-size:1rem;line-height:1.8}#preview_popup p>*,#article p>*{font-family:inherit}#preview_popup time,#preview_popup #reading_time,#article time,#article #reading_time{font-size:.8rem}@media screen and (max-width: 40rem){.hide-on-mobile{display:none}}@supports(-webkit-text-stroke: 1px black){#landing h1{-webkit-text-stroke:1px rgba(var(--text-color), 1);-webkit-text-fill-color:rgba(var(--background-color), 1)}}@media screen and (min-width: 40rem){sm-popup{--width: 24rem}h1,.h1{font-size:2rem}.h2{font-size:1.8rem}.h3{font-size:1.3rem}.h4{font-size:1rem}.popup__header{grid-column:1/-1;padding:1rem 1.5rem 0 .8rem}#confirmation_popup{--width: 24rem}.page-layout{grid-template-columns:1fr 90vw 1fr}.hide-on-desktop{display:none}#landing h1{-webkit-text-stroke-width:.1rem}#main_header{padding:1rem 1.5rem}#main_page{padding:1rem 6vw;grid-template-rows:auto 1fr;grid-template-columns:1fr 22rem}#main_page__header{grid-area:1/1/2/-1}#expanding_search{margin:1rem 1.5rem;left:0;width:20rem}#preview_popup h1,#article h1{font-size:2rem}#article{grid-template-columns:1fr 60ch 1fr}#preview_popup{--width: 60ch}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.interact,button:not(.button--primary){transition:background-color .3s}.interact:hover,button:not(.button--primary):hover{background-color:rgba(var(--text-color), 0.06)}.button--primary{transition:filter .3s}.button--primary:hover{filter:brightness(120%)}}
\ No newline at end of file
diff --git a/css/main.scss b/css/main.scss
index 6476253..ff7bdec 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -382,6 +382,7 @@ ul {
cursor: pointer;
}
.logo {
+ position: absolute;
color: inherit;
display: grid;
align-items: center;
@@ -610,6 +611,7 @@ main {
width: 100%;
}
theme-toggle {
+ margin-left: auto;
padding: 0 0.5rem;
}
@@ -631,7 +633,8 @@ theme-toggle {
font-size: 0.9rem;
}
-#latest_articles_list {
+#latest_articles_list,
+#query_results_list {
margin: 1rem 0;
gap: 1.6rem;
}
@@ -662,6 +665,10 @@ theme-toggle {
}
}
+#explore {
+ padding-top: 1.5rem;
+}
+
#article {
gap: 2rem 0;
padding-bottom: 3rem;
@@ -673,6 +680,17 @@ theme-toggle {
grid-template-columns: minmax(0, 1fr);
padding-top: 1.5rem;
}
+#article_contributors {
+ flex-wrap: wrap;
+ gap: 0.3rem;
+ margin: 0.5rem 0 1rem 0;
+}
+.contributor {
+ font-size: 0.8rem;
+ background-color: rgba(var(--text-color), 0.06);
+ border-radius: 0.3rem;
+ padding: 0.3rem 0.5rem;
+}
#dashboard {
height: max-content;
diff --git a/index.html b/index.html
index 002883a..43f9201 100644
--- a/index.html
+++ b/index.html
@@ -238,8 +238,10 @@
- Explore
-
+
@@ -588,11 +590,7 @@
let params = {}
let searchParams
if (targetPage === '') {
- if (typeof myFloID === "undefined") {
- pageId = 'landing'
- } else {
- pageId = 'main_page'
- }
+ pageId = 'main_page'
} else {
if (targetPage.includes('/')) {
if (targetPage.includes('?')) {
@@ -610,7 +608,6 @@
pageId = targetPage
}
}
- if (typeof myFloID === "undefined" && !(['sign_up', 'sign_in', 'loading', 'landing'].includes(pageId))) return
if (searchParams) {
const urlSearchParams = new URLSearchParams('?' + searchParams);
params = Object.fromEntries(urlSearchParams.entries());
@@ -638,11 +635,11 @@
break;
case 'article':
targetPage = 'article'
- renderArticle(params.articleID)
+ await renderArticle(params.articleID)
break;
case 'explore':
targetPage = 'explore'
- renderArticle(params.articleID)
+ renderExplorePage(params)
break;
case 'dashboard':
targetPage = 'dashboard'
@@ -777,7 +774,12 @@
}
const getArticles = async () => {
- await floCloudAPI.requestObjectData('articles')
+ await Promise.all([
+ floCloudAPI.requestObjectData('articles'),
+ floCloudAPI.requestObjectData('articlesContent')
+ ])
+ delete floGlobals.appObjects.articlesContent
+ showPage(window.location.hash, { firstLoad: true })
}
function getArrayOfObj(obj) {
@@ -809,13 +811,33 @@
}
async function renderArticle(articleID) {
- await floCloudAPI.requestObjectData(articleID)
- const articleBody = floGlobals.appObjects[articleID]
- const { title, published, readTime } = floGlobals.appObjects.articles[articleID]
+ const allArticles = await compactIDB.readData('appObjects', 'articlesContent')
+ const { title, published, readTime, contributors } = floGlobals.appObjects.articles[articleID]
getRef('article_title').textContent = title
getRef('published_time').textContent = getFormattedTime(published, 'date-only')
getRef('reading_time').textContent = `${readTime} Min read`
- getRef('article_body').innerHTML = articleBody
+ getRef('article_body').innerHTML = allArticles[articleID]
+ const frag = document.createDocumentFragment()
+ contributors.forEach(id => {
+ frag.append(createElement('div', {
+ textContent: id,
+ className: 'contributor'
+ }))
+ })
+ getRef('article_contributors').innerHTML = ''
+ getRef('article_contributors').append(frag)
+ }
+
+ function renderExplorePage(params) {
+ const { type, query } = params
+ const frag = document.createDocumentFragment()
+ const options = (type === 'category') ? { keys: ['category'] } : { keys: ['title', 'category', 'tags'], threshold: 0.3 }
+ const fuse = new Fuse(getArrayOfObj(floGlobals.appObjects.articles).sort((a, b) => b.published - a.published), options)
+ const searchResult = fuse.search(query).map(v => v.item)
+ searchResult.forEach(articleDetail => frag.append(render.articleCard(articleDetail)))
+ getRef('explore_heading').textContent = `${type === 'category' ? 'Explore' : 'Related to'} ${query}`
+ getRef('query_results_list').innerHTML = ''
+ getRef('query_results_list').append(frag)
}
async function renderPublishingRequests() {
@@ -834,12 +856,12 @@
if (e.target.closest('.publish-button')) {
const button = e.target.closest('.publish-button');
const vc = button.closest('.request-card').dataset.vc;
- const { message: { articleID, category, content, title, tags, readTime }, vectorClock } = floGlobals.generalData[`publishing_requests|${floGlobals.adminID}|${floGlobals.application}`][vc];
+ const { message: { articleID, category, content, contributors, title, tags, readTime }, vectorClock } = floGlobals.generalData[`publishing_requests|${floGlobals.adminID}|${floGlobals.application}`][vc];
const isPublished = floGlobals.appObjects['articles'].hasOwnProperty(articleID)
getConfirmation(`${isPublished ? 'Update' : 'Publish'} article?`).then(res => {
if (res) {
floGlobals.appObjects['publishedVc'][vectorClock] = true
- floGlobals.appObjects[articleID] = content
+ floGlobals.appObjects.articlesContent[articleID] = content
if (isPublished) {
floGlobals.appObjects['articles'][articleID]['updated'] = Date.now();
} else {
@@ -847,13 +869,14 @@
floGlobals.appObjects['articles'][articleID]['published'] = Date.now();
}
floGlobals.appObjects['articles'][articleID].category = category
+ floGlobals.appObjects['articles'][articleID].contributors = contributors
floGlobals.appObjects['articles'][articleID].title = title
floGlobals.appObjects['articles'][articleID].tags = tags
floGlobals.appObjects['articles'][articleID].readTime = readTime
Promise.all([
floCloudAPI.updateObjectData('articles'),
floCloudAPI.updateObjectData('publishedVc'),
- floCloudAPI.resetObjectData(articleID)
+ floCloudAPI.updateObjectData('articlesContent'),
]).then(() => {
notify(`${isPublished ? 'Updated' : 'Published'} article`, 'success')
button.closest('.request-card').remove()
@@ -886,7 +909,7 @@
keys: ['title', 'tags', 'category'],
threshold: 0.3
}
- const fuse = new Fuse(getArrayOfObj(floGlobals.appObjects.articles), options)
+ const fuse = new Fuse(getArrayOfObj(floGlobals.appObjects.articles).sort((a, b) => b.published - a.published), options)
const searchResult = fuse.search(searchKey).map(v => v.item)
getRef('search_suggestions').innerHTML = ''
if (searchResult.length) {
@@ -919,24 +942,24 @@
}
}, 100))
+ getRef('search_articles').addEventListener('keyup', e => {
+ if (e.target.value.trim() !== '' && e.code === 'Enter') {
+ location.hash = `#/explore?type=search&query=${e.target.value.trim()}`
+ e.target.value = ''
+ }
+ })
+
function getSignedIn() {
return new Promise((resolve, reject) => {
- if (window.location.hash.includes('sign_in') || window.location.hash.includes('sign_up')) {
- showPage(window.location.hash)
- } else {
- showPage('landing', { isPreview: location.hash.includes('preview') })
- }
getRef('sign_in_button').onclick = () => {
resolve(getRef('private_key_field').value.trim())
getRef('private_key_field').value = ''
- showPage('loading')
}
getRef('sign_up_button').onclick = () => {
resolve(getRef('generated_private_key').value.trim())
getRef('generated_private_key').value = ''
- showPage('loading')
}
})
}
@@ -962,15 +985,15 @@
getRef('user_flo_id').value = myFloID
floGlobals.isSubAdmin = floGlobals.subAdmins.includes(myFloID)
if (floGlobals.isSubAdmin) {
- getRef('publishing_requests').addEventListener('click', handleRequestClick)
- document.querySelectorAll('.admin-option').forEach(elem => elem.classList.remove('hide-completely'))
+ getRef('publishing_requests').addEventListener('click', handleRequestClick);
+ document.querySelectorAll('.admin-option').forEach(elem => elem.classList.remove('hide-completely'));
+ floGlobals.appObjects.articlesContent = await compactIDB.readData('appObjects', 'articlesContent')
} else {
getRef('publishing_requests').removeEventListener('click', handleRequestClick)
document.querySelectorAll('.admin-option').forEach(elem => elem.classList.add('hide-completely'))
}
if (location.hash.includes('sign_in') || location.hash.includes('sign_up'))
location.hash = floGlobals.isSubAdmin ? '#/dashboard' : '#/home'
- showPage(window.location.hash, { firstLoad: true })
console.log(result)
}).catch(error => console.error(error))
}
@@ -9930,7 +9953,7 @@
promises[i] = compactIDB.readAllData(loadData[i])
Promise.all(promises).then(results => {
for (var i = 0; i < loadData.length; i++)
- floGlobals[loadData[i]] = results[i]
+ floGlobals[loadData[i]] = results[i];
resolve("Loaded Data from app IDB")
}).catch(error => reject(error))
})