Status Message overhaul
This commit is contained in:
parent
ebf5b3f47e
commit
27380ec558
|
@ -122,6 +122,14 @@ img {
|
||||||
bottom: 4px;
|
bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* User status indicator in the lower left corner of DMs */
|
||||||
|
.user-status-dm-field {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 38; /* below auto-scroll checkbox */
|
||||||
|
left: 12px;
|
||||||
|
bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Footer row: message entry box */
|
/* Footer row: message entry box */
|
||||||
.chat-container > .chat-footer {
|
.chat-container > .chat-footer {
|
||||||
grid-column: 1 / 4;
|
grid-column: 1 / 4;
|
||||||
|
|
115
src/App.vue
115
src/App.vue
|
@ -16,6 +16,7 @@ import ProfileModal from './components/ProfileModal.vue';
|
||||||
import ChatClient from './lib/ChatClient';
|
import ChatClient from './lib/ChatClient';
|
||||||
import LocalStorage from './lib/LocalStorage';
|
import LocalStorage from './lib/LocalStorage';
|
||||||
import VideoFlag from './lib/VideoFlag';
|
import VideoFlag from './lib/VideoFlag';
|
||||||
|
import StatusMessage from './lib/StatusMessage';
|
||||||
import { SoundEffects, DefaultSounds } from './lib/sounds';
|
import { SoundEffects, DefaultSounds } from './lib/sounds';
|
||||||
import { isAppleWebkit } from './lib/browsers';
|
import { isAppleWebkit } from './lib/browsers';
|
||||||
|
|
||||||
|
@ -121,6 +122,7 @@ export default {
|
||||||
messageBox: null, // HTML element for message entry box
|
messageBox: null, // HTML element for message entry box
|
||||||
typingNotifDebounce: null,
|
typingNotifDebounce: null,
|
||||||
status: "online", // away/idle status
|
status: "online", // away/idle status
|
||||||
|
StatusMessage: StatusMessage,
|
||||||
|
|
||||||
// Emoji picker visible for messages
|
// Emoji picker visible for messages
|
||||||
showEmojiPicker: false,
|
showEmojiPicker: false,
|
||||||
|
@ -317,6 +319,15 @@ export default {
|
||||||
this.setupIdleDetection();
|
this.setupIdleDetection();
|
||||||
this.setupDropZone(); // file upload drag/drop
|
this.setupDropZone(); // file upload drag/drop
|
||||||
|
|
||||||
|
// Configure the StatusMessage controller.
|
||||||
|
StatusMessage.nsfw = this.config.permitNSFW;
|
||||||
|
StatusMessage.currentStatus = () => {
|
||||||
|
return this.status;
|
||||||
|
};
|
||||||
|
StatusMessage.isAdmin = () => {
|
||||||
|
return this.isOp;
|
||||||
|
};
|
||||||
|
|
||||||
this.webcam.elem = document.querySelector("#localVideo");
|
this.webcam.elem = document.querySelector("#localVideo");
|
||||||
this.historyScrollbox = document.querySelector("#chatHistory");
|
this.historyScrollbox = document.querySelector("#chatHistory");
|
||||||
|
|
||||||
|
@ -545,6 +556,27 @@ export default {
|
||||||
// Is the current channel a DM?
|
// Is the current channel a DM?
|
||||||
return this.channel.indexOf("@") === 0;
|
return this.channel.indexOf("@") === 0;
|
||||||
},
|
},
|
||||||
|
chatPartnerStatusMessage() {
|
||||||
|
// In a DM thread, returns your chat partner's status message.
|
||||||
|
if (!this.isDM) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let username = this.normalizeUsername(this.channel),
|
||||||
|
user = this.whoMap[username];
|
||||||
|
if (user == undefined || this.isUserOffline(username)) {
|
||||||
|
return this.StatusMessage.offline();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.StatusMessage.getStatus(user.status);
|
||||||
|
},
|
||||||
|
isChatPartnerAway() {
|
||||||
|
// In a DM thread, returns if your chat partner's status is anything
|
||||||
|
// other than "online".
|
||||||
|
if (!this.isDM) return false;
|
||||||
|
let status = this.chatPartnerStatusMessage;
|
||||||
|
return status === null || status.name !== "online";
|
||||||
|
},
|
||||||
canUploadFile() {
|
canUploadFile() {
|
||||||
// Public channels: OK
|
// Public channels: OK
|
||||||
if (!this.channel.indexOf('@') === 0) {
|
if (!this.channel.indexOf('@') === 0) {
|
||||||
|
@ -3948,6 +3980,15 @@ export default {
|
||||||
'p-1 pb-5': messageStyle.indexOf('compact') === 0
|
'p-1 pb-5': messageStyle.indexOf('compact') === 0
|
||||||
}">
|
}">
|
||||||
|
|
||||||
|
<!-- Show your chat partner's status message in DMs -->
|
||||||
|
<div class="user-status-dm-field tag is-info" v-if="isChatPartnerAway">
|
||||||
|
<strong class="mr-2 has-text-light">Status:</strong>
|
||||||
|
<span v-if="chatPartnerStatusMessage">
|
||||||
|
{{ chatPartnerStatusMessage.emoji }} {{ chatPartnerStatusMessage.label }}
|
||||||
|
</span>
|
||||||
|
<em v-else>undefined</em>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="autoscroll-field tag">
|
<div class="autoscroll-field tag">
|
||||||
<label class="checkbox is-size-6" title="Automatically scroll when new chat messages come in.">
|
<label class="checkbox is-size-6" title="Automatically scroll when new chat messages come in.">
|
||||||
<input type="checkbox" v-model="autoscroll" :value="true">
|
<input type="checkbox" v-model="autoscroll" :value="true">
|
||||||
|
@ -4016,8 +4057,7 @@ export default {
|
||||||
<div v-if="isDM && isMutedUser(channel)" class="has-text-danger">
|
<div v-if="isDM && isMutedUser(channel)" class="has-text-danger">
|
||||||
<i class="fa fa-comment-slash"></i>
|
<i class="fa fa-comment-slash"></i>
|
||||||
<strong>{{ channel }}</strong> is currently <strong>muted</strong> so you have not been seeing their
|
<strong>{{ channel }}</strong> is currently <strong>muted</strong> so you have not been seeing their
|
||||||
recent
|
recent chat messages or DMs.
|
||||||
chat messages or DMs.
|
|
||||||
<a href="#" v-on:click.prevent="muteUser(channel)">Unmute them?</a>
|
<a href="#" v-on:click.prevent="muteUser(channel)">Unmute them?</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -4121,25 +4161,15 @@ export default {
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="select is-small is-fullwidth">
|
<div class="select is-small is-fullwidth">
|
||||||
<select v-model="status">
|
<select v-model="status">
|
||||||
<optgroup label="Status">
|
<optgroup v-for="group in StatusMessage.iterSelectOptGroups()"
|
||||||
<option value="online">☀️ Active</option>
|
v-bind:key="group.category"
|
||||||
<option value="away">🕒 Away</option>
|
:label="group.category">
|
||||||
<option value="brb">⏰ Be right back</option>
|
<option v-for="item in StatusMessage.iterSelectOptions(group.category)"
|
||||||
<option value="lunch">🍴 Out to lunch</option>
|
v-bind:key="item.name"
|
||||||
<option value="call">📞 On the phone</option>
|
:value="item.name">
|
||||||
<option value="busy">💼 Working</option>
|
{{ item.emoji }} {{ item.label }}
|
||||||
<option value="book">📖 Studying</option>
|
|
||||||
<option value="gaming">🎮 Gaming</option>
|
|
||||||
<option value="idle" v-show="status === 'idle'">🕒 Idle</option>
|
|
||||||
<option value="hidden" v-if="jwt.claims != undefined && jwt.claims.op">🕵️ Hidden
|
|
||||||
</option>
|
</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Mood">
|
|
||||||
<option value="chatty">🗨️ Chatty and sociable</option>
|
|
||||||
<option value="introverted">🥄 Introverted and quiet</option>
|
|
||||||
<option value="horny" v-if="config.permitNSFW">🔥 Horny</option>
|
|
||||||
<option value="exhibitionist" v-if="config.permitNSFW">👀 Watch me</option>
|
|
||||||
</optgroup>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4185,23 +4215,48 @@ export default {
|
||||||
<!-- Who Is Online -->
|
<!-- Who Is Online -->
|
||||||
<ul class="menu-list" v-if="whoTab === 'online'">
|
<ul class="menu-list" v-if="whoTab === 'online'">
|
||||||
<li v-for="(u, i) in sortedWhoList" v-bind:key="i">
|
<li v-for="(u, i) in sortedWhoList" v-bind:key="i">
|
||||||
<WhoListRow :user="u" :username="username" :website-url="config.website"
|
<WhoListRow
|
||||||
:is-dnd="isUsernameDND(u.username)" :is-muted="isMutedUser(u.username)"
|
:user="u"
|
||||||
:is-booted="isBooted(u.username)" :is-op="isOp" :is-video-not-allowed="isVideoNotAllowed(u)"
|
:username="username"
|
||||||
:video-icon-class="webcamIconClass(u)" :vip-config="config.VIP" @send-dm="openDMs"
|
:website-url="config.website"
|
||||||
@mute-user="muteUser" @open-video="openVideo" @open-profile="showProfileModal"></WhoListRow>
|
:is-dnd="isUsernameDND(u.username)"
|
||||||
|
:is-muted="isMutedUser(u.username)"
|
||||||
|
:is-booted="isBooted(u.username)"
|
||||||
|
:is-op="isOp"
|
||||||
|
:is-video-not-allowed="isVideoNotAllowed(u)"
|
||||||
|
:video-icon-class="webcamIconClass(u)"
|
||||||
|
:vip-config="config.VIP"
|
||||||
|
:status-message="StatusMessage"
|
||||||
|
@send-dm="openDMs"
|
||||||
|
@mute-user="muteUser"
|
||||||
|
@open-video="openVideo"
|
||||||
|
@open-profile="showProfileModal">
|
||||||
|
</WhoListRow>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Watching My Webcam -->
|
<!-- Watching My Webcam -->
|
||||||
<ul class="menu-list" v-if="whoTab === 'watching'">
|
<ul class="menu-list" v-if="whoTab === 'watching'">
|
||||||
<li v-for="(u, i) in sortedWatchingList" v-bind:key="username">
|
<li v-for="(u, i) in sortedWatchingList" v-bind:key="username">
|
||||||
<WhoListRow :is-watching-tab="true" :user="u" :username="username" :website-url="config.website"
|
<WhoListRow
|
||||||
:is-dnd="isUsernameDND(username)" :is-muted="isMutedUser(username)"
|
:is-watching-tab="true"
|
||||||
:is-booted="isBooted(u.username)" :is-op="isOp" :is-video-not-allowed="isVideoNotAllowed(u)"
|
:user="u"
|
||||||
:video-icon-class="webcamIconClass(u)" :vip-config="config.VIP" @send-dm="openDMs"
|
:username="username"
|
||||||
@mute-user="muteUser" @open-video="openVideo" @boot-user="bootUser"
|
:website-url="config.website"
|
||||||
@open-profile="showProfileModal"></WhoListRow>
|
:is-dnd="isUsernameDND(username)"
|
||||||
|
:is-muted="isMutedUser(username)"
|
||||||
|
:is-booted="isBooted(u.username)"
|
||||||
|
:is-op="isOp"
|
||||||
|
:is-video-not-allowed="isVideoNotAllowed(u)"
|
||||||
|
:video-icon-class="webcamIconClass(u)"
|
||||||
|
:vip-config="config.VIP"
|
||||||
|
:status-message="StatusMessage"
|
||||||
|
@send-dm="openDMs"
|
||||||
|
@mute-user="muteUser"
|
||||||
|
@open-video="openVideo"
|
||||||
|
@boot-user="bootUser"
|
||||||
|
@open-profile="showProfileModal">
|
||||||
|
</WhoListRow>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ export default {
|
||||||
isVideoNotAllowed: Boolean, // whether opening this camera is not allowed
|
isVideoNotAllowed: Boolean, // whether opening this camera is not allowed
|
||||||
videoIconClass: String, // CSS class for the open video icon
|
videoIconClass: String, // CSS class for the open video icon
|
||||||
isWatchingTab: Boolean, // is the "Watching" tab (replace video button w/ boot)
|
isWatchingTab: Boolean, // is the "Watching" tab (replace video button w/ boot)
|
||||||
|
statusMessage: Object, // StatusMessage controller
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -101,6 +102,19 @@ export default {
|
||||||
hasReactions() {
|
hasReactions() {
|
||||||
return this.reactions != undefined && Object.keys(this.reactions).length > 0;
|
return this.reactions != undefined && Object.keys(this.reactions).length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Status icons
|
||||||
|
hasStatusIcon() {
|
||||||
|
return this.user.status !== 'online' && this.statusMessage != undefined;
|
||||||
|
},
|
||||||
|
statusIconClass() {
|
||||||
|
let status = this.statusMessage.getStatus(this.user.status);
|
||||||
|
return status.icon;
|
||||||
|
},
|
||||||
|
statusLabel() {
|
||||||
|
let status = this.statusMessage.getStatus(this.user.status);
|
||||||
|
return `${status.emoji} ${status.label}`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openProfile() {
|
openProfile() {
|
||||||
|
@ -157,34 +171,9 @@ export default {
|
||||||
<img v-else src="/static/img/shy.png" width="24" height="24">
|
<img v-else src="/static/img/shy.png" width="24" height="24">
|
||||||
|
|
||||||
<!-- Away symbol -->
|
<!-- Away symbol -->
|
||||||
<div v-if="user.status !== 'online'" class="status-away-icon">
|
<div v-if="hasStatusIcon" class="status-away-icon">
|
||||||
<i v-if="user.status === 'away'" class="fa fa-clock has-text-light"
|
<i :class="statusIconClass" class="has-text-light"
|
||||||
title="Status: Away"></i>
|
:title="'Status: ' + statusLabel"></i>
|
||||||
<i v-else-if="user.status === 'lunch'" class="fa fa-utensils has-text-light"
|
|
||||||
title="Status: Out to lunch"></i>
|
|
||||||
<i v-else-if="user.status === 'call'" class="fa fa-phone-volume has-text-light"
|
|
||||||
title="Status: On the phone"></i>
|
|
||||||
<i v-else-if="user.status === 'brb'" class="fa fa-stopwatch-20 has-text-light"
|
|
||||||
title="Status: Be right back"></i>
|
|
||||||
<i v-else-if="user.status === 'busy'" class="fa fa-briefcase has-text-light"
|
|
||||||
title="Status: Working"></i>
|
|
||||||
<i v-else-if="user.status === 'book'" class="fa fa-book has-text-light"
|
|
||||||
title="Status: Studying"></i>
|
|
||||||
<i v-else-if="user.status === 'gaming'"
|
|
||||||
class="fa fa-gamepad who-status-wide-icon-2 has-text-light"
|
|
||||||
title="Status: Gaming"></i>
|
|
||||||
<i v-else-if="user.status === 'idle'" class="fa-regular fa-moon has-text-light"
|
|
||||||
title="Status: Idle"></i>
|
|
||||||
<i v-else-if="user.status === 'horny'" class="fa fa-fire has-text-light"
|
|
||||||
title="Status: Horny"></i>
|
|
||||||
<i v-else-if="user.status === 'chatty'" class="fa fa-comment has-text-light"
|
|
||||||
title="Status: Chatty and sociable"></i>
|
|
||||||
<i v-else-if="user.status === 'introverted'" class="fa fa-spoon has-text-light"
|
|
||||||
title="Status: Introverted and quiet"></i>
|
|
||||||
<i v-else-if="user.status === 'exhibitionist'"
|
|
||||||
class="fa-regular fa-eye who-status-wide-icon-1 has-text-light"
|
|
||||||
title="Status: Watch me"></i>
|
|
||||||
<i v-else class="fa fa-clock has-text-light" :title="'Status: ' + user.status"></i>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
212
src/lib/StatusMessage.js
Normal file
212
src/lib/StatusMessage.js
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
// Available status options.
|
||||||
|
const StatusOptions = [
|
||||||
|
{
|
||||||
|
category: "Status",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "online",
|
||||||
|
label: "Active",
|
||||||
|
emoji: "☀️",
|
||||||
|
icon: "fa fa-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "away",
|
||||||
|
label: "Away",
|
||||||
|
emoji: "🕒",
|
||||||
|
icon: "fa fa-clock"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "brb",
|
||||||
|
label: "Be right back",
|
||||||
|
emoji: "⏰",
|
||||||
|
icon: "fa fa-stopwatch-20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "afk",
|
||||||
|
label: "Away from keyboard",
|
||||||
|
emoji: "⌨️",
|
||||||
|
icon: "fa fa-keyboard who-status-wide-icon-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lunch",
|
||||||
|
label: "Out to lunch",
|
||||||
|
emoji: "🍴",
|
||||||
|
icon: "fa fa-utensils"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "call",
|
||||||
|
label: "On the phone",
|
||||||
|
emoji: "📞",
|
||||||
|
icon: "fa fa-phone-volume"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "busy",
|
||||||
|
label: "Working",
|
||||||
|
emoji: "💼",
|
||||||
|
icon: "fa fa-briefcase"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "book",
|
||||||
|
label: "Studying",
|
||||||
|
emoji: "📖",
|
||||||
|
icon: "fa fa-book"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "gaming",
|
||||||
|
label: "Gaming",
|
||||||
|
emoji: "🎮",
|
||||||
|
icon: "fa fa-gamepad who-status-wide-icon-2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "movie",
|
||||||
|
label: "Watching a movie",
|
||||||
|
emoji: "🎞️",
|
||||||
|
icon: "fa fa-film"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "travel",
|
||||||
|
label: "Traveling",
|
||||||
|
emoji: "✈️",
|
||||||
|
icon: "fa fa-plane"
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hidden/special statuses
|
||||||
|
{
|
||||||
|
name: "idle",
|
||||||
|
label: "Idle",
|
||||||
|
emoji: "🕒",
|
||||||
|
icon: "fa-regular fa-moon",
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "hidden",
|
||||||
|
label: "Hidden",
|
||||||
|
emoji: "🕵️",
|
||||||
|
icon: "",
|
||||||
|
adminOnly: true
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Mood",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "chatty",
|
||||||
|
label: "Chatty and sociable",
|
||||||
|
emoji: "🗨️",
|
||||||
|
icon: "fa fa-comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "introverted",
|
||||||
|
label: "Introverted and quiet",
|
||||||
|
emoji: "🥄",
|
||||||
|
icon: "fa fa-spoon"
|
||||||
|
},
|
||||||
|
|
||||||
|
// If NSFW enabled
|
||||||
|
{
|
||||||
|
name: "horny",
|
||||||
|
label: "Horny",
|
||||||
|
emoji: "🔥",
|
||||||
|
icon: "fa fa-fire",
|
||||||
|
nsfw: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "exhibitionist",
|
||||||
|
label: "Watch me",
|
||||||
|
emoji: "👀",
|
||||||
|
icon: "fa-regular fa-eye who-status-wide-icon-1",
|
||||||
|
nsfw: true,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Flatten the set of all status options.
|
||||||
|
const StatusFlattened = (function() {
|
||||||
|
let result = [];
|
||||||
|
for (let category of StatusOptions) {
|
||||||
|
for (let option of category.options) {
|
||||||
|
result.push(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Hash map lookup of status by name.
|
||||||
|
const StatusByName = (function() {
|
||||||
|
let result = {};
|
||||||
|
for (let item of StatusFlattened) {
|
||||||
|
result[item.name] = item;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// An API surface layer of functions.
|
||||||
|
class StatusMessageController {
|
||||||
|
// The caller configures:
|
||||||
|
// - nsfw (bool): the BareRTC PermitNSFW setting, which controls some status options.
|
||||||
|
// - isAdmin (func): return a boolean if the current user is operator.
|
||||||
|
// - currentStatus (func): return the name of the user's current status.
|
||||||
|
constructor() {
|
||||||
|
this.nsfw = false;
|
||||||
|
this.isAdmin = function() { return false };
|
||||||
|
this.currentStatus = function() { return StatusFlattened[0] };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate the category <optgroup> for the Status dropdown menu.
|
||||||
|
iterSelectOptGroups() {
|
||||||
|
return StatusOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate the <option> for a category of statuses.
|
||||||
|
iterSelectOptions(category) {
|
||||||
|
let current = this.currentStatus(),
|
||||||
|
isAdmin = this.isAdmin();
|
||||||
|
|
||||||
|
for (let group of StatusOptions) {
|
||||||
|
if (group.category === category) {
|
||||||
|
// Return the filtered options.
|
||||||
|
let result = group.options.filter(option => {
|
||||||
|
if ((option.hidden && current !== option.name) ||
|
||||||
|
(option.adminOnly && !isAdmin) ||
|
||||||
|
(option.nsfw && !this.nsfw)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get details on a status message.
|
||||||
|
getStatus(name) {
|
||||||
|
if (StatusByName[name] != undefined) {
|
||||||
|
return StatusByName[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a dummy status object.
|
||||||
|
return {
|
||||||
|
name: name,
|
||||||
|
label: name,
|
||||||
|
icon: "fa fa-clock",
|
||||||
|
emoji: "🕒"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offline status.
|
||||||
|
offline() {
|
||||||
|
return {
|
||||||
|
name: "offline",
|
||||||
|
label: "Offline",
|
||||||
|
icon: "fa fa-house-circle-xmark",
|
||||||
|
emoji: "🌜",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const StatusMessage = new StatusMessageController();
|
||||||
|
export default StatusMessage;
|
Loading…
Reference in New Issue
Block a user