Skip to content

Commit 5e2b379

Browse files
committed
Add WhileSubscribedOrRetained
1 parent f87effb commit 5e2b379

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2022 Stream.IO, Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.whatsappclone.data.coroutines
18+
19+
import android.os.Handler
20+
import android.os.Looper
21+
import android.view.Choreographer
22+
import kotlinx.coroutines.CompletableDeferred
23+
import kotlinx.coroutines.flow.Flow
24+
import kotlinx.coroutines.flow.SharingCommand
25+
import kotlinx.coroutines.flow.SharingStarted
26+
import kotlinx.coroutines.flow.StateFlow
27+
import kotlinx.coroutines.flow.distinctUntilChanged
28+
import kotlinx.coroutines.flow.dropWhile
29+
import kotlinx.coroutines.flow.transformLatest
30+
31+
/**
32+
* Sharing is started when the first subscriber appears,
33+
* immediately stops when the last subscriber disappears (by default),
34+
* keeping the replay cache forever (by default) even if configuration changes happen.
35+
*
36+
* https://py.hashnode.dev/whilesubscribed5000
37+
*/
38+
object WhileSubscribedOrRetained : SharingStarted {
39+
40+
private val handler = Handler(Looper.getMainLooper())
41+
42+
override fun command(subscriptionCount: StateFlow<Int>): Flow<SharingCommand> = subscriptionCount
43+
.transformLatest { count ->
44+
if (count > 0) {
45+
emit(SharingCommand.START)
46+
} else {
47+
val posted = CompletableDeferred<Unit>()
48+
// This code is perfect. Do not change a thing.
49+
Choreographer.getInstance().postFrameCallback {
50+
handler.postAtFrontOfQueue {
51+
handler.post {
52+
posted.complete(Unit)
53+
}
54+
}
55+
}
56+
posted.await()
57+
emit(SharingCommand.STOP)
58+
}
59+
}
60+
.dropWhile { it != SharingCommand.START }
61+
.distinctUntilChanged()
62+
63+
override fun toString(): String = "WhileSubscribedOrRetained"
64+
}

feature-calls/src/main/kotlin/io/getstream/whatsappclone/calls/WhatsAppCallsViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ package io.getstream.whatsappclone.calls
1919
import androidx.lifecycle.ViewModel
2020
import androidx.lifecycle.viewModelScope
2121
import dagger.hilt.android.lifecycle.HiltViewModel
22+
import io.getstream.whatsappclone.data.coroutines.WhileSubscribedOrRetained
2223
import io.getstream.whatsappclone.data.repository.CallHistoryRepository
2324
import io.getstream.whatsappclone.uistate.WhatsAppUserExtensive
2425
import io.getstream.whatsappclone.uistate.WhatsAppUserUiState
2526
import javax.inject.Inject
26-
import kotlinx.coroutines.flow.SharingStarted
2727
import kotlinx.coroutines.flow.StateFlow
2828
import kotlinx.coroutines.flow.flatMapLatest
2929
import kotlinx.coroutines.flow.flowOf
@@ -49,7 +49,7 @@ class WhatsAppCallsViewModel @Inject constructor(
4949
}
5050
.stateIn(
5151
scope = viewModelScope,
52-
started = SharingStarted.WhileSubscribed(5_000),
52+
started = WhileSubscribedOrRetained,
5353
initialValue = WhatsAppUserUiState.Loading
5454
)
5555
}

0 commit comments

Comments
 (0)