Screenshots
parent
4d48c5dc34
commit
cc752cf797
|
@ -183,3 +183,4 @@ Third party libraries and resources:
|
||||||
* [GoReleaser](https://goreleaser.com/) (MIT) is used to create releases
|
* [GoReleaser](https://goreleaser.com/) (MIT) is used to create releases
|
||||||
* [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) (MIT) is used to provide the persistent message cache
|
* [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) (MIT) is used to provide the persistent message cache
|
||||||
* [Firebase Admin SDK](https://github.com/firebase/firebase-admin-go) (Apache 2.0) is used to send FCM messages
|
* [Firebase Admin SDK](https://github.com/firebase/firebase-admin-go) (Apache 2.0) is used to send FCM messages
|
||||||
|
* [Lightbox with vanilla JS](https://yossiabramov.com/blog/vanilla-js-lightbox)
|
||||||
|
|
|
@ -41,10 +41,21 @@
|
||||||
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 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,
|
||||||
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.
|
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>
|
||||||
|
|
||||||
|
<div id="screenshots">
|
||||||
|
<a href="static/img/screenshot-curl.png"><img src="static/img/screenshot-curl.png"/></a>
|
||||||
|
<a href="static/img/screenshot-web-detail.png"><img src="static/img/screenshot-web-detail.png"/></a>
|
||||||
|
<span class="nowrap">
|
||||||
|
<a href="static/img/screenshot-phone-main.jpg"><img src="static/img/screenshot-phone-main.jpg"/></a>
|
||||||
|
<a href="static/img/screenshot-phone-detail.jpg"><img src="static/img/screenshot-phone-detail.jpg"/></a>
|
||||||
|
<a href="static/img/screenshot-phone-notification.jpg"><img src="static/img/screenshot-phone-notification.jpg"/></a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
There are many ways to use ntfy. You can send yourself messages for all sorts of things: When a long process finishes or fails (a backup, a long rsync job, ...),
|
There are many ways to use Ntfy. You can send yourself messages for all sorts of things: When a long process finishes or fails (a backup, a long rsync job, ...),
|
||||||
or to notify yourself when somebody logs into your server(s). Or you may want to use it in your own app to distribute messages to subscribed clients.
|
or to notify yourself when somebody logs into your server(s). Or you may want to use it in your own app to distribute messages to subscribed clients.
|
||||||
Endless possibilities 😀.
|
Endless possibilities 😀. Be sure to check out the <a href="https://github.com/binwiederhier/ntfy/tree/main/examples">example on GitHub</a>!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Publishing messages</h2>
|
<h2>Publishing messages</h2>
|
||||||
|
@ -239,6 +250,7 @@
|
||||||
<div id="detailEventsList"></div>
|
<div id="detailEventsList"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="lightbox" class="lightbox"></div>
|
||||||
<script src="static/js/app.js"></script>
|
<script src="static/js/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -95,6 +95,83 @@ code {
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Screenshots */
|
||||||
|
|
||||||
|
#screenshots {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screenshots img {
|
||||||
|
height: 190px;
|
||||||
|
margin: 3px;
|
||||||
|
border-radius: 5px;
|
||||||
|
filter: drop-shadow(2px 2px 2px #ddd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#screenshots .nowrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lightbox; thanks to https://yossiabramov.com/blog/vanilla-js-lightbox */
|
||||||
|
|
||||||
|
.lightbox {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
position: fixed;
|
||||||
|
left:0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: -1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.15s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox.show {
|
||||||
|
background-color: rgba(0,0,0, 0.75);
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox img {
|
||||||
|
max-width: 90%;
|
||||||
|
max-height: 90%;
|
||||||
|
filter: drop-shadow(5px 5px 10px #222);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox .close-lightbox {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
right: 30px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox .close-lightbox::after,
|
||||||
|
.lightbox .close-lightbox::before {
|
||||||
|
content: '';
|
||||||
|
width: 3px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #ddd;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 5px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox .close-lightbox::before {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lightbox .close-lightbox:hover::after,
|
||||||
|
.lightbox .close-lightbox:hover::before {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* Subscribe box */
|
/* Subscribe box */
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 253 KiB |
Binary file not shown.
After Width: | Height: | Size: 227 KiB |
Binary file not shown.
After Width: | Height: | Size: 225 KiB |
Binary file not shown.
After Width: | Height: | Size: 128 KiB |
Binary file not shown.
After Width: | Height: | Size: 224 KiB |
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
|
@ -32,6 +32,9 @@ const detailNoNotifications = document.getElementById("detailNoNotifications");
|
||||||
const detailCloseButton = document.getElementById("detailCloseButton");
|
const detailCloseButton = document.getElementById("detailCloseButton");
|
||||||
const detailNotificationsDisallowed = document.getElementById("detailNotificationsDisallowed");
|
const detailNotificationsDisallowed = document.getElementById("detailNotificationsDisallowed");
|
||||||
|
|
||||||
|
/* Screenshots */
|
||||||
|
const lightbox = document.getElementById("lightbox");
|
||||||
|
|
||||||
const subscribe = (topic) => {
|
const subscribe = (topic) => {
|
||||||
if (Notification.permission !== "granted") {
|
if (Notification.permission !== "granted") {
|
||||||
Notification.requestPermission().then((permission) => {
|
Notification.requestPermission().then((permission) => {
|
||||||
|
@ -203,6 +206,54 @@ 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.");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showScreenshotOverlay = (e, el, index) => {
|
||||||
|
lightbox.classList.add('show');
|
||||||
|
document.addEventListener('keydown', nextScreenshotKeyboardListener);
|
||||||
|
return showScreenshot(e, index);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showScreenshot = (e, index) => {
|
||||||
|
const actualIndex = resolveScreenshotIndex(index);
|
||||||
|
lightbox.innerHTML = '<div class="close-lightbox"></div>' + screenshots[actualIndex].innerHTML;
|
||||||
|
lightbox.querySelector('img').onclick = (e) => { return showScreenshot(e,actualIndex+1); };
|
||||||
|
currentScreenshotIndex = actualIndex;
|
||||||
|
e.stopPropagation();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const nextScreenshot = (e) => {
|
||||||
|
return showScreenshot(e, currentScreenshotIndex+1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const previousScreenshot = (e) => {
|
||||||
|
return showScreenshot(e, currentScreenshotIndex-1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolveScreenshotIndex = (index) => {
|
||||||
|
if (index < 0) {
|
||||||
|
return screenshots.length - 1;
|
||||||
|
} else if (index > screenshots.length - 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
};
|
||||||
|
|
||||||
|
const hideScreenshotOverlay = (e) => {
|
||||||
|
lightbox.classList.remove('show');
|
||||||
|
document.removeEventListener('keydown', nextScreenshotKeyboardListener);
|
||||||
|
};
|
||||||
|
|
||||||
|
const nextScreenshotKeyboardListener = (e) => {
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case 37:
|
||||||
|
previousScreenshot(e);
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
nextScreenshot(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// From: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
|
// From: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
|
||||||
async function* makeTextFileLineIterator(fileURL) {
|
async function* makeTextFileLineIterator(fileURL) {
|
||||||
const utf8Decoder = new TextDecoder('utf-8');
|
const utf8Decoder = new TextDecoder('utf-8');
|
||||||
|
@ -248,6 +299,14 @@ detailCloseButton.onclick = () => {
|
||||||
hideDetailView();
|
hideDetailView();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let currentScreenshotIndex = 0;
|
||||||
|
const screenshots = [...document.querySelectorAll("#screenshots a")];
|
||||||
|
screenshots.forEach((el, index) => {
|
||||||
|
el.onclick = (e) => { return showScreenshotOverlay(e, el, index); };
|
||||||
|
});
|
||||||
|
|
||||||
|
lightbox.onclick = hideScreenshotOverlay;
|
||||||
|
|
||||||
// Disable Web UI if notifications of EventSource are not available
|
// Disable Web UI if notifications of EventSource are not available
|
||||||
if (!window["Notification"] || !window["EventSource"]) {
|
if (!window["Notification"] || !window["EventSource"]) {
|
||||||
showBrowserIncompatibleError();
|
showBrowserIncompatibleError();
|
||||||
|
|
Loading…
Reference in New Issue