util.js (3823B)
1 /* This file contains utility functions related to UI manipulation. Some code 2 * may be specific to areas of the UI and others are more utility based. As 3 * this file grows specific UI area code should be migrated to its own file. 4 */ 5 6 /* toggle_cw changes the active stage of the Content Warning for a post. It is 7 * relative to the element that is pressed. 8 */ 9 function toggle_cw(el) { 10 el.classList.toggle("active"); 11 const isOn = el.classList.contains("active"); 12 const input = el.parentElement.querySelector("input.cw"); 13 input.classList.toggle("hide", !isOn); 14 } 15 16 /* toggle_gnav hides or shows the global navigation's additional buttons based 17 * on its opened state. 18 */ 19 function toggle_gnav(el) { 20 el.parentElement.classList.toggle("open"); 21 } 22 23 /* post_input_changed checks the content of the textarea and updates the size 24 * of it's element. Additionally I will toggle the enabled state of the sending 25 * button. 26 */ 27 function post_input_changed(el) { 28 el.style.height = `0px`; 29 el.style.height = `${el.scrollHeight}px`; 30 let btn = el.parentElement.querySelector("button[role=send]"); 31 if (btn) btn.disabled = el.value === ""; 32 } 33 34 /* init_message_textareas finds all message textareas and updates their initial 35 * height based on their content (0). This is so there is no jaring affect when 36 * the page loads. 37 */ 38 function init_message_textareas() { 39 const els = document.querySelectorAll(".post-input"); 40 for (const el of els) { 41 post_input_changed(el); 42 } 43 } 44 45 // update_notification_markers will find all markers and hide or show them 46 // based on the passed in state of 'active'. 47 function update_notification_markers(active) { 48 let els = document.querySelectorAll(".new-notifications") 49 for (const el of els) { 50 el.classList.toggle("hide", !active) 51 } 52 } 53 54 /* show_profile updates the current view to the profile display and updates the 55 * information to the relevant profile based on the public key passed. 56 * TODO handle async waiting for relay not yet connected 57 */ 58 function show_profile(pk) { 59 switch_view("profile"); 60 const profile = DAMUS.profiles[pk]; 61 const el = find_node("#profile-view"); 62 // TODO show loading indicator then render 63 64 find_node("[role='profile-image']", el).src = get_picture(pk, profile); 65 find_nodes("[role='profile-name']", el).forEach(el => { 66 el.innerText = render_name_plain(profile); 67 }); 68 69 const el_nip5 = find_node("[role='profile-nip5']", el) 70 el_nip5.innerText = profile.nip05; 71 el_nip5.classList.toggle("hide", !profile.nip05); 72 73 const el_desc = find_node("[role='profile-desc']", el) 74 el_desc.innerHTML = newlines_to_br(profile.about); 75 el_desc.classList.toggle("hide", !profile.about); 76 77 find_node("button[role='copy-pk']", el).dataset.pk = pk; 78 79 const btn_follow = find_node("button[role='follow-user']", el) 80 btn_follow.dataset.pk = pk; 81 // TODO check follow status 82 btn_follow.innerText = 1 == 1 ? "Follow" : "Unfollow"; 83 btn_follow.classList.toggle("hide", pk == DAMUS.pubkey); 84 } 85 86 /* newlines_to_br takes a string and converts all newlines to HTML 'br' tags. 87 */ 88 function newlines_to_br(str="") { 89 return str.split("\n").reduce((acc, part, index) => { 90 return acc + part + "<br/>"; 91 }, ""); 92 } 93 94 /* click_copy_pk writes the element's dataset.pk field to the users OS' 95 * clipboard. No we don't use fallback APIs, use a recent browser. 96 */ 97 function click_copy_pk(el) { 98 // TODO show toast 99 navigator.clipboard.writeText(el.dataset.pk); 100 } 101 102 /* click_follow_user sends the event to the relay to subscribe the active user 103 * to the target public key of the element's dataset.pk field. 104 */ 105 function click_toggle_follow_user(el) { 106 alert("sorry not implemented"); 107 } 108 109 /* click_event opens the thread view from the element's specified element id 110 * "dataset.eid". 111 */ 112 function click_event(el) { 113 console.info(`thread to open: ${el.dataset.eid}`); 114 switch_view("thread"); 115 }