Inline Emojo Picker (#317)
* Inline emoji picker * Inline text editorremotes/1693045480750635534/spooky-22
parent
76cf6fb696
commit
4b47faa1ed
|
@ -1721,6 +1721,7 @@ button.close {
|
||||||
.modal-dialog-centered.modal-dialog-scrollable {
|
.modal-dialog-centered.modal-dialog-scrollable {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
.modal-dialog-centered.modal-dialog-scrollable .modal-content {
|
.modal-dialog-centered.modal-dialog-scrollable .modal-content {
|
||||||
max-height: none;
|
max-height: none;
|
||||||
|
@ -6086,4 +6087,60 @@ g {
|
||||||
.post-actions {
|
.post-actions {
|
||||||
margin-top: -5px;
|
margin-top: -5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ghostdiv
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
/* Attempt to copy the textarea/input padding */
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#speed-carot-modal
|
||||||
|
{
|
||||||
|
background-color: var(--gray-700);
|
||||||
|
min-width: 190px;
|
||||||
|
max-width: 190px;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#speed-carot-modal .speed-modal-option
|
||||||
|
{
|
||||||
|
border-bottom: 1px solid #606060;
|
||||||
|
padding: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#speed-carot-modal .speed-modal-option:hover,
|
||||||
|
#speed-carot-modal .speed-modal-option:focus,
|
||||||
|
#speed-carot-modal .speed-modal-option.selected
|
||||||
|
{
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#speed-carot-modal .speed-modal-image
|
||||||
|
{
|
||||||
|
object-fit: contain;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#speed-carot-modal .speed-modal-option span
|
||||||
|
{
|
||||||
|
overflow: hidden;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 10px;
|
||||||
|
width: 125px;
|
||||||
|
max-width: 125px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ GNU Affero General Public License for more details.
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Copyright (C) 2022 Dr Steven Transmisia, anti-evil engineer
|
Copyright (C) 2022 Dr Steven Transmisia, anti-evil engineer,
|
||||||
|
2022 Nekobit, king autist
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
|
@ -372,6 +373,176 @@ function emojiAddToInput(event)
|
||||||
localStorage.setItem("favorite_emojis", JSON.stringify(favorite_emojis));
|
localStorage.setItem("favorite_emojis", JSON.stringify(favorite_emojis));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
const insertAt = (str, sub, pos) => `${str.slice(0, pos)}${sub}${str.slice(pos)}`;
|
||||||
|
|
||||||
|
let emoji_typing_state = false;
|
||||||
|
|
||||||
|
function update_ghost_div_textarea(text)
|
||||||
|
{
|
||||||
|
let ghostdiv = text.parentNode.querySelector(".ghostdiv");
|
||||||
|
if (!ghostdiv) return;
|
||||||
|
|
||||||
|
ghostdiv.innerText = text.value.substring(0, text.selectionStart);
|
||||||
|
ghostdiv.innerHTML += "<span></span>";
|
||||||
|
|
||||||
|
// Now lets get coordinates
|
||||||
|
|
||||||
|
ghostdiv.style.display = "initial";
|
||||||
|
let end = ghostdiv.querySelector("span");
|
||||||
|
const carot_coords = end.getBoundingClientRect();
|
||||||
|
const ghostdiv_coords = ghostdiv.getBoundingClientRect();
|
||||||
|
ghostdiv.style.display = "none";
|
||||||
|
return { pos: text.selectionStart, x: carot_coords.x, y: carot_coords.y - ghostdiv_coords.y };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used for anything where a user is typing, specifically for the emoji modal
|
||||||
|
// Just leave it global, I don't care
|
||||||
|
let speed_carot_modal = document.createElement("div");
|
||||||
|
speed_carot_modal.id = "speed-carot-modal";
|
||||||
|
speed_carot_modal.style.position = "absolute";
|
||||||
|
speed_carot_modal.style.left = "0px";
|
||||||
|
speed_carot_modal.style.top = "0px";
|
||||||
|
speed_carot_modal.style.display = "none";
|
||||||
|
document.body.appendChild(speed_carot_modal);
|
||||||
|
|
||||||
|
let current_word = "";
|
||||||
|
let emojo_index = 0;
|
||||||
|
|
||||||
|
function curr_word_is_emoji()
|
||||||
|
{
|
||||||
|
return current_word && current_word.charAt(0) == ":" &&
|
||||||
|
current_word.charAt(current_word.length-1) != ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate_speed_emoji_modal(results, textbox)
|
||||||
|
{
|
||||||
|
if (!results || results.size === 0)
|
||||||
|
{
|
||||||
|
speed_carot_modal.style.display = "none";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
emojo_index = 0;
|
||||||
|
speed_carot_modal.innerHTML = "";
|
||||||
|
const MAXXX = 25;
|
||||||
|
// Not sure why the results is a Set... but oh well
|
||||||
|
let i = 0;
|
||||||
|
for (let result of results)
|
||||||
|
{
|
||||||
|
if (i++ > MAXXX) return i;
|
||||||
|
let emoji_option = document.createElement("div");
|
||||||
|
emoji_option.className = "speed-modal-option emoji-option " + (i === 1 ? "selected" : "");
|
||||||
|
emoji_option.tabIndex = 0;
|
||||||
|
let emoji_option_img = document.createElement("img");
|
||||||
|
emoji_option_img.className = "speed-modal-image emoji-option-image";
|
||||||
|
// This is a bit
|
||||||
|
emoji_option_img.src = `/e/${result}.webp`;
|
||||||
|
let emoji_option_text = document.createElement("span");
|
||||||
|
emoji_option_text.title = result;
|
||||||
|
emoji_option_text.innerText = result;
|
||||||
|
|
||||||
|
emoji_option.onclick = (e) => {
|
||||||
|
speed_carot_modal.style.display = "none";
|
||||||
|
textbox.value = textbox.value.replace(new RegExp(current_word+"(?=\\s|$)", "g"), `:${result}:`)
|
||||||
|
};
|
||||||
|
// Pack
|
||||||
|
emoji_option.appendChild(emoji_option_img);
|
||||||
|
emoji_option.appendChild(emoji_option_text);
|
||||||
|
speed_carot_modal.appendChild(emoji_option);
|
||||||
|
}
|
||||||
|
if (i === 0) speed_carot_modal.style.display = "none";
|
||||||
|
else speed_carot_modal.style.display = "initial";
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_speed_emoji_modal(event)
|
||||||
|
{
|
||||||
|
if (event.target.tagName.toLowerCase() !== 'textarea') return;
|
||||||
|
|
||||||
|
const box_coords = update_ghost_div_textarea(event.target);
|
||||||
|
|
||||||
|
let text = event.target.value;
|
||||||
|
|
||||||
|
// Unused, but left incase anyone wants to use this more efficient method for emojos
|
||||||
|
switch (event.data)
|
||||||
|
{
|
||||||
|
case ':':
|
||||||
|
emoji_typing_state = true;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
emoji_typing_state = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current word at string, such as ":marse" or "word"
|
||||||
|
let coords = text.indexOf(' ',box_coords.pos);
|
||||||
|
current_word = /\S+$/.exec(text.slice(0, coords === -1 ? text.length : coords));
|
||||||
|
if (current_word) current_word = current_word.toString();
|
||||||
|
|
||||||
|
/* We could also check emoji_typing_state here, which is less accurate but more efficient. I've
|
||||||
|
* kept it unless someone wants to provide an option to toggle it for performance */
|
||||||
|
if (curr_word_is_emoji() && current_word != ":")
|
||||||
|
{
|
||||||
|
loadEmojis(null);
|
||||||
|
let modal_pos = event.target.getBoundingClientRect();
|
||||||
|
modal_pos.x += window.scrollX;
|
||||||
|
modal_pos.y += window.scrollY;
|
||||||
|
|
||||||
|
speed_carot_modal.style.display = "initial";
|
||||||
|
speed_carot_modal.style.left = modal_pos.x + box_coords.x - 35 + "px";
|
||||||
|
speed_carot_modal.style.top = modal_pos.y + box_coords.y + 14 + "px";
|
||||||
|
|
||||||
|
// Do the search (and do something with it)
|
||||||
|
populate_speed_emoji_modal(emojisSearchDictionary.searchFor(current_word.substr(1)), event.target);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
speed_carot_modal.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update emoji position
|
||||||
|
document.addEventListener('input', update_speed_emoji_modal, false);
|
||||||
|
|
||||||
|
// Update emoji position
|
||||||
|
document.addEventListener('keydown', (e) => {
|
||||||
|
let select_items = speed_carot_modal.querySelectorAll(".speed-modal-option");
|
||||||
|
if (!select_items || !curr_word_is_emoji()) return false;
|
||||||
|
// Up or down arrow or enter
|
||||||
|
if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13)
|
||||||
|
{
|
||||||
|
if (emojo_index > select_items.length)
|
||||||
|
emojo_index = select_items;
|
||||||
|
|
||||||
|
select_items[emojo_index].classList.remove("selected");
|
||||||
|
switch (e.keyCode)
|
||||||
|
{
|
||||||
|
case 38: // Up arrow
|
||||||
|
if (emojo_index)
|
||||||
|
emojo_index--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 40: // Down arrow
|
||||||
|
if (emojo_index < select_items.length-1) emojo_index++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
select_items[emojo_index].click();
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
select_items[emojo_index].classList.add("selected");
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
function loadEmojis(inputTargetIDName)
|
function loadEmojis(inputTargetIDName)
|
||||||
{
|
{
|
||||||
if(!emojiEngineStarted)
|
if(!emojiEngineStarted)
|
||||||
|
@ -380,9 +551,10 @@ function loadEmojis(inputTargetIDName)
|
||||||
emojiRequest.send();
|
emojiRequest.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
emojiInputTargetDOM = document.getElementById(inputTargetIDName);
|
if (inputTargetIDName)
|
||||||
|
emojiInputTargetDOM = document.getElementById(inputTargetIDName);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('emojiModal').addEventListener('shown.bs.modal', function () {
|
document.getElementById('emojiModal').addEventListener('shown.bs.modal', function () {
|
||||||
emojiSearchBarDOM.focus();
|
emojiSearchBarDOM.focus();
|
||||||
});
|
});
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
<span class="font-weight-bold">Comment {{'Replies' if (replies | length)>1 else 'Reply'}}: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
<span class="font-weight-bold">Comment {{'Replies' if (replies | length)>1 else 'Reply'}}: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
||||||
{% elif c.post.author_id==v.id and c.level == 1 and is_notification_page%}
|
{% elif c.post.author_id==v.id and c.level == 1 and is_notification_page%}
|
||||||
<span class="font-weight-bold">Post Reply: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
<span class="font-weight-bold">Post Reply: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
||||||
{% elif is_notification_page and c.parent_submission in v.subscribed_idlist %}
|
{% elif is_notification_page and c.parent_submission in v.subscribed_idlist() %}
|
||||||
<span class="font-weight-bold">Subscribed Thread: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
<span class="font-weight-bold">Subscribed Thread: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
||||||
{% elif is_notification_page %}
|
{% elif is_notification_page %}
|
||||||
<span class="font-weight-bold">Username Mention: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
<span class="font-weight-bold">Username Mention: <a href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
|
||||||
|
@ -450,9 +450,9 @@
|
||||||
|
|
||||||
<button class="btn caction py-0 nobackground px-1 text-muted" role="button" data-bs-toggle="modal" data-bs-target="#awardModal" data-url="/award/comment/{{c.id}}"><i class="fas fa-gift" aria-hidden="true"></i>Give Award</button>
|
<button class="btn caction py-0 nobackground px-1 text-muted" role="button" data-bs-toggle="modal" data-bs-target="#awardModal" data-url="/award/comment/{{c.id}}"><i class="fas fa-gift" aria-hidden="true"></i>Give Award</button>
|
||||||
|
|
||||||
<button id="unsave-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if c.id in v.saved_comment_idlist %}d-md-inline-block{% endif %} text-muted d-none" role="button" onclick="post_toast(this,'/unsave_comment/{{c.id}}','save-{{c.id}}','unsave-{{c.id}}','d-md-inline-block')"><i class="fas fa-save"></i>Unsave</button>
|
<button id="unsave-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if c.id in v.saved_comment_idlist() %}d-md-inline-block{% endif %} text-muted d-none" role="button" onclick="post_toast(this,'/unsave_comment/{{c.id}}','save-{{c.id}}','unsave-{{c.id}}','d-md-inline-block')"><i class="fas fa-save"></i>Unsave</button>
|
||||||
|
|
||||||
<button id="save-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if c.id not in v.saved_comment_idlist %}d-md-inline-block{% endif %} text-muted d-none" role="button" onclick="post_toast(this,'/save_comment/{{c.id}}','save-{{c.id}}','unsave-{{c.id}}','d-md-inline-block')"><i class="fas fa-save"></i>Save</button>
|
<button id="save-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if c.id not in v.saved_comment_idlist() %}d-md-inline-block{% endif %} text-muted d-none" role="button" onclick="post_toast(this,'/save_comment/{{c.id}}','save-{{c.id}}','unsave-{{c.id}}','d-md-inline-block')"><i class="fas fa-save"></i>Save</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if c.parent_submission %}
|
{% if c.parent_submission %}
|
||||||
|
@ -551,7 +551,8 @@
|
||||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||||
<input type="hidden" name="parent_fullname" value="{{c.fullname}}">
|
<input type="hidden" name="parent_fullname" value="{{c.fullname}}">
|
||||||
<input autocomplete="off" id="reply-form-submission-{{c.fullname}}" type="hidden" name="submission" value="{{c.post.id}}">
|
<input autocomplete="off" id="reply-form-submission-{{c.fullname}}" type="hidden" name="submission" value="{{c.post.id}}">
|
||||||
<textarea required autocomplete="off" {% if v.longpost %}minlength="280"{% else %}minlength="1"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" oninput="markdown('reply-form-body-{{c.fullname}}', 'reply-edit-{{c.id}}');charLimit('reply-form-body-{{c.fullname}}','charcount-{{c.id}}')" id="reply-form-body-{{c.fullname}}" data-fullname="{{c.fullname}}" name="body" form="reply-to-t3_{{c.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
|
<textarea required autocomplete="off" {% if v.longpost %}minlength="280"{% else %}minlength="1"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" oninput="markdown('reply-form-body-{{c.fullname}}', 'reply-edit-{{c.id}}');charLimit('reply-form-body-{{c.fullname}}','charcount-{{c.id}}')" id="reply-form-body-{{c.fullname}}" data-fullname="{{c.fullname}}" name="body" form="reply-to-t3_{{c.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
|
||||||
|
<div class="ghostdiv" style="display:none;"></div>
|
||||||
|
|
||||||
<div class="text-small font-weight-bold mt-1" id="charcount-{{c.id}}" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
<div class="text-small font-weight-bold mt-1" id="charcount-{{c.id}}" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
||||||
|
|
||||||
|
@ -655,9 +656,9 @@
|
||||||
|
|
||||||
<a class="list-group-item" role="button" data-bs-toggle="modal" data-bs-target="#awardModal" data-url="/award/comment/{{c.id}}"><i class="fas fa-gift mr-2" aria-hidden="true"></i>Give Award</a>
|
<a class="list-group-item" role="button" data-bs-toggle="modal" data-bs-target="#awardModal" data-url="/award/comment/{{c.id}}"><i class="fas fa-gift mr-2" aria-hidden="true"></i>Give Award</a>
|
||||||
|
|
||||||
<a id="save2-{{c.id}}" class="list-group-item {% if c.id in v.saved_comment_idlist %}d-none{% endif %}" role="button" data-bs-dismiss="modal" onclick="post_toast(this,'/save_comment/{{c.id}}','save2-{{c.id}}','unsave2-{{c.id}}','d-none')"><i class="fas fa-save mr-2"></i>Save</a>
|
<a id="save2-{{c.id}}" class="list-group-item {% if c.id in v.saved_comment_idlist() %}d-none{% endif %}" role="button" data-bs-dismiss="modal" onclick="post_toast(this,'/save_comment/{{c.id}}','save2-{{c.id}}','unsave2-{{c.id}}','d-none')"><i class="fas fa-save mr-2"></i>Save</a>
|
||||||
|
|
||||||
<a id="unsave2-{{c.id}}" class="list-group-item {% if c.id not in v.saved_comment_idlist %}d-none{% endif %}" role="button" onclick="post_toast(this,'/unsave_comment/{{c.id}}','save2-{{c.id}}','unsave2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-save mr-2"></i>Unsave</a>
|
<a id="unsave2-{{c.id}}" class="list-group-item {% if c.id not in v.saved_comment_idlist() %}d-none{% endif %}" role="button" onclick="post_toast(this,'/unsave_comment/{{c.id}}','save2-{{c.id}}','unsave2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-save mr-2"></i>Unsave</a>
|
||||||
|
|
||||||
{% if c.author_id == v.id %}
|
{% if c.author_id == v.id %}
|
||||||
<a role="button" data-bs-dismiss="modal" onclick="toggleEdit('{{c.id}}')" class="list-group-item"><i class="fas fa-edit mr-2"></i>Edit</a>
|
<a role="button" data-bs-dismiss="modal" onclick="toggleEdit('{{c.id}}')" class="list-group-item"><i class="fas fa-edit mr-2"></i>Edit</a>
|
||||||
|
|
|
@ -983,6 +983,7 @@
|
||||||
<input type="hidden" name="parent_fullname" value="t2_{{p.id}}">
|
<input type="hidden" name="parent_fullname" value="t2_{{p.id}}">
|
||||||
<input autocomplete="off" id="reply-form-submission-{{p.fullname}}" type="hidden" name="submission" value="{{p.id}}">
|
<input autocomplete="off" id="reply-form-submission-{{p.fullname}}" type="hidden" name="submission" value="{{p.id}}">
|
||||||
<textarea required autocomplete="off" {% if not (p and p.id in ADMIGGERS) %}{% if v.longpost %}minlength="280"{% elif v.bird %}maxlength="140"{% endif %}{% endif %} minlength="1" maxlength="10000" oninput="markdown('reply-form-body-{{p.fullname}}', 'form-preview-{{p.id}}');charLimit('reply-form-body-{{p.fullname}}','charcount-reply')" id="reply-form-body-{{p.fullname}}" data-fullname="{{p.fullname}}" class="comment-box form-control rounded" id="comment-form" name="body" form="reply-to-{{p.fullname}}" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
|
<textarea required autocomplete="off" {% if not (p and p.id in ADMIGGERS) %}{% if v.longpost %}minlength="280"{% elif v.bird %}maxlength="140"{% endif %}{% endif %} minlength="1" maxlength="10000" oninput="markdown('reply-form-body-{{p.fullname}}', 'form-preview-{{p.id}}');charLimit('reply-form-body-{{p.fullname}}','charcount-reply')" id="reply-form-body-{{p.fullname}}" data-fullname="{{p.fullname}}" class="comment-box form-control rounded" id="comment-form" name="body" form="reply-to-{{p.fullname}}" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
|
||||||
|
<div class="ghostdiv" style="display:none;"></div>
|
||||||
|
|
||||||
<div class="text-small font-weight-bold mt-1" id="charcount-reply" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
<div class="text-small font-weight-bold mt-1" id="charcount-reply" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
||||||
|
|
||||||
|
@ -1225,4 +1226,4 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -125,6 +125,7 @@
|
||||||
<label for="body" class="mt-3">Text<i class="fas fa-info-circle text-gray-400 ml-1" data-bs-toggle="tooltip" data-bs-placement="top" title="Uses markdown. Limited to 20000 characters."></i></label>
|
<label for="body" class="mt-3">Text<i class="fas fa-info-circle text-gray-400 ml-1" data-bs-toggle="tooltip" data-bs-placement="top" title="Uses markdown. Limited to 20000 characters."></i></label>
|
||||||
|
|
||||||
<textarea form="submitform" id="post-text" class="form-control rounded" aria-label="With textarea" placeholder="Optional if you have a link or an image." rows="7" name="body" oninput="markdown('post-text','preview');charLimit('post-text','character-count-submit-text-form');checkForRequired();savetext()" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}20000{% endif %}" required></textarea>
|
<textarea form="submitform" id="post-text" class="form-control rounded" aria-label="With textarea" placeholder="Optional if you have a link or an image." rows="7" name="body" oninput="markdown('post-text','preview');charLimit('post-text','character-count-submit-text-form');checkForRequired();savetext()" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}20000{% endif %}" required></textarea>
|
||||||
|
<div class="ghostdiv" style="display:none;"></div>
|
||||||
|
|
||||||
<div class="text-small font-weight-bold mt-1" id="character-count-submit-text-form" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
<div class="text-small font-weight-bold mt-1" id="character-count-submit-text-form" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue