diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt index 39449c42..b5d34604 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt @@ -28,6 +28,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage import pl.szczodrzynski.edziennik.data.db.entity.Notification import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.full.EventFull +import pl.szczodrzynski.edziennik.ext.keys import pl.szczodrzynski.edziennik.ext.md5 import pl.szczodrzynski.edziennik.ext.toApiError import pl.szczodrzynski.edziennik.ext.toErrorCode @@ -126,7 +127,10 @@ class SzkolnyApi(val app: App) : CoroutineScope { * or null if it's a HTTP call error. */ @Throws(Exception::class) - private inline fun parseResponse(response: Response>): T { + private inline fun parseResponse( + response: Response>, + updateDeviceHash: Boolean = false, + ): T { app.config.update = response.body()?.update?.let { update -> if (update.versionCode > BuildConfig.VERSION_CODE) { if (update.updateMandatory @@ -144,6 +148,14 @@ class SzkolnyApi(val app: App) : CoroutineScope { } if (response.isSuccessful && response.body()?.success == true) { + // update the device's hash on success + if (updateDeviceHash) { + val hash = getDevice()?.toString()?.md5() + if (hash != null) { + app.config.hash = hash + } + } + if (Unit is T) { return Unit } @@ -168,7 +180,6 @@ class SzkolnyApi(val app: App) : CoroutineScope { throw SzkolnyApiException(body?.errors?.firstOrNull()) } - @Throws(Exception::class) private fun getDevice() = run { val config = app.config val device = Device( @@ -181,51 +192,50 @@ class SzkolnyApi(val app: App) : CoroutineScope { appVersionCode = BuildConfig.VERSION_CODE, syncInterval = app.config.sync.interval ) - device.toString().md5().let { - if (it == config.hash) - null - else { - config.hash = it - device - } - } + val hash = device.toString().md5() + if (hash == config.hash) + return@run null + return@run device } @Throws(Exception::class) fun getEvents(profiles: List, notifications: List, blacklistedIds: List, lastSyncTime: Long): List { val teams = app.db.teamDao().allNow + val users = profiles.mapNotNull { profile -> + val config = app.config.getFor(profile.id) + val user = ServerSyncRequest.User( + profile.userCode, + profile.studentNameLong, + profile.studentNameShort, + profile.loginStoreType, + teams.filter { it.profileId == profile.id }.map { it.code } + ) + val hash = user.toString().md5() + if (hash == config.hash) + return@mapNotNull null + return@mapNotNull user to config + } + val response = api.serverSync(ServerSyncRequest( deviceId = app.deviceId, device = getDevice(), userCodes = profiles.map { it.userCode }, - users = profiles.mapNotNull { profile -> - val config = app.config.getFor(profile.id) - val user = ServerSyncRequest.User( - profile.userCode, - profile.studentNameLong, - profile.studentNameShort, - profile.loginStoreType, - teams.filter { it.profileId == profile.id }.map { it.code } - ) - user.toString().md5().let { - if (it == config.hash) - null - else { - config.hash = it - user - } - } - }, + users = users.keys(), lastSync = lastSyncTime, notifications = notifications.map { ServerSyncRequest.Notification(it.profileName ?: "", it.type, it.text) } )).execute() - val (events, hasBrowsers) = parseResponse(response) + val (events, hasBrowsers) = parseResponse(response, updateDeviceHash = true) hasBrowsers?.let { app.config.sync.webPushEnabled = it } + // update users' hashes on success + users.forEach { (user, config) -> + config.hash = user.toString().md5() + } + val eventList = mutableListOf() events.forEach { event -> @@ -270,7 +280,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { shareTeamCode = team.code, event = event )).execute() - parseResponse(response) + parseResponse(response, updateDeviceHash = true) } @Throws(Exception::class) @@ -284,7 +294,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { unshareTeamCode = team.code, eventId = event.id )).execute() - parseResponse(response) + parseResponse(response, updateDeviceHash = true) } /*fun eventEditRequest(requesterName: String, event: Event): ApiResponse? { @@ -301,7 +311,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { pairToken = pairToken )).execute() - return parseResponse(response).browsers + return parseResponse(response, updateDeviceHash = true).browsers } @Throws(Exception::class) @@ -312,7 +322,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { action = "listBrowsers" )).execute() - return parseResponse(response).browsers + return parseResponse(response, updateDeviceHash = true).browsers } @Throws(Exception::class) @@ -324,7 +334,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { browserId = browserId )).execute() - return parseResponse(response).browsers + return parseResponse(response, updateDeviceHash = true).browsers } @Throws(Exception::class) @@ -335,7 +345,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { appVersion = BuildConfig.VERSION_NAME, errors = errors )).execute() - parseResponse(response) + parseResponse(response, updateDeviceHash = true) } @Throws(Exception::class) @@ -345,7 +355,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { device = getDevice(), userCode = userCode )).execute() - parseResponse(response) + parseResponse(response, updateDeviceHash = true) } @Throws(Exception::class) @@ -364,7 +374,7 @@ class SzkolnyApi(val app: App) : CoroutineScope { text = text )).execute() - return parseResponse(response).message + return parseResponse(response, updateDeviceHash = true).message } @Throws(Exception::class) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ext/ArrayExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ext/ArrayExtensions.kt index 34da3ec0..e263627c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ext/ArrayExtensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ext/ArrayExtensions.kt @@ -59,20 +59,8 @@ fun SparseIntArray.values(): List { return result } -fun List>.keys(): List { - val result = mutableListOf() - forEach { pair -> - result += pair.first - } - return result -} -fun List>.values(): List { - val result = mutableListOf() - forEach { pair -> - result += pair.second - } - return result -} +fun List>.keys() = map { it.first } +fun List>.values() = map { it.second } fun List.toSparseArray(destination: SparseArray, key: (T) -> Int) { forEach {