Skip to content

Commit

Permalink
Improve Routing, Feedback, Settings & Calendar (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobkoerber authored Apr 21, 2024
1 parent 3544f24 commit 11c6e27
Show file tree
Hide file tree
Showing 73 changed files with 702 additions and 782 deletions.
10 changes: 3 additions & 7 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "org.jetbrains.kotlin.plugin.serialization"
id "dev.flutter.flutter-gradle-plugin"
id "com.google.gms.google-services"
id "com.google.firebase.crashlytics"
Expand Down Expand Up @@ -71,7 +72,7 @@ android {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
proguardFile getDefaultProguardFile('proguard-android.txt')
} else {
signingConfig signingConfigs.debug
}
Expand All @@ -89,12 +90,7 @@ flutter {

dependencies {
implementation 'com.android.support:multidex'
implementation 'joda-time:joda-time:2.12.7'
def appcompat_version = "1.6.1"
implementation("androidx.appcompat:appcompat:$appcompat_version")
implementation("androidx.appcompat:appcompat-resources:$appcompat_version")
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'org.ocpsoft.prettytime:prettytime:5.0.4.Final'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0'
}

apply plugin: 'com.google.firebase.crashlytics'
42 changes: 0 additions & 42 deletions android/app/proguard-rules.pro

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package de.tum.`in`.tumcampus

import io.flutter.embedding.android.FlutterActivity

class MainActivity : FlutterActivity() {}
class MainActivity : FlutterActivity()
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
package de.tum.`in`.tumcampus.util

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import java.lang.reflect.Type
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

class LocalDateTimeDeserializer : JsonDeserializer<DateTime?> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): DateTime? {
return deserializeStringToDate(json?.asString)
@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = LocalDateTime::class)
object DateTimeSerializer : KSerializer<LocalDateTime> {
private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")

override fun serialize(encoder: Encoder, value: LocalDateTime) {
encoder.encodeString(value.format(formatter))
}

override fun deserialize(decoder: Decoder): LocalDateTime {
return LocalDateTime.parse(decoder.decodeString(), formatter)
}
}

fun deserializeStringToDate(dateString: String?): DateTime? {
return try {
val formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS")
DateTime.parse(dateString, formatter)
} catch (_: Exception) {
null
fun deserializeStringToDate(dateString: String?): LocalDateTime? {
return try {
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS")
LocalDateTime.parse(dateString, formatter)
} catch (_: Exception) {
null
}
}
}
150 changes: 24 additions & 126 deletions android/app/src/main/kotlin/de/tum/in/tumcampus/util/DateTimeUtils.kt
Original file line number Diff line number Diff line change
@@ -1,139 +1,37 @@
package de.tum.`in`.tumcampus.util

import android.content.Context
import android.text.format.DateUtils.*
import de.tum.`in`.tumcampus.R
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
import java.text.ParseException
import java.util.*
import java.time.Duration
import java.time.LocalDateTime

object DateTimeUtils {
/**
* Format an upcoming string nicely by being more precise as time comes closer
* E.g.:
* in 30 minutes
* in 2 h 4 min
* in 6 hours
* tomorrow
* @see getRelativeTimeSpanString()
*/
private fun formatFutureTime(time: DateTime, context: Context): String {
val timeInMillis = time.millis
val now = DateTime.now().millis

// Catch future dates: current clock might be running behind
if (timeInMillis < now || timeInMillis <= 0) return formatTimeOrDay(time, context)

val diff = timeInMillis - now
return when {
diff < 60 * MINUTE_IN_MILLIS -> {
val formatter = DateTimeFormat.forPattern("m")
.withLocale(Locale.ENGLISH)
"${context.getString(R.string.IN)} ${
formatter.print(
DateTime(
diff,
DateTimeZone.UTC
)
)
} " +
context.getString(R.string.MINUTES)
}

diff < 5 * HOUR_IN_MILLIS -> {
val formatter = DateTimeFormat.forPattern("h 'h' m 'min'")
.withLocale(Locale.ENGLISH)
"${context.getString(R.string.IN)} ${
formatter.print(
DateTime(
diff,
DateTimeZone.UTC
)
)
}"
}

else -> getRelativeTimeSpanString(
timeInMillis, now, MINUTE_IN_MILLIS,
FORMAT_ABBREV_RELATIVE
).toString()
}
}

/**
* @Deprecated use formatTimeOrDay(DateTime, Context)
*/
@Deprecated("Use the version with a proper DateTime object, there's really no reason to pass datetimes as strings")
fun formatTimeOrDayFromISO(datetime: String, context: Context): String {
val d = parseIsoDate(datetime) ?: return ""
return formatTimeOrDay(d, context)
}

/**
* Format a *past* ISO string timestamp with degrading granularity as time goes by
* E.g.:
* Just now
* 18:20
* Yesterday
* 12.03.2016
* Checks whether two DateTime contain the same day
*
* Please note, that this does *not* use getRelativeTimeSpanString(), because lectures scheduled
* at 12:00 and starting at 12:15 get a bit annoying nagging you with "12 minutes ago", when
* they actually only start in a couple of minutes
* This is similar to formatFutureTime(), but not specialized on future dates
* When in doubt, use formatFutureTime()
* @see formatFutureTime()
* @return true if both dates are on the same day
*/
private fun formatTimeOrDay(time: DateTime, context: Context): String {
val timeInMillis = time.millis
val now = DateTime.now().millis

// Catch future dates: current clock might be running behind
if (timeInMillis > now || timeInMillis <= 0) {
return context.getString(R.string.just_now)
}
fun isSameDay(first: LocalDateTime, second: LocalDateTime) =
first.year == second.year && first.dayOfYear == second.dayOfYear

val diff = now - timeInMillis
return when {
diff < MINUTE_IN_MILLIS ->
context.getString(R.string.just_now)

diff < 24 * HOUR_IN_MILLIS ->
DateTimeFormat.forPattern("HH:mm")
.withLocale(Locale.ENGLISH)
.print(time)

diff < 48 * HOUR_IN_MILLIS ->
context.getString(R.string.yesterday)

else ->
DateTimeFormat.forPattern("dd.MM.yyyy")
.withLocale(Locale.ENGLISH)
.print(time)
}
}

/**
* 2014-06-30T16:31:57Z
*/
private val isoDateFormatter: DateTimeFormatter =
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
}

