kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
				
				
				
			Fix #756: Dark Theme
							rodzic
							
								
									ca5b068a3f
								
							
						
					
					
						commit
						ce093ccc19
					
				|  | @ -0,0 +1 @@ | |||
| Dark theme (#756) | ||||
|  | @ -9,7 +9,7 @@ | |||
|   <title>Funkwhale</title> | ||||
| </head> | ||||
| 
 | ||||
| <body> | ||||
| <body class="theme-light" id="body"> | ||||
|   <noscript> | ||||
|     <strong>We're sorry but Funkwhale doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> | ||||
|   </noscript> | ||||
|  |  | |||
|  | @ -251,6 +251,14 @@ export default { | |||
|       this.$store.dispatch('instance/fetchSettings') | ||||
|       this.fetchNodeInfo() | ||||
|     }, | ||||
|     '$store.state.ui.theme': { | ||||
|       immediate: true, | ||||
|       handler (newValue, oldValue) { | ||||
|         let oldTheme = oldValue || 'light' | ||||
|         document.body.classList.remove(`theme-${oldTheme}`) | ||||
|         document.body.classList.add(`theme-${newValue}`) | ||||
|       }, | ||||
|     }, | ||||
|     '$store.state.auth.authenticated' (newValue) { | ||||
|       if (!newValue) { | ||||
|         this.disconnect() | ||||
|  |  | |||
|  | @ -33,6 +33,14 @@ | |||
|             <a href="https://funkwhale.audio/apps" class="item" target="_blank"><translate translate-context="Footer/*/List item.Link">Mobile and desktop apps</translate></a> | ||||
|             <div role="button" class="item" @click="$emit('show:shortcuts-modal')"><translate translate-context="*/*/*/Noun">Keyboard shortcuts</translate></div> | ||||
|           </div> | ||||
|           <div class="ui form"> | ||||
|             <div class="ui field"> | ||||
|               <label><translate translate-context="Footer/Settings/Dropdown.Label/Short, Verb">Change theme</translate></label> | ||||
|               <select class="ui dropdown" :value="$store.state.ui.theme" @change="$store.commit('ui/theme', $event.target.value)"> | ||||
|                 <option v-for="theme in themes" :key="theme.key" :value="theme.key">{{ theme.name }}</option> | ||||
|               </select> | ||||
|             </div> | ||||
|           </div> | ||||
|         </section> | ||||
|         <section class="four wide column"> | ||||
|           <h4 v-translate translate-context="Footer/*/Link" class="ui header">Getting help</h4> | ||||
|  | @ -76,15 +84,18 @@ export default { | |||
|       parser.href = url | ||||
|       return parser.hostname | ||||
|     }, | ||||
|     themes () { | ||||
|       return [ | ||||
|         { | ||||
|           name: this.$pgettext('Footer/Settings/Dropdown.Label/Theme name', 'Light'), | ||||
|           key: 'light' | ||||
|         }, | ||||
|         { | ||||
|           name: this.$pgettext('Footer/Settings/Dropdown.Label/Theme name', 'Dark'), | ||||
|           key: 'dark' | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| <style scoped> | ||||
| footer p { | ||||
|   color: grey; | ||||
| } | ||||
| 
 | ||||
| footer#footer div.item:hover { | ||||
|   color: rgba(0, 0, 0, 0.87); | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -126,7 +126,4 @@ export default { | |||
| .read > span { | ||||
|   cursor: pointer; | ||||
| } | ||||
| .disabled-row { | ||||
|   color: rgba(40, 40, 40, 0.3); | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -59,12 +59,10 @@ export default { | |||
| 
 | ||||
| <!-- Add "scoped" attribute to limit CSS to this component only --> | ||||
| <style> | ||||
| 
 | ||||
| .playlist.card .header .ellipsis.vertical.large.grey { | ||||
|   font-size: 1.2em; | ||||
|   margin-right: 0; | ||||
| } | ||||
| 
 | ||||
| </style> | ||||
| <style scoped> | ||||
| .card .header { | ||||
|  | @ -72,8 +70,7 @@ export default { | |||
| } | ||||
| 
 | ||||
| .attached.button { | ||||
|   background-color: rgb(243, 244, 245); | ||||
|   background-size: 25% ; | ||||
|   background-size: 25%; | ||||
|   background-repeat: no-repeat; | ||||
|   background-origin: border-box; | ||||
|   background-position: 0 0, 33.33% 0, 66.67% 0, 100% 0; | ||||
|  | @ -82,5 +79,4 @@ export default { | |||
|   font-size: 4em; | ||||
|   box-shadow: 0px 0px 0px 1px rgba(34, 36, 38, 0.15) inset !important; | ||||
| } | ||||
| 
 | ||||
| </style> | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ export default new Vuex.Store({ | |||
|     }), | ||||
|     createPersistedState({ | ||||
|       key: 'ui', | ||||
|       paths: ['ui.currentLanguage', 'ui.momentLocale'] | ||||
|       paths: ['ui.currentLanguage', 'ui.momentLocale', 'ui.theme'] | ||||
|     }), | ||||
|     createPersistedState({ | ||||
|       key: 'radios', | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ export default { | |||
|     maxMessages: 100, | ||||
|     messageDisplayDuration: 10000, | ||||
|     messages: [], | ||||
|     theme: 'light', | ||||
|     notifications: { | ||||
|       inbox: 0, | ||||
|       pendingReviewEdits: 0, | ||||
|  | @ -39,6 +40,9 @@ export default { | |||
|     computeLastDate: (state) => { | ||||
|       state.lastDate = new Date() | ||||
|     }, | ||||
|     theme: (state, value) => { | ||||
|       state.theme = value | ||||
|     }, | ||||
|     addMessage (state, message) { | ||||
|       state.messages.push(message) | ||||
|       if (state.messages.length > state.maxMessages) { | ||||
|  |  | |||
|  | @ -10,6 +10,10 @@ | |||
|   Import this file into your LESS project to use Semantic UI without build tools | ||||
| */ | ||||
| 
 | ||||
| // Those semantic-ui-css/*.scss don't exist in the package, but we create them | ||||
| // via scripts/link-scss-files.sh on postinstall, so we can include theme | ||||
| // under a class namespace | ||||
| 
 | ||||
| /* Global */ | ||||
| @import "~semantic-ui-css/components/reset.css"; | ||||
| // we use our custom site css here to avoid loading google font | ||||
|  | @ -96,6 +100,7 @@ body { | |||
| #app > main, #app > .main { | ||||
|   flex: 1; | ||||
| } | ||||
| 
 | ||||
| .instance-chooser { | ||||
|   margin-top: 2em; | ||||
| } | ||||
|  | @ -126,14 +131,10 @@ body { | |||
|   margin-left: 0; | ||||
|   margin-right: 0; | ||||
|   border: none; | ||||
|   box-shadow: inset 0px -2px 0px 0px rgba(34, 36, 38, 0.15); | ||||
|   .ui.item { | ||||
|     border: none; | ||||
|     border-bottom-style: none; | ||||
|     margin-bottom: 0px; | ||||
|     &.active { | ||||
|       box-shadow: inset 0px -2px 0px 0px #000; | ||||
|     } | ||||
|   } | ||||
|   @include media(">tablet") { | ||||
|     padding: 0 2.5rem; | ||||
|  | @ -148,7 +149,6 @@ body { | |||
|   @include media(">widedesktop") { | ||||
|     left: $widedesktop-sidebar-width; | ||||
|   } | ||||
|   background-color: white; | ||||
|   .item { | ||||
|     padding-top: 1.5em; | ||||
|     padding-bottom: 1.5em; | ||||
|  | @ -208,9 +208,6 @@ body { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| .discrete { | ||||
|   color: rgba(0, 0, 0, 0.87); | ||||
| } | ||||
| .link { | ||||
|   cursor: pointer; | ||||
| } | ||||
|  | @ -355,3 +352,8 @@ input + .help { | |||
| .table td .ui.dropdown { | ||||
|   min-width: 150px; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @import "./themes/_light.scss"; | ||||
| @import "./themes/_dark.scss"; | ||||
|  |  | |||
|  | @ -0,0 +1,222 @@ | |||
| $background-color: rgb(43, 58, 66); | ||||
| $button-hover-color: rgb(33, 48, 56); | ||||
| $light-background-color: rgb(51, 71, 82); | ||||
| $input-background-color: rgb(189, 211, 222); | ||||
| $loading-background-color: rgba(43, 58, 66, 0.9); | ||||
| $text-color: rgb(223, 235, 240); | ||||
| $discrete-text-color: rgba(223, 235, 240, 0.904); | ||||
| $border-color: rgb(63, 88, 102); | ||||
| $light-shadow-color: rgba(223, 235, 240, 0.15); | ||||
| $shadow-color: rgba(63, 102, 97, 0.95); | ||||
| $box-shadow: 0px 1px 3px 0px rgba(63, 88, 102, 0.95), 0px 0px 0px 1px rgba(63, 88, 102, 0.98); | ||||
| $link-color: rgb(255, 144, 0); | ||||
| 
 | ||||
| .theme-dark { | ||||
|   background-color: $background-color; | ||||
|   .ui.labeled.input { | ||||
|     input, .label { | ||||
|       background-color: $input-background-color; | ||||
|       &::placeholder { | ||||
|         color: $light-background-color; | ||||
| 
 | ||||
|       } | ||||
| 
 | ||||
|     } | ||||
|   } | ||||
|   .ui.statistics .statistic { | ||||
|     > .label, > .value { | ||||
|       color: $text-color; | ||||
|     } | ||||
|   } | ||||
|   .ui.link.list.list .active.item, .ui.link.list.list .active.item a:not(.ui) { | ||||
|     color: inherit; | ||||
|   } | ||||
|   .ui.form textarea, .ui.form select, .ui.selection.dropdown, .ui.dropdown.selected, .ui.dropdown .menu .selected.item, .ui.form input:not([type]), .ui.form input[type="date"], .ui.form input[type="datetime-local"], .ui.form input[type="email"], .ui.form input[type="number"], .ui.form input[type="password"], .ui.form input[type="search"], .ui.form input[type="tel"], .ui.form input[type="time"], .ui.form input[type="text"], .ui.form input[type="file"], .ui.form input[type="url"] { | ||||
|     background-color: $input-background-color; | ||||
|     &::placeholder { | ||||
|       color: $light-background-color; | ||||
| 
 | ||||
|     } | ||||
|   } | ||||
|   .ui.dropdown .menu .item:hover { | ||||
|     background-color: $light-background-color; | ||||
|     color: $text-color; | ||||
| 
 | ||||
|   } | ||||
|   .main.pusher > .ui.secondary.menu { | ||||
|     background-color: $background-color; | ||||
|     box-shadow: inset 0px -2px 0px 0px $light-background-color; | ||||
|     .ui.item { | ||||
|       color: $text-color; | ||||
|       &.active { | ||||
|         box-shadow: inset 0px -2px 0px 0px $shadow-color; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   .ui.modal { | ||||
|     > .header, > .content, > .actions { | ||||
|       background-color: $background-color; | ||||
|     } | ||||
|     > .header { | ||||
|       border-bottom: 1px solid $border-color; | ||||
|     } | ||||
| 
 | ||||
|     > .actions { | ||||
|       border-top: 1px solid $border-color; | ||||
|     } | ||||
|   } | ||||
|   main, .main, footer, .modal { | ||||
| 
 | ||||
|     .ui.menu { | ||||
|       background-color: $light-background-color; | ||||
|       .item { | ||||
| 
 | ||||
|         color: $text-color; | ||||
|       } | ||||
|     } | ||||
|     .ui.secondary.menu .dropdown.item:hover, .ui.secondary.menu .link.item:hover, .ui.secondary.menu a.item:hover { | ||||
|       background: $background-color; | ||||
|       color: $text-color; | ||||
|     } | ||||
|     .header, .ui.form .field > label, .sub.header { | ||||
|       color: $text-color; | ||||
|     } | ||||
|     .ui.attached.header { | ||||
|       background-color: transparent; | ||||
|     } | ||||
|     .ui.toggle.checkbox input:checked ~ .box, .ui.toggle.checkbox input:checked ~ label { | ||||
|       color: $text-color !important; | ||||
|     } | ||||
|     .ui.toggle.checkbox .box::before, .ui.toggle.checkbox label::before { | ||||
|       background-color: $light-background-color; | ||||
|     } | ||||
|     a:not(.ui):not(.discrete) { | ||||
|       color: $link-color; | ||||
|     } | ||||
|     .ui.segment:not(.basic) { | ||||
|       background-color: $light-background-color; | ||||
|     } | ||||
|     .ui.list, .ui.dropdown { | ||||
|       .item, div.item, a.item, .button.item { | ||||
|         background-color: $background-color; | ||||
|         color: $discrete-text-color; | ||||
|       } | ||||
|       .selected.item:not(:hover) { | ||||
|         color: $background-color; | ||||
|       } | ||||
|     } | ||||
|     .ui.divided.items > .item:not(:first-child) { | ||||
|       border-top: 1px solid $border-color; | ||||
|     } | ||||
|     .ui.items { | ||||
|       .extra { | ||||
|         color: $discrete-text-color; | ||||
|       } | ||||
|     } | ||||
|     label, .toggle label { | ||||
|       color: $text-color !important; | ||||
|     } | ||||
|     &, .main.pusher, .ui.vertical.segment { | ||||
|       color: $text-color; | ||||
|       background-color: $background-color; | ||||
|     } | ||||
| 
 | ||||
|     .discrete { | ||||
|       color: $discrete-text-color; | ||||
|     } | ||||
| 
 | ||||
|     .ui.table thead th, .ui.table { | ||||
|       color: $text-color; | ||||
|     } | ||||
|     .ui.divider:not(.vertical):not(.horizontal) { | ||||
|       border-top: 1px solid $border-color; | ||||
|       border-bottom: 1px solid $border-color; | ||||
|     } | ||||
|     .ui.cards > .card, .ui.card { | ||||
|       color: $text-color; | ||||
|       background-color: $background-color; | ||||
|       box-shadow: $box-shadow; | ||||
|       .content, .header, .description { | ||||
|         color: $text-color; | ||||
|       } | ||||
|       .extra, .meta { | ||||
|         color: $discrete-text-color; | ||||
|       } | ||||
|     } | ||||
|     .playlist.card { | ||||
|       .attached.button { | ||||
|         background-color: $light-background-color; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // buttons | ||||
|     [class='ui button ui button'], [class='ui button'], [class='ui icon button'], [class='ui fluid button'], [class='ui cancel button'] { | ||||
|       background-color: $light-background-color; | ||||
|       color: $text-color; | ||||
|       &:hover { | ||||
|         background-color: $button-hover-color; | ||||
| 
 | ||||
|       } | ||||
|     } | ||||
|     .ui.buttons > .ui.button:not(.basic):not(.inverted), .ui.buttons:not(.basic):not(.inverted) > .button { | ||||
|       box-shadow: 0px 0px 0px 1px $light-shadow-color inset; | ||||
| 
 | ||||
|     } | ||||
|     .ui.basic.buttons:not(:hover):not(.green):not(.orange):not(.yellow):not(.red) .button, .ui.basic.button { | ||||
|       box-shadow: 0px 0px 0px 1px $text-color inset; | ||||
|       &:not(:hover):not(.green):not(.orange):not(.yellow):not(.red) { | ||||
|         color: $text-color !important; | ||||
|       } | ||||
|     } | ||||
|     .ui.basic.buttons .button, .ui.basic.button { | ||||
|       &:hover { | ||||
|         color: $text-color !important; | ||||
|       } | ||||
| 
 | ||||
|     } | ||||
|     .ui.basic.buttons:not(.green):not(.orange):not(.yellow):not(.red) .button:hover, .ui.basic.button:not(.green):not(.orange):not(.yellow):not(.red):hover, .ui.basic.button:not(.green):not(.orange):not(.yellow):not(.red):active, .ui.basic.button:not(.green):not(.orange):not(.yellow):not(.red):focus { | ||||
|       color: $background-color !important; | ||||
|     } | ||||
|     // loading /dimmers | ||||
|     .ui.loading.form::before { | ||||
|       background-color: $loading-background-color; | ||||
|     } | ||||
|     .ui.inverted.dimmer { | ||||
|       background-color: $loading-background-color; | ||||
|     } | ||||
|     // table | ||||
|     .ui.basic.table tbody tr, .ui.table tr td { | ||||
|       border-bottom: 1px solid $border-color; | ||||
|     } | ||||
|     .ui.table thead th { | ||||
|       border-bottom: 1px solid $border-color; | ||||
|     } | ||||
|     .ui.table { | ||||
|       &:not(.basic) { | ||||
|         &, thead th { | ||||
|           background-color: $light-background-color; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   .ui.link.list.list a.item:hover, .ui.link.list.list .item a:not(.ui):not(.button):hover { | ||||
|     color: $link-color; | ||||
|   } | ||||
|   [data-tooltip]::after { | ||||
|     background-color: $light-background-color; | ||||
|     color: $text-color; | ||||
|   } | ||||
|   .ui.progress > .label { | ||||
|     color: $text-color; | ||||
| 
 | ||||
|   } | ||||
|   i.grey.icon { | ||||
|     color: $text-color !important; | ||||
|   } | ||||
|   input { | ||||
|     &::selection, &::-moz-selection { | ||||
|       background: $background-color; | ||||
|       color: $text-color; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,35 @@ | |||
| 
 | ||||
| 
 | ||||
| .theme-light { | ||||
| 
 | ||||
|   .main.pusher > .ui.secondary.menu { | ||||
|     box-shadow: inset 0px -2px 0px 0px rgba(34, 36, 38, 0.15); | ||||
|     background-color: white; | ||||
|     .ui.item { | ||||
|       &.active { | ||||
|         box-shadow: inset 0px -2px 0px 0px #000; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .discrete { | ||||
|     color: rgba(0, 0, 0, 0.87); | ||||
|   } | ||||
|   .playlist.card { | ||||
|     .attached.button { | ||||
|       background-color: rgb(243, 244, 245); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .disabled-row { | ||||
|     color: rgba(40, 40, 40, 0.3); | ||||
|   } | ||||
|   footer p { | ||||
|     color: grey; | ||||
|   } | ||||
| 
 | ||||
|   footer#footer div.item:hover { | ||||
|     color: rgba(0, 0, 0, 0.87); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Eliot Berriot
						Eliot Berriot