fix: compile issues and group display info for having admin

This commit is contained in:
0x330a 2023-11-13 15:39:04 +11:00
parent 639ea75bfe
commit 705f12e821
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
6 changed files with 93 additions and 94 deletions

View File

@ -14,7 +14,6 @@ import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.groups.compose.CreateGroup import org.thoughtcrime.securesms.groups.compose.CreateGroup
import org.thoughtcrime.securesms.groups.compose.CreateGroupState
import org.thoughtcrime.securesms.groups.compose.ViewState import org.thoughtcrime.securesms.groups.compose.ViewState
import org.thoughtcrime.securesms.ui.AppTheme import org.thoughtcrime.securesms.ui.AppTheme
@ -32,7 +31,6 @@ class CreateGroupTests {
val nameDesc = application.getString(R.string.AccessibilityId_closed_group_edit_group_name) val nameDesc = application.getString(R.string.AccessibilityId_closed_group_edit_group_name)
val buttonDesc = application.getString(R.string.AccessibilityId_create_closed_group_create_button) val buttonDesc = application.getString(R.string.AccessibilityId_create_closed_group_create_button)
var postedGroup: CreateGroupState? = null
var backPressed = false var backPressed = false
var closePressed = false var closePressed = false
@ -53,7 +51,6 @@ class CreateGroupTests {
onNode(hasContentDescriptionExactly(buttonDesc)).performClick() onNode(hasContentDescriptionExactly(buttonDesc)).performClick()
} }
assertThat(postedGroup!!.groupName, equalTo("Name"))
assertThat(backPressed, equalTo(false)) assertThat(backPressed, equalTo(false))
assertThat(closePressed, equalTo(false)) assertThat(closePressed, equalTo(false))
@ -95,7 +92,6 @@ class CreateGroupTests {
// Accessibility IDs // Accessibility IDs
val backDesc = application.getString(R.string.new_conversation_dialog_back_button_content_description) val backDesc = application.getString(R.string.new_conversation_dialog_back_button_content_description)
var postedGroup: CreateGroupState? = null
var backPressed = false var backPressed = false
composeTest.setContent { composeTest.setContent {
@ -114,7 +110,6 @@ class CreateGroupTests {
onNode(hasContentDescriptionExactly(backDesc)).performClick() onNode(hasContentDescriptionExactly(backDesc)).performClick()
} }
assertThat(postedGroup, nullValue())
assertThat(backPressed, equalTo(true)) assertThat(backPressed, equalTo(true))
} }
@ -123,8 +118,6 @@ class CreateGroupTests {
val application = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as ApplicationContext val application = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as ApplicationContext
// Accessibility IDs // Accessibility IDs
val closeDesc = application.getString(R.string.new_conversation_dialog_close_button_content_description) val closeDesc = application.getString(R.string.new_conversation_dialog_close_button_content_description)
var postedGroup: CreateGroupState? = null
var closePressed = false var closePressed = false
composeTest.setContent { composeTest.setContent {
@ -143,7 +136,6 @@ class CreateGroupTests {
onNode(hasContentDescriptionExactly(closeDesc)).performClick() onNode(hasContentDescriptionExactly(closeDesc)).performClick()
} }
assertThat(postedGroup, nullValue())
assertThat(closePressed, equalTo(true)) assertThat(closePressed, equalTo(true))
} }

View File

