Philipp Heckel 4 лет назад
Родитель
Сommit
1a3816c1ff

+ 6 - 48
server/index.gohtml

@@ -28,10 +28,6 @@
     <meta property="og:description" content="ntfy is a simple HTTP-based pub-sub notification service. It allows you to send desktop notifications via scripts from any computer, entirely without signup or cost. Made with ❤ by Philipp C. Heckel, Apache License 2.0, source at https://heckel.io/ntfy." />
     <meta property="og:image" content="/static/img/ntfy.png" />
     <meta property="og:url" content="https://ntfy.sh" />
-{{if .Topic}}
-    <!-- Never index topic page -->
-    <meta name="robots" content="noindex, nofollow" />
-{{end}}
 </head>
 <body>
 
@@ -48,7 +44,7 @@
         </ol>
     </div>
 </nav>
-<div id="main"{{if .Topic}} style="display: none"{{end}}>
+<div id="main">
     <h1>Send push notifications to your phone or desktop via PUT/POST</h1>
     <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.
@@ -122,24 +118,11 @@
         <figcaption>Sending push notifications to your Android phone</figcaption>
     </figure>
 
-    <div id="subscribeBox">
-        <h3 id="subscribe-web" class="anchor">Subscribe in this Web UI</h3>
-        <p id="error"></p>
-        <p>
-            Subscribe to topics here and receive messages as <b>desktop notification</b>. Topics are not password-protected,
-            so choose a name that's not easy to guess.
-        </p>
-        <form id="subscribeForm">
-            <p>
-                <b>Topic:</b><br/>
-                <input type="text" id="topicField" autocomplete="off" placeholder="Topic name, e.g. phil_alerts" maxlength="64" pattern="[-_A-Za-z0-9]{1,64}" />
-                <button id="subscribeButton">Subscribe</button>
-            </p>
-            <p id="topicsHeader"><b>Subscribed topics:</b></p>
-            <ul id="topicsList"></ul>
-        </form>
-        <audio id="notifySound" src="static/sound/mixkit-message-pop-alert-2354.mp3"></audio>
-    </div>
+    <h3 id="subscribe-web" class="anchor">Subscribe via web app</h3>
+    <p>
+        Subscribe to topics here and receive messages as <b>desktop notification</b>. Topics are not password-protected,
+        so choose a name that's not easy to guess.
+    </p>
 
     <h3 id="subscribe-api" class="anchor">Subscribe using the API</h3>
     <p>
@@ -186,31 +169,6 @@
 
     <center id="ironicCenterTagDontFreakOut"><i>Made with ❤️ by <a href="https://heckel.io">Philipp C. Heckel</a></i></center>
 </div>
-<div id="detail"{{if not .Topic}} style="display: none"{{end}}>
-    <div id="detailMain">
-        <button id="detailCloseButton"><img src="static/img/close.svg"/></button>
-        <h1><span id="detailTitle"></span></h1>
-        <p class="smallMarginBottom">
-            <b>ntfy</b> is a simple HTTP-based pub-sub notification service. This is a ntfy topic.
-            To send notifications to it, simply PUT or POST to the topic URL. Here's an example using <tt>curl</tt>:
-        </p>
-        <code>
-            curl -d "Backup failed" <span id="detailTopicUrl">ntfy.sh/topic</span>
-        </code>
-        <p id="detailNotificationsDisallowed">
-            If you'd like to receive desktop notifications when new messages arrive on this topic, you have to
-            <a href="#" onclick="return requestPermission()">grant the browser permission</a> to show notifications.
-            Click the link to do so.
-        </p>
-        <p class="smallMarginBottom">
-            <b>Recent notifications</b> ({{if .CacheDuration}}cached for {{.CacheDuration | durationToHuman}}{{else}}caching is disabled{{end}}):
-        </p>
-        <p id="detailNoNotifications">
-            <i>You haven't received any notifications for this topic yet.</i>
-        </p>
-        <div id="detailEventsList"></div>
-    </div>
-</div>
 <div id="lightbox" class="lightbox"></div>
 <script src="static/js/emoji.js"></script>
 <script src="static/js/app.js"></script>

