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:
parent
430a11282b
commit
e7e0264411
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user