@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.database.ConfigDatabase
import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.dependencies.ConfigFactory
import org.thoughtcrime.securesms.groups.CreateGroupViewModel import org.thoughtcrime.securesms.groups.CreateGroupViewModel
import org.thoughtcrime.securesms.groups.compose.CreateGroupState
@RunWith(MockitoJUnitRunner::class) @RunWith(MockitoJUnitRunner::class)
class ClosedGroupViewTests { class ClosedGroupViewTests {
@ -54,38 +53,23 @@ class ClosedGroupViewTests {
@Test @Test
fun tryCreateGroup_shouldErrorOnEmptyName() { fun tryCreateGroup_shouldErrorOnEmptyName() {
val viewModel = createViewModel() val viewModel = createViewModel()
val state = CreateGroupState( viewModel.tryCreateGroup()
groupName = "",
groupDescription = "",
members = emptySet()
)
viewModel.tryCreateGroup(state)
assertNotNull(viewModel.viewState.value?.error) assertNotNull(viewModel.viewState.value?.error)
} }
@Test @Test
fun tryCreateGroup_shouldErrorOnEmptyMembers() { fun tryCreateGroup_shouldErrorOnEmptyMembers() {
val viewModel = createViewModel() val viewModel = createViewModel()
val state = CreateGroupState( viewModel.tryCreateGroup()
groupName = "group",
groupDescription = "anything",
members = emptySet()
)
viewModel.tryCreateGroup(state)
assertNotNull(viewModel.viewState.value?.error) assertNotNull(viewModel.viewState.value?.error)
} }
@Test @Test
fun tryCreateGroup_shouldSucceedWithCorrectParameters() { fun tryCreateGroup_shouldSucceedWithCorrectParameters() {
val viewModel = createViewModel() val viewModel = createViewModel()
val state = CreateGroupState( assertNotNull(viewModel.tryCreateGroup())
groupName = "group",
groupDescription = "",
members = emptySet()
)
assertNotNull(viewModel.tryCreateGroup(state))
} }
private fun createViewModel() = CreateGroupViewModel(textSecurePreferences, storage) private fun createViewModel() = CreateGroupViewModel(storage)
} }

View File

@ -1257,7 +1257,21 @@ open class Storage(
} }
override fun getClosedGroupDisplayInfo(groupSessionId: String): GroupDisplayInfo? { override fun getClosedGroupDisplayInfo(groupSessionId: String): GroupDisplayInfo? {
return configFactory.getGroupInfoConfig(SessionId.from(groupSessionId))?.use(GroupInfoConfig::displayInfo) val infoConfig = configFactory.getGroupInfoConfig(SessionId.from(groupSessionId)) ?: return null
val isAdmin = configFactory.userGroups?.getClosedGroup(groupSessionId)?.hasAdminKey() ?: return null
return infoConfig.use { info ->
GroupDisplayInfo(
id = info.id(),
name = info.getName(),
profilePic = info.getProfilePic(),
expiryTimer = info.getExpiryTimer(),
destroyed = false,
created = info.getCreated(),
description = info.getDescription(),
isUserAdmin = isAdmin
)
}
} }
override fun setServerCapabilities(server: String, capabilities: List<String>) { override fun setServerCapabilities(server: String, capabilities: List<String>) {

View File

@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.rememberScaffoldState import androidx.compose.material.rememberScaffoldState
@ -61,6 +62,58 @@ fun EditClosedGroupScreen(
} }
class EditGroupViewModel @AssistedInject constructor(
@Assisted private val groupSessionId: String,
private val storage: StorageProtocol): ViewModel() {
val viewState = viewModelScope.launchMolecule(Immediate) {
val currentUserId = rememberSaveable {
storage.getUserPublicKey()!!
}
val closedGroupInfo = remember {
storage.getLibSessionClosedGroup(groupSessionId)!!
}
val closedGroup = remember(closedGroupInfo) {
storage.getClosedGroupDisplayInfo(groupSessionId)!!
}
val closedGroupMembers = remember(closedGroupInfo) {
storage.getMembers(groupSessionId).map { member ->
MemberViewModel(
memberName = member.name,
memberSessionId = member.sessionId,
currentUser = member.sessionId == currentUserId,
memberState = memberStateOf(member)
)
}
}
val name = closedGroup.name
val description = closedGroup.description
EditGroupState(
EditGroupViewState.Group(
groupName = name,
groupDescription = description,
memberStateList = closedGroupMembers,
admin = closedGroup.isUserAdmin
)
) { event ->
}
}
@AssistedFactory
interface Factory {
fun create(groupSessionId: String): EditGroupViewModel
}
}
@Composable @Composable
fun EditGroupView( fun EditGroupView(
onBack: ()->Unit, onBack: ()->Unit,
@ -114,6 +167,14 @@ fun EditGroupView(
.align(CenterVertically), .align(CenterVertically),
) )
// if admin add member outline button TODO // if admin add member outline button TODO
if (viewState.admin) {
OutlinedButton(onClick = { /*TODO*/ }) {
Text(
text = stringResource(id = R.string.activity_edit_closed_group_add_members),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
)
}
}
} }
Divider() Divider()
LazyColumn(modifier = Modifier) { LazyColumn(modifier = Modifier) {
@ -124,10 +185,19 @@ fun EditGroupView(
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 8.dp, horizontal = 16.dp)) { .padding(vertical = 8.dp, horizontal = 16.dp)) {
ContactPhoto(member.memberSessionId) ContactPhoto(member.memberSessionId)
Column(modifier = Modifier.weight(1f)) { Column(modifier = Modifier
.weight(1f)
.align(CenterVertically)) {
Row(modifier = Modifier.fillMaxSize()) { Row(modifier = Modifier.fillMaxSize()) {
// Needs
MemberName(name = member.memberName ?: member.memberSessionId, modifier = Modifier.align(CenterVertically)) MemberName(name = member.memberName ?: member.memberSessionId, modifier = Modifier.align(CenterVertically))
} }
if (member.memberState !in listOf(MemberState.Member, MemberState.Admin)) {
Text(
text = member.memberState.toString(),
modifier = Modifier.fillMaxWidth(),
)
}
} }
} }
} }
@ -137,58 +207,6 @@ fun EditGroupView(
} }
} }
class EditGroupViewModel @AssistedInject constructor(
@Assisted private val groupSessionId: String,
private val storage: StorageProtocol): ViewModel() {
val viewState = viewModelScope.launchMolecule(Immediate) {
val currentUserId = rememberSaveable {
storage.getUserPublicKey()!!
}
val closedGroupInfo = remember {
storage.getLibSessionClosedGroup(groupSessionId)!!
}
val closedGroup = remember(closedGroupInfo) {
storage.getClosedGroupDisplayInfo(groupSessionId)!!
}
val closedGroupMembers = remember(closedGroupInfo) {
storage.getMembers(groupSessionId).map { member ->
MemberViewModel(
memberName = member.name,
memberSessionId = member.sessionId,
currentUser = member.sessionId == currentUserId,
memberState = memberStateOf(member)
)
}
}
val name = closedGroup.name
val description = closedGroup.description
EditGroupState(
EditGroupViewState.Group(
groupName = name,
groupDescription = description,
memberStateList = closedGroupMembers,
)
) { event ->
}
}
@AssistedFactory
interface Factory {
fun create(groupSessionId: String): EditGroupViewModel
}
}
data class EditGroupState( data class EditGroupState(
val viewState: EditGroupViewState, val viewState: EditGroupViewState,
val eventSink: (Unit)->Unit val eventSink: (Unit)->Unit
@ -226,5 +244,6 @@ sealed class EditGroupViewState {
val groupName: String, val groupName: String,
val groupDescription: String?, val groupDescription: String?,
val memberStateList: List<MemberViewModel>, val memberStateList: List<MemberViewModel>,
val admin: Boolean
): EditGroupViewState() ): EditGroupViewState()
} }

