diff --git a/webroot/js/app-video-only.js b/webroot/js/app-video-only.js
index 0d79016c2..a9845ccae 100644
--- a/webroot/js/app-video-only.js
+++ b/webroot/js/app-video-only.js
@@ -12,7 +12,7 @@ import { OwncastPlayer } from './components/player.js';
import Websocket from './utils/websocket.js';
const websocket = new Websocket();
-import { addNewlines, pluralize } from './utils/helpers.js';
+import { addNewlines, makeLastOnlineString, pluralize } from './utils/helpers.js';
import {
URL_CONFIG,
URL_STATUS,
@@ -38,6 +38,7 @@ export default class VideoOnly extends Component {
//status
streamStatusMessage: MESSAGE_OFFLINE,
viewerCount: '',
+ lastDisconnectTime: null,
};
// timers
@@ -134,9 +135,7 @@ export default class VideoOnly extends Component {
if (!status) {
return;
}
- const { viewerCount, online } = status;
-
- this.lastDisconnectTime = status.lastDisconnectTime;
+ const { viewerCount, online, lastDisconnectTime } = status;
if (status.online && !curStreamOnline) {
// stream has just come online.
@@ -148,6 +147,7 @@ export default class VideoOnly extends Component {
this.setState({
viewerCount,
streamOnline: online,
+ lastDisconnectTime,
});
}
@@ -215,15 +215,18 @@ export default class VideoOnly extends Component {
playerActive,
streamOnline,
streamStatusMessage,
+ lastDisconnectTime,
isPlaying,
} = state;
const { logo = TEMP_IMAGE, customStyles } = configData;
- const viewerCountMessage =
- streamOnline && viewerCount > 0
- ? html`${viewerCount} ${pluralize('viewer', viewerCount)}`
- : null;
+ let viewerCountMessage = '';
+ if (streamOnline && viewerCount > 0) {
+ viewerCountMessage = html`${viewerCount} ${pluralize('viewer', viewerCount)}`;
+ } else if (lastDisconnectTime) {
+ viewerCountMessage = makeLastOnlineString(lastDisconnectTime);
+ }
const mainClass = playerActive ? 'online' : '';
@@ -252,10 +255,10 @@ export default class VideoOnly extends Component {
- ${streamStatusMessage}
- ${viewerCountMessage}
+ ${streamStatusMessage}
+ ${viewerCountMessage}
`;
diff --git a/webroot/js/app.js b/webroot/js/app.js
index 598a68032..8428672c3 100644
--- a/webroot/js/app.js
+++ b/webroot/js/app.js
@@ -8,11 +8,6 @@ import UsernameForm from './components/chat/username.js';
import VideoPoster from './components/video-poster.js';
import Chat from './components/chat/chat.js';
import Websocket from './utils/websocket.js';
-import {
- parseSecondsToDurationString,
- hasTouchScreen,
- getOrientation,
-} from './utils/helpers.js';
import ExternalActionModal, {
ExternalActionButton,
} from './components/external-action-modal.js';
@@ -24,6 +19,10 @@ import {
debounce,
generateUsername,
getLocalStorage,
+ getOrientation,
+ hasTouchScreen,
+ makeLastOnlineString,
+ parseSecondsToDurationString,
pluralize,
setLocalStorage,
} from './utils/helpers.js';
@@ -72,6 +71,7 @@ export default class App extends Component {
// status
streamStatusMessage: MESSAGE_OFFLINE,
viewerCount: '',
+ lastDisconnectTime: null,
// dom
windowWidth: window.innerWidth,
@@ -208,9 +208,7 @@ export default class App extends Component {
if (!status) {
return;
}
- const { viewerCount, online, lastConnectTime, streamTitle } = status;
-
- this.lastDisconnectTime = status.lastDisconnectTime;
+ const { viewerCount, online, lastConnectTime, streamTitle, lastDisconnectTime } = status;
if (status.online && !curStreamOnline) {
// stream has just come online.
@@ -225,6 +223,7 @@ export default class App extends Component {
lastConnectTime,
streamOnline: online,
streamTitle,
+ lastDisconnectTime,
});
}
@@ -260,7 +259,7 @@ export default class App extends Component {
clearInterval(this.streamDurationTimer);
const remainingChatTime =
TIMER_DISABLE_CHAT_AFTER_OFFLINE -
- (Date.now() - new Date(this.lastDisconnectTime));
+ (Date.now() - new Date(this.state.lastDisconnectTime));
const countdown = remainingChatTime < 0 ? 0 : remainingChatTime;
this.disableChatTimer = setTimeout(this.disableChatInput, countdown);
this.setState({
@@ -501,6 +500,7 @@ export default class App extends Component {
windowHeight,
windowWidth,
externalAction,
+ lastDisconnectTime,
} = state;
const {
@@ -520,10 +520,13 @@ export default class App extends Component {
const tagList = tags !== null && tags.length > 0 && tags.join(' #');
- const viewerCountMessage =
- streamOnline && viewerCount > 0
- ? html`${viewerCount} ${pluralize('viewer', viewerCount)}`
- : null;
+ let viewerCountMessage = '';
+ if (streamOnline && viewerCount > 0) {
+ viewerCountMessage = html`${viewerCount} ${pluralize('viewer', viewerCount)}`;
+ } else if (lastDisconnectTime) {
+ viewerCountMessage = makeLastOnlineString(lastDisconnectTime);
+ }
+
const mainClass = playerActive ? 'online' : '';
const isPortrait =
@@ -647,10 +650,10 @@ export default class App extends Component {
- ${streamStatusMessage}
- ${viewerCountMessage}
+ ${streamStatusMessage}
+ ${viewerCountMessage}
diff --git a/webroot/js/components/chat/chat-message-view.js b/webroot/js/components/chat/chat-message-view.js
index 8d4d03866..2a3d1e1b1 100644
--- a/webroot/js/components/chat/chat-message-view.js
+++ b/webroot/js/components/chat/chat-message-view.js
@@ -9,6 +9,7 @@ import {
} from '../../utils/user-colors.js';
import { convertToText } from '../../utils/chat.js';
import { SOCKET_MESSAGE_TYPES } from '../../utils/websocket.js';
+import { getDiffInDaysFromNow } from '../../utils/helpers.js';
export default class ChatMessageView extends Component {
constructor(props) {
@@ -155,7 +156,7 @@ function formatTimestamp(sentAt) {
return '';
}
- let diffInDays = (new Date() - sentAt) / (24 * 3600 * 1000);
+ let diffInDays = getDiffInDaysFromNow(sentAt); //(new Date() - sentAt) / (24 * 3600 * 1000);
if (diffInDays >= 1) {
return (
`Sent at ${sentAt.toLocaleDateString('en-US', {
diff --git a/webroot/js/utils/helpers.js b/webroot/js/utils/helpers.js
index aab4f856c..d732bba45 100644
--- a/webroot/js/utils/helpers.js
+++ b/webroot/js/utils/helpers.js
@@ -156,3 +156,26 @@ export function debounce(fn, time) {
timeout = setTimeout(functionCall, time);
}
}
+
+
+export function getDiffInDaysFromNow(timestamp) {
+ const time = typeof timestamp === 'string' ? new Date(timestamp) : timestamp;
+ return (new Date() - time) / (24 * 3600 * 1000);
+}
+
+// "Last live today at [time]" or "last live [date]"
+export function makeLastOnlineString(timestamp) {
+ if (!timestamp) {
+ return '';
+ }
+ let string = '';
+ const time = new Date(timestamp);
+ let diffInDays = getDiffInDaysFromNow(time);
+ if (diffInDays > 1) {
+ string = time.toLocaleDateString();
+ } else {
+ const atTime = time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
+ string = `Today ${atTime}`;
+ }
+ return `Last live: ${string}`;
+}
diff --git a/webroot/styles/app.css b/webroot/styles/app.css
index da23aea91..fbd8b08f6 100644
--- a/webroot/styles/app.css
+++ b/webroot/styles/app.css
@@ -78,17 +78,6 @@ header {
display: none;
}
-
-#stream-info span {
- font-size: .70rem;
-}
-#stream-viewer-count {
- display: none;
-}
-.online #stream-viewer-count {
- display: inline;
-}
-
#external-actions-container {
margin: 1em 0;
diff --git a/webroot/styles/video-only.css b/webroot/styles/video-only.css
index 64741cb90..5ccf8e453 100644
--- a/webroot/styles/video-only.css
+++ b/webroot/styles/video-only.css
@@ -24,8 +24,3 @@ The styles in this file mostly ovveride those coming from chat.css
opacity: 1;
pointer-events: auto;
}
-
-
-#video-only #stream-info {
- height: 3rem;
-}