1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-11 18:24:43 +02:00

Mobile: Improved side menu: Made button panel fixed at the bottom, and added dark overlay over right side content

This commit is contained in:
Laurent Cozic 2019-06-26 18:05:37 +00:00
parent 430a11282b
commit e7e0264411
2 changed files with 69 additions and 66 deletions

View File

@ -26,6 +26,8 @@ class SideMenuContentComponent extends Component {
this.tagButton_press = this.tagButton_press.bind(this);
this.newFolderButton_press = this.newFolderButton_press.bind(this);
this.synchronize_press = this.synchronize_press.bind(this);
this.configButton_press = this.configButton_press.bind(this);
}
styles() {
@ -58,6 +60,7 @@ class SideMenuContentComponent extends Component {
paddingRight: theme.marginRight,
color: theme.colorFaded,
fontSize: theme.fontSizeSmaller,
flex: 0,
},
sidebarIcon: {
fontSize: 22,
@ -74,7 +77,7 @@ class SideMenuContentComponent extends Component {
styles.folderIcon.color = theme.colorFaded;//'#0072d5';
styles.folderIcon.paddingTop = 3;
styles.sideButton = Object.assign({}, styles.button);
styles.sideButton = Object.assign({}, styles.button, { flex: 0 });
styles.sideButtonText = Object.assign({}, styles.buttonText);
this.styles_[this.props.theme] = StyleSheet.create(styles);
@ -107,6 +110,11 @@ class SideMenuContentComponent extends Component {
});
}
configButton_press() {
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
NavService.go('Config');
}
newFolderButton_press() {
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
@ -160,22 +168,6 @@ class SideMenuContentComponent extends Component {
);
}
synchronizeButton(state) {
const theme = themeStyle(this.props.theme);
const title = state == 'sync' ? _('Synchronise') : _('Cancel synchronisation');
const iconComp = state == 'sync' ? <Icon name='md-sync' style={this.styles().sidebarIcon} /> : <Icon name='md-close' style={this.styles().sidebarIcon} />;
return (
<TouchableOpacity key={'synchronize_button'} onPress={() => { this.synchronize_press() }}>
<View style={this.styles().sideButton}>
{ iconComp }
<Text style={this.styles().sideButtonText}>{title}</Text>
</View>
</TouchableOpacity>
);
}
renderSideBarButton(key, title, iconName, onPressHandler) {
const theme = themeStyle(this.props.theme);
@ -193,23 +185,52 @@ class SideMenuContentComponent extends Component {
return <View style={{ marginTop: 15, marginBottom: 15, flex: -1, borderBottomWidth: 1, borderBottomColor: globalStyle.dividerColor }} key={key}></View>
}
renderConfigButton() {
const buttons = [];
renderBottomPanel() {
const theme = themeStyle(this.props.theme);
buttons.push({
icon: 'md-settings',
onPress: () => {
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
NavService.go('Config');
},
});
const items = [];
items.push(this.makeDivider('divider_1'));
items.push(this.renderSideBarButton('newFolder_button', _('New Notebook'), 'md-folder-open', this.newFolderButton_press));
items.push(this.renderSideBarButton('tag_button', _('Tags'), 'md-pricetag', this.tagButton_press));
items.push(this.renderSideBarButton('config_button', _('Configuration'), 'md-settings', this.configButton_press));
items.push(this.makeDivider('divider_2'));
let lines = Synchronizer.reportToLines(this.props.syncReport);
const syncReportText = lines.join("\n");
let decryptionReportText = '';
if (this.props.decryptionWorker && this.props.decryptionWorker.state !== 'idle' && this.props.decryptionWorker.itemCount) {
decryptionReportText = _('Decrypting items: %d/%d', this.props.decryptionWorker.itemIndex + 1, this.props.decryptionWorker.itemCount);
}
let resourceFetcherText = '';
if (this.props.resourceFetcher && this.props.resourceFetcher.toFetchCount) {
resourceFetcherText = _('Fetching resources: %d/%d', this.props.resourceFetcher.fetchingCount, this.props.resourceFetcher.toFetchCount);
}
let fullReport = [];
if (syncReportText) fullReport.push(syncReportText);
if (resourceFetcherText) fullReport.push(resourceFetcherText);
if (decryptionReportText) fullReport.push(decryptionReportText);
items.push(this.renderSideBarButton(
'synchronize_button',
!this.props.syncStarted ? _('Synchronise') : _('Cancel synchronisation'),
!this.props.syncStarted ? 'md-sync' : 'md-close',
this.synchronize_press
));
if (fullReport.length) items.push(<Text key='sync_report' style={this.styles().syncStatus}>{fullReport.join('\n')}</Text>);
return (
<ActionButton
buttons={buttons}
buttonIndex={0}
multiStates={true}
/>
<View style={{ flex: 0, flexDirection: 'column', paddingBottom: theme.marginBottom }}>
{ items }
</View>
);
}
@ -228,39 +249,6 @@ class SideMenuContentComponent extends Component {
items = items.concat(folderItems);
}
items.push(this.makeDivider('divider_1'));
items.push(this.renderSideBarButton('newFolder_button', _('New Notebook'), 'md-folder-open', this.newFolderButton_press));
items.push(this.renderSideBarButton('tag_button', _('Tags'), 'md-pricetag', this.tagButton_press));
let lines = Synchronizer.reportToLines(this.props.syncReport);
const syncReportText = lines.join("\n");
let decryptionReportText = '';
if (this.props.decryptionWorker && this.props.decryptionWorker.state !== 'idle' && this.props.decryptionWorker.itemCount) {
decryptionReportText = _('Decrypting items: %d/%d', this.props.decryptionWorker.itemIndex + 1, this.props.decryptionWorker.itemCount);
}
let resourceFetcherText = '';
if (this.props.resourceFetcher && this.props.resourceFetcher.toFetchCount) {
resourceFetcherText = _('Fetching resources: %d/%d', this.props.resourceFetcher.fetchingCount, this.props.resourceFetcher.toFetchCount);
}
let fullReport = [];
if (syncReportText) fullReport.push(syncReportText);
// if (fullReport.length) fullReport.push('');
if (resourceFetcherText) fullReport.push(resourceFetcherText);
if (decryptionReportText) fullReport.push(decryptionReportText);
while (fullReport.length < 12) fullReport.push(''); // Add blank lines so that height of report text is fixed and doesn't affect scrolling
items.push(this.synchronizeButton(this.props.syncStarted ? 'cancel' : 'sync'));
items.push(<Text key='sync_report' style={this.styles().syncStatus}>{fullReport.join('\n')}</Text>);
items.push(<View style={{ height: globalStyle.marginBottom }} key='bottom_padding_hack'/>);
let style = {
flex:1,
borderRightWidth: 1,
@ -274,7 +262,7 @@ class SideMenuContentComponent extends Component {
<ScrollView scrollsToTop={false} style={this.styles().menu}>
{ items }
</ScrollView>
{ this.renderConfigButton() }
{ this.renderBottomPanel() }
</View>
</View>
);

View File

@ -1,5 +1,5 @@
const React = require('react'); const Component = React.Component;
const { AppState, Keyboard, NativeModules, BackHandler, Platform } = require('react-native');
const { AppState, Keyboard, NativeModules, BackHandler, Platform, View, Animated } = require('react-native');
const { SafeAreaView } = require('react-navigation');
const { connect, Provider } = require('react-redux');
const { BackButtonService } = require('lib/services/back-button.js');
@ -552,6 +552,11 @@ class AppComponent extends React.Component {
constructor() {
super();
this.state = {
sideMenuContentOpacity: new Animated.Value(0),
};
this.lastSyncStarted_ = defaultState.syncStarted;
this.backButtonHandler_ = () => {
@ -630,6 +635,15 @@ class AppComponent extends React.Component {
AppState.removeEventListener('change', this.onAppStateChange_);
}
componentDidUpdate(prevProps) {
if (this.props.showSideMenu !== prevProps.showSideMenu) {
Animated.timing(this.state.sideMenuContentOpacity, {
toValue: this.props.showSideMenu ? 0.5 : 0,
duration: 600,
}).start();
}
}
async backButtonHandler() {
if (this.props.noteSelectionEnabled) {
this.props.dispatch({ type: 'NOTE_SELECTION_END' });
@ -704,6 +718,7 @@ class AppComponent extends React.Component {
<AppNav screens={appNavInit} />
</SafeAreaView>
<DropdownAlert ref={ref => this.dropdownAlert_ = ref} tapToCloseEnabled={true} />
<Animated.View pointerEvents='none' style={{position:'absolute', backgroundColor:'black', opacity: this.state.sideMenuContentOpacity, width: '100%', height: '100%'}}/>
</MenuContext>
</SideMenu>
);