|
class Application {
|
|
constructor() {
|
|
this.initPasswordToggles();
|
|
this.initModals();
|
|
this.initPostForm();
|
|
this.initCommentForms();
|
|
this.initVoteButtons();
|
|
this.initMessageSearch();
|
|
this.initNotificationDismiss();
|
|
this.initProfileEdit();
|
|
this.initProjectForm();
|
|
this.loadCSS("/static/css/variables.css");
|
|
this.loadCSS("/static/css/base.css");
|
|
}
|
|
|
|
loadCSS(href) {
|
|
if (document.querySelector(`link[href="${href}"]`)) {
|
|
return;
|
|
}
|
|
const link = document.createElement("link");
|
|
link.rel = "stylesheet";
|
|
link.href = href;
|
|
document.head.appendChild(link);
|
|
}
|
|
|
|
initPasswordToggles() {
|
|
document.querySelectorAll(".auth-toggle-pw").forEach((btn) => {
|
|
btn.addEventListener("click", () => {
|
|
const input = btn.parentElement.querySelector("input");
|
|
if (!input) {
|
|
return;
|
|
}
|
|
const type = input.type === "password" ? "text" : "password";
|
|
input.type = type;
|
|
btn.textContent = type === "password" ? "\u{1F441}" : "\u{1F441}";
|
|
});
|
|
});
|
|
}
|
|
|
|
initModals() {
|
|
document.querySelectorAll("[data-modal]").forEach((trigger) => {
|
|
trigger.addEventListener("click", () => {
|
|
const modalId = trigger.dataset.modal;
|
|
const modal = document.getElementById(modalId);
|
|
if (modal) {
|
|
modal.classList.add("visible");
|
|
}
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll(".modal-overlay").forEach((modal) => {
|
|
modal.addEventListener("click", (e) => {
|
|
if (e.target === modal) {
|
|
modal.classList.remove("visible");
|
|
}
|
|
});
|
|
const closeBtn = modal.querySelector(".modal-close");
|
|
if (closeBtn) {
|
|
closeBtn.addEventListener("click", () => {
|
|
modal.classList.remove("visible");
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
initPostForm() {
|
|
const form = document.getElementById("create-post-form");
|
|
if (!form) {
|
|
return;
|
|
}
|
|
const content = form.querySelector("#post-content");
|
|
const title = form.querySelector("#post-title");
|
|
const contentCount = form.querySelector("#post-content-count");
|
|
const titleCount = form.querySelector("#post-title-count");
|
|
|
|
if (content && contentCount) {
|
|
content.addEventListener("input", () => {
|
|
contentCount.textContent = `${content.value.length}/2000`;
|
|
});
|
|
}
|
|
if (title && titleCount) {
|
|
title.addEventListener("input", () => {
|
|
titleCount.textContent = `${title.value.length}/500`;
|
|
});
|
|
}
|
|
}
|
|
|
|
initCommentForms() {
|
|
document.querySelectorAll(".comment-form").forEach((form) => {
|
|
const textarea = form.querySelector("textarea");
|
|
if (!textarea) {
|
|
return;
|
|
}
|
|
textarea.addEventListener("input", () => {
|
|
textarea.style.height = "auto";
|
|
textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
|
|
});
|
|
});
|
|
}
|
|
|
|
initVoteButtons() {
|
|
document.querySelectorAll(".post-action-btn[data-vote]").forEach((btn) => {
|
|
btn.addEventListener("click", async () => {
|
|
const targetUid = btn.dataset.target;
|
|
const targetType = btn.dataset.type || "post";
|
|
const value = btn.dataset.vote;
|
|
|
|
const form = document.createElement("form");
|
|
form.method = "POST";
|
|
form.action = `/votes/${targetType}/${targetUid}`;
|
|
const input = document.createElement("input");
|
|
input.type = "hidden";
|
|
input.name = "value";
|
|
input.value = value;
|
|
form.appendChild(input);
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
});
|
|
});
|
|
}
|
|
|
|
initMessageSearch() {
|
|
const searchInput = document.getElementById("message-search");
|
|
if (!searchInput) {
|
|
return;
|
|
}
|
|
searchInput.addEventListener("keydown", (e) => {
|
|
if (e.key === "Enter") {
|
|
const query = searchInput.value.trim();
|
|
if (query) {
|
|
window.location.href = `/messages?search=${encodeURIComponent(query)}`;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
initNotificationDismiss() {
|
|
document.querySelectorAll(".notification-dismiss").forEach((btn) => {
|
|
btn.addEventListener("click", async () => {
|
|
const uid = btn.dataset.uid;
|
|
if (!uid) {
|
|
return;
|
|
}
|
|
const form = document.createElement("form");
|
|
form.method = "POST";
|
|
form.action = `/notifications/mark-read/${uid}`;
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
});
|
|
});
|
|
}
|
|
|
|
initProfileEdit() {
|
|
document.querySelectorAll("[data-edit-field]").forEach((btn) => {
|
|
btn.addEventListener("click", () => {
|
|
const field = btn.dataset.editField;
|
|
const display = document.getElementById(`display-${field}`);
|
|
const input = document.getElementById(`input-${field}`);
|
|
if (!display || !input) {
|
|
return;
|
|
}
|
|
display.classList.toggle("hidden");
|
|
input.classList.toggle("hidden");
|
|
if (!input.classList.contains("hidden")) {
|
|
input.focus();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
initProjectForm() {
|
|
const platformsInput = document.getElementById("platforms-input");
|
|
if (!platformsInput) {
|
|
return;
|
|
}
|
|
const hiddenInput = document.getElementById("platforms");
|
|
const tagsContainer = document.getElementById("platforms-tags");
|
|
|
|
platformsInput.addEventListener("keydown", (e) => {
|
|
if (e.key === "Enter") {
|
|
e.preventDefault();
|
|
const val = platformsInput.value.trim();
|
|
if (!val) {
|
|
return;
|
|
}
|
|
const tag = document.createElement("span");
|
|
tag.className = "platform-tag";
|
|
tag.textContent = val;
|
|
const remove = document.createElement("button");
|
|
remove.type = "button";
|
|
remove.textContent = "x";
|
|
remove.style.marginLeft = "4px";
|
|
remove.style.fontSize = "0.75rem";
|
|
remove.style.padding = "0";
|
|
remove.addEventListener("click", () => {
|
|
tag.remove();
|
|
updatePlatforms();
|
|
});
|
|
tag.appendChild(remove);
|
|
tagsContainer.appendChild(tag);
|
|
platformsInput.value = "";
|
|
updatePlatforms();
|
|
}
|
|
});
|
|
|
|
function updatePlatforms() {
|
|
const tags = tagsContainer.querySelectorAll(".platform-tag");
|
|
const values = Array.from(tags).map((t) =>
|
|
t.textContent.replace("x", "").trim()
|
|
);
|
|
hiddenInput.value = values.join(",");
|
|
}
|
|
}
|
|
}
|
|
|
|
const app = new Application();
|