diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bbfc0f3..7891877 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -81,32 +81,33 @@ android { } dependencies { - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.lifecycle.runtime.ktx) - implementation(libs.androidx.activity.compose) - implementation(platform(libs.androidx.compose.bom)) - implementation(libs.androidx.ui) - implementation(libs.androidx.ui.graphics) - implementation(libs.androidx.ui.tooling.preview) - implementation(libs.androidx.material3) - implementation(libs.androidx.material.icons) - implementation(libs.okhttp) - implementation(libs.okhttp.coroutines) - implementation(libs.logging.interceptor) - implementation(libs.moshi) - implementation(libs.androidx.navigation.compose) - implementation(libs.androidx.navigation.fragment) - implementation(libs.androidx.navigation.ui) - implementation(libs.kotlinx.serialization.json) - implementation(libs.room.runtime) - implementation(libs.room.ktx) - implementation(libs.androidx.datastore.preferences) - implementation(libs.retrofit) - implementation(libs.converter.moshi) - implementation(libs.work.runtime) - implementation(libs.work.runtime.ktx) - implementation(libs.kotlinx.coroutines.guava) - implementation(libs.androidx.browser) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.material.icons) + implementation(libs.okhttp) + implementation(libs.okhttp.coroutines) + implementation(libs.logging.interceptor) + implementation(libs.moshi) + implementation(libs.androidx.navigation.compose) + implementation(libs.androidx.navigation.fragment) + implementation(libs.androidx.navigation.ui) + implementation(libs.kotlinx.serialization.json) + implementation(libs.room.runtime) + implementation(libs.room.ktx) + implementation(libs.androidx.datastore.preferences) + implementation(libs.retrofit) + implementation(libs.converter.moshi) + implementation(libs.work.runtime) + implementation(libs.work.runtime.ktx) + implementation(libs.kotlinx.coroutines.guava) + implementation(libs.androidx.browser) + implementation(libs.smartspacer) ksp(libs.room.compiler) ksp(libs.moshi.kotlin.codegen) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ca8788a..df2487c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,8 @@ + + + + + + + + diff --git a/app/src/main/java/dev/itsvic/parceltracker/NotificationWorker.kt b/app/src/main/java/dev/itsvic/parceltracker/NotificationWorker.kt index c4bbadf..295ff9c 100644 --- a/app/src/main/java/dev/itsvic/parceltracker/NotificationWorker.kt +++ b/app/src/main/java/dev/itsvic/parceltracker/NotificationWorker.kt @@ -11,8 +11,10 @@ import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkInfo import androidx.work.WorkManager import androidx.work.WorkerParameters +import com.kieronquinn.app.smartspacer.sdk.provider.SmartspacerTargetProvider import dev.itsvic.parceltracker.api.getParcel import dev.itsvic.parceltracker.db.ParcelStatus +import dev.itsvic.parceltracker.smartspacer.targets.ParcelStatusTarget import java.time.ZoneId import java.util.concurrent.TimeUnit import kotlinx.coroutines.Dispatchers @@ -67,6 +69,9 @@ class NotificationWorker(context: Context, params: WorkerParameters) : } } + // TODO: this most likely has to be moved + SmartspacerTargetProvider.notifyChange(applicationContext, ParcelStatusTarget::class.java) + return Result.success() } } diff --git a/app/src/main/java/dev/itsvic/parceltracker/smartspacer/targets/ParcelStatusTarget.kt b/app/src/main/java/dev/itsvic/parceltracker/smartspacer/targets/ParcelStatusTarget.kt new file mode 100644 index 0000000..a5def5a --- /dev/null +++ b/app/src/main/java/dev/itsvic/parceltracker/smartspacer/targets/ParcelStatusTarget.kt @@ -0,0 +1,105 @@ +package dev.itsvic.parceltracker.smartspacer.targets + +import android.content.ComponentName +import android.util.Log +import android.graphics.drawable.Icon as AndroidIcon +import com.kieronquinn.app.smartspacer.sdk.model.SmartspaceTarget +import com.kieronquinn.app.smartspacer.sdk.model.uitemplatedata.Icon +import com.kieronquinn.app.smartspacer.sdk.model.uitemplatedata.Text +import com.kieronquinn.app.smartspacer.sdk.provider.SmartspacerTargetProvider +import com.kieronquinn.app.smartspacer.sdk.utils.TargetTemplate +import dev.itsvic.parceltracker.ParcelApplication +import dev.itsvic.parceltracker.R +import dev.itsvic.parceltracker.api.Status +import dev.itsvic.parceltracker.api.getParcel +import dev.itsvic.parceltracker.db.ParcelWithStatus +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlin.String + +class ParcelStatusTarget: SmartspacerTargetProvider() { + override fun getSmartspaceTargets(smartspacerId: String): List { + val targets = mutableListOf() + + val db = ParcelApplication.db + val parcels: List = runBlocking(Dispatchers.IO) { + db.parcelDao().getAllNonArchivedWithStatusAsync() + } + + // this doesn't limit the number of returned targets + // it probably should, but I don't know whether to hardcode it or make configurable + + parcels.forEach { parcelWithStatus -> + val parcel = parcelWithStatus.parcel + + val apiParcel = try { + runBlocking(Dispatchers.IO) { + provideContext().getParcel(parcel.parcelId, parcel.postalCode, parcel.service) + } + } catch (e: Exception) { + Log.d(TAG, "Failed to fetch, skipping", e) + + return@forEach + } + + // TODO: is the one from API or db preferred + val status = apiParcel.currentStatus //parcelWithStatus.status?.status + + targets.add( + TargetTemplate.Basic( + id = "parcel_status_$smartspacerId", + componentName = ComponentName( + provideContext(), + ParcelStatusTarget::class.java + ), +// featureType = SmartspaceTarget.FEATURE_PACKAGE_TRACKING, + title = Text("${parcel.humanName}: ${status.name}"), + subtitle = Text(apiParcel.history.first().description), + icon = Icon( + AndroidIcon.createWithResource( + provideContext(), + // this when is the same as the one in ParcelRow, maybe unify those two? + when (status) { + Status.Preadvice -> R.drawable.outline_other_admission_24 + Status.InTransit -> R.drawable.outline_local_shipping_24 + Status.InWarehouse -> R.drawable.outline_warehouse_24 + Status.Customs -> R.drawable.outline_search_24 + Status.OutForDelivery -> R.drawable.outline_local_shipping_24 + Status.DeliveryFailure -> R.drawable.outline_error_24 + Status.AwaitingPickup -> R.drawable.outline_pin_drop_24 + Status.Delivered, Status.PickedUp -> R.drawable.outline_check_24 + + else -> R.drawable.outline_question_mark_24 + } + ) + ), + onClick = null // TODO: change + ).create().apply { + isSensitive = true + canBeDismissed = false + }) + } + + return targets + } + + override fun getConfig(smartspacerId: String?): Config { + return Config( + label = "Parcel Status", + description = "Shows the current status of a selected parcel", + icon = AndroidIcon.createWithResource(provideContext(), R.drawable.package_2), + allowAddingMoreThanOnce = true, +// configActivity = // Optional: An Intent given as an option to the user in the settings UI after adding +// setupActivity = // Optional: An Intent of an Activity presented to the user during setup (see below) + ) + } + + override fun onDismiss(smartspacerId: String, targetId: String): Boolean { + return false + } + + companion object { + private const val TAG = "ParcelStatusTarget" + } + +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a187b2..a1e6be3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,6 +21,7 @@ work = "2.10.0" kotlinxCoroutinesGuava = "1.10.1" material3 = "1.4.0-alpha11" browser = "1.8.0" +smartspacer = "1.1" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -57,6 +58,7 @@ work-runtime = { group = "androidx.work", name = "work-runtime", version.ref = " work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" } kotlinx-coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-guava", version.ref = "kotlinxCoroutinesGuava" } androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "browser" } +smartspacer = { group = "com.kieronquinn.smartspacer", name = "sdk-plugin", version.ref = "smartspacer" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" }