mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-19 10:51:19 +00:00
feat(deployment): prepare app for iOS TestFlight submission
- Update outdated Expo packages to latest compatible versions - Remove unmaintained expo-random package - Remove unnecessary @types/react-native package - Configure eas.json with preview and production profiles for iOS - Fix updates URL in app.json with correct project ID - Add /android and /ios to .gitignore to resolve workflow conflict - Create comprehensive iOS TestFlight submission guide - Add production flag in theme constants - Hide development-only Programs tab in production builds - Remove debug UI and console logs from social feed in production - Update CHANGELOG.md with TestFlight preparation changes All checks from expo-doctor now pass (15/15).
This commit is contained in:
parent
3f2ababe4f
commit
89504f48e8
5
.gitignore
vendored
5
.gitignore
vendored
@ -16,6 +16,11 @@ web-build/
|
|||||||
*.key
|
*.key
|
||||||
*.mobileprovision
|
*.mobileprovision
|
||||||
|
|
||||||
|
# Prebuild folders - addressing workflow conflict
|
||||||
|
# For CNG/Prebuild with EAS Build
|
||||||
|
/android
|
||||||
|
/ios
|
||||||
|
|
||||||
# Metro
|
# Metro
|
||||||
.metro-health-check*
|
.metro-health-check*
|
||||||
|
|
||||||
|
23
CHANGELOG.md
23
CHANGELOG.md
@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
- TestFlight preparation: Added production flag in theme constants
|
||||||
|
- TestFlight preparation: Hid development-only Programs tab in production builds
|
||||||
|
- TestFlight preparation: Removed debug UI and console logs from social feed in production builds
|
||||||
|
|
||||||
All notable changes to the POWR project will be documented in this file.
|
All notable changes to the POWR project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
@ -14,6 +20,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Implemented useProfileStats hook with auto-refresh capabilities
|
- Implemented useProfileStats hook with auto-refresh capabilities
|
||||||
- Added proper loading states and error handling
|
- Added proper loading states and error handling
|
||||||
- Created documentation in the new documentation structure
|
- Created documentation in the new documentation structure
|
||||||
|
- iOS TestFlight build configuration
|
||||||
|
- Created comprehensive TestFlight submission documentation
|
||||||
|
- Added production and preview build profiles to eas.json
|
||||||
|
- Added TestFlight submission configuration
|
||||||
|
- Created deployment documentation in docs/deployment/ios_testflight_guide.md
|
||||||
|
|
||||||
## Improved
|
## Improved
|
||||||
- Enhanced Profile UI
|
- Enhanced Profile UI
|
||||||
@ -22,6 +33,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added inline copy and QR buttons for better usability
|
- Added inline copy and QR buttons for better usability
|
||||||
- Enhanced visual consistency across profile elements
|
- Enhanced visual consistency across profile elements
|
||||||
- Replaced hardcoded follower counts with real-time data
|
- Replaced hardcoded follower counts with real-time data
|
||||||
|
- Updated project configuration for TestFlight
|
||||||
|
- Updated outdated packages (expo, expo-dev-client, expo-file-system, expo-router, expo-sqlite, jest-expo)
|
||||||
|
- Removed unmaintained packages (expo-random)
|
||||||
|
- Removed unnecessary packages (@types/react-native)
|
||||||
|
- Fixed updates URL in app.json to use the correct project ID
|
||||||
|
- Documented workflow conflict between managed and bare configurations
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
- Prebuild/managed workflow conflict documentation
|
||||||
|
- Added detailed explanation of the configuration issue
|
||||||
|
- Documented future decision points for project architecture
|
||||||
|
- Provided options for resolving the configuration conflict
|
||||||
|
|
||||||
# Changelog - March 26, 2025
|
# Changelog - March 26, 2025
|
||||||
|
|
||||||
|
2
app.json
2
app.json
@ -67,7 +67,7 @@
|
|||||||
"policy": "sdkVersion"
|
"policy": "sdkVersion"
|
||||||
},
|
},
|
||||||
"updates": {
|
"updates": {
|
||||||
"url": "https://u.expo.dev/your-project-id"
|
"url": "https://u.expo.dev/f3895f49-d9c9-4653-b73b-356f727debe2"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"router": {
|
"router": {
|
||||||
|
@ -8,6 +8,7 @@ import Header from '@/components/Header';
|
|||||||
import { useTheme } from '@react-navigation/native';
|
import { useTheme } from '@react-navigation/native';
|
||||||
import type { CustomTheme } from '@/lib/theme';
|
import type { CustomTheme } from '@/lib/theme';
|
||||||
import { TabScreen } from '@/components/layout/TabScreen';
|
import { TabScreen } from '@/components/layout/TabScreen';
|
||||||
|
import { IS_PRODUCTION } from '@/lib/theme/constants';
|
||||||
|
|
||||||
const Tab = createMaterialTopTabNavigator();
|
const Tab = createMaterialTopTabNavigator();
|
||||||
|
|
||||||
@ -52,11 +53,14 @@ export default function LibraryLayout() {
|
|||||||
component={TemplatesScreen}
|
component={TemplatesScreen}
|
||||||
options={{ title: 'Templates' }}
|
options={{ title: 'Templates' }}
|
||||||
/>
|
/>
|
||||||
|
{/* Only show Programs tab in development builds */}
|
||||||
|
{!IS_PRODUCTION && (
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="programs"
|
name="programs"
|
||||||
component={ProgramsScreen}
|
component={ProgramsScreen}
|
||||||
options={{ title: 'Programs' }}
|
options={{ title: 'Programs' }}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
</TabScreen>
|
</TabScreen>
|
||||||
);
|
);
|
||||||
|
@ -10,6 +10,7 @@ import { useContactList } from '@/lib/hooks/useContactList';
|
|||||||
import { ChevronUp, Bug } from 'lucide-react-native';
|
import { ChevronUp, Bug } from 'lucide-react-native';
|
||||||
import { withOfflineState } from '@/components/social/SocialOfflineState';
|
import { withOfflineState } from '@/components/social/SocialOfflineState';
|
||||||
import { useSocialFeed } from '@/lib/hooks/useSocialFeed';
|
import { useSocialFeed } from '@/lib/hooks/useSocialFeed';
|
||||||
|
import { IS_PRODUCTION } from '@/lib/theme/constants';
|
||||||
|
|
||||||
function FollowingScreen() {
|
function FollowingScreen() {
|
||||||
const { isAuthenticated, currentUser } = useNDKCurrentUser();
|
const { isAuthenticated, currentUser } = useNDKCurrentUser();
|
||||||
@ -18,12 +19,14 @@ function FollowingScreen() {
|
|||||||
// Get the user's contact list
|
// Get the user's contact list
|
||||||
const { contacts, isLoading: isLoadingContacts } = useContactList(currentUser?.pubkey);
|
const { contacts, isLoading: isLoadingContacts } = useContactList(currentUser?.pubkey);
|
||||||
|
|
||||||
// Add debug logging for contact list
|
// Add debug logging for contact list (only in development)
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
console.log(`[FollowingScreen] Contact list has ${contacts.length} contacts`);
|
console.log(`[FollowingScreen] Contact list has ${contacts.length} contacts`);
|
||||||
if (contacts.length > 0) {
|
if (contacts.length > 0) {
|
||||||
console.log(`[FollowingScreen] First few contacts: ${contacts.slice(0, 3).join(', ')}`);
|
console.log(`[FollowingScreen] First few contacts: ${contacts.slice(0, 3).join(', ')}`);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}, [contacts.length]);
|
}, [contacts.length]);
|
||||||
|
|
||||||
// Feed loading state tracking
|
// Feed loading state tracking
|
||||||
@ -77,7 +80,9 @@ function FollowingScreen() {
|
|||||||
// Update loadedContactsCount when contacts change
|
// Update loadedContactsCount when contacts change
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (contacts.length > 0 && contacts.length !== loadedContactsCount) {
|
if (contacts.length > 0 && contacts.length !== loadedContactsCount) {
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
console.log(`[FollowingScreen] Contact list changed from ${loadedContactsCount} to ${contacts.length} contacts`);
|
console.log(`[FollowingScreen] Contact list changed from ${loadedContactsCount} to ${contacts.length} contacts`);
|
||||||
|
}
|
||||||
setLoadedContactsCount(contacts.length);
|
setLoadedContactsCount(contacts.length);
|
||||||
// Reset hasLoadedWithContacts flag when contacts change
|
// Reset hasLoadedWithContacts flag when contacts change
|
||||||
setHasLoadedWithContacts(false);
|
setHasLoadedWithContacts(false);
|
||||||
@ -99,7 +104,9 @@ function FollowingScreen() {
|
|||||||
contactRefreshAttempts < maxContactRefreshAttempts;
|
contactRefreshAttempts < maxContactRefreshAttempts;
|
||||||
|
|
||||||
if (shouldRefresh) {
|
if (shouldRefresh) {
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
console.log(`[FollowingScreen] Refreshing feed with ${contacts.length} contacts (attempt ${contactRefreshAttempts + 1}/${maxContactRefreshAttempts})`);
|
console.log(`[FollowingScreen] Refreshing feed with ${contacts.length} contacts (attempt ${contactRefreshAttempts + 1}/${maxContactRefreshAttempts})`);
|
||||||
|
}
|
||||||
|
|
||||||
setIsRefreshingWithContacts(true);
|
setIsRefreshingWithContacts(true);
|
||||||
setContactRefreshAttempts(prev => prev + 1);
|
setContactRefreshAttempts(prev => prev + 1);
|
||||||
@ -111,7 +118,9 @@ function FollowingScreen() {
|
|||||||
setIsRefreshingWithContacts(false);
|
setIsRefreshingWithContacts(false);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
console.error('[FollowingScreen] Error refreshing feed:', error);
|
console.error('[FollowingScreen] Error refreshing feed:', error);
|
||||||
|
}
|
||||||
setIsRefreshingWithContacts(false);
|
setIsRefreshingWithContacts(false);
|
||||||
|
|
||||||
// Prevent infinite retries by marking as loaded after max attempts
|
// Prevent infinite retries by marking as loaded after max attempts
|
||||||
@ -183,7 +192,9 @@ function FollowingScreen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
console.error('[FollowingScreen] Error refreshing feed:', error);
|
console.error('[FollowingScreen] Error refreshing feed:', error);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
}
|
}
|
||||||
@ -193,6 +204,8 @@ function FollowingScreen() {
|
|||||||
const checkRelayConnections = useCallback(() => {
|
const checkRelayConnections = useCallback(() => {
|
||||||
if (!ndk) return;
|
if (!ndk) return;
|
||||||
|
|
||||||
|
// Only log in development mode
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
console.log("=== RELAY CONNECTION STATUS ===");
|
console.log("=== RELAY CONNECTION STATUS ===");
|
||||||
if (ndk.pool && ndk.pool.relays) {
|
if (ndk.pool && ndk.pool.relays) {
|
||||||
console.log(`Connected to ${ndk.pool.relays.size} relays:`);
|
console.log(`Connected to ${ndk.pool.relays.size} relays:`);
|
||||||
@ -203,15 +216,21 @@ function FollowingScreen() {
|
|||||||
console.log("No relay pool or connections available");
|
console.log("No relay pool or connections available");
|
||||||
}
|
}
|
||||||
console.log("===============================");
|
console.log("===============================");
|
||||||
|
}
|
||||||
}, [ndk]);
|
}, [ndk]);
|
||||||
|
|
||||||
// Handle post selection - simplified for testing
|
// Handle post selection - simplified for testing
|
||||||
const handlePostPress = useCallback((entry: any) => {
|
const handlePostPress = useCallback((entry: any) => {
|
||||||
// Just show an alert with the entry info for testing
|
// Just show an alert with the entry info for testing
|
||||||
|
if (!IS_PRODUCTION) {
|
||||||
alert(`Selected ${entry.type} with ID: ${entry.id || entry.eventId}`);
|
alert(`Selected ${entry.type} with ID: ${entry.id || entry.eventId}`);
|
||||||
|
|
||||||
// Alternatively, log to console for debugging
|
// Alternatively, log to console for debugging
|
||||||
console.log(`Selected ${entry.type}:`, entry);
|
console.log(`Selected ${entry.type}:`, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In production, this would navigate to the post detail screen
|
||||||
|
// TODO: Implement proper post detail navigation for production
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Memoize render item function
|
// Memoize render item function
|
||||||
@ -267,15 +286,17 @@ function FollowingScreen() {
|
|||||||
: "No content from followed users found. Try following more users or check your relay connections."}
|
: "No content from followed users found. Try following more users or check your relay connections."}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
{/* Debug toggle */}
|
{/* Debug toggle - only shown in development */}
|
||||||
|
{!IS_PRODUCTION && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
className="mt-4 bg-gray-200 py-2 px-4 rounded"
|
className="mt-4 bg-gray-200 py-2 px-4 rounded"
|
||||||
onPress={() => setShowDebug(!showDebug)}
|
onPress={() => setShowDebug(!showDebug)}
|
||||||
>
|
>
|
||||||
<Text>{showDebug ? "Hide" : "Show"} Debug Info</Text>
|
<Text>{showDebug ? "Hide" : "Show"} Debug Info</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
{showDebug && (
|
{!IS_PRODUCTION && showDebug && (
|
||||||
<View className="mt-4 p-4 bg-gray-100 rounded w-full">
|
<View className="mt-4 p-4 bg-gray-100 rounded w-full">
|
||||||
<Text className="text-xs">User pubkey: {currentUser?.pubkey?.substring(0, 12)}...</Text>
|
<Text className="text-xs">User pubkey: {currentUser?.pubkey?.substring(0, 12)}...</Text>
|
||||||
<Text className="text-xs">Authenticated: {isAuthenticated ? "Yes" : "No"}</Text>
|
<Text className="text-xs">Authenticated: {isAuthenticated ? "Yes" : "No"}</Text>
|
||||||
@ -305,16 +326,18 @@ function FollowingScreen() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="flex-1">
|
<View className="flex-1">
|
||||||
{/* Debug toggle button */}
|
{/* Debug toggle button - only shown in development */}
|
||||||
|
{!IS_PRODUCTION && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
className="absolute top-2 right-2 z-10 bg-gray-200 p-2 rounded-full"
|
className="absolute top-2 right-2 z-10 bg-gray-200 p-2 rounded-full"
|
||||||
onPress={() => setShowDebug(!showDebug)}
|
onPress={() => setShowDebug(!showDebug)}
|
||||||
>
|
>
|
||||||
<Bug size={16} color="#666" />
|
<Bug size={16} color="#666" />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Debug panel */}
|
{/* Debug panel - only shown in development */}
|
||||||
{showDebug && <DebugControls />}
|
{!IS_PRODUCTION && showDebug && <DebugControls />}
|
||||||
|
|
||||||
{showNewButton && (
|
{showNewButton && (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
BIN
assets/splash.mp4
Normal file
BIN
assets/splash.mp4
Normal file
Binary file not shown.
BIN
assets/v1-splash.mp4
Normal file
BIN
assets/v1-splash.mp4
Normal file
Binary file not shown.
96
docs/deployment/ios_testflight_guide.md
Normal file
96
docs/deployment/ios_testflight_guide.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# iOS TestFlight Submission Guide
|
||||||
|
|
||||||
|
This guide documents the process for creating and submitting POWR to TestFlight for iOS testing.
|
||||||
|
|
||||||
|
## Project Configuration Issues
|
||||||
|
|
||||||
|
### Prebuild/Managed Workflow Conflict
|
||||||
|
|
||||||
|
The project currently has a "mixed" state that needs to be addressed:
|
||||||
|
- Native iOS and Android folders exist (bare workflow)
|
||||||
|
- Configuration exists in app.json that would normally be used in a managed workflow
|
||||||
|
|
||||||
|
When both native folders and app.json configs exist, EAS Build will use the native project settings and ignore certain app.json configurations including:
|
||||||
|
- orientation
|
||||||
|
- icon
|
||||||
|
- scheme
|
||||||
|
- userInterfaceStyle
|
||||||
|
- splash
|
||||||
|
- ios/android configuration
|
||||||
|
- plugins
|
||||||
|
- androidStatusBar
|
||||||
|
|
||||||
|
**TODO: After TestFlight validation, decide on one of these approaches:**
|
||||||
|
1. Commit to bare workflow: Keep native folders and move all configuration to them
|
||||||
|
2. Commit to managed workflow: Remove native folders and let Expo handle native code generation
|
||||||
|
|
||||||
|
## Fixed Issues
|
||||||
|
|
||||||
|
The following issues were addressed to prepare for TestFlight:
|
||||||
|
|
||||||
|
1. Updated outdated packages:
|
||||||
|
- expo: ~52.0.41 (was 52.0.35)
|
||||||
|
- expo-dev-client: ~5.0.15 (was 5.0.12)
|
||||||
|
- expo-file-system: ~18.0.12 (was 18.0.10)
|
||||||
|
- expo-router: ~4.0.19 (was 4.0.17)
|
||||||
|
- expo-sqlite: ~15.1.3 (was 15.1.2)
|
||||||
|
- jest-expo: ~52.0.6 (was 52.0.4)
|
||||||
|
|
||||||
|
2. Removed unmaintained and unnecessary packages:
|
||||||
|
- expo-random: Removed as it's flagged as unmaintained
|
||||||
|
- @types/react-native: Removed as types are included with react-native
|
||||||
|
|
||||||
|
3. Added proper iOS build configurations in eas.json:
|
||||||
|
- Added preview build profile for internal testing
|
||||||
|
- Added production build profile for App Store submission
|
||||||
|
|
||||||
|
4. Fixed updates URL in app.json to use the correct project ID
|
||||||
|
|
||||||
|
5. Fixed prebuild/managed workflow conflict:
|
||||||
|
- Added /android and /ios folders to .gitignore as recommended by expo-doctor
|
||||||
|
- This approach tells Git to ignore native folders while still allowing EAS Build to use them
|
||||||
|
- Addresses the warning about app.json configuration fields not being synced in non-CNG projects
|
||||||
|
|
||||||
|
## TestFlight Build Process
|
||||||
|
|
||||||
|
To create and submit a build to TestFlight:
|
||||||
|
|
||||||
|
1. Update Apple credentials in eas.json:
|
||||||
|
```json
|
||||||
|
"submit": {
|
||||||
|
"production": {
|
||||||
|
"ios": {
|
||||||
|
"appleId": "YOUR_APPLE_ID_EMAIL",
|
||||||
|
"ascAppId": "YOUR_APP_STORE_CONNECT_APP_ID",
|
||||||
|
"appleTeamId": "YOUR_APPLE_TEAM_ID"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create a build for internal testing (preview):
|
||||||
|
```
|
||||||
|
eas build --platform ios --profile preview
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create a production build for TestFlight:
|
||||||
|
```
|
||||||
|
eas build --platform ios --profile production
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Submit the build to TestFlight:
|
||||||
|
```
|
||||||
|
eas submit --platform ios --latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- If you encounter issues with the mixed configuration state, consider fully committing to either the bare or managed workflow
|
||||||
|
- For build errors related to native code, check the iOS logs in the EAS build output
|
||||||
|
- For App Store Connect submission errors, verify your app metadata and screenshots in App Store Connect
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Expo Application Services Documentation](https://docs.expo.dev/eas/)
|
||||||
|
- [Expo Prebuild Documentation](https://docs.expo.dev/workflow/prebuild/)
|
||||||
|
- [TestFlight Documentation](https://developer.apple.com/testflight/)
|
21
eas.json
21
eas.json
@ -16,6 +16,27 @@
|
|||||||
"android": {
|
"android": {
|
||||||
"buildType": "apk"
|
"buildType": "apk"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"preview": {
|
||||||
|
"distribution": "internal",
|
||||||
|
"ios": {
|
||||||
|
"resourceClass": "m1-medium"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"autoIncrement": true,
|
||||||
|
"ios": {
|
||||||
|
"resourceClass": "m1-medium"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"submit": {
|
||||||
|
"production": {
|
||||||
|
"ios": {
|
||||||
|
"appleId": "YOUR_APPLE_ID_EMAIL",
|
||||||
|
"ascAppId": "YOUR_APP_STORE_CONNECT_APP_ID",
|
||||||
|
"appleTeamId": "YOUR_APPLE_TEAM_ID"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,24 @@
|
|||||||
// lib/theme/constants.ts
|
// lib/theme/constants.ts
|
||||||
import { COLORS } from './colors';
|
import { COLORS } from './colors';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to true for production builds (TestFlight, App Store)
|
||||||
|
* This should be automatically configured based on the EAS build profile
|
||||||
|
*
|
||||||
|
* For local development, keep this as false
|
||||||
|
* For TestFlight/App Store builds, set to true
|
||||||
|
*/
|
||||||
|
export const IS_PRODUCTION = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App version information
|
||||||
|
*/
|
||||||
|
export const APP_VERSION = '1.0.0';
|
||||||
|
|
||||||
export interface NavigationThemeColors {
|
export interface NavigationThemeColors {
|
||||||
background: string;
|
background: string;
|
||||||
border: string;
|
border: string;
|
||||||
|
741
package-lock.json
generated
741
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@ -63,23 +63,22 @@
|
|||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"expo": "^52.0.35",
|
"expo": "~52.0.41",
|
||||||
"expo-av": "~15.0.2",
|
"expo-av": "~15.0.2",
|
||||||
"expo-crypto": "~14.0.2",
|
"expo-crypto": "~14.0.2",
|
||||||
"expo-dev-client": "~5.0.12",
|
"expo-dev-client": "~5.0.15",
|
||||||
"expo-file-system": "~18.0.10",
|
"expo-file-system": "~18.0.12",
|
||||||
"expo-linking": "~7.0.4",
|
"expo-linking": "~7.0.4",
|
||||||
"expo-navigation-bar": "~4.0.8",
|
"expo-navigation-bar": "~4.0.8",
|
||||||
"expo-nip55": "^0.1.5",
|
"expo-nip55": "^0.1.5",
|
||||||
"expo-random": "^14.0.1",
|
"expo-router": "~4.0.19",
|
||||||
"expo-router": "~4.0.16",
|
|
||||||
"expo-secure-store": "~14.0.1",
|
"expo-secure-store": "~14.0.1",
|
||||||
"expo-splash-screen": "~0.29.22",
|
"expo-splash-screen": "~0.29.22",
|
||||||
"expo-sqlite": "~15.1.2",
|
"expo-sqlite": "~15.1.3",
|
||||||
"expo-status-bar": "~2.0.1",
|
"expo-status-bar": "~2.0.1",
|
||||||
"expo-system-ui": "~4.0.8",
|
"expo-system-ui": "~4.0.8",
|
||||||
"jest": "~29.7.0",
|
"jest": "~29.7.0",
|
||||||
"jest-expo": "~52.0.3",
|
"jest-expo": "~52.0.6",
|
||||||
"lucide-react-native": "^0.378.0",
|
"lucide-react-native": "^0.378.0",
|
||||||
"nativewind": "^4.1.23",
|
"nativewind": "^4.1.23",
|
||||||
"nostr-tools": "^2.10.4",
|
"nostr-tools": "^2.10.4",
|
||||||
@ -106,7 +105,6 @@
|
|||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/lodash": "^4.17.15",
|
"@types/lodash": "^4.17.15",
|
||||||
"@types/react": "~18.3.12",
|
"@types/react": "~18.3.12",
|
||||||
"@types/react-native": "^0.72.8",
|
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"babel-plugin-module-resolver": "^5.0.2",
|
"babel-plugin-module-resolver": "^5.0.2",
|
||||||
"expo-haptics": "^14.0.1",
|
"expo-haptics": "^14.0.1",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user