From 6213bbf30fa737ff459938512a2c005d432561d7 Mon Sep 17 00:00:00 2001 From: Oqba Date: Sat, 24 Oct 2026 07:37:35 +0330 Subject: [PATCH] =?UTF-8?q?=D8=A8=D9=87=D8=A8=D9=88=D8=AF=D9=87=D8=A7?= =?UTF-8?q?=DB=8C=20=D9=87=D9=85=DA=AF=D8=A7=D9=85=E2=80=8C=D8=B3=D8=A7?= =?UTF-8?q?=D8=B2=DB=8C=20=D8=B4=D8=A8=DA=A9=D9=87=20=D9=88=20=D8=A7=D8=B1?= =?UTF-8?q?=D8=AA=D9=82=D8=A7=20=D8=A8=D9=87=20=D9=86=D8=B3=D8=AE=D9=87=20?= =?UTF-8?q?1.1.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 12 +++-- .../data/remote/PocketBaseClient.kt | 9 ++++ .../data/repository/NetworkRepository.kt | 52 ++++++------------- update.json | 8 +-- 4 files changed, 37 insertions(+), 44 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ddbf6e5..0ee0d3e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,8 +30,8 @@ android { applicationId = "com.oqba26.monthlypaymentapp" minSdk = 25 targetSdk = 34 - versionCode = 11 - versionName = "1.1.0" + versionCode = 12 + versionName = "1.1.1" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } } @@ -76,7 +76,13 @@ android { targetCompatibility = JavaVersion.VERSION_21 isCoreLibraryDesugaringEnabled = true } - kotlinOptions { jvmTarget = "21" } + kotlinOptions { + jvmTarget = "21" + freeCompilerArgs += listOf( + "-opt-in=kotlinx.serialization.InternalSerializationApi", + "-opt-in=kotlinx.serialization.ExperimentalSerializationApi" + ) + } kotlin { jvmToolchain(21) } packaging { diff --git a/app/src/main/java/com/oqba26/monthlypaymentapp/data/remote/PocketBaseClient.kt b/app/src/main/java/com/oqba26/monthlypaymentapp/data/remote/PocketBaseClient.kt index 01e86d6..85a8446 100644 --- a/app/src/main/java/com/oqba26/monthlypaymentapp/data/remote/PocketBaseClient.kt +++ b/app/src/main/java/com/oqba26/monthlypaymentapp/data/remote/PocketBaseClient.kt @@ -1,3 +1,5 @@ +@file:OptIn(InternalSerializationApi::class) + package com.oqba26.monthlypaymentapp.data.remote import android.util.Log @@ -5,6 +7,7 @@ import io.ktor.client.HttpClient import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.plugins.HttpTimeout import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.plugins.timeout import io.ktor.client.request.delete import io.ktor.client.request.get import io.ktor.client.request.header @@ -25,6 +28,7 @@ import io.ktor.utils.io.readUTF8Line import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow +import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject @@ -347,6 +351,10 @@ class PocketBaseClient( authToken?.let { token -> header(HttpHeaders.Authorization, "Bearer $token") } + timeout { + requestTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + } }.execute { response -> val channel: ByteReadChannel = response.bodyAsChannel() var currentEvent = "" @@ -362,6 +370,7 @@ class PocketBaseClient( val connectObj = json.decodeFromString(dataJson) subscribeRealtime(cleanBaseUrl, connectObj.clientId, subscriptions) Log.d(TAG, "اتصال ریل‌تایم برقرار شد. ClientId: ${connectObj.clientId}") + emit("PB_CONNECT") } else if (currentEvent.isNotEmpty()) { emit(currentEvent) } diff --git a/app/src/main/java/com/oqba26/monthlypaymentapp/data/repository/NetworkRepository.kt b/app/src/main/java/com/oqba26/monthlypaymentapp/data/repository/NetworkRepository.kt index 2c3cc78..518d8ad 100644 --- a/app/src/main/java/com/oqba26/monthlypaymentapp/data/repository/NetworkRepository.kt +++ b/app/src/main/java/com/oqba26/monthlypaymentapp/data/repository/NetworkRepository.kt @@ -14,9 +14,10 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import java.util.UUID +import kotlin.time.Duration.Companion.milliseconds class NetworkRepository( - private val settingsRepository: SettingsRepository? = null + settingsRepository: SettingsRepository? = null ) { private val pocketBase = ApiClient.pocketBase @@ -43,13 +44,16 @@ class NetworkRepository( // --- Realtime Operations --- fun observeRealtimeChanges() { repositoryScope.launch { - try { - pocketBase.listenRealtime(listOf("persons", "payments")).collect { event -> - Log.d("PocketBase-Realtime", "Change detected in PocketBase: $event") - refresh() + while (true) { + try { + pocketBase.listenRealtime(listOf("persons", "payments")).collect { event -> + 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) { - Log.e("PocketBase-Realtime", "Realtime connection error, retrying...", e) + delay(3000.milliseconds) } } } @@ -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> = _personsFlow.asStateFlow() @@ -192,19 +172,17 @@ class NetworkRepository( } suspend fun deletePayment(paymentId: String): Boolean { - var retries = 0 val maxRetries = 2 - - while (retries <= maxRetries) { + for (retries in 1..maxRetries) { try { pocketBase.deleteRecordByFilter("payments", "id='$paymentId'") Log.d("PocketBase", "deletePayment Success: $paymentId") return true } catch (e: Exception) { - retries++ Log.e("PocketBase", "deletePayment error (Attempt $retries): ${e.message}", e) - if (retries > maxRetries) return false - delay(1000L * retries) + if (retries < maxRetries) { + delay((1000L * retries).milliseconds) + } } } return false diff --git a/update.json b/update.json index 3217216..3c0c6dd 100644 --- a/update.json +++ b/update.json @@ -1,7 +1,7 @@ { - "versionCode": 11, - "versionName": "1.1.0", - "url": "https://github.com/oqba26/MonthlyPaymentApp/releases/download/v1.1.0/MonthlyPaymentApp-v1.1.0.apk", - "releaseNotes": "اصلاح اسکرول یکپارچه دیالوگ گزارش مالی و نمایش کامل تفکیک ماه‌های گذشته", + "versionCode": 12, + "versionName": "1.1.1", + "url": "https://github.com/oqba26/MonthlyPaymentApp/releases/download/v1.1.1/MonthlyPaymentApp-v1.1.1.apk", + "releaseNotes": "بهبودهای همگام‌سازی شبکه و پایداری لایو PocketBase", "isForceUpdate": false }