Rebrand from MyCrib to Casera

- Rename Kotlin package from com.example.mycrib to com.example.casera
- Update Android app name, namespace, and application ID
- Update iOS bundle identifiers and project settings
- Rename iOS directories (MyCribTests -> CaseraTests, etc.)
- Update deep link schemes from mycrib:// to casera://
- Update app group identifiers
- Update subscription product IDs
- Update all UI strings and branding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-11-28 21:10:38 -06:00
parent 8dbc816a33
commit c6eef720ed
215 changed files with 767 additions and 767 deletions

View File

@@ -1,4 +1,4 @@
package com.example.mycrib.ui.components
package com.example.casera.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.mycrib.models.TaskSummary
import com.example.mycrib.models.TaskColumnCategory
import com.example.casera.models.TaskSummary
import com.example.casera.models.TaskColumnCategory
/**
* Displays a task summary with dynamic categories from the backend.

View File

@@ -1,4 +1,4 @@
package com.example.mycrib
package com.example.casera
import android.content.Intent
import android.net.Uri
@@ -22,14 +22,14 @@ import coil3.memory.MemoryCache
import coil3.request.crossfade
import coil3.util.DebugLogger
import okio.FileSystem
import com.example.mycrib.storage.TokenManager
import com.example.mycrib.storage.TokenStorage
import com.example.mycrib.storage.TaskCacheManager
import com.example.mycrib.storage.TaskCacheStorage
import com.example.mycrib.storage.ThemeStorage
import com.example.mycrib.storage.ThemeStorageManager
import com.example.mycrib.ui.theme.ThemeManager
import com.example.mycrib.fcm.FCMManager
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 kotlinx.coroutines.launch
class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
@@ -85,21 +85,21 @@ class MainActivity : ComponentActivity(), SingletonImageLoader.Factory {
try {
val authToken = TokenStorage.getToken()
if (authToken != null) {
val notificationApi = com.example.mycrib.network.NotificationApi()
val request = com.example.mycrib.models.DeviceRegistrationRequest(
val notificationApi = com.example.casera.network.NotificationApi()
val request = com.example.casera.models.DeviceRegistrationRequest(
registrationId = fcmToken,
platform = "android"
)
when (val result = notificationApi.registerDevice(authToken, request)) {
is com.example.mycrib.network.ApiResult.Success -> {
is com.example.casera.network.ApiResult.Success -> {
Log.d("MainActivity", "Device registered successfully: ${result.data}")
}
is com.example.mycrib.network.ApiResult.Error -> {
is com.example.casera.network.ApiResult.Error -> {
Log.e("MainActivity", "Failed to register device: ${result.message}")
}
is com.example.mycrib.network.ApiResult.Loading,
is com.example.mycrib.network.ApiResult.Idle -> {
is com.example.casera.network.ApiResult.Loading,
is com.example.casera.network.ApiResult.Idle -> {
// These states shouldn't occur for direct API calls
}
}

View File

@@ -1,4 +1,4 @@
package com.example.mycrib
package com.example.casera
import android.app.NotificationChannel
import android.app.NotificationManager
@@ -30,23 +30,23 @@ 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.mycrib.storage.TokenStorage.getToken()
val authToken = com.example.casera.storage.TokenStorage.getToken()
if (authToken != null) {
val notificationApi = com.example.mycrib.network.NotificationApi()
val request = com.example.mycrib.models.DeviceRegistrationRequest(
val notificationApi = com.example.casera.network.NotificationApi()
val request = com.example.casera.models.DeviceRegistrationRequest(
registrationId = token,
platform = "android"
)
when (val result = notificationApi.registerDevice(authToken, request)) {
is com.example.mycrib.network.ApiResult.Success -> {
is com.example.casera.network.ApiResult.Success -> {
Log.d(TAG, "Device registered successfully with new token")
}
is com.example.mycrib.network.ApiResult.Error -> {
is com.example.casera.network.ApiResult.Error -> {
Log.e(TAG, "Failed to register device with new token: ${result.message}")
}
is com.example.mycrib.network.ApiResult.Loading,
is com.example.mycrib.network.ApiResult.Idle -> {
is com.example.casera.network.ApiResult.Loading,
is com.example.casera.network.ApiResult.Idle -> {
// These states shouldn't occur for direct API calls
}
}

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
package com.example.mycrib.network
package com.example.casera.network
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*

View File

@@ -1,13 +1,13 @@
package com.example.mycrib.platform
package com.example.casera.platform
import android.app.Activity
import android.content.Context
import android.util.Log
import com.android.billingclient.api.*
import com.example.mycrib.cache.SubscriptionCache
import com.example.mycrib.network.APILayer
import com.example.mycrib.network.ApiResult
import com.example.mycrib.utils.SubscriptionHelper
import com.example.casera.cache.SubscriptionCache
import com.example.casera.network.APILayer
import com.example.casera.network.ApiResult
import com.example.casera.utils.SubscriptionHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@@ -36,8 +36,8 @@ class BillingManager private constructor(private val context: Context) {
// Product IDs (must match Google Play Console)
private val productIDs = listOf(
"com.example.mycrib.pro.monthly",
"com.example.mycrib.pro.annual"
"com.example.casera.pro.monthly",
"com.example.casera.pro.annual"
)
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
@@ -421,14 +421,14 @@ class BillingManager private constructor(private val context: Context) {
* Get monthly product
*/
fun getMonthlyProduct(): ProductDetails? {
return _products.value.find { it.productId == "com.example.mycrib.pro.monthly" }
return _products.value.find { it.productId == "com.example.casera.pro.monthly" }
}
/**
* Get annual product
*/
fun getAnnualProduct(): ProductDetails? {
return _products.value.find { it.productId == "com.example.mycrib.pro.annual" }
return _products.value.find { it.productId == "com.example.casera.pro.annual" }
}
/**

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
package com.example.mycrib.storage
package com.example.casera.storage
import android.content.Context
import android.content.SharedPreferences

View File

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

View File

@@ -1,4 +1,4 @@
package com.example.mycrib.storage
package com.example.casera.storage
import android.content.Context
import android.content.SharedPreferences

View File

@@ -1,4 +1,4 @@
package com.example.mycrib.storage
package com.example.casera.storage
import android.content.Context
import android.content.SharedPreferences

View File

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

View File

@@ -1,4 +1,4 @@
package com.example.mycrib.ui.subscription
package com.example.casera.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.mycrib.cache.SubscriptionCache
import com.example.mycrib.platform.BillingManager
import com.example.mycrib.ui.theme.AppSpacing
import com.example.casera.cache.SubscriptionCache
import com.example.casera.platform.BillingManager
import com.example.casera.ui.theme.AppSpacing
import kotlinx.coroutines.launch
/**

View File

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