بهبودهای همگام‌سازی شبکه و ارتقا به نسخه 1.1.1
Android Release / build (push) Canceled after 5s

This commit is contained in:
Oqba committed 2026-10-24 07:37:35 +03:30
1 parent 2c52c2c538
commit 6213bbf30f
4 files changed
+31 -38

No files matched your search

+9 -3
View File
@@ -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)
} }
@@ -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,6 +44,7 @@ class NetworkRepository(
// --- Realtime Operations --- // --- Realtime Operations ---
fun observeRealtimeChanges() { fun observeRealtimeChanges() {
repositoryScope.launch { repositoryScope.launch {
while (true) {
try { try {
pocketBase.listenRealtime(listOf("persons", "payments")).collect { event -> pocketBase.listenRealtime(listOf("persons", "payments")).collect { event ->
Log.d("PocketBase-Realtime", "Change detected in PocketBase: $event") Log.d("PocketBase-Realtime", "Change detected in PocketBase: $event")
@@ -51,6 +53,8 @@ class NetworkRepository(
} catch (e: Exception) { } catch (e: Exception) {
Log.e("PocketBase-Realtime", "Realtime connection error, retrying...", e) 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<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
View File
@@ -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
} }