UX improvements
This commit is contained in:
parent
b61adfc188
commit
47dc6de154
224
components.js
224
components.js
@ -2387,6 +2387,7 @@ smSelect.innerHTML = `
|
|||||||
-ms-flex-align: center;
|
-ms-flex-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
z-index: 2;
|
||||||
}
|
}
|
||||||
.selection:focus{
|
.selection:focus{
|
||||||
-webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);
|
-webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);
|
||||||
@ -2417,7 +2418,7 @@ smSelect.innerHTML = `
|
|||||||
background: rgba(var(--background-color), 1);
|
background: rgba(var(--background-color), 1);
|
||||||
border: solid 1px rgba(var(--text-color), 0.2);
|
border: solid 1px rgba(var(--text-color), 0.2);
|
||||||
border-radius: var(--border-radius, 0.5rem);
|
border-radius: var(--border-radius, 0.5rem);
|
||||||
z-index: 2;
|
z-index: 1;
|
||||||
-webkit-box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
|
-webkit-box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
|
||||||
box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
|
box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
|
||||||
}
|
}
|
||||||
@ -4290,4 +4291,223 @@ customElements.define('sm-textarea',
|
|||||||
this.checkInput()
|
this.checkInput()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const tagsInput = document.createElement('template')
|
||||||
|
tagsInput.innerHTML = `
|
||||||
|
<style>
|
||||||
|
*{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
:host{
|
||||||
|
--accent-color: #4d2588;
|
||||||
|
--text-color: 17, 17, 17;
|
||||||
|
--background-color: 255, 255, 255;
|
||||||
|
--danger-color: red;
|
||||||
|
--border-radius: 0.3rem;
|
||||||
|
--background: rgba(var(--text-color), 0.06);
|
||||||
|
}
|
||||||
|
.hide{
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.tags-wrapper{
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
cursor: text;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-items: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.5rem 0.5rem 0 0.5rem;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
background: var(--background);
|
||||||
|
}
|
||||||
|
.tags-wrapper:focus-within{
|
||||||
|
box-shadow: 0 0 0 0.1rem var(--accent-color) inset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
align-items: center;
|
||||||
|
display: inline-flex;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
padding: 0.3rem 0.5rem;
|
||||||
|
margin: 0 0.5rem 0.5rem 0;
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
height: 1.2rem;
|
||||||
|
width: 1.2rem;
|
||||||
|
margin-left: 0.3rem;
|
||||||
|
fill: rgba(var(--text-color), 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: inline-flex;
|
||||||
|
width: auto;
|
||||||
|
color: inherit;
|
||||||
|
max-width: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
padding: 0.4rem 0.5rem;
|
||||||
|
margin: 0 0.5rem 0.5rem 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.placeholder{
|
||||||
|
position: absolute;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
top: 50%;
|
||||||
|
font-weight: 500;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: rgba(var(--text-color), 0.6);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="tags-wrapper">
|
||||||
|
<input type="text" size="3"/>
|
||||||
|
<p class="placeholder"></p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
customElements.define('tags-input', class extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.attachShadow({
|
||||||
|
mode: 'open'
|
||||||
|
}).append(tagsInput.content.cloneNode(true))
|
||||||
|
|
||||||
|
this.input = this.shadowRoot.querySelector('input')
|
||||||
|
this.tagsWrapper = this.shadowRoot.querySelector('.tags-wrapper')
|
||||||
|
this.placeholder = this.shadowRoot.querySelector('.placeholder')
|
||||||
|
this.reflectedAttributes = ['placeholder', 'limit']
|
||||||
|
this.limit = undefined
|
||||||
|
this.tags = new Set()
|
||||||
|
|
||||||
|
this.reset = this.reset.bind(this)
|
||||||
|
this.handleInput = this.handleInput.bind(this)
|
||||||
|
this.handleKeydown = this.handleKeydown.bind(this)
|
||||||
|
this.handleClick = this.handleClick.bind(this)
|
||||||
|
this.removeTag = this.removeTag.bind(this)
|
||||||
|
}
|
||||||
|
static get observedAttributes() {
|
||||||
|
return ['placeholder', 'limit']
|
||||||
|
}
|
||||||
|
get value() {
|
||||||
|
return [...this.tags].join()
|
||||||
|
}
|
||||||
|
get isValid() {
|
||||||
|
return this.tags.size
|
||||||
|
}
|
||||||
|
focusIn() {
|
||||||
|
this.input.focus()
|
||||||
|
}
|
||||||
|
reset() {
|
||||||
|
this.input.value = ''
|
||||||
|
this.tags.clear()
|
||||||
|
while (this.input.previousElementSibling) {
|
||||||
|
this.input.previousElementSibling.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleInput(e) {
|
||||||
|
const inputValueLength = e.target.value.trim().length
|
||||||
|
e.target.setAttribute('size', inputValueLength ? inputValueLength : '3')
|
||||||
|
if (inputValueLength) {
|
||||||
|
this.placeholder.classList.add('hide')
|
||||||
|
}
|
||||||
|
else if (!inputValueLength && !this.tags.size) {
|
||||||
|
this.placeholder.classList.remove('hide')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleKeydown(e) {
|
||||||
|
if (e.key === ',' || e.key === '/') {
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
if (e.target.value.trim() !== '') {
|
||||||
|
if (e.key === 'Enter' || e.key === ',' || e.key === '/' || e.code === 'Space') {
|
||||||
|
const tagValue = e.target.value.trim()
|
||||||
|
if (this.tags.has(tagValue)) {
|
||||||
|
this.tagsWrapper.querySelector(`[data-value="${tagValue}"]`).animate([
|
||||||
|
{
|
||||||
|
backgroundColor: 'initial'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
backgroundColor: 'var(--accent-color)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
backgroundColor: 'initial'
|
||||||
|
},
|
||||||
|
], {
|
||||||
|
duration: 300,
|
||||||
|
easing: 'ease'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const tag = document.createElement('span')
|
||||||
|
tag.dataset.value = tagValue
|
||||||
|
tag.className = 'tag'
|
||||||
|
tag.innerHTML = `
|
||||||
|
<span class="tag-text">${tagValue}</span>
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
|
||||||
|
`
|
||||||
|
this.input.before(tag)
|
||||||
|
this.tags.add(tagValue)
|
||||||
|
}
|
||||||
|
e.target.value = ''
|
||||||
|
e.target.setAttribute('size', '3')
|
||||||
|
if (this.limit && this.limit < this.tags.size + 1) {
|
||||||
|
this.input.readOnly = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (e.key === 'Backspace' && this.input.previousElementSibling) {
|
||||||
|
this.removeTag(this.input.previousElementSibling)
|
||||||
|
}
|
||||||
|
if (this.limit && this.limit > this.tags.size) {
|
||||||
|
this.input.readOnly = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleClick(e) {
|
||||||
|
if (e.target.closest('.tag')) {
|
||||||
|
this.removeTag(e.target.closest('.tag'))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.input.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeTag(tag) {
|
||||||
|
this.tags.delete(tag.dataset.value)
|
||||||
|
tag.remove()
|
||||||
|
if (!this.tags.size) {
|
||||||
|
this.placeholder.classList.remove('hide')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
this.input.addEventListener('input', this.handleInput)
|
||||||
|
this.input.addEventListener('keydown', this.handleKeydown)
|
||||||
|
this.tagsWrapper.addEventListener('click', this.handleClick)
|
||||||
|
}
|
||||||
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
|
if (name === 'placeholder') {
|
||||||
|
this.placeholder.textContent = newValue
|
||||||
|
}
|
||||||
|
if (name === 'limit') {
|
||||||
|
this.limit = parseInt(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disconnectedCallback() {
|
||||||
|
this.input.removeEventListener('input', this.handleInput)
|
||||||
|
this.input.removeEventListener('keydown', this.handleKeydown)
|
||||||
|
this.tagsWrapper.removeEventListener('click', this.handleClick)
|
||||||
|
}
|
||||||
|
})
|
||||||
91
css/main.css
91
css/main.css
@ -136,7 +136,8 @@ a:any-link:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sm-input,
|
sm-input,
|
||||||
sm-textarea {
|
sm-textarea,
|
||||||
|
tags-input {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
--border-radius: 0.3rem;
|
--border-radius: 0.3rem;
|
||||||
}
|
}
|
||||||
@ -529,6 +530,8 @@ menu-option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#filter_panel {
|
#filter_panel {
|
||||||
|
position: sticky;
|
||||||
|
top: 6.5rem;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0.5rem 1.5rem;
|
||||||
grid-column: 1/-1;
|
grid-column: 1/-1;
|
||||||
@ -661,9 +664,6 @@ menu-option {
|
|||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
}
|
}
|
||||||
.heading::before {
|
.heading::before {
|
||||||
content: "";
|
content: "";
|
||||||
@ -673,17 +673,12 @@ menu-option {
|
|||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: var(--accent-color);
|
background-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
.heading button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.article-section {
|
.article-section {
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
overflow-x: auto;
|
|
||||||
-ms-flex-negative: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
-ms-scroll-snap-type: x mandatory;
|
|
||||||
scroll-snap-type: x mandatory;
|
|
||||||
}
|
}
|
||||||
.article-section:not(:last-of-type) {
|
.article-section:not(:last-of-type) {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
@ -693,10 +688,6 @@ menu-option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-card {
|
.content-card {
|
||||||
scroll-snap-align: start;
|
|
||||||
width: min(46ch, 100%);
|
|
||||||
-ms-flex-negative: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: var(--foreground-color);
|
background-color: var(--foreground-color);
|
||||||
-webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.16) inset;
|
-webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.16) inset;
|
||||||
@ -818,32 +809,17 @@ menu-option {
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
background-color: var(--foreground-color);
|
border-radius: 0.2rem;
|
||||||
border: solid thin rgba(var(--text-color), 0.2);
|
border: solid thin rgba(var(--text-color), 0.3);
|
||||||
border-radius: 0.5rem;
|
-webkit-box-shadow: 0.3rem 0.5rem 0 0.1rem rgba(var(--text-color), 0.8);
|
||||||
|
box-shadow: 0.1rem 0.2rem 0 0.1rem rgba(var(--text-color), 0.8);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
padding-left: 1.3rem;
|
padding-left: 1.3rem figcaption;
|
||||||
}
|
padding-left-margin-top: 0.5rem;
|
||||||
.quote-template::before {
|
padding-left-color: rgba(var(--text-color), 0.8);
|
||||||
display: -webkit-box;
|
padding-left-font-size: 0.8rem;
|
||||||
display: -ms-flexbox;
|
padding-left-margin-left: auto;
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
height: 100%;
|
|
||||||
width: 0.3rem;
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
}
|
|
||||||
.quote-template blockquote {
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.quote-template figcaption {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
color: rgba(var(--text-color), 0.8);
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#version_history_panel {
|
#version_history_panel {
|
||||||
@ -977,14 +953,18 @@ menu-option {
|
|||||||
width: 1rem;
|
width: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#publish_article_popup {
|
||||||
|
--min-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 40rem) {
|
@media screen and (max-width: 40rem) {
|
||||||
#article_name_wrapper,
|
#article_name_wrapper,
|
||||||
#selected_content_options {
|
#selected_content_options {
|
||||||
grid-row: 2/3;
|
grid-row: 2/3;
|
||||||
grid-column: 1/-1;
|
grid-column: 1/-1;
|
||||||
}
|
}
|
||||||
#article_name_wrapper sm-menu,
|
#article_name_wrapper #filter_button,
|
||||||
#selected_content_options sm-menu {
|
#selected_content_options #filter_button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,6 +974,24 @@ menu-option {
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.article-section {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-scroll-snap-type: x mandatory;
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
overflow-x: auto;
|
||||||
|
-ms-flex-negative: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-card {
|
||||||
|
scroll-snap-align: start;
|
||||||
|
-ms-flex-negative: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: min(45ch, calc(100% - 2rem));
|
||||||
|
}
|
||||||
|
|
||||||
.hide-on-mobile {
|
.hide-on-mobile {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -1041,6 +1039,10 @@ menu-option {
|
|||||||
grid-template-columns: auto 1fr auto auto;
|
grid-template-columns: auto 1fr auto auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#filter_panel {
|
||||||
|
top: 4.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
#main_page.active-sidebar {
|
#main_page.active-sidebar {
|
||||||
-ms-scroll-chaining: none;
|
-ms-scroll-chaining: none;
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
@ -1063,6 +1065,11 @@ menu-option {
|
|||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.article-section {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(40ch, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
#article_list_popup .popup__header {
|
#article_list_popup .popup__header {
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -116,7 +116,8 @@ a:any-link:focus-visible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sm-input,
|
sm-input,
|
||||||
sm-textarea {
|
sm-textarea,
|
||||||
|
tags-input {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
--border-radius: 0.3rem;
|
--border-radius: 0.3rem;
|
||||||
}
|
}
|
||||||
@ -460,6 +461,8 @@ menu-option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#filter_panel {
|
#filter_panel {
|
||||||
|
position: sticky;
|
||||||
|
top: 6.5rem;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding: 0.5rem 1.5rem;
|
padding: 0.5rem 1.5rem;
|
||||||
grid-column: 1/-1;
|
grid-column: 1/-1;
|
||||||
@ -576,7 +579,6 @@ menu-option {
|
|||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
display: flex;
|
|
||||||
&::before {
|
&::before {
|
||||||
content: "";
|
content: "";
|
||||||
width: 0.3rem;
|
width: 0.3rem;
|
||||||
@ -585,14 +587,13 @@ menu-option {
|
|||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: var(--accent-color);
|
background-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
button{
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-section {
|
.article-section {
|
||||||
display: flex;
|
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
overflow-x: auto;
|
|
||||||
flex-shrink: 0;
|
|
||||||
scroll-snap-type: x mandatory;
|
|
||||||
&:not(:last-of-type) {
|
&:not(:last-of-type) {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
@ -601,9 +602,6 @@ menu-option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.content-card {
|
.content-card {
|
||||||
scroll-snap-align: start;
|
|
||||||
width: min(46ch, 100%);
|
|
||||||
flex-shrink: 0;
|
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: var(--foreground-color);
|
background-color: var(--foreground-color);
|
||||||
box-shadow: 0 0 0 1px rgba(var(--text-color), 0.16) inset;
|
box-shadow: 0 0 0 1px rgba(var(--text-color), 0.16) inset;
|
||||||
@ -700,32 +698,22 @@ menu-option {
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
background-color: var(--foreground-color);
|
border-radius: .2rem;
|
||||||
border: solid thin rgba(var(--text-color), 0.2);
|
border: solid thin rgba(var(--text-color), 0.3);
|
||||||
border-radius: 0.5rem;
|
-webkit-box-shadow: .3rem .5rem 0 .1rem rgba(var(--text-color), 0.8);
|
||||||
|
box-shadow: .1rem .2rem 0 .1rem rgba(var(--text-color), 0.8);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
padding-left: 1.3rem;
|
padding-left: 1.3rem
|
||||||
&::before {
|
|
||||||
display: flex;
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
height: 100%;
|
|
||||||
width: 0.3rem;
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
}
|
|
||||||
blockquote {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.quote {
|
|
||||||
}
|
|
||||||
figcaption {
|
figcaption {
|
||||||
margin-top: 0.5rem;
|
margin-top: .5rem;
|
||||||
color: rgba(var(--text-color), 0.8);
|
color: rgba(var(--text-color), 0.8);
|
||||||
font-size: 0.8rem;
|
font-size: .8rem;
|
||||||
|
margin-left: auto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#version_history_panel {
|
#version_history_panel {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
width: min(24rem, 100%);
|
width: min(24rem, 100%);
|
||||||
@ -849,18 +837,33 @@ menu-option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#publish_article_popup{
|
||||||
|
--min-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 40rem) {
|
@media screen and (max-width: 40rem) {
|
||||||
#article_name_wrapper,
|
#article_name_wrapper,
|
||||||
#selected_content_options {
|
#selected_content_options {
|
||||||
grid-row: 2/3;
|
grid-row: 2/3;
|
||||||
grid-column: 1/-1;
|
grid-column: 1/-1;
|
||||||
sm-menu {
|
#filter_button {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#article_name_wrapper{
|
#article_name_wrapper{
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
.article-section{
|
||||||
|
display: flex;
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
overflow-x: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.content-card{
|
||||||
|
scroll-snap-align: start;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: min(45ch, calc(100% - 2rem));
|
||||||
|
}
|
||||||
.hide-on-mobile {
|
.hide-on-mobile {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -901,6 +904,9 @@ menu-option {
|
|||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
grid-template-columns: auto 1fr auto auto;
|
grid-template-columns: auto 1fr auto auto;
|
||||||
}
|
}
|
||||||
|
#filter_panel {
|
||||||
|
top: 4.2rem;
|
||||||
|
}
|
||||||
#main_page {
|
#main_page {
|
||||||
&.active-sidebar {
|
&.active-sidebar {
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
@ -921,6 +927,10 @@ menu-option {
|
|||||||
#article_wrapper {
|
#article_wrapper {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
|
.article-section{
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(40ch, 1fr));
|
||||||
|
}
|
||||||
#article_list_popup {
|
#article_list_popup {
|
||||||
.popup__header {
|
.popup__header {
|
||||||
grid-template-columns: auto 1fr auto;
|
grid-template-columns: auto 1fr auto;
|
||||||
|
|||||||
113
index.html
113
index.html
@ -83,7 +83,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<text-field id="current_article_title"></text-field>
|
<text-field id="current_article_title"></text-field>
|
||||||
<button class="icon-only" title="Show filters" onclick="toggleFilterPanel()">
|
<button id="filter_button" class="icon-only" title="Show filters" onclick="toggleFilterPanel()">
|
||||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
||||||
fill="#000000">
|
fill="#000000">
|
||||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
@ -389,6 +389,38 @@
|
|||||||
<span class="label">Copy link</span>
|
<span class="label">Copy link</span>
|
||||||
<sm-copy id="shared_url" clip-text></sm-copy>
|
<sm-copy id="shared_url" clip-text></sm-copy>
|
||||||
</sm-popup>
|
</sm-popup>
|
||||||
|
<sm-popup id="publish_article_popup">
|
||||||
|
<header slot="header" class="popup__header">
|
||||||
|
<div class="flex align-center">
|
||||||
|
<button class="popup__header__close" onclick="hidePopup()">
|
||||||
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px"
|
||||||
|
fill="#000000">
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path
|
||||||
|
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<h3>Publish article</h3>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<sm-form class="grid gap-1-5">
|
||||||
|
<div class="grid gap-0-5">
|
||||||
|
<h5>Select category</h5>
|
||||||
|
<sm-select id="published_article_category">
|
||||||
|
<sm-option value="entertainment">Entertainment</sm-option>
|
||||||
|
<sm-option value="politics">Politics</sm-option>
|
||||||
|
<sm-option value="science">Science</sm-option>
|
||||||
|
<sm-option value="sports">Sports</sm-option>
|
||||||
|
<sm-option value="tech">Tech</sm-option>
|
||||||
|
</sm-select>
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-0-5">
|
||||||
|
<h5>Add tags</h5>
|
||||||
|
<tags-input id="article_tags" limit="10" required></tags-input>
|
||||||
|
</div>
|
||||||
|
<sm-button variant="primary" onclick="publishArticle()">Request publishing</sm-button>
|
||||||
|
</sm-form>
|
||||||
|
</sm-popup>
|
||||||
<template id="contributor_template">
|
<template id="contributor_template">
|
||||||
<div class="contributor grid">
|
<div class="contributor grid">
|
||||||
<svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
@ -400,7 +432,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template id="section_template">
|
<template id="section_template">
|
||||||
<text-field class="heading"></text-field>
|
<div class="heading flex align-center">
|
||||||
|
<text-field></text-field>
|
||||||
|
</div>
|
||||||
<section class="article-section">
|
<section class="article-section">
|
||||||
<div class="content-card content-card--empty">
|
<div class="content-card content-card--empty">
|
||||||
<div class="content__area" data-type="origin" placeholder="Write something new or edit existing content"
|
<div class="content__area" data-type="origin" placeholder="Write something new or edit existing content"
|
||||||
@ -448,16 +482,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template id="quote_template">
|
|
||||||
<figure class="quote-template grid gap-0-5" contenteditable="false">
|
|
||||||
<blockquote class="flex">
|
|
||||||
<p class="quote" contenteditable="true">Words can be like X-rays, if you use them properly—they’ll go
|
|
||||||
through anything. You read and you’re pierced.</p>
|
|
||||||
</blockquote>
|
|
||||||
<figcaption class="flex"><span class="by" contenteditable="true">Aldous Huxley</span><cite class="citation"
|
|
||||||
contenteditable="true">Brave New World</cite></figcaption>
|
|
||||||
</figure>
|
|
||||||
</template>
|
|
||||||
<template id="history_entry_template">
|
<template id="history_entry_template">
|
||||||
<li class="history-entry grid gap-1">
|
<li class="history-entry grid gap-1">
|
||||||
<div class="flex align-center space-between">
|
<div class="flex align-center space-between">
|
||||||
@ -1166,7 +1190,7 @@
|
|||||||
const contributor = getRef('contributor_template').content.cloneNode(true)
|
const contributor = getRef('contributor_template').content.cloneNode(true)
|
||||||
contributor.querySelector('.contributor__id').textContent = floID
|
contributor.querySelector('.contributor__id').textContent = floID
|
||||||
contributor.querySelector('.contributor__time').textContent = `Last edited: ${getFormattedTime(contributors[floID])}`
|
contributor.querySelector('.contributor__time').textContent = `Last edited: ${getFormattedTime(contributors[floID])}`
|
||||||
frag.append(contributor)
|
frag.prepend(contributor)
|
||||||
}
|
}
|
||||||
getRef('contributor_list').append(frag)
|
getRef('contributor_list').append(frag)
|
||||||
showPopup('contributors_popup')
|
showPopup('contributors_popup')
|
||||||
@ -1285,6 +1309,12 @@
|
|||||||
window.location.hash = `#/preview?articleID=${currentArticle.id}`
|
window.location.hash = `#/preview?articleID=${currentArticle.id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getReadingTime(content) {
|
||||||
|
const wpm = 225;
|
||||||
|
const words = content.trim().split(/\s+/).length;
|
||||||
|
return Math.ceil(words / wpm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function downloadHTML(string, options = {}) {
|
function downloadHTML(string, options = {}) {
|
||||||
const { title } = options
|
const { title } = options
|
||||||
@ -1318,6 +1348,8 @@
|
|||||||
bodyTemplate.querySelector('#exported_title').textContent = articleTitle
|
bodyTemplate.querySelector('#exported_title').textContent = articleTitle
|
||||||
bodyTemplate.querySelector('#exported_time').textContent = `Exported on ${getFormattedTime(Date.now())}`
|
bodyTemplate.querySelector('#exported_time').textContent = `Exported on ${getFormattedTime(Date.now())}`
|
||||||
bodyTemplate.querySelector('#export_body').innerHTML = getCleanExportContent()
|
bodyTemplate.querySelector('#export_body').innerHTML = getCleanExportContent()
|
||||||
|
const readingTime = getReadingTime(bodyTemplate.querySelector('#export_body').textContent)
|
||||||
|
bodyTemplate.querySelector('#reading_time').textContent = `${readingTime} min read`
|
||||||
let bodyAttributes = ''
|
let bodyAttributes = ''
|
||||||
let extraScripts = ''
|
let extraScripts = ''
|
||||||
if (isSubAdmin) {
|
if (isSubAdmin) {
|
||||||
@ -1389,6 +1421,10 @@
|
|||||||
|
|
||||||
function publishArticle() {
|
function publishArticle() {
|
||||||
if (isSubAdmin) {
|
if (isSubAdmin) {
|
||||||
|
const category = getRef('published_article_category').value
|
||||||
|
const tags = getRef('article_tags').value
|
||||||
|
console.log(category, tags)
|
||||||
|
return
|
||||||
getConfirmation('Request publishing?', {
|
getConfirmation('Request publishing?', {
|
||||||
message: 'Send this article as publishing candidate on RanchiMall TImes',
|
message: 'Send this article as publishing candidate on RanchiMall TImes',
|
||||||
confirmText: 'Request'
|
confirmText: 'Request'
|
||||||
@ -1399,6 +1435,8 @@
|
|||||||
articleID: pagesData.params.articleID,
|
articleID: pagesData.params.articleID,
|
||||||
title: floGlobals.appObjects.cc.articleList[currentArticle.id].title,
|
title: floGlobals.appObjects.cc.articleList[currentArticle.id].title,
|
||||||
content: getCleanExportContent(),
|
content: getCleanExportContent(),
|
||||||
|
category,
|
||||||
|
tags,
|
||||||
}, 'publishing_requests', {
|
}, 'publishing_requests', {
|
||||||
application: 'Test_RM_Times',
|
application: 'Test_RM_Times',
|
||||||
receiverID: 'FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf'
|
receiverID: 'FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf'
|
||||||
@ -1506,6 +1544,7 @@
|
|||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
let currentArticle = {}
|
let currentArticle = {}
|
||||||
|
|
||||||
const render = {
|
const render = {
|
||||||
article(id) {
|
article(id) {
|
||||||
currentArticle.id = id
|
currentArticle.id = id
|
||||||
@ -1551,7 +1590,6 @@
|
|||||||
noOfContributors++
|
noOfContributors++
|
||||||
if (noOfContributors === 1)
|
if (noOfContributors === 1)
|
||||||
firstContributor = contributor
|
firstContributor = contributor
|
||||||
if (noOfContributors === 2) break
|
|
||||||
}
|
}
|
||||||
if (noOfContributors === 1) {
|
if (noOfContributors === 1) {
|
||||||
clone.querySelector('.content__author').textContent = firstContributor
|
clone.querySelector('.content__author').textContent = firstContributor
|
||||||
@ -1604,14 +1642,20 @@
|
|||||||
if (isSubAdmin) {
|
if (isSubAdmin) {
|
||||||
section.querySelector('.content-card--empty').remove()
|
section.querySelector('.content-card--empty').remove()
|
||||||
} else {
|
} else {
|
||||||
section.querySelector('.heading').setAttribute('disabled', '')
|
section.querySelector('text-field').setAttribute('disabled', '')
|
||||||
}
|
}
|
||||||
section.querySelector('.heading').setAttribute('value', title)
|
section.querySelector('text-field').setAttribute('value', title)
|
||||||
currentArticle.sections[sectionID].uniqueEntries.forEach(entry => {
|
currentArticle.sections[sectionID].uniqueEntries.slice(0, maxCardsPerSection).forEach(entry => {
|
||||||
const contentCard = render.contentCard(entry)
|
const contentCard = render.contentCard(entry)
|
||||||
if (contentCard)
|
if (contentCard)
|
||||||
frag.append(contentCard)
|
frag.append(contentCard)
|
||||||
})
|
})
|
||||||
|
if (currentArticle.sections[sectionID].uniqueEntries.length > maxCardsPerSection) {
|
||||||
|
section.querySelector('.heading').append(createElement('button', {
|
||||||
|
className: 'button hide-on-mobile',
|
||||||
|
textContent: `See ${currentArticle.sections[sectionID].uniqueEntries.length - maxCardsPerSection} more`
|
||||||
|
}))
|
||||||
|
}
|
||||||
section.querySelector('.article-section').append(frag)
|
section.querySelector('.article-section').append(frag)
|
||||||
return section
|
return section
|
||||||
},
|
},
|
||||||
@ -1722,7 +1766,9 @@
|
|||||||
emptyCard = section.firstElementChild.cloneNode(true)
|
emptyCard = section.firstElementChild.cloneNode(true)
|
||||||
section.innerHTML = ''
|
section.innerHTML = ''
|
||||||
const frag = document.createDocumentFragment()
|
const frag = document.createDocumentFragment()
|
||||||
currentArticle.sections[sectionID].uniqueEntries.forEach((entry, index) => frag.append(allContentCards[entry]))
|
currentArticle.sections[sectionID].uniqueEntries.slice(0, maxCardsPerSection).forEach((entry, index) => {
|
||||||
|
frag.append(allContentCards[entry] || render.contentCard(entry))
|
||||||
|
})
|
||||||
if (!isSubAdmin)
|
if (!isSubAdmin)
|
||||||
section.append(emptyCard)
|
section.append(emptyCard)
|
||||||
section.append(frag)
|
section.append(frag)
|
||||||
@ -2061,11 +2107,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function createQuote() {
|
function createQuote() {
|
||||||
const quote = getRef('quote_template').content.cloneNode(true)
|
return createElement('figure', {
|
||||||
quote.querySelector('.quote').textContent = '"Words can be like X-rays, if you use them properly—they’ll go through anything. You read and you’re pierced."'
|
className: 'quote-template grid gap-0-5',
|
||||||
quote.querySelector('.by').textContent = `- Aldous Huxley,`
|
attributes: { 'contenteditable': "false" },
|
||||||
quote.querySelector('.citation').textContent = 'Brave New World'
|
innerHTML: `<blockquote class="flex"> <p class="quote" contenteditable="true">Words can be like X-rays, if you use them properly—they’ll go through anything. You read and you’re pierced.</p> </blockquote> <figcaption class="flex"><span class="by" contenteditable="true">Aldous Huxley</span>, <cite class="citation" contenteditable="true">Brave New World</cite></figcaption>`
|
||||||
return quote
|
})
|
||||||
}
|
}
|
||||||
function insertBlockquote() {
|
function insertBlockquote() {
|
||||||
insertNode(createQuote())
|
insertNode(createQuote())
|
||||||
@ -2073,6 +2119,8 @@
|
|||||||
</script>
|
</script>
|
||||||
<script id="onLoadStartUp">
|
<script id="onLoadStartUp">
|
||||||
let isSubAdmin = false
|
let isSubAdmin = false
|
||||||
|
let maxCardsPerSection = isSubAdmin ? 3 : 2
|
||||||
|
|
||||||
function onLoadStartUp() {
|
function onLoadStartUp() {
|
||||||
|
|
||||||
//floDapps.addStartUpFunction('Sample', Promised Function)
|
//floDapps.addStartUpFunction('Sample', Promised Function)
|
||||||
@ -2093,7 +2141,7 @@
|
|||||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <g> <rect fill="none" height="24" width="24" /> </g> <g> <path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z" /> </g> </svg>
|
<svg class="icon" xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <g> <rect fill="none" height="24" width="24" /> </g> <g> <path d="M18,15v3H6v-3H4v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3H18z M17,11l-1.41-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5 L17,11z" /> </g> </svg>
|
||||||
</button>
|
</button>
|
||||||
`: ''}
|
`: ''}
|
||||||
<sm-button variant="primary" onclick="${isSubAdmin ? 'publishArticle()' : 'exportSelection()'}">
|
<sm-button variant="primary" onclick="${isSubAdmin ? "showPopup('publish_article_popup')" : 'exportSelection()'}">
|
||||||
${isSubAdmin ? `
|
${isSubAdmin ? `
|
||||||
<svg class="icon button__icon--left" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M5 4h14v2H5zm0 10h4v6h6v-6h4l-7-7-7 7zm8-2v6h-2v-6H9.83L12 9.83 14.17 12H13z" /> </svg>
|
<svg class="icon button__icon--left" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"> <path d="M0 0h24v24H0V0z" fill="none" /> <path d="M5 4h14v2H5zm0 10h4v6h6v-6h4l-7-7-7 7zm8-2v6h-2v-6H9.83L12 9.83 14.17 12H13z" /> </svg>
|
||||||
Publish
|
Publish
|
||||||
@ -11588,14 +11636,14 @@
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
color: rgba(var(--text-color), 1);
|
color: rgba(var(--text-color), 1);
|
||||||
background: var(--foreground-color)
|
background: rgba(var(--background-color), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
body,
|
body,
|
||||||
body * {
|
body * {
|
||||||
--accent-color: rgb(0, 156, 78);
|
--accent-color: rgb(0, 156, 78);
|
||||||
--text-color: 36, 36, 36;
|
--text-color: 36, 36, 36;
|
||||||
--background-color: 248, 248, 248;
|
--background-color: 252, 252, 252;
|
||||||
--foreground-color: rgb(255, 255, 255);
|
--foreground-color: rgb(255, 255, 255);
|
||||||
--danger-color: rgb(255, 75, 75);
|
--danger-color: rgb(255, 75, 75);
|
||||||
--like-color: #e91e63;
|
--like-color: #e91e63;
|
||||||
@ -11679,6 +11727,10 @@
|
|||||||
justify-self: end
|
justify-self: end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 1.2rem;
|
width: 1.2rem;
|
||||||
height: 1.2rem;
|
height: 1.2rem;
|
||||||
@ -11804,7 +11856,7 @@
|
|||||||
-ms-flex-align: center;
|
-ms-flex-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-template-columns: 1fr auto auto;
|
grid-template-columns: 1fr auto auto;
|
||||||
background-color: var(--foreground-color);
|
background-color: rgba(var(--background-color), 1);
|
||||||
z-index: 1
|
z-index: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11878,7 +11930,8 @@
|
|||||||
height: 40vh
|
height: 40vh
|
||||||
}
|
}
|
||||||
|
|
||||||
time {
|
time,
|
||||||
|
#reading_time {
|
||||||
font-size: .8rem
|
font-size: .8rem
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12065,7 +12118,9 @@
|
|||||||
</picture> -->
|
</picture> -->
|
||||||
<section class="hero-section">
|
<section class="hero-section">
|
||||||
<h1 id="exported_title"></h1>
|
<h1 id="exported_title"></h1>
|
||||||
<time id="exported_time"></time>
|
<div class="flex align-center">
|
||||||
|
<time id="exported_time"></time> • <span id="reading_time"></span>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section id="export_body" class="grid gap-1"></section>
|
<section id="export_body" class="grid gap-1"></section>
|
||||||
<section>
|
<section>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user