View File

@ -4,7 +4,6 @@ import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import network.loki.messenger.libsession_util.util.ConfigPush import network.loki.messenger.libsession_util.util.ConfigPush
import network.loki.messenger.libsession_util.util.Contact import network.loki.messenger.libsession_util.util.Contact
import network.loki.messenger.libsession_util.util.Conversation import network.loki.messenger.libsession_util.util.Conversation
import network.loki.messenger.libsession_util.util.GroupDisplayInfo
import network.loki.messenger.libsession_util.util.GroupInfo import network.loki.messenger.libsession_util.util.GroupInfo
import network.loki.messenger.libsession_util.util.GroupMember import network.loki.messenger.libsession_util.util.GroupMember
import network.loki.messenger.libsession_util.util.UserPic import network.loki.messenger.libsession_util.util.UserPic
@ -264,16 +263,6 @@ class GroupInfoConfig(pointer: Long): ConfigBase(pointer), Closeable {
external fun setProfilePic(newProfilePic: UserPic) external fun setProfilePic(newProfilePic: UserPic)
external fun storageNamespace(): Long external fun storageNamespace(): Long
fun displayInfo() = GroupDisplayInfo(
id = id(),
name = getName(),
description = null,
created = getCreated(),
destroyed = isDestroyed(),
expiryTimer = getExpiryTimer(),
profilePic = getProfilePic()
)
override fun close() { override fun close() {
free() free()
} }

View File

@ -9,5 +9,6 @@ data class GroupDisplayInfo(
val name: String, val name: String,
val description: String?, val description: String?,
val destroyed: Boolean, val destroyed: Boolean,
val profilePic: UserPic val profilePic: UserPic,
val isUserAdmin: Boolean,
) )