+ 0 - 196
server/static/css/app.css

@@ -333,199 +333,3 @@ li {
         display: none;
     }
 }
-
-/* Subscribe box SMALL SCREEN */
-@media only screen and (max-width: 1599px) {
-    #subscribeBox #subscribeForm {
-        border-left: 4px solid #3a9784;
-        padding: 10px;
-    }
-
-    #subscribeBox #topicsHeader {
-        margin-bottom: 0;
-    }
-
-    #subscribeBox input {
-        height: 24px;
-        min-width: 200px;
-        max-width: 300px;
-        border-radius: 3px;
-        border: none;
-        border-bottom: 1px solid #aaa;
-        font-size: 0.8em;
-    }
-
-    #subscribeBox input:focus {
-        border-bottom: 2px solid #3a9784;
-        outline: none;
-    }
-
-    #subscribeBox ul {
-        margin: 0;
-    }
-
-    #subscribeBox li {
-        margin: 3px 0;
-        padding: 0;
-    }
-
-    #subscribeBox li img {
-        width: 15px;
-        height: 15px;
-        vertical-align: bottom;
-    }
-
-    #subscribeBox li a {
-        padding: 0 5px 0 0;
-    }
-
-    #subscribeBox button {
-        font-size: 0.8em;
-        background: #3a9784;
-        border-radius: 3px;
-        padding: 5px;
-        color: white;
-        cursor: pointer;
-    }
-
-    #subscribeBox button:hover {
-        background: #317f6f;
-    }
-}
-
-/* Subscribe box BIG SCREEN */
-@media only screen and (min-width: 1600px) {
-    #subscribeBox {
-        position: fixed;
-        top: 170px;
-        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;
-    }
-
-    #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 li a {
-        padding: 0 5px 0 0;
-    }
-
-    #subscribeBox button {
-        font-size: 0.7em;
-        background: #3a9784;
-        border-radius: 3px;
-        padding: 5px;
-        color: white;
-        cursor: pointer;
-    }
-
-    #subscribeBox button:hover {
-        background: #317f6f;
-    }
-}
-
-/** Detail view */
-
-#detail .detailEntry {
-    margin-bottom: 20px;
-}
-
-#detail .detailDate {
-    margin-bottom: 2px;
-}
-
-#detail .detailDate, #detail .detailTags {
-    color: #888;
-    font-size: 0.9em;
-}
-
-#detail .detailTags {
-    margin-top: 2px;
-}
-
-#detail .detailDate img {
-    width: 20px;
-    height: 20px;
-    vertical-align: bottom;
-}
-
-#detail .detailTitle {
-    font-weight: bold;
-}
-
-#detail #detailMain {
-    max-width: 900px;
-    margin: 0 auto;
-    position: relative; /* required for close button's "position: absolute" */
-    padding: 0 10px 50px 10px; /* Chrome and Firefox behave differently regarding bottom margin */
-}
-
-#detail #detailCloseButton {
-    background: #eee;
-    border-radius: 5px;
-    border: none;
-    padding: 5px;
-    position: absolute;
-    right: 10px;
-    top: 10px;
-    display: block;
-}
-
-#detail #detailCloseButton:hover {
-    padding: 5px;
-    background: #ccc;
-}
-
-#detail #detailCloseButton img {
-    display: block; /* get rid of the weird bottom border */
-}
-
-#detail #detailNotificationsDisallowed {
-    display: none;
-    color: darkred;
-}
-
-#detail #events {
-    max-width: 900px;
-    margin: 0 auto 50px auto;
-}

+ 0 - 47
server/static/img/priority-1.svg

