add theme support to browser extension

This commit is contained in:
Kyle Spearrin 2018-05-30 17:26:43 -04:00
parent 7c0d4a1970
commit 344cd2ac40
7 changed files with 162 additions and 6 deletions

2
jslib

@ -1 +1 @@
Subproject commit c71b9703f3a7ca6f791e5f813c418c8ed23855b7
Subproject commit e9228a788813b8da22c71d0b8ddeda5e08702a14

View File

@ -491,6 +491,20 @@
"disableContextMenuItemDesc": {
"message": "Context menu options provide quick access to password generation and logins for the website in your current tab."
},
"theme": {
"message": "Theme"
},
"themeDesc": {
"message": "Change the application's color theme. You must re-open the window."
},
"dark": {
"message": "Dark",
"description": "Dark color"
},
"light": {
"message": "Light",
"description": "Light color"
},
"exportVault": {
"message": "Export Vault"
},
@ -1036,5 +1050,8 @@
},
"remove": {
"message": "Remove"
},
"default": {
"message": "Default"
}
}

View File

@ -1,7 +1,7 @@
@import "variables.scss";
.btn {
background-color: $button-backgound-color;
background-color: $button-background-color;
border-radius: $border-radius;
padding: 7px 15px;
border: 1px solid $button-border-color;
@ -21,7 +21,7 @@
&:hover:not([disabled]) {
cursor: pointer;
background-color: darken($button-backgound-color, 1.5%);
background-color: darken($button-background-color, 1.5%);
border-color: darken($button-border-color, 17%);
color: darken($button-color, 10%);
@ -36,7 +36,7 @@
&:focus:not([disabled]) {
cursor: pointer;
background-color: darken($button-backgound-color, 6%);
background-color: darken($button-background-color, 6%);
border-color: darken($button-border-color, 25%);
outline: 0;
}

View File

@ -31,7 +31,112 @@ $box-background-hover-color: $list-item-hover;
$box-border-color: $border-color;
$button-border-color: darken($border-color-dark, 12%);
$button-backgound-color: white;
$button-background-color: white;
$button-color: lighten($text-color, 40%);
$button-color-primary: darken($brand-primary, 8%);
$button-color-danger: darken($brand-danger, 10%);
$themes: (
light: (
textColor: $text-color,
borderColor: $border-color,
borderColorDark: $border-color-dark,
backgroundColor: $background-color,
backgroundColorAlt: $background-color-alt,
headerBackgroundColor: $brand-primary,
headerBorderColor: darken($brand-primary, 7%),
headerInputBackgroundColor: darken($brand-primary, 8%),
headerInputBackgroundFocusColor: darken($brand-primary, 10%),
headerInputColor: #ffffff,
headerInputPlaceholderColor: lighten($brand-primary, 35%),
listItemBackgroundColor: $background-color,
listItemBackgroundHoverColor: $list-item-hover,
boxBackgroundColor: $box-background-color,
boxBackgroundHoverColor: $box-background-hover-color,
boxBorderColor: $box-border-color,
groupingsActiveColor: darken($background-color-alt, 5%),
disabledIconColor: $list-icon-color,
headingColor: $gray-light,
headingButtonColor: lighten($gray-light, 30%),
headingButtonHoverColor: $gray-light,
labelColor: $gray-light,
mutedColor: $text-muted,
totpStrokeColor: $brand-primary,
boxRowButtonColor: $brand-primary,
boxRowButtonHoverColor: darken($brand-primary, 10%),
inputBorderColor: darken($border-color-dark, 7%),
inputBackgroundColor: #ffffff,
inputPlaceholderColor: lighten($gray-light, 35%),
buttonBackgroundColor: $button-background-color,
buttonBorderColor: $button-border-color,
buttonColor: $button-color,
buttonPrimaryColor: $button-color-primary,
buttonDangerColor: $button-color-danger,
primaryColor: $brand-primary,
primaryAccentColor: $brand-primary-accent,
dangerColor: $brand-danger,
successColor: $brand-success,
infoColor: $brand-info,
warningColor: $brand-warning,
),
dark: (
textColor: #ffffff,
borderColor: #2f2f2f,
borderColorDark: #2f2f2f,
backgroundColor: #363636,
backgroundColorAlt: #3d3d3d,
boxBackgroundColor: #363636,
boxBackgroundHoverColor: #3f3f3f,
boxBorderColor: #2f2f2f,
headerBackgroundColor: #363636,
headerBorderColor: #272727,
headerInputBackgroundColor: #222222,
headerInputBackgroundFocusColor: #1d1d1d,
headerInputColor: #ffffff,
headerInputPlaceholderColor: #707070,
listItemBackgroundColor: #363636,
listItemBackgroundHoverColor: #464646,
groupingsActiveColor: #292929,
disabledIconColor: #c7c7cd,
headingColor: #a3a3a3,
headingButtonColor: #a3a3a3,
headingButtonHoverColor: #ffffff,
labelColor: #a3a3a3,
mutedColor: #a3a3a3,
totpStrokeColor: #cacaca,
boxRowButtonColor: #cacaca,
boxRowButtonHoverColor: #ffffff,
inputBorderColor: #222222,
inputBackgroundColor: #363636,
inputPlaceholderColor: #707070,
buttonBackgroundColor: #363636,
buttonBorderColor: #1f1f1f,
buttonColor: #ffffff,
buttonPrimaryColor: #46ace7,
buttonDangerColor: #ff3e24,
primaryColor: #52bdfb,
primaryAccentColor: #3ea1da,
dangerColor: #ff3e24,
successColor: $brand-success,
infoColor: $brand-info,
warningColor: $brand-warning,
),
);
@mixin themify($themes: $themes) {
@each $theme, $map in $themes {
html.theme_#{$theme} & {
$theme-map: () !global;
@each $key, $submap in $map {
$value: map-get(map-get($themes, $theme), '#{$key}');
$theme-map: map-merge($theme-map, ($key: $value)) !global;
}
@content;
$theme-map: null !global;
}
}
}
@function themed($key) {
@return map-get($theme-map, $key);
}

View File

@ -77,7 +77,13 @@ export function initFactory(i18nService: I18nService, storageService: StorageSer
stateService.save(ConstantsService.disableFaviconKey,
await storageService.get<boolean>(ConstantsService.disableFaviconKey));
let theme = await storageService.get<string>(ConstantsService.themeKey);
if (theme == null) {
theme = 'light';
}
window.document.documentElement.classList.add('locale_' + i18nService.translationLocale);
window.document.documentElement.classList.add('theme_' + theme);
authService.init();
const analytics = new Analytics(window, () => BrowserApi.gaFilter(), null, null, null, () => {

View File

@ -71,4 +71,15 @@
</div>
<div class="box-footer">{{'disableFaviconDesc' | i18n}}</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="theme">{{'theme' | i18n}}</label>
<select id="theme" name="Theme" [(ngModel)]="theme" (change)="saveTheme()">
<option *ngFor="let o of themeOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
</div>
<div class="box-footer">{{'themeDesc' | i18n}}</div>
</div>
</content>

View File

@ -5,6 +5,7 @@ import {
import { Angulartics2 } from 'angulartics2';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { StateService } from 'jslib/abstractions/state.service';
@ -25,10 +26,19 @@ export class OptionsComponent implements OnInit {
disableAddLoginNotification = false;
showDisableContextMenu = true;
disableGa = false;
theme: string;
themeOptions: any[];
constructor(private analytics: Angulartics2, private messagingService: MessagingService,
private platformUtilsService: PlatformUtilsService, private storageService: StorageService,
private stateService: StateService, private totpService: TotpService) { }
private stateService: StateService, private totpService: TotpService,
private i18nService: I18nService) {
this.themeOptions = [
{ name: i18nService.t('default'), value: null },
{ name: i18nService.t('light'), value: 'light' },
{ name: i18nService.t('dark'), value: 'dark' },
];
}
async ngOnInit() {
this.showDisableContextMenu = !this.platformUtilsService.isSafari();
@ -49,6 +59,8 @@ export class OptionsComponent implements OnInit {
this.disableAutoTotpCopy = !await this.totpService.isAutoCopyEnabled();
this.disableFavicon = await this.storageService.get<boolean>(ConstantsService.disableFaviconKey);
this.theme = await this.storageService.get<string>(ConstantsService.themeKey);
}
async saveGa() {
@ -90,6 +102,11 @@ export class OptionsComponent implements OnInit {
this.callAnalytics('Favicon', !this.disableFavicon);
}
async saveTheme() {
await this.storageService.save(ConstantsService.themeKey, this.theme);
this.analytics.eventTrack.next({ action: 'Set Theme ' + this.theme });
}
private callAnalytics(name: string, enabled: boolean) {
const status = enabled ? 'Enabled' : 'Disabled';
this.analytics.eventTrack.next({ action: `${status} ${name}` });