├── .env
├── .gitignore
├── .vscode
└── settings.json
├── App.tsx
├── LICENSE
├── Readme.md
├── android.bak
├── .gitignore
├── app
│ ├── build.gradle
│ ├── debug.keystore
│ ├── google-services.json
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── me
│ │ │ └── isaacojo
│ │ │ └── qui
│ │ │ ├── MainActivity.kt
│ │ │ └── MainApplication.kt
│ │ └── res
│ │ ├── drawable-hdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-mdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-xhdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-xxhdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-xxxhdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable
│ │ ├── rn_edit_text_material.xml
│ │ └── splashscreen.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── values-night
│ │ └── colors.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── react-settings-plugin
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── expo
│ │ └── plugins
│ │ └── ReactSettingsPlugin.kt
└── settings.gradle
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ ├── debug.keystore
│ ├── google-services.json
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── me
│ │ │ └── isaacojo
│ │ │ └── qui
│ │ │ ├── MainActivity.kt
│ │ │ └── MainApplication.kt
│ │ └── res
│ │ ├── drawable-hdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-mdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-xhdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-xxhdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable-xxxhdpi
│ │ ├── notification_icon.png
│ │ └── splashscreen_image.png
│ │ ├── drawable
│ │ ├── rn_edit_text_material.xml
│ │ └── splashscreen.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── values-night
│ │ └── colors.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── app.json
├── assets
├── Theme
│ └── index.ts
├── adaptive-icon.png
├── avatar
│ ├── 1.jpg
│ ├── 2.jpg
│ ├── 3.jpg
│ └── placeholder.png
├── favicon.png
├── fonts
│ ├── Instagram.ttf
│ ├── Mulish-Black.ttf
│ ├── Mulish-Bold.ttf
│ ├── Mulish-ExtraBold.ttf
│ ├── Mulish-Light.ttf
│ ├── Mulish-Medium.ttf
│ ├── Mulish.ttf
│ ├── Panton.ttf
│ ├── PlusJakartaSans-ExtraBold.ttf
│ ├── PlusJakartaSans-Medium.ttf
│ ├── PlusJakartaSans-SemiBold.ttf
│ ├── Roboto-Bold.ttf
│ ├── Roboto-Medium.ttf
│ ├── UberMove-Bold.ttf
│ ├── inst-bold.otf
│ └── inst-regular.otf
├── icon.png
├── images
│ ├── auth.png
│ ├── bg.webp
│ ├── emptyNot.png
│ ├── emptySearch.png
│ ├── image1.jpg
│ ├── move.png
│ ├── notification.png
│ ├── phone.png
│ ├── place-dark.svg
│ ├── placeholder.jpg
│ ├── placeholder.png
│ ├── profile-black.svg
│ ├── profile-white.svg
│ ├── q.png
│ ├── seek.png
│ ├── shoot.png
│ ├── tv-static.gif
│ └── welcome.png
├── lottie
│ ├── emptyList.json
│ ├── isTyping-black.json
│ ├── isTyping-light.json
│ ├── like.json
│ ├── notification.json
│ ├── play.json
│ └── robot.json
├── notification.png
├── qc.png
├── splash copy.png
├── splash-lightmode.png
└── splash.png
├── babel.config.js
├── bun.lockb
├── components
├── chat
│ ├── ChatBox.tsx
│ ├── ChatBuilderText.tsx
│ ├── ModalChatText.tsx
│ ├── PickImageButton.tsx
│ └── TypingBox.tsx
├── discover
│ ├── HeaderTag
│ │ └── index.tsx
│ ├── PeopleContainer
│ │ └── index.tsx
│ ├── PostsContainer
│ │ └── index.tsx
│ ├── SearchBar
│ │ └── index.tsx
│ └── Skeleton
│ │ ├── PostSearchSkeleton.tsx
│ │ └── SearchSkeleton.tsx
├── editProfile
│ └── EditContent.tsx
├── followingFollowers
│ └── FollowingFollowerContainer.tsx
├── global
│ ├── AnimatedScreen
│ │ ├── FadeInView.tsx
│ │ └── index.tsx
│ ├── BottomSheetContainer
│ │ ├── components
│ │ │ ├── CheckBoxPair.tsx
│ │ │ ├── CustomBg.tsx
│ │ │ └── DarkModeView.tsx
│ │ └── index.tsx
│ ├── Buttons
│ │ ├── AddPostButton.tsx
│ │ ├── BottomBarButtons.tsx
│ │ ├── Button.tsx
│ │ └── IconButton.tsx
│ ├── Modal
│ │ └── LoadingOverlay.tsx
│ └── Toast
│ │ └── index.tsx
├── home
│ ├── drawer
│ │ ├── CustomDrawer.tsx
│ │ └── HeaderDrawer.tsx
│ ├── header
│ │ ├── CustomDrawerHeader.tsx
│ │ └── ProfileButton.tsx
│ ├── misc
│ │ ├── EmptyList.tsx
│ │ ├── Skeleton.tsx
│ │ └── SkeletonGroupPost.tsx
│ └── post
│ │ ├── FullScreenPost.tsx
│ │ ├── PostBuilder.tsx
│ │ ├── comment
│ │ ├── CommentBuilder.tsx
│ │ └── PostButton.tsx
│ │ ├── components
│ │ ├── AudioPlayLottie.tsx
│ │ ├── AudioPost.tsx
│ │ ├── CommentButton.tsx
│ │ ├── EmptyLottie.tsx
│ │ ├── Engagements.tsx
│ │ ├── EngagementsFullScreen.tsx
│ │ ├── Fab.tsx
│ │ ├── LikeButton.tsx
│ │ ├── LinkPost.tsx
│ │ ├── LoadingIndicator.tsx
│ │ ├── NameAndTag.tsx
│ │ ├── NameAndTagFullScreen.tsx
│ │ ├── PhotoPost.tsx
│ │ ├── PhotoPostFullScreen.tsx
│ │ ├── ProfileImage.tsx
│ │ ├── RepostButton.tsx
│ │ ├── RingAudio.tsx
│ │ ├── TextPost.tsx
│ │ ├── VideoPost.tsx
│ │ └── VideoPostForFullScreen.tsx
│ │ ├── misc
│ │ ├── EngagementText.tsx
│ │ └── Robot.tsx
│ │ └── testVideo.tsx
├── icons
│ └── index.tsx
├── messages
│ ├── ChatList
│ │ ├── ChatListView.tsx
│ │ ├── ChatModal.tsx
│ │ ├── Fab.tsx
│ │ ├── ListContainer.tsx
│ │ └── index.tsx
│ └── Recent
│ │ ├── AvatarName.tsx
│ │ ├── Me.tsx
│ │ └── index.tsx
├── notifications
│ ├── NotifLottie.tsx
│ └── NotificationBuilder
│ │ └── index.tsx
├── postContent
│ ├── PickAudioButton.tsx
│ ├── PickImageButton.tsx
│ ├── PickVideoButton.tsx
│ ├── PostButton.tsx
│ ├── TextArea.tsx
│ └── VideoTextArea.tsx
├── profile
│ ├── Bio.tsx
│ ├── EditProfile.tsx
│ ├── Header.tsx
│ ├── UploadGif.tsx
│ ├── UploadPhotoModal.tsx
│ └── UploadPic.tsx
├── profilePeople
│ ├── Bio.tsx
│ ├── FollowerUser.tsx
│ ├── Header.tsx
│ └── ViewProfilePhoto.tsx
└── searchUser
│ ├── SearchBox.tsx
│ └── UserContainer.tsx
├── credentials.json
├── data
├── chatDummyData.ts
├── dummyChat.ts
├── murphy.ts
└── test.ts
├── eas.json
├── google-services.json
├── hooks
├── Debounce.tsx
├── GetMode.tsx
└── Socket.tsx
├── ios
├── .gitignore
├── .xcode.env
├── Podfile
├── Podfile.lock
├── Podfile.properties.json
├── Qui.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Qui.xcscheme
├── Qui.xcworkspace
│ └── contents.xcworkspacedata
└── Qui
│ ├── AppDelegate.h
│ ├── AppDelegate.mm
│ ├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── App-Icon-1024x1024@1x.png
│ │ └── Contents.json
│ ├── Contents.json
│ ├── SplashScreen.imageset
│ │ ├── Contents.json
│ │ └── image.png
│ └── SplashScreenBackground.imageset
│ │ ├── Contents.json
│ │ └── image.png
│ ├── Info.plist
│ ├── PrivacyInfo.xcprivacy
│ ├── Qui-Bridging-Header.h
│ ├── Qui.entitlements
│ ├── SplashScreen.storyboard
│ ├── Supporting
│ └── Expo.plist
│ ├── main.m
│ └── noop-file.swift
├── models.json
├── package.json
├── redux
├── api
│ ├── auth.ts
│ ├── chat.ts
│ ├── services.ts
│ └── user.ts
├── hooks
│ └── hooks.ts
├── slice
│ ├── bottomSheet
│ │ └── index.tsx
│ ├── chat
│ │ ├── chatlist.ts
│ │ └── online.ts
│ ├── currentPage
│ │ └── index.ts
│ ├── modal
│ │ └── loading.ts
│ ├── people
│ │ └── search.ts
│ ├── post
│ │ ├── audio.ts
│ │ ├── followed.ts
│ │ ├── index.ts
│ │ └── search.ts
│ ├── prefs
│ │ └── index.ts
│ ├── routes
│ │ └── index.ts
│ ├── toast
│ │ └── toast.ts
│ └── user
│ │ ├── followers.ts
│ │ └── index.ts
├── storage.ts
└── store.ts
├── routes
├── Auth.tsx
├── Main.tsx
├── Main
│ ├── BottomNavigation.tsx
│ └── DrawerNavigation.tsx
└── OnBoard.tsx
├── screen
├── App
│ ├── ChangeData.tsx
│ ├── ChangeData
│ │ ├── ChangeName.tsx
│ │ ├── ChangePassword.tsx
│ │ ├── ChangeUserName.tsx
│ │ └── DeleteAccountModal.tsx
│ ├── ChatScreen.tsx
│ ├── Discover.tsx
│ ├── DiscoverScreens
│ │ ├── Posts.tsx
│ │ └── Users.tsx
│ ├── EditProfile.tsx
│ ├── FollowingFollowerScreens
│ │ ├── Followers.tsx
│ │ └── Following.tsx
│ ├── FollowingFollowers.tsx
│ ├── Home.tsx
│ ├── HomeScreens
│ │ ├── HomeAll.tsx
│ │ └── HomeFollowed.tsx
│ ├── ImageFullScreen.tsx
│ ├── Messages.tsx
│ ├── Notifications.tsx
│ ├── Post.tsx
│ ├── PostContent.tsx
│ ├── PostScreen.tsx
│ ├── Profile.tsx
│ ├── ProfilePeople.tsx
│ ├── ProfileScreens
│ │ ├── MyPosts.tsx
│ │ └── PeoplePosts.tsx
│ ├── SearchUsers.tsx
│ └── VideoFullScreen.tsx
├── Auth
│ ├── Login.tsx
│ ├── Register.tsx
│ └── components
│ │ ├── InputPassword.tsx
│ │ └── InputText.tsx
└── Onboard
│ ├── components
│ ├── OnboardBuilder.tsx
│ └── TrackerTag.tsx
│ └── index.tsx
├── screenshot
└── qui.gif
├── tsconfig.json
├── types
├── api.ts
├── app.ts
├── navigation.ts
└── socket.ts
└── util
├── chatSearch.ts
├── convert.ts
├── date.ts
├── emoji.ts
├── notification.ts
└── socket.ts
/.env:
--------------------------------------------------------------------------------
1 | EXPO_PUBLIC_API_URL=https://qui.isaacojo.me
2 | # EXPO_PUBLIC_API_URL=http://192.168.0.106
3 | EXPO_PUBLIC_PROJECT_ID=e618bb47-6149-4585-8cc8-884c5992795e
4 | # EXPO_PUBLIC_API_URL=https://285b-102-36-135-22.ngrok.io
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2 |
3 | # dependencies
4 | node_modules/
5 | android/.gradle
6 | # Expo
7 | .expo/
8 | dist/
9 | web-build/
10 |
11 | # Native
12 | *.orig.*
13 | *.jks
14 | *.p8
15 | *.p12
16 | *.key
17 | *.mobileprovision
18 | *.apk
19 | android/keystores/release.keystore
20 |
21 | # Metro
22 | .metro-health-check*
23 |
24 | # debug
25 | npm-debug.*
26 | yarn-debug.*
27 | yarn-error.*
28 |
29 | # macOS
30 | .DS_Store
31 | *.pem
32 |
33 | # local env files
34 | .env*.local
35 |
36 | # typescript
37 | *.tsbuildinfo
38 |
39 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": ["reposting"]
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Creative Commons Attribution 4.0 International (CC BY 4.0)
2 |
3 | Copyright (c) 2024 Isaac Ojo
4 |
5 | This work is licensed under the Creative Commons Attribution 4.0 International License.
6 | To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/
7 |
8 | You are free to:
9 | - Share: Copy and redistribute the material in any medium or format
10 | - Adapt: Remix, transform, and build upon the material
11 | - Use commercially: Use the material for commercial purposes
12 |
13 | Under the following terms:
14 | - Attribution: You must give appropriate credit, provide a link to the license, and indicate if changes were made.
15 |
16 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
--------------------------------------------------------------------------------
/android.bak/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Android/IntelliJ
6 | #
7 | build/
8 | .idea
9 | .gradle
10 | local.properties
11 | *.iml
12 | *.hprof
13 | .cxx/
14 |
15 | # Bundle artifacts
16 | *.jsbundle
17 |
--------------------------------------------------------------------------------
/android.bak/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/debug.keystore
--------------------------------------------------------------------------------
/android.bak/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "365442112752",
4 | "project_id": "quiapp-698b0",
5 | "storage_bucket": "quiapp-698b0.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:365442112752:android:f7cad07868aaef170af635",
11 | "android_client_info": {
12 | "package_name": "me.isaacojo.qui"
13 | }
14 | },
15 | "oauth_client": [],
16 | "api_key": [
17 | {
18 | "current_key": "AIzaSyBSquawmwCQmx9-dm4u0wD-VArumgSb0H0"
19 | }
20 | ],
21 | "services": {
22 | "appinvite_service": {
23 | "other_platform_oauth_client": []
24 | }
25 | }
26 | }
27 | ],
28 | "configuration_version": "1"
29 | }
--------------------------------------------------------------------------------
/android.bak/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # react-native-reanimated
11 | -keep class com.swmansion.reanimated.** { *; }
12 | -keep class com.facebook.react.turbomodule.** { *; }
13 |
14 | # Add any project specific keep options here:
15 |
--------------------------------------------------------------------------------
/android.bak/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/java/me/isaacojo/qui/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package me.isaacojo.qui
2 |
3 | import android.os.Build
4 | import android.os.Bundle
5 |
6 | import com.facebook.react.ReactActivity
7 | import com.facebook.react.ReactActivityDelegate
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
9 | import com.facebook.react.defaults.DefaultReactActivityDelegate
10 |
11 | import expo.modules.ReactActivityDelegateWrapper
12 |
13 | class MainActivity : ReactActivity() {
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | // Set the theme to AppTheme BEFORE onCreate to support
16 | // coloring the background, status bar, and navigation bar.
17 | // This is required for expo-splash-screen.
18 | setTheme(R.style.AppTheme);
19 | super.onCreate(null)
20 | }
21 |
22 | /**
23 | * Returns the name of the main component registered from JavaScript. This is used to schedule
24 | * rendering of the component.
25 | */
26 | override fun getMainComponentName(): String = "main"
27 |
28 | /**
29 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
30 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
31 | */
32 | override fun createReactActivityDelegate(): ReactActivityDelegate {
33 | return ReactActivityDelegateWrapper(
34 | this,
35 | BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
36 | object : DefaultReactActivityDelegate(
37 | this,
38 | mainComponentName,
39 | fabricEnabled
40 | ){})
41 | }
42 |
43 | /**
44 | * Align the back button behavior with Android S
45 | * where moving root activities to background instead of finishing activities.
46 | * @see onBackPressed
47 | */
48 | override fun invokeDefaultOnBackPressed() {
49 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
50 | if (!moveTaskToBack(false)) {
51 | // For non-root activities, use the default implementation to finish them.
52 | super.invokeDefaultOnBackPressed()
53 | }
54 | return
55 | }
56 |
57 | // Use the default back button implementation on Android S
58 | // because it's doing more than [Activity.moveTaskToBack] in fact.
59 | super.invokeDefaultOnBackPressed()
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/java/me/isaacojo/qui/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package me.isaacojo.qui
2 |
3 | import android.app.Application
4 | import android.content.res.Configuration
5 |
6 | import com.facebook.react.PackageList
7 | import com.facebook.react.ReactApplication
8 | import com.facebook.react.ReactNativeHost
9 | import com.facebook.react.ReactPackage
10 | import com.facebook.react.ReactHost
11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
12 | import com.facebook.react.defaults.DefaultReactNativeHost
13 | import com.facebook.soloader.SoLoader
14 |
15 | import expo.modules.ApplicationLifecycleDispatcher
16 | import expo.modules.ReactNativeHostWrapper
17 |
18 | class MainApplication : Application(), ReactApplication {
19 |
20 | override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
21 | this,
22 | object : DefaultReactNativeHost(this) {
23 | override fun getPackages(): List {
24 | // Packages that cannot be autolinked yet can be added manually here, for example:
25 | // packages.add(new MyReactNativePackage());
26 | return PackageList(this).packages
27 | }
28 |
29 | override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
30 |
31 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
32 |
33 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
34 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
35 | }
36 | )
37 |
38 | override val reactHost: ReactHost
39 | get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
40 |
41 | override fun onCreate() {
42 | super.onCreate()
43 | SoLoader.init(this, false)
44 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
45 | // If you opted-in for the New Architecture, we load the native entry point for this app.
46 | load()
47 | }
48 | ApplicationLifecycleDispatcher.onApplicationCreate(this)
49 | }
50 |
51 | override fun onConfigurationChanged(newConfig: Configuration) {
52 | super.onConfigurationChanged(newConfig)
53 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-hdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-hdpi/notification_icon.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-hdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-hdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-mdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-mdpi/notification_icon.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-mdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-mdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-xhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-xhdpi/notification_icon.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-xhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-xhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-xxhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-xxhdpi/notification_icon.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-xxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-xxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-xxxhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-xxxhdpi/notification_icon.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/drawable/splashscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #000000
3 | #ffffff
4 | #023c69
5 | #000000
6 | #ffffff
7 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Qui
3 | contain
4 | false
5 | automatic
6 |
--------------------------------------------------------------------------------
/android.bak/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
17 |
--------------------------------------------------------------------------------
/android.bak/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '34.0.0'
6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '23')
7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '34')
8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34')
9 | kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.23'
10 |
11 | ndkVersion = "26.1.10909125"
12 | }
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | dependencies {
18 | classpath 'com.google.gms:google-services:4.4.1'
19 | classpath('com.android.tools.build:gradle')
20 | classpath('com.facebook.react:react-native-gradle-plugin')
21 | classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
22 | }
23 | }
24 |
25 | apply plugin: "com.facebook.react.rootproject"
26 |
27 | allprojects {
28 | repositories {
29 | maven {
30 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
31 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
32 | }
33 | maven {
34 | // Android JSC is installed from npm
35 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist'))
36 | }
37 |
38 | google()
39 | mavenCentral()
40 | maven { url 'https://www.jitpack.io' }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/android.bak/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Automatically convert third-party libraries to use AndroidX
26 | android.enableJetifier=true
27 |
28 | # Enable AAPT2 PNG crunching
29 | android.enablePngCrunchInReleaseBuilds=true
30 |
31 | # Use this property to specify which architecture you want to build.
32 | # You can also override it from the CLI using
33 | # ./gradlew -PreactNativeArchitectures=x86_64
34 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
35 |
36 | # Use this property to enable support to the new architecture.
37 | # This will allow you to use TurboModules and the Fabric render in
38 | # your application. You should enable this flag either if you want
39 | # to write custom TurboModules/Fabric components OR use libraries that
40 | # are providing them.
41 | newArchEnabled=false
42 |
43 | # Use this property to enable or disable the Hermes JS engine.
44 | # If set to false, you will be using JSC instead.
45 | hermesEnabled=true
46 |
47 | # Enable GIF support in React Native images (~200 B increase)
48 | expo.gif.enabled=true
49 | # Enable webp support in React Native images (~85 KB increase)
50 | expo.webp.enabled=true
51 | # Enable animated webp support (~3.4 MB increase)
52 | # Disabled by default because iOS doesn't support animated webp
53 | expo.webp.animated=false
54 |
55 | # Enable network inspector
56 | EX_DEV_CLIENT_NETWORK_INSPECTOR=true
57 |
58 | # Use legacy packaging to compress native libraries in the resulting APK.
59 | expo.useLegacyPackaging=false
60 |
61 | android.extraMavenRepos=[]
--------------------------------------------------------------------------------
/android.bak/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android.bak/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android.bak/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/android.bak/react-settings-plugin/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2 |
3 | plugins {
4 | kotlin("jvm") version "1.9.24"
5 | id("java-gradle-plugin")
6 | }
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | gradlePlugin {
13 | plugins {
14 | create("reactSettingsPlugin") {
15 | id = "com.facebook.react.settings"
16 | implementationClass = "expo.plugins.ReactSettingsPlugin"
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android.bak/react-settings-plugin/src/main/kotlin/expo/plugins/ReactSettingsPlugin.kt:
--------------------------------------------------------------------------------
1 | package expo.plugins
2 |
3 | import org.gradle.api.Plugin
4 | import org.gradle.api.initialization.Settings
5 |
6 | class ReactSettingsPlugin : Plugin {
7 | override fun apply(settings: Settings) {
8 | // Do nothing, just register the plugin.
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Android/IntelliJ
6 | #
7 | build/
8 | .idea
9 | .gradle
10 | local.properties
11 | *.iml
12 | *.hprof
13 | .cxx/
14 |
15 | # Bundle artifacts
16 | *.jsbundle
17 |
--------------------------------------------------------------------------------
/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/debug.keystore
--------------------------------------------------------------------------------
/android/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "365442112752",
4 | "project_id": "quiapp-698b0",
5 | "storage_bucket": "quiapp-698b0.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:365442112752:android:f7cad07868aaef170af635",
11 | "android_client_info": {
12 | "package_name": "me.isaacojo.qui"
13 | }
14 | },
15 | "oauth_client": [],
16 | "api_key": [
17 | {
18 | "current_key": "AIzaSyBSquawmwCQmx9-dm4u0wD-VArumgSb0H0"
19 | }
20 | ],
21 | "services": {
22 | "appinvite_service": {
23 | "other_platform_oauth_client": []
24 | }
25 | }
26 | }
27 | ],
28 | "configuration_version": "1"
29 | }
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # react-native-reanimated
11 | -keep class com.swmansion.reanimated.** { *; }
12 | -keep class com.facebook.react.turbomodule.** { *; }
13 |
14 | # Add any project specific keep options here:
15 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/java/me/isaacojo/qui/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package me.isaacojo.qui
2 |
3 | import android.os.Build
4 | import android.os.Bundle
5 |
6 | import com.facebook.react.ReactActivity
7 | import com.facebook.react.ReactActivityDelegate
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
9 | import com.facebook.react.defaults.DefaultReactActivityDelegate
10 |
11 | import expo.modules.ReactActivityDelegateWrapper
12 |
13 | class MainActivity : ReactActivity() {
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | // Set the theme to AppTheme BEFORE onCreate to support
16 | // coloring the background, status bar, and navigation bar.
17 | // This is required for expo-splash-screen.
18 | setTheme(R.style.AppTheme);
19 | super.onCreate(null)
20 | }
21 |
22 | /**
23 | * Returns the name of the main component registered from JavaScript. This is used to schedule
24 | * rendering of the component.
25 | */
26 | override fun getMainComponentName(): String = "main"
27 |
28 | /**
29 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
30 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
31 | */
32 | override fun createReactActivityDelegate(): ReactActivityDelegate {
33 | return ReactActivityDelegateWrapper(
34 | this,
35 | BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
36 | object : DefaultReactActivityDelegate(
37 | this,
38 | mainComponentName,
39 | fabricEnabled
40 | ){})
41 | }
42 |
43 | /**
44 | * Align the back button behavior with Android S
45 | * where moving root activities to background instead of finishing activities.
46 | * @see onBackPressed
47 | */
48 | override fun invokeDefaultOnBackPressed() {
49 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
50 | if (!moveTaskToBack(false)) {
51 | // For non-root activities, use the default implementation to finish them.
52 | super.invokeDefaultOnBackPressed()
53 | }
54 | return
55 | }
56 |
57 | // Use the default back button implementation on Android S
58 | // because it's doing more than [Activity.moveTaskToBack] in fact.
59 | super.invokeDefaultOnBackPressed()
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/android/app/src/main/java/me/isaacojo/qui/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package me.isaacojo.qui
2 |
3 | import android.app.Application
4 | import android.content.res.Configuration
5 |
6 | import com.facebook.react.PackageList
7 | import com.facebook.react.ReactApplication
8 | import com.facebook.react.ReactNativeHost
9 | import com.facebook.react.ReactPackage
10 | import com.facebook.react.ReactHost
11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
12 | import com.facebook.react.defaults.DefaultReactNativeHost
13 | import com.facebook.react.soloader.OpenSourceMergedSoMapping
14 | import com.facebook.soloader.SoLoader
15 |
16 | import expo.modules.ApplicationLifecycleDispatcher
17 | import expo.modules.ReactNativeHostWrapper
18 |
19 | class MainApplication : Application(), ReactApplication {
20 |
21 | override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(
22 | this,
23 | object : DefaultReactNativeHost(this) {
24 | override fun getPackages(): List {
25 | val packages = PackageList(this).packages
26 | // Packages that cannot be autolinked yet can be added manually here, for example:
27 | // packages.add(new MyReactNativePackage());
28 | return packages
29 | }
30 |
31 | override fun getJSMainModuleName(): String = ".expo/.virtual-metro-entry"
32 |
33 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
34 |
35 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
36 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
37 | }
38 | )
39 |
40 | override val reactHost: ReactHost
41 | get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
42 |
43 | override fun onCreate() {
44 | super.onCreate()
45 | SoLoader.init(this, OpenSourceMergedSoMapping)
46 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
47 | // If you opted-in for the New Architecture, we load the native entry point for this app.
48 | load()
49 | }
50 | ApplicationLifecycleDispatcher.onApplicationCreate(this)
51 | }
52 |
53 | override fun onConfigurationChanged(newConfig: Configuration) {
54 | super.onConfigurationChanged(newConfig)
55 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-hdpi/notification_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-hdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-hdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-mdpi/notification_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-mdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-mdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-xhdpi/notification_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-xxhdpi/notification_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/notification_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-xxxhdpi/notification_icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/splashscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #000000
3 | #ffffff
4 | #023c69
5 | #000000
6 | #ffffff
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Qui
3 | contain
4 | false
5 | automatic
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
16 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '35.0.0'
6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '24')
7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '35')
8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '34')
9 | kotlinVersion = findProperty('android.kotlinVersion') ?: '1.9.24'
10 |
11 | ndkVersion = "26.1.10909125"
12 | }
13 | repositories {
14 | google()
15 | mavenCentral()
16 | }
17 | dependencies {
18 | classpath 'com.google.gms:google-services:4.4.1'
19 | classpath('com.android.tools.build:gradle')
20 | classpath('com.facebook.react:react-native-gradle-plugin')
21 | classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
22 | }
23 | }
24 |
25 | apply plugin: "com.facebook.react.rootproject"
26 |
27 | allprojects {
28 | repositories {
29 | maven {
30 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
31 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
32 | }
33 | maven {
34 | // Android JSC is installed from npm
35 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim(), '../dist'))
36 | }
37 |
38 | google()
39 | mavenCentral()
40 | maven { url 'https://www.jitpack.io' }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Enable AAPT2 PNG crunching
26 | android.enablePngCrunchInReleaseBuilds=true
27 |
28 | # Use this property to specify which architecture you want to build.
29 | # You can also override it from the CLI using
30 | # ./gradlew -PreactNativeArchitectures=x86_64
31 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
32 |
33 | # Use this property to enable support to the new architecture.
34 | # This will allow you to use TurboModules and the Fabric render in
35 | # your application. You should enable this flag either if you want
36 | # to write custom TurboModules/Fabric components OR use libraries that
37 | # are providing them.
38 | newArchEnabled=false
39 |
40 | # Use this property to enable or disable the Hermes JS engine.
41 | # If set to false, you will be using JSC instead.
42 | hermesEnabled=true
43 |
44 | # Enable GIF support in React Native images (~200 B increase)
45 | expo.gif.enabled=true
46 | # Enable webp support in React Native images (~85 KB increase)
47 | expo.webp.enabled=true
48 | # Enable animated webp support (~3.4 MB increase)
49 | # Disabled by default because iOS doesn't support animated webp
50 | expo.webp.animated=false
51 |
52 | # Enable network inspector
53 | EX_DEV_CLIENT_NETWORK_INSPECTOR=true
54 |
55 | # Use legacy packaging to compress native libraries in the resulting APK.
56 | expo.useLegacyPackaging=false
57 |
58 | android.extraMavenRepos=[]
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile().toString())
3 | }
4 | plugins { id("com.facebook.react.settings") }
5 |
6 | extensions.configure(com.facebook.react.ReactSettingsExtension) { ex ->
7 | if (System.getenv('EXPO_USE_COMMUNITY_AUTOLINKING') == '1') {
8 | ex.autolinkLibrariesFromCommand()
9 | } else {
10 | def command = [
11 | 'node',
12 | '--no-warnings',
13 | '--eval',
14 | 'require(require.resolve(\'expo-modules-autolinking\', { paths: [require.resolve(\'expo/package.json\')] }))(process.argv.slice(1))',
15 | 'react-native-config',
16 | '--json',
17 | '--platform',
18 | 'android'
19 | ].toList()
20 | ex.autolinkLibrariesFromCommand(command)
21 | }
22 | }
23 |
24 | rootProject.name = 'Qui'
25 |
26 | dependencyResolutionManagement {
27 | versionCatalogs {
28 | reactAndroidLibs {
29 | from(files(new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../gradle/libs.versions.toml")))
30 | }
31 | }
32 | }
33 |
34 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
35 | useExpoModules()
36 |
37 | include ':app'
38 | includeBuild(new File(["node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile())
39 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "Qui",
4 | "slug": "qui",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "userInterfaceStyle": "automatic",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#000000"
13 | },
14 | "install": {
15 | "exclude": [
16 | "react-native@~0.74.0",
17 | "react-native-reanimated@~3.10.0",
18 | "react-native-gesture-handler@~2.16.1",
19 | "react-native-screens@~3.31.1"
20 | ]
21 | },
22 | "assetBundlePatterns": [
23 | "**/*"
24 | ],
25 | "ios": {
26 | "supportsTablet": true,
27 | "bundleIdentifier": "me.isaacojo.qui"
28 | },
29 | "android": {
30 | "googleServicesFile": "./google-services.json",
31 | "adaptiveIcon": {
32 | "foregroundImage": "./assets/adaptive-icon.png",
33 | "backgroundColor": "#ffffff"
34 | },
35 | "package": "me.isaacojo.qui"
36 | },
37 | "web": {
38 | "favicon": "./assets/favicon.png"
39 | },
40 | "extra": {
41 | "eas": {
42 | "projectId": "e618bb47-6149-4585-8cc8-884c5992795e"
43 | }
44 | },
45 | "plugins": [
46 | [
47 | "expo-notifications",
48 | {
49 | "icon": "./assets/notification.png",
50 | "color": "#ffffff"
51 | }
52 | ],
53 | "react-native-compressor",
54 | "react-native-edge-to-edge",
55 | [
56 | "expo-build-properties",
57 | {
58 | "ios": {
59 | "newArchEnabled": false
60 | },
61 | "android": {
62 | "newArchEnabled": false
63 | }
64 | }
65 | ],
66 | [
67 | "expo-notifications",
68 | {
69 | "icon": "./assets/notification.png",
70 | "color": "#ffffff"
71 | }
72 | ],
73 | "react-native-compressor",
74 | "react-native-edge-to-edge",
75 | [
76 | "expo-build-properties",
77 | {
78 | "ios": {
79 | "newArchEnabled": false
80 | },
81 | "android": {
82 | "newArchEnabled": false
83 | }
84 | }
85 | ],
86 | "expo-video"
87 | ],
88 | "owner": "hojoisaac"
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/assets/Theme/index.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from "@react-navigation/native";
2 |
3 | export const themeLight: Theme = {
4 | dark: false,
5 | colors: {
6 | primary: "white",
7 | background: "white",
8 | card: "black",
9 | text: "black",
10 | border: "#FFFFFF30",
11 | notification: "black",
12 | },
13 | };
14 | export const themeDark: Theme = {
15 | dark: true,
16 | colors: {
17 | primary: "white",
18 | background: "black",
19 | card: "white",
20 | text: "white",
21 | border: "#FFFFFF30",
22 | notification: "white",
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/avatar/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/avatar/1.jpg
--------------------------------------------------------------------------------
/assets/avatar/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/avatar/2.jpg
--------------------------------------------------------------------------------
/assets/avatar/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/avatar/3.jpg
--------------------------------------------------------------------------------
/assets/avatar/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/avatar/placeholder.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/favicon.png
--------------------------------------------------------------------------------
/assets/fonts/Instagram.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Instagram.ttf
--------------------------------------------------------------------------------
/assets/fonts/Mulish-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Mulish-Black.ttf
--------------------------------------------------------------------------------
/assets/fonts/Mulish-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Mulish-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Mulish-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Mulish-ExtraBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Mulish-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Mulish-Light.ttf
--------------------------------------------------------------------------------
/assets/fonts/Mulish-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Mulish-Medium.ttf
--------------------------------------------------------------------------------
/assets/fonts/Mulish.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Mulish.ttf
--------------------------------------------------------------------------------
/assets/fonts/Panton.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Panton.ttf
--------------------------------------------------------------------------------
/assets/fonts/PlusJakartaSans-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/PlusJakartaSans-ExtraBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/PlusJakartaSans-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/PlusJakartaSans-Medium.ttf
--------------------------------------------------------------------------------
/assets/fonts/PlusJakartaSans-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/PlusJakartaSans-SemiBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/assets/fonts/UberMove-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/UberMove-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/inst-bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/inst-bold.otf
--------------------------------------------------------------------------------
/assets/fonts/inst-regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/fonts/inst-regular.otf
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/icon.png
--------------------------------------------------------------------------------
/assets/images/auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/auth.png
--------------------------------------------------------------------------------
/assets/images/bg.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/bg.webp
--------------------------------------------------------------------------------
/assets/images/emptyNot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/emptyNot.png
--------------------------------------------------------------------------------
/assets/images/emptySearch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/emptySearch.png
--------------------------------------------------------------------------------
/assets/images/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/image1.jpg
--------------------------------------------------------------------------------
/assets/images/move.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/move.png
--------------------------------------------------------------------------------
/assets/images/notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/notification.png
--------------------------------------------------------------------------------
/assets/images/phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/phone.png
--------------------------------------------------------------------------------
/assets/images/place-dark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/placeholder.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/placeholder.jpg
--------------------------------------------------------------------------------
/assets/images/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/placeholder.png
--------------------------------------------------------------------------------
/assets/images/profile-black.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/profile-white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/images/q.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/q.png
--------------------------------------------------------------------------------
/assets/images/seek.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/seek.png
--------------------------------------------------------------------------------
/assets/images/shoot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/shoot.png
--------------------------------------------------------------------------------
/assets/images/tv-static.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/tv-static.gif
--------------------------------------------------------------------------------
/assets/images/welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/images/welcome.png
--------------------------------------------------------------------------------
/assets/notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/notification.png
--------------------------------------------------------------------------------
/assets/qc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/qc.png
--------------------------------------------------------------------------------
/assets/splash copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/splash copy.png
--------------------------------------------------------------------------------
/assets/splash-lightmode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/splash-lightmode.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/assets/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 | return {
4 | presets: ["babel-preset-expo"],
5 | plugins: ["react-native-reanimated/plugin"],
6 | env: {
7 | production: {
8 | plugins: ["react-native-paper/babel","transform-remove-console"],
9 | },
10 | },
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/bun.lockb
--------------------------------------------------------------------------------
/components/chat/ChatBox.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, TextInput, Pressable, TextInputProps,Platform } from "react-native";
2 | import React from "react";
3 | import { BlurView } from "expo-blur";
4 | import { SendIcon } from "../icons";
5 | import useGetMode from "../../hooks/GetMode";
6 | import { IChatMessage } from "../../types/api";
7 | import PickImageButton from "./PickImageButton";
8 |
9 | export default function ChatBox({
10 | props,
11 | onPress,
12 | handleSetPhotoPost,
13 | }: {
14 | props: TextInputProps;
15 | onPress: () => void;
16 | handleSetPhotoPost: (mimeType: string, uri: string, size: number) => void;
17 | }) {
18 | const dark = useGetMode();
19 | const color = dark ? "white" : "black";
20 | const tint = dark ? "dark" : "light";
21 | const rippleColor = dark ? "#000000" : "#A1A0A0";
22 | return (
23 |
36 |
42 |
43 |
58 |
59 |
68 |
80 |
81 |
82 |
83 |
84 |
85 | );
86 | }
87 |
--------------------------------------------------------------------------------
/components/chat/PickImageButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import { CameraIcon } from "../icons";
4 | import ImagePicker from "react-native-image-crop-picker";
5 | import useGetMode from "../../hooks/GetMode";
6 | export default function PickImageButton({
7 | handleSetPhotoPost,
8 | }: {
9 | handleSetPhotoPost: (mimeType: string, uri: string, size: number) => void;
10 | }) {
11 | const dark = useGetMode();
12 | const backgroundColor = dark ? "white" : "black";
13 | const backgroundColorView = "#FD5E02" ;
14 | const rippleColor = !dark ? "#ABABAB" : "#55555500";
15 |
16 | return (
17 |
29 | {
31 | ImagePicker.openPicker({
32 | cropperStatusBarColor: "#000000",
33 | cropperToolbarColor: "#000000",
34 | showCropGuidelines: false,
35 | cropperTintColor: "red",
36 | cropperActiveWidgetColor: "red",
37 | mediaType: "photo",
38 | cropperToolbarWidgetColor: "#FFFFFF",
39 | cropperCancelText: "#FFFFFF",
40 | cropperChooseColor: "#FFFFFF",
41 | })
42 | .then((image) => {
43 | handleSetPhotoPost(image?.mime, image?.path, image?.size);
44 | })
45 | .catch((e) => {});
46 | }}
47 | android_ripple={{ color: rippleColor, foreground: true }}
48 | style={{
49 | width: 30,
50 | height: 30,
51 | justifyContent: "center",
52 | alignItems: "center",
53 | }}
54 | >
55 |
56 |
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/components/chat/TypingBox.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Dimensions } from "react-native";
2 | import React, { useEffect, useRef } from "react";
3 | import useGetMode from "../../hooks/GetMode";
4 | import { formatDateForChat } from "../../util/date";
5 | import Lottie from "lottie-react-native";
6 | import Animated, {
7 | FadeIn,
8 | FadeInDown,
9 | FadeInUp,
10 | FadeOutDown,
11 | FadeOutLeft,
12 | } from "react-native-reanimated";
13 | const { width } = Dimensions.get("window");
14 | export default function TypingBox() {
15 | const dark = useGetMode();
16 | const backgroundColorForMe = dark ? "#35383A" : "#0c81f8";
17 | const backgroundColor = dark ? "#181B1D" : "#e8e8eb";
18 | const color = dark ? "white" : "black";
19 | const animationRef = useRef(null);
20 |
21 | useEffect(() => {
22 | animationRef.current?.play();
23 |
24 | return () => {
25 | animationRef.current?.reset();
26 | };
27 | }, []);
28 | return (
29 |
34 |
35 |
47 |
55 |
64 |
65 |
66 |
67 |
68 | );
69 | }
70 |
--------------------------------------------------------------------------------
/components/discover/HeaderTag/index.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import useGetMode from "../../../hooks/GetMode";
4 |
5 | export default function HeaderTag({
6 | text,
7 | onPress,
8 | selected,
9 | }: {
10 | text: string;
11 | onPress: () => void;
12 | selected: boolean;
13 | }) {
14 | const dark = useGetMode();
15 | const color = !dark ? "white" : "black";
16 | const backgroundColor = !dark ? "black" : "white";
17 | return (
18 |
28 |
42 |
43 | {text}
44 |
45 |
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/components/discover/SearchBar/index.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | TextInput,
5 | StyleProp,
6 | ViewStyle,
7 | Dimensions,
8 | } from "react-native";
9 | import useGetMode from "../../../hooks/GetMode";
10 | import Animated, { FadeInRight } from "react-native-reanimated";
11 | import { useCallback, useEffect, useMemo, useState } from "react";
12 | import { useDebounce } from "../../../hooks/Debounce";
13 | import {
14 | useLazySearchPeopleQuery,
15 | useLazySearchPostsQuery,
16 | } from "../../../redux/api/services";
17 | import { useSafeAreaInsets } from "react-native-safe-area-context";
18 |
19 | const { width } = Dimensions.get("window");
20 | export default function SearchBar() {
21 | const dark = useGetMode();
22 | const [searchParam, setSearchParam] = useState("");
23 | const color = dark ? "white" : "black";
24 | const placeholderColor = !dark ? "grey" : "grey";
25 | const borderColor = dark ? "#FFFFFF" : "#DAD9D9";
26 | const backgroundColor = dark ? "#383838" : "#EAEBEB";
27 | const query = useDebounce(searchParam, 1000);
28 | const insets = useSafeAreaInsets();
29 | const [getSearchPosts, res] = useLazySearchPostsQuery();
30 | const [getSearchPeople] = useLazySearchPeopleQuery();
31 |
32 | useEffect(() => {
33 | if (query) {
34 | getSearchPosts({ q: query });
35 | getSearchPeople({ q: query });
36 | }
37 | }, [query]);
38 |
39 | return (
40 |
56 | setSearchParam(text)}
60 | placeholderTextColor={placeholderColor}
61 | style={{
62 | width: "100%",
63 | fontSize: 16,
64 | color,
65 | fontFamily: "jakara",
66 | includeFontPadding: false,
67 | }}
68 | />
69 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/components/discover/Skeleton/PostSearchSkeleton.tsx:
--------------------------------------------------------------------------------
1 | import { Dimensions, Text, View } from "react-native";
2 | import useGetMode from "../../../hooks/GetMode";
3 |
4 | const { width } = Dimensions.get("window");
5 |
6 | export const PostSearchSkeleton = () => {
7 | const dark = useGetMode();
8 | const backgroundColor = dark ? "#343434" : "#BBBBBB";
9 | return (
10 |
11 |
12 |
20 |
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/components/discover/Skeleton/SearchSkeleton.tsx:
--------------------------------------------------------------------------------
1 | import { Dimensions, Text, View } from "react-native";
2 | import useGetMode from "../../../hooks/GetMode";
3 |
4 | const { width } = Dimensions.get("window");
5 |
6 | export const SearchSkeleton = () => {
7 | const dark = useGetMode();
8 | const shimmerColors = dark
9 | ? ["#4C4C4C", "#696969", "#383838"]
10 | : ["#ebebeb", "#c5c5c5", "#ebebeb"];
11 | const backgroundColor = dark ? "#343434" : "#BBBBBB";
12 | return (
13 |
14 |
15 |
23 |
24 |
25 | );
26 | };
27 |
--------------------------------------------------------------------------------
/components/editProfile/EditContent.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import useGetMode from "../../hooks/GetMode";
3 |
4 | export default function EditContent({
5 | text,
6 | Icon,
7 | color,
8 | onPress,
9 | }: {
10 | text: string;
11 | Icon: React.ElementType;
12 | color: string;
13 | onPress: () => void;
14 | }) {
15 | const dark = useGetMode();
16 | const backgroundColor = !dark ? "#E5E9F899" : "#25252599";
17 | const textColor = !dark ? "black" : "white";
18 | const rColor = !dark ? "#00000014" : "#BBBBBB";
19 | return (
20 |
21 |
22 |
33 |
34 |
42 | {text}
43 |
44 |
45 |
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/components/global/AnimatedScreen/FadeInView.tsx:
--------------------------------------------------------------------------------
1 | import { PropsWithChildren, useRef, useEffect } from "react";
2 | import { ViewStyle, Animated } from "react-native";
3 |
4 | type FadeInViewProps = PropsWithChildren<{ style: ViewStyle }>;
5 |
6 | export const FadeInView: React.FC = (props) => {
7 | const fadeAnim = useRef(new Animated.Value(0)).current; // Initial value for opacity: 0
8 |
9 | useEffect(() => {
10 | Animated.timing(fadeAnim, {
11 | toValue: 1,
12 |
13 | duration: 1000,
14 | useNativeDriver: true,
15 | }).start();
16 | }, [fadeAnim]);
17 |
18 | return (
19 |
25 | {props.children}
26 |
27 | );
28 | };
29 |
--------------------------------------------------------------------------------
/components/global/AnimatedScreen/index.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode, useCallback, useEffect } from "react";
2 |
3 | import Animated, {
4 | interpolate,
5 | useAnimatedStyle,
6 | useSharedValue,
7 | withTiming,
8 | } from "react-native-reanimated";
9 | import { useFocusEffect, useRoute } from "@react-navigation/native";
10 | import {
11 | ImageBackground,
12 | StyleProp,
13 | View,
14 | ViewStyle,
15 | useColorScheme,
16 | } from "react-native";
17 | import useGetMode from "../../../hooks/GetMode";
18 | import { Image } from "expo-image";
19 |
20 | export default function AnimatedScreen({
21 | children,
22 | style,
23 | }: {
24 | children: ReactNode;
25 | style?: ViewStyle;
26 | }) {
27 | const opacity = useSharedValue(0);
28 | const animatedStyle = useAnimatedStyle(() => {
29 | return {
30 | opacity: interpolate(opacity.value, [0, 1], [0, 1]), // map opacity value to range between 0 and 1
31 | };
32 | });
33 |
34 | useFocusEffect(
35 | useCallback(() => {
36 | opacity.value = withTiming(1, { duration: 250 });
37 |
38 | return () => {
39 | Image.clearMemoryCache();
40 | opacity.value = withTiming(0, { duration: 250 });
41 | };
42 | }, [opacity])
43 | );
44 | return (
45 |
46 |
53 | {children}
54 |
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/components/global/BottomSheetContainer/components/CheckBoxPair.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import BouncyCheckbox from "react-native-bouncy-checkbox";
3 | import { useAppDispatch } from "../../../../redux/hooks/hooks";
4 | import { setMode } from "../../../../redux/slice/prefs";
5 | import useGetMode from "../../../../hooks/GetMode";
6 |
7 | export default function CheckBoxPair({
8 | text,
9 | type,
10 | checked,
11 | }: {
12 | text: string;
13 | checked: boolean;
14 | type: "system" | "light" | "dark";
15 | }) {
16 | const dispatch = useAppDispatch();
17 | const dark = useGetMode();
18 | const color = !dark ? "black" : "white";
19 | const fillColor = !dark ? "black" : "white";
20 | const unFillColor = !dark ? "#505050" : "#757575";
21 | const handleUpdateMode = ()=>{
22 | dispatch(setMode({ mode: type }));
23 | }
24 | return (
25 |
36 |
45 | {text}
46 |
47 |
48 |
58 |
59 |
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/components/global/BottomSheetContainer/components/CustomBg.tsx:
--------------------------------------------------------------------------------
1 | import React, { useMemo } from "react";
2 | import { BottomSheetBackgroundProps } from "@gorhom/bottom-sheet";
3 | import Animated, {
4 | useAnimatedStyle,
5 | interpolateColor,
6 | } from "react-native-reanimated";
7 | import { View, useColorScheme } from "react-native";
8 | import { BlurView } from "expo-blur";
9 | import useGetMode from "../../../../hooks/GetMode";
10 | import { useAppSelector } from "../../../../redux/hooks/hooks";
11 |
12 | export const CustomBackground: React.FC = ({
13 | style,
14 | animatedIndex,
15 | }) => {
16 | //#region styles
17 | const dark = useGetMode();
18 |
19 | const isDarkTheme = dark;
20 | const tint = isDarkTheme ? "dark": "light"
21 | const backgroundColor = isDarkTheme ? "white": "black"
22 | const containerAnimatedStyle = useAnimatedStyle(() => ({
23 | // @ts-ignore
24 | backgroundColor: interpolateColor(
25 | animatedIndex.value,
26 | [0, 1],
27 | ["#D7EBA800", isDarkTheme ? "#06060600" : "#D7EBA800"]
28 | ),
29 | }));
30 |
31 | const containerStyle = useMemo(
32 | () => [style, containerAnimatedStyle],
33 | [style, containerAnimatedStyle]
34 | );
35 | const isHighEndDevice = useAppSelector((state) => state?.prefs?.isHighEnd);
36 | // render
37 | return (
38 | <>
39 |
43 |
49 |
50 |
51 | >
52 | );
53 | };
54 |
55 | export default CustomBackground;
56 |
--------------------------------------------------------------------------------
/components/global/BottomSheetContainer/components/DarkModeView.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 |
3 | import CheckBoxPair from "./CheckBoxPair";
4 | import { useEffect, useMemo, useState } from "react";
5 | import { useAppSelector } from "../../../../redux/hooks/hooks";
6 | import useGetMode from "../../../../hooks/GetMode";
7 |
8 | export default function DarkModeView() {
9 | const mode = useAppSelector((state) => state?.prefs?.mode);
10 | const dark = useGetMode();
11 | const backgroundColor = dark ? "#969696" : "#B5AEAE";
12 | const color = dark ? "#FFFFFF" : "#000000";
13 | const [checked, setChecked] = useState(() => {
14 | return {
15 | system: mode === "system",
16 | dark: mode === "dark",
17 | light: mode === "light",
18 | };
19 | });
20 |
21 | useMemo(() => {
22 | setChecked({
23 | system: mode === "system" ? true : false,
24 | dark: mode === "dark" ? true : false,
25 | light: mode === "light" ? true : false,
26 | });
27 | }, [mode]);
28 |
29 | return (
30 |
31 |
32 |
33 | Dark mode
34 |
35 |
36 |
37 |
45 |
46 |
47 |
52 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/components/global/Buttons/AddPostButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import { AddIcon } from "../../icons";
4 |
5 | export default function AddPostButton() {
6 | return (
7 |
15 |
22 |
23 |
24 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/components/global/Buttons/BottomBarButtons.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable, useColorScheme } from "react-native";
2 | import React, { ElementType } from "react";
3 | import { useNavigation } from "@react-navigation/native";
4 | import { HomeNavigationProp, RootStackParamList } from "../../../types/navigation";
5 | import useGetMode from "../../../hooks/GetMode";
6 |
7 | export default function IconButtons({
8 | Icon,
9 | onPress,
10 | }: {
11 | Icon: ElementType;
12 | onPress: () => void;
13 | }) {
14 | const navigate = useNavigation();
15 | const dark = useGetMode();
16 | const isDark = dark;
17 | const color = isDark ? "white" : "black";
18 | return (
19 |
29 | {
42 | onPress();
43 |
44 | }}
45 | >
46 |
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/components/global/Buttons/Button.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | Pressable,
5 | useColorScheme,
6 | ActivityIndicator,
7 | } from "react-native";
8 | import React, { ReactNode } from "react";
9 | import useGetMode from "../../../hooks/GetMode";
10 |
11 | export default function Button({
12 | children,
13 | onPress,
14 | loading,
15 | }: {
16 | children: ReactNode;
17 | onPress: () => void;
18 | loading: boolean;
19 | }) {
20 | const dark = useGetMode();
21 | const isDark = dark;
22 | const backgroundColor = isDark ? "white" : "black";
23 | const color = !isDark ? "white" : "black";
24 | const loadingColor = isDark ? "black" : "white";
25 | return (
26 |
35 |
47 | {loading ? : children}
48 |
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/components/global/Buttons/IconButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React, { ElementType } from "react";
3 |
4 | export type IconButton = { Icon: JSX.Element; onPress: () => void };
5 |
6 | export default function IconButton({ Icon, onPress }: IconButton) {
7 | return (
8 |
9 |
12 | {Icon}
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/components/global/Modal/LoadingOverlay.tsx:
--------------------------------------------------------------------------------
1 | import { BlurView } from "expo-blur";
2 | import React, { useState } from "react";
3 | import {
4 | Alert,
5 | Modal,
6 | StyleSheet,
7 | Text,
8 | Pressable,
9 | View,
10 | Dimensions,
11 | } from "react-native";
12 | import { ActivityIndicator, Portal } from "react-native-paper";
13 | import useGetMode from "../../../hooks/GetMode";
14 | import { useAppDispatch, useAppSelector } from "../../../redux/hooks/hooks";
15 | import {
16 | closeLoadingModal,
17 | openLoadingModal,
18 | } from "../../../redux/slice/modal/loading";
19 |
20 | const { height, width } = Dimensions.get("screen");
21 | export const LoadingModal = () => {
22 | const loadingModal = useAppSelector((state) => state.loadingModal);
23 | const dispatch = useAppDispatch();
24 | const dark = useGetMode();
25 | const color = !dark ? "black" : "white";
26 | const tint = dark ? "dark" : "light";
27 | const isHighEndDevice = useAppSelector((state) => state?.prefs?.isHighEnd);
28 | return (
29 |
30 |
31 | {
37 | dispatch(closeLoadingModal());
38 | }}
39 | >
40 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | );
54 | };
55 |
56 | const styles = StyleSheet.create({
57 | centeredView: {
58 | flex: 1,
59 | justifyContent: "center",
60 | alignItems: "center",
61 | },
62 | });
63 |
--------------------------------------------------------------------------------
/components/home/header/CustomDrawerHeader.tsx:
--------------------------------------------------------------------------------
1 | import { BlurView } from "expo-blur";
2 | import {
3 | View,
4 | Text,
5 | StyleSheet,
6 | SafeAreaView,
7 | useColorScheme,
8 | } from "react-native";
9 | import { useNavigation } from "@react-navigation/native";
10 | import ProfileButton from "./ProfileButton";
11 | import React from "react";
12 | import { HomeNavigationProp } from "../../../types/navigation";
13 | import Animated from "react-native-reanimated";
14 | import {
15 | DrawerHeaderProps,
16 | DrawerProps,
17 | } from "@react-navigation/drawer/lib/typescript/src/types";
18 | import useGetMode from "../../../hooks/GetMode";
19 | import { useAppSelector } from "../../../redux/hooks/hooks";
20 | function CustomDrawerHeader(props: DrawerHeaderProps) {
21 | const navigation = useNavigation();
22 | const dark = useGetMode();
23 | const isDark = dark;
24 | const TextColor = isDark ? "white" : "black";
25 | const isHighEndDevice = useAppSelector((state) => state?.prefs?.isHighEnd);
26 | return (
27 |
28 |
37 |
38 |
39 | props.navigation.toggleDrawer()}
41 | size={45}
42 | color={isDark ? "white" : "black"}
43 | />
44 |
45 |
46 |
47 |
48 | {props.options.title}
49 |
50 |
51 |
52 |
53 |
54 |
55 | );
56 | }
57 |
58 | export default React.memo(CustomDrawerHeader);
59 | const style = StyleSheet.create({
60 | blurView: {
61 | position: "absolute",
62 | top: 0,
63 | left: 0,
64 | height: 90,
65 | paddingHorizontal: 10,
66 | borderBlockColor: "#0000002F",
67 | borderBottomWidth: 0.5,
68 | right: 0,
69 | alignItems: "center",
70 | },
71 | titleView: {
72 | paddingTop: 44,
73 | paddingBottom: 10,
74 | width: "100%",
75 | height: "100%",
76 | flexDirection: "row",
77 | alignItems: "center",
78 | },
79 | headerStyle: {
80 | fontFamily: "instaBold",
81 | fontSize: 20,
82 | },
83 | });
84 |
--------------------------------------------------------------------------------
/components/home/header/ProfileButton.tsx:
--------------------------------------------------------------------------------
1 | import { Pressable, StyleProp, View, ViewStyle } from "react-native";
2 | import { ProfileIcon } from "../../icons";
3 | import { ViewProps } from "react-native-svg/lib/typescript/fabric/utils";
4 | import { useAppSelector } from "../../../redux/hooks/hooks";
5 | import { Image } from "expo-image";
6 | import useGetMode from "../../../hooks/GetMode";
7 |
8 | type ProfileButtonType = {
9 | onPress: () => void;
10 | color: string;
11 | size: number;
12 | style?: StyleProp;
13 | };
14 | export default function ProfileButton({
15 | onPress,
16 | color,
17 | size,
18 | style,
19 | }: ProfileButtonType) {
20 | const imageUri = useAppSelector((state) => state.user.data?.imageUri);
21 | const dark = useGetMode();
22 | return (
23 |
24 |
25 | {imageUri ? (
26 |
36 | ) : (
37 |
38 | )}
39 |
40 |
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/components/home/misc/EmptyList.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import Animated, { FadeInDown, FadeOutDown } from "react-native-reanimated";
4 | import EmptyLottie from "../post/components/EmptyLottie";
5 | import useGetMode from "../../../hooks/GetMode";
6 | import { ReloadIcon } from "../../icons";
7 | import { useLazyGetAllPostsQuery } from "../../../redux/api/services";
8 |
9 | export default function EmptyList({handleRefetch}:{handleRefetch:()=>void}) {
10 | const dark = useGetMode();
11 | const isDark = dark;
12 | const [getPosts] = useLazyGetAllPostsQuery();
13 | const color = isDark ? "white" : "black";
14 | const backgroundColor = !isDark ? "#FFFFFFD2" : "#0000008F";
15 | return (
16 |
17 |
27 |
28 |
41 |
55 |
56 |
57 |
58 |
59 |
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/components/home/misc/Skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { Dimensions, Text, View } from "react-native";
2 | import useGetMode from "../../../hooks/GetMode";
3 |
4 | const { width } = Dimensions.get("window");
5 | export const Skeleton = () => {
6 | const dark = useGetMode();
7 | const shimmerColors = dark
8 | ? ["#4C4C4C", "#696969", "#383838"]
9 | : ["#ebebeb", "#c5c5c5", "#ebebeb"];
10 |
11 | const backgroundColor = dark ? "#343434" : "#BBBBBB";
12 | return (
13 |
14 |
17 |
18 |
26 |
34 |
35 |
43 |
44 |
45 | );
46 | };
47 |
--------------------------------------------------------------------------------
/components/home/misc/SkeletonGroupPost.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React, { useEffect } from "react";
3 | import { Skeleton } from "./Skeleton";
4 | import Animated, {
5 | cancelAnimation,
6 | interpolate,
7 | useAnimatedStyle,
8 | useSharedValue,
9 | withRepeat,
10 | withTiming,
11 | } from "react-native-reanimated";
12 |
13 | export default function SkeletonGroupPost() {
14 | const opacity = useSharedValue(0);
15 | const animatedStyle = useAnimatedStyle(() => {
16 | return {
17 | opacity: interpolate(opacity.value, [0, 1], [1, 0]),
18 | };
19 | });
20 |
21 | useEffect(() => {
22 | opacity.value = withRepeat(withTiming(1, { duration: 900 }), -1, true);
23 | return () => {
24 | cancelAnimation(opacity);
25 | };
26 | }, []);
27 |
28 | return (
29 |
35 | {[0, 1, 2].map((idx) => (
36 |
37 | ))}
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/components/home/post/comment/PostButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import useGetMode from "../../../../hooks/GetMode";
4 | import Animated, {
5 | BounceIn,
6 | BounceOut,
7 | FadeInDown,
8 | FadeInUp,
9 | FadeOutDown,
10 | } from "react-native-reanimated";
11 |
12 | export default function CommentButton({
13 | isLoading,
14 | isDisabled,
15 | onPress,
16 | }: {
17 | isLoading: boolean;
18 | isDisabled?: boolean;
19 | onPress: () => void;
20 | }) {
21 | const dark = useGetMode();
22 |
23 | const backgroundColor = dark ? "white" : "black";
24 | const backgroundColorLoad = dark ? "#FFFFFF38" : "#00000041";
25 | const rippleColor = !dark ? "white" : "black";
26 | const color = !dark ? "white" : "black";
27 | return (
28 |
40 |
53 | Post
54 |
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/components/home/post/components/AudioPlayLottie.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react";
2 | import Lottie from "lottie-react-native";
3 | import { View } from "react-native";
4 | import { useAppSelector } from "../../../../redux/hooks/hooks";
5 | import { Image } from "expo-image";
6 |
7 |
8 | export default function AudioPlayLottie({
9 | animationRef,
10 | src,
11 | }: {
12 | animationRef: React.RefObject;
13 | src: string;
14 | }) {
15 | useEffect(() => {
16 | animationRef.current?.pause();
17 | }, []);
18 |
19 | return (
20 |
28 |
38 |
42 |
43 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/components/home/post/components/EmptyLottie.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react";
2 | import Lottie from "lottie-react-native";
3 | import { Dimensions } from "react-native";
4 | const { width } = Dimensions.get("window");
5 | export default function EmptyLottie() {
6 | const lottieRef = useRef(null);
7 |
8 | useEffect(() => {
9 | lottieRef.current?.play();
10 | return () => lottieRef.current?.pause();
11 | }, []);
12 |
13 | return (
14 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/components/home/post/components/Fab.tsx:
--------------------------------------------------------------------------------
1 | import { BlurView } from "expo-blur";
2 | import { View, Pressable } from "react-native";
3 | import useGetMode from "../../../../hooks/GetMode";
4 | import { useNavigation } from "@react-navigation/native";
5 | import { HomeNavigationProp } from "../../../../types/navigation";
6 | import DeviceInfo from "react-native-device-info";
7 | import { useAppSelector } from "../../../../redux/hooks/hooks";
8 |
9 | export default function Fab({ item }: { item: JSX.Element }) {
10 | const dark = useGetMode();
11 | const isDark = dark;
12 | const navigation = useNavigation();
13 | const tint = isDark ? "dark" : "light";
14 | const backgroundColor = !isDark ? "#DEDEDE" : "#303030";
15 | const isHighEndDevice = useAppSelector((state) => state?.prefs?.isHighEnd);
16 |
17 | return (
18 |
36 | {
39 | navigation.navigate("PostContent");
40 | }}
41 | style={{
42 | height: "100%",
43 | width: "100%",
44 | alignItems: "center",
45 | justifyContent: "center",
46 | }}
47 | >
48 | <>
49 | {isHighEndDevice && (
50 |
63 | )}
64 | {item}
65 | >
66 |
67 |
68 | );
69 | }
70 |
--------------------------------------------------------------------------------
/components/home/post/components/LoadingIndicator.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { ActivityIndicator } from "react-native";
3 |
4 | function Loading() {
5 | return ;
6 | }
7 |
8 | export default React.memo(Loading);
9 |
--------------------------------------------------------------------------------
/components/home/post/components/NameAndTagFullScreen.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, useColorScheme } from "react-native";
2 | import React from "react";
3 | import { VerifiedIcon } from "../../../icons";
4 | import useGetMode from "../../../../hooks/GetMode";
5 |
6 | export default function NameAndTagFullScreen({
7 | name,
8 | verified,
9 |
10 | userTag,
11 | }: {
12 | name: string;
13 |
14 | verified: boolean;
15 | userTag: string;
16 | }) {
17 | const dark = useGetMode();
18 | const isDark = dark;
19 | const color = isDark ? "white" : "black";
20 | const backgroundColor = isDark ? "white" : "black";
21 | return (
22 |
23 |
24 |
25 |
33 | {name}
34 |
35 | {verified && }
36 |
37 |
38 |
47 | @{userTag}
48 |
49 |
50 |
51 | );
52 | }
53 |
--------------------------------------------------------------------------------
/components/home/post/components/PhotoPost.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | FlatList,
5 | Pressable,
6 | Button,
7 | Image as RNImage,
8 | } from "react-native";
9 | import { Image } from "expo-image";
10 | import { useNavigation } from "@react-navigation/native";
11 | import { HomeNavigationProp } from "../../../../types/navigation";
12 | import { useState } from "react";
13 |
14 | export default function PhotoPost({
15 | photoUri,
16 | width,
17 | height,
18 | id,
19 | }: {
20 | photoUri: string;
21 | width: number;
22 | height: number;
23 | id: string;
24 | }) {
25 | const navigation = useNavigation();
26 | return (
27 |
39 | {
42 | navigation.navigate("ImageFullScreen", {
43 | photoUri: photoUri,
44 | id,
45 | height,
46 | width,
47 | });
48 | }}
49 | style={{
50 | width: "100%",
51 | height: 200,
52 | borderRadius: 15,
53 | }}
54 | >
55 |
63 |
64 |
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/components/home/post/components/PhotoPostFullScreen.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | FlatList,
5 | Pressable,
6 | Button,
7 | Image as RNImage,
8 | } from "react-native";
9 | import { Image } from "expo-image";
10 | import { useNavigation } from "@react-navigation/native";
11 | import { HomeNavigationProp } from "../../../../types/navigation";
12 | import { useState } from "react";
13 |
14 | export default function PhotoPost({
15 | photoUri,
16 | width,
17 | height,
18 | id,
19 | }: {
20 | photoUri: string;
21 | width: number;
22 | height: number;
23 | id: string;
24 | }) {
25 | const navigation = useNavigation();
26 | return (
27 |
39 | {
42 | navigation.navigate("ImageFullScreen", {
43 | photoUri: photoUri,
44 | id,
45 | height,
46 | width,
47 | });
48 | }}
49 | style={{
50 | width: "100%",
51 | height: 200,
52 | borderRadius: 15,
53 | }}
54 | >
55 |
61 |
62 |
63 | );
64 | }
65 |
--------------------------------------------------------------------------------
/components/home/post/components/ProfileImage.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React from "react";
3 | import { Image } from "expo-image";
4 | import useGetMode from "../../../../hooks/GetMode";
5 |
6 | export default function ProfileImage({ imageUri }: { imageUri: string }) {
7 | const dark = useGetMode()
8 | return (
9 |
10 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/components/home/post/components/RingAudio.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react";
2 | import Lottie from "lottie-react-native";
3 | import { View } from "react-native";
4 | import { useAppSelector } from "../../../../redux/hooks/hooks";
5 | import { Image } from "expo-image";
6 |
7 |
8 |
9 | export default function RingAudio({
10 | animationRef,
11 | }: {
12 | animationRef: React.RefObject;
13 | }) {
14 | useEffect(() => {
15 | animationRef.current?.pause();
16 | }, []);
17 | const userImage = useAppSelector((state) => state.user.data?.imageUri);
18 | return (
19 |
27 |
37 |
41 |
42 |
47 |
48 | );
49 | }
50 |
--------------------------------------------------------------------------------
/components/home/post/components/TextPost.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, useColorScheme } from "react-native";
2 | import React from "react";
3 | import useGetMode from "../../../../hooks/GetMode";
4 |
5 | export default function TextPost({
6 | postText,
7 | photoUri,
8 | videoUri,
9 | }: {
10 | postText: string;
11 | photoUri: string[];
12 | videoUri?: string;
13 | }) {
14 | const dark = useGetMode();
15 | const isDark = dark;
16 | const color = isDark ? "white" : "black";
17 | const selectionColor = isDark ? "#C5C5C591" : "#0000007A"
18 | return (
19 | 0 || videoUri ? 2 : 10,
26 | color,
27 | }}
28 | >
29 | {postText}
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/components/home/post/components/VideoPost.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | Pressable,
5 | ActivityIndicator,
6 | useColorScheme,
7 | } from "react-native";
8 | import React, { useCallback, useEffect, useState } from "react";
9 | import IconButton from "../../../global/Buttons/IconButton";
10 | import { AVPlaybackStatus, ResizeMode, Video } from "expo-av";
11 | import { PlayIcon } from "../../../icons";
12 | import { Dimensions } from "react-native";
13 | import { useNavigation } from "@react-navigation/native";
14 | import Animated, {
15 | FadeIn,
16 | interpolate,
17 | useAnimatedStyle,
18 | useSharedValue,
19 | withDelay,
20 | withTiming,
21 | } from "react-native-reanimated";
22 | import { Image } from "expo-image";
23 | import { useFocusEffect } from "@react-navigation/native";
24 | import useGetMode from "../../../../hooks/GetMode";
25 | import { current } from "@reduxjs/toolkit";
26 | import { HomeNavigationProp } from "../../../../types/navigation";
27 |
28 | function VideoPost({
29 | videoTitle,
30 | thumbNail,
31 | videoUri,
32 | imageUri,
33 | userTag,
34 | name,
35 |
36 | videoViews,
37 | }: {
38 | videoTitle?: string;
39 | imageUri: string;
40 | videoUri: string;
41 | thumbNail: string | null;
42 | name: string;
43 | userTag: string;
44 | videoViews?: string;
45 | }) {
46 |
47 |
48 | const navigation = useNavigation();
49 | return (
50 |
58 |
59 |
69 | {
71 | navigation.navigate("VideoFullScreen", {
72 | videoUri,
73 | videoTitle: videoTitle || "",
74 | videoViews: videoViews || "0",
75 | userTag,
76 | name,
77 | imageUri,
78 | thumbNail,
79 | });
80 | }}
81 | >
82 |
83 |
84 |
85 |
90 |
91 |
92 | );
93 | }
94 |
95 | export default VideoPost;
96 |
--------------------------------------------------------------------------------
/components/home/post/misc/EngagementText.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React from "react";
3 | import useGetMode from "../../../../hooks/GetMode";
4 |
5 | export default function EngagementsText({
6 | engage,
7 | engagementNumber,
8 | }: {
9 | engage: string;
10 | engagementNumber: number;
11 | }) {
12 | const dark = useGetMode();
13 |
14 | const color = dark ? "white" : "black";
15 | return (
16 |
17 |
18 | {engagementNumber}
19 |
20 |
23 | {engage}
24 | {engagementNumber > 1 && "s"}
25 |
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/components/home/post/misc/Robot.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react";
2 | import Lottie from "lottie-react-native";
3 | import { View } from "react-native";
4 | import { useAppSelector } from "../../../../redux/hooks/hooks";
5 | import { Image } from "expo-image";
6 |
7 | export default function Robot() {
8 | const animationRef = useRef(null);
9 |
10 | useEffect(() => {
11 | animationRef.current?.play();
12 |
13 | }, []);
14 | return (
15 |
23 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/components/messages/ChatList/ChatListView.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, FlatList, ListRenderItem } from "react-native";
2 | import React from "react";
3 | import TypingBox from "../../chat/TypingBox";
4 | import { IChatList } from "../../../types/api";
5 | import Animated, { SequencedTransition } from "react-native-reanimated";
6 |
7 | function ChatListView({
8 | isTyping,
9 | messageText,
10 | userChats,
11 | renderItem,
12 | }: {
13 | isTyping: boolean;
14 | messageText: string;
15 | userChats?: IChatList;
16 | renderItem: ListRenderItem;
17 | }) {
18 |
19 | return (
20 |
21 | {
26 | return (
27 |
34 | {isTyping && messageText.length < 1 && }
35 |
36 | );
37 | }}
38 | data={userChats?.messages}
39 | contentContainerStyle={{ gap: 15, padding: 20, paddingBottom: 100 }}
40 | renderItem={renderItem}
41 | />
42 |
43 | );
44 | }
45 | export default ChatListView;
46 |
--------------------------------------------------------------------------------
/components/messages/ChatList/Fab.tsx:
--------------------------------------------------------------------------------
1 | import { View, Pressable } from "react-native";
2 | import useGetMode from "../../../hooks/GetMode";
3 | import { useNavigation } from "@react-navigation/native";
4 | import { HomeNavigationProp } from "../../../types/navigation";
5 |
6 | export default function Fab({ item }: { item: JSX.Element }) {
7 | const dark = useGetMode();
8 | const isDark = dark;
9 | const navigation = useNavigation();
10 | const backgroundColor = !isDark ? "#FFFFFF" : "#000000";
11 | const color = isDark ? "#42424260" : "#BABABA64";
12 | return (
13 |
29 | {
32 | navigation.navigate("SearchUser");
33 | }}
34 | style={{
35 | height: "100%",
36 | width: "100%",
37 | alignItems: "center",
38 | justifyContent: "center",
39 | }}
40 | >
41 | <>
42 | {item}
43 | >
44 |
45 |
46 | );
47 | }
48 |
--------------------------------------------------------------------------------
/components/messages/Recent/AvatarName.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 |
4 | import useGetMode from "../../../hooks/GetMode";
5 | import Animated, { FadeInLeft, FadeOutLeft } from "react-native-reanimated";
6 | import { useNavigation } from "@react-navigation/native";
7 | import { HomeNavigationProp } from "../../../types/navigation";
8 | import { ActivityIndicator } from "react-native-paper";
9 | import { Image } from "expo-image";
10 |
11 | export default function AvatarName({
12 | userName,
13 | imageUri,
14 | id,
15 | receiverId,
16 | }: {
17 | userName: string;
18 | imageUri: string;
19 | id: string;
20 | receiverId: string;
21 | }) {
22 | const dark = useGetMode();
23 | const color = dark ? "#FFFFFF" : "#000000";
24 | const navigation = useNavigation();
25 | return (
26 | <>
27 |
28 |
30 | navigation.navigate("ChatScreen", {
31 | id: id,
32 | receiverId,
33 | name: userName,
34 | imageUri,
35 | })
36 | }
37 | >
38 |
47 |
51 |
55 | @{userName}
56 |
57 |
58 |
59 | >
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/components/messages/Recent/Me.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 |
4 | import useGetMode from "../../../hooks/GetMode";
5 | import Animated, { FadeInLeft, FadeOutLeft } from "react-native-reanimated";
6 | import { useNavigation } from "@react-navigation/native";
7 | import { HomeNavigationProp } from "../../../types/navigation";
8 | import { ActivityIndicator } from "react-native-paper";
9 | import { useAppSelector } from "../../../redux/hooks/hooks";
10 | import { Image } from "expo-image";
11 |
12 | export default function Me() {
13 | const dark = useGetMode();
14 | const color = dark ? "#FFFFFF" : "#000000";
15 | const user = useAppSelector((state) => state.user.data);
16 | return (
17 | <>
18 |
19 |
28 |
32 |
36 | Me
37 |
38 |
39 |
40 | >
41 | );
42 | }
43 |
--------------------------------------------------------------------------------
/components/notifications/NotifLottie.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React, { useEffect, useRef } from "react";
3 | import Lottie from "lottie-react-native";
4 |
5 | export default function NotifLottie() {
6 | const animationRef = useRef(null);
7 | useEffect(() => {
8 | animationRef.current?.play();
9 | }, []);
10 | return (
11 |
20 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/components/postContent/PickAudioButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import { AudioIcon, CameraIcon } from "../icons";
4 | import DocumentPicker from "react-native-document-picker";
5 | import useGetMode from "../../hooks/GetMode";
6 | export default function PickAudioButton({
7 | handleSetAudioPost,
8 | }: {
9 | handleSetAudioPost: (
10 | mimeType: string,
11 | uri: string,
12 | size: number,
13 | name: string
14 | ) => void;
15 | }) {
16 | const dark = useGetMode();
17 | const backgroundColor = dark ? "white" : "black";
18 | const backgroundColorView = !dark ? "white" : "black";
19 | const rippleColor = !dark ? "#ABABAB" : "#55555500";
20 | return (
21 |
34 | {
36 | DocumentPicker.pick({ type: "audio/mpeg" })
37 | .then((e) => {
38 |
39 | handleSetAudioPost(
40 | e[0]?.type as string,
41 | e[0].uri,
42 | e[0]?.size || 0,
43 | e[0]?.name || "any.mp3"
44 | );
45 | })
46 | .catch((e) => {});
47 | }}
48 | android_ripple={{ color: rippleColor, foreground: true }}
49 | style={{
50 | width: 100,
51 | height: 100,
52 | justifyContent: "center",
53 | alignItems: "center",
54 | }}
55 | >
56 |
57 |
58 |
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/components/postContent/PickImageButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import { CameraIcon } from "../icons";
4 | import ImagePicker from "react-native-image-crop-picker";
5 | import useGetMode from "../../hooks/GetMode";
6 | export default function PickImageButton({
7 | handleSetPhotoPost,
8 | }: {
9 | handleSetPhotoPost: (mimeType: string, uri: string, size: number) => void;
10 | }) {
11 | const dark = useGetMode();
12 | const backgroundColor = dark ? "white" : "black";
13 | const backgroundColorView = !dark ? "white" : "black";
14 | const rippleColor = !dark ? "#ABABAB" : "#55555500";
15 | return (
16 |
29 | {
31 | ImagePicker.openPicker({
32 | cropping: true,
33 | cropperStatusBarColor: "#000000",
34 | cropperToolbarColor: "#000000",
35 | showCropGuidelines: false,
36 | cropperTintColor: "red",
37 | cropperActiveWidgetColor: "red",
38 |
39 | cropperToolbarWidgetColor: "#FFFFFF",
40 | cropperCancelText: "#FFFFFF",
41 | cropperChooseColor: "#FFFFFF",
42 | compressImageQuality: 0.5,
43 | })
44 | .then((image) => {
45 | handleSetPhotoPost(image?.mime, image?.path, image?.size);
46 | })
47 | .catch((e) => {});
48 | }}
49 | android_ripple={{ color: rippleColor, foreground: true }}
50 | style={{
51 | width: 100,
52 | height: 100,
53 | justifyContent: "center",
54 | alignItems: "center",
55 | }}
56 | >
57 |
58 |
59 |
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/components/postContent/PostButton.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import useGetMode from "../../hooks/GetMode";
4 | import { useAppDispatch } from "../../redux/hooks/hooks";
5 | import { openToast } from "../../redux/slice/toast/toast";
6 | import { resetPost } from "../../redux/slice/post";
7 |
8 | export default function PostButton({
9 | isLoading,
10 | isDisabled,
11 | onPress,
12 | }: {
13 | isLoading: boolean;
14 | isDisabled?: boolean;
15 | onPress: () => void;
16 | }) {
17 | const dark = useGetMode();
18 | const dispatch = useAppDispatch();
19 |
20 | const backgroundColor = dark ? "white" : "black";
21 | const backgroundColorLoad = dark ? "#FFFFFF38" : "#00000041";
22 | const rippleColor = !dark ? "white" : "black";
23 | const color = !dark ? "white" : "black";
24 | return (
25 |
36 | {
39 | dispatch(resetPost());
40 | onPress();
41 | }}
42 | android_ripple={{ color: rippleColor, foreground: true }}
43 | style={{
44 | height: 45,
45 | width: 80,
46 |
47 | borderRadius: 9999,
48 | justifyContent: "center",
49 | alignItems: "center",
50 | }}
51 | >
52 | Post
53 |
54 |
55 | );
56 | }
57 |
--------------------------------------------------------------------------------
/components/postContent/TextArea.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, TextInput, Dimensions } from "react-native";
2 | import React, { useState } from "react";
3 |
4 | import InputText from "../../screen/Auth/components/InputText";
5 | import useGetMode from "../../hooks/GetMode";
6 | import { useAppSelector } from "../../redux/hooks/hooks";
7 | import { ProfileIcon } from "../icons";
8 | import { Image } from "expo-image";
9 |
10 | const heightFromScreen = Dimensions.get("window").height;
11 | export default function TextArea({
12 | handlePostText,
13 | }: {
14 | handlePostText: (text: string) => void;
15 | }) {
16 | const dark = useGetMode();
17 | const color = dark ? "white" : "black";
18 | const [height, setHeight] = useState(50);
19 | const userDetails = useAppSelector((state) => state.user.data);
20 | return (
21 |
22 |
23 | {userDetails?.imageUri ? (
24 |
28 | ) : (
29 |
30 | )}
31 |
38 | @{userDetails?.userName}
39 |
40 |
41 |
42 | {
48 | setHeight(event.nativeEvent.contentSize.height);
49 | }}
50 | style={{
51 | fontSize: 16,
52 | color,
53 |
54 | fontFamily: "mulishMedium",
55 | minHeight: height,
56 | alignItems: "flex-start",
57 | }}
58 | placeholderTextColor={"grey"}
59 | placeholder="What's happening?"
60 | />
61 |
62 |
63 | );
64 | }
65 |
--------------------------------------------------------------------------------
/components/postContent/VideoTextArea.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | TextInput,
5 | Dimensions,
6 | TextInputProps,
7 | } from "react-native";
8 | import React, { useState } from "react";
9 | import { Image } from "expo-image";
10 | import InputText from "../../screen/Auth/components/InputText";
11 | import useGetMode from "../../hooks/GetMode";
12 | import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
13 | const heightFromScreen = Dimensions.get("window").height;
14 | export default function VideoTextArea(props: TextInputProps) {
15 | const dark = useGetMode();
16 | const color = dark ? "white" : "black";
17 | const [height, setHeight] = useState(50);
18 | return (
19 |
24 | {
28 | setHeight(event.nativeEvent.contentSize.height);
29 | }}
30 | style={{
31 | fontSize: 16,
32 | color,
33 |
34 | fontFamily: "mulishMedium",
35 | maxHeight: height,
36 | alignItems: "flex-start",
37 | }}
38 | placeholder="Video Title"
39 | {...props}
40 | />
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/components/profile/EditProfile.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import useGetMode from "../../hooks/GetMode";
4 | import { useNavigation } from "@react-navigation/native";
5 | import { HomeNavigationProp } from "../../types/navigation";
6 |
7 | export default function ButtonOutlined() {
8 | const dark = useGetMode();
9 | const navigate = useNavigation();
10 | const color = dark ? "white" : "black";
11 | return (
12 |
13 | {
15 | navigate.navigate("EditProfile");
16 | }}
17 | style={{
18 | paddingHorizontal: 15,
19 | paddingVertical: 10,
20 | borderColor: "#B4B4B4D1",
21 | borderRadius: 999,
22 | borderWidth: 1,
23 | }}
24 | >
25 | Edit Profile
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/components/profile/UploadPic.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React from "react";
3 | import { CameraIcon } from "../icons";
4 | import ImagePicker from "react-native-image-crop-picker";
5 | import useGetMode from "../../hooks/GetMode";
6 | export default function PickImageButton({
7 | handleSetPhotoPost,
8 | }: {
9 | handleSetPhotoPost: (mimeType: string, uri: string, size: number) => void;
10 | }) {
11 | const dark = useGetMode();
12 | const borderColor = dark ? "white" : "black";
13 |
14 | const rippleColor = !dark ? "#ABABAB" : "#55555500";
15 | return (
16 |
32 | {
34 | ImagePicker.openPicker({
35 | cropping: true,
36 | cropperStatusBarColor: "#000000",
37 | cropperToolbarColor: "#000000",
38 | showCropGuidelines: false,
39 | cropperTintColor: "red",
40 | width: 500,
41 | height: 500,
42 | cropperActiveWidgetColor: "red",
43 |
44 | cropperToolbarWidgetColor: "#FFFFFF",
45 | cropperCancelText: "#FFFFFF",
46 | cropperChooseColor: "#FFFFFF",
47 | compressImageQuality: 0.3,
48 | })
49 | .then((image) => {
50 | handleSetPhotoPost(image?.mime, image?.path, image?.size);
51 | })
52 | .catch((e) => {});
53 | }}
54 | android_ripple={{ color: rippleColor, foreground: true }}
55 | style={{
56 | width: 100,
57 | height: 50,
58 | justifyContent: "center",
59 | alignItems: "center",
60 | }}
61 | >
62 |
70 |
71 | Upload
72 |
73 |
74 |
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/components/profilePeople/FollowerUser.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Pressable } from "react-native";
2 | import React, { useState } from "react";
3 | import useGetMode from "../../hooks/GetMode";
4 | import { getBackgroundColorAsync } from "expo-system-ui";
5 | import Animated, { BounceIn, BounceOut } from "react-native-reanimated";
6 | import { useLazyFollowUserQuery } from "../../redux/api/services";
7 | import { useAppSelector } from "../../redux/hooks/hooks";
8 |
9 | export default function FollowUser({
10 | id,
11 | followed,
12 | handleFollow,
13 | }: {
14 | id: string;
15 | followed: boolean;
16 | handleFollow: () => void;
17 | }) {
18 | const dark = useGetMode();
19 | const color = !dark ? "white" : "black";
20 | const color2 = dark ? "white" : "black";
21 |
22 |
23 |
24 | return (
25 |
31 |
42 |
48 | {followed ? "Following" : "Follow"}
49 |
50 |
51 |
52 | );
53 | }
54 |
--------------------------------------------------------------------------------
/components/searchUser/SearchBox.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | TextInput,
5 | StyleProp,
6 | ViewStyle,
7 | Dimensions,
8 | } from "react-native";
9 | import useGetMode from "../../hooks/GetMode";
10 | import Animated, { FadeInRight } from "react-native-reanimated";
11 | import { useCallback, useEffect, useMemo, useState } from "react";
12 | import { useDebounce } from "../../hooks/Debounce";
13 | import { BlurView } from "expo-blur";
14 |
15 | const { width } = Dimensions.get("window");
16 | export default function SearchBox({
17 | setSearchParam,
18 | }: {
19 | setSearchParam: (text: string) => void;
20 | }) {
21 | const dark = useGetMode();
22 |
23 | const color = dark ? "white" : "black";
24 | const placeholderColor = !dark ? "grey" : "grey";
25 | const borderColor = dark ? "#FFFFFF" : "#DAD9D9";
26 | const tint = dark ? "dark" : "light";
27 | const backgroundColor = dark ? "#383838" : "#EAEBEB";
28 | return (
29 |
44 | setSearchParam(text)}
48 | placeholderTextColor={placeholderColor}
49 | style={{
50 | width: "100%",
51 | fontSize: 16,
52 | color,
53 | fontFamily: "jakara",
54 | includeFontPadding: false,
55 | }}
56 | />
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/credentials.json:
--------------------------------------------------------------------------------
1 | {
2 | "android": {
3 | "keystore": {
4 | "keystorePath": "android/keystores/release.keystore",
5 | "keystorePassword": "IOIZIK@100",
6 | "keyAlias": "Hizik",
7 | "keyPassword": "IOIZIK@100"
8 | }
9 | }
10 | }
11 |
12 |
13 |
--------------------------------------------------------------------------------
/data/murphy.ts:
--------------------------------------------------------------------------------
1 | export const murphyLaws = [
2 | "Anything that can go wrong will go wrong.",
3 | "If there is a possibility of several things going wrong, the one that will cause the most damage will be the one to go wrong.",
4 | "Left to themselves, things tend to go from bad to worse.",
5 | ];
6 |
--------------------------------------------------------------------------------
/eas.json:
--------------------------------------------------------------------------------
1 | {
2 | "cli": {
3 | "version": ">= 3.13.3"
4 | },
5 | "build": {
6 | "development": {
7 | "developmentClient": true,
8 | "distribution": "internal"
9 | },
10 | "preview": {
11 | "distribution": "internal"
12 | },
13 | "production": {
14 | "android": {
15 | "buildType": "apk"
16 | }
17 | }
18 | },
19 | "submit": {
20 | "production": {}
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "365442112752",
4 | "project_id": "quiapp-698b0",
5 | "storage_bucket": "quiapp-698b0.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:365442112752:android:f7cad07868aaef170af635",
11 | "android_client_info": {
12 | "package_name": "me.isaacojo.qui"
13 | }
14 | },
15 | "oauth_client": [],
16 | "api_key": [
17 | {
18 | "current_key": "AIzaSyBSquawmwCQmx9-dm4u0wD-VArumgSb0H0"
19 | }
20 | ],
21 | "services": {
22 | "appinvite_service": {
23 | "other_platform_oauth_client": []
24 | }
25 | }
26 | }
27 | ],
28 | "configuration_version": "1"
29 | }
--------------------------------------------------------------------------------
/hooks/Debounce.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | export const useDebounce = (value: string, delay: number) => {
4 | const [deBouncedValue, setDebouncedValue] = useState(value);
5 |
6 | useEffect(() => {
7 | const timeOutId = setTimeout(() => {
8 | setDebouncedValue(value);
9 | }, delay);
10 |
11 | return () => clearTimeout(timeOutId);
12 | }, [value, delay]);
13 |
14 | return deBouncedValue;
15 | };
16 |
--------------------------------------------------------------------------------
/hooks/GetMode.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, useColorScheme } from "react-native";
2 | import React, { useEffect, useLayoutEffect, useMemo, useState } from "react";
3 | import { useAppSelector } from "../redux/hooks/hooks";
4 |
5 | export default function useGetMode() {
6 | const scheme = useColorScheme();
7 | const [dark, setDark] = useState(false);
8 | const { mode } = useAppSelector((state) => state.prefs);
9 |
10 | useEffect(() => {
11 | if (mode === "system") {
12 | setDark(scheme === "dark");
13 | } else {
14 | setDark(mode === "dark");
15 | }
16 | }, [mode, scheme]);
17 |
18 | return dark;
19 | }
20 |
--------------------------------------------------------------------------------
/hooks/Socket.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, useRef, useMemo } from "react";
2 | import io, { Socket } from "socket.io-client";
3 | import { useAppSelector } from "../redux/hooks/hooks";
4 |
5 | const useSocket = (): Socket | undefined => {
6 | const [socket, setSocket] = useState(null);
7 | const token = useAppSelector((state) => state.user.token);
8 | const socketRef = useRef(null);
9 | useMemo(() => {
10 | if (token) {
11 | socketRef.current = io(process.env.EXPO_PUBLIC_API_URL as string, {
12 | autoConnect: true,
13 | auth: {
14 | token,
15 | },
16 | });
17 | }
18 | }, [token]);
19 |
20 | return socketRef?.current;
21 | };
22 |
23 | export default useSocket;
24 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 | .xcode.env.local
25 |
26 | # Bundle artifacts
27 | *.jsbundle
28 |
29 | # CocoaPods
30 | /Pods/
31 |
--------------------------------------------------------------------------------
/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/ios/Podfile.properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo.jsEngine": "hermes",
3 | "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true",
4 | "newArchEnabled": "false",
5 | "apple.extraPods": "[]",
6 | "apple.ccacheEnabled": "false",
7 | "apple.privacyManifestAggregationEnabled": "true"
8 | }
9 |
--------------------------------------------------------------------------------
/ios/Qui.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Qui/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @interface AppDelegate : EXAppDelegateWrapper
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/ios/Qui/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "filename": "App-Icon-1024x1024@1x.png",
5 | "idiom": "universal",
6 | "platform": "ios",
7 | "size": "1024x1024"
8 | }
9 | ],
10 | "info": {
11 | "version": 1,
12 | "author": "expo"
13 | }
14 | }
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "expo"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/SplashScreen.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "image.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "scale": "2x"
11 | },
12 | {
13 | "idiom": "universal",
14 | "scale": "3x"
15 | }
16 | ],
17 | "info": {
18 | "version": 1,
19 | "author": "expo"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/SplashScreen.imageset/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/ios/Qui/Images.xcassets/SplashScreen.imageset/image.png
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/SplashScreenBackground.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "image.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "scale": "2x"
11 | },
12 | {
13 | "idiom": "universal",
14 | "scale": "3x"
15 | }
16 | ],
17 | "info": {
18 | "version": 1,
19 | "author": "expo"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/Qui/Images.xcassets/SplashScreenBackground.imageset/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/ios/Qui/Images.xcassets/SplashScreenBackground.imageset/image.png
--------------------------------------------------------------------------------
/ios/Qui/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 | 0A2A.1
14 | 3B52.1
15 |
16 |
17 |
18 | NSPrivacyAccessedAPIType
19 | NSPrivacyAccessedAPICategoryUserDefaults
20 | NSPrivacyAccessedAPITypeReasons
21 |
22 | CA92.1
23 |
24 |
25 |
26 | NSPrivacyAccessedAPIType
27 | NSPrivacyAccessedAPICategorySystemBootTime
28 | NSPrivacyAccessedAPITypeReasons
29 |
30 | 35F9.1
31 |
32 |
33 |
34 | NSPrivacyAccessedAPIType
35 | NSPrivacyAccessedAPICategoryDiskSpace
36 | NSPrivacyAccessedAPITypeReasons
37 |
38 | E174.1
39 | 85F4.1
40 |
41 |
42 |
43 | NSPrivacyCollectedDataTypes
44 |
45 | NSPrivacyTracking
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/ios/Qui/Qui-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
--------------------------------------------------------------------------------
/ios/Qui/Qui.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 |
8 |
--------------------------------------------------------------------------------
/ios/Qui/Supporting/Expo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | EXUpdatesCheckOnLaunch
6 | ALWAYS
7 | EXUpdatesEnabled
8 |
9 | EXUpdatesLaunchWaitMs
10 | 0
11 |
12 |
--------------------------------------------------------------------------------
/ios/Qui/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char * argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/ios/Qui/noop-file.swift:
--------------------------------------------------------------------------------
1 | //
2 | // @generated
3 | // A blank Swift file must be created for native modules with Swift files to work correctly.
4 | //
5 |
--------------------------------------------------------------------------------
/models.json:
--------------------------------------------------------------------------------
1 | [{"analyzerName":"intellisense-members","languageName":"javascript","identity":{"modelId":"1A3F919CD5B7725108B03C349630A1C82B03","outputId":"4A84987F2428442A9EC84563BB2BC063","modifiedTimeUtc":"2020-09-28T23:11:53.754Z"},"filePath":"1A3F919CD5B7725108B03C349630A1C82B03_4A84987F2428442A9EC84563BB2BC063","lastAccessTimeUtc":"2023-09-25T02:20:44.895Z"}]
--------------------------------------------------------------------------------
/redux/api/auth.ts:
--------------------------------------------------------------------------------
1 | import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
2 | import { UserState } from "../slice/user";
3 | import { IUSerData } from "../../types/api";
4 | import storage from "../storage";
5 |
6 | interface loginResult {
7 | msg: string;
8 | token: string;
9 | data: IUSerData;
10 | }
11 |
12 | export const authApi = createApi({
13 | reducerPath: "authApi",
14 | baseQuery: fetchBaseQuery({
15 | baseUrl: `${process.env.EXPO_PUBLIC_API_URL}/api/auth`,
16 | }),
17 | tagTypes: ["user"],
18 | endpoints: (builder) => ({
19 | login: builder.mutation<
20 | loginResult,
21 | {
22 | userName: string;
23 | password: string;
24 | }
25 | >({
26 | query: (payload) => ({
27 | url: "/login",
28 | method: "POST",
29 | body: payload,
30 | headers: {
31 | "Content-type": "application/json; charset=UTF-8",
32 | },
33 | }),
34 | }),
35 | register: builder.mutation<
36 | loginResult,
37 | {
38 | userName: string;
39 | password: string;
40 | email: string;
41 | name: string;
42 | }
43 | >({
44 | query: (payload) => ({
45 | url: "/signup",
46 | method: "POST",
47 | body: payload,
48 | headers: {
49 | "Content-type": "application/json; charset=UTF-8",
50 | },
51 | }),
52 |
53 | }),
54 | }),
55 | });
56 |
57 | export const { useLoginMutation ,useRegisterMutation} = authApi;
58 |
--------------------------------------------------------------------------------
/redux/api/chat.ts:
--------------------------------------------------------------------------------
1 | import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
2 | import { UserState } from "../slice/user";
3 | import {
4 | IChatList,
5 | IComment,
6 | IPerson,
7 | IPost,
8 | IPostContent,
9 | IUSerData,
10 | } from "../../types/api";
11 | import storage from "../storage";
12 | import { RootState } from "../store";
13 |
14 | interface loginResult {
15 | msg: string;
16 | token: string;
17 | data: IUSerData;
18 | }
19 |
20 | export const chatApi = createApi({
21 | reducerPath: "chatApi",
22 | baseQuery: fetchBaseQuery({
23 | baseUrl: `${process.env.EXPO_PUBLIC_API_URL}/api/chat`,
24 | prepareHeaders: (headers, { getState }) => {
25 | const token = (getState() as RootState).user.token;
26 | // If we have a token, set it in the header
27 | if (token) {
28 | headers.set("Authorization", `Bearer ${token}`);
29 | }
30 | return headers;
31 | },
32 | }),
33 | tagTypes: ["chats"],
34 | endpoints: (builder) => ({
35 | getAllChats: builder.query<{ chatList: IChatList[] }, null>({
36 | query: () => `/get-all-chats`,
37 |
38 | extraOptions: { maxRetries: 2 },
39 | }),
40 | getAllMessages: builder.query<{ chatList: IChatList }, { id: string }>({
41 | query: ({id}) => `/get-all-messages?id=${id}`,
42 | extraOptions: { maxRetries: 2 },
43 | }),
44 | }),
45 | });
46 |
47 | export const { useGetAllChatsQuery,useLazyGetAllMessagesQuery,useLazyGetAllChatsQuery } = chatApi;
48 |
--------------------------------------------------------------------------------
/redux/hooks/hooks.ts:
--------------------------------------------------------------------------------
1 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
2 | import type { RootState, AppDispatch } from "../store";
3 |
4 | export const useAppDispatch = () => useDispatch();
5 | export const useAppSelector: TypedUseSelectorHook = useSelector;
6 |
--------------------------------------------------------------------------------
/redux/slice/bottomSheet/index.tsx:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | export type BottomSheet = {
4 | isOpen: boolean;
5 | type: string | null;
6 | };
7 | const bottomSheet = createSlice({
8 | name: "bottomSheet",
9 | initialState: {
10 | isOpen: false,
11 | type: null,
12 | } as BottomSheet,
13 | reducers: {
14 | openSheet: (state, action: PayloadAction<{ type: string }>) => {
15 | state.isOpen = true;
16 | state.type = action.payload.type;
17 | },
18 | closeSheet: (state) => {
19 | state.isOpen = false;
20 | state.type = null;
21 | },
22 | },
23 | });
24 |
25 | export default bottomSheet.reducer;
26 | export const { openSheet, closeSheet } = bottomSheet.actions;
27 |
--------------------------------------------------------------------------------
/redux/slice/chat/online.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createReducer, createSlice } from "@reduxjs/toolkit";
2 | import { useState } from "react";
3 |
4 | const onLineUserIDs = createSlice({
5 | name: "onlineUserIds",
6 | initialState: {
7 | ids: [],
8 | } as { ids: Array },
9 | reducers: {
10 | updateOnlineIds: (state, action: PayloadAction<{ ids: Array }>) => {
11 | console.log("🚀 ~ file: online.ts:11 ~ state:", state)
12 | state.ids = action.payload.ids;
13 | },
14 | },
15 | });
16 |
17 | export default onLineUserIDs.reducer;
18 | export const { updateOnlineIds } = onLineUserIDs.actions;
19 |
--------------------------------------------------------------------------------
/redux/slice/currentPage/index.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | const currentPage = createSlice({
4 | name: "currentPage",
5 | initialState: {
6 | page: null,
7 | } as {
8 | page: string | null;
9 | },
10 | reducers: {
11 | setCurrentPage: (state, action: PayloadAction<{ page: string }>) => {
12 | state.page = action.payload.page;
13 | },
14 | },
15 | });
16 |
17 | export default currentPage.reducer;
18 | export const { setCurrentPage } = currentPage.actions;
19 |
--------------------------------------------------------------------------------
/redux/slice/modal/loading.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | export type LoadingModal = {
4 | isOpen: boolean;
5 | };
6 | const loadingModal = createSlice({
7 | name: "bottomSheet",
8 | initialState: {
9 | isOpen: false,
10 | } as LoadingModal,
11 | reducers: {
12 | openLoadingModal: (state) => {
13 | state.isOpen = true;
14 | },
15 | closeLoadingModal: (state) => {
16 | state.isOpen = false;
17 | },
18 | },
19 | });
20 |
21 | export default loadingModal.reducer;
22 | export const { openLoadingModal, closeLoadingModal } = loadingModal.actions;
23 |
--------------------------------------------------------------------------------
/redux/slice/people/search.ts:
--------------------------------------------------------------------------------
1 | import { IPerson, IPost } from "./../../../types/api";
2 | import { createSlice } from "@reduxjs/toolkit";
3 | import { postLists } from "../../../data/test";
4 | import { servicesApi } from "../../api/services";
5 |
6 | export type personState = {
7 | data: IPerson[];
8 | error: any;
9 | loading: boolean;
10 | };
11 |
12 | const searchPeople = createSlice({
13 | name: "searchPeople",
14 | initialState: {
15 | data: [],
16 | error: null,
17 | loading: false,
18 | } as personState,
19 | reducers: {
20 | addPost: () => {},
21 | },
22 | extraReducers: (builder) => {
23 | builder.addMatcher(
24 | servicesApi.endpoints.getRandomPeople.matchFulfilled,
25 | (state, { payload }) => {
26 |
27 | state.data = payload.people;
28 | state.error = null;
29 | state.loading = false;
30 | }
31 | );
32 | builder.addMatcher(
33 | servicesApi.endpoints.getRandomPeople.matchPending,
34 | (state, { payload }) => {
35 | state.data = [];
36 | state.error = null;
37 | state.loading = true;
38 | }
39 | );
40 | builder.addMatcher(
41 | servicesApi.endpoints.getRandomPeople.matchRejected,
42 | (state, { payload, error }) => {
43 | state.data = [];
44 | state.error = error;
45 | state.loading = false;
46 | }
47 | );
48 |
49 | builder.addMatcher(
50 | servicesApi.endpoints.searchPeople.matchFulfilled,
51 | (state, { payload }) => {
52 |
53 | state.data = payload.people;
54 | state.error = null;
55 | state.loading = false;
56 | }
57 | );
58 | builder.addMatcher(
59 | servicesApi.endpoints.searchPeople.matchPending,
60 | (state, { payload }) => {
61 | state.data = [];
62 | state.error = null;
63 | state.loading = true;
64 | }
65 | );
66 | builder.addMatcher(
67 | servicesApi.endpoints.searchPeople.matchRejected,
68 | (state, { payload, error }) => {
69 | state.data = [];
70 | state.error = error;
71 | state.loading = false;
72 | }
73 | );
74 |
75 | },
76 | });
77 |
78 | export default searchPeople.reducer;
79 |
--------------------------------------------------------------------------------
/redux/slice/post/audio.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | const audio = createSlice({
4 | name: "audioPlaying",
5 | initialState: {
6 | playingId: []
7 | } as {
8 | playingId: number[]
9 | },
10 | reducers: {
11 | setPlayingIds: (state, action: PayloadAction) => {
12 | state.playingId = action.payload;
13 | },
14 | },
15 | });
16 |
17 |
18 | export default audio.reducer;
19 | export const { setPlayingIds } = audio.actions;
20 |
--------------------------------------------------------------------------------
/redux/slice/post/followed.ts:
--------------------------------------------------------------------------------
1 | import { IPost } from "./../../../types/api";
2 | import { createSlice } from "@reduxjs/toolkit";
3 | import { postLists } from "../../../data/test";
4 | import { servicesApi } from "../../api/services";
5 |
6 | export type postState = {
7 | data: IPost[];
8 | error: any;
9 | loading: boolean;
10 | };
11 |
12 | const fPost = createSlice({
13 | name: "fPost",
14 | initialState: {
15 | data: [],
16 | error: null,
17 | loading: false,
18 | } as postState,
19 | reducers: {
20 | addPost: () => {},
21 | resetPost: (state) => {
22 | state.data = [];
23 | state.error = null;
24 | state.loading = false;
25 | },
26 | },
27 |
28 | extraReducers: (builder) => {
29 | builder.addMatcher(
30 | servicesApi.endpoints.getFollowedPosts.matchFulfilled,
31 | (state, { payload }) => {
32 | const data = [...state.data, ...payload.posts];
33 | state.data = data;
34 | state.error = null;
35 | state.loading = false;
36 | }
37 | );
38 | builder.addMatcher(
39 | servicesApi.endpoints.getFollowedPosts.matchPending,
40 | (state, { payload }) => {
41 | state.error = null;
42 | state.loading = true;
43 | }
44 | );
45 | builder.addMatcher(
46 | servicesApi.endpoints.getFollowedPosts.matchRejected,
47 | (state, { payload, error }) => {
48 | state.error = error;
49 | state.loading = false;
50 | }
51 | );
52 | },
53 | });
54 |
55 | export default fPost.reducer;
56 | export const { resetPost } = fPost.actions;
57 |
--------------------------------------------------------------------------------
/redux/slice/post/index.ts:
--------------------------------------------------------------------------------
1 | import { IPost } from "./../../../types/api";
2 | import { createSlice } from "@reduxjs/toolkit";
3 | import { postLists } from "../../../data/test";
4 | import { servicesApi } from "../../api/services";
5 |
6 | export type postState = {
7 | data: IPost[];
8 | error: any;
9 | loading: boolean;
10 | };
11 |
12 | const post = createSlice({
13 | name: "post",
14 | initialState: {
15 | data: [],
16 | error: null,
17 | loading: false,
18 | } as postState,
19 | reducers: {
20 | addPost: () => {},
21 | resetPost: (state) => {
22 | state.data = [];
23 | state.error = null;
24 | state.loading = false;
25 | },
26 | },
27 |
28 | extraReducers: (builder) => {
29 | builder.addMatcher(
30 | servicesApi.endpoints.getAllPosts.matchFulfilled,
31 | (state, { payload }) => {
32 | const data = [...state.data, ...payload.posts];
33 | state.data = data;
34 | state.error = null;
35 | state.loading = false;
36 | }
37 | );
38 | builder.addMatcher(
39 | servicesApi.endpoints.getAllPosts.matchPending,
40 | (state, { payload }) => {
41 | state.error = null;
42 | state.loading = true;
43 | }
44 | );
45 | builder.addMatcher(
46 | servicesApi.endpoints.getAllPosts.matchRejected,
47 | (state, { payload, error }) => {
48 | state.error = error;
49 | state.loading = false;
50 | }
51 | );
52 | },
53 | });
54 |
55 | export default post.reducer;
56 | export const {resetPost} = post.actions
57 |
--------------------------------------------------------------------------------
/redux/slice/post/search.ts:
--------------------------------------------------------------------------------
1 | import { IPost } from "./../../../types/api";
2 | import { createSlice } from "@reduxjs/toolkit";
3 | import { postLists } from "../../../data/test";
4 | import { servicesApi } from "../../api/services";
5 |
6 | export type postState = {
7 | data: IPost[];
8 | error: any;
9 | loading: boolean;
10 | };
11 |
12 | const searchPost = createSlice({
13 | name: "searchPost",
14 | initialState: {
15 | data: [],
16 | error: null,
17 | loading: false,
18 | } as postState,
19 | reducers: {
20 | addPost: () => {},
21 | },
22 | extraReducers: (builder) => {
23 | builder.addMatcher(
24 | servicesApi.endpoints.getRandomPosts.matchFulfilled,
25 | (state, { payload }) => {
26 | state.data = payload.posts;
27 | state.error = null;
28 | state.loading = false;
29 | }
30 | );
31 | builder.addMatcher(
32 | servicesApi.endpoints.getRandomPosts.matchPending,
33 | (state, { payload }) => {
34 | state.data = [];
35 | state.error = null;
36 | state.loading = true;
37 | }
38 | );
39 | builder.addMatcher(
40 | servicesApi.endpoints.getRandomPosts.matchRejected,
41 | (state, { payload, error }) => {
42 | state.data = [];
43 | state.error = error;
44 | state.loading = false;
45 | }
46 | );
47 |
48 | builder.addMatcher(
49 | servicesApi.endpoints.searchPosts.matchFulfilled,
50 | (state, { payload }) => {
51 | state.data = payload.posts;
52 | state.error = null;
53 | state.loading = false;
54 | }
55 | );
56 | builder.addMatcher(
57 | servicesApi.endpoints.searchPosts.matchPending,
58 | (state, { payload }) => {
59 | state.data = [];
60 | state.error = null;
61 | state.loading = true;
62 | }
63 | );
64 | builder.addMatcher(
65 | servicesApi.endpoints.searchPosts.matchRejected,
66 | (state, { payload, error }) => {
67 | state.data = [];
68 | state.error = error;
69 | state.loading = false;
70 | }
71 | );
72 | },
73 | });
74 |
75 | export default searchPost.reducer;
76 |
--------------------------------------------------------------------------------
/redux/slice/prefs/index.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | export type Prefs = {
4 | mode: "system" | "light" | "dark";
5 | isHighEnd: boolean;
6 | };
7 | const prefs = createSlice({
8 | name: "prefs",
9 | initialState: {
10 | mode: "system",
11 | } as Prefs,
12 | reducers: {
13 | setMode: (
14 | state,
15 | action: PayloadAction<{ mode: "system" | "light" | "dark" }>
16 | ) => {
17 | state.mode = action.payload.mode;
18 | },
19 | setHighEnd: (state, action: PayloadAction<{ isHighEnd: boolean }>) => {
20 | state.isHighEnd = action.payload.isHighEnd;
21 | },
22 | },
23 | });
24 |
25 | export default prefs.reducer;
26 | export const { setMode, setHighEnd } = prefs.actions;
27 |
--------------------------------------------------------------------------------
/redux/slice/routes/index.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | export type Route = {
4 | route: "onBoard" | "Auth" | "App";
5 | };
6 |
7 | const routeSlice = createSlice({
8 | name: "route",
9 | initialState: {
10 | route: "onBoard",
11 | } as Route,
12 | reducers: {
13 | setRoute: (state, action: PayloadAction) => {
14 | state.route = action.payload.route;
15 | },
16 | },
17 | });
18 |
19 | export default routeSlice.reducer;
20 | export const { setRoute } = routeSlice.actions;
21 |
--------------------------------------------------------------------------------
/redux/slice/toast/toast.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | import * as Haptics from "expo-haptics";
4 | import { Platform } from "react-native";
5 | const ONE_SECOND_IN_MS = 1000;
6 |
7 | const PATTERN = [
8 | 1 * ONE_SECOND_IN_MS,
9 | 2 * ONE_SECOND_IN_MS,
10 | 3 * ONE_SECOND_IN_MS,
11 | ];
12 | const PATTERN_DESC =
13 | Platform.OS === "android"
14 | ? "wait 1s, vibrate 2s, wait 3s"
15 | : "wait 1s, vibrate, wait 2s, vibrate, wait 3s";
16 | export type ToastState = {
17 | text: string | null;
18 | imageUri?: string;
19 | open: boolean;
20 | type: "Failed" | "Success" | "Info" | "Message" | null;
21 | };
22 |
23 | const toastSlice = createSlice({
24 | name: "Toast",
25 | initialState: {
26 | text: null,
27 | open: false,
28 | type: null,
29 | } as ToastState,
30 | reducers: {
31 | openToast: (
32 | state,
33 | action: PayloadAction<{
34 | text: string;
35 | imageUri?: string;
36 | type: "Failed" | "Success" | "Info" | "Message";
37 | }>
38 | ) => {
39 | state.open = true;
40 | state.imageUri = action.payload.imageUri;
41 | state.text = action.payload.text;
42 | state.type = action.payload.type;
43 | },
44 | closeToast: (state) => {
45 | state.open = false;
46 | state.text = null;
47 | state.type = null;
48 | },
49 | },
50 | });
51 |
52 | export default toastSlice.reducer;
53 | export const { openToast, closeToast } = toastSlice.actions;
54 |
--------------------------------------------------------------------------------
/redux/slice/user/followers.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 |
3 | import { userApi } from "../../api/user";
4 |
5 | export interface FollowerState {
6 | following: number | null;
7 | followers: number | null;
8 | }
9 | const followsCount = createSlice({
10 | name: "followsCount",
11 | initialState: {
12 | followers: 0,
13 | following: 0,
14 | } as FollowerState,
15 | reducers: {
16 | resetFollowers: (state) => {
17 | state.following = 0;
18 | state.followers = 0;
19 | },
20 | updateFollowing: (state, action: PayloadAction<{ following: number }>) => {
21 | state.following = action.payload.following;
22 | },
23 | updateFollowers: (state, action: PayloadAction<{ followers: number }>) => {
24 | state.followers = action.payload.followers;
25 | },
26 | },
27 | extraReducers: (builder) => {
28 | builder.addMatcher(
29 | userApi.endpoints.getFollowDetails.matchFulfilled,
30 | (state, { payload }) => {
31 | state.followers = Number(payload.followers);
32 | state.following = Number(payload.following);
33 | }
34 | );
35 | },
36 | });
37 |
38 | export default followsCount.reducer;
39 | export const { resetFollowers, updateFollowers, updateFollowing } =
40 | followsCount.actions;
41 |
--------------------------------------------------------------------------------
/redux/slice/user/index.ts:
--------------------------------------------------------------------------------
1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit";
2 | import { authApi } from "../../api/auth";
3 | import { IUSerData } from "../../../types/api";
4 | import { userApi } from "../../api/user";
5 | import socket from "../../../util/socket";
6 |
7 | export interface UserState {
8 | data: IUSerData | null;
9 | error: any;
10 | token: string | null;
11 | loading: boolean;
12 | }
13 | const user = createSlice({
14 | name: "user",
15 | initialState: {
16 | data: null,
17 | error: null,
18 | loading: false,
19 | token: null,
20 | } as UserState,
21 | reducers: {
22 | signOut: (state) => {
23 | state.error = null;
24 | state.loading = false;
25 | state.token = null;
26 | socket.disconnect();
27 | },
28 | clearUserData: (state) => {
29 | state.data = null;
30 | state.error = null;
31 | state.loading = false;
32 | state.token = null;
33 | },
34 | },
35 | extraReducers: (builder) => {
36 | builder.addMatcher(
37 | userApi.endpoints.getUser.matchFulfilled,
38 | (state, { payload }) => {
39 | state.data = payload.data;
40 | state.error = null;
41 | state.loading = false;
42 | }
43 | );
44 | builder.addMatcher(userApi.endpoints.getUser.matchPending, (state) => {
45 | state.error = null;
46 | state.loading = true;
47 | });
48 | builder.addMatcher(
49 | userApi.endpoints.getUser.matchRejected,
50 | (state, { error }) => {
51 | state.data = null;
52 | state.error = error;
53 | state.loading = true;
54 | }
55 | );
56 | builder.addMatcher(
57 | authApi.endpoints.login.matchFulfilled,
58 | (state, { payload }) => {
59 | state.data = payload.data;
60 | state.error = null;
61 | state.loading = false;
62 | state.token = payload.token;
63 | }
64 | );
65 | builder.addMatcher(authApi.endpoints.login.matchPending, (state) => {
66 | state.data = null;
67 | state.error = null;
68 | state.loading = true;
69 | state.token = null;
70 | });
71 | builder.addMatcher(
72 | authApi.endpoints.login.matchRejected,
73 | (state, { error }) => {
74 | state.data = null;
75 | state.error = error;
76 | state.loading = true;
77 | state.token = null;
78 | }
79 | );
80 | },
81 | });
82 |
83 | export default user.reducer;
84 |
85 | export const { signOut, clearUserData } = user.actions;
86 |
--------------------------------------------------------------------------------
/redux/storage.ts:
--------------------------------------------------------------------------------
1 | import { Storage } from "redux-persist";
2 | import { MMKV } from "react-native-mmkv";
3 |
4 | const storage = new MMKV();
5 |
6 | export const reduxStorage: Storage = {
7 | setItem: (key, value) => {
8 | storage.set(key, value);
9 | return Promise.resolve(true);
10 | },
11 | getItem: (key) => {
12 | const value = storage.getString(key);
13 | return Promise.resolve(value);
14 | },
15 | removeItem: (key) => {
16 | storage.delete(key);
17 | return Promise.resolve();
18 | },
19 | };
20 |
21 | export default storage
--------------------------------------------------------------------------------
/routes/Auth.tsx:
--------------------------------------------------------------------------------
1 | import { createNativeStackNavigator } from "@react-navigation/native-stack";
2 |
3 | import Login from "../screen/Auth/Login";
4 | import useGetMode from "../hooks/GetMode";
5 | import Register from "../screen/Auth/Register";
6 | import { AuthRootStackParamList } from "../types/navigation";
7 |
8 | const Stack = createNativeStackNavigator();
9 |
10 | export default function Auth() {
11 | const dark = useGetMode();
12 | const isDark = dark;
13 |
14 | const backgroundColor= isDark ? "black" : "white"
15 | return (
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/routes/OnBoard.tsx:
--------------------------------------------------------------------------------
1 | import { createNativeStackNavigator } from "@react-navigation/native-stack";
2 |
3 | import Onboard from "../screen/Onboard";
4 | import useGetMode from "../hooks/GetMode";
5 |
6 | const Stack = createNativeStackNavigator();
7 | export default function OnboardNavigation() {
8 | const dark = useGetMode();
9 | const isDark = dark;
10 | const backgroundColor = isDark ? "black" : "white";
11 | return (
12 |
15 |
16 |
17 | );
18 | }
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/screen/App/ChangeData.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React from "react";
3 | import { ChangeDataProp } from "../../types/navigation";
4 | import AnimatedScreen from "../../components/global/AnimatedScreen";
5 | import ChangeName from "./ChangeData/ChangeName";
6 | import ChangePassword from "./ChangeData/ChangePassword";
7 | import ChangeUserName from "./ChangeData/ChangeUserName";
8 |
9 | export default function ChangeData({ navigation, route }: ChangeDataProp) {
10 | const { change } = route.params;
11 | function getRoute() {
12 | switch (change) {
13 | case "name":
14 | return ;
15 | case "password":
16 | return ;
17 | default:
18 | return ;
19 | }
20 | }
21 | return {getRoute()};
22 | }
23 |
--------------------------------------------------------------------------------
/screen/App/FollowingFollowerScreens/Followers.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from "react-native";
2 | import React, { useEffect, useState } from "react";
3 | import { FlatList } from "react-native-gesture-handler";
4 | import { useLazyGetFollowersListQuery } from "../../../redux/api/user";
5 | import { FollowData } from "../../../types/api";
6 | import FFContainer from "../../../components/followingFollowers/FollowingFollowerContainer";
7 | import { ActivityIndicator } from "react-native-paper";
8 | import useGetMode from "../../../hooks/GetMode";
9 |
10 | export default function Followers() {
11 | const dark = useGetMode();
12 | const color = dark ? "white" : "black";
13 | const [getLazyFollowers, followersResponse] = useLazyGetFollowersListQuery();
14 | const [data, setData] = useState([]);
15 |
16 | const [skip, setSkip] = useState(0);
17 | const [noMore, setNoMore] = useState(false);
18 | useEffect(() => {
19 | getLazyFollowers({ take: 20, skip })
20 | .unwrap()
21 | .then((e) => {
22 | setData(e);
23 | setSkip(e.length);
24 | })
25 | .catch((e) => {});
26 | }, []);
27 |
28 | const renderItem = ({ item }: { item: FollowData }) => {
29 | return (
30 |
37 | );
38 | };
39 |
40 | const fetchMoreData = () => {
41 | if (!noMore && !followersResponse.isError && skip > 0)
42 | getLazyFollowers({ take: 10, skip })
43 | .unwrap()
44 | .then((r) => {
45 | setSkip(skip + r.length);
46 | setData((prev) => [...prev, ...r]);
47 |
48 | if (r.length < 10) {
49 | setNoMore(true);
50 | }
51 | });
52 | };
53 |
54 | return (
55 |
56 |
62 |
63 |
64 | ) : (
65 | Such Empty
66 | )
67 | }
68 | data={data}
69 | onEndReachedThreshold={0.3}
70 | onEndReached={fetchMoreData}
71 | renderItem={renderItem}
72 | />
73 |
74 | );
75 | }
76 |
--------------------------------------------------------------------------------
/screen/App/FollowingFollowerScreens/Following.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, ActivityIndicator } from "react-native";
2 | import React, { useEffect, useState } from "react";
3 | import { FlatList } from "react-native-gesture-handler";
4 | import {
5 | useLazyGetFollowersListQuery,
6 | useLazyGetFollowingListQuery,
7 | } from "../../../redux/api/user";
8 | import { FollowData, FollowingData } from "../../../types/api";
9 | import FFContainer from "../../../components/followingFollowers/FollowingFollowerContainer";
10 | import useGetMode from "../../../hooks/GetMode";
11 |
12 | export default function Followers() {
13 | const dark = useGetMode();
14 | const [getLazyFollowers, followersResponse] = useLazyGetFollowingListQuery();
15 | const [data, setData] = useState([]);
16 | const color = dark ? "white" : "black";
17 | const [skip, setSkip] = useState(0);
18 | const [noMore, setNoMore] = useState(false);
19 | useEffect(() => {
20 | getLazyFollowers({ take: 20, skip })
21 | .unwrap()
22 | .then((e) => {
23 | setData(e);
24 | setSkip(e.length);
25 | })
26 | .catch((e) => {});
27 | }, []);
28 |
29 | const renderItem = ({ item }: { item: FollowingData }) => {
30 | return (
31 |
38 | );
39 | };
40 |
41 | const fetchMoreData = () => {
42 | if (!noMore && !followersResponse.isError && skip > 0)
43 | getLazyFollowers({ take: 10, skip })
44 | .unwrap()
45 | .then((r) => {
46 | setSkip(skip + r.length);
47 | setData((prev) => [...prev, ...r]);
48 |
49 | if (r.length < 10) {
50 | setNoMore(true);
51 | }
52 | });
53 | };
54 |
55 | return (
56 |
57 |
64 |
65 |
66 | ) : (
67 | Such Empty
68 | )
69 | }
70 | onEndReachedThreshold={0.3}
71 | onEndReached={fetchMoreData}
72 | renderItem={renderItem}
73 | />
74 |
75 | );
76 | }
77 |
--------------------------------------------------------------------------------
/screen/App/Messages.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Animated } from "react-native";
2 | import React, { useCallback, useEffect, useRef, useState } from "react";
3 | import {
4 | useFocusEffect,
5 | useIsFocused,
6 | useNavigationState,
7 | } from "@react-navigation/native";
8 | import AnimatedScreen from "../../components/global/AnimatedScreen";
9 | import Recent from "../../components/messages/Recent";
10 | import ChatList from "../../components/messages/ChatList";
11 | import Fab from "../../components/messages/ChatList/Fab";
12 | import { AddMessage, MessagesIcon } from "../../components/icons";
13 | import useGetMode from "../../hooks/GetMode";
14 | import { useAppDispatch, useAppSelector } from "../../redux/hooks/hooks";
15 | import { clearNewFromChatList } from "../../redux/slice/chat/chatlist";
16 | import { useLazyGetAllChatsQuery } from "../../redux/api/chat";
17 | import { useAnimatedScrollHandler, useSharedValue } from "react-native-reanimated";
18 |
19 | export default function Messages() {
20 |
21 | const dark = useGetMode();
22 | const color = dark ? "#FFFFFF" : "#000000";
23 | const dispatch = useAppDispatch();
24 | const offset = useSharedValue(0);
25 | console.log("🚀 ~ file: Profile.tsx:16 ~ Profile ~ offset:", offset);
26 | const scrollHandler = useAnimatedScrollHandler((event) => {
27 | console.log("🚀 ~ file: Profile.tsx:22 ~ scrollHandler ~ event:", event)
28 |
29 | offset.value = event.contentOffset.y;
30 | });
31 |
32 | const [chatlist, chatlistRes] = useLazyGetAllChatsQuery();
33 |
34 |
35 | useFocusEffect(
36 | useCallback(() => {
37 | chatlist(null).refetch()
38 | dispatch(clearNewFromChatList());
39 | }, [])
40 | );
41 | return (
42 |
43 |
44 |
45 | } />
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/screen/App/Post.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text } from 'react-native'
2 | import React from 'react'
3 |
4 | export default function Post() {
5 | return (
6 |
7 |
8 |
9 | )
10 | }
--------------------------------------------------------------------------------
/screen/App/Profile.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Animated, ScrollView } from "react-native";
2 | import React, { useEffect, useRef } from "react";
3 |
4 | import AnimatedScreen from "../../components/global/AnimatedScreen";
5 | import Header from "../../components/profile/Header";
6 | import { StatusBar as ExpoStatusBar } from "expo-status-bar";
7 | import Bio from "../../components/profile/Bio";
8 | import MyPosts from "./ProfileScreens/MyPosts";
9 | import { useGetFollowDetailsQuery } from "../../redux/api/user";
10 | import {
11 | useAnimatedRef,
12 | useAnimatedScrollHandler,
13 | useScrollViewOffset,
14 | useSharedValue,
15 | } from "react-native-reanimated";
16 |
17 | export default function Profile() {
18 | const getFollowData = useGetFollowDetailsQuery(null);
19 | const offset = useSharedValue(0);
20 | console.log("🚀 ~ file: Profile.tsx:16 ~ Profile ~ offset:", offset);
21 | const scrollHandler = useAnimatedScrollHandler((event) => {
22 | console.log("🚀 ~ file: Profile.tsx:22 ~ scrollHandler ~ event:", event)
23 |
24 | offset.value = event.contentOffset.y;
25 | });
26 | useEffect(() => {
27 | console.log(getFollowData.data);
28 | getFollowData.refetch();
29 | }, []);
30 |
31 | return (
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | }
41 |
--------------------------------------------------------------------------------
/screen/App/ProfilePeople.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Animated, ScrollView } from "react-native";
2 | import React, { useRef } from "react";
3 |
4 | import AnimatedScreen from "../../components/global/AnimatedScreen";
5 | import Header from "../../components/profilePeople/Header";
6 | import { StatusBar as ExpoStatusBar } from "expo-status-bar";
7 | import Bio from "../../components/profile/Bio";
8 | import MyPosts from "./ProfileScreens/MyPosts";
9 | import { ProfilePeopleProp } from "../../types/navigation";
10 | import PeoplePosts from "./ProfileScreens/PeoplePosts";
11 |
12 | export default function ProfilePeople({
13 | navigation,
14 | route,
15 | }: ProfilePeopleProp) {
16 | const offset = useRef(new Animated.Value(0)).current;
17 | const { id } = route.params;
18 | return (
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/screen/Auth/components/InputPassword.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | TextInput,
5 | useColorScheme,
6 | Pressable,
7 | StyleProp,
8 | ViewStyle,
9 | } from "react-native";
10 | import React, { useState } from "react";
11 | import { Eye, EyeSlash } from "../../../components/icons";
12 | import useGetMode from "../../../hooks/GetMode";
13 | import { TextInputProps } from "react-native-paper";
14 | import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
15 |
16 | export default function InputPassword({
17 | props,
18 | style,
19 | }: {
20 | props: TextInputProps;
21 | style?: StyleProp;
22 | }) {
23 | const dark = useGetMode();
24 | const isDark = dark;
25 | const backgroundColor = isDark ? "#292828" : "#f1f1f1";
26 | const color = isDark ? "white" : "black";
27 | const [show, setShow] = useState(false);
28 | const placeholderColor = isDark ? "#959595" : "#393939";
29 | return (
30 |
44 |
59 |
69 | {
71 | setShow(!show);
72 | }}
73 | style={{
74 | height: "100%",
75 | width: "100%",
76 | borderRadius: 999,
77 | alignItems: "center",
78 |
79 | justifyContent: "center",
80 | }}
81 | android_ripple={{ color: "#FFFFFF" }}
82 | >
83 | {!show ? (
84 |
85 |
86 |
87 | ) : (
88 |
89 | )}
90 |
91 |
92 |
93 | );
94 | }
95 |
--------------------------------------------------------------------------------
/screen/Auth/components/InputText.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | View,
3 | Text,
4 | TextInput,
5 | useColorScheme,
6 | TextInputProps,
7 | StyleProp,
8 | RegisteredStyle,
9 | ViewStyle,
10 | } from "react-native";
11 | import React from "react";
12 | import useGetMode from "../../../hooks/GetMode";
13 |
14 | export default function InputText({
15 | props,
16 | style,
17 | }: {
18 | props: TextInputProps;
19 | style?: StyleProp;
20 | }) {
21 | const dark = useGetMode();
22 | const isDark = dark;
23 | const backgroundColor = isDark ? "#292828" : "#f1f1f1";
24 | const color = isDark ? "white" : "black";
25 | const placeholderColor = isDark ? "#959595" : "#393939";
26 | return (
27 |
42 |
58 |
68 |
76 | @
77 |
78 |
79 |
80 | );
81 | }
82 |
--------------------------------------------------------------------------------
/screen/Onboard/components/OnboardBuilder.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, Dimensions, useColorScheme } from "react-native";
2 | import { Image, ImageSource, } from "expo-image";
3 |
4 | import Animated, { FadeInLeft } from "react-native-reanimated";
5 | import useGetMode from "../../../hooks/GetMode";
6 |
7 |
8 | const height = Dimensions.get("window").height;
9 | const width = Dimensions.get("window").width;
10 | console.log("🚀 ~ file: OnboardBuilder.tsx:10 ~ width:", width)
11 | export default function OnboardBuilder({
12 | header,
13 | subText,
14 | imageUri,
15 | quote,
16 | }: {
17 | header: string;
18 | subText: string;
19 | imageUri: ImageSource;
20 | quote: string;
21 | }) {
22 | const dark = useGetMode();
23 | const color = !dark ? "black" : "white";
24 |
25 | return (
26 |
27 |
35 |
36 |
37 |
40 | {header}
41 |
42 |
43 | {subText}
44 |
45 |
53 | {quote}
54 |
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/screen/Onboard/components/TrackerTag.tsx:
--------------------------------------------------------------------------------
1 | import { View, Text, useColorScheme } from "react-native";
2 | import React from "react";
3 | import Animated, {
4 | FadeIn,
5 | FadeInLeft,
6 | FadeInRight,
7 | FadeOut,
8 | FadeOutLeft,
9 | FadeOutRight,
10 | } from "react-native-reanimated";
11 | import useGetMode from "../../../hooks/GetMode";
12 |
13 | export default function TrackerTag({ color }: { color?: string }) {
14 | const dark = useGetMode();
15 | const isDark = dark;
16 | const backgroundColor = !isDark ? "black" : "white";
17 |
18 | return (
19 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/screenshot/qui.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElSierra/Social-app-React-Native/81f4784e9fe4b45d4130c4b8d37d82e2ee6a7d57/screenshot/qui.gif
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "expo/tsconfig.base",
3 | "compilerOptions": {
4 | "strict": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/types/app.ts:
--------------------------------------------------------------------------------
1 | import { Audio } from "expo-av";
2 |
3 | export type ArrElement = ArrType extends readonly (infer ElementType)[]
4 | ? ElementType
5 | : never;
6 |
7 | export type IPostBuilder = {
8 | imageUri: string;
9 | deletePost?: (id: string) => void;
10 | photo?: { uri: string; height: number; width: number };
11 | name: string;
12 | userId?: string;
13 | date: Date;
14 | myPost?: boolean;
15 | userTag: string;
16 | comments?: number;
17 | isLiked: boolean;
18 | isReposted: boolean;
19 | verified: boolean;
20 | photoUri: string[];
21 | videoUri?: string;
22 | videoTitle?: string;
23 | postText: string;
24 | videoViews?: string;
25 | repost?: string;
26 | title?: string;
27 | link: {
28 | id: string;
29 | imageHeight?: number;
30 | imageUri?: string;
31 | imageWidth?: number;
32 | title: string;
33 | } | null;
34 | thumbNail: string | null;
35 | like: number;
36 | id: string;
37 | audioUri?: string;
38 | postId?: string;
39 | inView?: boolean;
40 | idx:number;
41 |
42 | };
43 |
44 | export type SearchPostBuilder = {
45 | imageUri: string;
46 | userTag: string;
47 | verified: boolean;
48 | photoUri: string[];
49 | videoUri?: string;
50 | postText: string;
51 | title?: string;
52 | id: string;
53 | audioUri?: string;
54 | };
55 |
56 | export type ICommentBuilder = {
57 | imageUri: string;
58 | name: string;
59 | comment: string;
60 | date: string;
61 | userTag: string;
62 | verified: boolean;
63 | photoUri: string[];
64 | id: string;
65 | };
66 |
67 | export type ICommentContent = {
68 | name: string;
69 | id: string;
70 | comment: string;
71 | };
72 |
73 | export type ChatType = {
74 | id: string | number;
75 | user: {
76 | id: string | number;
77 | imageUri: string;
78 | name: string;
79 | userName: string;
80 | };
81 | messages: {
82 | id: string | number;
83 | text: string;
84 | createdAt: string;
85 | sender: {
86 | id: string;
87 | userName: string;
88 | };
89 | }[];
90 | };
91 |
--------------------------------------------------------------------------------
/types/socket.ts:
--------------------------------------------------------------------------------
1 | export interface IMessageSocket {
2 | message: {
3 | sender: { userName: string; id: string };
4 | text: string;
5 | id: string;
6 | createdAt: string;
7 | };
8 | imageUri :string;
9 | chatId: string;
10 | }
11 |
--------------------------------------------------------------------------------
/util/chatSearch.ts:
--------------------------------------------------------------------------------
1 | async function asyncFind(array: Array, predicate: any) {
2 | for (const item of array) {
3 | if (await predicate(item)) {
4 | return item;
5 | }
6 | }
7 | return undefined;
8 | }
9 |
10 | export async function findChatById(id: string, list: Array) {
11 | return asyncFind(list, async (chat: any) => chat.id === id);
12 | }
13 |
--------------------------------------------------------------------------------
/util/convert.ts:
--------------------------------------------------------------------------------
1 | export default function convertMsToHMS(ms: number) {
2 | const seconds = Math.floor((ms / 1000) % 60);
3 | const minutes = Math.floor((ms / (1000 * 60)) % 60);
4 | const hours = Math.floor(ms / (1000 * 60 * 60));
5 |
6 | if (hours === 0) {
7 | return `${minutes < 10 ? `0${minutes}` : minutes}:${
8 | seconds < 10 ? `0${seconds}` : seconds
9 | }`;
10 | }
11 | return `${hours}:${minutes.toString()}:${seconds}`;
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/util/date.ts:
--------------------------------------------------------------------------------
1 | export const dateAgo = (date: Date) => {
2 | const currentDatetime = new Date();
3 |
4 | const timeDifference = currentDatetime.getTime() - date.getTime();
5 |
6 | const minutesAgo = Math.floor(timeDifference / (1000 * 60));
7 | const hoursAgo = Math.floor(timeDifference / (1000 * 60 * 60));
8 | const daysAgo = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
9 | const secondsAgo = Math.floor(timeDifference / 1000);
10 | let result;
11 |
12 | if (secondsAgo < 60) {
13 | result = `${secondsAgo}s`;
14 | } else if (minutesAgo < 60) {
15 | result = `${minutesAgo}m`;
16 | } else if (hoursAgo < 24) {
17 | result = `${hoursAgo}h`;
18 | } else {
19 | result = `${daysAgo}d`;
20 | }
21 |
22 | return result;
23 | };
24 |
25 | export const dateFormatted = (date: Date) => {
26 | const months = [
27 | "Jan",
28 | "Feb",
29 | "Mar",
30 | "Apr",
31 | "May",
32 | "Jun",
33 | "Jul",
34 | "Aug",
35 | "Sep",
36 | "Oct",
37 | "Nov",
38 | "Dec",
39 | ];
40 | const formattedDate = `${date.getDate()} ${months[date.getMonth()]} ${date
41 | .getFullYear()
42 | .toString()
43 | .slice(-2)}, ${formatAMPM()}`;
44 |
45 | return formattedDate;
46 |
47 | function formatAMPM() {
48 | let hours = date.getHours();
49 | let minutes = date.getMinutes();
50 | const ampm = hours >= 12 ? "PM" : "AM";
51 | hours %= 12;
52 | hours = hours || 12;
53 | const minutesStr = minutes < 10 ? `0${minutes}` : minutes.toString();
54 | return `${hours}:${minutesStr} ${ampm}`;
55 | }
56 | };
57 |
58 | export function formatDateForChat(inputDateStr: string) {
59 | const inputDate = new Date(inputDateStr);
60 | const currentDate = new Date();
61 |
62 | // Check if the input date is today
63 | if (
64 | inputDate.getDate() === currentDate.getDate() &&
65 | inputDate.getMonth() === currentDate.getMonth() &&
66 | inputDate.getFullYear() === currentDate.getFullYear()
67 | ) {
68 | // If it's today, format as HH:mm
69 | const hours = String(inputDate.getHours()).padStart(2, "0");
70 | const minutes = String(inputDate.getMinutes()).padStart(2, "0");
71 | return `${hours}:${minutes}`;
72 | } else {
73 | // If it's not today, format as dd/mm HH:mm
74 | const day = String(inputDate.getDate()).padStart(2, "0");
75 | const month = String(inputDate.getMonth() + 1).padStart(2, "0"); // Month is zero-based
76 | const hours = String(inputDate.getHours()).padStart(2, "0");
77 | const minutes = String(inputDate.getMinutes()).padStart(2, "0");
78 | return `${day}/${month} ${hours}:${minutes}`;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/util/emoji.ts:
--------------------------------------------------------------------------------
1 | export function isEmoji(str: string): boolean {
2 |
3 |
4 | const emojiPattern = /\p{Emoji}/u;
5 |
6 | return emojiPattern.test(str) && str?.length <= 5;
7 | }
8 |
--------------------------------------------------------------------------------
/util/notification.ts:
--------------------------------------------------------------------------------
1 | import * as Notifications from "expo-notifications";
2 | import { Platform } from "react-native";
3 |
4 | Notifications.setNotificationHandler({
5 | handleNotification: async () => ({
6 | shouldShowAlert: true,
7 | shouldPlaySound: false,
8 | shouldSetBadge: true,
9 | }),
10 | });
11 |
12 | export default Notifications;
13 |
--------------------------------------------------------------------------------
/util/socket.ts:
--------------------------------------------------------------------------------
1 | import { io } from "socket.io-client";
2 | import storage from "../redux/storage";
3 | import { store } from "../redux/store";
4 |
5 |
6 | const persistRoot = storage.getString("persist:root");
7 | const userId = (): string | undefined => {
8 | if (persistRoot) {
9 | const routes = JSON.parse(persistRoot);
10 | if (routes) {
11 | const user = JSON.parse(routes.user);
12 |
13 | return user.token;
14 | }
15 | return undefined;
16 | }
17 | return undefined;
18 | };
19 | userId();
20 |
21 | const socket = io(process.env.EXPO_PUBLIC_API_URL as string, {
22 | autoConnect: true,
23 | auth: {
24 | token: userId(),
25 | },
26 | });
27 | export default socket;
28 |
--------------------------------------------------------------------------------