Display user avatars instead of talking indicators when possible
This commit is contained in:
parent
2b7f7c1625
commit
d7b03d2192
|
@ -160,6 +160,17 @@
|
|||
<input type="button" data-bind="value: pttKeyDisplay, click: recordPttKey">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Show Avatars</td>
|
||||
<td>
|
||||
<select data-bind='value: showAvatars'>
|
||||
<option value="always">Always</option>
|
||||
<option value="own_channel">Same Channel</option>
|
||||
<option value="linked_channel">Linked Channels</option>
|
||||
<option value="minimal_only">Minimal View</option>
|
||||
<option value="never">Never</option>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="dialog-footer">
|
||||
<input class="dialog-close" type="button" data-bind="click: $root.closeSettings" value="Cancel">
|
||||
|
@ -304,6 +315,15 @@
|
|||
<div data-bind="if: comment">
|
||||
<div class="user-comment tooltip" data-bind="html: comment"></div>
|
||||
</div>
|
||||
<!-- ko if: show_avatar() -->
|
||||
<img class="user-avatar" alt="avatar"
|
||||
data-bind="attr: { src: texture },
|
||||
css: { 'user-avatar-talk-off': talking() == 'off',
|
||||
'user-avatar-talk-on': talking() == 'on',
|
||||
'user-avatar-talk-whisper': talking() == 'whisper',
|
||||
'user-avatar-talk-shout': talking() == 'shout' }">
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: show_avatar() -->
|
||||
<img class="user-talk user-talk-off" data-bind="visible: talking() == 'off'"
|
||||
alt="talk off" src="/svg/talking_off.svg">
|
||||
<img class="user-talk user-talk-on" data-bind="visible: talking() == 'on'"
|
||||
|
|
45
app/index.js
45
app/index.js
|
@ -78,6 +78,7 @@ class SettingsDialog {
|
|||
this.vadLevel = ko.observable(settings.vadLevel)
|
||||
this.testVadLevel = ko.observable(0)
|
||||
this.testVadActive = ko.observable(false)
|
||||
this.showAvatars = ko.observable(settings.showAvatars())
|
||||
|
||||
this._setupTestVad()
|
||||
this.vadLevel.subscribe(() => this._setupTestVad())
|
||||
|
@ -98,6 +99,7 @@ class SettingsDialog {
|
|||
settings.voiceMode = this.voiceMode()
|
||||
settings.pttKey = this.pttKey()
|
||||
settings.vadLevel = this.vadLevel()
|
||||
settings.showAvatars(this.showAvatars())
|
||||
}
|
||||
|
||||
end () {
|
||||
|
@ -133,6 +135,7 @@ class Settings {
|
|||
this.pttKey = load('pttKey') || 'ctrl + shift'
|
||||
this.vadLevel = load('vadLevel') || 0.3
|
||||
this.toolbarVertical = load('toolbarVertical') || false
|
||||
this.showAvatars = ko.observable(load('showAvatars') || 'always')
|
||||
}
|
||||
|
||||
save () {
|
||||
|
@ -141,6 +144,7 @@ class Settings {
|
|||
save('pttKey', this.pttKey)
|
||||
save('vadLevel', this.vadLevel)
|
||||
save('toolbarVertical', this.toolbarVertical)
|
||||
save('showAvatars', this.showAvatars())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,6 +299,8 @@ class GlobalBindings {
|
|||
suppress: 'suppress',
|
||||
selfMute: 'selfMute',
|
||||
selfDeaf: 'selfDeaf',
|
||||
texture: 'rawTexture',
|
||||
textureHash: 'textureHash',
|
||||
comment: 'comment'
|
||||
}
|
||||
var ui = user.__ui = {
|
||||
|
@ -302,6 +308,40 @@ class GlobalBindings {
|
|||
talking: ko.observable('off'),
|
||||
channel: ko.observable()
|
||||
}
|
||||
ui.texture = ko.pureComputed(() => {
|
||||
let raw = ui.rawTexture()
|
||||
if (!raw || raw.offset >= raw.limit) return null
|
||||
return 'data:image/*;base64,' + raw.toBase64()
|
||||
})
|
||||
ui.show_avatar = () => {
|
||||
let setting = this.settings.showAvatars()
|
||||
switch (setting) {
|
||||
case 'always':
|
||||
break
|
||||
case 'own_channel':
|
||||
if (this.thisUser().channel() !== ui.channel()) return false
|
||||
break
|
||||
case 'linked_channel':
|
||||
if (!ui.channel().linked()) return false
|
||||
break
|
||||
case 'minimal_only':
|
||||
if (!this.minimalView()) return false
|
||||
if (this.thisUser().channel() !== ui.channel()) return false
|
||||
break
|
||||
case 'never':
|
||||
default: return false
|
||||
}
|
||||
if (!ui.texture()) {
|
||||
if (ui.textureHash()) {
|
||||
// The user has an avatar set but it's of sufficient size to not be
|
||||
// included by default, so we need to fetch it explicitly now.
|
||||
// mumble-client should make sure we only send one request per hash
|
||||
user.requestTexture()
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
Object.entries(simpleProperties).forEach(key => {
|
||||
ui[key[1]] = ko.observable(user[key[0]])
|
||||
})
|
||||
|
@ -327,6 +367,11 @@ class GlobalBindings {
|
|||
ui.channel().users.sort(compareUsers)
|
||||
this._updateLinks()
|
||||
}
|
||||
if (properties.textureHash !== undefined) {
|
||||
// Invalidate avatar texture when its hash has changed
|
||||
// If the avatar is still visible, this will trigger a fetch of the new one.
|
||||
ui.rawTexture(null)
|
||||
}
|
||||
}).on('remove', () => {
|
||||
if (ui.channel()) {
|
||||
ui.channel().users.remove(ui)
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
"libsamplerate.js": "^1.0.0",
|
||||
"mumble-client-codecs-browser": "^1.1.1",
|
||||
"mumble-client-websocket": "^1.0.0",
|
||||
"mumble-client": "^1.1.1",
|
||||
"mumble-client": "^1.2.0",
|
||||
"web-audio-buffer-queue": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ $chat-channel-color: orange !default
|
|||
$chat-user-color: green !default
|
||||
$chat-input-color: $font-color !default
|
||||
$mic-volume-border-color: $black !default
|
||||
$talk-outline-color: green !default
|
||||
$whisper-outline-color: purple !default
|
||||
$shout-outline-color: cyan !default
|
||||
|
||||
$toolbar-hover-bg-color: $lightgray !default
|
||||
$toolbar-hover-border-color: $gray !default
|
||||
|
@ -144,9 +147,27 @@ html, body {
|
|||
.user {
|
||||
margin-left: 9px;
|
||||
}
|
||||
.user-talk {
|
||||
.user-avatar, .user-talk {
|
||||
vertical-align: middle;
|
||||
}
|
||||
@mixin drop-shadow-4x($size, $blur, $color) {
|
||||
filter: drop-shadow(#{+$size} #{+$size} $blur $color)
|
||||
drop-shadow(#{+$size} #{-$size} $blur $color)
|
||||
drop-shadow(#{-$size} #{+$size} $blur $color)
|
||||
drop-shadow(#{-$size} #{-$size} $blur $color);
|
||||
}
|
||||
@mixin user-avatar-drop-shadow($color) {
|
||||
@include drop-shadow-4x(1px, 1px, $color);
|
||||
}
|
||||
.user-avatar-talk-on {
|
||||
@include user-avatar-drop-shadow($talk-outline-color);
|
||||
}
|
||||
.user-avatar-talk-whisper {
|
||||
@include user-avatar-drop-shadow($whisper-outline-color);
|
||||
}
|
||||
.user-avatar-talk-shout {
|
||||
@include user-avatar-drop-shadow($shout-outline-color);
|
||||
}
|
||||
.user-status, .channel-status {
|
||||
float: right;
|
||||
}
|
||||
|
@ -339,7 +360,7 @@ form {
|
|||
}
|
||||
.settings-dialog {
|
||||
width: 300px;
|
||||
height: 156px;
|
||||
height: 200px;
|
||||
top: calc(50% - 100px);
|
||||
left: calc(50% - 150px);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue