Merge pull request #297 from csmith/102-show-invites-list
Feat: show invites list
This commit is contained in:
commit
88360802af
75 changed files with 1376 additions and 79 deletions
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.theme.components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.ButtonElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||
|
||||
@Composable
|
||||
fun OutlinedButton(
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true,
|
||||
shape: Shape = ElementOutlinedButtonDefaults.shape,
|
||||
colors: ButtonColors = ElementOutlinedButtonDefaults.buttonColors(),
|
||||
elevation: ButtonElevation? = ElementOutlinedButtonDefaults.buttonElevation(),
|
||||
border: BorderStroke? = ElementOutlinedButtonDefaults.border,
|
||||
contentPadding: PaddingValues = ElementOutlinedButtonDefaults.ContentPadding,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
androidx.compose.material3.Button(
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
enabled = enabled,
|
||||
shape = shape,
|
||||
colors = colors,
|
||||
elevation = elevation,
|
||||
border = border,
|
||||
contentPadding = contentPadding,
|
||||
interactionSource = interactionSource,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
object ElementOutlinedButtonDefaults {
|
||||
val ContentPadding = PaddingValues(horizontal = 24.dp, vertical = 14.dp)
|
||||
val shape: Shape @Composable get() = ButtonDefaults.outlinedShape
|
||||
val border: BorderStroke @Composable get() = ButtonDefaults.outlinedButtonBorder
|
||||
@Composable
|
||||
fun buttonElevation(): ButtonElevation = ButtonDefaults.buttonElevation()
|
||||
|
||||
@Composable
|
||||
fun buttonColors(): ButtonColors = ButtonDefaults.outlinedButtonColors()
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun OutlinedButtonsLightPreview() = ElementPreviewLight { ContentToPreview() }
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
internal fun OutlinedButtonsDarkPreview() = ElementPreviewDark { ContentToPreview() }
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
Column {
|
||||
OutlinedButton(onClick = {}, enabled = true) {
|
||||
Text(text = "Click me! - Enabled")
|
||||
}
|
||||
OutlinedButton(onClick = {}, enabled = false) {
|
||||
Text(text = "Click me! - Disabled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ import java.io.Closeable
|
|||
interface MatrixClient : Closeable {
|
||||
val sessionId: SessionId
|
||||
val roomSummaryDataSource: RoomSummaryDataSource
|
||||
val invitesDataSource: RoomSummaryDataSource
|
||||
fun getRoom(roomId: RoomId): MatrixRoom?
|
||||
fun findDM(userId: UserId): MatrixRoom?
|
||||
suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId>
|
||||
|
|
|
|||
|
|
@ -34,9 +34,11 @@ sealed interface RoomSummary {
|
|||
data class RoomSummaryDetails(
|
||||
val roomId: RoomId,
|
||||
val name: String,
|
||||
val canonicalAlias: String? = null,
|
||||
val isDirect: Boolean,
|
||||
val avatarURLString: String?,
|
||||
val lastMessage: RoomMessage?,
|
||||
val lastMessageTimestamp: Long?,
|
||||
val unreadNotificationCount: Int,
|
||||
val inviter: RoomMember? = null,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -87,20 +87,18 @@ class RustMatrixClient constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private val slidingSyncFilters by lazy {
|
||||
SlidingSyncRequestListFilters(
|
||||
isDm = null,
|
||||
spaces = emptyList(),
|
||||
isEncrypted = null,
|
||||
isInvite = false,
|
||||
isTombstoned = false,
|
||||
roomTypes = emptyList(),
|
||||
notRoomTypes = listOf("m.space"),
|
||||
roomNameLike = null,
|
||||
tags = emptyList(),
|
||||
notTags = emptyList()
|
||||
)
|
||||
}
|
||||
private val visibleRoomsSlidingSyncFilters = SlidingSyncRequestListFilters(
|
||||
isDm = null,
|
||||
spaces = emptyList(),
|
||||
isEncrypted = null,
|
||||
isInvite = false,
|
||||
isTombstoned = false,
|
||||
roomTypes = emptyList(),
|
||||
notRoomTypes = listOf("m.space"),
|
||||
roomNameLike = null,
|
||||
tags = emptyList(),
|
||||
notTags = emptyList()
|
||||
)
|
||||
|
||||
private val visibleRoomsSlidingSyncList = SlidingSyncListBuilder()
|
||||
.timelineLimit(limit = 1u)
|
||||
|
|
@ -111,7 +109,7 @@ class RustMatrixClient constructor(
|
|||
RequiredState(key = "m.room.join_rules", value = ""),
|
||||
)
|
||||
)
|
||||
.filters(slidingSyncFilters)
|
||||
.filters(visibleRoomsSlidingSyncFilters)
|
||||
.name(name = "CurrentlyVisibleRooms")
|
||||
.syncMode(mode = SlidingSyncMode.SELECTIVE)
|
||||
.addRange(0u, 20u)
|
||||
|
|
@ -119,12 +117,32 @@ class RustMatrixClient constructor(
|
|||
it.build()
|
||||
}
|
||||
|
||||
private val invitesSlidingSyncFilters = visibleRoomsSlidingSyncFilters.copy(isInvite = true)
|
||||
|
||||
private val invitesSlidingSyncList = SlidingSyncListBuilder()
|
||||
.timelineLimit(limit = 1u)
|
||||
.requiredState(
|
||||
requiredState = listOf(
|
||||
RequiredState(key = "m.room.avatar", value = ""),
|
||||
RequiredState(key = "m.room.encryption", value = ""),
|
||||
RequiredState(key = "m.room.canonical_alias", value = ""),
|
||||
)
|
||||
)
|
||||
.filters(invitesSlidingSyncFilters)
|
||||
.name(name = "CurrentInvites")
|
||||
.syncMode(mode = SlidingSyncMode.SELECTIVE)
|
||||
.addRange(0u, 20u)
|
||||
.use {
|
||||
it.build()
|
||||
}
|
||||
|
||||
private val slidingSync = client
|
||||
.slidingSync()
|
||||
.homeserver("https://slidingsync.lab.matrix.org")
|
||||
.withCommonExtensions()
|
||||
.storageKey("ElementX")
|
||||
.addList(visibleRoomsSlidingSyncList)
|
||||
.addList(invitesSlidingSyncList)
|
||||
.use {
|
||||
it.build()
|
||||
}
|
||||
|
|
@ -142,6 +160,18 @@ class RustMatrixClient constructor(
|
|||
override val roomSummaryDataSource: RoomSummaryDataSource
|
||||
get() = rustRoomSummaryDataSource
|
||||
|
||||
private val rustInvitesDataSource: RustRoomSummaryDataSource =
|
||||
RustRoomSummaryDataSource(
|
||||
slidingSyncObserverProxy.updateSummaryFlow,
|
||||
slidingSync,
|
||||
invitesSlidingSyncList,
|
||||
dispatchers,
|
||||
::onRestartSync
|
||||
)
|
||||
|
||||
override val invitesDataSource: RoomSummaryDataSource
|
||||
get() = rustInvitesDataSource
|
||||
|
||||
private var slidingSyncObserverToken: TaskHandle? = null
|
||||
|
||||
private val mediaResolver = RustMediaResolver(this)
|
||||
|
|
@ -152,6 +182,7 @@ class RustMatrixClient constructor(
|
|||
init {
|
||||
client.setDelegate(clientDelegate)
|
||||
rustRoomSummaryDataSource.init()
|
||||
rustInvitesDataSource.init()
|
||||
slidingSync.setObserver(slidingSyncObserverProxy)
|
||||
slidingSyncUpdateJob = slidingSyncObserverProxy.updateSummaryFlow
|
||||
.onEach { onSlidingSyncUpdate() }
|
||||
|
|
@ -248,6 +279,7 @@ class RustMatrixClient constructor(
|
|||
stopSync()
|
||||
slidingSync.setObserver(null)
|
||||
rustRoomSummaryDataSource.close()
|
||||
rustInvitesDataSource.close()
|
||||
client.setDelegate(null)
|
||||
visibleRoomsSlidingSyncList.destroy()
|
||||
slidingSync.destroy()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package io.element.android.libraries.matrix.impl.room
|
||||
|
||||
import io.element.android.libraries.core.bool.orFalse
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.room.RoomSummaryDetails
|
||||
import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory
|
||||
|
|
@ -29,14 +28,17 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
|
|||
val latestRoomMessage = slidingSyncRoom.latestRoomMessage()?.use {
|
||||
roomMessageFactory.create(it)
|
||||
}
|
||||
|
||||
return RoomSummaryDetails(
|
||||
roomId = RoomId(slidingSyncRoom.roomId()),
|
||||
name = slidingSyncRoom.name() ?: slidingSyncRoom.roomId(),
|
||||
canonicalAlias = room?.canonicalAlias(),
|
||||
isDirect = slidingSyncRoom.isDm() ?: false,
|
||||
avatarURLString = room?.avatarUrl(),
|
||||
unreadNotificationCount = slidingSyncRoom.unreadNotifications().use { it.notificationCount().toInt() },
|
||||
lastMessage = latestRoomMessage,
|
||||
lastMessageTimestamp = latestRoomMessage?.originServerTs
|
||||
lastMessageTimestamp = latestRoomMessage?.originServerTs,
|
||||
inviter = room?.inviter()?.let(RoomMemberMapper::map),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class FakeMatrixClient(
|
|||
private val userDisplayName: Result<String> = Result.success(A_USER_NAME),
|
||||
private val userAvatarURLString: Result<String> = Result.success(AN_AVATAR_URL),
|
||||
override val roomSummaryDataSource: RoomSummaryDataSource = FakeRoomSummaryDataSource(),
|
||||
override val invitesDataSource: RoomSummaryDataSource = FakeRoomSummaryDataSource(),
|
||||
private val sessionVerificationService: FakeSessionVerificationService = FakeSessionVerificationService(),
|
||||
private val pushersService: FakePushersService = FakePushersService(),
|
||||
private val notificationService: FakeNotificationService = FakeNotificationService(),
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
<string name="action_view_source">"View Source"</string>
|
||||
<string name="action_yes">"Yes"</string>
|
||||
<string name="common_about">"About"</string>
|
||||
<string name="common_analytics">"Analytics"</string>
|
||||
<string name="common_audio">"Audio"</string>
|
||||
<string name="common_bubbles">"Bubbles"</string>
|
||||
<string name="common_creating_room">"Creating room…"</string>
|
||||
|
|
@ -181,8 +182,17 @@
|
|||
<string name="room_timeline_beginning_of_room">"This is the beginning of %1$s."</string>
|
||||
<string name="room_timeline_beginning_of_room_no_name">"This is the beginning of this conversation."</string>
|
||||
<string name="room_timeline_read_marker_title">"New"</string>
|
||||
<string name="screen_invites_empty_list">"No Invites"</string>
|
||||
<string name="screen_invites_invited_you">"%1$s invited you"</string>
|
||||
<string name="screen_analytics_help_us_improve">"Help us identify issues and improve %1$s by sharing anonymous usage data."</string>
|
||||
<string name="screen_analytics_prompt_data_usage">"We "<b>"don\'t"</b>" record or profile any account data"</string>
|
||||
<string name="screen_analytics_prompt_help_us_improve">"Help us identify issues and improve %1$s by sharing anonymous usage data."</string>
|
||||
<string name="screen_analytics_prompt_read_terms">"You can read all our terms %1$s."</string>
|
||||
<string name="screen_analytics_prompt_read_terms_content_link">"here"</string>
|
||||
<string name="screen_analytics_prompt_settings">"You can turn this off anytime in settings"</string>
|
||||
<string name="screen_analytics_prompt_third_party_sharing">"We "<b>"don\'t"</b>" share information with third parties"</string>
|
||||
<string name="screen_analytics_prompt_title">"Help improve %1$s"</string>
|
||||
<string name="screen_analytics_read_terms">"You can read all our terms %1$s."</string>
|
||||
<string name="screen_analytics_read_terms_content_link">"here"</string>
|
||||
<string name="screen_analytics_share_data">"Share analytics data"</string>
|
||||
<string name="screen_report_content_block_user">"Block user"</string>
|
||||
<string name="screen_report_content_block_user_hint">"Check if you want to hide all current and future messages from this user"</string>
|
||||
<string name="screen_room_member_details_block_alert_action">"Block"</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue