From a4cd571360a4c14fe022e1b251e8da5fc30e0060 Mon Sep 17 00:00:00 2001 From: myxmaster Date: Sat, 11 May 2024 14:49:03 +0200 Subject: [PATCH] set status and navigation bar colors matching theme colors --- App.tsx | 1107 +++++++++++++++++++----------------- package.json | 1 + stores/SettingsStore.ts | 93 +-- utils/ThemeUtils.ts | 676 +++++++++++----------- views/Settings/Display.tsx | 10 +- views/Wallet/Wallet.tsx | 14 +- yarn.lock | 5 + 7 files changed, 1006 insertions(+), 900 deletions(-) diff --git a/App.tsx b/App.tsx index e371db656..3b8815acc 100644 --- a/App.tsx +++ b/App.tsx @@ -4,7 +4,7 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { SafeAreaView } from 'react-native-safe-area-context'; -import { BackHandler, NativeEventSubscription } from 'react-native'; +import { BackHandler, NativeEventSubscription, StatusBar } from 'react-native'; import Stores from './stores/Stores'; import NavigationService from './NavigationService'; @@ -145,7 +145,7 @@ import CustodialWalletWarning from './views/Settings/CustodialWalletWarning'; import PSBT from './views/PSBT'; import TxHex from './views/TxHex'; -import { themeColor } from './utils/ThemeUtils'; +import { isLightTheme, themeColor } from './utils/ThemeUtils'; export default class App extends React.PureComponent { private backPressListenerSubscription: NativeEventSubscription; @@ -203,532 +203,591 @@ export default class App extends React.PureComponent { {() => ( - { - if (nav != null) { - NavigationService.setTopLevelNavigator( - nav - ); + <> + + { + if (nav != null) { + NavigationService.setTopLevelNavigator( + nav + ); + } + }} + theme={{ + dark: true, + colors: { + background: + themeColor( + 'background' + ), + border: themeColor( 'background' ), - border: themeColor( - 'background' - ), - card: themeColor( - 'background' - ), - notification: - themeColor('text'), - primary: - themeColor('highlight'), - text: themeColor('text') - } - }} - > - ({ - headerShown: false, - animation: ( - route.params as any - )?.animation - })} - screenListeners={({ - navigation - }) => ({ - focus: () => { - this.backPressListenerSubscription?.remove(); - this.backPressListenerSubscription = - BackHandler.addEventListener( - 'hardwareBackPress', - () => - this.handleBackPress( - navigation - ) - ); - }, - blur: () => - this.backPressListenerSubscription?.remove() - })} - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + }} + > + ({ + headerShown: false, + animation: ( + route.params as any + )?.animation + })} + screenListeners={({ + navigation + }) => ({ + focus: () => { + this.backPressListenerSubscription?.remove(); + this.backPressListenerSubscription = + BackHandler.addEventListener( + 'hardwareBackPress', + () => + this.handleBackPress( + navigation + ) + ); + }, + blur: () => + this.backPressListenerSubscription?.remove() + })} + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + )} diff --git a/package.json b/package.json index beebe073e..1d075f68a 100644 --- a/package.json +++ b/package.json @@ -131,6 +131,7 @@ "react-native-status-bar-height": "2.6.0", "react-native-svg": "14.1.0", "react-native-svg-transformer": "1.3.0", + "react-native-system-navigation-bar": "2.6.4", "react-native-tcp": "aprock/react-native-tcp#be5f656", "react-native-tor": "0.1.8", "react-native-udp": "4.1.7", diff --git a/stores/SettingsStore.ts b/stores/SettingsStore.ts index c8197977e..5625f1fd3 100644 --- a/stores/SettingsStore.ts +++ b/stores/SettingsStore.ts @@ -2,6 +2,7 @@ import { action, observable } from 'mobx'; import { BiometryType } from 'react-native-biometrics'; import ReactNativeBlobUtil from 'react-native-blob-util'; import EncryptedStorage from 'react-native-encrypted-storage'; +import isEqual from 'lodash/isEqual'; import BackendUtils from '../utils/BackendUtils'; import { localeString } from '../utils/LocaleUtils'; @@ -1231,33 +1232,33 @@ export default class SettingsStore { // Retrieve the settings const settings = await EncryptedStorage.getItem(STORAGE_KEY); if (settings) { - this.settings = JSON.parse(settings); - if (!this.settings.fiatRatesSource) { - this.settings.fiatRatesSource = DEFAULT_FIAT_RATES_SOURCE; + const newSettings = JSON.parse(settings); + if (!newSettings.fiatRatesSource) { + newSettings.fiatRatesSource = DEFAULT_FIAT_RATES_SOURCE; } // migrate fiat settings from older versions - if (!this.settings.fiat || this.settings.fiat === 'Disabled') { - this.settings.fiat = DEFAULT_FIAT; - this.settings.fiatEnabled = false; - } else if (this.settings.fiatEnabled == null) { - this.settings.fiatEnabled = true; + if (!newSettings.fiat || newSettings.fiat === 'Disabled') { + newSettings.fiat = DEFAULT_FIAT; + newSettings.fiatEnabled = false; + } else if (newSettings.fiatEnabled == null) { + newSettings.fiatEnabled = true; } // set default LSPs if not defined - if (this.settings.enableLSP === undefined) { - this.settings.enableLSP = true; + if (newSettings.enableLSP === undefined) { + newSettings.enableLSP = true; } - if (!this.settings.lspMainnet) { - this.settings.lspMainnet = DEFAULT_LSP_MAINNET; + if (!newSettings.lspMainnet) { + newSettings.lspMainnet = DEFAULT_LSP_MAINNET; } - if (!this.settings.lspTestnet) { - this.settings.lspTestnet = DEFAULT_LSP_TESTNET; + if (!newSettings.lspTestnet) { + newSettings.lspTestnet = DEFAULT_LSP_TESTNET; } // default Lightning Address settings - if (!this.settings.lightningAddress) { - this.settings.lightningAddress = { + if (!newSettings.lightningAddress) { + newSettings.lightningAddress = { enabled: false, automaticallyAccept: true, automaticallyAcceptAttestationLevel: 2, @@ -1272,11 +1273,11 @@ export default class SettingsStore { // migrate locale to ISO 639-1 if ( - this.settings.locale != null && - localeMigrationMapping[this.settings.locale] + newSettings.locale != null && + localeMigrationMapping[newSettings.locale] ) { - this.settings.locale = - localeMigrationMapping[this.settings.locale]; + newSettings.locale = + localeMigrationMapping[newSettings.locale]; } // TODO PEGASUS @@ -1284,12 +1285,12 @@ export default class SettingsStore { const MOD_KEY = 'beta5-mod'; const mod = await EncryptedStorage.getItem(MOD_KEY); if (!mod) { - this.settings.expressGraphSync = true; - if (this.settings.payments) { - this.settings.payments.defaultFeePercentage = '5.0'; - this.settings.payments.defaultFeeFixed = '1000'; + newSettings.expressGraphSync = true; + if (newSettings.payments) { + newSettings.payments.defaultFeePercentage = '5.0'; + newSettings.payments.defaultFeeFixed = '1000'; } else { - this.settings.payments = { + newSettings.payments = { defaultFeeMethod: 'fixed', // deprecated defaultFeePercentage: '5.0', defaultFeeFixed: '1000', @@ -1297,8 +1298,8 @@ export default class SettingsStore { preferredMempoolRate: 'fastestFee' }; } - this.settings.automaticDisasterRecoveryBackup = true; - this.setSettings(JSON.stringify(this.settings)); + newSettings.automaticDisasterRecoveryBackup = true; + this.setSettings(JSON.stringify(newSettings)); await EncryptedStorage.setItem(MOD_KEY, 'true'); } @@ -1306,18 +1307,18 @@ export default class SettingsStore { const mod2 = await EncryptedStorage.getItem(MOD_KEY2); if (!mod2) { if ( - this.settings?.lspMainnet === + newSettings?.lspMainnet === 'https://lsp-preview.lnolymp.us' ) { - this.settings.lspMainnet = DEFAULT_LSP_MAINNET; + newSettings.lspMainnet = DEFAULT_LSP_MAINNET; } if ( - this.settings?.lspTestnet === + newSettings?.lspTestnet === 'https://testnet-lsp.lnolymp.us' ) { - this.settings.lspTestnet = DEFAULT_LSP_TESTNET; + newSettings.lspTestnet = DEFAULT_LSP_TESTNET; } - this.setSettings(JSON.stringify(this.settings)); + this.setSettings(JSON.stringify(newSettings)); await EncryptedStorage.setItem(MOD_KEY2, 'true'); } @@ -1332,34 +1333,38 @@ export default class SettingsStore { 'noad.sathoarder.com' ]; if ( - JSON.stringify(this.settings?.neutrinoPeersMainnet) === + JSON.stringify(newSettings?.neutrinoPeersMainnet) === JSON.stringify(neutrinoPeersMainnetOld) ) { - this.settings.neutrinoPeersMainnet = + newSettings.neutrinoPeersMainnet = DEFAULT_NEUTRINO_PEERS_MAINNET; } - this.setSettings(JSON.stringify(this.settings)); + this.setSettings(JSON.stringify(newSettings)); await EncryptedStorage.setItem(MOD_KEY3, 'true'); } // migrate old POS squareEnabled setting to posEnabled - if (this.settings?.pos?.squareEnabled) { - this.settings.pos.posEnabled = PosEnabled.Square; - this.settings.pos.squareEnabled = false; + if (newSettings?.pos?.squareEnabled) { + newSettings.pos.posEnabled = PosEnabled.Square; + newSettings.pos.squareEnabled = false; } - if (!this.settings.neutrinoPeersMainnet) { - this.settings.neutrinoPeersMainnet = + if (!newSettings.neutrinoPeersMainnet) { + newSettings.neutrinoPeersMainnet = DEFAULT_NEUTRINO_PEERS_MAINNET; } - if (!this.settings.neutrinoPeersTestnet) { - this.settings.neutrinoPeersTestnet = + if (!newSettings.neutrinoPeersTestnet) { + newSettings.neutrinoPeersTestnet = DEFAULT_NEUTRINO_PEERS_TESTNET; } + if (!isEqual(this.settings, newSettings)) { + this.settings = newSettings; + } + const node: any = - this.settings.nodes?.length && - this.settings.nodes[this.settings.selectedNode || 0]; + newSettings.nodes?.length && + newSettings.nodes[newSettings.selectedNode || 0]; if (node) { this.host = node.host; this.port = node.port; diff --git a/utils/ThemeUtils.ts b/utils/ThemeUtils.ts index 97ca04189..17ae2eee6 100644 --- a/utils/ThemeUtils.ts +++ b/utils/ThemeUtils.ts @@ -1,355 +1,349 @@ import stores from '../stores/Stores'; -export function themeColor(themeString: string): any { - const { settings } = stores.settingsStore; - const theme = settings.display && settings.display.theme; +const Kyriaki: { [key: string]: any } = { + generalStyle: 'dark', + background: '#1E2022', + secondary: '#31363F', + text: 'white', + secondaryText: '#A7A9AC', + highlight: '#FFA900', + error: '#992600', + separator: '#31363F', + outbound: '#FFA900', + inbound: '#FFF0CA', + success: '#46BE43', + warning: '#E14C4C', + bitcoin: '#FFB040', + delete: '#992600', + bolt: '#FFF', + chain: '#FFF', + disabled: '#767577', + buttonBackground: '#FFA900', + buttonGradient: ['#FF9000', '#FFA900'], + buttonText: '#000000', + buttonTextSecondary: 'gray', + qr: '#000', + qrBackground: '#FFA900', + qrLogoBackground: '#FFA900', + qrFrame: '#FFD93F', + action: '#FFF' +}; - const Kyriaki: { [key: string]: any } = { - generalStyle: 'dark', - background: '#1E2022', - secondary: '#31363F', - text: 'white', - secondaryText: '#A7A9AC', - highlight: '#FFA900', - error: '#992600', - separator: '#31363F', - outbound: '#FFA900', - inbound: '#FFF0CA', - success: '#46BE43', - warning: '#E14C4C', - bitcoin: '#FFB040', - delete: '#992600', - bolt: '#FFF', - chain: '#FFF', - disabled: '#767577', - buttonBackground: '#FFA900', - buttonGradient: ['#FF9000', '#FFA900'], - buttonText: '#000000', - buttonTextSecondary: 'gray', - qr: '#000', - qrBackground: '#FFA900', - qrLogoBackground: '#FFA900', - qrFrame: '#FFD93F', - action: '#FFF' - }; +const Light: { [key: string]: any } = { + generalStyle: 'light', + background: '#fff', + secondary: '#f0f0f0', + text: 'black', + secondaryText: '#8a8999', + buttonText: 'black', + highlight: 'orange', + error: '#cc3300', + separator: '#CED0CE', + outbound: '#FFD93F', + inbound: '#FFF0CA', + success: '#46BE43', + warning: '#E14C4C', + bitcoin: '#FFB040', + delete: '#cc3300', + qrFrame: '#FFD93F', + bolt: '#FFD93F', + chain: '#FFD93F', + disabled: '#767577' + // TODO: pick outbound and inbound colors for light and junkie themes + // TODO: success / warning / bitcoin colors for light and junkie (are they just the same?) +}; - const Light: { [key: string]: any } = { - generalStyle: 'light', - background: '#fff', - secondary: '#f0f0f0', - text: 'black', - secondaryText: '#8a8999', - buttonText: 'black', - highlight: 'orange', - error: '#cc3300', - separator: '#CED0CE', - outbound: '#FFD93F', - inbound: '#FFF0CA', - success: '#46BE43', - warning: '#E14C4C', - bitcoin: '#FFB040', - delete: '#cc3300', - qrFrame: '#FFD93F', - bolt: '#FFD93F', - chain: '#FFD93F', - disabled: '#767577' - // TODO: pick outbound and inbound colors for light and junkie themes - // TODO: success / warning / bitcoin colors for light and junkie (are they just the same?) - }; +const Dark: { [key: string]: any } = { + generalStyle: 'dark', + background: '#1F242D', + secondary: '#31363F', + text: 'white', + secondaryText: '#A7A9AC', + highlight: '#ffd24b', + error: '#992600', + separator: '#31363F', + outbound: '#FFD93F', + inbound: '#FFF0CA', + success: '#46BE43', + warning: '#E14C4C', + bitcoin: '#FFB040', + delete: '#992600', + qrFrame: '#FFD93F', + bolt: '#FFD93F', + chain: '#FFD93F', + disabled: '#767577', + invertQrIcons: false, + buttonText: '#FFF' +}; - const Dark: { [key: string]: any } = { - generalStyle: 'dark', - background: '#1F242D', - secondary: '#31363F', - text: 'white', - secondaryText: '#A7A9AC', - highlight: '#ffd24b', - error: '#992600', - separator: '#31363F', - outbound: '#FFD93F', - inbound: '#FFF0CA', - success: '#46BE43', - warning: '#E14C4C', - bitcoin: '#FFB040', - delete: '#992600', - qrFrame: '#FFD93F', - bolt: '#FFD93F', - chain: '#FFD93F', - disabled: '#767577', - invertQrIcons: false, - buttonText: '#FFF' - }; +const Junkie: { [key: string]: any } = { + generalStyle: 'dark', + background: 'rgb(51, 51, 51)', + secondary: 'rgb(191, 0, 28)', + text: 'white', + secondaryText: 'lightgray', + highlight: 'rgb(249, 212, 0)', + error: '#992600', + separator: 'darkgray', + outbound: '#FFD93F', + inbound: '#FFF0CA', + delete: '#FFD699' +}; - const Junkie: { [key: string]: any } = { - generalStyle: 'dark', - background: 'rgb(51, 51, 51)', - secondary: 'rgb(191, 0, 28)', - text: 'white', - secondaryText: 'lightgray', - highlight: 'rgb(249, 212, 0)', - error: '#992600', - separator: 'darkgray', - outbound: '#FFD93F', - inbound: '#FFF0CA', - delete: '#FFD699' - }; +const BPM: { [key: string]: any } = { + generalStyle: 'light', + background: '#fff', + secondary: '#f0f0f0', + text: '#2b74b4', + secondaryText: '#8a8999', + highlight: 'orange', + error: '#cc3300', + separator: '#CED0CE', + bolt: '#2b74b4', + chain: '#2b74b4', + inbound: 'lightblue', + outbound: '#2b74b4' +}; - const BPM: { [key: string]: any } = { - generalStyle: 'light', - background: '#fff', - secondary: '#f0f0f0', - text: '#2b74b4', - secondaryText: '#8a8999', - highlight: 'orange', - error: '#cc3300', - separator: '#CED0CE', - bolt: '#2b74b4', - chain: '#2b74b4', - inbound: 'lightblue', - outbound: '#2b74b4' - }; +const Orange: { [key: string]: any } = { + generalStyle: 'light', + background: 'orange', + secondary: 'darkorange', + text: 'white', + secondaryText: 'lightgray', + highlight: 'black', + error: '#cc3300', + separator: '#CED0CE' +}; - const Orange: { [key: string]: any } = { - generalStyle: 'light', - background: 'orange', - secondary: 'darkorange', - text: 'white', - secondaryText: 'lightgray', - highlight: 'black', - error: '#cc3300', - separator: '#CED0CE' - }; +const BlackedOut: { [key: string]: any } = { + generalStyle: 'dark', + background: '#000', + secondary: '#141414', + separator: '#141414' +}; - const BlackedOut: { [key: string]: any } = { - generalStyle: 'dark', - background: '#000', - secondary: '#141414', - separator: '#141414' - }; +const Scarlet: { [key: string]: any } = { + generalStyle: 'dark', + background: '#56042c', + secondary: '#8A1538', + separator: '#8A1538', + highlight: '#ffd24b' +}; - const Scarlet: { [key: string]: any } = { - generalStyle: 'dark', - background: '#56042c', - secondary: '#8A1538', - separator: '#8A1538', - highlight: '#ffd24b' - }; +const Purple: { [key: string]: any } = { + generalStyle: 'light', + background: '#dbd0e1', + secondary: '#ba9cbf', + text: '#776d86', + secondaryText: '#6f7286', + highlight: '#ffd24b', + error: '#C9592D', + separator: '##9fa3bf', + outbound: '#FFD93F', + inbound: '#FFF0CA', + success: '#46BE43', + warning: '#E14C4C', + bitcoin: '#FFB040' +}; - const Purple: { [key: string]: any } = { - generalStyle: 'light', - background: '#dbd0e1', - secondary: '#ba9cbf', - text: '#776d86', - secondaryText: '#6f7286', - highlight: '#ffd24b', - error: '#C9592D', - separator: '##9fa3bf', - outbound: '#FFD93F', - inbound: '#FFF0CA', - success: '#46BE43', - warning: '#E14C4C', - bitcoin: '#FFB040' - }; +const Blueberry: { [key: string]: any } = { + generalStyle: 'dark', + background: '#04235A', + secondary: '#064490', + separator: '#064490', + highlight: '#ffd24b' +}; - const Blueberry: { [key: string]: any } = { - generalStyle: 'dark', - background: '#04235A', - secondary: '#064490', - separator: '#064490', - highlight: '#ffd24b' - }; +const DeepPurple: { [key: string]: any } = { + generalStyle: 'dark', + background: '#0a0612', + secondary: '#150c25', + separator: '#150c25', + highlight: '#ffd24b' +}; - const DeepPurple: { [key: string]: any } = { - generalStyle: 'dark', - background: '#0a0612', - secondary: '#150c25', - separator: '#150c25', - highlight: '#ffd24b' - }; +const Deadpool: { [key: string]: any } = { + generalStyle: 'dark', + background: '#000', + secondary: '#D12531', + text: '#F4F9FF', + secondaryText: '#F4F9FF', + highlight: '#ffd24b', + error: '#D12531', + separator: '#D12531', + outbound: '#D12531', + inbound: '#838996', + success: '#46BE43', + //warning: '#FFD699', + //bitcoin: '#D12531' + delete: '#FFD699', + qrFrame: '#D12531', + bolt: '#F4F9FF', + chain: '#F4F9FF' +}; - const Deadpool: { [key: string]: any } = { - generalStyle: 'dark', - background: '#000', - secondary: '#D12531', - text: '#F4F9FF', - secondaryText: '#F4F9FF', - highlight: '#ffd24b', - error: '#D12531', - separator: '#D12531', - outbound: '#D12531', - inbound: '#838996', - success: '#46BE43', - //warning: '#FFD699', - //bitcoin: '#D12531' - delete: '#FFD699', - qrFrame: '#D12531', - bolt: '#F4F9FF', - chain: '#F4F9FF' - }; +const Mighty: { [key: string]: any } = { + generalStyle: 'dark', + background: '#472243', + secondary: '#006a65', + separator: '#006a65', + highlight: '#fdb827', + bolt: '#fdb827', + chain: '#fdb827' +}; - const Mighty: { [key: string]: any } = { - generalStyle: 'dark', - background: '#472243', - secondary: '#006a65', - separator: '#006a65', - highlight: '#fdb827', - bolt: '#fdb827', - chain: '#fdb827' - }; +const Green: { [key: string]: any } = { + generalStyle: 'dark', + background: '#00793f', + text: '#fff', + secondary: '#204c39', + separator: '#204c39', + highlight: '#ffd24b', + bolt: '#fff', + chain: '#fff' +}; - const Green: { [key: string]: any } = { - generalStyle: 'dark', - background: '#00793f', - text: '#fff', - secondary: '#204c39', - separator: '#204c39', - highlight: '#ffd24b', - bolt: '#fff', - chain: '#fff' - }; +const Pub: { [key: string]: any } = { + generalStyle: 'dark', + background: '#000', + gradientBackground: ['#1E2022', '#000000'], + secondary: '#31363F', + text: 'white', + secondaryText: '#A7A9AC', + highlight: '#dccfff', + error: '#992600', + separator: '#31363F', + outbound: '#4C09F4', + inbound: '#dccfff', + success: '#46BE43', + warning: '#E14C4C', + bitcoin: '#FFB040', + delete: '#992600', + qr: '#4C09F4', + qrBackground: '#FFF', + qrLogoBackground: '#4C09F4', + invertQrIcons: true, + qrFrame: '#FFD93F', + bolt: '#FFF', + chain: '#FFF', + disabled: '#767577', + buttonBackground: '#4C09F4', + buttonText: '#FFF', + action: '#FFF' +}; - const Pub: { [key: string]: any } = { - generalStyle: 'dark', - background: '#000', - gradientBackground: ['#1E2022', '#000000'], - secondary: '#31363F', - text: 'white', - secondaryText: '#A7A9AC', - highlight: '#dccfff', - error: '#992600', - separator: '#31363F', - outbound: '#4C09F4', - inbound: '#dccfff', - success: '#46BE43', - warning: '#E14C4C', - bitcoin: '#FFB040', - delete: '#992600', - qr: '#4C09F4', - qrBackground: '#FFF', - qrLogoBackground: '#4C09F4', - invertQrIcons: true, - qrFrame: '#FFD93F', - bolt: '#FFF', - chain: '#FFF', - disabled: '#767577', - buttonBackground: '#4C09F4', - buttonText: '#FFF', - action: '#FFF' - }; +const Popsicle: { [key: string]: any } = { + gradientBackground: ['#FF5C98', '#FF9C23'], + generalStyle: 'dark', + background: '#FF9C23', + separator: '#141414', + bolt: '#fff', + chain: '#fff', + secondaryText: 'lightgray' +}; - const Popsicle: { [key: string]: any } = { - gradientBackground: ['#FF5C98', '#FF9C23'], - generalStyle: 'dark', - background: '#FF9C23', - separator: '#141414', - bolt: '#fff', - chain: '#fff', - secondaryText: 'lightgray' - }; +const Nostrich: { [key: string]: any } = { + gradientBackground: [ + '#000', + '#1B1B1B', + '#2A1E36', + '#3A2152', + '#49236D', + '#582688' + ], + generalStyle: 'dark', + background: '#582688', + secondary: '#141414', + separator: '#141414' +}; - const Nostrich: { [key: string]: any } = { - gradientBackground: [ - '#000', - '#1B1B1B', - '#2A1E36', - '#3A2152', - '#49236D', - '#582688' - ], - generalStyle: 'dark', - background: '#582688', - secondary: '#141414', - separator: '#141414' - }; +const Desert: { [key: string]: any } = { + gradientBackground: ['#006BB6', '#BEC0C2', '#F58426', '#000000'], + generalStyle: 'dark', + background: '#000', + secondary: '#141414', + separator: '#141414' +}; - const Desert: { [key: string]: any } = { - gradientBackground: ['#006BB6', '#BEC0C2', '#F58426', '#000000'], - generalStyle: 'dark', - background: '#000', - secondary: '#141414', - separator: '#141414' - }; +const OrangeCreamSoda: { [key: string]: any } = { + gradientBackground: ['#FDB777', '#FDA766', '#FD9346', '#FD7F2C', '#FF6200'], + generalStyle: 'dark', + background: '#FF6200', + secondary: '#141414', + separator: '#141414', + secondaryText: '#E6E6E6' +}; - const OrangeCreamSoda: { [key: string]: any } = { - gradientBackground: [ - '#FDB777', - '#FDA766', - '#FD9346', - '#FD7F2C', - '#FF6200' - ], - generalStyle: 'dark', - background: '#FF6200', - secondary: '#141414', - separator: '#141414', - secondaryText: '#E6E6E6' - }; +const Mint: { [key: string]: any } = { + gradientBackground: [ + '#ADF0D3', + '#98E4C4', + '#84D8B6', + '#6FCCA7', + '#5BC099', + '#46B48A' + ], + generalStyle: 'dark', + background: '#46B48A', + secondaryText: '#FFFDF2', + separator: '#141414', + highlight: '#ffd24b', + bolt: '#fff', + chain: '#fff' +}; - const Mint: { [key: string]: any } = { - gradientBackground: [ - '#ADF0D3', - '#98E4C4', - '#84D8B6', - '#6FCCA7', - '#5BC099', - '#46B48A' - ], - generalStyle: 'dark', - background: '#46B48A', - secondaryText: '#FFFDF2', - separator: '#141414', - highlight: '#ffd24b', - bolt: '#fff', - chain: '#fff' - }; +const RedMetallic: { [key: string]: any } = { + gradientBackground: ['#961E1E', '#A72F2F', '#B94A4A'], + generalStyle: 'dark', + background: '#B94A4A', + secondary: '#141414', + separator: '#141414' +}; - const RedMetallic: { [key: string]: any } = { - gradientBackground: ['#961E1E', '#A72F2F', '#B94A4A'], - generalStyle: 'dark', - background: '#B94A4A', - secondary: '#141414', - separator: '#141414' - }; +const Watermelon: { [key: string]: any } = { + gradientBackground: ['#FF5C98', 'green'], + generalStyle: 'dark', + background: 'green', + separator: '#141414', + highlight: '#ffd24b', + bolt: '#fff', + chain: '#fff', + secondaryText: 'lightgray' +}; - const Watermelon: { [key: string]: any } = { - gradientBackground: ['#FF5C98', 'green'], - generalStyle: 'dark', - background: 'green', - separator: '#141414', - highlight: '#ffd24b', - bolt: '#fff', - chain: '#fff', - secondaryText: 'lightgray' - }; +const Radioactive: { [key: string]: any } = { + generalStyle: 'dark', + background: '#000', + gradientBackground: ['#191919', '#000000'], + secondary: '#31363F', + text: 'white', + secondaryText: '#A7A9AC', + highlight: '#b8ff0f', + error: '#992600', + separator: '#31363F', + outbound: '#b8ff0f', + inbound: '#547506', + success: '#46BE43', + warning: '#E14C4C', + bitcoin: '#FFB040', + delete: '#992600', + qr: '#b8ff0f', + qrBackground: '#000', + qrLogoBackground: '#b8ff0f', + invertQrIcons: false, + qrFrame: '#FFD93F', + bolt: '#FFF', + chain: '#FFF', + disabled: '#767577', + buttonBackground: '#b8ff0f', + buttonText: '#000', + action: '#FFF' +}; - const Radioactive: { [key: string]: any } = { - generalStyle: 'dark', - background: '#000', - gradientBackground: ['#191919', '#000000'], - secondary: '#31363F', - text: 'white', - secondaryText: '#A7A9AC', - highlight: '#b8ff0f', - error: '#992600', - separator: '#31363F', - outbound: '#b8ff0f', - inbound: '#547506', - success: '#46BE43', - warning: '#E14C4C', - bitcoin: '#FFB040', - delete: '#992600', - qr: '#b8ff0f', - qrBackground: '#000', - qrLogoBackground: '#b8ff0f', - invertQrIcons: false, - qrFrame: '#FFD93F', - bolt: '#FFF', - chain: '#FFF', - disabled: '#767577', - buttonBackground: '#b8ff0f', - buttonText: '#000', - action: '#FFF' - }; +export function themeColor(themeString: string): any { + const { settings } = stores.settingsStore; + const theme = settings.display && settings.display.theme; switch (theme) { case 'kyriaki': @@ -400,3 +394,31 @@ export function themeColor(themeString: string): any { return Dark[themeString]; } } + +// based on https://stackoverflow.com/a/41491220/1836528 +export function isLightTheme() { + let backgroundColor = themeColor('background'); + if (backgroundColor.startsWith('#') && backgroundColor.length === 4) { + backgroundColor = + '#' + + `${backgroundColor[1]}${backgroundColor[1]}` + + `${backgroundColor[2]}${backgroundColor[2]}` + + `${backgroundColor[3]}${backgroundColor[3]}`; + } + var color = + backgroundColor.charAt(0) === '#' + ? backgroundColor.substring(1, 7) + : backgroundColor; + var r = parseInt(color.substring(0, 2), 16); // hexToR + var g = parseInt(color.substring(2, 4), 16); // hexToG + var b = parseInt(color.substring(4, 6), 16); // hexToB + var uicolors = [r / 255, g / 255, b / 255]; + var c = uicolors.map((col) => { + if (col <= 0.03928) { + return col / 12.92; + } + return Math.pow((col + 0.055) / 1.055, 2.4); + }); + var L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2]; + return L > 0.179; +} diff --git a/views/Settings/Display.tsx b/views/Settings/Display.tsx index 8e5cca6ed..62e9805c2 100644 --- a/views/Settings/Display.tsx +++ b/views/Settings/Display.tsx @@ -3,13 +3,14 @@ import { ScrollView, View } from 'react-native'; import { ListItem } from 'react-native-elements'; import { inject, observer } from 'mobx-react'; import { StackNavigationProp } from '@react-navigation/stack'; +import SystemNavigationBar from 'react-native-system-navigation-bar'; import SettingsStore, { DEFAULT_VIEW_KEYS, THEME_KEYS } from '../../stores/SettingsStore'; import { localeString } from '../../utils/LocaleUtils'; -import { themeColor } from '../../utils/ThemeUtils'; +import { isLightTheme, themeColor } from '../../utils/ThemeUtils'; import DropdownSetting from '../../components/DropdownSetting'; import Header from '../../components/Header'; @@ -120,6 +121,13 @@ export default class Display extends React.Component< showAllDecimalPlaces } }); + SystemNavigationBar.setNavigationColor( + themeColor('background'), + isLightTheme() ? 'dark' : 'light' + ); + SystemNavigationBar.setNavigationBarDividerColor( + themeColor('secondary') + ); }} values={THEME_KEYS} /> diff --git a/views/Wallet/Wallet.tsx b/views/Wallet/Wallet.tsx index b5a5d5222..29c655644 100644 --- a/views/Wallet/Wallet.tsx +++ b/views/Wallet/Wallet.tsx @@ -12,7 +12,6 @@ import { TouchableOpacity, View } from 'react-native'; - import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { DefaultTheme, @@ -22,6 +21,8 @@ import { } from '@react-navigation/native'; import { inject, observer } from 'mobx-react'; import RNRestart from 'react-native-restart'; +import { StackNavigationProp } from '@react-navigation/stack'; +import SystemNavigationBar from 'react-native-system-navigation-bar'; import ChannelsPane from '../Channels/ChannelsPane'; import BalancePane from './BalancePane'; @@ -46,7 +47,7 @@ import { } from '../../utils/LndMobileUtils'; import { localeString } from '../../utils/LocaleUtils'; import { protectedNavigation } from '../../utils/NavigationUtils'; -import { themeColor } from '../../utils/ThemeUtils'; +import { isLightTheme, themeColor } from '../../utils/ThemeUtils'; import BalanceStore from '../../stores/BalanceStore'; import ChannelBackupStore from '../../stores/ChannelBackupStore'; @@ -73,8 +74,6 @@ import POS from '../../assets/images/SVG/POS.svg'; import Temple from '../../assets/images/SVG/Temple.svg'; import Scan from '../../assets/images/SVG/Scan.svg'; -import { StackNavigationProp } from '@react-navigation/stack'; - interface WalletProps { enterSetup: any; exitTransaction: any; @@ -238,6 +237,13 @@ export default class Wallet extends React.Component { // This awaits on settings, so should await on Tor being bootstrapped before making requests await SettingsStore.getSettings().then(async (settings: Settings) => { + SystemNavigationBar.setNavigationColor( + themeColor('background'), + isLightTheme() ? 'dark' : 'light' + ); + SystemNavigationBar.setNavigationBarDividerColor( + themeColor('secondary') + ); const loginRequired = SettingsStore.loginRequired(); const posEnabled = settings?.pos?.posEnabled && diff --git a/yarn.lock b/yarn.lock index 8539e4460..dc38d21d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8523,6 +8523,11 @@ react-native-svg@14.1.0: css-select "^5.1.0" css-tree "^1.1.3" +react-native-system-navigation-bar@2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/react-native-system-navigation-bar/-/react-native-system-navigation-bar-2.6.4.tgz#34edee7051dea01531ff2be95dc14f9fa8a540b7" + integrity sha512-4pysgADW53PiuHv+2glzNLJnHSxqDszZvLoitLFI5os4D+gCDfxmR36VSET4EnXkzSf8X9mbeFkHYDypDHJyZA== + react-native-tcp@aprock/react-native-tcp#be5f656: version "4.0.0" resolved "https://codeload.github.com/aprock/react-native-tcp/tar.gz/be5f656ffd3aa4559270e8472ee24a1c36029cf1"