Rebrand from Casera/MyCrib to honeyDue

Total rebrand across KMM project:
- Kotlin package: com.example.casera -> com.tt.honeyDue (dirs + declarations)
- Gradle: rootProject.name, namespace, applicationId
- Android: manifest, strings.xml (all languages), widget resources
- iOS: pbxproj bundle IDs, Info.plist, entitlements, xcconfig
- iOS directories: Casera/ -> HoneyDue/, CaseraTests/ -> HoneyDueTests/, etc.
- Swift source: all class/struct/enum renames
- Deep links: casera:// -> honeydue://, .casera -> .honeydue
- App icons replaced with honeyDue honeycomb icon
- Domains: casera.treytartt.com -> honeyDue.treytartt.com
- Bundle IDs: com.tt.casera -> com.tt.honeyDue
- Database table names preserved

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-07 06:33:57 -06:00
parent 9c574c4343
commit 1e2adf7660
450 changed files with 1730 additions and 1788 deletions

View File

@@ -36,11 +36,11 @@
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="casera"
android:scheme="honeydue"
android:host="reset-password" />
</intent-filter>
<!-- .casera file import -->
<!-- .honeydue file import -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -50,10 +50,10 @@
<data android:scheme="file" />
<data android:host="*" />
<data android:mimeType="*/*" />
<data android:pathPattern=".*\\.casera" />
<data android:pathPattern=".*\\.honeydue" />
</intent-filter>
<!-- .casera file import via content:// -->
<!-- .honeydue file import via content:// -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -93,11 +93,11 @@
android:name=".NotificationActionReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.example.casera.ACTION_VIEW_TASK" />
<action android:name="com.example.casera.ACTION_COMPLETE_TASK" />
<action android:name="com.example.casera.ACTION_MARK_IN_PROGRESS" />
<action android:name="com.example.casera.ACTION_CANCEL_TASK" />
<action android:name="com.example.casera.ACTION_UNCANCEL_TASK" />
<action android:name="com.tt.honeyDue.ACTION_VIEW_TASK" />
<action android:name="com.tt.honeyDue.ACTION_COMPLETE_TASK" />
<action android:name="com.tt.honeyDue.ACTION_MARK_IN_PROGRESS" />
<action android:name="com.tt.honeyDue.ACTION_CANCEL_TASK" />
<action android:name="com.tt.honeyDue.ACTION_UNCANCEL_TASK" />
</intent-filter>
</receiver>
@@ -106,13 +106,13 @@
android:name=".widget.WidgetTaskActionReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.example.casera.COMPLETE_TASK" />
<action android:name="com.tt.honeyDue.COMPLETE_TASK" />
</intent-filter>
</receiver>
<!-- Small Widget Receiver (2x1) -->
<receiver
android:name=".widget.CaseraSmallWidgetReceiver"
android:name=".widget.HoneyDueSmallWidgetReceiver"
android:exported="true"
android:label="@string/widget_small_name">
<intent-filter>
@@ -120,12 +120,12 @@
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/casera_small_widget_info" />
android:resource="@xml/honeydue_small_widget_info" />
</receiver>
<!-- Medium Widget Receiver (4x2) -->
<receiver
android:name=".widget.CaseraMediumWidgetReceiver"
android:name=".widget.HoneyDueMediumWidgetReceiver"
android:exported="true"
android:label="@string/widget_medium_name">
<intent-filter>
@@ -133,12 +133,12 @@
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/casera_medium_widget_info" />
android:resource="@xml/honeydue_medium_widget_info" />
</receiver>
<!-- Large Widget Receiver (4x4) -->
<receiver
android:name=".widget.CaseraLargeWidgetReceiver"
android:name=".widget.HoneyDueLargeWidgetReceiver"
android:exported="true"
android:label="@string/widget_large_name">
<intent-filter>
@@ -146,7 +146,7 @@
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/casera_large_widget_info" />
android:resource="@xml/honeydue_large_widget_info" />
</receiver>
</application>

View File

