├── .gitignore
├── App.js
├── AppNavigator.js
├── CountlyConfig.js
├── LICENSE
├── OnboardingWrapper.js
├── README.md
├── ReactotronConfig.js
├── ServerBridgeNativeModule.js
├── StreamClient.js
├── __tests__
└── App.js
├── android
├── app
│ ├── BUCK
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ └── res
│ │ │ └── values
│ │ │ └── strings.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── AntDesign.ttf
│ │ │ │ ├── Entypo.ttf
│ │ │ │ ├── EvilIcons.ttf
│ │ │ │ ├── Feather.ttf
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── FontAwesome5_Brands.ttf
│ │ │ │ ├── FontAwesome5_Regular.ttf
│ │ │ │ ├── FontAwesome5_Solid.ttf
│ │ │ │ ├── Fontisto.ttf
│ │ │ │ ├── Foundation.ttf
│ │ │ │ ├── Ionicons.ttf
│ │ │ │ ├── MaterialCommunityIcons.ttf
│ │ │ │ ├── MaterialIcons.ttf
│ │ │ │ ├── Octicons.ttf
│ │ │ │ ├── SimpleLineIcons.ttf
│ │ │ │ └── Zocial.ttf
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── nativebazaar
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MainApplication.java
│ │ │ │ ├── ServerConfig.java
│ │ │ │ └── serverbridge
│ │ │ │ ├── ServerBridgeManager.java
│ │ │ │ ├── ServerBridgeModule.java
│ │ │ │ └── ServerBridgePackage.java
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── splash_logo.png
│ │ │ ├── layout
│ │ │ └── launch_screen.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_silhouette.png
│ │ │ ├── mipmap-ldpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ │ └── xml
│ │ │ └── provider_paths.xml
│ │ └── release
│ │ └── res
│ │ └── values
│ │ └── strings.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── keystores
│ ├── BUCK
│ ├── OB1_dev_keystore.jks
│ └── debug.keystore.properties
├── mobile
│ └── build.gradle
└── settings.gradle
├── api
├── block.js
├── cache.js
├── chat.js
├── checkout.js
├── common.js
├── const.js
├── featured.js
├── feed.js
├── follow.js
├── hash.js
├── images.js
├── mock
│ ├── create_listing.json
│ ├── index.js
│ ├── wallet_balance.json
│ ├── wallet_estimatefee_coin.json
│ ├── wallet_fees.json
│ ├── wallet_spend.json
│ ├── wallet_transactions_coin.json
│ └── wallet_transactions_coin_fail.json
├── moderators.js
├── notifications.js
├── onboarding.js
├── orders.js
├── products.js
├── profile.js
├── profiles.js
├── promo.js
├── publish.js
├── search.js
├── settings.js
├── signing.js
├── stream.js
└── wallet.js
├── app.json
├── appcenter-post-clone.sh
├── appcenter-pre-build.sh
├── assets
├── icons
│ ├── check-decagram.png
│ ├── coupon.png
│ ├── crypto
│ │ ├── BCH.png
│ │ ├── BTC.png
│ │ ├── ETH.png
│ │ ├── LNlogo.png
│ │ ├── LTC.png
│ │ ├── ZEC.png
│ │ ├── coinbase.png
│ │ └── shapeshift.png
│ ├── linkNewTab.png
│ ├── person_add.png
│ ├── qrcode.png
│ ├── shipping.png
│ └── transaction_icon.png
├── images
│ ├── backup_image.png
│ ├── cameraPlaceholder.png
│ ├── categories
│ │ ├── Apparel_Accessories.jpg
│ │ ├── Automobiles_Motorcycles.jpg
│ │ ├── Beauty_Health.jpg
│ │ ├── Books.jpg
│ │ ├── Cellphones_Telecommunications.jpg
│ │ ├── Computer_Office.jpg
│ │ ├── Consumer_Electronics.jpeg
│ │ ├── Electronic_Components_Supplies.jpg
│ │ ├── Furniture.png
│ │ ├── Gift_Cards.jpg
│ │ ├── Hair_Extensions_Wigs.jpg
│ │ ├── Home_Appliances.jpeg
│ │ ├── Home_Garden.jpeg
│ │ ├── Home_Improvement.jpg
│ │ ├── Jewelry_Accessories.jpg
│ │ ├── Lights_Lighting.jpg
│ │ ├── Luggage_Bags.jpg
│ │ ├── Mens_Clothing.jpg
│ │ ├── Mother_Kids.jpg
│ │ ├── Novelty_Special_Use.jpg
│ │ ├── Office_School_Supplies.png
│ │ ├── Other.jpg
│ │ ├── Security_Protection.jpg
│ │ ├── Shoes.jpeg
│ │ ├── Sports_Entertainment.jpg
│ │ ├── Tools.jpg
│ │ ├── Toys_Hobbies.jpg
│ │ ├── Underwear_Sleepwear.jpg
│ │ ├── Watches.jpeg
│ │ ├── Wedding_Events.jpg
│ │ └── Womens_Clothing.jpg
│ ├── defaultAvatar.png
│ ├── defaultHeader.png
│ ├── defaultItem.png
│ ├── listing_fail.png
│ ├── logo
│ │ ├── brand-logo.png
│ │ ├── brand-logo@2x.png
│ │ ├── brand-logo@3x.png
│ │ ├── splash-logo.png
│ │ ├── splash-logo@2x.png
│ │ └── splash-logo@3x.png
│ ├── notificationIcons
│ │ ├── blueChat.png
│ │ ├── blueProfile.png
│ │ ├── blueRepost.png
│ │ ├── blueThumbsUp.png
│ │ ├── greenTag.png
│ │ ├── greyShoppingCart.png
│ │ └── redGavel.png
│ ├── onboardingBackground.png
│ ├── privacyBottom.png
│ ├── privacyShield.png
│ ├── restore.png
│ ├── restore@2x.png
│ ├── restore@3x.png
│ ├── tab
│ │ ├── icon-chat-bg.png
│ │ ├── icon-chat-inactive.png
│ │ ├── icon-chat-inactive@2x.png
│ │ ├── icon-chat.png
│ │ ├── icon-home-inactive.png
│ │ ├── icon-home-inactive@2x.png
│ │ ├── icon-home.png
│ │ ├── icon-home@2x.png
│ │ ├── icon-social-inactive.png
│ │ ├── icon-social-inactive@2x.png
│ │ ├── icon-social.png
│ │ ├── icon-social@2x.png
│ │ ├── icon-store-inactive.png
│ │ ├── icon-store-inactive@2x.png
│ │ ├── icon-store.png
│ │ ├── icon-store@2x.png
│ │ └── wallet.png
│ ├── upload.png
│ ├── upload@2x.png
│ ├── upload@3x.png
│ ├── wyre_logo.png
│ └── wyre_logo_2.png
├── slider1.png
├── slider2.png
└── slider3.png
├── components
├── atoms
│ ├── AddItemTrigger.js
│ ├── AvatarImage.js
│ ├── Badge.js
│ ├── CatListItem.js
│ ├── CatSliderItem.js
│ ├── ChatBubble.js
│ ├── ChatNavIcon.js
│ ├── CheckBox.js
│ ├── CheckGroup.js
│ ├── Comment.js
│ ├── DescriptionText.js
│ ├── EditListingFooter.js
│ ├── EditProfileBanner.js
│ ├── Fee.js
│ ├── FilterButton.js
│ ├── FollowButton.js
│ ├── FormLabelText.js
│ ├── FullButton.js
│ ├── HollowButton.js
│ ├── ImageButton.js
│ ├── InputGroup.js
│ ├── Inventory.js
│ ├── LinkText.js
│ ├── ListingTitlePrice.js
│ ├── LocationPin.js
│ ├── MainSliderContentLoader.js
│ ├── MainSliderItem.js
│ ├── MeActionItem.js
│ ├── MessageText.js
│ ├── ModalBackButton.js
│ ├── ModalFavButton.js
│ ├── ModalImageIndicator.js
│ ├── ModalTooltip.js
│ ├── ModalTrashButton.js
│ ├── MoreButton.js
│ ├── NavBackButton.js
│ ├── NavCloseButton.js
│ ├── NavOptionButton.js
│ ├── NavPlusButton.js
│ ├── NavShareButton.js
│ ├── NotificationBadge.js
│ ├── OBFastImage.js
│ ├── OBSlidingPanel.js
│ ├── OptionGroup.js
│ ├── PayBanner.js
│ ├── PaymentMethod.js
│ ├── PlaceholderStyleTextInput.js
│ ├── PlusButton.js
│ ├── PostButton.js
│ ├── ProductCardLoader.js
│ ├── ProductImage.js
│ ├── ProductName.js
│ ├── ProductPrice.js
│ ├── ProductSection.js
│ ├── ProductState.js
│ ├── ProductTag.js
│ ├── ProfilePicture.js
│ ├── RadioGroup.js
│ ├── Rating.js
│ ├── RatingInput.js
│ ├── RecentKeyword.js
│ ├── ResetFilter.js
│ ├── SMRoundButton.js
│ ├── SMTextButton.js
│ ├── SearchModalWrapper.js
│ ├── SecureFund.js
│ ├── ShopGridLoader.js
│ ├── Stars.js
│ ├── StaticField.js
│ ├── Switch.js
│ ├── SwitchInput.js
│ ├── TagInput.js
│ ├── TextArea.js
│ ├── TextInput.js
│ ├── TransactionItem.js
│ └── UnavailableButton.js
├── commonColors.js
├── commonStyles.js
├── molecules
│ ├── BlockedNodeItem.js
│ ├── BuyWyre.js
│ ├── BuyerReview.js
│ ├── ChatListItem.js
│ ├── ChatSearchField.js
│ ├── CheckoutNote.js
│ ├── CoinListItem.js
│ ├── DirectPaymentOption.js
│ ├── EditProfileHeader.js
│ ├── ExternalStoreHeader.js
│ ├── FeedImageGrid.js
│ ├── FeedItem.js
│ ├── FeedItemFooter.js
│ ├── FeedListItem.js
│ ├── FeedPreview.js
│ ├── FriendItem.js
│ ├── HashtagHeader.js
│ ├── Header.js
│ ├── ImagePick.js
│ ├── ListingHeader.js
│ ├── ListingPaymentOptions.js
│ ├── ListingPreview.js
│ ├── ListingReview.js
│ ├── MainSlider.js
│ ├── ModerationFee.js
│ ├── MultiFilter.js
│ ├── NewChartHeader.js
│ ├── OrderNotification.js
│ ├── PeerItem.js
│ ├── ProductCard.js
│ ├── ProductDescription.js
│ ├── ProductImageSlider.js
│ ├── ProductListItem.js
│ ├── ProductPolicy.js
│ ├── ProductRating.js
│ ├── ProductTags.js
│ ├── QuantitySelector.js
│ ├── RadioFilter.js
│ ├── RadioModalFilter.js
│ ├── SearchField.js
│ ├── Section.js
│ ├── SellerInfo.js
│ ├── ShopCard.js
│ ├── ShopInfo.js
│ ├── SocialNotification.js
│ ├── StoreMoreMenu.js
│ ├── TextHeader.js
│ ├── VariantItem.js
│ └── WalletCoinItem.js
├── organism
│ ├── ActionSheet.js
│ ├── AverageRating.js
│ ├── Balance.js
│ ├── CategorySelector.js
│ ├── CheckoutHeader.js
│ ├── CheckoutSummary.js
│ ├── CoinBalance.js
│ ├── CoinSelectorModal.js
│ ├── CoinTypeSelector.js
│ ├── CommentInput.js
│ ├── ContentWithListingPreview.js
│ ├── CouponItem.js
│ ├── DefaultInventoryItem.js
│ ├── EmptyCoupons.js
│ ├── EmptyShippingMethods.js
│ ├── ErrorModal.js
│ ├── ImageSelector.js
│ ├── InventoryItem.js
│ ├── ItemDetail.js
│ ├── Listings.js
│ ├── ModerationSettingsEditor.js
│ ├── Moderator.js
│ ├── ModeratorPreview.js
│ ├── MultiSelector.js
│ ├── Notification.js
│ ├── OptionSelector.js
│ ├── OrderBrief.js
│ ├── OrderDispute.js
│ ├── OrderFooter.js
│ ├── OrderFulfillment.js
│ ├── OrderRating.js
│ ├── PanelView
│ │ ├── PanelViewBase.js
│ │ ├── PlusPanelView.js
│ │ └── SharePanelView.js
│ ├── PayPanel.js
│ ├── ProductGrid.js
│ ├── ProductModeSelector.js
│ ├── ProductRatings.js
│ ├── ProfileImages.js
│ ├── QRScanner.js
│ ├── SearchFilterHeader.js
│ ├── SearchHeader.js
│ ├── SelectableModerator.js
│ ├── SelectorModal.js
│ ├── SelectorPlaceholder.js
│ ├── SendingAddressSelector.js
│ ├── SendingAmount.js
│ ├── ShippingMethod.js
│ ├── ShippingOptions.js
│ ├── ShippingPrice.js
│ ├── ShippingPriceEditor.js
│ ├── ShippingPrices.js
│ ├── ShopGrid.js
│ ├── SingleVariantEditor.js
│ ├── SupportHaven.js
│ ├── TabHeader.js
│ ├── Tabs.js
│ ├── TagEditor.js
│ ├── TagSuggestion.js
│ ├── UserSearchItem.js
│ ├── VariantOptions.js
│ ├── VendorListings.js
│ └── VirtualKeyboard.js
└── templates
│ ├── AboutTab.js
│ ├── BackupWallet.js
│ ├── CategoryList.js
│ ├── CategoryProductGrid.js
│ ├── ChatDetail.js
│ ├── Checkout.js
│ ├── ContractModal.js
│ ├── CouponApplyModal.js
│ ├── CouponModal.js
│ ├── CouponsTemplate.js
│ ├── CovidModal.js
│ ├── DisputeModal.js
│ ├── EULAModal.js
│ ├── FeedDetail.js
│ ├── FeedTabContent.js
│ ├── FulfillModal.js
│ ├── GlobalFeed.js
│ ├── InfiniteProducts.js
│ ├── InventoryEditor.js
│ ├── InventoryList.js
│ ├── ListShippingMethod.js
│ ├── ListingAdvancedDetails.js
│ ├── ListingBasicInfo.js
│ ├── ListingCustomOptions.js
│ ├── ListingsTab.js
│ ├── ModerataionSettings.js
│ ├── NeedCoin.js
│ ├── NewsFeedFooter.js
│ ├── Notification.js
│ ├── OBModal.js
│ ├── OrderCategorySelector.js
│ ├── OrderState.js
│ ├── OrderStatus.js
│ ├── OrderSummary.js
│ ├── ParallaxScrollView.js
│ ├── Product.js
│ ├── PurchaseState.js
│ ├── RatingModal.js
│ ├── RecentSearch.js
│ ├── ReportTemplate.js
│ ├── SearchResults.js
│ ├── SendMoney.js
│ ├── SendReceiveMoney.js
│ ├── Settings.js
│ ├── SocialPostTemplate
│ ├── PostListingTemplate.js
│ ├── RepostTemplate.js
│ └── SocialPostBase.js
│ ├── StoreModeratorList.js
│ ├── StoreTabs.js
│ ├── Toast.js
│ ├── TransactionHistory.js
│ ├── UserSearchResults.js
│ ├── VariantEditor.js
│ ├── Wallet.js
│ ├── feed.js
│ └── wishlist.js
├── config
├── appIDConfig.js
├── categories.js
├── conditionFilter.json
├── countries.json
├── exchangeRates.json
├── feePlans.js
├── iosProductTypes.json
├── localCurrencies.json
├── nswf.json
├── orderStatus.json
├── productCondition.json
├── productTypes.json
├── sort.json
├── stream.js
└── supportUrls.js
├── havenBuildConfigFiles
└── copy_files.sh
├── index.js
├── install_server.sh
├── ios
├── Config.prod.debug.xcconfig
├── Config.prod.release.xcconfig
├── Config.staging.debug.xcconfig
├── Config.staging.release.xcconfig
├── NativeBazaar Prod-Bridging-Header.h
├── NativeBazaar Prod.entitlements
├── NativeBazaar-Bridging-Header.h
├── NativeBazaar-tvOS
│ └── Info.plist
├── NativeBazaar-tvOSTests
│ └── Info.plist
├── NativeBazaar.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── NativeBazaar Prod.xcscheme
│ │ └── NativeBazaar.xcscheme
├── NativeBazaar.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
├── NativeBazaar
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ └── LaunchScreen.xib
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── icon-1024@1x.png
│ │ │ ├── icon-20@1x.png
│ │ │ ├── icon-20@2x.png
│ │ │ ├── icon-20@3x.png
│ │ │ ├── icon-29@1x.png
│ │ │ ├── icon-29@2x.png
│ │ │ ├── icon-29@3x.png
│ │ │ ├── icon-40@1x.png
│ │ │ ├── icon-40@2x.png
│ │ │ ├── icon-40@3x.png
│ │ │ ├── icon-50@1x.png
│ │ │ ├── icon-50@2x.png
│ │ │ ├── icon-57@1x.png
│ │ │ ├── icon-57@2x.png
│ │ │ ├── icon-60@2x.png
│ │ │ ├── icon-60@3x.png
│ │ │ ├── icon-72@1x.png
│ │ │ ├── icon-72@2x.png
│ │ │ ├── icon-76@1x.png
│ │ │ ├── icon-76@2x.png
│ │ │ └── icon-83.5@2x.png
│ │ ├── Contents.json
│ │ └── splash-logo.imageset
│ │ │ ├── Contents.json
│ │ │ ├── splash-logo.png
│ │ │ ├── splash-logo@2x.png
│ │ │ └── splash-logo@3x.png
│ ├── Info-prod.plist
│ ├── Info.plist
│ ├── NativeBazaar.entitlements
│ ├── NativeModules
│ │ ├── ModuleWithEmitter.h
│ │ ├── ModuleWithEmitter.m
│ │ ├── ServerBridge.h
│ │ └── ServerBridgeManager.m
│ └── main.m
├── NativeBazaarTests
│ ├── Info.plist
│ └── NativeBazaarTests.m
├── Podfile
├── Podfile.lock
└── SwiftForBridge.swift
├── package.json
├── reducers
├── appstate.js
├── chat.js
├── config.js
├── createListing.js
├── exchangeRate.js
├── featured.js
├── feed.js
├── follow.js
├── followQueue.js
├── index.js
├── listings.js
├── moderationSettings.js
├── moderators.js
├── navigation.js
├── notifications.js
├── order.js
├── product.js
├── profile.js
├── profileFailedQueue.js
├── profileQueue.js
├── profiles.js
├── promo.js
├── ratings.js
├── saga
│ ├── appstate.js
│ ├── chat.js
│ ├── config.js
│ ├── createListing.js
│ ├── exchangeRate.js
│ ├── featured.js
│ ├── feed.js
│ ├── follow.js
│ ├── index.js
│ ├── listings.js
│ ├── moderationSettings.js
│ ├── moderators.js
│ ├── notification.js
│ ├── order.js
│ ├── product.js
│ ├── profile.js
│ ├── promo.js
│ ├── ratings.js
│ ├── sagaSelector.js
│ ├── search.js
│ ├── settings.js
│ ├── socket.js
│ ├── storeListings.js
│ ├── stream.js
│ └── wallet.js
├── search.js
├── settings.js
├── socket.js
├── storeListings.js
├── stream.js
├── wallet.js
└── wishlist.js
├── routes.js
├── screens
├── Me.js
├── ProductRatings.js
├── Resync.js
├── StoreRatings.js
├── acceptedCoins.js
├── addListingCoupon.js
├── addModerators.js
├── addShippingMethod.js
├── analytics.js
├── backupProfileInit.js
├── backupProfilePassword.js
├── backupProfileUpload.js
├── blocked-nodes.js
├── categories.js
├── categoryOverview.js
├── categoryResult.js
├── chatDetail.js
├── chats.js
├── checkout.js
├── checkoutModerators.js
├── checkoutOption.js
├── createListing.js
├── cryptoBalance.js
├── customOptions.js
├── editInventory.js
├── editListing.js
├── editShippingAddress.js
├── editVariants.js
├── externalPay.js
├── externalPaySuccess.js
├── externalStore.js
├── feed.js
├── feedDetail.js
├── followers.js
├── followings.js
├── hashtag.js
├── listing.js
├── listingAdvancedDetails.js
├── listingAdvancedOptions.js
├── moderationSettings.js
├── moderatorDetails.js
├── new-chat.js
├── new-feed.js
├── notificationSettings.js
├── notifications.js
├── onboarding.js
├── order.js
├── orderDetails.js
├── paymentMethod.js
├── paymentSuccess.js
├── policies.js
├── privacy.js
├── profileSettings.js
├── purchaseState.js
├── purchaseSuccess.js
├── queryResult.js
├── receiveMoney.js
├── restoreProfileInit.js
├── restoreProfilePassword.js
├── searchFilter.js
├── searchResult.js
├── sendMoney.js
├── serverLog.js
├── settings.js
├── shippingAddress.js
├── shippingOptions.js
├── shop.js
├── store.js
├── storeModerators.js
├── subCategories.js
├── tagEditor.js
├── transactions.js
├── wallet.js
└── wishlist.js
├── selectors
├── chat.js
├── currency.js
├── listing.js
├── moderators.js
├── notifications.js
├── order.js
├── profile.js
└── stream.js
├── status-bar.js
├── store.js
├── utils
├── EventTracker
│ ├── EventTracker.js
│ └── index.js
├── chat.js
├── checkout.js
├── coins.js
├── currency.js
├── dataMapping.js
├── fee.js
├── feed.js
├── files.js
├── firestore.js
├── hashtags.js
├── keyboard.js
├── listings.js
├── navbar.js
├── navigation.js
├── notification.js
├── order.js
├── parseText.js
├── profile.js
├── rateApp.js
├── ratings.js
├── server.js
├── stockManage.js
├── stream.js
├── string.js
├── styles.js
├── time.js
├── toast.js
└── webview.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 | package-lock.json
39 |
40 | # BUCK
41 | buck-out/
42 | \.buckd/
43 | *.keystore
44 |
45 | # fastlane
46 | #
47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48 | # screenshots whenever they are needed.
49 | # For more information about the recommended setup visit:
50 | # https://docs.fastlane.tools/best-practices/source-control/
51 |
52 | */fastlane/report.xml
53 | */fastlane/Preview.html
54 | */fastlane/screenshots
55 |
56 | # openbazaar-go
57 | ios/Mobile.framework
58 | ios/Mobile.framework.zip
59 | android/mobile/mobile.aar
60 |
61 | #Pods
62 | ios/Pods
63 | ios/env.prod.xcconfig
64 | ios/env.xcconfig
65 | ios/NativeBazaar/AppCenter-Config.plist
66 | android/app/google-services.json
67 | android/app/src/main/assets/appcenter-config.json
68 | ios/GoogleService-Info.plist
69 | .env
70 | .env.prod
71 | havenBuildConfigFiles/appcenter-config.json
72 | havenBuildConfigFiles/AppCenter-Config.plist
73 | havenBuildConfigFiles/google-services.json
74 | havenBuildConfigFiles/GoogleService-Info.plist
75 |
--------------------------------------------------------------------------------
/CountlyConfig.js:
--------------------------------------------------------------------------------
1 | import Config from 'react-native-config';
2 | import Countly from 'countly-sdk-react-native';
3 |
4 | export const COUNTLY_ROOT_URL = Config.COUNTLY_ROOT_URL;
5 | export const COUNTLY_APP_KEY = Config.COUNTLY_APP_KEY;
6 |
7 | Countly.isDebug = __DEV__;
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 OpenBazaar
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ReactotronConfig.js:
--------------------------------------------------------------------------------
1 | import Reactotron from 'reactotron-react-native';
2 | import { reactotronRedux } from 'reactotron-redux';
3 |
4 | Reactotron
5 | .configure({ host: 'localhost' }) // controls connection & communication settings
6 | .use(reactotronRedux())
7 | .useReactNative() // add all built-in react native plugins
8 | .connect(); // let's connect!
9 |
--------------------------------------------------------------------------------
/ServerBridgeNativeModule.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable class-methods-use-this */
2 | import { NativeModules } from 'react-native';
3 |
4 | const { ServerBridge } = NativeModules;
5 |
6 | class ServerBridgeNativeModule {
7 | static start() {
8 | return ServerBridge.start();
9 | }
10 |
11 | static stop() {
12 | return ServerBridge.stop();
13 | }
14 |
15 | static downloadFromCloudContentUri(zipUri) {
16 | return ServerBridge.downloadFromCloudContentUri(zipUri);
17 | }
18 |
19 | static EXAMPLE_CONSTANT = ServerBridge.EXAMPLE_CONSTANT
20 | }
21 |
22 | export default ServerBridgeNativeModule;
23 |
--------------------------------------------------------------------------------
/__tests__/App.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react';
3 | import App from '../App';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create();
10 | });
11 |
--------------------------------------------------------------------------------
/android/app/src/debug/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Haven Test
3 | true
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/AntDesign.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/AntDesign.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Feather.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Feather.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Fontisto.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Fontisto.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/SimpleLineIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/SimpleLineIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/android/app/src/main/java/com/nativebazaar/ServerConfig.java:
--------------------------------------------------------------------------------
1 | package com.nativebazaar;
2 |
3 | import android.provider.Settings;
4 |
5 | public class ServerConfig {
6 | public static String getServerToken() {
7 | String token = "Token:";
8 | String androidId = Settings.Secure.getString(MainApplication.getAppContext().getContentResolver(), Settings.Secure.ANDROID_ID);
9 | token = token + androidId;
10 | return token;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/nativebazaar/serverbridge/ServerBridgeManager.java:
--------------------------------------------------------------------------------
1 | package com.nativebazaar.serverbridge;
2 |
3 | import android.view.View;
4 |
5 | import com.facebook.react.uimanager.SimpleViewManager;
6 | import com.facebook.react.uimanager.ThemedReactContext;
7 |
8 | import com.facebook.react.uimanager.annotations.ReactProp;
9 |
10 | public class ServerBridgeManager extends SimpleViewManager {
11 | public static final String REACT_CLASS = "ServerBridge";
12 |
13 | @Override
14 | public String getName() {
15 | // Tell React the name of the module
16 | // https://facebook.github.io/react-native/docs/native-components-android.html#1-create-the-viewmanager-subclass
17 | return REACT_CLASS;
18 | }
19 |
20 | @Override
21 | public View createViewInstance(ThemedReactContext context){
22 | // Create a view here
23 | // https://facebook.github.io/react-native/docs/native-components-android.html#2-implement-method-createviewinstance
24 | return new View(context);
25 | }
26 |
27 | @ReactProp(name = "exampleProp")
28 | public void setExampleProp(View view, String prop) {
29 | // Set properties from React onto your native component via a setter method
30 | // https://facebook.github.io/react-native/docs/native-components-android.html#3-expose-view-property-setters-using-reactprop-or-reactpropgroup-annotation
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/nativebazaar/serverbridge/ServerBridgePackage.java:
--------------------------------------------------------------------------------
1 | package com.nativebazaar.serverbridge;
2 |
3 | import com.facebook.react.ReactPackage;
4 | import com.facebook.react.bridge.JavaScriptModule;
5 | import com.facebook.react.bridge.NativeModule;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.react.uimanager.ViewManager;
8 |
9 | import java.util.Arrays;
10 | import java.util.Collections;
11 | import java.util.List;
12 |
13 | public class ServerBridgePackage implements ReactPackage {
14 | @Override
15 | public List createNativeModules(ReactApplicationContext reactContext) {
16 | // Register your native module
17 | // https://facebook.github.io/react-native/docs/native-modules-android.html#register-the-module
18 | return Arrays.asList(
19 | new ServerBridgeModule(reactContext)
20 | );
21 | }
22 |
23 |
24 | public List createViewManagers(ReactApplicationContext reactContext) {
25 | // Register your native component's view manager
26 | // https://facebook.github.io/react-native/docs/native-components-android.html#4-register-the-viewmanager
27 | return Arrays.asList(
28 | new ServerBridgeManager()
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/splash_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/drawable/splash_logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/layout/launch_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
12 |
17 |
21 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_silhouette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-hdpi/ic_silhouette.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-ldpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #00BF65
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ALWAYS_SEND
3 | ALWAYS_SEND
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/android/app/src/release/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Haven
3 | false
4 |
5 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | #Sun, 02 Aug 2020 15:53:37 +0000
2 | ## Project-wide Gradle settings.
3 | #
4 | # For more details on how to configure your build environment visit
5 | # http://www.gradle.org/docs/current/userguide/build_environment.html
6 | #
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
10 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
11 | #
12 | # When configured, Gradle will run in incubating parallel mode.
13 | # This option should only be used with decoupled projects. More details, visit
14 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
15 | # org.gradle.parallel=true
16 | #Wed Apr 11 16:15:46 CST 2018
17 | # systemProp.https.proxyPort=808
18 | # systemProp.http.proxyHost=192.168.3.52
19 | # systemProp.https.proxyHost=192.168.3.52
20 | # systemProp.http.proxyPort=808
21 |
22 | org.gradle.jvmargs=-Xmx4608m
23 | android.useAndroidX=true
24 | android.enableJetifier=true
25 | android.enableAapt2=false
26 | android.useDeprecatedNdk=true
27 | VERSION_NAME=1.3.7
28 | VERSION_CODE=125
29 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri May 04 08:40:35 MYT 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
7 |
--------------------------------------------------------------------------------
/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = "debug",
3 | properties = "debug.keystore.properties",
4 | store = "debug.keystore",
5 | visibility = [
6 | "PUBLIC",
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/android/keystores/OB1_dev_keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/android/keystores/OB1_dev_keystore.jks
--------------------------------------------------------------------------------
/android/keystores/debug.keystore.properties:
--------------------------------------------------------------------------------
1 | key.store=debug.keystore
2 | key.alias=androiddebugkey
3 | key.store.password=android
4 | key.alias.password=android
5 |
--------------------------------------------------------------------------------
/android/mobile/build.gradle:
--------------------------------------------------------------------------------
1 | configurations.maybeCreate("default")
2 | artifacts.add("default", file('mobile.aar'))
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'NativeBazaar'
2 |
3 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
4 | applyNativeModulesSettingsGradle(settings)
5 |
6 | include ':app', ':mobile'
7 |
--------------------------------------------------------------------------------
/api/block.js:
--------------------------------------------------------------------------------
1 | import { gatewayAPI } from './const';
2 | import { makeFetch } from './common';
3 |
4 | // Block a store
5 | export const blockNode = (username, password, peerID) => makeFetch({
6 | url: `${gatewayAPI}/ob/blocknode/${peerID}`,
7 | method: 'POST',
8 | });
9 |
10 | // Unblock a store
11 | export const unblockNode = (username, password, peerID) => makeFetch({
12 | url: `${gatewayAPI}/ob/blocknode/${peerID}`,
13 | method: 'DELETE',
14 | });
15 |
--------------------------------------------------------------------------------
/api/cache.js:
--------------------------------------------------------------------------------
1 |
2 | import { gatewayAPI } from './const';
3 | import { serverConfig } from '../utils/server';
4 |
5 | export const purgeCache = () => {
6 | const apiURL = `${gatewayAPI}/ob/purgecache`;
7 | const headers = {
8 | method: 'POST',
9 | headers: serverConfig.getAuthHeader(),
10 | };
11 | return fetch(apiURL, headers).then(response => response.json());
12 | };
13 |
--------------------------------------------------------------------------------
/api/common.js:
--------------------------------------------------------------------------------
1 | import { serverConfig } from '../utils/server';
2 | import store from '../store';
3 |
4 | export function handleFetchErrors(response) {
5 | // Errors before logging into the server will be ignored, since those don't represent bugs.
6 | const loggedIn = store.getState().appstate.onboardingStatus === 'loggedIn';
7 | if (!response.ok && loggedIn) {
8 | const errMsg = response.statusText || response.reason || '';
9 | throw Error(`Error calling ${response.url}. Status ${response.status}. ${errMsg}`);
10 | }
11 | return response;
12 | }
13 |
14 | export function makeFetch(opts) {
15 | const { url, method = 'GET', body = '', auth = true } = opts;
16 | const serverAuthHeader = auth ? serverConfig.getAuthHeader() : {};
17 | const init = {
18 | method,
19 | headers: {
20 | ...serverAuthHeader,
21 | 'Content-Type': 'application/json',
22 | },
23 | body,
24 | };
25 |
26 | return fetch(url, init)
27 | .then(handleFetchErrors)
28 | .then(response => (response.json()))
29 | .catch((error) => {
30 | throw error;
31 | });
32 | }
33 |
34 |
35 | export const makeRequest = (apiURL, isLocal = true) => {
36 | const authHeader = serverConfig.getAuthHeader();
37 | const headers = {
38 | method: 'GET',
39 | headers: isLocal ? authHeader : {},
40 | };
41 | return fetch(
42 | apiURL,
43 | headers,
44 | )
45 | .then(handleFetchErrors)
46 | .then(response => (response.json()))
47 | .catch((err) => {
48 | console.log(`Error with ${apiURL} is ${err}`);
49 | return {};
50 | });
51 | };
52 |
--------------------------------------------------------------------------------
/api/featured.js:
--------------------------------------------------------------------------------
1 | import { take } from 'lodash';
2 |
3 | import { promoAPI } from './const';
4 |
5 | import { shuffle } from '../utils/listings';
6 |
7 | export const fetchFeatured = () =>
8 | fetch(`${promoAPI}`)
9 | .then(response => (response.json()))
10 | .then(data => take(shuffle(data.filter(({ peerid }) => peerid !== '').map(({ peerid }) => peerid)), 4),
11 | );
12 |
--------------------------------------------------------------------------------
/api/hash.js:
--------------------------------------------------------------------------------
1 | import { gatewayAPI } from './const';
2 | import { makeFetch } from './common';
3 |
4 | // Block a store
5 | export const getHashCode = content => makeFetch({
6 | url: `${gatewayAPI}/ob/hashmessage/`,
7 | method: 'POST',
8 | body: JSON.stringify({ content }),
9 | });
10 |
--------------------------------------------------------------------------------
/api/images.js:
--------------------------------------------------------------------------------
1 | import { gatewayAPI } from './const';
2 | import { serverConfig } from '../utils/server';
3 |
4 | const base64 = require('base-64');
5 |
6 | // Upload an image
7 | export const uploadImage = (username, password, image) => {
8 | const serverToken = serverConfig.getServerToken();
9 | const headers = {
10 | method: 'POST',
11 | headers: {
12 | authorization: `Basic ${base64.encode(`${username}:${password}`)}`,
13 | cookie: `OpenBazaar_Auth_Cookie=${serverToken}`,
14 | 'Content-Type': 'application/json',
15 | },
16 | body: JSON.stringify([image]),
17 | };
18 | return fetch(
19 | `${gatewayAPI}/ob/images`,
20 | headers,
21 | ).then(response => (response.json()))
22 | .catch((err) => {
23 | console.log(err);
24 | return [];
25 | });
26 | };
27 |
--------------------------------------------------------------------------------
/api/mock/index.js:
--------------------------------------------------------------------------------
1 | import Mock from 'react-native-fetch-mock';
2 |
3 | import { gatewayAPI } from '../const';
4 | import WALLET_BALANCE_MOCK from './wallet_balance.json';
5 | import WALLET_ESTIMATE_FEE_MOCK from './wallet_estimatefee_coin.json';
6 | import WALLET_FEES_MOCK from './wallet_fees.json';
7 | import WALLET_SPEND_MOCK from './wallet_spend.json';
8 | import WALLET_TRANSACTIONS_FAIL_MOCK from './wallet_transactions_coin_fail.json';
9 | import WALLET_TRANSACTIONS_MOCK from './wallet_transactions_coin.json';
10 | import LISTING_CREATE_MOCK from './create_listing.json';
11 |
12 | export const MOCK_FOR_ETH = false;
13 | export const MOCK_WALLET_TRANSACTION_FAIL = false;
14 |
15 | const mockSpec = {
16 | [`${gatewayAPI}/wallet/balance`]: () => WALLET_BALANCE_MOCK,
17 | [`${gatewayAPI}/wallet/fees`]: () => WALLET_FEES_MOCK,
18 | [`${gatewayAPI}/wallet/estimatefee/ETH`]: () => WALLET_ESTIMATE_FEE_MOCK,
19 | [`POST ${gatewayAPI}/wallet/spend`]: () => WALLET_SPEND_MOCK,
20 | [`${gatewayAPI}/wallet/transactions/eth`]: () => (
21 | MOCK_WALLET_TRANSACTION_FAIL ? WALLET_TRANSACTIONS_FAIL_MOCK : WALLET_TRANSACTIONS_MOCK
22 | ),
23 | [`POST ${gatewayAPI}/ob/listing`]: () => LISTING_CREATE_MOCK,
24 | };
25 |
26 | if (MOCK_FOR_ETH) {
27 | global.fetch = new Mock(mockSpec, {
28 | fetch: global.fetch,
29 | }).fetch;
30 | }
31 |
--------------------------------------------------------------------------------
/api/mock/wallet_estimatefee_coin.json:
--------------------------------------------------------------------------------
1 | {
2 | "estimatedFee": {
3 | "amount": "53000000000000",
4 | "currency": {
5 | "code": "ETH",
6 | "currencyType": "crypto",
7 | "divisibility": 18,
8 | "name": "Ethereum",
9 | "testnetCode": ""
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/api/mock/wallet_spend.json:
--------------------------------------------------------------------------------
1 | {
2 | "amount": {
3 | "amount": "13065",
4 | "currency": {
5 | "code": "LTC",
6 | "currencyType": "crypto",
7 | "divisibility": 8,
8 | "name": "Litecoin",
9 | "testnetCode": "TLTC"
10 | }
11 | },
12 | "confirmedBalance": {
13 | "amount": "521956",
14 | "currency": {
15 | "code": "LTC",
16 | "currencyType": "crypto",
17 | "divisibility": 8,
18 | "name": "Litecoin",
19 | "testnetCode": "TLTC"
20 | }
21 | },
22 | "memo": "Test spend",
23 | "orderId": "",
24 | "timestamp": "2019-08-30T16:51:49-04:00",
25 | "txid": "b6ed7af5e7d102270a4282dcc3b7851a0cfd7a81f04a5b988feef986a128481e",
26 | "unconfirmedBalance": {
27 | "amount": "0",
28 | "currency": {
29 | "code": "LTC",
30 | "currencyType": "crypto",
31 | "divisibility": 8,
32 | "name": "Litecoin",
33 | "testnetCode": "TLTC"
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/api/mock/wallet_transactions_coin.json:
--------------------------------------------------------------------------------
1 | {
2 | "count": 1,
3 | "transactions": [
4 | {
5 | "address": "",
6 | "canBumpFee": true,
7 | "confirmations": 1,
8 | "errorMessage": "",
9 | "height": 5081146,
10 | "memo": "",
11 | "orderId": "",
12 | "status": "CONFIRMED",
13 | "thumbnail": "",
14 | "timestamp": "2019-09-13T06:25:28Z",
15 | "txid": "0x8e72a75c567ca30d054d286ebe336eb73e27866b8bed173d35adfca3755f0939",
16 | "value": "300000000000000000"
17 | }
18 | ]
19 | }
--------------------------------------------------------------------------------
/api/mock/wallet_transactions_coin_fail.json:
--------------------------------------------------------------------------------
1 | {
2 | "count": 0
3 | }
--------------------------------------------------------------------------------
/api/profile.js:
--------------------------------------------------------------------------------
1 | import { isEmpty } from 'lodash';
2 |
3 | import { gatewayAPI, searchAPI } from './const';
4 | import { serverConfig } from '../utils/server';
5 | import { makeFetch } from './common';
6 |
7 | export const getProfile = (peerID = '') => {
8 | // Fetch the user or store profile
9 |
10 | let apiURL = '';
11 | const timestamp = Date.now();
12 | if (isEmpty(peerID)) {
13 | apiURL = `${gatewayAPI}/ob/profile?async=true`;
14 | } else {
15 | apiURL = `${searchAPI}/profile/${peerID}?${timestamp}`;
16 | }
17 | const headers = {
18 | method: 'GET',
19 | headers: isEmpty(peerID) ? serverConfig.getAuthHeader() : {},
20 | };
21 | return fetch(
22 | apiURL,
23 | headers,
24 | )
25 | .then((response) => {
26 | if (response.status === 404) {
27 | return null;
28 | } else {
29 | return response.json();
30 | }
31 | });
32 | };
33 |
34 | // Set the user's profile
35 | export const setProfile = profile => makeFetch({
36 | url: `${gatewayAPI}/ob/profile`,
37 | method: 'PUT',
38 | body: JSON.stringify({ ...profile, vendor: true }),
39 | });
40 |
41 | // Set the user's accepted coins
42 | export const setCoins = coins => makeFetch({
43 | url: `${gatewayAPI}/ob/bulkupdatecurrency`,
44 | method: 'POST',
45 | body: JSON.stringify({ currencies: coins }),
46 | });
47 |
48 | export const reportProfile = (peerID, reason, slug = '', report_type = 'node') => {
49 | const headers = {
50 | method: 'POST',
51 | body: JSON.stringify({ peerID, reason, slug, report_type }),
52 | };
53 | return fetch(`${searchAPI}/reports`, headers);
54 | };
55 |
--------------------------------------------------------------------------------
/api/profiles.js:
--------------------------------------------------------------------------------
1 | import { stringify } from 'query-string';
2 |
3 | import { obEthGatewayAPI } from './const';
4 |
5 | // Fetch batch profiles
6 | export const getProfiles = (peerIDList, async = false) => {
7 | const timestamp = Date.now();
8 | const searchQuery = { async };
9 | const queryString = stringify(searchQuery);
10 | const apiURL = `${obEthGatewayAPI}/ob/fetchprofiles?${queryString}&${timestamp}`;
11 |
12 | const headers = {
13 | method: 'POST',
14 | headers: {
15 | 'Content-Type': 'application/json',
16 | },
17 | body: JSON.stringify(peerIDList),
18 | };
19 | return fetch(apiURL, headers)
20 | .then(response => response.json())
21 | .catch(err => err);
22 | };
23 |
--------------------------------------------------------------------------------
/api/promo.js:
--------------------------------------------------------------------------------
1 | import { promoAPI } from './const';
2 |
3 | export const fetchPromo = () =>
4 | fetch(`${promoAPI}`)
5 | .then(response => (response.json()));
6 |
--------------------------------------------------------------------------------
/api/publish.js:
--------------------------------------------------------------------------------
1 |
2 | import { gatewayAPI, searchAPI } from './const';
3 | import { serverConfig } from '../utils/server';
4 |
5 | const base64 = require('base-64');
6 |
7 | export const publish = (username, password) => {
8 | const serverToken = serverConfig.getServerToken();
9 | const headers = {
10 | method: 'POST',
11 | headers: {
12 | authorization: `Basic ${base64.encode(`${username}:${password}`)}`,
13 | cookie: `OpenBazaar_Auth_Cookie=${serverToken}`,
14 | 'Content-Type': 'application/json',
15 | },
16 | };
17 | return fetch(
18 | `${gatewayAPI}/ob/publish`,
19 | headers,
20 | ).then(response => (response.json()))
21 | .catch(err => (err));
22 | };
23 |
24 | export const ingestPeer = (peerID, body) => {
25 | const headers = {
26 | method: 'PUT',
27 | headers: {
28 | 'Content-Type': 'application/json',
29 | },
30 | body: JSON.stringify(body),
31 | };
32 | return fetch(`${searchAPI}/ipns/${peerID}`, headers)
33 | .then(response => (response.json()))
34 | .catch(err => (err));
35 | };
36 |
37 | export const resolveIpns = (peerID, username, password) => {
38 | const serverToken = serverConfig.getServerToken();
39 | const headers = {
40 | method: 'GET',
41 | headers: {
42 | authorization: `Basic ${base64.encode(`${username}:${password}`)}`,
43 | cookie: `OpenBazaar_Auth_Cookie=${serverToken}`,
44 | 'Content-Type': 'application/json',
45 | },
46 | };
47 | return fetch(`${gatewayAPI}/ob/resolveipns`, headers)
48 | .then(response => (response.json()))
49 | .catch(err => err);
50 | };
51 |
--------------------------------------------------------------------------------
/api/signing.js:
--------------------------------------------------------------------------------
1 |
2 | import { gatewayAPI } from './const';
3 | import { serverConfig } from '../utils/server';
4 |
5 | export const signMessage = (content) => {
6 | const apiURL = `${gatewayAPI}/ob/signmessage`;
7 | const headers = {
8 | method: 'POST',
9 | headers: serverConfig.getAuthHeader(),
10 | body: JSON.stringify({ content }),
11 | };
12 | return fetch(apiURL, headers).then(response => response.json());
13 | };
14 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "NativeBazaar",
3 | "displayName": "NativeBazaar"
4 | }
--------------------------------------------------------------------------------
/appcenter-post-clone.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # fail if any commands fails
3 | set -e
4 | # debug log
5 | set -x
6 |
7 | # write your script here
8 | echo "Post clone script!"
9 |
--------------------------------------------------------------------------------
/appcenter-pre-build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # fail if any commands fails
3 | set -e
4 | # debug log
5 | set -x
6 |
7 | # write your script here
8 | echo "Ionicons fix!"
9 | rm -f ./node_modules/react-native/local-cli/core/__fixtures__/files/package.json
10 |
11 | # or run a script from your repository, like:
12 | # bash ./path/to/script.sh
13 | # not just bash, e.g.:
14 | # ruby ./path/to/script.rb
15 |
16 | echo "\nInstalling Pods...\n"
17 | cd ios
18 | pod install --repo-update
19 | cd ..
20 | echo "\nFinished installing Pods.\n"
--------------------------------------------------------------------------------
/assets/icons/check-decagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/check-decagram.png
--------------------------------------------------------------------------------
/assets/icons/coupon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/coupon.png
--------------------------------------------------------------------------------
/assets/icons/crypto/BCH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/BCH.png
--------------------------------------------------------------------------------
/assets/icons/crypto/BTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/BTC.png
--------------------------------------------------------------------------------
/assets/icons/crypto/ETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/ETH.png
--------------------------------------------------------------------------------
/assets/icons/crypto/LNlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/LNlogo.png
--------------------------------------------------------------------------------
/assets/icons/crypto/LTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/LTC.png
--------------------------------------------------------------------------------
/assets/icons/crypto/ZEC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/ZEC.png
--------------------------------------------------------------------------------
/assets/icons/crypto/coinbase.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/coinbase.png
--------------------------------------------------------------------------------
/assets/icons/crypto/shapeshift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/crypto/shapeshift.png
--------------------------------------------------------------------------------
/assets/icons/linkNewTab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/linkNewTab.png
--------------------------------------------------------------------------------
/assets/icons/person_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/person_add.png
--------------------------------------------------------------------------------
/assets/icons/qrcode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/qrcode.png
--------------------------------------------------------------------------------
/assets/icons/shipping.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/shipping.png
--------------------------------------------------------------------------------
/assets/icons/transaction_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/icons/transaction_icon.png
--------------------------------------------------------------------------------
/assets/images/backup_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/backup_image.png
--------------------------------------------------------------------------------
/assets/images/cameraPlaceholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/cameraPlaceholder.png
--------------------------------------------------------------------------------
/assets/images/categories/Apparel_Accessories.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Apparel_Accessories.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Automobiles_Motorcycles.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Automobiles_Motorcycles.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Beauty_Health.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Beauty_Health.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Books.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Books.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Cellphones_Telecommunications.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Cellphones_Telecommunications.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Computer_Office.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Computer_Office.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Consumer_Electronics.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Consumer_Electronics.jpeg
--------------------------------------------------------------------------------
/assets/images/categories/Electronic_Components_Supplies.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Electronic_Components_Supplies.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Furniture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Furniture.png
--------------------------------------------------------------------------------
/assets/images/categories/Gift_Cards.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Gift_Cards.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Hair_Extensions_Wigs.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Hair_Extensions_Wigs.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Home_Appliances.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Home_Appliances.jpeg
--------------------------------------------------------------------------------
/assets/images/categories/Home_Garden.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Home_Garden.jpeg
--------------------------------------------------------------------------------
/assets/images/categories/Home_Improvement.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Home_Improvement.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Jewelry_Accessories.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Jewelry_Accessories.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Lights_Lighting.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Lights_Lighting.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Luggage_Bags.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Luggage_Bags.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Mens_Clothing.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Mens_Clothing.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Mother_Kids.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Mother_Kids.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Novelty_Special_Use.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Novelty_Special_Use.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Office_School_Supplies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Office_School_Supplies.png
--------------------------------------------------------------------------------
/assets/images/categories/Other.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Other.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Security_Protection.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Security_Protection.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Shoes.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Shoes.jpeg
--------------------------------------------------------------------------------
/assets/images/categories/Sports_Entertainment.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Sports_Entertainment.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Tools.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Tools.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Toys_Hobbies.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Toys_Hobbies.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Underwear_Sleepwear.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Underwear_Sleepwear.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Watches.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Watches.jpeg
--------------------------------------------------------------------------------
/assets/images/categories/Wedding_Events.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Wedding_Events.jpg
--------------------------------------------------------------------------------
/assets/images/categories/Womens_Clothing.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/categories/Womens_Clothing.jpg
--------------------------------------------------------------------------------
/assets/images/defaultAvatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/defaultAvatar.png
--------------------------------------------------------------------------------
/assets/images/defaultHeader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/defaultHeader.png
--------------------------------------------------------------------------------
/assets/images/defaultItem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/defaultItem.png
--------------------------------------------------------------------------------
/assets/images/listing_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/listing_fail.png
--------------------------------------------------------------------------------
/assets/images/logo/brand-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/logo/brand-logo.png
--------------------------------------------------------------------------------
/assets/images/logo/brand-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/logo/brand-logo@2x.png
--------------------------------------------------------------------------------
/assets/images/logo/brand-logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/logo/brand-logo@3x.png
--------------------------------------------------------------------------------
/assets/images/logo/splash-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/logo/splash-logo.png
--------------------------------------------------------------------------------
/assets/images/logo/splash-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/logo/splash-logo@2x.png
--------------------------------------------------------------------------------
/assets/images/logo/splash-logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/logo/splash-logo@3x.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/blueChat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/blueChat.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/blueProfile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/blueProfile.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/blueRepost.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/blueRepost.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/blueThumbsUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/blueThumbsUp.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/greenTag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/greenTag.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/greyShoppingCart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/greyShoppingCart.png
--------------------------------------------------------------------------------
/assets/images/notificationIcons/redGavel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/notificationIcons/redGavel.png
--------------------------------------------------------------------------------
/assets/images/onboardingBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/onboardingBackground.png
--------------------------------------------------------------------------------
/assets/images/privacyBottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/privacyBottom.png
--------------------------------------------------------------------------------
/assets/images/privacyShield.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/privacyShield.png
--------------------------------------------------------------------------------
/assets/images/restore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/restore.png
--------------------------------------------------------------------------------
/assets/images/restore@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/restore@2x.png
--------------------------------------------------------------------------------
/assets/images/restore@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/restore@3x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-chat-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-chat-bg.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-chat-inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-chat-inactive.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-chat-inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-chat-inactive@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-chat.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-home-inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-home-inactive.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-home-inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-home-inactive@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-home.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-home@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-home@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-social-inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-social-inactive.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-social-inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-social-inactive@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-social.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-social.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-social@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-social@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-store-inactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-store-inactive.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-store-inactive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-store-inactive@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-store.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-store.png
--------------------------------------------------------------------------------
/assets/images/tab/icon-store@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/icon-store@2x.png
--------------------------------------------------------------------------------
/assets/images/tab/wallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/tab/wallet.png
--------------------------------------------------------------------------------
/assets/images/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/upload.png
--------------------------------------------------------------------------------
/assets/images/upload@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/upload@2x.png
--------------------------------------------------------------------------------
/assets/images/upload@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/upload@3x.png
--------------------------------------------------------------------------------
/assets/images/wyre_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/wyre_logo.png
--------------------------------------------------------------------------------
/assets/images/wyre_logo_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/images/wyre_logo_2.png
--------------------------------------------------------------------------------
/assets/slider1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/slider1.png
--------------------------------------------------------------------------------
/assets/slider2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/slider2.png
--------------------------------------------------------------------------------
/assets/slider3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/assets/slider3.png
--------------------------------------------------------------------------------
/components/atoms/AddItemTrigger.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/components/atoms/AddItemTrigger.js
--------------------------------------------------------------------------------
/components/atoms/Badge.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 |
4 | const styles = {
5 | wrapper: {
6 | paddingHorizontal: 6,
7 | height: 20,
8 | borderRadius: 1,
9 | alignItems: 'center',
10 | justifyContent: 'center',
11 | },
12 | text: {
13 | fontSize: 11,
14 | fontWeight: 'bold',
15 | fontStyle: 'normal',
16 | letterSpacing: 0,
17 | },
18 | };
19 |
20 | export default ({
21 | style, backgroundColor = '#00BF65', color = '#FFFFFF', text,
22 | }) => (
23 |
24 | {text}
25 |
26 | );
27 |
--------------------------------------------------------------------------------
/components/atoms/CatListItem.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Image, Text, View } from 'react-native';
3 |
4 | import { primaryTextColor, bgHightlightColor, borderColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | flexDirection: 'row',
9 | height: 72,
10 | alignItems: 'center',
11 | },
12 | text: {
13 | fontSize: 16,
14 | fontWeight: 'bold',
15 | letterSpacing: 0,
16 | color: primaryTextColor,
17 | },
18 | image: {
19 | width: 44,
20 | height: 44,
21 | marginLeft: 16,
22 | marginRight: 12,
23 | backgroundColor: borderColor,
24 | borderRadius: 22,
25 | },
26 | };
27 |
28 | export default ({ item, onPress }) => (
29 |
30 |
31 |
32 | {item.title}
33 |
34 |
35 | );
36 |
--------------------------------------------------------------------------------
/components/atoms/CatSliderItem.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Image, Text, View, Dimensions } from 'react-native';
3 |
4 | import { secondaryTextColor, borderColor } from '../commonColors';
5 |
6 | const { width: screenWidth } = Dimensions.get('screen');
7 |
8 | const styles = {
9 | wrapper: {
10 | width: screenWidth / 5,
11 | height: 65,
12 | alignItems: 'center',
13 | justifyContent: 'center',
14 | paddingTop: 0,
15 | },
16 | text: {
17 | fontSize: 12,
18 | color: secondaryTextColor,
19 | },
20 | image: {
21 | width: 44,
22 | height: 44,
23 | marginBottom: 5,
24 | backgroundColor: borderColor,
25 | borderRadius: 22,
26 | },
27 | };
28 |
29 | export default ({ item, onPress }) => (
30 |
31 |
32 |
33 | {item.short || item.name}
34 |
35 |
36 | );
37 |
--------------------------------------------------------------------------------
/components/atoms/ChatNavIcon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import { View } from 'react-native';
4 | import Feather from 'react-native-vector-icons/Feather';
5 |
6 | import NotificationBadge from './NotificationBadge';
7 | import { tabBadgeStyle } from '../../utils/navbar';
8 | import { chatsMap } from '../../selectors/chat';
9 |
10 | const styles = {
11 | iconWrapper: {
12 | flex: 1,
13 | justifyContent: 'center',
14 | alignItems: 'center',
15 | width: 35,
16 | },
17 | };
18 |
19 | class ChatNavIcon extends React.PureComponent {
20 | render() {
21 | const { focused, chats } = this.props;
22 | const unreads = chats.data.reduce((result, item) => (result + (item.unread > 0 ? 1 : 0)), 0);
23 |
24 | return (
25 |
26 |
27 |
31 |
32 | );
33 | }
34 | }
35 |
36 | const mapStateToProps = chatsMap;
37 |
38 | export default connect(mapStateToProps)(ChatNavIcon);
39 |
--------------------------------------------------------------------------------
/components/atoms/CheckBox.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text, TouchableWithoutFeedback } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 | import { borderColor, brandColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | flexDirection: 'row',
9 | paddingVertical: 20,
10 | alignItems: 'center',
11 | },
12 | checkWrapper: {
13 | width: 18,
14 | height: 18,
15 | borderWidth: 2,
16 | borderRadius: 2,
17 | alignItems: 'center',
18 | justifyContent: 'center',
19 | marginRight: 6,
20 | },
21 | title: {
22 | fontSize: 15,
23 | fontWeight: 'normal',
24 | color: '#000',
25 | },
26 | };
27 |
28 | export default ({ checked, title, onPress }) => (
29 |
30 |
31 |
32 | {checked && }
33 |
34 | {title}
35 |
36 |
37 | );
38 |
--------------------------------------------------------------------------------
/components/atoms/CheckGroup.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { FlatList, View, TouchableWithoutFeedback } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { brandColor } from '../commonColors';
6 |
7 | const styles = {
8 | radioWrapper: {
9 | flexDirection: 'row',
10 | paddingHorizontal: 16,
11 | alignItems: 'center',
12 | },
13 | };
14 |
15 | export default class CheckGroup extends PureComponent {
16 | isSelected = (val) => {
17 | const { selected, compare } = this.props;
18 | return selected.find(o => compare(val, o));
19 | }
20 |
21 | renderItem = ({ item }) => {
22 | const { onChange, renderItem } = this.props;
23 | return (
24 | onChange(item, !this.isSelected(item))}
26 | key={`cg_${item.value}`}
27 | >
28 |
29 | {renderItem(item)}
30 |
31 | {this.isSelected(item) && }
32 |
33 |
34 | );
35 | }
36 |
37 | render() {
38 | const { options } = this.props;
39 | return (
40 |
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/components/atoms/DescriptionText.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Text } from 'react-native';
3 |
4 | const textStyle = {
5 | marginVertical: 16,
6 | fontSize: 15,
7 | color: '#404040',
8 | lineHeight: 26,
9 | };
10 |
11 | export default ({ children, style }) => (
12 |
13 | {children}
14 |
15 | );
16 |
--------------------------------------------------------------------------------
/components/atoms/EditProfileBanner.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { View } from 'react-native';
3 |
4 | import SaveButton from './FullButton';
5 |
6 | const styles = {
7 | wrapper: {
8 | backgroundColor: 'white',
9 | flexDirection: 'row',
10 | alignItems: 'center',
11 | borderTopWidth: 1,
12 | borderColor: '#e8e8e8',
13 | },
14 | leftSpacer: {
15 | flex: 5,
16 | alignSelf: 'center',
17 | paddingLeft: 16,
18 | },
19 | saveButtonContainer: {
20 | flex: 3,
21 | },
22 | saveButton: {
23 | backgroundColor: '#00bf65',
24 | marginLeft: 0,
25 | },
26 | };
27 |
28 | class EditProfileBanner extends PureComponent {
29 | render() {
30 | const { onSave } = this.props;
31 | return (
32 |
33 |
34 |
35 |
40 |
41 |
42 | );
43 | }
44 | }
45 |
46 | export default EditProfileBanner;
47 |
--------------------------------------------------------------------------------
/components/atoms/FilterButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, View } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { primaryTextColor, borderColor, foregroundColor } from '../commonColors';
6 |
7 | const wrapperStyle = {
8 | paddingHorizontal: 10,
9 | };
10 |
11 | export default ({ disabled, onPress, secondary }) => (
12 |
13 |
14 |
19 |
20 |
21 | );
22 |
--------------------------------------------------------------------------------
/components/atoms/FormLabelText.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Text, View } from 'react-native';
3 |
4 | import Badge from './Badge';
5 | import { formLabelColor, brandColor, bgHightlightColor } from '../commonColors';
6 |
7 | const styles = {
8 | text: {
9 | fontSize: 15,
10 | fontWeight: 'normal',
11 | fontStyle: 'normal',
12 | letterSpacing: 0,
13 | textAlign: 'left',
14 | color: formLabelColor,
15 | paddingVertical: 20,
16 | minWidth: 150,
17 | },
18 | wrapper: {
19 | flexDirection: 'row',
20 | alignItems: 'center',
21 | height: 60,
22 | },
23 | coinsValue: {
24 | fontSize: 15,
25 | color: 'black',
26 | },
27 | };
28 |
29 | export default ({ text, value, style, isBeta }) => {
30 | if (!value) {
31 | return (
32 |
33 | {text}
34 | {isBeta && (
35 |
36 | )}
37 |
38 | );
39 | }
40 |
41 | return (
42 |
43 | {text}
44 | {value}
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/components/atoms/FullButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Text, View, ActivityIndicator } from 'react-native';
3 |
4 | import { brandColor, foregroundColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | backgroundColor: brandColor,
9 | margin: 15,
10 | padding: 12,
11 | justifyContent: 'center',
12 | borderRadius: 2,
13 | },
14 | text: {
15 | color: foregroundColor,
16 | fontSize: 16,
17 | lineHeight: 22,
18 | fontWeight: 'bold',
19 | fontStyle: 'normal',
20 | letterSpacing: 0,
21 | textAlign: 'center',
22 | },
23 | disabled: {
24 | opacity: 0.3,
25 | },
26 | };
27 |
28 | export default ({
29 | title, onPress, wrapperStyle, textStyle, disabled, loading,
30 | }) => (
31 |
35 |
36 | {loading ? (
37 |
38 | ) : (
39 |
40 | {title}
41 |
42 | )}
43 |
44 |
45 | );
46 |
--------------------------------------------------------------------------------
/components/atoms/HollowButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Text, View } from 'react-native';
3 | import { primaryTextColor } from '../commonColors';
4 |
5 | const styles = {
6 | wrapper: {
7 | minWidth: 250,
8 | height: 29,
9 | borderRadius: 2,
10 | backgroundColor: '#ffffff',
11 | borderStyle: 'solid',
12 | borderWidth: 1,
13 | borderColor: '#c8c7cc',
14 | alignItems: 'center',
15 | justifyContent: 'center',
16 | },
17 | title: {
18 | fontSize: 13,
19 | fontWeight: 'bold',
20 | fontStyle: 'normal',
21 | letterSpacing: 0,
22 | textAlign: 'center',
23 | color: primaryTextColor,
24 | },
25 | small: {
26 | minWidth: 83,
27 | },
28 | };
29 |
30 | export default ({
31 | style, title, onPress, small,
32 | }) => (
33 |
36 |
37 | {title}
38 |
39 |
40 | );
41 |
--------------------------------------------------------------------------------
/components/atoms/ImageButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, View } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 | import { borderColor, formLabelColor } from '../commonColors';
5 |
6 | const styles = {
7 | button: {
8 | width: 46,
9 | height: 33,
10 | borderRadius: 2,
11 | borderWidth: 1,
12 | borderColor,
13 | alignItems: 'center',
14 | justifyContent: 'center',
15 | },
16 | };
17 |
18 | export default ({ onPress }) => (
19 |
20 |
21 |
22 |
23 |
24 | );
25 |
--------------------------------------------------------------------------------
/components/atoms/Inventory.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { View, Text } from 'react-native';
3 | import { primaryTextColor } from '../commonColors';
4 |
5 | const styles = {
6 | wrapper: {
7 | flexDirection: 'column',
8 | paddingVertical: 5,
9 | },
10 | sku: {
11 | fontSize: 12,
12 | fontWeight: 'bold',
13 | color: primaryTextColor,
14 | },
15 | surcharge: {
16 | fontSize: 12,
17 | color: primaryTextColor,
18 | },
19 | stock: {
20 | fontSize: 12,
21 | color: primaryTextColor,
22 | },
23 | };
24 |
25 | export default class Inventory extends PureComponent {
26 | render() {
27 | const { inventory } = this.props;
28 | return (
29 |
30 |
31 | {inventory.productId}
32 |
33 |
34 | {`Surcharge: $${inventory.surcharge}`}
35 |
36 |
37 | {`Stock: ${inventory.quantity === -1 ? 'Unlimited' : inventory.quantity}`}
38 |
39 |
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/components/atoms/LinkText.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { brandColor } from '../commonColors';
6 |
7 | const styles = {
8 | wrapper: {
9 | flexDirection: 'row',
10 | alignItems: 'center',
11 | },
12 | text: {
13 | fontSize: 16,
14 | fontWeight: 'normal',
15 | fontStyle: 'normal',
16 | letterSpacing: 0,
17 | textAlign: 'right',
18 | color: brandColor,
19 | padding: 10,
20 | },
21 | arrowStyle: {
22 | paddingRight: 15,
23 | },
24 | arrowWrapper: {
25 | paddingRight: 20,
26 | },
27 | bold: {
28 | fontWeight: 'bold',
29 | textTransform: 'uppercase',
30 | },
31 | arrow: {
32 | marginTop: 2,
33 | },
34 | };
35 |
36 | export default ({
37 | style, text, color, fontSize, withArrow, bold,
38 | }) => (
39 |
40 |
50 | {text}
51 |
52 | {withArrow && }
53 |
54 | );
55 |
--------------------------------------------------------------------------------
/components/atoms/ListingTitlePrice.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import { View, Text } from 'react-native';
4 |
5 | import { primaryTextColor } from '../commonColors';
6 | import { priceStyle } from '../commonStyles';
7 |
8 | import { convertorsMap } from '../../selectors/currency';
9 |
10 | const styles = {
11 | wrapper: {
12 | flexDirection: 'row',
13 | alignItems: 'center',
14 | justifyContent: 'space-between',
15 | paddingVertical: 14,
16 | },
17 | title: {
18 | fontSize: 15,
19 | fontWeight: 'normal',
20 | fontStyle: 'normal',
21 | letterSpacing: 0,
22 | color: primaryTextColor,
23 | flex: 1,
24 | marginRight: 15,
25 | },
26 | };
27 |
28 | export default connect(convertorsMap)(({
29 | title, price, currency, quantity, localLabelFromBCH,
30 | }) => (
31 |
32 |
33 | {title}
34 |
35 | {localLabelFromBCH(price * quantity, currency)}
36 |
37 | ));
38 |
--------------------------------------------------------------------------------
/components/atoms/LocationPin.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { Text } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 | import { isEmpty } from 'lodash';
5 |
6 | import { formLabelColor, locationPinColor } from '../commonColors';
7 |
8 | const styles = {
9 | location: {
10 | fontSize: 14,
11 | fontWeight: 'normal',
12 | fontStyle: 'normal',
13 | letterSpacing: 0,
14 | textAlign: 'left',
15 | color: formLabelColor,
16 | paddingTop: 2.5,
17 | paddingBottom: 10,
18 | maxWidth: 200,
19 | },
20 | secondary: {
21 | paddingTop: 6,
22 | paddingBottom: 6,
23 | },
24 | emptyLocation: {
25 | fontStyle: 'italic',
26 | },
27 | };
28 |
29 | class LocationPin extends PureComponent {
30 | render() {
31 | const { location, style, secondary } = this.props;
32 |
33 | return (
34 |
43 |
44 |
45 | {location || 'Unknown'}
46 |
47 | );
48 | }
49 | }
50 |
51 | export default LocationPin;
52 |
--------------------------------------------------------------------------------
/components/atoms/MainSliderContentLoader.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Dimensions } from 'react-native';
3 | import ContentLoader, { Rect } from 'react-content-loader/native';
4 | import { foregroundColor } from '../commonColors';
5 |
6 | const { width: SCREEN_WIDTH } = Dimensions.get('window');
7 |
8 | const IMAGE_RATIO = 328.0 / 750;
9 |
10 | const IMAGE_WIDTH = SCREEN_WIDTH - 16;
11 | const IMAGE_HEIGHT = SCREEN_WIDTH * IMAGE_RATIO - 16;
12 |
13 | const styles = {
14 | wrapper: {
15 | margin: 8,
16 | width: IMAGE_WIDTH,
17 | height: IMAGE_HEIGHT,
18 | },
19 | };
20 |
21 | export default () => (
22 |
23 |
30 |
38 |
39 |
40 | );
41 |
--------------------------------------------------------------------------------
/components/atoms/MainSliderItem.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, TouchableWithoutFeedback, Image, Dimensions } from 'react-native';
3 | import { withNavigation } from 'react-navigation';
4 |
5 | import { handleOBDeeplinkWithNavigation } from '../../utils/navigation';
6 |
7 | const { width } = Dimensions.get('window');
8 |
9 | const IMAGE_RATIO = 328.0 / 750;
10 |
11 | const styles = {
12 | wrapper: {
13 | margin: 8,
14 | width: width - 16,
15 | height: width * IMAGE_RATIO - 16,
16 | },
17 | image: {
18 | width: '100%',
19 | height: '100%',
20 | borderRadius: 5,
21 | overflow: 'hidden',
22 | borderStyle: 'solid',
23 | borderColor: '#E8E8E8',
24 | borderWidth: 1,
25 | },
26 | };
27 |
28 | class MainSliderItem extends React.PureComponent {
29 | handlePress = () => {
30 | const { link } = this.props.source;
31 | handleOBDeeplinkWithNavigation(link, this.props.navigation);
32 | }
33 |
34 | render() {
35 | const { source, onLoadEnd } = this.props;
36 | return (
37 |
38 |
39 |
40 |
41 |
42 | );
43 | }
44 | }
45 |
46 | export default withNavigation(MainSliderItem);
47 |
--------------------------------------------------------------------------------
/components/atoms/ModalBackButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Ionicons from 'react-native-vector-icons/Ionicons';
3 | import { TouchableWithoutFeedback, Platform, View } from 'react-native';
4 |
5 | import { navHeightStyle } from '../../utils/navbar';
6 |
7 | const styles = {
8 | modalBack: {
9 | position: 'absolute',
10 | width: 32,
11 | height: 32,
12 | marginTop: (navHeightStyle.height - 32) / 2,
13 | marginLeft: 10,
14 | paddingLeft: (Platform.OS === 'ios' ? 6 : 16),
15 | justifyContent: 'center',
16 | zIndex: 999,
17 | },
18 | icon: {
19 | justifyContent: 'flex-start',
20 | },
21 | };
22 |
23 | const ModalBackButton = ({ onPress }) => (
24 |
27 |
28 |
34 |
35 |
36 | );
37 |
38 | export default ModalBackButton;
39 |
--------------------------------------------------------------------------------
/components/atoms/ModalFavButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Ionicons from 'react-native-vector-icons/Ionicons';
3 | import { TouchableWithoutFeedback, Platform, View } from 'react-native';
4 |
5 | import { navHeightStyle } from '../../utils/navbar';
6 |
7 | const styles = {
8 | modalFav: {
9 | position: 'absolute',
10 | width: 32,
11 | height: 32,
12 | marginTop: (navHeightStyle.height - 32) / 2,
13 | right: 62,
14 | paddingLeft: (Platform.OS === 'ios' ? 6 : 10),
15 | justifyContent: 'center',
16 | zIndex: 999,
17 | },
18 | icon: {
19 | justifyContent: 'flex-start',
20 | },
21 | };
22 |
23 | const ModalFavButton = ({ selected, onPress }) => {
24 | let iconName = 'ios-star';
25 | if (Platform.OS === 'ios') {
26 | iconName = selected ? 'ios-star' : 'ios-star-outline';
27 | } else {
28 | iconName = selected ? 'md-star' : 'md-star-outline';
29 | }
30 | return (
31 |
34 |
35 |
41 |
42 |
43 | );
44 | };
45 |
46 | export default ModalFavButton;
47 |
--------------------------------------------------------------------------------
/components/atoms/ModalImageIndicator.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text, Platform } from 'react-native';
3 |
4 | import { navHeightStyle } from '../../utils/navbar';
5 |
6 | const styles = {
7 | modalClose: {
8 | position: 'absolute',
9 | height: 32,
10 | marginTop: (navHeightStyle.height - 32) / 2,
11 | marginLeft: 40,
12 | paddingLeft: (Platform.OS === 'ios' ? 6 : 16),
13 | justifyContent: 'center',
14 | zIndex: 999,
15 | },
16 | text: {
17 | color: '#FFFFFF',
18 | fontSize: 15,
19 | },
20 | };
21 |
22 | const ModalImageIndicator = ({ pos, size }) => (
23 |
24 |
25 | {pos + 1} of {size}
26 |
27 |
28 | );
29 |
30 | export default ModalImageIndicator;
31 |
--------------------------------------------------------------------------------
/components/atoms/ModalTooltip.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Animated, Text } from 'react-native';
3 |
4 | import { navHeightStyle } from '../../utils/navbar';
5 |
6 | const styles = {
7 | wrapper: {
8 | position: 'absolute',
9 | marginTop: navHeightStyle.height + 16,
10 | justifyContent: 'center',
11 | alignSelf: 'center',
12 | },
13 | tooltip: {
14 | width: 'auto',
15 | height: 26,
16 | paddingHorizontal: 16,
17 | paddingVertical: 6,
18 | backgroundColor: 'rgba(108, 108, 108, 0.5)',
19 | borderRadius: 13,
20 | },
21 | text: {
22 | fontSize: 11,
23 | color: 'white',
24 | },
25 | };
26 |
27 | export default class ModalTooltip extends React.Component {
28 | aniVal = new Animated.Value(0);
29 |
30 | show() {
31 | Animated.timing(
32 | this.aniVal,
33 | {
34 | toValue: 1,
35 | duration: 500,
36 | },
37 | ).start(() => {
38 | Animated.timing(
39 | this.aniVal,
40 | {
41 | toValue: 0,
42 | duration: 500,
43 | delay: 1000,
44 | },
45 | ).start();
46 | });
47 | }
48 |
49 | render() {
50 | const { text } = this.props;
51 | return (
52 |
53 |
61 |
62 | {text}
63 |
64 |
65 |
66 | );
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/components/atoms/ModalTrashButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Ionicons from 'react-native-vector-icons/Ionicons';
3 | import { TouchableWithoutFeedback, Platform, View } from 'react-native';
4 |
5 | import { navHeightStyle } from '../../utils/navbar';
6 |
7 | const styles = {
8 | modalTrash: {
9 | position: 'absolute',
10 | width: 32,
11 | height: 32,
12 | right: 20,
13 | marginTop: (navHeightStyle.height - 32) / 2,
14 | paddingLeft: (Platform.OS === 'ios' ? 6 : 16),
15 | justifyContent: 'center',
16 | zIndex: 999,
17 | },
18 | icon: {
19 | justifyContent: 'flex-start',
20 | },
21 | };
22 |
23 | const ModalTrashButton = ({ onPress }) => (
24 |
27 |
28 |
34 |
35 |
36 | );
37 |
38 | export default ModalTrashButton;
39 |
--------------------------------------------------------------------------------
/components/atoms/MoreButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Text, View } from 'react-native';
3 |
4 | const styles = {
5 | wrapper: {
6 | marginBottom: 20,
7 | },
8 | text: {
9 | fontSize: 14,
10 | fontWeight: 'bold',
11 | color: '#00bf65',
12 | },
13 | };
14 |
15 | export default ({ onPress, title }) => (
16 |
17 |
18 | + {title || 'More'}
19 |
20 |
21 | );
22 |
--------------------------------------------------------------------------------
/components/atoms/NavBackButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Platform, View, Animated } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { foregroundColor, primaryTextColor } from '../commonColors';
6 |
7 | const styles = {
8 | container: {
9 | width: 32,
10 | height: 32,
11 | justifyContent: 'center',
12 | },
13 | iosStyle: {
14 | paddingLeft: 9,
15 | },
16 | androidStyle: {
17 | textAlign: 'center',
18 | },
19 | };
20 |
21 | const NavBackButton = ({ white, animColor }) => {
22 | const IconComponent = animColor ? Animated.createAnimatedComponent(Ionicons) : Ionicons;
23 | const color = animColor || (white ? foregroundColor : primaryTextColor);
24 |
25 | return (Platform.OS === 'ios' ? (
26 |
27 |
33 |
34 | ) : (
35 |
36 |
42 |
43 | ));
44 | };
45 |
46 | export default NavBackButton;
47 |
--------------------------------------------------------------------------------
/components/atoms/NavCloseButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Platform, View } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { primaryTextColor } from '../commonColors';
6 |
7 | const styles = {
8 | container: {
9 | width: 32,
10 | height: 32,
11 | justifyContent: 'center',
12 | },
13 | iosStyle: {
14 | paddingHorizontal: 10,
15 | },
16 | androidStyle: {
17 | textAlign: 'center',
18 | },
19 | };
20 |
21 | const NavCloseButton = () =>
22 | (Platform.OS === 'ios' ? (
23 |
24 | ) : (
25 |
26 |
27 |
28 | ));
29 |
30 | export default NavCloseButton;
31 |
--------------------------------------------------------------------------------
/components/atoms/NavOptionButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import Icons from 'react-native-vector-icons/MaterialIcons';
4 |
5 | import { primaryTextColor, foregroundColor } from '../commonColors';
6 |
7 | const styles = {
8 | container: {
9 | width: 24,
10 | height: 32,
11 | justifyContent: 'center',
12 | },
13 | };
14 |
15 | const NavOptionButton = ({ white }) => (
16 |
17 |
22 |
23 | )
24 |
25 | export default NavOptionButton;
26 |
--------------------------------------------------------------------------------
/components/atoms/NavPlusButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | const styles = {
6 | container: {
7 | width: 32,
8 | height: 32,
9 | justifyContent: 'center',
10 | },
11 | };
12 |
13 | const NavPlusButton = () => (
14 |
15 |
20 |
21 | );
22 |
23 | export default NavPlusButton;
24 |
--------------------------------------------------------------------------------
/components/atoms/NavShareButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Platform, View, Animated } from 'react-native';
3 | import EvilIcons from 'react-native-vector-icons/EvilIcons';
4 |
5 | import { foregroundColor, primaryTextColor } from '../commonColors';
6 |
7 | const styles = {
8 | container: {
9 | width: 32,
10 | height: 32,
11 | justifyContent: 'center',
12 | },
13 | iosStyle: {
14 | textAlign: 'center',
15 | marginTop: 5,
16 | },
17 | androidStyle: {
18 | textAlign: 'center',
19 | },
20 | };
21 |
22 | const NavShareButton = ({ white, animColor }) => {
23 | const IconComponent = animColor ? Animated.createAnimatedComponent(EvilIcons) : EvilIcons;
24 | const color = animColor || (white ? foregroundColor : primaryTextColor);
25 |
26 | return (Platform.OS === 'ios' ? (
27 |
28 |
34 |
35 | ) : (
36 |
37 |
43 |
44 | ));
45 | };
46 |
47 | export default NavShareButton;
48 |
--------------------------------------------------------------------------------
/components/atoms/NotificationBadge.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 |
4 | import { brandColor } from '../commonColors';
5 | import { tabNotifBadgeSize } from '../../utils/navbar';
6 |
7 | const styles = {
8 | notifCount: {
9 | ...tabNotifBadgeSize,
10 | borderRadius: 14,
11 | alignItems: 'center',
12 | justifyContent: 'center',
13 | backgroundColor: brandColor,
14 | elevation: 4,
15 | borderWidth: 2,
16 | borderColor: 'white',
17 | },
18 | notifCountText: {
19 | textAlign: 'center',
20 | fontSize: 12,
21 | fontWeight: 'bold',
22 | fontStyle: 'normal',
23 | letterSpacing: 0,
24 | color: '#ffffff',
25 | },
26 | };
27 |
28 | export default ({ notifCount, style, noBorder }) => {
29 | if (!notifCount) {
30 | return null;
31 | }
32 |
33 | return (
34 |
35 |
36 | {`${notifCount}`}
37 |
38 |
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/components/atoms/OBFastImage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import FastImage from 'react-native-fast-image';
3 | import { get } from 'lodash';
4 |
5 | import { getImageSourceWithFallback } from '../../utils/files';
6 |
7 | export default class OBFastImage extends React.Component {
8 | state = { tryStatus: 'first' }
9 |
10 | onLoadFailed = () => {
11 | const { tryStatus } = this.state;
12 | switch (tryStatus) {
13 | case 'first':
14 | this.setState({ tryStatus: 'second' });
15 | break;
16 | case 'second':
17 | this.setState({ tryStatus: 'third' });
18 | break;
19 | default:
20 | break;
21 | }
22 | }
23 |
24 | render() {
25 | const { hash, ...rest } = this.props;
26 | const imageSource = getImageSourceWithFallback(hash);
27 | const { tryStatus } = this.state;
28 | return (
29 |
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/components/atoms/PlaceholderStyleTextInput.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { TextInput } from 'react-native';
3 |
4 | export default class PlaceholderStyleTextInput extends PureComponent {
5 | constructor(props) {
6 | super(props);
7 | this.state = { placeholder: props.value.length === 0 };
8 | this.handleChange = this.handleChange.bind(this);
9 | }
10 |
11 | handleChange(ev) {
12 | this.setState({ placeholder: ev.nativeEvent.text.length === 0 });
13 | const { onChange } = this.props;
14 | if (onChange) {
15 | onChange(ev);
16 | }
17 | }
18 |
19 | render() {
20 | const {
21 | placeholderStyle, style, onChange, inputRef, ...rest
22 | } = this.props;
23 |
24 | return ();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/components/atoms/PlusButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import { View, TouchableWithoutFeedback } from 'react-native';
4 | import Feather from 'react-native-vector-icons/Feather';
5 |
6 | import { brandColor } from '../commonColors';
7 |
8 | import { showPanel } from '../../reducers/appstate';
9 |
10 | const styles = {
11 | container: {
12 | width: '100%',
13 | flexDirection: 'row',
14 | alignItems: 'center',
15 | justifyContent: 'center',
16 | height: '100%',
17 | },
18 | wrapper: {
19 | width: 40,
20 | height: 40,
21 | justifyContent: 'center',
22 | alignItems: 'center',
23 | backgroundColor: brandColor,
24 | borderRadius: 20,
25 | },
26 | icon: {
27 | width: 24,
28 | height: 24,
29 | textAlign: 'center',
30 | },
31 | };
32 |
33 | class PlusButton extends React.PureComponent {
34 | onPress = () => {
35 | this.props.showPanel({ type: 'plus' });
36 | }
37 |
38 | render() {
39 | return (
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | );
48 | }
49 | }
50 |
51 | const mapDispatchToProps = {
52 | showPanel,
53 | };
54 |
55 | export default connect(
56 | null,
57 | mapDispatchToProps,
58 | )(PlusButton);
59 |
--------------------------------------------------------------------------------
/components/atoms/PostButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, ActivityIndicator, View, Text } from 'react-native';
3 | import { brandColor } from '../commonColors';
4 |
5 | const styles = {
6 | button: {
7 | width: 118,
8 | height: 33,
9 | borderRadius: 2,
10 | backgroundColor: brandColor,
11 | alignItems: 'center',
12 | justifyContent: 'center',
13 | },
14 | text: {
15 | fontSize: 14,
16 | color: 'white',
17 | textAlign: 'center',
18 | fontWeight: 'bold',
19 | },
20 | disabled: {
21 | opacity: 0.35,
22 | },
23 | };
24 |
25 | export default ({ disabled, loading, onPress }) => (
26 |
27 |
28 | {loading ? (
29 |
30 | ) : (
31 | Post
32 | )}
33 |
34 |
35 | );
36 |
--------------------------------------------------------------------------------
/components/atoms/ProductImage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import FastImage from 'react-native-fast-image';
4 | import Ionicons from 'react-native-vector-icons/Ionicons';
5 | import { get, isEmpty } from 'lodash';
6 |
7 | import { getImageSourceForSelector } from '../../utils/files';
8 | import { borderColor } from '../commonColors';
9 |
10 | const styles = {
11 | image: {
12 | width: 110,
13 | height: 110,
14 | borderRightWidth: 1,
15 | borderRightColor: borderColor,
16 | alignItems: 'center',
17 | justifyContent: 'center',
18 | },
19 | };
20 |
21 | export default ({ images }) => {
22 | const thumbnail = get(images, '[0].hashes.small');
23 | return isEmpty(thumbnail) ?
24 | (
25 |
26 |
27 |
28 | ) : (
29 |
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/components/atoms/ProductName.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 | import decode from 'unescape';
4 |
5 | import { primaryTextColor } from '../commonColors';
6 |
7 | const styles = {
8 | wrapper: {
9 | marginTop: 15,
10 | paddingHorizontal: 20,
11 | },
12 | text: {
13 | fontSize: 17,
14 | fontWeight: 'bold',
15 | fontStyle: 'normal',
16 | letterSpacing: 0,
17 | textAlign: 'left',
18 | color: primaryTextColor,
19 | },
20 | };
21 |
22 | export default ({ prodName }) => (
23 |
24 | {decode(prodName)}
25 |
26 | );
27 |
--------------------------------------------------------------------------------
/components/atoms/ProductTag.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Text, View } from 'react-native';
3 | import decode from 'unescape';
4 |
5 | import { primaryTextColor, foregroundColor } from '../commonColors';
6 |
7 | const styles = {
8 | wrapper: {
9 | paddingHorizontal: 11,
10 | paddingVertical: 11,
11 | borderRadius: 2,
12 | backgroundColor: foregroundColor,
13 | borderStyle: 'solid',
14 | borderWidth: 1,
15 | borderColor: '#c8c7cc',
16 | marginRight: 6,
17 | marginBottom: 6,
18 | },
19 | text: {
20 | fontSize: 13,
21 | fontWeight: 'bold',
22 | fontStyle: 'normal',
23 | letterSpacing: 0,
24 | textAlign: 'left',
25 | color: primaryTextColor,
26 | },
27 | };
28 |
29 | export default ({ tag, onPress }) => (
30 | onPress(tag)}>
31 |
32 | #{decode(tag)}
33 |
34 |
35 | );
36 |
--------------------------------------------------------------------------------
/components/atoms/Rating.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 | import { formLabelColor, starRatingColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | flexDirection: 'row',
9 | alignItems: 'center',
10 | paddingVertical: 5,
11 | },
12 | title: {
13 | width: 140,
14 | fontSize: 15,
15 | color: formLabelColor,
16 | },
17 | starWrapper: {
18 | flexDirection: 'row',
19 | alignItems: 'center',
20 | },
21 | star: {
22 | marginHorizontal: 3,
23 | },
24 | };
25 |
26 | export default ({ title, value }) => {
27 | const stars = [];
28 | for (let i = 0; i < 5; i += 1) {
29 | stars.push((
30 |
37 | ));
38 | }
39 | return (
40 |
41 |
42 | {title}
43 |
44 |
45 | { stars }
46 |
47 |
48 | );
49 | };
50 |
--------------------------------------------------------------------------------
/components/atoms/ResetFilter.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, TouchableWithoutFeedback, Text } from 'react-native';
3 |
4 | import { borderColor, primaryTextColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | flexDirection: 'row',
9 | alignItems: 'center',
10 | justifyContent: 'center',
11 | height: 60,
12 | borderTopWidth: 1,
13 | borderColor,
14 | },
15 | text: {
16 | fontSize: 15,
17 | color: primaryTextColor,
18 | fontWeight: 'bold',
19 | },
20 | };
21 |
22 | export default ({ onPress }) => (
23 |
24 | Reset filters
25 |
26 | );
27 |
--------------------------------------------------------------------------------
/components/atoms/SMRoundButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableWithoutFeedback, Text, View, ActivityIndicator } from 'react-native';
3 |
4 | import { brandColor, foregroundColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | backgroundColor: brandColor,
9 | margin: 15,
10 | paddingVertical: 8,
11 | justifyContent: 'center',
12 | borderRadius: 4,
13 | width: 150,
14 | },
15 | text: {
16 | color: foregroundColor,
17 | fontSize: 14,
18 | lineHeight: 22,
19 | fontWeight: 'bold',
20 | fontStyle: 'normal',
21 | letterSpacing: 0,
22 | textAlign: 'center',
23 | },
24 | disabled: {
25 | opacity: 0.3,
26 | },
27 | };
28 |
29 | export default ({
30 | title, onPress, wrapperStyle, textStyle, disabled, loading,
31 | }) => (
32 |
33 |
34 | {loading ? (
35 |
36 | ) : (
37 | {title}
38 | )}
39 |
40 |
41 | );
42 |
--------------------------------------------------------------------------------
/components/atoms/SMTextButton.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from 'react';
2 | import { TouchableWithoutFeedback, Text, View, ActivityIndicator } from 'react-native';
3 |
4 | import { brandColor, foregroundColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | backgroundColor: 'transparent',
9 | justifyContent: 'center',
10 | borderRadius: 4,
11 | flexDirection: 'row',
12 | alignItems: 'center',
13 | },
14 | text: {
15 | color: brandColor,
16 | fontSize: 15,
17 | lineHeight: 22,
18 | fontWeight: 'bold',
19 | fontStyle: 'normal',
20 | letterSpacing: 0,
21 | textAlign: 'center',
22 | },
23 | disabled: {
24 | opacity: 0.3,
25 | },
26 | loading: {
27 | marginLeft: 4,
28 | },
29 | };
30 |
31 | export default ({
32 | title, onPress, wrapperStyle, textStyle, disabled, loadingText,
33 | }) => (
34 |
35 |
36 | {loadingText || title}
37 | {loadingText && }
38 |
39 |
40 | );
41 |
--------------------------------------------------------------------------------
/components/atoms/SearchModalWrapper.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Dimensions, KeyboardAvoidingView } from 'react-native';
3 |
4 | import { navHeightStyle } from '../../utils/navbar';
5 | import { StatusBarSpacer } from '../../status-bar';
6 | import { keyboardAvoidingViewSharedProps } from '../../utils/keyboard';
7 |
8 | const { height, width } = Dimensions.get('window');
9 | const styles = {
10 | wrapper: {
11 | position: 'absolute',
12 | width,
13 | height: height - navHeightStyle.height,
14 | top: navHeightStyle.height,
15 | left: 0,
16 | },
17 | };
18 |
19 | export default props => (
20 |
21 |
22 | {props.children}
23 |
24 | );
25 |
--------------------------------------------------------------------------------
/components/atoms/SecureFund.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, TouchableWithoutFeedback, Text } from 'react-native';
3 |
4 | import { brandColor, primaryTextColor, bgHightlightColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | flexDirection: 'row',
9 | alignItems: 'center',
10 | justifyContent: 'space-between',
11 | padding: 16,
12 | backgroundColor: bgHightlightColor,
13 | },
14 | secureText: {
15 | fontSize: 15,
16 | fontWeight: 'bold',
17 | color: primaryTextColor,
18 | },
19 | button: {
20 | justifyContent: 'center',
21 | alignItems: 'center',
22 | height: 35,
23 | backgroundColor: '#fff',
24 | paddingHorizontal: 12,
25 | borderWidth: 1,
26 | borderRadius: 5,
27 | borderColor: brandColor,
28 | },
29 | btnText: {
30 | fontSize: 13,
31 | fontWeight: 'bold',
32 | letterSpacing: 0,
33 | textAlign: 'center',
34 | color: brandColor,
35 | lineHeight: 35,
36 | height: 35,
37 | },
38 | };
39 |
40 | export default ({ onBackup }) => (
41 |
42 | Secure your funds
43 |
44 |
45 | Backup wallet
46 |
47 |
48 |
49 | );
50 |
--------------------------------------------------------------------------------
/components/atoms/Stars.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 | import { starRatingColor } from '../commonColors';
5 |
6 | const styles = {
7 | starContainer: {
8 | flexDirection: 'row',
9 | },
10 | };
11 |
12 | export default ({ score }) => {
13 | const nodes = [];
14 | for (let i = 1; i <= 5; i += 1) {
15 | if (i <= Math.floor(score)) {
16 | nodes.push();
17 | } else {
18 | nodes.push();
19 | }
20 | }
21 | return (
22 |
23 | {nodes}
24 |
25 | );
26 | };
27 |
--------------------------------------------------------------------------------
/components/atoms/SwitchInput.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text, Switch as NativeSwitch } from 'react-native';
3 |
4 | import { formLabelColor, borderColor, primaryTextColor } from '../commonColors';
5 |
6 | import Switch from './Switch';
7 |
8 | const styles = {
9 | wrapper: {
10 | flexDirection: 'row',
11 | alignItems: 'center',
12 | justifyContent: 'space-between',
13 | borderBottomWidth: 1,
14 | borderColor,
15 | paddingVertical: 14,
16 | },
17 | title: {
18 | flex: 1,
19 | fontSize: 15,
20 | fontWeight: 'normal',
21 | fontStyle: 'normal',
22 | letterSpacing: 0,
23 | textAlign: 'left',
24 | color: formLabelColor,
25 | paddingBottom: 8,
26 | },
27 | secondaryText: {
28 | color: primaryTextColor,
29 | flex: 1,
30 | width: 'auto',
31 | },
32 | input: {
33 | marginBottom: 8,
34 | },
35 | };
36 |
37 | export default class SwitchInput extends React.Component {
38 | render() {
39 | const {
40 | title, value, onChange, noBorder, secondary, useNative, style, wrapperStyle,
41 | } = this.props;
42 | return (
43 |
44 | {title}
45 | {useNative ? (
46 |
47 | ) : (
48 |
49 | )}
50 |
51 | );
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/components/atoms/UnavailableButton.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity, Text, Platform, View } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 | import { brandColor, primaryTextColor, foregroundColor, mainBorderColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | marginVertical: 15,
9 | marginHorizontal: 12,
10 | paddingHorizontal: 17,
11 | paddingVertical: 11,
12 | borderRadius: 2,
13 | backgroundColor: foregroundColor,
14 | borderStyle: 'solid',
15 | borderWidth: 1,
16 | borderColor: mainBorderColor,
17 | flexDirection: 'row',
18 | alignItems: 'center',
19 | justifyContent: 'center',
20 | },
21 | btnText: {
22 | color: primaryTextColor,
23 | fontWeight: 'bold',
24 | },
25 | btnIcon: {
26 | marginLeft: 3,
27 | marginTop: 2,
28 | width: 16,
29 | height: 16,
30 | alignItems: 'center',
31 | justifyContent: 'center',
32 | },
33 | };
34 |
35 | export default ({ onPress }) => (
36 |
37 | Unavailable
38 |
39 |
44 |
45 |
46 | );
47 |
--------------------------------------------------------------------------------
/components/commonColors.js:
--------------------------------------------------------------------------------
1 | export const backgroundColor = '#FFFFFF';
2 | export const foregroundColor = '#FFFFFF';
3 | export const secondaryBackgroundColor = '#F5F6F6';
4 | export const brandColor = '#00BF65';
5 | export const borderColor = '#E8E8E8';
6 | export const mainBorderColor = '#C8C7CC';
7 | export const bgHightlightColor = '#F1FBF2';
8 |
9 | export const highlightColor = '#007AFF';
10 |
11 | export const greenColor = '#00BF65';
12 | export const greenTintColor = '#E8F7E7';
13 |
14 | export const primaryTextColor = '#000000';
15 | export const secondaryTextColor = '#666666';
16 | export const sectionTitleTextColor = '#444444';
17 | export const warningColor = '#FF6C67';
18 |
19 | export const disabledButtonTextColor = '#79666666';
20 | export const linkTextColor = '#00BF65';
21 | export const formLabelColor = '#8A8A8F';
22 | export const staticLabelColor = '#777777';
23 | export const starRatingColor = '#FBD838';
24 | export const locationPinColor = 'tomato';
25 | export const loadingBackgroundColor = '#F3FBF2';
26 |
--------------------------------------------------------------------------------
/components/commonStyles.js:
--------------------------------------------------------------------------------
1 | import { greenColor } from './commonColors';
2 |
3 | export const priceStyle = {
4 | fontSize: 14,
5 | fontStyle: 'normal',
6 | letterSpacing: 0,
7 | textAlign: 'left',
8 | color: greenColor,
9 | fontWeight: 'bold',
10 | };
11 |
--------------------------------------------------------------------------------
/components/molecules/HashtagHeader.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { View } from 'react-native';
3 |
4 | import SearchField from './SearchField';
5 |
6 | import { primaryTextColor, foregroundColor, borderColor } from '../commonColors';
7 | import { navHeightStyle } from '../../utils/navbar';
8 | import StatusBarWrapper from '../../status-bar';
9 |
10 | const styles = {
11 | wrapper: {
12 | alignSelf: 'stretch',
13 | },
14 | contentWrapper: {
15 | paddingLeft: 6,
16 | paddingRight: 6,
17 | ...navHeightStyle,
18 | backgroundColor: 'white',
19 | flexDirection: 'row',
20 | justifyContent: 'space-between',
21 | alignItems: 'center',
22 | borderBottomWidth: 0,
23 | borderColor,
24 | },
25 | };
26 |
27 | export default ({ hasBorder, onBack, hashtag, doSearch }) => {
28 | const [val, setVal] = useState(hashtag);
29 | useEffect(() => { setVal(hashtag); }, [hashtag]);
30 | return (
31 |
32 |
33 |
34 | {
39 | doSearch(val);
40 | }}
41 | placeholder="Search #hashtags..."
42 | />
43 |
44 |
45 | );
46 | };
47 |
--------------------------------------------------------------------------------
/components/molecules/NewChartHeader.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, TouchableOpacity } from 'react-native';
3 |
4 | import { foregroundColor } from '../commonColors';
5 | import { navHeightStyle } from '../../utils/navbar';
6 | import NavBackButton from '../atoms/NavBackButton';
7 | import QRScanner from '../organism/QRScanner';
8 | import StatusBarWrapper from '../../status-bar';
9 |
10 | const styles = {
11 | wrapper: {
12 | alignSelf: 'stretch',
13 | },
14 | contentWrapper: {
15 | paddingLeft: 6,
16 | paddingRight: 6,
17 | ...navHeightStyle,
18 | backgroundColor: 'white',
19 | flexDirection: 'row',
20 | justifyContent: 'space-between',
21 | alignItems: 'center',
22 | },
23 | left: {
24 | width: 48,
25 | alignItems: 'flex-start',
26 | },
27 | center: {
28 | flex: 1,
29 | justifyContent: 'center',
30 | },
31 | right: {
32 | width: 56,
33 | alignItems: 'center',
34 | },
35 | };
36 |
37 | export default ({
38 | onBack, searchComponent,
39 | }) => (
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | {searchComponent}
50 |
51 |
52 |
53 |
54 |
55 |
56 | );
57 |
--------------------------------------------------------------------------------
/components/molecules/PeerItem.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { withNavigation } from 'react-navigation';
3 | import * as _ from 'lodash';
4 | import { connect } from 'react-redux';
5 | import { fetchProfile } from '../../reducers/profile';
6 | import { getDefaultProfileFromPeerId } from '../../utils/profile';
7 |
8 | import FriendItem from './FriendItem';
9 |
10 | class PeerItem extends Component {
11 | static getDerivedStateFromProps(props) {
12 | const { peerID, profiles } = props;
13 | return { profile: profiles && profiles[peerID] };
14 | }
15 |
16 | state = {
17 | profile: null,
18 | };
19 |
20 | shouldComponentUpdate(nextProps, nextState) {
21 | const { profile } = this.state;
22 | const nextProfile = nextState.profile;
23 | if (!profile && nextProfile) {
24 | return true;
25 | } else {
26 | return false;
27 | }
28 | }
29 |
30 | render() {
31 | const { peerID, ...props } = this.props;
32 | const profile = this.state.profile || getDefaultProfileFromPeerId(peerID);
33 |
34 | return ;
35 | }
36 | }
37 |
38 | const mapStateToProps = state => ({
39 | profiles: state.profiles,
40 | });
41 |
42 | const mapDispatchToProps = {
43 | fetchProfile,
44 | };
45 |
46 | export default withNavigation(connect(
47 | mapStateToProps,
48 | mapDispatchToProps,
49 | )(PeerItem));
50 |
--------------------------------------------------------------------------------
/components/molecules/ProductTags.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 |
4 | import ProductTag from '../atoms/ProductTag';
5 | import ProductSection from '../atoms/ProductSection';
6 |
7 | const styles = {
8 | wrapper: {
9 | flexDirection: 'row',
10 | flexWrap: 'wrap',
11 | },
12 | };
13 |
14 | export default ({ tags, onPress }) => (
15 |
16 |
17 | {tags.map((item, idx) => )}
18 |
19 |
20 | );
21 |
--------------------------------------------------------------------------------
/components/molecules/Section.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 | import { backgroundColor, primaryTextColor } from '../commonColors';
4 |
5 | const styles = {
6 | section: {
7 | marginTop: 20,
8 | backgroundColor,
9 | },
10 | sectionBody: {
11 | marginTop: 7,
12 | },
13 | title: {
14 | fontSize: 16,
15 | fontWeight: 'bold',
16 | fontStyle: 'normal',
17 | textAlign: 'left',
18 | letterSpacing: -0.1,
19 | color: primaryTextColor,
20 | paddingLeft: 15,
21 | },
22 | };
23 |
24 | export default ({
25 | style, title, children, bodyStyle,
26 | }) => (
27 |
28 | {title}
29 | {children}
30 |
31 | );
32 |
--------------------------------------------------------------------------------
/components/molecules/StoreMoreMenu.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { TouchableWithoutFeedback, View, Animated } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { primaryTextColor, foregroundColor } from '../commonColors';
6 |
7 | const styles = {
8 | moreIcon: {
9 | width: 32,
10 | height: 32,
11 | textAlign: 'center',
12 | alignItems: 'center',
13 | justifyContent: 'center',
14 | },
15 | };
16 |
17 | class StoreMoreMenu extends PureComponent {
18 | state = {};
19 |
20 | render() {
21 | const {
22 | onMore, black, size, animColor,
23 | } = this.props;
24 | const IconComponent = animColor ? Animated.createAnimatedComponent(Ionicons) : Ionicons;
25 | const color = black ? primaryTextColor : foregroundColor;
26 | return (
27 |
28 |
29 |
35 |
36 |
37 | );
38 | }
39 | }
40 |
41 | export default StoreMoreMenu;
42 |
--------------------------------------------------------------------------------
/components/molecules/TextHeader.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Text } from 'react-native';
3 |
4 | import { primaryTextColor } from '../../components/commonColors';
5 |
6 | const styles = {
7 | header: {
8 | fontSize: 16,
9 | fontWeight: 'bold',
10 | fontStyle: 'normal',
11 | letterSpacing: -0.1,
12 | color: primaryTextColor,
13 | paddingTop: 20,
14 | paddingLeft: 15,
15 | paddingBottom: 7,
16 | },
17 | };
18 |
19 | export const renderTextHeader = text => ({ style }) => (
20 | {text}
21 | );
22 |
--------------------------------------------------------------------------------
/components/molecules/VariantItem.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text } from 'react-native';
3 | import { borderColor, primaryTextColor } from '../commonColors';
4 |
5 | const styles = {
6 | wrapper: {
7 | borderBottomWidth: 1,
8 | borderBottomColor: borderColor,
9 | flexDirection: 'row',
10 | alignItems: 'center',
11 | paddingVertical: 15,
12 | },
13 | noBorder: {
14 | borderBottomColor: 'transparent',
15 | },
16 | variantName: {
17 | fontSize: 15,
18 | color: primaryTextColor,
19 | width: 100,
20 | },
21 | variantOptionsHolder: {
22 | flex: 1,
23 | flexDirection: 'row',
24 | alignItems: 'center',
25 | flexWrap: 'wrap',
26 | },
27 | variantOption: {
28 | paddingVertical: 7,
29 | paddingHorizontal: 11,
30 | fontSize: 13,
31 | color: primaryTextColor,
32 | fontWeight: 'bold',
33 | borderWidth: 1,
34 | borderColor: '#c8c7cc',
35 | marginLeft: 6,
36 | alignItems: 'center',
37 | justifyContent: 'center',
38 | marginBottom: 5,
39 | },
40 | };
41 |
42 | export default ({ item: { name, variants }, isLast }) => (
43 |
44 | {name}
45 |
46 | {variants.map((val, idx) => (
47 |
48 | {val}
49 |
50 | ))}
51 |
52 |
53 | );
54 |
--------------------------------------------------------------------------------
/components/organism/ActionSheet.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Platform } from 'react-native';
3 | import ActionSheet, { ActionSheetCustom } from 'react-native-actionsheet';
4 |
5 | import { actionSheetStyles } from '../../utils/styles';
6 |
7 | class OBActionSheet extends React.Component {
8 | setActionSheet = (component) => {
9 | this.actionSheet = component;
10 | };
11 |
12 | show() {
13 | this.actionSheet.show();
14 | }
15 |
16 | render() {
17 | const ActionSheetComponent = Platform.OS === 'ios' ? ActionSheet : ActionSheetCustom;
18 | return (
19 |
24 | );
25 | }
26 | }
27 |
28 | export default OBActionSheet;
29 |
--------------------------------------------------------------------------------
/components/organism/EmptyCoupons.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text, Image } from 'react-native';
3 |
4 | import HollowButton from '../atoms/HollowButton';
5 |
6 | import CouponIcon from '../../assets/icons/coupon.png';
7 |
8 | const styles = {
9 | wrapper: {
10 | flex: 1,
11 | flexDirection: 'column',
12 | alignItems: 'center',
13 | justifyContent: 'center',
14 | },
15 | text: {
16 | fontSize: 14,
17 | color: '#8a8a8f',
18 | marginBottom: 10,
19 | },
20 | img: {
21 | width: 49.1,
22 | height: 49.1,
23 | marginBottom: 11.5,
24 | },
25 | };
26 |
27 | export default ({ onAdd }) => (
28 |
29 |
30 | You haven’t added any coupons
31 |
32 |
33 | );
34 |
--------------------------------------------------------------------------------
/components/organism/EmptyShippingMethods.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, Text, Image } from 'react-native';
3 |
4 | import HollowButton from '../atoms/HollowButton';
5 |
6 | import CouponIcon from '../../assets/icons/shipping.png';
7 |
8 | const styles = {
9 | wrapper: {
10 | flex: 1,
11 | flexDirection: 'column',
12 | alignItems: 'center',
13 | justifyContent: 'center',
14 | },
15 | text: {
16 | fontSize: 14,
17 | color: '#8a8a8f',
18 | marginBottom: 10,
19 | },
20 | img: {
21 | width: 67.4,
22 | height: 49,
23 | marginBottom: 11.5,
24 | },
25 | };
26 |
27 | export default ({ onAdd }) => (
28 |
29 |
30 | You haven’t added any shipping options
31 |
32 |
33 | );
34 |
--------------------------------------------------------------------------------
/components/organism/ErrorModal.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Button, Modal, Text, View } from 'react-native';
3 |
4 | const styles = {
5 | wrapper: {
6 | backgroundColor: 'rgba(255, 255, 255, 0.9)',
7 | padding: 50,
8 | display: 'flex',
9 | justifyContent: 'center',
10 | alignItems: 'center',
11 | flexGrow: 1,
12 | },
13 | title: {
14 | fontWeight: 'bold',
15 | textAlign: 'center',
16 | marginBottom: 10,
17 | },
18 | body: {
19 | textAlign: 'center',
20 | },
21 | };
22 |
23 | export default function ErrorModal(props) {
24 | const { title, error, onPress, buttonText } = props;
25 | return (
26 |
27 |
28 | {title}
29 | Error: {error}
30 |
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/components/organism/Notification.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import SocialNotification from '../molecules/SocialNotification';
4 | import OrderNotification from '../molecules/OrderNotification';
5 |
6 | import { getNotificationType, SOCIAL_TYPES } from '../../utils/notification';
7 |
8 | export default class Notification extends React.PureComponent {
9 | render() {
10 | const { notification } = this.props;
11 | const { type, verb } = notification;
12 | const ntfType = getNotificationType(type);
13 | if (SOCIAL_TYPES.includes(verb)) {
14 | return ;
15 | } else if (ntfType === 'order') {
16 | return ;
17 | } else if (ntfType === 'dispute') {
18 | return ;
19 | }
20 | return false;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/components/organism/ProductModeSelector.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, TouchableWithoutFeedback, Text } from 'react-native';
3 | import Feather from 'react-native-vector-icons/Feather';
4 |
5 | import { primaryTextColor, borderColor } from '../commonColors';
6 |
7 | const styles = {
8 | wrapper: {
9 | paddingHorizontal: 19,
10 | paddingTop: 7,
11 | paddingBottom: 5,
12 | flexDirection: 'row',
13 | justifyContent: 'space-between',
14 | alignItems: 'center',
15 | borderTopWidth: 0,
16 | backgroundColor: '#FFF',
17 | borderColor,
18 | borderBottomWidth: 1,
19 | },
20 | noBorder: {
21 | borderBottomWidth: 0,
22 | },
23 | modeIconWrapper: {},
24 | counts: {
25 | fontSize: 14,
26 | fontWeight: 'normal',
27 | fontStyle: 'normal',
28 | letterSpacing: 0,
29 | textAlign: 'left',
30 | color: primaryTextColor,
31 | },
32 | };
33 |
34 | export default ({
35 | mode, onChange, counts, noBorder,
36 | }) => (
37 |
38 | {counts !== undefined ? `${counts} listings` : ''}
39 | {
41 | onChange(mode === 'card' ? 'list' : 'card');
42 | }}
43 | >
44 |
45 | {mode === 'card' ? (
46 |
47 | ) : (
48 |
49 | )}
50 |
51 |
52 |
53 | );
54 |
--------------------------------------------------------------------------------
/components/organism/SearchFilterHeader.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { View, Text } from 'react-native';
3 |
4 | import { primaryTextColor, borderColor } from '../commonColors';
5 |
6 | const styles = {
7 | wrapper: {
8 | flexDirection: 'row',
9 | paddingVertical: 12,
10 | paddingLeft: 20,
11 | alignItems: 'center',
12 | borderBottomWidth: 1,
13 | borderColor,
14 | },
15 | textStyle: {
16 | flex: 1,
17 | color: primaryTextColor,
18 | fontSize: 15,
19 | paddingRight: 15,
20 | },
21 | };
22 |
23 | export default class SearchFilterHeader extends PureComponent {
24 | render() {
25 | const {
26 | total,
27 | } = this.props;
28 | return (
29 |
30 | {total ? ({`${total} results`})
31 | : ()}
32 |
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/components/organism/ShippingPrice.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/components/organism/ShippingPrice.js
--------------------------------------------------------------------------------
/components/organism/TagEditor.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Text } from 'react-native';
3 |
4 | import InputGroup from '../atoms/InputGroup';
5 | import OptionGroup from '../atoms/OptionGroup';
6 | import FormLabelText from '../atoms/FormLabelText';
7 | import { primaryTextColor } from '../commonColors';
8 |
9 | const style = {
10 | fontSize: 15,
11 | fontWeight: 'normal',
12 | fontStyle: 'normal',
13 | letterSpacing: 0,
14 | textAlign: 'left',
15 | color: primaryTextColor,
16 | paddingVertical: 20,
17 | };
18 |
19 | export default class TagEditor extends React.PureComponent {
20 | render() {
21 | const { count } = this.props;
22 | return (
23 |
24 |
25 | { count > 0 ?
26 | {`${count} tag${count > 1 ? 's' : ''}`}
27 | :
28 |
29 | }
30 |
31 |
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/components/templates/InventoryList.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { FlatList, Text } from 'react-native';
3 |
4 | import InventoryItem from '../organism/InventoryItem';
5 |
6 | const styles = {
7 | text: {
8 | fontSize: 14,
9 | color: '#8d8d8d',
10 | textAlign: 'left',
11 | marginLeft: 16,
12 | marginBottom: 12,
13 | },
14 | };
15 |
16 | export default class InventoryList extends React.Component {
17 | keyExtractor = (item, index) => `inventory_${index}`;
18 |
19 | renderHeader = () => {
20 | const { inventory } = this.props;
21 | const count = inventory.length;
22 | return (
23 |
24 | {count} variant combos
25 |
26 | );
27 | }
28 |
29 | renderItem = ({ item, index }) => {
30 | const { inventory, toItem, isTracking } = this.props;
31 | return (
32 | toItem(index)}
37 | />
38 | );
39 | };
40 |
41 | render() {
42 | const { inventory } = this.props;
43 | return (
44 |
50 | );
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/components/templates/OBModal.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Modal, View } from 'react-native';
3 |
4 | import StatusBarWrapper from '../../status-bar';
5 |
6 | const styles = {
7 | black: {
8 | backgroundColor: 'black',
9 | flex: 1,
10 | },
11 | white: {
12 | backgroundColor: 'white',
13 | flex: 1,
14 | },
15 | overlay: {
16 | backgroundColor: 'transparent',
17 | flex: 1,
18 | },
19 | };
20 |
21 | // transparent - true if statusbar is transparent.
22 | // overlay - true if modal background is transparent
23 | export const OBLightModal = ({ children, overlay, transparent, ...props }) => (
24 |
25 | {!overlay && (
26 |
27 | )}
28 |
29 | {children}
30 |
31 |
32 | );
33 |
34 | export const OBDarkModal = ({ children, overlay, transparent, ...props }) => (
35 |
36 | {!overlay && (
37 |
38 | )}
39 |
40 | {children}
41 |
42 |
43 | );
44 |
--------------------------------------------------------------------------------
/components/templates/Product.js:
--------------------------------------------------------------------------------
1 | import React
--------------------------------------------------------------------------------
/config/appIDConfig.js:
--------------------------------------------------------------------------------
1 | export const APPLE_APP_ID = '1318395690';
2 | export const GOOGLE_PACKAGE_NAME = 'io.ob1.nativeandroid';
3 |
--------------------------------------------------------------------------------
/config/conditionFilter.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "any",
4 | "label": "Any",
5 | "checked": false,
6 | "default": true,
7 | "exclusive": true
8 | },
9 | {
10 | "value": "new",
11 | "label": "New",
12 | "checked": true,
13 | "default": false
14 | },
15 | {
16 | "value": ["used", "used_excellent", "used_good", "used_poor"],
17 | "label": "Used",
18 | "checked": true,
19 | "default": false
20 | },
21 | {
22 | "value": "refurbished",
23 | "label": "Refurbished",
24 | "checked": false,
25 | "default": false
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/feePlans.js:
--------------------------------------------------------------------------------
1 | const FEE_PLANS = [
2 | {
3 | label: 'Super economic (cheapest, slowest)',
4 | value: 'SUPER_ECONOMIC',
5 | displayLabel: 'Super Economic',
6 | },
7 | {
8 | label: 'Economic (cheap, slow)',
9 | value: 'ECONOMIC',
10 | displayLabel: 'Economic',
11 | },
12 | {
13 | label: 'Normal (average fee and wait time)',
14 | value: 'NORMAL',
15 | displayLabel: 'Normal',
16 | },
17 | {
18 | label: 'Priority (most expensive, fastest)',
19 | value: 'PRIORITY',
20 | displayLabel: 'Priority',
21 | },
22 | ];
23 |
24 | export default FEE_PLANS;
25 |
--------------------------------------------------------------------------------
/config/iosProductTypes.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "any",
4 | "label": "Any",
5 | "checked": true,
6 | "default": true,
7 | "exclusive": true
8 | },
9 | {
10 | "value": "physical_good",
11 | "label": "Physical Good",
12 | "checked": false,
13 | "default": false
14 | },
15 | {
16 | "value": "digital_good",
17 | "label": "Digital Good",
18 | "disabled": true,
19 | "checked": false,
20 | "default": false
21 | },
22 | {
23 | "value": "service",
24 | "label": "Service",
25 | "checked": false,
26 | "default": false
27 | }
28 | ]
29 |
--------------------------------------------------------------------------------
/config/nswf.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "true",
4 | "label": "Visible",
5 | "checked": false,
6 | "default": false
7 | },
8 | {
9 | "value": "false",
10 | "label": "Hidden",
11 | "checked": true,
12 | "default": true
13 | }
14 | ]
--------------------------------------------------------------------------------
/config/productCondition.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "any",
4 | "label": "Any",
5 | "checked": false,
6 | "default": true,
7 | "exclusive": true
8 | },
9 | {
10 | "value": "new",
11 | "label": "New",
12 | "checked": true,
13 | "default": false
14 | },
15 | {
16 | "value": "used",
17 | "label": "Used",
18 | "checked": true,
19 | "default": false
20 | },
21 | {
22 | "value": "used_excellent",
23 | "label": "Used - Excellent",
24 | "checked": false,
25 | "default": false
26 | },
27 | {
28 | "value": "used_good",
29 | "label": "Used - Good",
30 | "checked": false,
31 | "default": false
32 | },
33 | {
34 | "value": "used_poor",
35 | "label": "Used - Poor",
36 | "checked": false,
37 | "default": false
38 | },
39 | {
40 | "value": "refurbished",
41 | "label": "Refurbished",
42 | "checked": false,
43 | "default": false
44 | }
45 | ]
46 |
--------------------------------------------------------------------------------
/config/productTypes.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "any",
4 | "label": "Any",
5 | "checked": true,
6 | "default": true,
7 | "exclusive": true
8 | },
9 | {
10 | "value": "physical_good",
11 | "label": "Physical Good",
12 | "checked": false,
13 | "default": false
14 | },
15 | {
16 | "value": "digital_good",
17 | "label": "Digital Good",
18 | "checked": false,
19 | "default": false
20 | },
21 | {
22 | "value": "service",
23 | "label": "Service",
24 | "checked": false,
25 | "default": false
26 | }
27 | ]
28 |
--------------------------------------------------------------------------------
/config/sort.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "value": "relevance",
4 | "label": "Best match",
5 | "selected": false,
6 | "default": true
7 | },
8 | {
9 | "value": "rating",
10 | "label": "Rating",
11 | "selected": false,
12 | "default": false
13 | },
14 | {
15 | "value": "price-asc",
16 | "label": "Lowest Price",
17 | "selected": true,
18 | "default": false
19 | },
20 | {
21 | "value": "price-desc",
22 | "label": "Highest Price",
23 | "selected": false,
24 | "default": false
25 | }
26 | ]
--------------------------------------------------------------------------------
/config/stream.js:
--------------------------------------------------------------------------------
1 | export const STREAM_FEED_PAGE_SIZE = 6;
2 |
--------------------------------------------------------------------------------
/config/supportUrls.js:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 | import { version } from '../package.json';
3 |
4 | export const FAQ_URL = 'https://gethaven.app/faq';
5 | export const TELEGRAM_URL = 'https://t.me/GetHavenApp';
6 | export const EMAIL_URL = `mailto:haven@ob1.io?subject=Haven%20Customer%20Support&body=%0A%0ABuild%20version:%20${version}%0AOS:%20${Platform.OS}`;
7 |
--------------------------------------------------------------------------------
/havenBuildConfigFiles/copy_files.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cp ./GoogleService-Info.plist ../ios
4 | cp ./google-services.json ../android/app
5 |
6 | cp ./AppCenter-Config.plist ../ios/NativeBazaar
7 | cp ./appcenter-config.json ../android/app/src/main/assets
8 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native';
2 | import App from './App';
3 | import './CountlyConfig';
4 |
5 | AppRegistry.registerComponent('NativeBazaar', () => App);
6 |
--------------------------------------------------------------------------------
/install_server.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Download iOS framework
4 | cd ios
5 | rm Mobile.framework.zip
6 | wget https://github.com/OpenBazaar/openbazaar-go/releases/download/v0.14.4/Mobile.framework.zip
7 | unzip ./Mobile.framework.zip
8 |
9 | # Download Android library
10 | cd ../android/mobile
11 | rm mobile.aar
12 | wget https://github.com/OpenBazaar/openbazaar-go/releases/download/v0.14.4/mobile.aar
13 |
14 | # Return home
15 | cd ../..
16 |
--------------------------------------------------------------------------------
/ios/Config.prod.debug.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Config.xcconfig
3 | // NativeBazaar
4 | //
5 | // Copyright © 2020 Facebook. All rights reserved.
6 | //
7 |
8 | // Configuration settings file format documentation can be found at:
9 | // https://help.apple.com/xcode/#/dev745c5c974
10 |
11 | #include? "env.prod.xcconfig"
12 | #include "Pods/Target Support Files/Pods-NativeBazaar Prod/Pods-NativeBazaar Prod.debug.xcconfig"
13 |
--------------------------------------------------------------------------------
/ios/Config.prod.release.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Config.xcconfig
3 | // NativeBazaar
4 | //
5 | // Copyright © 2020 Facebook. All rights reserved.
6 | //
7 |
8 | // Configuration settings file format documentation can be found at:
9 | // https://help.apple.com/xcode/#/dev745c5c974
10 |
11 | #include? "env.prod.xcconfig"
12 | #include "Pods/Target Support Files/Pods-NativeBazaar Prod/Pods-NativeBazaar Prod.release.xcconfig"
13 |
--------------------------------------------------------------------------------
/ios/Config.staging.debug.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Config.xcconfig
3 | // NativeBazaar
4 | //
5 | // Copyright © 2020 Facebook. All rights reserved.
6 | //
7 |
8 | // Configuration settings file format documentation can be found at:
9 | // https://help.apple.com/xcode/#/dev745c5c974
10 |
11 | #include "env.xcconfig"
12 | #include "Pods/Target Support Files/Pods-NativeBazaar/Pods-NativeBazaar.debug.xcconfig"
13 |
--------------------------------------------------------------------------------
/ios/Config.staging.release.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Config.xcconfig
3 | // NativeBazaar
4 | //
5 | // Copyright © 2020 Facebook. All rights reserved.
6 | //
7 |
8 | // Configuration settings file format documentation can be found at:
9 | // https://help.apple.com/xcode/#/dev745c5c974
10 |
11 | #include "env.xcconfig"
12 | #include "Pods/Target Support Files/Pods-NativeBazaar/Pods-NativeBazaar.release.xcconfig"
13 |
--------------------------------------------------------------------------------
/ios/NativeBazaar Prod-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/ios/NativeBazaar Prod.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 | com.apple.developer.associated-domains
8 |
9 | applinks:openbazaar.com
10 | applinks:ob.app.link
11 | applinks:ob-alternate.app.link
12 |
13 | com.apple.developer.icloud-container-identifiers
14 |
15 | iCloud.$(CFBundleIdentifier)
16 |
17 | com.apple.developer.icloud-services
18 |
19 | CloudDocuments
20 |
21 | com.apple.developer.ubiquity-container-identifiers
22 |
23 | iCloud.$(CFBundleIdentifier)
24 |
25 | com.apple.developer.ubiquity-kvstore-identifier
26 | $(TeamIdentifierPrefix)$(CFBundleIdentifier)
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ios/NativeBazaar-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/ios/NativeBazaar-tvOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ios/NativeBazaar.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/NativeBazaar.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/NativeBazaar.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 | PreviewsEnabled
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/NativeBazaar/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 | #import
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (nonatomic, strong) UIWindow *window;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-1024@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-20@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-20@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-20@3x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-29@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-29@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-29@3x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-40@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-40@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-40@3x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-50@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-50@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-50@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-57@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-57@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-57@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-60@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-60@3x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-72@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-72@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-72@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-76@1x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-76@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/AppIcon.appiconset/icon-83.5@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "splash-logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "splash-logo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "splash-logo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/splash-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/splash-logo.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/splash-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/splash-logo@2x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/splash-logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/ios/NativeBazaar/Images.xcassets/splash-logo.imageset/splash-logo@3x.png
--------------------------------------------------------------------------------
/ios/NativeBazaar/NativeBazaar.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 | com.apple.developer.associated-domains
8 |
9 | applinks:openbazaar.com
10 | applinks:ob.app.link
11 | applinks:ob-alternate.app.link
12 |
13 | com.apple.developer.icloud-container-identifiers
14 |
15 | iCloud.$(CFBundleIdentifier)
16 |
17 | com.apple.developer.icloud-services
18 |
19 | CloudDocuments
20 |
21 | com.apple.developer.ubiquity-container-identifiers
22 |
23 | iCloud.$(CFBundleIdentifier)
24 |
25 | com.apple.developer.ubiquity-kvstore-identifier
26 | $(TeamIdentifierPrefix)$(CFBundleIdentifier)
27 | com.apple.developer.icloud-container-environment
28 | Development
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ios/NativeBazaar/NativeModules/ModuleWithEmitter.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface ModuleWithEmitter : RCTEventEmitter
5 | + (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload;
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/NativeBazaar/NativeModules/ModuleWithEmitter.m:
--------------------------------------------------------------------------------
1 | #import "ModuleWithEmitter.h"
2 |
3 | @implementation ModuleWithEmitter
4 |
5 | RCT_EXPORT_MODULE();
6 |
7 | - (NSArray *)supportedEvents {
8 | // register name, may be more...
9 | return @[@"onServerStarted", @"onServerStartFailed", @"onServerStopped", @"onServerStopFailed"];
10 | }
11 |
12 | - (void)startObserving {
13 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
14 | for (NSString *notificationName in [self supportedEvents]) {
15 | [center addObserver:self
16 | selector:@selector(emitEventInternal:)
17 | name:notificationName
18 | object:nil];
19 | }
20 | }
21 |
22 | - (void)stopObserving {
23 | [[NSNotificationCenter defaultCenter] removeObserver:self];
24 | }
25 |
26 | - (void)emitEventInternal:(NSNotification *)notification {
27 | [self sendEventWithName:notification.name
28 | body:notification.userInfo];
29 | }
30 |
31 | + (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload {
32 | [[NSNotificationCenter defaultCenter] postNotificationName:name
33 | object:self
34 | userInfo:payload];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/ios/NativeBazaar/NativeModules/ServerBridge.h:
--------------------------------------------------------------------------------
1 | // import RCTBridgeModule
2 | #if __has_include()
3 | #import
4 | #elif __has_include(“RCTBridgeModule.h”)
5 | #import “RCTBridgeModule.h”
6 | #else
7 | #import “React/RCTBridgeModule.h” // Required when used as a Pod in a Swift project
8 | #endif
9 |
10 | @interface ServerBridge : NSObject
11 | + (void)stopServerThread;
12 | + (void)startServerThread;
13 | @end
14 |
--------------------------------------------------------------------------------
/ios/NativeBazaar/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ios/NativeBazaarTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ios/SwiftForBridge.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftForBridge.swift
3 | // NativeBazaar
4 | //
5 | // Copyright © 2020 Facebook. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
--------------------------------------------------------------------------------
/reducers/config.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | getConfiguration: 'CONFIGURATION/GET',
5 | setConfiguration: 'CONFIGURATION/SET',
6 | };
7 |
8 | export const getConfiguration = createAction(actions.getConfiguration);
9 |
10 | const initialState = { config: null };
11 |
12 | export default handleActions(
13 | {
14 | [actions.setConfiguration]: (state, action) => ({
15 | ...state,
16 | config: action.payload,
17 | }),
18 | },
19 | initialState,
20 | );
21 |
--------------------------------------------------------------------------------
/reducers/exchangeRate.js:
--------------------------------------------------------------------------------
1 | import { handleActions, createAction } from 'redux-actions';
2 |
3 | import defaultRates from '../config/exchangeRates.json';
4 |
5 | export const actions = {
6 | fetchExchangeRate: 'EXCHANGE_RATE/FETCH',
7 | setExchangeRate: 'EXCHANGE_RATE/SET',
8 | };
9 |
10 | export const fetchExchangeRate = createAction(actions.fetchExchangeRate);
11 |
12 | const initialState = {
13 | rates: defaultRates,
14 | };
15 |
16 | export default handleActions({
17 | [actions.setExchangeRate]: (state, { payload }) => ({
18 | rates: payload,
19 | }),
20 | }, initialState);
21 |
--------------------------------------------------------------------------------
/reducers/featured.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchFeatured: 'STORE/FETCH_FEATURED',
5 | setFeatured: 'STORE/SET_FEATURED',
6 | setFeaturedLoading: 'STORE/SET_FEATURED_LOADING',
7 | };
8 |
9 | export const fetchFeatured = createAction(actions.fetchFeatured);
10 | export const setFeaturedLoading = createAction(actions.setFeaturedLoading);
11 |
12 | const initialState = {
13 | data: [],
14 | loading: false,
15 | };
16 |
17 | export default handleActions({
18 | [actions.setFeatured]: (state, action) => ({
19 | loading: state.loading,
20 | data: action.payload,
21 | }),
22 | [actions.setFeaturedLoading]: (state, action) => ({
23 | loading: action.payload,
24 | data: state.data,
25 | }),
26 | }, initialState);
27 |
--------------------------------------------------------------------------------
/reducers/followQueue.js:
--------------------------------------------------------------------------------
1 | import { handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | addToFollowQueue: 'FOLLOW/ADD_TO_FOLLOW_QUEUE',
5 | removeFromFollowQueue: 'FOLLOW/REMOVE_FROM_FOLLOW_QUEUE',
6 | addToUnfollowQueue: 'FOLLOW/ADD_TO_UNFOLLOW_QUEUE',
7 | removeFromUnfollowQueue: 'FOLLOW/REMOVE_FROM_UNFOLLOW_QUEUE',
8 | };
9 |
10 | const initialState = {
11 | followQueue: [],
12 | unfollowQueue: [],
13 | };
14 |
15 | export default handleActions(
16 | {
17 | [actions.addToFollowQueue]: (state, action) => ({
18 | ...state,
19 | followQueue: [...state.followQueue, action.payload],
20 | }),
21 | [actions.removeFromFollowQueue]: (state, action) => ({
22 | ...state,
23 | followQueue: state.followQueue.filter(item => item !== action.payload),
24 | }),
25 | [actions.addToUnfollowQueue]: (state, action) => ({
26 | ...state,
27 | unfollowQueue: [...state.unfollowQueue, action.payload],
28 | }),
29 | [actions.removeFromUnfollowQueue]: (state, action) => ({
30 | ...state,
31 | unfollowQueue: state.unfollowQueue.filter(item => item !== action.payload),
32 | }),
33 | },
34 | initialState,
35 | );
36 |
--------------------------------------------------------------------------------
/reducers/listings.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 | import * as _ from 'lodash';
3 |
4 | const MAXIMUM_LISTING_COUNT = 100;
5 |
6 | export const actions = {
7 | addListing: 'LISTING/ADD_LISTING',
8 | fetchListing: 'LISTING/FETCH_LISTING',
9 | loadingFromGatewayNow: 'LISTING/FETCH_LISTING_FROM_GATEWAY',
10 | };
11 |
12 | export const addListing = createAction(actions.addListing);
13 | export const fetchListing = createAction(actions.fetchListing);
14 |
15 | const initialState = {
16 | data: [],
17 | status: '',
18 | };
19 |
20 | export default handleActions(
21 | {
22 | [actions.fetchListing]: state => ({ ...state, status: 'LOADING_LISTING' }),
23 | [actions.loadingFromGatewayNow]: state => ({ ...state, status: 'LOADING_LISTING_FROM_GATEWAY' }),
24 | [actions.addListing]: (state, action) => {
25 | const slug = _.get(action, 'payload.listing.slug');
26 | if (slug) {
27 | const listings = state.data.filter(item => item.listing.slug !== slug);
28 | if (listings.length >= MAXIMUM_LISTING_COUNT) {
29 | listings.splice(0, 1);
30 | }
31 | listings.push(action.payload);
32 | return { data: listings, status: 'LISTING_LOADING_SUCCESS' };
33 | } else {
34 | return { ...state, status: 'LISTING_LOADING_FAILED' };
35 | }
36 | },
37 | },
38 | initialState,
39 | );
40 |
--------------------------------------------------------------------------------
/reducers/moderationSettings.js:
--------------------------------------------------------------------------------
1 | import { handleActions, createAction } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchModerationSettings: 'MODERATION_SETTINGS/FETCH',
5 | setModerationSettings: 'MODERATION_SETTINGS/SET',
6 | updateModerationSettings: 'MODERATION_SETTINGS/UPDATE',
7 | unsetModerationSettings: 'MODERATION_SETTINGS/UNSET',
8 | };
9 |
10 | export const fetchModerationSettings = createAction(actions.fetchModerationSettings);
11 | export const updateModerationSettings = createAction(actions.updateModerationSettings);
12 |
13 | const initialState = {
14 | description: '',
15 | termsAndConditions: '',
16 | languages: [],
17 | fee: {},
18 | };
19 |
20 | export default handleActions({
21 | [actions.setModerationSettings]: (state, action) => ({
22 | ...action.payload,
23 | }),
24 | [actions.updateModerationSettings]: (state, action) => ({
25 | ...action.payload,
26 | }),
27 | [actions.unsetModerationSettings]: (state, action) => ({
28 | ...initialState,
29 | }),
30 | }, initialState);
31 |
--------------------------------------------------------------------------------
/reducers/moderators.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchModerators: 'MODERATORS/FETCH_MODERATORS',
5 | setModerators: 'MODERATORS/SET_MODERATORS',
6 | };
7 |
8 | export const fetchModerators = createAction(actions.fetchModerators);
9 |
10 | const initialState = [];
11 |
12 | export default handleActions(
13 | {
14 | [actions.setModerators]: (state, action) => {
15 | return action.payload;
16 | },
17 | },
18 | initialState,
19 | );
20 |
--------------------------------------------------------------------------------
/reducers/navigation.js:
--------------------------------------------------------------------------------
1 | import { NavigationActions } from 'react-navigation';
2 | import AppNavigator from '../routes';
3 |
4 | const action = AppNavigator.router.getActionForPathAndParams(null);
5 | const initialState = AppNavigator.router.getStateForAction({});
6 | // const initialState = {};
7 | export const actions = {
8 | navigate: 'CUSTOM_NAV/NAVIGATE',
9 | };
10 |
11 | const navReducer = (state = initialState, action) => {
12 | let nextState;
13 | switch (action.type) {
14 | case actions.navigate:
15 | nextState = AppNavigator.router.getStateForAction(
16 | NavigationActions.navigate({
17 | routeName: action.payload,
18 | }),
19 | state,
20 | );
21 | break;
22 | default:
23 | nextState = AppNavigator.router.getStateForAction(action, state);
24 | break;
25 | }
26 |
27 | // Return original `state` if `nextState` is null/undefined
28 | return nextState || state;
29 | };
30 |
31 | export default navReducer;
32 |
--------------------------------------------------------------------------------
/reducers/profileFailedQueue.js:
--------------------------------------------------------------------------------
1 | import { handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | addToFailedQueue: 'PROFILE/ADD_FAILED_QUEUE',
5 | removeFromFailedQueue: 'PROFILE/REMOVE_FAILED_QUEUE',
6 | };
7 |
8 | const initialState = {};
9 |
10 | export default handleActions(
11 | {
12 | [actions.addToFailedQueue]: (state, { payload }) => {
13 | return {
14 | ...state,
15 | [payload]: new Date().getTime(),
16 | };
17 | },
18 | [actions.removeFromFailedQueue]: (state, { payload }) => {
19 | const newState = state;
20 | delete newState[payload];
21 | return newState;
22 | },
23 | },
24 | initialState,
25 | );
26 |
--------------------------------------------------------------------------------
/reducers/profileQueue.js:
--------------------------------------------------------------------------------
1 | import { handleActions } from 'redux-actions';
2 | import { filter } from 'lodash';
3 |
4 | export const actions = {
5 | addToQueue: 'PROFILE/ADD_QUEUE',
6 | addBatchToQueue: 'PROFILE/ADD_BATCH_QUEUE',
7 | removeFromQueue: 'PROFILE/REMOVE_QUEUE',
8 | };
9 |
10 | const initialState = [];
11 |
12 | export default handleActions(
13 | {
14 | [actions.addToQueue]: (state, { payload }) => [...new Set([...state, payload])],
15 | [actions.addBatchToQueue]: (state, { payload }) => [...new Set([...state, ...payload])],
16 | [actions.removeFromQueue]: (state, { payload }) => filter(state, peerID => peerID !== payload),
17 | },
18 | initialState,
19 | );
20 |
--------------------------------------------------------------------------------
/reducers/profiles.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchProfiles: 'PROFILES/FETCH_PROFILES',
5 | setProfiles: 'PROFILES/SET_PROFILES',
6 | };
7 |
8 | export const fetchProfiles = createAction(actions.fetchProfiles);
9 |
10 | const initialState = {};
11 |
12 | export default handleActions(
13 | {
14 | [actions.setProfiles]: (state, action) => {
15 | const newState = { ...state };
16 | const newArray = action.payload;
17 | newArray.forEach((profile) => {
18 | newState[profile.peerID] = profile;
19 | });
20 | return newState;
21 | },
22 | },
23 | initialState,
24 | );
25 |
--------------------------------------------------------------------------------
/reducers/promo.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchPromo: 'PRODUCT/FETCH_PROMO',
5 | setPromo: 'PRODUCT/SET_PROMO',
6 | setPromoLoading: 'PRODUCT/SET_PROMO_LOADING',
7 | };
8 |
9 | export const fetchPromo = createAction(actions.fetchPromo);
10 | export const setPromoLoading = createAction(actions.setPromoLoading);
11 |
12 | const initialState = {
13 | data: [],
14 | loading: false,
15 | };
16 |
17 | export default handleActions({
18 | [actions.fetchPromo]: state => ({
19 | data: [],
20 | loading: true,
21 | }),
22 | [actions.setPromo]: (state, action) => ({
23 | loading: false,
24 | data: action.payload,
25 | }),
26 | [actions.setPromoLoading]: (state, action) => ({
27 | loading: action.payload,
28 | data: state.data,
29 | }),
30 | }, initialState);
31 |
--------------------------------------------------------------------------------
/reducers/ratings.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchRatings: 'RATINGS/FETCH',
5 | setRatings: 'RATINGS/FETCH_SUCCESS',
6 | fetchRatingsFailure: 'RATINGS/FETCH_FAILURE',
7 | };
8 |
9 | export const fetchRatings = createAction(actions.fetchRatings);
10 |
11 | const initialState = { data: {}, status: '' };
12 |
13 | export default handleActions(
14 | {
15 | [actions.fetchRatings]: (state, { type }) => ({ ...state, status: type }),
16 | [actions.setRatings]: (state, { payload, type }) => {
17 | const { reference, ...ratingsData } = payload;
18 | const data = { ...state.data };
19 | data[reference] = ratingsData;
20 | return ({ ...state, data, type });
21 | },
22 | [actions.fetchRatingsFailure]: (state, { type }) => ({ ...state, status: type }),
23 | },
24 | initialState,
25 | );
26 |
--------------------------------------------------------------------------------
/reducers/saga/config.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery } from 'redux-saga/effects';
2 |
3 | import { actions } from '../config';
4 |
5 | import { getConfig } from '../../api/onboarding';
6 |
7 | export function* getConfiguration() {
8 | try {
9 | const config = yield call(getConfig);
10 | yield put({
11 | type: actions.setConfiguration,
12 | payload: config,
13 | });
14 | } catch (err) {
15 | console.log('Get Configuration Failed:', err);
16 | }
17 | }
18 |
19 | export default function* Chat() {
20 | yield takeEvery(actions.getConfiguration, getConfiguration);
21 | }
22 |
--------------------------------------------------------------------------------
/reducers/saga/exchangeRate.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery } from 'redux-saga/effects';
2 | import { isEmpty } from 'lodash';
3 |
4 | import { actions } from '../exchangeRate';
5 |
6 | import { getExchangeRate } from '../../api/wallet';
7 |
8 | function* fetchRates(action) {
9 | const coin = action.payload || 'BTC';
10 | try {
11 | const rates = yield call(getExchangeRate, coin);
12 | if (rates[coin]) {
13 | yield put({ type: actions.setExchangeRate, payload: rates });
14 | }
15 | } catch (err) {
16 | console.log('Exchange Rate failed');
17 | }
18 | }
19 |
20 | const exchangeRate = function* ExchagneRate() {
21 | yield takeEvery(actions.fetchExchangeRate, fetchRates);
22 | };
23 |
24 | export default exchangeRate;
25 |
--------------------------------------------------------------------------------
/reducers/saga/featured.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery } from 'redux-saga/effects';
2 |
3 | import { actions } from '../featured';
4 | import { actions as profileActions } from '../profile';
5 |
6 | import { fetchFeatured } from '../../api/featured';
7 |
8 | export function* getFeatured() {
9 | try {
10 | const result = yield call(fetchFeatured);
11 | yield put({ type: actions.setFeatured, payload: result });
12 | for (let i = 0; i < result.length; i += 1) {
13 | yield put({
14 | type: profileActions.fetchProfile,
15 | payload: {
16 | peerID: result[i],
17 | getLoaded: true,
18 | },
19 | });
20 | }
21 | } catch (err) {
22 | console.log('Featured Saga Error: ', err);
23 | }
24 | yield put({ type: actions.setFeaturedLoading, payload: false });
25 | }
26 |
27 | const FeaturedSaga = function* Featured() {
28 | yield takeEvery(actions.fetchFeatured, getFeatured);
29 | };
30 |
31 | export default FeaturedSaga;
32 |
--------------------------------------------------------------------------------
/reducers/saga/listings.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery, select } from 'redux-saga/effects';
2 |
3 | import { actions } from '../listings';
4 | import { getListing, getListingFromHash } from '../../api/products';
5 |
6 | import { getUserCredentails } from './sagaSelector';
7 |
8 | function* fetchListing(action) {
9 | const { username, password } = yield select(getUserCredentails);
10 | const { slug, peerID, hash } = action.payload;
11 |
12 | try {
13 | let listing;
14 | if (hash) {
15 | listing = yield call(getListingFromHash, username, password, hash);
16 | } else {
17 | listing = yield call(getListing, username, password, slug, peerID);
18 | }
19 | yield put({ type: actions.addListing, payload: listing });
20 | } catch (err) {
21 | if (hash) {
22 | try {
23 | yield put({ type: actions.loadingFromGatewayNow });
24 | listing = yield call(getListing, username, password, slug, peerID);
25 | yield put({ type: actions.addListing, payload: listing });
26 | } catch (err) {
27 | yield put({ type: actions.addListing });
28 | }
29 | } else {
30 | yield put({ type: actions.addListing });
31 | }
32 | console.log('fetchListing Saga Error: ', err);
33 | }
34 | }
35 |
36 | const ListingSaga = function* ListingSaga() {
37 | yield takeEvery(actions.fetchListing, fetchListing);
38 | };
39 |
40 | export default ListingSaga;
41 |
--------------------------------------------------------------------------------
/reducers/saga/moderationSettings.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery, select } from 'redux-saga/effects';
2 | import { hasIn } from 'lodash';
3 |
4 | import { actions } from '../moderationSettings';
5 | import { setModerator, getModerator, updateModerator, unsetModerator } from '../../api/moderators';
6 | import { getUserCredentails } from './sagaSelector';
7 |
8 | function* fetchSettings(action) {
9 | const { username, password } = yield select(getUserCredentails);
10 | const result = yield call(getModerator, username, password);
11 | yield put({ type: actions.setModerationSettings, payload: result });
12 | }
13 |
14 | function* updateSettings(action) {
15 | const { username, password } = yield select(getUserCredentails);
16 | const result = yield call(updateModerator, username, password, action.payload);
17 | if (result.success == false) {
18 | const result = yield call(setModerator, username, password, action.payload);
19 | }
20 | }
21 |
22 | function* unsetSettings(action) {
23 | const { username, password } = yield select(getUserCredentails);
24 | yield call(unsetModerator, username, password);
25 | }
26 |
27 | const moderationSettings = function* Search() {
28 | yield takeEvery(actions.fetchModerationSettings, fetchSettings);
29 | yield takeEvery(actions.updateModerationSettings, updateSettings);
30 | yield takeEvery(actions.unsetModerationSettings, unsetSettings);
31 | };
32 |
33 | export default moderationSettings;
34 |
--------------------------------------------------------------------------------
/reducers/saga/promo.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery, select } from 'redux-saga/effects';
2 | import { get } from 'lodash';
3 |
4 | import { actions } from '../promo';
5 |
6 | import { fetchPromo } from '../../api/promo';
7 |
8 | export function* getPromo() {
9 | try {
10 | const result = yield call(fetchPromo);
11 | yield put({ type: actions.setPromo, payload: result });
12 | } catch (err) {
13 | console.log('Promo Saga Error: ', err);
14 | }
15 | yield put({ type: actions.setPromoLoading, payload: false });
16 | }
17 |
18 | const PromoSaga = function* Promo() {
19 | yield takeEvery(actions.fetchPromo, getPromo);
20 | };
21 |
22 | export default PromoSaga;
23 |
--------------------------------------------------------------------------------
/reducers/saga/ratings.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery, select } from 'redux-saga/effects';
2 |
3 | import { actions } from '../ratings';
4 |
5 | import { getRatings } from '../../api/products';
6 |
7 | import { getUserCredentails } from './sagaSelector';
8 |
9 | export function* getRatingsAction(action) {
10 | const { username, password } = yield select(getUserCredentails);
11 | const { peerID, slug } = action.payload;
12 | try {
13 | const result = yield call(getRatings, username, password, slug, peerID);
14 | if (result.success !== false) {
15 | const { ratings = [], average = 0, count = 0 } = result;
16 | yield put({
17 | type: actions.setRatings,
18 | payload: {
19 | reference: `${peerID}/${slug}`,
20 | ratings: ratings.reverse(),
21 | avgRating: average,
22 | count,
23 | },
24 | });
25 | } else {
26 | yield put({ type: actions.fetchRatingsFailure });
27 | }
28 | } catch (err) {
29 | yield put({ type: actions.fetchRatingsFailure });
30 | }
31 | }
32 |
33 | export default function* RatingsSaga() {
34 | yield takeEvery(actions.fetchRatings, getRatingsAction);
35 | }
36 |
--------------------------------------------------------------------------------
/reducers/saga/storeListings.js:
--------------------------------------------------------------------------------
1 | import { call, put, takeEvery, select } from 'redux-saga/effects';
2 |
3 | import { actions } from '../storeListings';
4 |
5 | import { getListings } from '../../api/products';
6 | import { getUserCredentails } from './sagaSelector';
7 |
8 | function* fetchListings() {
9 | const { username, password } = yield select(getUserCredentails);
10 | const result = yield call(getListings, username, password);
11 | yield put({ type: actions.setListings, payload: result });
12 | }
13 |
14 | const SettingsSaga = function* Search() {
15 | yield takeEvery(actions.fetchListings, fetchListings);
16 | };
17 |
18 | export default SettingsSaga;
19 |
--------------------------------------------------------------------------------
/reducers/socket.js:
--------------------------------------------------------------------------------
1 | import { createAction } from 'redux-actions';
2 |
3 | export const actions = {
4 | incomingSocketMessage: 'SOCKET/INCOMING_SOCKET_MESSAGE',
5 | };
6 |
7 | export const incomingSocketMessage = createAction(actions.incomingSocketMessage);
8 |
--------------------------------------------------------------------------------
/reducers/storeListings.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 |
3 | export const actions = {
4 | fetchListings: 'STORE_LISTINGS/FETCH',
5 | setListings: 'STORE_LISTINGS/SET',
6 | };
7 |
8 | export const fetchListings = createAction(actions.fetchListings);
9 |
10 | const initialState = {
11 | listings: [],
12 | status: '',
13 | };
14 |
15 | export default handleActions(
16 | {
17 | [actions.fetchListings]: state => ({ ...state, status: 'fetching' }),
18 | [actions.setListings]: (state, action) => ({ ...state, listings: action.payload, status: 'fectched' }),
19 | },
20 | initialState,
21 | );
22 |
--------------------------------------------------------------------------------
/reducers/wishlist.js:
--------------------------------------------------------------------------------
1 | import { createAction, handleActions } from 'redux-actions';
2 | import { get } from 'lodash';
3 | import { eventTracker } from '../utils/EventTracker';
4 |
5 | export const actions = {
6 | addWishListing: 'WISHLIST/ADD_WISH_LISTING',
7 | removeWishListing: 'WISHLIST/REMOVE_WISH_LISTING',
8 | fetchWishList: 'WISHLIST/FETCH_WISH_LIST',
9 | };
10 |
11 | export const addWishListing = createAction(actions.addWishListing);
12 | export const removeWishListing = createAction(actions.removeWishListing);
13 |
14 | const initialState = [];
15 |
16 | export default handleActions(
17 | {
18 | [actions.addWishListing]: (state, action) => {
19 | eventTracker.trackEvent('Wishlist-AddItem');
20 | return [action.payload, ...state];
21 | },
22 | [actions.removeWishListing]: (state, action) => {
23 | eventTracker.trackEvent('Wishlist-RemoveItem');
24 | return state.filter(item => get(item, 'listing.slug') !== action.payload.listing.slug);
25 | },
26 | },
27 | initialState,
28 | );
29 |
--------------------------------------------------------------------------------
/screens/externalPaySuccess.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { View } from 'react-native';
3 |
4 | import Header from '../components/molecules/Header';
5 | import NavBackButton from '../components/atoms/NavBackButton';
6 | import PurchaseStateTemplate from '../components/templates/PurchaseState';
7 |
8 | import { screenWrapper } from '../utils/styles';
9 |
10 | export default class ExternalPaySuccess extends PureComponent {
11 | handleGoBack = () => {
12 | const { navigation } = this.props;
13 | const screenKey = navigation.getParam('screenKey');
14 | navigation.goBack(screenKey);
15 | }
16 |
17 | generatePaidOrderInfo = () => {
18 | const { navigation } = this.props;
19 | const orderId = navigation.getParam('orderId');
20 | return { orderId };
21 | }
22 |
23 | render() {
24 | const { navigation } = this.props;
25 | return (
26 |
27 | } onLeft={this.handleGoBack} />
28 |
33 |
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/screens/queryResult.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { Text, View } from 'react-native';
3 |
4 | import Header from '../components/molecules/Header';
5 | import InfiniteProducts from '../components/templates/InfiniteProducts';
6 | import NavBackButton from '../components/atoms/NavBackButton';
7 | import { screenWrapper } from '../utils/styles';
8 |
9 | class QueryResult extends PureComponent {
10 | goBack = () => {
11 | const { navigation } = this.props;
12 | navigation.goBack();
13 | };
14 |
15 | handleGoToListingDetails = (params) => {
16 | this.props.navigation.navigate('Listing', params);
17 | }
18 |
19 | render() {
20 | const queryString = this.props.navigation.getParam('query');
21 | return (
22 |
23 | } onLeft={this.goBack} title="Listings" />
24 |
29 |
30 | );
31 | }
32 | }
33 |
34 | export default QueryResult;
35 |
--------------------------------------------------------------------------------
/screens/shippingOptions.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { connect } from 'react-redux';
3 | import { View } from 'react-native';
4 |
5 | import Header from '../components/molecules/Header';
6 | import ListShippingMethod from '../components/templates/ListShippingMethod';
7 | import NavBackButton from '../components/atoms/NavBackButton';
8 |
9 | import { removeShippingOption } from '../reducers/createListing';
10 | import { screenWrapper } from '../utils/styles';
11 |
12 | class ShippingOptions extends PureComponent {
13 | onAdd = () => {
14 | this.props.navigation.navigate('AddShippingMethod');
15 | };
16 |
17 | onRemove = (idx) => {
18 | this.props.removeShippingOption(idx);
19 | };
20 |
21 | onEdit = (idx) => {
22 | this.props.navigation.navigate('AddShippingMethod', { idx });
23 | };
24 |
25 | render() {
26 | return (
27 |
28 | }
30 | onLeft={() => {
31 | this.props.navigation.goBack();
32 | }}
33 | title="Shipping"
34 | noBorder
35 | />
36 |
37 |
38 | );
39 | }
40 | }
41 |
42 | const mapDispatchToProps = {
43 | removeShippingOption,
44 | };
45 |
46 | export default connect(
47 | null,
48 | mapDispatchToProps,
49 | )(ShippingOptions);
50 |
--------------------------------------------------------------------------------
/screens/transactions.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { connect } from 'react-redux';
3 | import { View } from 'react-native';
4 |
5 | import Header from '../components/molecules/Header';
6 | import TransactionHistory from '../components/templates/TransactionHistory';
7 | import { fetchTransactions } from '../reducers/wallet';
8 | import NavBackButton from '../components/atoms/NavBackButton';
9 | import { screenWrapper } from '../utils/styles';
10 |
11 | class Transactions extends PureComponent {
12 | componentWillMount() {
13 | this.props.fetchTransactions();
14 | }
15 | render() {
16 | return (
17 |
18 | }
20 | onLeft={() => {
21 | this.props.navigation.goBack();
22 | }}
23 | title="Transactions"
24 | />
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | const mapStateToProps = state => ({});
32 |
33 | const mapDispatchToProps = {
34 | fetchTransactions,
35 | };
36 |
37 | export default connect(
38 | mapStateToProps,
39 | mapDispatchToProps,
40 | )(Transactions);
41 |
--------------------------------------------------------------------------------
/screens/wishlist.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { View } from 'react-native';
3 | import { connect } from 'react-redux';
4 |
5 | import Header from '../components/molecules/Header';
6 | import WishListView from '../components/templates/wishlist';
7 | import NavBackButton from '../components/atoms/NavBackButton';
8 | import { foregroundColor } from '../components/commonColors';
9 | import { eventTracker } from '../utils/EventTracker';
10 |
11 | const styles = {
12 | wrapper: {
13 | flex: 1,
14 | backgroundColor: foregroundColor,
15 | },
16 | };
17 |
18 | class WishList extends PureComponent {
19 | handleGoBack = () => this.props.navigation.goBack()
20 | handleGoToListing = (params) => {
21 | eventTracker.trackEvent('Wishlist-TappedWishlistItem');
22 | this.props.navigation.push('Listing', params);
23 | }
24 |
25 | render() {
26 | const { wishlist } = this.props;
27 | return (
28 |
29 | } onLeft={this.handleGoBack} title="Wishlist" />
30 |
34 |
35 | );
36 | }
37 | }
38 |
39 | const mapStateToProps = state => ({
40 | wishlist: state.wishlist,
41 | });
42 |
43 | export default connect(mapStateToProps)(WishList);
44 |
--------------------------------------------------------------------------------
/selectors/listing.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenBazaar/haven/ef354df0111284c76cc170c7988a3257c300c8e0/selectors/listing.js
--------------------------------------------------------------------------------
/selectors/moderators.js:
--------------------------------------------------------------------------------
1 | import { createSelector } from 'reselect';
2 |
3 | export const moderatorsSelector = state => state.moderators;
4 |
5 | export const filterModerators = createSelector(
6 | moderatorsSelector,
7 | moderators => filteringModerators =>
8 | filteringModerators.filter(moderator => moderators.find(peerID => moderator === peerID)),
9 | );
10 |
--------------------------------------------------------------------------------
/selectors/notifications.js:
--------------------------------------------------------------------------------
1 | export const getNetworkNotifications = state => state.notifications.notifications;
2 |
3 | export const getStreamNotifiactions = state => state.stream.notifications;
4 |
--------------------------------------------------------------------------------
/selectors/order.js:
--------------------------------------------------------------------------------
1 | import { createSelector } from 'reselect';
2 |
3 | const purchasesSelector = state => state.orders.purchases;
4 | const salesSelector = state => state.orders.sales;
5 |
6 | const ordersSelector = createSelector(
7 | purchasesSelector,
8 | salesSelector,
9 | (purchases, sales) => {
10 | return [...purchases, ...sales];
11 | },
12 | );
13 |
14 | const orderSelector = createSelector(
15 | ordersSelector,
16 | orders => (orderId) => {
17 | const order = orders.find(o => o.orderId === orderId);
18 | return order || {};
19 | },
20 | );
21 |
22 | const peerIDSelector = createSelector(
23 | orderSelector,
24 | getOrderBrief => (orderId, orderType) => {
25 | const order = getOrderBrief(orderId);
26 | const { vendorId, buyerId } = order;
27 | return orderType === 'purchases' ? vendorId : buyerId;
28 | },
29 | );
30 |
31 | export const ordersMap = state => ({
32 | getOrderBrief: orderSelector(state),
33 | getPeerIDFromOrder: peerIDSelector(state),
34 | });
35 |
--------------------------------------------------------------------------------
/selectors/profile.js:
--------------------------------------------------------------------------------
1 | import { get } from 'lodash';
2 |
3 | export const getUserPeerID = state => get(state, 'profile.data.peerID');
4 | export const getBlockedNodes = state => state.settings.blockedNodes || [];
5 |
--------------------------------------------------------------------------------
/status-bar.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View, StatusBar, Platform } from 'react-native';
3 | import { ifIphoneX } from 'react-native-iphone-x-helper';
4 |
5 | const iOSStatusBarHeight = ifIphoneX(44, 20);
6 |
7 | export const statusbarHeight = Platform.OS === 'ios' ? iOSStatusBarHeight : 24;
8 |
9 | export const StatusBarSpacer = ({ backgroundColor = 'transparent' }) => {
10 | if (Platform.OS === 'ios') {
11 | return (
12 |
13 | );
14 | } else {
15 | return null;
16 | }
17 | };
18 |
19 | export default function (props) {
20 | const { backgroundColor } = props;
21 | if (Platform.OS === 'ios') {
22 | return (
23 |
24 |
25 |
26 | );
27 | } else {
28 | return (
29 |
30 |
31 |
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/store.js:
--------------------------------------------------------------------------------
1 | import { applyMiddleware, createStore } from 'redux';
2 | import createSagaMiddleware from 'redux-saga';
3 | import { persistStore } from 'redux-persist';
4 | import Reactotron from 'reactotron-react-native';
5 | import { composeWithDevTools } from 'redux-devtools-extension';
6 |
7 | import reducer from './reducers';
8 | import mainSaga from './reducers/saga';
9 |
10 | const sagaMiddleware = createSagaMiddleware();
11 |
12 | const store = createStore(
13 | reducer,
14 | composeWithDevTools(
15 | applyMiddleware(sagaMiddleware),
16 | Reactotron.createEnhancer(),
17 | ),
18 | );
19 |
20 | sagaMiddleware.run(mainSaga);
21 |
22 | export const persistor = persistStore(store);
23 |
24 | export default store;
25 |
--------------------------------------------------------------------------------
/utils/EventTracker/EventTracker.js:
--------------------------------------------------------------------------------
1 | import Countly from 'countly-sdk-react-native';
2 |
3 | export default class EventTracker {
4 | constructor(isTracking = false) {
5 | this.isTracking = isTracking;
6 | }
7 |
8 | changeTrackingStatus(isTracking) {
9 | if (!isTracking) {
10 | Countly.stop();
11 | } else {
12 | Countly.start();
13 | }
14 | this.isTracking = isTracking;
15 | }
16 |
17 | getTrackingStatus() {
18 | return this.isTracking;
19 | }
20 |
21 | asyncEventStart(event) {
22 | if (this.isTracking) {
23 | Countly.startEvent(event);
24 | }
25 | }
26 |
27 | asyncEventFinished(event) {
28 | if (this.isTracking) {
29 | Countly.endEvent(event);
30 | }
31 | }
32 |
33 | asyncEventSuccess(event) {
34 | if (this.isTracking) {
35 | Countly.recordEvent({ key: 'AsyncEventSuccess', segmentation: { event } });
36 | }
37 | }
38 |
39 | trackEvent(key, segmentation = {}) {
40 | if (this.isTracking) {
41 | Countly.recordEvent({ key, segmentation });
42 | }
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/utils/EventTracker/index.js:
--------------------------------------------------------------------------------
1 | import EventTracker from './EventTracker';
2 |
3 | export const eventTracker = new EventTracker();
4 |
5 | export const changeTrackingStatus = (isTracking) => {
6 | eventTracker.changeTrackingStatus(isTracking);
7 | };
8 |
--------------------------------------------------------------------------------
/utils/fee.js:
--------------------------------------------------------------------------------
1 | export const DEFAULT_FEE_LEVELS = [
2 | {
3 | label: 'Super Economic',
4 | value: 'superEconomic',
5 | description: 'Cheapest, Slowest',
6 | fee: 0,
7 | },
8 | {
9 | label: 'Economic',
10 | value: 'economic',
11 | description: 'Cheap, Slow',
12 | fee: 0,
13 | },
14 | {
15 | label: 'Normal',
16 | value: 'normal',
17 | description: 'Average fee and wait time',
18 | fee: 0,
19 | },
20 | {
21 | label: 'Priority',
22 | value: 'priority',
23 | description: 'Most Expensive, Fastest',
24 | fee: 0,
25 | },
26 | ];
27 |
28 | export const getFeeLevelDescription = (level) => {
29 | switch (level) {
30 | case 'superEconomic':
31 | return 'Cheapest, Slowest';
32 | case 'priority':
33 | return 'Most Expensive, Fastest';
34 | case 'economic':
35 | return 'Cheap, Slow';
36 | case 'normal':
37 | default:
38 | return 'Average fee and wait time';
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/utils/firestore.js:
--------------------------------------------------------------------------------
1 | // firebase.js
2 | import Firestore from '@react-native-firebase/firestore';
3 |
4 | const ref = Firestore().collection('peer_token');
5 |
6 | export const addPeerToTokenMap = async (uid, peerID, token) => {
7 | await ref.doc(peerID).set({ token, uid });
8 | };
9 |
--------------------------------------------------------------------------------
/utils/hashtags.js:
--------------------------------------------------------------------------------
1 | export function getHashTags(inputText) {
2 | const regex = /(^|\B)#(?![0-9_]+\b)([a-zA-Z0-9_]{1,30})(\b|\r)/g;
3 | const matches = [];
4 | let match;
5 |
6 |
7 | while ((match = regex.exec(inputText))) {
8 | matches.push(match[0].slice(1));
9 | }
10 |
11 | return matches;
12 | }
13 |
--------------------------------------------------------------------------------
/utils/keyboard.js:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 |
3 | export const keyboardAvoidingViewSharedProps = Platform.OS === 'ios' ? { behavior: 'padding' } : {};
4 |
--------------------------------------------------------------------------------
/utils/navbar.js:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 |
3 | export const navHeightStyle = Platform.select({
4 | ios: {
5 | height: 44,
6 | },
7 | android: {
8 | height: 56,
9 | },
10 | });
11 |
12 | export const avatarSize = Platform.select({
13 | ios: {
14 | width: 32,
15 | height: 32,
16 | },
17 | android: {
18 | width: 36,
19 | height: 36,
20 | },
21 | });
22 |
23 | export const avatarHolderSize = Platform.select({
24 | ios: {
25 | width: 36,
26 | height: 36,
27 | },
28 | android: {
29 | width: 40,
30 | height: 40,
31 | },
32 | });
33 |
34 | export const tabNotifBadgeSize = Platform.select({
35 | ios: {
36 | width: 20,
37 | height: 20,
38 | },
39 | android: {
40 | width: 21,
41 | height: 21,
42 | },
43 | });
44 |
45 | export const notifBadgeSize = Platform.select({
46 | ios: {
47 | width: 23,
48 | height: 23,
49 | },
50 | android: {
51 | width: 24,
52 | height: 24,
53 | },
54 | });
55 |
56 | export const tabBadgeStyle = Platform.select({
57 | ios: {
58 | position: 'absolute',
59 | right: -5,
60 | top: 5,
61 | },
62 | android: {
63 | position: 'absolute',
64 | right: -5,
65 | top: 1,
66 | },
67 | });
68 |
69 | export const badgeStyle = Platform.select({
70 | ios: {
71 | position: 'absolute',
72 | right: -9,
73 | top: 0,
74 | },
75 | android: {
76 | position: 'absolute',
77 | right: -10,
78 | top: 1,
79 | },
80 | });
81 |
--------------------------------------------------------------------------------
/utils/profile.js:
--------------------------------------------------------------------------------
1 | export const getDefaultProfileFromPeerId = peerID => ({
2 | peerID,
3 | name: `OB ${(peerID || '').substring(0, 6)}`,
4 | });
5 |
--------------------------------------------------------------------------------
/utils/rateApp.js:
--------------------------------------------------------------------------------
1 | import { Alert, Platform } from 'react-native';
2 | import Rate, { AndroidMarket } from 'react-native-rate';
3 |
4 | import { APPLE_APP_ID, GOOGLE_PACKAGE_NAME } from '../config/appIDConfig';
5 |
6 | export const rateApp = () => {
7 | const options = {
8 | AppleAppID: APPLE_APP_ID,
9 | GooglePackageName: GOOGLE_PACKAGE_NAME,
10 | preferredAndroidMarket: AndroidMarket.Google,
11 | preferInApp: true,
12 | };
13 | if (Platform.OS === 'ios') {
14 | Rate.rate(options);
15 | } else {
16 | Alert.alert('Enjoying Haven?', "We'd love to hear your feedback.", [
17 | { text: 'Later' },
18 | {
19 | text: 'Rate Now',
20 | onPress: () => {
21 | Rate.rate(options);
22 | },
23 | },
24 | ]);
25 | }
26 | };
27 |
28 |
--------------------------------------------------------------------------------
/utils/ratings.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Text } from 'react-native';
3 | import Ionicons from 'react-native-vector-icons/Ionicons';
4 |
5 | import { starRatingColor } from '../components/commonColors';
6 |
7 | const starStyle = {
8 | marginRight: 3,
9 | };
10 |
11 | const ratingText = {
12 | marginLeft: 6,
13 | };
14 |
15 | export const ratingOptions = [0, 5, 4, 3].map((value) => {
16 | if (value === 0) {
17 | return { value, label: 'Any', exclusive: true };
18 | } else {
19 | const stars = [1, 2, 3, 4, 5].map((i) => {
20 | if (i <= value) {
21 | return ;
22 | } else {
23 | return ;
24 | }
25 | });
26 | stars.push({value.toFixed(1)});
27 | return { value, label: stars };
28 | }
29 | });
30 |
--------------------------------------------------------------------------------
/utils/server.js:
--------------------------------------------------------------------------------
1 | import base64 from 'base-64';
2 | import RnFs from 'react-native-fs';
3 |
4 | class ServerConfig {
5 | serverToken = '';
6 | username='';
7 | password='';
8 | constructor() {
9 | this.username = 'username';
10 | this.password = 'password';
11 | }
12 | setServerToken(serverToken) {
13 | this.serverToken = serverToken;
14 | }
15 | getServerToken() {
16 | return this.serverToken;
17 | }
18 | getAuthToken() {
19 | return `Basic ${base64.encode(`${this.username}:${this.password}`)}`;
20 | }
21 | getAuthHeader(username = this.username, password = this.password) {
22 | return {
23 | authorization: `Basic ${base64.encode(`${username}:${password}`)}`,
24 | cookie: `OpenBazaar_Auth_Cookie=${this.serverToken}`,
25 | };
26 | }
27 | }
28 |
29 | export const serverConfig = new ServerConfig();
30 |
31 | export const SERVER_PATH = `${RnFs.DocumentDirectoryPath}/Haven`;
32 | export const SERVER_UNZIP_PATH = `${RnFs.DocumentDirectoryPath}/Haven_Unzip`;
33 |
--------------------------------------------------------------------------------
/utils/stream.js:
--------------------------------------------------------------------------------
1 | import * as _ from 'lodash';
2 |
3 | export const parseFeedData = feedArray => feedArray.reduce((prev, feed) => {
4 | const { id: activityId } = feed;
5 | const result = { ...prev };
6 | if (feed.verb === 'REPOST') {
7 | result.repost = [...result.repost, _.get(feed, 'postData.activityId')];
8 | }
9 | result.feed = { ...result.feed, [activityId]: feed };
10 | result.feedList = [...result.feedList, activityId];
11 | return result;
12 | }, { feed: {}, feedList: [], repost: [] });
13 |
14 | export const parseReactions = reactions => reactions.reduce((prev, reaction) => {
15 | switch (reaction.kind) {
16 | case 'like':
17 | return { ...prev, likes: [...prev.likes, reaction.user_id] };
18 | case 'repost':
19 | return { ...prev, reposts: [...prev.reposts, reaction.user_id] };
20 | case 'comment':
21 | default:
22 | return { ...prev, comments: [reaction, ...prev.comments] };
23 | }
24 | }, { likes: [], reposts: [], comments: [] });
25 |
--------------------------------------------------------------------------------
/utils/string.js:
--------------------------------------------------------------------------------
1 | import { capitalize, trim } from 'lodash';
2 |
3 | export const getNumericPart = (str) => {
4 | if (typeof str === 'number') {
5 | return str;
6 | }
7 |
8 | let startPos = 0;
9 | let endPos = str.length - 1;
10 | for (let i = 0; i < str.length; i += 1) {
11 | if (isFinite(str[i])) {
12 | startPos = i;
13 | break;
14 | }
15 | }
16 | for (let j = str.length - 1; j >= 0; j -= 1) {
17 | if (isFinite(str[j])) {
18 | endPos = j;
19 | break;
20 | }
21 | }
22 | return str.slice(startPos, endPos + 1);
23 | };
24 |
25 | export const parseCountryName = (country) => {
26 | if (!country) {
27 | return '';
28 | }
29 |
30 | const parts = country.split('_');
31 | const newParts = parts.map(part => capitalize(part));
32 | return newParts.join(' ');
33 | };
34 |
35 | export const eatSpaces = (str) => {
36 | const trimedString = trim(str);
37 | const result = [trimedString[0]];
38 | for (let i = 1; i < trimedString.length; i += 1) {
39 | const curLetterAscii = trimedString[i].charCodeAt(0);
40 | const prevLetterAscii = result[result.length - 1].charCodeAt(0);
41 | if ((curLetterAscii !== 32 && curLetterAscii !== 160) || (prevLetterAscii !== 32 && prevLetterAscii !== 160)) {
42 | result.push(trimedString[i]);
43 | }
44 | }
45 | return result.join('');
46 | };
47 |
--------------------------------------------------------------------------------
/utils/toast.js:
--------------------------------------------------------------------------------
1 | export const TOAST_OPTION = {
2 | containerStyle: {
3 | height: 40,
4 | borderRadius: 30,
5 | paddingHorizontal: 20,
6 | backgroundColor: 'rgba(34, 34, 34, 0.7)',
7 | width: 150,
8 | bottom: 50,
9 | },
10 | shadow: false,
11 | };
12 |
--------------------------------------------------------------------------------
/utils/webview.js:
--------------------------------------------------------------------------------
1 | export const cssCode = `
2 |
3 |
4 | `;
5 |
6 | export const jsCode = `
7 | var imgs = document.getElementsByTagName("img");
8 | for(var i = 0; i < imgs.length; i++) {
9 | imgs[i].style.maxWidth='100%';
10 | }
11 | `;
12 |
--------------------------------------------------------------------------------