mirror of https://github.com/laurent22/joplin.git
Chore: Mobile: Migrate action button to `react-native-paper` (#7477)
parent
8b3c9e81a7
commit
257a24166e
|
@ -864,6 +864,9 @@ packages/app-desktop/utils/markupLanguageUtils.js.map
|
||||||
packages/app-mobile/PluginAssetsLoader.d.ts
|
packages/app-mobile/PluginAssetsLoader.d.ts
|
||||||
packages/app-mobile/PluginAssetsLoader.js
|
packages/app-mobile/PluginAssetsLoader.js
|
||||||
packages/app-mobile/PluginAssetsLoader.js.map
|
packages/app-mobile/PluginAssetsLoader.js.map
|
||||||
|
packages/app-mobile/components/ActionButton.d.ts
|
||||||
|
packages/app-mobile/components/ActionButton.js
|
||||||
|
packages/app-mobile/components/ActionButton.js.map
|
||||||
packages/app-mobile/components/BackButtonDialogBox.d.ts
|
packages/app-mobile/components/BackButtonDialogBox.d.ts
|
||||||
packages/app-mobile/components/BackButtonDialogBox.js
|
packages/app-mobile/components/BackButtonDialogBox.js
|
||||||
packages/app-mobile/components/BackButtonDialogBox.js.map
|
packages/app-mobile/components/BackButtonDialogBox.js.map
|
||||||
|
|
|
@ -852,6 +852,9 @@ packages/app-desktop/utils/markupLanguageUtils.js.map
|
||||||
packages/app-mobile/PluginAssetsLoader.d.ts
|
packages/app-mobile/PluginAssetsLoader.d.ts
|
||||||
packages/app-mobile/PluginAssetsLoader.js
|
packages/app-mobile/PluginAssetsLoader.js
|
||||||
packages/app-mobile/PluginAssetsLoader.js.map
|
packages/app-mobile/PluginAssetsLoader.js.map
|
||||||
|
packages/app-mobile/components/ActionButton.d.ts
|
||||||
|
packages/app-mobile/components/ActionButton.js
|
||||||
|
packages/app-mobile/components/ActionButton.js.map
|
||||||
packages/app-mobile/components/BackButtonDialogBox.d.ts
|
packages/app-mobile/components/BackButtonDialogBox.d.ts
|
||||||
packages/app-mobile/components/BackButtonDialogBox.js
|
packages/app-mobile/components/BackButtonDialogBox.js
|
||||||
packages/app-mobile/components/BackButtonDialogBox.js.map
|
packages/app-mobile/components/BackButtonDialogBox.js.map
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.multidex.MultiDex;
|
||||||
|
|
||||||
import com.facebook.react.PackageList;
|
import com.facebook.react.PackageList;
|
||||||
import com.facebook.react.ReactApplication;
|
import com.facebook.react.ReactApplication;
|
||||||
|
import com.oblador.vectoricons.VectorIconsPackage;
|
||||||
import com.facebook.react.ReactInstanceManager;
|
import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
rootProject.name = 'Joplin'
|
rootProject.name = 'Joplin'
|
||||||
|
include ':react-native-vector-icons'
|
||||||
|
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
|
||||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||||
include ':app'
|
include ':app'
|
||||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
const React = require('react');
|
||||||
|
import { useState, useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
|
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||||
|
import { FAB, Portal } from 'react-native-paper';
|
||||||
|
import { _ } from '@joplin/lib/locale';
|
||||||
|
|
||||||
|
|
||||||
|
type OnButtonPress = ()=> void;
|
||||||
|
interface ButtonSpec {
|
||||||
|
icon: string;
|
||||||
|
label: string;
|
||||||
|
color?: string;
|
||||||
|
onPress?: OnButtonPress;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ActionButtonProps {
|
||||||
|
buttons?: ButtonSpec[];
|
||||||
|
|
||||||
|
// If not given, an "add" button will be used.
|
||||||
|
mainButton?: ButtonSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultOnPress = () => {};
|
||||||
|
|
||||||
|
// Returns a render function compatible with React Native Paper.
|
||||||
|
const getIconRenderFunction = (iconName: string) => {
|
||||||
|
return (props: any) => <Icon name={iconName} {...props} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useIcon = (iconName: string) => {
|
||||||
|
return useMemo(() => {
|
||||||
|
return getIconRenderFunction(iconName);
|
||||||
|
}, [iconName]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ActionButton = (props: ActionButtonProps) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const onMenuToggled = useCallback(
|
||||||
|
(state: { open: boolean }) => setOpen(state.open)
|
||||||
|
, [setOpen]);
|
||||||
|
|
||||||
|
|
||||||
|
const actions = useMemo(() => (props.buttons ?? []).map(button => {
|
||||||
|
return {
|
||||||
|
...button,
|
||||||
|
icon: getIconRenderFunction(button.icon),
|
||||||
|
onPress: button.onPress ?? defaultOnPress,
|
||||||
|
};
|
||||||
|
}), [props.buttons]);
|
||||||
|
|
||||||
|
const closedIcon = useIcon(props.mainButton?.icon ?? 'md-add');
|
||||||
|
const openIcon = useIcon('close');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Portal>
|
||||||
|
<FAB.Group
|
||||||
|
open={open}
|
||||||
|
accessibilityLabel={props.mainButton?.label ?? _('Add new')}
|
||||||
|
icon={ open ? openIcon : closedIcon }
|
||||||
|
fabStyle={{
|
||||||
|
backgroundColor: props.mainButton?.color ?? 'rgba(231,76,60,1)',
|
||||||
|
}}
|
||||||
|
onStateChange={onMenuToggled}
|
||||||
|
actions={actions}
|
||||||
|
onPress={props.mainButton?.onPress ?? defaultOnPress}
|
||||||
|
visible={true}
|
||||||
|
/>
|
||||||
|
</Portal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActionButton;
|
|
@ -1,169 +0,0 @@
|
||||||
const React = require('react');
|
|
||||||
|
|
||||||
const { StyleSheet } = require('react-native');
|
|
||||||
const Note = require('@joplin/lib/models/Note').default;
|
|
||||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
|
||||||
const ReactNativeActionButton = require('react-native-action-button').default;
|
|
||||||
const { connect } = require('react-redux');
|
|
||||||
const { _ } = require('@joplin/lib/locale');
|
|
||||||
|
|
||||||
// We need this to suppress the useless warning
|
|
||||||
// https://github.com/oblador/react-native-vector-icons/issues/1465
|
|
||||||
Icon.loadFont().catch((error) => { console.info(error); });
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
actionButtonIcon: {
|
|
||||||
fontSize: 20,
|
|
||||||
height: 22,
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
itemText: {
|
|
||||||
// fontSize: 14, // Cannot currently set fontsize since the bow surrounding the label has a fixed size
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
class ActionButtonComponent extends React.Component {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
buttonIndex: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.renderIconMultiStates = this.renderIconMultiStates.bind(this);
|
|
||||||
this.renderIcon = this.renderIcon.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(newProps) {
|
|
||||||
if ('buttonIndex' in newProps) {
|
|
||||||
this.setState({ buttonIndex: newProps.buttonIndex });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async newNoteNavigate(folderId, isTodo) {
|
|
||||||
const newNote = await Note.save({
|
|
||||||
parent_id: folderId,
|
|
||||||
is_todo: isTodo ? 1 : 0,
|
|
||||||
}, { provisional: true });
|
|
||||||
|
|
||||||
this.props.dispatch({
|
|
||||||
type: 'NAV_GO',
|
|
||||||
routeName: 'Note',
|
|
||||||
noteId: newNote.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
newTodo_press() {
|
|
||||||
this.newNoteNavigate(this.props.parentFolderId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
newNote_press() {
|
|
||||||
this.newNoteNavigate(this.props.parentFolderId, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderIconMultiStates() {
|
|
||||||
const button = this.props.buttons[this.state.buttonIndex];
|
|
||||||
|
|
||||||
return <Icon
|
|
||||||
name={button.icon}
|
|
||||||
style={styles.actionButtonIcon}
|
|
||||||
accessibilityLabel={button.title}
|
|
||||||
/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderIcon() {
|
|
||||||
const mainButton = this.props.mainButton ? this.props.mainButton : {};
|
|
||||||
const iconName = mainButton.icon ?? 'md-add';
|
|
||||||
|
|
||||||
// Icons don't have alt text by default. We need to add it:
|
|
||||||
const iconTitle = mainButton.title ?? _('Add new');
|
|
||||||
|
|
||||||
// TODO: If the button toggles a sub-menu, state whether the submenu is open
|
|
||||||
// or closed.
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={iconName}
|
|
||||||
style={styles.actionButtonIcon}
|
|
||||||
accessibilityLabel={iconTitle}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const buttons = this.props.buttons ? this.props.buttons : [];
|
|
||||||
|
|
||||||
if (this.props.addFolderNoteButtons) {
|
|
||||||
if (this.props.folders.length) {
|
|
||||||
buttons.push({
|
|
||||||
title: _('New to-do'),
|
|
||||||
onPress: () => {
|
|
||||||
this.newTodo_press();
|
|
||||||
},
|
|
||||||
color: '#9b59b6',
|
|
||||||
icon: 'md-checkbox-outline',
|
|
||||||
});
|
|
||||||
|
|
||||||
buttons.push({
|
|
||||||
title: _('New note'),
|
|
||||||
onPress: () => {
|
|
||||||
this.newNote_press();
|
|
||||||
},
|
|
||||||
color: '#9b59b6',
|
|
||||||
icon: 'md-document',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const buttonComps = [];
|
|
||||||
for (let i = 0; i < buttons.length; i++) {
|
|
||||||
const button = buttons[i];
|
|
||||||
const buttonTitle = button.title ? button.title : '';
|
|
||||||
const key = `${buttonTitle.replace(/\s/g, '_')}_${button.icon}`;
|
|
||||||
buttonComps.push(
|
|
||||||
// TODO: By default, ReactNativeActionButton also adds a title, which is focusable
|
|
||||||
// by the screen reader. As such, each item currently is double-focusable
|
|
||||||
<ReactNativeActionButton.Item key={key} buttonColor={button.color} title={buttonTitle} onPress={button.onPress}>
|
|
||||||
<Icon
|
|
||||||
name={button.icon}
|
|
||||||
style={styles.actionButtonIcon}
|
|
||||||
accessibilityLabel={buttonTitle}
|
|
||||||
/>
|
|
||||||
</ReactNativeActionButton.Item>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!buttonComps.length && !this.props.mainButton) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.multiStates) {
|
|
||||||
if (!this.props.buttons || !this.props.buttons.length) throw new Error('Multi-state button requires at least one state');
|
|
||||||
if (this.state.buttonIndex < 0 || this.state.buttonIndex >= this.props.buttons.length) throw new Error(`Button index out of bounds: ${this.state.buttonIndex}/${this.props.buttons.length}`);
|
|
||||||
const button = this.props.buttons[this.state.buttonIndex];
|
|
||||||
return (
|
|
||||||
<ReactNativeActionButton
|
|
||||||
renderIcon={this.renderIconMultiStates}
|
|
||||||
buttonColor="rgba(231,76,60,1)"
|
|
||||||
onPress={() => {
|
|
||||||
button.onPress();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<ReactNativeActionButton textStyle={styles.itemText} renderIcon={this.renderIcon} buttonColor="rgba(231,76,60,1)" onPress={function() {}}>
|
|
||||||
{buttonComps}
|
|
||||||
</ReactNativeActionButton>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ActionButton = connect(state => {
|
|
||||||
return {
|
|
||||||
folders: state.folders,
|
|
||||||
locale: state.settings.locale,
|
|
||||||
};
|
|
||||||
})(ActionButtonComponent);
|
|
||||||
|
|
||||||
module.exports = { ActionButton };
|
|
|
@ -22,7 +22,7 @@ const md5 = require('md5');
|
||||||
const { BackButtonService } = require('../../services/back-button.js');
|
const { BackButtonService } = require('../../services/back-button.js');
|
||||||
import NavService from '@joplin/lib/services/NavService';
|
import NavService from '@joplin/lib/services/NavService';
|
||||||
import BaseModel from '@joplin/lib/BaseModel';
|
import BaseModel from '@joplin/lib/BaseModel';
|
||||||
const { ActionButton } = require('../action-button.js');
|
import ActionButton from '../ActionButton';
|
||||||
const { fileExtension, safeFileExtension } = require('@joplin/lib/path-utils');
|
const { fileExtension, safeFileExtension } = require('@joplin/lib/path-utils');
|
||||||
const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
|
const mimeUtils = require('@joplin/lib/mime-utils.js').mime;
|
||||||
import ScreenHeader from '../ScreenHeader';
|
import ScreenHeader from '../ScreenHeader';
|
||||||
|
@ -1145,21 +1145,19 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderActionButton = () => {
|
const renderActionButton = () => {
|
||||||
const buttons = [];
|
const editButton = {
|
||||||
|
label: _('Edit'),
|
||||||
buttons.push({
|
|
||||||
title: _('Edit'),
|
|
||||||
icon: 'md-create',
|
icon: 'md-create',
|
||||||
onPress: () => {
|
onPress: () => {
|
||||||
this.setState({ mode: 'edit' });
|
this.setState({ mode: 'edit' });
|
||||||
|
|
||||||
this.doFocusUpdate_ = true;
|
this.doFocusUpdate_ = true;
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
if (this.state.mode === 'edit') return null;
|
if (this.state.mode === 'edit') return null;
|
||||||
|
|
||||||
return <ActionButton multiStates={true} buttons={buttons} buttonIndex={0} />;
|
return <ActionButton mainButton={editButton} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionButtonComp = renderActionButton();
|
const actionButtonComp = renderActionButton();
|
||||||
|
|
|
@ -11,7 +11,7 @@ const Setting = require('@joplin/lib/models/Setting').default;
|
||||||
const { themeStyle } = require('../global-style.js');
|
const { themeStyle } = require('../global-style.js');
|
||||||
const { ScreenHeader } = require('../ScreenHeader');
|
const { ScreenHeader } = require('../ScreenHeader');
|
||||||
const { _ } = require('@joplin/lib/locale');
|
const { _ } = require('@joplin/lib/locale');
|
||||||
const { ActionButton } = require('../action-button.js');
|
const ActionButton = require('../ActionButton').default;
|
||||||
const { dialogs } = require('../../utils/dialogs.js');
|
const { dialogs } = require('../../utils/dialogs.js');
|
||||||
const DialogBox = require('react-native-dialogbox').default;
|
const DialogBox = require('react-native-dialogbox').default;
|
||||||
const { BaseScreenComponent } = require('../base-screen.js');
|
const { BaseScreenComponent } = require('../base-screen.js');
|
||||||
|
@ -179,6 +179,19 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newNoteNavigate = async (folderId, isTodo) => {
|
||||||
|
const newNote = await Note.save({
|
||||||
|
parent_id: folderId,
|
||||||
|
is_todo: isTodo ? 1 : 0,
|
||||||
|
}, { provisional: true });
|
||||||
|
|
||||||
|
this.props.dispatch({
|
||||||
|
type: 'NAV_GO',
|
||||||
|
routeName: 'Note',
|
||||||
|
noteId: newNote.id,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
parentItem(props = null) {
|
parentItem(props = null) {
|
||||||
if (!props) props = this.props;
|
if (!props) props = this.props;
|
||||||
|
|
||||||
|
@ -238,7 +251,35 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||||
|
|
||||||
const addFolderNoteButtons = !!buttonFolderId;
|
const addFolderNoteButtons = !!buttonFolderId;
|
||||||
const thisComp = this;
|
const thisComp = this;
|
||||||
const actionButtonComp = this.props.noteSelectionEnabled || !this.props.visible ? null : <ActionButton addFolderNoteButtons={addFolderNoteButtons} parentFolderId={buttonFolderId}></ActionButton>;
|
|
||||||
|
const makeActionButtonComp = () => {
|
||||||
|
if (addFolderNoteButtons && this.props.folders.length > 0) {
|
||||||
|
const buttons = [];
|
||||||
|
buttons.push({
|
||||||
|
label: _('New to-do'),
|
||||||
|
onPress: () => {
|
||||||
|
const isTodo = true;
|
||||||
|
this.newNoteNavigate(buttonFolderId, isTodo);
|
||||||
|
},
|
||||||
|
color: '#9b59b6',
|
||||||
|
icon: 'md-checkbox-outline',
|
||||||
|
});
|
||||||
|
|
||||||
|
buttons.push({
|
||||||
|
label: _('New note'),
|
||||||
|
onPress: () => {
|
||||||
|
const isTodo = false;
|
||||||
|
this.newNoteNavigate(buttonFolderId, isTodo);
|
||||||
|
},
|
||||||
|
color: '#9b59b6',
|
||||||
|
icon: 'md-document',
|
||||||
|
});
|
||||||
|
return <ActionButton buttons={buttons}/>;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionButtonComp = this.props.noteSelectionEnabled || !this.props.visible ? null : makeActionButtonComp();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={rootStyle}>
|
<View style={rootStyle}>
|
||||||
|
|
|
@ -248,6 +248,12 @@ PODS:
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-rsa-native (2.0.5):
|
- react-native-rsa-native (2.0.5):
|
||||||
- React
|
- React
|
||||||
|
- react-native-safe-area-context (4.4.1):
|
||||||
|
- RCT-Folly
|
||||||
|
- RCTRequired
|
||||||
|
- RCTTypeSafety
|
||||||
|
- React-Core
|
||||||
|
- ReactCommon/turbomodule/core
|
||||||
- react-native-slider (4.4.0):
|
- react-native-slider (4.4.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- react-native-sqlite-storage (6.0.1):
|
- react-native-sqlite-storage (6.0.1):
|
||||||
|
@ -376,6 +382,7 @@ DEPENDENCIES:
|
||||||
- react-native-image-resizer (from `../node_modules/react-native-image-resizer`)
|
- react-native-image-resizer (from `../node_modules/react-native-image-resizer`)
|
||||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||||
- react-native-rsa-native (from `../node_modules/react-native-rsa-native`)
|
- react-native-rsa-native (from `../node_modules/react-native-rsa-native`)
|
||||||
|
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||||
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
||||||
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
|
- react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`)
|
||||||
- react-native-version-info (from `../node_modules/react-native-version-info`)
|
- react-native-version-info (from `../node_modules/react-native-version-info`)
|
||||||
|
@ -469,6 +476,8 @@ EXTERNAL SOURCES:
|
||||||
:path: "../node_modules/@react-native-community/netinfo"
|
:path: "../node_modules/@react-native-community/netinfo"
|
||||||
react-native-rsa-native:
|
react-native-rsa-native:
|
||||||
:path: "../node_modules/react-native-rsa-native"
|
:path: "../node_modules/react-native-rsa-native"
|
||||||
|
react-native-safe-area-context:
|
||||||
|
:path: "../node_modules/react-native-safe-area-context"
|
||||||
react-native-slider:
|
react-native-slider:
|
||||||
:path: "../node_modules/@react-native-community/slider"
|
:path: "../node_modules/@react-native-community/slider"
|
||||||
react-native-sqlite-storage:
|
react-native-sqlite-storage:
|
||||||
|
@ -530,10 +539,10 @@ SPEC CHECKSUMS:
|
||||||
FBLazyVector: 2b47ff52037bd9ae07cc9b051c9975797814b736
|
FBLazyVector: 2b47ff52037bd9ae07cc9b051c9975797814b736
|
||||||
FBReactNativeSpec: 0e0d384ef17a33b385f13f0c7f97702c7cd17858
|
FBReactNativeSpec: 0e0d384ef17a33b385f13f0c7f97702c7cd17858
|
||||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||||
glog: 476ee3e89abb49e07f822b48323c51c57124b572
|
glog: 5337263514dd6f09803962437687240c5dc39aa4
|
||||||
JoplinCommonShareExtension: a8b60b02704d85a7305627912c0240e94af78db7
|
JoplinCommonShareExtension: a8b60b02704d85a7305627912c0240e94af78db7
|
||||||
JoplinRNShareExtension: 485f3e6dad83b7b77f1572eabc249f869ee55c02
|
JoplinRNShareExtension: 485f3e6dad83b7b77f1572eabc249f869ee55c02
|
||||||
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
|
RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9
|
||||||
RCTRequired: 0f06b6068f530932d10e1a01a5352fad4eaacb74
|
RCTRequired: 0f06b6068f530932d10e1a01a5352fad4eaacb74
|
||||||
RCTTypeSafety: b0ee81f10ef1b7d977605a2b266823dabd565e65
|
RCTTypeSafety: b0ee81f10ef1b7d977605a2b266823dabd565e65
|
||||||
React: 3becd12bd51ea8a43bdde7e09d0f40fba7820e03
|
React: 3becd12bd51ea8a43bdde7e09d0f40fba7820e03
|
||||||
|
@ -556,6 +565,7 @@ SPEC CHECKSUMS:
|
||||||
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
|
react-native-image-resizer: d9fb629a867335bdc13230ac2a58702bb8c8828f
|
||||||
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
|
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
|
||||||
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
react-native-rsa-native: 12132eb627797529fdb1f0d22fd0f8f9678df64a
|
||||||
|
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
|
||||||
react-native-slider: d2938a12c4e439a227c70eec65d119136eb4aeb5
|
react-native-slider: d2938a12c4e439a227c70eec65d119136eb4aeb5
|
||||||
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261
|
||||||
react-native-version-info: a106f23009ac0db4ee00de39574eb546682579b9
|
react-native-version-info: a106f23009ac0db4ee00de39574eb546682579b9
|
||||||
|
|
|
@ -51,9 +51,11 @@
|
||||||
"react-native-image-picker": "4.10.3",
|
"react-native-image-picker": "4.10.3",
|
||||||
"react-native-image-resizer": "1.4.5",
|
"react-native-image-resizer": "1.4.5",
|
||||||
"react-native-modal-datetime-picker": "14.0.1",
|
"react-native-modal-datetime-picker": "14.0.1",
|
||||||
|
"react-native-paper": "5.0.2",
|
||||||
"react-native-popup-menu": "0.16.1",
|
"react-native-popup-menu": "0.16.1",
|
||||||
"react-native-quick-actions": "0.3.13",
|
"react-native-quick-actions": "0.3.13",
|
||||||
"react-native-rsa-native": "2.0.5",
|
"react-native-rsa-native": "2.0.5",
|
||||||
|
"react-native-safe-area-context": "4.4.1",
|
||||||
"react-native-securerandom": "1.0.1",
|
"react-native-securerandom": "1.0.1",
|
||||||
"react-native-share": "8.1.0",
|
"react-native-share": "8.1.0",
|
||||||
"react-native-side-menu-updated": "1.3.2",
|
"react-native-side-menu-updated": "1.3.2",
|
||||||
|
|
|
@ -36,6 +36,7 @@ const DropdownAlert = require('react-native-dropdownalert').default;
|
||||||
const AlarmServiceDriver = require('./services/AlarmServiceDriver').default;
|
const AlarmServiceDriver = require('./services/AlarmServiceDriver').default;
|
||||||
const SafeAreaView = require('./components/SafeAreaView');
|
const SafeAreaView = require('./components/SafeAreaView');
|
||||||
const { connect, Provider } = require('react-redux');
|
const { connect, Provider } = require('react-redux');
|
||||||
|
import { Provider as PaperProvider, MD2DarkTheme as PaperDarkTheme, MD2LightTheme as PaperLightTheme } from 'react-native-paper';
|
||||||
const { BackButtonService } = require('./services/back-button.js');
|
const { BackButtonService } = require('./services/back-button.js');
|
||||||
import NavService from '@joplin/lib/services/NavService';
|
import NavService from '@joplin/lib/services/NavService';
|
||||||
import { createStore, applyMiddleware } from 'redux';
|
import { createStore, applyMiddleware } from 'redux';
|
||||||
|
@ -108,6 +109,7 @@ import SyncTargetNone from '@joplin/lib/SyncTargetNone';
|
||||||
import { setRSA } from '@joplin/lib/services/e2ee/ppk';
|
import { setRSA } from '@joplin/lib/services/e2ee/ppk';
|
||||||
import RSA from './services/e2ee/RSA.react-native';
|
import RSA from './services/e2ee/RSA.react-native';
|
||||||
import { runIntegrationTests } from '@joplin/lib/services/e2ee/ppkTestUtils';
|
import { runIntegrationTests } from '@joplin/lib/services/e2ee/ppkTestUtils';
|
||||||
|
import { Theme, ThemeAppearance } from '@joplin/lib/themes/type';
|
||||||
import { AppState } from './utils/types';
|
import { AppState } from './utils/types';
|
||||||
import sensorInfo from './components/biometrics/sensorInfo';
|
import sensorInfo from './components/biometrics/sensorInfo';
|
||||||
|
|
||||||
|
@ -881,7 +883,7 @@ class AppComponent extends React.Component {
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
if (this.props.appState !== 'ready') return null;
|
if (this.props.appState !== 'ready') return null;
|
||||||
const theme = themeStyle(this.props.themeId);
|
const theme: Theme = themeStyle(this.props.themeId);
|
||||||
|
|
||||||
let sideMenuContent = null;
|
let sideMenuContent = null;
|
||||||
let menuPosition = 'left';
|
let menuPosition = 'left';
|
||||||
|
@ -912,7 +914,7 @@ class AppComponent extends React.Component {
|
||||||
// const statusBarStyle = theme.appearance === 'light-content';
|
// const statusBarStyle = theme.appearance === 'light-content';
|
||||||
const statusBarStyle = 'light-content';
|
const statusBarStyle = 'light-content';
|
||||||
|
|
||||||
return (
|
const mainContent = (
|
||||||
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
|
<View style={{ flex: 1, backgroundColor: theme.backgroundColor }}>
|
||||||
<SideMenu
|
<SideMenu
|
||||||
menu={sideMenuContent}
|
menu={sideMenuContent}
|
||||||
|
@ -945,6 +947,24 @@ class AppComponent extends React.Component {
|
||||||
</SideMenu>
|
</SideMenu>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const paperTheme = theme.appearance === ThemeAppearance.Dark ? PaperDarkTheme : PaperLightTheme;
|
||||||
|
|
||||||
|
// Wrap everything in a PaperProvider -- this allows using components from react-native-paper
|
||||||
|
return (
|
||||||
|
<PaperProvider theme={{
|
||||||
|
...paperTheme,
|
||||||
|
version: 2,
|
||||||
|
colors: {
|
||||||
|
...paperTheme.colors,
|
||||||
|
primary: theme.backgroundColor,
|
||||||
|
accent: theme.backgroundColor2,
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
{mainContent}
|
||||||
|
</PaperProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import BaseModel from './BaseModel';
|
||||||
import { Store } from 'redux';
|
import { Store } from 'redux';
|
||||||
import { ProfileConfig } from './services/profileConfig/types';
|
import { ProfileConfig } from './services/profileConfig/types';
|
||||||
import * as ArrayUtils from './ArrayUtils';
|
import * as ArrayUtils from './ArrayUtils';
|
||||||
|
import { FolderEntity } from './services/database/types';
|
||||||
const fastDeepEqual = require('fast-deep-equal');
|
const fastDeepEqual = require('fast-deep-equal');
|
||||||
const { ALL_NOTES_FILTER_ID } = require('./reserved-ids');
|
const { ALL_NOTES_FILTER_ID } = require('./reserved-ids');
|
||||||
const { createSelectorCreator, defaultMemoize } = require('reselect');
|
const { createSelectorCreator, defaultMemoize } = require('reselect');
|
||||||
|
@ -55,7 +56,7 @@ export interface State {
|
||||||
noteSelectionEnabled?: boolean;
|
noteSelectionEnabled?: boolean;
|
||||||
notesSource: string;
|
notesSource: string;
|
||||||
notesParentType: string;
|
notesParentType: string;
|
||||||
folders: any[];
|
folders: FolderEntity[];
|
||||||
tags: any[];
|
tags: any[];
|
||||||
masterKeys: any[];
|
masterKeys: any[];
|
||||||
notLoadedMasterKeys: string[];
|
notLoadedMasterKeys: string[];
|
||||||
|
|
51
yarn.lock
51
yarn.lock
|
@ -3150,6 +3150,18 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@callstack/react-theme-provider@npm:^3.0.8":
|
||||||
|
version: 3.0.8
|
||||||
|
resolution: "@callstack/react-theme-provider@npm:3.0.8"
|
||||||
|
dependencies:
|
||||||
|
deepmerge: ^3.2.0
|
||||||
|
hoist-non-react-statics: ^3.3.0
|
||||||
|
peerDependencies:
|
||||||
|
react: ">=16.3.0"
|
||||||
|
checksum: 6077a4795aea4eb06a2a2ffe5cf299c3fdcba56530aa68eba5c3ac0728ce02be2f6e9e71278be303065cb7fbe252c35639538477d5d05ee14f6325d550c8c696
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@cloudcmd/create-element@npm:^2.0.0":
|
"@cloudcmd/create-element@npm:^2.0.0":
|
||||||
version: 2.0.2
|
version: 2.0.2
|
||||||
resolution: "@cloudcmd/create-element@npm:2.0.2"
|
resolution: "@cloudcmd/create-element@npm:2.0.2"
|
||||||
|
@ -4732,9 +4744,11 @@ __metadata:
|
||||||
react-native-image-picker: 4.10.3
|
react-native-image-picker: 4.10.3
|
||||||
react-native-image-resizer: 1.4.5
|
react-native-image-resizer: 1.4.5
|
||||||
react-native-modal-datetime-picker: 14.0.1
|
react-native-modal-datetime-picker: 14.0.1
|
||||||
|
react-native-paper: 5.0.2
|
||||||
react-native-popup-menu: 0.16.1
|
react-native-popup-menu: 0.16.1
|
||||||
react-native-quick-actions: 0.3.13
|
react-native-quick-actions: 0.3.13
|
||||||
react-native-rsa-native: 2.0.5
|
react-native-rsa-native: 2.0.5
|
||||||
|
react-native-safe-area-context: 4.4.1
|
||||||
react-native-securerandom: 1.0.1
|
react-native-securerandom: 1.0.1
|
||||||
react-native-share: 8.1.0
|
react-native-share: 8.1.0
|
||||||
react-native-side-menu-updated: 1.3.2
|
react-native-side-menu-updated: 1.3.2
|
||||||
|
@ -11994,7 +12008,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"color@npm:3.2.1":
|
"color@npm:3.2.1, color@npm:^3.1.2":
|
||||||
version: 3.2.1
|
version: 3.2.1
|
||||||
resolution: "color@npm:3.2.1"
|
resolution: "color@npm:3.2.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -27687,6 +27701,22 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-native-paper@npm:5.0.2":
|
||||||
|
version: 5.0.2
|
||||||
|
resolution: "react-native-paper@npm:5.0.2"
|
||||||
|
dependencies:
|
||||||
|
"@callstack/react-theme-provider": ^3.0.8
|
||||||
|
color: ^3.1.2
|
||||||
|
use-event-callback: ^0.1.0
|
||||||
|
peerDependencies:
|
||||||
|
react: "*"
|
||||||
|
react-native: "*"
|
||||||
|
react-native-safe-area-context: "*"
|
||||||
|
react-native-vector-icons: "*"
|
||||||
|
checksum: 46481e3db2b297f2f02d1d05710d7ab329f901acc5a663e4c81fb7db83534e5d63067e9287bb396703e50d955ddfb8c41d7546cbd1ea2825a6888fd2e0fa80de
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react-native-popup-menu@npm:0.16.1":
|
"react-native-popup-menu@npm:0.16.1":
|
||||||
version: 0.16.1
|
version: 0.16.1
|
||||||
resolution: "react-native-popup-menu@npm:0.16.1"
|
resolution: "react-native-popup-menu@npm:0.16.1"
|
||||||
|
@ -27708,6 +27738,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-native-safe-area-context@npm:4.4.1":
|
||||||
|
version: 4.4.1
|
||||||
|
resolution: "react-native-safe-area-context@npm:4.4.1"
|
||||||
|
peerDependencies:
|
||||||
|
react: "*"
|
||||||
|
react-native: "*"
|
||||||
|
checksum: ef7c41ea59a34b114c6481fb130e66ef85e8d5b88acb46279131367761ca9fbf22cd310fe613f49b6c9b56dbd83e044be640f0532eda1d3856bf708e96335a35
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"react-native-securerandom@npm:1.0.1":
|
"react-native-securerandom@npm:1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "react-native-securerandom@npm:1.0.1"
|
resolution: "react-native-securerandom@npm:1.0.1"
|
||||||
|
@ -33141,6 +33181,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"use-event-callback@npm:^0.1.0":
|
||||||
|
version: 0.1.0
|
||||||
|
resolution: "use-event-callback@npm:0.1.0"
|
||||||
|
peerDependencies:
|
||||||
|
react: ">=16.8"
|
||||||
|
checksum: 1e15fb21306c74f877e9d57686546c363165429412dcb9260254d2dd8f56692cb01ba2162f9169e6fc15b01cf3921b9cd8a9c60cf777d0143afcee92c1a7976a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"use-isomorphic-layout-effect@npm:^1.1.2":
|
"use-isomorphic-layout-effect@npm:^1.1.2":
|
||||||
version: 1.1.2
|
version: 1.1.2
|
||||||
resolution: "use-isomorphic-layout-effect@npm:1.1.2"
|
resolution: "use-isomorphic-layout-effect@npm:1.1.2"
|
||||||
|
|
Loading…
Reference in New Issue