@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   height="24px"
-   viewBox="0 0 24 24"
-   width="24px"
-   fill="#000000"
-   version="1.1"
-   id="svg1428"
-   sodipodi:docname="priority_1_24dp.svg"
-   inkscape:version="1.1.1 (3bf5ae0, 2021-09-20)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <defs
-     id="defs1432" />
-  <sodipodi:namedview
-     id="namedview1430"
-     pagecolor="#505050"
-     bordercolor="#eeeeee"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="0"
-     showgrid="false"
-     inkscape:zoom="20.517358"
-     inkscape:cx="22.834324"
-     inkscape:cy="15.742768"
-     inkscape:window-width="1863"
-     inkscape:window-height="1025"
-     inkscape:window-x="57"
-     inkscape:window-y="27"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg1428" />
-  <path
-     style="color:#000000;fill:#999999;fill-opacity:1;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.195014,20.828316 a 1.2747098,1.2747098 0 0 0 0.661605,-0.185206 l 6.646593,-4.037178 a 1.2745823,1.2745823 0 0 0 0.427537,-1.751107 1.2745823,1.2745823 0 0 0 -1.750928,-0.427718 l -5.984807,3.635327 -5.9848086,-3.635327 a 1.2745823,1.2745823 0 0 0 -1.750927,0.427718 1.2745823,1.2745823 0 0 0 0.427536,1.751107 l 6.6464146,4.037178 a 1.2747098,1.2747098 0 0 0 0.661785,0.185206 z"
-     id="rect3554" />
-  <path
-     style="color:#000000;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.195014,15.694014 a 1.2747098,1.2747098 0 0 0 0.661605,-0.185206 l 6.646593,-4.037176 A 1.2745823,1.2745823 0 0 0 19.930749,9.7205243 1.2745823,1.2745823 0 0 0 18.179821,9.2928073 L 12.195014,12.928134 6.2102054,9.2928073 a 1.2745823,1.2745823 0 0 0 -1.750927,0.427717 1.2745823,1.2745823 0 0 0 0.427536,1.7511077 l 6.6464146,4.037176 a 1.2747098,1.2747098 0 0 0 0.661785,0.185206 z"
-     id="path9314" />
-  <path
-     style="color:#000000;fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.116784,10.426777 a 1.2747098,1.2747098 0 0 0 0.661606,-0.185205 l 6.646593,-4.0371767 a 1.2745823,1.2745823 0 0 0 0.427537,-1.751108 1.2745823,1.2745823 0 0 0 -1.750928,-0.427718 l -5.984808,3.635327 -5.9848066,-3.635327 a 1.2745823,1.2745823 0 0 0 -1.750928,0.427718 1.2745823,1.2745823 0 0 0 0.427537,1.751108 L 11.455,10.241572 a 1.2747098,1.2747098 0 0 0 0.661784,0.185205 z"
-     id="path9316" />
-</svg>

+ 0 - 43
server/static/img/priority-2.svg

@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   height="24px"
-   viewBox="0 0 24 24"
-   width="24px"
-   fill="#000000"
-   version="1.1"
-   id="svg1428"
-   sodipodi:docname="priority_2_24dp.svg"
-   inkscape:version="1.1.1 (3bf5ae0, 2021-09-20)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <defs
-     id="defs1432" />
-  <sodipodi:namedview
-     id="namedview1430"
-     pagecolor="#505050"
-     bordercolor="#eeeeee"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="0"
-     showgrid="false"
-     inkscape:zoom="20.517358"
-     inkscape:cx="22.834324"
-     inkscape:cy="15.742768"
-     inkscape:window-width="1863"
-     inkscape:window-height="1025"
-     inkscape:window-x="57"
-     inkscape:window-y="27"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg1428" />
-  <path
-     style="color:#000000;fill:#999999;fill-opacity:1;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.172712,17.774352 a 1.2747098,1.2747098 0 0 0 0.661605,-0.185206 l 6.646593,-4.037178 a 1.2745823,1.2745823 0 0 0 0.427537,-1.751107 1.2745823,1.2745823 0 0 0 -1.750928,-0.427718 L 12.172712,15.00847 6.1879033,11.373143 a 1.2745823,1.2745823 0 0 0 -1.750927,0.427718 1.2745823,1.2745823 0 0 0 0.427536,1.751107 l 6.6464147,4.037178 a 1.2747098,1.2747098 0 0 0 0.661785,0.185206 z"
-     id="rect3554" />
-  <path
-     style="color:#000000;fill:#b3b3b3;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.172712,12.64005 a 1.2747098,1.2747098 0 0 0 0.661605,-0.185206 L 19.48091,8.4176679 A 1.2745823,1.2745823 0 0 0 19.908447,6.6665602 1.2745823,1.2745823 0 0 0 18.157519,6.2388432 L 12.172712,9.8741699 6.1879033,6.2388432 a 1.2745823,1.2745823 0 0 0 -1.750927,0.427717 1.2745823,1.2745823 0 0 0 0.427536,1.7511077 l 6.6464147,4.0371761 a 1.2747098,1.2747098 0 0 0 0.661785,0.185206 z"
-     id="path9314" />
-</svg>

