diff --git a/android/app/build.gradle b/android/app/build.gradle
index 16df9f14..e07bb378 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -137,8 +137,8 @@ android {
applicationId "com.pepo.v2.production"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 31
- versionName "1.0.4"
+ versionCode 32
+ versionName "1.0.5"
missingDimensionStrategy 'react-native-camera', 'general'
manifestPlaceholders = [
appAuthRedirectScheme: 'com.pepo.v2.production'
diff --git a/ios/Pepo2.xcodeproj/project.pbxproj b/ios/Pepo2.xcodeproj/project.pbxproj
index 1505953c..a5ce1c67 100644
--- a/ios/Pepo2.xcodeproj/project.pbxproj
+++ b/ios/Pepo2.xcodeproj/project.pbxproj
@@ -617,7 +617,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Pepo2/Pepo2.entitlements;
- CURRENT_PROJECT_VERSION = 29;
+ CURRENT_PROJECT_VERSION = 30;
DEAD_CODE_STRIPPING = NO;
DEVELOPMENT_TEAM = N83K86W6P4;
FRAMEWORK_SEARCH_PATHS = (
@@ -628,7 +628,7 @@
INFOPLIST_FILE = Pepo2/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- MARKETING_VERSION = 1.0.4;
+ MARKETING_VERSION = 1.0.5;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -649,7 +649,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Pepo2/Pepo2.entitlements;
- CURRENT_PROJECT_VERSION = 29;
+ CURRENT_PROJECT_VERSION = 30;
DEVELOPMENT_TEAM = N83K86W6P4;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -659,7 +659,7 @@
INFOPLIST_FILE = Pepo2/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- MARKETING_VERSION = 1.0.4;
+ MARKETING_VERSION = 1.0.5;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
diff --git a/ios/Pepo2/InfoPlist/com.pepo.staging-Info.plist b/ios/Pepo2/InfoPlist/com.pepo.staging-Info.plist
index 99a27cb3..b71e8db9 100644
--- a/ios/Pepo2/InfoPlist/com.pepo.staging-Info.plist
+++ b/ios/Pepo2/InfoPlist/com.pepo.staging-Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.0.4
+ 1.0.5
CFBundleSignature
????
CFBundleURLTypes
@@ -40,7 +40,7 @@
CFBundleVersion
- 29
+ 30
Fabric
APIKey
diff --git a/ios/Pepo2/InfoPlist/com.pepo.v2.production-Info.plist b/ios/Pepo2/InfoPlist/com.pepo.v2.production-Info.plist
index 30aacfeb..9911526f 100644
--- a/ios/Pepo2/InfoPlist/com.pepo.v2.production-Info.plist
+++ b/ios/Pepo2/InfoPlist/com.pepo.v2.production-Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.0.4
+ 1.0.5
CFBundleSignature
????
CFBundleURLTypes
@@ -40,7 +40,7 @@
CFBundleVersion
- 29
+ 30
Fabric
APIKey
diff --git a/ios/Pepo2/InfoPlist/com.pepo.v2.sandbox-Info.plist b/ios/Pepo2/InfoPlist/com.pepo.v2.sandbox-Info.plist
index 661a7ceb..3c51605e 100644
--- a/ios/Pepo2/InfoPlist/com.pepo.v2.sandbox-Info.plist
+++ b/ios/Pepo2/InfoPlist/com.pepo.v2.sandbox-Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.0.4
+ 1.0.5
CFBundleSignature
????
CFBundleURLTypes
@@ -40,7 +40,7 @@
CFBundleVersion
- 29
+ 30
Fabric
APIKey
diff --git a/src/assets/StorePink.png b/src/assets/StorePink.png
deleted file mode 100644
index 789ecfcd..00000000
Binary files a/src/assets/StorePink.png and /dev/null differ
diff --git a/src/assets/balanace-header-store.png b/src/assets/balanace-header-store.png
new file mode 100644
index 00000000..e5898823
Binary files /dev/null and b/src/assets/balanace-header-store.png differ
diff --git a/src/components/CommonComponents/UserInfo/styles.js b/src/components/CommonComponents/UserInfo/styles.js
index f04a3a73..645190aa 100644
--- a/src/components/CommonComponents/UserInfo/styles.js
+++ b/src/components/CommonComponents/UserInfo/styles.js
@@ -3,6 +3,8 @@ import Colors from '../../../theme/styles/Colors';
import { Dimensions } from 'react-native';
import {fontFamWeight} from "../../../theme/constants";
+const isSmallPhone = Dimensions.get('window').width <= 360;
+
let stylesMap = {
infoHeaderWrapper: {
justifyContent: 'space-between',
@@ -18,9 +20,19 @@ let stylesMap = {
shadowOffset: {width: 0, height: 0},
elevation: 5,
paddingVertical: 8,
- paddingHorizontal: 15,
+ paddingHorizontal: isSmallPhone ? 8 : 15,
marginBottom: 20
},
+ balanceHeaderIcons: {
+ width: 48,
+ height: 48
+ },
+ dividerLine:{
+ width: 1,
+ height: 20,
+ marginTop: 16.5,
+ marginHorizontal: isSmallPhone ? 5 : 8
+ },
userProfileImageSkipFont: {
height: 100,
width: 100,
diff --git a/src/components/CustomDrawerContent/index.js b/src/components/CustomDrawerContent/index.js
index da8f9352..c989ce9c 100644
--- a/src/components/CustomDrawerContent/index.js
+++ b/src/components/CustomDrawerContent/index.js
@@ -15,7 +15,6 @@ import helpIcon from '../../assets/settings-support.png';
import about from '../../assets/settings-about.png';
import privacy from '../../assets/settings-privacy.png';
import tac from '../../assets/settings-terms-and-conditions.png';
-import storePink from '../../assets/StorePink.png';
import Toast from '../../theme/components/NotificationToast';
import multipleClickHandler from '../../services/MultipleClickHandler';
import OstWalletSdkHelper from '../../helpers/OstWalletSdkHelper';
@@ -240,18 +239,6 @@ class CustomDrawerContent extends Component {
- {
- this.onPepocornsClick();
- })}
- disabled={this.state.disableButtons}
- {...testProps('side-toggle-drawer-pepo-store')}
- >
-
-
- Pepo.com Store
-
-
{
diff --git a/src/components/LoginPopover/index.js b/src/components/LoginPopover/index.js
index 166ad543..c79ae197 100644
--- a/src/components/LoginPopover/index.js
+++ b/src/components/LoginPopover/index.js
@@ -20,7 +20,6 @@ import profilePicture from "../../assets/default_user_icon.png";
import WebLogins from '../../services/WebLogins';
import { analyticsSetCurrentScreen } from '../../helpers/helpers';
import {globalEvents, globalEventsMap} from "../../helpers/GlobalEvents";
-import debounce from "lodash/debounce";
import {testProps} from "../../constants/AppiumAutomation";
@@ -29,7 +28,7 @@ const btnPostText = 'Connecting...';
const versionIOS = DeviceInfo.getSystemVersion();
const finalVersionIOS = parseFloat( versionIOS ) <= 13;
-let sequenceOfLoginServices = [serviceTypes.twitter, serviceTypes.google, serviceTypes.github ] ;
+let sequenceOfLoginServices = [serviceTypes.twitter, serviceTypes.google ] ; // Initially also had: serviceTypes.github
if( Platform.OS == 'ios' && !finalVersionIOS ){
sequenceOfLoginServices.splice(1, 0, serviceTypes.apple);
}
@@ -43,7 +42,7 @@ class loginPopover extends React.Component {
showAllOptions : !this.isLastLoginUser(),
currentConnecting: ''
};
- this.resetBtnTimeOut = 0
+ this.resetBtnTimeOut = 0;
this.setLoginServicesConfig();
}
@@ -62,7 +61,7 @@ class loginPopover extends React.Component {
this.resetBtnTimeOut = setTimeout(()=> {
this.setState({disableLoginBtn : false, currentConnecting: ""});
} , 100)
- }
+ };
setLoginServicesConfig = () => {
this.loginServicesConfig = {
@@ -93,15 +92,15 @@ class loginPopover extends React.Component {
connectingHeader: btnPostText,
testIdName: 'continue-with-google'
},
- [serviceTypes.github]: {
- header: 'Continue with GitHub',
- pressHandler: this.githubPressHandler,
- icon: LastLoginedUser.getOAuthIcon(serviceTypes.github),
- width: 19,
- height: 18.5,
- connectingHeader: btnPostText,
- testIdName: 'continue-with-github'
- },
+ // [serviceTypes.github]: {
+ // header: 'Continue with GitHub',
+ // pressHandler: this.githubPressHandler,
+ // icon: LastLoginedUser.getOAuthIcon(serviceTypes.github),
+ // width: 19,
+ // height: 18.5,
+ // connectingHeader: btnPostText,
+ // testIdName: 'continue-with-github'
+ // },
};
};
@@ -109,27 +108,27 @@ class loginPopover extends React.Component {
beforeOAuthInvoke = (service ) => {
analyticsSetCurrentScreen( service );
this.setState({disableLoginBtn : true , currentConnecting: AppConfig.authServiceTypes[service] })
- }
+ };
gmailPressHandler = () => {
this.beforeOAuthInvoke(AppConfig.authServiceTypes.google);
GoogleOAuth.signIn();
- }
+ };
githubPressHandler = () => {
this.beforeOAuthInvoke(AppConfig.authServiceTypes.github);
WebLogins.openGitHubWebLogin();
- }
+ };
twitterPressHandler = () => {
this.beforeOAuthInvoke(AppConfig.authServiceTypes.twitter);
WebLogins.openTwitterWebLogin();
- }
+ };
applePressHandler = () => {
this.beforeOAuthInvoke(AppConfig.authServiceTypes.apple);
AppleOAuth.signIn();
- }
+ };
//Use this function if needed to handle hardware back handling for android.
closeModal = () => {
@@ -193,7 +192,7 @@ class loginPopover extends React.Component {
onMoreOptionClick = () => {
this.setState({showAllOptions : true});
- }
+ };
getProfileImageMarkup(){
const profilePic = LastLoginedUser.getProfileImage();
@@ -208,7 +207,7 @@ class loginPopover extends React.Component {
signInViaLastLoginService = () => {
const serviceConfig = this.loginServicesConfig[LastLoginedUser.getLastLoginServiceType()];
- if(serviceConfig.pressHandler){
+ if(serviceConfig && serviceConfig.pressHandler){
serviceConfig.pressHandler.apply(this);
return;
}
@@ -217,9 +216,9 @@ class loginPopover extends React.Component {
* This should never happen. But just incase if it dose user can still login.
* The app wont be blocking for it.
*/
- console.warn("AS services was found but pressHandler was unavaialable in serviceConfig LoginPopover.");
+ console.warn("AS services / pressHandler was unavaialable in serviceConfig LoginPopover.");
this.setState({showAllOptions: true});
- }
+ };
render() {
return (
diff --git a/src/components/Profile/BalanceHeader.js b/src/components/Profile/BalanceHeader.js
index 08e9472e..dbac28f1 100644
--- a/src/components/Profile/BalanceHeader.js
+++ b/src/components/Profile/BalanceHeader.js
@@ -3,10 +3,11 @@ import {connect} from 'react-redux';
import { View, TouchableWithoutFeedback, TouchableOpacity } from 'react-native';
import { Text, Image } from 'react-native';
import pricer from '../../services/Pricer';
-import inlineStyles from './styles';
+import inlineProfileStyles from './styles';
import selfAmountWallet from '../../assets/pepo-amount-wallet.png';
-import topUpIcon from '../../assets/top-up-icon.png'
-import inlineStyle from "../CommonComponents/UserInfo/styles";
+import topUpIcon from '../../assets/top-up-icon.png';
+import storeIcon from '../../assets/balanace-header-store.png'
+import inlineUserStyles from "../CommonComponents/UserInfo/styles";
import LinearGradient from "react-native-linear-gradient";
import { withNavigation } from 'react-navigation';
import CurrentUser from '../../models/CurrentUser';
@@ -24,6 +25,9 @@ import MultipleClickHandler from '../../services/MultipleClickHandler';
import { OstWalletSdk } from '@ostdotcom/ost-wallet-sdk-react-native';
import pepoCornsImg from '../../assets/UnicornSmall.png';
import {testProps} from "../../constants/AppiumAutomation";
+import Utilities from "../../services/Utilities";
+
+import multipleClickHandler from '../../services/MultipleClickHandler';
const mapStateToProps = (state) => ({ balance: state.balance });
@@ -126,14 +130,18 @@ class BalanceHeader extends PureComponent {
}
}
+ onStoreClick = () => {
+ Utilities.openRedemptionWebView();
+ }
+
render() {
return (
-
+
-
- Top Up
+
+ Top Up
this.onRedemptionClick())} >
-
- {AppConfig.redemption.pepoCornsName}
+
+ {AppConfig.redemption.pepoCornsName}
+
+
+
+ {
+ this.onStoreClick();
+ })} >
+
+
+ Store
{this.getWalletIcon()}
- {' '}{this.toBt(this.props.balance) || 0.00}
+ {' '}{this.toBt(this.props.balance) || 0.00}
- ${' '}{this.toFiat( this.props.balance ) || 0.00}
+ ${' '}{this.toFiat( this.props.balance ) || 0.00}
);
diff --git a/src/components/Profile/ProfileScreen.js b/src/components/Profile/ProfileScreen.js
index c26895e9..b10bf517 100644
--- a/src/components/Profile/ProfileScreen.js
+++ b/src/components/Profile/ProfileScreen.js
@@ -17,7 +17,6 @@ import appConfig from '../../constants/AppConfig';
import profileEditIcon from '../../assets/profile_edit_icon.png';
import multipleClickHandler from '../../services/MultipleClickHandler';
import PepoApi from '../../services/PepoApi';
-import ReviewStatusBanner from './ReviewStatusBanner';
import CustomDrawer from '../CustomDrawer';
import {DrawerEmitter} from '../../helpers/Emitters';
import {testProps} from "../../constants/AppiumAutomation";
@@ -133,10 +132,10 @@ class ProfileScreen extends PureComponent {
onEmailSave = ( email ) => {
if(!email) return;
this.state.emailAddress = email;
- }
+ };
beforeRefresh = () => {
- fetchUser(CurrentUser.getUserId())
+ fetchUser(CurrentUser.getUserId());
this.getEmail();
Pricer.getBalance();
};
@@ -162,25 +161,25 @@ class ProfileScreen extends PureComponent {
onRefresh =(list , res) => {
this.setState({ hasVideos : !!list.length });
- }
+ };
videoInReviewHeader = () => {
if(this.state.hasVideos){
- return
+ return
}
- }
+ };
onClose = ()=>{
this.setState({
openDrawer: false
})
- }
+ };
onDelete = (list) => {
if (!list || list.length == 0){
this.setState({hasVideos: false});
}
- }
+ };
render() {
if(this.props.userId){
diff --git a/src/components/UserActivating/index.js b/src/components/UserActivating/index.js
index 9b874419..03c86418 100644
--- a/src/components/UserActivating/index.js
+++ b/src/components/UserActivating/index.js
@@ -7,6 +7,8 @@ import TouchableButton from '../../theme/components/TouchableButton';
import Theme from '../../theme/styles';
import air_drop from '../../assets/airdrop-create-pin.png';
import styles from './Style';
+import Pricer from '../../services/Pricer';
+import ReduxGetters from '../../services/ReduxGetters';
// create a component
export default class UserActivatingScreen extends Component {
@@ -22,6 +24,17 @@ export default class UserActivatingScreen extends Component {
this.props.navigation.navigate('SetPinScreen');
}
+ getAirDropPepoAmount(){
+ const pepoAmountInWei = ReduxGetters.getPepoAmtInWei();
+ return Pricer.getFromDecimal(pepoAmountInWei);
+ }
+
+ getAirDropUSDAmount(){
+ const pepoAmtInUSD = ReduxGetters.getPepoAmtInUSD();
+ return pepoAmtInUSD ;
+ }
+
+
render() {
return (
@@ -37,8 +50,8 @@ export default class UserActivatingScreen extends Component {
Welcome Gift!
- You’ve received 500 Pepo!
- $5 Value!
+ You’ve received {this.getAirDropPepoAmount()} Pepo!
+ ${this.getAirDropUSDAmount()} Value!
diff --git a/src/components/VideoRecorder/index.js b/src/components/VideoRecorder/index.js
index 2a688caf..804f4e6c 100644
--- a/src/components/VideoRecorder/index.js
+++ b/src/components/VideoRecorder/index.js
@@ -735,7 +735,7 @@ class VideoRecorder extends Component {
let durationByProgress = this.getLastSegmentProgress() * AppConfig.videoRecorderConstants.videoMaxLength * 1000;
const correctionVal = this.correctedRecordingDelay - (duration - durationByCode);
this.setCorrectionValue( correctionVal );
- // let logMsg = `DF ${duration.toFixed(2)} DC ${durationByCode.toFixed(2)} CD ${this.correctedRecordingDelay.toFixed(2)}`;
+ // let logMsg = `FFmpeg ${duration.toFixed(2)} Code ${durationByCode.toFixed(2)} Delay ${this.correctedRecordingDelay.toFixed(2)}`;
// Toast.show({text:logMsg, icon: 'success'});
Utilities.saveItem(AppConfig.videoRecorderConstants.recordingDelayKey, this.correctedRecordingDelay);
};
@@ -767,6 +767,16 @@ class VideoRecorder extends Component {
return ;
}
+ // Try parsing to get the video duration else use durationByCode
+ if(!videoInfo.duration) {
+ let duration = this.getVideoDurationFromRawInformation(videoInfo.rawInformation);
+ if(duration){
+ videoInfo.duration = duration;
+ } else {
+ videoInfo.duration = durationByCode;
+ }
+ }
+
if ( videoInfo.duration >= (MIN_VIDEO_LENGTH_IN_SEC * 1000)) {
this.videoLength += videoInfo.duration;
this.videoUrlsList.push({uri: data.uri, progress: this.progress, durationInMS: videoInfo.duration });
@@ -778,6 +788,23 @@ class VideoRecorder extends Component {
}
};
+ getVideoDurationFromRawInformation = (rawInformation) => {
+ if(rawInformation && rawInformation.trim() === '') return;
+
+ const regex = /duration:(\s)*([0-9]{2,2}:[0-9]{2,2}:[0-9]{2,2}[0-9.]*)/gi;
+ let matches = regex.exec(rawInformation);
+
+ if(matches && matches[2]){
+ let timestamp = matches[2];
+ let timestampParts = timestamp.split(':');
+ let duration = (timestampParts[0] * (60*60*1000)) + (timestampParts[1] * (60*1000)) + (timestampParts[2] * (1000));
+ if(duration > 1) return duration;
+ }
+
+
+
+ };
+
correctProgress = () => {
let correctedProgress = (this.videoLength / 1000) / AppConfig.videoRecorderConstants.videoMaxLength;
this.updateVideoUrlsListProgress(correctedProgress);
diff --git a/src/helpers/cameraHelper.js b/src/helpers/cameraHelper.js
index 5dd4fc88..87f9ac35 100644
--- a/src/helpers/cameraHelper.js
+++ b/src/helpers/cameraHelper.js
@@ -36,6 +36,10 @@ const getVideoReplyObject = (videoId, creatorUserId) => {
};
};
+const getCameraObjKeyAsyncStorage = (userId) => {
+ return `user-${userId}-recorded_video`;
+};
+
const navigateToCamera = (videoId , userId , navigation) => {
let activeTab = NavigationService.getActiveTab();
@@ -181,4 +185,4 @@ const replyPreValidationAndMessage = (videoId , userId) => {
}
-export { getVideoReplyObject , navigateToCamera , replyPreValidationAndMessage, getPixelDataOnFanVideoSuccess, getPixelDataOnReplyVideoSuccess}
+export { getVideoReplyObject , navigateToCamera , replyPreValidationAndMessage, getPixelDataOnFanVideoSuccess, getPixelDataOnReplyVideoSuccess, getCameraObjKeyAsyncStorage}
diff --git a/src/models/CurrentUser.js b/src/models/CurrentUser.js
index 8365ecfd..140c3717 100644
--- a/src/models/CurrentUser.js
+++ b/src/models/CurrentUser.js
@@ -11,6 +11,7 @@ import EventEmitter from "eventemitter3";
import {navigateTo} from "../helpers/navigateTo";
import AppConfig from '../constants/AppConfig';
import LastLoginedUser from "./LastLoginedUser";
+import {getCameraObjKeyAsyncStorage} from "../helpers/cameraHelper";
const RCTNetworking = require('react-native/Libraries/Network/RCTNetworking');
@@ -165,6 +166,7 @@ class CurrentUser {
Store.dispatch(logoutUser());
await utilities.removeItem(this._getCurrentUserIdKey());
await utilities.removeItem(this._getASKey(userId));
+ await utilities.removeItem(getCameraObjKeyAsyncStorage(userId));
} catch (e) {
console.log('clearCurrentUser gaved error!', e);
}
diff --git a/src/services/CameraWorker.js b/src/services/CameraWorker.js
index 504266db..015bebc1 100644
--- a/src/services/CameraWorker.js
+++ b/src/services/CameraWorker.js
@@ -28,7 +28,7 @@ import {TransactionExecutor} from './TransactionExecutor';
import { ostSdkErrors } from '../services/OstSdkErrors';
import AppConfig from '../constants/AppConfig';
import { fetchVideo } from '../helpers/helpers';
-import {getPixelDataOnFanVideoSuccess, getPixelDataOnReplyVideoSuccess} from "../helpers/cameraHelper";
+import {getPixelDataOnFanVideoSuccess, getPixelDataOnReplyVideoSuccess, getCameraObjKeyAsyncStorage} from "../helpers/cameraHelper";
const recordedVideoStates = [
'raw_video_list',
@@ -861,9 +861,8 @@ class CameraWorker extends PureComponent {
getCurrentUserRecordedVideoKey() {
if (this.props.currentUserId) {
- return `user-${this.props.currentUserId}-recorded_video`;
+ return getCameraObjKeyAsyncStorage(this.props.currentUserId);
}
- return;
}
getDataforAsync() {
diff --git a/src/services/ReduxGetters.js b/src/services/ReduxGetters.js
index 723bcb33..2ac50d15 100644
--- a/src/services/ReduxGetters.js
+++ b/src/services/ReduxGetters.js
@@ -649,6 +649,14 @@ class ReduxGetters {
return deepGet(state, `current_user_channel_relation_entities.id_${id}.notification_status`);
}
+ getPepoAmtInWei(state){
+ state = state || Store.getState();
+ return deepGet(state, `airdrop_details_entities.pepo_amount_in_wei`);
+ }
+ getPepoAmtInUSD(state){
+ state = state || Store.getState();
+ return deepGet(state, `airdrop_details_entities.pepo_amount_in_usd`);
+ }
}
diff --git a/src/services/ReduxSetters.js b/src/services/ReduxSetters.js
index 249c1c98..ddad3e3c 100644
--- a/src/services/ReduxSetters.js
+++ b/src/services/ReduxSetters.js
@@ -73,7 +73,8 @@ const backendToAppEntities = {
channel_user_relations: {
key : 'channel_user_relation_entities',
parser: parser_merge
- }
+ },
+ airdrop_details : 'airdrop_details_entities'
};
// This is a map of signular entity result_type w.r.t. result_type of result collect (Array/HashMap) of same type.