Implement theming support and add MetroMumbleDark theme
This commit is contained in:
parent
0a68f28c38
commit
ca83780109
10
README.md
10
README.md
|
@ -86,8 +86,18 @@ map $http_upgrade $connection_upgrade {
|
|||
}
|
||||
```
|
||||
|
||||
### Themes
|
||||
The default theme of mumble-web tries to mimic the excellent [MetroMumble]Light theme.
|
||||
mumble-web also includes a dark version, named MetroMumbleDark, which is heavily inspired by [MetroMumble]'s dark version.
|
||||
|
||||
To select a theme other than the default one, append a `theme=dark` query parameter (where `dark` is the name of the theme) when accessing the mumble-web page.
|
||||
E.g. [this](https://voice.johni0702.de/?address=voice.johni0702.de&port=443/demo&theme=dark)is the live demo linked above but using the dark theme (`dark` is an alias for `MetroMumbleDark`).
|
||||
|
||||
Custom themes can be created by deriving them from the MetroMumbleLight/Dark themes just like the MetroMumbleDark theme is derived from the MetroMumbleLight theme.
|
||||
|
||||
### License
|
||||
ISC
|
||||
|
||||
[Mumble]: https://wiki.mumble.info/wiki/Main_Page
|
||||
[websockify GitHub page]: https://github.com/novnc/websockify
|
||||
[MetroMumble]: https://github.com/xPoke/MetroMumble
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<meta name="msapplication-config" content="${require('./favicon/browserconfig.xml')}">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/loading.css">
|
||||
<script src="theme.js"></script>
|
||||
|
||||
<script src="matrix.js"></script>
|
||||
</head>
|
||||
|
@ -340,6 +340,5 @@
|
|||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<link rel="stylesheet" type="text/css" href="/main.css">
|
||||
<script src="index.js"></script>
|
||||
</html>
|
||||
|
|
33
app/theme.js
Normal file
33
app/theme.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import url from 'url'
|
||||
|
||||
var queryParams = url.parse(document.location.href, true).query
|
||||
var theme = queryParams.theme || window.localStorage.getItem('mumble.theme')
|
||||
var themes = {
|
||||
'MetroMumbleLight': 'MetroMumbleLight',
|
||||
'MetroMumbleDark': 'MetroMumbleDark',
|
||||
'light': 'MetroMumbleLight',
|
||||
'dark': 'MetroMumbleDark'
|
||||
}
|
||||
theme = themes[theme] || 'MetroMumbleLight'
|
||||
window.theme = theme
|
||||
|
||||
var [loadingTheme, mainTheme] = {
|
||||
'MetroMumbleLight': [
|
||||
require('../themes/MetroMumbleLight/loading.scss'),
|
||||
require('../themes/MetroMumbleLight/main.scss')
|
||||
],
|
||||
'MetroMumbleDark': [
|
||||
require('../themes/MetroMumbleDark/loading.scss'),
|
||||
require('../themes/MetroMumbleDark/main.scss')
|
||||
]
|
||||
}[theme]
|
||||
|
||||
function useStyle (url) {
|
||||
var style = document.createElement('link')
|
||||
style.rel = 'stylesheet'
|
||||
style.type = 'text/css'
|
||||
style.href = url
|
||||
document.getElementsByTagName('head')[0].appendChild(style)
|
||||
}
|
||||
useStyle(loadingTheme)
|
||||
useStyle(mainTheme)
|
|
@ -36,8 +36,10 @@
|
|||
"knockout": "^3.4.0",
|
||||
"lodash.assign": "^4.2.0",
|
||||
"microphone-stream": "^3.0.5",
|
||||
"node-sass": "^4.9.3",
|
||||
"raw-loader": "^0.5.1",
|
||||
"regexp-replace-loader": "0.0.1",
|
||||
"sass-loader": "^4.1.1",
|
||||
"stream-chunker": "^1.2.8",
|
||||
"transform-loader": "^0.2.3",
|
||||
"voice-activity-detection": "johni0702/voice-activity-detection#9f8bd90",
|
||||
|
|
5
themes/MetroMumbleDark/loading.scss
Normal file
5
themes/MetroMumbleDark/loading.scss
Normal file
|
@ -0,0 +1,5 @@
|
|||
$bg-color: #2c2c2c !default
|
||||
$spinner-color: #888 !default
|
||||
$spinner-bg-color: #222 !default
|
||||
|
||||
@import '../MetroMumbleLight/loading';
|
22
themes/MetroMumbleDark/main.scss
Normal file
22
themes/MetroMumbleDark/main.scss
Normal file
|
@ -0,0 +1,22 @@
|
|||
$black: #bbb !default
|
||||
$darkgray: #777 !default
|
||||
$gray: #555 !default
|
||||
$lightgray: #555 !default
|
||||
$bg-color: #2c2c2c !default
|
||||
$white: #1c1c1c !default
|
||||
|
||||
$lightblue: #557 !default
|
||||
|
||||
$toolbar-hover-bg-color: $lightblue !default
|
||||
$toolbar-hover-border-color: $lightblue !default
|
||||
$toolbar-active-bg-color: $gray !default
|
||||
$toolbar-active-border-color: $gray !default
|
||||
$dialog-color: $black !default
|
||||
$channel-selected-bg-color: $lightblue !default
|
||||
|
||||
@import '../MetroMumbleLight/main';
|
||||
|
||||
.dialog-header {
|
||||
color: #000;
|
||||
font-weight: bold;
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
$bg-color: #eee !default
|
||||
$spinner-color: #999 !default
|
||||
$spinner-bg-color: #ddd !default
|
||||
|
||||
.loading-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #eee;
|
||||
background-color: $bg-color;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
|
@ -15,8 +19,8 @@
|
|||
top: calc(50% - 40px);
|
||||
left: calc(50% - 40px);
|
||||
border-radius: 100%;
|
||||
border: 10px solid #ddd;
|
||||
border-top-color: #999;
|
||||
border: 10px solid $spinner-bg-color;
|
||||
border-top-color: $spinner-color;
|
||||
animation: spin 1s infinite linear;
|
||||
}
|
||||
|
|
@ -1,5 +1,50 @@
|
|||
$black: #000 !default
|
||||
$darkgray: #888 !default
|
||||
$gray: #a9a9a9 !default
|
||||
$lightgray: #d3d3d3 !default
|
||||
$bg-color: #eee !default
|
||||
$white: #fff !default
|
||||
|
||||
$font-color: $black !default
|
||||
$panel-bg-color: $white !default
|
||||
$panel-border-color: $lightgray !default
|
||||
$channel-tree-color: $lightgray !default
|
||||
$channel-hover-bg-color: $lightgray !default
|
||||
$channel-selected-bg-color: lightblue !default
|
||||
$channel-selected-border-color: $darkgray !default
|
||||
$tooltip-border-color: $darkgray !default
|
||||
$chat-channel-color: orange !default
|
||||
$chat-user-color: green !default
|
||||
$chat-input-color: $font-color !default
|
||||
$mic-volume-border-color: $black !default
|
||||
|
||||
$toolbar-hover-bg-color: $lightgray !default
|
||||
$toolbar-hover-border-color: $gray !default
|
||||
$toolbar-active-bg-color: $white !default
|
||||
$toolbar-active-border-color: $toolbar-hover-bg-color !default
|
||||
$toolbar-divider-color: $lightgray !default
|
||||
$dialog-header-color: $white !default
|
||||
$dialog-header-bg-color: $darkgray !default
|
||||
$dialog-header-border-bottom-color: $gray !default
|
||||
$dialog-bg-color: $bg-color !default
|
||||
$dialog-border-color: $darkgray !default
|
||||
$dialog-color: $font-color !default
|
||||
$dialog-button-border-color: $darkgray !default
|
||||
$dialog-button-bg-color: $white !default
|
||||
$dialog-button-color: $dialog-color !default
|
||||
$dialog-input-border-color: $darkgray !default
|
||||
$dialog-input-bg-color: $white !default
|
||||
$dialog-input-color: $dialog-color !default
|
||||
|
||||
$tooltip-bg-color: $panel-bg-color !default
|
||||
$channels-bg-color: $panel-bg-color !default
|
||||
$channels-border-color: $panel-border-color !default
|
||||
$chat-bg-color: $panel-bg-color !default
|
||||
$chat-border-color: $panel-border-color !default
|
||||
|
||||
html, body {
|
||||
background-color: #eee;
|
||||
background-color: $bg-color;
|
||||
color: $font-color;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
height: 100%
|
||||
|
@ -10,8 +55,8 @@ html, body {
|
|||
.channel-root-container {
|
||||
text-size: 16px;
|
||||
margin-left: 2px;
|
||||
background-color: white;
|
||||
border: 1px solid lightgray;
|
||||
background-color: $channels-bg-color;
|
||||
border: 1px solid $channels-border-color;
|
||||
float: left;
|
||||
border-radius: 3px;
|
||||
overflow-x: hidden;
|
||||
|
@ -44,10 +89,10 @@ html, body {
|
|||
height: calc(98% - 4px);
|
||||
}
|
||||
.log {
|
||||
background-color: white;
|
||||
background-color: $chat-bg-color;
|
||||
height: calc(100% - 42px);
|
||||
padding: 5px;
|
||||
border: 1px lightgray solid;
|
||||
border: 1px $chat-border-color solid;
|
||||
border-radius: 3px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
|
@ -59,8 +104,7 @@ html, body {
|
|||
float: left;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
background-color: white;
|
||||
margin-right:
|
||||
background-color: $channels-bg-color;
|
||||
}
|
||||
.channel-sub {
|
||||
margin-left: 9px;
|
||||
|
@ -68,7 +112,7 @@ html, body {
|
|||
padding-left: 9px;
|
||||
}
|
||||
.channel-wrapper:nth-last-child(n + 2) > .branch:not(:empty) + .channel-sub {
|
||||
border-left: 1px lightgray solid;
|
||||
border-left: 1px $channel-tree-color solid;
|
||||
}
|
||||
.channel-tree,
|
||||
.user-wrapper {
|
||||
|
@ -84,8 +128,8 @@ html, body {
|
|||
display: block;
|
||||
position: relative;
|
||||
width: 9px;
|
||||
border-left: 1px lightgray solid;
|
||||
border-bottom: 1px lightgray solid;
|
||||
border-left: 1px $channel-tree-color solid;
|
||||
border-bottom: 1px $channel-tree-color solid;
|
||||
height: 14px;
|
||||
}
|
||||
.channel-wrapper:nth-last-child(n + 2) > .channel-tree:after,
|
||||
|
@ -94,7 +138,7 @@ html, body {
|
|||
display: block;
|
||||
position: relative;
|
||||
width: 0px;
|
||||
border-left: 1px lightgray solid;
|
||||
border-left: 1px $channel-tree-color solid;
|
||||
height: 14px;
|
||||
}
|
||||
.user {
|
||||
|
@ -109,12 +153,12 @@ html, body {
|
|||
border: 1px solid transparent;
|
||||
}
|
||||
.selected {
|
||||
background-color: lightblue !important;
|
||||
border: 1px solid gray;
|
||||
background-color: $channel-selected-bg-color !important;
|
||||
border: 1px solid $channel-selected-border-color;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.user:hover,.channel:hover {
|
||||
background-color: lightgray;
|
||||
background-color: $channel-hover-bg-color;
|
||||
}
|
||||
.thisClient {
|
||||
font-weight: bold
|
||||
|
@ -142,8 +186,8 @@ html, body {
|
|||
.tooltip {
|
||||
visibility: hidden;
|
||||
height: 0px;
|
||||
background: white;
|
||||
border: 1px solid gray;
|
||||
background: $tooltip-bg-color;
|
||||
border: 1px solid $tooltip-border-color;
|
||||
margin-top: 16px;
|
||||
margin-left: 30px;
|
||||
padding: 10px;
|
||||
|
@ -162,12 +206,12 @@ html, body {
|
|||
border-radius: 3px;
|
||||
}
|
||||
.toolbar img:hover {
|
||||
border: 1px solid #bbb;
|
||||
background-color: #ddd;
|
||||
border: 1px solid $toolbar-hover-bg-color;
|
||||
background-color: $toolbar-hover-border-color;
|
||||
}
|
||||
.toolbar .tb-active {
|
||||
border: 1px solid #bbb;
|
||||
background-color: white;
|
||||
border: 1px solid $toolbar-active-bg-color;
|
||||
background-color: $toolbar-active-border-color;
|
||||
}
|
||||
.toolbar-horizontal {
|
||||
flex-direction: row;
|
||||
|
@ -195,16 +239,16 @@ html, body {
|
|||
}
|
||||
.toolbar-horizontal .divider {
|
||||
height: 32px;
|
||||
border-left: 1px lightgray solid;
|
||||
border-left: 1px $toolbar-divider-color solid;
|
||||
}
|
||||
.toolbar-vertical .divider {
|
||||
width: 32px;
|
||||
border-top: 1px lightgray solid;
|
||||
border-top: 1px $toolbar-divider-color solid;
|
||||
}
|
||||
.toolbar-horizontal .handle-horizontal {
|
||||
width: auto !important;
|
||||
border: none !important;
|
||||
background-color: #eee !important;
|
||||
background-color: $bg-color !important;
|
||||
}
|
||||
.toolbar-horizontal .handle-vertical {
|
||||
display: none;
|
||||
|
@ -212,7 +256,7 @@ html, body {
|
|||
.toolbar-vertical .handle-vertical {
|
||||
height: auto !important;
|
||||
border: none !important;
|
||||
background-color: #eee !important;
|
||||
background-color: $bg-color !important;
|
||||
}
|
||||
.toolbar-vertical .handle-horizontal {
|
||||
display: none;
|
||||
|
@ -222,16 +266,17 @@ html, body {
|
|||
}
|
||||
.channel-tag {
|
||||
font-weight: bold;
|
||||
color: orange;
|
||||
color: $chat-channel-color;
|
||||
}
|
||||
.user-tag {
|
||||
font-weight: bold;
|
||||
color: green;
|
||||
color: $chat-user-color;
|
||||
}
|
||||
#message-box {
|
||||
width: 100%;
|
||||
border: none;
|
||||
background: none;
|
||||
color: $chat-input-color;
|
||||
margin: 5px 0 5px 0;
|
||||
padding: 0;
|
||||
height: 20px;
|
||||
|
@ -251,9 +296,9 @@ form {
|
|||
width: calc(100% - 10px);
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
background-color: gray;
|
||||
border-bottom: 1px solid darkgray;
|
||||
color: $dialog-header-color;
|
||||
background-color: $dialog-header-bg-color;
|
||||
border-bottom: 1px solid $dialog-header-border-bottom-color;
|
||||
}
|
||||
.dialog-footer {
|
||||
position: absolute;
|
||||
|
@ -270,10 +315,10 @@ form {
|
|||
.dialog-close, .dialog-submit {
|
||||
width: 45%;
|
||||
font-size: 15px;
|
||||
border: 1px gray solid;
|
||||
border: 1px $dialog-button-border-color solid;
|
||||
border-radius: 3px;
|
||||
background-color: white;
|
||||
color: black;
|
||||
background-color: $dialog-button-bg-color;
|
||||
color: $dialog-button-color;
|
||||
padding: 1px;
|
||||
}
|
||||
.connect-dialog table {
|
||||
|
@ -282,8 +327,9 @@ form {
|
|||
}
|
||||
.dialog {
|
||||
position: absolute;
|
||||
background-color: #eee;
|
||||
border: 1px gray solid;
|
||||
background-color: $dialog-bg-color;
|
||||
color: $dialog-color;
|
||||
border: 1px $dialog-border-color solid;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.25);
|
||||
z-index: 20;
|
||||
}
|
||||
|
@ -309,7 +355,7 @@ form {
|
|||
}
|
||||
.settings-dialog .mic-volume-container {
|
||||
height: 10px;
|
||||
border: 3px solid black;
|
||||
border: 3px solid $mic-volume-border-color;
|
||||
}
|
||||
.settings-dialog .mic-volume {
|
||||
height: 100%;
|
||||
|
@ -335,19 +381,19 @@ form {
|
|||
}
|
||||
.connect-dialog input[type=text] {
|
||||
font-size: 15px;
|
||||
border: 1px gray solid;
|
||||
border: 1px $dialog-input-border-color solid;
|
||||
border-radius: 3px;
|
||||
background-color: white;
|
||||
color: black;
|
||||
background-color: $dialog-input-bg-color;
|
||||
color: $dialog-input-color;
|
||||
padding: 2px;
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
.connect-dialog input[type=password] {
|
||||
font-size: 15px;
|
||||
border: 1px gray solid;
|
||||
border: 1px $dialog-input-border-color solid;
|
||||
border-radius: 3px;
|
||||
background-color: white;
|
||||
color: black;
|
||||
background-color: $dialog-input-bg-color;
|
||||
color: $dialog-input-color;
|
||||
padding: 2px;
|
||||
width: calc(100% - 8px);
|
||||
}
|
|
@ -8,6 +8,7 @@ module.exports = {
|
|||
'./app/index.js',
|
||||
'./app/index.html'
|
||||
],
|
||||
theme: './app/theme.js',
|
||||
matrix: './app/matrix.js'
|
||||
},
|
||||
output: {
|
||||
|
@ -51,6 +52,15 @@ module.exports = {
|
|||
'css-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
loaders: [
|
||||
'file-loader?name=[hash].css',
|
||||
'extract-loader',
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /manifest\.json$|\.xml$/,
|
||||
loaders: [
|
||||
|
|
Loading…
Reference in a new issue