Merge branch 'master' of https://github.com/esteemapp/esteem-mobile into bugfix/#275

This commit is contained in:
u-e 2019-01-21 11:38:51 +03:00
commit 5e280ea6f5
25 changed files with 297 additions and 104 deletions

View File

@ -140,6 +140,7 @@ android {
}
dependencies {
compile project(':react-native-version-number')
compile project(':react-native-code-push')
compile project(':realm')
compile project(':react-native-fast-image')

View File

@ -3,6 +3,7 @@ package app.esteem.mobile;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.apsl.versionnumber.RNVersionNumberPackage;
import com.microsoft.codepush.react.CodePush;
import io.realm.react.RealmReactPackage;
import com.dylanvann.fastimage.FastImageViewPackage;
@ -43,6 +44,7 @@ public class MainApplication extends Application implements ReactApplication {
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNVersionNumberPackage(),
new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG),
new RealmReactPackage(),
new FastImageViewPackage(),

View File

@ -1,4 +1,6 @@
rootProject.name = 'eSteem'
include ':react-native-version-number'
project(':react-native-version-number').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-version-number/android')
include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
include ':realm'

View File

@ -36,6 +36,8 @@ target 'eSteem' do
pod 'CodePush', :path => '../node_modules/react-native-code-push'
pod 'react-native-version-number', :path => '../node_modules/react-native-version-number'
target 'eSteemTests' do
inherit! :search_paths
# Pods for testing

View File

@ -14,7 +14,7 @@
<key>FLAnimatedImage.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>14</integer>
<integer>67</integer>
</dict>
<key>Folly.xcscheme</key>
<dict>
@ -82,7 +82,7 @@
<key>SDWebImage.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>16</integer>
<integer>69</integer>
</dict>
<key>glog.xcscheme</key>
<dict>
@ -94,7 +94,7 @@
<key>react-native-fast-image.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>15</integer>
<integer>68</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -5,7 +5,6 @@
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };

View File

@ -47,7 +47,7 @@
<key>NSCameraUsageDescription</key>
<string>To access your photos, eSteem needs your permission to help you share your photos.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<string/>
<key>NSMainNibFile</key>
<string>LaunchScreen</string>
<key>NSMicrophoneUsageDescription</key>

View File

@ -54,6 +54,7 @@
"react-native-restart": "0.0.6",
"react-native-slider": "^0.11.0",
"react-native-vector-icons": "^6.0.2",
"react-native-version-number": "^0.3.5",
"react-native-view-overflow": "0.0.3",
"react-navigation": "^2.18.3",
"react-navigation-redux-helpers": "^2.0.8",

View File

