Add contractor sharing feature and move settings to navigation bar
Contractor Sharing: - Add .casera file format for sharing contractors between users - Create SharedContractor model with JSON serialization - Implement ContractorSharingManager for iOS (Swift) and Android (Kotlin) - Register .casera file type in iOS Info.plist and Android manifest - Add share button to ContractorDetailView (iOS) and ContractorDetailScreen (Android) - Add import confirmation, success, and error dialogs - Create expect/actual platform implementations for sharing and import handling Navigation Changes: - Remove Profile tab from bottom tab bar (iOS and Android) - Add settings gear icon to left side of "My Properties" title - Settings gear opens Profile/Settings screen as sheet (iOS) or navigates (Android) - Add property button to top right action bar Bug Fixes: - Fix ResidenceUsersResponse to match API's flat array response format - Fix GenerateShareCodeResponse handling to access nested shareCode property - Update ManageUsersDialog to accept residenceOwnerId parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -31,11 +31,14 @@ import com.example.casera.storage.ThemeStorageManager
|
||||
import com.example.casera.ui.theme.ThemeManager
|
||||
import com.example.casera.fcm.FCMManager
|
||||
import com.example.casera.platform.BillingManager
|
||||
import com.example.casera.network.APILayer
|
||||
import com.example.casera.sharing.ContractorSharingManager
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
|
||||
private var deepLinkResetToken by mutableStateOf<String?>(null)
|
||||
private var navigateToTaskId by mutableStateOf<Int?>(null)
|
||||
private var pendingContractorImportUri by mutableStateOf<Uri?>(null)
|
||||
private lateinit var billingManager: BillingManager
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -55,9 +58,10 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
|
||||
// Initialize BillingManager for subscription management
|
||||
billingManager = BillingManager.getInstance(applicationContext)
|
||||
|
||||
// Handle deep link and notification navigation from intent
|
||||
// Handle deep link, notification navigation, and file import from intent
|
||||
handleDeepLink(intent)
|
||||
handleNotificationNavigation(intent)
|
||||
handleFileImport(intent)
|
||||
|
||||
// Request notification permission and setup FCM
|
||||
setupFCM()
|
||||
@@ -74,6 +78,10 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
|
||||
navigateToTaskId = navigateToTaskId,
|
||||
onClearNavigateToTask = {
|
||||
navigateToTaskId = null
|
||||
},
|
||||
pendingContractorImportUri = pendingContractorImportUri,
|
||||
onClearContractorImport = {
|
||||
pendingContractorImportUri = null
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -183,10 +191,21 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// Check if lookups have changed on server (efficient ETag-based check)
|
||||
// This ensures app has fresh data when coming back from background
|
||||
lifecycleScope.launch {
|
||||
Log.d("MainActivity", "🔄 App resumed, checking for lookup updates...")
|
||||
APILayer.refreshLookupsIfChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
handleDeepLink(intent)
|
||||
handleNotificationNavigation(intent)
|
||||
handleFileImport(intent)
|
||||
}
|
||||
|
||||
private fun handleNotificationNavigation(intent: Intent?) {
|
||||
@@ -209,6 +228,16 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleFileImport(intent: Intent?) {
|
||||
if (intent?.action == Intent.ACTION_VIEW) {
|
||||
val uri = intent.data
|
||||
if (uri != null && ContractorSharingManager.isCaseraFile(applicationContext, uri)) {
|
||||
Log.d("MainActivity", "Contractor file received: $uri")
|
||||
pendingContractorImportUri = uri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun newImageLoader(context: PlatformContext): ImageLoader {
|
||||
return ImageLoader.Builder(context)
|
||||
.components {
|
||||
|
||||
Reference in New Issue
Block a user