mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-02 12:47:41 +02:00
parent
4e1ee87269
commit
9c8fbe831f
@ -443,6 +443,7 @@ packages/app-mobile/tools/buildInjectedJs.js
|
|||||||
packages/app-mobile/utils/ShareExtension.js
|
packages/app-mobile/utils/ShareExtension.js
|
||||||
packages/app-mobile/utils/ShareUtils.js
|
packages/app-mobile/utils/ShareUtils.js
|
||||||
packages/app-mobile/utils/TlsUtils.js
|
packages/app-mobile/utils/TlsUtils.js
|
||||||
|
packages/app-mobile/utils/autodetectTheme.js
|
||||||
packages/app-mobile/utils/checkPermissions.js
|
packages/app-mobile/utils/checkPermissions.js
|
||||||
packages/app-mobile/utils/createRootStyle.js
|
packages/app-mobile/utils/createRootStyle.js
|
||||||
packages/app-mobile/utils/debounce.js
|
packages/app-mobile/utils/debounce.js
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -428,6 +428,7 @@ packages/app-mobile/tools/buildInjectedJs.js
|
|||||||
packages/app-mobile/utils/ShareExtension.js
|
packages/app-mobile/utils/ShareExtension.js
|
||||||
packages/app-mobile/utils/ShareUtils.js
|
packages/app-mobile/utils/ShareUtils.js
|
||||||
packages/app-mobile/utils/TlsUtils.js
|
packages/app-mobile/utils/TlsUtils.js
|
||||||
|
packages/app-mobile/utils/autodetectTheme.js
|
||||||
packages/app-mobile/utils/checkPermissions.js
|
packages/app-mobile/utils/checkPermissions.js
|
||||||
packages/app-mobile/utils/createRootStyle.js
|
packages/app-mobile/utils/createRootStyle.js
|
||||||
packages/app-mobile/utils/debounce.js
|
packages/app-mobile/utils/debounce.js
|
||||||
|
@ -15,7 +15,7 @@ interface FolderPickerProps {
|
|||||||
folders: FolderEntity[];
|
folders: FolderEntity[];
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
darkText?: boolean;
|
darkText?: boolean;
|
||||||
themeId?: string;
|
themeId?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ interface ScreenHeaderProps {
|
|||||||
shouldUpgradeSyncTarget?: boolean;
|
shouldUpgradeSyncTarget?: boolean;
|
||||||
showShouldUpgradeSyncTargetMessage?: boolean;
|
showShouldUpgradeSyncTargetMessage?: boolean;
|
||||||
|
|
||||||
|
themeId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ScreenHeaderState {
|
interface ScreenHeaderState {
|
||||||
@ -100,7 +101,7 @@ class ScreenHeaderComponent extends PureComponent<ScreenHeaderProps, ScreenHeade
|
|||||||
}
|
}
|
||||||
|
|
||||||
private styles() {
|
private styles() {
|
||||||
const themeId = Setting.value('theme');
|
const themeId = this.props.themeId;
|
||||||
if (this.cachedStyles[themeId]) return this.cachedStyles[themeId];
|
if (this.cachedStyles[themeId]) return this.cachedStyles[themeId];
|
||||||
this.cachedStyles = {};
|
this.cachedStyles = {};
|
||||||
|
|
||||||
@ -297,7 +298,7 @@ class ScreenHeaderComponent extends PureComponent<ScreenHeaderProps, ScreenHeade
|
|||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const themeId = Setting.value('theme');
|
const themeId = this.props.themeId;
|
||||||
function sideMenuButton(styles: any, onPress: OnPressCallback) {
|
function sideMenuButton(styles: any, onPress: OnPressCallback) {
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
@ -104,7 +104,7 @@
|
|||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
</array>
|
</array>
|
||||||
<key>UIUserInterfaceStyle</key>
|
<key>UIUserInterfaceStyle</key>
|
||||||
<string>Light</string>
|
<string>Automatic</string>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>NSFaceIDUsageDescription</key>
|
<key>NSFaceIDUsageDescription</key>
|
||||||
|
@ -29,7 +29,7 @@ import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
|
|||||||
import initProfile from '@joplin/lib/services/profileConfig/initProfile';
|
import initProfile from '@joplin/lib/services/profileConfig/initProfile';
|
||||||
const VersionInfo = require('react-native-version-info').default;
|
const VersionInfo = require('react-native-version-info').default;
|
||||||
const { Keyboard, BackHandler, View, StatusBar, Platform, Dimensions } = require('react-native');
|
const { Keyboard, BackHandler, View, StatusBar, Platform, Dimensions } = require('react-native');
|
||||||
import { AppState as RNAppState, EmitterSubscription, Linking, NativeEventSubscription } from 'react-native';
|
import { AppState as RNAppState, EmitterSubscription, Linking, NativeEventSubscription, Appearance } from 'react-native';
|
||||||
import getResponsiveValue from './components/getResponsiveValue';
|
import getResponsiveValue from './components/getResponsiveValue';
|
||||||
import NetInfo from '@react-native-community/netinfo';
|
import NetInfo from '@react-native-community/netinfo';
|
||||||
const DropdownAlert = require('react-native-dropdownalert').default;
|
const DropdownAlert = require('react-native-dropdownalert').default;
|
||||||
@ -118,6 +118,7 @@ import { getCurrentProfile } from '@joplin/lib/services/profileConfig';
|
|||||||
import { getDatabaseName, getProfilesRootDir, getResourceDir, setDispatch } from './services/profiles';
|
import { getDatabaseName, getProfilesRootDir, getResourceDir, setDispatch } from './services/profiles';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { parseShareCache } from '@joplin/lib/services/share/reducer';
|
import { parseShareCache } from '@joplin/lib/services/share/reducer';
|
||||||
|
import autodetectTheme, { onSystemColorSchemeChange } from './utils/autodetectTheme';
|
||||||
|
|
||||||
type SideMenuPosition = 'left' | 'right';
|
type SideMenuPosition = 'left' | 'right';
|
||||||
|
|
||||||
@ -186,6 +187,14 @@ const generalMiddleware = (store: any) => (next: any) => async (action: any) =>
|
|||||||
void reg.scheduleSync(null, null, true);
|
void reg.scheduleSync(null, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
action.type === 'AUTODETECT_THEME'
|
||||||
|
|| action.type === 'SETTING_UPDATE_ALL'
|
||||||
|
|| (action.type === 'SETTING_UPDATE_ONE' && ['themeAutoDetect', 'preferredLightTheme', 'preferredDarkTheme'].includes(action.key))
|
||||||
|
) {
|
||||||
|
autodetectTheme();
|
||||||
|
}
|
||||||
|
|
||||||
if (action.type === 'NAV_GO' && action.routeName === 'Notes') {
|
if (action.type === 'NAV_GO' && action.routeName === 'Notes') {
|
||||||
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
||||||
}
|
}
|
||||||
@ -712,6 +721,7 @@ class AppComponent extends React.Component {
|
|||||||
|
|
||||||
private urlOpenListener_: EmitterSubscription|null = null;
|
private urlOpenListener_: EmitterSubscription|null = null;
|
||||||
private appStateChangeListener_: NativeEventSubscription|null = null;
|
private appStateChangeListener_: NativeEventSubscription|null = null;
|
||||||
|
private themeChangeListener_: NativeEventSubscription|null = null;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
@ -849,6 +859,11 @@ class AppComponent extends React.Component {
|
|||||||
this.appStateChangeListener_ = RNAppState.addEventListener('change', this.onAppStateChange_);
|
this.appStateChangeListener_ = RNAppState.addEventListener('change', this.onAppStateChange_);
|
||||||
this.unsubscribeScreenWidthChangeHandler_ = Dimensions.addEventListener('change', this.handleScreenWidthChange_);
|
this.unsubscribeScreenWidthChangeHandler_ = Dimensions.addEventListener('change', this.handleScreenWidthChange_);
|
||||||
|
|
||||||
|
this.themeChangeListener_ = Appearance.addChangeListener(
|
||||||
|
({ colorScheme }) => onSystemColorSchemeChange(colorScheme)
|
||||||
|
);
|
||||||
|
onSystemColorSchemeChange(Appearance.getColorScheme());
|
||||||
|
|
||||||
setupQuickActions(this.props.dispatch, this.props.selectedFolderId);
|
setupQuickActions(this.props.dispatch, this.props.selectedFolderId);
|
||||||
|
|
||||||
await setupNotifications(this.props.dispatch);
|
await setupNotifications(this.props.dispatch);
|
||||||
@ -868,6 +883,11 @@ class AppComponent extends React.Component {
|
|||||||
this.urlOpenListener_ = null;
|
this.urlOpenListener_ = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.themeChangeListener_) {
|
||||||
|
this.themeChangeListener_.remove();
|
||||||
|
this.themeChangeListener_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.unsubscribeScreenWidthChangeHandler_) {
|
if (this.unsubscribeScreenWidthChangeHandler_) {
|
||||||
this.unsubscribeScreenWidthChangeHandler_.remove();
|
this.unsubscribeScreenWidthChangeHandler_.remove();
|
||||||
this.unsubscribeScreenWidthChangeHandler_ = null;
|
this.unsubscribeScreenWidthChangeHandler_ = null;
|
||||||
|
38
packages/app-mobile/utils/autodetectTheme.ts
Normal file
38
packages/app-mobile/utils/autodetectTheme.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import Logger from '@joplin/lib/Logger';
|
||||||
|
import Setting from '@joplin/lib/models/Setting';
|
||||||
|
import { Appearance, ColorSchemeName } from 'react-native';
|
||||||
|
|
||||||
|
const logger = Logger.create('autodetectTheme');
|
||||||
|
|
||||||
|
let systemColorScheme: ColorSchemeName|null = null;
|
||||||
|
|
||||||
|
// We export an `onThemeChange`, rather than using `Appearance.getColorScheme()` directly
|
||||||
|
// to work around https://github.com/facebook/react-native/issues/36061. On some devices,
|
||||||
|
// `Appearance.getColorScheme()` returns incorrect values.
|
||||||
|
export const onSystemColorSchemeChange = (newColorScheme: ColorSchemeName|null) => {
|
||||||
|
if (systemColorScheme !== newColorScheme) {
|
||||||
|
systemColorScheme = newColorScheme;
|
||||||
|
autodetectTheme();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const autodetectTheme = () => {
|
||||||
|
if (!Setting.value('themeAutoDetect')) {
|
||||||
|
logger.info('Theme autodetect disabled, not switching theme to match system.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorScheme = systemColorScheme;
|
||||||
|
logger.debug(
|
||||||
|
'Autodetecting theme. getColorScheme returns', Appearance.getColorScheme(),
|
||||||
|
'and the expected theme is', systemColorScheme
|
||||||
|
);
|
||||||
|
|
||||||
|
if (colorScheme === 'dark') {
|
||||||
|
Setting.setValue('theme', Setting.value('preferredDarkTheme'));
|
||||||
|
} else {
|
||||||
|
Setting.setValue('theme', Setting.value('preferredLightTheme'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default autodetectTheme;
|
@ -6,4 +6,5 @@ export interface AppState extends State {
|
|||||||
route: any;
|
route: any;
|
||||||
smartFilterId: string;
|
smartFilterId: string;
|
||||||
noteSideMenuOptions: any;
|
noteSideMenuOptions: any;
|
||||||
|
themeId: number;
|
||||||
}
|
}
|
||||||
|
@ -840,7 +840,7 @@ class Setting extends BaseModel {
|
|||||||
value: false,
|
value: false,
|
||||||
type: SettingItemType.Bool,
|
type: SettingItemType.Bool,
|
||||||
section: 'appearance',
|
section: 'appearance',
|
||||||
appTypes: [AppType.Desktop],
|
appTypes: [AppType.Mobile, AppType.Desktop],
|
||||||
public: true,
|
public: true,
|
||||||
label: () => _('Automatically switch theme to match system theme'),
|
label: () => _('Automatically switch theme to match system theme'),
|
||||||
storage: SettingStorage.File,
|
storage: SettingStorage.File,
|
||||||
@ -854,7 +854,7 @@ class Setting extends BaseModel {
|
|||||||
show: (settings) => {
|
show: (settings) => {
|
||||||
return settings['themeAutoDetect'];
|
return settings['themeAutoDetect'];
|
||||||
},
|
},
|
||||||
appTypes: [AppType.Desktop],
|
appTypes: [AppType.Mobile, AppType.Desktop],
|
||||||
isEnum: true,
|
isEnum: true,
|
||||||
label: () => _('Preferred light theme'),
|
label: () => _('Preferred light theme'),
|
||||||
section: 'appearance',
|
section: 'appearance',
|
||||||
@ -870,7 +870,7 @@ class Setting extends BaseModel {
|
|||||||
show: (settings) => {
|
show: (settings) => {
|
||||||
return settings['themeAutoDetect'];
|
return settings['themeAutoDetect'];
|
||||||
},
|
},
|
||||||
appTypes: [AppType.Desktop],
|
appTypes: [AppType.Mobile, AppType.Desktop],
|
||||||
isEnum: true,
|
isEnum: true,
|
||||||
label: () => _('Preferred dark theme'),
|
label: () => _('Preferred dark theme'),
|
||||||
section: 'appearance',
|
section: 'appearance',
|
||||||
|
Loading…
Reference in New Issue
Block a user