Add Theme-Switcher for Dark-/Light-Mode
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
a200047352
commit
5c0ea48261
7 changed files with 469 additions and 124 deletions
File diff suppressed because one or more lines are too long
|
@ -9,6 +9,22 @@
|
||||||
<link rel="stylesheet" href="css/all.min.css"/>
|
<link rel="stylesheet" href="css/all.min.css"/>
|
||||||
|
|
||||||
<title>OTS - One Time Secrets</title>
|
<title>OTS - One Time Secrets</title>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.getTheme = () => localStorage.getItem('set-color-scheme') || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark')
|
||||||
|
|
||||||
|
window.refreshTheme = () => {
|
||||||
|
document.querySelector('html').setAttribute('mode', window.getTheme())
|
||||||
|
}
|
||||||
|
|
||||||
|
window.setTheme = (theme) => {
|
||||||
|
localStorage.setItem('set-color-scheme', theme)
|
||||||
|
window.refreshTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Very early load of theme definition to avoid flickering
|
||||||
|
document.addEventListener('DOMContentLoaded', () => window.refreshTheme())
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
27
src/app.vue
27
src/app.vue
|
@ -25,6 +25,14 @@
|
||||||
<b-nav-item @click="newSecret">
|
<b-nav-item @click="newSecret">
|
||||||
<i class="fas fa-plus" /> {{ $t('btn-new-secret') }}
|
<i class="fas fa-plus" /> {{ $t('btn-new-secret') }}
|
||||||
</b-nav-item>
|
</b-nav-item>
|
||||||
|
<b-nav-form class="ml-2">
|
||||||
|
<b-form-checkbox
|
||||||
|
v-model="darkTheme"
|
||||||
|
switch
|
||||||
|
>
|
||||||
|
<i class="fas fa-moon" />​
|
||||||
|
</b-form-checkbox>
|
||||||
|
</b-nav-form>
|
||||||
</b-navbar-nav>
|
</b-navbar-nav>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
</b-navbar>
|
</b-navbar>
|
||||||
|
@ -172,6 +180,7 @@ export default {
|
||||||
securePassword: '',
|
securePassword: '',
|
||||||
secretId: '',
|
secretId: '',
|
||||||
showError: false,
|
showError: false,
|
||||||
|
darkTheme: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -187,8 +196,15 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
darkTheme(to) {
|
||||||
|
window.setTheme(to ? 'dark' : 'light')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// Trigger initialization functions
|
// Trigger initialization functions
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.darkTheme = window.getTheme() === 'dark'
|
||||||
window.onhashchange = this.hashLoad
|
window.onhashchange = this.hashLoad
|
||||||
this.hashLoad()
|
this.hashLoad()
|
||||||
},
|
},
|
||||||
|
@ -269,14 +285,3 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
textarea {
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
color: #2f2f2f;
|
|
||||||
font-size: 0.9em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import BootstrapVue from 'bootstrap-vue'
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
import 'bootstrap/dist/css/bootstrap.css'
|
||||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||||
import 'bootswatch/dist/flatly/bootstrap.css'
|
import './style.scss'
|
||||||
|
|
||||||
import app from './app.vue'
|
import app from './app.vue'
|
||||||
import messages from './langs/langs.js'
|
import messages from './langs/langs.js'
|
||||||
|
|
492
src/package-lock.json
generated
492
src/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -24,9 +24,9 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.21.4",
|
"axios": "^0.21.4",
|
||||||
"bootstrap": "^4.0.0",
|
"bootstrap": "^4.6.0",
|
||||||
"bootstrap-vue": "^2.21.2",
|
"bootstrap-vue": "^2.21.2",
|
||||||
"bootswatch": "^4.0.0",
|
"bootswatch": "^4.6.0",
|
||||||
"gibberish-aes": "^1.0.0",
|
"gibberish-aes": "^1.0.0",
|
||||||
"popper.js": "^1.16.1",
|
"popper.js": "^1.16.1",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
|
|
50
src/style.scss
Normal file
50
src/style.scss
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
:root {
|
||||||
|
|
||||||
|
&[mode="dark"] {
|
||||||
|
@import "node_modules/bootswatch/dist/darkly/bootstrap";
|
||||||
|
|
||||||
|
.custom-control-input:checked ~ .custom-control-label::before {
|
||||||
|
border-color: #333;
|
||||||
|
background-color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
color: #d1d1d1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
/* Force overwrite bright textareas */
|
||||||
|
background-color: rgb(24, 26, 27);
|
||||||
|
border-color: rgb(129, 120, 106);
|
||||||
|
color: rgb(189, 183, 175);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
background-color: rgb(24, 26, 27);
|
||||||
|
border-color: rgb(49, 81, 113);
|
||||||
|
color: rgb(189, 183, 175);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[readonly] {
|
||||||
|
background-color: rgb(24, 26, 27);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[mode="light"] {
|
||||||
|
@import "node_modules/bootswatch/dist/flatly/bootstrap";
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
color: #2f2f2f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
font-family: monospace !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
font-size: 0.9em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue