بهبودهای همگامسازی شبکه و ارتقا به نسخه 1.1.1
This commit is contained in:
1 parent
2c52c2c538
commit
a85d83dc7e
4 files changed
+37
-44
No files matched your search
@@ -30,8 +30,8 @@ android {
|
|||||||
applicationId = "com.oqba26.monthlypaymentapp"
|
applicationId = "com.oqba26.monthlypaymentapp"
|
||||||
minSdk = 25
|
minSdk = 25
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 11
|
versionCode = 12
|
||||||
versionName = "1.1.0"
|
versionName = "1.1.1"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables { useSupportLibrary = true }
|
vectorDrawables { useSupportLibrary = true }
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,13 @@ android {
|
|||||||
targetCompatibility = JavaVersion.VERSION_21
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
isCoreLibraryDesugaringEnabled = true
|
isCoreLibraryDesugaringEnabled = true
|
||||||
}
|
}
|
||||||
kotlinOptions { jvmTarget = "21" }
|
kotlinOptions {
|
||||||
|
jvmTarget = "21"
|
||||||
|
freeCompilerArgs += listOf(
|
||||||
|
"-opt-in=kotlinx.serialization.InternalSerializationApi",
|
||||||
|
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi"
|
||||||
|
)
|
||||||
|
}
|
||||||
kotlin { jvmToolchain(21) }
|
kotlin { jvmToolchain(21) }
|
||||||
|
|
||||||
packaging {
|
packaging {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@file:OptIn(InternalSerializationApi::class)
|
||||||
|
|
||||||
package com.oqba26.monthlypaymentapp.data.remote
|
package com.oqba26.monthlypaymentapp.data.remote
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -5,6 +7,7 @@ import io.ktor.client.HttpClient
|
|||||||
import io.ktor.client.engine.okhttp.OkHttp
|
import io.ktor.client.engine.okhttp.OkHttp
|
||||||
import io.ktor.client.plugins.HttpTimeout
|
import io.ktor.client.plugins.HttpTimeout
|
||||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||||
|
import io.ktor.client.plugins.timeout
|
||||||
import io.ktor.client.request.delete
|
import io.ktor.client.request.delete
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
import io.ktor.client.request.header
|
import io.ktor.client.request.header
|
||||||
@@ -25,6 +28,7 @@ import io.ktor.utils.io.readUTF8Line
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import kotlinx.serialization.InternalSerializationApi
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@@ -347,6 +351,10 @@ class PocketBaseClient(
|
|||||||
authToken?.let { token ->
|
authToken?.let { token ->
|
||||||
header(HttpHeaders.Authorization, "Bearer $token")
|
header(HttpHeaders.Authorization, "Bearer $token")
|
||||||
}
|
}
|
||||||
|
timeout {
|
||||||
|
requestTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS
|
||||||
|
socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS
|
||||||
|
}
|
||||||
}.execute { response ->
|
}.execute { response ->
|
||||||
val channel: ByteReadChannel = response.bodyAsChannel()
|
val channel: ByteReadChannel = response.bodyAsChannel()
|
||||||
var currentEvent = ""
|
var currentEvent = ""
|
||||||
@@ -362,6 +370,7 @@ class PocketBaseClient(
|
|||||||
val connectObj = json.decodeFromString<PocketBaseConnectEvent>(dataJson)
|
val connectObj = json.decodeFromString<PocketBaseConnectEvent>(dataJson)
|
||||||
subscribeRealtime(cleanBaseUrl, connectObj.clientId, subscriptions)
|
subscribeRealtime(cleanBaseUrl, connectObj.clientId, subscriptions)
|
||||||
Log.d(TAG, "اتصال ریلتایم برقرار شد. ClientId: ${connectObj.clientId}")
|
Log.d(TAG, "اتصال ریلتایم برقرار شد. ClientId: ${connectObj.clientId}")
|
||||||
|
emit("PB_CONNECT")
|
||||||
} else if (currentEvent.isNotEmpty()) {
|
} else if (currentEvent.isNotEmpty()) {
|
||||||
emit(currentEvent)
|
emit(currentEvent)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-37
@@ -14,9 +14,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
class NetworkRepository(
|
class NetworkRepository(
|
||||||
private val settingsRepository: SettingsRepository? = null
|
settingsRepository: SettingsRepository? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val pocketBase = ApiClient.pocketBase
|
private val pocketBase = ApiClient.pocketBase
|
||||||
@@ -43,13 +44,16 @@ class NetworkRepository(
|
|||||||
// --- Realtime Operations ---
|
// --- Realtime Operations ---
|
||||||
fun observeRealtimeChanges() {
|
fun observeRealtimeChanges() {
|
||||||
repositoryScope.launch {
|
repositoryScope.launch {
|
||||||
try {
|
while (true) {
|
||||||
pocketBase.listenRealtime(listOf("persons", "payments")).collect { event ->
|
try {
|
||||||
Log.d("PocketBase-Realtime", "Change detected in PocketBase: $event")
|
pocketBase.listenRealtime(listOf("persons", "payments")).collect { event ->
|
||||||
refresh()
|
Log.d("PocketBase-Realtime", "Change detected in PocketBase: $event")
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("PocketBase-Realtime", "Realtime connection error, retrying...", e)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
delay(3000.milliseconds)
|
||||||
Log.e("PocketBase-Realtime", "Realtime connection error, retrying...", e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,31 +156,7 @@ class NetworkRepository(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updatePersonArchivedStatus(personId: String, isArchived: Boolean): Boolean {
|
|
||||||
return try {
|
|
||||||
val currentPerson = _personsFlow.value.find { it.id == personId }
|
|
||||||
if (currentPerson != null) {
|
|
||||||
pocketBase.upsertRecord("persons", "id='$personId'", currentPerson.copy(isArchived = isArchived))
|
|
||||||
}
|
|
||||||
true
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("PocketBase", "updateArchived error", e)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun updatePersonDisplayOrder(personId: String, displayOrder: Long): Boolean {
|
|
||||||
return try {
|
|
||||||
val currentPerson = _personsFlow.value.find { it.id == personId }
|
|
||||||
if (currentPerson != null) {
|
|
||||||
pocketBase.upsertRecord("persons", "id='$personId'", currentPerson.copy(displayOrder = displayOrder))
|
|
||||||
}
|
|
||||||
true
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("PocketBase", "updateOrder error", e)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPersonsFlow(): Flow<List<Person>> = _personsFlow.asStateFlow()
|
fun getPersonsFlow(): Flow<List<Person>> = _personsFlow.asStateFlow()
|
||||||
|
|
||||||
@@ -192,19 +172,17 @@ class NetworkRepository(
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deletePayment(paymentId: String): Boolean {
|
suspend fun deletePayment(paymentId: String): Boolean {
|
||||||
var retries = 0
|
|
||||||
val maxRetries = 2
|
val maxRetries = 2
|
||||||
|
for (retries in 1..maxRetries) {
|
||||||
while (retries <= maxRetries) {
|
|
||||||
try {
|
try {
|
||||||
pocketBase.deleteRecordByFilter("payments", "id='$paymentId'")
|
pocketBase.deleteRecordByFilter("payments", "id='$paymentId'")
|
||||||
Log.d("PocketBase", "deletePayment Success: $paymentId")
|
Log.d("PocketBase", "deletePayment Success: $paymentId")
|
||||||
return true
|
return true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
retries++
|
|
||||||
Log.e("PocketBase", "deletePayment error (Attempt $retries): ${e.message}", e)
|
Log.e("PocketBase", "deletePayment error (Attempt $retries): ${e.message}", e)
|
||||||
if (retries > maxRetries) return false
|
if (retries < maxRetries) {
|
||||||
delay(1000L * retries)
|
delay((1000L * retries).milliseconds)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
+4
-4
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"versionCode": 11,
|
"versionCode": 12,
|
||||||
"versionName": "1.1.0",
|
"versionName": "1.1.1",
|
||||||
"url": "https://github.com/oqba26/MonthlyPaymentApp/releases/download/v1.1.0/MonthlyPaymentApp-v1.1.0.apk",
|
"url": "https://github.com/oqba26/MonthlyPaymentApp/releases/download/v1.1.1/MonthlyPaymentApp-v1.1.1.apk",
|
||||||
"releaseNotes": "اصلاح اسکرول یکپارچه دیالوگ گزارش مالی و نمایش کامل تفکیک ماههای گذشته",
|
"releaseNotes": "بهبودهای همگامسازی شبکه و پایداری لایو PocketBase",
|
||||||
"isForceUpdate": false
|
"isForceUpdate": false
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user