diff --git a/grip/app.py b/grip/app.py index 123d00f..6bfe8bc 100644 --- a/grip/app.py +++ b/grip/app.py @@ -229,6 +229,7 @@ def _render_refresh(self, subpath=None): def gen(): last_updated = self.reader.last_updated(subpath) + yield ': started\r\n\r\n' try: while not shutdown_event.is_set(): time.sleep(0.3) diff --git a/grip/templates/index.html b/grip/templates/index.html index 10970f0..f0eb7e7 100644 --- a/grip/templates/index.html +++ b/grip/templates/index.html @@ -20,11 +20,52 @@ margin-top: 64px; margin-bottom: 21px; } + #grip-readme-header { + position: relative; + top: -1em; + color: #666; + } + #grip-status-indicator.grip-floating-indicator { + margin: calc(0.5em + 15px); + color: #666; + } + #grip-status-indicator { + float: right; + text-transform: uppercase; + cursor: default; + -webkit-user-select: none; + user-select: none; + font-weight: bold; + --yellow: #FFDC00; + --red: #FF4136; + --green: #2ECC40; + } + #grip-status-indicator::after { + content: ""; + display: inline-block; + width: 0.85em; + height: 0.85em; + background: var(--color); + border-radius: 50%; + vertical-align: middle; + position: relative; + bottom: 1.5px; + margin-left: 0.5em; + } + #grip-status-indicator + #grip-content > :first-child { + margin-top: 0; + } /* User-content tweaks */ + .timeline-comment-wrapper { + padding-left: 0; + } .timeline-comment-wrapper > .timeline-comment:after, .timeline-comment-wrapper > .timeline-comment:before { content: none; } + .discussion-timeline { + float: none; + } /* User-content overrides */ .discussion-timeline.wide { width: 920px; @@ -62,13 +103,27 @@ var source = new EventSource(eventSourceUrl); var isRendering = false; + var statusElement = document.getElementById('grip-status-indicator'); + statusElement.hidden = false; + statusElement.textContent = 'Connecting'; + statusElement.style.setProperty('--color', 'var(--yellow)'); + + source.onopen = function() { + statusElement.textContent = 'Connected'; + statusElement.style.setProperty('--color', 'var(--green)'); + } + source.onmessage = function(ev) { var msg = JSON.parse(ev.data); if (msg.updating) { isRendering = true; + statusElement.textContent = 'Updating'; + statusElement.style.setProperty('--color', 'var(--yellow)'); document.title = '(Rendering) ' + document.title; } else { isRendering = false; + statusElement.textContent = 'Connected'; + statusElement.style.setProperty('--color', 'var(--green)'); document.title = initialTitle; contentElement.innerHTML = msg.content; showCanonicalImages(); @@ -76,10 +131,12 @@ } source.onerror = function(e) { - if (e.readyState === EventSource.CLOSED && isRendering) { + if (isRendering) { isRendering = false; document.title = initialTitle; } + statusElement.textContent = 'Disconnected'; + statusElement.style.setProperty('--color', 'var(--red)'); } } @@ -108,20 +165,18 @@ {% if not user_content %} -
{{ title }} + Connecting