diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index b8fa72a07..a0f02f3ba 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -442,7 +442,7 @@ PODS:
- React-Core
- RNScreens (2.18.1):
- React-Core
- - RNSVG (9.13.6):
+ - RNSVG (12.1.1):
- React
- RNVectorIcons (6.7.0):
- React
@@ -761,7 +761,7 @@ SPEC CHECKSUMS:
RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027
RNReanimated: e03f7425cb7a38dcf1b644d680d1bfc91c3337ad
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
- RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
+ RNSVG: 551acb6562324b1d52a4e0758f7ca0ec234e278f
RNVectorIcons: 368d6d8b8301224e5ffb6254191f4f8876c2be0d
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21
diff --git a/package.json b/package.json
index 288221407..9c005511c 100644
--- a/package.json
+++ b/package.json
@@ -105,6 +105,7 @@
"react-native-modal-translucent": "^5.0.0",
"react-native-navigation-bar-color": "^1.0.0",
"react-native-os": "^1.0.1",
+ "react-native-progress": "^5.0.0",
"react-native-push-notification": "^7.3.1",
"react-native-qrcode-svg": "^6.0.3",
"react-native-randombytes": "^3.6.1",
@@ -117,7 +118,7 @@
"react-native-scrollable-tab-view": "ecency/react-native-scrollable-tab-view",
"react-native-snap-carousel": "^3.8.0",
"react-native-splash-screen": "^3.2.0",
- "react-native-svg": "^9.5.3",
+ "react-native-svg": "^12.1.1",
"react-native-swiper": "^1.6.0-rc.3",
"react-native-tcp": "^3.2.1",
"react-native-udp": "^2.1.0",
diff --git a/src/components/icon/view/iconView.js b/src/components/icon/view/iconView.js
index 8695f9565..247faf408 100644
--- a/src/components/icon/view/iconView.js
+++ b/src/components/icon/view/iconView.js
@@ -7,6 +7,7 @@ import FontAwesome from 'react-native-vector-icons/FontAwesome';
import Feather from 'react-native-vector-icons/Feather';
import AntDesign from 'react-native-vector-icons/AntDesign';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
+import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import styles from './iconStyles';
@@ -46,6 +47,8 @@ class IconView extends PureComponent {
return ;
case 'FontAwesome':
return ;
+ case 'FontAwesome5':
+ return ;
case 'SimpleLineIcons':
return {children};
case 'AntDesign':
diff --git a/src/components/index.js b/src/components/index.js
index ab033ece3..746d80704 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -91,6 +91,7 @@ import { ActionModal } from './actionModal';
import { CustomiseFiltersModal } from './customiseFiltersModal';
import { ForegroundNotification } from './foregroundNotification';
import { PostHtmlRenderer } from './postHtmlRenderer';
+import { QuickProfileModal } from './organisms';
// Basic UI Elements
import {
@@ -230,4 +231,5 @@ export {
CustomiseFiltersModal,
ForegroundNotification,
PostHtmlRenderer,
+ QuickProfileModal,
};
diff --git a/src/components/notification/view/notificationView.tsx b/src/components/notification/view/notificationView.tsx
index 7f2a38522..853c1e250 100644
--- a/src/components/notification/view/notificationView.tsx
+++ b/src/components/notification/view/notificationView.tsx
@@ -188,6 +188,7 @@ class NotificationView extends PureComponent {
{this.props.handleOnUserPress(item.source)}}
/>
>
)
diff --git a/src/components/notificationLine/view/notificationLineView.js b/src/components/notificationLine/view/notificationLineView.js
index 259c7d405..d35909280 100644
--- a/src/components/notificationLine/view/notificationLineView.js
+++ b/src/components/notificationLine/view/notificationLineView.js
@@ -1,6 +1,6 @@
/* eslint-disable react/jsx-one-expression-per-line */
import React, { useState, useEffect } from 'react';
-import { View, Text, Image, TouchableHighlight } from 'react-native';
+import { View, Text, Image, TouchableHighlight, TouchableOpacity } from 'react-native';
import { useIntl } from 'react-intl';
import get from 'lodash/get';
@@ -10,7 +10,7 @@ import { UserAvatar } from '../../userAvatar';
// Styles
import styles from './notificationLineStyles';
-const NotificationLineView = ({ notification, handleOnPressNotification }) => {
+const NotificationLineView = ({ notification, handleOnPressNotification, handleOnUserPress }) => {
const [isRead, setIsRead] = useState(notification.read);
const intl = useIntl();
let _title;
@@ -58,10 +58,14 @@ const NotificationLineView = ({ notification, handleOnPressNotification }) => {
key={`${get(notification, 'id')}${_title}`}
style={[styles.notificationWrapper, !isRead && styles.isNewNotification]}
>
-
+
+
+
+
{notification.source}
diff --git a/src/components/organisms/index.ts b/src/components/organisms/index.ts
new file mode 100644
index 000000000..839b779e0
--- /dev/null
+++ b/src/components/organisms/index.ts
@@ -0,0 +1 @@
+export * from './quickProfileModal';
\ No newline at end of file
diff --git a/src/components/organisms/quickProfileModal/children/actionPanel.tsx b/src/components/organisms/quickProfileModal/children/actionPanel.tsx
new file mode 100644
index 000000000..367a29339
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/children/actionPanel.tsx
@@ -0,0 +1,45 @@
+import * as React from 'react';
+import { Text, View, StyleSheet } from 'react-native';
+import EStyleSheet from 'react-native-extended-stylesheet';
+import { IconButton } from '../../..';
+import { useAppSelector } from '../../../../hooks';
+import styles from './quickProfileStyles';
+
+interface ActionPanelProps {
+ isFollowing:boolean,
+ isFavourite:boolean,
+ onFollowPress:()=>void,
+ onFavouritePress:()=>void
+}
+
+export const ActionPanel = ({isFollowing, isFavourite, onFavouritePress, onFollowPress}: ActionPanelProps) => {
+
+ const heartColor = isFavourite
+ ? '$primaryRed'
+ : '$primaryDarkGray'
+
+ const followIcon = isFollowing
+ ? 'user-check'
+ : 'user-plus'
+
+ return (
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/components/organisms/quickProfileModal/children/index.ts b/src/components/organisms/quickProfileModal/children/index.ts
new file mode 100644
index 000000000..22716c28c
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/children/index.ts
@@ -0,0 +1 @@
+export * from './quickProfileContent';
\ No newline at end of file
diff --git a/src/components/organisms/quickProfileModal/children/profileBasic.tsx b/src/components/organisms/quickProfileModal/children/profileBasic.tsx
new file mode 100644
index 000000000..e4881a12f
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/children/profileBasic.tsx
@@ -0,0 +1,61 @@
+import React from 'react'
+import { View, Text, TouchableOpacity } from 'react-native'
+import FastImage from 'react-native-fast-image';
+import styles from './quickProfileStyles';
+import * as Progress from 'react-native-progress';
+import EStyleSheet from 'react-native-extended-stylesheet';
+import { useIntl } from 'react-intl';
+
+interface Props {
+ avatarUrl:string,
+ username:string,
+ about:string,
+ created:{
+ unit:string,
+ value:number
+ },
+ votingPower:string,
+ isLoading:boolean,
+ onPress:()=>void
+}
+
+export const ProfileBasic = ({avatarUrl, username, about, votingPower, isLoading, created, onPress}: Props) => {
+ const intl = useIntl();
+ const progress = parseInt(votingPower || '0')/100;
+
+ let joinedString = '---'
+ if(created){
+ const timeString = `${(-created.value)} ${intl.formatMessage({id:`time.${created.unit}`})}`;
+ joinedString = intl.formatMessage({id:'profile.joined'}, {time:timeString})
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+ {`@${username}`}
+ {about}
+ {joinedString}
+
+
+ )
+}
diff --git a/src/components/organisms/quickProfileModal/children/profileStats.tsx b/src/components/organisms/quickProfileModal/children/profileStats.tsx
new file mode 100644
index 000000000..747e2da33
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/children/profileStats.tsx
@@ -0,0 +1,41 @@
+import React from 'react'
+import { View, Text } from 'react-native'
+import styles from './quickProfileStyles'
+import * as Animated from 'react-native-animatable'
+
+
+export interface StatsData {
+ label:string,
+ value:number|string,
+ suffix?:string
+}
+
+interface Props {
+ data:StatsData[],
+ horizontalMargin?:number
+}
+
+export const ProfileStats = ({data, horizontalMargin}: Props) => {
+ return (
+
+ {data.map((item)=>)}
+
+ )
+}
+
+const StatItem = (props:{label:string, value:number|string}) => (
+
+ {!!props.value ? (
+ {props.value}
+ ):(
+ {'--'}
+ )}
+
+ {props.label}
+
+)
+
+
+
+
+
diff --git a/src/components/organisms/quickProfileModal/children/quickProfileContent.tsx b/src/components/organisms/quickProfileModal/children/quickProfileContent.tsx
new file mode 100644
index 000000000..c51e617fc
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/children/quickProfileContent.tsx
@@ -0,0 +1,273 @@
+import React, { useEffect, useState } from 'react'
+import { useIntl } from 'react-intl'
+import { View, Alert } from 'react-native'
+import { ProfileStats, StatsData } from './profileStats'
+import { MainButton } from '../../..'
+import { addFavorite, checkFavorite, deleteFavorite } from '../../../../providers/ecency/ecency'
+import { followUser, getFollows, getRelationship, getUser } from '../../../../providers/hive/dhive'
+import { getRcPower, getVotingPower } from '../../../../utils/manaBar'
+import styles from './quickProfileStyles'
+import { ProfileBasic } from './profileBasic'
+import { parseReputation } from '../../../../utils/user'
+import { default as ROUTES } from '../../../../constants/routeNames';
+import { ActionPanel } from './actionPanel'
+import { getTimeFromNowNative } from '../../../../utils/time'
+import { useAppDispatch, useAppSelector } from '../../../../hooks'
+import { toastNotification } from '../../../../redux/actions/uiAction'
+import Bugsnag from '@bugsnag/react-native'
+
+interface QuickProfileContentProps {
+ username:string,
+ navigation:any;
+ onClose:()=>void;
+}
+
+export const QuickProfileContent = ({
+ username,
+ navigation,
+ onClose
+}:QuickProfileContentProps) => {
+ const intl = useIntl();
+ const dispatch = useAppDispatch();
+
+ const currentAccount = useAppSelector((state)=>state.account.currentAccount);
+ const pinCode = useAppSelector((state)=>state.application.pin);
+ const isLoggedIn = useAppSelector((state)=>state.application.isLoggedIn);
+
+ const [isLoading, setIsLoading] = useState(false);
+ const [user, setUser] = useState(null);
+ const [follows, setFollows] = useState(null);
+ const [isFollowing, setIsFollowing] = useState(false);
+ const [isMuted, setIsMuted] = useState(false);
+ const [isFavourite, setIsFavourite] = useState(false);
+
+ const isOwnProfile = currentAccount && currentAccount.name === username;
+ const currentAccountName = currentAccount ? currentAccount.name : null;
+
+ useEffect(() => {
+ if(username) {
+ _fetchUser();
+ _fetchExtraUserData();
+ } else {
+ setUser(null);
+ }
+ }, [username])
+
+
+ //NETWORK CALLS
+ const _fetchUser = async () => {
+ setIsLoading(true);
+ try {
+ const _user = await getUser(username, isOwnProfile);
+ setUser(_user)
+ } catch (error) {
+ setIsLoading(false);
+ }
+ };
+
+
+ const _fetchExtraUserData = async () => {
+ try {
+ if (username) {
+ let _isFollowing;
+ let _isMuted;
+ let _isFavourite;
+ let follows;
+
+ if (!isOwnProfile) {
+ const res = await getRelationship(currentAccountName, username);
+ _isFollowing = res && res.follows;
+ _isMuted = res && res.ignores;
+ _isFavourite = await checkFavorite(username);
+ }
+
+ try {
+ follows = await getFollows(username);
+ } catch (err) {
+ follows = null;
+ }
+
+
+ setFollows(follows);
+ setIsFollowing(_isFollowing);
+ setIsMuted(_isMuted)
+ setIsFavourite(_isFavourite)
+ setIsLoading(false);
+
+ }
+ } catch (error) {
+ console.warn('Failed to fetch complete profile data', error);
+ Alert.alert(
+ intl.formatMessage({
+ id: 'alert.fail',
+ }),
+ error.message || error.toString(),
+ );
+ setIsLoading(false);
+ }
+ };
+
+
+ const _onFollowPress = async () => {
+ try{
+ const follower = currentAccountName
+ const following = username;
+
+ setIsLoading(true);
+ await followUser(currentAccount, pinCode, {
+ follower,
+ following,
+ })
+
+ setIsLoading(false);
+ setIsFollowing(true)
+ dispatch(
+ toastNotification(
+ intl.formatMessage({
+ id: isFollowing ? 'alert.success_unfollow' : 'alert.success_follow',
+ }),
+ ),
+ );
+ }
+ catch(err){
+ setIsLoading(false);
+ console.warn("Failed to follow user", err)
+ Bugsnag.notify(err);
+ Alert.alert(intl.formatMessage({id:'alert.fail'}), err.message)
+ }
+ }
+
+ const _onFavouritePress = async () => {
+ try{
+ setIsLoading(true);
+ let favoriteAction;
+
+ if (isFavourite) {
+ favoriteAction = deleteFavorite;
+ } else {
+ favoriteAction = addFavorite;
+ }
+
+ await favoriteAction(username)
+
+ dispatch(
+ toastNotification(
+ intl.formatMessage({
+ id: isFavourite ? 'alert.success_unfavorite' : 'alert.success_favorite',
+ }),
+ ),
+ );
+ setIsFavourite(!isFavourite);
+ setIsLoading(false);
+ }
+
+ catch(error){
+ console.warn('Failed to perform favorite action');
+ setIsLoading(false);
+ Alert.alert(
+ intl.formatMessage({
+ id: 'alert.fail',
+ }),
+ error.message || error.toString(),
+ );
+ }
+ }
+
+
+
+ //UI CALLBACKS
+
+ const _openFullProfile = () => {
+ let params = {
+ username,
+ reputation: user ? user.reputation : null
+ };
+
+ if (isOwnProfile) {
+ navigation.navigate(ROUTES.TABBAR.PROFILE);
+ } else {
+ navigation.navigate({
+ routeName: ROUTES.SCREENS.PROFILE,
+ params,
+ key: username,
+ });
+ }
+ if(onClose){
+ onClose();
+ }
+ }
+
+ //extract prop values
+ let _votingPower = '';
+ let _resourceCredits = '';
+ let _followerCount = 0;
+ let _followingCount = 0;
+ let _postCount = 0;
+ let _avatarUrl = '';
+ let _about = '';
+ let _reputation = 0;
+ let _createdData = null;
+
+ if (user && follows) {
+ _votingPower = getVotingPower(user).toFixed(1);
+ _resourceCredits = getRcPower(user).toFixed(0);
+ _postCount = user.post_count || 0;
+ _avatarUrl = user.avatar || '';
+ _about = user.about?.profile?.about || '';
+ _reputation = parseReputation(user.reputation);
+ _createdData = getTimeFromNowNative(user.created)
+
+ if(follows){
+ _followerCount = follows.follower_count || 0;
+ _followingCount = follows.following_count || 0
+ }
+ }
+
+
+
+ const statsData1 = [
+ {label:'Follower', value:_followerCount},
+ {label:'Following', value:_followingCount},
+ {label:'Posts', value:_postCount},
+ ] as StatsData[]
+
+ const statsData2 = [
+ {label:'Resource Credits', value:_resourceCredits, suffix:'%'},
+ {label:'Reputation', value:_reputation},
+ ] as StatsData[]
+
+ return (
+
+
+
+
+
+ {isLoggedIn && (
+
+ )}
+
+
+ )
+};
diff --git a/src/components/organisms/quickProfileModal/children/quickProfileStyles.ts b/src/components/organisms/quickProfileModal/children/quickProfileStyles.ts
new file mode 100644
index 000000000..51704565b
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/children/quickProfileStyles.ts
@@ -0,0 +1,109 @@
+import { TextStyle, ViewStyle, ImageStyle } from 'react-native';
+import EStyleSheet from 'react-native-extended-stylesheet';
+import { getBottomSpace } from 'react-native-iphone-x-helper';
+
+export default EStyleSheet.create({
+ modalStyle: {
+ backgroundColor: '$primaryBackgroundColor',
+ margin:0,
+ paddingTop:32,
+ paddingBottom: getBottomSpace() + 8,
+ marginHorizontal:24,
+ },
+
+ sheetContent: {
+ backgroundColor: '$primaryBackgroundColor',
+ position:'absolute',
+ bottom:0,
+ left:0,
+ right:0,
+ zIndex:999
+ },
+
+ container:{
+ alignItems:'center',
+ marginHorizontal:16
+ } as ViewStyle,
+
+ image:{
+ width:128,
+ height:128,
+ borderRadius:64,
+ backgroundColor: '$primaryGray'
+ } as ImageStyle,
+
+ textContainer:{
+ marginTop:32,
+ marginBottom:44,
+ } as ViewStyle,
+
+ title: {
+ color: '$primaryBlack',
+ alignSelf: 'center',
+ textAlign: 'center',
+ fontSize: 18,
+ fontWeight: 'bold',
+ marginTop:32,
+ } as TextStyle,
+
+ statValue: {
+ fontFamily:'$editorFont',
+ color: '$primaryBlack',
+ alignSelf: 'center',
+ textAlign: 'center',
+ fontSize: 34,
+ fontWeight: 'normal',
+ } as TextStyle,
+
+ statLabel: {
+ color: '$primaryBlack',
+ alignSelf: 'center',
+ textAlign: 'center',
+ fontSize: 16,
+ fontWeight: 'bold',
+ } as TextStyle,
+
+
+ bodyText: {
+ color: '$primaryBlack',
+ alignSelf: 'center',
+ textAlign: 'center',
+ fontSize: 18,
+ fontWeight: '500',
+ marginTop:6,
+ } as TextStyle,
+
+ btnText:{
+ color:'$pureWhite'
+ } as TextStyle,
+
+ button:{
+ marginTop: 40,
+ backgroundColor:'$primaryBlue',
+ paddingHorizontal:44,
+ paddingVertical:16,
+ borderRadius:32,
+ justifyContent:'center',
+ alignItems:'center'
+ } as ViewStyle,
+
+
+ actionPanel:{
+ position: 'absolute',
+ right:0,
+ top:0,
+ flexDirection:'row',
+ alignItems:'center',
+ } as ViewStyle,
+
+ progressCircle:{
+ position:'absolute',
+ top:0,
+ bottom:0,
+ left:0,
+ right:0,
+ alignItems:'center',
+ justifyContent:'center'
+ } as ViewStyle
+
+})
\ No newline at end of file
diff --git a/src/components/organisms/quickProfileModal/container/quickProfileModal.tsx b/src/components/organisms/quickProfileModal/container/quickProfileModal.tsx
new file mode 100644
index 000000000..921f32bcc
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/container/quickProfileModal.tsx
@@ -0,0 +1,54 @@
+import React, { useEffect, useRef } from 'react';
+import { AlertButton } from 'react-native';
+import { Source } from 'react-native-fast-image';
+import ActionSheet from 'react-native-actions-sheet';
+import { QuickProfileContent } from '../children/quickProfileContent';
+import EStyleSheet from 'react-native-extended-stylesheet';
+import styles from '../children/quickProfileStyles';
+import { useAppDispatch, useAppSelector } from '../../../../hooks';
+import { hideProfileModal } from '../../../../redux/actions/uiAction';
+
+
+
+export interface ActionModalData {
+ navigation:any
+}
+
+
+export const QuickProfileModal = ({navigation}) => {
+ const sheetModalRef = useRef();
+ const dispatch = useAppDispatch();
+
+ const profileModalUsername = useAppSelector((state)=>state.ui.profileModalUsername);
+
+
+ useEffect(() => {
+ if(profileModalUsername){
+ sheetModalRef.current.show();
+ }else {
+ sheetModalRef.current.hide();
+ }
+ }, [profileModalUsername])
+
+
+ const _onClose = () => {
+ dispatch(hideProfileModal());
+ }
+
+
+ return (
+
+
+
+
+ );
+};
diff --git a/src/components/organisms/quickProfileModal/index.ts b/src/components/organisms/quickProfileModal/index.ts
new file mode 100644
index 000000000..d14f44d9e
--- /dev/null
+++ b/src/components/organisms/quickProfileModal/index.ts
@@ -0,0 +1 @@
+export * from './container/quickProfileModal';
\ No newline at end of file
diff --git a/src/components/postCard/container/postCardContainer.js b/src/components/postCard/container/postCardContainer.js
index 621013a00..a1c8ff9c9 100644
--- a/src/components/postCard/container/postCardContainer.js
+++ b/src/components/postCard/container/postCardContainer.js
@@ -4,16 +4,15 @@ import { connect } from 'react-redux';
import get from 'lodash/get';
// Services
-import { act } from 'react-test-renderer';
-import { getPost, getActiveVotes } from '../../../providers/hive/dhive';
+import { getPost } from '../../../providers/hive/dhive';
import { getPostReblogs } from '../../../providers/ecency/ecency';
-import { parseActiveVotes } from '../../../utils/postParser';
-
import PostCardView from '../view/postCardView';
// Constants
import { default as ROUTES } from '../../../constants/routeNames';
+import { useAppDispatch } from '../../../hooks';
+import { showProfileModal } from '../../../redux/actions/uiAction';
/*
* Props Name Description Value
*@props --> props name here description here Value Type Here
@@ -31,6 +30,8 @@ const PostCardContainer = ({
setImageHeight,
pageType,
}) => {
+ const dispatch = useAppDispatch();
+
const [_content, setContent] = useState(content);
const [reblogs, setReblogs] = useState([]);
const activeVotes = get(_content, 'active_votes', []);
@@ -78,23 +79,8 @@ const PostCardContainer = ({
const _handleOnUserPress = (username) => {
if (_content) {
- let params = {
- username: username || get(_content, 'author'),
- reputation: !username && get(_content, 'author_reputation'),
- };
-
- if (
- get(currentAccount, 'name') === params.username &&
- (pageType === 'main' || pageType === 'ownProfile')
- ) {
- navigation.navigate(ROUTES.TABBAR.PROFILE);
- } else {
- navigation.navigate({
- routeName: ROUTES.SCREENS.PROFILE,
- params,
- key: get(_content, 'author'),
- });
- }
+ username = username || get(_content, 'author');
+ dispatch(showProfileModal(username));
}
};
diff --git a/src/components/postElements/headerDescription/view/postHeaderDescription.js b/src/components/postElements/headerDescription/view/postHeaderDescription.js
index fa6b047f4..cc225430b 100644
--- a/src/components/postElements/headerDescription/view/postHeaderDescription.js
+++ b/src/components/postElements/headerDescription/view/postHeaderDescription.js
@@ -1,5 +1,6 @@
import React, { PureComponent } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
+import { connect } from 'react-redux';
import { withNavigation } from 'react-navigation';
import { injectIntl } from 'react-intl';
@@ -12,6 +13,7 @@ import styles from './postHeaderDescriptionStyles';
import { default as ROUTES } from '../../../../constants/routeNames';
import { IconButton } from '../../..';
+import { showProfileModal } from '../../../../redux/actions/uiAction';
// Constants
const DEFAULT_IMAGE = require('../../../../assets/ecency.png');
@@ -21,19 +23,12 @@ class PostHeaderDescription extends PureComponent {
// Component Functions
_handleOnUserPress = (username) => {
- const { navigation, profileOnPress, reputation } = this.props;
+ const { profileOnPress, dispatch } = this.props;
if (profileOnPress) {
profileOnPress(username);
} else {
- navigation.navigate({
- routeName: ROUTES.SCREENS.PROFILE,
- params: {
- username,
- reputation,
- },
- key: username,
- });
+ dispatch(showProfileModal(username));
}
};
@@ -181,4 +176,6 @@ class PostHeaderDescription extends PureComponent {
}
}
-export default withNavigation(injectIntl(PostHeaderDescription));
+const mapStateToProps = () => ({});
+
+export default connect(mapStateToProps)(withNavigation(injectIntl(PostHeaderDescription)));
diff --git a/src/config/locales/en-US.json b/src/config/locales/en-US.json
index ae0f94323..820566b76 100644
--- a/src/config/locales/en-US.json
+++ b/src/config/locales/en-US.json
@@ -174,6 +174,7 @@
"day": "day",
"hive_dollars": "Hive Dollars",
"savings": "Savings",
+ "joined": "Joined {time} ago",
"edit": {
"display_name": "Display Name",
"about": "About",
@@ -672,5 +673,14 @@
"line3_heading":"Join Ecency communities!",
"line3_body":"Build community you own, get rewarded and reward others.",
"get_started":"Get started!"
+ },
+ "time":{
+ "second":"seconds",
+ "minute":"minutes",
+ "hour":"hours",
+ "week":"weeks",
+ "day":"days",
+ "month":"months",
+ "year":"years"
}
}
diff --git a/src/redux/actions/uiAction.ts b/src/redux/actions/uiAction.ts
index cbf03406c..68d9568a4 100644
--- a/src/redux/actions/uiAction.ts
+++ b/src/redux/actions/uiAction.ts
@@ -9,6 +9,8 @@ import {
SHOW_ACTION_MODAL,
HIDE_ACTION_MODAL,
SET_AVATAR_CACHE_STAMP,
+ SHOW_PROFILE_MODAL,
+ HIDE_PROFILE_MODAL
} from '../constants/constants';
export const updateActiveBottomTab = (payload:string) => ({
@@ -35,10 +37,24 @@ export const showActionModal = (title:string, body?:string, buttons?:AlertButton
type: SHOW_ACTION_MODAL,
});
+
+
export const hideActionModal = () => ({
type: HIDE_ACTION_MODAL,
});
+
+export const showProfileModal = (username:string) => ({
+ payload: {
+ profileModalUsername: username
+ },
+ type: SHOW_PROFILE_MODAL,
+});
+
+export const hideProfileModal = () => ({
+ type: HIDE_PROFILE_MODAL,
+});
+
export const setRcOffer = (payload:boolean) => ({
payload,
type: RC_OFFER,
diff --git a/src/redux/constants/constants.js b/src/redux/constants/constants.js
index 8c5de7830..d90fef688 100644
--- a/src/redux/constants/constants.js
+++ b/src/redux/constants/constants.js
@@ -55,6 +55,8 @@ export const TOGGLE_ACCOUNTS_BOTTOM_SHEET = 'TOGGLE_ACCOUNTS_BOTTOM_SHEET';
export const SHOW_ACTION_MODAL = 'SHOW_ACTION_MODAL';
export const HIDE_ACTION_MODAL = 'HIDE_ACTION_MODAL';
export const SET_AVATAR_CACHE_STAMP = 'SET_AVATAR_CACHE_STAMP';
+export const SHOW_PROFILE_MODAL = 'SHOW_PROFILE_MODAL';
+export const HIDE_PROFILE_MODAL = 'HIDE_PROFILE_MODAL';
// POSTS
export const SET_FEED_POSTS = 'SET_FEED_POSTS';
diff --git a/src/redux/reducers/uiReducer.ts b/src/redux/reducers/uiReducer.ts
index b792ac16d..04652e1cf 100644
--- a/src/redux/reducers/uiReducer.ts
+++ b/src/redux/reducers/uiReducer.ts
@@ -7,6 +7,8 @@ import {
SHOW_ACTION_MODAL,
HIDE_ACTION_MODAL,
SET_AVATAR_CACHE_STAMP,
+ SHOW_PROFILE_MODAL,
+ HIDE_PROFILE_MODAL,
} from '../constants/constants';
interface UiState {
@@ -17,7 +19,8 @@ interface UiState {
isVisibleAccountsBottomSheet:boolean;
actionModalVisible:boolean;
actionModalData:any;
- avatarCacheStamp:number
+ avatarCacheStamp:number;
+ profileModalUsername:string;
}
const initialState:UiState = {
@@ -28,7 +31,8 @@ const initialState:UiState = {
isVisibleAccountsBottomSheet: false,
actionModalVisible: false,
actionModalData: null,
- avatarCacheStamp: 0
+ avatarCacheStamp: 0,
+ profileModalUsername: ''
};
export default function (state = initialState, action) {
@@ -61,6 +65,20 @@ export default function (state = initialState, action) {
};
}
+ case SHOW_PROFILE_MODAL: {
+ return {
+ ...state,
+ profileModalUsername: action.payload.profileModalUsername,
+ };
+ }
+
+ case HIDE_PROFILE_MODAL: {
+ return {
+ ...state,
+ profileModalUsername: '',
+ };
+ }
+
case RC_OFFER:
return {
...state,
diff --git a/src/screens/application/container/applicationContainer.js b/src/screens/application/container/applicationContainer.js
index abf621e3e..14ea83692 100644
--- a/src/screens/application/container/applicationContainer.js
+++ b/src/screens/application/container/applicationContainer.js
@@ -87,6 +87,7 @@ import {
} from '../../../redux/actions/applicationActions';
import {
hideActionModal,
+ hideProfileModal,
setAvatarCacheStamp,
setRcOffer,
showActionModal,
@@ -761,6 +762,7 @@ class ApplicationContainer extends Component {
//reset certain properties
dispatch(hideActionModal());
+ dispatch(hideProfileModal());
dispatch(toastNotification(''));
dispatch(resetLocalVoteMap());
dispatch(setRcOffer(false));
diff --git a/src/screens/application/screen/applicationScreen.js b/src/screens/application/screen/applicationScreen.js
index db7755d72..6c0741b02 100644
--- a/src/screens/application/screen/applicationScreen.js
+++ b/src/screens/application/screen/applicationScreen.js
@@ -25,6 +25,7 @@ import {
AccountsBottomSheet,
ActionModal,
ForegroundNotification,
+ QuickProfileModal,
} from '../../../components';
// Themes (Styles)
@@ -113,6 +114,7 @@ class ApplicationScreen extends Component {
toastNotification,
isReady,
foregroundNotificationData,
+ navigation,
} = this.props;
const { isShowToastNotification, showWelcomeModal } = this.state;
const barStyle = isDarkTheme ? 'light-content' : 'dark-content';
@@ -171,6 +173,7 @@ class ApplicationScreen extends Component {
+
);
}
diff --git a/src/screens/notification/container/notificationContainer.js b/src/screens/notification/container/notificationContainer.js
index c4d8b9f2d..08da60599 100644
--- a/src/screens/notification/container/notificationContainer.js
+++ b/src/screens/notification/container/notificationContainer.js
@@ -15,6 +15,7 @@ import ROUTES from '../../../constants/routeNames';
// Components
import NotificationScreen from '../screen/notificationScreen';
+import { showProfileModal } from '../../../redux/actions/uiAction';
class NotificationContainer extends Component {
constructor(props) {
@@ -118,6 +119,11 @@ class NotificationContainer extends Component {
}
};
+ _handleOnUserPress = (username) => {
+ const { dispatch } = this.props;
+ dispatch(showProfileModal(username));
+ };
+
_readAllNotification = () => {
const { dispatch, intl, isConnected } = this.props;
const { notifications } = this.state;
@@ -174,6 +180,7 @@ class NotificationContainer extends Component {
getActivities={this._getActivities}
notifications={notifications}
navigateToNotificationRoute={this._navigateToNotificationRoute}
+ handleOnUserPress={this._handleOnUserPress}
readAllNotification={this._readAllNotification}
handleLoginPress={this._handleOnPressLogin}
isNotificationRefreshing={isRefreshing}
diff --git a/src/screens/notification/screen/notificationScreen.js b/src/screens/notification/screen/notificationScreen.js
index 74aff39e7..d63701998 100644
--- a/src/screens/notification/screen/notificationScreen.js
+++ b/src/screens/notification/screen/notificationScreen.js
@@ -16,6 +16,7 @@ const NotificationScreen = ({
getActivities,
intl,
navigateToNotificationRoute,
+ handleOnUserPress,
readAllNotification,
isNotificationRefreshing,
changeSelectedFilter,
@@ -42,6 +43,7 @@ const NotificationScreen = ({
getActivities={getActivities}
notifications={notifications}
navigateToNotificationRoute={navigateToNotificationRoute}
+ handleOnUserPress={handleOnUserPress}
readAllNotification={readAllNotification}
isNotificationRefreshing={isNotificationRefreshing}
changeSelectedFilter={changeSelectedFilter}
diff --git a/yarn.lock b/yarn.lock
index b7711275a..42cbf86d0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3513,7 +3513,7 @@ css-mediaquery@^0.1.2:
resolved "https://registry.yarnpkg.com/css-mediaquery/-/css-mediaquery-0.1.2.tgz#6a2c37344928618631c54bd33cedd301da18bea0"
integrity sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA=
-css-select@^2.0.2:
+css-select@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef"
integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==
@@ -3532,10 +3532,10 @@ css-to-react-native@^3.0.0:
css-color-keywords "^1.0.0"
postcss-value-parser "^4.0.2"
-css-tree@^1.0.0-alpha.37:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5"
- integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==
+css-tree@^1.0.0-alpha.39:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
+ integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
dependencies:
mdn-data "2.0.14"
source-map "^0.6.1"
@@ -8877,6 +8877,13 @@ react-native-os@^1.0.1:
resolved "https://registry.yarnpkg.com/react-native-os/-/react-native-os-1.2.6.tgz#1bb16d78ccad1143972183a04f443cf1af9fbefa"
integrity sha512-OlT+xQAcvkcnf7imgXiu+myMkqDt4xw2bP5SlVo19hEn5XHBkPMLX7dk3sSGxxncH/ToMDsf1KLyrPabNVtadA==
+react-native-progress@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/react-native-progress/-/react-native-progress-5.0.0.tgz#f5ac6ceaeee27f184c660b00f29419e82a9d0ab0"
+ integrity sha512-KjnGIt3r9i5Kn2biOD9fXLJocf0bwxPRxOyAgXEnZTJQU2O+HyzgGFRCbM5h3izm9kKIkSc1txh8aGmMafCD9A==
+ dependencies:
+ prop-types "^15.7.2"
+
react-native-push-notification@^7.3.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/react-native-push-notification/-/react-native-push-notification-7.3.1.tgz#1495feacd25169b998446dcf7b448a197ae5dca0"
@@ -8975,13 +8982,13 @@ react-native-splash-screen@^3.2.0:
resolved "https://registry.yarnpkg.com/react-native-splash-screen/-/react-native-splash-screen-3.2.0.tgz#d47ec8557b1ba988ee3ea98d01463081b60fff45"
integrity sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg==
-react-native-svg@^9.5.3:
- version "9.13.6"
- resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-9.13.6.tgz#5365fba2bc460054b90851e71f2a71006a5d373f"
- integrity sha512-vjjuJhEhQCwWjqsgWyGy6/C/LIBM2REDxB40FU1PMhi8T3zQUwUHnA6M15pJKlQG8vaZyA+QnLyIVhjtujRgig==
+react-native-svg@^12.1.1:
+ version "12.1.1"
+ resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.1.1.tgz#5f292410b8bcc07bbc52b2da7ceb22caf5bcaaee"
+ integrity sha512-NIAJ8jCnXGCqGWXkkJ1GTzO4a3Md5at5sagYV8Vh4MXYnL4z5Rh428Wahjhh+LIjx40EE5xM5YtwyJBqOIba2Q==
dependencies:
- css-select "^2.0.2"
- css-tree "^1.0.0-alpha.37"
+ css-select "^2.1.0"
+ css-tree "^1.0.0-alpha.39"
react-native-swiper@^1.6.0-rc.3:
version "1.6.0"