display last online time (#1125)

* - if offline calculate and display last online time to address https://github.com/owncast/owncast/issues/1111
- clean up status bar styles

* clean up console
This commit is contained in:
gingervitis 2021-06-20 10:49:16 -07:00 committed by GitHub
parent d19ecab90c
commit c45e43c378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 44 deletions

View File

@ -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 {
<section
id="stream-info"
aria-label="Stream status"
class="flex text-center flex-row justify-between font-mono py-2 px-8 bg-gray-900 text-indigo-200 shadow-md border-b border-gray-100 border-solid"
class="flex flex-row justify-between font-mono py-2 px-4 bg-gray-900 text-indigo-200 shadow-md border-b border-gray-100 border-solid"
>
<span>${streamStatusMessage}</span>
<span id="stream-viewer-count">${viewerCountMessage}</span>
<span class="text-xs">${streamStatusMessage}</span>
<span id="stream-viewer-count" class="text-xs text-right">${viewerCountMessage}</span>
</section>
</main>
`;

View File

@ -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 {
<section
id="stream-info"
aria-label="Stream status"
class="flex text-center flex-row justify-between font-mono py-2 px-8 bg-gray-900 text-indigo-200 shadow-md border-b border-gray-100 border-solid"
class="flex text-center flex-row justify-between font-mono py-2 px-4 bg-gray-900 text-indigo-200 shadow-md border-b border-gray-100 border-solid"
>
<span>${streamStatusMessage}</span>
<span id="stream-viewer-count">${viewerCountMessage}</span>
<span class="text-xs">${streamStatusMessage}</span>
<span id="stream-viewer-count" class="text-xs text-right">${viewerCountMessage}</span>
</section>
</main>

View File

@ -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', {

View File

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

View File

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

View File

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