Browse Source

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
pull/1106/head
gingervitis 4 years ago committed by GitHub
parent
commit
c45e43c378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      webroot/js/app-video-only.js
  2. 35
      webroot/js/app.js
  3. 3
      webroot/js/components/chat/chat-message-view.js
  4. 23
      webroot/js/utils/helpers.js
  5. 11
      webroot/styles/app.css
  6. 5
      webroot/styles/video-only.css

25
webroot/js/app-video-only.js

@ -12,7 +12,7 @@ import { OwncastPlayer } from './components/player.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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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>
`;

35
webroot/js/app.js

@ -8,11 +8,6 @@ import UsernameForm from './components/chat/username.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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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>

3
webroot/js/components/chat/chat-message-view.js

@ -9,6 +9,7 @@ import { @@ -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) { @@ -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', {

23
webroot/js/utils/helpers.js

@ -156,3 +156,26 @@ export function debounce(fn, time) { @@ -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}`;
}

11
webroot/styles/app.css

@ -78,17 +78,6 @@ header { @@ -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;

5
webroot/styles/video-only.css

@ -24,8 +24,3 @@ The styles in this file mostly ovveride those coming from chat.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;
}

Loading…
Cancel
Save