diff --git a/app/src/androidTest/java/network/loki/messenger/CreateGroupTests.kt b/app/src/androidTest/java/network/loki/messenger/CreateGroupTests.kt index 652c6103c..a03a225a1 100644 --- a/app/src/androidTest/java/network/loki/messenger/CreateGroupTests.kt +++ b/app/src/androidTest/java/network/loki/messenger/CreateGroupTests.kt @@ -14,7 +14,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.thoughtcrime.securesms.ApplicationContext 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.ui.AppTheme @@ -32,7 +31,6 @@ class CreateGroupTests { val nameDesc = application.getString(R.string.AccessibilityId_closed_group_edit_group_name) val buttonDesc = application.getString(R.string.AccessibilityId_create_closed_group_create_button) - var postedGroup: CreateGroupState? = null var backPressed = false var closePressed = false @@ -53,7 +51,6 @@ class CreateGroupTests { onNode(hasContentDescriptionExactly(buttonDesc)).performClick() } - assertThat(postedGroup!!.groupName, equalTo("Name")) assertThat(backPressed, equalTo(false)) assertThat(closePressed, equalTo(false)) @@ -95,7 +92,6 @@ class CreateGroupTests { // Accessibility IDs val backDesc = application.getString(R.string.new_conversation_dialog_back_button_content_description) - var postedGroup: CreateGroupState? = null var backPressed = false composeTest.setContent { @@ -114,7 +110,6 @@ class CreateGroupTests { onNode(hasContentDescriptionExactly(backDesc)).performClick() } - assertThat(postedGroup, nullValue()) assertThat(backPressed, equalTo(true)) } @@ -123,8 +118,6 @@ class CreateGroupTests { val application = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as ApplicationContext // Accessibility IDs val closeDesc = application.getString(R.string.new_conversation_dialog_close_button_content_description) - - var postedGroup: CreateGroupState? = null var closePressed = false composeTest.setContent { @@ -143,7 +136,6 @@ class CreateGroupTests { onNode(hasContentDescriptionExactly(closeDesc)).performClick() } - assertThat(postedGroup, nullValue()) assertThat(closePressed, equalTo(true)) } diff --git a/app/src/androidTest/java/network/loki/messenger/groups/ClosedGroupViewTests.kt b/app/src/androidTest/java/network/loki/messenger/groups/ClosedGroupViewTests.kt index 76560eaad..f90fc1c88 100644 --- a/app/src/androidTest/java/network/loki/messenger/groups/ClosedGroupViewTests.kt +++ b/app/src/androidTest/java/network/loki/messenger/groups/ClosedGroupViewTests.kt @@ -20,7 +20,6 @@ import org.thoughtcrime.securesms.database.ConfigDatabase import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.dependencies.ConfigFactory import org.thoughtcrime.securesms.groups.CreateGroupViewModel -import org.thoughtcrime.securesms.groups.compose.CreateGroupState @RunWith(MockitoJUnitRunner::class) class ClosedGroupViewTests { @@ -54,38 +53,23 @@ class ClosedGroupViewTests { @Test fun tryCreateGroup_shouldErrorOnEmptyName() { val viewModel = createViewModel() - val state = CreateGroupState( - groupName = "", - groupDescription = "", - members = emptySet() - ) - viewModel.tryCreateGroup(state) + viewModel.tryCreateGroup() assertNotNull(viewModel.viewState.value?.error) } @Test fun tryCreateGroup_shouldErrorOnEmptyMembers() { val viewModel = createViewModel() - val state = CreateGroupState( - groupName = "group", - groupDescription = "anything", - members = emptySet() - ) - viewModel.tryCreateGroup(state) + viewModel.tryCreateGroup() assertNotNull(viewModel.viewState.value?.error) } @Test fun tryCreateGroup_shouldSucceedWithCorrectParameters() { val viewModel = createViewModel() - val state = CreateGroupState( - groupName = "group", - groupDescription = "", - members = emptySet() - ) - assertNotNull(viewModel.tryCreateGroup(state)) + assertNotNull(viewModel.tryCreateGroup()) } - private fun createViewModel() = CreateGroupViewModel(textSecurePreferences, storage) + private fun createViewModel() = CreateGroupViewModel(storage) } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index e493c8d46..11fa5a5b9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -1257,7 +1257,21 @@ open class Storage( } 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) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/compose/EditGroup.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/compose/EditGroup.kt index 9f00a182a..77e759aa1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/compose/EditGroup.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/compose/EditGroup.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material.OutlinedButton import androidx.compose.material.Scaffold import androidx.compose.material.Text 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 fun EditGroupView( onBack: ()->Unit, @@ -114,6 +167,14 @@ fun EditGroupView( .align(CenterVertically), ) // 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() LazyColumn(modifier = Modifier) { @@ -124,10 +185,19 @@ fun EditGroupView( .fillMaxWidth() .padding(vertical = 8.dp, horizontal = 16.dp)) { ContactPhoto(member.memberSessionId) - Column(modifier = Modifier.weight(1f)) { + Column(modifier = Modifier + .weight(1f) + .align(CenterVertically)) { Row(modifier = Modifier.fillMaxSize()) { + // Needs 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( val viewState: EditGroupViewState, val eventSink: (Unit)->Unit @@ -226,5 +244,6 @@ sealed class EditGroupViewState { val groupName: String, val groupDescription: String?, val memberStateList: List, + val admin: Boolean ): EditGroupViewState() } \ No newline at end of file diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt index d0c5ee6a5..dad97251b 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/Config.kt @@ -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.Contact 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.GroupMember 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 storageNamespace(): Long - fun displayInfo() = GroupDisplayInfo( - id = id(), - name = getName(), - description = null, - created = getCreated(), - destroyed = isDestroyed(), - expiryTimer = getExpiryTimer(), - profilePic = getProfilePic() - ) - override fun close() { free() } diff --git a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupDisplayInfo.kt b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupDisplayInfo.kt index 033614f14..8e54f3362 100644 --- a/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupDisplayInfo.kt +++ b/libsession-util/src/main/java/network/loki/messenger/libsession_util/util/GroupDisplayInfo.kt @@ -9,5 +9,6 @@ data class GroupDisplayInfo( val name: String, val description: String?, val destroyed: Boolean, - val profilePic: UserPic + val profilePic: UserPic, + val isUserAdmin: Boolean, ) \ No newline at end of file