Merge pull request 'amalia/28-jul-25' (#6) from amalia/28-jul-25 into join
Reviewed-on: bip/mobile-darmasaba#6
This commit is contained in:
13
app.json
13
app.json
@@ -14,7 +14,8 @@
|
|||||||
"bundleIdentifier": "mobiledarmasaba.app",
|
"bundleIdentifier": "mobiledarmasaba.app",
|
||||||
"infoPlist": {
|
"infoPlist": {
|
||||||
"ITSAppUsesNonExemptEncryption": false
|
"ITSAppUsesNonExemptEncryption": false
|
||||||
}
|
},
|
||||||
|
"googleServicesFile": "./ios/mobiledarmasaba/GoogleService-Info.plist"
|
||||||
},
|
},
|
||||||
"android": {
|
"android": {
|
||||||
"package": "mobiledarmasaba.app",
|
"package": "mobiledarmasaba.app",
|
||||||
@@ -41,7 +42,15 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"expo-font",
|
"expo-font",
|
||||||
"expo-web-browser"
|
"expo-web-browser",
|
||||||
|
[
|
||||||
|
"@react-native-firebase/app",
|
||||||
|
{
|
||||||
|
"ios": {
|
||||||
|
"googleServicesFile": "./ios/mobiledarmasaba/GoogleService-Info.plist"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
],
|
],
|
||||||
"experiments": {
|
"experiments": {
|
||||||
"typedRoutes": true
|
"typedRoutes": true
|
||||||
|
|||||||
@@ -6,17 +6,21 @@ import HeaderRightGroupList from "@/components/group/headerGroupList";
|
|||||||
import HeaderMemberList from "@/components/member/headerMemberList";
|
import HeaderMemberList from "@/components/member/headerMemberList";
|
||||||
import HeaderRightPositionList from "@/components/position/headerRightPositionList";
|
import HeaderRightPositionList from "@/components/position/headerRightPositionList";
|
||||||
import HeaderRightProjectList from "@/components/project/headerProjectList";
|
import HeaderRightProjectList from "@/components/project/headerProjectList";
|
||||||
|
import Text from "@/components/Text";
|
||||||
|
import ToastCustom from "@/components/toastCustom";
|
||||||
import { Headers } from "@/constants/Headers";
|
import { Headers } from "@/constants/Headers";
|
||||||
|
import Styles from "@/constants/Styles";
|
||||||
import { apiReadOneNotification } from "@/lib/api";
|
import { apiReadOneNotification } from "@/lib/api";
|
||||||
import { pushToPage } from "@/lib/pushToPage";
|
import { pushToPage } from "@/lib/pushToPage";
|
||||||
import store from "@/lib/store";
|
import store from "@/lib/store";
|
||||||
import { useAuthSession } from "@/providers/AuthProvider";
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
import messaging from "@react-native-firebase/messaging";
|
import firebase from '@react-native-firebase/app';
|
||||||
import { Redirect, router, Stack } from "expo-router";
|
import { Redirect, router, Stack } from "expo-router";
|
||||||
import { StatusBar } from 'expo-status-bar';
|
import { StatusBar } from 'expo-status-bar';
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { Text } from "react-native";
|
import { View } from "react-native";
|
||||||
import { Easing, Notifier } from 'react-native-notifier';
|
import { Easing, Notifier } from 'react-native-notifier';
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
|
|
||||||
export default function RootLayout() {
|
export default function RootLayout() {
|
||||||
@@ -33,7 +37,7 @@ export default function RootLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = messaging().onMessage(async remoteMessage => {
|
const unsubscribe = firebase.app().messaging().onMessage(async remoteMessage => {
|
||||||
const id = remoteMessage?.data?.id;
|
const id = remoteMessage?.data?.id;
|
||||||
const category = remoteMessage?.data?.category;
|
const category = remoteMessage?.data?.category;
|
||||||
const content = remoteMessage?.data?.content;
|
const content = remoteMessage?.data?.content;
|
||||||
@@ -122,6 +126,7 @@ export default function RootLayout() {
|
|||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<StatusBar style="light" translucent={false} backgroundColor="black" />
|
<StatusBar style="light" translucent={false} backgroundColor="black" />
|
||||||
|
<ToastCustom />
|
||||||
</Provider>
|
</Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import ViewLogin from "@/components/auth/viewLogin";
|
import ViewLogin from "@/components/auth/viewLogin";
|
||||||
import ViewVerification from "@/components/auth/viewVerification";
|
import ViewVerification from "@/components/auth/viewVerification";
|
||||||
|
import Text from '@/components/Text';
|
||||||
|
import ToastCustom from "@/components/toastCustom";
|
||||||
import { requestPermission } from "@/lib/useNotification";
|
import { requestPermission } from "@/lib/useNotification";
|
||||||
import { useAuthSession } from "@/providers/AuthProvider";
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
import { Redirect } from "expo-router";
|
import { Redirect } from "expo-router";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { View } from "react-native";
|
|
||||||
import Text from '@/components/Text';
|
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const [isValid, setValid] = useState(false)
|
const [isValid, setValid] = useState(false)
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ import Styles from "@/constants/Styles"
|
|||||||
import { apiCheckPhoneLogin, apiSendOtp } from "@/lib/api"
|
import { apiCheckPhoneLogin, apiSendOtp } from "@/lib/api"
|
||||||
import AsyncStorage from "@react-native-async-storage/async-storage"
|
import AsyncStorage from "@react-native-async-storage/async-storage"
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import { Image, SafeAreaView, Text, ToastAndroid, View } from "react-native"
|
import { Image, SafeAreaView, View } from "react-native"
|
||||||
|
import Toast from "react-native-toast-message"
|
||||||
import { ButtonForm } from "../buttonForm"
|
import { ButtonForm } from "../buttonForm"
|
||||||
import { InputForm } from "../inputForm"
|
import { InputForm } from "../inputForm"
|
||||||
import ModalLoading from "../modalLoading"
|
import ModalLoading from "../modalLoading"
|
||||||
|
import Text from "../Text"
|
||||||
|
import ToastCustom from "../toastCustom"
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -30,10 +33,9 @@ export default function ViewLogin({ onValidate }: Props) {
|
|||||||
return onValidate({ phone: `62${phone}`, otp })
|
return onValidate({ phone: `62${phone}`, otp })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ToastAndroid.show(response.message, ToastAndroid.SHORT)
|
return Toast.show({ type: 'small', text1: response.message, })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||||
return ToastAndroid.show(`Terjadi kesalahan ${error}`, ToastAndroid.SHORT)
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoadingLogin(false)
|
setLoadingLogin(false)
|
||||||
}
|
}
|
||||||
@@ -41,6 +43,7 @@ export default function ViewLogin({ onValidate }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView>
|
<SafeAreaView>
|
||||||
|
<ToastCustom />
|
||||||
<View style={Styles.p20}>
|
<View style={Styles.p20}>
|
||||||
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ import { apiSendOtp } from "@/lib/api";
|
|||||||
import { useAuthSession } from "@/providers/AuthProvider";
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Image, Text, ToastAndroid, View } from "react-native";
|
import { Image, View } from "react-native";
|
||||||
import { OtpInput } from "react-native-otp-entry";
|
import { OtpInput } from "react-native-otp-entry";
|
||||||
|
import Toast from 'react-native-toast-message';
|
||||||
import { ButtonForm } from "../buttonForm";
|
import { ButtonForm } from "../buttonForm";
|
||||||
|
import Text from "../Text";
|
||||||
|
import ToastCustom from "../toastCustom";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
phone: string
|
phone: string
|
||||||
@@ -24,7 +27,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
|||||||
const encrypted = await encryptToken(valueUser);
|
const encrypted = await encryptToken(valueUser);
|
||||||
signIn(encrypted);
|
signIn(encrypted);
|
||||||
} else {
|
} else {
|
||||||
return ToastAndroid.show('Terjadi kesalahan', ToastAndroid.SHORT)
|
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +35,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
|||||||
if (value === otpFix.toString()) {
|
if (value === otpFix.toString()) {
|
||||||
login()
|
login()
|
||||||
} else {
|
} else {
|
||||||
return ToastAndroid.show('Kode OTP tidak sesuai', ToastAndroid.SHORT)
|
return Toast.show({ type: 'error', text1: 'Kode OTP tidak sesuai' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,17 +45,18 @@ export default function ViewVerification({ phone, otp }: Props) {
|
|||||||
setOtpFix(otpNew)
|
setOtpFix(otpNew)
|
||||||
const responseOtp = await apiSendOtp({ phone, otp: otpNew })
|
const responseOtp = await apiSendOtp({ phone, otp: otpNew })
|
||||||
if (responseOtp == 200) {
|
if (responseOtp == 200) {
|
||||||
return ToastAndroid.show('Kode OTP berhasil dikirim ulang', ToastAndroid.SHORT)
|
return Toast.show({ type: 'small', text1: 'Kode OTP berhasil dikirim ulang', })
|
||||||
}
|
}
|
||||||
return ToastAndroid.show('Terjadi kesalahan dalam mengirim kode OTP', ToastAndroid.SHORT)
|
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan dalam mengirim kode OTP', })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
console.error('Error fetching data:', error);
|
||||||
return ToastAndroid.show('Terjadi kesalahan', ToastAndroid.SHORT)
|
return Toast.show({ type: 'small', text1: 'Terjadi kesalahan', })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<ToastCustom />
|
||||||
<View style={Styles.wrapLogin} >
|
<View style={Styles.wrapLogin} >
|
||||||
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
<View style={{ alignItems: "center", marginVertical: 50 }}>
|
||||||
<Image
|
<Image
|
||||||
@@ -77,6 +81,7 @@ export default function ViewVerification({ phone, otp }: Props) {
|
|||||||
alignSelf: 'center'
|
alignSelf: 'center'
|
||||||
},
|
},
|
||||||
pinCodeContainerStyle: Styles.verificationCell,
|
pinCodeContainerStyle: Styles.verificationCell,
|
||||||
|
pinCodeTextStyle: { color: 'black' }
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ButtonForm
|
<ButtonForm
|
||||||
|
|||||||
16
components/toastCustom.tsx
Normal file
16
components/toastCustom.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import Styles from "@/constants/Styles";
|
||||||
|
import { View } from "react-native";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
import Text from "./Text";
|
||||||
|
|
||||||
|
export default function ToastCustom() {
|
||||||
|
return (
|
||||||
|
<Toast autoHide onPress={() => Toast.hide()} visibilityTime={1500} position="bottom" config={{
|
||||||
|
small: ({ text1 }) => (
|
||||||
|
<View style={[Styles.toastContainer]}>
|
||||||
|
<Text style={{ fontSize: 12 }}>{text1}</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}} />
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -550,6 +550,14 @@ const Styles = StyleSheet.create({
|
|||||||
top: 18,
|
top: 18,
|
||||||
left: 20,
|
left: 20,
|
||||||
position: 'absolute'
|
position: 'absolute'
|
||||||
|
},
|
||||||
|
toastContainer: {
|
||||||
|
backgroundColor: 'white',
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 10,
|
||||||
|
width: '90%',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#d6d8f6',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
87
ios/Podfile
87
ios/Podfile
@@ -1,40 +1,69 @@
|
|||||||
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
|
||||||
|
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
|
||||||
|
|
||||||
platform :ios, '15.1'
|
require 'json'
|
||||||
install! 'cocoapods', :deterministic_uuids => false
|
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
|
||||||
|
|
||||||
# Add Expo modules autolinking
|
ENV['RCT_NEW_ARCH_ENABLED'] = '0' if podfile_properties['newArchEnabled'] == 'false'
|
||||||
expo_autolinking_script = File.join(File.dirname(%x(node --print "require.resolve('expo/package.json')").strip), "scripts/autolinking")
|
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
|
||||||
require expo_autolinking_script if File.exist?(expo_autolinking_script)
|
|
||||||
|
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
|
||||||
|
install! 'cocoapods',
|
||||||
|
:deterministic_uuids => false
|
||||||
|
|
||||||
|
prepare_react_native_project!
|
||||||
|
|
||||||
target 'mobiledarmasaba' do
|
target 'mobiledarmasaba' do
|
||||||
# Use Expo modules with guard
|
use_expo_modules!
|
||||||
use_expo_modules! if respond_to?(:use_expo_modules!)
|
|
||||||
|
if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1'
|
||||||
config = {
|
config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
|
||||||
:reactNativePath => "../node_modules/react-native"
|
else
|
||||||
}
|
config_command = [
|
||||||
|
'npx',
|
||||||
|
'expo-modules-autolinking',
|
||||||
|
'react-native-config',
|
||||||
|
'--json',
|
||||||
|
'--platform',
|
||||||
|
'ios'
|
||||||
|
]
|
||||||
|
|
||||||
|
pod 'FirebaseDatabase', :modular_headers => true
|
||||||
|
pod 'FirebaseCore', :modular_headers => true
|
||||||
|
pod 'FirebaseAppCheckInterop', :modular_headers => true
|
||||||
|
pod 'leveldb-library', :modular_headers => true
|
||||||
|
pod 'GoogleUtilities', :modular_headers => true
|
||||||
|
end
|
||||||
|
|
||||||
|
config = use_native_modules!(config_command)
|
||||||
|
|
||||||
|
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
|
||||||
|
use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
|
||||||
|
|
||||||
use_react_native!(
|
use_react_native!(
|
||||||
:path => config[:reactNativePath],
|
:path => config[:reactNativePath],
|
||||||
:hermes_enabled => true
|
:hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
|
||||||
|
# An absolute path to your application root.
|
||||||
|
:app_path => "#{Pod::Config.instance.installation_root}/..",
|
||||||
|
:privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
|
||||||
)
|
)
|
||||||
|
|
||||||
# Post Install processing
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
# Call react_native_post_install without parameters
|
react_native_post_install(
|
||||||
react_native_post_install(installer)
|
installer,
|
||||||
|
config[:reactNativePath],
|
||||||
# Set C++20 standard for all targets
|
:mac_catalyst_enabled => false,
|
||||||
installer.pods_project.targets.each do |target|
|
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
|
||||||
target.build_configurations.each do |config|
|
)
|
||||||
config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++20'
|
|
||||||
config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++'
|
# This is necessary for Xcode 14, because it signs resource bundles by default
|
||||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.1'
|
# when building for devices.
|
||||||
|
installer.target_installation_results.pod_target_installation_results
|
||||||
# Enable C++ modules
|
.each do |pod_name, target_installation_result|
|
||||||
config.build_settings['CLANG_ENABLE_MODULES'] = 'YES'
|
target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
|
||||||
config.build_settings['GCC_C_LANGUAGE_STANDARD'] = 'gnu11'
|
resource_bundle_target.build_configurations.each do |config|
|
||||||
|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
1197
ios/Podfile.lock
1197
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,48 +1,74 @@
|
|||||||
import UIKit
|
import Expo
|
||||||
import ExpoModulesCore
|
import FirebaseCore
|
||||||
import React
|
import React
|
||||||
|
import ReactAppDependencyProvider
|
||||||
|
|
||||||
@main
|
@UIApplicationMain
|
||||||
class AppDelegate: ExpoAppDelegate {
|
public class AppDelegate: ExpoAppDelegate {
|
||||||
override func application(
|
var window: UIWindow?
|
||||||
|
|
||||||
|
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
|
||||||
|
var reactNativeFactory: RCTReactNativeFactory?
|
||||||
|
|
||||||
|
public override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
// Make sure the expo modules provider is set up
|
let delegate = ReactNativeDelegate()
|
||||||
let reactNativeWindow = (window as? UIWindow) ?? UIWindow()
|
let factory = ExpoReactNativeFactory(delegate: delegate)
|
||||||
|
delegate.dependencyProvider = RCTAppDependencyProvider()
|
||||||
if #available(iOS 13.0, *) {
|
|
||||||
reactNativeWindow.overrideUserInterfaceStyle = .light
|
reactNativeDelegate = delegate
|
||||||
}
|
reactNativeFactory = factory
|
||||||
|
bindReactNativeFactory(factory)
|
||||||
// Initialize the Expo modules provider
|
|
||||||
let reactAppDelegate = ReactAppDelegateWrapper(moduleProvider: {
|
#if os(iOS) || os(tvOS)
|
||||||
return [
|
window = UIWindow(frame: UIScreen.main.bounds)
|
||||||
// Add any custom modules here if needed
|
// @generated begin @react-native-firebase/app-didFinishLaunchingWithOptions - expo prebuild (DO NOT MODIFY) sync-10e8520570672fd76b2403b7e1e27f5198a6349a
|
||||||
]
|
FirebaseApp.configure()
|
||||||
})
|
// @generated end @react-native-firebase/app-didFinishLaunchingWithOptions
|
||||||
|
factory.startReactNative(
|
||||||
// Call the parent's implementation
|
withModuleName: "main",
|
||||||
let result = super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
in: window,
|
||||||
|
launchOptions: launchOptions)
|
||||||
// Set up the React Native root view
|
#endif
|
||||||
if let rootView = self.window?.rootViewController?.view as? RCTRootView {
|
|
||||||
rootView.backgroundColor = .white
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UISceneSession Lifecycle
|
// Linking API
|
||||||
|
public override func application(
|
||||||
override func application(
|
_ app: UIApplication,
|
||||||
|
open url: URL,
|
||||||
|
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
|
||||||
|
) -> Bool {
|
||||||
|
return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Universal Links
|
||||||
|
public override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
configurationForConnecting connectingSceneSession: UISceneSession,
|
continue userActivity: NSUserActivity,
|
||||||
options: UIScene.ConnectionOptions
|
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
|
||||||
) -> UISceneConfiguration {
|
) -> Bool {
|
||||||
return UISceneConfiguration(
|
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
||||||
name: "Default Configuration",
|
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
|
||||||
sessionRole: connectingSceneSession.role
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
|
class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
|
||||||
|
// Extension point for config-plugins
|
||||||
|
|
||||||
|
override func sourceURL(for bridge: RCTBridge) -> URL? {
|
||||||
|
// needed to return the correct URL for expo-dev-client.
|
||||||
|
bridge.bundleURL ?? bundleURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func bundleURL() -> URL? {
|
||||||
|
#if DEBUG
|
||||||
|
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
|
||||||
|
#else
|
||||||
|
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
import Expo
|
|
||||||
import React
|
|
||||||
import ReactAppDependencyProvider
|
|
||||||
|
|
||||||
@UIApplicationMain
|
|
||||||
public class AppDelegate: ExpoAppDelegate {
|
|
||||||
var window: UIWindow?
|
|
||||||
|
|
||||||
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
|
|
||||||
var reactNativeFactory: RCTReactNativeFactory?
|
|
||||||
|
|
||||||
public override func application(
|
|
||||||
_ application: UIApplication,
|
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
|
|
||||||
) -> Bool {
|
|
||||||
let delegate = ReactNativeDelegate()
|
|
||||||
let factory = ExpoReactNativeFactory(delegate: delegate)
|
|
||||||
delegate.dependencyProvider = RCTAppDependencyProvider()
|
|
||||||
|
|
||||||
reactNativeDelegate = delegate
|
|
||||||
reactNativeFactory = factory
|
|
||||||
bindReactNativeFactory(factory)
|
|
||||||
|
|
||||||
#if os(iOS) || os(tvOS)
|
|
||||||
window = UIWindow(frame: UIScreen.main.bounds)
|
|
||||||
factory.startReactNative(
|
|
||||||
withModuleName: "main",
|
|
||||||
in: window,
|
|
||||||
launchOptions: launchOptions)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linking API
|
|
||||||
public override func application(
|
|
||||||
_ app: UIApplication,
|
|
||||||
open url: URL,
|
|
||||||
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
|
|
||||||
) -> Bool {
|
|
||||||
return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Universal Links
|
|
||||||
public override func application(
|
|
||||||
_ application: UIApplication,
|
|
||||||
continue userActivity: NSUserActivity,
|
|
||||||
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
|
|
||||||
) -> Bool {
|
|
||||||
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
|
||||||
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
|
|
||||||
// Extension point for config-plugins
|
|
||||||
|
|
||||||
override func sourceURL(for bridge: RCTBridge) -> URL? {
|
|
||||||
// needed to return the correct URL for expo-dev-client.
|
|
||||||
bridge.bundleURL ?? bundleURL()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func bundleURL() -> URL? {
|
|
||||||
#if DEBUG
|
|
||||||
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
|
|
||||||
#else
|
|
||||||
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
32
ios/mobiledarmasaba/GoogleService-Info.plist
Normal file
32
ios/mobiledarmasaba/GoogleService-Info.plist
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyBq_C4lMw-zIevHMpajQPzOQ4HRpUBBLHQ</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>867439221179</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>mobiledarmasaba.app</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>mobile-darmasaba</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>mobile-darmasaba.firebasestorage.app</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:867439221179:ios:aedc34b89ff4919e9b0c9e</string>
|
||||||
|
<key>DATABASE_URL</key>
|
||||||
|
<string>https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -53,14 +53,6 @@
|
|||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>Allow $(PRODUCT_NAME) to access your camera</string>
|
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
|
||||||
<string>Allow $(PRODUCT_NAME) to access your microphone</string>
|
|
||||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
|
||||||
<string>Allow $(PRODUCT_NAME) to save photos</string>
|
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
|
||||||
<string>Allow $(PRODUCT_NAME) to access your photos</string>
|
|
||||||
<key>NSUserActivityTypes</key>
|
<key>NSUserActivityTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
||||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||||
<array>
|
<array>
|
||||||
<string>85F4.1</string>
|
|
||||||
<string>E174.1</string>
|
<string>E174.1</string>
|
||||||
|
<string>85F4.1</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict/>
|
||||||
<key>aps-environment</key>
|
|
||||||
<string>development</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
</plist>
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import { getApp, getApps, initializeApp } from '@react-native-firebase/app';
|
import { getApp, getApps, initializeApp } from '@react-native-firebase/app';
|
||||||
import { getMessaging } from '@react-native-firebase/messaging';
|
import messaging, { getMessaging } from '@react-native-firebase/messaging';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { PermissionsAndroid } from 'react-native';
|
import { PermissionsAndroid, Platform } from 'react-native';
|
||||||
import { pushToPage } from './pushToPage';
|
|
||||||
|
|
||||||
// Your Firebase project configuration
|
// Your Firebase project configuration
|
||||||
const RNfirebaseConfig = {
|
const RNfirebaseConfig = {
|
||||||
@@ -21,6 +20,8 @@ const initializeFirebase = async () => {
|
|||||||
const app = getApps().length ? getApp() : initializeApp(RNfirebaseConfig);
|
const app = getApps().length ? getApp() : initializeApp(RNfirebaseConfig);
|
||||||
const mess = getMessaging(app);
|
const mess = getMessaging(app);
|
||||||
|
|
||||||
|
await messaging().registerDeviceForRemoteMessages();
|
||||||
|
|
||||||
// Set auto initialization and background message handler
|
// Set auto initialization and background message handler
|
||||||
mess.setAutoInitEnabled(true);
|
mess.setAutoInitEnabled(true);
|
||||||
mess.setBackgroundMessageHandler(async remoteMessage => {
|
mess.setBackgroundMessageHandler(async remoteMessage => {
|
||||||
@@ -36,15 +37,17 @@ const initializeFirebase = async () => {
|
|||||||
|
|
||||||
export const requestPermission = async () => {
|
export const requestPermission = async () => {
|
||||||
try {
|
try {
|
||||||
const cek = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS)
|
if (Platform.OS === 'android') {
|
||||||
if (!cek) {
|
const cek = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS)
|
||||||
const granted = await PermissionsAndroid.request(
|
if (!cek) {
|
||||||
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
|
const granted = await PermissionsAndroid.request(
|
||||||
);
|
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
|
||||||
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
|
);
|
||||||
return true
|
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -54,8 +57,8 @@ export const requestPermission = async () => {
|
|||||||
|
|
||||||
export const getToken = async () => {
|
export const getToken = async () => {
|
||||||
try {
|
try {
|
||||||
const mess = await initializeFirebase();
|
await initializeFirebase();
|
||||||
const token = await mess?.getToken();
|
const token = await messaging().getToken();
|
||||||
return token;
|
return token;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error getting token:", error);
|
console.error("Error getting token:", error);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@
|
|||||||
"react-native-safe-area-context": "5.4.0",
|
"react-native-safe-area-context": "5.4.0",
|
||||||
"react-native-screens": "~4.11.1",
|
"react-native-screens": "~4.11.1",
|
||||||
"react-native-svg": "15.11.2",
|
"react-native-svg": "15.11.2",
|
||||||
|
"react-native-toast-message": "^2.3.3",
|
||||||
"react-native-ui-datepicker": "^3.0.5",
|
"react-native-ui-datepicker": "^3.0.5",
|
||||||
"react-native-web": "^0.20.0",
|
"react-native-web": "^0.20.0",
|
||||||
"react-native-webview": "13.13.5",
|
"react-native-webview": "13.13.5",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
|
|||||||
import CryptoES from "crypto-es";
|
import CryptoES from "crypto-es";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import { createContext, MutableRefObject, ReactNode, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
import { createContext, MutableRefObject, ReactNode, useCallback, useContext, useEffect, useRef, useState } from 'react';
|
||||||
|
import { Platform } from 'react-native';
|
||||||
|
|
||||||
const AuthContext = createContext<{
|
const AuthContext = createContext<{
|
||||||
signIn: (arg0: string) => void;
|
signIn: (arg0: string) => void;
|
||||||
@@ -76,7 +77,9 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
|
|||||||
try {
|
try {
|
||||||
const hasil = await decryptToken(String(tokenRef.current))
|
const hasil = await decryptToken(String(tokenRef.current))
|
||||||
const token = await getToken()
|
const token = await getToken()
|
||||||
const response = await apiUnregisteredToken({ user: hasil, token: String(token) })
|
if (Platform.OS === 'android'){
|
||||||
|
const response = await apiUnregisteredToken({ user: hasil, token: String(token) })
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user