private fun parseIsoDate(datetime: String) = try {
isoDateFormatter.parseDateTime(datetime)
} catch (e: ParseException) {
//Utils.log(e)
null
fun LocalDateTime.timeAgo(context: Context): String {
val now = LocalDateTime.now()
val duration = Duration.between(this, now)

val years = duration.toDays() / 365
val months = duration.toDays() / 30
val days = duration.toDays()
val hours = duration.toHours()
val minutes = duration.toMinutes()

return when {
years > 0 -> context.resources.getQuantityString(R.plurals.yearsAgo, years.toInt())
months > 0 -> context.resources.getQuantityString(R.plurals.monthsAgo, months.toInt())
days > 0 -> context.resources.getQuantityString(R.plurals.daysAgo, days.toInt())
hours > 0 -> context.resources.getQuantityString(R.plurals.hoursAgo, hours.toInt())
minutes > 0 -> context.resources.getQuantityString(R.plurals.minutesAgo, minutes.toInt())
else -> context.resources.getString(R.string.just_now)
}

/**
* Checks whether two DateTime contain the same day
*
* @return true if both dates are on the same day
*/
fun isSameDay(first: DateTime, second: DateTime) =
first.year() == second.year() && first.dayOfYear() == second.dayOfYear()
}

This file was deleted.

Loading

0 comments on commit 11c6e27

Please sign in to comment.