Updated modals to be better for everyone.
This commit is contained in:
parent
3970bb5acd
commit
8ddeca2227
7 changed files with 78 additions and 211 deletions
|
@ -33,4 +33,15 @@
|
||||||
width: 44px;
|
width: 44px;
|
||||||
height: 44px;
|
height: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialog:modal {
|
||||||
|
width: initial;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
margin-top: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,6 +370,11 @@ button.nav > img.icon {
|
||||||
|
|
||||||
.action-bar button.icon {
|
.action-bar button.icon {
|
||||||
transition: opacity 0.3s linear;
|
transition: opacity 0.3s linear;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.action-bar button.icon img.icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
}
|
}
|
||||||
.action-bar button.icon:hover {
|
.action-bar button.icon:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -385,51 +390,45 @@ details.cw summary {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modal */
|
/* Modal */
|
||||||
.modal {
|
dialog:modal {
|
||||||
position: fixed;
|
width: 80%;
|
||||||
z-index: var(--zModal);
|
max-width: 700px;
|
||||||
left: 0;
|
padding: 20px;
|
||||||
top: 0;
|
border: none;
|
||||||
width: 100%;
|
background: transparent;
|
||||||
height: 100%;
|
color: var(--clrText);
|
||||||
background: rgba(255,255,255,0.4);
|
}
|
||||||
opacity: 1;
|
dialog::backdrop {
|
||||||
transition: opacity 0.2s linear;
|
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
-webkit-backdrop-filter: blur(20px);
|
-webkit-backdrop-filter: blur(20px);
|
||||||
}
|
}
|
||||||
.modal.scrollable {
|
dialog header {
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.modal.closed {
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.modal-content {
|
|
||||||
padding: 20px;
|
|
||||||
overflow: auto;
|
|
||||||
border-radius: 15px;
|
|
||||||
background: var(--clrPanel);
|
|
||||||
max-width: 700px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 35px;
|
|
||||||
}
|
|
||||||
.modal header {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.modal header label {
|
dialog header label {
|
||||||
|
flex: 1;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-size: var(--fsEnlarged);
|
font-size: var(--fsEnlarged);
|
||||||
flex: 1;
|
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.modal header button {
|
dialog header button {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
.modal .modal-floating-close-btn {
|
dialog > img {
|
||||||
position: sticky;
|
/* fix for media preview */
|
||||||
top: 20px;
|
max-width: 100%;
|
||||||
left: 20px;
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
dialog > .container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: var(--clrPanel);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
dialog > .container .max-content {
|
||||||
|
max-height: min(100vh/2, 500px);
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Post & Reply */
|
/* Post & Reply */
|
||||||
|
@ -440,6 +439,7 @@ details.cw summary {
|
||||||
textarea.post-input {
|
textarea.post-input {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-height: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-tools {
|
.post-tools {
|
||||||
|
@ -452,6 +452,9 @@ textarea.post-input {
|
||||||
.post-tools > button.icon.cw.active {
|
.post-tools > button.icon.cw.active {
|
||||||
opacity: 1.0;
|
opacity: 1.0;
|
||||||
}
|
}
|
||||||
|
.post-tools > button[name='reply-all'] {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
input[type="text"].cw {
|
input[type="text"].cw {
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: solid 2px var(--clrWarn);
|
border-bottom: solid 2px var(--clrWarn);
|
||||||
|
@ -490,21 +493,6 @@ label[role="profile-nip5"] {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Media Preview */
|
|
||||||
|
|
||||||
.modal .media-container {
|
|
||||||
text-align: center;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.modal .media-container > img {
|
|
||||||
object-fit: scale-down;
|
|
||||||
object-position: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Profile Editor */
|
/* Profile Editor */
|
||||||
|
|
||||||
#profile-editor header {
|
#profile-editor header {
|
||||||
|
|
132
index.html
132
index.html
|
@ -51,11 +51,6 @@
|
||||||
Sign In with Key
|
Sign In with Key
|
||||||
<img src="./icon/key.svg" class="icon svg small invert"/>
|
<img src="./icon/key.svg" class="icon svg small invert"/>
|
||||||
</button>
|
</button>
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
<button class="btn-text" action="open-faqs">
|
|
||||||
What's Nostr?
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -211,7 +206,6 @@
|
||||||
<label>
|
<label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button class="action mr-some" role='about-nostr'>Read About Nostr</button>
|
|
||||||
<button class="action" role="sign-out">
|
<button class="action" role="sign-out">
|
||||||
Sign Out
|
Sign Out
|
||||||
<img class="icon svg small invert" src="icon/sign-out.svg"/>
|
<img class="icon svg small invert" src="icon/sign-out.svg"/>
|
||||||
|
@ -246,15 +240,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal closed" id="media-preview">
|
<dialog id="media-preview">
|
||||||
<div class="media-container">
|
|
||||||
<img action="close-media" src=""/>
|
<img action="close-media" src=""/>
|
||||||
</div>
|
|
||||||
<!-- TODO add loader to media preview -->
|
<!-- TODO add loader to media preview -->
|
||||||
</div>
|
</dialog>
|
||||||
|
<dialog id="reply-modal">
|
||||||
<div class="modal closed" id="reply-modal">
|
<div class="container">
|
||||||
<div id="reply-modal-content" class="modal-content">
|
|
||||||
<header>
|
<header>
|
||||||
<label>Reply To</label>
|
<label>Reply To</label>
|
||||||
<button class="icon" action="close-modal">
|
<button class="icon" action="close-modal">
|
||||||
|
@ -266,14 +257,14 @@
|
||||||
<textarea id="reply-content" class="post-input"
|
<textarea id="reply-content" class="post-input"
|
||||||
placeholder="Reply..."></textarea>
|
placeholder="Reply..."></textarea>
|
||||||
<div class="post-tools">
|
<div class="post-tools">
|
||||||
<button id="reply-button" class="action">Reply</button>
|
<button class="action" name="reply-all" data-all="1">Reply All</button>
|
||||||
|
<button class="action" name="reply">Reply</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
|
<dialog id="profile-editor">
|
||||||
<div id="profile-editor" class="modal closed">
|
<div class="container">
|
||||||
<div class="modal-content">
|
|
||||||
<header>
|
<header>
|
||||||
<label>Update Profile</label>
|
<label>Update Profile</label>
|
||||||
<button class="icon" action="close-modal">
|
<button class="icon" action="close-modal">
|
||||||
|
@ -290,116 +281,21 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
<div id="event-details" class="modal closed">
|
<dialog id="event-details">
|
||||||
<div class="modal-content">
|
<div class="container">
|
||||||
<header>
|
<header>
|
||||||
<label>Event Details</label>
|
<label>Event Details</label>
|
||||||
<button class="icon modal-floating-close-btn" action="close-modal">
|
<button class="icon modal-floating-close-btn" action="close-modal">
|
||||||
<img class="icon svg" src="icon/close-modal.svg"/>
|
<img class="icon svg" src="icon/close-modal.svg"/>
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div>
|
<div class="max-content">
|
||||||
<pre><code></code></pre>
|
<pre><code></code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dialog>
|
||||||
|
|
||||||
<div id="faqs" class="modal scrollable closed">
|
|
||||||
<button class="icon modal-floating-close-btn" action="close-modal">
|
|
||||||
<img class="icon svg" src="icon/close-modal.svg"/>
|
|
||||||
</button>
|
|
||||||
<div class="page-content">
|
|
||||||
<h1>Welcome to Nostr</h1>
|
|
||||||
<p>The open social network for "literally" everyone.</p>
|
|
||||||
|
|
||||||
<h2>What is Nostr?</h2>
|
|
||||||
<p>
|
|
||||||
Nostr is a protocol, not a platform or an app. This means that
|
|
||||||
users can pick and choose which clients (apps) to use and which
|
|
||||||
relays (servers) they wish to connect to.
|
|
||||||
</p>
|
|
||||||
<p>Nostr uses encryption to validate content authors. This means
|
|
||||||
that there is no centralized account system. We use
|
|
||||||
<a href="https://en.wikipedia.org/wiki/Public-key_cryptography"
|
|
||||||
target="_blank">public & private</a> keys to sign our
|
|
||||||
content when we post. Do not confuse this with blockchain
|
|
||||||
technology.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Nostr stands for "Notes and Other Stuff Transmitted by Relays".
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Read more about the protocol <a
|
|
||||||
href="https://github.com/nostr-protocol/nostr"
|
|
||||||
target="_blank">here</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Apps</h2>
|
|
||||||
<p>
|
|
||||||
You are using one right now! You just haven't signed in yet to see
|
|
||||||
the actual application. Close this modal to sign in with your key.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A rich app ecosystem for Nostr. Anyone can build an app for the
|
|
||||||
protocol that fits their needs. This is the best option for users
|
|
||||||
as everyone has their own style. Another benifit is that you can
|
|
||||||
use multiple apps with the same account.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Since there are many apps for Nostr it allows developers to focus
|
|
||||||
on building certain experiences. Some apps may offer features that
|
|
||||||
others don't, such as direct messages, content viewing methods,
|
|
||||||
etc. You are allowed to choose how you want to interact with
|
|
||||||
Nostr.
|
|
||||||
</p>
|
|
||||||
<h3>Pick One</h3>
|
|
||||||
<p>
|
|
||||||
Here are a list of (trusted) apps that work with Nostr. Pick one
|
|
||||||
that fits you.
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://damus.io" target="_blank">Damus</a> (iOS)</li>
|
|
||||||
<li><a href="https://github.com/fiatjaf/noscl" target="_blank">noscl</a> (Linux, Windows, MacOS)</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Web Apps Warning</h3>
|
|
||||||
<p>
|
|
||||||
While the web is great for accessibility and is cross platform, it
|
|
||||||
is riddled with security implications you should be aware of. The
|
|
||||||
browser is susceptible to cross-site scripting (<a
|
|
||||||
href="https://en.wikipedia.org/wiki/Cross-site_scripting"
|
|
||||||
target="_blank">XSS</a>) attacks and extension malware. Therefore
|
|
||||||
you should be sure any web app you use is audited and trusted.
|
|
||||||
Additionally be aware of what apps you are using.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Secondly it is recommended you use a browser extension to handle
|
|
||||||
your Nostr key(s). This will delegate the signing process to an
|
|
||||||
extension that a XSS attack can't access. This is where native apps
|
|
||||||
have a stronger use case, but you should equally trust those as
|
|
||||||
well.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Relays</h2>
|
|
||||||
<p>
|
|
||||||
Relays are points of connection, a server. They allow you to read
|
|
||||||
events (content) and write to it depending on it's configuration.
|
|
||||||
Some may be read only, others may require some sort of payment to
|
|
||||||
use. Some may simply clone other relays.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Relays allow for specific needs and niches. You can host your
|
|
||||||
own relay for your club or community (such as gaming, art, sciences,
|
|
||||||
etc.) Or you can build your own relay with your own logic that
|
|
||||||
dictates who can access what and how. This is great for all kinds
|
|
||||||
of use cases for a range of users from individuals to businesses.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Account Creation</h2>
|
|
||||||
<p>You need to use a CLI tool. TODO fill this out.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -197,12 +197,9 @@ function render_action_bar(model, ev, opts={}) {
|
||||||
let str = html`<div class="action-bar">`;
|
let str = html`<div class="action-bar">`;
|
||||||
if (!shared && event_can_reply(ev)) {
|
if (!shared && event_can_reply(ev)) {
|
||||||
str += html`
|
str += html`
|
||||||
<button class="icon" title="Reply" action="reply-author" data-evid="${ev.id}">
|
<button class="icon" title="Reply" action="reply-to" data-evid="${ev.id}">
|
||||||
<img class="icon svg small" src="icon/event-reply.svg"/>
|
<img class="icon svg small" src="icon/event-reply.svg"/>
|
||||||
</button>
|
</button>
|
||||||
<button class="icon" title="Reply All" action="reply-all" data-evid="${ev.id}">
|
|
||||||
<img class="icon svg small" src="icon/event-reply-all.svg"/>
|
|
||||||
</button>
|
|
||||||
<button class="icon react heart ${ab(liked, 'liked', '')}"
|
<button class="icon react heart ${ab(liked, 'liked', '')}"
|
||||||
action="react-like"
|
action="react-like"
|
||||||
data-reaction-id="${reaction_id}"
|
data-reaction-id="${reaction_id}"
|
||||||
|
|
|
@ -5,7 +5,6 @@ function init_settings(model) {
|
||||||
embeds_el.addEventListener("click", on_click_toggle_embeds);
|
embeds_el.addEventListener("click", on_click_toggle_embeds);
|
||||||
embeds_el.checked = model.embeds != "friends";
|
embeds_el.checked = model.embeds != "friends";
|
||||||
find_node("[role='sign-out']", el).addEventListener("click", on_click_sign_out);
|
find_node("[role='sign-out']", el).addEventListener("click", on_click_sign_out);
|
||||||
find_node("[role='about-nostr']", el).addEventListener("click", open_faqs);
|
|
||||||
const rlist = find_node("#relay-list tbody", el);
|
const rlist = find_node("#relay-list tbody", el);
|
||||||
model.relays.forEach((str) => {
|
model.relays.forEach((str) => {
|
||||||
rlist.appendChild(new_relay_item(str));
|
rlist.appendChild(new_relay_item(str));
|
||||||
|
|
|
@ -501,11 +501,13 @@ function init_postbox(model) {
|
||||||
// Do reply box
|
// Do reply box
|
||||||
// TODO refactor & cleanup reply modal init
|
// TODO refactor & cleanup reply modal init
|
||||||
find_node("#reply-content").addEventListener("input", oninput_post);
|
find_node("#reply-content").addEventListener("input", oninput_post);
|
||||||
find_node("#reply-button").addEventListener("click", onclick_reply);
|
find_node("button[name='reply']")
|
||||||
|
.addEventListener("click", onclick_reply);
|
||||||
|
find_node("button[name='reply-all']")
|
||||||
|
.addEventListener("click", onclick_reply);
|
||||||
}
|
}
|
||||||
async function onclick_reply(ev) {
|
async function onclick_reply(ev) {
|
||||||
// Temp method
|
do_send_reply(ev.target.dataset.all == "1");
|
||||||
do_send_reply();
|
|
||||||
}
|
}
|
||||||
async function onclick_send(ev) {
|
async function onclick_send(ev) {
|
||||||
const el = view_get_timeline_el();
|
const el = view_get_timeline_el();
|
||||||
|
@ -571,9 +573,6 @@ function onclick_any(ev) {
|
||||||
const el = ev.target;
|
const el = ev.target;
|
||||||
const action = el.getAttribute("action");
|
const action = el.getAttribute("action");
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "open-faqs":
|
|
||||||
open_faqs();
|
|
||||||
break;
|
|
||||||
case "toggle-gnav":
|
case "toggle-gnav":
|
||||||
toggle_gnav(el);
|
toggle_gnav(el);
|
||||||
break;
|
break;
|
||||||
|
@ -607,11 +606,8 @@ function onclick_any(ev) {
|
||||||
case "delete":
|
case "delete":
|
||||||
delete_post(el.dataset.evid);
|
delete_post(el.dataset.evid);
|
||||||
break;
|
break;
|
||||||
case "reply-author":
|
case "reply-to":
|
||||||
reply_author(el.dataset.evid);
|
reply(el.dataset.evid);
|
||||||
break;
|
|
||||||
case "reply-all":
|
|
||||||
reply_all(el.dataset.evid);
|
|
||||||
break;
|
break;
|
||||||
case "react-like":
|
case "react-like":
|
||||||
click_toggle_like(el);
|
click_toggle_like(el);
|
||||||
|
|
|
@ -65,7 +65,7 @@ function click_toggle_like(el) {
|
||||||
*/
|
*/
|
||||||
function open_media_preview(url, type) {
|
function open_media_preview(url, type) {
|
||||||
const el = find_node("#media-preview");
|
const el = find_node("#media-preview");
|
||||||
el.classList.remove("closed");
|
el.showModal();
|
||||||
find_node("img", el).src = url;
|
find_node("img", el).src = url;
|
||||||
// TODO handle different medias such as audio and video
|
// TODO handle different medias such as audio and video
|
||||||
// TODO add loading state & error checking
|
// TODO add loading state & error checking
|
||||||
|
@ -74,7 +74,7 @@ function open_media_preview(url, type) {
|
||||||
/* close_media_preview closes any present media modal.
|
/* close_media_preview closes any present media modal.
|
||||||
*/
|
*/
|
||||||
function close_media_preview() {
|
function close_media_preview() {
|
||||||
find_node("#media-preview").classList.add("closed");
|
find_node("#media-preview").close();
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_post_confirm(evid) {
|
function delete_post_confirm(evid) {
|
||||||
|
@ -86,11 +86,10 @@ function delete_post_confirm(evid) {
|
||||||
delete_post(evid, reason)
|
delete_post(evid, reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function do_send_reply() {
|
async function do_send_reply(all=false) {
|
||||||
const modal = document.querySelector("#reply-modal");
|
const modal = document.querySelector("#reply-modal");
|
||||||
const replying_to = modal.querySelector("#replying-to");
|
const replying_to = modal.querySelector("#replying-to");
|
||||||
const evid = replying_to.dataset.evid;
|
const evid = replying_to.dataset.evid;
|
||||||
const all = replying_to.dataset.toAll != "";
|
|
||||||
const reply_content_el = document.querySelector("#reply-content");
|
const reply_content_el = document.querySelector("#reply-content");
|
||||||
const content = reply_content_el.value;
|
const content = reply_content_el.value;
|
||||||
await send_reply(content, evid, all);
|
await send_reply(content, evid, all);
|
||||||
|
@ -98,29 +97,20 @@ async function do_send_reply() {
|
||||||
close_modal(modal);
|
close_modal(modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
function reply(evid, all=false) {
|
function reply(evid) {
|
||||||
const ev = DAMUS.all_events[evid]
|
const ev = DAMUS.all_events[evid]
|
||||||
const modal = document.querySelector("#reply-modal")
|
const modal = document.querySelector("#reply-modal")
|
||||||
const replybox = modal.querySelector("#reply-content")
|
const replybox = modal.querySelector("#reply-content")
|
||||||
const replying_to = modal.querySelector("#replying-to")
|
const replying_to = modal.querySelector("#replying-to")
|
||||||
replying_to.dataset.evid = evid
|
replying_to.dataset.evid = evid
|
||||||
replying_to.dataset.toAll = all ? "all" : "";
|
|
||||||
replying_to.innerHTML = render_event_nointeract(DAMUS, ev, {
|
replying_to.innerHTML = render_event_nointeract(DAMUS, ev, {
|
||||||
is_composing: true,
|
is_composing: true,
|
||||||
nobar: true
|
nobar: true
|
||||||
});
|
});
|
||||||
modal.classList.remove("closed")
|
modal.showModal();
|
||||||
replybox.focus()
|
replybox.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
function reply_author(evid) {
|
|
||||||
reply(evid);
|
|
||||||
}
|
|
||||||
|
|
||||||
function reply_all(evid) {
|
|
||||||
reply(evid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_favicon(path) {
|
function update_favicon(path) {
|
||||||
let link = document.querySelector("link[rel~='icon']");
|
let link = document.querySelector("link[rel~='icon']");
|
||||||
const head = document.getElementsByTagName('head')[0]
|
const head = document.getElementsByTagName('head')[0]
|
||||||
|
@ -194,18 +184,8 @@ function open_thread(thread_id) {
|
||||||
view_timeline_apply_mode(DAMUS, VM_THREAD, { thread_id });
|
view_timeline_apply_mode(DAMUS, VM_THREAD, { thread_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
function open_faqs() {
|
|
||||||
find_node("#faqs").classList.remove("closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
function close_modal(el) {
|
function close_modal(el) {
|
||||||
while (el) {
|
find_parent(el, "dialog").close();
|
||||||
if (el.classList.contains("modal")) {
|
|
||||||
el.classList.add("closed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
el = el.parentElement;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function on_click_show_event_details(evid) {
|
function on_click_show_event_details(evid) {
|
||||||
|
@ -214,7 +194,7 @@ function on_click_show_event_details(evid) {
|
||||||
if (!ev)
|
if (!ev)
|
||||||
return;
|
return;
|
||||||
const el = find_node("#event-details");
|
const el = find_node("#event-details");
|
||||||
el.classList.remove("closed");
|
el.showModal();
|
||||||
find_node("code", el).innerText = JSON.stringify(ev, null, "\t");
|
find_node("code", el).innerText = JSON.stringify(ev, null, "\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue