mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-29 00:21:41 +03:00
wip on spin game
This commit is contained in:
commit
d63bd3df6e
@ -33,6 +33,7 @@
|
||||
"react/prop-types": 0,
|
||||
"import/no-named-default": "off",
|
||||
"no-param-reassign": "off",
|
||||
"no-case-declarations": "off"
|
||||
"no-case-declarations": "off",
|
||||
"no-cycle": "off"
|
||||
}
|
||||
}
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -57,6 +57,7 @@ buck-out/
|
||||
|
||||
config.js
|
||||
!src/screens/steem-connect/config.js
|
||||
google-services.json
|
||||
keystore/
|
||||
.env
|
||||
package-lock.json
|
||||
|
6
App.js
6
App.js
@ -1,7 +1,5 @@
|
||||
import { Client } from 'bugsnag-react-native';
|
||||
import Config from 'react-native-config';
|
||||
// eslint-disable-next-line
|
||||
import bugsnag from './src/config/bugsnag';
|
||||
import App from './src/index';
|
||||
|
||||
const bugsnag = new Client(Config.BUGSNAG_API_KEY);
|
||||
|
||||
export default App;
|
||||
|
@ -114,7 +114,7 @@ android {
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch
|
||||
versionName "2.2.0"
|
||||
versionName "2.2.2"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
resValue "string", "build_config_package", "app.esteem.mobile.android"
|
||||
}
|
||||
|
BIN
android/app/src/main/assets/fonts/Fontisto.ttf
Executable file
BIN
android/app/src/main/assets/fonts/Fontisto.ttf
Executable file
Binary file not shown.
@ -3,10 +3,10 @@
|
||||
|
||||
platform :ios, '9.0'
|
||||
target 'eSteem' do
|
||||
pod 'AppCenter/Push', '~> 2.2.0'
|
||||
pod 'AppCenter/Crashes', '~> 2.2.0'
|
||||
pod 'AppCenter/Analytics', '~> 2.2.0'
|
||||
pod 'AppCenterReactNativeShared', '~> 2.2.0'
|
||||
pod 'AppCenter/Push', '~> 2.3.0'
|
||||
pod 'AppCenter/Crashes', '~> 2.3.0'
|
||||
pod 'AppCenter/Analytics', '~> 2.3.0'
|
||||
pod 'AppCenterReactNativeShared', '~> 2.3.0'
|
||||
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
|
||||
# use_frameworks!
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
PODS:
|
||||
- AppCenter/Analytics (2.2.0):
|
||||
- AppCenter/Analytics (2.3.0):
|
||||
- AppCenter/Core
|
||||
- AppCenter/Core (2.2.0)
|
||||
- AppCenter/Crashes (2.2.0):
|
||||
- AppCenter/Core (2.3.0)
|
||||
- AppCenter/Crashes (2.3.0):
|
||||
- AppCenter/Core
|
||||
- AppCenter/Push (2.2.0):
|
||||
- AppCenter/Push (2.3.0):
|
||||
- AppCenter/Core
|
||||
- AppCenterReactNativeShared (2.2.0):
|
||||
- AppCenter/Core (= 2.2.0)
|
||||
- AppCenterReactNativeShared (2.3.0):
|
||||
- AppCenter/Core (= 2.3.0)
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BugsnagReactNative (2.21.0):
|
||||
- BugsnagReactNative/Core (= 2.21.0)
|
||||
- BugsnagReactNative (2.23.0):
|
||||
- BugsnagReactNative/Core (= 2.23.0)
|
||||
- React
|
||||
- BugsnagReactNative/Core (2.21.0):
|
||||
- BugsnagReactNative/Core (2.23.0):
|
||||
- React
|
||||
- CodePush (1000.0.0):
|
||||
- CodePush/Base64 (= 1000.0.0)
|
||||
@ -43,7 +43,7 @@ PODS:
|
||||
- React
|
||||
- SDWebImage/Core
|
||||
- SDWebImage/GIF
|
||||
- react-native-netinfo (4.1.3):
|
||||
- react-native-netinfo (4.1.5):
|
||||
- React
|
||||
- react-native-version-number (0.3.6):
|
||||
- React
|
||||
@ -95,7 +95,7 @@ PODS:
|
||||
- React/Core
|
||||
- React/fishhook
|
||||
- React/RCTBlob
|
||||
- RNIap (3.3.0):
|
||||
- RNIap (3.4.1):
|
||||
- React
|
||||
- RNImageCropPicker (0.24.1):
|
||||
- QBImagePickerController
|
||||
@ -109,10 +109,10 @@ PODS:
|
||||
- yoga (0.59.8.React)
|
||||
|
||||
DEPENDENCIES:
|
||||
- AppCenter/Analytics (~> 2.2.0)
|
||||
- AppCenter/Crashes (~> 2.2.0)
|
||||
- AppCenter/Push (~> 2.2.0)
|
||||
- AppCenterReactNativeShared (~> 2.2.0)
|
||||
- AppCenter/Analytics (~> 2.3.0)
|
||||
- AppCenter/Crashes (~> 2.3.0)
|
||||
- AppCenter/Push (~> 2.3.0)
|
||||
- AppCenterReactNativeShared (~> 2.3.0)
|
||||
- BugsnagReactNative (from `../node_modules/bugsnag-react-native`)
|
||||
- CodePush (from `../node_modules/react-native-code-push`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
@ -172,10 +172,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppCenter: c809e69d93218b9861b4f8e54ded8dcf4d2131e7
|
||||
AppCenterReactNativeShared: 5751a607a8aa06ebf19b48bf9d92bf3a75dab04e
|
||||
AppCenter: 9784d2fc998c9bd0b8fbaf4fb9ed69526d12ce1a
|
||||
AppCenterReactNativeShared: 7ac481cba7f926848a7be76dca4dcb2692df3b06
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BugsnagReactNative: 9f273f292378a016977f578e4467cf84b7182b07
|
||||
BugsnagReactNative: a469858d1040621a04247bb4ec15ca18dceabfd6
|
||||
CodePush: a503ca0caee269e68d8faaafe4414990ec282520
|
||||
DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd
|
||||
FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31
|
||||
@ -184,14 +184,14 @@ SPEC CHECKSUMS:
|
||||
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
||||
React: 76e6aa2b87d05eb6cccb6926d72685c9a07df152
|
||||
react-native-fast-image: 6d50167ad4d68b59640ceead8c2bc4e58d91d8bd
|
||||
react-native-netinfo: e2c8a843bb18ab6c3f1e6cbead694491b36e3ffd
|
||||
react-native-netinfo: 0e563248a4b9a99c33ec29bd03c2d50767db22a6
|
||||
react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f
|
||||
RNIap: ee89b7442f32161016fe213a3434ee1fc19c1a80
|
||||
RNIap: 8104f5fb44555f163531ca9c6200b7b405a44f1c
|
||||
RNImageCropPicker: 6134b66a3d5bc13e2895a97c630a4254006902b4
|
||||
RSKImageCropper: 98296ad26b41753f796b6898d015509598f13d97
|
||||
SDWebImage: 3f3f0c02f09798048c47a5ed0a13f17b063572d8
|
||||
yoga: 92b2102c3d373d1a790db4ab761d2b0ffc634f64
|
||||
|
||||
PODFILE CHECKSUM: afb8c6a227837e2a901eaed832d5bb66c6fd9cec
|
||||
PODFILE CHECKSUM: 0e644f6a56d015441b78d265a6c615ed194b94f0
|
||||
|
||||
COCOAPODS: 1.7.5
|
||||
|
Binary file not shown.
@ -55,7 +55,7 @@
|
||||
/*
|
||||
* The offset in minutes from UTC for the device time zone, including daylight savings time.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSNumber *timeZoneOffset;
|
||||
@property(nonatomic, readonly, strong) NSNumber *timeZoneOffset;
|
||||
|
||||
/*
|
||||
* Screen size of the device in pixels (example: 640x480).
|
||||
|
@ -15,7 +15,7 @@
|
||||
/**
|
||||
* Log timestamp.
|
||||
*/
|
||||
@property(nonatomic) NSDate *timestamp;
|
||||
@property(nonatomic, strong) NSDate *timestamp;
|
||||
|
||||
/**
|
||||
* A session identifier is used to correlate logs together. A session is an abstract concept in the API and is not necessarily an analytics
|
||||
@ -36,13 +36,13 @@
|
||||
/**
|
||||
* Device properties associated to this log.
|
||||
*/
|
||||
@property(nonatomic) MSDevice *device;
|
||||
@property(nonatomic, strong) MSDevice *device;
|
||||
|
||||
/**
|
||||
* Transient object tag. For example, a log can be tagged with a transmission target. We do this currently to prevent properties being
|
||||
* applied retroactively to previous logs by comparing their tags.
|
||||
*/
|
||||
@property(nonatomic) NSObject *tag;
|
||||
@property(nonatomic, strong) NSObject *tag;
|
||||
|
||||
/**
|
||||
* Checks if the object's values are valid.
|
||||
|
@ -10,6 +10,6 @@
|
||||
/**
|
||||
* Additional key/value pair parameters. [optional]
|
||||
*/
|
||||
@property(nonatomic) NSDictionary<NSString *, NSString *> *properties;
|
||||
@property(nonatomic, strong) NSDictionary<NSString *, NSString *> *properties;
|
||||
|
||||
@end
|
||||
|
@ -16,7 +16,7 @@
|
||||
/**
|
||||
* The flag indicates whether the service is started from application or not.
|
||||
*/
|
||||
@property(nonatomic) BOOL startedFromApplication;
|
||||
@property(nonatomic, assign) BOOL startedFromApplication;
|
||||
|
||||
/**
|
||||
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
|
||||
|
Binary file not shown.
@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* The type.
|
||||
*/
|
||||
@property(nonatomic, readonly) MSAnalyticsAuthenticationType type;
|
||||
@property(nonatomic, readonly, assign) MSAnalyticsAuthenticationType type;
|
||||
|
||||
/**
|
||||
* The ticket key for this authentication provider.
|
||||
|
@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* Property configurator.
|
||||
*/
|
||||
@property(nonatomic, readonly) MSPropertyConfigurator *propertyConfigurator;
|
||||
@property(nonatomic, readonly, strong) MSPropertyConfigurator *propertyConfigurator;
|
||||
|
||||
+ (void)addAuthenticationProvider:(MSAnalyticsAuthenticationProvider *)authenticationProvider
|
||||
NS_SWIFT_NAME(addAuthenticationProvider(authenticationProvider:));
|
||||
|
@ -16,6 +16,6 @@
|
||||
/**
|
||||
* Event properties.
|
||||
*/
|
||||
@property(nonatomic) MSEventProperties *typedProperties;
|
||||
@property(nonatomic, strong) MSEventProperties *typedProperties;
|
||||
|
||||
@end
|
||||
|
@ -10,6 +10,6 @@
|
||||
/**
|
||||
* Additional key/value pair parameters. [optional]
|
||||
*/
|
||||
@property(nonatomic) NSDictionary<NSString *, NSString *> *properties;
|
||||
@property(nonatomic, strong) NSDictionary<NSString *, NSString *> *properties;
|
||||
|
||||
@end
|
||||
|
@ -16,7 +16,7 @@
|
||||
/**
|
||||
* The flag indicates whether the service is started from application or not.
|
||||
*/
|
||||
@property(nonatomic) BOOL startedFromApplication;
|
||||
@property(nonatomic, assign) BOOL startedFromApplication;
|
||||
|
||||
/**
|
||||
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
|
||||
|
Binary file not shown.
@ -89,6 +89,13 @@ typedef NS_ENUM(NSUInteger, MSUserConfirmation) {
|
||||
*/
|
||||
+ (BOOL)hasCrashedInLastSession;
|
||||
|
||||
/**
|
||||
* Check if the app received memory warning in the last session.
|
||||
*
|
||||
* @return Returns YES is the app received memory warning in the last session.
|
||||
*/
|
||||
+ (BOOL)hasReceivedMemoryWarningInLastSession;
|
||||
|
||||
/**
|
||||
* Provides details about the crash that occurred in the last app session
|
||||
*/
|
||||
|
@ -35,17 +35,17 @@
|
||||
/**
|
||||
* Date and time the app started, nil if unknown.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDate *appStartTime;
|
||||
@property(nonatomic, readonly, strong) NSDate *appStartTime;
|
||||
|
||||
/**
|
||||
* Date and time the error occurred, nil if unknown
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDate *appErrorTime;
|
||||
@property(nonatomic, readonly, strong) NSDate *appErrorTime;
|
||||
|
||||
/**
|
||||
* Device information of the app when it crashed.
|
||||
*/
|
||||
@property(nonatomic, readonly) MSDevice *device;
|
||||
@property(nonatomic, readonly, strong) MSDevice *device;
|
||||
|
||||
/**
|
||||
* Identifier of the app process that crashed.
|
||||
|
@ -16,7 +16,7 @@
|
||||
/**
|
||||
* The flag indicates whether the service is started from application or not.
|
||||
*/
|
||||
@property(nonatomic) BOOL startedFromApplication;
|
||||
@property(nonatomic, assign) BOOL startedFromApplication;
|
||||
|
||||
/**
|
||||
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
|
||||
|
Binary file not shown.
@ -16,7 +16,7 @@
|
||||
/**
|
||||
* The flag indicates whether the service is started from application or not.
|
||||
*/
|
||||
@property(nonatomic) BOOL startedFromApplication;
|
||||
@property(nonatomic, assign) BOOL startedFromApplication;
|
||||
|
||||
/**
|
||||
* Start this service with a channel group. Also sets the flag that indicates that a service has been started.
|
||||
|
Binary file not shown.
1
ios/Pods/Headers/Private/BugsnagReactNative/BSG_KSCrashIdentifier.h
generated
Symbolic link
1
ios/Pods/Headers/Private/BugsnagReactNative/BSG_KSCrashIdentifier.h
generated
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../../node_modules/bugsnag-react-native/cocoa/vendor/bugsnag-cocoa/Source/KSCrash/Source/KSCrash/Recording/BSG_KSCrashIdentifier.h
|
@ -1 +0,0 @@
|
||||
../../../../../node_modules/bugsnag-react-native/cocoa/vendor/bugsnag-cocoa/Source/KSCrash/Source/KSCrash/Recording/Sentry/BSG_KSCrashSentry_Deadlock.h
|
@ -1 +0,0 @@
|
||||
../../../../../node_modules/bugsnag-react-native/cocoa/vendor/bugsnag-cocoa/Source/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSSafeCollections.h
|
@ -1 +0,0 @@
|
||||
../../../../../node_modules/bugsnag-react-native/cocoa/vendor/bugsnag-cocoa/Source/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSZombie.h
|
@ -1 +0,0 @@
|
||||
../../../../../node_modules/bugsnag-react-native/cocoa/vendor/bugsnag-cocoa/Source/KSCrash/Source/KSCrash/Recording/Tools/NSDictionary+BSG_Merge.h
|
1
ios/Pods/Headers/Private/BugsnagReactNative/Private.h
generated
Symbolic link
1
ios/Pods/Headers/Private/BugsnagReactNative/Private.h
generated
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../../node_modules/bugsnag-react-native/cocoa/vendor/bugsnag-cocoa/Source/Private.h
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "BugsnagReactNative",
|
||||
"version": "2.21.0",
|
||||
"version": "2.23.0",
|
||||
"license": "MIT",
|
||||
"summary": "Bugsnag crash and error reporting for React Native apps",
|
||||
"authors": {
|
||||
@ -9,7 +9,7 @@
|
||||
"homepage": "https://docs.bugsnag.com/platforms/react-native",
|
||||
"source": {
|
||||
"git": "https://github.com/bugsnag/bugsnag-react-native.git",
|
||||
"tag": "v2.21.0"
|
||||
"tag": "v2.23.0"
|
||||
},
|
||||
"platforms": {
|
||||
"ios": "8.0"
|
||||
|
13
ios/Pods/Local Podspecs/RNIap.podspec.json
generated
13
ios/Pods/Local Podspecs/RNIap.podspec.json
generated
@ -1,19 +1,18 @@
|
||||
{
|
||||
"name": "RNIap",
|
||||
"version": "3.3.0",
|
||||
"summary": "RNIap",
|
||||
"description": "React Native In App Purchase Module.",
|
||||
"version": "3.4.1",
|
||||
"summary": "React Native In App Purchase Module.",
|
||||
"homepage": "https://github.com/dooboolab/react-native-iap",
|
||||
"license": "MIT",
|
||||
"authors": "dooboolab",
|
||||
"platforms": {
|
||||
"ios": "7.0"
|
||||
"ios": "9.0"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/dooboolab/react-native-iap",
|
||||
"tag": "v3.3.0"
|
||||
"git": "https://github.com/dooboolab/react-native-iap.git",
|
||||
"tag": "3.4.1"
|
||||
},
|
||||
"source_files": "ios/**/*.{h,m}",
|
||||
"source_files": "ios/*.{h,m}",
|
||||
"requires_arc": true,
|
||||
"dependencies": {
|
||||
"React": [
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-netinfo",
|
||||
"version": "4.1.3",
|
||||
"version": "4.1.5",
|
||||
"summary": "React Native Network Info API for iOS & Android",
|
||||
"license": "MIT",
|
||||
"authors": "Matt Oakes <hello@mattoakes.net>",
|
||||
@ -11,7 +11,7 @@
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/react-native-community/react-native-netinfo.git",
|
||||
"tag": "4.1.3"
|
||||
"tag": "v4.1.5"
|
||||
},
|
||||
"source_files": "ios/**/*.{h,m}",
|
||||
"dependencies": {
|
||||
|
42
ios/Pods/Manifest.lock
generated
42
ios/Pods/Manifest.lock
generated
@ -1,18 +1,18 @@
|
||||
PODS:
|
||||
- AppCenter/Analytics (2.2.0):
|
||||
- AppCenter/Analytics (2.3.0):
|
||||
- AppCenter/Core
|
||||
- AppCenter/Core (2.2.0)
|
||||
- AppCenter/Crashes (2.2.0):
|
||||
- AppCenter/Core (2.3.0)
|
||||
- AppCenter/Crashes (2.3.0):
|
||||
- AppCenter/Core
|
||||
- AppCenter/Push (2.2.0):
|
||||
- AppCenter/Push (2.3.0):
|
||||
- AppCenter/Core
|
||||
- AppCenterReactNativeShared (2.2.0):
|
||||
- AppCenter/Core (= 2.2.0)
|
||||
- AppCenterReactNativeShared (2.3.0):
|
||||
- AppCenter/Core (= 2.3.0)
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BugsnagReactNative (2.21.0):
|
||||
- BugsnagReactNative/Core (= 2.21.0)
|
||||
- BugsnagReactNative (2.23.0):
|
||||
- BugsnagReactNative/Core (= 2.23.0)
|
||||
- React
|
||||
- BugsnagReactNative/Core (2.21.0):
|
||||
- BugsnagReactNative/Core (2.23.0):
|
||||
- React
|
||||
- CodePush (1000.0.0):
|
||||
- CodePush/Base64 (= 1000.0.0)
|
||||
@ -43,7 +43,7 @@ PODS:
|
||||
- React
|
||||
- SDWebImage/Core
|
||||
- SDWebImage/GIF
|
||||
- react-native-netinfo (4.1.3):
|
||||
- react-native-netinfo (4.1.5):
|
||||
- React
|
||||
- react-native-version-number (0.3.6):
|
||||
- React
|
||||
@ -95,7 +95,7 @@ PODS:
|
||||
- React/Core
|
||||
- React/fishhook
|
||||
- React/RCTBlob
|
||||
- RNIap (3.3.0):
|
||||
- RNIap (3.4.1):
|
||||
- React
|
||||
- RNImageCropPicker (0.24.1):
|
||||
- QBImagePickerController
|
||||
@ -109,10 +109,10 @@ PODS:
|
||||
- yoga (0.59.8.React)
|
||||
|
||||
DEPENDENCIES:
|
||||
- AppCenter/Analytics (~> 2.2.0)
|
||||
- AppCenter/Crashes (~> 2.2.0)
|
||||
- AppCenter/Push (~> 2.2.0)
|
||||
- AppCenterReactNativeShared (~> 2.2.0)
|
||||
- AppCenter/Analytics (~> 2.3.0)
|
||||
- AppCenter/Crashes (~> 2.3.0)
|
||||
- AppCenter/Push (~> 2.3.0)
|
||||
- AppCenterReactNativeShared (~> 2.3.0)
|
||||
- BugsnagReactNative (from `../node_modules/bugsnag-react-native`)
|
||||
- CodePush (from `../node_modules/react-native-code-push`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
@ -172,10 +172,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppCenter: c809e69d93218b9861b4f8e54ded8dcf4d2131e7
|
||||
AppCenterReactNativeShared: 5751a607a8aa06ebf19b48bf9d92bf3a75dab04e
|
||||
AppCenter: 9784d2fc998c9bd0b8fbaf4fb9ed69526d12ce1a
|
||||
AppCenterReactNativeShared: 7ac481cba7f926848a7be76dca4dcb2692df3b06
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BugsnagReactNative: 9f273f292378a016977f578e4467cf84b7182b07
|
||||
BugsnagReactNative: a469858d1040621a04247bb4ec15ca18dceabfd6
|
||||
CodePush: a503ca0caee269e68d8faaafe4414990ec282520
|
||||
DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd
|
||||
FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31
|
||||
@ -184,14 +184,14 @@ SPEC CHECKSUMS:
|
||||
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
||||
React: 76e6aa2b87d05eb6cccb6926d72685c9a07df152
|
||||
react-native-fast-image: 6d50167ad4d68b59640ceead8c2bc4e58d91d8bd
|
||||
react-native-netinfo: e2c8a843bb18ab6c3f1e6cbead694491b36e3ffd
|
||||
react-native-netinfo: 0e563248a4b9a99c33ec29bd03c2d50767db22a6
|
||||
react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f
|
||||
RNIap: ee89b7442f32161016fe213a3434ee1fc19c1a80
|
||||
RNIap: 8104f5fb44555f163531ca9c6200b7b405a44f1c
|
||||
RNImageCropPicker: 6134b66a3d5bc13e2895a97c630a4254006902b4
|
||||
RSKImageCropper: 98296ad26b41753f796b6898d015509598f13d97
|
||||
SDWebImage: 3f3f0c02f09798048c47a5ed0a13f17b063572d8
|
||||
yoga: 92b2102c3d373d1a790db4ab761d2b0ffc634f64
|
||||
|
||||
PODFILE CHECKSUM: afb8c6a227837e2a901eaed832d5bb66c6fd9cec
|
||||
PODFILE CHECKSUM: 0e644f6a56d015441b78d265a6c615ed194b94f0
|
||||
|
||||
COCOAPODS: 1.7.5
|
||||
|
3348
ios/Pods/Pods.xcodeproj/project.pbxproj
generated
3348
ios/Pods/Pods.xcodeproj/project.pbxproj
generated
File diff suppressed because it is too large
Load Diff
@ -9,154 +9,154 @@
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>7</integer>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
<key>AppCenterReactNativeShared.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>8</integer>
|
||||
<integer>4</integer>
|
||||
</dict>
|
||||
<key>BugsnagReactNative.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>10</integer>
|
||||
<integer>6</integer>
|
||||
</dict>
|
||||
<key>CodePush.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>11</integer>
|
||||
<integer>7</integer>
|
||||
</dict>
|
||||
<key>DoubleConversion.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>12</integer>
|
||||
<integer>8</integer>
|
||||
</dict>
|
||||
<key>FLAnimatedImage.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>13</integer>
|
||||
<integer>9</integer>
|
||||
</dict>
|
||||
<key>Folly.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>14</integer>
|
||||
<integer>10</integer>
|
||||
</dict>
|
||||
<key>Pods-eSteem-tvOS.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>17</integer>
|
||||
<integer>13</integer>
|
||||
</dict>
|
||||
<key>Pods-eSteem-tvOSTests.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>18</integer>
|
||||
<integer>14</integer>
|
||||
</dict>
|
||||
<key>Pods-eSteem.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>16</integer>
|
||||
<integer>12</integer>
|
||||
</dict>
|
||||
<key>Pods-eSteemTests.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>19</integer>
|
||||
<integer>15</integer>
|
||||
</dict>
|
||||
<key>QBImagePickerController-QBImagePicker.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>21</integer>
|
||||
<integer>17</integer>
|
||||
</dict>
|
||||
<key>QBImagePickerController.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>20</integer>
|
||||
<integer>16</integer>
|
||||
</dict>
|
||||
<key>RNIap.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>25</integer>
|
||||
<integer>21</integer>
|
||||
</dict>
|
||||
<key>RNImageCropPicker.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>26</integer>
|
||||
<integer>22</integer>
|
||||
</dict>
|
||||
<key>RSKImageCropper.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>27</integer>
|
||||
<integer>23</integer>
|
||||
</dict>
|
||||
<key>SDWebImage.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>28</integer>
|
||||
<integer>24</integer>
|
||||
</dict>
|
||||
<key>boost-for-react-native.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>9</integer>
|
||||
<integer>5</integer>
|
||||
</dict>
|
||||
<key>glog.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>15</integer>
|
||||
<integer>11</integer>
|
||||
</dict>
|
||||
<key>react-native-fast-image.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>22</integer>
|
||||
<integer>18</integer>
|
||||
</dict>
|
||||
<key>react-native-netinfo.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>23</integer>
|
||||
<integer>19</integer>
|
||||
</dict>
|
||||
<key>react-native-version-number.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>24</integer>
|
||||
<integer>20</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
@ -15,11 +15,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.2.0</string>
|
||||
<string>2.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3</string>
|
||||
<string>7</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true />
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
@ -15,10 +15,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.2.0</string>
|
||||
<string>2.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3</string>
|
||||
<string>7</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -82,6 +82,7 @@
|
||||
EDFF927300154818B0BF6EA4 /* libAppCenterReactNativePush.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D0E465F10CD4424E9B80CFD3 /* libAppCenterReactNativePush.a */; };
|
||||
F02CA133DF337C8C8FF1753C /* libPods-eSteem-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 38204CFB05512D7FC94CF03D /* libPods-eSteem-tvOSTests.a */; };
|
||||
FA64A93BC95743E58F77F404 /* FontAwesome5_Solid.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2DEB48DE97FD4A7585118CB4 /* FontAwesome5_Solid.ttf */; };
|
||||
06625C4421A949818C7F02C9 /* Fontisto.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C2DEBF9FC196418CA61B9CA9 /* Fontisto.ttf */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -563,6 +564,7 @@
|
||||
F202583F54E7475B0E1F9020 /* Pods-eSteem.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-eSteem.debug.xcconfig"; path = "Target Support Files/Pods-eSteem/Pods-eSteem.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
F3D23ACB36194C40BFB26B7A /* Roboto-medium.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Roboto-medium.ttf"; path = "../src/assets/Fonts/Roboto-medium.ttf"; sourceTree = "<group>"; };
|
||||
F81DF68DDD5447119FDA7F5F /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = ../src/assets/Fonts/EvilIcons.ttf; sourceTree = "<group>"; };
|
||||
C2DEBF9FC196418CA61B9CA9 /* Fontisto.ttf */ = {isa = PBXFileReference; name = "Fontisto.ttf"; path = "../node_modules/react-native-vector-icons/Fonts/Fontisto.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -990,6 +992,7 @@
|
||||
9A6F7F46844C4CAF9A9ABBDD /* Roboto.ttf */,
|
||||
434B140115EF4DE49D4CD6BA /* rubicon-icon-font.ttf */,
|
||||
F3D23ACB36194C40BFB26B7A /* Roboto-medium.ttf */,
|
||||
C2DEBF9FC196418CA61B9CA9 /* Fontisto.ttf */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
@ -1661,6 +1664,7 @@
|
||||
C872C215BA9C4FFF97A12F81 /* Roboto.ttf in Resources */,
|
||||
CF34742E37F4471D813F00E4 /* rubicon-icon-font.ttf in Resources */,
|
||||
5FA7E43947714B96866CAE94 /* Roboto-medium.ttf in Resources */,
|
||||
06625C4421A949818C7F02C9 /* Fontisto.ttf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1961,7 +1965,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = eSteem/eSteem.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 3;
|
||||
CURRENT_PROJECT_VERSION = 7;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = 75B6RXTKGT;
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
@ -2004,7 +2008,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = eSteem/eSteem.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 3;
|
||||
CURRENT_PROJECT_VERSION = 7;
|
||||
DEVELOPMENT_TEAM = 75B6RXTKGT;
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
|
@ -12,7 +12,7 @@
|
||||
<key>eSteem.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>29</integer>
|
||||
<integer>30</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
|
Binary file not shown.
Binary file not shown.
@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.2.0</string>
|
||||
<string>2.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@ -31,26 +31,26 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1666</string>
|
||||
<string>1674</string>
|
||||
<key>CodePushDeploymentKey</key>
|
||||
<string>13ThFZsgwk6UZp6mIe95IDbnfw8iHy1jfsn-E</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<true />
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<true />
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
<key>steemconnect.com</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
<true />
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
@ -91,6 +91,7 @@
|
||||
<string>FontAwesome5_Regular.ttf</string>
|
||||
<string>FontAwesome5_Solid.ttf</string>
|
||||
<string>Roboto-medium.ttf</string>
|
||||
<string>Fontisto.ttf</string>
|
||||
</array>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
@ -103,12 +104,12 @@
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<true />
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<false />
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -15,10 +15,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.2.0</string>
|
||||
<string>2.2.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3</string>
|
||||
<string>7</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eSteem",
|
||||
"version": "2.2.0",
|
||||
"version": "2.2.2",
|
||||
"private": true,
|
||||
"rnpm": {
|
||||
"assets": [
|
||||
@ -22,7 +22,7 @@
|
||||
"clear": "watchman watch-del-all && rm -rf $TMPDIR/react-native-packager-cache-* && rm -rf $TMPDIR/metro-bundler-cache-* && rm -rf node_modules/ && yarn install && yarn start -- --reset-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@esteemapp/esteem-render-helpers": "^1.1.0",
|
||||
"@ptomasroos/react-native-multi-slider": "^1.0.0",
|
||||
"@react-native-community/netinfo": "^4.1.3",
|
||||
@ -37,13 +37,13 @@
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"currency-symbol-map": "^4.0.4",
|
||||
"diff-match-patch": "^1.0.4",
|
||||
"dsteem": "^0.10.1",
|
||||
"dsteem": "https://github.com/esteemapp/dsteem#expire",
|
||||
"intl": "^1.2.5",
|
||||
"jsc-android": "^236355.1.1",
|
||||
"lodash": "^4.17.13",
|
||||
"moment": "^2.22.2",
|
||||
"react": "16.8.3",
|
||||
"react-intl": "^2.7.2",
|
||||
"react-intl": "^3.1.6",
|
||||
"react-native": "0.59.8",
|
||||
"react-native-actionsheet": "^2.4.2",
|
||||
"react-native-autocomplete-input": "^4.1.0",
|
||||
@ -52,7 +52,7 @@
|
||||
"react-native-datepicker": "^1.7.2",
|
||||
"react-native-extended-stylesheet": "^0.10.0",
|
||||
"react-native-fast-image": "^4.0.14",
|
||||
"react-native-iap": "^3.3.0",
|
||||
"react-native-iap": "^3.3.8",
|
||||
"react-native-image-crop-picker": "^0.24.1",
|
||||
"react-native-keyboard-aware-scroll-view": "^0.8.0",
|
||||
"react-native-linear-gradient": "^2.4.2",
|
||||
@ -78,11 +78,11 @@
|
||||
"rn-placeholder": "^1.3.2",
|
||||
"speakingurl": "^14.0.1",
|
||||
"stacktrace-parser": "0.1.4",
|
||||
"steemconnect": "^2.0.1"
|
||||
"steemconnect": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.4.4",
|
||||
"@babel/runtime": "^7.4.4",
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-jest": "^24.8.0",
|
||||
"babel-preset-react-native": "~5.0.2",
|
||||
|
46
src/components/avatarHeader/avatarHeaderStyles.js
Normal file
46
src/components/avatarHeader/avatarHeaderStyles.js
Normal file
@ -0,0 +1,46 @@
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
headerContainer: {
|
||||
height: 100,
|
||||
flexDirection: 'row',
|
||||
padding: 21,
|
||||
},
|
||||
backIcon: {
|
||||
color: '$white',
|
||||
},
|
||||
wrapper: {
|
||||
marginLeft: 16,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
textWrapper: {
|
||||
marginLeft: 16,
|
||||
},
|
||||
name: {
|
||||
color: '$white',
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
username: {
|
||||
color: '$white',
|
||||
fontSize: 12,
|
||||
marginTop: 4,
|
||||
},
|
||||
addIcon: {
|
||||
color: '$white',
|
||||
textAlign: 'center',
|
||||
},
|
||||
addButton: {
|
||||
backgroundColor: '$iconColor',
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 20 / 2,
|
||||
borderColor: '$white',
|
||||
borderWidth: 1,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 45,
|
||||
},
|
||||
});
|
61
src/components/avatarHeader/avatarHeaderView.js
Normal file
61
src/components/avatarHeader/avatarHeaderView.js
Normal file
@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
import { View, Text, SafeAreaView } from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
||||
import { UserAvatar } from '../userAvatar';
|
||||
import { IconButton } from '../iconButton';
|
||||
|
||||
// Styles
|
||||
import styles from './avatarHeaderStyles';
|
||||
|
||||
const AvatarHeader = ({
|
||||
username,
|
||||
name,
|
||||
reputation,
|
||||
navigation,
|
||||
avatarUrl,
|
||||
showImageUploadActions,
|
||||
}) => (
|
||||
<LinearGradient
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 0 }}
|
||||
colors={['#357ce6', '#2d5aa0']}
|
||||
style={styles.headerView}
|
||||
>
|
||||
<SafeAreaView>
|
||||
<View style={styles.headerContainer}>
|
||||
<IconButton
|
||||
iconStyle={styles.backIcon}
|
||||
iconType="MaterialIcons"
|
||||
name="arrow-back"
|
||||
onPress={navigation.goBack}
|
||||
size={25}
|
||||
/>
|
||||
<View style={styles.wrapper}>
|
||||
<UserAvatar
|
||||
key={avatarUrl || username}
|
||||
noAction
|
||||
size="xl"
|
||||
username={username}
|
||||
avatarUrl={avatarUrl}
|
||||
/>
|
||||
<IconButton
|
||||
iconStyle={styles.addIcon}
|
||||
style={styles.addButton}
|
||||
iconType="MaterialCommunityIcons"
|
||||
name="plus"
|
||||
onPress={showImageUploadActions}
|
||||
size={15}
|
||||
/>
|
||||
<View style={styles.textWrapper}>
|
||||
{!!name && <Text style={styles.name}>{name}</Text>}
|
||||
<Text style={styles.username}>{`@${username} (${reputation})`}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</LinearGradient>
|
||||
);
|
||||
|
||||
export default withNavigation(AvatarHeader);
|
3
src/components/avatarHeader/index.js
Normal file
3
src/components/avatarHeader/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import AvatarHeader from './avatarHeaderView';
|
||||
|
||||
export { AvatarHeader };
|
@ -67,6 +67,7 @@ class BasicHeaderView extends Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
disabled,
|
||||
dropdownComponent,
|
||||
handleOnPressBackButton,
|
||||
handleOnPressClose,
|
||||
@ -83,10 +84,10 @@ class BasicHeaderView extends Component {
|
||||
isLoading,
|
||||
isLoggedIn,
|
||||
isModalHeader,
|
||||
rightButtonText,
|
||||
isPreviewActive,
|
||||
isReply,
|
||||
quickTitle,
|
||||
rightButtonText,
|
||||
rightIconName,
|
||||
title,
|
||||
} = this.props;
|
||||
@ -99,8 +100,9 @@ class BasicHeaderView extends Component {
|
||||
<IconButton
|
||||
iconStyle={[styles.backIcon, isModalHeader && styles.closeIcon]}
|
||||
iconType="MaterialIcons"
|
||||
name={isModalHeader ? 'arrow-back' : 'arrow-back'}
|
||||
name="arrow-back"
|
||||
onPress={() => (isModalHeader ? handleOnPressClose() : handleOnPressBackButton())}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{isHasIcons && !isReply && (
|
||||
<View>
|
||||
@ -148,7 +150,6 @@ class BasicHeaderView extends Component {
|
||||
|
||||
{rightIconName && !isHasSearch && (
|
||||
<IconButton
|
||||
style={styles.rightIcon}
|
||||
size={25}
|
||||
onPress={() => handleRightIconPress()}
|
||||
iconStyle={styles.rightIcon}
|
||||
@ -171,7 +172,6 @@ class BasicHeaderView extends Component {
|
||||
|
||||
{isHasSearch && (
|
||||
<IconButton
|
||||
style={styles.rightIcon}
|
||||
size={22}
|
||||
onPress={() => this._handleSearchButtonPress()}
|
||||
iconStyle={styles.rightIcon}
|
||||
|
@ -9,9 +9,10 @@ export default EStyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
width: '$deviceWidth',
|
||||
height: 50,
|
||||
shadowOpacity: 0.2,
|
||||
shadowOpacity: 0.1,
|
||||
shadowOffset: {
|
||||
height: 1.5,
|
||||
width: 0,
|
||||
height: -3,
|
||||
},
|
||||
elevation: 3,
|
||||
},
|
||||
|
@ -1,9 +1,11 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { View, SafeAreaView } from 'react-native';
|
||||
import styles from './stickyBarStyles';
|
||||
|
||||
const StickyBar = ({ children, isFixedFooter }) => (
|
||||
<View style={[styles.container, isFixedFooter && styles.fixedFooter]}>{children}</View>
|
||||
<SafeAreaView>
|
||||
<View style={[styles.container, isFixedFooter && styles.fixedFooter]}>{children}</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
||||
export default StickyBar;
|
||||
|
@ -1,17 +1,15 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import React from 'react';
|
||||
import { Text, View, TouchableOpacity } from 'react-native';
|
||||
import styles from './tagStyles';
|
||||
|
||||
const Tag = ({ onPress, isPin, value, isPostCardTag }) => (
|
||||
<Fragment>
|
||||
<TouchableOpacity onPress={() => onPress && onPress(value)}>
|
||||
<View
|
||||
style={[styles.textWrapper, isPin && styles.isPin, isPostCardTag && styles.isPostCardTag]}
|
||||
>
|
||||
<Text style={[styles.text]}>{value}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</Fragment>
|
||||
<TouchableOpacity onPress={() => onPress && onPress(value)}>
|
||||
<View
|
||||
style={[styles.textWrapper, isPin && styles.isPin, isPostCardTag && styles.isPostCardTag]}
|
||||
>
|
||||
<Text style={[styles.text]}>{value}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
export default Tag;
|
||||
|
@ -18,19 +18,34 @@ const UserListItem = ({
|
||||
handleOnLongPress,
|
||||
isClickable,
|
||||
text,
|
||||
middleText,
|
||||
rightTextStyle,
|
||||
}) => (
|
||||
<TouchableOpacity
|
||||
onLongPress={() => handleOnLongPress && handleOnLongPress()}
|
||||
disabled={!isClickable}
|
||||
onPress={() => handleOnPress && handleOnPress()}
|
||||
>
|
||||
<View style={[styles.voteItemWrapper, index % 2 !== 0 && styles.voteItemWrapperGray]}>
|
||||
<View style={[styles.voteItemWrapper, index % 2 === 0 && styles.voteItemWrapperGray]}>
|
||||
{itemIndex && <Text style={styles.itemIndex}>{itemIndex}</Text>}
|
||||
<UserAvatar noAction={userCanPress} style={styles.avatar} username={username} />
|
||||
<View style={styles.userDescription}>
|
||||
<Text style={styles.name}>{text || username}</Text>
|
||||
{description && <Text style={styles.date}>{description}</Text>}
|
||||
</View>
|
||||
{middleText && (
|
||||
<View style={styles.middleWrapper}>
|
||||
<Text
|
||||
style={[
|
||||
styles.value,
|
||||
isRightColor && styles.valueGray,
|
||||
isBlackRightColor && styles.valueBlack,
|
||||
]}
|
||||
>
|
||||
{middleText}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{isHasRightItem && (
|
||||
<View style={styles.rightWrapper}>
|
||||
<Text
|
||||
@ -38,6 +53,7 @@ const UserListItem = ({
|
||||
styles.value,
|
||||
isRightColor && styles.valueGray,
|
||||
isBlackRightColor && styles.valueBlack,
|
||||
rightTextStyle,
|
||||
]}
|
||||
>
|
||||
{rightText}
|
||||
|
@ -47,6 +47,7 @@ export default EStyleSheet.create({
|
||||
rightWrapper: {
|
||||
textAlign: 'center',
|
||||
alignItems: 'center',
|
||||
width: 80,
|
||||
},
|
||||
text: {
|
||||
color: '$iconColor',
|
||||
@ -68,4 +69,7 @@ export default EStyleSheet.create({
|
||||
fontSize: 10,
|
||||
marginRight: 17,
|
||||
},
|
||||
middleWrapper: {
|
||||
marginRight: 30,
|
||||
},
|
||||
});
|
||||
|
@ -27,7 +27,6 @@ const WalletLineItem = ({
|
||||
isHasdropdown,
|
||||
dropdownOptions,
|
||||
onDropdownSelect,
|
||||
dropdownStyle,
|
||||
}) => (
|
||||
<GrayWrapper isGray={index && index % 2 !== 0}>
|
||||
<View style={[styles.container, fitContent && styles.fitContent, style]}>
|
||||
|
@ -1 +1,3 @@
|
||||
export { default } from './view/checkboxView';
|
||||
import CheckBox from './view/checkboxView';
|
||||
|
||||
export { CheckBox };
|
||||
|
@ -41,7 +41,7 @@ export default EStyleSheet.create({
|
||||
alignSelf: 'center',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
fontSize: 10,
|
||||
fontSize: 12,
|
||||
color: '$iconColor',
|
||||
},
|
||||
voteCountWrapper: {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { View, Text, TouchableWithoutFeedback } from 'react-native';
|
||||
import { View, TouchableWithoutFeedback } from 'react-native';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import get from 'lodash/get';
|
||||
|
||||
import { getTimeFromNow } from '../../../utils/time';
|
||||
// Constants
|
||||
@ -51,6 +52,7 @@ class CommentView extends PureComponent {
|
||||
handleOnLongPress,
|
||||
handleOnReplyPress,
|
||||
handleOnUserPress,
|
||||
handleOnVotersPress,
|
||||
isLoggedIn,
|
||||
isShowComments,
|
||||
isShowMoreButton,
|
||||
@ -84,15 +86,23 @@ class CommentView extends PureComponent {
|
||||
{isLoggedIn && (
|
||||
<Fragment>
|
||||
<Upvote isShowPayoutValue content={comment} />
|
||||
<IconButton
|
||||
size={18}
|
||||
iconStyle={styles.leftIcon}
|
||||
<TextWithIcon
|
||||
iconName="people"
|
||||
iconSize={20}
|
||||
wrapperStyle={styles.leftButton}
|
||||
iconType="MaterialIcons"
|
||||
name="people"
|
||||
isClickable
|
||||
onPress={() =>
|
||||
handleOnVotersPress &&
|
||||
voteCount > 0 &&
|
||||
handleOnVotersPress(get(comment, 'active_votes'))
|
||||
}
|
||||
text={voteCount}
|
||||
textMarginLeft={20}
|
||||
textStyle={styles.voteCountText}
|
||||
/>
|
||||
<Text style={styles.voteCountText}>{voteCount}</Text>
|
||||
<IconButton
|
||||
size={18}
|
||||
size={20}
|
||||
iconStyle={styles.leftIcon}
|
||||
style={styles.leftButton}
|
||||
name="reply"
|
||||
@ -102,7 +112,7 @@ class CommentView extends PureComponent {
|
||||
{currentAccountUsername === comment.author && (
|
||||
<Fragment>
|
||||
<IconButton
|
||||
size={18}
|
||||
size={20}
|
||||
iconStyle={styles.leftIcon}
|
||||
style={styles.leftButton}
|
||||
name="create"
|
||||
@ -112,7 +122,7 @@ class CommentView extends PureComponent {
|
||||
{!comment.children && !voteCount && (
|
||||
<Fragment>
|
||||
<IconButton
|
||||
size={18}
|
||||
size={20}
|
||||
iconStyle={styles.leftIcon}
|
||||
style={styles.leftButton}
|
||||
name="delete-forever"
|
||||
|
@ -51,9 +51,11 @@ class CommentsContainer extends Component {
|
||||
|
||||
// Component Functions
|
||||
|
||||
_shortComments = sortOrder => {
|
||||
_shortComments = (sortOrder, comments) => {
|
||||
const { comments: parent } = this.state;
|
||||
|
||||
const sortedComments = comments || parent;
|
||||
|
||||
const allPayout = c =>
|
||||
parseFloat(get(c, 'pending_payout_value').split(' ')[0]) +
|
||||
parseFloat(get(c, 'total_payout_value').split(' ')[0]) +
|
||||
@ -116,25 +118,39 @@ class CommentsContainer extends Component {
|
||||
},
|
||||
};
|
||||
|
||||
parent.sort(sortOrders[sortOrder]);
|
||||
sortedComments.sort(sortOrders[sortOrder]);
|
||||
|
||||
return parent;
|
||||
return sortedComments;
|
||||
};
|
||||
|
||||
_getComments = async () => {
|
||||
const {
|
||||
author,
|
||||
permlink,
|
||||
selectedFilter,
|
||||
currentAccount: { name },
|
||||
isOwnProfile,
|
||||
fetchPost,
|
||||
} = this.props;
|
||||
|
||||
await getComments(author, permlink, name)
|
||||
.then(comments => {
|
||||
this.setState({
|
||||
comments,
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
if (isOwnProfile) {
|
||||
fetchPost();
|
||||
} else {
|
||||
await getComments(author, permlink, name)
|
||||
.then(comments => {
|
||||
if (selectedFilter && selectedFilter !== 'TRENDING') {
|
||||
const sortComments = this._shortComments(selectedFilter, comments);
|
||||
this.setState({
|
||||
comments: sortComments,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
comments,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
_handleOnReplyPress = item => {
|
||||
@ -165,31 +181,43 @@ class CommentsContainer extends Component {
|
||||
};
|
||||
|
||||
_handleDeleteComment = permlink => {
|
||||
const { currentAccount, pinCode } = this.props;
|
||||
const { currentAccount, pinCode, comments } = this.props;
|
||||
const { comments: _comments } = this.state;
|
||||
let filteredComments;
|
||||
|
||||
deleteComment(currentAccount, pinCode, permlink).then(() => {
|
||||
this._getComments();
|
||||
if (_comments.length > 0) {
|
||||
filteredComments = _comments.filter(item => item.permlink !== permlink);
|
||||
} else {
|
||||
filteredComments = comments.filter(item => item.permlink !== permlink);
|
||||
}
|
||||
this.setState({ comments: filteredComments });
|
||||
});
|
||||
};
|
||||
|
||||
_handleCommentCopyAction = (index, selectedComment) => {
|
||||
const { dispatch, intl } = this.props;
|
||||
_handleOnPressCommentMenu = (index, selectedComment) => {
|
||||
const { dispatch, intl, navigation, isOwnProfile } = this.props;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
writeToClipboard(`https://steemit.com${get(selectedComment, 'url')}`).then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.copied',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if (index === 0) {
|
||||
writeToClipboard(`https://esteem.app${get(selectedComment, 'url')}`).then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
id: 'alert.copied',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
} else if (index === 1 && isOwnProfile) {
|
||||
navigation.navigate({
|
||||
routeName: ROUTES.SCREENS.POST,
|
||||
key: get(selectedComment, 'permlink'),
|
||||
params: {
|
||||
author: get(selectedComment, 'author'),
|
||||
permlink: get(selectedComment, 'permlink'),
|
||||
isHasParentPost: get(selectedComment, 'parent_permlink'),
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -207,6 +235,7 @@ class CommentsContainer extends Component {
|
||||
selectedFilter,
|
||||
mainAuthor,
|
||||
selectedPermlink: _selectedPermlink,
|
||||
isOwnProfile,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -219,15 +248,15 @@ class CommentsContainer extends Component {
|
||||
isShowMoreButton={isShowMoreButton}
|
||||
commentNumber={commentNumber || 1}
|
||||
commentCount={commentCount}
|
||||
comments={_comments || comments}
|
||||
comments={_comments.length > 0 ? _comments : comments}
|
||||
currentAccountUsername={currentAccount.name}
|
||||
handleOnEditPress={this._handleOnEditPress}
|
||||
handleOnReplyPress={this._handleOnReplyPress}
|
||||
isLoggedIn={isLoggedIn}
|
||||
fetchPost={fetchPost}
|
||||
handleDeleteComment={this._handleDeleteComment}
|
||||
handleCommentCopyAction={this._handleCommentCopyAction}
|
||||
{...this.props}
|
||||
handleOnPressCommentMenu={this._handleOnPressCommentMenu}
|
||||
isOwnProfile={isOwnProfile}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
text: {
|
||||
color: '$primaryBlack',
|
||||
fontSize: 10,
|
||||
list: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { FlatList } from 'react-native';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
import get from 'lodash/get';
|
||||
@ -9,9 +9,9 @@ import { injectIntl } from 'react-intl';
|
||||
import { Comment } from '../../comment';
|
||||
|
||||
// Styles
|
||||
// import styles from './commentStyles';
|
||||
import styles from './commentStyles';
|
||||
|
||||
class CommentsView extends PureComponent {
|
||||
class CommentsView extends Component {
|
||||
/* Props
|
||||
* ------------------------------------------------
|
||||
* @prop { type } name - Description....
|
||||
@ -52,14 +52,25 @@ class CommentsView extends PureComponent {
|
||||
isShowSubComments,
|
||||
marginLeft,
|
||||
handleDeleteComment,
|
||||
handleCommentCopyAction,
|
||||
handleOnPressCommentMenu,
|
||||
handleOnVotersPress,
|
||||
intl,
|
||||
isOwnProfile,
|
||||
} = this.props;
|
||||
const { selectedComment } = this.state;
|
||||
|
||||
const menuItems = isOwnProfile
|
||||
? [
|
||||
intl.formatMessage({ id: 'post.copy_link' }),
|
||||
intl.formatMessage({ id: 'post.open_thread' }),
|
||||
intl.formatMessage({ id: 'alert.cancel' }),
|
||||
]
|
||||
: [intl.formatMessage({ id: 'post.copy_link' }), intl.formatMessage({ id: 'alert.cancel' })];
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<FlatList
|
||||
style={styles.list}
|
||||
data={comments}
|
||||
keyExtractor={this._keyExtractor}
|
||||
renderItem={({ item }) => (
|
||||
@ -75,6 +86,7 @@ class CommentsView extends PureComponent {
|
||||
handleOnEditPress={handleOnEditPress}
|
||||
handleOnReplyPress={handleOnReplyPress}
|
||||
handleOnUserPress={handleOnUserPress}
|
||||
handleOnVotersPress={handleOnVotersPress}
|
||||
isLoggedIn={isLoggedIn}
|
||||
isShowMoreButton={commentNumber === 1 && get(item, 'children') > 0}
|
||||
voteCount={get(item, 'vote_count')}
|
||||
@ -87,17 +99,10 @@ class CommentsView extends PureComponent {
|
||||
/>
|
||||
<ActionSheet
|
||||
ref={this.commentMenu}
|
||||
options={[
|
||||
intl.formatMessage({
|
||||
id: 'post.copy_link',
|
||||
}),
|
||||
intl.formatMessage({
|
||||
id: 'alert.cancel',
|
||||
}),
|
||||
]}
|
||||
options={menuItems}
|
||||
title={get(selectedComment, 'summary')}
|
||||
cancelButtonIndex={1}
|
||||
onPress={index => handleCommentCopyAction(index, selectedComment)}
|
||||
cancelButtonIndex={isOwnProfile ? 2 : 1}
|
||||
onPress={index => handleOnPressCommentMenu(index, selectedComment)}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
|
@ -31,7 +31,15 @@ class CommentsDisplayView extends PureComponent {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { author, commentCount, fetchPost, intl, permlink, mainAuthor } = this.props;
|
||||
const {
|
||||
author,
|
||||
commentCount,
|
||||
fetchPost,
|
||||
intl,
|
||||
permlink,
|
||||
mainAuthor,
|
||||
handleOnVotersPress,
|
||||
} = this.props;
|
||||
const { selectedFilter } = this.state;
|
||||
|
||||
return (
|
||||
@ -56,6 +64,7 @@ class CommentsDisplayView extends PureComponent {
|
||||
author={author}
|
||||
permlink={permlink}
|
||||
mainAuthor={mainAuthor}
|
||||
handleOnVotersPress={handleOnVotersPress}
|
||||
/>
|
||||
</View>
|
||||
</Fragment>
|
||||
|
@ -40,7 +40,7 @@ class DateTimePickerView extends PureComponent {
|
||||
}
|
||||
|
||||
if (date && _value) {
|
||||
const formatedDateTime = new Date(`${date} ${_value}`).toISOString();
|
||||
const formatedDateTime = moment(`${date} ${_value}`, 'YYYY-MM-DD HH:mm').toISOString();
|
||||
onSubmit(formatedDateTime);
|
||||
this._initState();
|
||||
}
|
||||
@ -55,11 +55,11 @@ class DateTimePickerView extends PureComponent {
|
||||
|
||||
if (type === 'date-time') {
|
||||
_type = date ? 'time' : 'date';
|
||||
_format = date ? 'HH:MM' : 'YYYY-MM-DD';
|
||||
_format = date ? 'HH:mm' : 'YYYY-MM-DD';
|
||||
_minDate = date ? null : moment().format('YYYY-MM-DD');
|
||||
} else {
|
||||
_type = type;
|
||||
_format = type === 'date' ? 'YYYY-MM-DD' : 'HH:MM';
|
||||
_format = type === 'date' ? 'YYYY-MM-DD' : 'HH:mm';
|
||||
_minDate = type === 'date' ? moment().format('YYYY-MM-DD') : null;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ export default class TagAreaView extends Component {
|
||||
this.state = {
|
||||
currentText: '',
|
||||
chips: props.draftChips || [' '],
|
||||
chipsCount: props.chipsCount || 5,
|
||||
chipsCount: props.chipsCount || 7,
|
||||
activeChip: 0,
|
||||
};
|
||||
}
|
||||
@ -102,7 +102,7 @@ export default class TagAreaView extends Component {
|
||||
<ScrollView horizontal style={styles.tagWrapper}>
|
||||
{chips.map(
|
||||
(chip, i) =>
|
||||
i < 5 && (
|
||||
i < 7 && (
|
||||
<Chip
|
||||
key={i}
|
||||
refs={input => {
|
||||
|
@ -4,8 +4,7 @@ export default EStyleSheet.create({
|
||||
wrapper: {
|
||||
borderTopLeftRadius: 8,
|
||||
borderTopRightRadius: 8,
|
||||
marginHorizontal: 30,
|
||||
marginVertical: 10,
|
||||
marginTop: 16,
|
||||
flexDirection: 'row',
|
||||
backgroundColor: '$primaryGray',
|
||||
height: 60,
|
||||
@ -21,7 +20,6 @@ export default EStyleSheet.create({
|
||||
textInput: {
|
||||
flex: 0.7,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
icon: {
|
||||
flex: 0.15,
|
||||
|
@ -1,12 +1,14 @@
|
||||
import React, { Component } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import { Icon } from '../../icon';
|
||||
|
||||
// Constants
|
||||
|
||||
// Components
|
||||
import { TextInput } from '../../textInput';
|
||||
import { Icon } from '../../icon';
|
||||
|
||||
// Utils
|
||||
import { getResizedAvatar } from '../../../utils/image';
|
||||
|
||||
// Styles
|
||||
import styles from './formInputStyles';
|
||||
|
||||
@ -19,28 +21,18 @@ class FormInputView extends Component {
|
||||
* @prop { boolean } isEditable - Can permission edit.
|
||||
* @prop { boolean } isValid - This delegate input valit or not.
|
||||
* @prop { boolean } secureTextEntry - For hiding password value.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
value: '',
|
||||
inputBorderColor: '#c1c5c7',
|
||||
value: props.value || '',
|
||||
inputBorderColor: '#e7e7e7',
|
||||
isValid: true,
|
||||
formInputWidth: '99%',
|
||||
};
|
||||
}
|
||||
|
||||
// Component Life Cycles
|
||||
componentWillMount() {
|
||||
setTimeout(() => {
|
||||
this.setState({ formInputWidth: '100%' });
|
||||
}, 100);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { isValid } = this.props;
|
||||
|
||||
@ -54,18 +46,15 @@ class FormInputView extends Component {
|
||||
const { onChange } = this.props;
|
||||
|
||||
this.setState({ value });
|
||||
onChange && onChange(value);
|
||||
if (onChange) onChange(value);
|
||||
};
|
||||
|
||||
_handleOnFocus = () => {
|
||||
const { inputBorderColor } = this.state;
|
||||
if (inputBorderColor !== '#357ce6') {
|
||||
this.setState({ inputBorderColor: '#357ce6' });
|
||||
}
|
||||
this.setState({ inputBorderColor: '#357ce6' });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { inputBorderColor, isValid, value, formInputWidth } = this.state;
|
||||
const { inputBorderColor, isValid, value } = this.state;
|
||||
const {
|
||||
placeholder,
|
||||
type,
|
||||
@ -75,6 +64,9 @@ class FormInputView extends Component {
|
||||
rightIconName,
|
||||
secureTextEntry,
|
||||
iconType,
|
||||
wrapperStyle,
|
||||
height,
|
||||
inputStyle,
|
||||
} = this.props;
|
||||
return (
|
||||
<View
|
||||
@ -83,6 +75,7 @@ class FormInputView extends Component {
|
||||
{
|
||||
borderBottomColor: isValid ? inputBorderColor : 'red',
|
||||
},
|
||||
wrapperStyle,
|
||||
]}
|
||||
>
|
||||
{isFirstImage && value && value.length > 2 ? (
|
||||
@ -90,26 +83,30 @@ class FormInputView extends Component {
|
||||
<FastImage
|
||||
style={styles.firstImage}
|
||||
source={{
|
||||
uri: `https://steemitimages.com/u/${value}/avatar/small`,
|
||||
uri: getResizedAvatar(value),
|
||||
priority: FastImage.priority.high,
|
||||
}}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Icon iconType={iconType || 'MaterialIcons'} name={rightIconName} style={styles.icon} />
|
||||
rightIconName && (
|
||||
<Icon iconType={iconType || 'MaterialIcons'} name={rightIconName} style={styles.icon} />
|
||||
)
|
||||
)}
|
||||
<View style={styles.textInput}>
|
||||
<TextInput
|
||||
onFocus={() => this._handleOnFocus()}
|
||||
style={inputStyle}
|
||||
onFocus={() => this.setState({ inputBorderColor: '#357ce6' })}
|
||||
onBlur={() => this.setState({ inputBorderColor: '#e7e7e7' })}
|
||||
autoCapitalize="none"
|
||||
secureTextEntry={secureTextEntry}
|
||||
height={height}
|
||||
placeholder={placeholder}
|
||||
editable={isEditable || true}
|
||||
textContentType={type}
|
||||
onChangeText={val => this._handleOnChange(val)}
|
||||
onChangeText={this._handleOnChange}
|
||||
value={value}
|
||||
style={{ width: formInputWidth }}
|
||||
/>
|
||||
</View>
|
||||
|
||||
|
@ -1,12 +1,7 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
// Services and Actions
|
||||
|
||||
// Middleware
|
||||
|
||||
// Constants
|
||||
import { get, has } from 'lodash';
|
||||
|
||||
// Component
|
||||
import HeaderView from '../view/headerView';
|
||||
@ -30,7 +25,7 @@ class HeaderContainer extends PureComponent {
|
||||
_handleOpenDrawer = () => {
|
||||
const { navigation } = this.props;
|
||||
|
||||
if (navigation && navigation.openDrawer && typeof navigation.openDrawer === 'function') {
|
||||
if (has(navigation, 'openDrawer') && typeof get(navigation, 'openDrawer') === 'function') {
|
||||
navigation.openDrawer();
|
||||
}
|
||||
};
|
||||
@ -52,19 +47,11 @@ class HeaderContainer extends PureComponent {
|
||||
isLoginDone,
|
||||
isDarkTheme,
|
||||
} = this.props;
|
||||
let displayName;
|
||||
let username;
|
||||
let reputation;
|
||||
const _user = isReverse && selectedUser ? selectedUser : currentAccount;
|
||||
|
||||
if (isReverse && selectedUser) {
|
||||
displayName = selectedUser.display_name;
|
||||
username = selectedUser.name;
|
||||
reputation = selectedUser.reputation;
|
||||
} else if (!isReverse) {
|
||||
displayName = currentAccount.display_name;
|
||||
username = currentAccount.name;
|
||||
reputation = currentAccount.reputation;
|
||||
}
|
||||
const displayName = get(_user, 'display_name');
|
||||
const username = get(_user, 'name');
|
||||
const reputation = get(_user, 'reputation');
|
||||
|
||||
return (
|
||||
<HeaderView
|
||||
|
@ -34,19 +34,20 @@ class HeaderView extends Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
avatarUrl,
|
||||
displayName,
|
||||
handleOnPressBackButton,
|
||||
handleOpenDrawer,
|
||||
intl,
|
||||
isDarkTheme,
|
||||
isLoggedIn,
|
||||
isLoginDone,
|
||||
isReverse,
|
||||
reputation,
|
||||
username,
|
||||
isDarkTheme,
|
||||
} = this.props;
|
||||
const { isSearchModalOpen } = this.state;
|
||||
let gredientColor = isDarkTheme ? ['#081c36', '#43638e'] : ['#2d5aa0', '#357ce6'];
|
||||
let gredientColor;
|
||||
|
||||
if (isReverse) {
|
||||
gredientColor = isDarkTheme ? ['#43638e', '#081c36'] : ['#357ce6', '#2d5aa0'];
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { TouchableHighlight } from 'react-native';
|
||||
import { TouchableHighlight, ActivityIndicator } from 'react-native';
|
||||
import { Icon } from '../../icon';
|
||||
|
||||
import styles from './iconButtonStyles';
|
||||
@ -22,28 +22,33 @@ const IconButton = ({
|
||||
onPress,
|
||||
size,
|
||||
style,
|
||||
isLoading,
|
||||
}) => (
|
||||
<Fragment>
|
||||
<TouchableHighlight
|
||||
style={[styles.iconButton, style]}
|
||||
onPress={() => onPress && onPress()}
|
||||
onPress={() => !isLoading && onPress && onPress()}
|
||||
underlayColor={backgroundColor || 'white'}
|
||||
disabled={disabled}
|
||||
>
|
||||
<Icon
|
||||
style={[
|
||||
color && { color },
|
||||
backgroundColor && { backgroundColor },
|
||||
styles.icon,
|
||||
iconStyle && iconStyle,
|
||||
]}
|
||||
badgeTextStyle={badgeTextStyle}
|
||||
name={name}
|
||||
badgeStyle={badgeStyle}
|
||||
size={size}
|
||||
iconType={iconType}
|
||||
badgeCount={badgeCount}
|
||||
/>
|
||||
{!isLoading ? (
|
||||
<Icon
|
||||
style={[
|
||||
color && { color },
|
||||
backgroundColor && { backgroundColor },
|
||||
styles.icon,
|
||||
iconStyle && iconStyle,
|
||||
]}
|
||||
badgeTextStyle={badgeTextStyle}
|
||||
name={name}
|
||||
badgeStyle={badgeStyle}
|
||||
size={size}
|
||||
iconType={iconType}
|
||||
badgeCount={badgeCount}
|
||||
/>
|
||||
) : (
|
||||
<ActivityIndicator color="white" style={styles.activityIndicator} />
|
||||
)}
|
||||
</TouchableHighlight>
|
||||
</Fragment>
|
||||
);
|
||||
|
@ -1,31 +1,184 @@
|
||||
import { CircularButton, TextButton, IconButton } from './buttons';
|
||||
import { AvatarHeader } from './avatarHeader';
|
||||
import { BasicHeader } from './basicHeader';
|
||||
import { BottomTabBar } from './bottomTabBar';
|
||||
import { CheckBox } from './checkbox';
|
||||
import { CircularButton, TextButton, SquareButton } from './buttons';
|
||||
import { CollapsibleCard } from './collapsibleCard';
|
||||
import { ContainerHeader } from './containerHeader';
|
||||
import { DateTimePicker } from './dateTimePicker';
|
||||
import { DropdownButton } from './dropdownButton';
|
||||
import { FilterBar } from './filterBar';
|
||||
import { FormatedCurrency } from './formatedElements';
|
||||
import { FormInput } from './formInput';
|
||||
import { Header } from './header';
|
||||
import { Icon } from './icon';
|
||||
import { IconButton } from './iconButton';
|
||||
import { InformationArea } from './informationArea';
|
||||
import { InformationBox } from './informationBox';
|
||||
import { LoginHeader } from './loginHeader';
|
||||
import { MainButton } from './mainButton';
|
||||
import { MarkdownEditor } from './markdownEditor';
|
||||
import { Modal } from './modal';
|
||||
import { NotificationLine } from './notificationLine';
|
||||
import { NumericKeyboard } from './numericKeyboard';
|
||||
import { ParentPost } from './parentPost';
|
||||
import { PercentBar } from './percentBar';
|
||||
import { PinAnimatedInput } from './pinAnimatedInput';
|
||||
import { PostCard } from './postCard';
|
||||
import { PostDisplay } from './postView';
|
||||
import { PostDropdown } from './postDropdown';
|
||||
import { PostForm } from './postForm';
|
||||
import { PostHeaderDescription, PostBody, Tags } from './postElements';
|
||||
import { PostListItem } from './postListItem';
|
||||
import { ProfileSummary } from './profileSummary';
|
||||
import { PulseAnimation } from './animations';
|
||||
import { SearchInput } from './searchInput';
|
||||
import { SearchModal } from './searchModal';
|
||||
import { SettingsItem } from './settingsItem';
|
||||
import { SideMenu } from './sideMenu';
|
||||
import Icon from './icon';
|
||||
import Logo from './logo/logo';
|
||||
import Modal from './modal';
|
||||
import { SummaryArea, TagArea, TextArea, TitleArea } from './editorElements';
|
||||
import { TabBar } from './tabBar';
|
||||
import { TextInput } from './textInput';
|
||||
import ScaleSlider from './scaleSlider/scaleSliderView';
|
||||
import UserListItem from './basicUIElements/view/userListItem/userListItem';
|
||||
import { ToastNotification } from './toastNotification';
|
||||
import { ToggleSwitch } from './toggleSwitch';
|
||||
import { TransferFormItem } from './transferFormItem';
|
||||
import { Upvote } from './upvote';
|
||||
import { UserAvatar } from './userAvatar';
|
||||
import Logo from './logo/logo';
|
||||
import PostButton from './postButton/postButtonView';
|
||||
import SpinGame from './spinGame/view/spinGameView';
|
||||
import ProfileEditForm from './profileEditForm/profileEditFormView';
|
||||
import ScaleSlider from './scaleSlider/scaleSliderView';
|
||||
|
||||
// View
|
||||
import { Comment } from './comment';
|
||||
import { Comments } from './comments';
|
||||
import { CommentsDisplay } from './commentsDisplay';
|
||||
import { LeaderBoard } from './leaderboard';
|
||||
import { Notification } from './notification';
|
||||
import { Points } from './points';
|
||||
import { Posts } from './posts';
|
||||
import { Transaction } from './transaction';
|
||||
import { VotersDisplay } from './votersDisplay';
|
||||
import { Wallet } from './wallet';
|
||||
import { WalletDetails } from './walletDetails';
|
||||
import PostBoost from './postBoost/postBoostView';
|
||||
import Profile from './profile/profileView';
|
||||
import Promote from './promote/promoteView';
|
||||
|
||||
// Basic UI Elements
|
||||
import {
|
||||
BoostPlaceHolder,
|
||||
Card,
|
||||
Chip,
|
||||
GrayWrapper,
|
||||
LineBreak,
|
||||
ListItemPlaceHolder,
|
||||
ListPlaceHolder,
|
||||
NoInternetConnection,
|
||||
NoPost,
|
||||
PostCardPlaceHolder,
|
||||
PostPlaceHolder,
|
||||
ProfileSummaryPlaceHolder,
|
||||
StickyBar,
|
||||
Tag,
|
||||
TextWithIcon,
|
||||
UserListItem,
|
||||
WalletDetailsPlaceHolder,
|
||||
WalletLineItem,
|
||||
WalletUnclaimedPlaceHolder,
|
||||
} from './basicUIElements';
|
||||
|
||||
export {
|
||||
Card,
|
||||
Chip,
|
||||
GrayWrapper,
|
||||
LineBreak,
|
||||
ListItemPlaceHolder,
|
||||
ListPlaceHolder,
|
||||
BoostPlaceHolder,
|
||||
NoInternetConnection,
|
||||
NoPost,
|
||||
PostCardPlaceHolder,
|
||||
PostPlaceHolder,
|
||||
ProfileSummaryPlaceHolder,
|
||||
StickyBar,
|
||||
Tag,
|
||||
TextWithIcon,
|
||||
UserListItem,
|
||||
WalletDetailsPlaceHolder,
|
||||
WalletLineItem,
|
||||
WalletUnclaimedPlaceHolder,
|
||||
AvatarHeader,
|
||||
BasicHeader,
|
||||
InformationBox,
|
||||
BottomTabBar,
|
||||
CheckBox,
|
||||
CircularButton,
|
||||
CollapsibleCard,
|
||||
Comment,
|
||||
Comments,
|
||||
CommentsDisplay,
|
||||
ContainerHeader,
|
||||
DateTimePicker,
|
||||
DropdownButton,
|
||||
FilterBar,
|
||||
FormatedCurrency,
|
||||
FormInput,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
InformationArea,
|
||||
LeaderBoard,
|
||||
LoginHeader,
|
||||
Logo,
|
||||
SpinGame,
|
||||
MainButton,
|
||||
MarkdownEditor,
|
||||
Modal,
|
||||
Notification,
|
||||
NotificationLine,
|
||||
NumericKeyboard,
|
||||
ParentPost,
|
||||
PercentBar,
|
||||
PinAnimatedInput,
|
||||
Points,
|
||||
PostBody,
|
||||
PostBoost,
|
||||
PostButton,
|
||||
PostCard,
|
||||
PostDisplay,
|
||||
PostDropdown,
|
||||
PostForm,
|
||||
PostHeaderDescription,
|
||||
PostListItem,
|
||||
Posts,
|
||||
Profile,
|
||||
ProfileEditForm,
|
||||
ProfileSummary,
|
||||
Promote,
|
||||
PulseAnimation,
|
||||
ScaleSlider,
|
||||
SearchInput,
|
||||
SearchModal,
|
||||
SettingsItem,
|
||||
SideMenu,
|
||||
SquareButton,
|
||||
SummaryArea,
|
||||
TabBar,
|
||||
TagArea,
|
||||
Tags,
|
||||
TextArea,
|
||||
TextButton,
|
||||
TextInput,
|
||||
UserListItem,
|
||||
PostButton,
|
||||
TitleArea,
|
||||
ToastNotification,
|
||||
ToggleSwitch,
|
||||
Transaction,
|
||||
TransferFormItem,
|
||||
Upvote,
|
||||
UserAvatar,
|
||||
VotersDisplay,
|
||||
Wallet,
|
||||
WalletDetails,
|
||||
};
|
||||
|
@ -1 +1,3 @@
|
||||
export { default } from './view/informationBox';
|
||||
import InformationBox from './view/informationBoxView';
|
||||
|
||||
export { InformationBox };
|
||||
|
@ -48,7 +48,7 @@ class LeaderboardContainer extends PureComponent {
|
||||
});
|
||||
};
|
||||
|
||||
_fetchLeaderBoard = async () => {
|
||||
_fetchLeaderBoard = async selectedFilter => {
|
||||
const { intl, isConnected } = this.props;
|
||||
let users;
|
||||
|
||||
@ -57,7 +57,7 @@ class LeaderboardContainer extends PureComponent {
|
||||
this.setState({ refreshing: true });
|
||||
|
||||
try {
|
||||
users = await getLeaderboard();
|
||||
users = await getLeaderboard(selectedFilter);
|
||||
} catch (error) {
|
||||
Alert.alert(
|
||||
intl.formatMessage({ id: 'alert.error' }),
|
||||
|
@ -5,12 +5,29 @@ export default EStyleSheet.create({
|
||||
flex: 1,
|
||||
padding: 8,
|
||||
},
|
||||
text: {
|
||||
title: {
|
||||
color: '$primaryDarkGray',
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold',
|
||||
marginLeft: 20,
|
||||
fontFamily: '$primaryFont',
|
||||
paddingBottom: 10,
|
||||
flexGrow: 1,
|
||||
},
|
||||
rewardText: {
|
||||
color: '$primaryBlue',
|
||||
},
|
||||
columnTitleWrapper: {
|
||||
flexDirection: 'row',
|
||||
marginTop: 10,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
columnTitle: {
|
||||
color: '$primaryDarkGray',
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
marginRight: 40,
|
||||
marginBottom: 10,
|
||||
fontFamily: '$primaryFont',
|
||||
},
|
||||
});
|
||||
|
@ -1,11 +1,12 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { View, FlatList, Text } from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import get from 'lodash/get';
|
||||
|
||||
// Components
|
||||
import { UserListItem, ListPlaceHolder } from '../../basicUIElements';
|
||||
|
||||
import { FilterBar } from '../../filterBar';
|
||||
import FILTER_OPTIONS, { VALUE } from '../../../constants/options/leaderboard';
|
||||
// Styles
|
||||
import styles from './leaderboardStyles';
|
||||
|
||||
@ -28,9 +29,11 @@ class LeaderboardView extends PureComponent {
|
||||
isHasRightItem
|
||||
isClickable
|
||||
isBlackRightColor
|
||||
rightText={get(item, 'count')}
|
||||
rightText={get(item, 'points')}
|
||||
middleText={get(item, 'count')}
|
||||
itemIndex={index + 1}
|
||||
handleOnPress={() => handleOnUserPress(get(item, '_id'))}
|
||||
rightTextStyle={styles.rewardText}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -39,25 +42,37 @@ class LeaderboardView extends PureComponent {
|
||||
const { users, intl, fetchLeaderBoard, refreshing } = this.props;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.text}>
|
||||
{intl.formatMessage({
|
||||
id: 'notification.leaderboard_title',
|
||||
})}
|
||||
</Text>
|
||||
{!users ? (
|
||||
<ListPlaceHolder />
|
||||
) : (
|
||||
<Fragment>
|
||||
<FilterBar
|
||||
dropdownIconName="arrow-drop-down"
|
||||
options={VALUE.map(val => intl.formatMessage({ id: `leaderboard.${val}` }))}
|
||||
selectedOptionIndex={0}
|
||||
defaultText={intl.formatMessage({ id: `leaderboard.${VALUE[0]}` })}
|
||||
onDropdownSelect={selectedIndex => fetchLeaderBoard(FILTER_OPTIONS[selectedIndex])}
|
||||
/>
|
||||
|
||||
<View style={styles.container}>
|
||||
<View style={styles.columnTitleWrapper}>
|
||||
<Text style={styles.title}>
|
||||
{intl.formatMessage({
|
||||
id: 'notification.leaderboard_title',
|
||||
})}
|
||||
</Text>
|
||||
<Text style={[styles.columnTitle]}>Activities</Text>
|
||||
<Text style={[styles.columnTitle]}>Reward</Text>
|
||||
</View>
|
||||
|
||||
<FlatList
|
||||
data={users}
|
||||
refreshing={refreshing}
|
||||
keyExtractor={item => get(item, '_id', Math.random()).toString()}
|
||||
removeClippedSubviews={false}
|
||||
ListEmptyComponent={<ListPlaceHolder />}
|
||||
onRefresh={() => fetchLeaderBoard()}
|
||||
renderItem={({ item, index }) => this._renderItem(item, index)}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -63,9 +63,9 @@ export default class MarkdownEditorView extends Component {
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { text } = this.state;
|
||||
const { isFormValid, handleIsFormValid } = this.props;
|
||||
const { handleIsFormValid } = this.props;
|
||||
|
||||
if (prevState.text !== text && !isFormValid) {
|
||||
if (prevState.text !== text) {
|
||||
const nextText = text.replace(prevState.text, '');
|
||||
|
||||
if (nextText && nextText.length > 0) {
|
||||
@ -81,14 +81,6 @@ export default class MarkdownEditorView extends Component {
|
||||
// Component functions
|
||||
_changeText = input => {
|
||||
const { onChange, handleOnTextChange, handleIsValid, componentID } = this.props;
|
||||
const { textUpdated } = this.state;
|
||||
|
||||
if (textUpdated) {
|
||||
this.setState({
|
||||
textUpdated: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ text: input });
|
||||
|
||||
@ -199,7 +191,7 @@ export default class MarkdownEditorView extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { handleOpenImagePicker, intl, isPreviewActive, isReply } = this.props;
|
||||
const { handleOpenImagePicker, intl, isPreviewActive, isReply, isLoading } = this.props;
|
||||
const { text, selection } = this.state;
|
||||
|
||||
return (
|
||||
@ -223,6 +215,7 @@ export default class MarkdownEditorView extends Component {
|
||||
underlineColorAndroid="transparent"
|
||||
value={text}
|
||||
innerRef={this.inputRef}
|
||||
editable={!isLoading}
|
||||
/>
|
||||
) : (
|
||||
this._renderPreview()
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable react/jsx-wrap-multilines */
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { View, FlatList, ActivityIndicator, RefreshControl } from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
@ -7,7 +8,7 @@ import { injectIntl } from 'react-intl';
|
||||
// Components
|
||||
import { ContainerHeader } from '../../containerHeader';
|
||||
import { FilterBar } from '../../filterBar';
|
||||
import NotificationLine from '../../notificationLine';
|
||||
import { NotificationLine } from '../..';
|
||||
import { ListPlaceHolder } from '../../basicUIElements';
|
||||
|
||||
// Utils
|
||||
@ -168,38 +169,35 @@ class NotificationView extends PureComponent {
|
||||
rightIconType="MaterialIcons"
|
||||
onRightIconPress={readAllNotification}
|
||||
/>
|
||||
{_notifications.length === 0 ? (
|
||||
<ListPlaceHolder />
|
||||
) : (
|
||||
<FlatList
|
||||
data={_notifications}
|
||||
refreshing={isNotificationRefreshing}
|
||||
onRefresh={() => getActivities()}
|
||||
keyExtractor={item => item.title}
|
||||
onEndReached={() => getActivities(null, selectedFilter, true)}
|
||||
ListFooterComponent={this._renderFooterLoading}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={isNotificationRefreshing}
|
||||
progressBackgroundColor="#357CE6"
|
||||
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
|
||||
titleColor="#fff"
|
||||
colors={['#fff']}
|
||||
<FlatList
|
||||
data={_notifications}
|
||||
refreshing={isNotificationRefreshing}
|
||||
onRefresh={() => getActivities()}
|
||||
keyExtractor={item => item.title}
|
||||
onEndReached={() => getActivities(null, selectedFilter, true)}
|
||||
ListFooterComponent={this._renderFooterLoading}
|
||||
ListEmptyComponent={<ListPlaceHolder />}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={isNotificationRefreshing}
|
||||
progressBackgroundColor="#357CE6"
|
||||
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
|
||||
titleColor="#fff"
|
||||
colors={['#fff']}
|
||||
/>
|
||||
}
|
||||
renderItem={({ item, index }) => (
|
||||
<Fragment>
|
||||
<ContainerHeader
|
||||
hasSeperator={index !== 0}
|
||||
isBoldTitle
|
||||
title={item.title}
|
||||
key={item.title}
|
||||
/>
|
||||
}
|
||||
renderItem={({ item, index }) => (
|
||||
<Fragment>
|
||||
<ContainerHeader
|
||||
hasSeperator={index !== 0}
|
||||
isBoldTitle
|
||||
title={item.title}
|
||||
key={item.title}
|
||||
/>
|
||||
{this._renderList(item.notifications)}
|
||||
</Fragment>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{this._renderList(item.notifications)}
|
||||
</Fragment>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
import NotificationLineView from './view/notificationLineView';
|
||||
import NotificationLine from './view/notificationLineView';
|
||||
|
||||
export default NotificationLineView;
|
||||
export { NotificationLine };
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import times from 'lodash/times';
|
||||
import { CircularButton, IconButton } from '../../buttons';
|
||||
import { CircularButton } from '../../buttons';
|
||||
import { IconButton } from '../../iconButton';
|
||||
|
||||
import styles from './numericKeyboardStyles';
|
||||
|
||||
@ -26,11 +27,11 @@ const NumericKeyboard = ({ onPress }) => (
|
||||
onPress={value => onPress && onPress(value)}
|
||||
/>
|
||||
<IconButton
|
||||
handleOnPress={() => onPress && onPress('clear')}
|
||||
onPress={() => onPress && onPress('clear')}
|
||||
isCircle
|
||||
buttonStyle={styles.buttonWithoutBorder}
|
||||
style={styles.iconButton}
|
||||
name="backspace"
|
||||
name="ios-backspace"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable react/jsx-wrap-multilines */
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Text, View, FlatList, ScrollView, RefreshControl, TouchableOpacity } from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
@ -11,6 +12,7 @@ import { IconButton } from '../../iconButton';
|
||||
import { Icon } from '../../icon';
|
||||
import { MainButton } from '../../mainButton';
|
||||
import { DropdownButton } from '../../dropdownButton';
|
||||
import { CollapsibleCard } from '../../collapsibleCard';
|
||||
|
||||
// Utils
|
||||
import { getTimeFromNow } from '../../../utils/time';
|
||||
@ -140,6 +142,7 @@ class PointsView extends Component {
|
||||
<FlatList
|
||||
style={styles.iconsList}
|
||||
data={POINTS_KEYS}
|
||||
keyExtractor={item => get(item, 'type', Math.random()).toString()}
|
||||
horizontal
|
||||
renderItem={({ item }) => (
|
||||
<PopoverController key={get(item, 'type')}>
|
||||
@ -192,27 +195,45 @@ class PointsView extends Component {
|
||||
</View>
|
||||
|
||||
<View style={styles.listWrapper}>
|
||||
{!userActivities ? (
|
||||
this._renderLoading()
|
||||
) : (
|
||||
<FlatList
|
||||
data={userActivities}
|
||||
keyExtractor={item => item.id.toString()}
|
||||
renderItem={({ item, index }) => (
|
||||
<WalletLineItem
|
||||
index={index + 1}
|
||||
text={this._getTranslation(get(item, 'textKey'))}
|
||||
description={getTimeFromNow(get(item, 'created'))}
|
||||
isCircleIcon
|
||||
isThin
|
||||
isBlackText
|
||||
iconName={get(item, 'icon')}
|
||||
iconType={get(item, 'iconType')}
|
||||
rightText={`${get(item, 'amount')} ESTM`}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<FlatList
|
||||
data={userActivities}
|
||||
keyExtractor={item => item.id.toString()}
|
||||
ListEmptyComponent={this._renderLoading()}
|
||||
renderItem={({ item, index }) => (
|
||||
<CollapsibleCard
|
||||
noBorder
|
||||
noContainer
|
||||
key={item.id.toString()}
|
||||
titleComponent={
|
||||
<WalletLineItem
|
||||
index={index + 1}
|
||||
text={this._getTranslation(get(item, 'textKey'))}
|
||||
description={getTimeFromNow(get(item, 'created'))}
|
||||
isCircleIcon
|
||||
isThin
|
||||
isBlackText
|
||||
iconName={get(item, 'icon')}
|
||||
iconType={get(item, 'iconType')}
|
||||
rightText={`${get(item, 'amount')} ESTM`}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{(get(item, 'memo') || get(item, 'sender')) && (
|
||||
<WalletLineItem
|
||||
isBlackText
|
||||
isThin
|
||||
text={
|
||||
get(item, 'sender')
|
||||
? `${intl.formatMessage({ id: 'points.from' })} @${get(item, 'sender')}`
|
||||
: get(item, 'receiver') &&
|
||||
`${intl.formatMessage({ id: 'points.to' })} @${get(item, 'receiver')}`
|
||||
}
|
||||
description={get(item, 'memo')}
|
||||
/>
|
||||
)}
|
||||
</CollapsibleCard>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</Fragment>
|
||||
|
@ -37,7 +37,7 @@ export default EStyleSheet.create({
|
||||
color: '$primaryBlack',
|
||||
width: 172,
|
||||
},
|
||||
autocomplate: {
|
||||
autocomplete: {
|
||||
borderWidth: 0,
|
||||
borderColor: '$borderColor',
|
||||
borderRadius: 8,
|
||||
@ -46,33 +46,34 @@ export default EStyleSheet.create({
|
||||
width: 172,
|
||||
marginRight: 33,
|
||||
},
|
||||
autocomplateLineContainer: {
|
||||
autocompleteLineContainer: {
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 20,
|
||||
zIndex: 999,
|
||||
},
|
||||
autocomplateLabelText: {
|
||||
autocompleteLabelText: {
|
||||
color: '$primaryBlack',
|
||||
fontWeight: '600',
|
||||
},
|
||||
autocomplateListContainer: {
|
||||
autocompleteListContainer: {
|
||||
backgroundColor: '$primaryWhiteLightBackground',
|
||||
width: 172,
|
||||
zIndex: 999,
|
||||
},
|
||||
autocomplateItemText: {
|
||||
autocompleteItemText: {
|
||||
color: '$primaryBlack',
|
||||
padding: 3,
|
||||
},
|
||||
autocomplateList: {
|
||||
autocompleteList: {
|
||||
zIndex: 999,
|
||||
backgroundColor: '$primaryWhiteLightBackground',
|
||||
},
|
||||
autocomplateLabelContainer: {
|
||||
autocompleteLabelContainer: {
|
||||
flex: 1,
|
||||
padding: 10,
|
||||
justifyContent: 'center',
|
||||
color: '$primaryBlack',
|
||||
maxWidth: '$deviceWidth / 2.9',
|
||||
},
|
||||
textarea: {
|
||||
borderWidth: 1,
|
272
src/components/postBoost/postBoostView.js
Normal file
272
src/components/postBoost/postBoostView.js
Normal file
@ -0,0 +1,272 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import { Text, View, WebView, ScrollView, TouchableOpacity, Alert } from 'react-native';
|
||||
import get from 'lodash/get';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
import Autocomplete from 'react-native-autocomplete-input';
|
||||
import { Icon, TextInput } from '..';
|
||||
import { steemConnectOptions } from '../../constants/steemConnectOptions';
|
||||
|
||||
// Services and Actions
|
||||
import { getUser } from '../../providers/esteem/ePoint';
|
||||
import { searchPath } from '../../providers/esteem/esteem';
|
||||
|
||||
// Components
|
||||
import { BasicHeader } from '../basicHeader';
|
||||
import { TransferFormItem } from '../transferFormItem';
|
||||
import { MainButton } from '../mainButton';
|
||||
import { DropdownButton } from '../dropdownButton';
|
||||
import { Modal } from '../modal';
|
||||
|
||||
// Styles
|
||||
import styles from './postBoostStyles';
|
||||
|
||||
class BoostPostScreen extends PureComponent {
|
||||
/* Props
|
||||
* ------------------------------------------------
|
||||
* @prop { type } name - Description....
|
||||
*/
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
permlink: '',
|
||||
selectedUser: '',
|
||||
balance: '',
|
||||
factor: 0,
|
||||
permlinkSuggestions: [],
|
||||
isValid: false,
|
||||
};
|
||||
|
||||
this.startActionSheet = React.createRef();
|
||||
}
|
||||
|
||||
// Component Life Cycles
|
||||
|
||||
// Component Functions
|
||||
|
||||
_handleOnPermlinkChange = async text => {
|
||||
this.setState({ permlink: text, isValid: false });
|
||||
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
|
||||
if (text.trim().length < 3) {
|
||||
this.setState({ permlinkSuggestions: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
if (text && text.length > 0) {
|
||||
this.timer = setTimeout(
|
||||
() =>
|
||||
searchPath(text).then(res => {
|
||||
this.setState({ permlinkSuggestions: res && res.length > 10 ? res.slice(0, 7) : res });
|
||||
}),
|
||||
500,
|
||||
);
|
||||
} else {
|
||||
await this.setState({ permlinkSuggestions: [], isValid: false });
|
||||
}
|
||||
};
|
||||
|
||||
_renderDescription = text => <Text style={styles.description}>{text}</Text>;
|
||||
|
||||
_renderDropdown = (accounts, currentAccountName) => (
|
||||
<DropdownButton
|
||||
dropdownButtonStyle={styles.dropdownButtonStyle}
|
||||
rowTextStyle={styles.rowTextStyle}
|
||||
style={styles.dropdown}
|
||||
dropdownStyle={styles.dropdownStyle}
|
||||
textStyle={styles.dropdownText}
|
||||
options={accounts.map(item => item.username)}
|
||||
defaultText={currentAccountName}
|
||||
selectedOptionIndex={accounts.findIndex(item => item.username === currentAccountName)}
|
||||
onSelect={(index, value) => {
|
||||
this.setState({ selectedUser: value }, () => {
|
||||
this._getUserBalance(value);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
_getUserBalance = async username => {
|
||||
await getUser(username)
|
||||
.then(userPoints => {
|
||||
const balance = Math.round(get(userPoints, 'points') * 1000) / 1000;
|
||||
this.setState({ balance });
|
||||
})
|
||||
.catch(err => {
|
||||
Alert.alert(err.message || err.toString());
|
||||
});
|
||||
};
|
||||
|
||||
_handleOnSubmit = async () => {
|
||||
const { handleOnSubmit, redeemType, navigationParams } = this.props;
|
||||
const { permlink, selectedUser, factor } = this.state;
|
||||
const fullPermlink = permlink || get(navigationParams, 'permlink');
|
||||
|
||||
const amount = 150 + 50 * factor;
|
||||
|
||||
handleOnSubmit(redeemType, amount, fullPermlink, selectedUser);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { intl } = this.props;
|
||||
const { selectedUser, balance, factor, permlinkSuggestions, permlink, isValid } = this.state;
|
||||
|
||||
const {
|
||||
isLoading,
|
||||
accounts,
|
||||
currentAccountName,
|
||||
balance: _balance,
|
||||
navigationParams,
|
||||
SCPath,
|
||||
isSCModalOpen,
|
||||
handleOnSCModalClose,
|
||||
getESTMPrice,
|
||||
} = this.props;
|
||||
|
||||
const calculatedESTM = 150 + 50 * factor;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<BasicHeader title={intl.formatMessage({ id: 'boostPost.title' })} />
|
||||
<View style={styles.container}>
|
||||
<ScrollView>
|
||||
<View style={styles.middleContent}>
|
||||
<TransferFormItem
|
||||
label={intl.formatMessage({ id: 'promote.user' })}
|
||||
rightComponent={() =>
|
||||
this._renderDropdown(accounts, selectedUser || currentAccountName)
|
||||
}
|
||||
/>
|
||||
<Text style={styles.balanceText}>{`${balance || _balance} ESTM`}</Text>
|
||||
<View style={styles.autocompleteLineContainer}>
|
||||
<View style={styles.autocompleteLabelContainer}>
|
||||
{
|
||||
<Text style={styles.autocompleteLabelText}>
|
||||
{intl.formatMessage({ id: 'promote.permlink' })}
|
||||
</Text>
|
||||
}
|
||||
</View>
|
||||
|
||||
<Autocomplete
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
inputContainerStyle={styles.autocomplete}
|
||||
data={permlinkSuggestions}
|
||||
listContainerStyle={styles.autocompleteListContainer}
|
||||
listStyle={styles.autocompleteList}
|
||||
onChangeText={this._handleOnPermlinkChange}
|
||||
renderTextInput={() => (
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
onChangeText={text => this._handleOnPermlinkChange(text)}
|
||||
value={permlink || get(navigationParams, 'permlink', '')}
|
||||
placeholder={intl.formatMessage({ id: 'promote.permlinkPlaceholder' })}
|
||||
placeholderTextColor="#c1c5c7"
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
)}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity
|
||||
key={item}
|
||||
onPress={() =>
|
||||
this.setState({
|
||||
permlink: item,
|
||||
isValid: true,
|
||||
permlinkSuggestions: [],
|
||||
})
|
||||
}
|
||||
>
|
||||
<Text style={styles.autocompleteItemText}>{item}</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.total}>
|
||||
<Text style={styles.price}>
|
||||
{` $${getESTMPrice(calculatedESTM).toFixed(3)} ~ `}
|
||||
</Text>
|
||||
<Text style={styles.esteem}>{`${calculatedESTM} ESTM`}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.quickButtonsWrapper}>
|
||||
<MainButton
|
||||
style={styles.quickButtons}
|
||||
isDisable={!(calculatedESTM > 150)}
|
||||
onPress={() =>
|
||||
this.setState({
|
||||
factor: calculatedESTM > 150 ? factor - 1 : factor,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
size={24}
|
||||
style={{ color: 'white' }}
|
||||
iconType="MaterialCommunityIcons"
|
||||
name="minus"
|
||||
/>
|
||||
</MainButton>
|
||||
|
||||
<MainButton
|
||||
style={styles.quickButtons}
|
||||
isDisable={!((balance || _balance) / 50 > factor + 4)}
|
||||
onPress={() =>
|
||||
this.setState({
|
||||
factor: (balance || _balance) / 50 > factor + 4 ? factor + 1 : factor,
|
||||
})
|
||||
}
|
||||
>
|
||||
<Icon size={24} style={{ color: 'white' }} iconType="MaterialIcons" name="add" />
|
||||
</MainButton>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.bottomContent}>
|
||||
<MainButton
|
||||
style={styles.button}
|
||||
isDisable={
|
||||
(!permlink ? !get(navigationParams, 'permlink') : permlink) &&
|
||||
(balance || _balance) > 150 &&
|
||||
(isLoading || !isValid)
|
||||
}
|
||||
onPress={() => this.startActionSheet.current.show()}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
<Text style={styles.buttonText}>{intl.formatMessage({ id: 'transfer.next' })}</Text>
|
||||
</MainButton>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
<ActionSheet
|
||||
ref={this.startActionSheet}
|
||||
options={[
|
||||
intl.formatMessage({ id: 'alert.confirm' }),
|
||||
intl.formatMessage({ id: 'alert.cancel' }),
|
||||
]}
|
||||
title={intl.formatMessage({ id: 'promote.information' })}
|
||||
cancelButtonIndex={1}
|
||||
destructiveButtonIndex={0}
|
||||
onPress={index => {
|
||||
if (index === 0) if (index === 0) this._handleOnSubmit();
|
||||
}}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
isOpen={isSCModalOpen}
|
||||
isFullScreen
|
||||
isCloseButton
|
||||
handleOnModalClose={handleOnSCModalClose}
|
||||
title={intl.formatMessage({ id: 'transfer.steemconnect_title' })}
|
||||
>
|
||||
<WebView source={{ uri: `${steemConnectOptions.base_url}${SCPath}` }} />
|
||||
</Modal>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(BoostPostScreen);
|
@ -1,8 +1,9 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
import { connect } from 'react-redux';
|
||||
import get from 'lodash/get';
|
||||
|
||||
// Dsteem
|
||||
// Services
|
||||
import { getPost } from '../../../providers/steem/dsteem';
|
||||
|
||||
import PostCardView from '../view/postCardView';
|
||||
@ -24,21 +25,21 @@ class PostCardContainer extends PureComponent {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.isRefresh) {
|
||||
if (get(nextProps, 'isRefresh')) {
|
||||
this._fetchPost();
|
||||
}
|
||||
}
|
||||
|
||||
_handleOnUserPress = () => {
|
||||
const { navigation, currentAccount, content } = this.props;
|
||||
if (content && currentAccount.name !== content.author) {
|
||||
if (content && get(currentAccount, 'name') !== get(content, 'author')) {
|
||||
navigation.navigate({
|
||||
routeName: ROUTES.SCREENS.PROFILE,
|
||||
params: {
|
||||
username: content.author,
|
||||
reputation: content.author_reputation,
|
||||
username: get(content, 'author'),
|
||||
reputation: get(content, 'author_reputation'),
|
||||
},
|
||||
key: content.author,
|
||||
key: get(content, 'author'),
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -52,7 +53,7 @@ class PostCardContainer extends PureComponent {
|
||||
params: {
|
||||
content,
|
||||
},
|
||||
key: content.permlink,
|
||||
key: get(content, 'permlink'),
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -65,14 +66,26 @@ class PostCardContainer extends PureComponent {
|
||||
params: {
|
||||
activeVotes,
|
||||
},
|
||||
key: content.permlink,
|
||||
key: get(content, 'permlink'),
|
||||
});
|
||||
};
|
||||
|
||||
_handleOnReblogsPress = reblogs => {
|
||||
const { navigation, content } = this.props;
|
||||
|
||||
navigation.navigate({
|
||||
routeName: ROUTES.SCREENS.REBLOGS,
|
||||
params: {
|
||||
reblogs,
|
||||
},
|
||||
key: get(content, 'permlink', get(content, 'author', '')),
|
||||
});
|
||||
};
|
||||
|
||||
_fetchPost = async () => {
|
||||
const { currentAccount, content } = this.props;
|
||||
|
||||
await getPost(content.author, content.permlink, currentAccount.username)
|
||||
await getPost(get(content, 'author'), get(content, 'permlink'), get(currentAccount, 'username'))
|
||||
.then(result => {
|
||||
if (result) {
|
||||
this.setState({ _content: result });
|
||||
@ -82,7 +95,7 @@ class PostCardContainer extends PureComponent {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { content, isHideImage, nsfw, isHideReblogOption } = this.props;
|
||||
const { content, isHideImage, nsfw } = this.props;
|
||||
const { _content } = this.state;
|
||||
|
||||
const isNsfwPost = nsfw === '1';
|
||||
@ -92,11 +105,11 @@ class PostCardContainer extends PureComponent {
|
||||
handleOnUserPress={this._handleOnUserPress}
|
||||
handleOnContentPress={this._handleOnContentPress}
|
||||
handleOnVotersPress={this._handleOnVotersPress}
|
||||
handleOnReblogsPress={this._handleOnReblogsPress}
|
||||
fetchPost={this._fetchPost}
|
||||
content={_content || content}
|
||||
isHideImage={isHideImage}
|
||||
isNsfwPost={isNsfwPost}
|
||||
isHideReblogOption={isHideReblogOption}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -15,12 +15,7 @@ export default EStyleSheet.create({
|
||||
padding: 0,
|
||||
margin: 0,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
comment: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 10,
|
||||
marginLeft: 3,
|
||||
color: '$iconColor',
|
||||
alignSelf: 'flex-end',
|
||||
},
|
||||
commentIcon: {
|
||||
alignSelf: 'flex-start',
|
||||
@ -28,6 +23,7 @@ export default EStyleSheet.create({
|
||||
color: '$iconColor',
|
||||
margin: 0,
|
||||
width: 20,
|
||||
marginLeft: 25,
|
||||
},
|
||||
postBodyWrapper: {
|
||||
marginHorizontal: 9,
|
||||
@ -60,7 +56,6 @@ export default EStyleSheet.create({
|
||||
backgroundColor: '$primaryBackgroundColor',
|
||||
flexDirection: 'row',
|
||||
margin: 16,
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
bodyHeader: {
|
||||
backgroundColor: '$primaryBackgroundColor',
|
||||
@ -70,7 +65,14 @@ export default EStyleSheet.create({
|
||||
marginBottom: 12,
|
||||
},
|
||||
leftFooterWrapper: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
rightFooterWrapper: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
dropdownWrapper: {
|
||||
position: 'absolute',
|
||||
|
@ -10,7 +10,6 @@ import { getTimeFromNow } from '../../../utils/time';
|
||||
// Components
|
||||
import { PostHeaderDescription } from '../../postElements';
|
||||
import { PostDropdown } from '../../postDropdown';
|
||||
import { Icon } from '../../icon';
|
||||
import { TextWithIcon } from '../../basicUIElements';
|
||||
|
||||
// STEEM
|
||||
@ -67,7 +66,15 @@ class PostCardView extends Component {
|
||||
_handleOnVotersPress = () => {
|
||||
const { handleOnVotersPress, content } = this.props;
|
||||
|
||||
handleOnVotersPress(content.active_votes);
|
||||
handleOnVotersPress(get(content, 'active_votes'));
|
||||
};
|
||||
|
||||
_handleOnReblogsPress = () => {
|
||||
const { handleOnReblogsPress, content } = this.props;
|
||||
|
||||
if (content.reblogs.length > 0) {
|
||||
handleOnReblogsPress(get(content, 'reblogs'));
|
||||
}
|
||||
};
|
||||
|
||||
_getPostImage = (content, isNsfwPost) => {
|
||||
@ -81,7 +88,7 @@ class PostCardView extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { content, isHideImage, fetchPost, isNsfwPost, isHideReblogOption, intl } = this.props;
|
||||
const { content, isHideImage, fetchPost, isNsfwPost, intl } = this.props;
|
||||
const { rebloggedBy } = this.state;
|
||||
const _image = this._getPostImage(content, isNsfwPost);
|
||||
|
||||
@ -101,11 +108,7 @@ class PostCardView extends Component {
|
||||
isPromoted={get(content, 'is_promoted')}
|
||||
/>
|
||||
<View style={styles.dropdownWrapper}>
|
||||
<PostDropdown
|
||||
isHideReblogOption={isHideReblogOption}
|
||||
content={content}
|
||||
fetchPost={fetchPost}
|
||||
/>
|
||||
<PostDropdown content={content} fetchPost={fetchPost} />
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.postBodyWrapper}>
|
||||
@ -134,17 +137,32 @@ class PostCardView extends Component {
|
||||
<View style={styles.leftFooterWrapper}>
|
||||
<Upvote fetchPost={fetchPost} isShowPayoutValue content={content} />
|
||||
<TouchableOpacity style={styles.commentButton} onPress={this._handleOnVotersPress}>
|
||||
<Icon
|
||||
style={[styles.commentIcon, { marginLeft: 25 }]}
|
||||
<TextWithIcon
|
||||
iconName="people"
|
||||
iconStyle={styles.commentIcon}
|
||||
iconType="MaterialIcons"
|
||||
name="people"
|
||||
isClickable
|
||||
text={get(content, 'vote_count', 0)}
|
||||
onPress={this._handleOnVotersPress}
|
||||
/>
|
||||
<Text style={styles.comment}>{get(content, 'vote_count', 0)}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.commentButton}>
|
||||
<Icon style={[styles.commentIcon]} iconType="MaterialIcons" name="comment" />
|
||||
<Text style={styles.comment}>{get(content, 'children')}</Text>
|
||||
<View style={styles.rightFooterWrapper}>
|
||||
<TextWithIcon
|
||||
iconName="repeat"
|
||||
iconStyle={styles.commentIcon}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
text={get(content, 'reblogCount', 0)}
|
||||
onPress={this._handleOnReblogsPress}
|
||||
/>
|
||||
<TextWithIcon
|
||||
iconName="comment"
|
||||
iconStyle={styles.commentIcon}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
text={get(content, 'children', 0)}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -95,11 +95,11 @@ class PostDropdownContainer extends PureComponent {
|
||||
break;
|
||||
|
||||
case 'PROMOTE':
|
||||
this._redirectToPromote(ROUTES.SCREENS.PROMOTE, 1);
|
||||
this._redirectToPromote(ROUTES.SCREENS.REDEEM, 1, 'promote');
|
||||
break;
|
||||
|
||||
case 'BOOST':
|
||||
this._redirectToPromote(ROUTES.SCREENS.BOOST_POST, 2);
|
||||
this._redirectToPromote(ROUTES.SCREENS.REDEEM, 2, 'boost');
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -112,14 +112,14 @@ class PostDropdownContainer extends PureComponent {
|
||||
const postUrl = getPostUrl(get(content, 'url'));
|
||||
|
||||
Share.share({
|
||||
message: `${content.title} ${postUrl}`,
|
||||
message: `${get(content, 'title')} ${postUrl}`,
|
||||
});
|
||||
};
|
||||
|
||||
_addToBookmarks = () => {
|
||||
const { content, currentAccount, dispatch, intl } = this.props;
|
||||
|
||||
addBookmark(currentAccount.name, content.author, content.permlink)
|
||||
addBookmark(get(currentAccount, 'name'), get(content, 'author'), get(content, 'permlink'))
|
||||
.then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
@ -143,7 +143,7 @@ class PostDropdownContainer extends PureComponent {
|
||||
_reblog = () => {
|
||||
const { content, currentAccount, dispatch, intl, isLoggedIn, pinCode } = this.props;
|
||||
if (isLoggedIn) {
|
||||
reblog(currentAccount, pinCode, content.author, content.permlink)
|
||||
reblog(currentAccount, pinCode, content.author, get(content, 'permlink', ''))
|
||||
.then(() => {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
@ -154,7 +154,7 @@ class PostDropdownContainer extends PureComponent {
|
||||
);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.jse_shortmsg && String(error.jse_shortmsg).indexOf('has already reblogged')) {
|
||||
if (String(get(error, 'jse_shortmsg', '')).indexOf('has already reblogged')) {
|
||||
dispatch(
|
||||
toastNotification(
|
||||
intl.formatMessage({
|
||||
@ -184,11 +184,12 @@ class PostDropdownContainer extends PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
_redirectToPromote = (routeName, from) => {
|
||||
_redirectToPromote = (routeName, from, redeemType) => {
|
||||
const { content, isLoggedIn, navigation, dispatch, isPinCodeOpen } = this.props;
|
||||
const params = {
|
||||
from,
|
||||
permlink: `${get(content, 'author')}/${get(content, 'permlink')}`,
|
||||
redeemType,
|
||||
};
|
||||
|
||||
if (isPinCodeOpen) {
|
||||
@ -207,10 +208,14 @@ class PostDropdownContainer extends PureComponent {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { intl, currentAccount, content, isHideReblogOption } = this.props;
|
||||
const {
|
||||
intl,
|
||||
currentAccount: { name },
|
||||
content,
|
||||
} = this.props;
|
||||
let _OPTIONS = OPTIONS;
|
||||
|
||||
if ((content && content.author === currentAccount.name) || isHideReblogOption) {
|
||||
if ((content && content.author === name) || get(content, 'reblogged_by[0]', null) === name) {
|
||||
_OPTIONS = OPTIONS.filter(item => item !== 'reblog');
|
||||
}
|
||||
|
||||
|
@ -65,14 +65,7 @@ export default EStyleSheet.create({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
postImage: {
|
||||
marginTop: 10,
|
||||
minHeight: 216,
|
||||
width: '100%',
|
||||
},
|
||||
commentImage: {
|
||||
marginTop: 10,
|
||||
minHeight: 80,
|
||||
width: '100%',
|
||||
img: {
|
||||
alignSelf: 'center',
|
||||
},
|
||||
});
|
||||
|
@ -2,8 +2,6 @@ import React, { PureComponent, Fragment } from 'react';
|
||||
import { Dimensions, Linking, Alert, TouchableOpacity, Text } from 'react-native';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import { proxifyImageSrc } from '@esteemapp/esteem-render-helpers';
|
||||
|
||||
import HTML from 'react-native-render-html';
|
||||
import { getParentsTagsRecursively } from 'react-native-render-html/src/HTMLUtils';
|
||||
@ -13,7 +11,6 @@ import styles from './postBodyStyles';
|
||||
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../../constants/routeNames';
|
||||
import DEFAULT_IMAGE from '../../../../assets/no_image.png';
|
||||
// Components
|
||||
|
||||
const WIDTH = Dimensions.get('window').width;
|
||||
@ -153,18 +150,6 @@ class PostBody extends PureComponent {
|
||||
: { width: WIDTH, height: 216 };
|
||||
|
||||
const _customRenderer = {
|
||||
img: (htmlAttribs, children, convertedCSSStyles, passProps) => (
|
||||
<FastImage
|
||||
key={passProps.key}
|
||||
defaultSource={DEFAULT_IMAGE}
|
||||
source={{
|
||||
uri: proxifyImageSrc(htmlAttribs.src, _initialDimensions.width, 0),
|
||||
priority: FastImage.priority.normal,
|
||||
}}
|
||||
style={isComment ? styles.commentImage : styles.postImage}
|
||||
resizeMode={FastImage.resizeMode.contain}
|
||||
/>
|
||||
),
|
||||
a: (htmlAttribs, children, convertedCSSStyles, passProps) => {
|
||||
if (passProps.parentWrapper === 'Text') {
|
||||
return (
|
||||
@ -187,6 +172,9 @@ class PostBody extends PureComponent {
|
||||
</TouchableOpacity>
|
||||
);
|
||||
},
|
||||
br: (htmlAttribs, children, passProps) => {
|
||||
return <Text {...passProps}>{'\n'}</Text>;
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -74,7 +74,7 @@ class PostHeaderDescription extends PureComponent {
|
||||
</TouchableOpacity>
|
||||
{!!tag && (
|
||||
<TouchableOpacity onPress={() => tagOnPress && tagOnPress()}>
|
||||
<Tag isPostCardTag isPin value={tag} />
|
||||
<Tag isPostCardTag={!isPromoted} isPin value={tag} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<Text style={styles.date}>
|
||||
|
@ -3,5 +3,11 @@ import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
export default EStyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
marginLeft: -20,
|
||||
marginRight: -20,
|
||||
height: 30,
|
||||
},
|
||||
firstTag: {
|
||||
marginLeft: 10,
|
||||
},
|
||||
});
|
||||
|
@ -27,7 +27,9 @@ class TagsView extends PureComponent {
|
||||
data={tags}
|
||||
horizontal
|
||||
renderItem={({ item, index }) => (
|
||||
<Tag key={index} value={item} isPin={index === 0} onPress={handleOnTagPress} />
|
||||
<View style={index === 0 && styles.firstTag}>
|
||||
<Tag key={index} value={item} isPin={index === 0} onPress={handleOnTagPress} />
|
||||
</View>
|
||||
)}
|
||||
keyExtractor={item => item}
|
||||
/>
|
||||
|
@ -47,10 +47,24 @@ class PostDisplayContainer extends Component {
|
||||
activeVotes,
|
||||
},
|
||||
// TODO: make unic
|
||||
key: post.permlink + Math.random(),
|
||||
key: post.permlink + activeVotes.length,
|
||||
});
|
||||
};
|
||||
|
||||
_handleOnReblogsPress = reblogs => {
|
||||
const { navigation, post } = this.props;
|
||||
|
||||
if (reblogs.length > 0) {
|
||||
navigation.navigate({
|
||||
routeName: ROUTES.SCREENS.REBLOGS,
|
||||
params: {
|
||||
reblogs,
|
||||
},
|
||||
key: post.permlink + reblogs.length,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
_handleOnReplyPress = () => {
|
||||
const { post, navigation } = this.props;
|
||||
|
||||
@ -123,6 +137,7 @@ class PostDisplayContainer extends Component {
|
||||
handleOnRemovePress={this._handleDeleteComment}
|
||||
handleOnReplyPress={this._handleOnReplyPress}
|
||||
handleOnVotersPress={this._handleOnVotersPress}
|
||||
handleOnReblogsPress={this._handleOnReblogsPress}
|
||||
isLoggedIn={isLoggedIn}
|
||||
isNewPost={isNewPost}
|
||||
isPostUnavailable={isPostUnavailable}
|
||||
|
@ -62,7 +62,7 @@ export default EStyleSheet.create({
|
||||
opacity: 0.7,
|
||||
},
|
||||
barIconButton: {
|
||||
marginLeft: 16,
|
||||
marginLeft: 0,
|
||||
},
|
||||
stickyRightWrapper: {
|
||||
flexGrow: 1,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { View, Text, ScrollView, Dimensions } from 'react-native';
|
||||
import { View, Text, ScrollView, Dimensions, SafeAreaView } from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import get from 'lodash/get';
|
||||
import ActionSheet from 'react-native-actionsheet';
|
||||
@ -71,64 +71,76 @@ class PostDisplayView extends PureComponent {
|
||||
handleOnEditPress,
|
||||
handleOnReplyPress,
|
||||
handleOnVotersPress,
|
||||
handleOnReblogsPress,
|
||||
isLoggedIn,
|
||||
post,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<StickyBar isFixedFooter={isFixedFooter}>
|
||||
<View style={styles.stickyWrapper}>
|
||||
<Upvote fetchPost={fetchPost} isShowPayoutValue content={post} />
|
||||
<TextWithIcon
|
||||
iconName="people"
|
||||
iconStyle={styles.barIcons}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
onPress={() => handleOnVotersPress && handleOnVotersPress(get(post, 'active_votes'))}
|
||||
text={get(post, 'vote_count')}
|
||||
textMarginLeft={20}
|
||||
/>
|
||||
<TextWithIcon
|
||||
iconName="comment"
|
||||
iconStyle={styles.barIcons}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
text={get(post, 'children')}
|
||||
textMarginLeft={20}
|
||||
/>
|
||||
<View style={styles.stickyRightWrapper}>
|
||||
{get(currentAccount, 'name') === get(post, 'author') && (
|
||||
<Fragment>
|
||||
{!get(post, 'children') && !get(post, 'vote_count') && (
|
||||
<SafeAreaView>
|
||||
<StickyBar isFixedFooter={isFixedFooter}>
|
||||
<View style={styles.stickyWrapper}>
|
||||
<Upvote fetchPost={fetchPost} isShowPayoutValue content={post} />
|
||||
<TextWithIcon
|
||||
iconName="people"
|
||||
iconStyle={styles.barIcons}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
onPress={() => handleOnVotersPress && handleOnVotersPress(get(post, 'active_votes'))}
|
||||
text={get(post, 'vote_count', 0)}
|
||||
textMarginLeft={20}
|
||||
/>
|
||||
<TextWithIcon
|
||||
iconName="comment"
|
||||
iconStyle={styles.barIcons}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
text={get(post, 'children', 0)}
|
||||
textMarginLeft={20}
|
||||
/>
|
||||
<TextWithIcon
|
||||
iconName="repeat"
|
||||
iconStyle={styles.barIcons}
|
||||
iconType="MaterialIcons"
|
||||
isClickable
|
||||
onPress={() => handleOnReblogsPress && handleOnReblogsPress(get(post, 'reblogs'))}
|
||||
text={get(post, 'reblogCount', 0)}
|
||||
textMarginLeft={20}
|
||||
/>
|
||||
<View style={styles.stickyRightWrapper}>
|
||||
{get(currentAccount, 'name') === get(post, 'author') && (
|
||||
<Fragment>
|
||||
{!get(post, 'children') && !get(post, 'vote_count') && (
|
||||
<IconButton
|
||||
iconStyle={styles.barIconRight}
|
||||
iconType="MaterialIcons"
|
||||
name="delete-forever"
|
||||
onPress={() => this.ActionSheet.show()}
|
||||
style={styles.barIconButton}
|
||||
/>
|
||||
)}
|
||||
<IconButton
|
||||
iconStyle={styles.barIconRight}
|
||||
iconType="MaterialIcons"
|
||||
name="delete-forever"
|
||||
onPress={() => this.ActionSheet.show()}
|
||||
name="create"
|
||||
onPress={() => handleOnEditPress && handleOnEditPress()}
|
||||
style={styles.barIconButton}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
{isLoggedIn && (
|
||||
<IconButton
|
||||
iconStyle={styles.barIconRight}
|
||||
iconType="MaterialIcons"
|
||||
name="create"
|
||||
onPress={() => handleOnEditPress && handleOnEditPress()}
|
||||
name="reply"
|
||||
onPress={() => handleOnReplyPress && handleOnReplyPress()}
|
||||
style={styles.barIconButton}
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
{isLoggedIn && (
|
||||
<IconButton
|
||||
iconStyle={styles.barIconRight}
|
||||
iconType="MaterialIcons"
|
||||
name="reply"
|
||||
onPress={() => handleOnReplyPress && handleOnReplyPress()}
|
||||
style={styles.barIconButton}
|
||||
/>
|
||||
)}
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</StickyBar>
|
||||
</StickyBar>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
@ -142,6 +154,7 @@ class PostDisplayView extends PureComponent {
|
||||
author,
|
||||
intl,
|
||||
handleOnRemovePress,
|
||||
handleOnVotersPress,
|
||||
} = this.props;
|
||||
const { postHeight, scrollHeight, isLoadedComments } = this.state;
|
||||
|
||||
@ -201,6 +214,7 @@ class PostDisplayView extends PureComponent {
|
||||
permlink={post.permlink}
|
||||
commentCount={post.children}
|
||||
fetchPost={fetchPost}
|
||||
handleOnVotersPress={handleOnVotersPress}
|
||||
/>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import get from 'lodash/get';
|
||||
|
||||
// Component
|
||||
import PostsView from '../view/postsView';
|
||||
import { PostCardPlaceHolder } from '../../basicUIElements';
|
||||
|
||||
// Actions
|
||||
import { setFeedPosts } from '../../../redux/actions/postsAction';
|
||||
import { hidePostsThumbnails } from '../../../redux/actions/uiAction';
|
||||
|
||||
/*
|
||||
* Props Name Description Value
|
||||
*@props --> props name here description here Value Type Here
|
||||
@ -32,30 +33,55 @@ class PostsContainer extends PureComponent {
|
||||
dispatch(setFeedPosts(posts));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { currentAccount, isLoginDone, tag, feedPosts, isConnected } = this.props;
|
||||
const { promotedPosts } = this.state;
|
||||
_handleImagesHide = () => {
|
||||
const { dispatch, isHideImages } = this.props;
|
||||
|
||||
if (!isLoginDone && !tag) {
|
||||
return (
|
||||
<Fragment>
|
||||
<PostCardPlaceHolder />
|
||||
<PostCardPlaceHolder />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
dispatch(hidePostsThumbnails(!isHideImages));
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
changeForceLoadPostState,
|
||||
currentAccount,
|
||||
feedPosts,
|
||||
filterOptions,
|
||||
forceLoadPost,
|
||||
getFor,
|
||||
handleOnScroll,
|
||||
isConnected,
|
||||
isHideImages,
|
||||
pageType,
|
||||
selectedOptionIndex,
|
||||
tag,
|
||||
isLoginDone,
|
||||
isLoggedIn,
|
||||
isDarkTheme,
|
||||
nsfw,
|
||||
} = this.props;
|
||||
const { promotedPosts } = this.state;
|
||||
|
||||
return (
|
||||
<PostsView
|
||||
promotedPosts={promotedPosts}
|
||||
handleOnScrollStart={this._handleOnScrollStart}
|
||||
currentAccountUsername={
|
||||
currentAccount && (get(currentAccount, 'username') || get(currentAccount, 'name'))
|
||||
}
|
||||
setFeedPosts={this._setFeedPosts}
|
||||
changeForceLoadPostState={changeForceLoadPostState}
|
||||
currentAccountUsername={get(currentAccount, 'name', '')}
|
||||
feedPosts={feedPosts}
|
||||
filterOptions={filterOptions}
|
||||
forceLoadPost={forceLoadPost}
|
||||
getFor={getFor}
|
||||
handleOnScroll={handleOnScroll}
|
||||
handleImagesHide={this._handleImagesHide}
|
||||
hidePostsThumbnails={hidePostsThumbnails}
|
||||
isConnected={isConnected}
|
||||
{...this.props}
|
||||
isHideImage={isHideImages}
|
||||
pageType={pageType}
|
||||
promotedPosts={promotedPosts}
|
||||
selectedOptionIndex={selectedOptionIndex}
|
||||
setFeedPosts={this._setFeedPosts}
|
||||
tag={tag}
|
||||
isLoginDone={isLoginDone}
|
||||
isLoggedIn={isLoggedIn}
|
||||
isDarkTheme={isDarkTheme}
|
||||
nsfw={nsfw}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -69,6 +95,7 @@ const mapStateToProps = state => ({
|
||||
nsfw: state.application.nsfw,
|
||||
feedPosts: state.posts.feedPosts,
|
||||
isConnected: state.application.isConnected,
|
||||
isHideImages: state.ui.hidePostsThumbnails,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(PostsContainer);
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* eslint-disable react/jsx-wrap-multilines */
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { FlatList, View, ActivityIndicator, RefreshControl } from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
import get from 'lodash/get';
|
||||
import { get, isEqual, unionWith } from 'lodash';
|
||||
|
||||
// STEEM
|
||||
import { getPostsSummary, getPost } from '../../../providers/steem/dsteem';
|
||||
@ -28,11 +29,12 @@ class PostsView extends Component {
|
||||
startPermlink: '',
|
||||
refreshing: false,
|
||||
isLoading: false,
|
||||
isPostsLoading: true,
|
||||
isHideImage: false,
|
||||
isShowFilterBar: true,
|
||||
selectedFilterIndex: get(props, 'selectedOptionIndex', 0),
|
||||
isNoPost: false,
|
||||
promotedPosts: [],
|
||||
scrollOffsetY: 0,
|
||||
lockFilterBar: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -46,15 +48,14 @@ class PostsView extends Component {
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { isConnected } = this.props;
|
||||
const { isConnected, pageType } = this.props;
|
||||
|
||||
if (isConnected) {
|
||||
await this._getPromotePosts();
|
||||
if (pageType !== 'profiles') await this._getPromotePosts();
|
||||
this._loadPosts();
|
||||
} else {
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
isPostsLoading: false,
|
||||
isLoading: false,
|
||||
});
|
||||
}
|
||||
@ -77,8 +78,6 @@ class PostsView extends Component {
|
||||
startPermlink: '',
|
||||
refreshing: false,
|
||||
isLoading: false,
|
||||
isPostsLoading: false,
|
||||
isHideImage: false,
|
||||
selectedFilterIndex: get(nextProps, 'selectedOptionIndex', 0),
|
||||
isNoPost: false,
|
||||
},
|
||||
@ -94,16 +93,19 @@ class PostsView extends Component {
|
||||
|
||||
_getPromotePosts = async () => {
|
||||
const { currentAccountUsername } = this.props;
|
||||
await getPromotePosts().then(async res => {
|
||||
const promotedPosts = [];
|
||||
res &&
|
||||
res.length > 0 &&
|
||||
res.map(async item => {
|
||||
const post = await getPost(item.author, item.permlink, currentAccountUsername, true);
|
||||
promotedPosts.push(post);
|
||||
});
|
||||
|
||||
await this.setState({ promotedPosts });
|
||||
await getPromotePosts().then(async res => {
|
||||
if (res && res.length) {
|
||||
const promotedPosts = await Promise.all(
|
||||
res.map(item =>
|
||||
getPost(get(item, 'author'), get(item, 'permlink'), currentAccountUsername, true).then(
|
||||
post => post,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
this.setState({ promotedPosts });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@ -135,13 +137,12 @@ class PostsView extends Component {
|
||||
? POPULAR_FILTERS[selectedFilterIndex].toLowerCase()
|
||||
: PROFILE_FILTERS[selectedFilterIndex].toLowerCase();
|
||||
let options;
|
||||
let newPosts = [];
|
||||
const limit = promotedPosts ? (promotedPosts.length >= 3 ? 9 : 6) : 3;
|
||||
const newPosts = [];
|
||||
const limit = 3;
|
||||
|
||||
if (!isConnected) {
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
isPostsLoading: false,
|
||||
isLoading: false,
|
||||
});
|
||||
return null;
|
||||
@ -188,10 +189,7 @@ class PostsView extends Component {
|
||||
if (_posts.length > 0) {
|
||||
if (posts.length > 0) {
|
||||
if (refreshing) {
|
||||
// TODO: make sure post is not duplicated, because checking with `includes` might re-add post
|
||||
// if there was change in post object from blockchain
|
||||
newPosts = _posts.filter(post => posts.includes(post));
|
||||
_posts = [...newPosts, ...posts];
|
||||
_posts = unionWith(_posts, posts, isEqual);
|
||||
} else {
|
||||
_posts.shift();
|
||||
_posts = [...posts, ..._posts];
|
||||
@ -202,17 +200,38 @@ class PostsView extends Component {
|
||||
setFeedPosts(_posts);
|
||||
}
|
||||
|
||||
if (refreshing && newPosts.length > 0) {
|
||||
// Promoted post start
|
||||
if (promotedPosts && promotedPosts.length > 0) {
|
||||
const insert = (arr, index, newItem) => [
|
||||
...arr.slice(0, index),
|
||||
|
||||
newItem,
|
||||
|
||||
...arr.slice(index),
|
||||
];
|
||||
|
||||
if (refreshing) {
|
||||
_posts = _posts.filter(item => !item.is_promoted);
|
||||
}
|
||||
|
||||
_posts.map((d, i) => {
|
||||
if ([3, 6, 9].includes(i)) {
|
||||
const ix = i / 3 - 1;
|
||||
if (promotedPosts[ix] !== undefined) {
|
||||
if (get(_posts, [i], {}).permlink !== promotedPosts[ix].permlink) {
|
||||
_posts = insert(_posts, i, promotedPosts[ix]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Promoted post end
|
||||
|
||||
if (refreshing) {
|
||||
this.setState({
|
||||
posts: _posts,
|
||||
});
|
||||
} else if (!refreshing) {
|
||||
if (!startAuthor) {
|
||||
promotedPosts.map((promotedItem, i) => {
|
||||
_posts.splice((i + 1) * 3, i * 3, promotedItem);
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
posts: _posts,
|
||||
startAuthor: result[result.length - 1] && result[result.length - 1].author,
|
||||
@ -222,7 +241,6 @@ class PostsView extends Component {
|
||||
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
isPostsLoading: false,
|
||||
isLoading: false,
|
||||
});
|
||||
}
|
||||
@ -233,17 +251,20 @@ class PostsView extends Component {
|
||||
.catch(() => {
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
isPostsLoading: false,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
_handleOnRefreshPosts = () => {
|
||||
const { pageType } = this.props;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
refreshing: true,
|
||||
},
|
||||
() => {
|
||||
async () => {
|
||||
if (pageType !== 'profiles') await this._getPromotePosts();
|
||||
|
||||
this._loadPosts();
|
||||
},
|
||||
);
|
||||
@ -264,7 +285,6 @@ class PostsView extends Component {
|
||||
|
||||
_handleOnDropdownSelect = async index => {
|
||||
await this.setState({
|
||||
isPostsLoading: true,
|
||||
selectedFilterIndex: index,
|
||||
posts: [],
|
||||
startAuthor: '',
|
||||
@ -274,34 +294,74 @@ class PostsView extends Component {
|
||||
this._loadPosts();
|
||||
};
|
||||
|
||||
_onRightIconPress = () => {
|
||||
const { isHideImage } = this.state;
|
||||
|
||||
this.setState({ isHideImage: !isHideImage });
|
||||
};
|
||||
|
||||
_handleOnPressLogin = () => {
|
||||
const { navigation } = this.props;
|
||||
navigation.navigate(ROUTES.SCREENS.LOGIN);
|
||||
};
|
||||
|
||||
_renderEmptyContent = () => {
|
||||
const { intl, getFor, isLoginDone, isLoggedIn, tag } = this.props;
|
||||
const { isNoPost } = this.state;
|
||||
|
||||
if (getFor === 'feed' && isLoginDone && !isLoggedIn) {
|
||||
return (
|
||||
<NoPost
|
||||
imageStyle={styles.noImage}
|
||||
isButtonText
|
||||
defaultText={intl.formatMessage({
|
||||
id: 'profile.login_to_see',
|
||||
})}
|
||||
handleOnButtonPress={this._handleOnPressLogin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (isNoPost) {
|
||||
return (
|
||||
<NoPost
|
||||
imageStyle={styles.noImage}
|
||||
name={tag}
|
||||
text={intl.formatMessage({
|
||||
id: 'profile.havent_posted',
|
||||
})}
|
||||
defaultText={intl.formatMessage({
|
||||
id: 'profile.login_to_see',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PostCardPlaceHolder />
|
||||
<PostCardPlaceHolder />
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
_handleOnScroll = event => {
|
||||
const { scrollOffsetY } = this.state;
|
||||
const { handleOnScroll } = this.props;
|
||||
const currentOffset = event.nativeEvent.contentOffset.y;
|
||||
|
||||
if (handleOnScroll) handleOnScroll();
|
||||
this.setState({ scrollOffsetY: currentOffset });
|
||||
this.setState({ isShowFilterBar: scrollOffsetY > currentOffset || scrollOffsetY <= 0 });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { refreshing, posts, isPostsLoading, isHideImage, isNoPost } = this.state;
|
||||
const { refreshing, posts, isShowFilterBar } = this.state;
|
||||
const {
|
||||
filterOptions,
|
||||
selectedOptionIndex,
|
||||
intl,
|
||||
isLoggedIn,
|
||||
getFor,
|
||||
isLoginDone,
|
||||
tag,
|
||||
isDarkTheme,
|
||||
isHideReblogOption,
|
||||
isHideImage,
|
||||
handleImagesHide,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{filterOptions && (
|
||||
{filterOptions && isShowFilterBar && (
|
||||
<FilterBar
|
||||
dropdownIconName="arrow-drop-down"
|
||||
options={filterOptions}
|
||||
@ -310,75 +370,42 @@ class PostsView extends Component {
|
||||
rightIconName="view-module"
|
||||
rightIconType="MaterialIcons"
|
||||
onDropdownSelect={this._handleOnDropdownSelect}
|
||||
onRightIconPress={this._onRightIconPress}
|
||||
onRightIconPress={handleImagesHide}
|
||||
/>
|
||||
)}
|
||||
<Fragment>
|
||||
{getFor === 'feed' && isLoginDone && !isLoggedIn && (
|
||||
<NoPost
|
||||
imageStyle={styles.noImage}
|
||||
isButtonText
|
||||
defaultText={intl.formatMessage({
|
||||
id: 'profile.login_to_see',
|
||||
})}
|
||||
handleOnButtonPress={this._handleOnPressLogin}
|
||||
|
||||
<FlatList
|
||||
data={posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) =>
|
||||
get(item, 'author', null) && (
|
||||
<PostCard isRefresh={refreshing} content={item} isHideImage={isHideImage} />
|
||||
)
|
||||
}
|
||||
keyExtractor={(content, i) => `${get(content, 'permlink', '')}${i.toString()}`}
|
||||
onEndReached={() => this._loadPosts()}
|
||||
removeClippedSubviews
|
||||
refreshing={refreshing}
|
||||
onRefresh={() => this._handleOnRefreshPosts()}
|
||||
onEndThreshold={0}
|
||||
initialNumToRender={10}
|
||||
ListFooterComponent={this._renderFooter}
|
||||
onScrollEndDrag={this._handleOnScroll}
|
||||
ListEmptyComponent={this._renderEmptyContent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={this._handleOnRefreshPosts}
|
||||
progressBackgroundColor="#357CE6"
|
||||
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
|
||||
titleColor="#fff"
|
||||
colors={['#fff']}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
|
||||
{posts && posts.length > 0 && !isPostsLoading && (
|
||||
<FlatList
|
||||
data={posts}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) => (
|
||||
<PostCard
|
||||
isHideReblogOption={isHideReblogOption}
|
||||
isRefresh={refreshing}
|
||||
content={item}
|
||||
isHideImage={isHideImage}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
onEndReached={() => this._loadPosts()}
|
||||
removeClippedSubviews
|
||||
refreshing={refreshing}
|
||||
onRefresh={() => this._handleOnRefreshPosts()}
|
||||
onEndThreshold={0}
|
||||
initialNumToRender={10}
|
||||
ListFooterComponent={this._renderFooter}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
onRefresh={this._handleOnRefreshPosts}
|
||||
progressBackgroundColor="#357CE6"
|
||||
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
|
||||
titleColor="#fff"
|
||||
colors={['#fff']}
|
||||
/>
|
||||
}
|
||||
ref={ref => {
|
||||
this.flatList = ref;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isNoPost ? (
|
||||
<NoPost
|
||||
imageStyle={styles.noImage}
|
||||
name={tag}
|
||||
text={intl.formatMessage({
|
||||
id: 'profile.havent_posted',
|
||||
})}
|
||||
defaultText={intl.formatMessage({
|
||||
id: 'profile.login_to_see',
|
||||
})}
|
||||
/>
|
||||
) : (
|
||||
<Fragment>
|
||||
<PostCardPlaceHolder />
|
||||
<PostCardPlaceHolder />
|
||||
</Fragment>
|
||||
)}
|
||||
}
|
||||
ref={ref => {
|
||||
this.flatList = ref;
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
238
src/components/profile/profileView.js
Normal file
238
src/components/profile/profileView.js
Normal file
@ -0,0 +1,238 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { View, ScrollView } from 'react-native';
|
||||
import { injectIntl } from 'react-intl';
|
||||
import get from 'lodash/get';
|
||||
import ScrollableTabView from 'react-native-scrollable-tab-view';
|
||||
|
||||
// Components
|
||||
import { CollapsibleCard } from '../collapsibleCard';
|
||||
import { Comments } from '../comments';
|
||||
import { Header } from '../header';
|
||||
import { NoPost, ProfileSummaryPlaceHolder, WalletDetailsPlaceHolder } from '../basicUIElements';
|
||||
import { Posts } from '../posts';
|
||||
import { ProfileSummary } from '../profileSummary';
|
||||
import { TabBar } from '../tabBar';
|
||||
import { Wallet } from '../wallet';
|
||||
|
||||
// Constants
|
||||
import { PROFILE_FILTERS } from '../../constants/options/filters';
|
||||
|
||||
// Utils
|
||||
import { getFormatedCreatedDate } from '../../utils/time';
|
||||
|
||||
// Styles
|
||||
import styles from './profileStyles';
|
||||
import globalStyles from '../../globalStyles';
|
||||
|
||||
class ProfileView extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isSummaryOpen: true,
|
||||
collapsibleMoreHeight: 0,
|
||||
estimatedWalletValue: 0,
|
||||
oldEstimatedWalletValue: 0,
|
||||
};
|
||||
}
|
||||
|
||||
_handleOnScroll = () => {
|
||||
const { isSummaryOpen } = this.state;
|
||||
|
||||
if (isSummaryOpen) this.setState({ isSummaryOpen: false });
|
||||
};
|
||||
|
||||
_handleOnSummaryExpanded = () => {
|
||||
const { isSummaryOpen } = this.state;
|
||||
|
||||
if (!isSummaryOpen) this.setState({ isSummaryOpen: true });
|
||||
};
|
||||
|
||||
_handleUIChange = height => {
|
||||
this.setState({ collapsibleMoreHeight: height });
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
about,
|
||||
activePage,
|
||||
changeForceLoadPostState,
|
||||
comments,
|
||||
currencyRate,
|
||||
currencySymbol,
|
||||
follows,
|
||||
forceLoadPost,
|
||||
getReplies,
|
||||
handleFollowUnfollowUser,
|
||||
handleMuteUnmuteUser,
|
||||
handleOnBackPress,
|
||||
handleOnFavoritePress,
|
||||
handleOnFollowsPress,
|
||||
handleOnPressProfileEdit,
|
||||
intl,
|
||||
isDarkTheme,
|
||||
isFavorite,
|
||||
isFollowing,
|
||||
isLoggedIn,
|
||||
isMuted,
|
||||
isOwnProfile,
|
||||
isProfileLoading,
|
||||
isReady,
|
||||
quickProfile,
|
||||
resourceCredits,
|
||||
selectedUser,
|
||||
username,
|
||||
votingPower,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
isSummaryOpen,
|
||||
collapsibleMoreHeight,
|
||||
estimatedWalletValue,
|
||||
oldEstimatedWalletValue,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Header
|
||||
key={quickProfile && quickProfile.name}
|
||||
selectedUser={quickProfile}
|
||||
isReverse={!isOwnProfile}
|
||||
handleOnBackPress={handleOnBackPress}
|
||||
/>
|
||||
<View style={styles.container}>
|
||||
{!isReady ? (
|
||||
<ProfileSummaryPlaceHolder />
|
||||
) : (
|
||||
<CollapsibleCard
|
||||
title={get(about, 'about')}
|
||||
isTitleCenter
|
||||
defaultTitle={intl.formatMessage({
|
||||
id: 'profile.details',
|
||||
})}
|
||||
expanded
|
||||
isExpanded={isSummaryOpen}
|
||||
handleOnExpanded={this._handleOnSummaryExpanded}
|
||||
moreHeight={collapsibleMoreHeight}
|
||||
// expanded={isLoggedIn}
|
||||
// locked={!isLoggedIn}
|
||||
>
|
||||
<ProfileSummary
|
||||
date={getFormatedCreatedDate(get(selectedUser, 'created'))}
|
||||
about={about}
|
||||
followerCount={follows.follower_count}
|
||||
followingCount={follows.following_count}
|
||||
handleFollowUnfollowUser={handleFollowUnfollowUser}
|
||||
handleMuteUnmuteUser={handleMuteUnmuteUser}
|
||||
handleOnFavoritePress={handleOnFavoritePress}
|
||||
handleOnFollowsPress={handleOnFollowsPress}
|
||||
handleUIChange={this._handleUIChange}
|
||||
hoursRC={Math.ceil((100 - resourceCredits) * 0.833333) || null}
|
||||
hoursVP={Math.ceil((100 - votingPower) * 0.833333) || null}
|
||||
intl={intl}
|
||||
isDarkTheme={isDarkTheme}
|
||||
isFavorite={isFavorite}
|
||||
isFollowing={isFollowing}
|
||||
isLoggedIn={isLoggedIn}
|
||||
isMuted={isMuted}
|
||||
isOwnProfile={isOwnProfile}
|
||||
isProfileLoading={isProfileLoading}
|
||||
percentRC={resourceCredits}
|
||||
percentVP={votingPower}
|
||||
handleOnPressProfileEdit={handleOnPressProfileEdit}
|
||||
/>
|
||||
</CollapsibleCard>
|
||||
)}
|
||||
|
||||
<ScrollableTabView
|
||||
style={[globalStyles.tabView, styles.tabView]}
|
||||
initialPage={activePage}
|
||||
renderTabBar={() => (
|
||||
<TabBar style={styles.tabbar} tabUnderlineDefaultWidth={80} tabUnderlineScaleX={2} />
|
||||
)}
|
||||
onChangeTab={({ i }) => {
|
||||
if (i !== 2) {
|
||||
this.setState({
|
||||
estimatedWalletValue: 0,
|
||||
oldEstimatedWalletValue: estimatedWalletValue,
|
||||
});
|
||||
} else this.setState({ estimatedWalletValue: oldEstimatedWalletValue });
|
||||
}}
|
||||
>
|
||||
<View
|
||||
tabLabel={intl.formatMessage({
|
||||
id: 'profile.post',
|
||||
})}
|
||||
style={styles.postTabBar}
|
||||
>
|
||||
<Posts
|
||||
filterOptions={PROFILE_FILTERS}
|
||||
selectedOptionIndex={0}
|
||||
pageType="profiles"
|
||||
getFor="blog"
|
||||
tag={username}
|
||||
key={username}
|
||||
handleOnScroll={isSummaryOpen ? this._handleOnScroll : null}
|
||||
forceLoadPost={forceLoadPost}
|
||||
changeForceLoadPostState={changeForceLoadPostState}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
tabLabel={
|
||||
!isOwnProfile
|
||||
? intl.formatMessage({
|
||||
id: 'profile.comments',
|
||||
})
|
||||
: intl.formatMessage({
|
||||
id: 'profile.replies',
|
||||
})
|
||||
}
|
||||
style={styles.commentsTabBar}
|
||||
>
|
||||
{comments && comments.length > 0 ? (
|
||||
<ScrollView onScroll={this._handleOnScroll}>
|
||||
<Comments
|
||||
isProfilePreview
|
||||
comments={comments}
|
||||
fetchPost={getReplies}
|
||||
isOwnProfile={isOwnProfile}
|
||||
/>
|
||||
</ScrollView>
|
||||
) : (
|
||||
<NoPost
|
||||
name={username}
|
||||
text={intl.formatMessage({
|
||||
id: 'profile.havent_commented',
|
||||
})}
|
||||
defaultText={intl.formatMessage({
|
||||
id: 'profile.login_to_see',
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
<View
|
||||
tabLabel={
|
||||
estimatedWalletValue
|
||||
? `${currencySymbol} ${(estimatedWalletValue * currencyRate).toFixed()}`
|
||||
: intl.formatMessage({
|
||||
id: 'profile.wallet',
|
||||
})
|
||||
}
|
||||
>
|
||||
{selectedUser ? (
|
||||
<Wallet
|
||||
setEstimatedWalletValue={value => this.setState({ estimatedWalletValue: value })}
|
||||
selectedUser={selectedUser}
|
||||
handleOnScroll={isSummaryOpen ? this._handleOnScroll : null}
|
||||
/>
|
||||
) : (
|
||||
<WalletDetailsPlaceHolder />
|
||||
)}
|
||||
</View>
|
||||
</ScrollableTabView>
|
||||
</View>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default injectIntl(ProfileView);
|
71
src/components/profileEditForm/profileEditFormStyles.js
Normal file
71
src/components/profileEditForm/profileEditFormStyles.js
Normal file
@ -0,0 +1,71 @@
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
container: {
|
||||
paddingHorizontal: 32,
|
||||
paddingVertical: 16,
|
||||
backgroundColor: '$primaryBackgroundColor',
|
||||
flex: 1,
|
||||
},
|
||||
formStyle: {
|
||||
backgroundColor: '$white',
|
||||
height: 30,
|
||||
marginTop: 8,
|
||||
},
|
||||
label: {
|
||||
fontSize: 14,
|
||||
color: '$primaryDarkText',
|
||||
fontWeight: '500',
|
||||
},
|
||||
formItem: {
|
||||
marginBottom: 24,
|
||||
},
|
||||
coverImg: {
|
||||
borderRadius: 5,
|
||||
height: 60,
|
||||
marginBottom: 12,
|
||||
alignSelf: 'stretch',
|
||||
backgroundColor: '#296CC0',
|
||||
},
|
||||
coverImageWrapper: {},
|
||||
addIcon: {
|
||||
color: '$white',
|
||||
textAlign: 'center',
|
||||
},
|
||||
addButton: {
|
||||
backgroundColor: '$iconColor',
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 20 / 2,
|
||||
borderColor: '$white',
|
||||
borderWidth: 1,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
right: 10,
|
||||
},
|
||||
|
||||
saveButton: {
|
||||
backgroundColor: '$primaryBlue',
|
||||
width: 55,
|
||||
height: 55,
|
||||
borderRadius: 55 / 2,
|
||||
position: 'absolute',
|
||||
top: -25,
|
||||
right: 10,
|
||||
zIndex: 999,
|
||||
borderWidth: 2,
|
||||
borderColor: '$white',
|
||||
},
|
||||
saveIcon: {
|
||||
color: '$white',
|
||||
textAlign: 'center',
|
||||
},
|
||||
|
||||
input: {
|
||||
fontSize: 14,
|
||||
color: '$primaryDarkText',
|
||||
alignSelf: 'flex-start',
|
||||
width: '100%',
|
||||
height: 30,
|
||||
},
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user