Skip to content

Commit

Permalink
Displaying number of expirations and warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
jumpiniasty committed Sep 27, 2023
1 parent 4cf1524 commit 9e5d28b
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 73 deletions.
4 changes: 3 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ dependencies {
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.navigation:navigation-compose:2.7.2")
implementation("androidx.navigation:navigation-compose:2.7.3")
implementation("com.google.code.gson:gson:2.10.1")
implementation("androidx.glance:glance-appwidget:1.0.0")
implementation("androidx.glance:glance-material3:1.0.0")

testImplementation("junit:junit:4.13.2")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
Expand Down
13 changes: 12 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.FixMyRide"
android:screenOrientation="portrait"
android:theme="@style/Theme.FixMyRide"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver
android:name=".ui.widgets.ExpirationsReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/expirations_widget" />
</receiver>
</application>
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/java/io/fixmyride/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState)
DatabaseManager.initialize(this)
PrefsManager.initialize(this)

val prefs = PrefsManager.getInstance()
if (prefs.getInt("notifications_days", -1) == -1) {
prefs.edit().putInt("notifications_days", 7).apply()
Expand Down
13 changes: 9 additions & 4 deletions app/src/main/java/io/fixmyride/enums/NotificationType.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package io.fixmyride.enums

enum class NotificationType {
TPL_EXPIRY,
CI_EXPIRY,
UPCOMING_INSPECTION;
object NotificationType {
const val TPL_ABOUT_TO_EXPIRE = 1
const val TPL_EXPIRED = -1

const val CI_ABOUT_TO_EXPIRE = 2
const val CI_EXPIRED = -2

const val INSPECTION_UPCOMING = 3
const val INSPECTION_EXPIRED = -3
}
4 changes: 1 addition & 3 deletions app/src/main/java/io/fixmyride/models/Notification.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package io.fixmyride.models

import io.fixmyride.enums.NotificationType

data class Notification(
val relatedVehicleId: Int,
val expirations: List<NotificationType>,
val expirations: List<Int>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import io.fixmyride.R
Expand Down Expand Up @@ -94,7 +95,11 @@ fun NotificationItem(notification: Notification) {
}

}
WarningsAndExpand(notification.expirations.size, isExpanded.value) {
WarningsAndExpand(
expired = notification.expirations.filter { it < 0 }.size,
warnings = notification.expirations.filter { it > 0 }.size,
expanded = isExpanded.value,
) {
isExpanded.value = !isExpanded.value
}
}
Expand All @@ -103,29 +108,63 @@ fun NotificationItem(notification: Notification) {

@Composable
fun WarningsAndExpand(
expired: Int,
warnings: Int,
expanded: Boolean,
onClickExpand: () -> Unit,
) {
val hasOnlyExpirationsOrWarnings = when {
expired == 0 && warnings != 0 -> true
expired != 0 && warnings == 0 -> true
else -> false
}

Row {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.background(
color = ColorPalette.yellow.copy(alpha = 0.1f),
shape = RoundedCornerShape(5.dp),
if (expired != 0) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.background(
color = ColorPalette.lightRed.copy(alpha = 0.1f),
shape = RoundedCornerShape(5.dp),
)
.clip(RoundedCornerShape(5.dp))
) {
Text(
text = "$expired ${if (hasOnlyExpirationsOrWarnings) stringResource(R.string.expirations) else ""}".trim(),
style = Typing.expiredText,
modifier = Modifier
.padding(
horizontal = 5.dp,
vertical = 2.dp,
),
)
.clip(RoundedCornerShape(5.dp))
) {
Text(
text = "$warnings warnings",
style = Typing.warningText,
}
}

if (!hasOnlyExpirationsOrWarnings) Spacer(Modifier.width(5.dp))


if (warnings != 0) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(
horizontal = 5.dp,
vertical = 2.dp,
),
)
.background(
color = ColorPalette.yellow.copy(alpha = 0.1f),
shape = RoundedCornerShape(5.dp),
)
.clip(RoundedCornerShape(5.dp))
) {
Text(
text = "$warnings ${if (hasOnlyExpirationsOrWarnings) stringResource(R.string.warnings) else ""}".trim(),
style = Typing.warningText,
modifier = Modifier
.padding(
horizontal = 5.dp,
vertical = 2.dp,
),
)
}
}
Spacer(Modifier.width(10.dp))

Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/io/fixmyride/ui/theme/Typing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ object Typing {
lineHeight = 16.sp,
)

/** e.g. notifications for every single vehicle expiration text */
val expiredText = TextStyle(
color = ColorPalette.lightRed,
fontFamily = customFont,
fontWeight = FontWeight.Normal,
fontSize = 12.sp,
lineHeight = 16.sp,
)

/** Used only for text field texts */
val textFieldText = TextStyle(
color = ColorPalette.secondary,
Expand Down
37 changes: 37 additions & 0 deletions app/src/main/java/io/fixmyride/ui/widgets/Expirations.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.fixmyride.ui.widgets

import android.content.Context
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.provideContent
import androidx.glance.background
import androidx.glance.layout.Column
import androidx.glance.layout.fillMaxSize
import androidx.glance.text.Text
import io.fixmyride.ui.theme.ColorPalette

private object ExpirationsWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {

// In this method, load data needed to render the AppWidget.
// Use `withContext` to switch to another thread for long running
// operations.
provideContent {
Column(
modifier = GlanceModifier
.fillMaxSize()
.background(color = ColorPalette.background),
) {
Text("Sup'")
}
}
}

}

object ExpirationsReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget
get() = ExpirationsWidget
}
34 changes: 0 additions & 34 deletions app/src/main/java/io/fixmyride/utils/DataExchange.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
package io.fixmyride.utils

import android.os.Build
import android.os.Environment
import androidx.annotation.RequiresApi
import com.google.gson.Gson
import io.fixmyride.database.DatabaseManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.time.LocalDate

/** Provides functions for importing and exporting data to/from files */
object DataExchange {
/** Used for importing data from previously exported file */
Expand All @@ -20,29 +8,7 @@ object DataExchange {
}

/** Used for exporting data to a file */
@RequiresApi(Build.VERSION_CODES.O)
suspend fun exportData() {
val vehicleData = DatabaseManager.getInstance().dao.getData()
val gson = Gson()
val fileName = "FixMyRide_${LocalDate.now()}.json"
val file = File("${Environment.getExternalStorageDirectory()}/${File.separator}$fileName")

try {
val dataToConvert = mutableListOf<Map<String, Any?>>()
for (v in vehicleData) dataToConvert.add(v.toMap())
val json = gson.toJson(dataToConvert)

withContext(Dispatchers.IO) {
if (!file.exists()) {
file.createNewFile()
}
val fos = FileOutputStream(file)
fos.write(json.toByteArray())
fos.close()
}

} catch (e: IOException) {
e.printStackTrace()
}
}
}
31 changes: 19 additions & 12 deletions app/src/main/java/io/fixmyride/utils/NotificationChecker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,35 @@ import java.time.LocalDate
/** Provides methods used for checking if vehicle's insurance (or inspection) is about to expire */
object NotificationChecker {
@RequiresApi(Build.VERSION_CODES.O)
fun checkForNotifications(v: Vehicle): List<NotificationType> {
val expired = arrayListOf<NotificationType>()
val notifDays = PrefsManager.getInstance().getInt("notifications_days", -1)
fun checkForNotifications(v: Vehicle): List<Int> {
val expired = arrayListOf<Int>()
val notificationDays = PrefsManager.getInstance().getInt("notifications_days", -1)

fun dateDifference(date: LocalDate): Long =
date.minusDays(LocalDate.now().toEpochDay()).toEpochDay()

fun dateDifference(date: LocalDate): Long {
return date.minusDays(LocalDate.now().toEpochDay()).toEpochDay()
}

if (dateDifference(v.tplInsuranceExpiry) in 1..notifDays) {
expired.add(NotificationType.TPL_EXPIRY)
val tplDifference = dateDifference(v.tplInsuranceExpiry)
when {
tplDifference < 0 -> expired.add(NotificationType.TPL_EXPIRED)
tplDifference in 1..notificationDays -> expired.add(NotificationType.TPL_ABOUT_TO_EXPIRE)
}

if (v.collisionInsuranceExpiry != null) {
if (dateDifference(v.collisionInsuranceExpiry) in 1..notifDays) {
expired.add(NotificationType.CI_EXPIRY)
val ciDifference = dateDifference(v.collisionInsuranceExpiry)
when {
ciDifference < 0 -> expired.add(NotificationType.CI_EXPIRED)
ciDifference in 1..notificationDays -> expired.add(NotificationType.CI_ABOUT_TO_EXPIRE)
}
}

if (dateDifference(v.nextInspectionDate) in 1..notifDays) {
expired.add(NotificationType.UPCOMING_INSPECTION)
val inspectionDifference = dateDifference(v.nextInspectionDate)
when {
inspectionDifference < 0 -> expired.add(NotificationType.INSPECTION_EXPIRED)
inspectionDifference in 1..notificationDays -> expired.add(NotificationType.INSPECTION_UPCOMING)
}


return expired
}
}
2 changes: 2 additions & 0 deletions app/src/main/res/values-pl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@
<string name="by_inspection_date">Według daty przeglądu</string>
<string name="number_of_days">Ilość dni</string>
<string name="days">dni</string>
<string name="expirations">wygaśnięcia</string>
<string name="warnings">ostrzeżenia</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@
<string name="by_inspection_date">By inspection date</string>
<string name="number_of_days">Number of days</string>
<string name="days">days</string>
<string name="expirations">expirations</string>
<string name="warnings">warnings</string>
</resources>
9 changes: 9 additions & 0 deletions app/src/main/res/xml/expirations_widget.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_name"
android:initialLayout="@layout/glance_default_loading_layout"
android:minWidth="100dp"
android:minHeight="50dp"
android:resizeMode="none"
android:updatePeriodMillis="10000"
android:widgetCategory="home_screen" />

0 comments on commit 9e5d28b

Please sign in to comment.