diff --git a/Icon.psd b/Icon.psd new file mode 100644 index 000000000..e92deb6e4 Binary files /dev/null and b/Icon.psd differ diff --git a/Icon144.png b/Icon144.png new file mode 100644 index 000000000..252c16948 Binary files /dev/null and b/Icon144.png differ diff --git a/Icon48.png b/Icon48.png new file mode 100644 index 000000000..f5ab076ae Binary files /dev/null and b/Icon48.png differ diff --git a/Icon512.png b/Icon512.png new file mode 100644 index 000000000..ef8624663 Binary files /dev/null and b/Icon512.png differ diff --git a/Icon72.png b/Icon72.png new file mode 100644 index 000000000..dbac3fae8 Binary files /dev/null and b/Icon72.png differ diff --git a/Icon96.png b/Icon96.png new file mode 100644 index 000000000..cb1faeb10 Binary files /dev/null and b/Icon96.png differ diff --git a/ReactNativeClient/android/app/build.gradle b/ReactNativeClient/android/app/build.gradle index 1e8fe217c..2e9abc594 100644 --- a/ReactNativeClient/android/app/build.gradle +++ b/ReactNativeClient/android/app/build.gradle @@ -90,8 +90,8 @@ android { applicationId "net.cozic.joplin" minSdkVersion 16 targetSdkVersion 22 - versionCode 24 - versionName "0.9.11" + versionCode 26 + versionName "0.9.13" ndk { abiFilters "armeabi-v7a", "x86" } diff --git a/ReactNativeClient/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/ReactNativeClient/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index cde69bccc..dbac3fae8 100644 Binary files a/ReactNativeClient/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/ReactNativeClient/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/ReactNativeClient/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/ReactNativeClient/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index c133a0cbd..f5ab076ae 100644 Binary files a/ReactNativeClient/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/ReactNativeClient/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/ReactNativeClient/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/ReactNativeClient/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index bfa42f0e7..cb1faeb10 100644 Binary files a/ReactNativeClient/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/ReactNativeClient/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/ReactNativeClient/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/ReactNativeClient/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 324e72cdd..252c16948 100644 Binary files a/ReactNativeClient/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/ReactNativeClient/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/ReactNativeClient/lib/components/action-button.js b/ReactNativeClient/lib/components/action-button.js index 871ba6a2e..5a68972b9 100644 --- a/ReactNativeClient/lib/components/action-button.js +++ b/ReactNativeClient/lib/components/action-button.js @@ -102,7 +102,7 @@ class ActionButtonComponent extends React.Component { } let mainButton = this.props.mainButton ? this.props.mainButton : {}; - let mainIcon = mainButton.icon ? : +; + let mainIcon = mainButton.icon ? : if (this.props.multiStates) { if (!this.props.buttons || !this.props.buttons.length) throw new Error('Multi-state button requires at least one state'); diff --git a/ReactNativeClient/lib/components/base-screen.js b/ReactNativeClient/lib/components/base-screen.js index af515edd3..c19ef093f 100644 --- a/ReactNativeClient/lib/components/base-screen.js +++ b/ReactNativeClient/lib/components/base-screen.js @@ -1,10 +1,11 @@ import React, { Component } from 'react'; import { StyleSheet } from 'react-native'; +import { globalStyle } from 'lib/components/global-style.js'; const styles_ = StyleSheet.create({ screen: { flex: 1, - backgroundColor: "#E9E9E9", + backgroundColor: globalStyle.backgroundColor, }, }); diff --git a/ReactNativeClient/lib/components/checkbox.js b/ReactNativeClient/lib/components/checkbox.js index 72fb0b04b..e93f8a70a 100644 --- a/ReactNativeClient/lib/components/checkbox.js +++ b/ReactNativeClient/lib/components/checkbox.js @@ -2,13 +2,13 @@ import React, { Component } from 'react'; import { StyleSheet, TouchableHighlight } from 'react-native'; import Icon from 'react-native-vector-icons/Ionicons'; -const styles = StyleSheet.create({ +const styles = { checkboxIcon: { fontSize: 20, height: 22, marginRight: 10, }, -}); +}; class Checkbox extends Component { @@ -42,9 +42,19 @@ class Checkbox extends Component { style.justifyContent = 'center'; style.alignItems = 'center'; + const checkboxIconStyle = Object.assign({}, styles.checkboxIcon); + if (style.color) checkboxIconStyle.color = style.color; + + const thStyle = { + justifyContent: 'center', + alignItems: 'center', + }; + + if (style.display) thStyle.display = style.display; + return ( - this.onPress()} style={style}> - + this.onPress()} style={thStyle}> + ); } diff --git a/ReactNativeClient/lib/components/global-style.js b/ReactNativeClient/lib/components/global-style.js new file mode 100644 index 000000000..b58109837 --- /dev/null +++ b/ReactNativeClient/lib/components/global-style.js @@ -0,0 +1,17 @@ +const globalStyle = { + margin: 15, // No text and no interactive component should be within this margin + backgroundColor: "#ffffff", + color: "#555555", + fontSize: 10, + dividerColor: "#dddddd", + + // For WebView - must correspond to the properties above + htmlFontSize: '14px', + htmlColor: 'black', // Note: CSS in WebView component only seem to work if the colour is written in full letters (so no hexadecimal) +}; + +globalStyle.marginRight = globalStyle.margin; +globalStyle.marginLeft = globalStyle.margin; +globalStyle.htmlMarginLeft = ((globalStyle.marginLeft / 10) * 0.6).toFixed(2) + 'em'; + +export { globalStyle } \ No newline at end of file diff --git a/ReactNativeClient/lib/components/item-list.js b/ReactNativeClient/lib/components/item-list.js index b4a066755..f00ea3e9e 100644 --- a/ReactNativeClient/lib/components/item-list.js +++ b/ReactNativeClient/lib/components/item-list.js @@ -1,12 +1,25 @@ import React, { Component } from 'react'; import { connect } from 'react-redux' -import { ListView, Text, TouchableHighlight, Switch, View } from 'react-native'; +import { ListView, Text, TouchableHighlight, Switch, View, StyleSheet } from 'react-native'; import { Log } from 'lib/log.js'; import { _ } from 'lib/locale.js'; import { Checkbox } from 'lib/components/checkbox.js'; import { reg } from 'lib/registry.js'; import { Note } from 'lib/models/note.js'; import { time } from 'lib/time-utils.js'; +import { globalStyle } from 'lib/components/global-style.js'; + +const styles = StyleSheet.create({ + listItem: { + flexDirection: 'row', + height: 40, + borderBottomWidth: 1, + borderBottomColor: globalStyle.dividerColor, + alignItems: 'center', + paddingLeft: globalStyle.marginLeft, + backgroundColor: globalStyle.backgroundColor, + }, +}); class ItemListComponent extends Component { @@ -53,15 +66,16 @@ class ItemListComponent extends Component { this.listView_itemLongPress(item.id); } - const checkboxStyle = {}; + const listItemStyle = { color: globalStyle.color }; + const checkboxStyle = Object.assign({}, listItemStyle); if (!Number(item.is_todo)) checkboxStyle.display = 'none'; const checkboxChecked = !!Number(item.todo_completed); return ( - - - { this.todoCheckbox_change(item.id, checked) }}/>{item.title} + + + { this.todoCheckbox_change(item.id, checked) }}/>{item.title} ); diff --git a/ReactNativeClient/lib/components/screen-header.js b/ReactNativeClient/lib/components/screen-header.js index 6361e02b6..ce91cfa46 100644 --- a/ReactNativeClient/lib/components/screen-header.js +++ b/ReactNativeClient/lib/components/screen-header.js @@ -8,13 +8,30 @@ import { Setting } from 'lib/models/setting.js'; import { FileApi } from 'lib/file-api.js'; import { FileApiDriverOneDrive } from 'lib/file-api-driver-onedrive.js'; import { reg } from 'lib/registry.js' +import { globalStyle } from 'lib/components/global-style.js'; let styleObject = { + container: { + flexDirection: 'row', + paddingLeft: globalStyle.marginLeft, + paddingTop: 10, + paddingBottom: 10, + paddingRight: 0, + backgroundColor: globalStyle.backgroundColor, + alignItems: 'center', + shadowColor: '#000000', + elevation: 5, + }, + folderPicker: { + height: 30, + flex:1, + color: globalStyle.color, + backgroundColor: globalStyle.backgroundColor, + }, divider: { - marginVertical: 5, - marginHorizontal: 2, borderBottomWidth: 1, - borderColor: '#ccc' + borderColor: globalStyle.dividerColor, + backgroundColor: "#0000ff" }, sideMenuButton: { flex: 1, @@ -55,6 +72,31 @@ let styleObject = { fontWeight: 'bold', flex: 1, }, + contextMenuTrigger: { + fontSize: 25, + paddingRight: globalStyle.marginRight, + color: globalStyle.color, + }, + contextMenu: { + backgroundColor: globalStyle.backgroundColor, + }, + contextMenuItem: { + backgroundColor: globalStyle.backgroundColor, + }, + contextMenuItemText: { + flex: 1, + height: 40, + textAlignVertical: 'center', + paddingLeft: globalStyle.marginLeft, + paddingRight: globalStyle.marginRight, + color: globalStyle.color, + backgroundColor: globalStyle.backgroundColor, + }, + titleText: { + flex: 1, + marginLeft: 10, + color: globalStyle.color, + } }; styleObject.backButtonDisabled = Object.assign({}, styleObject.backButton, { backgroundColor: "#c6c6c6" }); @@ -131,8 +173,8 @@ class ScreenHeaderComponent extends Component { for (let i = 0; i < this.props.menuOptions.length; i++) { let o = this.props.menuOptions[i]; menuOptionComponents.push( - - {o.title} + + {o.title} ); } @@ -141,13 +183,13 @@ class ScreenHeaderComponent extends Component { } menuOptionComponents.push( - this.log_press()} key={'menuOption_' + key++}> - {_('Log')} + this.log_press()} key={'menuOption_' + key++} style={styles.contextMenuItem}> + {_('Log')} ); menuOptionComponents.push( - this.status_press()} key={'menuOption_' + key++}> - {_('Status')} + this.status_press()} key={'menuOption_' + key++} style={styles.contextMenuItem}> + {_('Status')} ); const createTitleComponent = () => { @@ -156,30 +198,30 @@ class ScreenHeaderComponent extends Component { let items = []; for (let i = 0; i < p.items.length; i++) { let item = p.items[i]; - items.push(); + items.push(); } return ( - { if (p.onValueChange) p.onValueChange(itemValue, itemIndex); }}> + { if (p.onValueChange) p.onValueChange(itemValue, itemIndex); }}> { items } ); } else { let title = 'title' in this.props && this.props.title !== null ? this.props.title : _(this.props.navState.routeName); - return {title} + return {title} } } const titleComp = createTitleComponent(); return ( - + { sideMenuButton(styles, () => this.sideMenuButton_press()) } { backButton(styles, () => this.backButton_press(), !this.props.historyCanGoBack) } { saveButton(styles, () => { if (this.props.onSaveButtonPress) this.props.onSaveButtonPress() }, this.props.saveButtonDisabled === true, this.props.showSaveButton === true) } { titleComp } - this.menu_select(value)}> + this.menu_select(value)} style={styles.contextMenu}> - + { menuOptionComponents } diff --git a/ReactNativeClient/lib/components/screens/note.js b/ReactNativeClient/lib/components/screens/note.js index 1875e29f8..73671f1a8 100644 --- a/ReactNativeClient/lib/components/screens/note.js +++ b/ReactNativeClient/lib/components/screens/note.js @@ -16,11 +16,22 @@ import { reg } from 'lib/registry.js'; import { BaseScreenComponent } from 'lib/components/base-screen.js'; import { dialogs } from 'lib/dialogs.js'; import { NotesScreenUtils } from 'lib/components/screens/notes-utils.js' +import { globalStyle } from 'lib/components/global-style.js'; import DialogBox from 'react-native-dialogbox'; const styles = StyleSheet.create({ - webView: { - fontSize: 10, + titleTextInput: { + flex: 1, + color: globalStyle.color, + backgroundColor: globalStyle.backgroundColor, + }, + bodyTextInput: { + flex: 1, + marginLeft: globalStyle.marginLeft, + marginRight: globalStyle.marginRight, + textAlignVertical: 'top', + color: globalStyle.color, + backgroundColor: globalStyle.backgroundColor, }, }); @@ -259,7 +270,7 @@ class NoteScreenComponent extends BaseScreenComponent { return body; } - function markdownToHtml(body) { + function markdownToHtml(body, style) { // https://necolas.github.io/normalize.css/ const normalizeCss = ` html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} @@ -267,10 +278,12 @@ class NoteScreenComponent extends BaseScreenComponent { pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects} b,strong{font-weight:bolder}small{font-size:80%}img{border-style:none} `; + const css = ` body { - font-size: 16px; - margin: 1em; + font-size: ` + style.htmlFontSize + `; + margin: ` + style.htmlMarginLeft + `; + color: ` + style.htmlColor + `; } h1 { font-size: 1.2em; @@ -291,7 +304,7 @@ class NoteScreenComponent extends BaseScreenComponent { position: relative; top: 0.1em; text-decoration: none; - color: black; + color: ` + style.htmlColor + `; } table { border-collapse: collapse; @@ -327,9 +340,8 @@ class NoteScreenComponent extends BaseScreenComponent { bodyComponent = ( { - // 'checkboxclick_NOTICK_0' let msg = event.nativeEvent.data; if (msg.indexOf('checkboxclick_') === 0) { msg = msg.split('_'); @@ -347,7 +359,7 @@ class NoteScreenComponent extends BaseScreenComponent { this.body_changeText(text)} @@ -387,6 +399,15 @@ class NoteScreenComponent extends BaseScreenComponent { if (showSaveButton) this.saveButtonHasBeenShown_ = true; + let titleContainerStyle = { + flexDirection: 'row', + paddingLeft: globalStyle.marginLeft, + height: 40, + borderBottomColor: globalStyle.dividerColor, + borderBottomWidth: 1, + }; + if (!isTodo) titleContainerStyle.paddingLeft -= 3; // Because the TextInput already includes a padding + return ( this.saveNoteButton_press()} /> - - { isTodo && { this.todoCheckbox_change(checked) }} /> } this.title_changeText(text)} /> + + { isTodo && { this.todoCheckbox_change(checked) }} /> } this.title_changeText(text)} /> { bodyComponent } { actionButtonComp } diff --git a/ReactNativeClient/lib/components/side-menu-content.js b/ReactNativeClient/lib/components/side-menu-content.js index aab86f28c..45898fa19 100644 --- a/ReactNativeClient/lib/components/side-menu-content.js +++ b/ReactNativeClient/lib/components/side-menu-content.js @@ -7,6 +7,7 @@ import { NotesScreenUtils } from 'lib/components/screens/notes-utils.js' import { Synchronizer } from 'lib/synchronizer.js'; import { reg } from 'lib/registry.js'; import { _ } from 'lib/locale.js'; +import { globalStyle } from 'lib/components/global-style.js'; const React = require('react'); const { @@ -21,7 +22,7 @@ const { Component } = React; const styles = StyleSheet.create({ menu: { flex: 1, - backgroundColor: 'white', + backgroundColor: globalStyle.backgroundColor, padding: 20, }, name: { @@ -37,15 +38,15 @@ const styles = StyleSheet.create({ folderButton: { flex: 1, backgroundColor: "#0482E3", - paddingLeft: 20, - paddingRight: 20, - paddingTop: 14, - paddingBottom: 14, + height: 36, marginBottom: 5, }, folderButtonText: { color: "#ffffff", fontWeight: 'bold', + textAlign: 'center', + textAlignVertical: 'center', + flex: 1, }, button: { flex: 1, diff --git a/ReactNativeClient/lib/components/style.js b/ReactNativeClient/lib/components/style.js deleted file mode 100644 index 0944a0044..000000000 --- a/ReactNativeClient/lib/components/style.js +++ /dev/null @@ -1,7 +0,0 @@ -const styles = StyleSheet.create({ - webView: { - fontSize: 10, - }, -}); - -export { styles } \ No newline at end of file