@ -4,12 +4,20 @@ import { Icon } from '../../../icon';
import styles from './textWithIconStyles';
const TextWithIcon = ({
iconName, text, isClickable, onPress, iconStyle, iconType, iconSize,
iconName,
text,
isClickable,
onPress,
iconStyle,
iconType,
iconSize,
wrapperStyle,
textStyle,
}) => (
<View style={styles.container}>
{isClickable || onPress ? (
<TouchableHighlight
style={styles.wrapper}
style={[styles.wrapper, wrapperStyle]}
underlayColor="transparent"
onPress={() => onPress && onPress()}
>
@ -19,7 +27,7 @@ const TextWithIcon = ({
name={iconName}
iconType={iconType}
/>
<Text style={[styles.text]}>{text}</Text>
<Text style={[styles.text, textStyle]}>{text}</Text>
</Fragment>
</TouchableHighlight>
) : (

View File

@ -0,0 +1,4 @@
import Comment from './view/commentView';
export { Comment };
export default Comment;

View File

@ -0,0 +1,39 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
leftIcon: {
color: '$iconColor',
},
leftButton: {
marginLeft: 10,
},
rightButton: {
backgroundColor: '$iconColor',
height: 18,
flexDirection: 'row-reverse',
borderRadius: 20,
},
moreText: {
color: '$white',
fontSize: 10,
marginLeft: 12,
marginRight: 2,
},
bodyWrapper: {
marginTop: -10,
},
iconStyle: {
color: '$white',
marginRight: 12,
marginTop: 1,
},
footerWrapper: {
flex: 1,
flexDirection: 'row',
},
rightButtonWrapper: {
alignSelf: 'flex-end',
position: 'absolute',
right: 0,
},
});

View File

@ -0,0 +1,127 @@
import React, { PureComponent, Fragment } from 'react';
import { View } from 'react-native';
import { getTimeFromNow } from '../../../utils/time';
// Constants
// Components
import { PostBody, PostHeaderDescription } from '../../postElements';
import { Upvote } from '../../upvote';
import { IconButton } from '../../iconButton';
import { Comments } from '../../comments';
import { TextWithIcon } from '../../basicUIElements';
// Styles
import styles from './commentStyles';
class CommentView extends PureComponent {
/* Props
* ------------------------------------------------
* @prop { type } name - Description....
*/
constructor(props) {
super(props);
this.state = {
isShowSubComments: props.isShowSubComments || false,
};
}
// Component Life Cycles
// Component Functions
_showSubCommentsToggle = () => {
const { isShowSubComments } = this.state;
this.setState({ isShowSubComments: !isShowSubComments });
};
render() {
const {
avatarSize,
currentAccountUsername,
handleOnEditPress,
handleOnReplyPress,
handleOnUserPress,
isLoggedIn,
marginLeft,
isShowMoreButton,
comment,
commentNumber,
fetchPost,
isShowComments,
} = this.props;
const { isShowSubComments } = this.state;
return (
<View style={{ marginLeft: marginLeft || 29 }}>
<PostHeaderDescription
key={comment.permlink}
date={getTimeFromNow(comment.created)}
name={comment.author}
reputation={comment.author_reputation}
size={avatarSize || 24}
/>
<View style={[{ marginLeft: marginLeft || 29 }, styles.bodyWrapper]}>
<PostBody isComment handleOnUserPress={handleOnUserPress} body={comment.body} />
<View style={styles.footerWrapper}>
{isLoggedIn && (
<Fragment>
<Upvote isShowPayoutValue content={comment} />
<IconButton
size={18}
iconStyle={styles.leftIcon}
style={styles.leftButton}
name="reply"
onPress={() => handleOnReplyPress && handleOnReplyPress(comment)}
iconType="MaterialIcons"
/>
{currentAccountUsername === comment.author && (
<IconButton
size={18}
iconStyle={styles.leftIcon}
style={styles.leftButton}
name="create"
onPress={() => handleOnEditPress && handleOnEditPress(comment)}
iconType="MaterialIcons"
/>
)}
</Fragment>
)}
{isShowMoreButton && (
<View style={styles.rightButtonWrapper}>
<TextWithIcon
wrapperStyle={styles.rightButton}
iconName={isShowSubComments ? 'keyboard-arrow-up' : 'keyboard-arrow-down'}
textStyle={styles.moreText}
iconType="MaterialIcons"
isClickable
iconStyle={styles.iconStyle}
iconSize={16}
onPress={() => this._showSubCommentsToggle()}
text={`${comment.children} more replies`}
/>
</View>
)}
</View>
{isShowSubComments && commentNumber > 0 && (
<Comments
isShowComments={isShowComments}
commentNumber={commentNumber && commentNumber * 2}
marginLeft={20}
isShowSubComments={isShowSubComments}
avatarSize={avatarSize || 16}
author={comment.author}
permlink={comment.permlink}
commentCount={comment.children}
isShowMoreButton={false}
fetchPost={fetchPost}
/>
)}
</View>
</View>
);
}
}
export default CommentView;

View File

@ -82,29 +82,36 @@ class CommentsContainer extends Component {
};
render() {
const { comments: _comments } = this.state;
const { comments: _comments, selectedPermlink } = this.state;
const {
isLoggedIn,
commentCount,
author,
permlink,
currentAccount,
isProfilePreview,
commentNumber,
comments,
fetchPost,
isShowMoreButton,
selectedPermlink: _selectedPermlink,
} = this.props;
return (
<CommentsView
key={permlink}
selectedPermlink={_selectedPermlink || selectedPermlink}
author={author}
commentNumber={commentCount}
comments={comments || _comments}
isShowMoreButton={isShowMoreButton}
commentNumber={commentNumber || 1}
commentCount={commentCount}
comments={_comments || comments}
currentAccountUsername={currentAccount.name}
handleOnEditPress={this._handleOnEditPress}
handleOnReplyPress={this._handleOnReplyPress}
isLoggedIn={isLoggedIn}
permlink={permlink}
fetchPost={this._getComments}
isProfilePreview={isProfilePreview}
fetchPost={fetchPost}
{...this.props}
/>
);
}

View File

@ -1,14 +1,8 @@
import React, { PureComponent, Fragment } from 'react';
import React, { PureComponent } from 'react';
import { View, FlatList } from 'react-native';
import { getTimeFromNow } from '../../../utils/time';
// Constants
// Components
import Comments from '../container/commentsContainer';
import { PostBody, PostHeaderDescription } from '../../postElements';
import { Upvote } from '../../upvote';
import { IconButton } from '../../iconButton';
import { Comment } from '../../comment';
// Styles
// import styles from './commentStyles';
@ -41,81 +35,37 @@ class CommentsView extends PureComponent {
handleOnReplyPress,
handleOnUserPress,
isLoggedIn,
isProfilePreview,
marginLeft,
isShowSubComments,
fetchPost,
commentCount,
} = this.props;
return (
<View>
{!!comments && (
<FlatList
data={comments}
keyExtractor={this._keyExtractor}
renderItem={({ item, index }) => (
<View key={index}>
<PostHeaderDescription
key={item.permlink}
// date={intl.formatRelative(item.created)}
date={getTimeFromNow(item.created)}
name={item.author}
reputation={item.author_reputation}
size={avatarSize || 24}
/>
<View
style={{
marginLeft: marginLeft || 29,
flexDirection: 'column',
marginTop: -10,
}}
>
<PostBody isComment handleOnUserPress={handleOnUserPress} body={item.body} />
<View style={{ flexDirection: 'row' }}>
{isLoggedIn && (
<Fragment>
<Upvote isShowPayoutValue content={item} />
<IconButton
size={18}
iconStyle={{ color: '#c1c5c7' }}
style={{ marginLeft: 10 }}
name="reply"
onPress={() => handleOnReplyPress && handleOnReplyPress(item)}
iconType="MaterialIcons"
/>
{currentAccountUsername === item.author && (
<IconButton
size={18}
iconStyle={{ color: '#c1c5c7' }}
style={{ marginLeft: 10 }}
name="create"
onPress={() => handleOnEditPress && handleOnEditPress(item)}
iconType="MaterialIcons"
/>
)}
</Fragment>
)}
</View>
</View>
{!isProfilePreview && (
<View style={{ marginLeft: marginLeft || 29 }}>
{commentNumber !== 8 && (
<Comments
commentNumber={commentNumber ? commentNumber * 2 : 1}
marginLeft={20}
avatarSize={avatarSize || 16}
author={item.author}
permlink={item.permlink}
commentCount={item.children}
fetchPost={fetchPost}
/>
)}
</View>
)}
</View>
)}
/>
<FlatList
data={comments}
keyExtractor={this._keyExtractor}
renderItem={({ item, index }) => (
<View key={index}>
<Comment
isShowMoreButton={commentNumber === 1 && item.children > 0}
comment={item}
marginLeft={marginLeft}
commentNumber={commentNumber}
fetchPost={fetchPost}
commentCount={commentCount || item.children}
isShowSubComments={isShowSubComments}
avatarSize={avatarSize}
currentAccountUsername={currentAccountUsername}
handleOnReplyPress={handleOnReplyPress}
handleOnEditPress={handleOnEditPress}
handleOnUserPress={handleOnUserPress}
isLoggedIn={isLoggedIn}
showComentsToggle={this._showComentsToggle}
/>
</View>
)}
</View>
/>
);
}
}

View File

@ -1,7 +1,7 @@
import React, { PureComponent, Fragment } from 'react';
import { connect } from 'react-redux';
import { withNavigation } from 'react-navigation';
import { Alert } from 'react-native';
import { Alert, Share } from 'react-native';
import ActionSheet from 'react-native-actionsheet';
import { injectIntl } from 'react-intl';
@ -16,6 +16,7 @@ import { default as ROUTES } from '../../../constants/routeNames';
// Utilities
import { writeToClipboard } from '../../../utils/clipboard';
import { getPostUrl } from '../../../utils/post';
// Component
import PostDropdownView from '../view/postDropdownView';
@ -40,7 +41,7 @@ class PostDropdownContainer extends PureComponent {
switch (index) {
case '0':
writeToClipboard(`https://steemit.com${content.url}`);
writeToClipboard(getPostUrl(content.url));
break;
case '1':
@ -52,12 +53,26 @@ class PostDropdownContainer extends PureComponent {
case '2':
this._replyNavigation();
break;
case '3':
setTimeout(() => {
this._share();
}, 500);
break;
default:
break;
}
};
_share = () => {
const { content } = this.props;
Share.share({
message: content.title,
url: getPostUrl(content.url),
});
};
_reblog = () => {
const {
currentAccount, content, isLoggedIn, pinCode, intl,
@ -115,7 +130,7 @@ class PostDropdownContainer extends PureComponent {
return (
<Fragment>
<PostDropdownView
options={OPTIONS}
options={OPTIONS.map(item => intl.formatMessage({ id: `post_dropdown.${item}` }).toUpperCase())}
handleOnDropdownSelect={this._handleOnDropdownSelect}
{...this.props}
/>

View File

@ -83,4 +83,8 @@ export default EStyleSheet.create({
flexDirection: 'row',
marginLeft: 55,
},
versionText: {
textAlign: 'center',
color: '$iconColor',
},
});

View File

@ -5,6 +5,7 @@ import {
import { injectIntl } from 'react-intl';
import LinearGradient from 'react-native-linear-gradient';
import ActionSheet from 'react-native-actionsheet';
import VersionNumber from 'react-native-version-number';
// Components
import { IconButton } from '../../buttons';
@ -13,6 +14,7 @@ import { UserAvatar } from '../../userAvatar';
// Constants
import { default as MENU } from '../../../constants/sideMenuItems';
import PackageJson from '../../../../package.json';
// Styles
import styles from './sideMenuStyles';
@ -85,6 +87,8 @@ class SideMenuView extends Component {
currentAccount, isLoggedIn, intl, handleLogout,
} = this.props;
const { menuItems, isAddAccountIconActive } = this.state;
const { version } = PackageJson;
const { buildVersion } = VersionNumber;
return (
<View style={styles.container}>
@ -163,6 +167,7 @@ class SideMenuView extends Component {
)}
/>
</View>
<Text style={styles.versionText}>{`v${version}, ${buildVersion}`}</Text>
<ActionSheet
ref={o => (this.ActionSheet = o)}
options={[intl.formatMessage({ id: 'side_menu.logout' }), intl.formatMessage({ id: 'side_menu.cancel' })]}

View File

@ -35,7 +35,7 @@
"profile": {
"following": "Following",
"follower": "Follower",
"post": "Post",
"post": "Posts",
"details": "Profile Details",
"comments": "Comments",
"replies": "Replies",
@ -62,7 +62,7 @@
"server": "Server",
"dark_theme": "Dark Theme",
"push_notification": "Push Notification",
"pincode": "Pincode",
"pincode": "PIN code",
"reset": "Reset"
},
"voters": {
@ -116,8 +116,8 @@
"reply": "Reply"
},
"pincode": {
"enter_text": "Enter pin to unlock",
"set_new": "Set new pin",
"enter_text": "Enter PIN to unlock",
"set_new": "Set new PIN",
"write_again": "Write again",
"forgot_text": "Oh, I forgot it..."
},
@ -132,8 +132,8 @@
"success_rebloged": "Reblogged!",
"already_rebloged": "You have already reblogged!",
"warning": "Warning",
"invalid_pincode": "Invalid pin code, please check and try again.",
"remove_alert": "Are you sure want to remove?",
"invalid_pincode": "Invalid PIN code, please check and try again.",
"remove_alert": "Are you sure you want to remove?",
"cancel": "Cancel",
"delete": "Delete"
},
@ -167,7 +167,7 @@
"search": "Search in favorites"
},
"auth": {
"invalid_pin": "Invalid pin code, please check and try again",
"invalid_pin": "Invalid PIN code, please check and try again",
"invalid_username": "Invalid username, please check and try again",
"already_logged": "You are already logged in, please try to add another account",
"invalid_credentials": "Invalid credentials, please check and try again",
@ -179,5 +179,11 @@
"author_payout": "Author Payout",
"curation_payout": "Curation Payout",
"payout_date": "Payout"
},
"post_dropdown": {
"copy": "copy link",
"reblog": "reblog",
"reply": "reply",
"share": "share"
}
}

View File

@ -179,5 +179,11 @@
"author_payout": "Автору",
"curation_payout": "Кураторам",
"payout_date": "Выплата"
},
"post_dropdown": {
"copy": "copy link",
"reblog": "reblog",
"reply": "reply",
"share": "share"
}
}

View File

@ -179,5 +179,11 @@
"author_payout": "Yazar Ödemeleri",
"curation_payout": "Küratör Ödemeleri",
"payout_date": "Ödeme"
},
"post_dropdown": {
"copy": "kopyala",
"reblog": "reblog",
"reply": "cevapla",
"share": "paylaş"
}
}

View File

@ -1,3 +1 @@
export default ['COPY LINK', 'REBLOG', 'REPLY'];
export const VALUE = ['copy', 'reblog', 'reply'];
export default ['copy', 'reblog', 'reply', 'share'];

View File

@ -12,3 +12,9 @@ export const postSumTotal = (content) => {
? parseToken(content.total_payout_value) + parseToken(content.curator_payout_value)
: 0;
};
export const getPostUrl = (url) => {
const BASE_URL = 'https://steemit.com';
return BASE_URL + url;
};

View File

@ -7088,6 +7088,11 @@ react-native-vector-icons@^6.0.2:
prop-types "^15.6.2"
yargs "^8.0.2"
react-native-version-number@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/react-native-version-number/-/react-native-version-number-0.3.5.tgz#90f1b49bcb5e72f801bdc22ed6bad6c7cbbc2222"
integrity sha512-iANHQrYyDSe5Yts2qVjAjFXpK5EHkJGSFAqnVa3Bu/UKBRUjhnMqvskc3EH+IIvvJH9N2Qpidm1KCq42BWa6jQ==
react-native-view-overflow@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/react-native-view-overflow/-/react-native-view-overflow-0.0.3.tgz#d7b08e8c1e5047a2cf07f3ece82025899f930674"