From 7a1392bf3cc81abf8f90f84b4929f66314fde753 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Tue, 28 Jun 2022 09:38:17 -0500 Subject: [PATCH 01/13] refactor --- interfaces/Interfaces.tsx | 4 - package.json | 5 +- pages/_document.tsx | 2 +- pages/index.tsx | 8 +- skyhitz-common/index.ts | 1 - .../src/backends/apollo-client.backend.ts | 53 ----- .../src/backends/payments.backend.ts | 72 ------- skyhitz-common/src/backends/user.backend.ts | 132 ------------- skyhitz-common/src/index.ts | 2 - .../src/utils/unique-id-generator.ts | 63 ------ {modules => src}/accounts/AuthScreen.tsx | 11 +- {modules => src}/accounts/LoadingScreen.tsx | 2 +- {modules => src}/accounts/OpenEmail.ts | 0 {modules => src}/accounts/SignInScreen.tsx | 12 +- {modules => src}/accounts/SignUpScreen.tsx | 10 +- {modules => src}/accounts/ValidationIcon.tsx | 6 +- .../accounts/WalletConnectBtn.tsx | 6 +- .../src => src}/algolia/algolia.ts | 0 src/api/client.ts | 4 + .../entries.backend.ts => src/api/entries.ts | 139 ++++++------- .../likes.backend.ts => src/api/likes.ts | 31 ++- src/api/payments.ts | 65 ++++++ src/api/user.ts | 125 ++++++++++++ .../users.backend.ts => src/api/users.ts | 0 src/atoms/atoms.ts | 33 ++++ .../src => src}/config/config.development.ts | 0 .../src => src}/config/config.production.ts | 0 .../src => src}/config/config.staging.ts | 0 {skyhitz-common/src => src}/config/config.ts | 0 .../src/constants => src/config}/constants.ts | 0 {skyhitz-common/src => src}/config/index.ts | 0 {constants => src/constants}/Colors.ts | 0 {constants => src/constants}/CursorPointer.ts | 0 {constants => src/constants}/Layout.ts | 0 .../functions}/CacheResourcesAsync.ts | 0 {functions => src/functions}/Stores.ts | 2 +- {functions => src/functions}/utils.ts | 2 +- {hooks => src/hooks}/nft-listener.ts | 4 +- {modules => src}/marketing/ShareAppBanner.tsx | 8 +- {modules => src}/marketing/web/Footer.tsx | 2 +- {modules => src}/marketing/web/Home.tsx | 2 +- .../marketing/web/MainWrapper.tsx | 4 +- {modules => src}/marketing/web/NavBar.tsx | 4 +- {modules => src}/marketing/web/Privacy.tsx | 2 +- .../marketing/web/SkyhitzLogo.tsx | 0 .../marketing/web/SocialLinks.tsx | 10 +- {modules => src}/marketing/web/Terms.tsx | 2 +- .../src => src}/models/entry.model.ts | 2 +- {skyhitz-common/src => src}/models/index.ts | 0 .../src => src}/models/payload.model.ts | 0 .../src => src}/models/user.model.ts | 16 +- {modules => src}/navigation/BottomTabBar.tsx | 0 {modules => src}/navigation/BottomTabView.tsx | 0 .../navigation/LazyAppStackNavigator.tsx | 34 ++-- .../navigation/LazyNavigationContainer.tsx | 4 +- .../navigation/LinkingConfiguration.tsx | 0 .../navigation/MainTabNavigator.tsx | 14 +- .../navigation/RootNavigation.tsx | 8 +- .../navigation/SuspenseLoading.tsx | 0 .../navigation/WebTabNavigator.tsx | 0 .../player/player-bar/MiniPlayer.tsx | 8 +- .../player/player-bar/MiniPlayerDesktop.tsx | 4 +- .../player/player-bar/PlayerDrawer.tsx | 4 +- .../play-btn-small/PlayBtnSmall.tsx | 8 +- .../player/player-screen/PlayerEntryInfo.tsx | 2 +- .../player/player-screen/PlayerNav.tsx | 6 +- .../player/player-screen/PlayerScreen.tsx | 10 +- .../player-screen/forward-btn/ForwardBtn.tsx | 8 +- .../player/player-screen/like-btn/LikeBtn.tsx | 8 +- .../likers-section/LikersSection.tsx | 8 +- .../player/player-screen/loop-btn/LoopBtn.tsx | 8 +- .../player/player-screen/play-btn/PlayBtn.tsx | 10 +- .../player-screen/play-btn/PlayDesktopBtn.tsx | 10 +- .../player-controls/PlayerControls.tsx | 10 +- .../player/player-screen/prev-btn/PrevBtn.tsx | 6 +- .../player-screen/shuffle-btn/ShuffleBtn.tsx | 8 +- .../player/player-screen/slider/Slider.tsx | 4 +- .../video-player/BlurImageBackground.tsx | 0 .../video-player/CenteredView.tsx | 2 +- .../player-screen/video-player/Control.tsx | 0 .../video-player/FullscreenControl.tsx | 8 +- .../video-player/PlayPauseInvisibleArea.tsx | 6 +- .../player-screen/video-player/UiStates.tsx | 0 .../video-player/VideoComponent.tsx | 2 +- .../video-player/VideoConstants.tsx | 0 .../video-player/VideoErrorText.tsx | 6 +- .../player-screen/video-player/VideoIcons.tsx | 6 +- .../video-player/VideoPlayer.tsx | 10 +- .../video-player/VideoTimeDisplay.tsx | 4 +- .../playlists/CollectionScreen.tsx | 10 +- {modules => src}/playlists/LikesRow.tsx | 10 +- {modules => src}/playlists/LikesScreen.tsx | 10 +- {modules => src}/playlists/MyMusicRow.tsx | 10 +- .../profile/EditProfilePhotoBtn.tsx | 6 +- .../profile/EditProfileScreen.tsx | 20 +- {modules => src}/profile/LowBalanceModal.tsx | 14 +- {modules => src}/profile/MediaUpload.tsx | 24 +-- {modules => src}/profile/MintNFT.tsx | 0 .../profile/PaymentModal.native.tsx | 6 +- {modules => src}/profile/PaymentModal.tsx | 10 +- {modules => src}/profile/PaymentStep.tsx | 6 +- .../profile/ProfileEntryListView.tsx | 10 +- {modules => src}/profile/ProfileScreen.tsx | 6 +- .../profile/ProfileSettingsScreen.tsx | 18 +- .../profile/ProfileSettingsTopContainer.tsx | 14 +- .../profile/ProfileTopContainer.tsx | 6 +- {modules => src}/profile/WithdrawalModal.tsx | 14 +- {modules => src}/providers/Providers.tsx | 2 +- {modules => src}/search/ChartsView.tsx | 6 +- {modules => src}/search/EntryOptionsModal.tsx | 12 +- {modules => src}/search/LikeOptionRow.tsx | 8 +- .../search/PricingOptionsModal.tsx | 12 +- {modules => src}/search/RecentlyAdded.tsx | 8 +- .../search/RemoveFromMyMusicRow.tsx | 8 +- {modules => src}/search/SearchEntryList.tsx | 10 +- {modules => src}/search/SearchEntryView.tsx | 6 +- {modules => src}/search/SearchHeader.tsx | 6 +- {modules => src}/search/SearchNavigator.tsx | 6 +- {modules => src}/search/SearchTabsView.tsx | 6 +- {modules => src}/search/SearchUserList.tsx | 10 +- {modules => src}/search/SearchUserView.tsx | 6 +- {modules => src}/search/SetPrice.tsx | 6 +- {modules => src}/search/TopRecentUserView.tsx | 6 +- {modules => src}/search/TopUserSearchView.tsx | 8 +- {stellar => src/stellar}/index.ts | 2 +- .../src => src}/stores/edit-profile.store.ts | 4 +- .../stores/entries-search.store.ts | 2 +- .../src => src}/stores/entry.store.ts | 4 +- {skyhitz-common/src => src}/stores/index.ts | 0 .../src => src}/stores/input-search.store.ts | 0 .../src => src}/stores/likes.store.ts | 2 +- .../src => src}/stores/payments.store.ts | 4 +- .../src => src}/stores/player.store.ts | 2 +- .../src => src}/stores/profile.store.ts | 2 +- .../src => src}/stores/session.store.ts | 17 +- .../stores/sign-in-validation.store.ts | 1 + .../stores/sign-up-validation.store.ts | 0 .../src => src}/stores/user-entries.store.ts | 2 +- .../username-and-email-validation.store.ts | 0 .../src => src}/stores/users-search.store.ts | 2 +- .../stores/wallet-connect.store.ts | 0 {skyhitz-common/src => src}/types/index.ts | 0 {modules => src}/ui/ArrowDownBackBtn.tsx | 6 +- {modules => src}/ui/BackgroundImage.tsx | 0 {modules => src}/ui/BottomPlaceholder.tsx | 0 {modules => src}/ui/BuyOptionsModal.tsx | 4 +- {modules => src}/ui/CancelEditBtn.tsx | 4 +- {modules => src}/ui/Divider.tsx | 2 +- {modules => src}/ui/DoneEditBtn.tsx | 6 +- {modules => src}/ui/EditBtn.tsx | 6 +- {modules => src}/ui/EntryChartRow.tsx | 8 +- {modules => src}/ui/EntryPrice.tsx | 8 +- {modules => src}/ui/EntryRow.tsx | 8 +- {modules => src}/ui/Input.tsx | 2 +- {modules => src}/ui/LargeBtn.tsx | 4 +- {modules => src}/ui/Letter.tsx | 0 {modules => src}/ui/LogOutBtn.tsx | 6 +- {modules => src}/ui/MediaQueries.tsx | 0 {modules => src}/ui/ResponsiveLayout.tsx | 0 {modules => src}/ui/SearchingLoader.tsx | 2 +- {modules => src}/ui/TextWithLetterSpacing.tsx | 2 +- {modules => src}/ui/ThreeDots.tsx | 4 +- {modules => src}/ui/UserAvatar.tsx | 2 +- {modules => src}/ui/UserRow.tsx | 6 +- {modules => src}/ui/ViewPropTypes.tsx | 0 {modules => src}/ui/buy-btn/BuyBtn.tsx | 8 +- {modules => src}/ui/icons/account-box.tsx | 0 {modules => src}/ui/icons/check.tsx | 0 {modules => src}/ui/icons/chevron-down.tsx | 0 {modules => src}/ui/icons/chevron-left.tsx | 0 {modules => src}/ui/icons/chevron-right.tsx | 0 {modules => src}/ui/icons/chevron-up.tsx | 0 {modules => src}/ui/icons/circle.tsx | 0 {modules => src}/ui/icons/cog.tsx | 0 {modules => src}/ui/icons/discord.tsx | 0 {modules => src}/ui/icons/dollar.tsx | 0 {modules => src}/ui/icons/fullscreen-exit.tsx | 0 {modules => src}/ui/icons/fullscreen.tsx | 0 {modules => src}/ui/icons/github.tsx | 0 {modules => src}/ui/icons/info-circle.tsx | 0 {modules => src}/ui/icons/instagram.tsx | 0 {modules => src}/ui/icons/key.tsx | 0 {modules => src}/ui/icons/like.tsx | 0 {modules => src}/ui/icons/logout.tsx | 0 {modules => src}/ui/icons/mail-outline.tsx | 0 {modules => src}/ui/icons/money.tsx | 0 {modules => src}/ui/icons/pause.tsx | 0 {modules => src}/ui/icons/person-outline.tsx | 0 {modules => src}/ui/icons/phone.tsx | 0 {modules => src}/ui/icons/pie.tsx | 0 {modules => src}/ui/icons/play.tsx | 0 {modules => src}/ui/icons/remove.tsx | 0 {modules => src}/ui/icons/repeat.tsx | 0 {modules => src}/ui/icons/search.tsx | 0 {modules => src}/ui/icons/shuffle.tsx | 0 {modules => src}/ui/icons/skip-backward.tsx | 0 {modules => src}/ui/icons/skip-forward.tsx | 0 {modules => src}/ui/icons/star-border.tsx | 0 {modules => src}/ui/icons/twitter.tsx | 0 {modules => src}/ui/icons/upload.tsx | 0 {modules => src}/ui/icons/user.tsx | 0 {modules => src}/ui/icons/wallet.tsx | 0 .../ui/icons/walletconnect-icon.tsx | 0 {modules => src}/ui/icons/x.tsx | 0 .../ui/searchbar/SearchBar.android.js | 8 +- .../ui/searchbar/SearchBar.ios.js | 8 +- {modules => src}/ui/searchbar/SearchBar.tsx | 0 yarn.lock | 187 ++++++++++-------- 208 files changed, 817 insertions(+), 910 deletions(-) delete mode 100644 interfaces/Interfaces.tsx delete mode 100644 skyhitz-common/index.ts delete mode 100644 skyhitz-common/src/backends/apollo-client.backend.ts delete mode 100644 skyhitz-common/src/backends/payments.backend.ts delete mode 100644 skyhitz-common/src/backends/user.backend.ts delete mode 100644 skyhitz-common/src/index.ts delete mode 100644 skyhitz-common/src/utils/unique-id-generator.ts rename {modules => src}/accounts/AuthScreen.tsx (92%) rename {modules => src}/accounts/LoadingScreen.tsx (89%) rename {modules => src}/accounts/OpenEmail.ts (100%) rename {modules => src}/accounts/SignInScreen.tsx (95%) rename {modules => src}/accounts/SignUpScreen.tsx (95%) rename {modules => src}/accounts/ValidationIcon.tsx (67%) rename {modules => src}/accounts/WalletConnectBtn.tsx (89%) rename {skyhitz-common/src => src}/algolia/algolia.ts (100%) create mode 100644 src/api/client.ts rename skyhitz-common/src/backends/entries.backend.ts => src/api/entries.ts (73%) rename skyhitz-common/src/backends/likes.backend.ts => src/api/likes.ts (72%) create mode 100644 src/api/payments.ts create mode 100644 src/api/user.ts rename skyhitz-common/src/backends/users.backend.ts => src/api/users.ts (100%) create mode 100644 src/atoms/atoms.ts rename {skyhitz-common/src => src}/config/config.development.ts (100%) rename {skyhitz-common/src => src}/config/config.production.ts (100%) rename {skyhitz-common/src => src}/config/config.staging.ts (100%) rename {skyhitz-common/src => src}/config/config.ts (100%) rename {skyhitz-common/src/constants => src/config}/constants.ts (100%) rename {skyhitz-common/src => src}/config/index.ts (100%) rename {constants => src/constants}/Colors.ts (100%) rename {constants => src/constants}/CursorPointer.ts (100%) rename {constants => src/constants}/Layout.ts (100%) rename {functions => src/functions}/CacheResourcesAsync.ts (100%) rename {functions => src/functions}/Stores.ts (83%) rename {functions => src/functions}/utils.ts (89%) rename {hooks => src/hooks}/nft-listener.ts (91%) rename {modules => src}/marketing/ShareAppBanner.tsx (86%) rename {modules => src}/marketing/web/Footer.tsx (95%) rename {modules => src}/marketing/web/Home.tsx (81%) rename {modules => src}/marketing/web/MainWrapper.tsx (96%) rename {modules => src}/marketing/web/NavBar.tsx (95%) rename {modules => src}/marketing/web/Privacy.tsx (99%) rename {modules => src}/marketing/web/SkyhitzLogo.tsx (100%) rename {modules => src}/marketing/web/SocialLinks.tsx (85%) rename {modules => src}/marketing/web/Terms.tsx (99%) rename {skyhitz-common/src => src}/models/entry.model.ts (98%) rename {skyhitz-common/src => src}/models/index.ts (100%) rename {skyhitz-common/src => src}/models/payload.model.ts (100%) rename {skyhitz-common/src => src}/models/user.model.ts (79%) rename {modules => src}/navigation/BottomTabBar.tsx (100%) rename {modules => src}/navigation/BottomTabView.tsx (100%) rename {modules => src}/navigation/LazyAppStackNavigator.tsx (88%) rename {modules => src}/navigation/LazyNavigationContainer.tsx (83%) rename {modules => src}/navigation/LinkingConfiguration.tsx (100%) rename {modules => src}/navigation/MainTabNavigator.tsx (87%) rename {modules => src}/navigation/RootNavigation.tsx (85%) rename {modules => src}/navigation/SuspenseLoading.tsx (100%) rename {modules => src}/navigation/WebTabNavigator.tsx (100%) rename {modules => src}/player/player-bar/MiniPlayer.tsx (90%) rename {modules => src}/player/player-bar/MiniPlayerDesktop.tsx (96%) rename {modules => src}/player/player-bar/PlayerDrawer.tsx (97%) rename {modules => src}/player/player-bar/play-btn-small/PlayBtnSmall.tsx (78%) rename {modules => src}/player/player-screen/PlayerEntryInfo.tsx (96%) rename {modules => src}/player/player-screen/PlayerNav.tsx (87%) rename {modules => src}/player/player-screen/PlayerScreen.tsx (86%) rename {modules => src}/player/player-screen/forward-btn/ForwardBtn.tsx (75%) rename {modules => src}/player/player-screen/like-btn/LikeBtn.tsx (84%) rename {modules => src}/player/player-screen/likers-section/LikersSection.tsx (91%) rename {modules => src}/player/player-screen/loop-btn/LoopBtn.tsx (78%) rename {modules => src}/player/player-screen/play-btn/PlayBtn.tsx (88%) rename {modules => src}/player/player-screen/play-btn/PlayDesktopBtn.tsx (88%) rename {modules => src}/player/player-screen/player-controls/PlayerControls.tsx (61%) rename {modules => src}/player/player-screen/prev-btn/PrevBtn.tsx (78%) rename {modules => src}/player/player-screen/shuffle-btn/ShuffleBtn.tsx (82%) rename {modules => src}/player/player-screen/slider/Slider.tsx (91%) rename {modules => src}/player/player-screen/video-player/BlurImageBackground.tsx (100%) rename {modules => src}/player/player-screen/video-player/CenteredView.tsx (82%) rename {modules => src}/player/player-screen/video-player/Control.tsx (100%) rename {modules => src}/player/player-screen/video-player/FullscreenControl.tsx (81%) rename {modules => src}/player/player-screen/video-player/PlayPauseInvisibleArea.tsx (86%) rename {modules => src}/player/player-screen/video-player/UiStates.tsx (100%) rename {modules => src}/player/player-screen/video-player/VideoComponent.tsx (97%) rename {modules => src}/player/player-screen/video-player/VideoConstants.tsx (100%) rename {modules => src}/player/player-screen/video-player/VideoErrorText.tsx (76%) rename {modules => src}/player/player-screen/video-player/VideoIcons.tsx (77%) rename {modules => src}/player/player-screen/video-player/VideoPlayer.tsx (68%) rename {modules => src}/player/player-screen/video-player/VideoTimeDisplay.tsx (88%) rename {modules => src}/playlists/CollectionScreen.tsx (81%) rename {modules => src}/playlists/LikesRow.tsx (88%) rename {modules => src}/playlists/LikesScreen.tsx (81%) rename {modules => src}/playlists/MyMusicRow.tsx (87%) rename {modules => src}/profile/EditProfilePhotoBtn.tsx (90%) rename {modules => src}/profile/EditProfileScreen.tsx (94%) rename {modules => src}/profile/LowBalanceModal.tsx (93%) rename {modules => src}/profile/MediaUpload.tsx (95%) rename {modules => src}/profile/MintNFT.tsx (100%) rename {modules => src}/profile/PaymentModal.native.tsx (94%) rename {modules => src}/profile/PaymentModal.tsx (91%) rename {modules => src}/profile/PaymentStep.tsx (97%) rename {modules => src}/profile/ProfileEntryListView.tsx (77%) rename {modules => src}/profile/ProfileScreen.tsx (73%) rename {modules => src}/profile/ProfileSettingsScreen.tsx (86%) rename {modules => src}/profile/ProfileSettingsTopContainer.tsx (90%) rename {modules => src}/profile/ProfileTopContainer.tsx (91%) rename {modules => src}/profile/WithdrawalModal.tsx (94%) rename {modules => src}/providers/Providers.tsx (97%) rename {modules => src}/search/ChartsView.tsx (92%) rename {modules => src}/search/EntryOptionsModal.tsx (88%) rename {modules => src}/search/LikeOptionRow.tsx (89%) rename {modules => src}/search/PricingOptionsModal.tsx (95%) rename {modules => src}/search/RecentlyAdded.tsx (90%) rename {modules => src}/search/RemoveFromMyMusicRow.tsx (86%) rename {modules => src}/search/SearchEntryList.tsx (83%) rename {modules => src}/search/SearchEntryView.tsx (77%) rename {modules => src}/search/SearchHeader.tsx (88%) rename {modules => src}/search/SearchNavigator.tsx (81%) rename {modules => src}/search/SearchTabsView.tsx (91%) rename {modules => src}/search/SearchUserList.tsx (76%) rename {modules => src}/search/SearchUserView.tsx (71%) rename {modules => src}/search/SetPrice.tsx (88%) rename {modules => src}/search/TopRecentUserView.tsx (73%) rename {modules => src}/search/TopUserSearchView.tsx (85%) rename {stellar => src/stellar}/index.ts (97%) rename {skyhitz-common/src => src}/stores/edit-profile.store.ts (96%) rename {skyhitz-common/src => src}/stores/entries-search.store.ts (98%) rename {skyhitz-common/src => src}/stores/entry.store.ts (98%) rename {skyhitz-common/src => src}/stores/index.ts (100%) rename {skyhitz-common/src => src}/stores/input-search.store.ts (100%) rename {skyhitz-common/src => src}/stores/likes.store.ts (98%) rename {skyhitz-common/src => src}/stores/payments.store.ts (96%) rename {skyhitz-common/src => src}/stores/player.store.ts (99%) rename {skyhitz-common/src => src}/stores/profile.store.ts (92%) rename {skyhitz-common/src => src}/stores/session.store.ts (85%) rename {skyhitz-common/src => src}/stores/sign-in-validation.store.ts (98%) rename {skyhitz-common/src => src}/stores/sign-up-validation.store.ts (100%) rename {skyhitz-common/src => src}/stores/user-entries.store.ts (92%) rename {skyhitz-common/src => src}/stores/username-and-email-validation.store.ts (100%) rename {skyhitz-common/src => src}/stores/users-search.store.ts (96%) rename {skyhitz-common/src => src}/stores/wallet-connect.store.ts (100%) rename {skyhitz-common/src => src}/types/index.ts (100%) rename {modules => src}/ui/ArrowDownBackBtn.tsx (79%) rename {modules => src}/ui/BackgroundImage.tsx (100%) rename {modules => src}/ui/BottomPlaceholder.tsx (100%) rename {modules => src}/ui/BuyOptionsModal.tsx (97%) rename {modules => src}/ui/CancelEditBtn.tsx (84%) rename {modules => src}/ui/Divider.tsx (87%) rename {modules => src}/ui/DoneEditBtn.tsx (84%) rename {modules => src}/ui/EditBtn.tsx (79%) rename {modules => src}/ui/EntryChartRow.tsx (94%) rename {modules => src}/ui/EntryPrice.tsx (85%) rename {modules => src}/ui/EntryRow.tsx (93%) rename {modules => src}/ui/Input.tsx (98%) rename {modules => src}/ui/LargeBtn.tsx (92%) rename {modules => src}/ui/Letter.tsx (100%) rename {modules => src}/ui/LogOutBtn.tsx (82%) rename {modules => src}/ui/MediaQueries.tsx (100%) rename {modules => src}/ui/ResponsiveLayout.tsx (100%) rename {modules => src}/ui/SearchingLoader.tsx (96%) rename {modules => src}/ui/TextWithLetterSpacing.tsx (94%) rename {modules => src}/ui/ThreeDots.tsx (86%) rename {modules => src}/ui/UserAvatar.tsx (97%) rename {modules => src}/ui/UserRow.tsx (92%) rename {modules => src}/ui/ViewPropTypes.tsx (100%) rename {modules => src}/ui/buy-btn/BuyBtn.tsx (91%) rename {modules => src}/ui/icons/account-box.tsx (100%) rename {modules => src}/ui/icons/check.tsx (100%) rename {modules => src}/ui/icons/chevron-down.tsx (100%) rename {modules => src}/ui/icons/chevron-left.tsx (100%) rename {modules => src}/ui/icons/chevron-right.tsx (100%) rename {modules => src}/ui/icons/chevron-up.tsx (100%) rename {modules => src}/ui/icons/circle.tsx (100%) rename {modules => src}/ui/icons/cog.tsx (100%) rename {modules => src}/ui/icons/discord.tsx (100%) rename {modules => src}/ui/icons/dollar.tsx (100%) rename {modules => src}/ui/icons/fullscreen-exit.tsx (100%) rename {modules => src}/ui/icons/fullscreen.tsx (100%) rename {modules => src}/ui/icons/github.tsx (100%) rename {modules => src}/ui/icons/info-circle.tsx (100%) rename {modules => src}/ui/icons/instagram.tsx (100%) rename {modules => src}/ui/icons/key.tsx (100%) rename {modules => src}/ui/icons/like.tsx (100%) rename {modules => src}/ui/icons/logout.tsx (100%) rename {modules => src}/ui/icons/mail-outline.tsx (100%) rename {modules => src}/ui/icons/money.tsx (100%) rename {modules => src}/ui/icons/pause.tsx (100%) rename {modules => src}/ui/icons/person-outline.tsx (100%) rename {modules => src}/ui/icons/phone.tsx (100%) rename {modules => src}/ui/icons/pie.tsx (100%) rename {modules => src}/ui/icons/play.tsx (100%) rename {modules => src}/ui/icons/remove.tsx (100%) rename {modules => src}/ui/icons/repeat.tsx (100%) rename {modules => src}/ui/icons/search.tsx (100%) rename {modules => src}/ui/icons/shuffle.tsx (100%) rename {modules => src}/ui/icons/skip-backward.tsx (100%) rename {modules => src}/ui/icons/skip-forward.tsx (100%) rename {modules => src}/ui/icons/star-border.tsx (100%) rename {modules => src}/ui/icons/twitter.tsx (100%) rename {modules => src}/ui/icons/upload.tsx (100%) rename {modules => src}/ui/icons/user.tsx (100%) rename {modules => src}/ui/icons/wallet.tsx (100%) rename {modules => src}/ui/icons/walletconnect-icon.tsx (100%) rename {modules => src}/ui/icons/x.tsx (100%) rename {modules => src}/ui/searchbar/SearchBar.android.js (95%) rename {modules => src}/ui/searchbar/SearchBar.ios.js (95%) rename {modules => src}/ui/searchbar/SearchBar.tsx (100%) diff --git a/interfaces/Interfaces.tsx b/interfaces/Interfaces.tsx deleted file mode 100644 index a56f625..0000000 --- a/interfaces/Interfaces.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export interface NavStatelessComponent extends React.StatelessComponent { - navigationOptions?: Object; - router?: any; -} diff --git a/package.json b/package.json index f8db423..d47c1cf 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "license": "MIT", "main": "node_modules/expo/AppEntry.js", "dependencies": { - "@apollo/client": "^3.5.6", "@expo/html-elements": "^0.1.0", "@expo/match-media": "^0.1.0", "@react-native-async-storage/async-storage": "~1.15.0", @@ -56,7 +55,8 @@ "expo-linking": "~2.4.2", "expo-next-react-navigation": "0.0.25", "expo-permissions": "~13.0.3", - "graphql": "^16.2.0", + "graphql": "^16.5.0", + "graphql-request": "^4.3.0", "list": "^2.0.19", "lodash.debounce": "4.0.8", "mobx": "5.15.4", @@ -79,6 +79,7 @@ "react-native-tab-view": "^3.0.1", "react-native-web": "0.17.1", "react-responsive": "8.0.3", + "recoil": "^0.7.4", "setimmediate": "^1.0.5", "stellar-base": "^8.0.1", "twrnc": "^3.3.2" diff --git a/pages/_document.tsx b/pages/_document.tsx index 886b530..ccf21fb 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -62,7 +62,7 @@ class CustomDocument extends Document { /> - Skyhitz - Beats market for music creators + Skyhitz - Music NFTs on Stellar { console.log('error', error); /* Log the error to an error reporting service */ }; -const Providers = lazy(() => import('app/modules/providers/Providers')); +const Providers = lazy(() => import('app/src/providers/Providers')); -import LoadingScreen from 'app/modules/accounts/LoadingScreen'; +import LoadingScreen from 'app/src/accounts/LoadingScreen'; const SuspenseLoading = (props) => ( }>{props.children} ); diff --git a/skyhitz-common/index.ts b/skyhitz-common/index.ts deleted file mode 100644 index 8420b10..0000000 --- a/skyhitz-common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './src'; diff --git a/skyhitz-common/src/backends/apollo-client.backend.ts b/skyhitz-common/src/backends/apollo-client.backend.ts deleted file mode 100644 index 0f0b589..0000000 --- a/skyhitz-common/src/backends/apollo-client.backend.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - ApolloClient, - InMemoryCache, - from, - createHttpLink, -} from '@apollo/client'; -import { onError } from '@apollo/client/link/error'; -import { setContext } from '@apollo/client/link/context'; - -import { observable } from 'mobx'; -import { Config } from '../config'; -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { userDataKey } from '../constants/constants'; - -export let forceSignOut = observable.box(false); - -const httpLink = createHttpLink({ - uri: Config.GRAPHQL_URL, -}); - -const authLink = setContext(async (_, { headers }) => { - // get the authentication token from local storage if it exists - const userData = await AsyncStorage.getItem(userDataKey); - if (userData) { - const { jwt } = JSON.parse(userData); - if (jwt) { - return { - headers: { - ...headers, - authorization: jwt ? `Bearer ${jwt}` : '', - }, - }; - } - } - return { - headers: { - ...headers, - }, - }; -}); - -const logoutLink = onError(({ networkError }: any) => { - if ( - (networkError && networkError.statusCode === 401) || - networkError?.statusText === 'Unauthorized' - ) - forceSignOut.set(true); -}); - -export const client = new ApolloClient({ - link: from([authLink, logoutLink, httpLink]), - cache: new InMemoryCache(), -}); diff --git a/skyhitz-common/src/backends/payments.backend.ts b/skyhitz-common/src/backends/payments.backend.ts deleted file mode 100644 index 8bfb16c..0000000 --- a/skyhitz-common/src/backends/payments.backend.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { client } from './apollo-client.backend'; -import { gql } from '@apollo/client'; - -export class PaymentsBackend { - async subscribe(cardToken: string) { - return client - .mutate({ - mutation: gql` - mutation { - subscribeUser(cardToken: "${cardToken}") - } - `, - }) - .then((data: any) => data.data) - .then(({ subscribeUser }) => subscribeUser); - } - async buyCredits(cardToken: string, amount: number) { - return client - .mutate({ - mutation: gql` - mutation { - buyCredits(cardToken: "${cardToken}", amount: ${amount}) - } - `, - }) - .then((data: any) => data.data) - .then(({ buyCredits }) => buyCredits); - } - async getXLMPrice() { - return client - .query({ - query: gql` - { - xlmPrice - } - `, - fetchPolicy: 'network-only', - }) - .then((data: any) => data.data) - .then(({ xlmPrice }) => xlmPrice); - } - async withdrawToExternalWallet(address: string, amount: number) { - return client - .mutate({ - mutation: gql` - mutation { - withdrawToExternalWallet(address: "${address}", amount: ${amount}) - } - `, - }) - .then((data: any) => data.data) - .then(({ withdrawToExternalWallet }) => withdrawToExternalWallet); - } - async refreshSubscription() { - return client - .query({ - query: gql` - { - paymentsInfo { - subscribed - credits - } - } - `, - fetchPolicy: 'network-only', - }) - .then((data: any) => data.data) - .then(({ paymentsInfo }) => paymentsInfo); - } -} - -export const paymentsBackend = new PaymentsBackend(); diff --git a/skyhitz-common/src/backends/user.backend.ts b/skyhitz-common/src/backends/user.backend.ts deleted file mode 100644 index de40d8d..0000000 --- a/skyhitz-common/src/backends/user.backend.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { client } from './apollo-client.backend'; -import { gql } from '@apollo/client'; -import { SignUpForm } from '../types'; - -export class UserBackend { - async getAuthenticatedUser() { - return client - .query({ - query: gql` - { - authenticatedUser { - avatarUrl - displayName - username - id - jwt - publishedAt - email - description - } - } - `, - }) - .then((data: any) => data.data) - .then(({ authenticatedUser }) => authenticatedUser); - } - - async signUp({ displayName, email, username, publicKey }: SignUpForm) { - return client - .mutate({ - mutation: gql` - mutation { - createUserWithEmail(displayName: "${displayName}", email: "${email}", username: "${username}",publicKey: "${publicKey}"){ - avatarUrl - displayName - username - id - jwt - publishedAt - email - description - publicKey - } - } - `, - }) - .then((data: any) => data.data) - .then(({ createUserWithEmail }) => createUserWithEmail) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } - - async requestToken(usernameOrEmail, publicKey) { - return client - .mutate({ - mutation: gql` - mutation { - requestToken(usernameOrEmail: "${usernameOrEmail}", publicKey: "${publicKey}") - } - `, - }) - .then(({ data }: any) => { - return data; - }) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } - - async signIn(token?: string, uid?: string, xdr?: string) { - return client - .mutate({ - mutation: gql` - mutation { - signIn(token: "${token}", uid: "${uid}", signedXDR: "${xdr}"){ - avatarUrl - displayName - username - id - jwt - publishedAt - email - description - publicKey - } - } - `, - }) - .then((data: any) => data.data) - .then(({ signIn }) => signIn) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } - - async updateUser( - avatarUrl: string, - displayName: string, - description: string, - username: string, - email: string - ) { - return client - .mutate({ - mutation: gql` - mutation { - updateUser(avatarUrl: "${avatarUrl}", displayName: "${displayName}", description: "${description}", username: "${username}", email: "${email}"){ - avatarUrl - displayName - username - id - publishedAt - email - description - } - } - `, - }) - .then((data: any) => data.data) - .then(({ updateUser }) => updateUser) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } -} - -export const userBackend = new UserBackend(); diff --git a/skyhitz-common/src/index.ts b/skyhitz-common/src/index.ts deleted file mode 100644 index 36d472a..0000000 --- a/skyhitz-common/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './stores'; -export * from './models'; \ No newline at end of file diff --git a/skyhitz-common/src/utils/unique-id-generator.ts b/skyhitz-common/src/utils/unique-id-generator.ts deleted file mode 100644 index d63481d..0000000 --- a/skyhitz-common/src/utils/unique-id-generator.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Fancy ID generator that creates 20-character string identifiers with the following properties: - * - * 1. They're based on timestamp so that they sort *after* any existing ids. - * 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs. - * 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly). - * 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the - * latter ones will sort after the former ones. We do this by using the previous random bits - * but "incrementing" them by 1 (only in the case of a timestamp collision). - */ - -export default class UniqueIdGenerator { - // Timestamp of last push, used to prevent local collisions if you push twice in one ms. - private static lastPushTime = 0; - - // Modeled after base64 web-safe chars, but ordered by ASCII. - private static PUSH_CHARS = - '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'; - - // We generate 72-bits of randomness which get turned into 12 characters and appended to the - // timestamp to prevent collisions with other clients. We store the last characters we - // generated because in the event of a collision, we'll use those same characters except - // "incremented" by one. - private static lastRandChars: any = []; - - // Generates chronologically orderable unique string one by one - public static generate() { - var now = new Date().getTime(); - var duplicateTime = now === UniqueIdGenerator.lastPushTime; - UniqueIdGenerator.lastPushTime = now; - - var timeStampChars = new Array(8); - for (var i = 7; i >= 0; i--) { - timeStampChars[i] = UniqueIdGenerator.PUSH_CHARS.charAt(now % 64); - // NOTE: Can't use << here because javascript will convert to int and lose the upper bits. - now = Math.floor(now / 64); - } - if (now !== 0) - throw new Error('We should have converted the entire timestamp.'); - - var id = timeStampChars.join(''); - - if (!duplicateTime) { - for (i = 0; i < 12; i++) { - UniqueIdGenerator.lastRandChars[i] = Math.floor(Math.random() * 64); - } - } else { - // If the timestamp hasn't changed since last push, use the same random number, except incremented by 1. - for (i = 11; i >= 0 && UniqueIdGenerator.lastRandChars[i] === 63; i--) { - UniqueIdGenerator.lastRandChars[i] = 0; - } - UniqueIdGenerator.lastRandChars[i]++; - } - for (i = 0; i < 12; i++) { - id += UniqueIdGenerator.PUSH_CHARS.charAt( - UniqueIdGenerator.lastRandChars[i] - ); - } - if (id.length !== 20) throw new Error('Length should be 20.'); - - return id; - } -} diff --git a/modules/accounts/AuthScreen.tsx b/src/accounts/AuthScreen.tsx similarity index 92% rename from modules/accounts/AuthScreen.tsx rename to src/accounts/AuthScreen.tsx index 79cbcd6..28f8797 100644 --- a/modules/accounts/AuthScreen.tsx +++ b/src/accounts/AuthScreen.tsx @@ -1,14 +1,13 @@ import React from 'react'; import { StyleSheet, View, Text, TouchableHighlight } from 'react-native'; -import Layout from 'app/constants/Layout'; -import TextWithLetterSpacing from 'app/modules/ui/TextWithLetterSpacing'; -import Colors from 'app/constants/Colors'; -import { NavStatelessComponent } from 'app/interfaces/Interfaces'; +import Layout from 'app/src/constants/Layout'; +import TextWithLetterSpacing from 'app/src/ui/TextWithLetterSpacing'; +import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; -import BackgroundImage from 'app/modules/ui/BackgroundImage'; +import BackgroundImage from 'app/src/ui/BackgroundImage'; import SkyhitzLogo from '../marketing/web/SkyhitzLogo'; -const AuthScreen: NavStatelessComponent = (props) => { +const AuthScreen = (props) => { const linkTo = useLinkTo(); return ( diff --git a/modules/accounts/LoadingScreen.tsx b/src/accounts/LoadingScreen.tsx similarity index 89% rename from modules/accounts/LoadingScreen.tsx rename to src/accounts/LoadingScreen.tsx index 4cb38ba..5f75897 100644 --- a/modules/accounts/LoadingScreen.tsx +++ b/src/accounts/LoadingScreen.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { ActivityIndicator, StyleSheet, View } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; export default () => { return ( diff --git a/modules/accounts/OpenEmail.ts b/src/accounts/OpenEmail.ts similarity index 100% rename from modules/accounts/OpenEmail.ts rename to src/accounts/OpenEmail.ts diff --git a/modules/accounts/SignInScreen.tsx b/src/accounts/SignInScreen.tsx similarity index 95% rename from modules/accounts/SignInScreen.tsx rename to src/accounts/SignInScreen.tsx index 1b46a92..facddc3 100644 --- a/modules/accounts/SignInScreen.tsx +++ b/src/accounts/SignInScreen.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { StyleSheet, View, @@ -10,15 +10,15 @@ import { ActivityIndicator, Platform, } from 'react-native'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; -import BackgroundImage from 'app/modules/ui/BackgroundImage'; -import cursorPointer from 'app/constants/CursorPointer'; +import BackgroundImage from 'app/src/ui/BackgroundImage'; +import cursorPointer from 'app/src/constants/CursorPointer'; import { openEmail } from './OpenEmail'; import * as Linking from 'expo-linking'; -import { Config } from 'app/skyhitz-common/src/config'; +import { Config } from 'app/src/config'; import * as Device from 'expo-device'; -import WalletConnectBtn from 'app/modules/accounts/WalletConnectBtn'; +import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; export default observer(({ route, navigation }) => { diff --git a/modules/accounts/SignUpScreen.tsx b/src/accounts/SignUpScreen.tsx similarity index 95% rename from modules/accounts/SignUpScreen.tsx rename to src/accounts/SignUpScreen.tsx index e3f192d..c30f057 100644 --- a/modules/accounts/SignUpScreen.tsx +++ b/src/accounts/SignUpScreen.tsx @@ -9,12 +9,12 @@ import { Platform, } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; -import ValidationIcon from 'app/modules/accounts/ValidationIcon'; -import { Stores } from 'app/functions/Stores'; -import BackgroundImage from 'app/modules/ui/BackgroundImage'; -import WalletConnectBtn from 'app/modules/accounts/WalletConnectBtn'; +import ValidationIcon from 'app/src/accounts/ValidationIcon'; +import { Stores } from 'app/src/functions/Stores'; +import BackgroundImage from 'app/src/ui/BackgroundImage'; +import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; export default observer(() => { diff --git a/modules/accounts/ValidationIcon.tsx b/src/accounts/ValidationIcon.tsx similarity index 67% rename from modules/accounts/ValidationIcon.tsx rename to src/accounts/ValidationIcon.tsx index 003673a..484d894 100644 --- a/modules/accounts/ValidationIcon.tsx +++ b/src/accounts/ValidationIcon.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import Colors from 'app/constants/Colors'; -import CheckIcon from 'app/modules/ui/icons/check'; -import CloseIcon from 'app/modules/ui/icons/x'; +import Colors from 'app/src/constants/Colors'; +import CheckIcon from 'app/src/ui/icons/check'; +import CloseIcon from 'app/src/ui/icons/x'; const validationIcon = (props) => { if (props.isFieldValid) { diff --git a/modules/accounts/WalletConnectBtn.tsx b/src/accounts/WalletConnectBtn.tsx similarity index 89% rename from modules/accounts/WalletConnectBtn.tsx rename to src/accounts/WalletConnectBtn.tsx index 034c75a..f16b490 100644 --- a/modules/accounts/WalletConnectBtn.tsx +++ b/src/accounts/WalletConnectBtn.tsx @@ -1,11 +1,11 @@ import React, { useEffect } from 'react'; import { Pressable, Text } from 'react-native'; -import WalletConnectIcon from 'app/modules/ui/icons/walletconnect-icon'; -import { Stores } from 'app/functions/Stores'; +import WalletConnectIcon from 'app/src/ui/icons/walletconnect-icon'; +import { Stores } from 'app/src/functions/Stores'; import QRCodeModal from '@walletconnect/qrcode-modal'; import { observer } from 'mobx-react'; import tw from 'twin.macro'; -import { signManageDataOp } from 'app/stellar'; +import { signManageDataOp } from 'app/src/stellar'; export default observer(({ signInWithXDR }: { signInWithXDR?: (_) => {} }) => { let { walletConnectStore } = Stores(); diff --git a/skyhitz-common/src/algolia/algolia.ts b/src/algolia/algolia.ts similarity index 100% rename from skyhitz-common/src/algolia/algolia.ts rename to src/algolia/algolia.ts diff --git a/src/api/client.ts b/src/api/client.ts new file mode 100644 index 0000000..907b6ca --- /dev/null +++ b/src/api/client.ts @@ -0,0 +1,4 @@ +import { Config } from '../config'; +import { GraphQLClient } from 'graphql-request'; + +export const client = new GraphQLClient(Config.GRAPHQL_URL); diff --git a/skyhitz-common/src/backends/entries.backend.ts b/src/api/entries.ts similarity index 73% rename from skyhitz-common/src/backends/entries.backend.ts rename to src/api/entries.ts index 2eba567..fb6ff12 100644 --- a/skyhitz-common/src/backends/entries.backend.ts +++ b/src/api/entries.ts @@ -1,5 +1,5 @@ -import { client } from './apollo-client.backend'; -import { gql } from '@apollo/client'; +import { client } from './client'; +import { gql } from 'graphql-request'; import { Entry } from '../models/entry.model'; import { entriesIndex } from '../algolia/algolia'; @@ -17,17 +17,16 @@ export class EntriesBackend { async getPriceInfo(id: string) { return client - .query({ - query: gql` - { - entryPrice(id: "${id}"){ - price - amount - } - } - `, - }) - .then((data: any) => data.data) + .request( + gql` + { + entryPrice(id: "${id}"){ + price + amount + } + } + ` + ) .then(({ entryPrice }: any) => { return { price: @@ -45,8 +44,8 @@ export class EntriesBackend { async getById(id: string) { return client - .query({ - query: gql` + .request( + gql` { entries(id: "${id}"){ imageUrl @@ -59,9 +58,8 @@ export class EntriesBackend { issuer } } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ entries }: any) => { if (!entries.length) { return null; @@ -76,8 +74,8 @@ export class EntriesBackend { async getByUserId(userId: string) { return client - .query({ - query: gql` + .request( + gql` { entries(userId: "${userId}"){ imageUrl @@ -90,10 +88,8 @@ export class EntriesBackend { issuer } } - `, - fetchPolicy: 'network-only', - }) - .then((data: any) => data.data) + ` + ) .then(({ entries }: any) => { if (!entries.length) { return []; @@ -110,31 +106,30 @@ export class EntriesBackend { async buyEntry(id: string, amount: number, price: number) { return client - .mutate({ - mutation: gql` - mutation { - buyEntry(id: "${id}", amount: ${amount}, price: ${price}) { - xdr - success - submitted - } - } - `, - }) - .then(({ data }) => data) + .request( + gql` + mutation { + buyEntry(id: "${id}", amount: ${amount}, price: ${price}) { + xdr + success + submitted + } + } + ` + ) .then(({ buyEntry }: { buyEntry: ConditionalXdr }) => buyEntry); } async indexEntry(issuer: string) { return client - .mutate({ - mutation: gql` + .request( + gql` mutation { indexEntry(issuer: "${issuer}") } - `, - }) - .then(({ data }) => data.indexEntry); + ` + ) + .then(({ indexEntry }) => indexEntry); } async createFromUpload( @@ -146,8 +141,8 @@ export class EntriesBackend { equityForSale: number = 1 ) { return client - .mutate({ - mutation: gql` + .request( + gql` mutation { createEntry(fileCid: "${fileCid}",metaCid: "${metaCid}", code: "${code}", forSale: ${forSale}, price: ${price}, equityForSale: ${ equityForSale / 100 @@ -157,9 +152,8 @@ export class EntriesBackend { submitted } } - `, - }) - .then(({ data }) => data) + ` + ) .then(({ createEntry }: { createEntry: ConditionalXdr }) => createEntry) .catch((e) => { console.info(e); @@ -169,8 +163,8 @@ export class EntriesBackend { async getTopChart(page = 0): Promise { return client - .query({ - query: gql` + .request( + gql` { topChart(page: ${page} ) { imageUrl @@ -183,9 +177,8 @@ export class EntriesBackend { issuer } } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ topChart }: any) => { if (!topChart) { return []; @@ -204,8 +197,8 @@ export class EntriesBackend { async getRecentlyAdded(page = 0): Promise { return client - .query({ - query: gql` + .request( + gql` { recentlyAdded(page: ${page} ) { imageUrl @@ -218,9 +211,8 @@ export class EntriesBackend { issuer } } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ recentlyAdded }: any) => { if (!recentlyAdded) { return []; @@ -238,27 +230,24 @@ export class EntriesBackend { } remove(id: string) { - return client - .mutate({ - mutation: gql` + return client.request( + gql` mutation { removeEntry(id: "${id}") } - `, - }) - .then((data: any) => data.data); + ` + ); } getIssuer(cid: string) { return client - .query({ - query: gql` + .request( + gql` { getIssuer(cid: "${cid}") } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ getIssuer }) => getIssuer); } @@ -268,15 +257,13 @@ export class EntriesBackend { forSale: boolean, equityForSale: number ) { - return client - .mutate({ - mutation: gql` - mutation { - updatePricing(id: "${id}", price: ${price}, forSale: ${forSale}, equityForSale: ${equityForSale}) - } - `, - }) - .then((data: any) => data.data); + return client.request( + gql` + mutation { + updatePricing(id: "${id}", price: ${price}, forSale: ${forSale}, equityForSale: ${equityForSale}) + } + ` + ); } } diff --git a/skyhitz-common/src/backends/likes.backend.ts b/src/api/likes.ts similarity index 72% rename from skyhitz-common/src/backends/likes.backend.ts rename to src/api/likes.ts index 4d42836..8d31930 100644 --- a/skyhitz-common/src/backends/likes.backend.ts +++ b/src/api/likes.ts @@ -1,11 +1,11 @@ -import { client } from './apollo-client.backend'; -import { gql } from '@apollo/client'; +import { client } from './client'; +import { gql } from 'graphql-request'; export class LikesBackend { async userLikes() { return client - .query({ - query: gql` + .request( + gql` { userLikes { imageUrl @@ -16,16 +16,15 @@ export class LikesBackend { videoUrl } } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ userLikes }: any) => userLikes) .catch((e) => console.error(e)); } async entryLikes(id: string) { return client - .query({ - query: gql` + .request( + gql` { entryLikes(id: "${id}") { count @@ -37,22 +36,20 @@ export class LikesBackend { } } } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ entryLikes }: any) => entryLikes) .catch((e) => console.error(e)); } async like(id: string, like = true) { return client - .mutate({ - mutation: gql` + .request( + gql` mutation { likeEntry(id: "${id}", like: ${like}) } - `, - }) - .then((data: any) => data.data) + ` + ) .then(({ likeEntry }: any) => likeEntry) .catch((e) => console.error(e)); } diff --git a/src/api/payments.ts b/src/api/payments.ts new file mode 100644 index 0000000..f191c3c --- /dev/null +++ b/src/api/payments.ts @@ -0,0 +1,65 @@ +import { client } from './client'; +import { gql } from 'graphql-request'; + +export class PaymentsBackend { + async subscribe(cardToken: string) { + client + .request( + gql` + mutation { + subscribeUser(cardToken: "${cardToken}") + } + ` + ) + .then(({ subscribeUser }) => subscribeUser); + } + async buyCredits(cardToken: string, amount: number) { + return client + .request( + gql` + mutation { + buyCredits(cardToken: "${cardToken}", amount: ${amount}) + } + ` + ) + .then(({ buyCredits }) => buyCredits); + } + async getXLMPrice() { + return client + .request( + gql` + { + xlmPrice + } + ` + ) + .then(({ xlmPrice }) => xlmPrice); + } + async withdrawToExternalWallet(address: string, amount: number) { + return client + .request( + gql` + mutation { + withdrawToExternalWallet(address: "${address}", amount: ${amount}) + } + ` + ) + .then(({ withdrawToExternalWallet }) => withdrawToExternalWallet); + } + async refreshSubscription() { + return client + .request( + gql` + { + paymentsInfo { + subscribed + credits + } + } + ` + ) + .then(({ paymentsInfo }) => paymentsInfo); + } +} + +export const paymentsBackend = new PaymentsBackend(); diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..16db2be --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,125 @@ +import { gql } from 'graphql-request'; +import { client } from './client'; +import { SignUpForm } from '../types'; + +export class UserBackend { + async getAuthenticatedUser() { + return client + .request( + gql` + { + authenticatedUser { + avatarUrl + displayName + username + id + jwt + publishedAt + email + description + } + } + ` + ) + .then(({ authenticatedUser }) => authenticatedUser); + } + + async signUp({ displayName, email, username, publicKey }: SignUpForm) { + return client + .request( + gql` + mutation { + createUserWithEmail(displayName: "${displayName}", email: "${email}", username: "${username}",publicKey: "${publicKey}"){ + avatarUrl + displayName + username + id + jwt + publishedAt + email + description + publicKey + } + } + ` + ) + .then(({ createUserWithEmail }) => createUserWithEmail) + .catch(({ graphQLErrors }) => { + let [{ message }] = graphQLErrors; + throw message; + }); + } + + async requestToken(usernameOrEmail, publicKey) { + return client + .request( + gql` + mutation { + requestToken(usernameOrEmail: "${usernameOrEmail}", publicKey: "${publicKey}") + } + ` + ) + .catch((graphQLErrors) => { + let [{ message }] = graphQLErrors; + throw message; + }); + } + + async signIn(token?: string, uid?: string, xdr?: string) { + return client + .request( + gql` + mutation { + signIn(token: "${token}", uid: "${uid}", signedXDR: "${xdr}"){ + avatarUrl + displayName + username + id + jwt + publishedAt + email + description + publicKey + } + } + ` + ) + .then(({ signIn }) => signIn) + .catch(({ graphQLErrors }) => { + let [{ message }] = graphQLErrors; + throw message; + }); + } + + async updateUser( + avatarUrl: string, + displayName: string, + description: string, + username: string, + email: string + ) { + client + .request( + gql` + mutation { + updateUser(avatarUrl: "${avatarUrl}", displayName: "${displayName}", description: "${description}", username: "${username}", email: "${email}"){ + avatarUrl + displayName + username + id + publishedAt + email + description + } + } + ` + ) + .then(({ updateUser }) => updateUser) + .catch(({ graphQLErrors }) => { + let [{ message }] = graphQLErrors; + throw message; + }); + } +} + +export const userBackend = new UserBackend(); diff --git a/skyhitz-common/src/backends/users.backend.ts b/src/api/users.ts similarity index 100% rename from skyhitz-common/src/backends/users.backend.ts rename to src/api/users.ts diff --git a/src/atoms/atoms.ts b/src/atoms/atoms.ts new file mode 100644 index 0000000..721fcc3 --- /dev/null +++ b/src/atoms/atoms.ts @@ -0,0 +1,33 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { atom, DefaultValue } from 'recoil'; +import { client } from '../api/client'; +import { userDataKey } from '../config/constants'; +import { UserData } from '../models'; + +const localStorageEffect = (key) => ({ setSelf, onSet }) => { + setSelf( + AsyncStorage.getItem(key).then((savedValue) => + savedValue != null ? JSON.parse(savedValue) : new DefaultValue() + ) + ); + + onSet((newValue, _, isReset) => { + isReset + ? AsyncStorage.removeItem(key) + : AsyncStorage.setItem(key, JSON.stringify(newValue)); + }); +}; + +const headersEffect = () => ({ setSelf, onSet }) => { + onSet((newValue, _, isReset) => { + isReset + ? client.setHeader('authorization', '') + : client.setHeader('authorization', `Bearer ${newValue.jwt}`); + }); +}; + +export const userAtom = atom({ + key: 'user', + default: null, + effects_UNSTABLE: [localStorageEffect(userDataKey), headersEffect()], +}); diff --git a/skyhitz-common/src/config/config.development.ts b/src/config/config.development.ts similarity index 100% rename from skyhitz-common/src/config/config.development.ts rename to src/config/config.development.ts diff --git a/skyhitz-common/src/config/config.production.ts b/src/config/config.production.ts similarity index 100% rename from skyhitz-common/src/config/config.production.ts rename to src/config/config.production.ts diff --git a/skyhitz-common/src/config/config.staging.ts b/src/config/config.staging.ts similarity index 100% rename from skyhitz-common/src/config/config.staging.ts rename to src/config/config.staging.ts diff --git a/skyhitz-common/src/config/config.ts b/src/config/config.ts similarity index 100% rename from skyhitz-common/src/config/config.ts rename to src/config/config.ts diff --git a/skyhitz-common/src/constants/constants.ts b/src/config/constants.ts similarity index 100% rename from skyhitz-common/src/constants/constants.ts rename to src/config/constants.ts diff --git a/skyhitz-common/src/config/index.ts b/src/config/index.ts similarity index 100% rename from skyhitz-common/src/config/index.ts rename to src/config/index.ts diff --git a/constants/Colors.ts b/src/constants/Colors.ts similarity index 100% rename from constants/Colors.ts rename to src/constants/Colors.ts diff --git a/constants/CursorPointer.ts b/src/constants/CursorPointer.ts similarity index 100% rename from constants/CursorPointer.ts rename to src/constants/CursorPointer.ts diff --git a/constants/Layout.ts b/src/constants/Layout.ts similarity index 100% rename from constants/Layout.ts rename to src/constants/Layout.ts diff --git a/functions/CacheResourcesAsync.ts b/src/functions/CacheResourcesAsync.ts similarity index 100% rename from functions/CacheResourcesAsync.ts rename to src/functions/CacheResourcesAsync.ts diff --git a/functions/Stores.ts b/src/functions/Stores.ts similarity index 83% rename from functions/Stores.ts rename to src/functions/Stores.ts index 6a38766..acffff0 100644 --- a/functions/Stores.ts +++ b/src/functions/Stores.ts @@ -1,6 +1,6 @@ import React from 'react'; import { MobXProviderContext } from 'mobx-react'; -import * as stores from 'app/skyhitz-common'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; import 'mobx-react-lite/batchingForReactDom'; diff --git a/functions/utils.ts b/src/functions/utils.ts similarity index 89% rename from functions/utils.ts rename to src/functions/utils.ts index 3b0ceb4..4fcbbff 100644 --- a/functions/utils.ts +++ b/src/functions/utils.ts @@ -1,4 +1,4 @@ -import { Config } from 'app/skyhitz-common/src/config'; +import { Config } from 'app/src/config'; const stellarExplorer = 'https://stellar.expert/explorer/'; const horizonTestnet = 'https://horizon-testnet.stellar.org'; diff --git a/hooks/nft-listener.ts b/src/hooks/nft-listener.ts similarity index 91% rename from hooks/nft-listener.ts rename to src/hooks/nft-listener.ts index c132872..38ad68f 100644 --- a/hooks/nft-listener.ts +++ b/src/hooks/nft-listener.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; -import { Stores } from 'app/functions/Stores'; -import { Config } from 'app/skyhitz-common/src/config'; +import { Stores } from 'app/src/functions/Stores'; +import { Config } from 'app/src/config'; const EventSource = require('eventsource'); const nftListener = (open) => { diff --git a/modules/marketing/ShareAppBanner.tsx b/src/marketing/ShareAppBanner.tsx similarity index 86% rename from modules/marketing/ShareAppBanner.tsx rename to src/marketing/ShareAppBanner.tsx index 97dcfff..4b01add 100644 --- a/modules/marketing/ShareAppBanner.tsx +++ b/src/marketing/ShareAppBanner.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { StyleSheet, View, Platform } from 'react-native'; -import Colors from 'app/constants/Colors'; -import LargeBtn from 'app/modules/ui/LargeBtn'; +import Colors from 'app/src/constants/Colors'; +import LargeBtn from 'app/src/ui/LargeBtn'; import { useLinkTo } from '@react-navigation/native'; -import UploadIcon from 'app/modules/ui/icons/upload'; -import DollarIcon from 'app/modules/ui/icons/dollar'; +import UploadIcon from 'app/src/ui/icons/upload'; +import DollarIcon from 'app/src/ui/icons/dollar'; export default ({ credits }) => { const linkTo = useLinkTo(); diff --git a/modules/marketing/web/Footer.tsx b/src/marketing/web/Footer.tsx similarity index 95% rename from modules/marketing/web/Footer.tsx rename to src/marketing/web/Footer.tsx index ec59550..fcc16c9 100644 --- a/modules/marketing/web/Footer.tsx +++ b/src/marketing/web/Footer.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Footer } from '@expo/html-elements'; import SocialLinks from './SocialLinks'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; import { Text } from 'react-native'; diff --git a/modules/marketing/web/Home.tsx b/src/marketing/web/Home.tsx similarity index 81% rename from modules/marketing/web/Home.tsx rename to src/marketing/web/Home.tsx index 4ffd978..ecd17f7 100644 --- a/modules/marketing/web/Home.tsx +++ b/src/marketing/web/Home.tsx @@ -1,6 +1,6 @@ import React from 'react'; import NavBar from './NavBar'; -import BackgroundImage from 'app/modules/ui/BackgroundImage'; +import BackgroundImage from 'app/src/ui/BackgroundImage'; import MainWrapper from './MainWrapper'; import LandingFooter from './Footer'; diff --git a/modules/marketing/web/MainWrapper.tsx b/src/marketing/web/MainWrapper.tsx similarity index 96% rename from modules/marketing/web/MainWrapper.tsx rename to src/marketing/web/MainWrapper.tsx index 707d7a4..c895bd4 100644 --- a/modules/marketing/web/MainWrapper.tsx +++ b/src/marketing/web/MainWrapper.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { H1, Main, P } from '@expo/html-elements'; import { View, Text, StyleSheet, Pressable } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useMediaQuery } from 'react-responsive'; import { useLinkTo } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; // https://apps.apple.com/us/app/skyhitz/id1105406020 diff --git a/modules/marketing/web/NavBar.tsx b/src/marketing/web/NavBar.tsx similarity index 95% rename from modules/marketing/web/NavBar.tsx rename to src/marketing/web/NavBar.tsx index 4349ea7..4cb09a7 100644 --- a/modules/marketing/web/NavBar.tsx +++ b/src/marketing/web/NavBar.tsx @@ -3,9 +3,9 @@ import { Nav } from '@expo/html-elements'; import SkyhitzLogo from './SkyhitzLogo'; import { View, Text, StyleSheet, Pressable } from 'react-native'; import { useLinkTo } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; export default observer(() => { const { sessionStore } = Stores(); diff --git a/modules/marketing/web/Privacy.tsx b/src/marketing/web/Privacy.tsx similarity index 99% rename from modules/marketing/web/Privacy.tsx rename to src/marketing/web/Privacy.tsx index 9f32711..dfc06d5 100644 --- a/modules/marketing/web/Privacy.tsx +++ b/src/marketing/web/Privacy.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { StyleSheet, View } from 'react-native'; -import NavBar from 'app/modules/marketing/web/NavBar'; +import NavBar from 'app/src/marketing/web/NavBar'; import { H1, H2, BR, P } from '@expo/html-elements'; export default () => { diff --git a/modules/marketing/web/SkyhitzLogo.tsx b/src/marketing/web/SkyhitzLogo.tsx similarity index 100% rename from modules/marketing/web/SkyhitzLogo.tsx rename to src/marketing/web/SkyhitzLogo.tsx diff --git a/modules/marketing/web/SocialLinks.tsx b/src/marketing/web/SocialLinks.tsx similarity index 85% rename from modules/marketing/web/SocialLinks.tsx rename to src/marketing/web/SocialLinks.tsx index 9139375..5cf5049 100644 --- a/modules/marketing/web/SocialLinks.tsx +++ b/src/marketing/web/SocialLinks.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { A } from '@expo/html-elements'; import { View } from 'react-native'; let Anchor: React.ComponentType = A; -import Github from 'app/modules/ui/icons/github'; -import Insta from 'app/modules/ui/icons/instagram'; -import Discord from 'app/modules/ui/icons/discord'; -import Twitter from 'app/modules/ui/icons/twitter'; +import Github from 'app/src/ui/icons/github'; +import Insta from 'app/src/ui/icons/instagram'; +import Discord from 'app/src/ui/icons/discord'; +import Twitter from 'app/src/ui/icons/twitter'; export default () => { return ( diff --git a/modules/marketing/web/Terms.tsx b/src/marketing/web/Terms.tsx similarity index 99% rename from modules/marketing/web/Terms.tsx rename to src/marketing/web/Terms.tsx index 37dfa48..31a21b0 100644 --- a/modules/marketing/web/Terms.tsx +++ b/src/marketing/web/Terms.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { StyleSheet, View } from 'react-native'; -import NavBar from 'app/modules/marketing/web/NavBar'; +import NavBar from 'app/src/marketing/web/NavBar'; import { H1, H2, BR, P, Section } from '@expo/html-elements'; export default () => { diff --git a/skyhitz-common/src/models/entry.model.ts b/src/models/entry.model.ts similarity index 98% rename from skyhitz-common/src/models/entry.model.ts rename to src/models/entry.model.ts index a1e1f5b..a2666b1 100644 --- a/skyhitz-common/src/models/entry.model.ts +++ b/src/models/entry.model.ts @@ -3,7 +3,7 @@ import { videosGateway, imagesGateway, skyhitzCdn, -} from '../constants/constants'; +} from '../config/constants'; import { Payload } from './payload.model'; export class EntryPayload extends Payload { diff --git a/skyhitz-common/src/models/index.ts b/src/models/index.ts similarity index 100% rename from skyhitz-common/src/models/index.ts rename to src/models/index.ts diff --git a/skyhitz-common/src/models/payload.model.ts b/src/models/payload.model.ts similarity index 100% rename from skyhitz-common/src/models/payload.model.ts rename to src/models/payload.model.ts diff --git a/skyhitz-common/src/models/user.model.ts b/src/models/user.model.ts similarity index 79% rename from skyhitz-common/src/models/user.model.ts rename to src/models/user.model.ts index 5d0aa9f..ed489be 100644 --- a/skyhitz-common/src/models/user.model.ts +++ b/src/models/user.model.ts @@ -1,6 +1,20 @@ import { Payload } from './payload.model'; -class UserPayload extends Payload { +export type UserData = { + avatarUrl?: string; + displayName?: string; + email?: string; + reputation?: number; + publishedAt?: string; + username?: string; + id?: string; + userType?: number; + jwt?: string; + description?: string; + publicKey?: string; +}; + +class UserPayload extends Payload implements UserData { avatarUrl?: string; displayName?: string; email?: string; diff --git a/modules/navigation/BottomTabBar.tsx b/src/navigation/BottomTabBar.tsx similarity index 100% rename from modules/navigation/BottomTabBar.tsx rename to src/navigation/BottomTabBar.tsx diff --git a/modules/navigation/BottomTabView.tsx b/src/navigation/BottomTabView.tsx similarity index 100% rename from modules/navigation/BottomTabView.tsx rename to src/navigation/BottomTabView.tsx diff --git a/modules/navigation/LazyAppStackNavigator.tsx b/src/navigation/LazyAppStackNavigator.tsx similarity index 88% rename from modules/navigation/LazyAppStackNavigator.tsx rename to src/navigation/LazyAppStackNavigator.tsx index 4024583..494f2fe 100644 --- a/modules/navigation/LazyAppStackNavigator.tsx +++ b/src/navigation/LazyAppStackNavigator.tsx @@ -1,13 +1,13 @@ import React, { lazy } from 'react'; import { createStackNavigator } from '@react-navigation/stack'; import { SuspenseLoading } from './SuspenseLoading'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { Platform } from 'react-native'; import CancelEditBtn from '../ui/CancelEditBtn'; import DoneEditBtn from '../ui/DoneEditBtn'; const MainTabNavigator = lazy(() => - import('app/modules/navigation/MainTabNavigator') + import('app/src/navigation/MainTabNavigator') ); const MainTabNavigatorSuspense = (props) => ( @@ -17,7 +17,7 @@ const MainTabNavigatorSuspense = (props) => ( ); const EditProfileScreen = lazy(() => - import('app/modules/profile/EditProfileScreen') + import('app/src/profile/EditProfileScreen') ); const EditProfileScreenSuspense = (props) => ( @@ -26,7 +26,7 @@ const EditProfileScreenSuspense = (props) => ( ); const EntryOptionsModal = lazy(() => - import('app/modules/search/EntryOptionsModal') + import('app/src/search/EntryOptionsModal') ); const EntryOptionsModalSuspense = (props) => ( @@ -35,7 +35,7 @@ const EntryOptionsModalSuspense = (props) => ( ); const PricingOptionsModal = lazy(() => - import('app/modules/search/PricingOptionsModal') + import('app/src/search/PricingOptionsModal') ); const PricingOptionsModalSuspense = (props) => ( @@ -43,67 +43,63 @@ const PricingOptionsModalSuspense = (props) => ( ); -const PaymentModal = lazy(() => import('app/modules/profile/PaymentModal')); +const PaymentModal = lazy(() => import('app/src/profile/PaymentModal')); const PaymentModalSuspense = (props) => ( ); -const LowBalanceModal = lazy(() => - import('app/modules/profile/LowBalanceModal') -); +const LowBalanceModal = lazy(() => import('app/src/profile/LowBalanceModal')); const LowBalanceModalSuspense = (props) => ( ); -const WithdrawalModal = lazy(() => - import('app/modules/profile/WithdrawalModal') -); +const WithdrawalModal = lazy(() => import('app/src/profile/WithdrawalModal')); const WithdrawalModalSuspense = (props) => ( ); -const BuyOptionsModal = lazy(() => import('app/modules/ui/BuyOptionsModal')); +const BuyOptionsModal = lazy(() => import('app/src/ui/BuyOptionsModal')); const BuyOptionsModalSuspense = (props) => ( ); -const AuthScreen = lazy(() => import('app/modules/accounts/AuthScreen')); +const AuthScreen = lazy(() => import('app/src/accounts/AuthScreen')); const AuthScreenSuspense = (props) => ( ); -const SignUpScreen = lazy(() => import('app/modules/accounts/SignUpScreen')); +const SignUpScreen = lazy(() => import('app/src/accounts/SignUpScreen')); const SignUpScreenSuspense = (props) => ( ); -const SignInScreen = lazy(() => import('app/modules/accounts/SignInScreen')); +const SignInScreen = lazy(() => import('app/src/accounts/SignInScreen')); const SignInScreenSuspense = (props) => ( ); -const WebApp = lazy(() => import('app/modules/marketing/web/Home')); +const WebApp = lazy(() => import('app/src/marketing/web/Home')); const WebAppSuspense = (props) => ( ); -const Privacy = lazy(() => import('app/modules/marketing/web/Privacy')); +const Privacy = lazy(() => import('app/src/marketing/web/Privacy')); const PrivacySuspense = (props) => ( ); -const Terms = lazy(() => import('app/modules/marketing/web/Terms')); +const Terms = lazy(() => import('app/src/marketing/web/Terms')); const TermsSuspense = (props) => ( diff --git a/modules/navigation/LazyNavigationContainer.tsx b/src/navigation/LazyNavigationContainer.tsx similarity index 83% rename from modules/navigation/LazyNavigationContainer.tsx rename to src/navigation/LazyNavigationContainer.tsx index bff5bf2..33afc66 100644 --- a/modules/navigation/LazyNavigationContainer.tsx +++ b/src/navigation/LazyNavigationContainer.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { NavigationContainer, DefaultTheme } from '@react-navigation/native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import LinkingConfiguration from './LinkingConfiguration'; -import LoadingScreen from 'app/modules/accounts/LoadingScreen'; +import LoadingScreen from 'app/src/accounts/LoadingScreen'; const Theme = { ...DefaultTheme, diff --git a/modules/navigation/LinkingConfiguration.tsx b/src/navigation/LinkingConfiguration.tsx similarity index 100% rename from modules/navigation/LinkingConfiguration.tsx rename to src/navigation/LinkingConfiguration.tsx diff --git a/modules/navigation/MainTabNavigator.tsx b/src/navigation/MainTabNavigator.tsx similarity index 87% rename from modules/navigation/MainTabNavigator.tsx rename to src/navigation/MainTabNavigator.tsx index 04d17be..425146f 100644 --- a/modules/navigation/MainTabNavigator.tsx +++ b/src/navigation/MainTabNavigator.tsx @@ -1,9 +1,9 @@ import React, { lazy } from 'react'; import { View } from 'react-native'; -import ProfileSettingsScreen from 'app/modules/profile/ProfileSettingsScreen'; -import SearchNavigator from 'app/modules/search/SearchNavigator'; -import Colors from 'app/constants/Colors'; -import ChartsView from 'app/modules/search/ChartsView'; +import ProfileSettingsScreen from 'app/src/profile/ProfileSettingsScreen'; +import SearchNavigator from 'app/src/search/SearchNavigator'; +import Colors from 'app/src/constants/Colors'; +import ChartsView from 'app/src/search/ChartsView'; import BottomTabBar from './BottomTabBar'; import createBottomTabNavigator from './WebTabNavigator'; @@ -11,11 +11,11 @@ import { useMediaQuery } from 'react-responsive'; import MiniPlayerDesktop from '../player/player-bar/MiniPlayerDesktop'; import SkyhitzLogo from '../marketing/web/SkyhitzLogo'; import { SuspenseLoading } from './SuspenseLoading'; -import SearchIcon from 'app/modules/ui/icons/search'; -import UserIcon from 'app/modules/ui/icons/user'; +import SearchIcon from 'app/src/ui/icons/search'; +import UserIcon from 'app/src/ui/icons/user'; const PlayerDrawer = lazy(() => - import('app/modules/player/player-bar/PlayerDrawer') + import('app/src/player/player-bar/PlayerDrawer') ); const PlayerDrawerSuspense = (props) => ( diff --git a/modules/navigation/RootNavigation.tsx b/src/navigation/RootNavigation.tsx similarity index 85% rename from modules/navigation/RootNavigation.tsx rename to src/navigation/RootNavigation.tsx index be35de4..85a2570 100644 --- a/modules/navigation/RootNavigation.tsx +++ b/src/navigation/RootNavigation.tsx @@ -2,12 +2,12 @@ import React, { useState, useEffect, lazy } from 'react'; import { StatusBar } from 'react-native'; import { observer } from 'mobx-react'; import { useMediaQuery } from 'react-responsive'; -import { Stores } from 'app/functions/Stores'; -import LoadingScreen from 'app/modules/accounts/LoadingScreen'; +import { Stores } from 'app/src/functions/Stores'; +import LoadingScreen from 'app/src/accounts/LoadingScreen'; import { SuspenseLoading } from './SuspenseLoading'; const LazyAppStackNavigator = lazy(() => - import('app/modules/navigation/LazyAppStackNavigator').then((mod) => ({ + import('app/src/navigation/LazyAppStackNavigator').then((mod) => ({ default: mod.LazyAppStackNavigator, })) ); @@ -19,7 +19,7 @@ export const LazyAppStackNavigatorSuspense = (props) => ( ); const LazyNavigationContainer = lazy(() => - import('app/modules/navigation/LazyNavigationContainer') + import('app/src/navigation/LazyNavigationContainer') ); const LazyNavigationContainerSuspense = (props) => ( diff --git a/modules/navigation/SuspenseLoading.tsx b/src/navigation/SuspenseLoading.tsx similarity index 100% rename from modules/navigation/SuspenseLoading.tsx rename to src/navigation/SuspenseLoading.tsx diff --git a/modules/navigation/WebTabNavigator.tsx b/src/navigation/WebTabNavigator.tsx similarity index 100% rename from modules/navigation/WebTabNavigator.tsx rename to src/navigation/WebTabNavigator.tsx diff --git a/modules/player/player-bar/MiniPlayer.tsx b/src/player/player-bar/MiniPlayer.tsx similarity index 90% rename from modules/player/player-bar/MiniPlayer.tsx rename to src/player/player-bar/MiniPlayer.tsx index 8a0d599..0b0ab17 100644 --- a/modules/player/player-bar/MiniPlayer.tsx +++ b/src/player/player-bar/MiniPlayer.tsx @@ -1,11 +1,11 @@ import { observer } from 'mobx-react'; import React from 'react'; import { View, Text, StyleSheet, Pressable } from 'react-native'; -import { Stores } from 'app/functions/Stores'; -import Colors from 'app/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; +import Colors from 'app/src/constants/Colors'; import PlayBtnSmall from './play-btn-small/PlayBtnSmall'; -import cursorPointer from 'app/constants/CursorPointer'; -import ChevronUpIcon from 'app/modules/ui/icons/chevron-up'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import ChevronUpIcon from 'app/src/ui/icons/chevron-up'; export default observer(() => { let { playerStore } = Stores(); diff --git a/modules/player/player-bar/MiniPlayerDesktop.tsx b/src/player/player-bar/MiniPlayerDesktop.tsx similarity index 96% rename from modules/player/player-bar/MiniPlayerDesktop.tsx rename to src/player/player-bar/MiniPlayerDesktop.tsx index 9f5a7a2..049194c 100644 --- a/modules/player/player-bar/MiniPlayerDesktop.tsx +++ b/src/player/player-bar/MiniPlayerDesktop.tsx @@ -11,8 +11,8 @@ import { } from '../player-screen/video-player/VideoTimeDisplay'; import Slider from '../player-screen/slider/Slider'; import VideoComponent from '../player-screen/video-player/VideoComponent'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; export default observer(() => { diff --git a/modules/player/player-bar/PlayerDrawer.tsx b/src/player/player-bar/PlayerDrawer.tsx similarity index 97% rename from modules/player/player-bar/PlayerDrawer.tsx rename to src/player/player-bar/PlayerDrawer.tsx index 0fea8e5..9ceceff 100644 --- a/modules/player/player-bar/PlayerDrawer.tsx +++ b/src/player/player-bar/PlayerDrawer.tsx @@ -6,8 +6,8 @@ import MiniPlayer from './MiniPlayer'; import { State } from 'react-native-gesture-handler'; import { getBottomSpace } from 'react-native-iphone-x-helper'; import { clamp, timing, withSpring } from 'react-native-redash/lib/module/v1'; -import { Stores } from 'app/functions/Stores'; -import Colors from 'app/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; +import Colors from 'app/src/constants/Colors'; import Animated from 'react-native-reanimated'; let tabNavBottom = 89; diff --git a/modules/player/player-bar/play-btn-small/PlayBtnSmall.tsx b/src/player/player-bar/play-btn-small/PlayBtnSmall.tsx similarity index 78% rename from modules/player/player-bar/play-btn-small/PlayBtnSmall.tsx rename to src/player/player-bar/play-btn-small/PlayBtnSmall.tsx index 990a385..92cf8b6 100644 --- a/modules/player/player-bar/play-btn-small/PlayBtnSmall.tsx +++ b/src/player/player-bar/play-btn-small/PlayBtnSmall.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { observer } from 'mobx-react'; import { StyleSheet, Pressable } from 'react-native'; -import Play from 'app/modules/ui/icons/play'; -import Pause from 'app/modules/ui/icons/pause'; -import { Stores } from 'app/functions/Stores'; -import cursorPointer from 'app/constants/CursorPointer'; +import Play from 'app/src/ui/icons/play'; +import Pause from 'app/src/ui/icons/pause'; +import { Stores } from 'app/src/functions/Stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; export default observer(() => { let { playerStore } = Stores(); diff --git a/modules/player/player-screen/PlayerEntryInfo.tsx b/src/player/player-screen/PlayerEntryInfo.tsx similarity index 96% rename from modules/player/player-screen/PlayerEntryInfo.tsx rename to src/player/player-screen/PlayerEntryInfo.tsx index a5dd66a..587faf7 100644 --- a/modules/player/player-screen/PlayerEntryInfo.tsx +++ b/src/player/player-screen/PlayerEntryInfo.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StyleSheet, View, Text } from 'react-native'; import { inject } from 'mobx-react'; -import * as stores from 'app/skyhitz-common'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; const PlayerEntryInfo = inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/PlayerNav.tsx b/src/player/player-screen/PlayerNav.tsx similarity index 87% rename from modules/player/player-screen/PlayerNav.tsx rename to src/player/player-screen/PlayerNav.tsx index 1e3980c..4611048 100644 --- a/modules/player/player-screen/PlayerNav.tsx +++ b/src/player/player-screen/PlayerNav.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; import { observer } from 'mobx-react'; -import ChevronDown from 'app/modules/ui/icons/chevron-down'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import ChevronDown from 'app/src/ui/icons/chevron-down'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; export default observer(({ onPress }) => { let { playerStore } = Stores(); diff --git a/modules/player/player-screen/PlayerScreen.tsx b/src/player/player-screen/PlayerScreen.tsx similarity index 86% rename from modules/player/player-screen/PlayerScreen.tsx rename to src/player/player-screen/PlayerScreen.tsx index 6c786ed..852ee3a 100644 --- a/modules/player/player-screen/PlayerScreen.tsx +++ b/src/player/player-screen/PlayerScreen.tsx @@ -6,16 +6,16 @@ import { View, Pressable, } from 'react-native'; -import ChevronDown from 'app/modules/ui/icons/chevron-down'; +import ChevronDown from 'app/src/ui/icons/chevron-down'; import VideoPlayer from './video-player/VideoPlayer'; import PlayerEntryInfo from './PlayerEntryInfo'; -import BuyBtn from 'app/modules/ui/buy-btn/BuyBtn'; +import BuyBtn from 'app/src/ui/buy-btn/BuyBtn'; import PlayerControls from './player-controls/PlayerControls'; import LikersSection from './likers-section/LikersSection'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; -import cursorPointer from 'app/constants/CursorPointer'; +import { Stores } from 'app/src/functions/Stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; const { width } = Dimensions.get('window'); const styles = StyleSheet.create({ diff --git a/modules/player/player-screen/forward-btn/ForwardBtn.tsx b/src/player/player-screen/forward-btn/ForwardBtn.tsx similarity index 75% rename from modules/player/player-screen/forward-btn/ForwardBtn.tsx rename to src/player/player-screen/forward-btn/ForwardBtn.tsx index 9776e5b..104936a 100644 --- a/modules/player/player-screen/forward-btn/ForwardBtn.tsx +++ b/src/player/player-screen/forward-btn/ForwardBtn.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; import { inject } from 'mobx-react'; -import * as stores from 'app/skyhitz-common'; -import SkipForwardIcon from 'app/modules/ui/icons/skip-forward'; -import cursorPointer from 'app/constants/CursorPointer'; -import Colors from 'app/constants/Colors'; +import * as stores from 'app/src/stores'; +import SkipForwardIcon from 'app/src/ui/icons/skip-forward'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import Colors from 'app/src/constants/Colors'; type Stores = typeof stores; const ForwardBtn = inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/like-btn/LikeBtn.tsx b/src/player/player-screen/like-btn/LikeBtn.tsx similarity index 84% rename from modules/player/player-screen/like-btn/LikeBtn.tsx rename to src/player/player-screen/like-btn/LikeBtn.tsx index ac9dff3..e376465 100644 --- a/modules/player/player-screen/like-btn/LikeBtn.tsx +++ b/src/player/player-screen/like-btn/LikeBtn.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; import { inject } from 'mobx-react'; -import LikeIcon from 'app/modules/ui/icons/like'; -import Colors from 'app/constants/Colors'; -import * as stores from 'app/skyhitz-common'; -import cursorPointer from 'app/constants/CursorPointer'; +import LikeIcon from 'app/src/ui/icons/like'; +import Colors from 'app/src/constants/Colors'; +import * as stores from 'app/src/stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; type Stores = typeof stores; @inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/likers-section/LikersSection.tsx b/src/player/player-screen/likers-section/LikersSection.tsx similarity index 91% rename from modules/player/player-screen/likers-section/LikersSection.tsx rename to src/player/player-screen/likers-section/LikersSection.tsx index c41b5fc..779e074 100644 --- a/modules/player/player-screen/likers-section/LikersSection.tsx +++ b/src/player/player-screen/likers-section/LikersSection.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { inject } from 'mobx-react'; import { StyleSheet, View, Text } from 'react-native'; -import LikeBtn from 'app/modules/player/player-screen/like-btn/LikeBtn'; -import Divider from 'app/modules/ui/Divider'; -import { UserAvatar } from 'app/modules/ui/UserAvatar'; +import LikeBtn from 'app/src/player/player-screen/like-btn/LikeBtn'; +import Divider from 'app/src/ui/Divider'; +import { UserAvatar } from 'app/src/ui/UserAvatar'; import * as L from 'list'; -import * as stores from 'app/skyhitz-common'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; @inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/loop-btn/LoopBtn.tsx b/src/player/player-screen/loop-btn/LoopBtn.tsx similarity index 78% rename from modules/player/player-screen/loop-btn/LoopBtn.tsx rename to src/player/player-screen/loop-btn/LoopBtn.tsx index dcf6e42..39e66f5 100644 --- a/modules/player/player-screen/loop-btn/LoopBtn.tsx +++ b/src/player/player-screen/loop-btn/LoopBtn.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; import { observer } from 'mobx-react'; -import LoopIcon from 'app/modules/ui/icons/repeat'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; -import cursorPointer from 'app/constants/CursorPointer'; +import LoopIcon from 'app/src/ui/icons/repeat'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; export default observer(({ size = 20 }) => { let { playerStore } = Stores(); diff --git a/modules/player/player-screen/play-btn/PlayBtn.tsx b/src/player/player-screen/play-btn/PlayBtn.tsx similarity index 88% rename from modules/player/player-screen/play-btn/PlayBtn.tsx rename to src/player/player-screen/play-btn/PlayBtn.tsx index 1e3738d..fe12ca5 100644 --- a/modules/player/player-screen/play-btn/PlayBtn.tsx +++ b/src/player/player-screen/play-btn/PlayBtn.tsx @@ -4,11 +4,11 @@ import { observer } from 'mobx-react'; import { ReplayIcon, Spinner, -} from 'app/modules/player/player-screen/video-player/VideoIcons'; -import { Stores } from 'app/functions/Stores'; -import cursorPointer from 'app/constants/CursorPointer'; -import PlayIcon from 'app/modules/ui/icons/play'; -import PauseIcon from 'app/modules/ui/icons/pause'; +} from 'app/src/player/player-screen/video-player/VideoIcons'; +import { Stores } from 'app/src/functions/Stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import PlayIcon from 'app/src/ui/icons/play'; +import PauseIcon from 'app/src/ui/icons/pause'; export default observer(() => { let { playerStore } = Stores(); diff --git a/modules/player/player-screen/play-btn/PlayDesktopBtn.tsx b/src/player/player-screen/play-btn/PlayDesktopBtn.tsx similarity index 88% rename from modules/player/player-screen/play-btn/PlayDesktopBtn.tsx rename to src/player/player-screen/play-btn/PlayDesktopBtn.tsx index 765dc8e..d03696e 100644 --- a/modules/player/player-screen/play-btn/PlayDesktopBtn.tsx +++ b/src/player/player-screen/play-btn/PlayDesktopBtn.tsx @@ -1,15 +1,15 @@ import React from 'react'; import { StyleSheet, View, Pressable } from 'react-native'; import { observer } from 'mobx-react'; -import PlayIcon from 'app/modules/ui/icons/play'; -import PauseIcon from 'app/modules/ui/icons/pause'; +import PlayIcon from 'app/src/ui/icons/play'; +import PauseIcon from 'app/src/ui/icons/pause'; import { ReplayIcon, Spinner, -} from 'app/modules/player/player-screen/video-player/VideoIcons'; -import { Stores } from 'app/functions/Stores'; -import cursorPointer from 'app/constants/CursorPointer'; +} from 'app/src/player/player-screen/video-player/VideoIcons'; +import { Stores } from 'app/src/functions/Stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; export default observer(({ size = 28 }) => { let { playerStore } = Stores(); diff --git a/modules/player/player-screen/player-controls/PlayerControls.tsx b/src/player/player-screen/player-controls/PlayerControls.tsx similarity index 61% rename from modules/player/player-screen/player-controls/PlayerControls.tsx rename to src/player/player-screen/player-controls/PlayerControls.tsx index af685ed..6c04e22 100644 --- a/modules/player/player-screen/player-controls/PlayerControls.tsx +++ b/src/player/player-screen/player-controls/PlayerControls.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import PrevBtn from 'app/modules/player/player-screen/prev-btn/PrevBtn'; -import ForwardBtn from 'app/modules/player/player-screen/forward-btn/ForwardBtn'; -import ShuffleBtn from 'app/modules/player/player-screen/shuffle-btn/ShuffleBtn'; -import LoopBtn from 'app/modules/player/player-screen/loop-btn/LoopBtn'; -import PlayBtn from 'app/modules/player/player-screen/play-btn/PlayBtn'; +import PrevBtn from 'app/src/player/player-screen/prev-btn/PrevBtn'; +import ForwardBtn from 'app/src/player/player-screen/forward-btn/ForwardBtn'; +import ShuffleBtn from 'app/src/player/player-screen/shuffle-btn/ShuffleBtn'; +import LoopBtn from 'app/src/player/player-screen/loop-btn/LoopBtn'; +import PlayBtn from 'app/src/player/player-screen/play-btn/PlayBtn'; import { StyleSheet, View } from 'react-native'; diff --git a/modules/player/player-screen/prev-btn/PrevBtn.tsx b/src/player/player-screen/prev-btn/PrevBtn.tsx similarity index 78% rename from modules/player/player-screen/prev-btn/PrevBtn.tsx rename to src/player/player-screen/prev-btn/PrevBtn.tsx index 52c7c6d..e95d1d2 100644 --- a/modules/player/player-screen/prev-btn/PrevBtn.tsx +++ b/src/player/player-screen/prev-btn/PrevBtn.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; import { inject } from 'mobx-react'; -import * as stores from 'app/skyhitz-common'; -import SkipBackwardIcon from 'app/modules/ui/icons/skip-backward'; -import cursorPointer from 'app/constants/CursorPointer'; +import * as stores from 'app/src/stores'; +import SkipBackwardIcon from 'app/src/ui/icons/skip-backward'; +import cursorPointer from 'app/src/constants/CursorPointer'; type Stores = typeof stores; diff --git a/modules/player/player-screen/shuffle-btn/ShuffleBtn.tsx b/src/player/player-screen/shuffle-btn/ShuffleBtn.tsx similarity index 82% rename from modules/player/player-screen/shuffle-btn/ShuffleBtn.tsx rename to src/player/player-screen/shuffle-btn/ShuffleBtn.tsx index e204d97..c5b8e9b 100644 --- a/modules/player/player-screen/shuffle-btn/ShuffleBtn.tsx +++ b/src/player/player-screen/shuffle-btn/ShuffleBtn.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; import { inject } from 'mobx-react'; -import * as stores from 'app/skyhitz-common'; -import ShuffleIcon from 'app/modules/ui/icons/shuffle'; -import Colors from 'app/constants/Colors'; -import cursorPointer from 'app/constants/CursorPointer'; +import * as stores from 'app/src/stores'; +import ShuffleIcon from 'app/src/ui/icons/shuffle'; +import Colors from 'app/src/constants/Colors'; +import cursorPointer from 'app/src/constants/CursorPointer'; type Stores = typeof stores; const ShuffleBtn = inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/slider/Slider.tsx b/src/player/player-screen/slider/Slider.tsx similarity index 91% rename from modules/player/player-screen/slider/Slider.tsx rename to src/player/player-screen/slider/Slider.tsx index f7876bc..0ebf139 100644 --- a/modules/player/player-screen/slider/Slider.tsx +++ b/src/player/player-screen/slider/Slider.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { Pressable } from 'react-native'; import Slider from '@react-native-community/slider'; diff --git a/modules/player/player-screen/video-player/BlurImageBackground.tsx b/src/player/player-screen/video-player/BlurImageBackground.tsx similarity index 100% rename from modules/player/player-screen/video-player/BlurImageBackground.tsx rename to src/player/player-screen/video-player/BlurImageBackground.tsx diff --git a/modules/player/player-screen/video-player/CenteredView.tsx b/src/player/player-screen/video-player/CenteredView.tsx similarity index 82% rename from modules/player/player-screen/video-player/CenteredView.tsx rename to src/player/player-screen/video-player/CenteredView.tsx index 0db0544..186f494 100644 --- a/modules/player/player-screen/video-player/CenteredView.tsx +++ b/src/player/player-screen/video-player/CenteredView.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Animated } from 'react-native'; -import { centeredContentWidth } from 'app/modules/player/player-screen/video-player/VideoConstants'; +import { centeredContentWidth } from 'app/src/player/player-screen/video-player/VideoConstants'; const CenteredView = ({ children, ...otherProps }: any) => ( ({ diff --git a/modules/player/player-screen/video-player/PlayPauseInvisibleArea.tsx b/src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx similarity index 86% rename from modules/player/player-screen/video-player/PlayPauseInvisibleArea.tsx rename to src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx index f8745d6..53fd409 100644 --- a/modules/player/player-screen/video-player/PlayPauseInvisibleArea.tsx +++ b/src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx @@ -4,12 +4,12 @@ import { inject } from 'mobx-react'; import { PLAYBACK_STATES, SEEK_STATES, -} from 'app/modules/player/player-screen/video-player/UiStates'; +} from 'app/src/player/player-screen/video-player/UiStates'; import { videoHeight, videoWidth, -} from 'app/modules/player/player-screen/video-player/VideoConstants'; -import * as stores from 'app/skyhitz-common'; +} from 'app/src/player/player-screen/video-player/VideoConstants'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; const PlayPauseInvisibleArea = inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/video-player/UiStates.tsx b/src/player/player-screen/video-player/UiStates.tsx similarity index 100% rename from modules/player/player-screen/video-player/UiStates.tsx rename to src/player/player-screen/video-player/UiStates.tsx diff --git a/modules/player/player-screen/video-player/VideoComponent.tsx b/src/player/player-screen/video-player/VideoComponent.tsx similarity index 97% rename from modules/player/player-screen/video-player/VideoComponent.tsx rename to src/player/player-screen/video-player/VideoComponent.tsx index 622328c..979a272 100644 --- a/modules/player/player-screen/video-player/VideoComponent.tsx +++ b/src/player/player-screen/video-player/VideoComponent.tsx @@ -1,6 +1,6 @@ import { Video, Audio } from 'expo-av'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { useState } from 'react'; import tw from 'twin.macro'; import BlurImageBackground from './BlurImageBackground'; diff --git a/modules/player/player-screen/video-player/VideoConstants.tsx b/src/player/player-screen/video-player/VideoConstants.tsx similarity index 100% rename from modules/player/player-screen/video-player/VideoConstants.tsx rename to src/player/player-screen/video-player/VideoConstants.tsx diff --git a/modules/player/player-screen/video-player/VideoErrorText.tsx b/src/player/player-screen/video-player/VideoErrorText.tsx similarity index 76% rename from modules/player/player-screen/video-player/VideoErrorText.tsx rename to src/player/player-screen/video-player/VideoErrorText.tsx index ef8e69b..44c3d22 100644 --- a/modules/player/player-screen/video-player/VideoErrorText.tsx +++ b/src/player/player-screen/video-player/VideoErrorText.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { View, Text } from 'react-native'; import { inject } from 'mobx-react'; -import { videoWidth } from 'app/modules/player/player-screen/video-player/VideoConstants'; -import { PLAYBACK_STATES } from 'app/modules/player/player-screen/video-player/UiStates'; -import * as stores from 'app/skyhitz-common'; +import { videoWidth } from 'app/src/player/player-screen/video-player/VideoConstants'; +import { PLAYBACK_STATES } from 'app/src/player/player-screen/video-player/UiStates'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; const VideoErrorText = inject((stores: Stores) => ({ diff --git a/modules/player/player-screen/video-player/VideoIcons.tsx b/src/player/player-screen/video-player/VideoIcons.tsx similarity index 77% rename from modules/player/player-screen/video-player/VideoIcons.tsx rename to src/player/player-screen/video-player/VideoIcons.tsx index ea9a075..5db7827 100644 --- a/modules/player/player-screen/video-player/VideoIcons.tsx +++ b/src/player/player-screen/video-player/VideoIcons.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { ActivityIndicator } from 'react-native'; -import FullScreenIcon from 'app/modules/ui/icons/fullscreen'; -import FullScreenExitIcon from 'app/modules/ui/icons/fullscreen-exit'; -import LoopIcon from 'app/modules/ui/icons/repeat'; +import FullScreenIcon from 'app/src/ui/icons/fullscreen'; +import FullScreenExitIcon from 'app/src/ui/icons/fullscreen-exit'; +import LoopIcon from 'app/src/ui/icons/repeat'; const ICON_COLOR = '#FFFFFF'; const CENTER_ICON_SIZE = 36; diff --git a/modules/player/player-screen/video-player/VideoPlayer.tsx b/src/player/player-screen/video-player/VideoPlayer.tsx similarity index 68% rename from modules/player/player-screen/video-player/VideoPlayer.tsx rename to src/player/player-screen/video-player/VideoPlayer.tsx index d664a92..329c151 100644 --- a/modules/player/player-screen/video-player/VideoPlayer.tsx +++ b/src/player/player-screen/video-player/VideoPlayer.tsx @@ -3,11 +3,11 @@ import { View, StyleSheet } from 'react-native'; import { CurrentTimeDisplay, DurationDisplay, -} from 'app/modules/player/player-screen/video-player/VideoTimeDisplay'; -import { videoWidth } from 'app/modules/player/player-screen/video-player/VideoConstants'; -import FullscreenControl from 'app/modules/player/player-screen/video-player/FullscreenControl'; -import PlayPauseInvisibleArea from 'app/modules/player/player-screen/video-player/PlayPauseInvisibleArea'; -import VideoErrorText from 'app/modules/player/player-screen/video-player/VideoErrorText'; +} from 'app/src/player/player-screen/video-player/VideoTimeDisplay'; +import { videoWidth } from 'app/src/player/player-screen/video-player/VideoConstants'; +import FullscreenControl from 'app/src/player/player-screen/video-player/FullscreenControl'; +import PlayPauseInvisibleArea from 'app/src/player/player-screen/video-player/PlayPauseInvisibleArea'; +import VideoErrorText from 'app/src/player/player-screen/video-player/VideoErrorText'; import Slider from '../slider/Slider'; import VideoComponent from './VideoComponent'; diff --git a/modules/player/player-screen/video-player/VideoTimeDisplay.tsx b/src/player/player-screen/video-player/VideoTimeDisplay.tsx similarity index 88% rename from modules/player/player-screen/video-player/VideoTimeDisplay.tsx rename to src/player/player-screen/video-player/VideoTimeDisplay.tsx index 6276608..82baf9d 100644 --- a/modules/player/player-screen/video-player/VideoTimeDisplay.tsx +++ b/src/player/player-screen/video-player/VideoTimeDisplay.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Text, StyleSheet } from 'react-native'; import { observer } from 'mobx-react'; -import { PLAYBACK_STATES } from 'app/modules/player/player-screen/video-player/UiStates'; -import { Stores } from 'app/functions/Stores'; +import { PLAYBACK_STATES } from 'app/src/player/player-screen/video-player/UiStates'; +import { Stores } from 'app/src/functions/Stores'; export const CurrentTimeDisplay = observer(() => { const { playerStore } = Stores(); diff --git a/modules/playlists/CollectionScreen.tsx b/src/playlists/CollectionScreen.tsx similarity index 81% rename from modules/playlists/CollectionScreen.tsx rename to src/playlists/CollectionScreen.tsx index 51a7d71..9d9725b 100644 --- a/modules/playlists/CollectionScreen.tsx +++ b/src/playlists/CollectionScreen.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { ScrollView } from 'react-native'; import { inject } from 'mobx-react'; -import EntryRow from 'app/modules/ui/EntryRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; -import Colors from 'app/constants/Colors'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; -import * as stores from 'app/skyhitz-common'; +import EntryRow from 'app/src/ui/EntryRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; +import * as stores from 'app/src/stores'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; type Stores = typeof stores; diff --git a/modules/playlists/LikesRow.tsx b/src/playlists/LikesRow.tsx similarity index 88% rename from modules/playlists/LikesRow.tsx rename to src/playlists/LikesRow.tsx index f9c5473..ff2391d 100644 --- a/modules/playlists/LikesRow.tsx +++ b/src/playlists/LikesRow.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; -import Colors from 'app/constants/Colors'; -import LikeIcon from 'app/modules/ui/icons/like'; -import ChevronRight from 'app/modules/ui/icons/chevron-right'; +import Colors from 'app/src/constants/Colors'; +import LikeIcon from 'app/src/ui/icons/like'; +import ChevronRight from 'app/src/ui/icons/chevron-right'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; export default observer(() => { let { likesStore, playerStore } = Stores(); diff --git a/modules/playlists/LikesScreen.tsx b/src/playlists/LikesScreen.tsx similarity index 81% rename from modules/playlists/LikesScreen.tsx rename to src/playlists/LikesScreen.tsx index 88e3a24..ae90955 100644 --- a/modules/playlists/LikesScreen.tsx +++ b/src/playlists/LikesScreen.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { ScrollView } from 'react-native'; import { inject } from 'mobx-react'; -import EntryRow from 'app/modules/ui/EntryRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; -import Colors from 'app/constants/Colors'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; -import * as stores from 'app/skyhitz-common'; +import EntryRow from 'app/src/ui/EntryRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; +import * as stores from 'app/src/stores'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; type Stores = typeof stores; diff --git a/modules/playlists/MyMusicRow.tsx b/src/playlists/MyMusicRow.tsx similarity index 87% rename from modules/playlists/MyMusicRow.tsx rename to src/playlists/MyMusicRow.tsx index cf11800..f9d00e8 100644 --- a/modules/playlists/MyMusicRow.tsx +++ b/src/playlists/MyMusicRow.tsx @@ -2,12 +2,12 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import ChevronRightIcon from 'app/modules/ui/icons/chevron-right'; -import StarBorderIcon from 'app/modules/ui/icons/star-border'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import ChevronRightIcon from 'app/src/ui/icons/chevron-right'; +import StarBorderIcon from 'app/src/ui/icons/star-border'; export default observer(() => { let { userEntriesStore } = Stores(); diff --git a/modules/profile/EditProfilePhotoBtn.tsx b/src/profile/EditProfilePhotoBtn.tsx similarity index 90% rename from modules/profile/EditProfilePhotoBtn.tsx rename to src/profile/EditProfilePhotoBtn.tsx index e4f2979..95d9279 100644 --- a/modules/profile/EditProfilePhotoBtn.tsx +++ b/src/profile/EditProfilePhotoBtn.tsx @@ -3,9 +3,9 @@ import { Pressable, StyleSheet, Text, Platform } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; import * as Permissions from 'expo-permissions'; import { inject } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import * as stores from 'app/skyhitz-common'; -import cursorPointer from 'app/constants/CursorPointer'; +import Colors from 'app/src/constants/Colors'; +import * as stores from 'app/src/stores'; +import cursorPointer from 'app/src/constants/CursorPointer'; type Stores = typeof stores; @inject((stores: Stores) => ({ diff --git a/modules/profile/EditProfileScreen.tsx b/src/profile/EditProfileScreen.tsx similarity index 94% rename from modules/profile/EditProfileScreen.tsx rename to src/profile/EditProfileScreen.tsx index 6985886..4063bf7 100644 --- a/modules/profile/EditProfileScreen.tsx +++ b/src/profile/EditProfileScreen.tsx @@ -9,21 +9,21 @@ import { KeyboardAvoidingView, } from 'react-native'; import { inject } from 'mobx-react'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { UserAvatarMedium, UserAvatarMediumWithUrlOnly, LoadingUserAvatar, -} from 'app/modules/ui/UserAvatar'; -import EditProfilePhotoBtn from 'app/modules/profile/EditProfilePhotoBtn'; -import * as stores from 'app/skyhitz-common'; +} from 'app/src/ui/UserAvatar'; +import EditProfilePhotoBtn from 'app/src/profile/EditProfilePhotoBtn'; +import * as stores from 'app/src/stores'; import LargeBtn from '../ui/LargeBtn'; -import cursorPointer from 'app/constants/CursorPointer'; -import AccountBoxIcon from 'app/modules/ui/icons/account-box'; -import PersonOutlineIcon from 'app/modules/ui/icons/person-outline'; -import MailOutlineIcon from 'app/modules/ui/icons/mail-outline'; -import LogoutIcon from 'app/modules/ui/icons/logout'; -import InfoCirlceIcon from 'app/modules/ui/icons/info-circle'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import AccountBoxIcon from 'app/src/ui/icons/account-box'; +import PersonOutlineIcon from 'app/src/ui/icons/person-outline'; +import MailOutlineIcon from 'app/src/ui/icons/mail-outline'; +import LogoutIcon from 'app/src/ui/icons/logout'; +import InfoCirlceIcon from 'app/src/ui/icons/info-circle'; import AsyncStorage from '@react-native-async-storage/async-storage'; type Stores = typeof stores; diff --git a/modules/profile/LowBalanceModal.tsx b/src/profile/LowBalanceModal.tsx similarity index 93% rename from modules/profile/LowBalanceModal.tsx rename to src/profile/LowBalanceModal.tsx index 75dc0ad..d7c4149 100644 --- a/modules/profile/LowBalanceModal.tsx +++ b/src/profile/LowBalanceModal.tsx @@ -8,14 +8,14 @@ import { Platform, } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import LargeBtn from 'app/modules/ui/LargeBtn'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import LargeBtn from 'app/src/ui/LargeBtn'; +import { Stores } from 'app/src/functions/Stores'; import { useLinkTo, useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import CloseIcon from 'app/modules/ui/icons/x'; -import WalletIcon from 'app/modules/ui/icons/wallet'; -import DollarIcon from 'app/modules/ui/icons/dollar'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import CloseIcon from 'app/src/ui/icons/x'; +import WalletIcon from 'app/src/ui/icons/wallet'; +import DollarIcon from 'app/src/ui/icons/dollar'; export default observer((props) => { const { paymentsStore, sessionStore } = Stores(); diff --git a/modules/profile/MediaUpload.tsx b/src/profile/MediaUpload.tsx similarity index 95% rename from modules/profile/MediaUpload.tsx rename to src/profile/MediaUpload.tsx index a150ddf..0fd6c0f 100644 --- a/modules/profile/MediaUpload.tsx +++ b/src/profile/MediaUpload.tsx @@ -14,20 +14,20 @@ import { observer } from 'mobx-react'; import * as ImagePicker from 'expo-image-picker'; import * as DocumentPicker from 'expo-document-picker'; import * as Permissions from 'expo-permissions'; -import Colors from 'app/constants/Colors'; -import LargeBtn from 'app/modules/ui/LargeBtn'; -import cursorPointer from 'app/constants/CursorPointer'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import LargeBtn from 'app/src/ui/LargeBtn'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; import Slider from '@react-native-community/slider'; -import PieChartIcon from 'app/modules/ui/icons/pie'; -import InfoIcon from 'app/modules/ui/icons/info-circle'; -import DollarIcon from 'app/modules/ui/icons/dollar'; -import CircleIcon from 'app/modules/ui/icons/circle'; -import UploadIcon from 'app/modules/ui/icons/upload'; -import CheckIcon from 'app/modules/ui/icons/check'; -import CloseIcon from 'app/modules/ui/icons/x'; -import nftListener from 'app/hooks/nft-listener'; +import PieChartIcon from 'app/src/ui/icons/pie'; +import InfoIcon from 'app/src/ui/icons/info-circle'; +import DollarIcon from 'app/src/ui/icons/dollar'; +import CircleIcon from 'app/src/ui/icons/circle'; +import UploadIcon from 'app/src/ui/icons/upload'; +import CheckIcon from 'app/src/ui/icons/check'; +import CloseIcon from 'app/src/ui/icons/x'; +import nftListener from 'app/src/hooks/nft-listener'; const SwitchWeb: any = Switch; diff --git a/modules/profile/MintNFT.tsx b/src/profile/MintNFT.tsx similarity index 100% rename from modules/profile/MintNFT.tsx rename to src/profile/MintNFT.tsx diff --git a/modules/profile/PaymentModal.native.tsx b/src/profile/PaymentModal.native.tsx similarity index 94% rename from modules/profile/PaymentModal.native.tsx rename to src/profile/PaymentModal.native.tsx index bc8202f..603dc95 100644 --- a/modules/profile/PaymentModal.native.tsx +++ b/src/profile/PaymentModal.native.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; -import CloseIcon from 'app/modules/ui/icons/x'; +import { Stores } from 'app/src/functions/Stores'; +import CloseIcon from 'app/src/ui/icons/x'; export default observer((props) => { let { entryStore } = Stores(); diff --git a/modules/profile/PaymentModal.tsx b/src/profile/PaymentModal.tsx similarity index 91% rename from modules/profile/PaymentModal.tsx rename to src/profile/PaymentModal.tsx index 3dde8a2..9dae39d 100644 --- a/modules/profile/PaymentModal.tsx +++ b/src/profile/PaymentModal.tsx @@ -1,14 +1,14 @@ import React from 'react'; import { Pressable, StyleSheet, Text, View, Platform } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { Elements } from '@stripe/react-stripe-js'; import { loadStripe } from '@stripe/stripe-js'; -import { Config } from 'app/skyhitz-common/src/config/index'; +import { Config } from 'app/src/config/index'; import PaymentStep from './PaymentStep'; -import cursorPointer from 'app/constants/CursorPointer'; -import CloseIcon from 'app/modules/ui/icons/x'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import CloseIcon from 'app/src/ui/icons/x'; let stripePromise; diff --git a/modules/profile/PaymentStep.tsx b/src/profile/PaymentStep.tsx similarity index 97% rename from modules/profile/PaymentStep.tsx rename to src/profile/PaymentStep.tsx index baf1692..7bd3d86 100644 --- a/modules/profile/PaymentStep.tsx +++ b/src/profile/PaymentStep.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { StyleSheet, View, @@ -11,9 +11,9 @@ import { Pressable, } from 'react-native'; import { P, H3 } from '@expo/html-elements'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; async function timeout(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/modules/profile/ProfileEntryListView.tsx b/src/profile/ProfileEntryListView.tsx similarity index 77% rename from modules/profile/ProfileEntryListView.tsx rename to src/profile/ProfileEntryListView.tsx index 1c9b663..4bf2bb0 100644 --- a/modules/profile/ProfileEntryListView.tsx +++ b/src/profile/ProfileEntryListView.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { ScrollView } from 'react-native'; import { inject } from 'mobx-react'; -import EntryRow from 'app/modules/ui/EntryRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; -import Colors from 'app/constants/Colors'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; +import EntryRow from 'app/src/ui/EntryRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; import * as L from 'list'; -import * as stores from 'app/skyhitz-common'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; const ProfileEntryListView = inject((stores: Stores) => ({ diff --git a/modules/profile/ProfileScreen.tsx b/src/profile/ProfileScreen.tsx similarity index 73% rename from modules/profile/ProfileScreen.tsx rename to src/profile/ProfileScreen.tsx index ef719f9..bb837bd 100644 --- a/modules/profile/ProfileScreen.tsx +++ b/src/profile/ProfileScreen.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { View, StyleSheet } from 'react-native'; -import ProfileTopContainer from 'app/modules/profile/ProfileTopContainer'; -import ProfileEntryListView from 'app/modules/profile/ProfileEntryListView'; -import Colors from 'app/constants/Colors'; +import ProfileTopContainer from 'app/src/profile/ProfileTopContainer'; +import ProfileEntryListView from 'app/src/profile/ProfileEntryListView'; +import Colors from 'app/src/constants/Colors'; import ResponsiveLayout from '../ui/ResponsiveLayout'; export default class ProfileScreen extends React.Component { diff --git a/modules/profile/ProfileSettingsScreen.tsx b/src/profile/ProfileSettingsScreen.tsx similarity index 86% rename from modules/profile/ProfileSettingsScreen.tsx rename to src/profile/ProfileSettingsScreen.tsx index 1d7fb02..a7d4314 100644 --- a/modules/profile/ProfileSettingsScreen.tsx +++ b/src/profile/ProfileSettingsScreen.tsx @@ -2,19 +2,19 @@ import React, { useEffect } from 'react'; import { View, StyleSheet } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import ProfileSettingsTopContainer from 'app/modules/profile/ProfileSettingsTopContainer'; -import ShareAppBanner from 'app/modules/marketing/ShareAppBanner'; -import LikesScreen from 'app/modules/playlists/LikesScreen'; -import CollectionScreen from 'app/modules/playlists/CollectionScreen'; -import LikesRow from 'app/modules/playlists/LikesRow'; -import MyMusicRow from 'app/modules/playlists/MyMusicRow'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import ProfileSettingsTopContainer from 'app/src/profile/ProfileSettingsTopContainer'; +import ShareAppBanner from 'app/src/marketing/ShareAppBanner'; +import LikesScreen from 'app/src/playlists/LikesScreen'; +import CollectionScreen from 'app/src/playlists/CollectionScreen'; +import LikesRow from 'app/src/playlists/LikesRow'; +import MyMusicRow from 'app/src/playlists/MyMusicRow'; +import { Stores } from 'app/src/functions/Stores'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import MintNFT from './MintNFT'; import { useLinkTo } from '@react-navigation/native'; import { HeaderBackButton } from '@react-navigation/elements'; -import ChevronLeftIcon from 'app/modules/ui/icons/chevron-left'; +import ChevronLeftIcon from 'app/src/ui/icons/chevron-left'; import tw from 'twin.macro'; const ProfileSettingsScreen = observer(() => { diff --git a/modules/profile/ProfileSettingsTopContainer.tsx b/src/profile/ProfileSettingsTopContainer.tsx similarity index 90% rename from modules/profile/ProfileSettingsTopContainer.tsx rename to src/profile/ProfileSettingsTopContainer.tsx index d0cb5d8..145245d 100644 --- a/modules/profile/ProfileSettingsTopContainer.tsx +++ b/src/profile/ProfileSettingsTopContainer.tsx @@ -1,15 +1,15 @@ import React from 'react'; import { View, StyleSheet, Text } from 'react-native'; -import Colors from 'app/constants/Colors'; -import Layout from 'app/constants/Layout'; -import { UserAvatarMedium } from 'app/modules/ui/UserAvatar'; +import Colors from 'app/src/constants/Colors'; +import Layout from 'app/src/constants/Layout'; +import { UserAvatarMedium } from 'app/src/ui/UserAvatar'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import EditBtn from '../ui/EditBtn'; -import DollarIcon from 'app/modules/ui/icons/dollar'; -import WalletIcon from 'app/modules/ui/icons/wallet'; +import DollarIcon from 'app/src/ui/icons/dollar'; +import WalletIcon from 'app/src/ui/icons/wallet'; import { A } from '@expo/html-elements'; -import { stellarAccountLink } from 'app/functions/utils'; +import { stellarAccountLink } from 'app/src/functions/utils'; export default observer((props) => { const { paymentsStore, sessionStore } = Stores(); diff --git a/modules/profile/ProfileTopContainer.tsx b/src/profile/ProfileTopContainer.tsx similarity index 91% rename from modules/profile/ProfileTopContainer.tsx rename to src/profile/ProfileTopContainer.tsx index 73109fe..7f9bc19 100644 --- a/modules/profile/ProfileTopContainer.tsx +++ b/src/profile/ProfileTopContainer.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { View, StyleSheet, Text } from 'react-native'; -import Colors from 'app/constants/Colors'; -import { UserAvatarMedium } from 'app/modules/ui/UserAvatar'; +import Colors from 'app/src/constants/Colors'; +import { UserAvatarMedium } from 'app/src/ui/UserAvatar'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; export default observer((props) => { const { profileStore } = Stores(); diff --git a/modules/profile/WithdrawalModal.tsx b/src/profile/WithdrawalModal.tsx similarity index 94% rename from modules/profile/WithdrawalModal.tsx rename to src/profile/WithdrawalModal.tsx index 168e97b..044b291 100644 --- a/modules/profile/WithdrawalModal.tsx +++ b/src/profile/WithdrawalModal.tsx @@ -8,14 +8,14 @@ import { Platform, } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import LargeBtn from 'app/modules/ui/LargeBtn'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import LargeBtn from 'app/src/ui/LargeBtn'; +import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import CloseIcon from 'app/modules/ui/icons/x'; -import WalletIcon from 'app/modules/ui/icons/wallet'; -import DollarIcon from 'app/modules/ui/icons/dollar'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import CloseIcon from 'app/src/ui/icons/x'; +import WalletIcon from 'app/src/ui/icons/wallet'; +import DollarIcon from 'app/src/ui/icons/dollar'; export default observer((props) => { const { paymentsStore } = Stores(); diff --git a/modules/providers/Providers.tsx b/src/providers/Providers.tsx similarity index 97% rename from modules/providers/Providers.tsx rename to src/providers/Providers.tsx index 664a401..e5f5cad 100644 --- a/modules/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -16,7 +16,7 @@ import { userEntriesStore, paymentsStore, walletConnectStore, -} from 'app/skyhitz-common'; +} from 'app/src/stores'; export default function Providers(props) { return ( diff --git a/modules/search/ChartsView.tsx b/src/search/ChartsView.tsx similarity index 92% rename from modules/search/ChartsView.tsx rename to src/search/ChartsView.tsx index b826068..2802f2a 100644 --- a/modules/search/ChartsView.tsx +++ b/src/search/ChartsView.tsx @@ -1,11 +1,11 @@ import React, { useEffect, useState } from 'react'; import { SafeAreaView, StyleSheet, FlatList, Text } from 'react-native'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; -import Colors from 'app/constants/Colors'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; +import Colors from 'app/src/constants/Colors'; import SearchingLoader from '../ui/SearchingLoader'; import EntryChartRow from '../ui/EntryChartRow'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; export default observer((props) => { diff --git a/modules/search/EntryOptionsModal.tsx b/src/search/EntryOptionsModal.tsx similarity index 88% rename from modules/search/EntryOptionsModal.tsx rename to src/search/EntryOptionsModal.tsx index d209ab6..537f8bb 100644 --- a/modules/search/EntryOptionsModal.tsx +++ b/src/search/EntryOptionsModal.tsx @@ -1,13 +1,13 @@ import React from 'react'; import { View, StyleSheet, Image, Text, Pressable } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import LikeOptionRow from 'app/modules/search/LikeOptionRow'; -import SetPrice from 'app/modules/search/SetPrice'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import LikeOptionRow from 'app/src/search/LikeOptionRow'; +import SetPrice from 'app/src/search/SetPrice'; +import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import BuyBtn from 'app/modules/ui/buy-btn/BuyBtn'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import BuyBtn from 'app/src/ui/buy-btn/BuyBtn'; export default observer(({ route }) => { const { sessionStore } = Stores(); diff --git a/modules/search/LikeOptionRow.tsx b/src/search/LikeOptionRow.tsx similarity index 89% rename from modules/search/LikeOptionRow.tsx rename to src/search/LikeOptionRow.tsx index 5deee26..5f26481 100644 --- a/modules/search/LikeOptionRow.tsx +++ b/src/search/LikeOptionRow.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import LikeIcon from 'app/modules/ui/icons/like'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import LikeIcon from 'app/src/ui/icons/like'; export default observer(({ entry, iconOnly = false, size = 24 }) => { const { likesStore } = Stores(); diff --git a/modules/search/PricingOptionsModal.tsx b/src/search/PricingOptionsModal.tsx similarity index 95% rename from modules/search/PricingOptionsModal.tsx rename to src/search/PricingOptionsModal.tsx index c27b7ae..f6c223b 100644 --- a/modules/search/PricingOptionsModal.tsx +++ b/src/search/PricingOptionsModal.tsx @@ -9,14 +9,14 @@ import { Platform, } from 'react-native'; import { observer } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import cursorPointer from 'app/constants/CursorPointer'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; import Slider from '@react-native-community/slider'; -import DollarIcon from 'app/modules/ui/icons/dollar'; -import PieIcon from 'app/modules/ui/icons/pie'; -import CircleIcon from 'app/modules/ui/icons/circle'; +import DollarIcon from 'app/src/ui/icons/dollar'; +import PieIcon from 'app/src/ui/icons/pie'; +import CircleIcon from 'app/src/ui/icons/circle'; const SwitchWeb: any = Switch; diff --git a/modules/search/RecentlyAdded.tsx b/src/search/RecentlyAdded.tsx similarity index 90% rename from modules/search/RecentlyAdded.tsx rename to src/search/RecentlyAdded.tsx index d9a119c..6efefc0 100644 --- a/modules/search/RecentlyAdded.tsx +++ b/src/search/RecentlyAdded.tsx @@ -1,10 +1,10 @@ import React, { useState } from 'react'; import { Text, StyleSheet, SafeAreaView, FlatList } from 'react-native'; import { observer } from 'mobx-react'; -import EntryRow from 'app/modules/ui/EntryRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import EntryRow from 'app/src/ui/EntryRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import BottomPlaceholder from '../ui/BottomPlaceholder'; diff --git a/modules/search/RemoveFromMyMusicRow.tsx b/src/search/RemoveFromMyMusicRow.tsx similarity index 86% rename from modules/search/RemoveFromMyMusicRow.tsx rename to src/search/RemoveFromMyMusicRow.tsx index 68d0c4e..24aaf26 100644 --- a/modules/search/RemoveFromMyMusicRow.tsx +++ b/src/search/RemoveFromMyMusicRow.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { StyleSheet, Pressable, View, Text } from 'react-native'; import { observer } from 'mobx-react'; -import RemoveIcon from 'app/modules/ui/icons/remove'; -import Colors from 'app/constants/Colors'; -import * as stores from 'app/skyhitz-common'; -import { Stores } from 'app/functions/Stores'; +import RemoveIcon from 'app/src/ui/icons/remove'; +import Colors from 'app/src/constants/Colors'; +import * as stores from 'app/src/stores'; +import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; type Stores = typeof stores; diff --git a/modules/search/SearchEntryList.tsx b/src/search/SearchEntryList.tsx similarity index 83% rename from modules/search/SearchEntryList.tsx rename to src/search/SearchEntryList.tsx index 3f23568..e87f2d7 100644 --- a/modules/search/SearchEntryList.tsx +++ b/src/search/SearchEntryList.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { ScrollView } from 'react-native'; import { inject } from 'mobx-react'; -import EntryRow from 'app/modules/ui/EntryRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; -import Colors from 'app/constants/Colors'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; -import * as stores from 'app/skyhitz-common'; +import EntryRow from 'app/src/ui/EntryRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; +import * as stores from 'app/src/stores'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; type Stores = typeof stores; diff --git a/modules/search/SearchEntryView.tsx b/src/search/SearchEntryView.tsx similarity index 77% rename from modules/search/SearchEntryView.tsx rename to src/search/SearchEntryView.tsx index b692577..19d9794 100644 --- a/modules/search/SearchEntryView.tsx +++ b/src/search/SearchEntryView.tsx @@ -1,9 +1,9 @@ import React, { useCallback, useEffect } from 'react'; import { observer } from 'mobx-react'; -import SearchEntryList from 'app/modules/search/SearchEntryList'; -import RecentlyAdded from 'app/modules/search/RecentlyAdded'; +import SearchEntryList from 'app/src/search/SearchEntryList'; +import RecentlyAdded from 'app/src/search/RecentlyAdded'; import { useFocusEffect } from '@react-navigation/native'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; export default observer(() => { let { entriesSearchStore, inputSearchStore } = Stores(); diff --git a/modules/search/SearchHeader.tsx b/src/search/SearchHeader.tsx similarity index 88% rename from modules/search/SearchHeader.tsx rename to src/search/SearchHeader.tsx index 35e1125..f1b3eca 100644 --- a/modules/search/SearchHeader.tsx +++ b/src/search/SearchHeader.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Platform } from 'react-native'; import { inject } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import SearchBar from 'app/modules/ui/searchbar/SearchBar'; -import * as stores from 'app/skyhitz-common'; +import Colors from 'app/src/constants/Colors'; +import SearchBar from 'app/src/ui/searchbar/SearchBar'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; let platform = Platform.OS === 'ios' ? 'ios' : 'android'; diff --git a/modules/search/SearchNavigator.tsx b/src/search/SearchNavigator.tsx similarity index 81% rename from modules/search/SearchNavigator.tsx rename to src/search/SearchNavigator.tsx index 17f7da1..b0824a3 100644 --- a/modules/search/SearchNavigator.tsx +++ b/src/search/SearchNavigator.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { createStackNavigator } from '@react-navigation/stack'; -import SearchTabsView from 'app/modules/search/SearchTabsView'; -import Colors from 'app/constants/Colors'; -import ProfileScreen from 'app/modules/profile/ProfileScreen'; +import SearchTabsView from 'app/src/search/SearchTabsView'; +import Colors from 'app/src/constants/Colors'; +import ProfileScreen from 'app/src/profile/ProfileScreen'; const Stack = createStackNavigator(); diff --git a/modules/search/SearchTabsView.tsx b/src/search/SearchTabsView.tsx similarity index 91% rename from modules/search/SearchTabsView.tsx rename to src/search/SearchTabsView.tsx index c38ee95..2492802 100644 --- a/modules/search/SearchTabsView.tsx +++ b/src/search/SearchTabsView.tsx @@ -4,9 +4,9 @@ import { createMaterialTopTabNavigator, MaterialTopTabBar, } from '@react-navigation/material-top-tabs'; -import SearchEntryView from 'app/modules/search/SearchEntryView'; -import SearchUserView from 'app/modules/search/SearchUserView'; -import Colors from 'app/constants/Colors'; +import SearchEntryView from 'app/src/search/SearchEntryView'; +import SearchUserView from 'app/src/search/SearchUserView'; +import Colors from 'app/src/constants/Colors'; import SearchHeader from './SearchHeader'; import ResponsiveLayout from '../ui/ResponsiveLayout'; diff --git a/modules/search/SearchUserList.tsx b/src/search/SearchUserList.tsx similarity index 76% rename from modules/search/SearchUserList.tsx rename to src/search/SearchUserList.tsx index 8b8a5da..6c9b529 100644 --- a/modules/search/SearchUserList.tsx +++ b/src/search/SearchUserList.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { ScrollView } from 'react-native'; import { inject } from 'mobx-react'; -import UserRow from 'app/modules/ui/UserRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; -import Colors from 'app/constants/Colors'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; -import * as stores from 'app/skyhitz-common'; +import UserRow from 'app/src/ui/UserRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; +import * as stores from 'app/src/stores'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; type Stores = typeof stores; diff --git a/modules/search/SearchUserView.tsx b/src/search/SearchUserView.tsx similarity index 71% rename from modules/search/SearchUserView.tsx rename to src/search/SearchUserView.tsx index e0af231..a76ed75 100644 --- a/modules/search/SearchUserView.tsx +++ b/src/search/SearchUserView.tsx @@ -1,9 +1,9 @@ import React, { useCallback } from 'react'; import { observer } from 'mobx-react'; -import SearchUserList from 'app/modules/search/SearchUserList'; -import TopRecentUserView from 'app/modules/search/TopRecentUserView'; +import SearchUserList from 'app/src/search/SearchUserList'; +import TopRecentUserView from 'app/src/search/TopRecentUserView'; import { useFocusEffect } from '@react-navigation/native'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; export default observer(() => { let { usersSearchStore, inputSearchStore } = Stores(); diff --git a/modules/search/SetPrice.tsx b/src/search/SetPrice.tsx similarity index 88% rename from modules/search/SetPrice.tsx rename to src/search/SetPrice.tsx index b2cfc03..00b29e2 100644 --- a/modules/search/SetPrice.tsx +++ b/src/search/SetPrice.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { StyleSheet, Pressable, View, Text } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { CommonActions, useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import DollarIcon from 'app/modules/ui/icons/dollar'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import DollarIcon from 'app/src/ui/icons/dollar'; export default ({ entry }) => { const { dispatch, goBack } = useNavigation(); diff --git a/modules/search/TopRecentUserView.tsx b/src/search/TopRecentUserView.tsx similarity index 73% rename from modules/search/TopRecentUserView.tsx rename to src/search/TopRecentUserView.tsx index e485593..7155932 100644 --- a/modules/search/TopRecentUserView.tsx +++ b/src/search/TopRecentUserView.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { ScrollView, StyleSheet } from 'react-native'; -import TopUserSearchView from 'app/modules/search/TopUserSearchView'; -import BottomPlaceholder from 'app/modules/ui/BottomPlaceholder'; -import Colors from 'app/constants/Colors'; +import TopUserSearchView from 'app/src/search/TopUserSearchView'; +import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; +import Colors from 'app/src/constants/Colors'; import ResponsiveLayout from '../ui/ResponsiveLayout'; const TopRecentUserView = () => ( diff --git a/modules/search/TopUserSearchView.tsx b/src/search/TopUserSearchView.tsx similarity index 85% rename from modules/search/TopUserSearchView.tsx rename to src/search/TopUserSearchView.tsx index 1cd1cd1..f2d7203 100644 --- a/modules/search/TopUserSearchView.tsx +++ b/src/search/TopUserSearchView.tsx @@ -1,11 +1,11 @@ import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { inject } from 'mobx-react'; -import Colors from 'app/constants/Colors'; -import UserRow from 'app/modules/ui/UserRow'; -import SearchingLoader from 'app/modules/ui/SearchingLoader'; +import Colors from 'app/src/constants/Colors'; +import UserRow from 'app/src/ui/UserRow'; +import SearchingLoader from 'app/src/ui/SearchingLoader'; import * as L from 'list'; -import * as stores from 'app/skyhitz-common'; +import * as stores from 'app/src/stores'; type Stores = typeof stores; @inject((stores: Stores) => ({ diff --git a/stellar/index.ts b/src/stellar/index.ts similarity index 97% rename from stellar/index.ts rename to src/stellar/index.ts index 3282b35..ee7a771 100644 --- a/stellar/index.ts +++ b/src/stellar/index.ts @@ -1,4 +1,4 @@ -import { Config } from 'app/skyhitz-common/src/config'; +import { Config } from 'app/src/config'; import { TransactionBuilder, Account, diff --git a/skyhitz-common/src/stores/edit-profile.store.ts b/src/stores/edit-profile.store.ts similarity index 96% rename from skyhitz-common/src/stores/edit-profile.store.ts rename to src/stores/edit-profile.store.ts index 3db6cbc..b8ce712 100644 --- a/skyhitz-common/src/stores/edit-profile.store.ts +++ b/src/stores/edit-profile.store.ts @@ -1,8 +1,8 @@ import { User } from '../models/user.model'; import { observable, observe, action } from 'mobx'; -import { userBackend } from '../backends/user.backend'; +import { userBackend } from '../api/user'; import { SessionStore } from './session.store'; -import { nftStorageApi, imagesGateway } from '../constants/constants'; +import { nftStorageApi, imagesGateway } from '../config/constants'; export class EditProfileStore { @observable error: string | undefined | unknown; diff --git a/skyhitz-common/src/stores/entries-search.store.ts b/src/stores/entries-search.store.ts similarity index 98% rename from skyhitz-common/src/stores/entries-search.store.ts rename to src/stores/entries-search.store.ts index fad8b83..b1d9e43 100644 --- a/skyhitz-common/src/stores/entries-search.store.ts +++ b/src/stores/entries-search.store.ts @@ -1,5 +1,5 @@ import { Entry } from '../models/entry.model'; -import { entriesBackend } from '../backends/entries.backend'; +import { entriesBackend } from '../api/entries'; import { observable, observe, computed } from 'mobx'; import * as L from 'list'; diff --git a/skyhitz-common/src/stores/entry.store.ts b/src/stores/entry.store.ts similarity index 98% rename from skyhitz-common/src/stores/entry.store.ts rename to src/stores/entry.store.ts index 3574e82..3018a7e 100644 --- a/skyhitz-common/src/stores/entry.store.ts +++ b/src/stores/entry.store.ts @@ -1,6 +1,6 @@ import { observable, action, computed } from 'mobx'; -import { nftStorageApi } from '../constants/constants'; -import { entriesBackend } from '../backends/entries.backend'; +import { nftStorageApi } from '../config/constants'; +import { entriesBackend } from '../api/entries'; export class EntryStore { @observable uploadingVideo: boolean = false; diff --git a/skyhitz-common/src/stores/index.ts b/src/stores/index.ts similarity index 100% rename from skyhitz-common/src/stores/index.ts rename to src/stores/index.ts diff --git a/skyhitz-common/src/stores/input-search.store.ts b/src/stores/input-search.store.ts similarity index 100% rename from skyhitz-common/src/stores/input-search.store.ts rename to src/stores/input-search.store.ts diff --git a/skyhitz-common/src/stores/likes.store.ts b/src/stores/likes.store.ts similarity index 98% rename from skyhitz-common/src/stores/likes.store.ts rename to src/stores/likes.store.ts index bba4e22..5d12d82 100644 --- a/skyhitz-common/src/stores/likes.store.ts +++ b/src/stores/likes.store.ts @@ -1,6 +1,6 @@ import { observable, observe, IObservableObject } from 'mobx'; import * as L from 'list'; -import { likesBackend } from '../backends/likes.backend'; +import { likesBackend } from '../api/likes'; import { Entry, User } from '../models'; export class LikesStore { diff --git a/skyhitz-common/src/stores/payments.store.ts b/src/stores/payments.store.ts similarity index 96% rename from skyhitz-common/src/stores/payments.store.ts rename to src/stores/payments.store.ts index 6c0f29e..5f1d9b9 100644 --- a/skyhitz-common/src/stores/payments.store.ts +++ b/src/stores/payments.store.ts @@ -1,6 +1,6 @@ import { observable } from 'mobx'; -import { paymentsBackend } from '../backends/payments.backend'; -import { entriesBackend } from '../backends/entries.backend'; +import { paymentsBackend } from '../api/payments'; +import { entriesBackend } from '../api/entries'; import { Config } from '../config'; export class PaymentsStore { diff --git a/skyhitz-common/src/stores/player.store.ts b/src/stores/player.store.ts similarity index 99% rename from skyhitz-common/src/stores/player.store.ts rename to src/stores/player.store.ts index f62b839..88cf632 100644 --- a/skyhitz-common/src/stores/player.store.ts +++ b/src/stores/player.store.ts @@ -1,7 +1,7 @@ import { observable, computed, action } from 'mobx'; import { Entry } from '../models'; import * as L from 'list'; -import { entriesBackend } from '../backends/entries.backend'; +import { entriesBackend } from '../api/entries'; import { PlaybackState, SeekState, ControlsState } from '../types/index'; import { Platform } from 'react-native'; diff --git a/skyhitz-common/src/stores/profile.store.ts b/src/stores/profile.store.ts similarity index 92% rename from skyhitz-common/src/stores/profile.store.ts rename to src/stores/profile.store.ts index f708bca..f6d0063 100644 --- a/skyhitz-common/src/stores/profile.store.ts +++ b/src/stores/profile.store.ts @@ -1,7 +1,7 @@ import { observable } from 'mobx'; import { User, Entry } from '../models'; import * as L from 'list'; -import { entriesBackend } from '../backends/entries.backend'; +import { entriesBackend } from '../api/entries'; export class ProfileStore { @observable diff --git a/skyhitz-common/src/stores/session.store.ts b/src/stores/session.store.ts similarity index 85% rename from skyhitz-common/src/stores/session.store.ts rename to src/stores/session.store.ts index 756e061..a982848 100644 --- a/skyhitz-common/src/stores/session.store.ts +++ b/src/stores/session.store.ts @@ -1,10 +1,9 @@ -import { observable, observe, computed, IObservableObject } from 'mobx'; +import { observable, computed, IObservableObject } from 'mobx'; import { User } from '../models'; -import { userBackend } from '../backends/user.backend'; -import { forceSignOut } from '../backends/apollo-client.backend'; +import { userBackend } from '../api/user'; import { SignUpForm } from '../types'; import AsyncStorage from '@react-native-async-storage/async-storage'; -import { userDataKey } from '../constants/constants'; +import { userDataKey } from '../config/constants'; export class SessionStore { public session: { user: User | null } & IObservableObject = observable({ @@ -42,11 +41,11 @@ export class SessionStore { else console.info('not set, stringify failed:', userDataKey, value); } - public forceSignOutDisposer = observe(forceSignOut, ({ object }) => { - if (object.value) { - this.signOut(); - } - }); + // public forceSignOutDisposer = observe(forceSignOut, ({ object }) => { + // if (object.value) { + // this.signOut(); + // } + // }); async signOut() { this.session.user = null; diff --git a/skyhitz-common/src/stores/sign-in-validation.store.ts b/src/stores/sign-in-validation.store.ts similarity index 98% rename from skyhitz-common/src/stores/sign-in-validation.store.ts rename to src/stores/sign-in-validation.store.ts index 89bbeb0..8763dea 100644 --- a/skyhitz-common/src/stores/sign-in-validation.store.ts +++ b/src/stores/sign-in-validation.store.ts @@ -46,6 +46,7 @@ export class SignInValidationStore { } setBackendError(error: string) { + debugger; this.backendError = error; } } diff --git a/skyhitz-common/src/stores/sign-up-validation.store.ts b/src/stores/sign-up-validation.store.ts similarity index 100% rename from skyhitz-common/src/stores/sign-up-validation.store.ts rename to src/stores/sign-up-validation.store.ts diff --git a/skyhitz-common/src/stores/user-entries.store.ts b/src/stores/user-entries.store.ts similarity index 92% rename from skyhitz-common/src/stores/user-entries.store.ts rename to src/stores/user-entries.store.ts index 1681ef8..891518c 100644 --- a/skyhitz-common/src/stores/user-entries.store.ts +++ b/src/stores/user-entries.store.ts @@ -1,6 +1,6 @@ import { observable } from 'mobx'; import * as L from 'list'; -import { entriesBackend } from '../backends/entries.backend'; +import { entriesBackend } from '../api/entries'; import { Entry } from '../models'; import { SessionStore } from './session.store'; diff --git a/skyhitz-common/src/stores/username-and-email-validation.store.ts b/src/stores/username-and-email-validation.store.ts similarity index 100% rename from skyhitz-common/src/stores/username-and-email-validation.store.ts rename to src/stores/username-and-email-validation.store.ts diff --git a/skyhitz-common/src/stores/users-search.store.ts b/src/stores/users-search.store.ts similarity index 96% rename from skyhitz-common/src/stores/users-search.store.ts rename to src/stores/users-search.store.ts index 7fd4aa1..3d60c5e 100644 --- a/skyhitz-common/src/stores/users-search.store.ts +++ b/src/stores/users-search.store.ts @@ -1,5 +1,5 @@ import { User } from '../models/user.model'; -import { usersBackend } from '../backends/users.backend'; +import { usersBackend } from '../api/users'; import { observable, observe, computed } from 'mobx'; import * as L from 'list'; const debounce = require('lodash.debounce'); diff --git a/skyhitz-common/src/stores/wallet-connect.store.ts b/src/stores/wallet-connect.store.ts similarity index 100% rename from skyhitz-common/src/stores/wallet-connect.store.ts rename to src/stores/wallet-connect.store.ts diff --git a/skyhitz-common/src/types/index.ts b/src/types/index.ts similarity index 100% rename from skyhitz-common/src/types/index.ts rename to src/types/index.ts diff --git a/modules/ui/ArrowDownBackBtn.tsx b/src/ui/ArrowDownBackBtn.tsx similarity index 79% rename from modules/ui/ArrowDownBackBtn.tsx rename to src/ui/ArrowDownBackBtn.tsx index 138b65f..2cf57ef 100644 --- a/modules/ui/ArrowDownBackBtn.tsx +++ b/src/ui/ArrowDownBackBtn.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Pressable, StyleSheet } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import ChevronDownIcon from 'app/modules/ui/icons/chevron-down'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import ChevronDownIcon from 'app/src/ui/icons/chevron-down'; export default () => { const { goBack } = useNavigation(); diff --git a/modules/ui/BackgroundImage.tsx b/src/ui/BackgroundImage.tsx similarity index 100% rename from modules/ui/BackgroundImage.tsx rename to src/ui/BackgroundImage.tsx diff --git a/modules/ui/BottomPlaceholder.tsx b/src/ui/BottomPlaceholder.tsx similarity index 100% rename from modules/ui/BottomPlaceholder.tsx rename to src/ui/BottomPlaceholder.tsx diff --git a/modules/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx similarity index 97% rename from modules/ui/BuyOptionsModal.tsx rename to src/ui/BuyOptionsModal.tsx index d4582a7..5b30044 100644 --- a/modules/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -1,9 +1,9 @@ import React, { useState } from 'react'; import { View, StyleSheet, Text, ActivityIndicator } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import LargeBtn from './LargeBtn'; import { observer } from 'mobx-react'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; diff --git a/modules/ui/CancelEditBtn.tsx b/src/ui/CancelEditBtn.tsx similarity index 84% rename from modules/ui/CancelEditBtn.tsx rename to src/ui/CancelEditBtn.tsx index 24ff036..b431d90 100644 --- a/modules/ui/CancelEditBtn.tsx +++ b/src/ui/CancelEditBtn.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Pressable, StyleSheet, Text } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; const CancelEditBtn = () => { const linkTo = useLinkTo(); diff --git a/modules/ui/Divider.tsx b/src/ui/Divider.tsx similarity index 87% rename from modules/ui/Divider.tsx rename to src/ui/Divider.tsx index aaf594f..835e076 100644 --- a/modules/ui/Divider.tsx +++ b/src/ui/Divider.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { View, StyleSheet } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; export default class Divider extends React.Component { render() { diff --git a/modules/ui/DoneEditBtn.tsx b/src/ui/DoneEditBtn.tsx similarity index 84% rename from modules/ui/DoneEditBtn.tsx rename to src/ui/DoneEditBtn.tsx index 3dbb42f..81d3dce 100644 --- a/modules/ui/DoneEditBtn.tsx +++ b/src/ui/DoneEditBtn.tsx @@ -1,10 +1,10 @@ import React from 'react'; import { Pressable, StyleSheet, Text } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; -import { Stores } from 'app/functions/Stores'; +import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; const DoneEditBtn = observer(() => { const linkTo = useLinkTo(); diff --git a/modules/ui/EditBtn.tsx b/src/ui/EditBtn.tsx similarity index 79% rename from modules/ui/EditBtn.tsx rename to src/ui/EditBtn.tsx index 9503e82..6e98d19 100644 --- a/modules/ui/EditBtn.tsx +++ b/src/ui/EditBtn.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Pressable, StyleSheet } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; -import CogIcon from 'app/modules/ui/icons/cog'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import CogIcon from 'app/src/ui/icons/cog'; export default ({ customStyles }) => { const linkTo = useLinkTo(); diff --git a/modules/ui/EntryChartRow.tsx b/src/ui/EntryChartRow.tsx similarity index 94% rename from modules/ui/EntryChartRow.tsx rename to src/ui/EntryChartRow.tsx index 3787aa9..0dc611d 100644 --- a/modules/ui/EntryChartRow.tsx +++ b/src/ui/EntryChartRow.tsx @@ -7,11 +7,11 @@ import { Pressable, Platform, } from 'react-native'; -import Layout from 'app/constants/Layout'; -import Colors from 'app/constants/Colors'; -import ThreeDots from 'app/modules/ui/ThreeDots'; +import Layout from 'app/src/constants/Layout'; +import Colors from 'app/src/constants/Colors'; +import ThreeDots from 'app/src/ui/ThreeDots'; import { CommonActions, useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; import LikeOptionRow from '../search/LikeOptionRow'; import EntryPrice from './EntryPrice'; diff --git a/modules/ui/EntryPrice.tsx b/src/ui/EntryPrice.tsx similarity index 85% rename from modules/ui/EntryPrice.tsx rename to src/ui/EntryPrice.tsx index 15b12ca..770bfb7 100644 --- a/modules/ui/EntryPrice.tsx +++ b/src/ui/EntryPrice.tsx @@ -1,10 +1,10 @@ import React, { useEffect, useState } from 'react'; import { StyleSheet, View, Text } from 'react-native'; -import DollarIcon from 'app/modules/ui/icons/dollar'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import DollarIcon from 'app/src/ui/icons/dollar'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { A } from '@expo/html-elements'; -import { stellarAssetLink } from 'app/functions/utils'; +import { stellarAssetLink } from 'app/src/functions/utils'; function EntryPrice({ code, issuer }) { const [value, setValue] = useState({ price: 0, amount: 0 }); diff --git a/modules/ui/EntryRow.tsx b/src/ui/EntryRow.tsx similarity index 93% rename from modules/ui/EntryRow.tsx rename to src/ui/EntryRow.tsx index d604048..7719913 100644 --- a/modules/ui/EntryRow.tsx +++ b/src/ui/EntryRow.tsx @@ -7,11 +7,11 @@ import { Platform, Pressable, } from 'react-native'; -import Layout from 'app/constants/Layout'; -import Colors from 'app/constants/Colors'; -import ThreeDots from 'app/modules/ui/ThreeDots'; +import Layout from 'app/src/constants/Layout'; +import Colors from 'app/src/constants/Colors'; +import ThreeDots from 'app/src/ui/ThreeDots'; import { CommonActions, useNavigation } from '@react-navigation/native'; -import cursorPointer from 'app/constants/CursorPointer'; +import cursorPointer from 'app/src/constants/CursorPointer'; import EntryPrice from './EntryPrice'; import LikeOptionRow from '../search/LikeOptionRow'; diff --git a/modules/ui/Input.tsx b/src/ui/Input.tsx similarity index 98% rename from modules/ui/Input.tsx rename to src/ui/Input.tsx index 356f3cc..ae82a04 100644 --- a/modules/ui/Input.tsx +++ b/src/ui/Input.tsx @@ -7,7 +7,7 @@ import { Dimensions, Animated, } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; const SCREEN_WIDTH = Dimensions.get('window').width; diff --git a/modules/ui/LargeBtn.tsx b/src/ui/LargeBtn.tsx similarity index 92% rename from modules/ui/LargeBtn.tsx rename to src/ui/LargeBtn.tsx index 928f860..031eef4 100644 --- a/modules/ui/LargeBtn.tsx +++ b/src/ui/LargeBtn.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Pressable, StyleSheet, Text } from 'react-native'; -import Colors from 'app/constants/Colors'; -import cursorPointer from 'app/constants/CursorPointer'; +import Colors from 'app/src/constants/Colors'; +import cursorPointer from 'app/src/constants/CursorPointer'; import tw from 'twin.macro'; export default class LargeBtn extends React.Component { diff --git a/modules/ui/Letter.tsx b/src/ui/Letter.tsx similarity index 100% rename from modules/ui/Letter.tsx rename to src/ui/Letter.tsx diff --git a/modules/ui/LogOutBtn.tsx b/src/ui/LogOutBtn.tsx similarity index 82% rename from modules/ui/LogOutBtn.tsx rename to src/ui/LogOutBtn.tsx index 48bdd96..dd64a96 100644 --- a/modules/ui/LogOutBtn.tsx +++ b/src/ui/LogOutBtn.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Pressable, StyleSheet } from 'react-native'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; -import LogOutIcon from 'app/modules/ui/icons/logout'; +import LogOutIcon from 'app/src/ui/icons/logout'; import { useLinkTo } from '@react-navigation/native'; export default observer(() => { diff --git a/modules/ui/MediaQueries.tsx b/src/ui/MediaQueries.tsx similarity index 100% rename from modules/ui/MediaQueries.tsx rename to src/ui/MediaQueries.tsx diff --git a/modules/ui/ResponsiveLayout.tsx b/src/ui/ResponsiveLayout.tsx similarity index 100% rename from modules/ui/ResponsiveLayout.tsx rename to src/ui/ResponsiveLayout.tsx diff --git a/modules/ui/SearchingLoader.tsx b/src/ui/SearchingLoader.tsx similarity index 96% rename from modules/ui/SearchingLoader.tsx rename to src/ui/SearchingLoader.tsx index af0165a..d79c869 100644 --- a/modules/ui/SearchingLoader.tsx +++ b/src/ui/SearchingLoader.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { StyleSheet, View, Text, ActivityIndicator } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; const SearchingLoader = (searching: any, query?: any) => { if (searching) { diff --git a/modules/ui/TextWithLetterSpacing.tsx b/src/ui/TextWithLetterSpacing.tsx similarity index 94% rename from modules/ui/TextWithLetterSpacing.tsx rename to src/ui/TextWithLetterSpacing.tsx index 111e3fb..040d868 100644 --- a/modules/ui/TextWithLetterSpacing.tsx +++ b/src/ui/TextWithLetterSpacing.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { StyleSheet, View } from 'react-native'; -import { Letter } from 'app/modules/ui/Letter'; +import { Letter } from 'app/src/ui/Letter'; const spacingForLetterIndex = (letters: any, index: any, spacing: any) => letters.length - 1 === index ? 0 : spacing; diff --git a/modules/ui/ThreeDots.tsx b/src/ui/ThreeDots.tsx similarity index 86% rename from modules/ui/ThreeDots.tsx rename to src/ui/ThreeDots.tsx index 205517f..3801dd3 100644 --- a/modules/ui/ThreeDots.tsx +++ b/src/ui/ThreeDots.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StyleSheet, View, Pressable } from 'react-native'; -import Colors from 'app/constants/Colors'; -import cursorPointer from 'app/constants/CursorPointer'; +import Colors from 'app/src/constants/Colors'; +import cursorPointer from 'app/src/constants/CursorPointer'; var styles = StyleSheet.create({ dot: { diff --git a/modules/ui/UserAvatar.tsx b/src/ui/UserAvatar.tsx similarity index 97% rename from modules/ui/UserAvatar.tsx rename to src/ui/UserAvatar.tsx index 4cbcdbd..b558ae0 100644 --- a/modules/ui/UserAvatar.tsx +++ b/src/ui/UserAvatar.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { StyleSheet, View, Text, Image, ActivityIndicator } from 'react-native'; -import Colors from 'app/constants/Colors'; +import Colors from 'app/src/constants/Colors'; export class UserAvatar extends React.Component { state = { diff --git a/modules/ui/UserRow.tsx b/src/ui/UserRow.tsx similarity index 92% rename from modules/ui/UserRow.tsx rename to src/ui/UserRow.tsx index 24b993e..2dcc75d 100644 --- a/modules/ui/UserRow.tsx +++ b/src/ui/UserRow.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; -import Colors from 'app/constants/Colors'; -import { UserAvatar } from 'app/modules/ui/UserAvatar'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { UserAvatar } from 'app/src/ui/UserAvatar'; +import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; import { CommonActions, useNavigation } from '@react-navigation/native'; diff --git a/modules/ui/ViewPropTypes.tsx b/src/ui/ViewPropTypes.tsx similarity index 100% rename from modules/ui/ViewPropTypes.tsx rename to src/ui/ViewPropTypes.tsx diff --git a/modules/ui/buy-btn/BuyBtn.tsx b/src/ui/buy-btn/BuyBtn.tsx similarity index 91% rename from modules/ui/buy-btn/BuyBtn.tsx rename to src/ui/buy-btn/BuyBtn.tsx index 50ddd49..2ad7669 100644 --- a/modules/ui/buy-btn/BuyBtn.tsx +++ b/src/ui/buy-btn/BuyBtn.tsx @@ -1,11 +1,11 @@ import React, { useEffect, useState } from 'react'; import { StyleSheet, Text, View, Pressable } from 'react-native'; -import Colors from 'app/constants/Colors'; -import { Stores } from 'app/functions/Stores'; +import Colors from 'app/src/constants/Colors'; +import { Stores } from 'app/src/functions/Stores'; import { CommonActions, useNavigation } from '@react-navigation/native'; import { observer } from 'mobx-react'; -import cursorPointer from 'app/constants/CursorPointer'; -import DollarIcon from 'app/modules/ui/icons/dollar'; +import cursorPointer from 'app/src/constants/CursorPointer'; +import DollarIcon from 'app/src/ui/icons/dollar'; import tw from 'twin.macro'; const Placeholder = () => ; diff --git a/modules/ui/icons/account-box.tsx b/src/ui/icons/account-box.tsx similarity index 100% rename from modules/ui/icons/account-box.tsx rename to src/ui/icons/account-box.tsx diff --git a/modules/ui/icons/check.tsx b/src/ui/icons/check.tsx similarity index 100% rename from modules/ui/icons/check.tsx rename to src/ui/icons/check.tsx diff --git a/modules/ui/icons/chevron-down.tsx b/src/ui/icons/chevron-down.tsx similarity index 100% rename from modules/ui/icons/chevron-down.tsx rename to src/ui/icons/chevron-down.tsx diff --git a/modules/ui/icons/chevron-left.tsx b/src/ui/icons/chevron-left.tsx similarity index 100% rename from modules/ui/icons/chevron-left.tsx rename to src/ui/icons/chevron-left.tsx diff --git a/modules/ui/icons/chevron-right.tsx b/src/ui/icons/chevron-right.tsx similarity index 100% rename from modules/ui/icons/chevron-right.tsx rename to src/ui/icons/chevron-right.tsx diff --git a/modules/ui/icons/chevron-up.tsx b/src/ui/icons/chevron-up.tsx similarity index 100% rename from modules/ui/icons/chevron-up.tsx rename to src/ui/icons/chevron-up.tsx diff --git a/modules/ui/icons/circle.tsx b/src/ui/icons/circle.tsx similarity index 100% rename from modules/ui/icons/circle.tsx rename to src/ui/icons/circle.tsx diff --git a/modules/ui/icons/cog.tsx b/src/ui/icons/cog.tsx similarity index 100% rename from modules/ui/icons/cog.tsx rename to src/ui/icons/cog.tsx diff --git a/modules/ui/icons/discord.tsx b/src/ui/icons/discord.tsx similarity index 100% rename from modules/ui/icons/discord.tsx rename to src/ui/icons/discord.tsx diff --git a/modules/ui/icons/dollar.tsx b/src/ui/icons/dollar.tsx similarity index 100% rename from modules/ui/icons/dollar.tsx rename to src/ui/icons/dollar.tsx diff --git a/modules/ui/icons/fullscreen-exit.tsx b/src/ui/icons/fullscreen-exit.tsx similarity index 100% rename from modules/ui/icons/fullscreen-exit.tsx rename to src/ui/icons/fullscreen-exit.tsx diff --git a/modules/ui/icons/fullscreen.tsx b/src/ui/icons/fullscreen.tsx similarity index 100% rename from modules/ui/icons/fullscreen.tsx rename to src/ui/icons/fullscreen.tsx diff --git a/modules/ui/icons/github.tsx b/src/ui/icons/github.tsx similarity index 100% rename from modules/ui/icons/github.tsx rename to src/ui/icons/github.tsx diff --git a/modules/ui/icons/info-circle.tsx b/src/ui/icons/info-circle.tsx similarity index 100% rename from modules/ui/icons/info-circle.tsx rename to src/ui/icons/info-circle.tsx diff --git a/modules/ui/icons/instagram.tsx b/src/ui/icons/instagram.tsx similarity index 100% rename from modules/ui/icons/instagram.tsx rename to src/ui/icons/instagram.tsx diff --git a/modules/ui/icons/key.tsx b/src/ui/icons/key.tsx similarity index 100% rename from modules/ui/icons/key.tsx rename to src/ui/icons/key.tsx diff --git a/modules/ui/icons/like.tsx b/src/ui/icons/like.tsx similarity index 100% rename from modules/ui/icons/like.tsx rename to src/ui/icons/like.tsx diff --git a/modules/ui/icons/logout.tsx b/src/ui/icons/logout.tsx similarity index 100% rename from modules/ui/icons/logout.tsx rename to src/ui/icons/logout.tsx diff --git a/modules/ui/icons/mail-outline.tsx b/src/ui/icons/mail-outline.tsx similarity index 100% rename from modules/ui/icons/mail-outline.tsx rename to src/ui/icons/mail-outline.tsx diff --git a/modules/ui/icons/money.tsx b/src/ui/icons/money.tsx similarity index 100% rename from modules/ui/icons/money.tsx rename to src/ui/icons/money.tsx diff --git a/modules/ui/icons/pause.tsx b/src/ui/icons/pause.tsx similarity index 100% rename from modules/ui/icons/pause.tsx rename to src/ui/icons/pause.tsx diff --git a/modules/ui/icons/person-outline.tsx b/src/ui/icons/person-outline.tsx similarity index 100% rename from modules/ui/icons/person-outline.tsx rename to src/ui/icons/person-outline.tsx diff --git a/modules/ui/icons/phone.tsx b/src/ui/icons/phone.tsx similarity index 100% rename from modules/ui/icons/phone.tsx rename to src/ui/icons/phone.tsx diff --git a/modules/ui/icons/pie.tsx b/src/ui/icons/pie.tsx similarity index 100% rename from modules/ui/icons/pie.tsx rename to src/ui/icons/pie.tsx diff --git a/modules/ui/icons/play.tsx b/src/ui/icons/play.tsx similarity index 100% rename from modules/ui/icons/play.tsx rename to src/ui/icons/play.tsx diff --git a/modules/ui/icons/remove.tsx b/src/ui/icons/remove.tsx similarity index 100% rename from modules/ui/icons/remove.tsx rename to src/ui/icons/remove.tsx diff --git a/modules/ui/icons/repeat.tsx b/src/ui/icons/repeat.tsx similarity index 100% rename from modules/ui/icons/repeat.tsx rename to src/ui/icons/repeat.tsx diff --git a/modules/ui/icons/search.tsx b/src/ui/icons/search.tsx similarity index 100% rename from modules/ui/icons/search.tsx rename to src/ui/icons/search.tsx diff --git a/modules/ui/icons/shuffle.tsx b/src/ui/icons/shuffle.tsx similarity index 100% rename from modules/ui/icons/shuffle.tsx rename to src/ui/icons/shuffle.tsx diff --git a/modules/ui/icons/skip-backward.tsx b/src/ui/icons/skip-backward.tsx similarity index 100% rename from modules/ui/icons/skip-backward.tsx rename to src/ui/icons/skip-backward.tsx diff --git a/modules/ui/icons/skip-forward.tsx b/src/ui/icons/skip-forward.tsx similarity index 100% rename from modules/ui/icons/skip-forward.tsx rename to src/ui/icons/skip-forward.tsx diff --git a/modules/ui/icons/star-border.tsx b/src/ui/icons/star-border.tsx similarity index 100% rename from modules/ui/icons/star-border.tsx rename to src/ui/icons/star-border.tsx diff --git a/modules/ui/icons/twitter.tsx b/src/ui/icons/twitter.tsx similarity index 100% rename from modules/ui/icons/twitter.tsx rename to src/ui/icons/twitter.tsx diff --git a/modules/ui/icons/upload.tsx b/src/ui/icons/upload.tsx similarity index 100% rename from modules/ui/icons/upload.tsx rename to src/ui/icons/upload.tsx diff --git a/modules/ui/icons/user.tsx b/src/ui/icons/user.tsx similarity index 100% rename from modules/ui/icons/user.tsx rename to src/ui/icons/user.tsx diff --git a/modules/ui/icons/wallet.tsx b/src/ui/icons/wallet.tsx similarity index 100% rename from modules/ui/icons/wallet.tsx rename to src/ui/icons/wallet.tsx diff --git a/modules/ui/icons/walletconnect-icon.tsx b/src/ui/icons/walletconnect-icon.tsx similarity index 100% rename from modules/ui/icons/walletconnect-icon.tsx rename to src/ui/icons/walletconnect-icon.tsx diff --git a/modules/ui/icons/x.tsx b/src/ui/icons/x.tsx similarity index 100% rename from modules/ui/icons/x.tsx rename to src/ui/icons/x.tsx diff --git a/modules/ui/searchbar/SearchBar.android.js b/src/ui/searchbar/SearchBar.android.js similarity index 95% rename from modules/ui/searchbar/SearchBar.android.js rename to src/ui/searchbar/SearchBar.android.js index 7c25e2a..f8a824e 100644 --- a/modules/ui/searchbar/SearchBar.android.js +++ b/src/ui/searchbar/SearchBar.android.js @@ -8,10 +8,10 @@ import { Platform, Pressable, } from 'react-native'; -import Input from 'app/modules/ui/Input'; -import Colors from 'app/constants/Colors'; -import SearchIcon from 'app/modules/ui/icons/search'; -import CloseIcon from 'app/modules/ui/icons/x'; +import Input from 'app/src/ui/Input'; +import Colors from 'app/src/constants/Colors'; +import SearchIcon from 'app/src/ui/icons/search'; +import CloseIcon from 'app/src/ui/icons/x'; class SearchBar extends Component { focus = () => { diff --git a/modules/ui/searchbar/SearchBar.ios.js b/src/ui/searchbar/SearchBar.ios.js similarity index 95% rename from modules/ui/searchbar/SearchBar.ios.js rename to src/ui/searchbar/SearchBar.ios.js index 3056de5..724dc59 100644 --- a/modules/ui/searchbar/SearchBar.ios.js +++ b/src/ui/searchbar/SearchBar.ios.js @@ -11,11 +11,11 @@ import { Platform, Pressable, } from 'react-native'; -import Colors from 'app/constants/Colors'; -import CloseIcon from 'app/modules/ui/icons/x'; -import SearchIcon from 'app/modules/ui/icons/search'; +import Colors from 'app/src/constants/Colors'; +import CloseIcon from 'app/src/ui/icons/x'; +import SearchIcon from 'app/src/ui/icons/search'; -import Input from 'app/modules/ui/Input'; +import Input from 'app/src/ui/Input'; const SCREEN_WIDTH = Dimensions.get('window').width; const IOS_GRAY = Colors.searchTextColor; diff --git a/modules/ui/searchbar/SearchBar.tsx b/src/ui/searchbar/SearchBar.tsx similarity index 100% rename from modules/ui/searchbar/SearchBar.tsx rename to src/ui/searchbar/SearchBar.tsx diff --git a/yarn.lock b/yarn.lock index 273f5e6..a2b48d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -151,24 +151,6 @@ dependencies: cross-fetch "3.0.4" -"@apollo/client@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.5.6.tgz#911929df073280689efd98e5603047b79e0c39a2" - integrity sha512-XHoouuEJ4L37mtfftcHHO1caCRrKKAofAwqRoq28UQIPMJk+e7n3X9OtRRNXKk/9tmhNkwelSary+EilfPwI7A== - dependencies: - "@graphql-typed-document-node/core" "^3.0.0" - "@wry/context" "^0.6.0" - "@wry/equality" "^0.5.0" - "@wry/trie" "^0.3.0" - graphql-tag "^2.12.3" - hoist-non-react-statics "^3.3.2" - optimism "^0.16.1" - prop-types "^15.7.2" - symbol-observable "^4.0.0" - ts-invariant "^0.9.4" - tslib "^2.3.0" - zen-observable-ts "^1.2.0" - "@babel/code-frame@7.10.4", "@babel/code-frame@~7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -2937,11 +2919,6 @@ webpack "4.43.0" webpack-manifest-plugin "~2.2.0" -"@graphql-typed-document-node/core@^3.0.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.1.tgz#076d78ce99822258cf813ecc1e7fa460fa74d052" - integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg== - "@hapi/accept@5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.2.tgz#ab7043b037e68b722f93f376afb05e85c0699523" @@ -4002,27 +3979,6 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" -"@wry/context@^0.6.0": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.6.1.tgz#c3c29c0ad622adb00f6a53303c4f965ee06ebeb2" - integrity sha512-LOmVnY1iTU2D8tv4Xf6MVMZZ+juIJ87Kt/plMijjN20NMAXGmH4u8bS1t0uT74cZ5gwpocYueV58YwyI8y+GKw== - dependencies: - tslib "^2.3.0" - -"@wry/equality@^0.5.0": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.2.tgz#72c8a7a7d884dff30b612f4f8464eba26c080e73" - integrity sha512-oVMxbUXL48EV/C0/M7gLVsoK6qRHPS85x8zECofEZOVvxGmIPLA9o5Z27cc2PoAyZz1S2VoM2A7FLAnpfGlneA== - dependencies: - tslib "^2.3.0" - -"@wry/trie@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.3.1.tgz#2279b790f15032f8bcea7fc944d27988e5b3b139" - integrity sha512-WwB53ikYudh9pIorgxrkHKrQZcCqNM/Q/bDzZBffEaGUKGuHrRb3zZUT9Sh2qw9yogC7SsdRmQ1ER0pqvd3bfw== - dependencies: - tslib "^2.3.0" - "@xmldom/xmldom@~0.7.0": version "0.7.5" resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d" @@ -4472,6 +4428,11 @@ async@^2.4.0: dependencies: lodash "^4.17.14" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" @@ -5481,6 +5442,13 @@ colors@^1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + command-exists@^1.2.8: version "1.2.9" resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" @@ -5758,6 +5726,13 @@ cross-fetch@^3.0.4: dependencies: node-fetch "2.6.1" +cross-fetch@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-spawn@7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -6182,6 +6157,11 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -6955,6 +6935,11 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-files@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" + integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -7274,6 +7259,15 @@ fork-ts-checker-webpack-plugin@4.1.6: tapable "^1.0.0" worker-rpc "^0.1.0" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -7577,17 +7571,19 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graphql-tag@^2.12.3: - version "2.12.6" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" - integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== +graphql-request@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-4.3.0.tgz#b934e08fcae764aa2cdc697d3c821f046cb5dbf2" + integrity sha512-2v6hQViJvSsifK606AliqiNiijb1uwWp6Re7o0RTyH+uRTv/u7Uqm2g4Fjq/LgZIzARB38RZEvVBFOQOVdlBow== dependencies: - tslib "^2.1.0" + cross-fetch "^3.1.5" + extract-files "^9.0.0" + form-data "^3.0.0" -graphql@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.2.0.tgz#de3150e80f1fc009590b92a9d16ab1b46e12b656" - integrity sha512-MuQd7XXrdOcmfwuLwC2jNvx0n3rxIuNYOxUtiee5XOmfrWo613ar2U8pE7aHAKh8VwfpifubpD9IP+EdEAEOsA== +graphql@^16.5.0: + version "16.5.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.5.0.tgz#41b5c1182eaac7f3d47164fb247f61e4dfb69c85" + integrity sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA== gzip-size@5.1.1: version "5.1.1" @@ -7604,6 +7600,11 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" +hamt_plus@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hamt_plus/-/hamt_plus-1.0.2.tgz#e21c252968c7e33b20f6a1b094cd85787a265601" + integrity sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA== + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -7732,7 +7733,7 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -9450,6 +9451,18 @@ mime-db@1.48.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mime-types@^2.1.26, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" @@ -9928,6 +9941,13 @@ node-fetch@2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -10282,14 +10302,6 @@ opener@^1.5.2: resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -optimism@^0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.16.1.tgz#7c8efc1f3179f18307b887e18c15c5b7133f6e7d" - integrity sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg== - dependencies: - "@wry/context" "^0.6.0" - "@wry/trie" "^0.3.0" - optimize-css-assets-webpack-plugin@^5.0.3: version "5.0.8" resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz#cbccdcf5a6ef61d4f8cc78cf083a67446e5f402a" @@ -11739,6 +11751,13 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +recoil@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.7.4.tgz#d6508fa656d9c93e66fdf334e1f723a9e98801cf" + integrity sha512-sCXvQGMfSprkNU4ZRkJV4B0qFQSURJMgsICqY1952WRlg66NMwYqi6n67vhnhn0qw4zHU1gHXJuMvRDaiRNFZw== + dependencies: + hamt_plus "1.0.2" + recursive-readdir@2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" @@ -12967,11 +12986,6 @@ svgo@^1.0.0: unquote "~1.1.1" util.promisify "~1.0.0" -symbol-observable@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" - integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== - tailwindcss@>=2.0.0: version "3.0.24" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.0.24.tgz#22e31e801a44a78a1d9a81ecc52e13b69d85704d" @@ -13244,6 +13258,11 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + traverse@0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" @@ -13254,13 +13273,6 @@ ts-interface-checker@^0.1.9: resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== -ts-invariant@^0.9.4: - version "0.9.4" - resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.9.4.tgz#42ac6c791aade267dd9dc65276549df5c5d71cac" - integrity sha512-63jtX/ZSwnUNi/WhXjnK8kz4cHHpYS60AnmA6ixz17l7E12a5puCWFlNpkne5Rl0J8TBPVHpGjsj4fxs8ObVLQ== - dependencies: - tslib "^2.1.0" - ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -13271,7 +13283,7 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== -tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0: +tslib@^2.0.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== @@ -13722,6 +13734,11 @@ web-vitals@0.2.1: resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-0.2.1.tgz#60782fa690243fe35613759a0c26431f57ba7b2d" integrity sha512-2pdRlp6gJpOCg0oMMqwFF0axjk5D9WInc09RSYtqFgPXQ15+YKNQ7YnBBEqAL5jvmfH9WvoXDMb8DHwux7pIew== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -13794,6 +13811,14 @@ whatwg-fetch@3.0.0, whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" @@ -14062,15 +14087,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zen-observable-ts@^1.2.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.3.tgz#c2f5ccebe812faf0cfcde547e6004f65b1a6d769" - integrity sha512-hc/TGiPkAWpByykMwDcem3SdUgA4We+0Qb36bItSuJC9xD0XVBZoFHYoadAomDSNf64CG8Ydj0Qb8Od8BUWz5g== - dependencies: - zen-observable "0.8.15" - -zen-observable@0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" - integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== From 8575dbb24498be88b2cf6d204f5e5954ce5d092b Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Wed, 29 Jun 2022 10:11:05 -0500 Subject: [PATCH 02/13] refactor phase 1 --- pages/index.tsx | 14 +- src/accounts/SignInScreen.tsx | 14 +- src/accounts/SignUpScreen.tsx | 13 +- src/api/user.ts | 143 ++++---- src/atoms/atoms.ts | 85 ++++- src/hooks/nft-listener.ts | 12 +- src/marketing/web/NavBar.tsx | 12 +- src/models/profile.ts | 9 + src/navigation/RootNavigation.tsx | 11 +- src/player/player-screen/like-btn/LikeBtn.tsx | 47 ++- .../likers-section/LikersSection.tsx | 74 ++-- src/playlists/CollectionScreen.tsx | 69 ++-- src/playlists/LikesRow.tsx | 10 +- src/playlists/LikesScreen.tsx | 69 ++-- src/playlists/MyMusicRow.tsx | 14 +- src/profile/EditProfilePhotoBtn.tsx | 87 +++-- src/profile/EditProfileScreen.tsx | 327 +++++++++--------- src/profile/LowBalanceModal.tsx | 7 +- src/profile/MediaUpload.tsx | 6 +- src/profile/ProfileSettingsScreen.tsx | 11 +- src/providers/Providers.tsx | 10 - src/search/LikeOptionRow.tsx | 13 +- src/search/PricingOptionsModal.tsx | 6 +- src/search/RemoveFromMyMusicRow.tsx | 6 +- src/stores/edit-profile.store.ts | 144 -------- src/stores/index.ts | 18 - src/stores/likes.store.ts | 206 ++++++----- src/stores/session.store.ts | 91 ----- src/stores/session.ts | 54 +++ src/stores/sign-in-validation.store.ts | 1 - src/stores/user-entries.store.ts | 35 +- .../username-and-email-validation.store.ts | 80 ----- src/ui/BuyOptionsModal.tsx | 5 +- src/ui/DoneEditBtn.tsx | 55 ++- src/ui/LogOutBtn.tsx | 12 +- 35 files changed, 822 insertions(+), 948 deletions(-) create mode 100644 src/models/profile.ts delete mode 100644 src/stores/edit-profile.store.ts delete mode 100644 src/stores/session.store.ts create mode 100644 src/stores/session.ts delete mode 100644 src/stores/username-and-email-validation.store.ts diff --git a/pages/index.tsx b/pages/index.tsx index 2fef03d..7ea07ac 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,5 +1,7 @@ import 'setimmediate'; import React, { lazy, Suspense } from 'react'; +import { RecoilRoot } from 'recoil'; + import RootNavigation from 'app/src/navigation/RootNavigation'; import '@expo/match-media'; import useCachedResources from '../src/functions/CacheResourcesAsync'; @@ -29,10 +31,12 @@ export default () => { return ; } return ( - - - - - + + + + + + + ); }; diff --git a/src/accounts/SignInScreen.tsx b/src/accounts/SignInScreen.tsx index facddc3..a668ce2 100644 --- a/src/accounts/SignInScreen.tsx +++ b/src/accounts/SignInScreen.tsx @@ -20,19 +20,21 @@ import { Config } from 'app/src/config'; import * as Device from 'expo-device'; import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; +import { SessionStore } from '../stores/session'; export default observer(({ route, navigation }) => { - const { signInValidationStore, sessionStore } = Stores(); + const { signInValidationStore } = Stores(); + const { requestToken, signIn } = SessionStore(); const [usernameOrEmail, setUsernameOrEmail] = useState(''); const [loading, setLoading] = useState(false); const [showEmailLink, setShowEmailLink] = useState(false); const { token, uid } = route.params || {}; const linkTo = useLinkTo(); - const signIn = async () => { + const handleSignIn = async () => { setLoading(true); try { - await sessionStore.requestToken(usernameOrEmail, ''); + await requestToken(usernameOrEmail, ''); // check your email to access your account setLoading(false); setShowEmailLink(true); @@ -46,7 +48,7 @@ export default observer(({ route, navigation }) => { const signInWithXDR = async (xdr) => { setLoading(true); try { - await sessionStore.signIn(undefined, undefined, xdr); + await signIn(undefined, undefined, xdr); // check your email to access your account setLoading(false); return; @@ -86,7 +88,7 @@ export default observer(({ route, navigation }) => { ); return; } - const res = await sessionStore.signIn(token, uid); + const res = await signIn(token, uid); if (res) { return linkTo('/'); } @@ -182,7 +184,7 @@ export default observer(({ route, navigation }) => { styles.joinBtn, { opacity: signInValidationStore.validForm ? 1 : 0.5 }, ]} - onPress={signIn} + onPress={handleSignIn} underlayColor={Colors.underlayColor} disabled={!signInValidationStore.validForm} > diff --git a/src/accounts/SignUpScreen.tsx b/src/accounts/SignUpScreen.tsx index c30f057..6fb8dab 100644 --- a/src/accounts/SignUpScreen.tsx +++ b/src/accounts/SignUpScreen.tsx @@ -16,9 +16,12 @@ import { Stores } from 'app/src/functions/Stores'; import BackgroundImage from 'app/src/ui/BackgroundImage'; import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; +import { SessionStore } from '../stores/session'; export default observer(() => { - const { signUpValidationStore, sessionStore, walletConnectStore } = Stores(); + const { signUpValidationStore, walletConnectStore } = Stores(); + const { signUp } = SessionStore(); + const [username, setUsername] = useState(''); const [displayName, setDisplayName] = useState(''); const [email, setEmail] = useState(''); @@ -40,10 +43,10 @@ export default observer(() => { signUpValidationStore.validateEmail(target.value); }; - const signUp = async () => { + const handleSignUp = async () => { setLoading(true); try { - await sessionStore.signUp({ + await signUp({ username: username, displayName: displayName, email: email, @@ -61,7 +64,7 @@ export default observer(() => { const onSubmit = (e) => { if (e.nativeEvent.key == 'Enter') { - signUp(); + handleSignUp(); } }; @@ -144,7 +147,7 @@ export default observer(() => { styles.joinBtn, { opacity: signUpValidationStore.validForm ? 1 : 0.5 }, ]} - onPress={signUp} + onPress={handleSignUp} underlayColor={Colors.underlayColor} disabled={!signUpValidationStore.validForm} > diff --git a/src/api/user.ts b/src/api/user.ts index 16db2be..c40089b 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -2,32 +2,36 @@ import { gql } from 'graphql-request'; import { client } from './client'; import { SignUpForm } from '../types'; -export class UserBackend { - async getAuthenticatedUser() { - return client - .request( - gql` - { - authenticatedUser { - avatarUrl - displayName - username - id - jwt - publishedAt - email - description - } +export async function getAuthenticatedUser() { + return client + .request( + gql` + { + authenticatedUser { + avatarUrl + displayName + username + id + jwt + publishedAt + email + description } - ` - ) - .then(({ authenticatedUser }) => authenticatedUser); - } + } + ` + ) + .then(({ authenticatedUser }) => authenticatedUser); +} - async signUp({ displayName, email, username, publicKey }: SignUpForm) { - return client - .request( - gql` +export async function signUp({ + displayName, + email, + username, + publicKey, +}: SignUpForm) { + return client + .request( + gql` mutation { createUserWithEmail(displayName: "${displayName}", email: "${email}", username: "${username}",publicKey: "${publicKey}"){ avatarUrl @@ -42,33 +46,33 @@ export class UserBackend { } } ` - ) - .then(({ createUserWithEmail }) => createUserWithEmail) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } + ) + .then(({ createUserWithEmail }) => createUserWithEmail) + .catch(({ graphQLErrors }) => { + let [{ message }] = graphQLErrors; + throw message; + }); +} - async requestToken(usernameOrEmail, publicKey) { - return client - .request( - gql` +export async function requestToken(usernameOrEmail, publicKey) { + return client + .request( + gql` mutation { requestToken(usernameOrEmail: "${usernameOrEmail}", publicKey: "${publicKey}") } ` - ) - .catch((graphQLErrors) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } + ) + .catch((graphQLErrors) => { + let [{ message }] = graphQLErrors; + throw message; + }); +} - async signIn(token?: string, uid?: string, xdr?: string) { - return client - .request( - gql` +export async function signIn(token?: string, uid?: string, xdr?: string) { + return client + .request( + gql` mutation { signIn(token: "${token}", uid: "${uid}", signedXDR: "${xdr}"){ avatarUrl @@ -83,24 +87,24 @@ export class UserBackend { } } ` - ) - .then(({ signIn }) => signIn) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } + ) + .then(({ signIn }) => signIn) + .catch(({ graphQLErrors }) => { + let [{ message }] = graphQLErrors; + throw message; + }); +} - async updateUser( - avatarUrl: string, - displayName: string, - description: string, - username: string, - email: string - ) { - client - .request( - gql` +export async function updateUser( + avatarUrl: string, + displayName: string, + description: string, + username: string, + email: string +) { + client + .request( + gql` mutation { updateUser(avatarUrl: "${avatarUrl}", displayName: "${displayName}", description: "${description}", username: "${username}", email: "${email}"){ avatarUrl @@ -113,13 +117,10 @@ export class UserBackend { } } ` - ) - .then(({ updateUser }) => updateUser) - .catch(({ graphQLErrors }) => { - let [{ message }] = graphQLErrors; - throw message; - }); - } + ) + .then(({ updateUser }) => updateUser) + .catch(({ graphQLErrors }) => { + let [{ message }] = graphQLErrors; + throw message; + }); } - -export const userBackend = new UserBackend(); diff --git a/src/atoms/atoms.ts b/src/atoms/atoms.ts index 721fcc3..757e569 100644 --- a/src/atoms/atoms.ts +++ b/src/atoms/atoms.ts @@ -1,10 +1,12 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; -import { atom, DefaultValue } from 'recoil'; +import { atom, selector, DefaultValue } from 'recoil'; import { client } from '../api/client'; import { userDataKey } from '../config/constants'; -import { UserData } from '../models'; +import { User } from '../models'; +import { ProfileEdit } from '../models/profile'; const localStorageEffect = (key) => ({ setSelf, onSet }) => { + console.log('localstorage effect'); setSelf( AsyncStorage.getItem(key).then((savedValue) => savedValue != null ? JSON.parse(savedValue) : new DefaultValue() @@ -26,8 +28,85 @@ const headersEffect = () => ({ setSelf, onSet }) => { }); }; -export const userAtom = atom({ +export const userAtom = atom({ key: 'user', default: null, effects_UNSTABLE: [localStorageEffect(userDataKey), headersEffect()], }); + +export const profileAtom = atom({ + key: 'profileEdit', + default: selector({ + key: 'user', + get: ({ get }) => { + const user = get(userAtom); + if (!user) + return { + avatarUrl: '', + displayName: '', + description: '', + username: '', + email: '', + loadingAvatar: false, + uploadError: '', + }; + const { + avatarUrl, + displayName, + description, + username, + email, + } = (user as unknown) as ProfileEdit; + return { + avatarUrl, + displayName, + description, + username, + email, + loadingAvatar: false, + uploadError: '', + }; + }, + }), +}); + +export const profileValidationErrorAtom = selector({ + key: 'profileError', + get: ({ get }) => { + const { avatarUrl, displayName, description, username, email } = get( + profileAtom + ); + if (!avatarUrl) { + return 'Upload a profile picture.'; + } + + if (!displayName) { + return 'Add a display name.'; + } + + if (!description) { + return 'Add a description.'; + } + + if (!username) { + return 'Add a username.'; + } + + if (!email) { + return 'Add an email.'; + } + return null; + }, +}); + +export const canUpdateProfileAtom = selector({ + key: 'profileError', + get: ({ get }) => { + const { avatarUrl, displayName, description, username, email } = get( + profileAtom + ); + return ( + !!avatarUrl && !!displayName && !!description && !!username && !!email + ); + }, +}); diff --git a/src/hooks/nft-listener.ts b/src/hooks/nft-listener.ts index 38ad68f..0cdbd80 100644 --- a/src/hooks/nft-listener.ts +++ b/src/hooks/nft-listener.ts @@ -1,17 +1,21 @@ import { useEffect, useState } from 'react'; import { Stores } from 'app/src/functions/Stores'; import { Config } from 'app/src/config'; +import { userAtom } from '../atoms/atoms'; +import { useRecoilValue } from 'recoil'; const EventSource = require('eventsource'); const nftListener = (open) => { - const { entryStore, sessionStore } = Stores(); + const { entryStore } = Stores(); + const user = useRecoilValue(userAtom); + const [indexed, setIndexed] = useState(false); useEffect(() => { if (!open) return; const es = new EventSource( open - ? `${Config.HORIZON_URL}/accounts/${sessionStore.user?.publicKey}/payments?cursor=now&include_failed=false` + ? `${Config.HORIZON_URL}/accounts/${user?.publicKey}/payments?cursor=now&include_failed=false` : '' ); es.onmessage = async function (message) { @@ -31,9 +35,9 @@ const nftListener = (open) => { return () => { es.close(); }; - }, [sessionStore.user?.publicKey, open]); + }, [user?.publicKey, open]); - return { publicKey: sessionStore.user?.publicKey, indexed }; + return { publicKey: user?.publicKey, indexed }; }; export default nftListener; diff --git a/src/marketing/web/NavBar.tsx b/src/marketing/web/NavBar.tsx index 4cb09a7..a95cfd3 100644 --- a/src/marketing/web/NavBar.tsx +++ b/src/marketing/web/NavBar.tsx @@ -4,11 +4,11 @@ import SkyhitzLogo from './SkyhitzLogo'; import { View, Text, StyleSheet, Pressable } from 'react-native'; import { useLinkTo } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; +import { userAtom } from 'app/src/atoms/atoms'; +import { useRecoilValue } from 'recoil'; -export default observer(() => { - const { sessionStore } = Stores(); +export default () => { + const user = useRecoilValue(userAtom); const linkTo = useLinkTo(); @@ -45,7 +45,7 @@ export default observer(() => { paddingRight: 20, }} > - {sessionStore.user ? null : ( + {user ? null : ( <> linkTo('/accounts/sign-in')} @@ -64,7 +64,7 @@ export default observer(() => { ); -}); +}; let styles = StyleSheet.create({ logo: { diff --git a/src/models/profile.ts b/src/models/profile.ts new file mode 100644 index 0000000..7b2bccd --- /dev/null +++ b/src/models/profile.ts @@ -0,0 +1,9 @@ +export type ProfileEdit = { + avatarUrl: string; + displayName: string; + description: string; + username: string; + email: string; + loadingAvatar: boolean; + uploadError: string; +}; diff --git a/src/navigation/RootNavigation.tsx b/src/navigation/RootNavigation.tsx index 85a2570..133d777 100644 --- a/src/navigation/RootNavigation.tsx +++ b/src/navigation/RootNavigation.tsx @@ -2,9 +2,10 @@ import React, { useState, useEffect, lazy } from 'react'; import { StatusBar } from 'react-native'; import { observer } from 'mobx-react'; import { useMediaQuery } from 'react-responsive'; -import { Stores } from 'app/src/functions/Stores'; import LoadingScreen from 'app/src/accounts/LoadingScreen'; import { SuspenseLoading } from './SuspenseLoading'; +import { userAtom } from '../atoms/atoms'; +import { useRecoilValue } from 'recoil'; const LazyAppStackNavigator = lazy(() => import('app/src/navigation/LazyAppStackNavigator').then((mod) => ({ @@ -30,12 +31,11 @@ const LazyNavigationContainerSuspense = (props) => ( export default observer(() => { const [loaded, setLoaded] = useState(false); - const { sessionStore } = Stores(); + const user = useRecoilValue(userAtom); StatusBar.setBarStyle('light-content'); const loadAll = async () => { - await sessionStore.loadSession(); setLoaded(true); }; @@ -54,10 +54,7 @@ export default observer(() => { if (loaded) { return ( - + ); } diff --git a/src/player/player-screen/like-btn/LikeBtn.tsx b/src/player/player-screen/like-btn/LikeBtn.tsx index e376465..e824370 100644 --- a/src/player/player-screen/like-btn/LikeBtn.tsx +++ b/src/player/player-screen/like-btn/LikeBtn.tsx @@ -1,42 +1,37 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; -import { inject } from 'mobx-react'; import LikeIcon from 'app/src/ui/icons/like'; import Colors from 'app/src/constants/Colors'; -import * as stores from 'app/src/stores'; import cursorPointer from 'app/src/constants/CursorPointer'; -type Stores = typeof stores; +import { LikesStore } from 'app/src/stores/likes.store'; -@inject((stores: Stores) => ({ - toggleLike: stores.likesStore.toggleLike.bind(stores.likesStore), - isLiked: stores.likesStore.isLiked, - entry: stores.playerStore.entry, -})) -export default class LikeBtn extends React.Component { - render() { - if (!this.props.entry) { - return null; - } - if (this.props.isLiked) { - return ( - this.props.toggleLike(this.props.entry)} - > - - - ); - } +export default (props) => { + const { toggleLike, isLiked } = LikesStore(); + // const { entry } = PlayerStore(); + const entry = null; + + if (!entry) { + return null; + } + if (isLiked()) { return ( this.props.toggleLike(this.props.entry)} + onPress={() => toggleLike(entry)} > - + ); } -} + return ( + toggleLike(entry)} + > + + + ); +}; var styles = StyleSheet.create({ controlTouch: { diff --git a/src/player/player-screen/likers-section/LikersSection.tsx b/src/player/player-screen/likers-section/LikersSection.tsx index 779e074..8adf293 100644 --- a/src/player/player-screen/likers-section/LikersSection.tsx +++ b/src/player/player-screen/likers-section/LikersSection.tsx @@ -1,56 +1,48 @@ import React from 'react'; -import { inject } from 'mobx-react'; import { StyleSheet, View, Text } from 'react-native'; import LikeBtn from 'app/src/player/player-screen/like-btn/LikeBtn'; import Divider from 'app/src/ui/Divider'; import { UserAvatar } from 'app/src/ui/UserAvatar'; import * as L from 'list'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; +import { LikesStore } from 'app/src/stores/likes.store'; -@inject((stores: Stores) => ({ - likers: stores.likesStore.entryLikes, - hasMoreLikers: stores.likesStore.hasMoreLikers, - plusLikers: stores.likesStore.plusLikers, -})) -export default class LikersSection extends React.Component { - renderMoreLikersBtn() { - if (!this.props.hasMoreLikers) { - return null; - } - return ( - - +{this.props.plusLikers} - - ); - } +export default () => { + const { entryLikes, hasMoreLikers, plusLikers } = LikesStore(); - render() { + const renderMoreLikersBtn = () => { return ( - - - Liked By - - - + hasMoreLikers() && ( + + +{plusLikers} - - - {this.props.likers && - L.map( - (liker: any) => ( - - - - ), - this.props.likers - )} - {this.renderMoreLikersBtn()} + ) + ); + }; + + return ( + + + Liked By + + - ); - } -} + + + {entryLikes && + L.map( + (liker: any) => ( + + + + ), + entryLikes + )} + {renderMoreLikersBtn()} + + + ); +}; let styles = StyleSheet.create({ bottomSection: { diff --git a/src/playlists/CollectionScreen.tsx b/src/playlists/CollectionScreen.tsx index 9d9725b..bb715c3 100644 --- a/src/playlists/CollectionScreen.tsx +++ b/src/playlists/CollectionScreen.tsx @@ -1,47 +1,40 @@ import React from 'react'; import { ScrollView } from 'react-native'; -import { inject } from 'mobx-react'; import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as stores from 'app/src/stores'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -type Stores = typeof stores; +import { UserEntriesStore } from '../stores/user-entries.store'; -@inject((stores: Stores) => ({ - loadAndPlay: stores.playerStore.loadAndPlay.bind(stores.playerStore), - entries: stores.userEntriesStore.entries, - loading: stores.userEntriesStore.loading, -})) -export default class CollectionScreen extends React.Component { - render() { - return ( - - - {SearchingLoader(this.props.loading)} - {L.map( - (entry: any) => ( - - ), - this.props.entries - )} - - - - ); - } -} +export default () => { + const { entries, loading } = UserEntriesStore(); + // TO DO: add load and play + return ( + + + {SearchingLoader(loading)} + {L.map( + (entry: any) => ( + {}} + entry={entry} + options={null} + disablePlaylistMode={null} + previousScreen={'CollectionScreen'} + /> + ), + entries + )} + + + + ); +}; diff --git a/src/playlists/LikesRow.tsx b/src/playlists/LikesRow.tsx index ff2391d..8d96bff 100644 --- a/src/playlists/LikesRow.tsx +++ b/src/playlists/LikesRow.tsx @@ -7,21 +7,23 @@ import { observer } from 'mobx-react'; import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { LikesStore } from '../stores/likes.store'; export default observer(() => { - let { likesStore, playerStore } = Stores(); + let { playerStore } = Stores(); + const { userLikes, userLikesCount } = LikesStore(); let linkTo = useLinkTo(); const handleLikesNavigation = () => { linkTo('/dashboard/profile/likes'); - playerStore.setPlaylistMode(likesStore.userLikes); + playerStore.setPlaylistMode(userLikes); }; const likesCopy = () => { - if (!likesStore.userLikesCount) { + if (!userLikesCount) { return null; } - return `${likesStore.userLikesCount}`; + return `${userLikesCount}`; }; return ( diff --git a/src/playlists/LikesScreen.tsx b/src/playlists/LikesScreen.tsx index ae90955..489870a 100644 --- a/src/playlists/LikesScreen.tsx +++ b/src/playlists/LikesScreen.tsx @@ -1,47 +1,40 @@ import React from 'react'; import { ScrollView } from 'react-native'; -import { inject } from 'mobx-react'; import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as stores from 'app/src/stores'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -type Stores = typeof stores; +import { LikesStore } from '../stores/likes.store'; -@inject((stores: Stores) => ({ - loadAndPlay: stores.playerStore.loadAndPlay.bind(stores.playerStore), - entries: stores.likesStore.userLikes, - loading: stores.likesStore.loading, -})) -export default class LikesScreen extends React.Component { - render() { - return ( - - - {SearchingLoader(this.props.loading)} - {L.map( - (entry: any) => ( - - ), - this.props.entries - )} - - - - ); - } -} +export default () => { + const { userLikes, loading } = LikesStore(); + const loadAndPlay = () => {}; + return ( + + + {SearchingLoader(loading)} + {L.map( + (entry: any) => ( + + ), + userLikes + )} + + + + ); +}; diff --git a/src/playlists/MyMusicRow.tsx b/src/playlists/MyMusicRow.tsx index f9d00e8..8cea708 100644 --- a/src/playlists/MyMusicRow.tsx +++ b/src/playlists/MyMusicRow.tsx @@ -1,16 +1,14 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; - import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import ChevronRightIcon from 'app/src/ui/icons/chevron-right'; import StarBorderIcon from 'app/src/ui/icons/star-border'; +import { UserEntriesStore } from '../stores/user-entries.store'; -export default observer(() => { - let { userEntriesStore } = Stores(); +export default () => { + let { entries } = UserEntriesStore(); let linkTo = useLinkTo(); const handleNavigation = () => { @@ -18,10 +16,10 @@ export default observer(() => { }; const copy = () => { - if (!userEntriesStore.entriesCount) { + if (!entries.length) { return null; } - return `${userEntriesStore.entriesCount}`; + return `${entries.length}`; }; return ( @@ -41,7 +39,7 @@ export default observer(() => { ); -}); +}; let styles = StyleSheet.create({ rowWrap: { diff --git a/src/profile/EditProfilePhotoBtn.tsx b/src/profile/EditProfilePhotoBtn.tsx index 95d9279..ab372c5 100644 --- a/src/profile/EditProfilePhotoBtn.tsx +++ b/src/profile/EditProfilePhotoBtn.tsx @@ -2,19 +2,55 @@ import React from 'react'; import { Pressable, StyleSheet, Text, Platform } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; import * as Permissions from 'expo-permissions'; -import { inject } from 'mobx-react'; +import { useSetRecoilState } from 'recoil'; import Colors from 'app/src/constants/Colors'; -import * as stores from 'app/src/stores'; import cursorPointer from 'app/src/constants/CursorPointer'; -type Stores = typeof stores; +import { imagesGateway, nftStorageApi } from '../config/constants'; +import { profileAtom } from '../atoms/atoms'; -@inject((stores: Stores) => ({ - uploadProfilePhoto: stores.editProfileStore.uploadProfilePhoto.bind( - stores.editProfileStore - ), -})) -export default class EditProfilePhotoBtn extends React.Component { - async launchImageLibrary() { +export default () => { + const setEditProfile = useSetRecoilState(profileAtom); + + const uploadProfilePhoto = async (image) => { + const isPng = image.uri.startsWith('data:image/png'); + if (!isPng) { + setEditProfile((oldState) => ({ + ...oldState, + uploadError: 'Only png files supported!', + })); + return; + } + if (image.height !== image.width) { + setEditProfile((oldState) => ({ + ...oldState, + uploadError: 'Only square images supported!', + })); + return; + } + const blobRes = await fetch(image.uri); + const file = await blobRes.blob(); + setEditProfile((oldState) => ({ ...oldState, loadingAvatar: true })); + let res = await fetch(`${nftStorageApi}/upload`, { + method: 'POST', + body: file, + headers: new Headers({ + Authorization: `Bearer ${process.env.NEXT_PUBLIC_NFT_STORAGE_API_KEY}`, + }), + }); + let { value, ok } = await res.json(); + + if (ok) { + setEditProfile((oldState) => ({ + ...oldState, + avatarUrl: `${imagesGateway}/${value.cid}`, + loadingAvatar: false, + })); + return; + } + setEditProfile((oldState) => ({ ...oldState, loadingAvatar: false })); + }; + + const launchImageLibrary = async () => { let image = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, @@ -24,29 +60,26 @@ export default class EditProfilePhotoBtn extends React.Component { exif: true, }); if (image && !image.cancelled) { - this.props.uploadProfilePhoto(image); + uploadProfilePhoto(image); } - } - async changeProfilePhoto() { + }; + + const changeProfilePhoto = async () => { if (Platform.OS === 'ios' || Platform.OS === 'android') { const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL); if (status === 'granted') { - return this.launchImageLibrary(); + return launchImageLibrary(); } } - this.launchImageLibrary(); - } - render() { - return ( - - Change Profile Photo - - ); - } -} + launchImageLibrary(); + }; + + return ( + + Change Profile Photo + + ); +}; const styles = StyleSheet.create({ btn: { diff --git a/src/profile/EditProfileScreen.tsx b/src/profile/EditProfileScreen.tsx index 4063bf7..8245503 100644 --- a/src/profile/EditProfileScreen.tsx +++ b/src/profile/EditProfileScreen.tsx @@ -8,7 +8,6 @@ import { Platform, KeyboardAvoidingView, } from 'react-native'; -import { inject } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import { UserAvatarMedium, @@ -16,7 +15,6 @@ import { LoadingUserAvatar, } from 'app/src/ui/UserAvatar'; import EditProfilePhotoBtn from 'app/src/profile/EditProfilePhotoBtn'; -import * as stores from 'app/src/stores'; import LargeBtn from '../ui/LargeBtn'; import cursorPointer from 'app/src/constants/CursorPointer'; import AccountBoxIcon from 'app/src/ui/icons/account-box'; @@ -25,191 +23,192 @@ import MailOutlineIcon from 'app/src/ui/icons/mail-outline'; import LogoutIcon from 'app/src/ui/icons/logout'; import InfoCirlceIcon from 'app/src/ui/icons/info-circle'; import AsyncStorage from '@react-native-async-storage/async-storage'; +import { SessionStore } from '../stores/session'; +import { profileAtom, profileValidationErrorAtom } from '../atoms/atoms'; +import { useRecoilState, useRecoilValue } from 'recoil'; -type Stores = typeof stores; +export default (props) => { + const { signOut } = SessionStore(); + const [ + { loadingAvatar, avatarUrl, displayName, username, email, description }, + setEditProfile, + ] = useRecoilState(profileAtom); -@inject((stores: Stores) => ({ - profile: stores.editProfileStore.profile, - avatarUrl: stores.editProfileStore.avatarUrl, - loadingAvatar: stores.editProfileStore.loadingAvatar, - displayName: stores.editProfileStore.displayName, - description: stores.editProfileStore.description, - username: stores.editProfileStore.username, - email: stores.editProfileStore.email, - updateDisplayName: stores.editProfileStore.updateDisplayName.bind( - stores.editProfileStore - ), - updateDescription: stores.editProfileStore.updateDescription.bind( - stores.editProfileStore - ), - updateUsername: stores.editProfileStore.updateUsername.bind( - stores.editProfileStore - ), - updateEmail: stores.editProfileStore.updateEmail.bind( - stores.editProfileStore - ), - logOut: stores.sessionStore.signOut.bind(stores.sessionStore), - credits: stores.paymentsStore.credits, - validationError: stores.editProfileStore.validationError, -})) -export default class EditProfileScreen extends React.Component { - async handleLogOut() { - await this.props.logOut(); + const validationError = useRecoilValue(profileValidationErrorAtom); + + const handleLogOut = async () => { + await signOut(); await AsyncStorage.multiRemove(await AsyncStorage.getAllKeys()); - this.props.navigation.navigate( - Platform.OS === 'web' ? 'WebApp' : 'AuthScreen' - ); - } - async handleWithdrawal() { - this.props.navigation.navigate('WithdrawalModal'); - } - renderAvatar() { - if (this.props.loadingAvatar) { + props.navigation.navigate(Platform.OS === 'web' ? 'WebApp' : 'AuthScreen'); + }; + + const handleWithdrawal = async () => { + props.navigation.navigate('WithdrawalModal'); + }; + + // TODO: fix props.profile with initials + const renderAvatar = () => { + if (loadingAvatar) { return ; } - if (this.props.avatarUrl) { - return UserAvatarMediumWithUrlOnly(this.props.avatarUrl); + if (avatarUrl) { + return UserAvatarMediumWithUrlOnly(avatarUrl); } - return UserAvatarMedium(this.props.profile); - } - renderWithdrawalXLM() { - if (this.props.credits && this.props.credits > 0) { + return UserAvatarMedium(props.profile); + }; + + // TODO: get credits from payments store + const renderWithdrawalXLM = () => { + if (props.credits && props.credits > 0) { return ( Credits - + ); } return null; - } - render() { - return ( - - + + - - {this.props.validationError} - - - {this.renderAvatar()} - - + {validationError} + + + {renderAvatar()} + + - - - - - - this.props.updateDisplayName(t)} - maxLength={30} - /> + + + + - - - - - this.props.updateDescription(t)} - maxLength={150} - /> + + setEditProfile((oldState) => ({ + ...oldState, + displayName: text, + })) + } + maxLength={30} + /> + + + + - - - - - this.props.updateUsername(t)} - maxLength={30} - /> + + setEditProfile((oldState) => ({ + ...oldState, + description: text, + })) + } + maxLength={150} + /> + + + + + + setEditProfile((oldState) => ({ + ...oldState, + username: text, + })) + } + maxLength={30} + /> - Private Information - - - - - - - this.props.updateEmail(t)} - maxLength={34} - /> + + Private Information + + + + + + + setEditProfile((oldState) => ({ + ...oldState, + email: text, + })) + } + maxLength={34} + /> - {this.renderWithdrawalXLM()} - More - - + + {renderWithdrawalXLM()} + More + + + - - - - Log Out + - - - - - ); - } -} + Log Out + + + + + + ); +}; const formPadding = 20; const maxHeight = 50; diff --git a/src/profile/LowBalanceModal.tsx b/src/profile/LowBalanceModal.tsx index d7c4149..5de1c3e 100644 --- a/src/profile/LowBalanceModal.tsx +++ b/src/profile/LowBalanceModal.tsx @@ -16,9 +16,12 @@ import cursorPointer from 'app/src/constants/CursorPointer'; import CloseIcon from 'app/src/ui/icons/x'; import WalletIcon from 'app/src/ui/icons/wallet'; import DollarIcon from 'app/src/ui/icons/dollar'; +import { userAtom } from '../atoms/atoms'; +import { useRecoilValue } from 'recoil'; export default observer((props) => { - const { paymentsStore, sessionStore } = Stores(); + const { paymentsStore } = Stores(); + const user = useRecoilValue(userAtom); const { goBack } = useNavigation(); const linkTo = useLinkTo(); @@ -80,7 +83,7 @@ export default observer((props) => { Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, ]} placeholderTextColor="white" - value={sessionStore.user?.publicKey} + value={user?.publicKey} maxLength={56} /> diff --git a/src/profile/MediaUpload.tsx b/src/profile/MediaUpload.tsx index 0fd6c0f..8f2343e 100644 --- a/src/profile/MediaUpload.tsx +++ b/src/profile/MediaUpload.tsx @@ -28,6 +28,7 @@ import UploadIcon from 'app/src/ui/icons/upload'; import CheckIcon from 'app/src/ui/icons/check'; import CloseIcon from 'app/src/ui/icons/x'; import nftListener from 'app/src/hooks/nft-listener'; +import { UserEntriesStore } from '../stores/user-entries.store'; const SwitchWeb: any = Switch; @@ -75,7 +76,8 @@ const ArtworkSection = ({ imageSelected, selectArtwork }) => { }; export default observer(() => { - const { entryStore, userEntriesStore, walletConnectStore } = Stores(); + const { entryStore, walletConnectStore } = Stores(); + const { refreshEntries } = UserEntriesStore(); const linkTo = useLinkTo(); const [openListener, setOpenListener] = useState(false); @@ -164,7 +166,7 @@ export default observer(() => { }; const handleIndexedEntry = async () => { - await userEntriesStore.refreshEntries(); + await refreshEntries(); entryStore.clearStore(); linkTo('/dashboard/profile'); }; diff --git a/src/profile/ProfileSettingsScreen.tsx b/src/profile/ProfileSettingsScreen.tsx index a7d4314..554cc02 100644 --- a/src/profile/ProfileSettingsScreen.tsx +++ b/src/profile/ProfileSettingsScreen.tsx @@ -16,12 +16,17 @@ import { useLinkTo } from '@react-navigation/native'; import { HeaderBackButton } from '@react-navigation/elements'; import ChevronLeftIcon from 'app/src/ui/icons/chevron-left'; import tw from 'twin.macro'; +import { UserEntriesStore } from '../stores/user-entries.store'; +import { LikesStore } from '../stores/likes.store'; const ProfileSettingsScreen = observer(() => { - let { likesStore, userEntriesStore, paymentsStore } = Stores(); + let { paymentsStore } = Stores(); + const { refreshLikes } = LikesStore(); + const { refreshEntries } = UserEntriesStore(); + useEffect(() => { - likesStore.refreshLikes(); - userEntriesStore.refreshEntries(); + refreshLikes(); + refreshEntries(); paymentsStore.refreshSubscription(); }); diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx index e5f5cad..9bdada9 100644 --- a/src/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -1,19 +1,14 @@ import { Provider } from 'mobx-react'; import React from 'react'; import { - sessionStore, signUpValidationStore, signInValidationStore, - usernameAndEmailValidationStore, playerStore, usersSearchStore, entriesSearchStore, inputSearchStore, profileStore, - editProfileStore, - likesStore, entryStore, - userEntriesStore, paymentsStore, walletConnectStore, } from 'app/src/stores'; @@ -21,19 +16,14 @@ import { export default function Providers(props) { return ( diff --git a/src/search/LikeOptionRow.tsx b/src/search/LikeOptionRow.tsx index 5f26481..41b42a0 100644 --- a/src/search/LikeOptionRow.tsx +++ b/src/search/LikeOptionRow.tsx @@ -1,22 +1,21 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import LikeIcon from 'app/src/ui/icons/like'; +import { LikesStore } from '../stores/likes.store'; -export default observer(({ entry, iconOnly = false, size = 24 }) => { - const { likesStore } = Stores(); +export default ({ entry, iconOnly = false, size = 24 }) => { + const { toggleLike, isEntryLiked } = LikesStore(); const { goBack } = useNavigation(); const handleToggle = async () => { - await likesStore.toggleLike(entry); + await toggleLike(entry); goBack(); }; const isLiked = () => { - return likesStore.isEntryLiked(entry); + return isEntryLiked(entry); }; if (!entry) { return null; @@ -46,7 +45,7 @@ export default observer(({ entry, iconOnly = false, size = 24 }) => { ); -}); +}; var styles = StyleSheet.create({ field: { diff --git a/src/search/PricingOptionsModal.tsx b/src/search/PricingOptionsModal.tsx index f6c223b..b24eb7d 100644 --- a/src/search/PricingOptionsModal.tsx +++ b/src/search/PricingOptionsModal.tsx @@ -17,11 +17,13 @@ import Slider from '@react-native-community/slider'; import DollarIcon from 'app/src/ui/icons/dollar'; import PieIcon from 'app/src/ui/icons/pie'; import CircleIcon from 'app/src/ui/icons/circle'; +import { UserEntriesStore } from '../stores/user-entries.store'; const SwitchWeb: any = Switch; export default observer(({ route }) => { - const { entryStore, userEntriesStore } = Stores(); + const { entryStore } = Stores(); + const { refreshEntries } = UserEntriesStore(); const { goBack } = useNavigation(); const { entry } = route.params; let equityForSaleValue = entryStore.equityForSale @@ -38,7 +40,7 @@ export default observer(({ route }) => { const handleUpdatePricing = async (entry: any) => { await entryStore.updatePricing(entry); - userEntriesStore.refreshEntries(); + refreshEntries(); goBack(); }; diff --git a/src/search/RemoveFromMyMusicRow.tsx b/src/search/RemoveFromMyMusicRow.tsx index 24aaf26..dbaf8a2 100644 --- a/src/search/RemoveFromMyMusicRow.tsx +++ b/src/search/RemoveFromMyMusicRow.tsx @@ -6,16 +6,18 @@ import Colors from 'app/src/constants/Colors'; import * as stores from 'app/src/stores'; import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; +import { UserEntriesStore } from '../stores/user-entries.store'; type Stores = typeof stores; export default observer(({ entry }) => { - const { userEntriesStore, entryStore } = Stores(); + const { entryStore } = Stores(); + const { refreshEntries } = UserEntriesStore(); const { goBack } = useNavigation(); const handleRemoveEntry = async () => { await entryStore.remove(entry.id); - await userEntriesStore.refreshEntries(); + await refreshEntries(); goBack(); }; if (!entry) { diff --git a/src/stores/edit-profile.store.ts b/src/stores/edit-profile.store.ts deleted file mode 100644 index b8ce712..0000000 --- a/src/stores/edit-profile.store.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { User } from '../models/user.model'; -import { observable, observe, action } from 'mobx'; -import { userBackend } from '../api/user'; -import { SessionStore } from './session.store'; -import { nftStorageApi, imagesGateway } from '../config/constants'; - -export class EditProfileStore { - @observable error: string | undefined | unknown; - @observable avatarUrl: string | undefined; - @observable displayName: string | undefined; - @observable description: string | undefined; - @observable username: string | undefined; - @observable email: string | undefined; - @observable profile: User | undefined; - @observable loadingAvatar: boolean | undefined; - disposer; - - constructor(public sessionStore: SessionStore) { - this.disposer = observe(sessionStore.session, ({ object }) => { - this.profile = object.user; - if (!this.profile) { - return; - } - let { - avatarUrl, - displayName, - description, - username, - email, - } = this.profile; - this.avatarUrl = avatarUrl; - this.displayName = displayName; - this.description = description; - this.username = username; - this.email = email; - }); - } - - async uploadProfilePhoto(image: any) { - const isPng = image.uri.startsWith('data:image/png'); - if (!isPng) { - this.error = 'Only png files supported!'; - return; - } - if (image.height !== image.width) { - return (this.error = 'Only square images supported!'); - } - const blobRes = await fetch(image.uri); - const file = await blobRes.blob(); - if (!this.sessionStore.user) return; - this.loadingAvatar = true; - let res = await fetch(`${nftStorageApi}/upload`, { - method: 'POST', - body: file, - headers: new Headers({ - Authorization: `Bearer ${process.env.NEXT_PUBLIC_NFT_STORAGE_API_KEY}`, - }), - }); - let { value, ok } = await res.json(); - - if (ok) { - this.updateAvatarUrl(`${imagesGateway}/${value.cid}`); - } - this.loadingAvatar = false; - } - - @action - updateAvatarUrl = (text: string) => { - this.avatarUrl = text; - }; - - @action - updateDisplayName = (text: string) => { - this.displayName = text; - }; - - @action - updateDescription = (text: string) => { - this.description = text; - }; - - @action - updateUsername = (text: string) => { - this.username = text; - }; - - @action - updateEmail = (text: string) => { - this.email = text; - }; - - get validationError() { - if (!this.avatarUrl) { - return 'Upload a profile picture.'; - } - - if (!this.displayName) { - return 'Add a display name.'; - } - - if (!this.description) { - return 'Add a description.'; - } - - if (!this.username) { - return 'Add a username.'; - } - - if (!this.email) { - return 'Add an email.'; - } - - return null; - } - - get canUpdate() { - return ( - this.avatarUrl && - this.displayName && - this.description && - this.username && - this.email - ); - } - - async updateProfile() { - let user; - try { - user = await userBackend.updateUser( - this.avatarUrl as string, - this.displayName as string, - this.description as string, - this.username as string, - this.email as string - ); - } catch (e) { - this.error = e; - return; - } - if (user) { - return await this.sessionStore.refreshUser(); - } - } -} diff --git a/src/stores/index.ts b/src/stores/index.ts index 570df98..3eb9a61 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,23 +1,16 @@ -import { SessionStore } from './session.store'; import { SignUpValidationStore } from './sign-up-validation.store'; import { SignInValidationStore } from './sign-in-validation.store'; -import { UsernameAndEmailValidationStore } from './username-and-email-validation.store'; import { PlayerStore } from './player.store'; import { InputSearchStore } from './input-search.store'; import { EntriesSearchStore } from './entries-search.store'; import { UsersSearchStore } from './users-search.store'; import { ProfileStore } from './profile.store'; -import { EditProfileStore } from './edit-profile.store'; -import { LikesStore } from './likes.store'; import { PaymentsStore } from './payments.store'; import { EntryStore } from './entry.store'; -import { UserEntriesStore } from './user-entries.store'; import { WalletConnectStore } from './wallet-connect.store'; -export const sessionStore = new SessionStore(); export const signUpValidationStore = new SignUpValidationStore(); export const signInValidationStore = new SignInValidationStore(); -export const usernameAndEmailValidationStore = new UsernameAndEmailValidationStore(); export const playerStore = new PlayerStore(); export const inputSearchStore = new InputSearchStore(); export const entriesSearchStore = new EntriesSearchStore( @@ -25,30 +18,19 @@ export const entriesSearchStore = new EntriesSearchStore( ); export const usersSearchStore = new UsersSearchStore(inputSearchStore.query); export const profileStore = new ProfileStore(); -export const editProfileStore = new EditProfileStore(sessionStore); -export const likesStore = new LikesStore( - playerStore.observables, - sessionStore.session -); export const paymentsStore = new PaymentsStore(); export const entryStore = new EntryStore(); -export const userEntriesStore = new UserEntriesStore(sessionStore); export const walletConnectStore = new WalletConnectStore(); export type Stores = { - sessionStore: SessionStore; signInValidationStore: SignInValidationStore; signUpValidationStore: SignUpValidationStore; - usernameAndEmailValidationStore: UsernameAndEmailValidationStore; playerStore: PlayerStore; inputSearchStore: InputSearchStore; entriesSearchStore: EntriesSearchStore; usersSearchStore: UsersSearchStore; profileStore: ProfileStore; - editProfileStore: EditProfileStore; - likesStore: LikesStore; paymentsStore: PaymentsStore; entryStore: EntryStore; - userEntriesStore: UserEntriesStore; walletConnectStore: WalletConnectStore; }; diff --git a/src/stores/likes.store.ts b/src/stores/likes.store.ts index 5d12d82..6a04151 100644 --- a/src/stores/likes.store.ts +++ b/src/stores/likes.store.ts @@ -1,154 +1,172 @@ -import { observable, observe, IObservableObject } from 'mobx'; +import { useRecoilValue } from 'recoil'; import * as L from 'list'; import { likesBackend } from '../api/likes'; +import { userAtom } from '../atoms/atoms'; import { Entry, User } from '../models'; -export class LikesStore { - @observable ids: Set = new Set([]); - @observable loading: boolean = false; - @observable loadingEntryLikes: boolean = false; - @observable entry!: Entry; - @observable entryLikes: L.List = L.from([]); - @observable entryLikesCount!: number; - @observable userLikes: L.List = L.from([]); - @observable userLikesCount!: number; - @observable user!: User; - - public viewLimit: number = 8; - disposer: any; - userDisposer: any; - - get hasMoreLikers(): boolean { - if (this.entryLikesCount > this.viewLimit) { +export const LikesStore = () => { + let ids: Set = new Set([]); + let loading: boolean = false; + let loadingEntryLikes: boolean = false; + let entry!: Entry; + let entryLikes: L.List = L.from([]); + let entryLikesCount!: number; + let userLikes: L.List = L.from([]); + let userLikesCount!: number; + + const user = useRecoilValue(userAtom); + + let viewLimit: number = 8; + let disposer: any; + let userDisposer: any; + + const hasMoreLikers = () => { + if (entryLikesCount > viewLimit) { return true; } return false; - } + }; - get plusLikers() { - return this.kFormatter(this.entryLikesCount - this.viewLimit); - } + const plusLikers = () => { + return kFormatter(entryLikesCount - viewLimit); + }; - kFormatter(num: number) { + const kFormatter = (num: number) => { return num > 999 ? (num / 1000).toFixed(1) + 'k' : num; - } - - constructor( - public observables: IObservableObject, - public session: IObservableObject - ) { - this.disposer = observe(observables, ({ object }) => { - if (!object.entry) { - return; - } - this.entry = object.entry; - this.refreshEntryLikes(this.entry.id); - }); - - this.userDisposer = observe(this.session, ({ object }) => { - this.user = object.user; - }); - } - - public clearLikes() { - this.entryLikes = L.from([]); - this.userLikes = L.from([]); - } - - public refreshEntryLikes(id: string) { - this.loadingEntryLikes = true; + }; + + // TODO: wire up effects + // constructor( + // public observables: IObservableObject, + // public session: IObservableObject + // ) { + // this.disposer = observe(observables, ({ object }) => { + // if (!object.entry) { + // return; + // } + // this.entry = object.entry; + // this.refreshEntryLikes(this.entry.id); + // }); + + // this.userDisposer = observe(this.session, ({ object }) => { + // this.user = object.user; + // }); + // } + + const clearLikes = () => { + entryLikes = L.from([]); + userLikes = L.from([]); + }; + + const refreshEntryLikes = (id: string) => { + loadingEntryLikes = true; likesBackend.entryLikes(id).then((payload) => { if (payload) { - this.entryLikesCount = payload.count; + entryLikesCount = payload.count; let users = payload.users.map( (userPayload: any) => new User(userPayload) ); - this.entryLikes = L.from(users); + entryLikes = L.from(users); } - this.loadingEntryLikes = false; + loadingEntryLikes = false; }); - } + }; - public refreshLikes() { - this.loading = true; + const refreshLikes = () => { + loading = true; likesBackend.userLikes().then((userLikes) => { if (!userLikes) { return; } else { let ids = userLikes.map((like: any) => like.id); let entries = userLikes.map((like: any) => new Entry(like)); - this.ids = new Set(ids); - this.userLikes = L.from(entries); - this.userLikesCount = this.userLikes.length; + ids = new Set(ids); + userLikes = L.from(entries); + userLikesCount = userLikes.length; } - this.loading = false; + loading = false; }); - } + }; - async unlike(entry: Entry) { - this.ids.delete(entry.id); + const unlike = async (entry: Entry) => { + ids.delete(entry.id); let index = L.findIndex((like) => { if (like) { return like.id === entry.id; } return false; - }, this.userLikes); - this.userLikes = L.remove(index, 1, this.userLikes); + }, userLikes); + userLikes = L.remove(index, 1, userLikes); let unliked = await likesBackend.like(entry.id, false); if (!unliked) { - this.ids = this.ids.add(entry.id); - this.userLikes = L.append(entry, this.userLikes); + ids = ids.add(entry.id); + userLikes = L.append(entry, userLikes); } - this.userLikesCount = this.userLikes.length; + userLikesCount = userLikes.length; let userIndex = L.findIndex((like) => { if (like) { - return like.id === this.user.id; + return like.id === user?.id; } return false; - }, this.entryLikes); - this.entryLikes = L.remove(userIndex, 1, this.entryLikes); - } - - async like(entry: Entry) { - this.ids = this.ids.add(entry.id); - this.userLikes = L.append(entry, this.userLikes); + }, entryLikes); + entryLikes = L.remove(userIndex, 1, entryLikes); + }; + + const like = async (entry: Entry) => { + if (!user) return; + ids = ids.add(entry.id); + userLikes = L.append(entry, userLikes); let liked = await likesBackend.like(entry.id); if (!liked) { - this.ids.delete(entry.id); + ids.delete(entry.id); let index = L.findIndex((like) => { if (like) { return like.id === entry.id; } return false; - }, this.userLikes); - this.userLikes = L.remove(index, 1, this.userLikes); + }, userLikes); + userLikes = L.remove(index, 1, userLikes); } - this.userLikesCount = this.userLikes.length; + userLikesCount = userLikes.length; - this.entryLikes = L.append(this.user, this.entryLikes); - } + entryLikes = L.append(user, entryLikes); + }; - public toggleLike(entry: Entry) { - if (this.isEntryLiked(entry)) { - return this.unlike(entry); + const toggleLike = (entry: Entry) => { + if (isEntryLiked(entry)) { + return unlike(entry); } - return this.like(entry); - } + return like(entry); + }; - get isLiked() { - if (!this.entry) { + const isLiked = () => { + if (!entry) { return false; } - return this.ids.has(this.entry.id); - } + return ids.has(entry.id); + }; - isEntryLiked(entry: Entry) { + const isEntryLiked = (entry: Entry) => { if (!entry) { return false; } - return this.ids.has(entry.id); - } -} + return ids.has(entry.id); + }; + + return { + toggleLike, + isLiked, + entryLikes, + hasMoreLikers, + plusLikers, + userLikes, + userLikesCount, + loading, + refreshLikes, + isEntryLiked, + clearLikes, + }; +}; diff --git a/src/stores/session.store.ts b/src/stores/session.store.ts deleted file mode 100644 index a982848..0000000 --- a/src/stores/session.store.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { observable, computed, IObservableObject } from 'mobx'; -import { User } from '../models'; -import { userBackend } from '../api/user'; -import { SignUpForm } from '../types'; -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { userDataKey } from '../config/constants'; - -export class SessionStore { - public session: { user: User | null } & IObservableObject = observable({ - user: null, - }); - @computed - get user() { - return this.session.user; - } - constructor() {} - - async signUp(signUp: SignUpForm) { - let userPayload = await userBackend.signUp(signUp); - await this.setUser(userPayload); - return (this.session.user = new User(userPayload)); - } - - async requestToken(usernameOrEmail: string, publicKey: string) { - await userBackend.requestToken(usernameOrEmail, publicKey); - return; - } - - async signIn(token?: string, uid?: string, xdr = '') { - let userPayload = await userBackend.signIn(token, uid, xdr); - if (userPayload) { - await this.setUser(userPayload); - return (this.session.user = new User(userPayload)); - } - return null; - } - - async setUser(value: any) { - value = JSON.stringify(value); - if (value) return AsyncStorage.setItem(userDataKey, value); - else console.info('not set, stringify failed:', userDataKey, value); - } - - // public forceSignOutDisposer = observe(forceSignOut, ({ object }) => { - // if (object.value) { - // this.signOut(); - // } - // }); - - async signOut() { - this.session.user = null; - return await AsyncStorage.removeItem(userDataKey); - } - - async loadSession() { - return await this.loadFromStorage(); - } - - async loadFromStorage() { - try { - let userPayload = await AsyncStorage.getItem(userDataKey); - if (userPayload) { - this.session.user = new User(JSON.parse(userPayload)); - return this.session.user; - } - } catch (e) { - console.info(e); - } - - return await this.signOut(); - } - - async refreshUser() { - if (!this.session.user) { - return await this.signOut(); - } - try { - let userPayload = await userBackend.getAuthenticatedUser(); - if (userPayload) { - let userPayloadClone = Object.assign({}, userPayload); - userPayloadClone.jwt = this.session.user.jwt; - await this.setUser(userPayloadClone); - this.session.user = new User(userPayloadClone); - return this.session.user; - } - } catch (e) { - console.info(e); - } - return await this.signOut(); - } -} diff --git a/src/stores/session.ts b/src/stores/session.ts new file mode 100644 index 0000000..94c612e --- /dev/null +++ b/src/stores/session.ts @@ -0,0 +1,54 @@ +import { User } from '../models'; +import { + getAuthenticatedUser, + requestToken, + signIn as sendSignIn, + signUp as sendSignUp, +} from '../api/user'; +import { SignUpForm } from '../types'; +import { userAtom } from '../atoms/atoms'; +import { useRecoilState } from 'recoil'; + +export const SessionStore = () => { + const [user, setUser] = useRecoilState(userAtom); + + async function signUp(payload: SignUpForm) { + let userPayload = await sendSignUp(payload); + return setUser(new User(userPayload)); + } + + async function signIn(token?: string, uid?: string, xdr = '') { + let userPayload = await sendSignIn(token, uid, xdr); + if (userPayload) { + return setUser(new User(userPayload)); + } + return null; + } + + // public forceSignOutDisposer = observe(forceSignOut, ({ object }) => { + // if (object.value) { + // this.signOut(); + // } + // }); + + async function signOut() { + return setUser(null); + } + + async function refreshUser() { + try { + let userPayload = await getAuthenticatedUser(); + if (userPayload) { + let userPayloadClone = Object.assign({}, userPayload); + userPayloadClone.jwt = user?.jwt; + setUser(new User(userPayloadClone)); + return user; + } + } catch (e) { + console.info(e); + } + return await signOut(); + } + + return { requestToken, signUp, signIn, signOut, refreshUser }; +}; diff --git a/src/stores/sign-in-validation.store.ts b/src/stores/sign-in-validation.store.ts index 8763dea..89bbeb0 100644 --- a/src/stores/sign-in-validation.store.ts +++ b/src/stores/sign-in-validation.store.ts @@ -46,7 +46,6 @@ export class SignInValidationStore { } setBackendError(error: string) { - debugger; this.backendError = error; } } diff --git a/src/stores/user-entries.store.ts b/src/stores/user-entries.store.ts index 891518c..328a38b 100644 --- a/src/stores/user-entries.store.ts +++ b/src/stores/user-entries.store.ts @@ -1,30 +1,27 @@ -import { observable } from 'mobx'; import * as L from 'list'; import { entriesBackend } from '../api/entries'; import { Entry } from '../models'; -import { SessionStore } from './session.store'; +import { userAtom } from '../atoms/atoms'; +import { useRecoilValue } from 'recoil'; -export class UserEntriesStore { - @observable entries: L.List = L.from([]); - @observable loading: boolean = false; +export const UserEntriesStore = () => { + const user = useRecoilValue(userAtom); - constructor(private sessionStore: SessionStore) {} + let entries: L.List = L.from([]); + let loading: boolean = false; - public async refreshEntries() { - if (!this.sessionStore.user) { + const refreshEntries = async () => { + if (!user) { return; } - if (!this.sessionStore.user.id) { + if (!user.id) { return; } - this.loading = true; + loading = true; - const entries = await entriesBackend.getByUserId(this.sessionStore.user.id); - this.loading = false; - this.entries = L.from(entries ? entries : []); - } - - get entriesCount() { - return this.entries ? this.entries.length : 0; - } -} + const res = await entriesBackend.getByUserId(user.id); + loading = false; + entries = L.from(res ? res : []); + }; + return { entries, loading, refreshEntries }; +}; diff --git a/src/stores/username-and-email-validation.store.ts b/src/stores/username-and-email-validation.store.ts deleted file mode 100644 index 457366c..0000000 --- a/src/stores/username-and-email-validation.store.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { observable, computed } from 'mobx'; - -export class UsernameAndEmailValidationStore { - @observable usernameError: string = ''; - @observable usernameValid: boolean = true; - @observable emailError: string = ''; - @observable emailValid: boolean = true; - @observable backendError: string = ''; - - constructor() {} - - validateUsername(username: string) { - if (!username) { - this.usernameValid = false; - this.usernameError = 'Username is required.'; - return; - } - - if (username.length < 2) { - this.usernameValid = false; - this.usernameError = 'Username is minimum 2 characters.'; - return; - } - - let validRegex = /^[a-zA-Z0-9_-]+$/.test(username); - if (!validRegex) { - this.usernameValid = false; - this.usernameError = - 'Usernames cannot have spaces or special characters.'; - return; - } - - this.usernameError = ''; - return (this.usernameValid = true); - } - - validateEmail(email: string) { - if (!email) { - this.emailValid = false; - this.emailError = 'Email is required.'; - return; - } - - var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - if (!re.test(email)) { - this.emailValid = false; - this.emailError = 'Please enter a valid email.'; - return; - } - - this.emailError = ''; - return (this.emailValid = true); - } - - @computed - get error() { - if (this.usernameError) { - return this.usernameError; - } - - if (this.emailError) { - return this.emailError; - } - - if (this.backendError) { - return this.backendError; - } - - return null; - } - - @computed - get validForm() { - return this.usernameValid && this.emailValid; - } - - setBackendError(error: string) { - this.backendError = error; - } -} diff --git a/src/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx index 5b30044..732be11 100644 --- a/src/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -6,6 +6,7 @@ import { observer } from 'mobx-react'; import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; +import { UserEntriesStore } from '../stores/user-entries.store'; export default observer(({ route }) => { const { entry, priceInfo } = route.params; @@ -19,11 +20,11 @@ export default observer(({ route }) => { const { paymentsStore, - userEntriesStore, entriesSearchStore, playerStore, walletConnectStore, } = Stores(); + const { refreshEntries } = UserEntriesStore(); const buyEntry = async (id: string) => { setSubmitting(true); @@ -39,7 +40,7 @@ export default observer(({ route }) => { await walletConnectStore.signAndSubmitXdr(xdr); } await Promise.all([ - await userEntriesStore.refreshEntries(), + await refreshEntries(), await entriesSearchStore.getRecentSearches(), await paymentsStore.refreshSubscription(), ]); diff --git a/src/ui/DoneEditBtn.tsx b/src/ui/DoneEditBtn.tsx index 81d3dce..a1132da 100644 --- a/src/ui/DoneEditBtn.tsx +++ b/src/ui/DoneEditBtn.tsx @@ -2,35 +2,60 @@ import React from 'react'; import { Pressable, StyleSheet, Text } from 'react-native'; import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; -import { Stores } from 'app/src/functions/Stores'; -import { observer } from 'mobx-react'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { updateUser } from '../api/user'; +import { SessionStore } from '../stores/session'; +import { canUpdateProfileAtom, profileAtom } from '../atoms/atoms'; +import { useRecoilState, useRecoilValue } from 'recoil'; -const DoneEditBtn = observer(() => { +const DoneEditBtn = () => { const linkTo = useLinkTo(); - const { editProfileStore } = Stores(); + + const [ + { avatarUrl, displayName, description, username, email }, + setEditProfile, + ] = useRecoilState(profileAtom); + + const canUpdate = useRecoilValue(canUpdateProfileAtom); + const { refreshUser } = SessionStore(); + + const updateProfile = async () => { + let user; + try { + user = await updateUser( + avatarUrl as string, + displayName as string, + description as string, + username as string, + email as string + ); + } catch (e) { + setEditProfile((oldState) => ({ + ...oldState, + uploadError: (e as any).toString(), + })); + return; + } + if (user) { + return await refreshUser(); + } + }; const closeProfileModal = () => { - editProfileStore.updateProfile(); + updateProfile(); linkTo('/dashboard/profile'); }; + return ( - - Done - + Done ); -}); +}; export default DoneEditBtn; diff --git a/src/ui/LogOutBtn.tsx b/src/ui/LogOutBtn.tsx index dd64a96..ba2c1d6 100644 --- a/src/ui/LogOutBtn.tsx +++ b/src/ui/LogOutBtn.tsx @@ -5,16 +5,22 @@ import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; import LogOutIcon from 'app/src/ui/icons/logout'; import { useLinkTo } from '@react-navigation/native'; +import { LikesStore } from '../stores/likes.store'; +import { SessionStore } from '../stores/session'; export default observer(() => { const linkTo = useLinkTo(); - const { sessionStore, likesStore, walletConnectStore } = Stores(); + const { walletConnectStore } = Stores(); + const { signOut } = SessionStore(); + const { clearLikes } = LikesStore(); + const handleLogOut = async () => { await walletConnectStore.disconnect(); - await sessionStore.signOut(); + await signOut(); linkTo('/'); - likesStore.clearLikes(); + clearLikes(); }; + return ( From c8784e5824583dd50321e7beef8f45ec5e088993 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Thu, 30 Jun 2022 15:41:36 -0500 Subject: [PATCH 03/13] move validation inside of components --- src/accounts/SignInScreen.tsx | 57 ++++++++----- src/accounts/SignUpScreen.tsx | 107 ++++++++++++++++++----- src/atoms/atoms.ts | 112 +++++++++++++++++++++++++ src/providers/Providers.tsx | 4 - src/stores/index.ts | 6 -- src/stores/sign-in-validation.store.ts | 51 ----------- src/stores/sign-up-validation.store.ts | 103 ----------------------- 7 files changed, 234 insertions(+), 206 deletions(-) delete mode 100644 src/stores/sign-in-validation.store.ts delete mode 100644 src/stores/sign-up-validation.store.ts diff --git a/src/accounts/SignInScreen.tsx b/src/accounts/SignInScreen.tsx index a668ce2..f1a8e54 100644 --- a/src/accounts/SignInScreen.tsx +++ b/src/accounts/SignInScreen.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect } from 'react'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import { StyleSheet, @@ -10,7 +9,6 @@ import { ActivityIndicator, Platform, } from 'react-native'; -import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; import BackgroundImage from 'app/src/ui/BackgroundImage'; import cursorPointer from 'app/src/constants/CursorPointer'; @@ -21,10 +19,23 @@ import * as Device from 'expo-device'; import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; import { SessionStore } from '../stores/session'; +import { + usernameOrEmailValidationErrorAtom, + usernameOrEmailBackendErrorAtom, + usernameOrEmailErrorAtom, + usernameOrEmailValidAtom, +} from 'app/src/atoms/atoms'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; -export default observer(({ route, navigation }) => { - const { signInValidationStore } = Stores(); +export default ({ route, navigation }) => { const { requestToken, signIn } = SessionStore(); + const setValidationError = useSetRecoilState( + usernameOrEmailValidationErrorAtom + ); + const setBackendError = useSetRecoilState(usernameOrEmailBackendErrorAtom); + const error = useRecoilValue(usernameOrEmailErrorAtom); + const validForm = useRecoilValue(usernameOrEmailValidAtom); + const [usernameOrEmail, setUsernameOrEmail] = useState(''); const [loading, setLoading] = useState(false); const [showEmailLink, setShowEmailLink] = useState(false); @@ -40,7 +51,7 @@ export default observer(({ route, navigation }) => { setShowEmailLink(true); return; } catch (e) { - signInValidationStore.setBackendError(e as any); + setBackendError(e as any); } return setLoading(false); }; @@ -53,7 +64,7 @@ export default observer(({ route, navigation }) => { setLoading(false); return; } catch (e) { - signInValidationStore.setBackendError(e as any); + setBackendError(e as any); linkTo('/accounts/sign-up'); } return setLoading(false); @@ -63,9 +74,23 @@ export default observer(({ route, navigation }) => { openEmail(); }; + const validateUsernameOrEmail = (usernameOrEmail: string) => { + if (!usernameOrEmail) { + setValidationError('Username is required.'); + return; + } + + if (usernameOrEmail.length < 2) { + setValidationError('Enter a valid username or email.'); + return; + } + + setValidationError(''); + }; + const updateUsernameOrEmail = ({ target }: any) => { setUsernameOrEmail(target.value); - signInValidationStore.validateUsernameOrEmail(target.value); + validateUsernameOrEmail(target.value); }; const onSubmit = (e) => { @@ -170,23 +195,15 @@ export default observer(({ route, navigation }) => { /> - - {signInValidationStore.error} + + {error} {loading ? ( { )} ); -}); +}; let styles = StyleSheet.create({ line: { diff --git a/src/accounts/SignUpScreen.tsx b/src/accounts/SignUpScreen.tsx index 6fb8dab..c8200fe 100644 --- a/src/accounts/SignUpScreen.tsx +++ b/src/accounts/SignUpScreen.tsx @@ -8,6 +8,7 @@ import { ActivityIndicator, Platform, } from 'react-native'; +import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil'; import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; @@ -17,10 +18,31 @@ import BackgroundImage from 'app/src/ui/BackgroundImage'; import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; import { SessionStore } from '../stores/session'; +import { + displayNameValidationErrorAtom, + emailValidationErrorAtom, + signUpBackendErrorAtom, + usernameValidationErrorAtom, + signUpValidAtom, + signUpErrorAtom, +} from '../atoms/atoms'; export default observer(() => { - const { signUpValidationStore, walletConnectStore } = Stores(); + const { walletConnectStore } = Stores(); const { signUp } = SessionStore(); + const [usernameValidation, setUsernameValidation] = useRecoilState( + usernameValidationErrorAtom + ); + const [displayNameValidation, setDisplayNameValidation] = useRecoilState( + displayNameValidationErrorAtom + ); + const [emailValidation, setEmailValidation] = useRecoilState( + emailValidationErrorAtom + ); + + const setBackendError = useSetRecoilState(signUpBackendErrorAtom); + const validForm = useRecoilValue(signUpValidAtom); + const error = useRecoilValue(signUpErrorAtom); const [username, setUsername] = useState(''); const [displayName, setDisplayName] = useState(''); @@ -28,19 +50,70 @@ export default observer(() => { const [loading, setLoading] = useState(false); const linkTo = useLinkTo(); + const validateUsername = (username: string) => { + if (!username) { + setUsernameValidation('Username is required.'); + return; + } + + if (username.length < 2) { + setUsernameValidation('Username is minimum 2 characters.'); + return; + } + + let validRegex = /^[a-zA-Z0-9_-]+$/.test(username); + if (!validRegex) { + setUsernameValidation( + 'Usernames cannot have spaces or special characters.' + ); + return; + } + + setUsernameValidation(''); + }; + const updateUsername = ({ target }: any) => { setUsername(target.value); - signUpValidationStore.validateUsername(target.value); + validateUsername(target.value); + }; + + const validateDisplayName = (displayName: string) => { + if (!displayName) { + setDisplayNameValidation('Display name is required.'); + return; + } + + if (displayName.length < 2) { + setDisplayNameValidation('Display name is minimum 2 characters.'); + return; + } + + setDisplayNameValidation(''); + }; + + const validateEmail = (email: string) => { + if (!email) { + setEmailValidation('Email is required.'); + return; + } + + var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + if (!re.test(email)) { + setEmailValidation('Please enter a valid email.'); + return; + } + + setEmailValidation(''); }; const updateDisplayName = ({ target }: any) => { setDisplayName(target.value); - signUpValidationStore.validateDisplayName(target.value); + validateDisplayName(target.value); }; const updateEmail = ({ target }: any) => { setEmail(target.value); - signUpValidationStore.validateEmail(target.value); + validateEmail(target.value); }; const handleSignUp = async () => { @@ -56,7 +129,7 @@ export default observer(() => { return linkTo('/'); } catch (e) { if (typeof e === 'string') { - signUpValidationStore.setBackendError(e); + setBackendError(e); } } return setLoading(false); @@ -91,7 +164,7 @@ export default observer(() => { onChange={updateUsername} maxLength={30} /> - + { } maxLength={30} /> - + { maxLength={34} onKeyPress={onSubmit} /> - + - - {signUpValidationStore.error} + + {error} {loading ? ( ({ ); }, }); + +export const usernameValidationErrorAtom = atom({ + key: 'usernameValidationError', + default: '', +}); + +export const displayNameValidationErrorAtom = atom({ + key: 'displayNameValidationError', + default: '', +}); + +export const emailValidationErrorAtom = atom({ + key: 'emailValidationError', + default: '', +}); + +export const usernameOrEmailValidationErrorAtom = atom({ + key: 'usernameOrEmailValidationError', + default: '', +}); + +export const usernameOrEmailBackendErrorAtom = atom({ + key: 'usernameOrEmailBackendError', + default: '', +}); + +export const signUpBackendErrorAtom = atom({ + key: 'signUpBackendError', + default: '', +}); + +export const usernameOrEmailErrorAtom = selector({ + key: 'usernameOrEmailError', + get: ({ get }) => { + const usernameOrEmailBackendError = get(usernameOrEmailBackendErrorAtom); + const usernameOrEmailValidationError = get( + usernameOrEmailValidationErrorAtom + ); + + if (usernameOrEmailValidationError) { + return usernameOrEmailValidationError; + } + + if (usernameOrEmailBackendError) { + return usernameOrEmailBackendError; + } + + return ''; + }, +}); + +export const usernameOrEmailValidAtom = selector({ + key: 'usernameOrEmailValid', + get: ({ get }) => { + const usernameOrEmailError = get(usernameOrEmailValidationErrorAtom); + + if (usernameOrEmailError) { + return false; + } + + return true; + }, +}); + +export const signUpValidAtom = selector({ + key: 'signUpValid', + get: ({ get }) => { + const usernameValid = get(usernameValidationErrorAtom); + const displayNameValid = get(displayNameValidationErrorAtom); + const emailValid = get(emailValidationErrorAtom); + + if (usernameValid) { + return false; + } + if (displayNameValid) { + return false; + } + if (emailValid) { + return false; + } + + return true; + }, +}); + +export const signUpErrorAtom = selector({ + key: 'signUpError', + get: ({ get }) => { + const usernameValidationError = get(usernameValidationErrorAtom); + const displayNameValidationError = get(displayNameValidationErrorAtom); + const emailValidationError = get(emailValidationErrorAtom); + const signUpBackendError = get(signUpBackendErrorAtom); + + if (usernameValidationError) { + return usernameValidationError; + } + + if (displayNameValidationError) { + return displayNameValidationError; + } + + if (emailValidationError) { + return emailValidationError; + } + + if (signUpBackendError) { + return signUpBackendError; + } + + return ''; + }, +}); diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx index 9bdada9..269da46 100644 --- a/src/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -1,8 +1,6 @@ import { Provider } from 'mobx-react'; import React from 'react'; import { - signUpValidationStore, - signInValidationStore, playerStore, usersSearchStore, entriesSearchStore, @@ -16,8 +14,6 @@ import { export default function Providers(props) { return ( ()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - if (!re.test(email)) { - this.emailValid = false; - this.emailError = 'Please enter a valid email.'; - return; - } - - this.emailError = ''; - return (this.emailValid = true); - } - - @computed - get error() { - if (this.usernameError) { - return this.usernameError; - } - - if (this.displayNameError) { - return this.displayNameError; - } - - if (this.emailError) { - return this.emailError; - } - - if (this.backendError) { - return this.backendError; - } - - return null; - } - - @computed - get validForm() { - return this.usernameValid && this.displayNameValid && this.emailValid; - } - - setBackendError(error: string) { - this.backendError = error; - } -} From 5ea14fb98a8a568dad09058607d9e8e7b2bc1d9a Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Fri, 1 Jul 2022 11:06:45 -0500 Subject: [PATCH 04/13] migrate search --- src/player/player-screen/like-btn/LikeBtn.tsx | 2 +- .../likers-section/LikersSection.tsx | 2 +- src/playlists/CollectionScreen.tsx | 2 +- src/playlists/LikesRow.tsx | 2 +- src/playlists/LikesScreen.tsx | 2 +- src/playlists/MyMusicRow.tsx | 2 +- src/profile/MediaUpload.tsx | 2 +- src/profile/ProfileEntryListView.tsx | 33 ++- src/profile/ProfileSettingsScreen.tsx | 4 +- src/profile/ProfileTopContainer.tsx | 40 ++-- src/providers/Providers.tsx | 8 - src/search/ChartsView.tsx | 23 +- src/search/LikeOptionRow.tsx | 2 +- src/search/PricingOptionsModal.tsx | 2 +- src/search/RecentlyAdded.tsx | 25 ++- src/search/RemoveFromMyMusicRow.tsx | 2 +- src/search/SearchEntryList.tsx | 58 ++--- src/search/SearchEntryView.tsx | 17 +- src/search/SearchHeader.tsx | 74 +++---- src/search/SearchUserList.tsx | 36 ++- src/search/SearchUserView.tsx | 16 +- src/search/TopRecentUserView.tsx | 24 -- src/search/TopUserSearchView.tsx | 48 ---- src/stores/entries-search.store.ts | 116 ---------- src/stores/index.ts | 14 -- src/stores/input-search.store.ts | 18 -- src/stores/{likes.store.ts => likes.ts} | 0 src/stores/profile.store.ts | 30 --- src/stores/profile.ts | 50 +++++ src/stores/search.ts | 205 ++++++++++++++++++ ...{user-entries.store.ts => user-entries.ts} | 0 src/stores/users-search.store.ts | 66 ------ src/ui/BuyOptionsModal.tsx | 10 +- src/ui/LogOutBtn.tsx | 2 +- src/ui/UserRow.tsx | 6 +- 35 files changed, 419 insertions(+), 524 deletions(-) delete mode 100644 src/search/TopRecentUserView.tsx delete mode 100644 src/search/TopUserSearchView.tsx delete mode 100644 src/stores/entries-search.store.ts delete mode 100644 src/stores/input-search.store.ts rename src/stores/{likes.store.ts => likes.ts} (100%) delete mode 100644 src/stores/profile.store.ts create mode 100644 src/stores/profile.ts create mode 100644 src/stores/search.ts rename src/stores/{user-entries.store.ts => user-entries.ts} (100%) delete mode 100644 src/stores/users-search.store.ts diff --git a/src/player/player-screen/like-btn/LikeBtn.tsx b/src/player/player-screen/like-btn/LikeBtn.tsx index e824370..ef37a69 100644 --- a/src/player/player-screen/like-btn/LikeBtn.tsx +++ b/src/player/player-screen/like-btn/LikeBtn.tsx @@ -3,7 +3,7 @@ import { StyleSheet, Pressable } from 'react-native'; import LikeIcon from 'app/src/ui/icons/like'; import Colors from 'app/src/constants/Colors'; import cursorPointer from 'app/src/constants/CursorPointer'; -import { LikesStore } from 'app/src/stores/likes.store'; +import { LikesStore } from 'app/src/stores/likes'; export default (props) => { const { toggleLike, isLiked } = LikesStore(); diff --git a/src/player/player-screen/likers-section/LikersSection.tsx b/src/player/player-screen/likers-section/LikersSection.tsx index 8adf293..8ecda01 100644 --- a/src/player/player-screen/likers-section/LikersSection.tsx +++ b/src/player/player-screen/likers-section/LikersSection.tsx @@ -4,7 +4,7 @@ import LikeBtn from 'app/src/player/player-screen/like-btn/LikeBtn'; import Divider from 'app/src/ui/Divider'; import { UserAvatar } from 'app/src/ui/UserAvatar'; import * as L from 'list'; -import { LikesStore } from 'app/src/stores/likes.store'; +import { LikesStore } from 'app/src/stores/likes'; export default () => { const { entryLikes, hasMoreLikers, plusLikers } = LikesStore(); diff --git a/src/playlists/CollectionScreen.tsx b/src/playlists/CollectionScreen.tsx index bb715c3..f7655ed 100644 --- a/src/playlists/CollectionScreen.tsx +++ b/src/playlists/CollectionScreen.tsx @@ -6,7 +6,7 @@ import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -import { UserEntriesStore } from '../stores/user-entries.store'; +import { UserEntriesStore } from '../stores/user-entries'; export default () => { const { entries, loading } = UserEntriesStore(); diff --git a/src/playlists/LikesRow.tsx b/src/playlists/LikesRow.tsx index 8d96bff..0e10e28 100644 --- a/src/playlists/LikesRow.tsx +++ b/src/playlists/LikesRow.tsx @@ -7,7 +7,7 @@ import { observer } from 'mobx-react'; import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; -import { LikesStore } from '../stores/likes.store'; +import { LikesStore } from '../stores/likes'; export default observer(() => { let { playerStore } = Stores(); diff --git a/src/playlists/LikesScreen.tsx b/src/playlists/LikesScreen.tsx index 489870a..2e7b719 100644 --- a/src/playlists/LikesScreen.tsx +++ b/src/playlists/LikesScreen.tsx @@ -6,7 +6,7 @@ import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -import { LikesStore } from '../stores/likes.store'; +import { LikesStore } from '../stores/likes'; export default () => { const { userLikes, loading } = LikesStore(); diff --git a/src/playlists/MyMusicRow.tsx b/src/playlists/MyMusicRow.tsx index 8cea708..41660fc 100644 --- a/src/playlists/MyMusicRow.tsx +++ b/src/playlists/MyMusicRow.tsx @@ -5,7 +5,7 @@ import { useLinkTo } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import ChevronRightIcon from 'app/src/ui/icons/chevron-right'; import StarBorderIcon from 'app/src/ui/icons/star-border'; -import { UserEntriesStore } from '../stores/user-entries.store'; +import { UserEntriesStore } from '../stores/user-entries'; export default () => { let { entries } = UserEntriesStore(); diff --git a/src/profile/MediaUpload.tsx b/src/profile/MediaUpload.tsx index 8f2343e..50229dc 100644 --- a/src/profile/MediaUpload.tsx +++ b/src/profile/MediaUpload.tsx @@ -28,7 +28,7 @@ import UploadIcon from 'app/src/ui/icons/upload'; import CheckIcon from 'app/src/ui/icons/check'; import CloseIcon from 'app/src/ui/icons/x'; import nftListener from 'app/src/hooks/nft-listener'; -import { UserEntriesStore } from '../stores/user-entries.store'; +import { UserEntriesStore } from '../stores/user-entries'; const SwitchWeb: any = Switch; diff --git a/src/profile/ProfileEntryListView.tsx b/src/profile/ProfileEntryListView.tsx index 4bf2bb0..a315cd2 100644 --- a/src/profile/ProfileEntryListView.tsx +++ b/src/profile/ProfileEntryListView.tsx @@ -1,23 +1,19 @@ import React from 'react'; import { ScrollView } from 'react-native'; -import { inject } from 'mobx-react'; import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as L from 'list'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; +import ProfileStore from '../stores/profile'; -const ProfileEntryListView = inject((stores: Stores) => ({ - loadAndPlay: stores.playerStore.loadAndPlay.bind(stores.playerStore), - entries: stores.profileStore.entries, - loading: stores.profileStore.loadingEntries, -}))(({ loadAndPlay, entries, loading }: any) => ( - - {SearchingLoader(loading)} - {L.map( - (entry: any) => ( +const ProfileEntryListView = () => { + const { profileEntries, loadingEntries } = ProfileStore(); + const loadAndPlay = () => {}; + + return ( + + {SearchingLoader(loadingEntries)} + {profileEntries.map((entry: any) => ( ({ options={null} previousScreen={null} /> - ), - entries - )} - - -)); + ))} + + + ); +}; export default ProfileEntryListView; diff --git a/src/profile/ProfileSettingsScreen.tsx b/src/profile/ProfileSettingsScreen.tsx index 554cc02..6ea53d1 100644 --- a/src/profile/ProfileSettingsScreen.tsx +++ b/src/profile/ProfileSettingsScreen.tsx @@ -16,8 +16,8 @@ import { useLinkTo } from '@react-navigation/native'; import { HeaderBackButton } from '@react-navigation/elements'; import ChevronLeftIcon from 'app/src/ui/icons/chevron-left'; import tw from 'twin.macro'; -import { UserEntriesStore } from '../stores/user-entries.store'; -import { LikesStore } from '../stores/likes.store'; +import { UserEntriesStore } from '../stores/user-entries'; +import { LikesStore } from '../stores/likes'; const ProfileSettingsScreen = observer(() => { let { paymentsStore } = Stores(); diff --git a/src/profile/ProfileTopContainer.tsx b/src/profile/ProfileTopContainer.tsx index 7f9bc19..b45b75e 100644 --- a/src/profile/ProfileTopContainer.tsx +++ b/src/profile/ProfileTopContainer.tsx @@ -2,39 +2,33 @@ import React from 'react'; import { View, StyleSheet, Text } from 'react-native'; import Colors from 'app/src/constants/Colors'; import { UserAvatarMedium } from 'app/src/ui/UserAvatar'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; +import ProfileStore from '../stores/profile'; -export default observer((props) => { - const { profileStore } = Stores(); +export default (props) => { + const { user } = ProfileStore(); - const renderBlurSection = () => { - return ( + if (!user) { + return null; + } + let source; + if (user.avatarUrl) { + source = { uri: user.avatarUrl }; + } + return ( + - {UserAvatarMedium(profileStore.user)} + {UserAvatarMedium(user)} - {profileStore.user.displayName} + {user.displayName} - ); - }; - - if (!profileStore.user) { - return null; - } - let source; - if (profileStore.user.avatarUrl) { - source = { uri: profileStore.user.avatarUrl }; - } - if (source) { - return {renderBlurSection()}; - } - return {renderBlurSection()}; -}); + + ); +}; const styles = StyleSheet.create({ container: { diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx index 269da46..14d360e 100644 --- a/src/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -2,10 +2,6 @@ import { Provider } from 'mobx-react'; import React from 'react'; import { playerStore, - usersSearchStore, - entriesSearchStore, - inputSearchStore, - profileStore, entryStore, paymentsStore, walletConnectStore, @@ -15,10 +11,6 @@ export default function Providers(props) { return ( { - const { playerStore, entriesSearchStore } = Stores(); + const { playerStore } = Stores(); + const { + topChart, + hasMoreTopChart, + loadMoreTopChart, + loadingTopChart, + } = SearchStore(); const [page, setPage] = useState(0); const renderItem = (item, index) => { return ( @@ -19,7 +26,7 @@ export default observer((props) => { entry={item} options={null} disablePlaylistMode={() => - playerStore.setPlaylistModeFromArray(entriesSearchStore.topChart) + playerStore.setPlaylistModeFromArray(topChart) } previousScreen={null} position={index + 1} @@ -32,17 +39,17 @@ export default observer((props) => { }, []); const handleLoadMore = () => { - if (!entriesSearchStore.hasMoreTopChart) return; + if (!hasMoreTopChart) return; setPage((oldPage) => oldPage + 1); - entriesSearchStore.loadMoreTopChart(page); + loadMoreTopChart(page); }; return ( - {entriesSearchStore.topChart.length > 0 && ( + {topChart.length > 0 && ( renderItem(item, index)} keyExtractor={(entry) => entry.id} onEndReached={handleLoadMore} @@ -50,10 +57,10 @@ export default observer((props) => { ListHeaderComponent={() => ( Top Beats )} - refreshing={entriesSearchStore.loadingTopChart} + refreshing={loadingTopChart} /> )} - {SearchingLoader(entriesSearchStore.loadingTopChart)} + {SearchingLoader(loadingTopChart)} diff --git a/src/search/LikeOptionRow.tsx b/src/search/LikeOptionRow.tsx index 41b42a0..c524327 100644 --- a/src/search/LikeOptionRow.tsx +++ b/src/search/LikeOptionRow.tsx @@ -4,7 +4,7 @@ import Colors from 'app/src/constants/Colors'; import { useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import LikeIcon from 'app/src/ui/icons/like'; -import { LikesStore } from '../stores/likes.store'; +import { LikesStore } from '../stores/likes'; export default ({ entry, iconOnly = false, size = 24 }) => { const { toggleLike, isEntryLiked } = LikesStore(); diff --git a/src/search/PricingOptionsModal.tsx b/src/search/PricingOptionsModal.tsx index b24eb7d..c2707eb 100644 --- a/src/search/PricingOptionsModal.tsx +++ b/src/search/PricingOptionsModal.tsx @@ -17,7 +17,7 @@ import Slider from '@react-native-community/slider'; import DollarIcon from 'app/src/ui/icons/dollar'; import PieIcon from 'app/src/ui/icons/pie'; import CircleIcon from 'app/src/ui/icons/circle'; -import { UserEntriesStore } from '../stores/user-entries.store'; +import { UserEntriesStore } from '../stores/user-entries'; const SwitchWeb: any = Switch; diff --git a/src/search/RecentlyAdded.tsx b/src/search/RecentlyAdded.tsx index 6efefc0..79d3b73 100644 --- a/src/search/RecentlyAdded.tsx +++ b/src/search/RecentlyAdded.tsx @@ -7,9 +7,16 @@ import Colors from 'app/src/constants/Colors'; import { Stores } from 'app/src/functions/Stores'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import BottomPlaceholder from '../ui/BottomPlaceholder'; +import { SearchStore } from '../stores/search'; export default observer((props) => { - const { playerStore, entriesSearchStore } = Stores(); + const { playerStore } = Stores(); + const { + recentlyAdded, + hasMoreRecentlyAdded, + loadMoreRecentlyAdded, + loadingRecentlyAdded, + } = SearchStore(); const [page, setPage] = useState(1); const renderItem = (item) => { return ( @@ -19,9 +26,7 @@ export default observer((props) => { entry={item} options={null} disablePlaylistMode={() => { - playerStore.setPlaylistModeFromArray( - entriesSearchStore.recentlyAdded - ); + playerStore.setPlaylistModeFromArray(recentlyAdded); }} previousScreen={null} /> @@ -29,17 +34,17 @@ export default observer((props) => { }; const handleLoadMore = () => { - if (!entriesSearchStore.hasMoreRecentlyAdded) return; + if (!hasMoreRecentlyAdded) return; setPage((oldPage) => oldPage + 1); - entriesSearchStore.loadMoreRecentlyAdded(page); + loadMoreRecentlyAdded(page); }; return ( - {entriesSearchStore.recentlyAdded.length > 0 && ( + {recentlyAdded.length > 0 && ( renderItem(item)} keyExtractor={(entry) => entry.id} onEndReached={handleLoadMore} @@ -47,10 +52,10 @@ export default observer((props) => { ListHeaderComponent={() => ( Recently Added )} - refreshing={entriesSearchStore.loadingRecentlyAdded} + refreshing={loadingRecentlyAdded} /> )} - {SearchingLoader(entriesSearchStore.loadingRecentlyAdded)} + {SearchingLoader(loadingRecentlyAdded)} diff --git a/src/search/RemoveFromMyMusicRow.tsx b/src/search/RemoveFromMyMusicRow.tsx index dbaf8a2..aa85d18 100644 --- a/src/search/RemoveFromMyMusicRow.tsx +++ b/src/search/RemoveFromMyMusicRow.tsx @@ -6,7 +6,7 @@ import Colors from 'app/src/constants/Colors'; import * as stores from 'app/src/stores'; import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; -import { UserEntriesStore } from '../stores/user-entries.store'; +import { UserEntriesStore } from '../stores/user-entries'; type Stores = typeof stores; diff --git a/src/search/SearchEntryList.tsx b/src/search/SearchEntryList.tsx index e87f2d7..0e0d76f 100644 --- a/src/search/SearchEntryList.tsx +++ b/src/search/SearchEntryList.tsx @@ -1,33 +1,19 @@ import React from 'react'; import { ScrollView } from 'react-native'; -import { inject } from 'mobx-react'; import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as stores from 'app/src/stores'; -import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -type Stores = typeof stores; +import { SearchStore } from '../stores/search'; -const SearchEntryList = inject((stores: Stores) => ({ - loadPlayAndPushToCueList: stores.playerStore.loadPlayAndPushToCueList.bind( - stores.playerStore - ), - entries: stores.entriesSearchStore.entries, - searching: stores.entriesSearchStore.searching, - query: stores.entriesSearchStore.query, - disablePlaylistMode: stores.playerStore.disablePlaylistMode.bind( - stores.playerStore - ), -}))( - ({ - loadPlayAndPushToCueList, - entries, - searching, - query, - disablePlaylistMode, - }: any) => ( +const SearchEntryList = () => { + const { searching, entries } = SearchStore(); + const query = ''; + const loadPlayAndPushToCueList = () => {}; + const disablePlaylistMode = () => {}; + + return ( ({ > {SearchingLoader(searching, query)} - - {L.map( - (entry: any) => ( - - ), - entries - )} + {entries.map((entry: any) => ( + + ))} - ) -); + ); +}; export default SearchEntryList; diff --git a/src/search/SearchEntryView.tsx b/src/search/SearchEntryView.tsx index 19d9794..d227887 100644 --- a/src/search/SearchEntryView.tsx +++ b/src/search/SearchEntryView.tsx @@ -1,29 +1,30 @@ import React, { useCallback, useEffect } from 'react'; -import { observer } from 'mobx-react'; +import { useRecoilValue } from 'recoil'; import SearchEntryList from 'app/src/search/SearchEntryList'; import RecentlyAdded from 'app/src/search/RecentlyAdded'; import { useFocusEffect } from '@react-navigation/native'; -import { Stores } from 'app/src/functions/Stores'; +import { SearchStore, activeSearchAtom } from '../stores/search'; -export default observer(() => { - let { entriesSearchStore, inputSearchStore } = Stores(); +export default () => { + const { getRecentlyAdded, updateSearchType } = SearchStore(); + const active = useRecoilValue(activeSearchAtom); useFocusEffect( useCallback(() => { - inputSearchStore.updateSearchType('entries'); + updateSearchType('entries'); }, []) ); const handleRecentlyAdded = async () => { - await entriesSearchStore.getRecentlyAdded(); + await getRecentlyAdded(); }; useEffect(() => { handleRecentlyAdded(); }, []); - if (entriesSearchStore.active) { + if (active) { return ; } return ; -}); +}; diff --git a/src/search/SearchHeader.tsx b/src/search/SearchHeader.tsx index f1b3eca..f99242c 100644 --- a/src/search/SearchHeader.tsx +++ b/src/search/SearchHeader.tsx @@ -1,52 +1,44 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Platform } from 'react-native'; -import { inject } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import SearchBar from 'app/src/ui/searchbar/SearchBar'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; +import { SearchStore } from '../stores/search'; let platform = Platform.OS === 'ios' ? 'ios' : 'android'; -@inject((stores: Stores) => ({ - inputSearchStore: stores.inputSearchStore, -})) -class SearchHeader extends React.Component { - state = { - value: '', - }; +const SearchHeader = () => { + const [value, setValue] = useState(''); + const { search } = SearchStore(); - changeText = (value: any) => { - this.setState({ value }); + const changeText = (value: any) => { + setValue(value); }; - render() { - return ( - { - this.props.inputSearchStore.search(q); - this.changeText(q); - }} - placeholder="Search" - icon={{ - style: { top: 15 }, - color: Colors.searchTextColor, - name: 'search', - }} - clearIcon={true} - value={this.state.value} - autoCorrect={false} - placeholderTextColor={Colors.searchTextColor} - inputStyle={{ - height: 30, - margin: 7.5, - borderRadius: 5, - color: Colors.searchTextColor, - }} - /> - ); - } -} + return ( + { + search(q); + changeText(q); + }} + placeholder="Search" + icon={{ + style: { top: 15 }, + color: Colors.searchTextColor, + name: 'search', + }} + clearIcon={true} + value={value} + autoCorrect={false} + placeholderTextColor={Colors.searchTextColor} + inputStyle={{ + height: 30, + margin: 7.5, + borderRadius: 5, + color: Colors.searchTextColor, + }} + /> + ); +}; export default SearchHeader; diff --git a/src/search/SearchUserList.tsx b/src/search/SearchUserList.tsx index 6c9b529..9fcf1d4 100644 --- a/src/search/SearchUserList.tsx +++ b/src/search/SearchUserList.tsx @@ -1,32 +1,26 @@ import React from 'react'; import { ScrollView } from 'react-native'; -import { inject } from 'mobx-react'; import UserRow from 'app/src/ui/UserRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as stores from 'app/src/stores'; -import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -type Stores = typeof stores; +import { SearchStore } from '../stores/search'; -const UserSearchList = inject((stores: Stores) => ({ - users: stores.usersSearchStore.users, - searching: stores.usersSearchStore.searching, - query: stores.usersSearchStore.query, -}))(({ users, searching, query }: any) => ( - - - {SearchingLoader(searching, query)} - {L.map( - (user: { id: string | number | undefined }) => ( +const UserSearchList = () => { + const { users, searching, query } = SearchStore(); + + return ( + + + {SearchingLoader(searching, query)} + {users.map((user) => ( - ), - users - )} - - - -)); + ))} + + + + ); +}; export default UserSearchList; diff --git a/src/search/SearchUserView.tsx b/src/search/SearchUserView.tsx index a76ed75..699dde0 100644 --- a/src/search/SearchUserView.tsx +++ b/src/search/SearchUserView.tsx @@ -1,21 +1,19 @@ import React, { useCallback } from 'react'; -import { observer } from 'mobx-react'; import SearchUserList from 'app/src/search/SearchUserList'; -import TopRecentUserView from 'app/src/search/TopRecentUserView'; import { useFocusEffect } from '@react-navigation/native'; -import { Stores } from 'app/src/functions/Stores'; +import { SearchStore } from '../stores/search'; -export default observer(() => { - let { usersSearchStore, inputSearchStore } = Stores(); +export default () => { + const { updateSearchType, active } = SearchStore(); useFocusEffect( useCallback(() => { - inputSearchStore.updateSearchType('users'); + updateSearchType('users'); }, []) ); - if (usersSearchStore.active) { + if (active) { return ; } - return ; -}); + return null; +}; diff --git a/src/search/TopRecentUserView.tsx b/src/search/TopRecentUserView.tsx deleted file mode 100644 index 7155932..0000000 --- a/src/search/TopRecentUserView.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import { ScrollView, StyleSheet } from 'react-native'; -import TopUserSearchView from 'app/src/search/TopUserSearchView'; -import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import Colors from 'app/src/constants/Colors'; -import ResponsiveLayout from '../ui/ResponsiveLayout'; - -const TopRecentUserView = () => ( - - - - - - -); - -const styles = StyleSheet.create({ - scrollView: { - backgroundColor: Colors.listItemBackground, - flex: 1, - }, -}); - -export default TopRecentUserView; diff --git a/src/search/TopUserSearchView.tsx b/src/search/TopUserSearchView.tsx deleted file mode 100644 index f2d7203..0000000 --- a/src/search/TopUserSearchView.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { View, Text, StyleSheet } from 'react-native'; -import { inject } from 'mobx-react'; -import Colors from 'app/src/constants/Colors'; -import UserRow from 'app/src/ui/UserRow'; -import SearchingLoader from 'app/src/ui/SearchingLoader'; -import * as L from 'list'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; - -@inject((stores: Stores) => ({ - getTopSearches: stores.usersSearchStore.getTopSearches.bind( - stores.usersSearchStore - ), - topSearches: stores.usersSearchStore.topSearches, - loadingTopSearches: stores.usersSearchStore.loadingTopSearches, -})) -export default class TopUserSearchView extends React.Component { - componentDidMount() { - this.props.getTopSearches(); - } - render() { - if (!this.props.loadingTopSearches && !this.props.topSearches.length) { - return null; - } - return ( - - TOP - {SearchingLoader(this.props.loadingTopSearches)} - {L.map( - (user: { id: string | number | undefined }) => ( - - ), - this.props.topSearches - )} - - ); - } -} - -const styles = StyleSheet.create({ - recentText: { - color: Colors.defaultTextLight, - fontSize: 14, - paddingTop: 10, - paddingLeft: 10, - }, -}); diff --git a/src/stores/entries-search.store.ts b/src/stores/entries-search.store.ts deleted file mode 100644 index b1d9e43..0000000 --- a/src/stores/entries-search.store.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { Entry } from '../models/entry.model'; -import { entriesBackend } from '../api/entries'; -import { observable, observe, computed } from 'mobx'; -import * as L from 'list'; - -const debounce = require('lodash.debounce'); - -export class EntriesSearchStore { - @observable searching: boolean = false; - @observable loadingRecentSearches: boolean = false; - @observable loadingTopSearches: boolean = false; - @observable loadingRecentlyAdded: boolean = false; - @observable load: boolean = false; - @observable loadingTopChart: boolean = false; - @observable query: string = ''; - @observable public entries: L.List = L.from([]); - @observable public recentSearches: L.List = L.from([]); - @observable public recentlyAdded: Entry[] = []; - @observable public hasMoreRecentlyAdded = true; - @observable topChart: Entry[] = []; - @observable public hasMoreTopChart = true; - disposer: any; - - @computed get active() { - return !!this.query; - } - - constructor(public queryObservable: any) { - this.disposer = observe(queryObservable, ({ object }) => { - if (object.type === 'entries' && object.q !== this.query) { - this.query = object.q; - this.searching = true; - this.debouncedSearch(object.q); - } - }); - } - - public searchEntries(q: string) { - return entriesBackend.search(q).then((results) => { - let entries: Entry[] = results.map((result: any) => new Entry(result)); - this.setEntries(L.from(entries)); - this.searching = false; - }); - } - - public debouncedSearch = debounce(this.searchEntries, 400); - - public setEntries(entries: L.List) { - this.entries = entries; - } - - public setRecentSearches(entries: L.List) { - this.recentSearches = entries; - } - - public setTopChart(entries: Entry[]) { - this.topChart = entries; - } - - public setRecentlyAdded(entries: Entry[]) { - this.recentlyAdded = entries; - } - - public getTopChart() { - this.loadingTopChart = true; - return entriesBackend.getTopChart().then((entries) => { - this.setTopChart(entries); - this.loadingTopChart = false; - }); - } - - public loadMoreTopChart(page: number) { - this.loadingTopChart = true; - return entriesBackend.getTopChart(page).then((entries) => { - if (entries.length == 0) { - this.hasMoreTopChart = false; - this.loadingTopChart = false; - return; - } - this.setTopChart([...this.topChart, ...entries]); - this.loadingTopChart = false; - return this.topChart; - }); - } - - public getRecentSearches() { - this.loadingRecentSearches = true; - return entriesBackend.getRecentSearches().then((entries) => { - this.setRecentSearches(L.from(entries)); - this.loadingRecentSearches = false; - }); - } - - public getRecentlyAdded() { - this.loadingRecentlyAdded = true; - return entriesBackend.getRecentlyAdded().then((entries) => { - this.setRecentlyAdded(entries); - this.loadingRecentlyAdded = false; - return this.recentlyAdded; - }); - } - - public loadMoreRecentlyAdded(page: number) { - this.loadingRecentlyAdded = true; - return entriesBackend.getRecentlyAdded(page).then((entries) => { - if (entries.length == 0) { - this.hasMoreRecentlyAdded = false; - this.loadingRecentlyAdded = false; - return; - } - this.setRecentlyAdded([...this.recentlyAdded, ...entries]); - this.loadingRecentlyAdded = false; - return this.recentlyAdded; - }); - } -} diff --git a/src/stores/index.ts b/src/stores/index.ts index 85c88ab..824f692 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,29 +1,15 @@ import { PlayerStore } from './player.store'; -import { InputSearchStore } from './input-search.store'; -import { EntriesSearchStore } from './entries-search.store'; -import { UsersSearchStore } from './users-search.store'; -import { ProfileStore } from './profile.store'; import { PaymentsStore } from './payments.store'; import { EntryStore } from './entry.store'; import { WalletConnectStore } from './wallet-connect.store'; export const playerStore = new PlayerStore(); -export const inputSearchStore = new InputSearchStore(); -export const entriesSearchStore = new EntriesSearchStore( - inputSearchStore.query -); -export const usersSearchStore = new UsersSearchStore(inputSearchStore.query); -export const profileStore = new ProfileStore(); export const paymentsStore = new PaymentsStore(); export const entryStore = new EntryStore(); export const walletConnectStore = new WalletConnectStore(); export type Stores = { playerStore: PlayerStore; - inputSearchStore: InputSearchStore; - entriesSearchStore: EntriesSearchStore; - usersSearchStore: UsersSearchStore; - profileStore: ProfileStore; paymentsStore: PaymentsStore; entryStore: EntryStore; walletConnectStore: WalletConnectStore; diff --git a/src/stores/input-search.store.ts b/src/stores/input-search.store.ts deleted file mode 100644 index adf28c9..0000000 --- a/src/stores/input-search.store.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { observable } from 'mobx'; - -export class InputSearchStore { - public query = observable({ - type: 'entries', - q: '', - }); - - constructor() {} - - public search(query: string) { - this.query.q = query; - } - - public updateSearchType(type: 'entries' | 'users') { - this.query.type = type; - } -} diff --git a/src/stores/likes.store.ts b/src/stores/likes.ts similarity index 100% rename from src/stores/likes.store.ts rename to src/stores/likes.ts diff --git a/src/stores/profile.store.ts b/src/stores/profile.store.ts deleted file mode 100644 index f6d0063..0000000 --- a/src/stores/profile.store.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { observable } from 'mobx'; -import { User, Entry } from '../models'; -import * as L from 'list'; -import { entriesBackend } from '../api/entries'; - -export class ProfileStore { - @observable - user!: User; - @observable entries: L.List = L.from([]); - @observable loadingEntries: boolean = false; - constructor() {} - - public async getProfileInfo(user: User) { - if (!user) return; - this.user = user; - return this.getUserEntries(user.id as string); - } - - public async getUserEntries(userId: string) { - this.loadingEntries = true; - this.entries = L.from([]); - const entries = await entriesBackend.getByUserId(userId); - this.loadingEntries = false; - return this.setEntries(L.from(entries)); - } - - public setEntries(entries: L.List) { - return (this.entries = entries); - } -} diff --git a/src/stores/profile.ts b/src/stores/profile.ts new file mode 100644 index 0000000..71ecf0a --- /dev/null +++ b/src/stores/profile.ts @@ -0,0 +1,50 @@ +import { User, Entry } from '../models'; +import { entriesBackend } from '../api/entries'; +import { atom, useRecoilState } from 'recoil'; + +const profileUserAtom = atom({ + key: 'profileUser', + default: null, +}); +const profileEntriesAtom = atom({ + key: 'profileEntries', + default: [], +}); +const loadingEntriesAtom = atom({ + key: 'loadingEntries', + default: false, +}); + +export const ProfileStore = () => { + const [user, setUser] = useRecoilState(profileUserAtom); + const [profileEntries, setProfileEntries] = useRecoilState( + profileEntriesAtom + ); + const [loadingEntries, setLoadingEntries] = useRecoilState( + loadingEntriesAtom + ); + + const getProfileInfo = async (user: User) => { + if (!user) return; + setUser(user); + return getUserEntries(user.id as string); + }; + + const getUserEntries = async (userId: string) => { + setLoadingEntries(true); + setProfileEntries([]); + const entries = await entriesBackend.getByUserId(userId); + setLoadingEntries(false); + return setProfileEntries(entries); + }; + + return { + user, + profileEntries, + loadingEntries, + getProfileInfo, + getUserEntries, + }; +}; + +export default ProfileStore; diff --git a/src/stores/search.ts b/src/stores/search.ts new file mode 100644 index 0000000..5375c70 --- /dev/null +++ b/src/stores/search.ts @@ -0,0 +1,205 @@ +import { Entry } from '../models/entry.model'; +import { User } from '../models/user.model'; +import { entriesBackend } from '../api/entries'; +import { atom, selector, useRecoilState, useRecoilValue } from 'recoil'; +import { usersBackend } from '../api/users'; +import { useEffect } from 'react'; + +const debounce = require('lodash.debounce'); + +export const searchingAtom = atom({ + key: 'searching', + default: false, +}); +export const loadingRecentSearchesAtom = atom({ + key: 'loadingRecentSearches', + default: false, +}); +export const loadingTopSearchesAtom = atom({ + key: 'loadingTopSearches', + default: false, +}); +export const loadingRecentlyAddedAtom = atom({ + key: 'loadingRecentlyAdded', + default: false, +}); +export const loadingTopChartAtom = atom({ + key: 'loadingTopChart', + default: false, +}); +export const queryAtom = atom<{ type: 'entries' | 'users'; q: string }>({ + key: 'query', + default: { + type: 'entries', + q: '', + }, +}); +export const entriesAtom = atom({ + key: 'entries', + default: [], +}); +export const recentlyAddedAtom = atom({ + key: 'recentlyAdded', + default: [], +}); + +export const hasMoreRecentlyAddedAtom = atom({ + key: 'hasMoreRecentlyAdded', + default: true, +}); + +export const topChartAtom = atom({ + key: 'topChart', + default: [], +}); + +export const hasMoreTopChartAtom = atom({ + key: 'hasMoreTopChart', + default: true, +}); + +export const activeSearchAtom = selector({ + key: 'activeSearch', + get: ({ get }) => { + const { q } = get(queryAtom); + return !!q; + }, +}); + +export const usersAtom = atom({ + key: 'users', + default: [], +}); +export const searchingUsersAtom = atom({ + key: 'searchingUsers', + default: false, +}); +export const queryUsersAtom = atom({ + key: 'queryUsers', + default: '', +}); + +export const SearchStore = () => { + const [entries, setEntries] = useRecoilState(entriesAtom); + const [searching, setSearching] = useRecoilState(searchingAtom); + const [topChart, setTopChart] = useRecoilState(topChartAtom); + const [recentlyAdded, setRecentlyAdded] = useRecoilState(recentlyAddedAtom); + + const [loadingTopChart, setLoadingTopChart] = useRecoilState( + loadingTopChartAtom + ); + const [hasMoreTopChart, setHasMoreTopChart] = useRecoilState( + hasMoreTopChartAtom + ); + const [hasMoreRecentlyAdded, setHasMoreRecentlyAdded] = useRecoilState( + hasMoreRecentlyAddedAtom + ); + const [loadingRecentlyAdded, setLoadingRecentlyAdded] = useRecoilState( + loadingRecentlyAddedAtom + ); + + const [users, setUsers] = useRecoilState(usersAtom); + const [query, setQuery] = useRecoilState(queryAtom); + const active = useRecoilValue(activeSearchAtom); + + const search = (query: string) => { + setQuery((oldState) => ({ ...oldState, q: query })); + }; + + const updateSearchType = (type: 'entries' | 'users') => { + setQuery((oldState) => ({ ...oldState, type })); + }; + + const searchUsers = (q: string) => { + usersBackend.search(q).then((users) => { + setUsers(users); + setSearching(false); + }); + }; + + const searchEntries = (q: string) => { + return entriesBackend.search(q).then((results) => { + let entries: Entry[] = results.map((result: any) => new Entry(result)); + setEntries(entries); + setSearching(false); + }); + }; + + const debouncedEntriesSearch = debounce(searchEntries, 400); + const debouncedUsersSearch = debounce(searchUsers, 400); + + useEffect(() => { + if (query.type === 'users') { + debouncedUsersSearch(query.q); + } else { + debouncedEntriesSearch(query.q); + } + }, [query]); + + const getTopChart = () => { + setLoadingTopChart(true); + return entriesBackend.getTopChart().then((entries) => { + setTopChart(entries); + setLoadingTopChart(false); + }); + }; + + const loadMoreTopChart = (page: number) => { + setLoadingTopChart(true); + return entriesBackend.getTopChart(page).then((entries) => { + if (entries.length == 0) { + setHasMoreTopChart(false); + setLoadingTopChart(false); + return; + } + setTopChart([...topChart, ...entries]); + setLoadingTopChart(false); + return topChart; + }); + }; + + const getRecentlyAdded = () => { + setLoadingRecentlyAdded(true); + return entriesBackend.getRecentlyAdded().then((entries) => { + setRecentlyAdded(entries); + setLoadingRecentlyAdded(false); + return recentlyAdded; + }); + }; + + const loadMoreRecentlyAdded = (page: number) => { + setLoadingRecentlyAdded(true); + return entriesBackend.getRecentlyAdded(page).then((entries) => { + if (entries.length == 0) { + setHasMoreRecentlyAdded(false); + setLoadingRecentlyAdded(false); + return; + } + setRecentlyAdded([...recentlyAdded, ...entries]); + setLoadingRecentlyAdded(false); + return recentlyAdded; + }); + }; + + return { + searchEntries, + getTopChart, + loadMoreTopChart, + getRecentlyAdded, + loadMoreRecentlyAdded, + entries, + searching, + topChart, + recentlyAdded, + loadingTopChart, + hasMoreTopChart, + hasMoreRecentlyAdded, + loadingRecentlyAdded, + users, + query, + searchUsers, + updateSearchType, + search, + active, + }; +}; diff --git a/src/stores/user-entries.store.ts b/src/stores/user-entries.ts similarity index 100% rename from src/stores/user-entries.store.ts rename to src/stores/user-entries.ts diff --git a/src/stores/users-search.store.ts b/src/stores/users-search.store.ts deleted file mode 100644 index 3d60c5e..0000000 --- a/src/stores/users-search.store.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { User } from '../models/user.model'; -import { usersBackend } from '../api/users'; -import { observable, observe, computed } from 'mobx'; -import * as L from 'list'; -const debounce = require('lodash.debounce'); - -export class UsersSearchStore { - @observable public users: L.List = L.from([]); - @observable public recentSearches: L.List = L.from([]); - @observable public topSearches: L.List = L.from([]); - @observable searching: boolean = false; - @observable loadingRecentSearches: boolean = false; - @observable loadingTopSearches: boolean = false; - @observable query: string = ''; - disposer: any; - @computed get active() { - return !!this.query; - } - - constructor(public queryObservable: any) { - this.disposer = observe(queryObservable, ({ object }) => { - if (object.type === 'users' && object.q !== this.query) { - this.query = object.q; - this.searching = true; - this.searchUsers(object.q); - } - }); - } - - public searchUsers(q: string) { - usersBackend.search(q).then((users) => { - this.setUsers(L.from(users)); - this.searching = false; - }); - } - - public debouncedSearch = debounce(this.searchUsers, 400); - - public setUsers(users: L.List) { - this.users = users; - } - - public setRecentSearches(users: L.List) { - this.recentSearches = users; - } - - public setTopSearches(users: L.List) { - this.topSearches = users; - } - - public getRecentSearches() { - this.loadingRecentSearches = true; - return usersBackend.getRecentSearches().then((users) => { - this.setRecentSearches(L.from(users)); - this.loadingRecentSearches = false; - }); - } - - public getTopSearches() { - this.loadingTopSearches = true; - return usersBackend.getTopSearches().then((users) => { - this.setTopSearches(L.from(users)); - this.loadingTopSearches = false; - }); - } -} diff --git a/src/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx index 732be11..42d84b8 100644 --- a/src/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -6,7 +6,7 @@ import { observer } from 'mobx-react'; import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; -import { UserEntriesStore } from '../stores/user-entries.store'; +import { UserEntriesStore } from '../stores/user-entries'; export default observer(({ route }) => { const { entry, priceInfo } = route.params; @@ -18,12 +18,7 @@ export default observer(({ route }) => { const { goBack } = useNavigation(); const linkTo = useLinkTo(); - const { - paymentsStore, - entriesSearchStore, - playerStore, - walletConnectStore, - } = Stores(); + const { paymentsStore, playerStore, walletConnectStore } = Stores(); const { refreshEntries } = UserEntriesStore(); const buyEntry = async (id: string) => { @@ -41,7 +36,6 @@ export default observer(({ route }) => { } await Promise.all([ await refreshEntries(), - await entriesSearchStore.getRecentSearches(), await paymentsStore.refreshSubscription(), ]); playerStore.refreshEntry(); diff --git a/src/ui/LogOutBtn.tsx b/src/ui/LogOutBtn.tsx index ba2c1d6..72814cf 100644 --- a/src/ui/LogOutBtn.tsx +++ b/src/ui/LogOutBtn.tsx @@ -5,7 +5,7 @@ import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; import LogOutIcon from 'app/src/ui/icons/logout'; import { useLinkTo } from '@react-navigation/native'; -import { LikesStore } from '../stores/likes.store'; +import { LikesStore } from '../stores/likes'; import { SessionStore } from '../stores/session'; export default observer(() => { diff --git a/src/ui/UserRow.tsx b/src/ui/UserRow.tsx index 2dcc75d..22477d5 100644 --- a/src/ui/UserRow.tsx +++ b/src/ui/UserRow.tsx @@ -5,16 +5,18 @@ import { UserAvatar } from 'app/src/ui/UserAvatar'; import { Stores } from 'app/src/functions/Stores'; import { observer } from 'mobx-react'; import { CommonActions, useNavigation } from '@react-navigation/native'; +import ProfileStore from '../stores/profile'; export default observer(({ user }) => { - const { profileStore, playerStore } = Stores(); + const { playerStore } = Stores(); + const { getProfileInfo } = ProfileStore(); const { dispatch } = useNavigation(); return ( { - profileStore.getProfileInfo(user).then((entries: any) => { + getProfileInfo(user).then((entries: any) => { playerStore.setPlaylistMode(entries); }); dispatch( From e2195fdf248da33b2f81b832691a4f91faf1540d Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Tue, 5 Jul 2022 22:38:11 -0500 Subject: [PATCH 05/13] migrate paymentsStore --- src/profile/LowBalanceModal.tsx | 11 +- src/profile/PaymentStep.tsx | 68 +++---- src/profile/ProfileSettingsScreen.tsx | 8 +- src/profile/ProfileSettingsTopContainer.tsx | 36 ++-- src/profile/WithdrawalModal.tsx | 27 ++- src/providers/Providers.tsx | 8 +- src/stores/index.ts | 7 +- src/stores/payments.store.ts | 189 ++++++++++++-------- src/stores/session.ts | 2 +- src/ui/BuyOptionsModal.tsx | 17 +- src/ui/EntryPrice.tsx | 6 +- src/ui/buy-btn/BuyBtn.tsx | 13 +- 12 files changed, 212 insertions(+), 180 deletions(-) diff --git a/src/profile/LowBalanceModal.tsx b/src/profile/LowBalanceModal.tsx index 5de1c3e..e728ff6 100644 --- a/src/profile/LowBalanceModal.tsx +++ b/src/profile/LowBalanceModal.tsx @@ -7,10 +7,8 @@ import { TextInput, Platform, } from 'react-native'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import LargeBtn from 'app/src/ui/LargeBtn'; -import { Stores } from 'app/src/functions/Stores'; import { useLinkTo, useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import CloseIcon from 'app/src/ui/icons/x'; @@ -18,9 +16,10 @@ import WalletIcon from 'app/src/ui/icons/wallet'; import DollarIcon from 'app/src/ui/icons/dollar'; import { userAtom } from '../atoms/atoms'; import { useRecoilValue } from 'recoil'; +import { PaymentsStore } from '../stores/payments.store'; -export default observer((props) => { - const { paymentsStore } = Stores(); +export default (props) => { + const { credits } = PaymentsStore(); const user = useRecoilValue(userAtom); const { goBack } = useNavigation(); const linkTo = useLinkTo(); @@ -51,7 +50,7 @@ export default observer((props) => { {' '} - {paymentsStore.credits.toFixed(4)} + {credits.toFixed(4)} @@ -94,7 +93,7 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ fieldWithoutBorderTop: { diff --git a/src/profile/PaymentStep.tsx b/src/profile/PaymentStep.tsx index 7bd3d86..f9f2156 100644 --- a/src/profile/PaymentStep.tsx +++ b/src/profile/PaymentStep.tsx @@ -1,7 +1,5 @@ import React, { useEffect, useState } from 'react'; import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; import { StyleSheet, View, @@ -14,35 +12,49 @@ import { P, H3 } from '@expo/html-elements'; import Colors from 'app/src/constants/Colors'; import { useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { PaymentsStore } from '../stores/payments.store'; async function timeout(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } -export default observer((props) => { +export default (props) => { const [amount, setAmount] = useState(200); const stripe = useStripe(); const elements = useElements(); const { goBack } = useNavigation(); - const { paymentsStore } = Stores(); + const { + subscribed, + refreshXLMPrice, + setLoadingBalance, + refreshSubscription, + credits, + subscribeUser, + setSubmittingSubscription, + buyCredits, + xlmPriceWithFees, + subscriptionLoaded, + xlmPrice, + submittingSubscription, + } = PaymentsStore(); const [selectedOption, setSelectedOption] = useState( - paymentsStore.subscribed ? 'one-time' : 'subscription' + subscribed ? 'one-time' : 'subscription' ); useEffect(() => { - paymentsStore.refreshXLMPrice(); + refreshXLMPrice(); }, []); - const refreshSubscription = async () => { - paymentsStore.setLoadingBalance(true); - let lastBalance = paymentsStore.credits; + const handleRefreshSubscription = async () => { + setLoadingBalance(true); + let lastBalance = credits; await timeout(15000); - await paymentsStore.refreshSubscription(); - if (lastBalance === paymentsStore.credits) { - paymentsStore.setLoadingBalance(true); + await refreshSubscription(); + if (lastBalance === credits) { + setLoadingBalance(true); await timeout(15000); - paymentsStore.refreshSubscription(); + refreshSubscription(); } }; @@ -53,7 +65,7 @@ export default observer((props) => { }; const submit = async () => { - paymentsStore.setSubmittingSubscription(true); + setSubmittingSubscription(true); if (!stripe || !elements) { // Stripe.js has not loaded yet. Make sure to disable // form submission until Stripe.js has loaded. @@ -72,22 +84,19 @@ export default observer((props) => { if (!token) return; const { id } = token; if (selectedOption === 'one-time') { - const purchased = await paymentsStore.buyCredits( - id, - amount * paymentsStore.xlmPriceWithFees - ); + const purchased = await buyCredits(id, amount * xlmPriceWithFees()); if (purchased) { goBack(); - refreshSubscription(); + handleRefreshSubscription(); } return; } - const subscribed = await paymentsStore.subscribeUser(id); + const subscribed = await subscribeUser(id); if (subscribed) { goBack(); - refreshSubscription(); + handleRefreshSubscription(); } }; @@ -110,7 +119,7 @@ export default observer((props) => { setSelectedOption('subscription'); }; - if (!paymentsStore.subscriptionLoaded) { + if (!subscriptionLoaded) { return (

Checking if you already subscribed...

@@ -120,7 +129,7 @@ export default observer((props) => { return ( - {!paymentsStore.subscribed && ( + {!subscribed && ( { >

- {paymentsStore.xlmPrice && - (7.99 / paymentsStore.xlmPriceWithFees).toFixed(2)} + {xlmPrice && (7.99 / xlmPriceWithFees()).toFixed(2)}

Monthly XLM plan

@@ -167,10 +175,8 @@ export default observer((props) => {

Buy XLM

- $ - {paymentsStore.xlmPrice && - (amount * paymentsStore.xlmPriceWithFees).toFixed(2)}{' '} - one time + ${xlmPrice && (amount * xlmPriceWithFees()).toFixed(2)} one + time

@@ -193,7 +199,7 @@ export default observer((props) => { }, }} /> - {paymentsStore.submittingSubscription ? ( + {submittingSubscription ? (

Submitting Transaction...

@@ -207,7 +213,7 @@ export default observer((props) => { )}
); -}); +}; const styles = StyleSheet.create({ radioWrapper: { diff --git a/src/profile/ProfileSettingsScreen.tsx b/src/profile/ProfileSettingsScreen.tsx index 6ea53d1..669a03a 100644 --- a/src/profile/ProfileSettingsScreen.tsx +++ b/src/profile/ProfileSettingsScreen.tsx @@ -9,7 +9,6 @@ import LikesScreen from 'app/src/playlists/LikesScreen'; import CollectionScreen from 'app/src/playlists/CollectionScreen'; import LikesRow from 'app/src/playlists/LikesRow'; import MyMusicRow from 'app/src/playlists/MyMusicRow'; -import { Stores } from 'app/src/functions/Stores'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import MintNFT from './MintNFT'; import { useLinkTo } from '@react-navigation/native'; @@ -18,16 +17,17 @@ import ChevronLeftIcon from 'app/src/ui/icons/chevron-left'; import tw from 'twin.macro'; import { UserEntriesStore } from '../stores/user-entries'; import { LikesStore } from '../stores/likes'; +import { PaymentsStore } from '../stores/payments.store'; const ProfileSettingsScreen = observer(() => { - let { paymentsStore } = Stores(); + let { refreshSubscription, credits } = PaymentsStore(); const { refreshLikes } = LikesStore(); const { refreshEntries } = UserEntriesStore(); useEffect(() => { refreshLikes(); refreshEntries(); - paymentsStore.refreshSubscription(); + refreshSubscription(); }); return ( @@ -37,7 +37,7 @@ const ProfileSettingsScreen = observer(() => { - +
diff --git a/src/profile/ProfileSettingsTopContainer.tsx b/src/profile/ProfileSettingsTopContainer.tsx index 145245d..e5dd436 100644 --- a/src/profile/ProfileSettingsTopContainer.tsx +++ b/src/profile/ProfileSettingsTopContainer.tsx @@ -3,19 +3,21 @@ import { View, StyleSheet, Text } from 'react-native'; import Colors from 'app/src/constants/Colors'; import Layout from 'app/src/constants/Layout'; import { UserAvatarMedium } from 'app/src/ui/UserAvatar'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; import EditBtn from '../ui/EditBtn'; import DollarIcon from 'app/src/ui/icons/dollar'; import WalletIcon from 'app/src/ui/icons/wallet'; import { A } from '@expo/html-elements'; import { stellarAccountLink } from 'app/src/functions/utils'; +import { PaymentsStore } from '../stores/payments.store'; +import { userAtom } from '../atoms/atoms'; +import { useRecoilValue } from 'recoil'; -export default observer((props) => { - const { paymentsStore, sessionStore } = Stores(); +export default (props) => { + const { credits, loadingBalance } = PaymentsStore(); + const user = useRecoilValue(userAtom); const renderDollarSign = () => { - if (paymentsStore.credits > 0) { + if (credits > 0) { return ( @@ -26,20 +28,18 @@ export default observer((props) => { }; const renderCreditsSection = () => { - if (paymentsStore.loadingBalance) { + if (loadingBalance) { return {' '}Loading Balance...; } return ( <> {renderDollarSign()} - - {paymentsStore.credits ? paymentsStore.credits.toFixed(4) : ''} - + {credits ? credits.toFixed(4) : ''} ); }; - if (!sessionStore.user) { + if (!user) { return null; } return ( @@ -47,19 +47,17 @@ export default observer((props) => { - {UserAvatarMedium(sessionStore.user)} + {UserAvatarMedium(user)} - - {sessionStore.user?.displayName} - + {user?.displayName} {renderCreditsSection()} - {sessionStore.user.publicKey ? ( + {user.publicKey ? ( { > - - {sessionStore.user.publicKey} - + {user.publicKey} ) : null} @@ -83,7 +79,7 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ container: { diff --git a/src/profile/WithdrawalModal.tsx b/src/profile/WithdrawalModal.tsx index 044b291..2b6cad9 100644 --- a/src/profile/WithdrawalModal.tsx +++ b/src/profile/WithdrawalModal.tsx @@ -7,18 +7,21 @@ import { TextInput, Platform, } from 'react-native'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import LargeBtn from 'app/src/ui/LargeBtn'; -import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import CloseIcon from 'app/src/ui/icons/x'; import WalletIcon from 'app/src/ui/icons/wallet'; import DollarIcon from 'app/src/ui/icons/dollar'; +import { PaymentsStore } from '../stores/payments.store'; -export default observer((props) => { - const { paymentsStore } = Stores(); +export default (props) => { + const { + credits, + withdrawToExternalWallet, + submittingWithdraw, + } = PaymentsStore(); const { goBack } = useNavigation(); const [address, setAddress] = useState(''); const [creditsToWithdraw, setCreditsToWithdraw] = useState(0); @@ -29,7 +32,7 @@ export default observer((props) => { const updateAmount = ({ target }: any) => { let creditsToWithdraw = parseFloat(target.value); - if (paymentsStore.credits < creditsToWithdraw) { + if (credits < creditsToWithdraw) { return; } @@ -37,7 +40,7 @@ export default observer((props) => { }; const onWithdraw = async () => { - await paymentsStore.withdrawToExternalWallet(address, creditsToWithdraw); + await withdrawToExternalWallet(address, creditsToWithdraw); goBack(); }; @@ -54,9 +57,7 @@ export default observer((props) => { Withdraw credits - - Current balance: {paymentsStore.credits} - + Current balance: {credits} @@ -114,16 +115,12 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ fieldWithoutBorderTop: { diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx index 14d360e..15de567 100644 --- a/src/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -1,18 +1,12 @@ import { Provider } from 'mobx-react'; import React from 'react'; -import { - playerStore, - entryStore, - paymentsStore, - walletConnectStore, -} from 'app/src/stores'; +import { playerStore, entryStore, walletConnectStore } from 'app/src/stores'; export default function Providers(props) { return ( {props.children} diff --git a/src/stores/index.ts b/src/stores/index.ts index 824f692..b8ef5a7 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,16 +1,13 @@ import { PlayerStore } from './player.store'; -import { PaymentsStore } from './payments.store'; import { EntryStore } from './entry.store'; import { WalletConnectStore } from './wallet-connect.store'; export const playerStore = new PlayerStore(); -export const paymentsStore = new PaymentsStore(); export const entryStore = new EntryStore(); export const walletConnectStore = new WalletConnectStore(); export type Stores = { - playerStore: PlayerStore; - paymentsStore: PaymentsStore; - entryStore: EntryStore; walletConnectStore: WalletConnectStore; + entryStore: EntryStore; + playerStore: PlayerStore; }; diff --git a/src/stores/payments.store.ts b/src/stores/payments.store.ts index 5f1d9b9..214592d 100644 --- a/src/stores/payments.store.ts +++ b/src/stores/payments.store.ts @@ -1,94 +1,116 @@ -import { observable } from 'mobx'; import { paymentsBackend } from '../api/payments'; import { entriesBackend } from '../api/entries'; import { Config } from '../config'; - -export class PaymentsStore { - @observable - subscribed: boolean = false; - @observable - subscriptionLoaded: boolean = false; - @observable - credits: number = 0; - @observable - submittingSubscription: boolean = false; - @observable - submittingWithdraw: boolean = false; - @observable - loadingBalance: boolean = false; - @observable - xlmPrice: number = 0; - - @observable - entryPrices: Map = new Map(); - - constructor() {} - - setLoadingBalance(loading: boolean) { - this.loadingBalance = loading; - } - - setSubmittingSubscription(submitting) { - this.submittingSubscription = submitting; - } - - async subscribeUser(cardToken: string) { - this.submittingSubscription = true; +import { atom, useRecoilState } from 'recoil'; + +const subscribedAtom = atom({ + key: 'subscribed', + default: false, +}); +const subscriptionLoadedAtom = atom({ + key: 'subscriptionLoaded', + default: false, +}); +const creditsAtom = atom({ + key: 'credits', + default: 0, +}); +const submittingSubscriptionAtom = atom({ + key: 'submittingSubscription', + default: false, +}); +const submittingWithdrawAtom = atom({ + key: 'submittingWithdraw', + default: false, +}); +const loadingBalanceAtom = atom({ + key: 'loadingBalance', + default: false, +}); +const xlmPriceAtom = atom({ + key: 'xlmPrice', + default: 0, +}); +const entryPricesAtom = atom>({ + key: 'entryPrices', + default: new Map(), +}); + +export const PaymentsStore = () => { + const [submittingSubscription, setSubmittingSubscription] = useRecoilState( + submittingSubscriptionAtom + ); + const [subscribed, setSubscribed] = useRecoilState(subscribedAtom); + const [loadingBalance, setLoadingBalance] = useRecoilState( + loadingBalanceAtom + ); + const [credits, setCredits] = useRecoilState(creditsAtom); + const [subscriptionLoaded, setSubscriptionLoaded] = useRecoilState( + subscriptionLoadedAtom + ); + const [submittingWithdraw, setSubmittingWithdraw] = useRecoilState( + submittingWithdrawAtom + ); + const [xlmPrice, setXlmPrice] = useRecoilState(xlmPriceAtom); + const [entryPrices, setEntryPrices] = useRecoilState(entryPricesAtom); + + const subscribeUser = async (cardToken: string) => { + setSubmittingSubscription(true); await paymentsBackend.subscribe(cardToken); - this.submittingSubscription = false; - this.subscribed = true; + setSubmittingSubscription(false); + setSubscribed(true); return true; - } + }; - async buyCredits(cardToken: string, amount: number) { - this.submittingSubscription = true; + const buyCredits = async (cardToken: string, amount: number) => { + setSubmittingSubscription(true); await paymentsBackend.buyCredits(cardToken, amount); - this.submittingSubscription = false; - this.subscribed = true; + setSubmittingSubscription(false); + setSubscribed(true); return true; - } + }; - async refreshSubscription() { - this.loadingBalance = true; + const refreshSubscription = async () => { + setLoadingBalance(true); let { subscribed, credits } = await paymentsBackend.refreshSubscription(); - this.subscribed = subscribed; - this.credits = credits; - this.subscriptionLoaded = true; - this.loadingBalance = false; - } + setSubscribed(subscribed); + setCredits(credits); + setSubscriptionLoaded(true); + setLoadingBalance(false); + }; - async withdrawToExternalWallet( + const withdrawToExternalWallet = async ( withdrawAddress: string, creditsToWithdraw: number - ) { - this.submittingWithdraw = true; + ) => { + setSubmittingWithdraw(true); await paymentsBackend.withdrawToExternalWallet( withdrawAddress, creditsToWithdraw ); - await this.refreshSubscription(); - this.submittingWithdraw = false; - } + await refreshSubscription(); + setSubmittingWithdraw(false); + }; - public async buyEntry(id: string, amount: number, price: number) { + const buyEntry = async (id: string, amount: number, price: number) => { return await entriesBackend.buyEntry(id, amount, price); - } + }; - public getPriceInfo(id: string) { + const getPriceInfo = (id: string) => { return entriesBackend.getPriceInfo(id); - } + }; - get xlmPriceWithFees() { - return this.xlmPrice * 1.06; - } + const xlmPriceWithFees = () => { + return xlmPrice * 1.06; + }; - public async refreshXLMPrice() { + const refreshXLMPrice = async () => { const price = await paymentsBackend.getXLMPrice(); - this.xlmPrice = parseFloat(price); - } + setXlmPrice(parseFloat(price)); + }; - public async fetchPriceFromHorizon(code: string, issuer: string) { + const fetchPriceFromHorizon = async (code: string, issuer: string) => { let { asks } = await fetch( `${Config.HORIZON_URL}/order_book?selling_asset_type=credit_alphanum12&selling_asset_code=${code}&selling_asset_issuer=${issuer}&buying_asset_type=native` ).then((res: any) => res.json()); @@ -99,19 +121,42 @@ export class PaymentsStore { } return null; - } + }; - public async fetchAndCachePrice(code: string, issuer: string) { + const fetchAndCachePrice = async (code: string, issuer: string) => { const identifier = `${code}-${issuer}`; - const val = this.entryPrices.get(identifier); + const val = entryPrices.get(identifier); if (val) { return val; } - const newval = await this.fetchPriceFromHorizon(code, issuer); + const newval = await fetchPriceFromHorizon(code, issuer); if (newval) { - this.entryPrices.set(identifier, newval); + setEntryPrices((oldValue) => oldValue.set(identifier, newval)); return newval; } return { price: 0, amount: 0 }; - } -} + }; + + return { + fetchAndCachePrice, + fetchPriceFromHorizon, + refreshXLMPrice, + xlmPriceWithFees, + getPriceInfo, + buyEntry, + withdrawToExternalWallet, + refreshSubscription, + buyCredits, + subscribeUser, + entryPrices, + xlmPrice, + submittingSubscription, + submittingWithdraw, + subscriptionLoaded, + credits, + loadingBalance, + subscribed, + setLoadingBalance, + setSubmittingSubscription, + }; +}; diff --git a/src/stores/session.ts b/src/stores/session.ts index 94c612e..fa75e0e 100644 --- a/src/stores/session.ts +++ b/src/stores/session.ts @@ -50,5 +50,5 @@ export const SessionStore = () => { return await signOut(); } - return { requestToken, signUp, signIn, signOut, refreshUser }; + return { requestToken, signUp, signIn, signOut, refreshUser, user }; }; diff --git a/src/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx index 42d84b8..9774f22 100644 --- a/src/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -7,6 +7,7 @@ import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; import { UserEntriesStore } from '../stores/user-entries'; +import { PaymentsStore } from '../stores/payments.store'; export default observer(({ route }) => { const { entry, priceInfo } = route.params; @@ -18,12 +19,13 @@ export default observer(({ route }) => { const { goBack } = useNavigation(); const linkTo = useLinkTo(); - const { paymentsStore, playerStore, walletConnectStore } = Stores(); + const { playerStore, walletConnectStore } = Stores(); + const { buyEntry, refreshSubscription, credits } = PaymentsStore(); const { refreshEntries } = UserEntriesStore(); - const buyEntry = async (id: string) => { + const handleBuyEntry = async (id: string) => { setSubmitting(true); - let { xdr, success, submitted } = await paymentsStore.buyEntry( + let { xdr, success, submitted } = await buyEntry( id, priceInfo.amount, priceInfo.price @@ -34,10 +36,7 @@ export default observer(({ route }) => { setMustSignAndSubmitWithWalletConnect(true); await walletConnectStore.signAndSubmitXdr(xdr); } - await Promise.all([ - await refreshEntries(), - await paymentsStore.refreshSubscription(), - ]); + await Promise.all([await refreshEntries(), await refreshSubscription()]); playerStore.refreshEntry(); setSubmitting(false); goBack(); @@ -46,7 +45,7 @@ export default observer(({ route }) => { } }; - if (!paymentsStore.credits || paymentsStore.credits < entry.price) { + if (!credits || credits < entry.price) { return ( @@ -87,7 +86,7 @@ export default observer(({ route }) => { goBack()} /> - buyEntry(entry.id)} /> + handleBuyEntry(entry.id)} /> ); diff --git a/src/ui/EntryPrice.tsx b/src/ui/EntryPrice.tsx index 770bfb7..f4cae71 100644 --- a/src/ui/EntryPrice.tsx +++ b/src/ui/EntryPrice.tsx @@ -2,16 +2,16 @@ import React, { useEffect, useState } from 'react'; import { StyleSheet, View, Text } from 'react-native'; import DollarIcon from 'app/src/ui/icons/dollar'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import { A } from '@expo/html-elements'; import { stellarAssetLink } from 'app/src/functions/utils'; +import { PaymentsStore } from '../stores/payments.store'; function EntryPrice({ code, issuer }) { const [value, setValue] = useState({ price: 0, amount: 0 }); - const { paymentsStore } = Stores(); + const { fetchAndCachePrice } = PaymentsStore(); const handleFetchPrice = async () => { - setValue(await paymentsStore.fetchAndCachePrice(code, issuer)); + setValue(await fetchAndCachePrice(code, issuer)); }; useEffect(() => { diff --git a/src/ui/buy-btn/BuyBtn.tsx b/src/ui/buy-btn/BuyBtn.tsx index 2ad7669..b78bedf 100644 --- a/src/ui/buy-btn/BuyBtn.tsx +++ b/src/ui/buy-btn/BuyBtn.tsx @@ -1,17 +1,16 @@ import React, { useEffect, useState } from 'react'; import { StyleSheet, Text, View, Pressable } from 'react-native'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import { CommonActions, useNavigation } from '@react-navigation/native'; -import { observer } from 'mobx-react'; import cursorPointer from 'app/src/constants/CursorPointer'; import DollarIcon from 'app/src/ui/icons/dollar'; import tw from 'twin.macro'; +import { PaymentsStore } from 'app/src/stores/payments.store'; const Placeholder = () => ; -export default observer(({ entry }) => { - const { paymentsStore } = Stores(); +export default ({ entry }) => { + const { fetchAndCachePrice, refreshSubscription } = PaymentsStore(); const { dispatch } = useNavigation(); const [priceInfo, setPriceInfo] = useState({ @@ -32,7 +31,7 @@ export default observer(({ entry }) => { }; const getPriceInfo = async () => { - const { price, amount } = await paymentsStore.fetchAndCachePrice( + const { price, amount } = await fetchAndCachePrice( entry.code, entry.issuer ); @@ -42,7 +41,7 @@ export default observer(({ entry }) => { useEffect(() => { if (entry && entry.id) { getPriceInfo(); - paymentsStore.refreshSubscription(); + refreshSubscription(); } }, [entry]); @@ -64,7 +63,7 @@ export default observer(({ entry }) => {
); -}); +}; var styles = StyleSheet.create({ wrap: { From 9bc260a40aab11b354756a72a34d910d8523be23 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Wed, 6 Jul 2022 10:48:39 -0500 Subject: [PATCH 06/13] migrate entry store --- src/hooks/nft-listener.ts | 10 +- src/profile/MediaUpload.tsx | 126 +++++---- src/profile/PaymentModal.native.tsx | 11 +- src/profile/PaymentModal.tsx | 11 +- src/providers/Providers.tsx | 8 +- src/search/PricingOptionsModal.tsx | 45 +-- src/search/RemoveFromMyMusicRow.tsx | 15 +- src/stores/entry.store.ts | 410 +++++++++++++++------------- src/stores/index.ts | 3 - 9 files changed, 345 insertions(+), 294 deletions(-) diff --git a/src/hooks/nft-listener.ts b/src/hooks/nft-listener.ts index 0cdbd80..60e5ca2 100644 --- a/src/hooks/nft-listener.ts +++ b/src/hooks/nft-listener.ts @@ -1,12 +1,12 @@ import { useEffect, useState } from 'react'; -import { Stores } from 'app/src/functions/Stores'; import { Config } from 'app/src/config'; import { userAtom } from '../atoms/atoms'; import { useRecoilValue } from 'recoil'; +import { EntryStore } from '../stores/entry.store'; const EventSource = require('eventsource'); const nftListener = (open) => { - const { entryStore } = Stores(); + const { indexEntry, issuer } = EntryStore(); const user = useRecoilValue(userAtom); const [indexed, setIndexed] = useState(false); @@ -21,9 +21,9 @@ const nftListener = (open) => { es.onmessage = async function (message) { const data = message.data ? JSON.parse(message.data) : message; - if ((data.type = 'payment' && entryStore.issuer === data.asset_issuer)) { - const indexEntry = await entryStore.indexEntry(data.asset_issuer); - if (indexEntry) { + if ((data.type = 'payment' && issuer === data.asset_issuer)) { + const res = await indexEntry(data.asset_issuer); + if (res) { setIndexed(true); } } diff --git a/src/profile/MediaUpload.tsx b/src/profile/MediaUpload.tsx index 50229dc..6fbfb73 100644 --- a/src/profile/MediaUpload.tsx +++ b/src/profile/MediaUpload.tsx @@ -10,7 +10,6 @@ import { Alert, ActivityIndicator, } from 'react-native'; -import { observer } from 'mobx-react'; import * as ImagePicker from 'expo-image-picker'; import * as DocumentPicker from 'expo-document-picker'; import * as Permissions from 'expo-permissions'; @@ -29,6 +28,7 @@ import CheckIcon from 'app/src/ui/icons/check'; import CloseIcon from 'app/src/ui/icons/x'; import nftListener from 'app/src/hooks/nft-listener'; import { UserEntriesStore } from '../stores/user-entries'; +import { EntryStore } from '../stores/entry.store'; const SwitchWeb: any = Switch; @@ -75,15 +75,45 @@ const ArtworkSection = ({ imageSelected, selectArtwork }) => { return ; }; -export default observer(() => { - const { entryStore, walletConnectStore } = Stores(); +export default () => { + const { walletConnectStore } = Stores(); + const { + equityForSale, + setUploadingError, + create, + canCreate, + setLoadingVideo, + setImageBlob, + setVideoBlob, + clearStore, + uploadingError, + clearUploadingError, + setArtist, + artist, + title, + setTitle, + availableForSale, + setAvailableForSale, + description, + setDescription, + setPrice, + price, + setEquityForSale, + equityForSalePercentage, + imageBlob, + videoBlob, + creating, + currentUpload, + loadingVideo, + progress, + } = EntryStore(); const { refreshEntries } = UserEntriesStore(); const linkTo = useLinkTo(); const [openListener, setOpenListener] = useState(false); const { indexed } = nftListener(openListener); - let equityForSaleValue = entryStore.equityForSale; + let equityForSaleValue = equityForSale; const getPermissionAsync = async () => { if (Platform.OS === 'ios' || Platform.OS === 'android') { const { status } = await Permissions.askAsync(Permissions.MEDIA_LIBRARY); @@ -118,21 +148,21 @@ export default observer(() => { }); } catch (e) { console.log('error', e); - entryStore.setUploadingError('Error picking file!'); + setUploadingError('Error picking file!'); } if (video && !video.cancelled) { - entryStore.setLoadingVideo(true); + setLoadingVideo(true); // const isMp4 = video.uri.startsWith('data:video/mp4'); // if (!isMp4) { - // entryStore.setUploadingError('Only mp4 files supported!'); + // setUploadingError('Only mp4 files supported!'); // return; // } const res = await fetch(video.uri); const file = await res.blob(); - entryStore.setLoadingVideo(false); - entryStore.setVideoBlob(file); + setLoadingVideo(false); + setVideoBlob(file); } }; @@ -148,26 +178,24 @@ export default observer(() => { if (image && !image.cancelled) { const isPng = image.uri.startsWith('data:image/png'); if (!isPng) { - entryStore.setUploadingError('Only png files supported!'); + setUploadingError('Only png files supported!'); return; } if (image.height !== image.width) { - return entryStore.setUploadingError('Only square images supported!'); + return setUploadingError('Only square images supported!'); } if (image.width < 3000) { - return entryStore.setUploadingError( - 'Image should be at least 3000px wide!' - ); + return setUploadingError('Image should be at least 3000px wide!'); } const res = await fetch(image.uri); const file = await res.blob(); - entryStore.setImageBlob(file); + setImageBlob(file); } }; const handleIndexedEntry = async () => { await refreshEntries(); - entryStore.clearStore(); + clearStore(); linkTo('/dashboard/profile'); }; @@ -181,18 +209,14 @@ export default observer(() => { const onCreate = async () => { setOpenListener(true); - const res = await entryStore.create(); + const res = await create(); if (!res) { - return entryStore.setUploadingError( - 'Something went wrong. Please try again!' - ); + return setUploadingError('Something went wrong. Please try again!'); } let { xdr, submitted, success } = res; if (!success) { - return entryStore.setUploadingError( - 'Something went very wrong. Please contact us!' - ); + return setUploadingError('Something went very wrong. Please contact us!'); } if (!submitted) { @@ -208,11 +232,11 @@ export default observer(() => { return; }; - if (entryStore.uploadingError) { + if (uploadingError) { return ( entryStore.clearUploadingError()} + uploadingError={uploadingError} + clearUploadingError={() => clearUploadingError()} /> ); } @@ -232,8 +256,8 @@ export default observer(() => { Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, ]} placeholderTextColor="white" - value={entryStore.artist} - onChangeText={(t) => entryStore.updateArtist(t)} + value={artist} + onChangeText={(t) => setArtist(t)} maxLength={34} /> @@ -249,8 +273,8 @@ export default observer(() => { Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, ]} placeholderTextColor="white" - value={entryStore.title} - onChangeText={(t) => entryStore.updateTitle(t)} + value={title} + onChangeText={(t) => setTitle(t)} maxLength={34} /> @@ -266,8 +290,8 @@ export default observer(() => { Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, ]} placeholderTextColor="white" - value={entryStore.description} - onChangeText={(t) => entryStore.updateDescription(t)} + value={description} + onChangeText={(t) => setDescription(t)} maxLength={60} /> @@ -275,9 +299,7 @@ export default observer(() => { { {'Available for Sale: '} - entryStore.updateAvailableForSale(forSale) - } - value={entryStore.availableForSale} + onValueChange={(forSale) => setAvailableForSale(forSale)} + value={availableForSale} style={[ styles.switch, Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, @@ -304,7 +324,7 @@ export default observer(() => { thumbColor={Colors.defaultTextLight} /> - {entryStore.availableForSale && ( + {availableForSale && ( <> @@ -328,8 +348,8 @@ export default observer(() => { Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, ]} placeholderTextColor="white" - value={entryStore.price ? entryStore.price.toString() : ''} - onChangeText={(price) => entryStore.updatePrice(parseInt(price))} + value={price ? price.toString() : ''} + onChangeText={(price) => setPrice(parseInt(price))} maxLength={30} /> @@ -341,7 +361,7 @@ export default observer(() => { numberOfLines={1} > {'Equity for Sale: '} - {entryStore.equityForSalePercentage} + {equityForSalePercentage} { maximumValue={100} value={equityForSaleValue} onValueChange={(target) => { - entryStore.updateEquityForSalePercentage(target); + setEquityForSale(target); }} step={1} minimumTrackTintColor={Colors.brandBlue} @@ -370,7 +390,7 @@ export default observer(() => { {'Artwork: '} @@ -385,9 +405,9 @@ export default observer(() => { @@ -399,13 +419,13 @@ export default observer(() => { { ); -}); +}; const styles = StyleSheet.create({ wrap: { diff --git a/src/profile/PaymentModal.native.tsx b/src/profile/PaymentModal.native.tsx index 603dc95..0ed55fe 100644 --- a/src/profile/PaymentModal.native.tsx +++ b/src/profile/PaymentModal.native.tsx @@ -1,19 +1,18 @@ import React from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import Colors from 'app/src/constants/Colors'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; import CloseIcon from 'app/src/ui/icons/x'; +import { EntryStore } from '../stores/entry.store'; -export default observer((props) => { - let { entryStore } = Stores(); +export default (props) => { + let { clearUploadingError } = EntryStore(); return ( { - entryStore.clearUploadingError(); + clearUploadingError(); props.navigation.goBack(); }} > @@ -25,7 +24,7 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ btn: { diff --git a/src/profile/PaymentModal.tsx b/src/profile/PaymentModal.tsx index 9dae39d..e8f9c68 100644 --- a/src/profile/PaymentModal.tsx +++ b/src/profile/PaymentModal.tsx @@ -1,14 +1,13 @@ import React from 'react'; import { Pressable, StyleSheet, Text, View, Platform } from 'react-native'; import Colors from 'app/src/constants/Colors'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; import { Elements } from '@stripe/react-stripe-js'; import { loadStripe } from '@stripe/stripe-js'; import { Config } from 'app/src/config/index'; import PaymentStep from './PaymentStep'; import cursorPointer from 'app/src/constants/CursorPointer'; import CloseIcon from 'app/src/ui/icons/x'; +import { EntryStore } from '../stores/entry.store'; let stripePromise; @@ -16,15 +15,15 @@ if (Platform.OS === 'web') { stripePromise = loadStripe(Config.STRIPE_PUBLISHABLE_KEY); } -export default observer((props) => { - let { entryStore } = Stores(); +export default (props) => { + let { clearUploadingError } = EntryStore(); return ( { - entryStore.clearUploadingError(); + clearUploadingError(); props.navigation.goBack(); }} > @@ -41,7 +40,7 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ btn: { diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx index 15de567..ea0399e 100644 --- a/src/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -1,14 +1,10 @@ import { Provider } from 'mobx-react'; import React from 'react'; -import { playerStore, entryStore, walletConnectStore } from 'app/src/stores'; +import { playerStore, walletConnectStore } from 'app/src/stores'; export default function Providers(props) { return ( - + {props.children} ); diff --git a/src/search/PricingOptionsModal.tsx b/src/search/PricingOptionsModal.tsx index c2707eb..75cd6a8 100644 --- a/src/search/PricingOptionsModal.tsx +++ b/src/search/PricingOptionsModal.tsx @@ -8,38 +8,43 @@ import { Switch, Platform, } from 'react-native'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import cursorPointer from 'app/src/constants/CursorPointer'; -import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; import Slider from '@react-native-community/slider'; import DollarIcon from 'app/src/ui/icons/dollar'; import PieIcon from 'app/src/ui/icons/pie'; import CircleIcon from 'app/src/ui/icons/circle'; import { UserEntriesStore } from '../stores/user-entries'; +import { EntryStore } from '../stores/entry.store'; const SwitchWeb: any = Switch; -export default observer(({ route }) => { - const { entryStore } = Stores(); +export default ({ route }) => { + const { + equityForSale, + setAvailableForSale, + setPrice, + setEquityForSale, + equityForSalePercentage, + availableForSale, + price, + } = EntryStore(); const { refreshEntries } = UserEntriesStore(); const { goBack } = useNavigation(); const { entry } = route.params; - let equityForSaleValue = entryStore.equityForSale - ? entryStore.equityForSale - : 0; + let equityForSaleValue = equityForSale ? equityForSale : 0; useEffect(() => { if (!entry) return; - entryStore.updateAvailableForSale(entry.forSale); + setAvailableForSale(entry.forSale); if (entry.price) { - entryStore.updatePrice(entry.price); + setPrice(entry.price); } }, []); const handleUpdatePricing = async (entry: any) => { - await entryStore.updatePricing(entry); + await setPrice(entry); refreshEntries(); goBack(); }; @@ -60,9 +65,7 @@ export default observer(({ route }) => { { {'Available for Sale: '} - entryStore.updateAvailableForSale(forSale) - } - value={entryStore.availableForSale} + onValueChange={(forSale) => setAvailableForSale(forSale)} + value={availableForSale} style={styles.switch} activeThumbColor={Colors.defaultTextLight} trackColor={{ @@ -107,8 +108,8 @@ export default observer(({ route }) => { Platform.OS === 'web' ? ({ outlineWidth: 0 } as any) : {}, ]} placeholderTextColor="white" - value={entryStore.price ? String(entryStore.price) : undefined} - onChangeText={(price) => entryStore.updatePrice(parseInt(price))} + value={price ? String(price) : undefined} + onChangeText={(price) => setPrice(parseInt(price))} maxLength={30} /> @@ -120,7 +121,7 @@ export default observer(({ route }) => { numberOfLines={1} > {'Equity for Sale: '} - {entryStore.equityForSalePercentage} + {equityForSalePercentage} { maximumValue={100} value={equityForSaleValue} onValueChange={(target) => { - entryStore.updateEquityForSalePercentage(target); + setEquityForSale(target); }} step={1} minimumTrackTintColor={Colors.brandBlue} @@ -148,7 +149,7 @@ export default observer(({ route }) => { ); -}); +}; const styles = StyleSheet.create({ container: { diff --git a/src/search/RemoveFromMyMusicRow.tsx b/src/search/RemoveFromMyMusicRow.tsx index aa85d18..a1b9889 100644 --- a/src/search/RemoveFromMyMusicRow.tsx +++ b/src/search/RemoveFromMyMusicRow.tsx @@ -1,25 +1,22 @@ import React from 'react'; import { StyleSheet, Pressable, View, Text } from 'react-native'; -import { observer } from 'mobx-react'; import RemoveIcon from 'app/src/ui/icons/remove'; import Colors from 'app/src/constants/Colors'; -import * as stores from 'app/src/stores'; -import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; import { UserEntriesStore } from '../stores/user-entries'; +import { EntryStore } from '../stores/entry.store'; -type Stores = typeof stores; - -export default observer(({ entry }) => { - const { entryStore } = Stores(); +export default ({ entry }) => { + const { remove } = EntryStore(); const { refreshEntries } = UserEntriesStore(); const { goBack } = useNavigation(); const handleRemoveEntry = async () => { - await entryStore.remove(entry.id); + await remove(entry.id); await refreshEntries(); goBack(); }; + if (!entry) { return null; } @@ -31,7 +28,7 @@ export default observer(({ entry }) => { ); -}); +}; var styles = StyleSheet.create({ field: { diff --git a/src/stores/entry.store.ts b/src/stores/entry.store.ts index 3018a7e..c8d6455 100644 --- a/src/stores/entry.store.ts +++ b/src/stores/entry.store.ts @@ -1,116 +1,141 @@ -import { observable, action, computed } from 'mobx'; +import { atom, selector, useRecoilState, useRecoilValue } from 'recoil'; import { nftStorageApi } from '../config/constants'; import { entriesBackend } from '../api/entries'; -export class EntryStore { - @observable uploadingVideo: boolean = false; - @observable - uploadingError!: string; - @observable loadingVideo: boolean = false; - @observable - loadingImage!: boolean; - @observable - description!: string; - @observable - issuer = ''; - @observable - title!: string; - @observable - artist!: string; - @observable - availableForSale!: boolean; - @observable - price: number | undefined; - @observable - equityForSale: number = 1; - @observable - equityForSalePercentage: string = '1 %'; - @observable - filesProgress: { [key: string]: number } = {}; - - @observable - creating: boolean = false; - - @observable - imageBlob: Blob | undefined; - - @observable - videoBlob: Blob | undefined; - - @action - clearUploadingError() { - this.uploadingError = ''; - } - - @action - setIssuer(issuer) { - this.issuer = issuer; - } - - @action - setUploadingError(error) { - this.uploadingError = error; - } - - @action - setLoadingVideo(loading: boolean) { - this.loadingVideo = loading; - } - - @action - updateLoadingImage = (state: boolean) => { - this.loadingImage = state; - }; - - @action - updateUploadingVideo = (state: boolean) => { - this.uploadingVideo = state; - }; - - @action - updateDescription = (text: string) => { - this.description = text; - }; - - @action - updateTitle = (text: string) => { - this.title = text; - }; - - @action - updateArtist = (text: string) => { - this.artist = text; - }; - - @action - updateAvailableForSale = (state: boolean) => { - this.availableForSale = state; - }; - - @action - updatePrice = (price: number) => { - this.price = price; - }; - - @action - updateEquityForSalePercentage = (value: number) => { - this.equityForSale = value; - this.equityForSalePercentage = `${value ? value : 0} %`; +const uploadingVideoAtom = atom({ + key: 'uploadingVideo', + default: false, +}); +const uploadingErrorAtom = atom({ + key: 'uploadingError', + default: '', +}); +const loadingVideoAtom = atom({ + key: 'loadingVideo', + default: false, +}); +const loadingImageAtom = atom({ + key: 'loadingImage', + default: false, +}); +const descriptionAtom = atom({ + key: 'description', + default: '', +}); +const issuerAtom = atom({ + key: 'issuer', + default: '', +}); +const titleAtom = atom({ + key: 'title', + default: '', +}); +const artistAtom = atom({ + key: 'artist', + default: '', +}); +const availableForSaleAtom = atom({ + key: 'availableForSale', + default: false, +}); +const equityForSaleAtom = atom({ + key: 'equityForSale', + default: 1, +}); +const equityForSalePercentageAtom = selector({ + key: 'equityForSalePercentage', + get: ({ get }) => { + const equity = get(equityForSaleAtom); + return `${equity} %`; + }, +}); +const priceAtom = atom({ + key: 'price', + default: 1, +}); +const filesProgressAtom = atom<{ [key: string]: number }>({ + key: 'filesProgress', + default: {}, +}); + +const currentUploadAtom = selector({ + key: 'currentUpload', + get: () => { + return Object.keys(filesProgressAtom).includes('video') + ? 'video' + : Object.keys(filesProgressAtom).includes('meta') + ? 'meta' + : 'none'; + }, +}); +const canCreateAtom = selector({ + key: 'canCreate', + get: ({ get }) => { + return ( + get(imageBlobAtom) && + get(videoBlobAtom) && + get(descriptionAtom) && + get(titleAtom) && + get(artistAtom) + ); + }, +}); +const progressAtom = selector({ + key: 'progress', + get: () => { + return Math.min(...Object.values(filesProgressAtom)); + }, +}); +const creatingAtom = atom({ + key: 'creating', + default: false, +}); +const imageBlobAtom = atom({ + key: 'imageBlob', + default: undefined, +}); +const videoBlobAtom = atom({ + key: 'videoBlob', + default: undefined, +}); + +export const EntryStore = () => { + const [filesProgress, setFilesProgress] = useRecoilState(filesProgressAtom); + const [issuer, setIssuer] = useRecoilState(issuerAtom); + const [uploadingError, setUploadingError] = useRecoilState( + uploadingErrorAtom + ); + const [creating, setCreating] = useRecoilState(creatingAtom); + const [loadingVideo, setLoadingVideo] = useRecoilState(loadingVideoAtom); + const [loadingImage, setLoadingImage] = useRecoilState(loadingImageAtom); + const [uploadingVideo, setUploadingVideo] = useRecoilState( + uploadingVideoAtom + ); + const [description, setDescription] = useRecoilState(descriptionAtom); + const [title, setTitle] = useRecoilState(titleAtom); + const [artist, setArtist] = useRecoilState(artistAtom); + const [availableForSale, setAvailableForSale] = useRecoilState( + availableForSaleAtom + ); + const [price, setPrice] = useRecoilState(priceAtom); + const [equityForSale, setEquityForSale] = useRecoilState(equityForSaleAtom); + const [imageBlob, setImageBlob] = useRecoilState(imageBlobAtom); + const [videoBlob, setVideoBlob] = useRecoilState(videoBlobAtom); + const equityForSalePercentage = useRecoilValue(equityForSalePercentageAtom); + const currentUpload = useRecoilValue(currentUploadAtom); + const canCreate = useRecoilValue(canCreateAtom); + const progress = useRecoilValue(progressAtom); + + const clearUploadingError = () => { + setUploadingError(''); }; - constructor() {} - - setImageBlob(imageBlob) { - this.imageBlob = imageBlob; - } - - setVideoBlob(videoBlob) { - this.videoBlob = videoBlob; - } - - async uploadFile(file: any, id: string) { + const uploadFile = async (file: any, id: string) => { return new Promise((resolve: (value: string) => void, reject) => { - this.filesProgress[id] = 0; + setFilesProgress((oldValue) => { + oldValue[id] = 0; + return oldValue; + }); let xhr = new XMLHttpRequest(); xhr.open('POST', `${nftStorageApi}/upload`, true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); @@ -122,9 +147,15 @@ export class EntryStore { xhr.upload.addEventListener('progress', (e) => { const progress = Math.round((e.loaded * 100.0) / e.total); - this.filesProgress[id] = progress; + setFilesProgress((oldValue) => { + oldValue[id] = progress; + return oldValue; + }); if (progress === 100) { - delete this.filesProgress[id]; + setFilesProgress((oldValue) => { + delete oldValue[id]; + return oldValue; + }); } }); @@ -132,7 +163,7 @@ export class EntryStore { if (xhr.readyState == 4 && xhr.status == 200) { let { value, ok } = JSON.parse(xhr.responseText); if (!ok) { - this.uploadingError = 'Something went wrong!'; + setUploadingError('Something went wrong!'); reject(); return; } @@ -142,13 +173,13 @@ export class EntryStore { xhr.send(file); }); - } + }; - async storeNFT() { - const name = `${this.artist} - ${this.title}`; + const storeNFT = async () => { + const name = `${artist} - ${title}`; const ipfsProtocol = 'ipfs://'; - const code = `${this.title}${this.artist}` + const code = `${title}${artist}` .normalize('NFD') .replace(/\p{Diacritic}/gu, '') .replace(/ /g, '') @@ -158,20 +189,20 @@ export class EntryStore { .toUpperCase(); const [imageCid, videoCid] = [ - await this.uploadFile(this.imageBlob, 'image'), - await this.uploadFile(this.videoBlob, 'video'), + await uploadFile(imageBlob, 'image'), + await uploadFile(videoBlob, 'video'), ]; const imageUrl = `${ipfsProtocol}${imageCid}`; const videoUrl = `${ipfsProtocol}${videoCid}`; const issuer = await entriesBackend.getIssuer(videoCid); - this.setIssuer(issuer); + setIssuer(issuer); if (!issuer) throw 'could not generate issuer'; const json = { name: name, - description: this.description, + description: description, code: code, issuer: issuer, domain: 'skyhitz.io', @@ -184,93 +215,104 @@ export class EntryStore { const blob = new Blob([JSON.stringify(json)], { type: 'application/json' }); - const nftCid = await this.uploadFile(blob, 'meta'); + const nftCid = await uploadFile(blob, 'meta'); return { videoCid, nftCid, imageUrl, videoUrl, code }; - } - - clearStore() { - this.updateUploadingVideo(false); - this.updateLoadingImage(false); - this.updateDescription(''); - this.updateTitle(''); - this.updateArtist(''); - this.updateAvailableForSale(false); - this.updatePrice(0); - this.updateEquityForSalePercentage(1); - this.creating = false; - } - - get currentUpload() { - return Object.keys(this.filesProgress).includes('video') - ? 'video' - : Object.keys(this.filesProgress).includes('meta') - ? 'meta' - : 'none'; - } - - get progress() { - return Math.min(...Object.values(this.filesProgress)); - } + }; - @computed - get canCreate() { - return ( - this.imageBlob && - this.videoBlob && - this.description && - this.title && - this.artist - ); - } + const clearStore = () => { + setUploadingVideo(false); + setLoadingImage(false); + setDescription(''); + setTitle(''); + setArtist(''); + setAvailableForSale(false); + setPrice(0); + setEquityForSale(1); + setCreating(false); + }; - async indexEntry(issuer = this.issuer) { - if (!issuer) return false; - return await entriesBackend.indexEntry(issuer); - } + const indexEntry = async (issuerPayload = issuer) => { + if (!issuerPayload) return false; + return await entriesBackend.indexEntry(issuerPayload); + }; - async create() { - this.creating = true; - const { - videoCid, - nftCid, - imageUrl, - videoUrl, - code, - } = await this.storeNFT(); + const create = async () => { + setCreating(true); + const { videoCid, nftCid, imageUrl, videoUrl, code } = await storeNFT(); if (!nftCid || !imageUrl || !videoUrl) { - this.setUploadingError('Could not store NFT'); + setUploadingError('Could not store NFT'); return; } return await entriesBackend.createFromUpload( videoCid, nftCid, code, - this.availableForSale, - this.price, - this.equityForSale + availableForSale, + price, + equityForSale ); - } + }; - async updatePricing(entry: any) { - if (!this.availableForSale) { + const updatePricing = async (entry: any) => { + if (!availableForSale) { return; } - if (!this.price) { + if (!price) { return; } - if (!this.equityForSale) { + if (!equityForSale) { return; } await entriesBackend.updatePricing( entry.id, - this.price, - this.availableForSale, - this.equityForSale + price, + availableForSale, + equityForSale ); - this.clearStore(); - } + clearStore(); + }; - async remove(entryId: string) { + const remove = async (entryId: string) => { await entriesBackend.remove(entryId); - } -} + }; + + return { + remove, + updatePricing, + create, + indexEntry, + clearStore, + storeNFT, + uploadFile, + clearUploadingError, + filesProgress, + uploadingError, + creating, + loadingVideo, + loadingImage, + uploadingVideo, + setLoadingVideo, + setImageBlob, + setVideoBlob, + equityForSalePercentage, + currentUpload, + canCreate, + progress, + issuer, + equityForSale, + setUploadingError, + setArtist, + artist, + setDescription, + title, + setTitle, + availableForSale, + setAvailableForSale, + description, + price, + setPrice, + setEquityForSale, + imageBlob, + videoBlob, + }; +}; diff --git a/src/stores/index.ts b/src/stores/index.ts index b8ef5a7..3a670ae 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,13 +1,10 @@ import { PlayerStore } from './player.store'; -import { EntryStore } from './entry.store'; import { WalletConnectStore } from './wallet-connect.store'; export const playerStore = new PlayerStore(); -export const entryStore = new EntryStore(); export const walletConnectStore = new WalletConnectStore(); export type Stores = { walletConnectStore: WalletConnectStore; - entryStore: EntryStore; playerStore: PlayerStore; }; From 6cbb8448b11ed8dac525b0bf69628bb54fd9db24 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Wed, 6 Jul 2022 17:32:32 -0500 Subject: [PATCH 07/13] migrate walletconnect store --- src/accounts/SignUpScreen.tsx | 11 +- src/accounts/WalletConnectBtn.tsx | 28 ++--- src/profile/MediaUpload.tsx | 6 +- src/providers/Providers.tsx | 8 +- src/stores/index.ts | 3 - src/stores/wallet-connect.store.ts | 164 ------------------------- src/stores/wallet-connect.ts | 188 +++++++++++++++++++++++++++++ src/ui/BuyOptionsModal.tsx | 11 +- src/ui/LogOutBtn.tsx | 11 +- 9 files changed, 222 insertions(+), 208 deletions(-) delete mode 100644 src/stores/wallet-connect.store.ts create mode 100644 src/stores/wallet-connect.ts diff --git a/src/accounts/SignUpScreen.tsx b/src/accounts/SignUpScreen.tsx index c8200fe..3950bb0 100644 --- a/src/accounts/SignUpScreen.tsx +++ b/src/accounts/SignUpScreen.tsx @@ -9,11 +9,9 @@ import { Platform, } from 'react-native'; import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import { useLinkTo } from '@react-navigation/native'; import ValidationIcon from 'app/src/accounts/ValidationIcon'; -import { Stores } from 'app/src/functions/Stores'; import BackgroundImage from 'app/src/ui/BackgroundImage'; import WalletConnectBtn from 'app/src/accounts/WalletConnectBtn'; import tw from 'twin.macro'; @@ -26,9 +24,10 @@ import { signUpValidAtom, signUpErrorAtom, } from '../atoms/atoms'; +import { WalletConnectStore } from '../stores/wallet-connect'; -export default observer(() => { - const { walletConnectStore } = Stores(); +export default () => { + const { publicKey } = WalletConnectStore(); const { signUp } = SessionStore(); const [usernameValidation, setUsernameValidation] = useRecoilState( usernameValidationErrorAtom @@ -123,7 +122,7 @@ export default observer(() => { username: username, displayName: displayName, email: email, - publicKey: walletConnectStore.publicKey, + publicKey: publicKey, }); setLoading(false); return linkTo('/'); @@ -227,7 +226,7 @@ export default observer(() => { ); -}); +}; var styles = StyleSheet.create({ line: { diff --git a/src/accounts/WalletConnectBtn.tsx b/src/accounts/WalletConnectBtn.tsx index f16b490..c819ec4 100644 --- a/src/accounts/WalletConnectBtn.tsx +++ b/src/accounts/WalletConnectBtn.tsx @@ -1,49 +1,47 @@ import React, { useEffect } from 'react'; import { Pressable, Text } from 'react-native'; import WalletConnectIcon from 'app/src/ui/icons/walletconnect-icon'; -import { Stores } from 'app/src/functions/Stores'; import QRCodeModal from '@walletconnect/qrcode-modal'; -import { observer } from 'mobx-react'; import tw from 'twin.macro'; import { signManageDataOp } from 'app/src/stellar'; +import { WalletConnectStore } from '../stores/wallet-connect'; -export default observer(({ signInWithXDR }: { signInWithXDR?: (_) => {} }) => { - let { walletConnectStore } = Stores(); +export default ({ signInWithXDR }: { signInWithXDR?: (_) => {} }) => { + let { uri, signXdr, publicKey, connect, state } = WalletConnectStore(); useEffect(() => { - if (!walletConnectStore.uri) return QRCodeModal.close(); - QRCodeModal.open(walletConnectStore.uri, () => {}, { + if (!uri) return QRCodeModal.close(); + QRCodeModal.open(uri, () => {}, { desktopLinks: [], mobileLinks: ['lobstr'], }); - }, [walletConnectStore.uri]); + }, [uri]); const handleSignInWithXdr = async (publicKey: string) => { const xdr = await signManageDataOp(publicKey); - const { signedXDR } = await walletConnectStore.signXdr(xdr); + const { signedXDR } = await signXdr(xdr); signInWithXDR && signInWithXDR(signedXDR); }; useEffect(() => { - if (walletConnectStore.publicKey && signInWithXDR) - handleSignInWithXdr(walletConnectStore.publicKey); - }, [walletConnectStore.publicKey]); + if (publicKey && signInWithXDR) handleSignInWithXdr(publicKey); + }, [publicKey]); return ( walletConnectStore.connect()} + onPress={() => connect()} > - {walletConnectStore.state === 'session-proposal' + {state === 'session-proposal' ? 'Waiting for approval' - : walletConnectStore.state === 'session-created' + : state === 'session-created' ? 'Connected' : 'WalletConnect'} ); -}); +}; diff --git a/src/profile/MediaUpload.tsx b/src/profile/MediaUpload.tsx index 6fbfb73..5e003f1 100644 --- a/src/profile/MediaUpload.tsx +++ b/src/profile/MediaUpload.tsx @@ -16,7 +16,6 @@ import * as Permissions from 'expo-permissions'; import Colors from 'app/src/constants/Colors'; import LargeBtn from 'app/src/ui/LargeBtn'; import cursorPointer from 'app/src/constants/CursorPointer'; -import { Stores } from 'app/src/functions/Stores'; import { useLinkTo } from '@react-navigation/native'; import Slider from '@react-native-community/slider'; import PieChartIcon from 'app/src/ui/icons/pie'; @@ -29,6 +28,7 @@ import CloseIcon from 'app/src/ui/icons/x'; import nftListener from 'app/src/hooks/nft-listener'; import { UserEntriesStore } from '../stores/user-entries'; import { EntryStore } from '../stores/entry.store'; +import { WalletConnectStore } from '../stores/wallet-connect'; const SwitchWeb: any = Switch; @@ -76,7 +76,7 @@ const ArtworkSection = ({ imageSelected, selectArtwork }) => { }; export default () => { - const { walletConnectStore } = Stores(); + const { signAndSubmitXdr } = WalletConnectStore(); const { equityForSale, setUploadingError, @@ -222,7 +222,7 @@ export default () => { if (!submitted) { let message; try { - message = await walletConnectStore.signAndSubmitXdr(xdr); + message = await signAndSubmitXdr(xdr); } catch (e) { console.log(e); } diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx index ea0399e..2fe258c 100644 --- a/src/providers/Providers.tsx +++ b/src/providers/Providers.tsx @@ -1,11 +1,7 @@ import { Provider } from 'mobx-react'; import React from 'react'; -import { playerStore, walletConnectStore } from 'app/src/stores'; +import { playerStore } from 'app/src/stores'; export default function Providers(props) { - return ( - - {props.children} - - ); + return {props.children}; } diff --git a/src/stores/index.ts b/src/stores/index.ts index 3a670ae..62f4b4f 100644 --- a/src/stores/index.ts +++ b/src/stores/index.ts @@ -1,10 +1,7 @@ import { PlayerStore } from './player.store'; -import { WalletConnectStore } from './wallet-connect.store'; export const playerStore = new PlayerStore(); -export const walletConnectStore = new WalletConnectStore(); export type Stores = { - walletConnectStore: WalletConnectStore; playerStore: PlayerStore; }; diff --git a/src/stores/wallet-connect.store.ts b/src/stores/wallet-connect.store.ts deleted file mode 100644 index 5c6d07b..0000000 --- a/src/stores/wallet-connect.store.ts +++ /dev/null @@ -1,164 +0,0 @@ -import WalletConnect, { CLIENT_EVENTS } from '@walletconnect/client'; - -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { observable } from 'mobx'; - -const stellarMeta = { - chainName: 'stellar:pubnet', - methods: ['stellar_signAndSubmitXDR', 'stellar_signXDR'], -}; - -export class WalletConnectStore { - client: null | WalletConnect; - session: any; - proposals: Map; - @observable uri: null | string; - @observable state: - | 'disconnected' - | 'paring-proposal' - | 'paring-created' - | 'session-proposal' - | 'session-created'; - @observable publicKey: string = ''; - sessions: any; - - constructor() { - this.state = 'disconnected'; - this.client = null; - this.session = null; - this.uri = null; - this.proposals = new Map(); - WalletConnect.init({ - projectId: '422a527ddc3ed4c5fff60954fcc8ed83', - metadata: { - name: 'Skyhitz', - description: 'Skyhitz', - url: 'https://skyhitz.io', - icons: ['https://skyhitz.io/img/icon-512.png'], - }, - storageOptions: { - asyncStorage: AsyncStorage as any, - }, - }) - .then(async (result) => { - this.client = result; - const itemsStored = await this.client?.storage.keyValueStorage.getItem( - 'wc@2:client:0.3//session:settled' - ); - if (itemsStored && itemsStored.length) { - const [session] = itemsStored; - this.setSession(session); - } - - this.subscribeToEvents(); - }) - .catch((e) => { - console.log(e); - }); - } - - clearState() { - this.state = 'disconnected'; - this.publicKey = ''; - this.session = null; - return AsyncStorage.clear(); - } - - setSession(session) { - this.session = session; - const { state } = session; - const [stellarAccount] = state.accounts; - this.publicKey = stellarAccount.replace(`${stellarMeta.chainName}:`, ''); - this.state = 'session-created'; - return this.publicKey; - } - - async connect() { - try { - return this.setSession( - await this.client?.connect({ - permissions: { - blockchain: { - chains: [stellarMeta.chainName], - }, - jsonrpc: { - methods: stellarMeta.methods, - }, - }, - }) - ); - } catch (e) { - console.log('catched error on reject:', e); - this.state = 'disconnected'; - } - - return this.publicKey; - } - - async disconnect() { - await this.client?.disconnect({ - topic: this.session.topic, - reason: { - code: 1, - message: 'Logged out', - }, - }); - await this.clearState(); - } - - subscribeToEvents() { - console.log('subscribed to events'); - this.client?.on(CLIENT_EVENTS.pairing.proposal, async (proposal) => { - const { uri } = proposal.signal.params; - console.log('pairing proposal'); - this.uri = uri; - this.state = 'paring-proposal'; - }); - - this.client?.on(CLIENT_EVENTS.pairing.created, async (proposal) => { - this.uri = null; - this.state = 'paring-created'; - }); - - this.client?.on(CLIENT_EVENTS.session.proposal, async (proposal) => { - this.state = 'session-proposal'; - }); - - this.client?.on(CLIENT_EVENTS.session.created, async (proposal) => { - this.state = 'session-created'; - }); - - this.client?.on(CLIENT_EVENTS.session.deleted, (session) => { - console.log(session); - this.clearState(); - }); - } - - signXdr(xdr) { - return this.client?.request({ - topic: this.session.topic, - chainId: stellarMeta.chainName, - request: { - jsonrpc: '2.0', - method: 'stellar_signXDR', - params: { - xdr, - }, - } as any, - }); - } - - signAndSubmitXdr(xdr) { - return this.client?.request({ - topic: this.session.topic, - chainId: stellarMeta.chainName, - request: { - jsonrpc: '2.0', - method: 'stellar_signAndSubmitXDR', - params: { - xdr, - }, - } as any, - }); - } -} diff --git a/src/stores/wallet-connect.ts b/src/stores/wallet-connect.ts new file mode 100644 index 0000000..16da5ea --- /dev/null +++ b/src/stores/wallet-connect.ts @@ -0,0 +1,188 @@ +import WalletConnect, { CLIENT_EVENTS } from '@walletconnect/client'; +import { atom, useRecoilState } from 'recoil'; +import { Session } from '@walletconnect/client/dist/cjs/controllers'; +import { useEffect } from 'react'; + +const stellarMeta = { + chainName: 'stellar:pubnet', + methods: ['stellar_signAndSubmitXDR', 'stellar_signXDR'], +}; + +const clientAtom = atom({ + key: 'client', + default: null, +}); + +const uriAtom = atom({ + key: 'uri', + default: null, +}); + +const stateAtom = atom< + | 'disconnected' + | 'paring-proposal' + | 'paring-created' + | 'session-proposal' + | 'session-created' +>({ + key: 'state', + default: 'disconnected', +}); + +const publicKeyAtom = atom({ + key: 'publicKey', +}); + +const sessionAtom = atom({ + key: 'session', +}); + +export const WalletConnectStore = () => { + const [client, setClient] = useRecoilState(clientAtom); + const [uri, setUri] = useRecoilState(uriAtom); + const [state, setState] = useRecoilState(stateAtom); + const [publicKey, setPublicKey] = useRecoilState(publicKeyAtom); + const [session, setSession] = useRecoilState(sessionAtom); + + const init = async () => { + if (client) return; + const result = await WalletConnect.init({ + projectId: '422a527ddc3ed4c5fff60954fcc8ed83', + metadata: { + name: 'Skyhitz', + description: 'Skyhitz', + url: 'https://skyhitz.io', + icons: ['https://skyhitz.io/img/icon-512.png'], + }, + }); + + setClient(result); + if (result.session) { + handleSetSession(result.session); + } + + subscribeToEvents(); + }; + + useEffect(() => { + init(); + }); + + const clearState = () => { + setState('disconnected'); + setPublicKey(''); + handleSetSession(null); + setClient(null); + }; + + const handleSetSession = (session) => { + setSession(session); + const { state } = session; + const [stellarAccount] = state.accounts; + setPublicKey(stellarAccount.replace(`${stellarMeta.chainName}:`, '')); + setState('session-created'); + return publicKey; + }; + + const connect = async () => { + try { + return handleSetSession( + await client?.connect({ + permissions: { + blockchain: { + chains: [stellarMeta.chainName], + }, + jsonrpc: { + methods: stellarMeta.methods, + }, + }, + }) + ); + } catch (e) { + console.log('catched error on reject:', e); + setState('disconnected'); + } + + return publicKey; + }; + + const disconnect = async () => { + await client?.disconnect({ + topic: session.topics[0], + reason: { + code: 1, + message: 'Logged out', + }, + }); + await clearState(); + }; + + const subscribeToEvents = () => { + console.log('subscribed to events'); + client?.on(CLIENT_EVENTS.pairing.proposal, async (proposal) => { + const { uri } = proposal.signal.params; + console.log('pairing proposal'); + setUri(uri); + setState('paring-proposal'); + }); + + client?.on(CLIENT_EVENTS.pairing.created, async (proposal) => { + setUri(null); + setState('paring-created'); + }); + + client?.on(CLIENT_EVENTS.session.proposal, async (proposal) => { + setState('session-proposal'); + }); + + client?.on(CLIENT_EVENTS.session.created, async (proposal) => { + setState('session-created'); + }); + + client?.on(CLIENT_EVENTS.session.deleted, (session) => { + console.log(session); + clearState(); + }); + }; + + const signXdr = (xdr) => { + return client?.request({ + topic: session.topics[0], + chainId: stellarMeta.chainName, + request: { + jsonrpc: '2.0', + method: 'stellar_signXDR', + params: { + xdr, + }, + } as any, + }); + }; + + const signAndSubmitXdr = (xdr) => { + return client?.request({ + topic: session.topics[0], + chainId: stellarMeta.chainName, + request: { + jsonrpc: '2.0', + method: 'stellar_signAndSubmitXDR', + params: { + xdr, + }, + } as any, + }); + }; + return { + signAndSubmitXdr, + signXdr, + subscribeToEvents, + disconnect, + connect, + clearState, + init, + publicKey, + uri, + session, + state, + }; +}; diff --git a/src/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx index 9774f22..528e7b8 100644 --- a/src/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -2,14 +2,14 @@ import React, { useState } from 'react'; import { View, StyleSheet, Text, ActivityIndicator } from 'react-native'; import Colors from 'app/src/constants/Colors'; import LargeBtn from './LargeBtn'; -import { observer } from 'mobx-react'; import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; import { UserEntriesStore } from '../stores/user-entries'; import { PaymentsStore } from '../stores/payments.store'; +import { WalletConnectStore } from '../stores/wallet-connect'; -export default observer(({ route }) => { +export default ({ route }) => { const { entry, priceInfo } = route.params; const [submitting, setSubmitting] = useState(false); const [ @@ -19,7 +19,8 @@ export default observer(({ route }) => { const { goBack } = useNavigation(); const linkTo = useLinkTo(); - const { playerStore, walletConnectStore } = Stores(); + const { playerStore } = Stores(); + const { signAndSubmitXdr } = WalletConnectStore(); const { buyEntry, refreshSubscription, credits } = PaymentsStore(); const { refreshEntries } = UserEntriesStore(); @@ -34,7 +35,7 @@ export default observer(({ route }) => { if (xdr && success) { if (!submitted) { setMustSignAndSubmitWithWalletConnect(true); - await walletConnectStore.signAndSubmitXdr(xdr); + await signAndSubmitXdr(xdr); } await Promise.all([await refreshEntries(), await refreshSubscription()]); playerStore.refreshEntry(); @@ -90,7 +91,7 @@ export default observer(({ route }) => { ); -}); +}; const styles = StyleSheet.create({ container: { diff --git a/src/ui/LogOutBtn.tsx b/src/ui/LogOutBtn.tsx index 72814cf..4240345 100644 --- a/src/ui/LogOutBtn.tsx +++ b/src/ui/LogOutBtn.tsx @@ -1,21 +1,20 @@ import React from 'react'; import { Pressable, StyleSheet } from 'react-native'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; -import { observer } from 'mobx-react'; import LogOutIcon from 'app/src/ui/icons/logout'; import { useLinkTo } from '@react-navigation/native'; import { LikesStore } from '../stores/likes'; import { SessionStore } from '../stores/session'; +import { WalletConnectStore } from '../stores/wallet-connect'; -export default observer(() => { +export default () => { const linkTo = useLinkTo(); - const { walletConnectStore } = Stores(); + const { disconnect } = WalletConnectStore(); const { signOut } = SessionStore(); const { clearLikes } = LikesStore(); const handleLogOut = async () => { - await walletConnectStore.disconnect(); + await disconnect(); await signOut(); linkTo('/'); clearLikes(); @@ -26,7 +25,7 @@ export default observer(() => { ); -}); +}; const styles = StyleSheet.create({ btn: { From de21b295a1e412170bd500c9052ad4a99ad91169 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Thu, 7 Jul 2022 14:49:17 -0500 Subject: [PATCH 08/13] remove mobx --- package.json | 2 - pages/index.tsx | 16 +- src/functions/Stores.ts | 9 - src/hooks/nft-listener.ts | 2 +- src/models/entry.model.ts | 2 + src/navigation/RootNavigation.tsx | 5 +- src/player/player-bar/MiniPlayer.tsx | 18 +- src/player/player-bar/MiniPlayerDesktop.tsx | 13 +- src/player/player-bar/PlayerDrawer.tsx | 15 +- .../play-btn-small/PlayBtnSmall.tsx | 15 +- src/player/player-screen/PlayerEntryInfo.tsx | 11 +- src/player/player-screen/PlayerNav.tsx | 11 +- src/player/player-screen/PlayerScreen.tsx | 13 +- .../player-screen/forward-btn/ForwardBtn.tsx | 26 +- src/player/player-screen/loop-btn/LoopBtn.tsx | 15 +- src/player/player-screen/play-btn/PlayBtn.tsx | 21 +- .../player-screen/play-btn/PlayDesktopBtn.tsx | 21 +- src/player/player-screen/prev-btn/PrevBtn.tsx | 26 +- .../player-screen/shuffle-btn/ShuffleBtn.tsx | 12 +- src/player/player-screen/slider/Slider.tsx | 30 +- .../video-player/FullscreenControl.tsx | 31 +- .../video-player/PlayPauseInvisibleArea.tsx | 13 +- .../video-player/VideoComponent.tsx | 32 +- .../video-player/VideoErrorText.tsx | 12 +- .../video-player/VideoTimeDisplay.tsx | 25 +- src/playlists/LikesRow.tsx | 11 +- src/profile/LowBalanceModal.tsx | 2 +- src/profile/MediaUpload.tsx | 2 +- src/profile/PaymentModal.native.tsx | 2 +- src/profile/PaymentModal.tsx | 2 +- src/profile/PaymentStep.tsx | 2 +- src/profile/ProfileSettingsScreen.tsx | 7 +- src/profile/ProfileSettingsTopContainer.tsx | 2 +- src/profile/WithdrawalModal.tsx | 2 +- src/providers/Providers.tsx | 7 - src/search/ChartsView.tsx | 15 +- src/search/EntryOptionsModal.tsx | 11 +- src/search/PricingOptionsModal.tsx | 2 +- src/search/RecentlyAdded.tsx | 13 +- src/search/RemoveFromMyMusicRow.tsx | 2 +- src/stores/{entry.store.ts => entry.ts} | 0 src/stores/index.ts | 7 - src/stores/{payments.store.ts => payments.ts} | 0 src/stores/player.store.ts | 535 --------------- src/stores/player.ts | 608 ++++++++++++++++++ src/ui/BuyOptionsModal.tsx | 2 +- src/ui/EntryPrice.tsx | 2 +- src/ui/UserRow.tsx | 11 +- src/ui/buy-btn/BuyBtn.tsx | 2 +- yarn.lock | 17 - 50 files changed, 820 insertions(+), 842 deletions(-) delete mode 100644 src/functions/Stores.ts delete mode 100644 src/providers/Providers.tsx rename src/stores/{entry.store.ts => entry.ts} (100%) delete mode 100644 src/stores/index.ts rename src/stores/{payments.store.ts => payments.ts} (100%) delete mode 100644 src/stores/player.store.ts create mode 100644 src/stores/player.ts diff --git a/package.json b/package.json index d47c1cf..a1d5bae 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,6 @@ "graphql-request": "^4.3.0", "list": "^2.0.19", "lodash.debounce": "4.0.8", - "mobx": "5.15.4", - "mobx-react": "6.2.2", "next": "^12.0.1", "next-fonts": "^1.5.1", "next-images": "^1.8.1", diff --git a/pages/index.tsx b/pages/index.tsx index 7ea07ac..173ca00 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,5 +1,5 @@ import 'setimmediate'; -import React, { lazy, Suspense } from 'react'; +import React from 'react'; import { RecoilRoot } from 'recoil'; import RootNavigation from 'app/src/navigation/RootNavigation'; @@ -11,18 +11,8 @@ const errorHandler = (error: Error, stackTrace: string) => { console.log('error', error); /* Log the error to an error reporting service */ }; -const Providers = lazy(() => import('app/src/providers/Providers')); import LoadingScreen from 'app/src/accounts/LoadingScreen'; -const SuspenseLoading = (props) => ( - }>{props.children} -); - -const ProvidersSuspense = (props) => ( - - - -); export default () => { const isLoadingComplete = useCachedResources(); @@ -33,9 +23,7 @@ export default () => { return ( - - - + ); diff --git a/src/functions/Stores.ts b/src/functions/Stores.ts deleted file mode 100644 index acffff0..0000000 --- a/src/functions/Stores.ts +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { MobXProviderContext } from 'mobx-react'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; -import 'mobx-react-lite/batchingForReactDom'; - -export function Stores() { - return React.useContext(MobXProviderContext) as Stores; -} diff --git a/src/hooks/nft-listener.ts b/src/hooks/nft-listener.ts index 60e5ca2..309c015 100644 --- a/src/hooks/nft-listener.ts +++ b/src/hooks/nft-listener.ts @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { Config } from 'app/src/config'; import { userAtom } from '../atoms/atoms'; import { useRecoilValue } from 'recoil'; -import { EntryStore } from '../stores/entry.store'; +import { EntryStore } from '../stores/entry'; const EventSource = require('eventsource'); const nftListener = (open) => { diff --git a/src/models/entry.model.ts b/src/models/entry.model.ts index a2666b1..6c185ad 100644 --- a/src/models/entry.model.ts +++ b/src/models/entry.model.ts @@ -22,6 +22,7 @@ export class EntryPayload extends Payload { price?: number; issuer?: string; code?: string; + artist?: string; } export class Entry extends EntryPayload { @@ -42,6 +43,7 @@ export class Entry extends EntryPayload { this.price = payload.price; this.issuer = payload.issuer; this.code = payload.code; + this.artist = payload.artist; } get isIpfs() { diff --git a/src/navigation/RootNavigation.tsx b/src/navigation/RootNavigation.tsx index 133d777..4cd159e 100644 --- a/src/navigation/RootNavigation.tsx +++ b/src/navigation/RootNavigation.tsx @@ -1,6 +1,5 @@ import React, { useState, useEffect, lazy } from 'react'; import { StatusBar } from 'react-native'; -import { observer } from 'mobx-react'; import { useMediaQuery } from 'react-responsive'; import LoadingScreen from 'app/src/accounts/LoadingScreen'; import { SuspenseLoading } from './SuspenseLoading'; @@ -29,7 +28,7 @@ const LazyNavigationContainerSuspense = (props) => (
); -export default observer(() => { +export default () => { const [loaded, setLoaded] = useState(false); const user = useRecoilValue(userAtom); @@ -59,4 +58,4 @@ export default observer(() => { ); } return ; -}); +}; diff --git a/src/player/player-bar/MiniPlayer.tsx b/src/player/player-bar/MiniPlayer.tsx index 0b0ab17..6d35471 100644 --- a/src/player/player-bar/MiniPlayer.tsx +++ b/src/player/player-bar/MiniPlayer.tsx @@ -1,21 +1,17 @@ -import { observer } from 'mobx-react'; import React from 'react'; import { View, Text, StyleSheet, Pressable } from 'react-native'; -import { Stores } from 'app/src/functions/Stores'; import Colors from 'app/src/constants/Colors'; import PlayBtnSmall from './play-btn-small/PlayBtnSmall'; import cursorPointer from 'app/src/constants/CursorPointer'; import ChevronUpIcon from 'app/src/ui/icons/chevron-up'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(() => { - let { playerStore } = Stores(); +export default () => { + const { setShow, entry } = PlayerStore(); return ( - playerStore.showPlayer()} - style={[cursorPointer]} - > + setShow(true)} style={[cursorPointer]}> @@ -25,16 +21,14 @@ export default observer(() => { ellipsizeMode="tail" numberOfLines={1} > - {playerStore.entry - ? playerStore.entry.title + ' - ' + playerStore.entry.artist - : ''} + {entry ? entry.title + ' - ' + entry.artist : ''} ); -}); +}; let styles = StyleSheet.create({ bg: { diff --git a/src/player/player-bar/MiniPlayerDesktop.tsx b/src/player/player-bar/MiniPlayerDesktop.tsx index 049194c..decd6a2 100644 --- a/src/player/player-bar/MiniPlayerDesktop.tsx +++ b/src/player/player-bar/MiniPlayerDesktop.tsx @@ -12,25 +12,24 @@ import { import Slider from '../player-screen/slider/Slider'; import VideoComponent from '../player-screen/video-player/VideoComponent'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; -import { observer } from 'mobx-react'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(() => { - let { playerStore } = Stores(); +export default () => { + let { entry } = PlayerStore(); return ( - {playerStore.entry?.title} + {entry?.title} - {playerStore.entry?.artist} + {entry?.artist} @@ -51,7 +50,7 @@ export default observer(() => { ); -}); +}; let styles = StyleSheet.create({ rowControls: { diff --git a/src/player/player-bar/PlayerDrawer.tsx b/src/player/player-bar/PlayerDrawer.tsx index 9ceceff..11b80ed 100644 --- a/src/player/player-bar/PlayerDrawer.tsx +++ b/src/player/player-bar/PlayerDrawer.tsx @@ -1,14 +1,13 @@ import React, { useEffect } from 'react'; -import { observer } from 'mobx-react'; import { StyleSheet, Dimensions } from 'react-native'; import PlayerScreen from '../player-screen/PlayerScreen'; import MiniPlayer from './MiniPlayer'; import { State } from 'react-native-gesture-handler'; import { getBottomSpace } from 'react-native-iphone-x-helper'; import { clamp, timing, withSpring } from 'react-native-redash/lib/module/v1'; -import { Stores } from 'app/src/functions/Stores'; import Colors from 'app/src/constants/Colors'; import Animated from 'react-native-reanimated'; +import { PlayerStore } from 'app/src/stores/player'; let tabNavBottom = 89; @@ -48,8 +47,8 @@ const state = new Value(State.UNDETERMINED); const offset = new Value(SNAP_BOTTOM); const clock = new Clock(); -export default observer(({ children }) => { - const { playerStore } = Stores(); +export default ({ children }) => { + const { show, entry } = PlayerStore(); const translateY = withSpring({ value: clamp(translationY, SNAP_TOP, SNAP_BOTTOM), @@ -85,12 +84,12 @@ export default observer(({ children }) => { }); useEffect(() => { - if (playerStore.show) { + if (show) { goUp.setValue(1 as any); } else { goDown.setValue(1 as any); } - }, [playerStore.show]); + }, [show]); useCode( () => @@ -126,7 +125,7 @@ export default observer(({ children }) => { { ); -}); +}; let styles = StyleSheet.create({ playerSheet: { diff --git a/src/player/player-bar/play-btn-small/PlayBtnSmall.tsx b/src/player/player-bar/play-btn-small/PlayBtnSmall.tsx index 92cf8b6..f942dd7 100644 --- a/src/player/player-bar/play-btn-small/PlayBtnSmall.tsx +++ b/src/player/player-bar/play-btn-small/PlayBtnSmall.tsx @@ -1,19 +1,18 @@ import React from 'react'; -import { observer } from 'mobx-react'; import { StyleSheet, Pressable } from 'react-native'; import Play from 'app/src/ui/icons/play'; import Pause from 'app/src/ui/icons/pause'; -import { Stores } from 'app/src/functions/Stores'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(() => { - let { playerStore } = Stores(); +export default () => { + let { isPlaying, pauseAsync, playAsync } = PlayerStore(); - if (playerStore.isPlaying) { + if (isPlaying()) { return ( playerStore.pauseAsync()} + onPress={() => pauseAsync()} > @@ -22,12 +21,12 @@ export default observer(() => { return ( playerStore.playAsync()} + onPress={() => playAsync()} > ); -}); +}; let styles = StyleSheet.create({ playBtnWrapper: { diff --git a/src/player/player-screen/PlayerEntryInfo.tsx b/src/player/player-screen/PlayerEntryInfo.tsx index 587faf7..dbfc8b6 100644 --- a/src/player/player-screen/PlayerEntryInfo.tsx +++ b/src/player/player-screen/PlayerEntryInfo.tsx @@ -1,12 +1,9 @@ import React from 'react'; import { StyleSheet, View, Text } from 'react-native'; -import { inject } from 'mobx-react'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; +import { PlayerStore } from 'app/src/stores/player'; -const PlayerEntryInfo = inject((stores: Stores) => ({ - entry: stores.playerStore.entry, -}))(({ entry }: any) => { +const PlayerEntryInfo = () => { + const { entry } = PlayerStore(); if (!entry) { return null; } @@ -24,7 +21,7 @@ const PlayerEntryInfo = inject((stores: Stores) => ({ ); -}); +}; export default PlayerEntryInfo; diff --git a/src/player/player-screen/PlayerNav.tsx b/src/player/player-screen/PlayerNav.tsx index 4611048..07f9cac 100644 --- a/src/player/player-screen/PlayerNav.tsx +++ b/src/player/player-screen/PlayerNav.tsx @@ -1,23 +1,22 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; import ChevronDown from 'app/src/ui/icons/chevron-down'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(({ onPress }) => { - let { playerStore } = Stores(); +export default ({ onPress }) => { + let { entry } = PlayerStore(); return ( - {playerStore.entry?.artist} + {entry?.artist} ); -}); +}; let styles = StyleSheet.create({ playerNav: { diff --git a/src/player/player-screen/PlayerScreen.tsx b/src/player/player-screen/PlayerScreen.tsx index 852ee3a..806ce75 100644 --- a/src/player/player-screen/PlayerScreen.tsx +++ b/src/player/player-screen/PlayerScreen.tsx @@ -13,9 +13,8 @@ import BuyBtn from 'app/src/ui/buy-btn/BuyBtn'; import PlayerControls from './player-controls/PlayerControls'; import LikersSection from './likers-section/LikersSection'; import Colors from 'app/src/constants/Colors'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { PlayerStore } from 'app/src/stores/player'; const { width } = Dimensions.get('window'); const styles = StyleSheet.create({ @@ -62,24 +61,24 @@ const styles = StyleSheet.create({ }, }); -export default observer(() => { - let { playerStore } = Stores(); +export default () => { + let { hidePlayer, entry } = PlayerStore(); return ( playerStore.hidePlayer()} + onPress={() => hidePlayer()} > - + ); -}); +}; diff --git a/src/player/player-screen/forward-btn/ForwardBtn.tsx b/src/player/player-screen/forward-btn/ForwardBtn.tsx index 104936a..e382b12 100644 --- a/src/player/player-screen/forward-btn/ForwardBtn.tsx +++ b/src/player/player-screen/forward-btn/ForwardBtn.tsx @@ -1,22 +1,22 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; -import { inject } from 'mobx-react'; -import * as stores from 'app/src/stores'; import SkipForwardIcon from 'app/src/ui/icons/skip-forward'; import cursorPointer from 'app/src/constants/CursorPointer'; import Colors from 'app/src/constants/Colors'; -type Stores = typeof stores; +import { PlayerStore } from 'app/src/stores/player'; -const ForwardBtn = inject((stores: Stores) => ({ - playNext: stores.playerStore.playNext.bind(stores.playerStore), -}))(({ playNext, size = 24 }: any) => ( - playNext()} - > - - -)); +const ForwardBtn = ({ size = 24 }) => { + const { playNext } = PlayerStore(); + + return ( + playNext()} + > + + + ); +}; export default ForwardBtn; diff --git a/src/player/player-screen/loop-btn/LoopBtn.tsx b/src/player/player-screen/loop-btn/LoopBtn.tsx index 39e66f5..4e62704 100644 --- a/src/player/player-screen/loop-btn/LoopBtn.tsx +++ b/src/player/player-screen/loop-btn/LoopBtn.tsx @@ -1,19 +1,18 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; import LoopIcon from 'app/src/ui/icons/repeat'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(({ size = 20 }) => { - let { playerStore } = Stores(); +export default ({ size = 20 }) => { + const { toggleLoop, loop } = PlayerStore(); - if (playerStore.loop) { + if (loop) { return ( playerStore.toggleLoop()} + onPress={() => toggleLoop()} > @@ -22,12 +21,12 @@ export default observer(({ size = 20 }) => { return ( playerStore.toggleLoop()} + onPress={() => toggleLoop()} > ); -}); +}; var styles = StyleSheet.create({ controlTouch: { diff --git a/src/player/player-screen/play-btn/PlayBtn.tsx b/src/player/player-screen/play-btn/PlayBtn.tsx index fe12ca5..8622dc8 100644 --- a/src/player/player-screen/play-btn/PlayBtn.tsx +++ b/src/player/player-screen/play-btn/PlayBtn.tsx @@ -1,23 +1,22 @@ import React from 'react'; import { StyleSheet, View, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; import { ReplayIcon, Spinner, } from 'app/src/player/player-screen/video-player/VideoIcons'; -import { Stores } from 'app/src/functions/Stores'; import cursorPointer from 'app/src/constants/CursorPointer'; import PlayIcon from 'app/src/ui/icons/play'; import PauseIcon from 'app/src/ui/icons/pause'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(() => { - let { playerStore } = Stores(); +export default () => { + let { togglePlay, playbackState, replay } = PlayerStore(); - if (playerStore.playbackState === 'PAUSED') { + if (playbackState === 'PAUSED') { return ( playerStore.togglePlay()} + onPress={() => togglePlay()} > @@ -27,11 +26,11 @@ export default observer(() => { ); } - if (playerStore.playbackState === 'PLAYING') { + if (playbackState === 'PLAYING') { return ( playerStore.togglePlay()} + onPress={() => togglePlay()} > @@ -41,11 +40,11 @@ export default observer(() => { ); } - if (playerStore.playbackState === 'ENDED') { + if (playbackState === 'ENDED') { return ( playerStore.replay()} + onPress={() => replay()} > @@ -62,7 +61,7 @@ export default observer(() => { ); -}); +}; var styles = StyleSheet.create({ controlTouch: { diff --git a/src/player/player-screen/play-btn/PlayDesktopBtn.tsx b/src/player/player-screen/play-btn/PlayDesktopBtn.tsx index d03696e..aa2564a 100644 --- a/src/player/player-screen/play-btn/PlayDesktopBtn.tsx +++ b/src/player/player-screen/play-btn/PlayDesktopBtn.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { StyleSheet, View, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; import PlayIcon from 'app/src/ui/icons/play'; import PauseIcon from 'app/src/ui/icons/pause'; @@ -8,17 +7,17 @@ import { ReplayIcon, Spinner, } from 'app/src/player/player-screen/video-player/VideoIcons'; -import { Stores } from 'app/src/functions/Stores'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(({ size = 28 }) => { - let { playerStore } = Stores(); +export default ({ size = 28 }) => { + let { togglePlay, playbackState, replay } = PlayerStore(); - if (playerStore.playbackState === 'PAUSED') { + if (playbackState === 'PAUSED') { return ( playerStore.togglePlay()} + onPress={() => togglePlay()} > @@ -28,11 +27,11 @@ export default observer(({ size = 28 }) => { ); } - if (playerStore.playbackState === 'PLAYING') { + if (playbackState === 'PLAYING') { return ( playerStore.togglePlay()} + onPress={() => togglePlay()} > @@ -42,11 +41,11 @@ export default observer(({ size = 28 }) => { ); } - if (playerStore.playbackState === 'ENDED') { + if (playbackState === 'ENDED') { return ( playerStore.replay()} + onPress={() => replay()} > @@ -63,7 +62,7 @@ export default observer(({ size = 28 }) => { ); -}); +}; var styles = StyleSheet.create({ controlTouch: { diff --git a/src/player/player-screen/prev-btn/PrevBtn.tsx b/src/player/player-screen/prev-btn/PrevBtn.tsx index e95d1d2..98b0524 100644 --- a/src/player/player-screen/prev-btn/PrevBtn.tsx +++ b/src/player/player-screen/prev-btn/PrevBtn.tsx @@ -1,22 +1,20 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; -import { inject } from 'mobx-react'; -import * as stores from 'app/src/stores'; import SkipBackwardIcon from 'app/src/ui/icons/skip-backward'; import cursorPointer from 'app/src/constants/CursorPointer'; +import { PlayerStore } from 'app/src/stores/player'; -type Stores = typeof stores; - -const PrevBtn = inject((stores: Stores) => ({ - playPrev: stores.playerStore.playPrev.bind(stores.playerStore), -}))(({ playPrev, size = 24 }: any) => ( - playPrev()} - > - - -)); +const PrevBtn = ({ size = 24 }) => { + const { playPrev } = PlayerStore(); + return ( + playPrev()} + > + + + ); +}; export default PrevBtn; diff --git a/src/player/player-screen/shuffle-btn/ShuffleBtn.tsx b/src/player/player-screen/shuffle-btn/ShuffleBtn.tsx index c5b8e9b..bb81276 100644 --- a/src/player/player-screen/shuffle-btn/ShuffleBtn.tsx +++ b/src/player/player-screen/shuffle-btn/ShuffleBtn.tsx @@ -1,16 +1,12 @@ import React from 'react'; import { StyleSheet, Pressable } from 'react-native'; -import { inject } from 'mobx-react'; -import * as stores from 'app/src/stores'; import ShuffleIcon from 'app/src/ui/icons/shuffle'; import Colors from 'app/src/constants/Colors'; import cursorPointer from 'app/src/constants/CursorPointer'; -type Stores = typeof stores; +import { PlayerStore } from 'app/src/stores/player'; -const ShuffleBtn = inject((stores: Stores) => ({ - toggleShuffle: stores.playerStore.toggleShuffle.bind(stores.playerStore), - shuffle: stores.playerStore.shuffle, -}))(({ toggleShuffle, shuffle, size = 20 }: any) => { +const ShuffleBtn = ({ size = 20 }) => { + const { toggleShuffle, shuffle } = PlayerStore(); if (shuffle) { return ( ({ ); -}); +}; export default ShuffleBtn; diff --git a/src/player/player-screen/slider/Slider.tsx b/src/player/player-screen/slider/Slider.tsx index 0ebf139..6e98610 100644 --- a/src/player/player-screen/slider/Slider.tsx +++ b/src/player/player-screen/slider/Slider.tsx @@ -1,19 +1,25 @@ import React from 'react'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import { Pressable } from 'react-native'; import Slider from '@react-native-community/slider'; +import { PlayerStore } from 'app/src/stores/player'; -export default observer(() => { - const { playerStore } = Stores(); +export default () => { + const { + onSeekBarTap, + onSliderLayout, + seekPosition, + setSliding, + onSeekSliderValueChange, + onSeekSliderSlidingComplete, + } = PlayerStore(); return ( { - playerStore.onSeekBarTap(evt); + onSeekBarTap(evt); }} onLayout={(evt) => { - playerStore.onSliderLayout(evt); + onSliderLayout(evt); }} style={{ zIndex: 15, @@ -24,14 +30,14 @@ export default observer(() => { style={{ flex: 1 }} minimumValue={0} maximumValue={1} - value={playerStore.seekPosition} + value={seekPosition} onSlidingStart={(_) => { - playerStore.setSliding(true); - playerStore.onSeekSliderValueChange(); + setSliding(true); + onSeekSliderValueChange(); }} onSlidingComplete={(value) => { - playerStore.setSliding(false); - playerStore.onSeekSliderSlidingComplete(value); + setSliding(false); + onSeekSliderSlidingComplete(value); }} minimumTrackTintColor={Colors.brandBlue} maximumTrackTintColor={Colors.backgroundTrackColor} @@ -39,4 +45,4 @@ export default observer(() => { /> ); -}); +}; diff --git a/src/player/player-screen/video-player/FullscreenControl.tsx b/src/player/player-screen/video-player/FullscreenControl.tsx index ed7b7af..4c695f3 100644 --- a/src/player/player-screen/video-player/FullscreenControl.tsx +++ b/src/player/player-screen/video-player/FullscreenControl.tsx @@ -1,28 +1,19 @@ import React from 'react'; -import { inject } from 'mobx-react'; import Control from 'app/src/player/player-screen/video-player/Control'; import { FullscreenEnterIcon, FullscreenExitIcon, } from 'app/src/player/player-screen/video-player/VideoIcons'; -import * as stores from 'app/src/stores'; import cursorPointer from 'app/src/constants/CursorPointer'; -type Stores = typeof stores; +import { PlayerStore } from 'app/src/stores/player'; -const FullscreenControl = inject((stores: Stores) => ({ - isOnFullScreenMode: stores.playerStore.isOnFullScreenMode, - presentFullscreenPlayer: stores.playerStore.presentFullscreenPlayer.bind( - stores.playerStore - ), - dismissFullscreenPlayer: stores.playerStore.dismissFullscreenPlayer.bind( - stores.playerStore - ), -}))( - ({ - isOnFullScreenMode, +const FullscreenControl = () => { + const { + fullscreen, presentFullscreenPlayer, dismissFullscreenPlayer, - }: any) => ( + } = PlayerStore(); + return ( ({ ]} center={false} callback={() => { - isOnFullScreenMode - ? dismissFullscreenPlayer() - : presentFullscreenPlayer(); + fullscreen ? dismissFullscreenPlayer() : presentFullscreenPlayer(); }} > - {isOnFullScreenMode ? : } + {fullscreen ? : } - ) -); + ); +}; export default FullscreenControl; diff --git a/src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx b/src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx index 53fd409..e971e6e 100644 --- a/src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx +++ b/src/player/player-screen/video-player/PlayPauseInvisibleArea.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { TouchableWithoutFeedback, View } from 'react-native'; -import { inject } from 'mobx-react'; import { PLAYBACK_STATES, SEEK_STATES, @@ -9,14 +8,10 @@ import { videoHeight, videoWidth, } from 'app/src/player/player-screen/video-player/VideoConstants'; -import * as stores from 'app/src/stores'; -type Stores = typeof stores; +import { PlayerStore } from 'app/src/stores/player'; -const PlayPauseInvisibleArea = inject((stores: Stores) => ({ - playbackState: stores.playerStore.playbackState, - seekState: stores.playerStore.seekState, - togglePlay: stores.playerStore.togglePlay.bind(stores.playerStore), -}))(({ playbackState, seekState, togglePlay }: any) => { +const PlayPauseInvisibleArea = () => { + const { playbackState, seekState, togglePlay } = PlayerStore(); if ( (seekState == SEEK_STATES.NOT_SEEKING || seekState == SEEK_STATES.SEEKED) && (playbackState == PLAYBACK_STATES.PLAYING || @@ -39,6 +34,6 @@ const PlayPauseInvisibleArea = inject((stores: Stores) => ({ ); } return null; -}); +}; export default PlayPauseInvisibleArea; diff --git a/src/player/player-screen/video-player/VideoComponent.tsx b/src/player/player-screen/video-player/VideoComponent.tsx index 979a272..fc99d35 100644 --- a/src/player/player-screen/video-player/VideoComponent.tsx +++ b/src/player/player-screen/video-player/VideoComponent.tsx @@ -1,6 +1,5 @@ +import { PlayerStore } from 'app/src/stores/player'; import { Video, Audio } from 'expo-av'; -import { observer } from 'mobx-react'; -import { Stores } from 'app/src/functions/Stores'; import { useState } from 'react'; import tw from 'twin.macro'; import BlurImageBackground from './BlurImageBackground'; @@ -15,8 +14,15 @@ Audio.setAudioModeAsync({ playThroughEarpieceAndroid: false, }); -export default observer(({ desktop = false }) => { - let { playerStore } = Stores(); +export default ({ desktop = false }) => { + const { + entry, + streamUrl, + onPlaybackStatusUpdate, + mountVideo, + onFullscreenUpdate, + onError, + } = PlayerStore(); const [loading, setLoading] = useState(false); const [hasVideo, setHasVideo] = useState(false); @@ -25,22 +31,22 @@ export default observer(({ desktop = false }) => { image={ loading || !hasVideo ? desktop - ? playerStore.entry?.imageUrlSmall - : playerStore.entry?.imageSrc + ? entry?.imageUrlSmall + : entry?.imageSrc : null } - style={[playerStore.streamUrl && tw`bg-blue-dark`]} + style={[streamUrl && tw`bg-blue-dark`]} intensity={0} > ); -}); +}; let styles = StyleSheet.create({ rowWrap: { diff --git a/src/profile/LowBalanceModal.tsx b/src/profile/LowBalanceModal.tsx index e728ff6..9fd6b6c 100644 --- a/src/profile/LowBalanceModal.tsx +++ b/src/profile/LowBalanceModal.tsx @@ -16,7 +16,7 @@ import WalletIcon from 'app/src/ui/icons/wallet'; import DollarIcon from 'app/src/ui/icons/dollar'; import { userAtom } from '../atoms/atoms'; import { useRecoilValue } from 'recoil'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; export default (props) => { const { credits } = PaymentsStore(); diff --git a/src/profile/MediaUpload.tsx b/src/profile/MediaUpload.tsx index 5e003f1..dda9523 100644 --- a/src/profile/MediaUpload.tsx +++ b/src/profile/MediaUpload.tsx @@ -27,7 +27,7 @@ import CheckIcon from 'app/src/ui/icons/check'; import CloseIcon from 'app/src/ui/icons/x'; import nftListener from 'app/src/hooks/nft-listener'; import { UserEntriesStore } from '../stores/user-entries'; -import { EntryStore } from '../stores/entry.store'; +import { EntryStore } from '../stores/entry'; import { WalletConnectStore } from '../stores/wallet-connect'; const SwitchWeb: any = Switch; diff --git a/src/profile/PaymentModal.native.tsx b/src/profile/PaymentModal.native.tsx index 0ed55fe..70ca752 100644 --- a/src/profile/PaymentModal.native.tsx +++ b/src/profile/PaymentModal.native.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; import Colors from 'app/src/constants/Colors'; import CloseIcon from 'app/src/ui/icons/x'; -import { EntryStore } from '../stores/entry.store'; +import { EntryStore } from '../stores/entry'; export default (props) => { let { clearUploadingError } = EntryStore(); diff --git a/src/profile/PaymentModal.tsx b/src/profile/PaymentModal.tsx index e8f9c68..960ab0b 100644 --- a/src/profile/PaymentModal.tsx +++ b/src/profile/PaymentModal.tsx @@ -7,7 +7,7 @@ import { Config } from 'app/src/config/index'; import PaymentStep from './PaymentStep'; import cursorPointer from 'app/src/constants/CursorPointer'; import CloseIcon from 'app/src/ui/icons/x'; -import { EntryStore } from '../stores/entry.store'; +import { EntryStore } from '../stores/entry'; let stripePromise; diff --git a/src/profile/PaymentStep.tsx b/src/profile/PaymentStep.tsx index f9f2156..e412c1f 100644 --- a/src/profile/PaymentStep.tsx +++ b/src/profile/PaymentStep.tsx @@ -12,7 +12,7 @@ import { P, H3 } from '@expo/html-elements'; import Colors from 'app/src/constants/Colors'; import { useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; async function timeout(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/src/profile/ProfileSettingsScreen.tsx b/src/profile/ProfileSettingsScreen.tsx index 669a03a..83d27a4 100644 --- a/src/profile/ProfileSettingsScreen.tsx +++ b/src/profile/ProfileSettingsScreen.tsx @@ -1,7 +1,6 @@ import React, { useEffect } from 'react'; import { View, StyleSheet } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import ProfileSettingsTopContainer from 'app/src/profile/ProfileSettingsTopContainer'; import ShareAppBanner from 'app/src/marketing/ShareAppBanner'; @@ -17,9 +16,9 @@ import ChevronLeftIcon from 'app/src/ui/icons/chevron-left'; import tw from 'twin.macro'; import { UserEntriesStore } from '../stores/user-entries'; import { LikesStore } from '../stores/likes'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; -const ProfileSettingsScreen = observer(() => { +const ProfileSettingsScreen = () => { let { refreshSubscription, credits } = PaymentsStore(); const { refreshLikes } = LikesStore(); const { refreshEntries } = UserEntriesStore(); @@ -42,7 +41,7 @@ const ProfileSettingsScreen = observer(() => { ); -}); +}; const ProfileSettingsStack = createStackNavigator(); diff --git a/src/profile/ProfileSettingsTopContainer.tsx b/src/profile/ProfileSettingsTopContainer.tsx index e5dd436..00a05cd 100644 --- a/src/profile/ProfileSettingsTopContainer.tsx +++ b/src/profile/ProfileSettingsTopContainer.tsx @@ -8,7 +8,7 @@ import DollarIcon from 'app/src/ui/icons/dollar'; import WalletIcon from 'app/src/ui/icons/wallet'; import { A } from '@expo/html-elements'; import { stellarAccountLink } from 'app/src/functions/utils'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; import { userAtom } from '../atoms/atoms'; import { useRecoilValue } from 'recoil'; diff --git a/src/profile/WithdrawalModal.tsx b/src/profile/WithdrawalModal.tsx index 2b6cad9..e1dfe8a 100644 --- a/src/profile/WithdrawalModal.tsx +++ b/src/profile/WithdrawalModal.tsx @@ -14,7 +14,7 @@ import cursorPointer from 'app/src/constants/CursorPointer'; import CloseIcon from 'app/src/ui/icons/x'; import WalletIcon from 'app/src/ui/icons/wallet'; import DollarIcon from 'app/src/ui/icons/dollar'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; export default (props) => { const { diff --git a/src/providers/Providers.tsx b/src/providers/Providers.tsx deleted file mode 100644 index 2fe258c..0000000 --- a/src/providers/Providers.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { Provider } from 'mobx-react'; -import React from 'react'; -import { playerStore } from 'app/src/stores'; - -export default function Providers(props) { - return {props.children}; -} diff --git a/src/search/ChartsView.tsx b/src/search/ChartsView.tsx index 788203a..40cce5f 100644 --- a/src/search/ChartsView.tsx +++ b/src/search/ChartsView.tsx @@ -5,12 +5,11 @@ import Colors from 'app/src/constants/Colors'; import SearchingLoader from '../ui/SearchingLoader'; import EntryChartRow from '../ui/EntryChartRow'; import ResponsiveLayout from '../ui/ResponsiveLayout'; -import { Stores } from 'app/src/functions/Stores'; -import { observer } from 'mobx-react'; import { SearchStore } from '../stores/search'; +import { PlayerStore } from '../stores/player'; -export default observer((props) => { - const { playerStore } = Stores(); +export default (props) => { + const { loadAndPlay, setPlaylistModeFromArray } = PlayerStore(); const { topChart, hasMoreTopChart, @@ -22,12 +21,10 @@ export default observer((props) => { return ( playerStore.loadAndPlay(item)} + play={() => loadAndPlay(item)} entry={item} options={null} - disablePlaylistMode={() => - playerStore.setPlaylistModeFromArray(topChart) - } + disablePlaylistMode={() => setPlaylistModeFromArray(topChart)} previousScreen={null} position={index + 1} /> @@ -65,7 +62,7 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ container: { diff --git a/src/search/EntryOptionsModal.tsx b/src/search/EntryOptionsModal.tsx index 537f8bb..d66eb19 100644 --- a/src/search/EntryOptionsModal.tsx +++ b/src/search/EntryOptionsModal.tsx @@ -1,21 +1,20 @@ import React from 'react'; import { View, StyleSheet, Image, Text, Pressable } from 'react-native'; -import { observer } from 'mobx-react'; import Colors from 'app/src/constants/Colors'; import LikeOptionRow from 'app/src/search/LikeOptionRow'; import SetPrice from 'app/src/search/SetPrice'; -import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import BuyBtn from 'app/src/ui/buy-btn/BuyBtn'; +import { SessionStore } from '../stores/session'; -export default observer(({ route }) => { - const { sessionStore } = Stores(); +export default ({ route }) => { + const { user } = SessionStore(); const { entry, previousScreen } = route.params; const { goBack } = useNavigation(); const renderSetPrice = (entry: any) => { - if (!sessionStore.user) return; + if (!user) return; if (previousScreen === 'MyMusicScreen') { return ; } @@ -47,7 +46,7 @@ export default observer(({ route }) => { ); -}); +}; const styles = StyleSheet.create({ container: { diff --git a/src/search/PricingOptionsModal.tsx b/src/search/PricingOptionsModal.tsx index 75cd6a8..cb2e3ed 100644 --- a/src/search/PricingOptionsModal.tsx +++ b/src/search/PricingOptionsModal.tsx @@ -16,7 +16,7 @@ import DollarIcon from 'app/src/ui/icons/dollar'; import PieIcon from 'app/src/ui/icons/pie'; import CircleIcon from 'app/src/ui/icons/circle'; import { UserEntriesStore } from '../stores/user-entries'; -import { EntryStore } from '../stores/entry.store'; +import { EntryStore } from '../stores/entry'; const SwitchWeb: any = Switch; diff --git a/src/search/RecentlyAdded.tsx b/src/search/RecentlyAdded.tsx index 79d3b73..e2124d8 100644 --- a/src/search/RecentlyAdded.tsx +++ b/src/search/RecentlyAdded.tsx @@ -1,16 +1,15 @@ import React, { useState } from 'react'; import { Text, StyleSheet, SafeAreaView, FlatList } from 'react-native'; -import { observer } from 'mobx-react'; import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; -import { Stores } from 'app/src/functions/Stores'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import BottomPlaceholder from '../ui/BottomPlaceholder'; import { SearchStore } from '../stores/search'; +import { PlayerStore } from '../stores/player'; -export default observer((props) => { - const { playerStore } = Stores(); +export default (props) => { + const { loadAndPlay, setPlaylistModeFromArray } = PlayerStore(); const { recentlyAdded, hasMoreRecentlyAdded, @@ -22,11 +21,11 @@ export default observer((props) => { return ( playerStore.loadAndPlay(item)} + play={() => loadAndPlay(item)} entry={item} options={null} disablePlaylistMode={() => { - playerStore.setPlaylistModeFromArray(recentlyAdded); + setPlaylistModeFromArray(recentlyAdded); }} previousScreen={null} /> @@ -60,7 +59,7 @@ export default observer((props) => { ); -}); +}; const styles = StyleSheet.create({ recentText: { diff --git a/src/search/RemoveFromMyMusicRow.tsx b/src/search/RemoveFromMyMusicRow.tsx index a1b9889..6b714f0 100644 --- a/src/search/RemoveFromMyMusicRow.tsx +++ b/src/search/RemoveFromMyMusicRow.tsx @@ -4,7 +4,7 @@ import RemoveIcon from 'app/src/ui/icons/remove'; import Colors from 'app/src/constants/Colors'; import { useNavigation } from '@react-navigation/native'; import { UserEntriesStore } from '../stores/user-entries'; -import { EntryStore } from '../stores/entry.store'; +import { EntryStore } from '../stores/entry'; export default ({ entry }) => { const { remove } = EntryStore(); diff --git a/src/stores/entry.store.ts b/src/stores/entry.ts similarity index 100% rename from src/stores/entry.store.ts rename to src/stores/entry.ts diff --git a/src/stores/index.ts b/src/stores/index.ts deleted file mode 100644 index 62f4b4f..0000000 --- a/src/stores/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { PlayerStore } from './player.store'; - -export const playerStore = new PlayerStore(); - -export type Stores = { - playerStore: PlayerStore; -}; diff --git a/src/stores/payments.store.ts b/src/stores/payments.ts similarity index 100% rename from src/stores/payments.store.ts rename to src/stores/payments.ts diff --git a/src/stores/player.store.ts b/src/stores/player.store.ts deleted file mode 100644 index 88cf632..0000000 --- a/src/stores/player.store.ts +++ /dev/null @@ -1,535 +0,0 @@ -import { observable, computed, action } from 'mobx'; -import { Entry } from '../models'; -import * as L from 'list'; -import { entriesBackend } from '../api/entries'; -import { PlaybackState, SeekState, ControlsState } from '../types/index'; -import { Platform } from 'react-native'; - -export class PlayerStore { - constructor() {} - - public observables: any = observable({ - entry: null, - }); - @computed - get entry(): any { - return this.observables.entry; - } - - @observable - showMiniPlayer: boolean = false; - - @observable - show: boolean = false; - @observable - tabBarBottomPosition: number = 0; - @observable - loop: boolean = false; - @observable - shuffle: boolean = false; - @observable - playbackState: PlaybackState = 'LOADING'; - @observable - seekState: SeekState = 'NOT_SEEKING'; - @observable - controlsState: ControlsState = 'SHOWN'; - @observable - shouldPlay: boolean = false; - @observable - isOnFullScreenMode: boolean = false; - @observable - positionMillis: number = 0; - @observable - playbackInstancePosition: number = 0; - @observable - playbackInstanceDuration: number = 0; - @observable - lastPlaybackStateUpdate: number = Date.now(); - @observable - error: any; - @observable - networkState: any; - @observable - shouldPlayAtEndOfSeek: boolean = false; - @observable - sliderWidth: number = 0; - @observable - cueList: L.List = L.from([]); - @observable - currentIndex: number = 0; - @observable - retryTimes: number = 0; - @observable - playlistMode: boolean = false; - @observable - playbackInstance: any; - - @observable - seekPosition: number = 0; - - @observable - sliding: boolean = false; - - @observable - streamUrl: string = ''; - - video: any; - - @action - setSliding(sliding) { - this.sliding = sliding; - } - - mountVideo = (component) => { - if (!component) return; - - this.video = component; - this.loadNewPlaybackInstance(false); - }; - - async loadNewPlaybackInstance(playing, streamUrl = this.streamUrl) { - if (this.playbackInstance != null) { - try { - await this.playbackInstance.unloadAsync(); - } catch (e) {} - - this.playbackInstance = null; - } - - if (!streamUrl) return; - if (!this.video) return; - - await this.video.loadAsync( - { uri: streamUrl }, - { - shouldPlay: playing, - positionMillis: 0, - progressUpdateIntervalMillis: 50, - } - ); - this.playbackInstance = this.video; - if (playing && !this.isPlaying) { - this.playAsync(); - } - } - - @action - async refreshEntry() { - if (this.entry && this.entry.id) { - let entry = await entriesBackend.getById(this.entry.id); - this.observables.entry = entry; - } - } - - setPlaylistMode(entries: L.List) { - this.playlistMode = true; - this.cueList = entries; - } - - setPlaylistModeFromArray(entries: Entry[]) { - this.playlistMode = true; - this.cueList = L.from(entries); - } - - disablePlaylistMode() { - this.playlistMode = false; - this.cueList = L.from([]); - } - - setPlaybackInstance(playbackInstance: any) { - if (playbackInstance !== null) { - this.playbackInstance = playbackInstance; - } - } - - @computed - get playbackInstanceExists() { - return !!this.playbackInstance; - } - - async playAsync() { - if (this.playbackInstanceExists) { - this.setPlaybackState('PLAYING'); - return await this.playbackInstance.setStatusAsync({ shouldPlay: true }); - } - } - - async pauseAsync() { - if (this.playbackInstanceExists) { - this.setPlaybackState('PAUSED'); - await this.playbackInstance.setStatusAsync({ shouldPlay: false }); - this.setPlaybackState('PAUSED'); - return true; - } - } - - async stopAsync() { - if (this.playbackInstanceExists) { - this.setPlaybackState('PAUSED'); - return await this.playbackInstance.setStatusAsync({ - shouldPlay: false, - positionMillis: 0, - }); - } - } - - async toggleLoop() { - if (this.playbackInstanceExists) { - this.loop = !this.loop; - return await this.playbackInstance.setIsLoopingAsync(this.loop); - } - } - - async presentFullscreenPlayer() { - if (this.playbackInstance) { - await this.playbackInstance.presentFullscreenPlayer(); - return; - } - } - - async dismissFullscreenPlayer() { - if (this.playbackInstance) { - await this.playbackInstance.dismissFullscreenPlayer(); - return; - } - } - - onFullscreenUpdate(status: any) { - if (status.fullscreenUpdate === 1) { - this.isOnFullScreenMode = true; - } - - if (status.fullscreenUpdate === 3) { - this.isOnFullScreenMode = false; - // resume video manually, - // TODO: add bug to expo client on github. - if (this.shouldPlay) { - this.playAsync(); - } - } - } - - async togglePlay() { - if (this.isPlaying) { - return this.pauseAsync(); - } - return this.playAsync(); - } - - async replay() { - await this.stopAsync(); - this.setPlaybackState('PLAYING'); - return this.playAsync(); - } - - @computed - get isPlaying() { - if (this.playbackState === 'PLAYING') { - return true; - } - return false; - } - - async loadAndPlay(entry: Entry, play = true) { - if (!entry) { - return null; - } - const currentIndex = L.findIndex( - (item) => !!item && item.id === entry.id, - this.cueList - ); - if (currentIndex !== -1) { - this.currentIndex = currentIndex; - } - - this.setPlaybackState('LOADING'); - this.observables.entry = entry; - this.showPlayer(); - let { videoUrl, isIpfs, videoSrc } = entry; - - if (!videoUrl) { - return; - } - - this.streamUrl = isIpfs && videoSrc ? videoSrc : videoUrl; - await this.loadNewPlaybackInstance(play, this.streamUrl); - this.setPlaybackState(play ? 'PLAYING' : 'PAUSED'); - return; - } - - async playNext() { - this.setPlaybackState('LOADING'); - this.pauseAsync(); - - if (this.isCurrentIndexAtTheEndOfCue) { - // Override the value if playlistMode was set to true, it will loop through the - // list instead of playing a related video. - if (this.playlistMode) { - let entry = L.nth(0, this.cueList); - this.currentIndex = 0; - if (!entry) return; - return this.loadAndPlay(entry); - } - } - - this.currentIndex++; - let nextEntry = L.nth(this.currentIndex, this.cueList); - if (!nextEntry) return; - this.loadAndPlay(nextEntry); - } - - async loadPlayAndPushToCueList(entry: Entry) { - this.loadAndPlay(entry); - this.cueList = L.append(this.entry, this.cueList); - this.currentIndex = this.cueList.length - 1; - } - - async loadPlayAndUnshiftToCueList(entry: Entry) { - this.loadAndPlay(entry); - this.cueList = L.prepend(this.entry, this.cueList); - this.currentIndex = 0; - } - - onError(e: string) { - console.info(e); - } - - @action - toggleShuffle() { - this.shuffle = !this.shuffle; - } - - @action - unmountMiniPlayer() { - this.showMiniPlayer = false; - } - - @action - mountMiniPlayer() { - this.showMiniPlayer = true; - } - - @action - hidePlayer() { - this.show = false; - } - - @action - showPlayer() { - this.show = true; - } - - @computed - get isCurrentIndexAtTheStartOfCue() { - return this.currentIndex === 0; - } - - @computed - get isCurrentIndexAtTheEndOfCue() { - return this.currentIndex === this.cueList.length - 1; - } - - @action - updateTabBarBottomPosition(bottom: number) { - this.tabBarBottomPosition = bottom; - } - - async playPrev() { - this.setPlaybackState('LOADING'); - this.pauseAsync(); - if (this.isCurrentIndexAtTheStartOfCue) { - // Override the value if playlistMode was set to true, it will loop through the - // list instead of playing a related video. - if (this.playlistMode) { - let lastIndexInCueList = this.cueList.length - 1; - let entry = L.nth(lastIndexInCueList, this.cueList); - this.currentIndex = lastIndexInCueList; - if (!entry) return; - return this.loadAndPlay(entry); - } - - return; - } - - this.currentIndex--; - let prevEntry = L.nth(this.currentIndex, this.cueList); - if (!prevEntry) return; - this.loadAndPlay(prevEntry); - } - - padWithZero = (value: number) => { - const result = value.toString(); - if (value < 10) { - return '0' + result; - } - return result; - }; - - getMMSSFromMillis(millis: number) { - const totalSeconds = millis / 1000; - const seconds = Math.floor(totalSeconds % 60); - const minutes = Math.floor(totalSeconds / 60); - return this.padWithZero(minutes) + ':' + this.padWithZero(seconds); - } - - @computed - get durationDisplay() { - return this.getMMSSFromMillis(this.playbackInstanceDuration); - } - - @computed - get positionDisplay() { - return this.getMMSSFromMillis(this.playbackInstancePosition); - } - - @action - setSeekState(seekState: SeekState) { - this.seekState = seekState; - } - - onSeekSliderValueChange = () => { - if ( - this.playbackInstance !== null && - this.seekState !== 'SEEKING' && - this.seekState !== 'SEEKED' - ) { - this.shouldPlayAtEndOfSeek = false; - this.setSeekState('SEEKING'); - - if (this.isPlaying) { - this.pauseAsync(); - this.shouldPlayAtEndOfSeek = true; - } - } - }; - - onSeekSliderSlidingComplete = async (value: number) => { - if (this.seekState !== 'SEEKED') { - this.setSeekState('SEEKED'); - let status; - try { - status = await this.playbackInstance.setStatusAsync({ - positionMillis: value * this.playbackInstanceDuration, - shouldPlay: this.shouldPlayAtEndOfSeek, - }); - - this.setSeekState('NOT_SEEKING'); - this.setPlaybackState(this.getPlaybackStateFromStatus(status)); - } catch (message) {} - } - }; - - onSeekBarTap = (evt: any) => { - if (this.sliding) return; - if ( - !( - this.playbackState === 'LOADING' || - this.playbackState === 'ENDED' || - this.playbackState === 'ERROR' || - this.controlsState !== 'SHOWN' - ) - ) { - let xValue; - if (Platform.OS === 'web') { - xValue = evt.nativeEvent.clientX - evt.target.getBoundingClientRect().x; - } else { - xValue = evt.nativeEvent.locationX; - } - const value = xValue / this.sliderWidth; - this.onSeekSliderSlidingComplete(value); - } - }; - - onSliderLayout = (evt: any) => { - this.sliderWidth = evt.nativeEvent.layout.width; - }; - - setNetworkState(state: any) { - this.networkState = state; - } - - generateRandomNumber(max: number): number { - var num = Math.floor(Math.random() * (max + 1)); - return num === this.currentIndex ? this.generateRandomNumber(max) : num; - } - - async handleEndedPlaybackState() { - if (this.playbackState === 'ENDED') { - let pause = await this.pauseAsync(); - if (pause) { - if (this.shuffle) { - this.currentIndex = this.generateRandomNumber(this.cueList.length); - } - return this.playNext(); - } - } - } - - @computed - get disablePlaybackStatusUpdate(): boolean { - if ( - this.playbackState === 'ENDED' || - this.playbackState === 'LOADING' || - this.seekState === 'SEEKING' || - this.seekState === 'SEEKED' - ) { - return true; - } - return false; - } - - @action - onPlaybackStatusUpdate(status: any) { - if (!status.isLoaded) { - if (status.error) { - const errorMsg = `Encountered a fatal error during playback: ${status.error}`; - this.error = errorMsg; - return this.setPlaybackState('ERROR'); - } - return; - } - - if (this.networkState === 'none' && status.isBuffering) { - this.setPlaybackState('ERROR'); - this.error = - 'You are probably offline. Please make sure you are connected to the Internet to watch this video'; - return; - } - - if (status.isPlaying && !status.isBuffering) { - this.playbackInstancePosition = status.positionMillis; - this.playbackInstanceDuration = status.durationMillis; - this.seekPosition = - this.playbackInstancePosition / this.playbackInstanceDuration; - } - - this.shouldPlay = status.shouldPlay; - - this.setPlaybackState(this.getPlaybackStateFromStatus(status)); - } - - @action - async setPlaybackState(playbackState: PlaybackState) { - if (this.playbackState !== playbackState) { - this.playbackState = playbackState; - this.handleEndedPlaybackState(); - this.lastPlaybackStateUpdate = Date.now(); - } - } - - getPlaybackStateFromStatus = (status: any) => { - if (status.didJustFinish && !status.isLooping) { - return 'ENDED'; - } - - if (status.isPlaying) { - return 'PLAYING'; - } - - if (status.isBuffering) { - return 'BUFFERING'; - } - - return 'PAUSED'; - }; -} diff --git a/src/stores/player.ts b/src/stores/player.ts new file mode 100644 index 0000000..7e9e140 --- /dev/null +++ b/src/stores/player.ts @@ -0,0 +1,608 @@ +import { Entry } from '../models'; +import { entriesBackend } from '../api/entries'; +import { PlaybackState, SeekState, ControlsState } from '../types/index'; +import { Platform } from 'react-native'; +import { atom, useRecoilState } from 'recoil'; + +const entryAtom = atom({ + key: 'subscribed', + default: null, +}); +const showMiniPlayerAtom = atom({ + key: 'showMiniPlayer', + default: false, +}); +const showAtom = atom({ + key: 'show', + default: false, +}); +const tabBarBottomAtom = atom({ + key: 'tabBarBottom', + default: 0, +}); +const loopAtom = atom({ + key: 'tabBarBottom', + default: false, +}); +const shuffleAtom = atom({ + key: 'shuffle', + default: false, +}); +const playbackStateAtom = atom({ + key: 'playbackState', + default: 'LOADING', +}); +const seekStateAtom = atom({ + key: 'seekState', + default: 'NOT_SEEKING', +}); +const controlsStateAtom = atom({ + key: 'controlsState', + default: 'SHOWN', +}); +const shouldPlayAtom = atom({ + key: 'shouldPlay', + default: false, +}); +const fullscreenAtom = atom({ + key: 'fullscreen', + default: false, +}); +const positionMillisAtom = atom({ + key: 'positionMillis', + default: 0, +}); + +const playbackInstancePositionAtom = atom({ + key: 'playbackInstancePosition', + default: 0, +}); +const playbackInstanceDurationAtom = atom({ + key: 'playbackInstanceDuration', + default: 0, +}); +const lastPlaybackStateUpdateAtom = atom({ + key: 'lastPlaybackStateUpdate', + default: Date.now(), +}); +const errorAtom = atom({ key: 'error' }); +const networkStateAtom = atom({ key: 'networkState' }); +const shouldPlayAtEndOfSeekAtom = atom({ + key: 'shouldPlayAtEndOfSeek', + default: false, +}); +const sliderWidthAtom = atom({ key: 'sliderWidth', default: 0 }); +const cueListAtom = atom({ key: 'cueList', default: [] }); +const currentIndexAtom = atom({ key: 'currentIndex', default: 0 }); +const retryTimesAtom = atom({ key: 'retryTimes', default: 0 }); +const playlistModeAtom = atom({ key: 'playlistMode', default: false }); +const playbackInstanceAtom = atom({ key: 'playbackInstance' }); +const seekPositionAtom = atom({ key: 'seekPosition', default: 0 }); +const slidingAtom = atom({ key: 'sliding', default: false }); +const streamUrlAtom = atom({ key: 'streamUrl', default: '' }); +const videoAtom = atom({ key: 'video' }); + +export const PlayerStore = () => { + const [entry, setEntry] = useRecoilState(entryAtom); + const [showMiniPlayer, setShowMiniPlayer] = useRecoilState( + showMiniPlayerAtom + ); + const [show, setShow] = useRecoilState(showAtom); + const [tabBarBottom, setTabBarBottom] = useRecoilState(tabBarBottomAtom); + const [loop, setLoop] = useRecoilState(loopAtom); + const [shuffle, setShuffle] = useRecoilState(shuffleAtom); + const [playbackState, setPlaybackState] = useRecoilState(playbackStateAtom); + const [seekState, setSeekState] = useRecoilState(seekStateAtom); + const [controlsState, setControlsState] = useRecoilState(controlsStateAtom); + const [shouldPlay, setShouldPlay] = useRecoilState(shouldPlayAtom); + const [fullscreen, setFullscreen] = useRecoilState(fullscreenAtom); + const [positionMillis, setPositionMillis] = useRecoilState( + positionMillisAtom + ); + const [ + playbackInstancePosition, + setPlaybackInstancePosition, + ] = useRecoilState(playbackInstancePositionAtom); + const [ + playbackInstanceDuration, + setPlaybackInstanceDuration, + ] = useRecoilState(playbackInstanceDurationAtom); + const [lastPlaybackState, setLastPlaybackState] = useRecoilState( + lastPlaybackStateUpdateAtom + ); + const [error, setError] = useRecoilState(errorAtom); + const [networkState, setNetworkState] = useRecoilState(networkStateAtom); + const [shouldPlayEndOfSeek, setShouldPlayEndofSeek] = useRecoilState( + shouldPlayAtEndOfSeekAtom + ); + const [sliderWidth, setSliderWidth] = useRecoilState(sliderWidthAtom); + const [cueList, setCueList] = useRecoilState(cueListAtom); + const [currentIndex, setCurrentIndex] = useRecoilState(currentIndexAtom); + const [retryTimes, setRetryTimes] = useRecoilState(retryTimesAtom); + const [playlistMode, setPlaylistMode] = useRecoilState(playlistModeAtom); + const [playbackInstance, setPlaybackInstance] = useRecoilState( + playbackInstanceAtom + ); + const [seekPosition, setSeekPosition] = useRecoilState(seekPositionAtom); + const [sliding, setSliding] = useRecoilState(slidingAtom); + const [streamUrl, setStreamUrl] = useRecoilState(streamUrlAtom); + const [video, setVideo] = useRecoilState(videoAtom); + + const mountVideo = (component) => { + if (!component) return; + + setVideo(component); + loadNewPlaybackInstance(false); + }; + + const loadNewPlaybackInstance = async ( + playing, + streamUrlPayload = streamUrl + ) => { + if (playbackInstance != null) { + try { + await playbackInstance.unloadAsync(); + } catch (e) {} + + setPlaybackInstance(null); + } + + if (!streamUrlPayload) return; + if (!video) return; + + await video.loadAsync( + { uri: streamUrlPayload }, + { + shouldPlay: playing, + positionMillis: 0, + progressUpdateIntervalMillis: 50, + } + ); + setPlaybackInstance(video); + if (playing && !isPlaying) { + playAsync(); + } + }; + + const refreshEntry = async () => { + if (entry && entry.id) { + let res = await entriesBackend.getById(entry.id); + setEntry(res); + } + }; + + const handleSetPlaylistMode = (entries: Entry[]) => { + setPlaylistMode(true); + setCueList(entries); + }; + + const setPlaylistModeFromArray = (entries: Entry[]) => { + setPlaylistMode(true); + setCueList(entries); + }; + + const disablePlaylistMode = () => { + setPlaylistMode(false); + setCueList([]); + }; + + const handleSetPlaybackInstance = (playbackInstance: any) => { + if (playbackInstance !== null) { + setPlaybackInstance(playbackInstance); + } + }; + + const playbackInstanceExists = () => { + return !!playbackInstance; + }; + + const playAsync = async () => { + if (playbackInstanceExists()) { + setPlaybackState('PLAYING'); + return await playbackInstance.setStatusAsync({ shouldPlay: true }); + } + }; + + const pauseAsync = async () => { + if (playbackInstanceExists()) { + setPlaybackState('PAUSED'); + await playbackInstance.setStatusAsync({ shouldPlay: false }); + setPlaybackState('PAUSED'); + return true; + } + }; + + const stopAsync = async () => { + if (playbackInstanceExists()) { + setPlaybackState('PAUSED'); + return await playbackInstance.setStatusAsync({ + shouldPlay: false, + positionMillis: 0, + }); + } + }; + + const toggleLoop = async () => { + if (playbackInstanceExists()) { + setLoop(!loop); + return await playbackInstance.setIsLoopingAsync(loop); + } + }; + + const presentFullscreenPlayer = async () => { + if (playbackInstance) { + await playbackInstance.presentFullscreenPlayer(); + return; + } + }; + + const dismissFullscreenPlayer = async () => { + if (playbackInstance) { + await playbackInstance.dismissFullscreenPlayer(); + return; + } + }; + + const onFullscreenUpdate = (status: any) => { + if (status.fullscreenUpdate === 1) { + setFullscreen(true); + } + + if (status.fullscreenUpdate === 3) { + setFullscreen(false); + // resume video manually, + // TODO: add bug to expo client on github. + if (shouldPlay) { + playAsync(); + } + } + }; + const isPlaying = () => { + if (playbackState === 'PLAYING') { + return true; + } + return false; + }; + + const togglePlay = async () => { + if (isPlaying()) { + return pauseAsync(); + } + return playAsync(); + }; + + const replay = async () => { + await stopAsync(); + setPlaybackState('PLAYING'); + return playAsync(); + }; + + const loadAndPlay = async (entry: Entry, play = true) => { + if (!entry) { + return null; + } + const currentIndex = cueList.findIndex( + (item) => !!item && item.id === entry.id + ); + if (currentIndex !== -1) { + setCurrentIndex(currentIndex); + } + + setPlaybackState('LOADING'); + setEntry(entry); + setShow(true); + let { videoUrl, isIpfs, videoSrc } = entry; + + if (!videoUrl) { + return; + } + + setStreamUrl(isIpfs && videoSrc ? videoSrc : videoUrl); + await loadNewPlaybackInstance(play, streamUrl); + setPlaybackState(play ? 'PLAYING' : 'PAUSED'); + return; + }; + + const playNext = async () => { + setPlaybackState('LOADING'); + pauseAsync(); + + if (isCurrentIndexAtTheEndOfCue()) { + // Override the value if playlistMode was set to true, it will loop through the + // list instead of playing a related video. + if (playlistMode) { + let entry = cueList[0]; + setCurrentIndex(0); + if (!entry) return; + return loadAndPlay(entry); + } + } + + setCurrentIndex((oldVal) => oldVal++); + let nextEntry = cueList[currentIndex]; + if (!nextEntry) return; + loadAndPlay(nextEntry); + }; + + const loadPlayAndPushToCueList = async (entry: Entry) => { + loadAndPlay(entry); + setCueList((oldVal) => { + const arr = oldVal; + arr.push(entry); + return arr; + }); + setCurrentIndex(cueList.length - 1); + }; + + const loadPlayAndUnshiftToCueList = async (entry: Entry) => { + loadAndPlay(entry); + setCueList((oldVal) => { + const arr = oldVal; + arr.unshift(entry); + return arr; + }); + setCurrentIndex(0); + }; + + const onError = (e: string) => { + console.info(e); + }; + + const toggleShuffle = () => { + setShuffle(!shuffle); + }; + + const unmountMiniPlayer = () => { + setShowMiniPlayer(false); + }; + + const mountMiniPlayer = () => { + setShowMiniPlayer(true); + }; + + const hidePlayer = () => { + setShow(false); + }; + + const isCurrentIndexAtTheStartOfCue = () => { + return currentIndex === 0; + }; + + const isCurrentIndexAtTheEndOfCue = () => { + return currentIndex === cueList.length - 1; + }; + + const updateTabBarBottomPosition = (bottom: number) => { + setTabBarBottom(bottom); + }; + + const playPrev = async () => { + setPlaybackState('LOADING'); + pauseAsync(); + if (isCurrentIndexAtTheStartOfCue()) { + // Override the value if playlistMode was set to true, it will loop through the + // list instead of playing a related video. + if (playlistMode) { + let lastIndexInCueList = cueList.length - 1; + let entry = cueList[lastIndexInCueList]; + setCurrentIndex(lastIndexInCueList); + if (!entry) return; + return loadAndPlay(entry); + } + + return; + } + + setCurrentIndex((oldVal) => oldVal--); + let prevEntry = cueList[currentIndex]; + if (!prevEntry) return; + loadAndPlay(prevEntry); + }; + + const padWithZero = (value: number) => { + const result = value.toString(); + if (value < 10) { + return '0' + result; + } + return result; + }; + + const getMMSSFromMillis = (millis: number) => { + const totalSeconds = millis / 1000; + const seconds = Math.floor(totalSeconds % 60); + const minutes = Math.floor(totalSeconds / 60); + return padWithZero(minutes) + ':' + padWithZero(seconds); + }; + + const durationDisplay = () => { + return getMMSSFromMillis(playbackInstanceDuration); + }; + + const positionDisplay = () => { + return getMMSSFromMillis(playbackInstancePosition); + }; + + const onSeekSliderValueChange = () => { + if ( + playbackInstance !== null && + seekState !== 'SEEKING' && + seekState !== 'SEEKED' + ) { + setShouldPlayEndofSeek(false); + setSeekState('SEEKING'); + + if (isPlaying()) { + pauseAsync(); + setShouldPlayEndofSeek(true); + } + } + }; + + const onSeekSliderSlidingComplete = async (value: number) => { + if (seekState !== 'SEEKED') { + setSeekState('SEEKED'); + let status; + try { + status = await playbackInstance.setStatusAsync({ + positionMillis: value * playbackInstanceDuration, + shouldPlay: shouldPlayEndOfSeek, + }); + + setSeekState('NOT_SEEKING'); + setPlaybackState(getPlaybackStateFromStatus(status)); + } catch (message) {} + } + }; + + const onSeekBarTap = (evt: any) => { + if (sliding) return; + if ( + !( + playbackState === 'LOADING' || + playbackState === 'ENDED' || + playbackState === 'ERROR' || + controlsState !== 'SHOWN' + ) + ) { + let xValue; + if (Platform.OS === 'web') { + xValue = evt.nativeEvent.clientX - evt.target.getBoundingClientRect().x; + } else { + xValue = evt.nativeEvent.locationX; + } + const value = xValue / sliderWidth; + onSeekSliderSlidingComplete(value); + } + }; + + const onSliderLayout = (evt: any) => { + setSliderWidth(evt.nativeEvent.layout.width); + }; + + const generateRandomNumber = (max: number): number => { + var num = Math.floor(Math.random() * (max + 1)); + return num === currentIndex ? generateRandomNumber(max) : num; + }; + + const handleEndedPlaybackState = async () => { + if (playbackState === 'ENDED') { + let pause = await pauseAsync(); + if (pause) { + if (shuffle) { + setCurrentIndex(generateRandomNumber(cueList.length)); + } + return playNext(); + } + } + }; + + const disablePlaybackStatusUpdate = () => { + if ( + playbackState === 'ENDED' || + playbackState === 'LOADING' || + seekState === 'SEEKING' || + seekState === 'SEEKED' + ) { + return true; + } + return false; + }; + + const onPlaybackStatusUpdate = (status: any) => { + if (!status.isLoaded) { + if (status.error) { + const errorMsg = `Encountered a fatal error during playback: ${status.error}`; + setError(errorMsg); + return setPlaybackState('ERROR'); + } + return; + } + + if (networkState === 'none' && status.isBuffering) { + setPlaybackState('ERROR'); + setError( + 'You are probably offline. Please make sure you are connected to the Internet to watch this video' + ); + return; + } + + if (status.isPlaying && !status.isBuffering) { + setPlaybackInstancePosition(status.positionMillis); + setPlaybackInstanceDuration(status.durationMillis); + setSeekPosition(playbackInstancePosition / playbackInstanceDuration); + } + + setShouldPlay(status.shouldPlay); + + handleSetPlaybackState(getPlaybackStateFromStatus(status)); + }; + + const handleSetPlaybackState = async (playbackState: PlaybackState) => { + if (playbackState !== playbackState) { + setPlaybackState(playbackState); + handleEndedPlaybackState(); + setLastPlaybackState(Date.now()); + } + }; + + const getPlaybackStateFromStatus = (status: any) => { + if (status.didJustFinish && !status.isLooping) { + return 'ENDED'; + } + + if (status.isPlaying) { + return 'PLAYING'; + } + + if (status.isBuffering) { + return 'BUFFERING'; + } + + return 'PAUSED'; + }; + + return { + entry, + setShow, + getPlaybackStateFromStatus, + handleSetPlaybackState, + onPlaybackStatusUpdate, + disablePlaybackStatusUpdate, + handleEndedPlaybackState, + onSliderLayout, + onSeekBarTap, + onSeekSliderSlidingComplete, + onSeekSliderValueChange, + positionDisplay, + durationDisplay, + playPrev, + updateTabBarBottomPosition, + hidePlayer, + toggleShuffle, + playNext, + shuffle, + fullscreen, + presentFullscreenPlayer, + dismissFullscreenPlayer, + playbackState, + error, + seekState, + togglePlay, + show, + isPlaying, + pauseAsync, + playAsync, + toggleLoop, + loop, + replay, + seekPosition, + setSliding, + streamUrl, + mountVideo, + onFullscreenUpdate, + onError, + handleSetPlaylistMode, + loadAndPlay, + setPlaylistModeFromArray, + }; +}; diff --git a/src/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx index 528e7b8..53f4a0b 100644 --- a/src/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -6,7 +6,7 @@ import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; import { UserEntriesStore } from '../stores/user-entries'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; import { WalletConnectStore } from '../stores/wallet-connect'; export default ({ route }) => { diff --git a/src/ui/EntryPrice.tsx b/src/ui/EntryPrice.tsx index f4cae71..d4c5f3e 100644 --- a/src/ui/EntryPrice.tsx +++ b/src/ui/EntryPrice.tsx @@ -4,7 +4,7 @@ import DollarIcon from 'app/src/ui/icons/dollar'; import Colors from 'app/src/constants/Colors'; import { A } from '@expo/html-elements'; import { stellarAssetLink } from 'app/src/functions/utils'; -import { PaymentsStore } from '../stores/payments.store'; +import { PaymentsStore } from '../stores/payments'; function EntryPrice({ code, issuer }) { const [value, setValue] = useState({ price: 0, amount: 0 }); diff --git a/src/ui/UserRow.tsx b/src/ui/UserRow.tsx index 22477d5..6a40869 100644 --- a/src/ui/UserRow.tsx +++ b/src/ui/UserRow.tsx @@ -2,13 +2,12 @@ import React from 'react'; import { StyleSheet, View, Text, Pressable } from 'react-native'; import Colors from 'app/src/constants/Colors'; import { UserAvatar } from 'app/src/ui/UserAvatar'; -import { Stores } from 'app/src/functions/Stores'; -import { observer } from 'mobx-react'; import { CommonActions, useNavigation } from '@react-navigation/native'; import ProfileStore from '../stores/profile'; +import { PlayerStore } from '../stores/player'; -export default observer(({ user }) => { - const { playerStore } = Stores(); +export default ({ user }) => { + const { handleSetPlaylistMode } = PlayerStore(); const { getProfileInfo } = ProfileStore(); const { dispatch } = useNavigation(); return ( @@ -17,7 +16,7 @@ export default observer(({ user }) => { { getProfileInfo(user).then((entries: any) => { - playerStore.setPlaylistMode(entries); + handleSetPlaylistMode(entries); }); dispatch( CommonActions.navigate({ @@ -40,7 +39,7 @@ export default observer(({ user }) => { ); -}); +}; let styles = StyleSheet.create({ rowWrap: { diff --git a/src/ui/buy-btn/BuyBtn.tsx b/src/ui/buy-btn/BuyBtn.tsx index b78bedf..7aeb0c1 100644 --- a/src/ui/buy-btn/BuyBtn.tsx +++ b/src/ui/buy-btn/BuyBtn.tsx @@ -5,7 +5,7 @@ import { CommonActions, useNavigation } from '@react-navigation/native'; import cursorPointer from 'app/src/constants/CursorPointer'; import DollarIcon from 'app/src/ui/icons/dollar'; import tw from 'twin.macro'; -import { PaymentsStore } from 'app/src/stores/payments.store'; +import { PaymentsStore } from 'app/src/stores/payments'; const Placeholder = () => ; diff --git a/yarn.lock b/yarn.lock index a2b48d6..ee1b7e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9627,23 +9627,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mobx-react-lite@2: - version "2.0.7" - resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz#1bfb3b4272668e288047cf0c7940b14e91cba284" - integrity sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q== - -mobx-react@6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.2.2.tgz#45e8e7c4894cac8399bba0a91060d7cfb8ea084b" - integrity sha512-Us6V4ng/iKIRJ8pWxdbdysC6bnS53ZKLKlVGBqzHx6J+gYPYbOotWvhHZnzh/W5mhpYXxlXif4kL2cxoWJOplQ== - dependencies: - mobx-react-lite "2" - -mobx@5.15.4: - version "5.15.4" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab" - integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw== - mockdate@^3.0.2: version "3.0.5" resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb" From 2062673771c55296655b4b2994229e07906814f9 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Thu, 7 Jul 2022 23:16:32 -0500 Subject: [PATCH 09/13] take out list --- package.json | 1 - .../likers-section/LikersSection.tsx | 14 +++---- src/playlists/CollectionScreen.tsx | 24 +++++------- src/playlists/LikesScreen.tsx | 24 +++++------- src/stores/likes.ts | 39 +++++++++---------- src/stores/user-entries.ts | 5 +-- yarn.lock | 5 --- 7 files changed, 45 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index a1d5bae..c6863d0 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "expo-permissions": "~13.0.3", "graphql": "^16.5.0", "graphql-request": "^4.3.0", - "list": "^2.0.19", "lodash.debounce": "4.0.8", "next": "^12.0.1", "next-fonts": "^1.5.1", diff --git a/src/player/player-screen/likers-section/LikersSection.tsx b/src/player/player-screen/likers-section/LikersSection.tsx index 8ecda01..5404a78 100644 --- a/src/player/player-screen/likers-section/LikersSection.tsx +++ b/src/player/player-screen/likers-section/LikersSection.tsx @@ -3,7 +3,6 @@ import { StyleSheet, View, Text } from 'react-native'; import LikeBtn from 'app/src/player/player-screen/like-btn/LikeBtn'; import Divider from 'app/src/ui/Divider'; import { UserAvatar } from 'app/src/ui/UserAvatar'; -import * as L from 'list'; import { LikesStore } from 'app/src/stores/likes'; export default () => { @@ -30,14 +29,11 @@ export default () => { {entryLikes && - L.map( - (liker: any) => ( - - - - ), - entryLikes - )} + entryLikes.map((liker) => ( + + + + ))} {renderMoreLikersBtn()} diff --git a/src/playlists/CollectionScreen.tsx b/src/playlists/CollectionScreen.tsx index f7655ed..f1757f1 100644 --- a/src/playlists/CollectionScreen.tsx +++ b/src/playlists/CollectionScreen.tsx @@ -4,7 +4,6 @@ import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import { UserEntriesStore } from '../stores/user-entries'; @@ -20,19 +19,16 @@ export default () => { > {SearchingLoader(loading)} - {L.map( - (entry: any) => ( - {}} - entry={entry} - options={null} - disablePlaylistMode={null} - previousScreen={'CollectionScreen'} - /> - ), - entries - )} + {entries.map((entry: any) => ( + {}} + entry={entry} + options={null} + disablePlaylistMode={null} + previousScreen={'CollectionScreen'} + /> + ))} diff --git a/src/playlists/LikesScreen.tsx b/src/playlists/LikesScreen.tsx index 2e7b719..15d15c1 100644 --- a/src/playlists/LikesScreen.tsx +++ b/src/playlists/LikesScreen.tsx @@ -4,7 +4,6 @@ import EntryRow from 'app/src/ui/EntryRow'; import SearchingLoader from 'app/src/ui/SearchingLoader'; import Colors from 'app/src/constants/Colors'; import BottomPlaceholder from 'app/src/ui/BottomPlaceholder'; -import * as L from 'list'; import ResponsiveLayout from '../ui/ResponsiveLayout'; import { LikesStore } from '../stores/likes'; @@ -20,19 +19,16 @@ export default () => { > {SearchingLoader(loading)} - {L.map( - (entry: any) => ( - - ), - userLikes - )} + {userLikes.map((entry) => ( + + ))} diff --git a/src/stores/likes.ts b/src/stores/likes.ts index 6a04151..a7c7f94 100644 --- a/src/stores/likes.ts +++ b/src/stores/likes.ts @@ -1,5 +1,4 @@ import { useRecoilValue } from 'recoil'; -import * as L from 'list'; import { likesBackend } from '../api/likes'; import { userAtom } from '../atoms/atoms'; import { Entry, User } from '../models'; @@ -9,16 +8,14 @@ export const LikesStore = () => { let loading: boolean = false; let loadingEntryLikes: boolean = false; let entry!: Entry; - let entryLikes: L.List = L.from([]); + let entryLikes: User[] = []; let entryLikesCount!: number; - let userLikes: L.List = L.from([]); + let userLikes: Entry[] = []; let userLikesCount!: number; const user = useRecoilValue(userAtom); let viewLimit: number = 8; - let disposer: any; - let userDisposer: any; const hasMoreLikers = () => { if (entryLikesCount > viewLimit) { @@ -54,8 +51,8 @@ export const LikesStore = () => { // } const clearLikes = () => { - entryLikes = L.from([]); - userLikes = L.from([]); + entryLikes = []; + userLikes = []; }; const refreshEntryLikes = (id: string) => { @@ -66,7 +63,7 @@ export const LikesStore = () => { let users = payload.users.map( (userPayload: any) => new User(userPayload) ); - entryLikes = L.from(users); + entryLikes = users; } loadingEntryLikes = false; @@ -82,7 +79,7 @@ export const LikesStore = () => { let ids = userLikes.map((like: any) => like.id); let entries = userLikes.map((like: any) => new Entry(like)); ids = new Set(ids); - userLikes = L.from(entries); + userLikes = entries; userLikesCount = userLikes.length; } @@ -92,47 +89,47 @@ export const LikesStore = () => { const unlike = async (entry: Entry) => { ids.delete(entry.id); - let index = L.findIndex((like) => { + let index = userLikes.findIndex((like) => { if (like) { return like.id === entry.id; } return false; - }, userLikes); - userLikes = L.remove(index, 1, userLikes); + }); + userLikes.splice(index, 1); let unliked = await likesBackend.like(entry.id, false); if (!unliked) { ids = ids.add(entry.id); - userLikes = L.append(entry, userLikes); + userLikes.push(entry); } userLikesCount = userLikes.length; - let userIndex = L.findIndex((like) => { + let userIndex = entryLikes.findIndex((like) => { if (like) { return like.id === user?.id; } return false; - }, entryLikes); - entryLikes = L.remove(userIndex, 1, entryLikes); + }); + entryLikes.splice(userIndex, 1); }; const like = async (entry: Entry) => { if (!user) return; ids = ids.add(entry.id); - userLikes = L.append(entry, userLikes); + userLikes.push(entry); let liked = await likesBackend.like(entry.id); if (!liked) { ids.delete(entry.id); - let index = L.findIndex((like) => { + let index = userLikes.findIndex((like) => { if (like) { return like.id === entry.id; } return false; - }, userLikes); - userLikes = L.remove(index, 1, userLikes); + }); + userLikes.splice(index, 1); } userLikesCount = userLikes.length; - entryLikes = L.append(user, entryLikes); + entryLikes.push(user); }; const toggleLike = (entry: Entry) => { diff --git a/src/stores/user-entries.ts b/src/stores/user-entries.ts index 328a38b..c452a48 100644 --- a/src/stores/user-entries.ts +++ b/src/stores/user-entries.ts @@ -1,4 +1,3 @@ -import * as L from 'list'; import { entriesBackend } from '../api/entries'; import { Entry } from '../models'; import { userAtom } from '../atoms/atoms'; @@ -7,7 +6,7 @@ import { useRecoilValue } from 'recoil'; export const UserEntriesStore = () => { const user = useRecoilValue(userAtom); - let entries: L.List = L.from([]); + let entries: Entry[] = []; let loading: boolean = false; const refreshEntries = async () => { @@ -21,7 +20,7 @@ export const UserEntriesStore = () => { const res = await entriesBackend.getByUserId(user.id); loading = false; - entries = L.from(res ? res : []); + entries = res ? res : []; }; return { entries, loading, refreshEntries }; }; diff --git a/yarn.lock b/yarn.lock index ee1b7e5..4637c6a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8728,11 +8728,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -list@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/list/-/list-2.0.19.tgz#370a3d7d3e24cfd5ced2c89cda2baf28e31e2830" - integrity sha512-nnVaRp4RaMAQkCpypTThsdxKqgPMiSwJq93eAm2/IbpUa8sd04XKBhkKu+bMk63HmdjK8b8Cuh4xARHWX2ye/Q== - loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" From c5df71452e831f78e782e70ae3849bbd22d5be39 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Thu, 7 Jul 2022 23:28:37 -0500 Subject: [PATCH 10/13] fixes --- src/player/player-screen/like-btn/LikeBtn.tsx | 4 ++-- src/profile/ProfileTopContainer.tsx | 4 ---- src/stores/likes.ts | 2 ++ src/stores/player.ts | 17 +++++++++++++++-- src/ui/BuyOptionsModal.tsx | 6 +++--- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/player/player-screen/like-btn/LikeBtn.tsx b/src/player/player-screen/like-btn/LikeBtn.tsx index ef37a69..f98d9ef 100644 --- a/src/player/player-screen/like-btn/LikeBtn.tsx +++ b/src/player/player-screen/like-btn/LikeBtn.tsx @@ -4,11 +4,11 @@ import LikeIcon from 'app/src/ui/icons/like'; import Colors from 'app/src/constants/Colors'; import cursorPointer from 'app/src/constants/CursorPointer'; import { LikesStore } from 'app/src/stores/likes'; +import { PlayerStore } from 'app/src/stores/player'; export default (props) => { const { toggleLike, isLiked } = LikesStore(); - // const { entry } = PlayerStore(); - const entry = null; + const { entry } = PlayerStore(); if (!entry) { return null; diff --git a/src/profile/ProfileTopContainer.tsx b/src/profile/ProfileTopContainer.tsx index b45b75e..af4ff99 100644 --- a/src/profile/ProfileTopContainer.tsx +++ b/src/profile/ProfileTopContainer.tsx @@ -10,10 +10,6 @@ export default (props) => { if (!user) { return null; } - let source; - if (user.avatarUrl) { - source = { uri: user.avatarUrl }; - } return ( diff --git a/src/stores/likes.ts b/src/stores/likes.ts index a7c7f94..a07ca34 100644 --- a/src/stores/likes.ts +++ b/src/stores/likes.ts @@ -165,5 +165,7 @@ export const LikesStore = () => { refreshLikes, isEntryLiked, clearLikes, + refreshEntryLikes, + loadingEntryLikes, }; }; diff --git a/src/stores/player.ts b/src/stores/player.ts index 7e9e140..d111e1b 100644 --- a/src/stores/player.ts +++ b/src/stores/player.ts @@ -74,7 +74,6 @@ const shouldPlayAtEndOfSeekAtom = atom({ const sliderWidthAtom = atom({ key: 'sliderWidth', default: 0 }); const cueListAtom = atom({ key: 'cueList', default: [] }); const currentIndexAtom = atom({ key: 'currentIndex', default: 0 }); -const retryTimesAtom = atom({ key: 'retryTimes', default: 0 }); const playlistModeAtom = atom({ key: 'playlistMode', default: false }); const playbackInstanceAtom = atom({ key: 'playbackInstance' }); const seekPositionAtom = atom({ key: 'seekPosition', default: 0 }); @@ -118,7 +117,6 @@ export const PlayerStore = () => { const [sliderWidth, setSliderWidth] = useRecoilState(sliderWidthAtom); const [cueList, setCueList] = useRecoilState(cueListAtom); const [currentIndex, setCurrentIndex] = useRecoilState(currentIndexAtom); - const [retryTimes, setRetryTimes] = useRecoilState(retryTimesAtom); const [playlistMode, setPlaylistMode] = useRecoilState(playlistModeAtom); const [playbackInstance, setPlaybackInstance] = useRecoilState( playbackInstanceAtom @@ -604,5 +602,20 @@ export const PlayerStore = () => { handleSetPlaylistMode, loadAndPlay, setPlaylistModeFromArray, + showMiniPlayer, + tabBarBottom, + setControlsState, + positionMillis, + setPositionMillis, + lastPlaybackState, + setLastPlaybackState, + setNetworkState, + refreshEntry, + disablePlaylistMode, + loadPlayAndUnshiftToCueList, + unmountMiniPlayer, + mountMiniPlayer, + loadPlayAndPushToCueList, + handleSetPlaybackInstance, }; }; diff --git a/src/ui/BuyOptionsModal.tsx b/src/ui/BuyOptionsModal.tsx index 53f4a0b..aa8a6f8 100644 --- a/src/ui/BuyOptionsModal.tsx +++ b/src/ui/BuyOptionsModal.tsx @@ -2,12 +2,12 @@ import React, { useState } from 'react'; import { View, StyleSheet, Text, ActivityIndicator } from 'react-native'; import Colors from 'app/src/constants/Colors'; import LargeBtn from './LargeBtn'; -import { Stores } from 'app/src/functions/Stores'; import { useNavigation } from '@react-navigation/core'; import { useLinkTo } from '@react-navigation/native'; import { UserEntriesStore } from '../stores/user-entries'; import { PaymentsStore } from '../stores/payments'; import { WalletConnectStore } from '../stores/wallet-connect'; +import { PlayerStore } from '../stores/player'; export default ({ route }) => { const { entry, priceInfo } = route.params; @@ -19,7 +19,7 @@ export default ({ route }) => { const { goBack } = useNavigation(); const linkTo = useLinkTo(); - const { playerStore } = Stores(); + const { refreshEntry } = PlayerStore(); const { signAndSubmitXdr } = WalletConnectStore(); const { buyEntry, refreshSubscription, credits } = PaymentsStore(); const { refreshEntries } = UserEntriesStore(); @@ -38,7 +38,7 @@ export default ({ route }) => { await signAndSubmitXdr(xdr); } await Promise.all([await refreshEntries(), await refreshSubscription()]); - playerStore.refreshEntry(); + refreshEntry(); setSubmitting(false); goBack(); linkTo('/dashboard/profile'); From cc90b07272cde8c96354eb3a0e71f4a9609f8a07 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Thu, 7 Jul 2022 23:32:57 -0500 Subject: [PATCH 11/13] remove dups --- src/atoms/atoms.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atoms/atoms.ts b/src/atoms/atoms.ts index b732c93..0a94f5a 100644 --- a/src/atoms/atoms.ts +++ b/src/atoms/atoms.ts @@ -37,7 +37,7 @@ export const userAtom = atom({ export const profileAtom = atom({ key: 'profileEdit', default: selector({ - key: 'user', + key: 'userSelect', get: ({ get }) => { const user = get(userAtom); if (!user) @@ -71,7 +71,7 @@ export const profileAtom = atom({ }); export const profileValidationErrorAtom = selector({ - key: 'profileError', + key: 'profileValidationError', get: ({ get }) => { const { avatarUrl, displayName, description, username, email } = get( profileAtom @@ -100,7 +100,7 @@ export const profileValidationErrorAtom = selector({ }); export const canUpdateProfileAtom = selector({ - key: 'profileError', + key: 'canUpdateProfile', get: ({ get }) => { const { avatarUrl, displayName, description, username, email } = get( profileAtom From 9401be80f05c2be4cc17cbed630e69f9722d8697 Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Fri, 8 Jul 2022 00:07:08 -0500 Subject: [PATCH 12/13] fix dup keys --- src/navigation/LazyAppStackNavigator.tsx | 8 ++++- src/navigation/RootNavigation.tsx | 42 +++++------------------- src/stores/player.ts | 4 +-- 3 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/navigation/LazyAppStackNavigator.tsx b/src/navigation/LazyAppStackNavigator.tsx index 494f2fe..8865f9a 100644 --- a/src/navigation/LazyAppStackNavigator.tsx +++ b/src/navigation/LazyAppStackNavigator.tsx @@ -1,10 +1,13 @@ import React, { lazy } from 'react'; import { createStackNavigator } from '@react-navigation/stack'; +import { useMediaQuery } from 'react-responsive'; import { SuspenseLoading } from './SuspenseLoading'; import Colors from 'app/src/constants/Colors'; import { Platform } from 'react-native'; import CancelEditBtn from '../ui/CancelEditBtn'; import DoneEditBtn from '../ui/DoneEditBtn'; +import { useRecoilValue } from 'recoil'; +import { userAtom } from '../atoms/atoms'; const MainTabNavigator = lazy(() => import('app/src/navigation/MainTabNavigator') @@ -132,7 +135,10 @@ export const AppStack = createStackNavigator(); const appTitle = 'Skyhitz - Music NFTs on Stellar'; -export function LazyAppStackNavigator({ user, headerShown }) { +export function LazyAppStackNavigator() { + const user = useRecoilValue(userAtom); + const isDesktop = useMediaQuery({ minWidth: 768 }); + const headerShown = !isDesktop; return ( import('app/src/navigation/LazyAppStackNavigator').then((mod) => ({ @@ -28,34 +24,14 @@ const LazyNavigationContainerSuspense = (props) => ( ); -export default () => { - const [loaded, setLoaded] = useState(false); - const user = useRecoilValue(userAtom); - +const RootNavigation = () => { StatusBar.setBarStyle('light-content'); - const loadAll = async () => { - setLoaded(true); - }; - - useEffect(() => { - loadAll(); - }, []); - - const [headerShown, setHeaderShown] = useState(true); - const isDesktop = useMediaQuery({ minWidth: 768 }); - useEffect(() => { - if (isDesktop) { - setHeaderShown(false); - } - }, []); - - if (loaded) { - return ( - - - - ); - } - return ; + return ( + + + + ); }; + +export default RootNavigation; diff --git a/src/stores/player.ts b/src/stores/player.ts index d111e1b..00b6495 100644 --- a/src/stores/player.ts +++ b/src/stores/player.ts @@ -5,7 +5,7 @@ import { Platform } from 'react-native'; import { atom, useRecoilState } from 'recoil'; const entryAtom = atom({ - key: 'subscribed', + key: 'playerEntry', default: null, }); const showMiniPlayerAtom = atom({ @@ -21,7 +21,7 @@ const tabBarBottomAtom = atom({ default: 0, }); const loopAtom = atom({ - key: 'tabBarBottom', + key: 'loop', default: false, }); const shuffleAtom = atom({ From 6e1d734fcce8b6885e8c15f46f9a5583cb59ff6d Mon Sep 17 00:00:00 2001 From: Alejo Mendoza Date: Mon, 11 Jul 2022 09:21:28 -0500 Subject: [PATCH 13/13] take out lazy modifications --- pages/index.tsx | 8 +- ...ackNavigator.tsx => AppStackNavigator.tsx} | 147 ++++-------------- src/navigation/LazyNavigationContainer.tsx | 26 ---- src/navigation/RootNavigation.tsx | 47 +++--- 4 files changed, 55 insertions(+), 173 deletions(-) rename src/navigation/{LazyAppStackNavigator.tsx => AppStackNavigator.tsx} (58%) delete mode 100644 src/navigation/LazyNavigationContainer.tsx diff --git a/pages/index.tsx b/pages/index.tsx index 173ca00..51887ce 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -21,10 +21,10 @@ export default () => { return ; } return ( - - + + - - + + ); }; diff --git a/src/navigation/LazyAppStackNavigator.tsx b/src/navigation/AppStackNavigator.tsx similarity index 58% rename from src/navigation/LazyAppStackNavigator.tsx rename to src/navigation/AppStackNavigator.tsx index 8865f9a..ecb1ce6 100644 --- a/src/navigation/LazyAppStackNavigator.tsx +++ b/src/navigation/AppStackNavigator.tsx @@ -1,113 +1,26 @@ -import React, { lazy } from 'react'; +import React from 'react'; import { createStackNavigator } from '@react-navigation/stack'; import { useMediaQuery } from 'react-responsive'; -import { SuspenseLoading } from './SuspenseLoading'; import Colors from 'app/src/constants/Colors'; import { Platform } from 'react-native'; import CancelEditBtn from '../ui/CancelEditBtn'; import DoneEditBtn from '../ui/DoneEditBtn'; import { useRecoilValue } from 'recoil'; import { userAtom } from '../atoms/atoms'; - -const MainTabNavigator = lazy(() => - import('app/src/navigation/MainTabNavigator') -); - -const MainTabNavigatorSuspense = (props) => ( - - - -); - -const EditProfileScreen = lazy(() => - import('app/src/profile/EditProfileScreen') -); - -const EditProfileScreenSuspense = (props) => ( - - - -); -const EntryOptionsModal = lazy(() => - import('app/src/search/EntryOptionsModal') -); - -const EntryOptionsModalSuspense = (props) => ( - - - -); -const PricingOptionsModal = lazy(() => - import('app/src/search/PricingOptionsModal') -); -const PricingOptionsModalSuspense = (props) => ( - - - -); - -const PaymentModal = lazy(() => import('app/src/profile/PaymentModal')); -const PaymentModalSuspense = (props) => ( - - - -); - -const LowBalanceModal = lazy(() => import('app/src/profile/LowBalanceModal')); -const LowBalanceModalSuspense = (props) => ( - - - -); - -const WithdrawalModal = lazy(() => import('app/src/profile/WithdrawalModal')); -const WithdrawalModalSuspense = (props) => ( - - - -); -const BuyOptionsModal = lazy(() => import('app/src/ui/BuyOptionsModal')); -const BuyOptionsModalSuspense = (props) => ( - - - -); -const AuthScreen = lazy(() => import('app/src/accounts/AuthScreen')); -const AuthScreenSuspense = (props) => ( - - - -); -const SignUpScreen = lazy(() => import('app/src/accounts/SignUpScreen')); -const SignUpScreenSuspense = (props) => ( - - - -); -const SignInScreen = lazy(() => import('app/src/accounts/SignInScreen')); -const SignInScreenSuspense = (props) => ( - - - -); -const WebApp = lazy(() => import('app/src/marketing/web/Home')); -const WebAppSuspense = (props) => ( - - - -); -const Privacy = lazy(() => import('app/src/marketing/web/Privacy')); -const PrivacySuspense = (props) => ( - - - -); -const Terms = lazy(() => import('app/src/marketing/web/Terms')); -const TermsSuspense = (props) => ( - - - -); +import SignInScreen from 'app/src/accounts/SignInScreen'; +import MainTabNavigator from 'app/src/navigation/MainTabNavigator'; +import EditProfileModal from 'app/src/profile/EditProfileScreen'; +import EntryOptionsModal from 'app/src/search/EntryOptionsModal'; +import PricingOptionsModal from 'app/src/search/PricingOptionsModal'; +import PaymentModal from 'app/src/profile/PaymentModal'; +import LowBalanceModal from 'app/src/profile/LowBalanceModal'; +import WithdrawalModal from 'app/src/profile/WithdrawalModal'; +import BuyOptionsModal from 'app/src/ui/BuyOptionsModal'; +import AuthScreen from 'app/src/accounts/AuthScreen'; +import SignUpScreen from 'app/src/accounts/SignUpScreen'; +import WebApp from 'app/src/marketing/web/Home'; +import Privacy from 'app/src/marketing/web/Privacy'; +import Terms from 'app/src/marketing/web/Terms'; const modalOptions = { headerShown: false, @@ -135,7 +48,7 @@ export const AppStack = createStackNavigator(); const appTitle = 'Skyhitz - Music NFTs on Stellar'; -export function LazyAppStackNavigator() { +export function AppStackNavigator() { const user = useRecoilValue(userAtom); const isDesktop = useMediaQuery({ minWidth: 768 }); const headerShown = !isDesktop; @@ -151,7 +64,7 @@ export function LazyAppStackNavigator() { <> MainTabNavigatorSuspense} + getComponent={() => MainTabNavigator} options={{ headerShown: false }} /> @@ -160,7 +73,7 @@ export function LazyAppStackNavigator() { {Platform.OS === 'web' ? ( WebAppSuspense} + getComponent={() => WebApp} options={{ headerShown: false, title: appTitle, @@ -169,7 +82,7 @@ export function LazyAppStackNavigator() { ) : ( AuthScreenSuspense} + getComponent={() => AuthScreen} options={{ headerShown: false, gestureEnabled: false, @@ -179,7 +92,7 @@ export function LazyAppStackNavigator() { )} SignUpScreenSuspense} + getComponent={() => SignUpScreen} options={{ headerShown: headerShown, headerTitleStyle: { color: Colors.white }, @@ -193,7 +106,7 @@ export function LazyAppStackNavigator() { /> SignInScreenSuspense} + getComponent={() => SignInScreen} options={{ headerShown: headerShown, headerTitleStyle: { color: Colors.white }, @@ -207,7 +120,7 @@ export function LazyAppStackNavigator() { /> PrivacySuspense} + getComponent={() => Privacy} options={{ headerShown: headerShown, headerTitleStyle: { color: Colors.white }, @@ -221,7 +134,7 @@ export function LazyAppStackNavigator() { /> TermsSuspense} + getComponent={() => Terms} options={{ headerShown: headerShown, headerTitleStyle: { color: Colors.white }, @@ -239,7 +152,7 @@ export function LazyAppStackNavigator() { EditProfileScreenSuspense} + getComponent={() => EditProfileModal} options={{ gestureEnabled: false, title: 'Edit Profile', @@ -259,32 +172,32 @@ export function LazyAppStackNavigator() { PaymentModalSuspense} + getComponent={() => PaymentModal} options={modalOptions} /> WithdrawalModalSuspense} + getComponent={() => WithdrawalModal} options={modalOptions} /> BuyOptionsModalSuspense} + getComponent={() => BuyOptionsModal} options={modalOptions} /> EntryOptionsModalSuspense} + getComponent={() => EntryOptionsModal} options={modalOptions} /> PricingOptionsModalSuspense} + getComponent={() => PricingOptionsModal} options={modalOptions} /> LowBalanceModalSuspense} + getComponent={() => LowBalanceModal} options={modalOptions} /> diff --git a/src/navigation/LazyNavigationContainer.tsx b/src/navigation/LazyNavigationContainer.tsx deleted file mode 100644 index 33afc66..0000000 --- a/src/navigation/LazyNavigationContainer.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { NavigationContainer, DefaultTheme } from '@react-navigation/native'; -import Colors from 'app/src/constants/Colors'; -import LinkingConfiguration from './LinkingConfiguration'; -import LoadingScreen from 'app/src/accounts/LoadingScreen'; - -const Theme = { - ...DefaultTheme, - colors: { - ...DefaultTheme.colors, - card: Colors.darkBlue, - background: Colors.darkBlue, - }, -}; - -export default function LazyNavigationContainer(props) { - return ( - } - theme={Theme} - > - {props.children} - - ); -} diff --git a/src/navigation/RootNavigation.tsx b/src/navigation/RootNavigation.tsx index e72bbf8..f03e14c 100644 --- a/src/navigation/RootNavigation.tsx +++ b/src/navigation/RootNavigation.tsx @@ -1,36 +1,31 @@ -import React, { lazy } from 'react'; +import React from 'react'; import { StatusBar } from 'react-native'; -import { SuspenseLoading } from './SuspenseLoading'; +import { AppStackNavigator } from 'app/src/navigation/AppStackNavigator'; +import { NavigationContainer, DefaultTheme } from '@react-navigation/native'; +import Colors from 'app/src/constants/Colors'; +import LinkingConfiguration from './LinkingConfiguration'; +import LoadingScreen from 'app/src/accounts/LoadingScreen'; -const LazyAppStackNavigator = lazy(() => - import('app/src/navigation/LazyAppStackNavigator').then((mod) => ({ - default: mod.LazyAppStackNavigator, - })) -); - -export const LazyAppStackNavigatorSuspense = (props) => ( - - - -); - -const LazyNavigationContainer = lazy(() => - import('app/src/navigation/LazyNavigationContainer') -); - -const LazyNavigationContainerSuspense = (props) => ( - - - -); +const Theme = { + ...DefaultTheme, + colors: { + ...DefaultTheme.colors, + card: Colors.darkBlue, + background: Colors.darkBlue, + }, +}; const RootNavigation = () => { StatusBar.setBarStyle('light-content'); return ( - - - + } + theme={Theme} + > + + ); };