feat: only show appropriate buttons in channel info sheet

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2023-11-11 03:46:18 +01:00
parent f0461b3bfe
commit 551be72a94
5 changed files with 118 additions and 94 deletions

View File

@ -67,6 +67,10 @@ fun Long.hasPermission(permission: PermissionBit): Boolean {
return this and permission.value == permission.value
}
infix fun Long?.has(permission: PermissionBit): Boolean {
return this != null && this.hasPermission(permission)
}
object BitDefaults {
val AllowedInTimeout =
PermissionBit.ViewChannel + PermissionBit.ReadMessageHistory
@ -76,30 +80,30 @@ object BitDefaults {
val Default =
ViewOnly +
PermissionBit.SendMessage +
PermissionBit.InviteOthers +
PermissionBit.SendEmbeds +
PermissionBit.UploadFiles +
PermissionBit.Connect +
PermissionBit.Speak
PermissionBit.SendMessage +
PermissionBit.InviteOthers +
PermissionBit.SendEmbeds +
PermissionBit.UploadFiles +
PermissionBit.Connect +
PermissionBit.Speak
val SavedMessages =
PermissionBit.GrantAllSafe.value
val DirectMessages =
Default +
PermissionBit.ManageChannel +
PermissionBit.React
PermissionBit.ManageChannel +
PermissionBit.React
val Server =
Default +
PermissionBit.React +
PermissionBit.ChangeNickname +
PermissionBit.ChangeAvatar
PermissionBit.React +
PermissionBit.ChangeNickname +
PermissionBit.ChangeAvatar
val Webhook =
PermissionBit.SendMessage +
PermissionBit.SendEmbeds +
PermissionBit.Masquerade +
PermissionBit.React
PermissionBit.SendEmbeds +
PermissionBit.Masquerade +
PermissionBit.React
}

View File

@ -8,12 +8,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
@ -21,14 +21,16 @@ import androidx.compose.ui.unit.dp
import chat.revolt.api.REVOLT_FILES
import chat.revolt.api.schemas.AutumnResource
import chat.revolt.api.schemas.ChannelType
import chat.revolt.api.schemas.User
import chat.revolt.components.generic.RemoteImage
import chat.revolt.components.generic.UserAvatar
@Composable
fun ChannelSheetHeader(
channelName: String,
channelIcon: AutumnResource? = null,
channelType: ChannelType,
channelId: String
dmPartner: User? = null
) {
Row(
modifier = Modifier.padding(vertical = 4.dp),
@ -39,8 +41,7 @@ fun ChannelSheetHeader(
.size(48.dp)
.clip(CircleShape)
.background(
getIconBackColour(channelId)
.copy(alpha = if (channelIcon != null) 0.6f else 0.2f)
MaterialTheme.colorScheme.primary.copy(alpha = 0.2f)
),
contentAlignment = Alignment.Center
) {
@ -54,57 +55,28 @@ fun ChannelSheetHeader(
modifier = Modifier
.size(24.dp)
)
} else if (dmPartner != null) {
UserAvatar(
username = User.resolveDefaultName(dmPartner),
userId = dmPartner.id ?: "",
avatar = dmPartner.avatar,
presence = null,
size = 48.dp,
modifier = Modifier
.size(48.dp)
)
} else {
ChannelIcon(channelType = channelType)
}
}
Spacer(modifier = Modifier.width(8.dp))
Spacer(modifier = Modifier.width(12.dp))
Text(
text = channelName,
fontWeight = FontWeight.Medium,
fontWeight = FontWeight.SemiBold,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
}
fun getIconBackColour(channelId: String): Color {
// The ULID alphabet does not include I, L, O, or U.
return when (channelId.uppercase().last()) {
'0' -> Color(0xFFE91E63)
'1' -> Color(0xFF9C27B0)
'2' -> Color(0xFF673AB7)
'3' -> Color(0xFF3F51B5)
'4' -> Color(0xFF2196F3)
'5' -> Color(0xFF03A9F4)
'6' -> Color(0xFF00BCD4)
'7' -> Color(0xFF009688)
'8' -> Color(0xFF4CAF50)
'9' -> Color(0xFF8BC34A)
'A' -> Color(0xFFCDDC39)
'B' -> Color(0xFFFFEB3B)
'C' -> Color(0xFFFFC107)
'D' -> Color(0xFFFF9800)
'E' -> Color(0xFFFF5722)
'F' -> Color(0xFF795548)
'G' -> Color(0xFF9E9E9E)
'H' -> Color(0xFF607D8B)
'J' -> Color(0xFF9FA8DA)
'K' -> Color(0xFF90CAF9)
'M' -> Color(0xFF81D4FA)
'N' -> Color(0xFF80DEEA)
'P' -> Color(0xFF80CBC4)
'Q' -> Color(0xFFA5D6A7)
'R' -> Color(0xFFC5E1A5)
'S' -> Color(0xFFE6EE9C)
'T' -> Color(0xFFFFF59D)
'V' -> Color(0xFFFFE082)
'W' -> Color(0xFFFFCC80)
'X' -> Color(0xFFFFAB91)
'Y' -> Color(0xFFFF8A65)
'Z' -> Color(0xFFFF8A80)
else -> Color(0xFFFFFFFF)
}
}

View File

@ -463,8 +463,8 @@ class ChannelScreenViewModel : ViewModel() {
}
val newContent = currentContent.substring(0, currentSelection.start) +
content +
currentContent.substring(currentSelection.end)
content +
currentContent.substring(currentSelection.end)
pendingMessageContent = newContent
textSelection = TextRange(currentSelection.start + content.length)

View File

@ -30,6 +30,10 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.internals.ChannelUtils
import chat.revolt.api.internals.PermissionBit
import chat.revolt.api.internals.Roles
import chat.revolt.api.internals.has
import chat.revolt.api.schemas.ChannelType
import chat.revolt.components.generic.SheetClickable
import chat.revolt.components.screens.chat.ChannelSheetHeader
@ -72,32 +76,43 @@ fun ChannelInfoSheet(channelId: String) {
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState())
) {
val isDM = ChannelUtils.resolveDMPartner(channel) != null
val partner = ChannelUtils
.resolveDMPartner(channel)
?.let {
RevoltAPI.userCache[it]
}
ChannelSheetHeader(
channelName = channel.name ?: stringResource(id = R.string.unknown),
channelName = channel.name
?: ChannelUtils.resolveDMName(channel)
?: stringResource(id = R.string.unknown),
channelIcon = channel.icon,
channelType = channel.channelType ?: ChannelType.TextChannel,
channelId = channel.id ?: "9"
dmPartner = partner
)
Spacer(modifier = Modifier.height(8.dp))
if (!isDM) {
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(id = R.string.channel_info_sheet_description),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(bottom = 10.dp)
)
Text(
text = if (channel.description.isNullOrBlank()) {
stringResource(
id = R.string.channel_info_sheet_description_empty
)
} else {
channel.description
},
modifier = Modifier.padding(bottom = 10.dp)
)
Text(
text = stringResource(id = R.string.channel_info_sheet_description),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(bottom = 10.dp)
)
Text(
text = if (channel.description.isNullOrBlank()) {
stringResource(
id = R.string.channel_info_sheet_description_empty
)
} else {
channel.description
},
modifier = Modifier.padding(bottom = 10.dp)
)
}
Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(id = R.string.channel_info_sheet_options),
@ -129,21 +144,53 @@ fun ChannelInfoSheet(channelId: String) {
else -> {}
}
SheetClickable(
icon = { modifier ->
Icon(
imageVector = Icons.Default.Add,
contentDescription = null,
modifier = modifier
)
},
label = { style ->
Text(
text = stringResource(id = R.string.channel_info_sheet_options_invite),
style = style
)
}
if (
Roles.permissionFor(
channel,
RevoltAPI.userCache[RevoltAPI.selfId]
) has PermissionBit.InviteOthers
) {
when (channel.channelType) {
ChannelType.TextChannel, ChannelType.VoiceChannel -> {
SheetClickable(
icon = { modifier ->
Icon(
imageVector = Icons.Default.Add,
contentDescription = null,
modifier = modifier
)
},
label = { style ->
Text(
text = stringResource(id = R.string.channel_info_sheet_options_invite),
style = style
)
}
) {
}
}
ChannelType.Group -> {
SheetClickable(
icon = { modifier ->
Icon(
imageVector = Icons.Default.Add,
contentDescription = null,
modifier = modifier
)
},
label = { style ->
Text(
text = stringResource(id = R.string.channel_info_sheet_options_add),
style = style
)
}
) {
}
}
else -> {}
}
}
SheetClickable(

View File

@ -233,6 +233,7 @@
<string name="channel_info_sheet_options">Options</string>
<string name="channel_info_sheet_options_members">Members</string>
<string name="channel_info_sheet_options_invite">Invite</string>
<string name="channel_info_sheet_options_add">Add members</string>
<string name="channel_info_sheet_options_notifications_manage">Manage notifications</string>
<string name="message_context_sheet_actions_copy">Copy</string>