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.