Chat style updates
This commit is contained in:
parent
f9fb6b5b0d
commit
50d7aea39d
|
@ -33,6 +33,11 @@
|
||||||
background-color: rgba(0, 0, 0, 0.86) !important;
|
background-color: rgba(0, 0, 0, 0.86) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification.is-success.is-light {
|
||||||
|
background-color: #232e29 !important;
|
||||||
|
color: #56cf98 !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* end nonshy custom overrides */
|
/* end nonshy custom overrides */
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
|
|
@ -215,6 +215,9 @@ const app = Vue.createApp({
|
||||||
window.addEventListener("click", () => {
|
window.addEventListener("click", () => {
|
||||||
this.setupSounds();
|
this.setupSounds();
|
||||||
});
|
});
|
||||||
|
window.addEventListener("keydown", () => {
|
||||||
|
this.setupSounds();
|
||||||
|
});
|
||||||
|
|
||||||
for (let channel of this.config.channels) {
|
for (let channel of this.config.channels) {
|
||||||
this.initHistory(channel.ID);
|
this.initHistory(channel.ID);
|
||||||
|
@ -488,25 +491,29 @@ const app = Vue.createApp({
|
||||||
// User logged in or out.
|
// User logged in or out.
|
||||||
onPresence(msg) {
|
onPresence(msg) {
|
||||||
// TODO: make a dedicated leave event
|
// TODO: make a dedicated leave event
|
||||||
|
let isLeave = false;
|
||||||
if (msg.message.indexOf("has exited the room!") > -1) {
|
if (msg.message.indexOf("has exited the room!") > -1) {
|
||||||
// Clean up data about this user.
|
// Clean up data about this user.
|
||||||
this.onUserExited(msg);
|
this.onUserExited(msg);
|
||||||
this.playSound("Leave");
|
this.playSound("Leave");
|
||||||
|
isLeave = true;
|
||||||
} else {
|
} else {
|
||||||
this.playSound("Enter");
|
this.playSound("Enter");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push it to the history of all public channels.
|
// Push it to the history of all public channels (not leaves).
|
||||||
for (let channel of this.config.channels) {
|
if (!isLeave) {
|
||||||
this.pushHistory({
|
for (let channel of this.config.channels) {
|
||||||
channel: channel.ID,
|
this.pushHistory({
|
||||||
action: msg.action,
|
channel: channel.ID,
|
||||||
username: msg.username,
|
action: msg.action,
|
||||||
message: msg.message,
|
username: msg.username,
|
||||||
});
|
message: msg.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push also to any DM channels for this user.
|
// Push also to any DM channels for this user (leave events do push to DM thread for visibility).
|
||||||
let channel = "@" + msg.username;
|
let channel = "@" + msg.username;
|
||||||
if (this.channels[channel] != undefined) {
|
if (this.channels[channel] != undefined) {
|
||||||
this.pushHistory({
|
this.pushHistory({
|
||||||
|
@ -896,6 +903,9 @@ const app = Vue.createApp({
|
||||||
if (nick) {
|
if (nick) {
|
||||||
return nick;
|
return nick;
|
||||||
}
|
}
|
||||||
|
} else if (this.whoMap[username] == undefined && username !== 'ChatServer' && username !== 'ChatClient') {
|
||||||
|
// User is not even logged in! Add this note to their name
|
||||||
|
username += " (offline)";
|
||||||
}
|
}
|
||||||
return username;
|
return username;
|
||||||
},
|
},
|
||||||
|
@ -1468,6 +1478,9 @@ const app = Vue.createApp({
|
||||||
// allow it to set up the AudioContext. If we've successfully set one up before, exit
|
// allow it to set up the AudioContext. If we've successfully set one up before, exit
|
||||||
// this function immediately.
|
// this function immediately.
|
||||||
if (this.config.sounds.audioContext) {
|
if (this.config.sounds.audioContext) {
|
||||||
|
if (this.config.sounds.audioContext.state === 'suspended') {
|
||||||
|
this.config.sounds.audioContext.resume();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/bulma.min.css">
|
<link rel="stylesheet" type="text/css" href="/static/css/bulma.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/bulma-prefers-dark.css">
|
<link rel="stylesheet" type="text/css" href="/static/css/bulma-prefers-dark.css?{{.CacheHash}}">
|
||||||
<link rel="stylesheet" href="/static/fontawesome-free-6.1.2-web/css/all.css">
|
<link rel="stylesheet" href="/static/fontawesome-free-6.1.2-web/css/all.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/chat.css?{{.CacheHash}}">
|
<link rel="stylesheet" type="text/css" href="/static/css/chat.css?{{.CacheHash}}">
|
||||||
<title>{{.Config.Title}}</title>
|
<title>{{.Config.Title}}</title>
|
||||||
|
@ -733,97 +733,120 @@
|
||||||
</em>
|
</em>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="(msg, i) in chatHistory" v-bind:key="i" class="box mb-2 px-4 pt-3 pb-1">
|
<div v-for="(msg, i) in chatHistory" v-bind:key="i">
|
||||||
<div class="media mb-0">
|
<!-- Enter chat presence messages draw as a short banner -->
|
||||||
<div class="media-left">
|
<div v-if="msg.action === 'presence'" class="notification is-success is-light py-1 px-3 mb-2">
|
||||||
<a :href="profileURLForUsername(msg.username)" @click.prevent="openProfile({username: msg.username})"
|
|
||||||
:class="{'cursor-default': !profileURLForUsername(msg.username)}">
|
<!-- Tiny avatar next to name and action buttons -->
|
||||||
<figure class="image is-48x48">
|
<div class="columns is-mobile">
|
||||||
<img v-if="msg.isChatServer"
|
<div class="column is-narrow pr-0 pt-4">
|
||||||
src="/static/img/server.png">
|
<figure class="image is-16x16">
|
||||||
<img v-else-if="msg.isChatClient"
|
<img v-if="avatarForUsername(msg.username)"
|
||||||
src="/static/img/client.png">
|
|
||||||
<img v-else-if="avatarForUsername(msg.username)"
|
|
||||||
:src="avatarForUsername(msg.username)">
|
:src="avatarForUsername(msg.username)">
|
||||||
<img v-else src="/static/img/shy.png">
|
<img v-else src="/static/img/shy.png">
|
||||||
</figure>
|
</figure>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="media-content">
|
|
||||||
<div class="columns is-mobile pb-0">
|
|
||||||
<div class="column is-narrow pb-0">
|
|
||||||
<label class="label"
|
|
||||||
:class="{'has-text-success is-dark': msg.isChatServer,
|
|
||||||
'has-text-warning is-dark': msg.isAdmin,
|
|
||||||
'has-text-danger': msg.isChatClient}">
|
|
||||||
|
|
||||||
<!-- User nickname/display name -->
|
|
||||||
[[nicknameForUsername(msg.username)]]
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="column has-text-right pb-0">
|
|
||||||
<small class="has-text-grey is-size-7" :title="msg.at">[[prettyDate(msg.at)]]</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="column">
|
||||||
<!-- User @username below it which may link to a profile URL if JWT -->
|
<strong>[[ msg.username ]]</strong> [[msg.message]]
|
||||||
<div class="columns is-mobile pt-0" v-if="(msg.isChatClient || msg.isChatServer)">
|
|
||||||
<div class="column is-narrow pt-0">
|
|
||||||
<small v-if="!(msg.isChatClient || msg.isChatServer)">
|
|
||||||
<a v-if="profileURLForUsername(msg.username)"
|
|
||||||
:href="profileURLForUsername(msg.username)"
|
|
||||||
target="_blank"
|
|
||||||
class="has-text-grey">
|
|
||||||
@[[msg.username]]
|
|
||||||
</a>
|
|
||||||
<span v-else class="has-text-grey">@[[msg.username]]</span>
|
|
||||||
</small>
|
|
||||||
<small v-else class="has-text-grey">internal</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else class="columns is-mobile pt-0">
|
|
||||||
<div class="column is-narrow pt-0">
|
|
||||||
<small v-if="!(msg.isChatClient || msg.isChatServer)">
|
|
||||||
<a v-if="profileURLForUsername(msg.username)"
|
|
||||||
:href="profileURLForUsername(msg.username)"
|
|
||||||
target="_blank"
|
|
||||||
class="has-text-grey">
|
|
||||||
@[[msg.username]]
|
|
||||||
</a>
|
|
||||||
<span v-else class="has-text-grey">@[[msg.username]]</span>
|
|
||||||
</small>
|
|
||||||
<small v-else class="has-text-grey">internal</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column is-narrow px-1 pt-0"
|
|
||||||
v-if="!(msg.username === username || isDM)">
|
|
||||||
<!-- DMs button -->
|
|
||||||
<button type="button"
|
|
||||||
class="button is-grey is-outlined is-small px-2"
|
|
||||||
@click="openDMs({username: msg.username})">
|
|
||||||
<i class="fa fa-message"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="column is-narrow pl-1 pt-0"
|
|
||||||
v-if="!(msg.username === username)">
|
|
||||||
<!-- Mute button -->
|
|
||||||
<button type="button"
|
|
||||||
class="button is-grey is-outlined is-small px-2"
|
|
||||||
@click="muteUser(msg.username)"
|
|
||||||
title="Mute user">
|
|
||||||
<i class="fa fa-comment-slash"
|
|
||||||
:class="{'has-text-success': isMutedUser(msg.username),
|
|
||||||
'has-text-danger': !isMutedUser(msg.username)}"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Message box -->
|
<!-- Normal chat message: full size card w/ avatar -->
|
||||||
<div class="content pl-5 py-3 mb-0">
|
<div v-else class="box mb-2 px-4 pt-3 pb-1">
|
||||||
<em v-if="msg.action === 'presence'">[[msg.message]]</em>
|
<div class="media mb-0">
|
||||||
<div v-else v-html="msg.message"></div>
|
<div class="media-left">
|
||||||
|
<a :href="profileURLForUsername(msg.username)" @click.prevent="openProfile({username: msg.username})"
|
||||||
|
:class="{'cursor-default': !profileURLForUsername(msg.username)}">
|
||||||
|
<figure class="image is-48x48">
|
||||||
|
<img v-if="msg.isChatServer"
|
||||||
|
src="/static/img/server.png">
|
||||||
|
<img v-else-if="msg.isChatClient"
|
||||||
|
src="/static/img/client.png">
|
||||||
|
<img v-else-if="avatarForUsername(msg.username)"
|
||||||
|
:src="avatarForUsername(msg.username)">
|
||||||
|
<img v-else src="/static/img/shy.png">
|
||||||
|
</figure>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="media-content">
|
||||||
|
<div class="columns is-mobile pb-0">
|
||||||
|
<div class="column is-narrow pb-0">
|
||||||
|
<label class="label"
|
||||||
|
:class="{'has-text-success is-dark': msg.isChatServer,
|
||||||
|
'has-text-warning is-dark': msg.isAdmin,
|
||||||
|
'has-text-danger': msg.isChatClient}">
|
||||||
|
|
||||||
|
<!-- User nickname/display name -->
|
||||||
|
[[nicknameForUsername(msg.username)]]
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="column has-text-right pb-0">
|
||||||
|
<small class="has-text-grey is-size-7" :title="msg.at">[[prettyDate(msg.at)]]</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- User @username below it which may link to a profile URL if JWT -->
|
||||||
|
<div class="columns is-mobile pt-0" v-if="(msg.isChatClient || msg.isChatServer)">
|
||||||
|
<div class="column is-narrow pt-0">
|
||||||
|
<small v-if="!(msg.isChatClient || msg.isChatServer)">
|
||||||
|
<a v-if="profileURLForUsername(msg.username)"
|
||||||
|
:href="profileURLForUsername(msg.username)"
|
||||||
|
target="_blank"
|
||||||
|
class="has-text-grey">
|
||||||
|
@[[msg.username]]
|
||||||
|
</a>
|
||||||
|
<span v-else class="has-text-grey">@[[msg.username]]</span>
|
||||||
|
</small>
|
||||||
|
<small v-else class="has-text-grey">internal</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="columns is-mobile pt-0">
|
||||||
|
<div class="column is-narrow pt-0">
|
||||||
|
<small v-if="!(msg.isChatClient || msg.isChatServer)">
|
||||||
|
<a v-if="profileURLForUsername(msg.username)"
|
||||||
|
:href="profileURLForUsername(msg.username)"
|
||||||
|
target="_blank"
|
||||||
|
class="has-text-grey">
|
||||||
|
@[[msg.username]]
|
||||||
|
</a>
|
||||||
|
<span v-else class="has-text-grey">@[[msg.username]]</span>
|
||||||
|
</small>
|
||||||
|
<small v-else class="has-text-grey">internal</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column is-narrow px-1 pt-0"
|
||||||
|
v-if="!(msg.username === username || isDM)">
|
||||||
|
<!-- DMs button -->
|
||||||
|
<button type="button"
|
||||||
|
class="button is-grey is-outlined is-small px-2"
|
||||||
|
@click="openDMs({username: msg.username})">
|
||||||
|
<i class="fa fa-message"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="column is-narrow pl-1 pt-0"
|
||||||
|
v-if="!(msg.username === username)">
|
||||||
|
<!-- Mute button -->
|
||||||
|
<button type="button"
|
||||||
|
class="button is-grey is-outlined is-small px-2"
|
||||||
|
@click="muteUser(msg.username)"
|
||||||
|
title="Mute user">
|
||||||
|
<i class="fa fa-comment-slash"
|
||||||
|
:class="{'has-text-success': isMutedUser(msg.username),
|
||||||
|
'has-text-danger': !isMutedUser(msg.username)}"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Message box -->
|
||||||
|
<div class="content pl-5 py-3 mb-0">
|
||||||
|
<em v-if="msg.action === 'presence'">[[msg.message]]</em>
|
||||||
|
<div v-else v-html="msg.message"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user