WIP: Web UI improvements

This commit is contained in:
Philipp Heckel 2021-11-04 10:55:34 -04:00
parent 5948f39a53
commit 644ffa1420
6 changed files with 129 additions and 22 deletions

View file

@ -33,10 +33,9 @@
<h1><img src="static/img/ntfy.png" alt="ntfy"/><br/>ntfy.sh - simple HTTP-based pub-sub</h1> <h1><img src="static/img/ntfy.png" alt="ntfy"/><br/>ntfy.sh - simple HTTP-based pub-sub</h1>
<p> <p>
<b>ntfy</b> (pronounce: <i>notify</i>) is a simple HTTP-based <a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">pub-sub</a> notification service. <b>ntfy</b> (pronounce: <i>notify</i>) is a simple HTTP-based <a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">pub-sub</a> notification service.
It allows you to send <b>notifications to your phone or desktop via scripts from any computer</b>, entirely <b>without signup or cost</b>. It allows you to send notifications <a href="https://play.google.com/store/apps/details?id=io.heckel.ntfy">to your phone</a> or desktop via scripts from any computer,
It's also <a href="https://github.com/binwiederhier/ntfy">open source</a> if you want to run your own. entirely <b>without signup or cost</b>. It's also <a href="https://github.com/binwiederhier/ntfy">open source</a> if you want to run your own.
</p> </p>
<p id="error"></p>
<h2>Publishing messages</h2> <h2>Publishing messages</h2>
<p> <p>
@ -65,21 +64,24 @@
<a href="https://developer.mozilla.org/en-US/docs/Web/API/EventSource">EventSource</a>, a JSON feed, or raw feed. <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventSource">EventSource</a>, a JSON feed, or raw feed.
</p> </p>
<h3>Subscribe via web</h3> <div id="subscribeBox">
<p> <form id="subscribeForm">
If you subscribe to a topic via this web UI in the field below, messages published to any subscribed topic <h3>Subscribe via web</h3>
will show up as <b>desktop notification</b>. <p id="error"></p>
</p> <p>
<form id="subscribeForm"> Messages published to topics subscribed here will show up as <b>desktop notification</b>.
<p> Topics are not password-protected, so choose a name that's not easy to guess. Once subscribed, you can
<label for="topicField">Subscribe to topic:</label> publish messages via PUT/POST.
<input type="text" id="topicField" placeholder="Letters, numbers, _ and -" pattern="[-_A-Za-z]{1,64}" /> </p>
<input type="submit" id="subscribeButton" value="Subscribe" /> <p>
</p> <input type="text" id="topicField" autocomplete="off" placeholder="Topic name, e.g. phil_alerts" pattern="[-_A-Za-z]{1,64}" />
</form> <button id="subscribeButton">Subscribe</button>
<p id="topicsHeader">Topics:</p> </p>
<ul id="topicsList"></ul> </form>
<audio id="notifySound" src="static/sound/mixkit-message-pop-alert-2354.mp3"></audio> <p id="topicsHeader"><b>Subscribed topics:</b></p>
<ul id="topicsList"></ul>
<audio id="notifySound" src="static/sound/mixkit-message-pop-alert-2354.mp3"></audio>
</div>
<h3>Subscribe via phone</h3> <h3>Subscribe via phone</h3>
<p> <p>

View file