+ 0 - 43
server/static/img/priority-4.svg

@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   height="24px"
-   viewBox="0 0 24 24"
-   width="24px"
-   fill="#000000"
-   version="1.1"
-   id="svg1428"
-   sodipodi:docname="priority_4_24dp.svg"
-   inkscape:version="1.1.1 (3bf5ae0, 2021-09-20)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <defs
-     id="defs1432" />
-  <sodipodi:namedview
-     id="namedview1430"
-     pagecolor="#505050"
-     bordercolor="#eeeeee"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="0"
-     showgrid="false"
-     inkscape:zoom="20.517358"
-     inkscape:cx="22.834324"
-     inkscape:cy="15.742768"
-     inkscape:window-width="1863"
-     inkscape:window-height="1025"
-     inkscape:window-x="57"
-     inkscape:window-y="27"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg1428" />
-  <path
-     style="color:#000000;fill:#c60000;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="M 12.116784,6.5394415 A 1.2747098,1.2747098 0 0 0 11.455179,6.724648 l -6.6465926,4.037176 a 1.2745823,1.2745823 0 0 0 -0.427537,1.751108 1.2745823,1.2745823 0 0 0 1.7509281,0.427717 l 5.9848065,-3.635327 5.984809,3.635327 A 1.2745823,1.2745823 0 0 0 19.85252,12.512932 1.2745823,1.2745823 0 0 0 19.424984,10.761824 L 12.778569,6.724648 A 1.2747098,1.2747098 0 0 0 12.116784,6.5394415 Z"
-     id="path9314" />
-  <path
-     style="color:#000000;fill:#de0000;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.195014,11.806679 a 1.2747098,1.2747098 0 0 0 -0.661606,0.185205 l -6.6465924,4.037177 a 1.2745823,1.2745823 0 0 0 -0.427537,1.751108 1.2745823,1.2745823 0 0 0 1.750928,0.427718 l 5.9848074,-3.635327 5.984807,3.635327 a 1.2745823,1.2745823 0 0 0 1.750928,-0.427718 1.2745823,1.2745823 0 0 0 -0.427537,-1.751108 l -6.646414,-4.037177 a 1.2747098,1.2747098 0 0 0 -0.661784,-0.185205 z"
-     id="path9316" />
-</svg>

+ 0 - 47
server/static/img/priority-5.svg

