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; -}