@@ -1,4 +1,4 @@
package com.example.casera.ui.components
package com.tt.honeyDue.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
@@ -10,8 +10,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.example.casera.models.TaskSummary
import com.example.casera.models.TaskColumnCategory
import com.tt.honeyDue.models.TaskSummary
import com.tt.honeyDue.models.TaskColumnCategory
/**
* Displays a task summary with dynamic categories from the backend.

View File

@@ -1,4 +1,4 @@
package com.example.casera
package com.tt.honeyDue
import android.content.Intent
import android.net.Uri
@@ -22,22 +22,22 @@ import coil3.memory.MemoryCache
import coil3.request.crossfade
import coil3.util.DebugLogger
import okio.FileSystem
import com.example.casera.storage.TokenManager
import com.example.casera.storage.TokenStorage
import com.example.casera.storage.TaskCacheManager
import com.example.casera.storage.TaskCacheStorage
import com.example.casera.storage.ThemeStorage
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 com.example.casera.data.DataManager
import com.example.casera.data.PersistenceManager
import com.example.casera.models.CaseraPackageType
import com.example.casera.models.detectCaseraPackageType
import com.example.casera.analytics.PostHogAnalytics
import com.tt.honeyDue.storage.TokenManager
import com.tt.honeyDue.storage.TokenStorage
import com.tt.honeyDue.storage.TaskCacheManager
import com.tt.honeyDue.storage.TaskCacheStorage
import com.tt.honeyDue.storage.ThemeStorage
import com.tt.honeyDue.storage.ThemeStorageManager
import com.tt.honeyDue.ui.theme.ThemeManager
import com.tt.honeyDue.fcm.FCMManager
import com.tt.honeyDue.platform.BillingManager
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.sharing.ContractorSharingManager
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.data.PersistenceManager
import com.tt.honeyDue.models.honeyDuePackageType
import com.tt.honeyDue.models.detecthoneyDuePackageType
import com.tt.honeyDue.analytics.PostHogAnalytics
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
@@ -158,12 +158,12 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
try {
val authToken = TokenStorage.getToken()
if (authToken != null) {
val notificationApi = com.example.casera.network.NotificationApi()
val notificationApi = com.tt.honeyDue.network.NotificationApi()
val deviceId = android.provider.Settings.Secure.getString(
contentResolver,
android.provider.Settings.Secure.ANDROID_ID
)
val request = com.example.casera.models.DeviceRegistrationRequest(
val request = com.tt.honeyDue.models.DeviceRegistrationRequest(
deviceId = deviceId,
registrationId = fcmToken,
platform = "android",
@@ -171,14 +171,14 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
)
when (val result = notificationApi.registerDevice(authToken, request)) {
is com.example.casera.network.ApiResult.Success -> {
is com.tt.honeyDue.network.ApiResult.Success -> {
Log.d("MainActivity", "Device registered successfully: ${result.data}")
}
is com.example.casera.network.ApiResult.Error -> {
is com.tt.honeyDue.network.ApiResult.Error -> {
Log.e("MainActivity", "Failed to register device: ${result.message}")
}
is com.example.casera.network.ApiResult.Loading,
is com.example.casera.network.ApiResult.Idle -> {
is com.tt.honeyDue.network.ApiResult.Loading,
is com.tt.honeyDue.network.ApiResult.Idle -> {
// These states shouldn't occur for direct API calls
}
}
@@ -248,7 +248,7 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
private fun handleDeepLink(intent: Intent?) {
val data: Uri? = intent?.data
val isResetLink = data != null &&
data.scheme == "casera" &&
data.scheme == "honeydue" &&
data.host == "reset-password"
if (isResetLink) {
// Extract token from query parameter
@@ -263,8 +263,8 @@ 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", "Casera file received: $uri")
if (uri != null && ContractorSharingManager.ishoneyDueFile(applicationContext, uri)) {
Log.d("MainActivity", "honeyDue file received: $uri")
// Read file content to detect package type
try {
@@ -273,11 +273,11 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
val jsonString = inputStream.bufferedReader().use { it.readText() }
inputStream.close()
val packageType = detectCaseraPackageType(jsonString)
val packageType = detecthoneyDuePackageType(jsonString)
Log.d("MainActivity", "Detected package type: $packageType")
when (packageType) {
CaseraPackageType.RESIDENCE -> {
honeyDuePackageType.RESIDENCE -> {
Log.d("MainActivity", "Routing to residence import")
pendingResidenceImportUri = uri
}

View File

@@ -1,4 +1,4 @@
package com.example.casera
package com.tt.honeyDue
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -8,7 +8,7 @@ import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import com.example.casera.data.DataManager
import com.tt.honeyDue.data.DataManager
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import kotlinx.coroutines.CoroutineScope
@@ -31,14 +31,14 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
// Note: In a real app, you might want to use WorkManager for reliable delivery
CoroutineScope(Dispatchers.IO).launch {
try {
val authToken = com.example.casera.storage.TokenStorage.getToken()
val authToken = com.tt.honeyDue.storage.TokenStorage.getToken()
if (authToken != null) {
val notificationApi = com.example.casera.network.NotificationApi()
val notificationApi = com.tt.honeyDue.network.NotificationApi()
val deviceId = android.provider.Settings.Secure.getString(
applicationContext.contentResolver,
android.provider.Settings.Secure.ANDROID_ID
)
val request = com.example.casera.models.DeviceRegistrationRequest(
val request = com.tt.honeyDue.models.DeviceRegistrationRequest(
deviceId = deviceId,
registrationId = token,
platform = "android",
@@ -46,14 +46,14 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
)
when (val result = notificationApi.registerDevice(authToken, request)) {
is com.example.casera.network.ApiResult.Success -> {
is com.tt.honeyDue.network.ApiResult.Success -> {
Log.d(TAG, "Device registered successfully with new token")
}
is com.example.casera.network.ApiResult.Error -> {
is com.tt.honeyDue.network.ApiResult.Error -> {
Log.e(TAG, "Failed to register device with new token: ${result.message}")
}
is com.example.casera.network.ApiResult.Loading,
is com.example.casera.network.ApiResult.Idle -> {
is com.tt.honeyDue.network.ApiResult.Loading,
is com.tt.honeyDue.network.ApiResult.Idle -> {
// These states shouldn't occur for direct API calls
}
}
@@ -73,7 +73,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
message.notification?.let { notification ->
Log.d(TAG, "Notification: ${notification.title} - ${notification.body}")
sendNotification(
notification.title ?: "MyCrib",
notification.title ?: "honeyDue",
notification.body ?: "",
message.data
)
@@ -85,7 +85,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
// If there's no notification payload, create one from data
if (message.notification == null) {
val title = message.data["title"] ?: "MyCrib"
val title = message.data["title"] ?: "honeyDue"
val body = message.data["body"] ?: ""
sendNotification(title, body, message.data)
}
@@ -143,7 +143,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Casera Notifications",
"honeyDue Notifications",
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "Notifications for tasks, residences, and warranties"
@@ -210,7 +210,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
companion object {
private const val TAG = "FCMService"
private const val NOTIFICATION_ID = 0
private const val PREFS_NAME = "mycrib_prefs"
private const val PREFS_NAME = "honeydue_prefs"
private const val KEY_FCM_TOKEN = "fcm_token"
fun getStoredToken(context: Context): String? {

View File

@@ -1,15 +1,15 @@
package com.example.casera
package com.tt.honeyDue
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.core.app.NotificationManagerCompat
import com.example.casera.data.DataManager
import com.example.casera.models.TaskCompletionCreateRequest
import com.example.casera.network.APILayer
import com.example.casera.network.ApiResult
import com.example.casera.storage.TokenStorage
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.models.TaskCompletionCreateRequest
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.storage.TokenStorage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -157,11 +157,11 @@ class NotificationActionReceiver : BroadcastReceiver() {
private const val TAG = "NotificationAction"
// Action constants
const val ACTION_VIEW_TASK = "com.example.casera.ACTION_VIEW_TASK"
const val ACTION_COMPLETE_TASK = "com.example.casera.ACTION_COMPLETE_TASK"
const val ACTION_MARK_IN_PROGRESS = "com.example.casera.ACTION_MARK_IN_PROGRESS"
const val ACTION_CANCEL_TASK = "com.example.casera.ACTION_CANCEL_TASK"
const val ACTION_UNCANCEL_TASK = "com.example.casera.ACTION_UNCANCEL_TASK"
const val ACTION_VIEW_TASK = "com.tt.honeyDue.ACTION_VIEW_TASK"
const val ACTION_COMPLETE_TASK = "com.tt.honeyDue.ACTION_COMPLETE_TASK"
const val ACTION_MARK_IN_PROGRESS = "com.tt.honeyDue.ACTION_MARK_IN_PROGRESS"
const val ACTION_CANCEL_TASK = "com.tt.honeyDue.ACTION_CANCEL_TASK"
const val ACTION_UNCANCEL_TASK = "com.tt.honeyDue.ACTION_UNCANCEL_TASK"
// Extra constants
const val EXTRA_TASK_ID = "task_id"

View File

@@ -1,4 +1,4 @@
package com.example.casera
package com.tt.honeyDue
import android.os.Build

View File

@@ -1,4 +1,4 @@
package com.example.casera.analytics
package com.tt.honeyDue.analytics
import android.app.Application
import com.posthog.PostHog

View File

@@ -1,4 +1,4 @@
package com.example.casera.auth
package com.tt.honeyDue.auth
import android.content.Context
import androidx.credentials.CredentialManager
@@ -6,7 +6,7 @@ import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.credentials.GetCredentialResponse
import androidx.credentials.exceptions.GetCredentialException
import com.example.casera.network.ApiConfig
import com.tt.honeyDue.network.ApiConfig
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential

View File

@@ -1,4 +1,4 @@
package com.example.casera.data
package com.tt.honeyDue.data
import android.content.Context
import android.content.SharedPreferences
@@ -29,7 +29,7 @@ actual class PersistenceManager(context: Context) {
}
companion object {
private const val PREFS_NAME = "casera_data_manager"
private const val PREFS_NAME = "honeydue_data_manager"
@Volatile
private var instance: PersistenceManager? = null

View File

@@ -1,4 +1,4 @@
package com.example.casera.fcm
package com.tt.honeyDue.fcm
import android.Manifest
import android.app.Activity

View File

@@ -1,4 +1,4 @@
package com.example.casera.network
package com.tt.honeyDue.network
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
@@ -34,7 +34,7 @@ actual fun createHttpClient(): HttpClient {
logger = Logger.DEFAULT
// Only log full request/response bodies in debug builds to avoid
// leaking auth tokens and PII in production logcat.
level = if (com.example.casera.BuildConfig.DEBUG) LogLevel.ALL else LogLevel.INFO
level = if (com.tt.honeyDue.BuildConfig.DEBUG) LogLevel.ALL else LogLevel.INFO
}
install(DefaultRequest) {

View File

@@ -1,12 +1,12 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.app.Activity
import android.content.Context
import android.util.Log
import com.android.billingclient.api.*
import com.example.casera.network.APILayer
import com.example.casera.network.ApiResult
import com.example.casera.utils.SubscriptionProducts
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.utils.SubscriptionProducts
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob

View File

@@ -1,9 +1,9 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.net.Uri
import androidx.compose.runtime.Composable
import com.example.casera.models.Contractor
import com.example.casera.ui.components.ContractorImportHandler as ContractorImportHandlerImpl
import com.tt.honeyDue.models.Contractor
import com.tt.honeyDue.ui.components.ContractorImportHandler as ContractorImportHandlerImpl
@Composable
actual fun ContractorImportHandler(

View File

@@ -1,12 +1,12 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.content.Intent
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import com.example.casera.models.Contractor
import com.example.casera.sharing.ContractorSharingManager
import com.example.casera.analytics.PostHogAnalytics
import com.example.casera.analytics.AnalyticsEvents
import com.tt.honeyDue.models.Contractor
import com.tt.honeyDue.sharing.ContractorSharingManager
import com.tt.honeyDue.analytics.PostHogAnalytics
import com.tt.honeyDue.analytics.AnalyticsEvents
@Composable
actual fun rememberShareContractor(): (Contractor) -> Unit {

View File

@@ -1,4 +1,4 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.content.Context
import android.os.Build

View File

@@ -1,4 +1,4 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.graphics.BitmapFactory
import androidx.compose.runtime.Composable

View File

@@ -1,4 +1,4 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.content.Context
import coil3.ImageLoader

View File

@@ -1,4 +1,4 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.content.Context
import android.net.Uri

View File

@@ -1,9 +1,9 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.app.Activity
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import com.example.casera.ui.subscription.UpgradeScreen
import com.tt.honeyDue.ui.subscription.UpgradeScreen
import kotlinx.coroutines.launch
@Composable

View File

@@ -1,9 +1,9 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.net.Uri
import androidx.compose.runtime.Composable
import com.example.casera.models.JoinResidenceResponse
import com.example.casera.ui.components.ResidenceImportHandler as ResidenceImportHandlerImpl
import com.tt.honeyDue.models.JoinResidenceResponse
import com.tt.honeyDue.ui.components.ResidenceImportHandler as ResidenceImportHandlerImpl
@Composable
actual fun ResidenceImportHandler(

View File

@@ -1,4 +1,4 @@
package com.example.casera.platform
package com.tt.honeyDue.platform
import android.content.Intent
import androidx.compose.runtime.Composable
@@ -8,10 +8,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.example.casera.models.Residence
import com.example.casera.sharing.ResidenceSharingManager
import com.example.casera.analytics.PostHogAnalytics
import com.example.casera.analytics.AnalyticsEvents
import com.tt.honeyDue.models.Residence
import com.tt.honeyDue.sharing.ResidenceSharingManager
import com.tt.honeyDue.analytics.PostHogAnalytics
import com.tt.honeyDue.analytics.AnalyticsEvents
import kotlinx.coroutines.launch
@Composable

View File

@@ -1,26 +1,26 @@
package com.example.casera.sharing
package com.tt.honeyDue.sharing
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
import com.example.casera.data.DataManager
import com.example.casera.models.CaseraShareCodec
import com.example.casera.models.Contractor
import com.example.casera.network.APILayer
import com.example.casera.network.ApiResult
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.models.honeyDueShareCodec
import com.tt.honeyDue.models.Contractor
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
/**
* Manages contractor export and import via .casera files on Android.
* Manages contractor export and import via .honeydue files on Android.
*/
object ContractorSharingManager {
/**
* Creates a share Intent for a contractor.
* The contractor data is written to a temporary .casera file and shared via FileProvider.
* The contractor data is written to a temporary .honeydue file and shared via FileProvider.
*
* @param context Android context
* @param contractor The contractor to share
@@ -29,8 +29,8 @@ object ContractorSharingManager {
fun createShareIntent(context: Context, contractor: Contractor): Intent? {
return try {
val currentUsername = DataManager.currentUser.value?.username ?: "Unknown"
val jsonString = CaseraShareCodec.encodeContractorPackage(contractor, currentUsername)
val fileName = CaseraShareCodec.safeShareFileName(contractor.name)
val jsonString = honeyDueShareCodec.encodeContractorPackage(contractor, currentUsername)
val fileName = honeyDueShareCodec.safeShareFileName(contractor.name)
// Create shared directory
val shareDir = File(context.cacheDir, "shared")
@@ -61,7 +61,7 @@ object ContractorSharingManager {
* Imports a contractor from a content URI.
*
* @param context Android context
* @param uri The content URI of the .casera file
* @param uri The content URI of the .honeydue file
* @return ApiResult with the created Contractor on success, or error on failure
*/
suspend fun importContractor(context: Context, uri: Uri): ApiResult<Contractor> {
@@ -79,7 +79,7 @@ object ContractorSharingManager {
val jsonString = inputStream.bufferedReader().use { it.readText() }
inputStream.close()
val createRequest = CaseraShareCodec.createContractorImportRequestOrNull(
val createRequest = honeyDueShareCodec.createContractorImportRequestOrNull(
jsonContent = jsonString,
availableSpecialties = DataManager.contractorSpecialties.value
) ?: return@withContext ApiResult.Error("Invalid contractor share package")
@@ -94,12 +94,12 @@ object ContractorSharingManager {
}
/**
* Checks if the given URI appears to be a .casera file.
* Checks if the given URI appears to be a .honeydue file.
*/
fun isCaseraFile(context: Context, uri: Uri): Boolean {
fun ishoneyDueFile(context: Context, uri: Uri): Boolean {
// Check file extension from URI path
val path = uri.path ?: uri.toString()
if (path.endsWith(".casera", ignoreCase = true)) {
if (path.endsWith(".honeydue", ignoreCase = true)) {
return true
}
@@ -110,7 +110,7 @@ object ContractorSharingManager {
val nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
if (nameIndex >= 0) {
val name = cursor.getString(nameIndex)
if (name?.endsWith(".casera", ignoreCase = true) == true) {
if (name?.endsWith(".honeydue", ignoreCase = true) == true) {
return true
}
}

View File

@@ -1,21 +1,21 @@
package com.example.casera.sharing
package com.tt.honeyDue.sharing
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
import com.example.casera.data.DataManager
import com.example.casera.models.CaseraShareCodec
import com.example.casera.models.JoinResidenceResponse
import com.example.casera.models.Residence
import com.example.casera.network.APILayer
import com.example.casera.network.ApiResult
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.models.honeyDueShareCodec
import com.tt.honeyDue.models.JoinResidenceResponse
import com.tt.honeyDue.models.Residence
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
/**
* Manages residence share package creation and import via .casera files on Android.
* Manages residence share package creation and import via .honeydue files on Android.
* Unlike contractors (which are exported client-side), residence sharing uses
* server-generated share codes.
*/
@@ -38,8 +38,8 @@ object ResidenceSharingManager {
when (result) {
is ApiResult.Success -> {
val sharedResidence = result.data
val jsonString = CaseraShareCodec.encodeSharedResidence(sharedResidence)
val fileName = CaseraShareCodec.safeShareFileName(residence.name)
val jsonString = honeyDueShareCodec.encodeSharedResidence(sharedResidence)
val fileName = honeyDueShareCodec.safeShareFileName(residence.name)
// Create shared directory
val shareDir = File(context.cacheDir, "shared")
@@ -77,7 +77,7 @@ object ResidenceSharingManager {
* Imports (joins) a residence from a content URI containing a share code.
*
* @param context Android context
* @param uri The content URI of the .casera file
* @param uri The content URI of the .honeydue file
* @return ApiResult with the JoinResidenceResponse on success, or error on failure
*/
suspend fun importResidence(context: Context, uri: Uri): ApiResult<JoinResidenceResponse> {
@@ -95,7 +95,7 @@ object ResidenceSharingManager {
val jsonString = inputStream.bufferedReader().use { it.readText() }
inputStream.close()
val shareCode = CaseraShareCodec.extractResidenceShareCodeOrNull(jsonString)
val shareCode = honeyDueShareCodec.extractResidenceShareCodeOrNull(jsonString)
?: return@withContext ApiResult.Error("Invalid residence share package")
// Call API with share code

View File

@@ -1,4 +1,4 @@
package com.example.casera.storage
package com.tt.honeyDue.storage
import android.content.Context
import android.content.SharedPreferences
@@ -47,7 +47,7 @@ actual class TaskCacheManager(private val context: Context) {
}
companion object {
private const val PREFS_NAME = "mycrib_cache"
private const val PREFS_NAME = "honeydue_cache"
private const val KEY_TASKS = "cached_tasks"
private const val KEY_DIRTY_FLAG = "tasks_dirty"

View File

@@ -1,4 +1,4 @@
package com.example.casera.storage
package com.tt.honeyDue.storage
internal actual fun getPlatformTaskCacheManager(): TaskCacheManager? {
// Android requires context, so must use initialize() method

View File

@@ -1,4 +1,4 @@
package com.example.casera.storage
package com.tt.honeyDue.storage
import android.content.Context
import android.content.SharedPreferences
@@ -22,7 +22,7 @@ actual class ThemeStorageManager(context: Context) {
}
companion object {
private const val PREFS_NAME = "mycrib_theme_prefs"
private const val PREFS_NAME = "honeydue_theme_prefs"
private const val KEY_THEME_ID = "theme_id"
@Volatile

View File

@@ -1,4 +1,4 @@
package com.example.casera.storage
package com.tt.honeyDue.storage
import android.content.Context
import android.content.SharedPreferences
@@ -31,8 +31,8 @@ actual class TokenManager(private val context: Context) {
companion object {
private const val TAG = "TokenManager"
private const val ENCRYPTED_PREFS_NAME = "mycrib_secure_prefs"
private const val FALLBACK_PREFS_NAME = "mycrib_prefs"
private const val ENCRYPTED_PREFS_NAME = "honeydue_secure_prefs"
private const val FALLBACK_PREFS_NAME = "honeydue_prefs"
private const val KEY_TOKEN = "auth_token"
@Volatile

View File

@@ -1,4 +1,4 @@
package com.example.casera.storage
package com.tt.honeyDue.storage
internal actual fun getPlatformTokenManager(): TokenManager? {
// Android requires context, so must use initialize() method

View File

@@ -1,4 +1,4 @@
package com.example.casera.ui.components
package com.tt.honeyDue.ui.components
import android.net.Uri
import androidx.compose.runtime.Composable
@@ -9,10 +9,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.example.casera.models.Contractor
import com.example.casera.models.SharedContractor
import com.example.casera.network.ApiResult
import com.example.casera.sharing.ContractorSharingManager
import com.tt.honeyDue.models.Contractor
import com.tt.honeyDue.models.SharedContractor
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.sharing.ContractorSharingManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -33,7 +33,7 @@ sealed class ImportState {
* Android-specific composable that handles the contractor import flow.
* Shows confirmation dialog, performs import, and displays result.
*
* @param pendingImportUri The URI of the .casera file to import (or null if none)
* @param pendingImportUri The URI of the .honeydue file to import (or null if none)
* @param onClearImport Called when import flow is complete and URI should be cleared
* @param onImportSuccess Called when import succeeds, with the imported contractor
*/
@@ -57,7 +57,7 @@ fun ContractorImportHandler(
}
}
// Parse the .casera file when a new URI is received
// Parse the .honeydue file when a new URI is received
LaunchedEffect(pendingImportUri) {
if (pendingImportUri != null && importState is ImportState.Idle) {
pendingUri = pendingImportUri

View File

@@ -1,4 +1,4 @@
package com.example.casera.ui.components
package com.tt.honeyDue.ui.components
import android.net.Uri
import androidx.compose.runtime.Composable
@@ -9,10 +9,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.example.casera.models.JoinResidenceResponse
import com.example.casera.models.SharedResidence
import com.example.casera.network.ApiResult
import com.example.casera.sharing.ResidenceSharingManager
import com.tt.honeyDue.models.JoinResidenceResponse
import com.tt.honeyDue.models.SharedResidence
import com.tt.honeyDue.network.ApiResult
import com.tt.honeyDue.sharing.ResidenceSharingManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -33,7 +33,7 @@ sealed class ResidenceImportState {
* Android-specific composable that handles the residence import flow.
* Shows confirmation dialog, performs import, and displays result.
*
* @param pendingImportUri The URI of the .casera file to import (or null if none)
* @param pendingImportUri The URI of the .honeydue file to import (or null if none)
* @param onClearImport Called when import flow is complete and URI should be cleared
* @param onImportSuccess Called when import succeeds, with the join response
*/
@@ -57,7 +57,7 @@ fun ResidenceImportHandler(
}
}
// Parse the .casera file when a new URI is received
// Parse the .honeydue file when a new URI is received
LaunchedEffect(pendingImportUri) {
if (pendingImportUri != null && importState is ResidenceImportState.Idle) {
pendingUri = pendingImportUri

View File

@@ -1,4 +1,4 @@
package com.example.casera.ui.components.auth
package com.tt.honeyDue.ui.components.auth
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
@@ -13,8 +13,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.example.casera.auth.GoogleSignInManager
import com.example.casera.auth.GoogleSignInResult
import com.tt.honeyDue.auth.GoogleSignInManager
import com.tt.honeyDue.auth.GoogleSignInResult
import kotlinx.coroutines.launch
@Composable

View File

@@ -1,4 +1,4 @@
package com.example.casera.ui.subscription
package com.tt.honeyDue.ui.subscription
import android.app.Activity
import androidx.compose.foundation.BorderStroke
@@ -17,9 +17,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.android.billingclient.api.ProductDetails
import com.example.casera.data.DataManager
import com.example.casera.platform.BillingManager
import com.example.casera.ui.theme.AppSpacing
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.platform.BillingManager
import com.tt.honeyDue.ui.theme.AppSpacing
import kotlinx.coroutines.launch
/**
@@ -344,7 +344,7 @@ private fun SubscriptionProductCardAndroid(
onSelect: () -> Unit
) {
val isAnnual = productDetails.productId.contains("annual")
val productName = if (isAnnual) "MyCrib Pro Annual" else "MyCrib Pro Monthly"
val productName = if (isAnnual) "honeyDue Pro Annual" else "honeyDue Pro Monthly"
val billingPeriod = if (isAnnual) "Billed annually" else "Billed monthly"
Card(

View File

@@ -1,8 +1,8 @@
package com.example.casera.util
package com.tt.honeyDue.util
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.example.casera.platform.ImageData
import com.tt.honeyDue.platform.ImageData
import java.io.ByteArrayOutputStream
/**

View File

@@ -1,4 +1,4 @@
package com.example.casera.widget
package com.tt.honeyDue.widget
import android.content.Context
import android.content.Intent
@@ -50,7 +50,7 @@ import kotlinx.serialization.json.Json
* Large widget showing task list with stats and interactive actions (Pro only)
* Size: 4x4
*/
class CaseraLargeWidget : GlanceAppWidget() {
class HoneyDueLargeWidget : GlanceAppWidget() {
override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition
@@ -97,7 +97,7 @@ class CaseraLargeWidget : GlanceAppWidget() {
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "Casera",
text = "honeyDue",
style = TextStyle(
color = ColorProvider(Color(0xFF07A0C3)),
fontSize = 20.sp,
@@ -346,7 +346,7 @@ class CompleteTaskAction : ActionCallback {
val taskId = parameters[ActionParameters.Key<Int>("task_id")] ?: return
// Send broadcast to app to complete the task
val intent = Intent("com.example.casera.COMPLETE_TASK").apply {
val intent = Intent("com.tt.honeyDue.COMPLETE_TASK").apply {
putExtra("task_id", taskId)
setPackage(context.packageName)
}
@@ -354,7 +354,7 @@ class CompleteTaskAction : ActionCallback {
// Update widget after action
withContext(Dispatchers.Main) {
CaseraLargeWidget().update(context, glanceId)
HoneyDueLargeWidget().update(context, glanceId)
}
}
}
@@ -362,6 +362,6 @@ class CompleteTaskAction : ActionCallback {
/**
* Receiver for the large widget
*/
class CaseraLargeWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = CaseraLargeWidget()
class HoneyDueLargeWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = HoneyDueLargeWidget()
}

View File

@@ -1,4 +1,4 @@
package com.example.casera.widget
package com.tt.honeyDue.widget
import android.content.Context
import android.content.Intent
@@ -46,7 +46,7 @@ import kotlinx.serialization.json.Json
* Medium widget showing a list of upcoming tasks
* Size: 4x2
*/
class CaseraMediumWidget : GlanceAppWidget() {
class HoneyDueMediumWidget : GlanceAppWidget() {
override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition
@@ -90,7 +90,7 @@ class CaseraMediumWidget : GlanceAppWidget() {
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "Casera",
text = "honeyDue",
style = TextStyle(
color = ColorProvider(Color(0xFF07A0C3)),
fontSize = 18.sp,
@@ -247,6 +247,6 @@ class OpenTaskAction : ActionCallback {
/**
* Receiver for the medium widget
*/
class CaseraMediumWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = CaseraMediumWidget()
class HoneyDueMediumWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = HoneyDueMediumWidget()
}

View File

@@ -1,4 +1,4 @@
package com.example.casera.widget
package com.tt.honeyDue.widget
import android.content.Context
import android.content.Intent
@@ -39,13 +39,13 @@ import androidx.glance.text.TextStyle
import androidx.glance.unit.ColorProvider
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.intPreferencesKey
import com.example.casera.R
import com.tt.honeyDue.R
/**
* Small widget showing task count summary
* Size: 2x1 or 2x2
*/
class CaseraSmallWidget : GlanceAppWidget() {
class HoneyDueSmallWidget : GlanceAppWidget() {
override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition
@@ -78,7 +78,7 @@ class CaseraSmallWidget : GlanceAppWidget() {
) {
// App name/logo
Text(
text = "Casera",
text = "honeyDue",
style = TextStyle(
color = ColorProvider(Color(0xFF07A0C3)),
fontSize = 16.sp,
@@ -166,6 +166,6 @@ class OpenAppAction : ActionCallback {
/**
* Receiver for the small widget
*/
class CaseraSmallWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = CaseraSmallWidget()
class HoneyDueSmallWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = HoneyDueSmallWidget()
}

View File

@@ -1,4 +1,4 @@
package com.example.casera.widget
package com.tt.honeyDue.widget
import android.content.Context
import androidx.datastore.core.DataStore

View File

@@ -1,11 +1,11 @@
package com.example.casera.widget
package com.tt.honeyDue.widget
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.example.casera.data.DataManager
import com.example.casera.models.TaskCompletionCreateRequest
import com.example.casera.network.APILayer
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.models.TaskCompletionCreateRequest
import com.tt.honeyDue.network.APILayer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -17,7 +17,7 @@ class WidgetTaskActionReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
"com.example.casera.COMPLETE_TASK" -> {
"com.tt.honeyDue.COMPLETE_TASK" -> {
val taskId = intent.getIntExtra("task_id", -1)
if (taskId != -1) {
completeTask(context, taskId)
@@ -45,7 +45,7 @@ class WidgetTaskActionReceiver : BroadcastReceiver() {
val result = APILayer.createTaskCompletion(request)
// Update widgets after completion
if (result is com.example.casera.network.ApiResult.Success) {
if (result is com.tt.honeyDue.network.ApiResult.Success) {
WidgetUpdateManager.updateAllWidgets(context)
}
} catch (e: Exception) {

View File

@@ -1,4 +1,4 @@
package com.example.casera.widget
package com.tt.honeyDue.widget
import android.content.Context
import androidx.datastore.preferences.core.intPreferencesKey
@@ -22,7 +22,7 @@ object WidgetUpdateManager {
private val json = Json { ignoreUnknownKeys = true }
/**
* Update all Casera widgets with new data
* Update all honeyDue widgets with new data
*/
fun updateAllWidgets(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
@@ -49,7 +49,7 @@ object WidgetUpdateManager {
val glanceManager = GlanceAppWidgetManager(context)
// Update small widgets
val smallWidgetIds = glanceManager.getGlanceIds(CaseraSmallWidget::class.java)
val smallWidgetIds = glanceManager.getGlanceIds(HoneyDueSmallWidget::class.java)
smallWidgetIds.forEach { id ->
updateAppWidgetState(context, PreferencesGlanceStateDefinition, id) { prefs ->
prefs.toMutablePreferences().apply {
@@ -58,11 +58,11 @@ object WidgetUpdateManager {
this[intPreferencesKey("in_progress_count")] = summary.inProgressCount
}
}
CaseraSmallWidget().update(context, id)
HoneyDueSmallWidget().update(context, id)
}
// Update medium widgets
val mediumWidgetIds = glanceManager.getGlanceIds(CaseraMediumWidget::class.java)
val mediumWidgetIds = glanceManager.getGlanceIds(HoneyDueMediumWidget::class.java)
mediumWidgetIds.forEach { id ->
updateAppWidgetState(context, PreferencesGlanceStateDefinition, id) { prefs ->
prefs.toMutablePreferences().apply {
@@ -72,11 +72,11 @@ object WidgetUpdateManager {
this[stringPreferencesKey("tasks_json")] = json.encodeToString(summary.tasks)
}
}
CaseraMediumWidget().update(context, id)
HoneyDueMediumWidget().update(context, id)
}
// Update large widgets
val largeWidgetIds = glanceManager.getGlanceIds(CaseraLargeWidget::class.java)
val largeWidgetIds = glanceManager.getGlanceIds(HoneyDueLargeWidget::class.java)
largeWidgetIds.forEach { id ->
updateAppWidgetState(context, PreferencesGlanceStateDefinition, id) { prefs ->
prefs.toMutablePreferences().apply {
@@ -89,7 +89,7 @@ object WidgetUpdateManager {
this[longPreferencesKey("last_updated")] = summary.lastUpdated
}
}
CaseraLargeWidget().update(context, id)
HoneyDueLargeWidget().update(context, id)
}
}

View File

@@ -15,7 +15,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Casera"
android:text="honeyDue"
android:textColor="#07A0C3"
android:textSize="20sp"
android:textStyle="bold" />

View File

@@ -15,7 +15,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Casera"
android:text="honeyDue"
android:textColor="#07A0C3"
android:textSize="18sp"
android:textStyle="bold" />

View File

@@ -10,7 +10,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Casera"
android:text="honeyDue"
android:textColor="#07A0C3"
android:textSize="16sp"
android:textStyle="bold" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -1,14 +1,14 @@
<resources>
<string name="app_name">Casera</string>
<string name="default_notification_channel_id">casera_notifications</string>
<string name="app_name">honeyDue</string>
<string name="default_notification_channel_id">honeydue_notifications</string>
<!-- Widget Strings -->
<string name="widget_small_name">Casera Summary</string>
<string name="widget_small_name">honeyDue Summary</string>
<string name="widget_small_description">Quick task count summary showing overdue, due soon, and active tasks</string>
<string name="widget_medium_name">Casera Tasks</string>
<string name="widget_medium_name">honeyDue Tasks</string>
<string name="widget_medium_description">List of upcoming tasks with quick access to task details</string>
<string name="widget_large_name">Casera Dashboard</string>
<string name="widget_large_name">honeyDue Dashboard</string>
<string name="widget_large_description">Full task dashboard with stats and interactive actions (Pro feature)</string>
</resources>