@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   height="24px"
-   viewBox="0 0 24 24"
-   width="24px"
-   fill="#000000"
-   version="1.1"
-   id="svg1428"
-   sodipodi:docname="priority_5_24dp.svg"
-   inkscape:version="1.1.1 (3bf5ae0, 2021-09-20)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <defs
-     id="defs1432" />
-  <sodipodi:namedview
-     id="namedview1430"
-     pagecolor="#505050"
-     bordercolor="#eeeeee"
-     borderopacity="1"
-     inkscape:pageshadow="0"
-     inkscape:pageopacity="0"
-     inkscape:pagecheckerboard="0"
-     showgrid="false"
-     inkscape:zoom="20.517358"
-     inkscape:cx="22.834323"
-     inkscape:cy="15.742767"
-     inkscape:window-width="1863"
-     inkscape:window-height="1025"
-     inkscape:window-x="57"
-     inkscape:window-y="27"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg1428" />
-  <path
-     style="color:#000000;fill:#aa0000;fill-opacity:1;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="M 12.116784,3.40514 A 1.2747098,1.2747098 0 0 0 11.455179,3.5903463 L 4.8085864,7.6275238 A 1.2745823,1.2745823 0 0 0 4.3810494,9.3786313 1.2745823,1.2745823 0 0 0 6.1319775,9.8063489 L 12.116784,6.1710217 18.101593,9.8063489 A 1.2745823,1.2745823 0 0 0 19.85252,9.3786313 1.2745823,1.2745823 0 0 0 19.424984,7.6275238 L 12.778569,3.5903463 A 1.2747098,1.2747098 0 0 0 12.116784,3.40514 Z"
-     id="rect3554" />
-  <path
-     style="color:#000000;fill:#c60000;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="M 12.116784,8.5394415 A 1.2747098,1.2747098 0 0 0 11.455179,8.724648 l -6.6465926,4.037176 a 1.2745823,1.2745823 0 0 0 -0.427537,1.751108 1.2745823,1.2745823 0 0 0 1.7509281,0.427717 l 5.9848065,-3.635327 5.984809,3.635327 A 1.2745823,1.2745823 0 0 0 19.85252,14.512932 1.2745823,1.2745823 0 0 0 19.424984,12.761824 L 12.778569,8.724648 A 1.2747098,1.2747098 0 0 0 12.116784,8.5394415 Z"
-     id="path9314" />
-  <path
-     style="color:#000000;fill:#de0000;fill-opacity:1;stroke:none;stroke-width:0.0919748;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
-     d="m 12.195014,13.806679 a 1.2747098,1.2747098 0 0 0 -0.661606,0.185205 l -6.6465924,4.037177 a 1.2745823,1.2745823 0 0 0 -0.427537,1.751108 1.2745823,1.2745823 0 0 0 1.750928,0.427718 l 5.9848074,-3.635327 5.984807,3.635327 a 1.2745823,1.2745823 0 0 0 1.750928,-0.427718 1.2745823,1.2745823 0 0 0 -0.427537,-1.751108 l -6.646414,-4.037177 a 1.2747098,1.2747098 0 0 0 -0.661784,-0.185205 z"
-     id="path9316" />
-</svg>

+ 0 - 1
server/static/img/send.svg

@@ -1 +0,0 @@
-<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>

+ 0 - 1
server/static/img/unsubscribe.svg

@@ -1 +0,0 @@
-<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>

+ 0 - 343
server/static/js/app.js

@@ -9,233 +9,14 @@
 
 /* All the things */
 
-let topics = {};
-let currentTopic = "";
-let currentTopicUnsubscribeOnClose = false;
 let currentUrl = window.location.hostname;
 if (window.location.port) {
     currentUrl += ':' + window.location.port
 }
 
-/* Main view */
-const main = document.getElementById("main");
-const topicsHeader = document.getElementById("topicsHeader");
-const topicsList = document.getElementById("topicsList");
-const topicField = document.getElementById("topicField");
-const notifySound = document.getElementById("notifySound");
-const subscribeButton = document.getElementById("subscribeButton");
-const errorField = document.getElementById("error");
-const originalTitle = document.title;
-
-/* Detail view */
-const detailView = document.getElementById("detail");
-const detailTitle = document.getElementById("detailTitle");
-const detailEventsList = document.getElementById("detailEventsList");
-const detailTopicUrl = document.getElementById("detailTopicUrl");
-const detailNoNotifications = document.getElementById("detailNoNotifications");
-const detailCloseButton = document.getElementById("detailCloseButton");
-const detailNotificationsDisallowed = document.getElementById("detailNotificationsDisallowed");
-
 /* Screenshots */
 const lightbox = document.getElementById("lightbox");
 
