Add support for System theme - dynamic switching between Light and Dark themes (#405)
* add support for system theme * add EN texts
This commit is contained in:
parent
717a2ace25
commit
eaa57925ff
|
@ -227,6 +227,9 @@
|
|||
"darkLabel": {
|
||||
"message": "Dark"
|
||||
},
|
||||
"systemLabel": {
|
||||
"message": "System"
|
||||
},
|
||||
"buttonStyleLabel": {
|
||||
"message": "Translation button"
|
||||
},
|
||||
|
@ -299,6 +302,9 @@
|
|||
"resultFontColorLabel": {
|
||||
"message": "Font color of translation result"
|
||||
},
|
||||
"isOverrideColorsLabel": {
|
||||
"message": "Override default colors with colors below"
|
||||
},
|
||||
"candidateFontColorLabel": {
|
||||
"message": "Font color of translation candidates"
|
||||
},
|
||||
|
@ -782,4 +788,4 @@
|
|||
"lang_zh": {
|
||||
"message": "Chinese"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import React, { Component } from "react";
|
|||
import ReactDOM from "react-dom";
|
||||
import { getSettings } from "src/settings/settings";
|
||||
import "../styles/TranslatePanel.scss";
|
||||
import { getBackgroundColor, getCandidateFontColor, getResultFontColor } from "../../settings/defaultColors";
|
||||
|
||||
const splitLine = text => {
|
||||
const regex = /(\n)/g;
|
||||
|
@ -173,17 +174,17 @@ export default class TranslatePanel extends Component {
|
|||
top: this.state.panelPosition.y,
|
||||
left: this.state.panelPosition.x,
|
||||
fontSize: parseInt(getSettings("fontSize")),
|
||||
backgroundColor: getSettings("bgColor")
|
||||
};
|
||||
|
||||
const backgroundColor = getBackgroundColor()
|
||||
if (backgroundColor) {
|
||||
panelStyles.backgroundColor = backgroundColor.backgroundColor
|
||||
}
|
||||
|
||||
const wrapperStyles = {
|
||||
overflow: this.state.isOverflow ? "auto" : "hidden"
|
||||
};
|
||||
const resultStyles = {
|
||||
color: getSettings("resultFontColor")
|
||||
};
|
||||
const candidateStyles = {
|
||||
color: getSettings("candidateFontColor")
|
||||
};
|
||||
|
||||
const translationApi = getSettings("translationApi");
|
||||
|
||||
return (
|
||||
|
@ -195,10 +196,10 @@ export default class TranslatePanel extends Component {
|
|||
<div className="simple-translate-result-wrapper" ref="wrapper" style={wrapperStyles}>
|
||||
<div className="simple-translate-move" draggable="true" ref="move"></div>
|
||||
<div className="simple-translate-result-contents">
|
||||
<p className="simple-translate-result" style={resultStyles} dir="auto">
|
||||
<p className="simple-translate-result" style={getResultFontColor()} dir="auto">
|
||||
{splitLine(resultText)}
|
||||
</p>
|
||||
<p className="simple-translate-candidate" style={candidateStyles} dir="auto">
|
||||
<p className="simple-translate-candidate" style={getCandidateFontColor()} dir="auto">
|
||||
{splitLine(candidateText)}
|
||||
</p>
|
||||
{isError && (
|
||||
|
|
|
@ -216,7 +216,9 @@ const showTranslateContainer = (
|
|||
if (element) return;
|
||||
if (!isEnabled) return;
|
||||
|
||||
document.body.insertAdjacentHTML("beforeend", "<div id='simple-translate'></div>");
|
||||
const themeClass = getSettings("theme") + "-theme";
|
||||
|
||||
document.body.insertAdjacentHTML("beforeend", `<div id="simple-translate" class="${themeClass}"></div>`);
|
||||
ReactDOM.render(
|
||||
<TranslateContainer
|
||||
removeContainer={removeTranslatecontainer}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#simple-translate {
|
||||
.simple-translate-button {
|
||||
all: initial;
|
||||
background-color: #fff;
|
||||
background-color: var(--simple-translate-main-bg);
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
|
||||
border-radius: 10%;
|
||||
background-size: 75%;
|
||||
|
|
|
@ -5,10 +5,35 @@
|
|||
}
|
||||
position: absolute;
|
||||
|
||||
--simple-translate-main-text: #0c0c0d;
|
||||
--simple-translate-sub-text: #737373;
|
||||
--simple-translate-line: #ededf0;
|
||||
--simple-translate-button: #d7d7db;
|
||||
--simple-translate-highlight: #5595ff;
|
||||
}
|
||||
|
||||
.light-theme {
|
||||
--simple-translate-main-text: #0c0c0d;
|
||||
--simple-translate-sub-text: #737373;
|
||||
--simple-translate-main-bg: #ffffff;
|
||||
}
|
||||
|
||||
.dark-theme {
|
||||
--simple-translate-main-text: #e6e6e6;
|
||||
--simple-translate-sub-text: #aaaaaa;
|
||||
--simple-translate-main-bg: #181818;
|
||||
}
|
||||
|
||||
// copy of .light-theme
|
||||
.system-theme {
|
||||
--simple-translate-main-text: #000000;
|
||||
--simple-translate-sub-text: #737373;
|
||||
--simple-translate-main-bg: #ffffff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
// copy of .dark-theme
|
||||
.system-theme {
|
||||
--simple-translate-main-text: #e6e6e6;
|
||||
--simple-translate-sub-text: #aaaaaa;
|
||||
--simple-translate-main-bg: #181818;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
all: initial;
|
||||
display: block;
|
||||
margin: 0;
|
||||
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans", "Roboto", "Arial",
|
||||
"Helvetica", sans-serif !important;
|
||||
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans",
|
||||
"Roboto", "Arial", "Helvetica", sans-serif !important;
|
||||
word-wrap: break-word;
|
||||
font-size: inherit;
|
||||
line-height: 150%;
|
||||
|
@ -62,11 +62,11 @@
|
|||
background: var(--simple-translate-line);
|
||||
}
|
||||
|
||||
&.simple-translate-result {
|
||||
.simple-translate-result {
|
||||
color: var(--simple-translate-main-text);
|
||||
}
|
||||
&.simple-translate-candidate,
|
||||
&.simple-translate-error {
|
||||
.simple-translate-candidate,
|
||||
.simple-translate-error {
|
||||
color: var(--simple-translate-sub-text);
|
||||
margin-top: 1em;
|
||||
&:empty {
|
||||
|
|
|
@ -9,11 +9,16 @@ import "../styles/OptionsPage.scss";
|
|||
|
||||
const setupTheme = async () => {
|
||||
await initSettings();
|
||||
document.body.dataset.theme = getSettings("theme");
|
||||
document.body.classList.add(getSettings("theme") + "-theme");
|
||||
|
||||
browser.storage.onChanged.addListener((changes) => {
|
||||
if (changes.Settings.newValue.theme === changes.Settings.oldValue.theme) return;
|
||||
document.body.dataset.theme = changes.Settings.newValue.theme;
|
||||
if (changes.Settings.newValue.theme === changes.Settings.oldValue.theme)
|
||||
return;
|
||||
|
||||
document.body.classList.replace(
|
||||
changes.Settings.oldValue.theme + "-theme",
|
||||
changes.Settings.newValue.theme + "-theme"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
body {
|
||||
background-color: var(--main-bg);
|
||||
|
||||
.light-theme {
|
||||
--main-text: #0c0c0d;
|
||||
--sub-text: #737373;
|
||||
--line: #ededf0;
|
||||
|
@ -9,8 +7,32 @@ body {
|
|||
--main-bg: #ffffff;
|
||||
--sub-bg: #ffffff;
|
||||
--new: #ff4f4f;
|
||||
}
|
||||
|
||||
&[data-theme="dark"] {
|
||||
.dark-theme {
|
||||
--main-text: #e6e6e6;
|
||||
--sub-text: #aaaaaa;
|
||||
--line: #373737;
|
||||
--button: #929292;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #181818;
|
||||
--sub-bg: #101010;
|
||||
--new: #ed5f5f;
|
||||
}
|
||||
|
||||
.system-theme {
|
||||
--main-text: #0c0c0d;
|
||||
--sub-text: #737373;
|
||||
--line: #ededf0;
|
||||
--button: #d7d7db;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #ffffff;
|
||||
--sub-bg: #ffffff;
|
||||
--new: #ff4f4f;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.system-theme {
|
||||
--main-text: #e6e6e6;
|
||||
--sub-text: #aaaaaa;
|
||||
--line: #373737;
|
||||
|
@ -22,9 +44,13 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--main-bg);
|
||||
}
|
||||
|
||||
.optionsPage {
|
||||
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans", "Roboto", "Arial", "Helvetica",
|
||||
sans-serif;
|
||||
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans", "Roboto",
|
||||
"Arial", "Helvetica", sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
color: var(--main-text);
|
||||
|
|
|
@ -10,6 +10,7 @@ import InputArea from "./InputArea";
|
|||
import ResultArea from "./ResultArea";
|
||||
import Footer from "./Footer";
|
||||
import "../styles/PopupPage.scss";
|
||||
import { getBackgroundColor } from "../../settings/defaultColors";
|
||||
|
||||
const logDir = "popup/PopupPage";
|
||||
|
||||
|
@ -58,7 +59,8 @@ export default class PopupPage extends Component {
|
|||
overWriteLogLevel();
|
||||
updateLogLevel();
|
||||
|
||||
document.body.dataset.theme = getSettings("theme");
|
||||
this.themeClass = getSettings("theme") + "-theme";
|
||||
document.body.classList.add(this.themeClass)
|
||||
const targetLang = getSettings("targetLang");
|
||||
let langHistory = getSettings("langHistory");
|
||||
if (!langHistory) {
|
||||
|
|
|
@ -1,11 +1,71 @@
|
|||
.light-theme {
|
||||
--main-text: #0c0c0d;
|
||||
--sub-text: #737373;
|
||||
--line: #ededf0;
|
||||
--button: #d7d7db;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #ffffff;
|
||||
--confirm: #ff4f4f;
|
||||
--error: #d70022;
|
||||
--warn: #ff8f00;
|
||||
--success: #058b00;
|
||||
--info: #0a84ff;
|
||||
}
|
||||
|
||||
.dark-theme {
|
||||
--main-text: #e6e6e6;
|
||||
--sub-text: #aaaaaa;
|
||||
--line: #373737;
|
||||
--button: #929292;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #181818;
|
||||
--highlight-bg: #2e4343;
|
||||
--confirm: #ed5f5f;
|
||||
--error: #ca1532;
|
||||
--warn: #ee8e12;
|
||||
--success: #2a9c26;
|
||||
--info: #1471d0;
|
||||
}
|
||||
|
||||
.system-theme {
|
||||
--main-text: #0c0c0d;
|
||||
--sub-text: #737373;
|
||||
--line: #ededf0;
|
||||
--button: #d7d7db;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #ffffff;
|
||||
--confirm: #ff4f4f;
|
||||
--error: #d70022;
|
||||
--warn: #ff8f00;
|
||||
--success: #058b00;
|
||||
--info: #0a84ff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.system-theme {
|
||||
--main-text: #e6e6e6;
|
||||
--sub-text: #aaaaaa;
|
||||
--line: #373737;
|
||||
--button: #929292;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #181818;
|
||||
--highlight-bg: #2e4343;
|
||||
--confirm: #ed5f5f;
|
||||
--error: #ca1532;
|
||||
--warn: #ee8e12;
|
||||
--success: #2a9c26;
|
||||
--info: #1471d0;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans", "Roboto", "Arial", "Helvetica",
|
||||
sans-serif;
|
||||
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans", "Roboto",
|
||||
"Arial", "Helvetica", sans-serif;
|
||||
font-size: 13px;
|
||||
width: 100%;
|
||||
min-width: 348px;
|
||||
|
@ -26,31 +86,4 @@ body {
|
|||
::-moz-selection {
|
||||
background: var(--line);
|
||||
}
|
||||
|
||||
--main-text: #0c0c0d;
|
||||
--sub-text: #737373;
|
||||
--line: #ededf0;
|
||||
--button: #d7d7db;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #ffffff;
|
||||
--confirm: #ff4f4f;
|
||||
--error: #d70022;
|
||||
--warn: #ff8f00;
|
||||
--success: #058b00;
|
||||
--info: #0a84ff;
|
||||
|
||||
&[data-theme="dark"] {
|
||||
--main-text: #e6e6e6;
|
||||
--sub-text: #aaaaaa;
|
||||
--line: #373737;
|
||||
--button: #929292;
|
||||
--highlight: #5595ff;
|
||||
--main-bg: #181818;
|
||||
--highlight-bg: #2e4343;
|
||||
--confirm: #ed5f5f;
|
||||
--error: #ca1532;
|
||||
--warn: #ee8e12;
|
||||
--success: #2a9c26;
|
||||
--info: #1471d0;
|
||||
}
|
||||
}
|
||||
|
|
41
src/settings/defaultColors.js
Normal file
41
src/settings/defaultColors.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { getSettings } from "./settings";
|
||||
|
||||
export const RESULT_FONT_COLOR_LIGHT = "#000000";
|
||||
export const RESULT_FONT_COLOR_DARK = "#e6e6e6";
|
||||
export const CANDIDATE_FONT_COLOR_LIGHT = "#737373";
|
||||
export const CANDIDATE_FONT_COLOR_DARK = "#aaaaaa";
|
||||
export const BG_COLOR_LIGHT = "#ffffff";
|
||||
export const BG_COLOR_DARK = "#181818";
|
||||
|
||||
/**
|
||||
* Return style object if color override is enabled
|
||||
*/
|
||||
export function getResultFontColor() {
|
||||
const isOverrideColors = getSettings("isOverrideColors");
|
||||
|
||||
if (!isOverrideColors) return undefined;
|
||||
|
||||
return { color: getSettings("resultFontColor") };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return style object if color override is enabled
|
||||
*/
|
||||
export function getCandidateFontColor() {
|
||||
const isOverrideColors = getSettings("isOverrideColors");
|
||||
|
||||
if (!isOverrideColors) return undefined;
|
||||
|
||||
return { color: getSettings("candidateFontColor") };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return style object if color override is enabled
|
||||
*/
|
||||
export function getBackgroundColor() {
|
||||
const isOverrideColors = getSettings("isOverrideColors");
|
||||
|
||||
if (!isOverrideColors) return undefined;
|
||||
|
||||
return { backgroundColor: getSettings("bgColor") };
|
||||
}
|
|
@ -2,6 +2,14 @@ import React from "react";
|
|||
import browser from "webextension-polyfill";
|
||||
import generateLangOptions from "src/common/generateLangOptions";
|
||||
import { getSettings, setSettings } from "./settings";
|
||||
import {
|
||||
RESULT_FONT_COLOR_LIGHT,
|
||||
RESULT_FONT_COLOR_DARK,
|
||||
CANDIDATE_FONT_COLOR_LIGHT,
|
||||
CANDIDATE_FONT_COLOR_DARK,
|
||||
BG_COLOR_LIGHT,
|
||||
BG_COLOR_DARK
|
||||
} from "./defaultColors"
|
||||
|
||||
const getDefaultLangs = () => {
|
||||
const uiLang = browser.i18n.getUILanguage();
|
||||
|
@ -300,7 +308,7 @@ export default [
|
|||
title: "themeLabel",
|
||||
captions: ["themeCaptionLabel"],
|
||||
type: "select",
|
||||
default: getTheme(),
|
||||
default: 'system',
|
||||
options: [
|
||||
{
|
||||
name: "lightLabel",
|
||||
|
@ -309,6 +317,10 @@ export default [
|
|||
{
|
||||
name: "darkLabel",
|
||||
value: "dark"
|
||||
},
|
||||
{
|
||||
name: "systemLabel",
|
||||
value: "system"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -479,27 +491,40 @@ export default [
|
|||
default: 10,
|
||||
placeholder: 10
|
||||
},
|
||||
{
|
||||
id: "isOverrideColors",
|
||||
title: "isOverrideColorsLabel",
|
||||
captions: [],
|
||||
type: "checkbox",
|
||||
default: false
|
||||
},
|
||||
{
|
||||
id: "resultFontColor",
|
||||
title: "resultFontColorLabel",
|
||||
captions: [],
|
||||
type: "color",
|
||||
default: getTheme() === "light" ? "#000000" : "#e6e6e6"
|
||||
default:
|
||||
getTheme() === "light"
|
||||
? RESULT_FONT_COLOR_LIGHT
|
||||
: RESULT_FONT_COLOR_DARK,
|
||||
},
|
||||
{
|
||||
id: "candidateFontColor",
|
||||
title: "candidateFontColorLabel",
|
||||
captions: [],
|
||||
type: "color",
|
||||
default: getTheme() === "light" ? "#737373" : "#aaaaaa"
|
||||
default:
|
||||
getTheme() === "light"
|
||||
? CANDIDATE_FONT_COLOR_LIGHT
|
||||
: CANDIDATE_FONT_COLOR_DARK,
|
||||
},
|
||||
{
|
||||
id: "bgColor",
|
||||
title: "bgColorLabel",
|
||||
captions: [],
|
||||
type: "color",
|
||||
default: getTheme() === "light" ? "#ffffff" : "#181818"
|
||||
}
|
||||
default: getTheme() === "light" ? BG_COLOR_LIGHT : BG_COLOR_DARK,
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue