mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Mobile: Made tag UI a dialog
This commit is contained in:
parent
d6f7893c56
commit
ca3946689a
@ -30,21 +30,21 @@ class ModalDialog extends React.Component {
|
||||
borderColor:theme.dividerColor,
|
||||
margin: 20,
|
||||
padding: 10,
|
||||
borderRadius: 5,
|
||||
},
|
||||
modalContentWrapper2: {
|
||||
paddingTop: 10,
|
||||
flex:1,
|
||||
},
|
||||
title: {
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: theme.dividerColor,
|
||||
paddingBottom: 10,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
buttonRow: {
|
||||
flexDirection: 'row',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: theme.dividerColor,
|
||||
paddingTop: 10,
|
||||
},
|
||||
};
|
||||
|
||||
@ -54,21 +54,22 @@ class ModalDialog extends React.Component {
|
||||
|
||||
render() {
|
||||
const ContentComponent = this.props.ContentComponent;
|
||||
const buttonBarEnabled = this.props.buttonBarEnabled !== false;
|
||||
|
||||
return (
|
||||
<View style={this.styles().modalWrapper}>
|
||||
<Modal transparent={true} visible={true} onRequestClose={() => { }} >
|
||||
<View style={this.styles().modalContentWrapper}>
|
||||
<Text style={this.styles().title}>Title</Text>
|
||||
<View elevation={10} style={this.styles().modalContentWrapper}>
|
||||
<Text style={this.styles().title}>{this.props.title}</Text>
|
||||
<View style={this.styles().modalContentWrapper2}>
|
||||
{ContentComponent}
|
||||
</View>
|
||||
<View style={this.styles().buttonRow}>
|
||||
<View style={{flex:1}}>
|
||||
<Button title={_('OK')} onPress={() => {}}></Button>
|
||||
<Button disabled={!buttonBarEnabled} title={_('OK')} onPress={this.props.onOkPress}></Button>
|
||||
</View>
|
||||
<View style={{flex:1, marginLeft: 5}}>
|
||||
<Button title={_('Cancel')} onPress={() => {}}></Button>
|
||||
<Button disabled={!buttonBarEnabled} title={_('Cancel')} onPress={this.props.onCancelPress}></Button>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -12,18 +12,12 @@ const { Database } = require('lib/database.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { BaseScreenComponent } = require('lib/components/base-screen.js');
|
||||
const { globalStyle, themeStyle } = require('lib/components/global-style.js');
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const ModalDialog = require('lib/components/ModalDialog');
|
||||
const naturalCompare = require('string-natural-compare');
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
body: {
|
||||
flex: 1,
|
||||
margin: globalStyle.margin,
|
||||
},
|
||||
});
|
||||
|
||||
class NoteTagsScreenComponent extends BaseScreenComponent {
|
||||
class NoteTagsDialogComponent extends React.Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -94,15 +88,11 @@ class NoteTagsScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ savingTags: false });
|
||||
}
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_BACK',
|
||||
});
|
||||
if (this.props.onCloseRequested) this.props.onCloseRequested();
|
||||
}
|
||||
|
||||
this.cancelButton_press = () => {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_BACK',
|
||||
});
|
||||
if (this.props.onCloseRequested) this.props.onCloseRequested();
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,6 +112,11 @@ class NoteTagsScreenComponent extends BaseScreenComponent {
|
||||
selected: tagIds.indexOf(tag.id) >= 0,
|
||||
}});
|
||||
|
||||
tagListData.sort((a, b) => {
|
||||
return naturalCompare.caseInsensitive(a.title, b.title);
|
||||
//return a.title.toLowerCase() < b.title.toLowerCase() ? -1 : +1;
|
||||
});
|
||||
|
||||
this.setState({ tagListData: tagListData });
|
||||
}
|
||||
|
||||
@ -151,8 +146,8 @@ class NoteTagsScreenComponent extends BaseScreenComponent {
|
||||
alignItems: 'center',
|
||||
paddingLeft: theme.marginLeft,
|
||||
paddingRight: theme.marginRight,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: theme.dividerColor
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: theme.dividerColor
|
||||
},
|
||||
};
|
||||
|
||||
@ -163,32 +158,32 @@ class NoteTagsScreenComponent extends BaseScreenComponent {
|
||||
render() {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
return (
|
||||
<View style={this.rootStyle(this.props.theme).root}>
|
||||
<ScreenHeader title={_('Note tags')} showSideMenuButton={false} showSearchButton={false} showContextMenuButton={false}/>
|
||||
const dialogContent = (
|
||||
<View style={{flex:1}}>
|
||||
<View style={this.styles().newTagBox}>
|
||||
<Text>{_('New tags:')}</Text><TextInput value={this.state.newTags} onChangeText={value => { this.setState({ newTags: value }) }} style={{flex:1}}/>
|
||||
</View>
|
||||
<FlatList
|
||||
data={this.state.tagListData}
|
||||
renderItem={this.renderTag}
|
||||
keyExtractor={this.tagKeyExtractor}
|
||||
/>
|
||||
<View style={this.styles().newTagBox}>
|
||||
<Text>{_('Or type tags:')}</Text><TextInput value={this.state.newTags} onChangeText={value => { this.setState({ newTags: value }) }} style={{flex:1}}/>
|
||||
</View>
|
||||
<View style={theme.buttonRow}>
|
||||
<View style={{flex:1}}>
|
||||
<Button disabled={this.state.savingTags} title={_('OK')} onPress={this.okButton_press}></Button>
|
||||
</View>
|
||||
<View style={{flex:1, marginLeft: 5}}>
|
||||
<Button disabled={this.state.savingTags} title={_('Cancel')} onPress={this.cancelButton_press}></Button>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
return <ModalDialog
|
||||
theme={this.props.theme}
|
||||
ContentComponent={dialogContent}
|
||||
title={_('Type new tags or select from list')}
|
||||
onOkPress={this.okButton_press}
|
||||
onCancelPress={this.cancelButton_press}
|
||||
buttonBarEnabled={!this.state.savingTags}
|
||||
/>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const NoteTagsScreen = connect(
|
||||
const NoteTagsDialog = connect(
|
||||
(state) => {
|
||||
return {
|
||||
theme: state.settings.theme,
|
||||
@ -196,6 +191,6 @@ const NoteTagsScreen = connect(
|
||||
noteId: state.selectedNoteIds.length ? state.selectedNoteIds[0] : null,
|
||||
};
|
||||
}
|
||||
)(NoteTagsScreenComponent)
|
||||
)(NoteTagsDialogComponent)
|
||||
|
||||
module.exports = { NoteTagsScreen };
|
||||
module.exports = NoteTagsDialog;
|
@ -15,6 +15,7 @@ const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const { fileExtension, basename, safeFileExtension } = require('lib/path-utils.js');
|
||||
const mimeUtils = require('lib/mime-utils.js').mime;
|
||||
const { ScreenHeader } = require('lib/components/screen-header.js');
|
||||
const NoteTagsDialog = require('lib/components/screens/NoteTagsDialog');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { Checkbox } = require('lib/components/checkbox.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
@ -51,7 +52,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
isLoading: true,
|
||||
titleTextInputHeight: 20,
|
||||
alarmDialogShown: false,
|
||||
heightBumpView:0
|
||||
heightBumpView:0,
|
||||
noteTagDialogShown: false,
|
||||
};
|
||||
|
||||
// iOS doesn't support multiline text fields properly so disable it
|
||||
@ -101,6 +103,10 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.noteTagDialog_closeRequested = () => {
|
||||
this.setState({ noteTagDialogShown: false });
|
||||
}
|
||||
}
|
||||
|
||||
styles() {
|
||||
@ -360,11 +366,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
tags_onPress() {
|
||||
if (!this.state.note || !this.state.note.id) return;
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'NoteTags',
|
||||
noteId: this.state.note.id,
|
||||
});
|
||||
this.setState({ noteTagDialogShown: true });
|
||||
}
|
||||
|
||||
setAlarm_onPress() {
|
||||
@ -547,6 +549,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
</View>
|
||||
);
|
||||
|
||||
const noteTagDialog = !this.state.noteTagDialogShown ? null : <NoteTagsDialog onCloseRequested={this.noteTagDialog_closeRequested}/>;
|
||||
|
||||
return (
|
||||
<View style={this.rootStyle(this.props.theme).root}>
|
||||
<ScreenHeader
|
||||
@ -584,6 +588,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
/>
|
||||
|
||||
<DialogBox ref={dialogbox => { this.dialogbox = dialogbox }}/>
|
||||
{ noteTagDialog }
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class FsDriverRN extends FsDriverBase {
|
||||
|
||||
// same as rm -rf
|
||||
async remove(path) {
|
||||
throw new Error('Not implemented');
|
||||
return await this.unlink(path);
|
||||
}
|
||||
|
||||
writeBinaryFile(path, content) {
|
||||
|
5
ReactNativeClient/package-lock.json
generated
5
ReactNativeClient/package-lock.json
generated
@ -6533,6 +6533,11 @@
|
||||
"strip-ansi": "3.0.1"
|
||||
}
|
||||
},
|
||||
"string-natural-compare": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-2.0.2.tgz",
|
||||
"integrity": "sha1-xc5OJ4q10SZa5vxVQ1rre3b8sAE="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
|
@ -46,6 +46,7 @@
|
||||
"react-redux": "4.4.8",
|
||||
"redux": "3.6.0",
|
||||
"stream": "0.0.2",
|
||||
"string-natural-compare": "^2.0.2",
|
||||
"timers": "^0.1.1",
|
||||
"url-parse": "^1.2.0",
|
||||
"uuid": "^3.0.1",
|
||||
|
@ -32,7 +32,6 @@ const { ConfigScreen } = require('lib/components/screens/config.js');
|
||||
const { FolderScreen } = require('lib/components/screens/folder.js');
|
||||
const { LogScreen } = require('lib/components/screens/log.js');
|
||||
const { StatusScreen } = require('lib/components/screens/status.js');
|
||||
const { NoteTagsScreen } = require('lib/components/screens/note-tags.js');
|
||||
const { WelcomeScreen } = require('lib/components/screens/welcome.js');
|
||||
const { SearchScreen } = require('lib/components/screens/search.js');
|
||||
const { OneDriveLoginScreen } = require('lib/components/screens/onedrive-login.js');
|
||||
@ -129,7 +128,7 @@ const generalMiddleware = store => next => async (action) => {
|
||||
let navHistory = [];
|
||||
|
||||
function historyCanGoBackTo(route, nextRoute) {
|
||||
if (route.routeName === 'Note' && nextRoute.routeName !== 'NoteTags') return false;
|
||||
if (route.routeName === 'Note') return false;
|
||||
if (route.routeName === 'Folder') return false;
|
||||
|
||||
return true;
|
||||
@ -565,7 +564,6 @@ class AppComponent extends React.Component {
|
||||
Status: { screen: StatusScreen },
|
||||
Search: { screen: SearchScreen },
|
||||
Config: { screen: ConfigScreen },
|
||||
NoteTags: { screen: NoteTagsScreen },
|
||||
};
|
||||
|
||||
return (
|
||||
|
Loading…
Reference in New Issue
Block a user