aboutsummaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-09-26 19:36:27 -0600
committerIván Ávalos <avalos@disroot.org>2023-09-26 19:36:27 -0600
commit3e72d9b02e864f4f79ae494c67418031b7625659 (patch)
tree3d6d7ae3997b9372d50932e0e489dced12e5b07c /shared
parent8765d82d3ad055945c6221e4f46bc38d903bf58d (diff)
parent3022b877d0cf9b7546c80953237c7bca5a4afa50 (diff)
downloadetbsa-trackermap-mobile-3e72d9b02e864f4f79ae494c67418031b7625659.tar.gz
etbsa-trackermap-mobile-3e72d9b02e864f4f79ae494c67418031b7625659.tar.bz2
etbsa-trackermap-mobile-3e72d9b02e864f4f79ae494c67418031b7625659.zip
Merge branch 'main' of https://git.sr.ht/~avalos/trackermap-mobile
Diffstat (limited to 'shared')
-rw-r--r--shared/build.gradle.kts5
-rw-r--r--shared/src/androidMain/AndroidManifest.xml4
-rw-r--r--shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt55
-rw-r--r--shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/ApiClient.kt2
-rw-r--r--shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/SessionManager.kt2
-rw-r--r--shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/UnitInformation.kt12
-rw-r--r--shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt8
-rw-r--r--shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/SessionController.kt18
-rw-r--r--shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt6
-rw-r--r--shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt25
10 files changed, 118 insertions, 19 deletions
diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts
index 67acdb8..6517f7f 100644
--- a/shared/build.gradle.kts
+++ b/shared/build.gradle.kts
@@ -19,6 +19,11 @@ kotlin {
).forEach {
it.binaries.framework {
baseName = "shared"
+
+ // Fix builds in Xcode 15
+ if (System.getenv("XCODE_VERSION_MAJOR") == "1500") {
+ linkerOpts += "-ld64"
+ }
}
}
diff --git a/shared/src/androidMain/AndroidManifest.xml b/shared/src/androidMain/AndroidManifest.xml
index 568741e..f0f34af 100644
--- a/shared/src/androidMain/AndroidManifest.xml
+++ b/shared/src/androidMain/AndroidManifest.xml
@@ -1,2 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
-<manifest /> \ No newline at end of file
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+</manifest> \ No newline at end of file
diff --git a/shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt b/shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt
new file mode 100644
index 0000000..eecd7de
--- /dev/null
+++ b/shared/src/androidMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt
@@ -0,0 +1,55 @@
+package mx.trackermap.TrackerMap.controllers
+
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
+import android.os.Build
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import mx.trackermap.TrackerMap.Injectable
+
+actual class NetworkController(context: Context): Injectable {
+ private val networkRequest = NetworkRequest.Builder().build()
+ private val connectivityManager: ConnectivityManager
+ private val _networkAvailable = MutableStateFlow<Boolean?>(null)
+ actual val networkAvailable = _networkAvailable.asStateFlow()
+
+ private val networkCallback = object: ConnectivityManager.NetworkCallback() {
+ override fun onCapabilitiesChanged(
+ network: Network,
+ networkCapabilities: NetworkCapabilities
+ ) {
+ super.onCapabilitiesChanged(network, networkCapabilities)
+ _networkAvailable.value = checkNetworkAccess(networkCapabilities)
+ }
+
+ override fun onLost(network: Network) {
+ super.onLost(network)
+ _networkAvailable.value = false
+ }
+ }
+
+ init {
+ connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ _networkAvailable.value = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ checkNetworkAccess(connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork))
+ } else {
+ connectivityManager.activeNetworkInfo?.isConnected == true
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ connectivityManager.registerDefaultNetworkCallback(networkCallback)
+ } else {
+ connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
+ }
+ }
+
+ private fun checkNetworkAccess(capabilities: NetworkCapabilities?) =
+ capabilities != null
+ && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ && if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ } else true
+} \ No newline at end of file
diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/ApiClient.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/ApiClient.kt
index 937b2dd..8238f7e 100644
--- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/ApiClient.kt
+++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/ApiClient.kt
@@ -168,7 +168,7 @@ open class ApiClient(
}
}
- if (sessionManager.token.isNotEmpty()) {
+ if (sessionManager.hasSession) {
request.headers["Cookie"] = sessionManager.token
}
val response: HttpResponse = client.request(request)
diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/SessionManager.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/SessionManager.kt
index caf2da1..71ae5d0 100644
--- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/SessionManager.kt
+++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/infrastructure/SessionManager.kt
@@ -28,6 +28,8 @@ class SessionManager(
settings[ACCESS_TOKEN_KEY] = token
}
+ val hasSession: Boolean get() = settings.hasKey(ACCESS_TOKEN_KEY)
+
fun clearSession() {
settings.remove(ACCESS_TOKEN_KEY)
settings.remove(SERVER_URL_KEY)
diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/UnitInformation.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/UnitInformation.kt
index 6afa350..33e85ee 100644
--- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/UnitInformation.kt
+++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/UnitInformation.kt
@@ -53,5 +53,15 @@ data class UnitInformation(
} ?: EngineStop.UNKNOWN
} else EngineStop.UNKNOWN
- fun getHourmeter() = position?.attributes?.get("hours")?.longOrNull
+ fun getHourmeter() = position?.attributes?.let { attrs ->
+ if ("io16" in attrs) {
+ // Minutes
+ attrs["io16"]?.longOrNull?.let { it * 60 * 1000 }
+ } else if ("hours" in attrs) {
+ // Milliseconds
+ attrs["hours"]?.longOrNull
+ } else {
+ null
+ }
+ }
} \ No newline at end of file
diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt
new file mode 100644
index 0000000..08dcc87
--- /dev/null
+++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt
@@ -0,0 +1,8 @@
+package mx.trackermap.TrackerMap.controllers
+
+import kotlinx.coroutines.flow.StateFlow
+import mx.trackermap.TrackerMap.Injectable
+
+expect class NetworkController: Injectable {
+ val networkAvailable: StateFlow<Boolean?>
+} \ No newline at end of file
diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/SessionController.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/SessionController.kt
index a63bba2..5cfdf96 100644
--- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/SessionController.kt
+++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/SessionController.kt
@@ -25,13 +25,15 @@ import kotlinx.serialization.json.JsonPrimitive
import mx.trackermap.TrackerMap.Injectable
import mx.trackermap.TrackerMap.client.apis.SessionApi
import mx.trackermap.TrackerMap.client.apis.UsersApi
+import mx.trackermap.TrackerMap.client.infrastructure.SessionManager
import mx.trackermap.TrackerMap.client.models.SessionBody
import mx.trackermap.TrackerMap.client.models.User
@DelicateCoroutinesApi
class SessionController(
+ private val sessionManager: SessionManager,
private val sessionApi: SessionApi,
- private val usersApi: UsersApi
+ private val usersApi: UsersApi,
): Injectable {
sealed class LoginState {
object Nothing: LoginState()
@@ -46,6 +48,7 @@ class SessionController(
val loginStateFlow = MutableStateFlow<LoginState?>(null)
val userFlow = MutableStateFlow<User?>(null)
+ val hasSession: Boolean get() = sessionManager.hasSession
fun getSession() {
loginStateFlow.value = LoginState.Loading
@@ -59,19 +62,6 @@ class SessionController(
}
}
- fun restoreSession() {
- loginStateFlow.value = LoginState.Loading
- GlobalScope.launch {
- try {
- userFlow.value = sessionApi.sessionGet()
- loginStateFlow.value = LoginState.Success
- } catch (e: Exception) {
- e.printStackTrace()
- loginStateFlow.value = LoginState.Nothing
- }
- }
- }
-
fun login(body: SessionBody) {
val url = body.url.trim()
val email = body.email.trim()
diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt
index 5298df3..9f3a142 100644
--- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt
+++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt
@@ -22,6 +22,8 @@ import kotlinx.datetime.*
@DelicateCoroutinesApi
class ReportDates {
+
+ // Don't remove! Used by iOS
enum class PeriodTypes {
TODAY,
LAST_24,
@@ -35,7 +37,7 @@ class ReportDates {
sealed class ReportPeriod {
val timezone = TimeZone.currentSystemDefault()
- val clock = Clock.System
+ private val clock = Clock.System
val instant = clock.now()
val dateTime = instant.toLocalDateTime(timezone)
val date = dateTime.date
@@ -47,7 +49,7 @@ class ReportDates {
return formatDateTime(from) to formatDateTime(to)
}
- fun formatDateTime(dateTime: LocalDateTime) =
+ private fun formatDateTime(dateTime: LocalDateTime) =
dateTime.toInstant(timezone).toString()
class Today : ReportPeriod() {
diff --git a/shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt b/shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt
new file mode 100644
index 0000000..d112c11
--- /dev/null
+++ b/shared/src/iosMain/kotlin/mx/trackermap/TrackerMap/controllers/NetworkController.kt
@@ -0,0 +1,25 @@
+package mx.trackermap.TrackerMap.controllers
+
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import mx.trackermap.TrackerMap.Injectable
+import platform.Network.*
+import platform.darwin.*
+
+actual class NetworkController: Injectable {
+ private val monitor = nw_path_monitor_create()
+ private val queue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND.toLong(), 0u)
+ private val _networkAvailable = MutableStateFlow<Boolean?>(null)
+ actual val networkAvailable = _networkAvailable.asStateFlow()
+
+ private val updateHandler: nw_path_monitor_update_handler_t = { path: nw_path_t ->
+ val status = nw_path_get_status(path)
+ _networkAvailable.value = status in arrayOf(nw_path_status_satisfied, nw_path_status_satisfiable)
+ }
+
+ init {
+ nw_path_monitor_set_update_handler(monitor, updateHandler)
+ nw_path_monitor_set_queue(monitor, queue)
+ nw_path_monitor_start(monitor)
+ }
+} \ No newline at end of file