-const subscribe = (topic) => {
-    if (Notification.permission !== "granted") {
-        Notification.requestPermission().then((permission) => {
-            if (permission === "granted") {
-                subscribeInternal(topic, true, 0);
-            } else {
-                showNotificationDeniedError();
-            }
-        });
-    } else {
-        subscribeInternal(topic, true,0);
-    }
-};
-
-const subscribeInternal = (topic, persist, delaySec) => {
-    setTimeout(() => {
-        // Render list entry
-        let topicEntry = document.getElementById(`topic-${topic}`);
-        if (!topicEntry) {
-            topicEntry = document.createElement('li');
-            topicEntry.id = `topic-${topic}`;
-            topicEntry.innerHTML = `<a href="/${topic}" onclick="return showDetail('${topic}')">${topic}</a> <button onclick="test('${topic}'); return false;"> <img src="static/img/send.svg"> Test</button> <button onclick="unsubscribe('${topic}'); return false;"> <img src="static/img/unsubscribe.svg"> Unsubscribe</button>`;
-            topicsList.appendChild(topicEntry);
-        }
-        topicsHeader.style.display = '';
-
-        // Open event source
-        let eventSource = new EventSource(`${topic}/sse`);
-        eventSource.onopen = () => {
-            topicEntry.innerHTML = `<a href="/${topic}" onclick="return showDetail('${topic}')">${topic}</a> <button onclick="test('${topic}'); return false;"> <img src="static/img/send.svg"> Test</button> <button onclick="unsubscribe('${topic}'); return false;"> <img src="static/img/unsubscribe.svg"> Unsubscribe</button>`;
-            delaySec = 0; // Reset on successful connection
-        };
-        eventSource.onerror = (e) => {
-            topicEntry.innerHTML = `<a href="/${topic}" onclick="return showDetail('${topic}')">${topic}</a> <i>(Reconnecting)</i> <button disabled="disabled">Test</button> <button onclick="unsubscribe('${topic}'); return false;">Unsubscribe</button>`;
-            eventSource.close();
-            const newDelaySec = (delaySec + 5 <= 15) ? delaySec + 5 : 15;
-            subscribeInternal(topic, persist, newDelaySec);
-        };
-        eventSource.onmessage = (e) => {
-            const event = JSON.parse(e.data);
-            topics[topic]['messages'].push(event);
-            topics[topic]['messages'].sort((a, b) => { return a.time < b.time ? 1 : -1; }); // Newest first
-            if (currentTopic === topic) {
-                rerenderDetailView();
-            }
-            if (Notification.permission === "granted") {
-                notifySound.play();
-                const title = formatTitle(event);
-                const message = formatMessage(event);
-                const notification = new Notification(title, {
-                    body: message,
-                    icon: '/static/img/favicon.png'
-                });
-                notification.onclick = (e) => {
-                    showDetail(event.topic);
-                };
-            }
-        };
-        topics[topic] = {
-            'eventSource': eventSource,
-            'messages': [],
-            'persist': persist
-        };
-        fetchCachedMessages(topic).then(() => {
-            if (currentTopic === topic) {
-                rerenderDetailView();
-            }
-        })
-        let persistedTopicKeys = Object.keys(topics).filter(t => topics[t].persist);
-        localStorage.setItem('topics', JSON.stringify(persistedTopicKeys));
-    }, delaySec * 1000);
-};
-
-const unsubscribe = (topic) => {
-    topics[topic]['eventSource'].close();
-    delete topics[topic];
-    localStorage.setItem('topics', JSON.stringify(Object.keys(topics)));
-    document.getElementById(`topic-${topic}`).remove();
-    if (Object.keys(topics).length === 0) {
-        topicsHeader.style.display = 'none';
-    }
-};
-
-const test = (topic) => {
-    fetch(`/${topic}`, {
-        method: 'PUT',
-        body: `This is a test notification sent by the ntfy.sh Web UI at ${new Date().toString()}.`
-    });
-};
-
-const fetchCachedMessages = async (topic) => {
-    const topicJsonUrl = `/${topic}/json?poll=1`; // Poll!
-    for await (let line of makeTextFileLineIterator(topicJsonUrl)) {
-        const message = JSON.parse(line);
-        topics[topic]['messages'].push(message);
-    }
-    topics[topic]['messages'].sort((a, b) => { return a.time < b.time ? 1 : -1; }); // Newest first
-};
-
-const showDetail = (topic) => {
-    currentTopic = topic;
-    history.replaceState(topic, `${currentUrl}/${topic}`, `/${topic}`);
-    window.scrollTo(0, 0);
-    rerenderDetailView();
-    return false;
-};
-
-const rerenderDetailView = () => {
-    detailTitle.innerHTML = `${currentUrl}/${currentTopic}`; // document.location.replaceAll(..)
-    detailTopicUrl.innerHTML = `${currentUrl}/${currentTopic}`;
-    while (detailEventsList.firstChild) {
-        detailEventsList.removeChild(detailEventsList.firstChild);
-    }
-    topics[currentTopic]['messages'].forEach(m => {
-        const entryDiv = document.createElement('div');
-        const dateDiv = document.createElement('div');
-        const titleDiv = document.createElement('div');
-        const messageDiv = document.createElement('div');
-        const tagsDiv = document.createElement('div');
-
-        entryDiv.classList.add('detailEntry');
-        dateDiv.classList.add('detailDate');
-        titleDiv.classList.add('detailTitle');
-        messageDiv.classList.add('detailMessage');
-        tagsDiv.classList.add('detailTags');
-
-        const dateStr = new Date(m.time * 1000).toLocaleString();
-        if (m.priority && [1,2,4,5].includes(m.priority)) {
-            dateDiv.innerHTML = `${dateStr} <img src="static/img/priority-${m.priority}.svg"/>`;
-        } else {
-            dateDiv.innerHTML = `${dateStr}`;
-        }
-        messageDiv.innerText = formatMessage(m);
-        entryDiv.appendChild(dateDiv);
-        if (m.title) {
-            titleDiv.innerText = formatTitleA(m);
-            entryDiv.appendChild(titleDiv);
-        }
-        entryDiv.appendChild(messageDiv);
-        const otherTags = unmatchedTags(m.tags);
-        if (otherTags.length > 0) {
-            tagsDiv.innerText = `Tags: ${otherTags.join(", ")}`;
-            entryDiv.appendChild(tagsDiv);
-        }
-        detailEventsList.appendChild(entryDiv);
-    })
-    if (topics[currentTopic]['messages'].length === 0) {
-        detailNoNotifications.style.display = '';
-    } else {
-        detailNoNotifications.style.display = 'none';
-    }
-    if (Notification.permission === "granted") {
-        detailNotificationsDisallowed.style.display = 'none';
-    } else {
-        detailNotificationsDisallowed.style.display = 'block';
-    }
-    detailView.style.display = 'block';
-    main.style.display = 'none';
-};
-
-const hideDetailView = () => {
-    if (currentTopicUnsubscribeOnClose) {
-        unsubscribe(currentTopic);
-        currentTopicUnsubscribeOnClose = false;
-    }
-    currentTopic = "";
-    history.replaceState('', originalTitle, '/');
-    detailView.style.display = 'none';
-    main.style.display = 'block';
-    return false;
-};
-
-const requestPermission = () => {
-    if (Notification.permission !== "granted") {
-        Notification.requestPermission().then((permission) => {
-            if (permission === "granted") {
-                detailNotificationsDisallowed.style.display = 'none';
-            }
-        });
-    }
-    return false;
-};
-
-const showError = (msg) => {
-    errorField.innerHTML = msg;
-    topicField.disabled = true;
-    subscribeButton.disabled = true;
-};
-
-const showBrowserIncompatibleError = () => {
-    showError("Your browser is not compatible to use the web-based desktop notifications.");
-};
-
-const showNotificationDeniedError = () => {
-    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);
@@ -284,91 +65,6 @@ const nextScreenshotKeyboardListener = (e) => {
     }
 };
 