@ -60,6 +60,7 @@ code {
margin-bottom: 20px; margin-bottom: 20px;
} }
/* Lato font (OFL), https://fonts.google.com/specimen/Lato#about, /* Lato font (OFL), https://fonts.google.com/specimen/Lato#about,
embedded with the help of https://google-webfonts-helper.herokuapp.com/fonts/lato?subsets=latin */ embedded with the help of https://google-webfonts-helper.herokuapp.com/fonts/lato?subsets=latin */
@ -87,3 +88,104 @@ code {
#ironicCenterTagDontFreakOut { #ironicCenterTagDontFreakOut {
color: #666; color: #666;
} }
/* Subscribe box */
button {
background: #3a9784;
border: none;
border-radius: 3px;
padding: 3px 5px;
color: white;
cursor: pointer;
}
button:hover {
background: #317f6f;
padding: 5px;
}
ul {
padding-left: 1em;
list-style-type: none;
padding-bottom: 0;
margin: 0;
}
li {
padding: 4px 0;
margin: 4px 0;
font-size: 0.9em;
}
@media only screen and (min-width: 1600px) {
#subscribeBox {
position: fixed;
top: 180px;
right: 10px;
width: 300px;
border-left: 4px solid #3a9784;
padding: 10px;
}
#subscribeBox h3 {
margin-top: 0;
margin-bottom: 5px;
font-size: 1.1em;
}
#subscribeBox #topicsHeader {
margin-bottom: 0;
}
#subscribeBox p {
font-size: 0.9em;
margin-bottom: 10px;
}
#subscribeBox ul {
margin: 0;
padding: 0;
}
#subscribeBox input {
height: 18px;
border-radius: 3px;
border: none;
border-bottom: 1px solid #aaa;
}
#subscribeBox input:focus {
border-bottom: 2px solid #3a9784;
outline: none;
}
#subscribeBox li {
margin: 3px 0;
padding: 0;
}
#subscribeBox li img {
width: 15px;
height: 15px;
vertical-align: bottom;
}
#subscribeBox button {
font-size: 0.7em;
background: #3a9784;
border-radius: 3px;
padding: 3px 5px;
color: white;
cursor: pointer;
border-top: solid transparent 2px;
border-bottom: solid transparent 2px;
}
#subscribeBox button:hover {
background: #317f6f;
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>

After

Width:  |  Height:  |  Size: 269 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#FFFFFF"><path d="M0 0h24v24H0z" fill="none"/><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>

After

Width:  |  Height:  |  Size: 235 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#ffffff"><path d="M0 0h24v24H0z" fill="none"/><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>

After

Width:  |  Height:  |  Size: 195 B

View file

@ -40,7 +40,7 @@ const subscribeInternal = (topic, delaySec) => {
if (!topicEntry) { if (!topicEntry) {
topicEntry = document.createElement('li'); topicEntry = document.createElement('li');
topicEntry.id = `topic-${topic}`; topicEntry.id = `topic-${topic}`;
topicEntry.innerHTML = `${topic} <button onclick="test('${topic}')">Test</button> <button onclick="unsubscribe('${topic}')">Unsubscribe</button>`; topicEntry.innerHTML = `${topic} <button onclick="test('${topic}')"> <img src="static/img/send_black_24dp.svg"> Test</button> <button onclick="unsubscribe('${topic}')"> <img src="static/img/clear_black_24dp.svg"> Unsubscribe</button>`;
topicsList.appendChild(topicEntry); topicsList.appendChild(topicEntry);
} }
topicsHeader.style.display = ''; topicsHeader.style.display = '';
@ -48,7 +48,7 @@ const subscribeInternal = (topic, delaySec) => {
// Open event source // Open event source
let eventSource = new EventSource(`${topic}/sse`); let eventSource = new EventSource(`${topic}/sse`);
eventSource.onopen = () => { eventSource.onopen = () => {
topicEntry.innerHTML = `${topic} <button onclick="test('${topic}')">Test</button> <button onclick="unsubscribe('${topic}')">Unsubscribe</button>`; topicEntry.innerHTML = `${topic} <button onclick="test('${topic}')"> <img src="static/img/send_black_24dp.svg"> Test</button> <button onclick="unsubscribe('${topic}')"> <img src="static/img/clear_black_24dp.svg"> Unsubscribe</button>`;
delaySec = 0; // Reset on successful connection delaySec = 0; // Reset on successful connection
}; };
eventSource.onerror = (e) => { eventSource.onerror = (e) => {
@ -83,7 +83,7 @@ const unsubscribe = (topic) => {
const test = (topic) => { const test = (topic) => {
fetch(`/${topic}`, { fetch(`/${topic}`, {
method: 'PUT', method: 'PUT',
body: `This is a test notification` body: `This is a test notification sent from the Ntfy Web UI. It was sent at ${new Date().toString()}.`
}) })
}; };
@ -101,7 +101,7 @@ const showNotificationDeniedError = () => {
showError("You have blocked desktop notifications for this website. Please unblock them and refresh to use the web-based desktop notifications."); showError("You have blocked desktop notifications for this website. Please unblock them and refresh to use the web-based desktop notifications.");
}; };
subscribeForm.onsubmit = function () { subscribeButton.onclick = function () {
if (!topicField.value) { if (!topicField.value) {
return false; return false;
} }