feature: blurbs
refactor: style updates and fixes
This commit is contained in:
parent
591fd38088
commit
cbd58071b8
9 changed files with 101 additions and 52 deletions
|
|
@ -31,6 +31,7 @@
|
||||||
<script src="./js/totp.js" type="text/javascript"></script>
|
<script src="./js/totp.js" type="text/javascript"></script>
|
||||||
<script src="./js/api.js" type="text/javascript"></script>
|
<script src="./js/api.js" type="text/javascript"></script>
|
||||||
<script src="./js/smartforms.js" type="text/javascript"></script>
|
<script src="./js/smartforms.js" type="text/javascript"></script>
|
||||||
|
<script src="./js/textareaenhancements.js" type="text/javascript"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- #include file="./signup_login_wall.html" -->
|
<!-- #include file="./signup_login_wall.html" -->
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
function smarten_forms() {
|
function smarten_forms() {
|
||||||
const forms = document.body.querySelectorAll("form[data-smart]:not([data-smartened])");
|
const forms = document?.body?.querySelectorAll("form[data-smart]:not([data-smartened])") ?? [];
|
||||||
for (const form of forms) {
|
for (const form of forms) {
|
||||||
async function on_submit(event) {
|
async function on_submit(event) {
|
||||||
debugger;
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
form.disabled = true;
|
form.disabled = true;
|
||||||
form.__submitted_at = new Date();
|
form.__submitted_at = new Date();
|
||||||
|
|
|
||||||
31
public/js/textareaenhancements.js
Normal file
31
public/js/textareaenhancements.js
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
function enhance_textareas() {
|
||||||
|
const textareas = document.body.querySelectorAll("textarea:not([data-enhanced])");
|
||||||
|
for (const textarea of textareas) {
|
||||||
|
const max_length_attr = textarea.getAttribute("maxlength");
|
||||||
|
if (/^\d+$/.test(max_length_attr)) {
|
||||||
|
const max_length = parseInt(max_length_attr, 10);
|
||||||
|
|
||||||
|
function on_updated() {
|
||||||
|
const counters = this.parentElement.querySelectorAll(
|
||||||
|
`[data-limit-counter-for="${this.name}"]`,
|
||||||
|
);
|
||||||
|
for (const counter of counters) {
|
||||||
|
counter.innerHTML = `${this.value.length} / ${max_length}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.addEventListener("keyup", on_updated);
|
||||||
|
textarea.addEventListener("paste", on_updated);
|
||||||
|
textarea.addEventListener("blur", on_updated);
|
||||||
|
on_updated.call(textarea);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.dataset.enhanced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const textarea_enhancement_observer = new MutationObserver(enhance_textareas);
|
||||||
|
textarea_enhancement_observer.observe(document, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<style>
|
<style>
|
||||||
.blurbs-container {
|
#blurbs-container {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
max-width: 40rem;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container {
|
.blurb-container {
|
||||||
|
|
@ -9,12 +11,11 @@
|
||||||
grid-template-rows: auto auto auto auto 1fr;
|
grid-template-rows: auto auto auto auto 1fr;
|
||||||
grid-template-columns: auto auto 1fr;
|
grid-template-columns: auto auto 1fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"expander preview info"
|
"preview"
|
||||||
"expander preview subject"
|
"info"
|
||||||
". . content"
|
"content"
|
||||||
". . newblurb"
|
"newblurb"
|
||||||
". . replies";
|
"replies";
|
||||||
max-height: 6rem;
|
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border: 1px solid var(--border-subtle);
|
border: 1px solid var(--border-subtle);
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
|
@ -60,9 +61,7 @@
|
||||||
|
|
||||||
.blurb-container .media-preview-container {
|
.blurb-container .media-preview-container {
|
||||||
grid-area: preview;
|
grid-area: preview;
|
||||||
width: 6rem;
|
max-height: 600px;
|
||||||
height: 4rem;
|
|
||||||
margin-right: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .media-preview-container img {
|
.blurb-container .media-preview-container img {
|
||||||
|
|
@ -80,52 +79,48 @@
|
||||||
margin: 0.5rem;
|
margin: 0.5rem;
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
border-radius: 16%;
|
border-radius: 20%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .info-container .avatar-container img {
|
.blurb-container .info-container .avatar-container img {
|
||||||
width: 100%;
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .info-container .username-container {
|
.blurb-container .info-container .username-container {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
align-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .info-container .datetime-container {
|
.blurb-container .info-container .datetime-container {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 0.5rem;
|
margin: 0 0.5rem;
|
||||||
|
align-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .info-container .datetime-container .long {
|
.blurb-container .info-container .datetime-container .long {
|
||||||
font-size: x-small;
|
font-size: x-small;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
visibility: hidden;
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .info-container .datetime-container .short {
|
.blurb-container .info-container .datetime-container .short {
|
||||||
font-size: xx-small;
|
font-size: xx-small;
|
||||||
}
|
visibility: hidden;
|
||||||
|
display: none;
|
||||||
.blurb-container .subject-container {
|
|
||||||
grid-area: subject;
|
|
||||||
padding-left: 5rem;
|
|
||||||
margin-top: -2.5rem;
|
|
||||||
font-size: larger;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .content-container {
|
.blurb-container .content-container {
|
||||||
grid-area: content;
|
grid-area: content;
|
||||||
padding-left: 5rem;
|
padding-left: 1rem;
|
||||||
margin-top: 2rem;
|
margin: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .new-blurb-container {
|
.blurb-container .new-blurb-container {
|
||||||
grid-area: newblurb;
|
grid-area: newblurb;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurb-container .replies-container {
|
.blurb-container .replies-container {
|
||||||
|
|
@ -145,10 +140,10 @@
|
||||||
><div class="icon blurb"></div>
|
><div class="icon blurb"></div>
|
||||||
<div class="label">Blurbs</div>
|
<div class="label">Blurbs</div>
|
||||||
</label>
|
</label>
|
||||||
<div class="tab-content blurbs-container">
|
<div class="tab-content">
|
||||||
<!-- #include file="./README.md" -->
|
<div id="blurbs-container" class="container">
|
||||||
|
<!-- #include file="./README.md" -->
|
||||||
|
|
||||||
<div id="blurbs" class="container">
|
|
||||||
<div id="blurbs-list"></div>
|
<div id="blurbs-list"></div>
|
||||||
<script>
|
<script>
|
||||||
const blurbs_list = document.getElementById("blurbs-list");
|
const blurbs_list = document.getElementById("blurbs-list");
|
||||||
|
|
@ -161,14 +156,8 @@
|
||||||
const blurb_datetime = datetime_to_local(blurb.timestamps.created);
|
const blurb_datetime = datetime_to_local(blurb.timestamps.created);
|
||||||
|
|
||||||
const html_content = `<div class="blurb-container" data-creator_id="${creator.id}" data-blurb_id="${blurb.id}">
|
const html_content = `<div class="blurb-container" data-creator_id="${creator.id}" data-blurb_id="${blurb.id}">
|
||||||
<div class="expand-toggle-container">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" name="expanded"/><i class="icon plus"></i><i class="icon minus"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="media-preview-container">
|
<div class="media-preview-container">
|
||||||
<img src="/images/placeholders/${String(blurb_datetime.ms % 10).padStart(2, "0")}.svg" />
|
${blurb.data?.media?.length ? blurb.data.media.map((url) => `<img src="${url}" />`).join("\n") : ""}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-container">
|
<div class="info-container">
|
||||||
|
|
@ -306,8 +295,8 @@
|
||||||
document.addEventListener("topic_changed", load_active_topic_for_blurbs);
|
document.addEventListener("topic_changed", load_active_topic_for_blurbs);
|
||||||
document.addEventListener("user_logged_in", load_active_topic_for_blurbs);
|
document.addEventListener("user_logged_in", load_active_topic_for_blurbs);
|
||||||
</script>
|
</script>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- #include file="./new_blurb.html" -->
|
<!-- #include file="./new_blurb.html" -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,26 @@
|
||||||
|
<style>
|
||||||
|
.new-blurb-container input[type="file"] {
|
||||||
|
display: none;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-blurb-container .blurb-limit-counter {
|
||||||
|
font-size: smaller;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-blurb-container .file-attach-label {
|
||||||
|
display: block;
|
||||||
|
text-align: right;
|
||||||
|
margin-top: -2.5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-blurb-container .file-attach-label .icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div class="new-blurb-container" data-requires-permission="topics.blurbs.create">
|
<div class="new-blurb-container" data-requires-permission="topics.blurbs.create">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" collapse-toggle />
|
<input type="checkbox" collapse-toggle />
|
||||||
|
|
@ -53,10 +76,21 @@
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="parent_id"
|
name="parent_id"
|
||||||
generator="(_input, form) => { debugger; const parent_blurb = form.closest( '.blurb-container' ); return parent_blurb?.dataset?.blurb_id; }"
|
generator="(_input, form) => { const parent_blurb = form.closest( '.blurb-container' ); return parent_blurb?.dataset?.blurb_id; }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label>
|
<textarea
|
||||||
|
type="text"
|
||||||
|
name="data.blurb"
|
||||||
|
value=""
|
||||||
|
maxlength="256"
|
||||||
|
rows="4"
|
||||||
|
placeholder=" ... "
|
||||||
|
reset-on-submit
|
||||||
|
></textarea>
|
||||||
|
<div class="blurb-limit-counter" data-limit-counter-for="data.blurb">0 / 256</div>
|
||||||
|
|
||||||
|
<label class="file-attach-label">
|
||||||
<input
|
<input
|
||||||
aria-label="Upload and share file"
|
aria-label="Upload and share file"
|
||||||
type="file"
|
type="file"
|
||||||
|
|
@ -67,14 +101,6 @@
|
||||||
/>
|
/>
|
||||||
<div class="icon attachment"></div>
|
<div class="icon attachment"></div>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<input type="submit" value="Blurb It!" />
|
||||||
type="text"
|
|
||||||
name="data.blurb"
|
|
||||||
value=""
|
|
||||||
maxlength="256"
|
|
||||||
placeholder=" ... "
|
|
||||||
reset-on-submit
|
|
||||||
></textarea>
|
|
||||||
<input type="submit" value="Blurb" />
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .message-container .info-container .avatar-container img {
|
#chat .message-container .info-container .avatar-container img {
|
||||||
width: 100%;
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat .message-container .info-container .username-container {
|
#chat .message-container .info-container .username-container {
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-container .info-container .avatar-container img {
|
.post-container .info-container .avatar-container img {
|
||||||
width: 100%;
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-container .info-container .username-container {
|
.post-container .info-container .username-container {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="parent_id"
|
name="parent_id"
|
||||||
generator="(_input, form) => { debugger; const parent_post = form.closest( '.post-container' ); return parent_post?.dataset?.post_id; }"
|
generator="(_input, form) => { const parent_post = form.closest( '.post-container' ); return parent_post?.dataset?.post_id; }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@
|
||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
border-top: 1px solid var(--border-subtle);
|
border-top: 1px solid var(--border-subtle);
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-switch,
|
.tab-switch,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue