mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-24 10:35:19 +00:00
Merge pull request #1669 from oxen-io/feature/dynamic-community-rights
Listening to changes in community write access
This commit is contained in:
commit
d044f12d3f
@ -710,7 +710,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
|
||||
// called from onCreate
|
||||
private fun setUpInputBar() {
|
||||
binding.inputBar.isGone = viewModel.hidesInputBar()
|
||||
binding.inputBar.delegate = this
|
||||
binding.inputBarRecordingView.delegate = this
|
||||
// GIF button
|
||||
@ -854,6 +853,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
// Conversation should be deleted now, just go back
|
||||
finish()
|
||||
}
|
||||
|
||||
binding.inputBar.isGone = uiState.hideInputBar
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -948,11 +949,20 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
block(deleteThread = true)
|
||||
}
|
||||
binding.declineMessageRequestButton.setOnClickListener {
|
||||
viewModel.declineMessageRequest()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@ConversationActivityV2)
|
||||
fun doDecline() {
|
||||
viewModel.declineMessageRequest()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@ConversationActivityV2)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
showSessionDialog {
|
||||
title(R.string.delete)
|
||||
text(resources.getString(R.string.messageRequestsDelete))
|
||||
dangerButton(R.string.delete) { doDecline() }
|
||||
button(R.string.cancel)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,12 @@ import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import org.session.libsession.database.MessageDataProvider
|
||||
@ -29,6 +33,7 @@ import org.thoughtcrime.securesms.audio.AudioSlidePlayer
|
||||
import org.thoughtcrime.securesms.database.Storage
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.groups.OpenGroupManager
|
||||
import org.thoughtcrime.securesms.repository.ConversationRepository
|
||||
import java.util.UUID
|
||||
|
||||
@ -65,6 +70,8 @@ class ConversationViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private var communityWriteAccessJob: Job? = null
|
||||
|
||||
private var _openGroup: RetrieveOnce<OpenGroup> = RetrieveOnce {
|
||||
storage.getOpenGroup(threadId)
|
||||
}
|
||||
@ -105,6 +112,27 @@ class ConversationViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// listen to community write access updates from this point
|
||||
communityWriteAccessJob?.cancel()
|
||||
communityWriteAccessJob = viewModelScope.launch {
|
||||
OpenGroupManager.getCommunitiesWriteAccessFlow()
|
||||
.map {
|
||||
if(openGroup?.groupId != null)
|
||||
it[openGroup?.groupId]
|
||||
else null
|
||||
}
|
||||
.filterNotNull()
|
||||
.collect{
|
||||
// update our community object
|
||||
_openGroup.updateTo(openGroup?.copy(canWrite = it))
|
||||
// when we get an update on the write access of a community
|
||||
// we need to update the input text accordingly
|
||||
_uiState.update { state ->
|
||||
state.copy(hideInputBar = shouldHideInputBar())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
@ -267,7 +295,7 @@ class ConversationViewModel(
|
||||
* - We are dealing with a contact from a community (blinded recipient) that does not allow
|
||||
* requests form community members
|
||||
*/
|
||||
fun hidesInputBar(): Boolean = openGroup?.canWrite == false ||
|
||||
fun shouldHideInputBar(): Boolean = openGroup?.canWrite == false ||
|
||||
blindedRecipient?.blocksCommunityMessageRequests == true
|
||||
|
||||
fun legacyBannerRecipient(context: Context): Recipient? = recipient?.run {
|
||||
@ -311,7 +339,8 @@ data class UiMessage(val id: Long, val message: String)
|
||||
data class ConversationUiState(
|
||||
val uiMessages: List<UiMessage> = emptyList(),
|
||||
val isMessageRequestAccepted: Boolean? = null,
|
||||
val conversationExists: Boolean
|
||||
val conversationExists: Boolean,
|
||||
val hideInputBar: Boolean = false
|
||||
)
|
||||
|
||||
data class RetrieveOnce<T>(val retrieval: () -> T?) {
|
||||
|
@ -18,7 +18,7 @@ class LinkPreviewDialog(private val onEnabled: () -> Unit) : DialogFragment() {
|
||||
title(R.string.linkPreviewsEnable)
|
||||
val txt = context.getSubbedCharSequence(R.string.linkPreviewsFirstDescription, APP_NAME_KEY to APP_NAME)
|
||||
text(txt)
|
||||
button(R.string.enable) { enable() }
|
||||
dangerButton(R.string.enable) { enable() }
|
||||
cancelButton { dismiss() }
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,9 @@ import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.squareup.phrase.Phrase
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import java.util.concurrent.Executors
|
||||
import network.loki.messenger.R
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
@ -39,6 +42,9 @@ object OpenGroupManager {
|
||||
return true
|
||||
}
|
||||
|
||||
// flow holding information on write access for our current communities
|
||||
private val _communityWriteAccess: MutableStateFlow<Map<String, Boolean>> = MutableStateFlow(emptyMap())
|
||||
|
||||
fun startPolling() {
|
||||
if (isPolling) { return }
|
||||
isPolling = true
|
||||
@ -66,6 +72,8 @@ object OpenGroupManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun getCommunitiesWriteAccessFlow() = _communityWriteAccess.asStateFlow()
|
||||
|
||||
@WorkerThread
|
||||
fun add(server: String, room: String, publicKey: String, context: Context): Pair<Long,OpenGroupApi.RoomInfo?> {
|
||||
val openGroupID = "$server.$room"
|
||||
@ -164,9 +172,13 @@ object OpenGroupManager {
|
||||
|
||||
fun updateOpenGroup(openGroup: OpenGroup, context: Context) {
|
||||
val threadDB = DatabaseComponent.get(context).lokiThreadDatabase()
|
||||
val openGroupID = "${openGroup.server}.${openGroup.room}"
|
||||
val threadID = GroupManager.getOpenGroupThreadID(openGroupID, context)
|
||||
val threadID = GroupManager.getOpenGroupThreadID(openGroup.groupId, context)
|
||||
threadDB.setOpenGroupChat(openGroup, threadID)
|
||||
|
||||
// update write access for this community
|
||||
val writeAccesses = _communityWriteAccess.value.toMutableMap()
|
||||
writeAccesses[openGroup.groupId] = openGroup.canWrite
|
||||
_communityWriteAccess.value = writeAccesses
|
||||
}
|
||||
|
||||
fun isUserModerator(context: Context, groupId: String, standardPublicKey: String, blindedPublicKey: String? = null): Boolean {
|
||||
|
@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.SessionShieldIcon
|
||||
import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.SlimPrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
@ -60,8 +61,8 @@ internal fun SeedReminder(startRecoveryPasswordActivity: () -> Unit) {
|
||||
style = LocalType.current.small
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.width(LocalDimensions.current.xsSpacing))
|
||||
SlimPrimaryOutlineButton(
|
||||
Spacer(Modifier.width(LocalDimensions.current.smallSpacing))
|
||||
PrimaryOutlineButton(
|
||||
text = stringResource(R.string.theContinue),
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterVertically)
|
||||
|
@ -108,7 +108,7 @@ class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), Conversat
|
||||
showSessionDialog {
|
||||
title(R.string.delete)
|
||||
text(resources.getString(R.string.messageRequestsDelete))
|
||||
button(R.string.delete) { doDecline() }
|
||||
dangerButton(R.string.delete) { doDecline() }
|
||||
button(R.string.cancel)
|
||||
}
|
||||
}
|
||||
@ -129,9 +129,10 @@ class MessageRequestsActivity : PassphraseRequiredActionBarActivity(), Conversat
|
||||
}
|
||||
|
||||
showSessionDialog {
|
||||
title(resources.getString(R.string.clearAll))
|
||||
text(resources.getString(R.string.messageRequestsClearAllExplanation))
|
||||
button(R.string.yes) { doDeleteAllAndBlock() }
|
||||
button(R.string.no)
|
||||
dangerButton(R.string.clear) { doDeleteAllAndBlock() }
|
||||
button(R.string.cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,6 @@
|
||||
android:title="@string/helpReportABug"
|
||||
android:summary="@string/helpReportABugExportLogsDescription"
|
||||
android:widgetLayout="@layout/export_logs_widget" />
|
||||
|
||||
<!-- Note: Having this as `android:layout` rather than `android:layoutWidget` allows it to fit the screen width -->
|
||||
<Preference android:layout="@layout/preference_widget_progress" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory>
|
||||
|
@ -203,7 +203,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
|
||||
@Test
|
||||
fun `local recipient should have input and no blinded recipient`() {
|
||||
whenever(recipient.isLocalNumber).thenReturn(true)
|
||||
assertThat(viewModel.hidesInputBar(), equalTo(false))
|
||||
assertThat(viewModel.shouldHideInputBar(), equalTo(false))
|
||||
assertThat(viewModel.blindedRecipient, nullValue())
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ class ConversationViewModelTest: BaseViewModelTest() {
|
||||
}
|
||||
whenever(repository.maybeGetBlindedRecipient(recipient)).thenReturn(blinded)
|
||||
assertThat(viewModel.blindedRecipient, notNullValue())
|
||||
assertThat(viewModel.hidesInputBar(), equalTo(true))
|
||||
assertThat(viewModel.shouldHideInputBar(), equalTo(true))
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user