feat: primary color switching now persists

fixed isDarkMode, will need to confirm when we add ocean themes
This commit is contained in:
William Grant 2022-09-26 15:52:31 +10:00
parent e14f4832aa
commit e5bfda37af
11 changed files with 72 additions and 23 deletions

View file

@ -150,6 +150,11 @@ window.readyForUpdates = () => {
ipc.send('ready-for-updates'); ipc.send('ready-for-updates');
}; };
ipc.on('get-primary-color-setting', () => {
const primaryColor = window.Events.getPrimaryColorSetting();
ipc.send('get-success-primary-color-setting', primaryColor);
});
ipc.on('get-theme-setting', () => { ipc.on('get-theme-setting', () => {
const theme = window.Events.getThemeSetting(); const theme = window.Events.getThemeSetting();
ipc.send('get-success-theme-setting', theme); ipc.send('get-success-theme-setting', theme);

View file

@ -9,8 +9,9 @@ import { getTheme } from '../../state/selectors/theme';
import { noop } from 'lodash'; import { noop } from 'lodash';
import { loadEmojiPanelI18n } from '../../util/i18n'; import { loadEmojiPanelI18n } from '../../util/i18n';
import { FixedBaseEmoji, FixedPickerProps } from '../../types/Reaction'; import { FixedBaseEmoji, FixedPickerProps } from '../../types/Reaction';
import { ThemeStateType } from '../../themes/colors.js';
export const StyledEmojiPanel = styled.div<{ isModal: boolean; theme: 'light' | 'dark' }>` export const StyledEmojiPanel = styled.div<{ isModal: boolean; theme: ThemeStateType }>`
padding: var(--margins-lg); padding: var(--margins-lg);
z-index: 5; z-index: 5;
opacity: 0; opacity: 0;
@ -40,15 +41,20 @@ export const StyledEmojiPanel = styled.div<{ isModal: boolean; theme: 'light' |
${props => { ${props => {
switch (props.theme) { switch (props.theme) {
// TODO Theming - Add Ocean Colors case 'ocean-dark':
case 'dark': // TODO Theming
return ``;
case 'ocean-light':
// TODO Theming
return ``;
case 'classic-dark':
return ` return `
--background-rgb: 27, 27, 27; // var(--color-cell-background) --background-rgb: 27, 27, 27; // var(--color-cell-background)
--rgb-background: 27, 27, 27; --rgb-background: 27, 27, 27;
--rgb-color: 255, 255, 255; // var(--color-text) --rgb-color: 255, 255, 255; // var(--color-text)
--rgb-input: 27, 27, 27; --rgb-input: 27, 27, 27;
`; `;
case 'light': case 'classic-light':
default: default:
return ` return `
--background-rgb: 249, 249, 249; // var(--color-cell-background) --background-rgb: 249, 249, 249; // var(--color-cell-background)
@ -97,6 +103,7 @@ const pickerProps: FixedPickerProps = {
export const SessionEmojiPanel = forwardRef<HTMLDivElement, Props>((props: Props, ref) => { export const SessionEmojiPanel = forwardRef<HTMLDivElement, Props>((props: Props, ref) => {
const { onEmojiClicked, show, isModal = false, onKeyDown } = props; const { onEmojiClicked, show, isModal = false, onKeyDown } = props;
const theme = useSelector(getTheme); const theme = useSelector(getTheme);
const emojiPanelTheme = theme.includes('light') ? 'light' : 'dark';
const pickerRef = ref as MutableRefObject<HTMLDivElement>; const pickerRef = ref as MutableRefObject<HTMLDivElement>;
useEffect(() => { useEffect(() => {
@ -113,7 +120,7 @@ export const SessionEmojiPanel = forwardRef<HTMLDivElement, Props>((props: Props
data, data,
ref, ref,
i18n, i18n,
theme, theme: emojiPanelTheme,
onEmojiSelect: onEmojiClicked, onEmojiSelect: onEmojiClicked,
onKeyDown, onKeyDown,
...pickerProps, ...pickerProps,

View file

@ -96,7 +96,7 @@ const generateContactsString = async (
}; };
const Contacts = (contacts: Array<string>, count: number) => { const Contacts = (contacts: Array<string>, count: number) => {
const darkMode = useSelector(getTheme) === 'classic-dark'; const darkMode = useSelector(getTheme).includes('dark');
if (!Boolean(contacts?.length > 0)) { if (!Boolean(contacts?.length > 0)) {
return; return;

View file

@ -67,7 +67,7 @@ export const BanOrUnBanUserDialog = (props: {
const { i18n } = window; const { i18n } = window;
const isBan = banType === 'ban'; const isBan = banType === 'ban';
const dispatch = useDispatch(); const dispatch = useDispatch();
const darkMode = useSelector(getTheme) === 'classic-dark'; const darkMode = useSelector(getTheme).includes('dark');
const convo = getConversationController().get(conversationId); const convo = getConversationController().get(conversationId);
const inputRef = useRef(null); const inputRef = useRef(null);

View file

@ -20,7 +20,7 @@ export const AddModeratorsDialog = (props: Props) => {
const { conversationId } = props; const { conversationId } = props;
const dispatch = useDispatch(); const dispatch = useDispatch();
const darkMode = useSelector(getTheme) === 'classic-dark'; const darkMode = useSelector(getTheme).includes('dark');
const convo = getConversationController().get(conversationId); const convo = getConversationController().get(conversationId);
const [inputBoxValue, setInputBoxValue] = useState(''); const [inputBoxValue, setInputBoxValue] = useState('');

View file

@ -54,7 +54,7 @@ export const ReactClearAllModal = (props: Props): ReactElement => {
const [clearingInProgress, setClearingInProgress] = useState(false); const [clearingInProgress, setClearingInProgress] = useState(false);
const dispatch = useDispatch(); const dispatch = useDispatch();
const darkMode = useSelector(getTheme) === 'classic-dark'; const darkMode = useSelector(getTheme).includes('dark');
const msgProps = useMessageReactsPropsById(messageId); const msgProps = useMessageReactsPropsById(messageId);
if (!msgProps) { if (!msgProps) {

View file

@ -52,6 +52,7 @@ import { getLatestReleaseFromFileServer } from '../../session/apis/file_server_a
import { switchThemeTo } from '../../session/utils/Theme'; import { switchThemeTo } from '../../session/utils/Theme';
import { ThemeStateType } from '../../themes/colors'; import { ThemeStateType } from '../../themes/colors';
import { getTheme } from '../../state/selectors/theme'; import { getTheme } from '../../state/selectors/theme';
import { switchPrimaryColor } from '../../themes/switchPrimaryColor';
const Section = (props: { type: SectionType }) => { const Section = (props: { type: SectionType }) => {
const ourNumber = useSelector(getOurNumber); const ourNumber = useSelector(getOurNumber);
@ -153,6 +154,9 @@ const cleanUpMediasInterval = DURATION.MINUTES * 60;
const fetchReleaseFromFileServerInterval = 1000 * 60; // try to fetch the latest release from the fileserver every minute const fetchReleaseFromFileServerInterval = 1000 * 60; // try to fetch the latest release from the fileserver every minute
const setupTheme = async () => { const setupTheme = async () => {
const primaryColor = window.Events.getPrimaryColorSetting();
await switchPrimaryColor(primaryColor, window?.inboxStore?.dispatch || null);
const theme = window.Events.getThemeSetting(); const theme = window.Events.getThemeSetting();
await switchThemeTo(theme, window?.inboxStore?.dispatch || null); await switchThemeTo(theme, window?.inboxStore?.dispatch || null);
}; };

View file

@ -641,6 +641,8 @@ async function showDebugLogWindow() {
return; return;
} }
// TODO Theming - Use on debug and about pages
const primaryColor = await getPrimaryColorFromMainWindow();
const theme = await getThemeFromMainWindow(); const theme = await getThemeFromMainWindow();
const size = mainWindow.getSize(); const size = mainWindow.getSize();
const options = { const options = {
@ -667,6 +669,7 @@ async function showDebugLogWindow() {
captureClicks(debugLogWindow); captureClicks(debugLogWindow);
// TODO Theming - Check if it needs the priary color
await debugLogWindow.loadURL(prepareURL([getAppRootPath(), 'debug_log.html'], { theme })); await debugLogWindow.loadURL(prepareURL([getAppRootPath(), 'debug_log.html'], { theme }));
debugLogWindow.on('closed', () => { debugLogWindow.on('closed', () => {
@ -1099,6 +1102,15 @@ ipc.on('set-auto-update-setting', async (_event, enabled) => {
} }
}); });
async function getPrimaryColorFromMainWindow() {
return new Promise(resolve => {
ipc.once('get-success-primary-color-setting', (_event, value) => {
resolve(value);
});
mainWindow?.webContents.send('get-primary-color-setting');
});
}
async function getThemeFromMainWindow() { async function getThemeFromMainWindow() {
return new Promise(resolve => { return new Promise(resolve => {
ipc.once('get-success-theme-setting', (_event, value) => { ipc.once('get-success-theme-setting', (_event, value) => {

View file

@ -127,6 +127,10 @@ Storage.onready(async () => {
// These make key operations available to IPC handlers created in preload.js // These make key operations available to IPC handlers created in preload.js
window.Events = { window.Events = {
getPrimaryColorSetting: () => Storage.get('primary-color-setting', 'green'),
setPrimaryColorSetting: async (value: any) => {
await Storage.put('primary-color-setting', value);
},
getThemeSetting: () => Storage.get('theme-setting', 'classic-light'), getThemeSetting: () => Storage.get('theme-setting', 'classic-light'),
setThemeSetting: async (value: any) => { setThemeSetting: async (value: any) => {
await Storage.put('theme-setting', value); await Storage.put('theme-setting', value);

View file

@ -2,7 +2,9 @@ import { Dispatch } from 'redux';
import { applyPrimaryColor } from '../state/ducks/primaryColor'; import { applyPrimaryColor } from '../state/ducks/primaryColor';
import { COLORS, PrimaryColorStateType } from './colors'; import { COLORS, PrimaryColorStateType } from './colors';
export function switchPrimaryColor(color: PrimaryColorStateType, dispatch: Dispatch | null) { export async function switchPrimaryColor(color: PrimaryColorStateType, dispatch: Dispatch | null) {
await window.Events.setPrimaryColorSetting(color);
document.documentElement.style.setProperty( document.documentElement.style.setProperty(
'--primary-color', '--primary-color',
(COLORS.PRIMARY as any)[`${color.toUpperCase()}`] (COLORS.PRIMARY as any)[`${color.toUpperCase()}`]

View file

@ -1,8 +1,13 @@
import { hexColorToRGB } from '../util/hexColorToRGB'; import { hexColorToRGB } from '../util/hexColorToRGB';
import { COLORS, THEMES, ThemeStateType } from './colors'; import { COLORS, PrimaryColorStateType, THEMES, ThemeStateType } from './colors';
function loadClassicLight() { function loadClassicLight(primaryColor?: PrimaryColorStateType) {
document.documentElement.style.setProperty('--primary-color', THEMES.CLASSIC_LIGHT.PRIMARY); document.documentElement.style.setProperty(
'--primary-color',
primaryColor && primaryColor !== THEMES.CLASSIC_LIGHT.PRIMARY
? primaryColor
: THEMES.CLASSIC_LIGHT.PRIMARY
);
document.documentElement.style.setProperty('--danger-color', THEMES.CLASSIC_LIGHT.DANGER); document.documentElement.style.setProperty('--danger-color', THEMES.CLASSIC_LIGHT.DANGER);
document.documentElement.style.setProperty( document.documentElement.style.setProperty(
@ -354,8 +359,13 @@ function loadClassicLight() {
); );
} }
function loadClassicDark() { function loadClassicDark(primaryColor?: PrimaryColorStateType) {
document.documentElement.style.setProperty('--primary-color', THEMES.CLASSIC_DARK.PRIMARY); document.documentElement.style.setProperty(
'--primary-color',
primaryColor && primaryColor !== THEMES.CLASSIC_DARK.PRIMARY
? primaryColor
: THEMES.CLASSIC_DARK.PRIMARY
);
document.documentElement.style.setProperty('--danger-color', THEMES.CLASSIC_DARK.DANGER); document.documentElement.style.setProperty('--danger-color', THEMES.CLASSIC_DARK.DANGER);
document.documentElement.style.setProperty( document.documentElement.style.setProperty(
@ -695,26 +705,31 @@ function loadClassicDark() {
); );
} }
function loadOceanLight() {} function loadOceanLight(primaryColor?: PrimaryColorStateType) {}
function loadOceanDark() {} function loadOceanDark(primaryColor?: PrimaryColorStateType) {}
export async function switchTheme(theme: ThemeStateType) {
const selectedPrimaryColor = await window.Events.getPrimaryColorSetting();
const primaryColor =
(selectedPrimaryColor && (COLORS.PRIMARY as any)[`${selectedPrimaryColor.toUpperCase()}`]) ||
null;
export const switchTheme = (theme: ThemeStateType) => {
switch (theme) { switch (theme) {
case 'classic-light': case 'classic-light':
loadClassicLight(); loadClassicLight(primaryColor);
break; break;
case 'classic-dark': case 'classic-dark':
loadClassicDark(); loadClassicDark(primaryColor);
break; break;
case 'ocean-light': case 'ocean-light':
loadOceanLight(); loadOceanLight(primaryColor);
break; break;
case 'ocean-dark': case 'ocean-dark':
loadOceanDark(); loadOceanDark(primaryColor);
break; break;
default: default:
window.log.warn('Unsupported theme:', theme); window.log.warn('Unsupported theme:', theme);
break; break;
} }
}; }