mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-23 05:13:04 +03:00
Merge branch 'development' of github.com:esteemapp/esteem-mobile into bugfix/post-display
This commit is contained in:
commit
03136101d6
@ -16,7 +16,7 @@ export default EStyleSheet.create({
|
||||
zIndex: 1,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
marginHorizontal: 19,
|
||||
marginHorizontal: 20,
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
navItem: {
|
||||
|
@ -48,7 +48,7 @@ export default class TitleAreaView extends Component {
|
||||
const { text, height } = this.state;
|
||||
|
||||
return (
|
||||
<View style={globalStyles.containerHorizontal16}>
|
||||
<View style={[globalStyles.containerHorizontal16, { height: Math.max(35, height) }]}>
|
||||
<TextInput
|
||||
style={[styles.textInput, { height: Math.max(35, height) }]}
|
||||
placeholderTextColor="#c1c5c7"
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { replaceBetween } from './utils';
|
||||
|
||||
export default async ({ getState, item, setState }) => {
|
||||
const states = getState();
|
||||
let { text } = states;
|
||||
const { selection } = states;
|
||||
export default async ({ text, selection, setTextAndSelection, item }) => {
|
||||
let newText;
|
||||
let newSelection;
|
||||
|
||||
@ -35,6 +32,5 @@ export default async ({ getState, item, setState }) => {
|
||||
newSelection = { start: selection.start + 3, end: selection.start + 3 };
|
||||
}
|
||||
|
||||
await setState({ text: newText, textUpdated: true });
|
||||
await setState({ newSelection });
|
||||
setTextAndSelection({ text: newText, selection: newSelection });
|
||||
};
|
||||
|
@ -3,8 +3,7 @@ import { isStringWebLink, replaceBetween } from './utils';
|
||||
export const writeUrlTextHere = 'https://example.com';
|
||||
export const writeTextHereString = 'Text here';
|
||||
|
||||
export default async ({ getState, item, setState, isImage = null }) => {
|
||||
const { selection, text } = getState();
|
||||
export default async ({ text, selection, setTextAndSelection, item, isImage = null }) => {
|
||||
const imagePrefix = isImage ? '!' : '';
|
||||
const itemText = item ? item.text : writeTextHereString;
|
||||
const itemUrl = item ? item.url : writeUrlTextHere;
|
||||
@ -41,7 +40,5 @@ export default async ({ getState, item, setState, isImage = null }) => {
|
||||
}
|
||||
}
|
||||
|
||||
await setState({ text: newText, textUpdated: true }, async () => {
|
||||
await setState({ newSelection });
|
||||
});
|
||||
setTextAndSelection({ text: newText, selection: newSelection });
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { replaceBetween } from './utils';
|
||||
|
||||
export default ({ getState, item, setState }) => {
|
||||
const { text, selection } = getState();
|
||||
export default async ({ text, selection, setTextAndSelection, item }) => {
|
||||
const newText = replaceBetween(
|
||||
text,
|
||||
selection,
|
||||
@ -14,8 +13,6 @@ export default ({ getState, item, setState }) => {
|
||||
} else {
|
||||
newPosition = selection.end + item.wrapper.length * 2;
|
||||
}
|
||||
|
||||
setState({ text: newText, textUpdated: true }, () => {
|
||||
setState({ newSelection: { start: newPosition, end: newPosition } });
|
||||
});
|
||||
const newSelection = { start: newPosition, end: newPosition };
|
||||
setTextAndSelection({ text: newText, selection: newSelection });
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { replaceBetween } from './utils';
|
||||
|
||||
export default async ({ getState, item, setState }) => {
|
||||
const { text, selection } = getState();
|
||||
export default async ({ text, selection, setTextAndSelection, item }) => {
|
||||
let newText = replaceBetween(
|
||||
text,
|
||||
selection,
|
||||
@ -42,7 +41,6 @@ export default async ({ getState, item, setState }) => {
|
||||
);
|
||||
}
|
||||
|
||||
await setState({ text: newText, textUpdated: true }, async () => {
|
||||
await setState({ newSelection: { start: newPosition, end: newPosition } });
|
||||
});
|
||||
const newSelection = { start: newPosition, end: newPosition };
|
||||
setTextAndSelection({ text: newText, selection: newSelection });
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
import regexValidator from './webLinkValidator';
|
||||
|
||||
export const replaceBetween = (text: string, selection: Object, what: string) =>
|
||||
export const replaceBetween = (text, selection, what) =>
|
||||
text.substring(0, selection.start) + what + text.substring(selection.end);
|
||||
|
||||
export const isStringWebLink = (text: string): boolean => {
|
||||
export const isStringWebLink = text => {
|
||||
const pattern = regexValidator;
|
||||
return pattern.test(text);
|
||||
};
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import { View, KeyboardAvoidingView, FlatList, Text, Platform, ScrollView } from 'react-native';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
import { renderPostBody } from '@esteemapp/esteem-render-helpers';
|
||||
|
||||
// Utils
|
||||
import applyImageLink from './formats/applyWebLinkFormat';
|
||||
import Formats from './formats/formats';
|
||||
import applyImageLink from './formats/applyWebLinkFormat';
|
||||
|
||||
// Components
|
||||
import { IconButton } from '../../iconButton';
|
||||
@ -18,73 +18,83 @@ import { ThemeContainer } from '../../../containers';
|
||||
// Styles
|
||||
import styles from './markdownEditorStyles';
|
||||
|
||||
export default class MarkdownEditorView extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
text: props.draftBody || '',
|
||||
selection: { start: 0, end: 0 },
|
||||
textUpdated: false,
|
||||
newSelection: null,
|
||||
};
|
||||
const MarkdownEditorView = ({
|
||||
draftBody,
|
||||
handleIsFormValid,
|
||||
handleOpenImagePicker,
|
||||
intl,
|
||||
isPreviewActive,
|
||||
isReply,
|
||||
isLoading,
|
||||
initialFields,
|
||||
onChange,
|
||||
handleOnTextChange,
|
||||
handleIsValid,
|
||||
componentID,
|
||||
uploadedImage,
|
||||
}) => {
|
||||
const [text, setText] = useState(draftBody || '');
|
||||
const [selection, setSelection] = useState({ start: 0, end: 0 });
|
||||
const [editable, setEditable] = useState(null);
|
||||
|
||||
this.inputRef = React.createRef();
|
||||
this.galleryRef = React.createRef();
|
||||
this.clearRef = React.createRef();
|
||||
}
|
||||
const inputRef = useRef(null);
|
||||
const galleryRef = useRef(null);
|
||||
const clearRef = useRef(null);
|
||||
|
||||
// Lifecycle functions
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
const { draftBody, uploadedImage, isPreviewActive } = this.props;
|
||||
if (!nextProps.isPreviewActive && isPreviewActive) {
|
||||
this.setState({
|
||||
selection: { start: 0, end: 0 },
|
||||
});
|
||||
}
|
||||
if (nextProps.draftBody && draftBody !== nextProps.draftBody) {
|
||||
this.setState({
|
||||
text: nextProps.draftBody,
|
||||
});
|
||||
useEffect(() => {
|
||||
if (!isPreviewActive) {
|
||||
_setTextAndSelection({ selection: { start: 0, end: 0 }, text });
|
||||
}
|
||||
}, [isPreviewActive]);
|
||||
|
||||
if (
|
||||
nextProps.uploadedImage &&
|
||||
nextProps.uploadedImage.url &&
|
||||
nextProps.uploadedImage !== uploadedImage
|
||||
) {
|
||||
useEffect(() => {
|
||||
if (text === '' && draftBody !== '') {
|
||||
_setTextAndSelection({ selection: { start: 0, end: 0 }, text: draftBody });
|
||||
}
|
||||
}, [draftBody]);
|
||||
|
||||
useEffect(() => {
|
||||
if (editable === null) {
|
||||
// workaround for android context menu issue
|
||||
setEditable(false);
|
||||
setTimeout(() => {
|
||||
setEditable(!isLoading);
|
||||
}, 100);
|
||||
} else {
|
||||
setEditable(!isLoading);
|
||||
}
|
||||
}, [isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (uploadedImage && uploadedImage.url) {
|
||||
applyImageLink({
|
||||
getState: this._getState,
|
||||
setState: async (state, callback) => {
|
||||
await this.setState(state, callback);
|
||||
},
|
||||
item: { url: nextProps.uploadedImage.url, text: nextProps.uploadedImage.hash },
|
||||
isImage: !!nextProps.uploadedImage,
|
||||
text,
|
||||
selection,
|
||||
setTextAndSelection: _setTextAndSelection,
|
||||
item: { url: uploadedImage.url, text: uploadedImage.hash },
|
||||
isImage: !!uploadedImage,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [uploadedImage]);
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { text } = this.state;
|
||||
const { handleIsFormValid } = this.props;
|
||||
useEffect(() => {
|
||||
setText(draftBody);
|
||||
}, [draftBody]);
|
||||
|
||||
if (prevState.text !== text) {
|
||||
const nextText = text.replace(prevState.text, '');
|
||||
useEffect(() => {
|
||||
const nextText = text.replace(text, '');
|
||||
|
||||
if (nextText && nextText.length > 0) {
|
||||
this._changeText(text);
|
||||
if (nextText && nextText.length > 0) {
|
||||
_changeText(text);
|
||||
|
||||
if (handleIsFormValid) {
|
||||
handleIsFormValid(text);
|
||||
}
|
||||
if (handleIsFormValid) {
|
||||
handleIsFormValid(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [text]);
|
||||
|
||||
// Component functions
|
||||
_changeText = input => {
|
||||
const { onChange, handleOnTextChange, handleIsValid, componentID } = this.props;
|
||||
|
||||
this.setState({ text: input });
|
||||
const _changeText = input => {
|
||||
setText(input);
|
||||
|
||||
if (onChange) {
|
||||
onChange(input);
|
||||
@ -99,36 +109,31 @@ export default class MarkdownEditorView extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
_handleOnSelectionChange = event => {
|
||||
const { newSelection } = this.state;
|
||||
const _handleOnSelectionChange = async event => {
|
||||
setSelection(event.nativeEvent.selection);
|
||||
};
|
||||
|
||||
if (newSelection) {
|
||||
this.setState({
|
||||
selection: newSelection,
|
||||
newSelection: null,
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
selection: event.nativeEvent.selection,
|
||||
const _setTextAndSelection = ({ selection: _selection, text: _text }) => {
|
||||
inputRef.current.setNativeProps({
|
||||
text: _text,
|
||||
});
|
||||
// Workaround for iOS selection update issue
|
||||
setTimeout(() => {
|
||||
inputRef.current.setNativeProps({
|
||||
selection: _selection,
|
||||
});
|
||||
setSelection(_selection);
|
||||
}, 200);
|
||||
_changeText(_text);
|
||||
};
|
||||
|
||||
_getState = () => {
|
||||
return this.state;
|
||||
};
|
||||
const _renderPreview = () => (
|
||||
<ScrollView style={styles.previewContainer}>
|
||||
{text ? <PostBody body={renderPostBody(text)} /> : <Text>...</Text>}
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
_renderPreview = () => {
|
||||
const { text } = this.state;
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.previewContainer}>
|
||||
{text ? <PostBody body={renderPostBody(text)} /> : <Text>...</Text>}
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
_renderMarkupButton = ({ item, getState, setState }) => (
|
||||
const _renderMarkupButton = ({ item }) => (
|
||||
<View style={styles.buttonWrapper}>
|
||||
<IconButton
|
||||
size={20}
|
||||
@ -136,20 +141,20 @@ export default class MarkdownEditorView extends Component {
|
||||
iconStyle={styles.icon}
|
||||
iconType={item.iconType}
|
||||
name={item.icon}
|
||||
onPress={() => item.onPress({ getState, setState, item })}
|
||||
onPress={() =>
|
||||
item.onPress({ text, selection, setTextAndSelection: _setTextAndSelection, item })
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
_renderEditorButtons = ({ getState, setState }) => (
|
||||
const _renderEditorButtons = () => (
|
||||
<StickyBar>
|
||||
<View style={styles.leftButtonsWrapper}>
|
||||
<FlatList
|
||||
data={Formats}
|
||||
keyboardShouldPersistTaps="always"
|
||||
renderItem={({ item, index }) =>
|
||||
index !== 9 && this._renderMarkupButton({ item, getState, setState })
|
||||
}
|
||||
renderItem={({ item, index }) => index !== 9 && _renderMarkupButton({ item })}
|
||||
horizontal
|
||||
/>
|
||||
</View>
|
||||
@ -160,10 +165,12 @@ export default class MarkdownEditorView extends Component {
|
||||
iconStyle={styles.icon}
|
||||
iconType="FontAwesome"
|
||||
name="link"
|
||||
onPress={() => Formats[9].onPress({ getState, setState })}
|
||||
onPress={() =>
|
||||
Formats[9].onPress({ text, selection, setTextAndSelection: _setTextAndSelection })
|
||||
}
|
||||
/>
|
||||
<IconButton
|
||||
onPress={() => this.galleryRef.current.show()}
|
||||
onPress={() => galleryRef.current.show()}
|
||||
style={styles.rightIcons}
|
||||
size={20}
|
||||
iconStyle={styles.icon}
|
||||
@ -172,7 +179,7 @@ export default class MarkdownEditorView extends Component {
|
||||
/>
|
||||
<View style={styles.clearButtonWrapper}>
|
||||
<IconButton
|
||||
onPress={() => this.clearRef.current.show()}
|
||||
onPress={() => clearRef.current.show()}
|
||||
size={20}
|
||||
iconStyle={styles.clearIcon}
|
||||
iconType="FontAwesome"
|
||||
@ -184,91 +191,81 @@ export default class MarkdownEditorView extends Component {
|
||||
</StickyBar>
|
||||
);
|
||||
|
||||
_handleClear = () => {
|
||||
const { initialFields } = this.props;
|
||||
|
||||
initialFields();
|
||||
|
||||
this.setState({ text: '' });
|
||||
const _handleClear = index => {
|
||||
if (index === 0) {
|
||||
initialFields();
|
||||
setText('');
|
||||
_setTextAndSelection({ text: '', selection: { start: 0, end: 0 } });
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { handleOpenImagePicker, intl, isPreviewActive, isReply, isLoading } = this.props;
|
||||
const { text, selection } = this.state;
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={styles.container}
|
||||
keyboardVerticalOffset={Platform.select({ ios: 0, android: 25 })}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : null}
|
||||
>
|
||||
{!isPreviewActive ? (
|
||||
<ThemeContainer>
|
||||
{({ isDarkTheme }) => (
|
||||
<TextInput
|
||||
multiline
|
||||
autoCorrect={false}
|
||||
onChangeText={_changeText}
|
||||
onSelectionChange={_handleOnSelectionChange}
|
||||
placeholder={intl.formatMessage({
|
||||
id: isReply ? 'editor.reply_placeholder' : 'editor.default_placeholder',
|
||||
})}
|
||||
placeholderTextColor={isDarkTheme ? '#526d91' : '#c1c5c7'}
|
||||
selectionColor="#357ce6"
|
||||
style={styles.textWrapper}
|
||||
underlineColorAndroid="transparent"
|
||||
innerRef={inputRef}
|
||||
editable={editable}
|
||||
contextMenuHidden={false}
|
||||
/>
|
||||
)}
|
||||
</ThemeContainer>
|
||||
) : (
|
||||
_renderPreview()
|
||||
)}
|
||||
{!isPreviewActive && _renderEditorButtons()}
|
||||
<ActionSheet
|
||||
ref={galleryRef}
|
||||
options={[
|
||||
intl.formatMessage({
|
||||
id: 'editor.open_gallery',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'editor.capture_photo',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'alert.cancel',
|
||||
}),
|
||||
]}
|
||||
cancelButtonIndex={2}
|
||||
onPress={index => {
|
||||
handleOpenImagePicker(index === 0 ? 'image' : index === 1 && 'camera');
|
||||
}}
|
||||
/>
|
||||
<ActionSheet
|
||||
ref={clearRef}
|
||||
title={intl.formatMessage({
|
||||
id: 'alert.clear_alert',
|
||||
})}
|
||||
options={[
|
||||
intl.formatMessage({
|
||||
id: 'alert.clear',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'alert.cancel',
|
||||
}),
|
||||
]}
|
||||
cancelButtonIndex={1}
|
||||
onPress={_handleClear}
|
||||
/>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={styles.container}
|
||||
keyboardVerticalOffset={Platform.select({ ios: 0, android: 25 })}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : null}
|
||||
>
|
||||
{!isPreviewActive ? (
|
||||
<ThemeContainer>
|
||||
{({ isDarkTheme }) => (
|
||||
<TextInput
|
||||
multiline
|
||||
onChangeText={this._changeText}
|
||||
onSelectionChange={this._handleOnSelectionChange}
|
||||
placeholder={intl.formatMessage({
|
||||
id: isReply ? 'editor.reply_placeholder' : 'editor.default_placeholder',
|
||||
})}
|
||||
placeholderTextColor={isDarkTheme ? '#526d91' : '#c1c5c7'}
|
||||
selection={selection}
|
||||
selectionColor="#357ce6"
|
||||
style={styles.textWrapper}
|
||||
underlineColorAndroid="transparent"
|
||||
value={text}
|
||||
innerRef={this.inputRef}
|
||||
editable={!isLoading}
|
||||
/>
|
||||
)}
|
||||
</ThemeContainer>
|
||||
) : (
|
||||
this._renderPreview()
|
||||
)}
|
||||
{!isPreviewActive &&
|
||||
this._renderEditorButtons({
|
||||
getState: this._getState,
|
||||
setState: (state, callback) => {
|
||||
this.inputRef.current.focus();
|
||||
this.setState(state, callback);
|
||||
},
|
||||
})}
|
||||
<ActionSheet
|
||||
ref={this.galleryRef}
|
||||
options={[
|
||||
intl.formatMessage({
|
||||
id: 'editor.open_gallery',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'editor.capture_photo',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'alert.cancel',
|
||||
}),
|
||||
]}
|
||||
cancelButtonIndex={2}
|
||||
onPress={index => {
|
||||
handleOpenImagePicker(index === 0 ? 'image' : index === 1 && 'camera');
|
||||
}}
|
||||
/>
|
||||
<ActionSheet
|
||||
ref={this.clearRef}
|
||||
title={intl.formatMessage({
|
||||
id: 'alert.clear_alert',
|
||||
})}
|
||||
options={[
|
||||
intl.formatMessage({
|
||||
id: 'alert.clear',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'alert.cancel',
|
||||
}),
|
||||
]}
|
||||
cancelButtonIndex={1}
|
||||
onPress={index => index === 0 && this._handleClear()}
|
||||
/>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default MarkdownEditorView;
|
||||
|
@ -4,5 +4,6 @@ export default EStyleSheet.create({
|
||||
icon: {
|
||||
color: '$iconColor',
|
||||
marginRight: 2.7,
|
||||
fontSize: 25,
|
||||
},
|
||||
});
|
||||
|
@ -359,12 +359,7 @@ class PostsView extends Component {
|
||||
|
||||
render() {
|
||||
const { refreshing, posts, isShowFilterBar } = this.state;
|
||||
const {
|
||||
filterOptions,
|
||||
selectedOptionIndex,
|
||||
isHideImage,
|
||||
handleImagesHide,
|
||||
} = this.props;
|
||||
const { filterOptions, selectedOptionIndex, isHideImage, handleImagesHide } = this.props;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
|
@ -9,8 +9,9 @@ export default EStyleSheet.create({
|
||||
},
|
||||
upvoteIcon: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 20,
|
||||
fontSize: 24,
|
||||
color: '$primaryBlue',
|
||||
marginRight: 5,
|
||||
},
|
||||
popoverSlider: {
|
||||
flexDirection: 'row',
|
||||
|
@ -249,12 +249,14 @@ class UpvoteView extends Component {
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Icon
|
||||
style={[styles.upvoteIcon, isDownVoted && { color: '#ec8b88' }]}
|
||||
active={!isLoggedIn}
|
||||
iconType={isDownVoted ? 'AntDesign' : iconType}
|
||||
name={isDownVoted ? 'downcircle' : iconName}
|
||||
/>
|
||||
<View hitSlop={{ top: 10, bottom: 10, left: 10, right: 5 }}>
|
||||
<Icon
|
||||
style={[styles.upvoteIcon, isDownVoted && { color: '#ec8b88' }]}
|
||||
active={!isLoggedIn}
|
||||
iconType={isDownVoted ? 'AntDesign' : iconType}
|
||||
name={isDownVoted ? 'downcircle' : iconName}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</Fragment>
|
||||
</TouchableOpacity>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { Component } from 'react';
|
||||
import { TouchableOpacity } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { NavigationActions } from 'react-navigation';
|
||||
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import styles from './userAvatarStyles';
|
||||
import NavigationService from '../../../navigation/service';
|
||||
|
||||
// Constants
|
||||
import ROUTES from '../../../constants/routeNames';
|
||||
@ -30,21 +30,18 @@ class UserAvatarView extends Component {
|
||||
// Component Functions
|
||||
_handleOnAvatarPress = username => {
|
||||
const {
|
||||
dispatch,
|
||||
currentUsername: { name },
|
||||
} = this.props;
|
||||
|
||||
const routeName = name === username ? ROUTES.TABBAR.PROFILE : ROUTES.SCREENS.PROFILE;
|
||||
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
routeName,
|
||||
NavigationService.navigate({
|
||||
routeName: routeName,
|
||||
params: {
|
||||
username,
|
||||
},
|
||||
key: username,
|
||||
action: NavigationActions.navigate({ routeName }),
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -61,7 +58,9 @@ class UserAvatarView extends Component {
|
||||
let _size;
|
||||
const _avatar = username
|
||||
? {
|
||||
uri: avatarUrl || (name === username ? avatar : getResizedAvatar(username, imageSize)),
|
||||
uri:
|
||||
avatarUrl ||
|
||||
(name === username && avatar ? avatar : getResizedAvatar(username, imageSize)),
|
||||
}
|
||||
: DEFAULT_IMAGE;
|
||||
|
||||
|
@ -3,7 +3,6 @@ import { Provider, connect } from 'react-redux';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { useScreens } from 'react-native-screens';
|
||||
import { setTopLevelNavigator } from './navigation/service';
|
||||
|
||||
import { flattenMessages } from './utils/flattenMessages';
|
||||
import messages from './config/locales';
|
||||
@ -30,11 +29,7 @@ const App = connect(mapStateToProps)(_renderApp);
|
||||
export default () => {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<App
|
||||
ref={navigatorRef => {
|
||||
setTopLevelNavigator(navigatorRef);
|
||||
}}
|
||||
/>
|
||||
<App />
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ const BaseNavigator = createBottomTabNavigator(
|
||||
screen: Profile,
|
||||
navigationOptions: () => ({
|
||||
tabBarIcon: ({ tintColor }) => (
|
||||
<Icon iconType="MaterialIcons" name="credit-card" color={tintColor} size={26} />
|
||||
<Icon iconType="MaterialIcons" name="person-outline" color={tintColor} size={26} />
|
||||
),
|
||||
}),
|
||||
},
|
||||
|
@ -2,15 +2,21 @@ import { NavigationActions } from 'react-navigation';
|
||||
|
||||
let _navigator;
|
||||
|
||||
export const setTopLevelNavigator = navigatorRef => {
|
||||
const setTopLevelNavigator = navigatorRef => {
|
||||
_navigator = navigatorRef;
|
||||
};
|
||||
|
||||
export const navigate = (routeName, params) => {
|
||||
const navigate = navigationProps => {
|
||||
_navigator.dispatch(
|
||||
NavigationActions.navigate({
|
||||
routeName,
|
||||
params,
|
||||
...navigationProps,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
// add other navigation functions that you need and export them
|
||||
|
||||
export default {
|
||||
navigate,
|
||||
setTopLevelNavigator,
|
||||
};
|
||||
|
@ -38,6 +38,7 @@ import {
|
||||
import { getUser, getPost } from '../../../providers/steem/dsteem';
|
||||
import { switchAccount } from '../../../providers/steem/auth';
|
||||
import { setPushToken } from '../../../providers/esteem/esteem';
|
||||
import NavigationService from '../../../navigation/service';
|
||||
|
||||
// Actions
|
||||
import {
|
||||
@ -260,13 +261,11 @@ class ApplicationContainer extends Component {
|
||||
if (routeName && (profile || content)) {
|
||||
this.navigationTimeout = setTimeout(() => {
|
||||
clearTimeout(this.navigationTimeout);
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
NavigationService.navigate({
|
||||
routeName,
|
||||
params,
|
||||
key: permlink || author,
|
||||
action: NavigationActions.navigate({ routeName }),
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
@ -402,13 +401,11 @@ class ApplicationContainer extends Component {
|
||||
}
|
||||
|
||||
if (!some(params, isEmpty)) {
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
NavigationService.navigate({
|
||||
routeName,
|
||||
params,
|
||||
key,
|
||||
action: NavigationActions.navigate({ routeName }),
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5,6 +5,7 @@ import { connect } from 'react-redux';
|
||||
import { createAppContainer } from 'react-navigation';
|
||||
|
||||
import AppNavitation from '../../../navigation/routes';
|
||||
import NavigationService from '../../../navigation/service';
|
||||
|
||||
// Services
|
||||
import { toastNotification as toastNotificationAction } from '../../../redux/actions/uiAction';
|
||||
@ -59,7 +60,11 @@ class ApplicationScreen extends Component {
|
||||
)}
|
||||
<Fragment>
|
||||
{!isConnected && <NoInternetConnection />}
|
||||
<Navigation />
|
||||
<Navigation
|
||||
ref={navigatorRef => {
|
||||
NavigationService.setTopLevelNavigator(navigatorRef);
|
||||
}}
|
||||
/>
|
||||
</Fragment>
|
||||
|
||||
{isShowToastNotification && (
|
||||
|
@ -3,10 +3,10 @@ import { Alert } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import Config from 'react-native-config';
|
||||
import { NavigationActions } from 'react-navigation';
|
||||
import get from 'lodash/get';
|
||||
|
||||
// Actions & Services
|
||||
import NavigationService from '../../../navigation/service';
|
||||
import {
|
||||
setUserDataWithPinCode,
|
||||
verifyPinCode,
|
||||
@ -111,12 +111,10 @@ class PinCodeContainer extends Component {
|
||||
if (callback) callback(pin, oldPinCode);
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
NavigationService.navigate({
|
||||
routeName: navigateTo,
|
||||
params: navigateParams,
|
||||
action: NavigationActions.navigate({ routeName: navigateTo }),
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
@ -174,12 +172,10 @@ class PinCodeContainer extends Component {
|
||||
if (callback) callback(pin, oldPinCode);
|
||||
dispatch(closePinCodeModal());
|
||||
if (navigateTo) {
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
NavigationService.navigate({
|
||||
routeName: navigateTo,
|
||||
params: navigateParams,
|
||||
action: NavigationActions.navigate({ routeName: navigateTo }),
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
@ -215,12 +211,10 @@ class PinCodeContainer extends Component {
|
||||
dispatch(closePinCodeModal());
|
||||
if (callback) callback(pin, oldPinCode);
|
||||
if (navigateTo) {
|
||||
const navigateAction = NavigationActions.navigate({
|
||||
NavigationService.navigate({
|
||||
routeName: navigateTo,
|
||||
params: navigateParams,
|
||||
action: NavigationActions.navigate({ routeName: navigateTo }),
|
||||
});
|
||||
dispatch(navigateAction);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
|
@ -236,21 +236,23 @@ class SettingsContainer extends Component {
|
||||
dispatch(changeNotificationSettings({ action, type: actionType }));
|
||||
setNotificationSettings({ action, type: actionType });
|
||||
|
||||
if (actionType === 'notification') {
|
||||
await Push.setEnabled(action);
|
||||
this._setPushToken(action ? [1, 2, 3, 4, 5, 6] : notifyTypes);
|
||||
} else {
|
||||
Object.keys(notificationDetails).map(item => {
|
||||
const notificationType = item.replace('Notification', '');
|
||||
Object.keys(notificationDetails).map(item => {
|
||||
const notificationType = item.replace('Notification', '');
|
||||
|
||||
if (notificationType === actionType.replace('notification.', '')) {
|
||||
if (action) {
|
||||
notifyTypes.push(notifyTypesConst[notificationType]);
|
||||
}
|
||||
} else if (notificationDetails[item]) {
|
||||
if (notificationType === actionType.replace('notification.', '')) {
|
||||
if (action) {
|
||||
notifyTypes.push(notifyTypesConst[notificationType]);
|
||||
}
|
||||
});
|
||||
} else if (notificationDetails[item]) {
|
||||
notifyTypes.push(notifyTypesConst[notificationType]);
|
||||
}
|
||||
});
|
||||
notifyTypes.sort();
|
||||
|
||||
if (actionType === 'notification') {
|
||||
await Push.setEnabled(action);
|
||||
this._setPushToken(action ? notifyTypes : []);
|
||||
} else {
|
||||
this._setPushToken(notifyTypes);
|
||||
}
|
||||
};
|
||||
@ -286,21 +288,25 @@ class SettingsContainer extends Component {
|
||||
};
|
||||
|
||||
_setPushToken = async notifyTypes => {
|
||||
const { isNotificationSettingsOpen, isLoggedIn, username } = this.props;
|
||||
const { isLoggedIn, otherAccounts = [] } = this.props;
|
||||
|
||||
if (isLoggedIn) {
|
||||
const token = await AppCenter.getInstallId();
|
||||
|
||||
getExistUser().then(isExistUser => {
|
||||
if (isExistUser) {
|
||||
const data = {
|
||||
username,
|
||||
token,
|
||||
system: Platform.OS,
|
||||
allows_notify: Number(isNotificationSettingsOpen),
|
||||
notify_types: notifyTypes,
|
||||
};
|
||||
setPushToken(data);
|
||||
otherAccounts.forEach(item => {
|
||||
const { isNotificationSettingsOpen } = this.props;
|
||||
|
||||
const data = {
|
||||
username: item.username,
|
||||
token,
|
||||
system: Platform.OS,
|
||||
allows_notify: Number(isNotificationSettingsOpen),
|
||||
notify_types: notifyTypes,
|
||||
};
|
||||
setPushToken(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -401,6 +407,7 @@ const mapStateToProps = state => ({
|
||||
|
||||
username: state.account.currentAccount && state.account.currentAccount.name,
|
||||
currentAccount: state.account.currentAccount,
|
||||
otherAccounts: state.account.otherAccounts,
|
||||
});
|
||||
|
||||
export default injectIntl(connect(mapStateToProps)(SettingsContainer));
|
||||
|
@ -31,10 +31,10 @@ class TransferView extends Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
from: props.currentAccountName,
|
||||
destination: '',
|
||||
destination: props.transferType === 'powerUp' ? props.currentAccountName : '',
|
||||
amount: '',
|
||||
memo: '',
|
||||
isUsernameValid: false,
|
||||
isUsernameValid: props.transferType === 'powerUp' && props.currentAccountName ? true : false,
|
||||
steemConnectTransfer: false,
|
||||
isTransfering: false,
|
||||
};
|
||||
@ -217,22 +217,26 @@ class TransferView extends Component {
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
<TransferFormItem
|
||||
label={intl.formatMessage({ id: 'transfer.memo' })}
|
||||
rightComponent={() =>
|
||||
this._renderInput(
|
||||
intl.formatMessage({ id: 'transfer.memo_placeholder' }),
|
||||
'memo',
|
||||
'default',
|
||||
true,
|
||||
)
|
||||
}
|
||||
/>
|
||||
<TransferFormItem
|
||||
rightComponent={() =>
|
||||
this._renderDescription(intl.formatMessage({ id: 'transfer.memo_desc' }))
|
||||
}
|
||||
/>
|
||||
{transferType !== 'powerUp' && (
|
||||
<TransferFormItem
|
||||
label={intl.formatMessage({ id: 'transfer.memo' })}
|
||||
rightComponent={() =>
|
||||
this._renderInput({
|
||||
placeholder: intl.formatMessage({ id: 'transfer.memo_placeholder' }),
|
||||
state: 'memo',
|
||||
keyboardType: 'default',
|
||||
isTextArea: true,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{transferType !== 'powerUp' && (
|
||||
<TransferFormItem
|
||||
rightComponent={() =>
|
||||
this._renderDescription(intl.formatMessage({ id: 'transfer.memo_desc' }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.bottomContent}>
|
||||
<MainButton
|
||||
|
Loading…
Reference in New Issue
Block a user