Compare commits
5 Commits
qc/27-mar-
...
clean/31-m
| Author | SHA1 | Date | |
|---|---|---|---|
| 81bbd8e6b0 | |||
| 57159d2c45 | |||
| 66373fa65b | |||
| 6d545f2af9 | |||
| eeb95336f2 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -81,4 +81,7 @@ yarn-error.*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# secrets
|
||||||
|
secrets/
|
||||||
|
|
||||||
# @end expo-cli
|
# @end expo-cli
|
||||||
@@ -3,5 +3,6 @@
|
|||||||
"allow": [
|
"allow": [
|
||||||
"Bash(git add *)"
|
"Bash(git add *)"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"$version": 3
|
||||||
}
|
}
|
||||||
@@ -1,369 +0,0 @@
|
|||||||
# Fix Phone Number Input - iOS 16+ Compatibility
|
|
||||||
|
|
||||||
## 📋 Ringkasan Task
|
|
||||||
Memperbaiki masalah phone number input pada `screens/Authentication/LoginView.tsx` yang tidak berfungsi dengan baik pada iOS versi 16 ke atas.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Tujuan
|
|
||||||
1. Fix keyboard overlay issues pada iOS 16+
|
|
||||||
2. Perbaiki layout measurement dan safe area
|
|
||||||
3. Pastikan input phone number responsive di semua device
|
|
||||||
4. Maintain UX yang konsisten dengan Android
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 File yang Terlibat
|
|
||||||
|
|
||||||
### File Utama
|
|
||||||
- **Target**: `screens/Authentication/LoginView.tsx`
|
|
||||||
|
|
||||||
### File Pendukung
|
|
||||||
- `components/TextInput/TextInputCustom.tsx` - Alternatif custom input
|
|
||||||
- `styles/global-styles.ts` - Styling adjustments
|
|
||||||
- `package.json` - Update dependencies (jika perlu)
|
|
||||||
|
|
||||||
### Dependencies Terkait
|
|
||||||
- `react-native-international-phone-number`: ^0.9.3
|
|
||||||
- `react-native-keyboard-controller`: ^1.18.6
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔍 Analisis Masalah
|
|
||||||
|
|
||||||
### Issues pada iOS 16+
|
|
||||||
|
|
||||||
#### 1. **Keyboard Overlay Problem**
|
|
||||||
**Symptom**: Input field tertutup keyboard saat aktif
|
|
||||||
**Cause**:
|
|
||||||
- Safe area insets tidak terhitung dengan benar
|
|
||||||
- Keyboard animation tidak sinkron dengan layout
|
|
||||||
- `react-native-keyboard-controller` tidak terintegrasi dengan baik
|
|
||||||
|
|
||||||
#### 2. **Layout Measurement Issues**
|
|
||||||
**Symptom**: Input field berubah ukuran secara tidak terduga
|
|
||||||
**Cause**:
|
|
||||||
- Dynamic Type settings mempengaruhi layout
|
|
||||||
- Font scaling pada iOS 16+ berbeda
|
|
||||||
- Container tidak memiliki fixed height
|
|
||||||
|
|
||||||
#### 3. **Focus Behavior**
|
|
||||||
**Symptom**: Input tidak auto-scroll saat di-focus
|
|
||||||
**Cause**:
|
|
||||||
- ScrollView/KeyboardAvoidingView configuration salah
|
|
||||||
- Keyboard dismissing behavior tidak konsisten
|
|
||||||
|
|
||||||
#### 4. **Visual Glitches**
|
|
||||||
**Symptom**: Country flag dropdown tidak muncul atau terpotong
|
|
||||||
**Cause**:
|
|
||||||
- Z-index issues pada iOS
|
|
||||||
- Modal/Popover rendering problems
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 Solusi yang Direkomendasikan
|
|
||||||
|
|
||||||
### Option 1: **KeyboardAvoidingView Enhancement** (RECOMMENDED)
|
|
||||||
**Effort**: Medium
|
|
||||||
**Impact**: High
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { KeyboardAvoidingView, Platform } from "react-native";
|
|
||||||
|
|
||||||
<KeyboardAvoidingView
|
|
||||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
||||||
keyboardVerticalOffset={Platform.OS === "ios" ? 90 : 50}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
>
|
|
||||||
<ViewWrapper>
|
|
||||||
{/* Content */}
|
|
||||||
</ViewWrapper>
|
|
||||||
</KeyboardAvoidingView>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Keuntungan**:
|
|
||||||
- Native solution dari React Native
|
|
||||||
- Tidak perlu tambahan library
|
|
||||||
- Stabil untuk iOS 16+
|
|
||||||
|
|
||||||
**Kekurangan**:
|
|
||||||
- Perlu tuning offset untuk setiap device
|
|
||||||
- Tidak se-smooth keyboard controller
|
|
||||||
|
|
||||||
### Option 2: **React Native Keyboard Controller** (BETTER UX)
|
|
||||||
**Effort**: Medium-High
|
|
||||||
**Impact**: High
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { KeyboardProvider } from "react-native-keyboard-controller";
|
|
||||||
|
|
||||||
// Wrap di root app (sudah ada di _layout.tsx)
|
|
||||||
<KeyboardProvider>
|
|
||||||
<App />
|
|
||||||
</KeyboardProvider>
|
|
||||||
|
|
||||||
// Di LoginView
|
|
||||||
import { KeyboardAwareScrollView } from "react-native-keyboard-controller";
|
|
||||||
|
|
||||||
<KeyboardAwareScrollView
|
|
||||||
bottomOffset={20}
|
|
||||||
keyboardOffset={10}
|
|
||||||
>
|
|
||||||
{/* Content */}
|
|
||||||
</KeyboardAwareScrollView>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Keuntungan**:
|
|
||||||
- Smooth keyboard animations
|
|
||||||
- Better control over keyboard behavior
|
|
||||||
- Cross-platform consistency
|
|
||||||
|
|
||||||
**Kekurangan**:
|
|
||||||
- Perlu verify konfigurasi yang sudah ada
|
|
||||||
- Mungkin perlu update library
|
|
||||||
|
|
||||||
### Option 3: **Custom Phone Input** (FALLBACK)
|
|
||||||
**Effort**: High
|
|
||||||
**Impact**: Medium
|
|
||||||
|
|
||||||
Membuat custom phone input dengan:
|
|
||||||
- TextInputCustom component
|
|
||||||
- Country code picker modal
|
|
||||||
- Validation logic
|
|
||||||
|
|
||||||
**Keuntungan**:
|
|
||||||
- Full control atas behavior
|
|
||||||
- Tidak depend on third-party issues
|
|
||||||
|
|
||||||
**Kekurangan**:
|
|
||||||
- Development time lebih lama
|
|
||||||
- Perlu testing ekstensif
|
|
||||||
- Maintain code sendiri
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Breakdown Task
|
|
||||||
|
|
||||||
### Task 1: Research & Setup ✅
|
|
||||||
- [x] Identifikasi masalah pada iOS 16+
|
|
||||||
- [x] Cek dokumentasi library
|
|
||||||
- [x] Review existing implementation
|
|
||||||
- [ ] Test di iOS simulator (iOS 16+)
|
|
||||||
- [ ] Test di device fisik (jika ada)
|
|
||||||
|
|
||||||
### Task 2: Implement KeyboardAvoidingView Fix
|
|
||||||
- [ ] Wrap ViewWrapper dengan KeyboardAvoidingView
|
|
||||||
- [ ] Set behavior berdasarkan Platform
|
|
||||||
- [ ] Adjust keyboardVerticalOffset
|
|
||||||
- [ ] Test di berbagai ukuran layar
|
|
||||||
- [ ] Test landscape mode (jika applicable)
|
|
||||||
|
|
||||||
### Task 3: Adjust Layout & Styling
|
|
||||||
- [ ] Fix container height/width
|
|
||||||
- [ ] Adjust safe area insets
|
|
||||||
- [ ] Test dengan Dynamic Type settings
|
|
||||||
- [ ] Ensure consistent padding/margin
|
|
||||||
|
|
||||||
### Task 4: Test Focus Behavior
|
|
||||||
- [ ] Auto-scroll saat focus
|
|
||||||
- [ ] Keyboard dismiss saat tap outside
|
|
||||||
- [ ] Next/previous field navigation (jika ada)
|
|
||||||
- [ ] Input validation on blur
|
|
||||||
|
|
||||||
### Task 5: Country Picker Fix
|
|
||||||
- [ ] Verify dropdown z-index
|
|
||||||
- [ ] Test modal presentation
|
|
||||||
- [ ] Ensure flag icons visible
|
|
||||||
- [ ] Test search functionality
|
|
||||||
|
|
||||||
### Task 6: Testing & QA
|
|
||||||
- [ ] Test iOS 16, 17, 18
|
|
||||||
- [ ] Test Android (regression)
|
|
||||||
- [ ] Test dengan berbagai device sizes
|
|
||||||
- [ ] Test accessibility (VoiceOver)
|
|
||||||
- [ ] Performance test (no lag)
|
|
||||||
|
|
||||||
### Task 7: Documentation
|
|
||||||
- [ ] Update code comments
|
|
||||||
- [ ] Document iOS-specific workarounds
|
|
||||||
- [ ] Add troubleshooting notes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💻 Implementation Guidelines
|
|
||||||
|
|
||||||
### Recommended Implementation (Option 1 + 2 Hybrid)
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import { KeyboardAvoidingView, Platform } from "react-native";
|
|
||||||
import { KeyboardProvider } from "react-native-keyboard-controller";
|
|
||||||
|
|
||||||
// Di LoginView.tsx
|
|
||||||
export default function LoginView() {
|
|
||||||
return (
|
|
||||||
<ViewWrapper
|
|
||||||
withBackground
|
|
||||||
refreshControl={
|
|
||||||
<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<KeyboardAvoidingView
|
|
||||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
||||||
keyboardVerticalOffset={Platform.OS === "ios" ? 100 : 50}
|
|
||||||
style={{ flex: 1 }}
|
|
||||||
>
|
|
||||||
<View style={[GStyles.authContainer, { paddingBottom: 40 }]}>
|
|
||||||
{/* Title Section */}
|
|
||||||
<View style={GStyles.authContainerTitle}>
|
|
||||||
<Text style={GStyles.authSubTitle}>WELCOME TO</Text>
|
|
||||||
<Spacing height={5} />
|
|
||||||
<Text style={GStyles.authTitle}>HIPMI BADUNG APPS</Text>
|
|
||||||
<Spacing height={5} />
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Spacing height={50} />
|
|
||||||
|
|
||||||
{/* Phone Input - Wrap dengan View untuk stability */}
|
|
||||||
<View style={{ marginBottom: 20 }}>
|
|
||||||
<PhoneInput
|
|
||||||
value={inputValue}
|
|
||||||
onChangePhoneNumber={handleInputValue}
|
|
||||||
selectedCountry={selectedCountry}
|
|
||||||
onChangeSelectedCountry={handleSelectedCountry}
|
|
||||||
defaultCountry="ID"
|
|
||||||
placeholder="Masukkan nomor"
|
|
||||||
// Add iOS-specific props
|
|
||||||
textInputProps={{
|
|
||||||
keyboardType: "phone-pad",
|
|
||||||
autoComplete: "tel",
|
|
||||||
importantForAutofill: "yes",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Spacing />
|
|
||||||
|
|
||||||
{/* Login Button */}
|
|
||||||
<ButtonCustom
|
|
||||||
onPress={handleLogin}
|
|
||||||
disabled={loadingTerm}
|
|
||||||
isLoading={loading || loadingTerm}
|
|
||||||
>
|
|
||||||
Login
|
|
||||||
</ButtonCustom>
|
|
||||||
|
|
||||||
<Spacing height={50} />
|
|
||||||
|
|
||||||
{/* Terms Text */}
|
|
||||||
<Text style={{ ...GStyles.textLabel, textAlign: "center", fontSize: 12 }}>
|
|
||||||
Dengan menggunakan aplikasi ini, Anda telah menyetujui{" "}
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
color: MainColor.yellow,
|
|
||||||
textDecorationLine: "underline",
|
|
||||||
}}
|
|
||||||
onPress={() => {
|
|
||||||
const toUrl = `${url}/terms-of-service.html`;
|
|
||||||
openBrowser(toUrl);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Syarat & Ketentuan
|
|
||||||
</Text>{" "}
|
|
||||||
dan seluruh kebijakan privasi yang berlaku.
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
{/* Version Info */}
|
|
||||||
<Text
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
bottom: 35,
|
|
||||||
right: 50,
|
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: "thin",
|
|
||||||
fontStyle: "italic",
|
|
||||||
color: MainColor.white_gray,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{version} | powered by muku.id
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</KeyboardAvoidingView>
|
|
||||||
</ViewWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Styling Adjustments
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// styles/global-styles.ts
|
|
||||||
export const GStyles = StyleSheet.create({
|
|
||||||
authContainer: {
|
|
||||||
flex: 1,
|
|
||||||
justifyContent: "center",
|
|
||||||
paddingHorizontal: 24,
|
|
||||||
// Add padding bottom untuk keyboard space
|
|
||||||
paddingBottom: Platform.OS === "ios" ? 40 : 20,
|
|
||||||
},
|
|
||||||
// ... existing styles
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Acceptance Criteria
|
|
||||||
|
|
||||||
### Functional
|
|
||||||
- [ ] Input field tidak tertutup keyboard saat focus
|
|
||||||
- [ ] Country picker dropdown berfungsi dengan baik
|
|
||||||
- [ ] Auto-scroll bekerja smooth saat focus
|
|
||||||
- [ ] Keyboard dismiss saat tap outside
|
|
||||||
- [ ] Input validation berjalan normal
|
|
||||||
|
|
||||||
### Visual
|
|
||||||
- [ ] Layout tidak berubah saat keyboard muncul
|
|
||||||
- [ ] No visual glitches atau flickering
|
|
||||||
- [ ] Country flag icons visible
|
|
||||||
- [ ] Consistent spacing dan padding
|
|
||||||
|
|
||||||
### Compatibility
|
|
||||||
- [ ] iOS 16, 17, 18 - Tested ✅
|
|
||||||
- [ ] Android - No regression ✅
|
|
||||||
- [ ] iPad - Responsive ✅
|
|
||||||
- [ ] Landscape mode - Usable ✅
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
- [ ] No lag saat typing
|
|
||||||
- [ ] Smooth keyboard animations
|
|
||||||
- [ ] No memory leaks
|
|
||||||
- [ ] Fast input response
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔗 References
|
|
||||||
- [React Native KeyboardAvoidingView Docs](https://reactnative.dev/docs/keyboardavoidingview)
|
|
||||||
- [react-native-keyboard-controller](https://github.com/kirillzyusko/react-native-keyboard-controller)
|
|
||||||
- [react-native-international-phone-number Issues](https://github.com/bluesky01/react-native-international-phone-number/issues)
|
|
||||||
- [iOS 16+ Keyboard Changes](https://developer.apple.com/documentation/uikit/uikit)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Estimated Effort
|
|
||||||
- **Complexity**: Medium
|
|
||||||
- **Time Estimate**: 2-4 jam
|
|
||||||
- **Risk Level**: Medium (perlu testing ekstensif di device)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Notes
|
|
||||||
- **Priority**: High (login adalah critical path)
|
|
||||||
- **Testing**: Wajib test di device fisik jika memungkinkan
|
|
||||||
- **Fallback**: Jika Option 1 & 2 gagal, siap untuk implement Option 3 (custom input)
|
|
||||||
- **Monitoring**: Add analytics untuk track input completion rate
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Created**: 2026-03-25
|
|
||||||
**Status**: Pending
|
|
||||||
**Priority**: High
|
|
||||||
**Related Issue**: iOS 16+ keyboard compatibility
|
|
||||||
@@ -100,7 +100,7 @@ packagingOptions {
|
|||||||
applicationId 'com.bip.hipmimobileapp'
|
applicationId 'com.bip.hipmimobileapp'
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 1
|
versionCode 5
|
||||||
versionName "1.0.2"
|
versionName "1.0.2"
|
||||||
|
|
||||||
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
|
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
|
||||||
|
|||||||
7
android/app/src/debugOptimized/AndroidManifest.xml
Normal file
7
android/app/src/debugOptimized/AndroidManifest.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||||
|
|
||||||
|
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
|
||||||
|
</manifest>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
<intent-filter android:autoVerify="true" data-generated="true">
|
<intent-filter android:autoVerify="true" data-generated="true">
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
<data android:scheme="https" android:host="cld-dkr-hipmi-stg.wibudev.com" android:pathPrefix="/"/>
|
<data android:scheme="https" android:host="hipmi.muku.id" android:pathPrefix="/"/>
|
||||||
<category android:name="android.intent.category.BROWSABLE"/>
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|||||||
@@ -6,32 +6,17 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.google.gms:google-services:4.4.1'
|
classpath 'com.google.gms:google-services:4.4.1'
|
||||||
classpath('com.android.tools.build:gradle')
|
classpath('com.android.tools.build:gradle')
|
||||||
classpath('com.facebook.react:react-native-gradle-plugin')
|
classpath('com.facebook.react:react-native-gradle-plugin')
|
||||||
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
|
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
google()
|
|
||||||
mavenCentral()
|
|
||||||
maven { url 'https://www.jitpack.io' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: "expo-root-project"
|
|
||||||
apply plugin: "com.facebook.react.rootproject"
|
|
||||||
// @generated begin @rnmapbox/maps-v2-maven - expo prebuild (DO NOT MODIFY) sync-d4ccbfdff48fdba3138b02a8ba41b9722af001d8
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url 'https://api.mapbox.com/downloads/v2/releases/maven'
|
url 'https://api.mapbox.com/downloads/v2/releases/maven'
|
||||||
// Authentication is no longer required as per Mapbox's removal of download token requirement
|
|
||||||
// See: https://github.com/mapbox/mapbox-maps-flutter/issues/775
|
|
||||||
// Keeping this as optional for backward compatibility
|
|
||||||
def token = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: System.getenv('RNMAPBOX_MAPS_DOWNLOAD_TOKEN')
|
def token = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: System.getenv('RNMAPBOX_MAPS_DOWNLOAD_TOKEN')
|
||||||
if (token) {
|
if (token) {
|
||||||
authentication { basic(BasicAuthentication) }
|
authentication { basic(BasicAuthentication) }
|
||||||
@@ -41,7 +26,11 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
maven { url 'https://www.jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @generated end @rnmapbox/maps-v2-maven
|
apply plugin: "expo-root-project"
|
||||||
|
apply plugin: "com.facebook.react.rootproject"
|
||||||
|
|||||||
@@ -25,27 +25,27 @@ export default {
|
|||||||
ios: {
|
ios: {
|
||||||
supportsTablet: true,
|
supportsTablet: true,
|
||||||
bundleIdentifier: "com.anonymous.hipmi-mobile",
|
bundleIdentifier: "com.anonymous.hipmi-mobile",
|
||||||
googleServicesFile: "./ios/HIPMIBadungConnect/GoogleService-Info.plist",
|
googleServicesFile: "./secrets/GoogleService-Info.plist",
|
||||||
infoPlist: {
|
infoPlist: {
|
||||||
ITSAppUsesNonExemptEncryption: false,
|
ITSAppUsesNonExemptEncryption: false,
|
||||||
NSLocationWhenInUseUsageDescription:
|
NSLocationWhenInUseUsageDescription:
|
||||||
"Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
|
"Aplikasi membutuhkan akses lokasi untuk menampilkan peta.",
|
||||||
},
|
},
|
||||||
associatedDomains: [
|
associatedDomains: [
|
||||||
"applinks:cld-dkr-hipmi-stg.wibudev.com",
|
"applinks:hipmi.muku.id",
|
||||||
],
|
],
|
||||||
buildNumber: "7",
|
buildNumber: "7",
|
||||||
},
|
},
|
||||||
|
|
||||||
android: {
|
android: {
|
||||||
googleServicesFile: "./google-services.json",
|
googleServicesFile: "./secrets/google-services.json",
|
||||||
adaptiveIcon: {
|
adaptiveIcon: {
|
||||||
foregroundImage: "./assets/images/splash-icon.png",
|
foregroundImage: "./assets/images/splash-icon.png",
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
},
|
},
|
||||||
edgeToEdgeEnabled: true,
|
edgeToEdgeEnabled: true,
|
||||||
package: "com.bip.hipmimobileapp",
|
package: "com.bip.hipmimobileapp",
|
||||||
versionCode: 1,
|
versionCode: 5,
|
||||||
// softwareKeyboardLayoutMode: 'resize', // option: untuk mengatur keyboard pada room chst collaboration
|
// softwareKeyboardLayoutMode: 'resize', // option: untuk mengatur keyboard pada room chst collaboration
|
||||||
intentFilters: [
|
intentFilters: [
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ export default {
|
|||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
scheme: "https",
|
scheme: "https",
|
||||||
host: "cld-dkr-hipmi-stg.wibudev.com",
|
host: "hipmi.muku.id",
|
||||||
pathPrefix: "/",
|
pathPrefix: "/",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -70,6 +70,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
|
"./plugins/withCustomConfig",
|
||||||
"expo-router",
|
"expo-router",
|
||||||
"expo-web-browser",
|
"expo-web-browser",
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// OS Height
|
// OS Height
|
||||||
const OS_ANDROID_HEIGHT = 115
|
const OS_ANDROID_HEIGHT = 70
|
||||||
const OS_IOS_HEIGHT = 80
|
const OS_IOS_HEIGHT = 80
|
||||||
const OS_HEIGHT = Platform.OS === "ios" ? OS_IOS_HEIGHT : OS_ANDROID_HEIGHT
|
const OS_HEIGHT = Platform.OS === "ios" ? OS_IOS_HEIGHT : OS_ANDROID_HEIGHT
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"originHash" : "e70d3525c8e2819a8b34f22909815dab5c700c25a06c32388f3930f7b3627768",
|
|
||||||
"pins" : [
|
|
||||||
{
|
|
||||||
"identity" : "maplibre-gl-native-distribution",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/maplibre/maplibre-gl-native-distribution",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "c68c970ff3ece56cfc3b36849db70167fa208beb",
|
|
||||||
"version" : "6.17.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"version" : 3
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<string>development</string>
|
<string>development</string>
|
||||||
<key>com.apple.developer.associated-domains</key>
|
<key>com.apple.developer.associated-domains</key>
|
||||||
<array>
|
<array>
|
||||||
<string>applinks:cld-dkr-hipmi-stg.wibudev.com</string>
|
<string>applinks:hipmi.muku.id</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
39
ios/Podfile
39
ios/Podfile
@@ -1,15 +1,22 @@
|
|||||||
use_modular_headers!
|
|
||||||
|
|
||||||
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
|
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")
|
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
|
||||||
|
|
||||||
require 'json'
|
require 'json'
|
||||||
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
|
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
|
||||||
|
|
||||||
|
def ccache_enabled?(podfile_properties)
|
||||||
|
# Environment variable takes precedence
|
||||||
|
return ENV['USE_CCACHE'] == '1' if ENV['USE_CCACHE']
|
||||||
|
|
||||||
|
# Fall back to Podfile properties
|
||||||
|
podfile_properties['apple.ccacheEnabled'] == 'true'
|
||||||
|
end
|
||||||
|
|
||||||
ENV['RCT_NEW_ARCH_ENABLED'] ||= '0' if podfile_properties['newArchEnabled'] == 'false'
|
ENV['RCT_NEW_ARCH_ENABLED'] ||= '0' if podfile_properties['newArchEnabled'] == 'false'
|
||||||
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
|
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
|
||||||
ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
|
ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
|
||||||
ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
|
ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
|
||||||
|
use_modular_headers!
|
||||||
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
|
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
|
||||||
|
|
||||||
prepare_react_native_project!
|
prepare_react_native_project!
|
||||||
@@ -21,7 +28,10 @@ target 'HIPMIBadungConnect' do
|
|||||||
config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
|
config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
|
||||||
else
|
else
|
||||||
config_command = [
|
config_command = [
|
||||||
'npx',
|
'node',
|
||||||
|
'--no-warnings',
|
||||||
|
'--eval',
|
||||||
|
'require(\'expo/bin/autolinking\')',
|
||||||
'expo-modules-autolinking',
|
'expo-modules-autolinking',
|
||||||
'react-native-config',
|
'react-native-config',
|
||||||
'--json',
|
'--json',
|
||||||
@@ -35,7 +45,6 @@ target 'HIPMIBadungConnect' do
|
|||||||
use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
|
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_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 => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
|
:hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
|
||||||
@@ -44,23 +53,12 @@ target 'HIPMIBadungConnect' do
|
|||||||
:privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
|
:privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
|
||||||
)
|
)
|
||||||
|
|
||||||
pod 'Firebase'
|
|
||||||
pod 'Firebase/Messaging'
|
|
||||||
|
|
||||||
# @generated begin post_installer - expo prebuild (DO NOT MODIFY) sync-4092f82b887b5b9edb84642c2a56984d69b9a403
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
# @generated begin @maplibre/maplibre-react-native:post-install - expo prebuild (DO NOT MODIFY) sync-6e76c80af0d70c0003d06822dd59b7c729fca472
|
|
||||||
$MLRN.post_install(installer)
|
|
||||||
# @generated end @maplibre/maplibre-react-native:post-install
|
|
||||||
|
|
||||||
# Fix all script phases with incorrect paths
|
# Fix all script phases with incorrect paths
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
target.build_phases.each do |phase|
|
target.build_phases.each do |phase|
|
||||||
next unless phase.respond_to?(:shell_script)
|
next unless phase.respond_to?(:shell_script)
|
||||||
|
|
||||||
# Fix duplicated path issue
|
|
||||||
if phase.shell_script.include?('with-environment.sh')
|
if phase.shell_script.include?('with-environment.sh')
|
||||||
# Remove any existing path and use proper relative path
|
|
||||||
phase.shell_script = phase.shell_script.gsub(
|
phase.shell_script = phase.shell_script.gsub(
|
||||||
%r{(/.*?/node_modules/react-native)+/scripts/xcode/with-environment.sh},
|
%r{(/.*?/node_modules/react-native)+/scripts/xcode/with-environment.sh},
|
||||||
'${PODS_ROOT}/../../node_modules/react-native/scripts/xcode/with-environment.sh'
|
'${PODS_ROOT}/../../node_modules/react-native/scripts/xcode/with-environment.sh'
|
||||||
@@ -68,15 +66,14 @@ target 'HIPMIBadungConnect' do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
# @generated begin @maplibre/maplibre-react-native:post-install - expo prebuild (DO NOT MODIFY) sync-6e76c80af0d70c0003d06822dd59b7c729fca472
|
||||||
# Standard React Native post install
|
$MLRN.post_install(installer)
|
||||||
|
# @generated end @maplibre/maplibre-react-native:post-install
|
||||||
react_native_post_install(
|
react_native_post_install(
|
||||||
installer,
|
installer,
|
||||||
config[:reactNativePath],
|
config[:reactNativePath],
|
||||||
:mac_catalyst_enabled => false,
|
:mac_catalyst_enabled => false,
|
||||||
:ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
|
:ccache_enabled => ccache_enabled?(podfile_properties),
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
# @generated end post_installer
|
end
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -279,34 +279,11 @@ PODS:
|
|||||||
- EXUpdatesInterface (2.0.0):
|
- EXUpdatesInterface (2.0.0):
|
||||||
- ExpoModulesCore
|
- ExpoModulesCore
|
||||||
- FBLazyVector (0.81.5)
|
- FBLazyVector (0.81.5)
|
||||||
- Firebase (12.8.0):
|
|
||||||
- Firebase/Core (= 12.8.0)
|
|
||||||
- Firebase/Core (12.8.0):
|
|
||||||
- Firebase/CoreOnly
|
|
||||||
- FirebaseAnalytics (~> 12.8.0)
|
|
||||||
- Firebase/CoreOnly (12.8.0):
|
- Firebase/CoreOnly (12.8.0):
|
||||||
- FirebaseCore (~> 12.8.0)
|
- FirebaseCore (~> 12.8.0)
|
||||||
- Firebase/Messaging (12.8.0):
|
- Firebase/Messaging (12.8.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseMessaging (~> 12.8.0)
|
- FirebaseMessaging (~> 12.8.0)
|
||||||
- FirebaseAnalytics (12.8.0):
|
|
||||||
- FirebaseAnalytics/Default (= 12.8.0)
|
|
||||||
- FirebaseCore (~> 12.8.0)
|
|
||||||
- FirebaseInstallations (~> 12.8.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
|
||||||
- nanopb (~> 3.30910.0)
|
|
||||||
- FirebaseAnalytics/Default (12.8.0):
|
|
||||||
- FirebaseCore (~> 12.8.0)
|
|
||||||
- FirebaseInstallations (~> 12.8.0)
|
|
||||||
- GoogleAppMeasurement/Default (= 12.8.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
|
||||||
- nanopb (~> 3.30910.0)
|
|
||||||
- FirebaseCore (12.8.0):
|
- FirebaseCore (12.8.0):
|
||||||
- FirebaseCoreInternal (~> 12.8.0)
|
- FirebaseCoreInternal (~> 12.8.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
@@ -329,33 +306,6 @@ PODS:
|
|||||||
- GoogleUtilities/Reachability (~> 8.1)
|
- GoogleUtilities/Reachability (~> 8.1)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAdsOnDeviceConversion (3.2.0):
|
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
|
||||||
- GoogleUtilities/Logger (~> 8.1)
|
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
|
||||||
- nanopb (~> 3.30910.0)
|
|
||||||
- GoogleAppMeasurement/Core (12.8.0):
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
|
||||||
- nanopb (~> 3.30910.0)
|
|
||||||
- GoogleAppMeasurement/Default (12.8.0):
|
|
||||||
- GoogleAdsOnDeviceConversion (~> 3.2.0)
|
|
||||||
- GoogleAppMeasurement/Core (= 12.8.0)
|
|
||||||
- GoogleAppMeasurement/IdentitySupport (= 12.8.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
|
||||||
- nanopb (~> 3.30910.0)
|
|
||||||
- GoogleAppMeasurement/IdentitySupport (12.8.0):
|
|
||||||
- GoogleAppMeasurement/Core (= 12.8.0)
|
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
|
||||||
- nanopb (~> 3.30910.0)
|
|
||||||
- GoogleDataTransport (10.1.0):
|
- GoogleDataTransport (10.1.0):
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- PromisesObjC (~> 2.4)
|
- PromisesObjC (~> 2.4)
|
||||||
@@ -369,9 +319,6 @@ PODS:
|
|||||||
- GoogleUtilities/Logger (8.1.0):
|
- GoogleUtilities/Logger (8.1.0):
|
||||||
- GoogleUtilities/Environment
|
- GoogleUtilities/Environment
|
||||||
- GoogleUtilities/Privacy
|
- GoogleUtilities/Privacy
|
||||||
- GoogleUtilities/MethodSwizzler (8.1.0):
|
|
||||||
- GoogleUtilities/Logger
|
|
||||||
- GoogleUtilities/Privacy
|
|
||||||
- GoogleUtilities/Network (8.1.0):
|
- GoogleUtilities/Network (8.1.0):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- "GoogleUtilities/NSData+zlib"
|
- "GoogleUtilities/NSData+zlib"
|
||||||
@@ -2581,9 +2528,9 @@ PODS:
|
|||||||
- ReactCommon/turbomodule/core
|
- ReactCommon/turbomodule/core
|
||||||
- ReactNativeDependencies
|
- ReactNativeDependencies
|
||||||
- Yoga
|
- Yoga
|
||||||
- SDWebImage (5.21.6):
|
- SDWebImage (5.21.7):
|
||||||
- SDWebImage/Core (= 5.21.6)
|
- SDWebImage/Core (= 5.21.7)
|
||||||
- SDWebImage/Core (5.21.6)
|
- SDWebImage/Core (5.21.7)
|
||||||
- SDWebImageAVIFCoder (0.11.1):
|
- SDWebImageAVIFCoder (0.11.1):
|
||||||
- libavif/core (>= 0.11.0)
|
- libavif/core (>= 0.11.0)
|
||||||
- SDWebImage (~> 5.10)
|
- SDWebImage (~> 5.10)
|
||||||
@@ -2633,8 +2580,6 @@ DEPENDENCIES:
|
|||||||
- ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`)
|
- ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`)
|
||||||
- EXUpdatesInterface (from `../node_modules/expo-updates-interface/ios`)
|
- EXUpdatesInterface (from `../node_modules/expo-updates-interface/ios`)
|
||||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||||
- Firebase
|
|
||||||
- Firebase/Messaging
|
|
||||||
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
||||||
- "maplibre-react-native (from `../node_modules/@maplibre/maplibre-react-native`)"
|
- "maplibre-react-native (from `../node_modules/@maplibre/maplibre-react-native`)"
|
||||||
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
|
- RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
|
||||||
@@ -2722,14 +2667,11 @@ DEPENDENCIES:
|
|||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- Firebase
|
- Firebase
|
||||||
- FirebaseAnalytics
|
|
||||||
- FirebaseCore
|
- FirebaseCore
|
||||||
- FirebaseCoreExtension
|
- FirebaseCoreExtension
|
||||||
- FirebaseCoreInternal
|
- FirebaseCoreInternal
|
||||||
- FirebaseInstallations
|
- FirebaseInstallations
|
||||||
- FirebaseMessaging
|
- FirebaseMessaging
|
||||||
- GoogleAdsOnDeviceConversion
|
|
||||||
- GoogleAppMeasurement
|
|
||||||
- GoogleDataTransport
|
- GoogleDataTransport
|
||||||
- GoogleUtilities
|
- GoogleUtilities
|
||||||
- libavif
|
- libavif
|
||||||
@@ -3011,14 +2953,11 @@ SPEC CHECKSUMS:
|
|||||||
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
|
EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734
|
||||||
FBLazyVector: e95a291ad2dadb88e42b06e0c5fb8262de53ec12
|
FBLazyVector: e95a291ad2dadb88e42b06e0c5fb8262de53ec12
|
||||||
Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d
|
Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d
|
||||||
FirebaseAnalytics: f20bbad8cb7f65d8a5eaefeb424ae8800a31bdfc
|
|
||||||
FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c
|
FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c
|
||||||
FirebaseCoreExtension: 6605938d51f765d8b18bfcafd2085276a252bee2
|
FirebaseCoreExtension: 6605938d51f765d8b18bfcafd2085276a252bee2
|
||||||
FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21
|
FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21
|
||||||
FirebaseInstallations: 6a14ab3d694ebd9f839c48d330da5547e9ca9dc0
|
FirebaseInstallations: 6a14ab3d694ebd9f839c48d330da5547e9ca9dc0
|
||||||
FirebaseMessaging: 7f42cfd10ec64181db4e01b305a613791c8e782c
|
FirebaseMessaging: 7f42cfd10ec64181db4e01b305a613791c8e782c
|
||||||
GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f
|
|
||||||
GoogleAppMeasurement: 72c9a682fec6290327ea5e3c4b829b247fcb2c17
|
|
||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||||
hermes-engine: 9f4dfe93326146a1c99eb535b1cb0b857a3cd172
|
hermes-engine: 9f4dfe93326146a1c99eb535b1cb0b857a3cd172
|
||||||
@@ -3107,13 +3046,13 @@ SPEC CHECKSUMS:
|
|||||||
RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34
|
RNSVG: 31d6639663c249b7d5abc9728dde2041eb2a3c34
|
||||||
RNVectorIcons: 4351544f100d4f12cac156a7c13399e60bab3e26
|
RNVectorIcons: 4351544f100d4f12cac156a7c13399e60bab3e26
|
||||||
RNWorklets: 43cd6af94c18f89cbca10ea83fee281b69d75da5
|
RNWorklets: 43cd6af94c18f89cbca10ea83fee281b69d75da5
|
||||||
SDWebImage: 1bb6a1b84b6fe87b972a102bdc77dd589df33477
|
SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
|
||||||
SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
|
SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
|
||||||
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
|
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
|
||||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||||
Yoga: 5934998fbeaef7845dbf698f698518695ab4cd1a
|
Yoga: 5934998fbeaef7845dbf698f698518695ab4cd1a
|
||||||
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
|
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
|
||||||
|
|
||||||
PODFILE CHECKSUM: c099c57001b36661ca723fa0edfdb338496e8b9d
|
PODFILE CHECKSUM: 98fc0b2be4d9f9b5a23816e3c77ad0e74ea84fa0
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|||||||
287
plugins/withCustomConfig.js
Normal file
287
plugins/withCustomConfig.js
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
const {
|
||||||
|
withAppBuildGradle,
|
||||||
|
withProjectBuildGradle,
|
||||||
|
withInfoPlist,
|
||||||
|
} = require("@expo/config-plugins");
|
||||||
|
|
||||||
|
const { withPodfile } = require("@expo/config-plugins");
|
||||||
|
const { withAndroidManifest } = require("@expo/config-plugins");
|
||||||
|
const { withDangerousMod } = require("@expo/config-plugins");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// 1. PROJECT-LEVEL build.gradle
|
||||||
|
// Tambah: google-services classpath + Mapbox maven
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
const withCustomProjectBuildGradle = (config) => {
|
||||||
|
return withProjectBuildGradle(config, (config) => {
|
||||||
|
let contents = config.modResults.contents;
|
||||||
|
|
||||||
|
// Tambah google-services classpath jika belum ada
|
||||||
|
if (!contents.includes("com.google.gms:google-services")) {
|
||||||
|
contents = contents.replace(
|
||||||
|
/classpath\('com\.android\.tools\.build:gradle'\)/,
|
||||||
|
`classpath('com.android.tools.build:gradle')
|
||||||
|
classpath 'com.google.gms:google-services:4.4.1'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambah Mapbox maven repository jika belum ada
|
||||||
|
if (!contents.includes("api.mapbox.com")) {
|
||||||
|
contents = contents.replace(
|
||||||
|
/allprojects\s*\{[\s\S]*?repositories\s*\{/,
|
||||||
|
`allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url 'https://api.mapbox.com/downloads/v2/releases/maven'
|
||||||
|
def token = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: System.getenv('RNMAPBOX_MAPS_DOWNLOAD_TOKEN')
|
||||||
|
if (token) {
|
||||||
|
authentication { basic(BasicAuthentication) }
|
||||||
|
credentials {
|
||||||
|
username = 'mapbox'
|
||||||
|
password = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.modResults.contents = contents;
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// 2. APP-LEVEL build.gradle
|
||||||
|
// Tambah: buildConfigField + google-services plugin
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
const withCustomAppBuildGradle = (config) => {
|
||||||
|
return withAppBuildGradle(config, (config) => {
|
||||||
|
let contents = config.modResults.contents;
|
||||||
|
|
||||||
|
// Tambah Mapbox packagingOptions
|
||||||
|
if (!contents.includes("rnmapbox/maps-libcpp")) {
|
||||||
|
contents = contents.replace(
|
||||||
|
/android\s*\{/,
|
||||||
|
`android {
|
||||||
|
// @generated begin @rnmapbox/maps-libcpp - expo prebuild (DO NOT MODIFY) sync-e24830a5a3e854b398227dfe9630aabfaa1cadd1
|
||||||
|
packagingOptions {
|
||||||
|
pickFirst 'lib/x86/libc++_shared.so'
|
||||||
|
pickFirst 'lib/x86_64/libc++_shared.so'
|
||||||
|
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||||
|
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||||
|
}
|
||||||
|
// @generated end @rnmapbox/maps-libcpp`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambah buildConfigField REACT_NATIVE_RELEASE_LEVEL
|
||||||
|
if (!contents.includes("REACT_NATIVE_RELEASE_LEVEL")) {
|
||||||
|
contents = contents.replace(
|
||||||
|
/defaultConfig\s*\{/,
|
||||||
|
`defaultConfig {
|
||||||
|
buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\\"${`$`}{findProperty('reactNativeReleaseLevel') ?: 'stable'}\\""`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambah apply plugin google-services di akhir file
|
||||||
|
if (!contents.includes("com.google.gms.google-services")) {
|
||||||
|
contents += `\napply plugin: 'com.google.gms.google-services'\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.modResults.contents = contents;
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// 3. Info.plist
|
||||||
|
// Tambah: custom URL schemes + deskripsi Bahasa Indonesia
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
const withCustomInfoPlist = (config) => {
|
||||||
|
return withInfoPlist(config, (config) => {
|
||||||
|
const plist = config.modResults;
|
||||||
|
|
||||||
|
// Custom URL Schemes
|
||||||
|
// Pastikan CFBundleURLTypes sudah ada, lalu tambahkan scheme custom
|
||||||
|
if (!plist.CFBundleURLTypes) {
|
||||||
|
plist.CFBundleURLTypes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasHipmiScheme = plist.CFBundleURLTypes.some((entry) =>
|
||||||
|
entry.CFBundleURLSchemes?.includes("hipmimobile"),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!hasHipmiScheme) {
|
||||||
|
plist.CFBundleURLTypes.push({
|
||||||
|
CFBundleURLSchemes: ["hipmimobile", "com.anonymous.hipmi-mobile"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// NSLocationWhenInUseUsageDescription — Bahasa Indonesia
|
||||||
|
plist.NSLocationWhenInUseUsageDescription =
|
||||||
|
"Aplikasi membutuhkan akses lokasi untuk menampilkan peta.";
|
||||||
|
|
||||||
|
// NSPhotoLibraryUsageDescription — Bahasa Indonesia (panjang)
|
||||||
|
plist.NSPhotoLibraryUsageDescription =
|
||||||
|
"Untuk mengunggah dokumen dan media bisnis seperti foto profil, logo usaha, poster lowongan, atau bukti transaksi di berbagai fitur aplikasi: Profile, Portofolio, Job Vacancy, Investasi, dan Donasi.";
|
||||||
|
|
||||||
|
plist.NSFaceIDUsageDescription =
|
||||||
|
"Allow $(PRODUCT_NAME) to access your Face ID biometric data.";
|
||||||
|
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// 4. Android Manifest
|
||||||
|
// Tambah: backup rules untuk expo-secure-store
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
const withCustomManifest = (config) => {
|
||||||
|
return withAndroidManifest(config, (config) => {
|
||||||
|
const manifest = config.modResults.manifest;
|
||||||
|
const application = manifest.application[0];
|
||||||
|
|
||||||
|
// Tambah atribut backup untuk expo-secure-store
|
||||||
|
application.$["android:fullBackupContent"] =
|
||||||
|
"@xml/secure_store_backup_rules";
|
||||||
|
application.$["android:dataExtractionRules"] =
|
||||||
|
"@xml/secure_store_data_extraction_rules";
|
||||||
|
|
||||||
|
// Tambah tools:replace pada meta-data notification color
|
||||||
|
const metaDataList = application["meta-data"] || [];
|
||||||
|
const notifColorMeta = metaDataList.find(
|
||||||
|
(m) =>
|
||||||
|
m.$["android:name"] ===
|
||||||
|
"com.google.firebase.messaging.default_notification_color",
|
||||||
|
);
|
||||||
|
if (notifColorMeta) {
|
||||||
|
notifColorMeta.$["tools:replace"] = "android:resource";
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// 5. Podfile
|
||||||
|
// Tambah: use_modular_headers!
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
|
||||||
|
const withCustomPodfile = (config) => {
|
||||||
|
return withPodfile(config, (config) => {
|
||||||
|
let contents = config.modResults.contents;
|
||||||
|
|
||||||
|
// Tambah use_modular_headers! jika belum ada
|
||||||
|
if (!contents.includes("use_modular_headers!")) {
|
||||||
|
contents = contents.replace(
|
||||||
|
/platform :ios/,
|
||||||
|
`use_modular_headers!\nplatform :ios`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambah Firebase pods jika belum ada
|
||||||
|
if (!contents.includes("pod 'Firebase/Messaging'")) {
|
||||||
|
contents = contents.replace(
|
||||||
|
/use_react_native_pods\!/,
|
||||||
|
`pod 'Firebase'\n pod 'Firebase/Messaging'\n\n use_react_native_pods!`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambah fix script with-environment.sh jika belum ada
|
||||||
|
// Tambah fix script with-environment.sh jika belum ada
|
||||||
|
if (!contents.includes("with-environment.sh")) {
|
||||||
|
const fixScript = [
|
||||||
|
"post_install do |installer|",
|
||||||
|
" # Fix all script phases with incorrect paths",
|
||||||
|
" installer.pods_project.targets.each do |target|",
|
||||||
|
" target.build_phases.each do |phase|",
|
||||||
|
" next unless phase.respond_to?(:shell_script)",
|
||||||
|
" if phase.shell_script.include?('with-environment.sh')",
|
||||||
|
" phase.shell_script = phase.shell_script.gsub(",
|
||||||
|
" %r{(/.*?/node_modules/react-native)+/scripts/xcode/with-environment.sh},",
|
||||||
|
" '${PODS_ROOT}/../../node_modules/react-native/scripts/xcode/with-environment.sh'",
|
||||||
|
" )",
|
||||||
|
" end",
|
||||||
|
" end",
|
||||||
|
" end",
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
contents = contents.replace(/post_install do \|installer\|/, fixScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.modResults.contents = contents;
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// 6. Android XML Files
|
||||||
|
// Tambah: secure_store_backup_rules.xml dan secure_store_data_extraction_rules.xml
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
|
||||||
|
const withSecureStoreXml = (config) => {
|
||||||
|
return withDangerousMod(config, [
|
||||||
|
"android",
|
||||||
|
(config) => {
|
||||||
|
const xmlDir = path.join(
|
||||||
|
config.modRequest.platformProjectRoot,
|
||||||
|
"app/src/main/res/xml",
|
||||||
|
);
|
||||||
|
|
||||||
|
// Buat folder jika belum ada
|
||||||
|
if (!fs.existsSync(xmlDir)) {
|
||||||
|
fs.mkdirSync(xmlDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Definisikan path variabel di sini ← INI yang kurang sebelumnya
|
||||||
|
const backupRulesPath = path.join(
|
||||||
|
xmlDir,
|
||||||
|
"secure_store_backup_rules.xml",
|
||||||
|
);
|
||||||
|
const dataExtractionPath = path.join(
|
||||||
|
xmlDir,
|
||||||
|
"secure_store_data_extraction_rules.xml",
|
||||||
|
);
|
||||||
|
|
||||||
|
// secure_store_backup_rules.xml
|
||||||
|
fs.writeFileSync(
|
||||||
|
backupRulesPath,
|
||||||
|
`<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<full-backup-content>
|
||||||
|
<exclude domain="sharedpref" path="SECURESTORE"/>
|
||||||
|
</full-backup-content>`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// secure_store_data_extraction_rules.xml
|
||||||
|
fs.writeFileSync(
|
||||||
|
dataExtractionPath,
|
||||||
|
`<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<exclude domain="sharedpref" path="SECURESTORE"/>
|
||||||
|
</cloud-backup>
|
||||||
|
<device-transfer>
|
||||||
|
<exclude domain="sharedpref" path="SECURESTORE"/>
|
||||||
|
</device-transfer>
|
||||||
|
</data-extraction-rules>`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
// EXPORT
|
||||||
|
// ─────────────────────────────────────────
|
||||||
|
module.exports = (config) => {
|
||||||
|
config = withCustomProjectBuildGradle(config);
|
||||||
|
config = withCustomAppBuildGradle(config);
|
||||||
|
config = withCustomManifest(config);
|
||||||
|
config = withSecureStoreXml(config);
|
||||||
|
config = withCustomInfoPlist(config);
|
||||||
|
config = withCustomPodfile(config);
|
||||||
|
return config;
|
||||||
|
};
|
||||||
@@ -28,7 +28,7 @@ export default function Home_BottomFeatureSection({
|
|||||||
{/* Vacancy Item 1 */}
|
{/* Vacancy Item 1 */}
|
||||||
{_.isEmpty(listData) ? (
|
{_.isEmpty(listData) ? (
|
||||||
<CenterCustom style={{ paddingBlock: 50 }}>
|
<CenterCustom style={{ paddingBlock: 50 }}>
|
||||||
<TextCustom>Lowongan pekerjaan belum tersedia</TextCustom>
|
<TextCustom color="gray">Lowongan pekerjaan belum tersedia</TextCustom>
|
||||||
</CenterCustom>
|
</CenterCustom>
|
||||||
) : (
|
) : (
|
||||||
listData?.map((item: any, index: number) => (
|
listData?.map((item: any, index: number) => (
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default function Home_ImageSection() {
|
|||||||
transition={1000}
|
transition={1000}
|
||||||
style={{
|
style={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: 120,
|
height: 150,
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -115,15 +115,15 @@ export default function UserSearchMainView_V2() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 🔁 Refresh otomatis saat kembali ke halaman ini
|
// 🔁 Refresh otomatis saat kembali ke halaman ini
|
||||||
useFocusEffect(
|
// useFocusEffect(
|
||||||
useCallback(() => {
|
// useCallback(() => {
|
||||||
if (isInitialMount.current) {
|
// if (isInitialMount.current) {
|
||||||
isInitialMount.current = false;
|
// isInitialMount.current = false;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
pagination.onRefresh();
|
// pagination.onRefresh();
|
||||||
}, [pagination.onRefresh]),
|
// }, [pagination.onRefresh]),
|
||||||
);
|
// );
|
||||||
|
|
||||||
const { ListEmptyComponent, ListFooterComponent } =
|
const { ListEmptyComponent, ListFooterComponent } =
|
||||||
createPaginationComponents({
|
createPaginationComponents({
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ export const TabsStyles: BottomTabNavigationOptions = {
|
|||||||
paddingTop: 5,
|
paddingTop: 5,
|
||||||
height: OS_ANDROID_HEIGHT,
|
height: OS_ANDROID_HEIGHT,
|
||||||
},
|
},
|
||||||
default: {},
|
|
||||||
}),
|
}),
|
||||||
tabBarBackground: TabBarBackground,
|
tabBarBackground: TabBarBackground,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user