-const formatTitle = (m) => {
-    if (m.title) {
-        return formatTitleA(m);
-    } else {
-        return `${location.host}/${m.topic}`; // FIXME
-    }
-};
-
-const formatTitleA = (m) => {
-    const emojiList = toEmojis(m.tags);
-    if (emojiList.length > 0) {
-        return `${emojiList.join(" ")} ${m.title}`;
-    } else {
-        return m.title;
-    }
-};
-
-const formatMessage = (m) => {
-    if (m.title) {
-        return m.message;
-    } else {
-        const emojiList = toEmojis(m.tags);
-        if (emojiList.length > 0) {
-            return `${emojiList.join(" ")} ${m.message}`;
-        } else {
-            return m.message;
-        }
-    }
-};
-
-const toEmojis = (tags) => {
-    if (!tags) return [];
-    else return tags.filter(tag => tag in emojis).map(tag => emojis[tag]);
-}
-
-const unmatchedTags = (tags) => {
-    if (!tags) return [];
-    else return tags.filter(tag => !(tag in emojis));
-}
-
-// From: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
-async function* makeTextFileLineIterator(fileURL) {
-    const utf8Decoder = new TextDecoder('utf-8');
-    const response = await fetch(fileURL);
-    const reader = response.body.getReader();
-    let { value: chunk, done: readerDone } = await reader.read();
-    chunk = chunk ? utf8Decoder.decode(chunk) : '';
-
-    const re = /\n|\r|\r\n/gm;
-    let startIndex = 0;
-    let result;
-
-    for (;;) {
-        let result = re.exec(chunk);
-        if (!result) {
-            if (readerDone) {
-                break;
-            }
-            let remainder = chunk.substr(startIndex);
-            ({ value: chunk, done: readerDone } = await reader.read());
-            chunk = remainder + (chunk ? utf8Decoder.decode(chunk) : '');
-            startIndex = re.lastIndex = 0;
-            continue;
-        }
-        yield chunk.substring(startIndex, result.index);
-        startIndex = re.lastIndex;
-    }
-    if (startIndex < chunk.length) {
-        yield chunk.substr(startIndex); // last line didn't end in a newline char
-    }
-}
-
-subscribeButton.onclick = () => {
-    if (!topicField.value) {
-        return false;
-    }
-    subscribe(topicField.value);
-    topicField.value = "";
-    return false;
-};
-
-detailCloseButton.onclick = () => {
-    hideDetailView();
-};
-
 let currentScreenshotIndex = 0;
 const screenshots = [...document.querySelectorAll("#screenshots a")];
 screenshots.forEach((el, index) => {
@@ -377,37 +73,6 @@ screenshots.forEach((el, index) => {
 
 lightbox.onclick = hideScreenshotOverlay;
 
-// Disable Web UI if notifications of EventSource are not available
-if (!window["Notification"] || !window["EventSource"]) {
-    showBrowserIncompatibleError();
-} else if (Notification.permission === "denied") {
-    showNotificationDeniedError();
-}
-
-// Reset UI
-topicField.value = "";
-
-// Restore topics
-const storedTopics = JSON.parse(localStorage.getItem('topics') || "[]");
-if (storedTopics) {
-    storedTopics.forEach((topic) => { subscribeInternal(topic, true, 0); });
-    if (storedTopics.length === 0) {
-        topicsHeader.style.display = 'none';
-    }
-} else {
-    topicsHeader.style.display = 'none';
-}
-
-// (Temporarily) subscribe topic if we navigated to /sometopic URL
-const match = location.pathname.match(/^\/([-_a-zA-Z0-9]{1,64})$/) // Regex must match Go & Android app!
-if (match) {
-    currentTopic = match[1];
-    if (!storedTopics.includes(currentTopic)) {
-        subscribeInternal(currentTopic, false,0);
-        currentTopicUnsubscribeOnClose = true;
-    }
-}
-
 // Add anchor links
 document.querySelectorAll('.anchor').forEach((el) => {
     if (el.hasAttribute('id')) {
@@ -425,11 +90,3 @@ document.querySelectorAll('.ntfyUrl').forEach((el) => {
 document.querySelectorAll('.ntfyProtocol').forEach((el) => {
     el.innerHTML = window.location.protocol + "//";
 });
-
-// Format emojis (see emoji.js)
-const emojis = {};
-rawEmojis.forEach(emoji => {
-    emoji.aliases.forEach(alias => {
-        emojis[alias] = emoji.emoji;
-    });
-});

Разница между файлами не показана из-за своего большого размера
+ 0 - 2
server/static/js/emoji.js


BIN
server/static/sound/mixkit-message-pop-alert-2354.mp3


Некоторые файлы не были показаны из-за большого количества измененных файлов