Skip to content

Commit cdfc7c3

Browse files
committed
Fix crash issue
1 parent 0c6dec4 commit cdfc7c3

File tree

5 files changed

+46
-22
lines changed

5 files changed

+46
-22
lines changed

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ android {
4141
else -> 0
4242
}
4343

44-
val vCode = 412
44+
val vCode = 415
4545
versionCode = vCode - singleAbiNum
46-
versionName = "2.1.10"
46+
versionName = "2.1.11"
4747

4848
ndk {
4949
//noinspection ChromeOsAbiSupport

app/src/main/java/com/ismartcoding/plain/ui/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class MainActivity : AppCompatActivity() {
131131
val service = Intent(this, ScreenMirrorService::class.java)
132132
service.putExtra("code", result.resultCode)
133133
service.putExtra("data", result.data)
134-
ContextCompat.startForegroundService(this, service)
134+
startService(service)
135135
} else {
136136
sendEvent(WebSocketEvent(EventType.SCREEN_MIRRORING, image))
137137
}

app/src/main/java/com/ismartcoding/plain/ui/models/ChatListViewModel.kt

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.ismartcoding.plain.web.ChatApiManager
1818
import kotlinx.coroutines.Dispatchers
1919
import kotlinx.coroutines.Job
2020
import kotlinx.coroutines.launch
21+
import kotlinx.coroutines.withContext
2122
import kotlinx.datetime.Clock
2223
import kotlinx.datetime.Instant
2324
import kotlin.time.Duration.Companion.seconds
@@ -96,19 +97,35 @@ class ChatListViewModel : ViewModel() {
9697
}
9798
}
9899

99-
latestChatCache.clear()
100-
latestChatCache.putAll(chatCache)
101-
102-
// Sort paired peers by latest chat time (most recent first), then by name
103-
pairedPeers.clear()
104-
pairedPeers.addAll(allPeers.filter { it.status == "paired" }.toList()
105-
.sortedWith(compareByDescending<DPeer> { getLatestChat(it.id)?.createdAt ?: Instant.DISTANT_PAST }.thenBy { Pinyin.toPinyin(it.name) }))
106-
unpairedPeers.clear()
107-
unpairedPeers.addAll(allPeers.filter { it.status == "unpaired" }.toList().sortedBy { Pinyin.toPinyin(it.name) })
100+
// Prepare new lists off the main thread
101+
val newPairedPeers = allPeers
102+
.filter { it.status == "paired" }
103+
.sortedWith(
104+
compareByDescending<DPeer> { peer ->
105+
chatCache[peer.id]?.createdAt ?: Instant.DISTANT_PAST
106+
}.thenBy { Pinyin.toPinyin(it.name) }
107+
)
108+
val newUnpairedPeers = allPeers
109+
.filter { it.status == "unpaired" }
110+
.sortedBy { Pinyin.toPinyin(it.name) }
111+
112+
// Apply state updates on the main thread to avoid snapshot violations
113+
withContext(Dispatchers.Main) {
114+
latestChatCache.clear()
115+
latestChatCache.putAll(chatCache)
116+
117+
pairedPeers.clear()
118+
pairedPeers.addAll(newPairedPeers)
119+
120+
unpairedPeers.clear()
121+
unpairedPeers.addAll(newUnpairedPeers)
122+
}
108123
} catch (e: Exception) {
109-
pairedPeers.clear()
110-
unpairedPeers.clear()
111-
latestChatCache.clear()
124+
withContext(Dispatchers.Main) {
125+
pairedPeers.clear()
126+
unpairedPeers.clear()
127+
latestChatCache.clear()
128+
}
112129
}
113130
}
114131
}
@@ -142,9 +159,12 @@ class ChatListViewModel : ViewModel() {
142159
}
143160

144161
fun updatePeerLastActive(peerId: String) {
145-
val currentMap = onlineMap.value.toMutableMap()
146-
currentMap[peerId] = Clock.System.now()
147-
onlineMap.value = currentMap
162+
// Ensure state mutation happens on the main thread
163+
viewModelScope.launch(Dispatchers.Main) {
164+
val currentMap = onlineMap.value.toMutableMap()
165+
currentMap[peerId] = Clock.System.now()
166+
onlineMap.value = currentMap
167+
}
148168
}
149169

150170
fun isPeerOnline(peerId: String): Boolean {

app/src/main/java/com/ismartcoding/plain/ui/page/chat/components/ForwardTargetDialog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fun ForwardTargetDialog(
5656
}
5757

5858
if (pairedPeers.isNotEmpty()) {
59-
items(pairedPeers) { peer ->
59+
items(pairedPeers, key = { it.id }) { peer ->
6060
PDialogListItem(
6161
modifier = Modifier.clickable {
6262
onTargetSelected(ForwardTarget.Peer(peer))

app/src/main/java/com/ismartcoding/plain/ui/page/root/contents/TabContentChat.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,10 @@ fun TabContentChat(
142142
// Device discovery timer with dynamic interval
143143
LaunchedEffect(Unit) {
144144
while (isActive) {
145+
// Snapshot the current peers list on the main thread to avoid reading state on IO
146+
val peersSnapshot = pairedPeers.toList()
145147
scope.launch(Dispatchers.IO) {
146-
pairedPeers.forEach { peer ->
148+
peersSnapshot.forEach { peer ->
147149
val key = ChatApiManager.peerKeyCache[peer.id]
148150
if (key != null) {
149151
try {
@@ -243,7 +245,8 @@ fun TabContentChat(
243245
}
244246

245247
items(
246-
items = pairedPeers,
248+
items = pairedPeers.toList(),
249+
key = { it.id }
247250
) { peer ->
248251
PeerListItem(
249252
title = peer.name,
@@ -271,7 +274,8 @@ fun TabContentChat(
271274
}
272275

273276
items(
274-
items = unpairedPeers,
277+
items = unpairedPeers.toList(),
278+
key = { it.id }
275279
) { peer ->
276280
PeerListItem(
277281
title = peer.name,

0 commit comments

Comments
 (0)