feat: move schemas to their own module

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2025-11-29 19:03:32 +01:00
parent 968b3dccd1
commit 75bb23982b
114 changed files with 607 additions and 555 deletions

View File

@ -57,13 +57,13 @@ fun buildproperty(propertyName: String, fallbackEnv: String? = null): String? {
}
android {
compileSdk = 36
compileSdk = libs.versions.compileSdk.get().toInt()
namespace = "chat.stoat"
defaultConfig {
applicationId = "chat.revolt"
minSdk = 26
targetSdk = 36
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = Integer.parseInt("001_003_409".replace("_", ""), 10)
versionName = "1.3.9a"

View File

@ -51,9 +51,9 @@ import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPIError
import chat.stoat.api.routes.invites.fetchInviteByCode
import chat.stoat.api.routes.invites.joinInviteByCode
import chat.stoat.api.schemas.Invite
import chat.stoat.api.schemas.InviteJoined
import chat.stoat.api.schemas.RsResult
import chat.stoat.core.model.schemas.Invite
import chat.stoat.core.model.schemas.InviteJoined
import chat.stoat.core.model.util.RsResult
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.SyncedSettings
import chat.stoat.composables.generic.IconPlaceholder
@ -206,7 +206,7 @@ fun InviteScreen(
) {
if (invite?.serverIcon != null) {
RemoteImage(
url = "$STOAT_FILES/icons/${invite.serverIcon.id}/${invite.serverIcon.filename}",
url = "$STOAT_FILES/icons/${invite.serverIcon!!.id}/${invite.serverIcon!!.filename}",
allowAnimation = false,
description = viewModel.inviteResult?.value?.serverName
?: stringResource(id = R.string.unknown),

View File

@ -82,7 +82,7 @@ import chat.stoat.api.api
import chat.stoat.api.routes.microservices.geo.queryGeo
import chat.stoat.api.routes.microservices.health.healthCheck
import chat.stoat.api.routes.onboard.needsOnboarding
import chat.stoat.api.schemas.HealthNotice
import chat.stoat.core.model.schemas.HealthNotice
import chat.stoat.api.settings.Experiments
import chat.stoat.api.settings.GeoStateProvider
import chat.stoat.api.settings.LoadedSettings

View File

@ -57,7 +57,7 @@ import chat.stoat.api.routes.channel.sendMessage
import chat.stoat.api.routes.microservices.autumn.FileArgs
import chat.stoat.api.routes.microservices.autumn.MAX_ATTACHMENTS_PER_MESSAGE
import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.SyncedSettings
import chat.stoat.composables.chat.MessageField

View File

@ -43,7 +43,7 @@ import androidx.core.view.WindowCompat
import chat.stoat.R
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatHttp
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.SyncedSettings
import chat.stoat.providers.getAttachmentContentUri

View File

@ -21,7 +21,7 @@ import androidx.media3.exoplayer.ExoPlayer
import chat.stoat.R
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatHttp
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.databinding.ActivityVideoplayerBinding
import chat.stoat.providers.getAttachmentContentUri
import com.google.android.material.color.MaterialColors

View File

@ -11,14 +11,14 @@ import chat.stoat.api.internals.Members
import chat.stoat.api.realtime.DisconnectionState
import chat.stoat.api.realtime.RealtimeSocket
import chat.stoat.api.routes.user.fetchSelf
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.ChannelVoiceState
import chat.stoat.api.schemas.Emoji
import chat.stoat.api.schemas.Message
import chat.stoat.api.schemas.Server
import chat.stoat.api.schemas.User
import chat.stoat.core.model.util.ChannelVoiceState
import chat.stoat.core.model.schemas.Emoji
import chat.stoat.core.model.schemas.Message
import chat.stoat.core.model.schemas.Server
import chat.stoat.api.unreads.Unreads
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.User
import chat.stoat.persistence.Database
import chat.stoat.persistence.SqlStorage
import com.chuckerteam.chucker.api.ChuckerCollector
@ -52,7 +52,7 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.json.Json
import java.net.SocketException
import chat.stoat.api.schemas.Channel as ChannelSchema
import chat.stoat.core.model.schemas.Channel as ChannelSchema
private const val USE_ALPHA_API = false

View File

@ -1,13 +1,16 @@
package chat.stoat.api.internals
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.Server
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.Server
import chat.stoat.core.model.schemas.User
sealed class CategorisedChannelList {
data class Channel(val channel: chat.stoat.api.schemas.Channel) : CategorisedChannelList()
data class Category(val category: chat.stoat.api.schemas.Category) : CategorisedChannelList()
data class Channel(val channel: chat.stoat.core.model.schemas.Channel) :
CategorisedChannelList()
data class Category(val category: chat.stoat.core.model.schemas.Category) :
CategorisedChannelList()
}
object ChannelUtils {

View File

@ -2,8 +2,8 @@ package chat.stoat.api.internals
import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.SpecialUsers.PLATFORM_MODERATION_USER
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.ChannelType
object DirectMessages {
fun unreadDMs(): List<Channel> {

View File

@ -1,7 +1,7 @@
package chat.stoat.api.internals
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
object FriendRequests {
fun getIncoming(): List<User> {

View File

@ -1,6 +1,6 @@
package chat.stoat.api.internals
import chat.stoat.api.schemas.Member
import chat.stoat.core.model.schemas.Member
class Members {
// memberCache (mapping of serverId to userId to member)
@ -35,7 +35,7 @@ class Members {
*/
fun markdownMemberMapFor(serverId: String): Map<String, String> {
return memberCache[serverId]?.mapNotNull { (userId, member) ->
member.nickname?.let { userId to member.nickname }
member.nickname?.let { userId to it }
}?.toMap() ?: emptyMap()
}

View File

@ -2,12 +2,12 @@ package chat.stoat.api.internals
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.api
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
object ResourceLocations {
fun userAvatarUrl(user: User?): String {
if (user?.avatar != null) {
return "$STOAT_FILES/avatars/${user.avatar.id}"
return "$STOAT_FILES/avatars/${user.avatar!!.id}"
}
return "/users/${(user?.id ?: "").ifBlank { "0".repeat(26) }}/default_avatar".api()
}

View File

@ -1,13 +1,13 @@
package chat.stoat.api.internals
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.Member
import chat.stoat.api.schemas.PermissionDescription
import chat.stoat.api.schemas.Role
import chat.stoat.api.schemas.Server
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.Member
import chat.stoat.core.model.schemas.PermissionDescription
import chat.stoat.core.model.schemas.Role
import chat.stoat.core.model.schemas.Server
import chat.stoat.core.model.schemas.User
import kotlinx.datetime.Clock
object Roles {
@ -95,11 +95,11 @@ object Roles {
if (channel.defaultPermissions != null) {
calculated =
calculated or channel.defaultPermissions.a and channel.defaultPermissions.d.inv()
calculated or channel.defaultPermissions!!.a and channel.defaultPermissions!!.d.inv()
}
if (chMember.roles?.isNotEmpty() == true) {
chMember.roles.forEach { roleId ->
chMember.roles!!.forEach { roleId ->
val override = channel.rolePermissions?.get(roleId) ?: return@forEach
calculated = calculated or override.a and override.d.inv()
}

View File

@ -3,7 +3,7 @@ package chat.stoat.api.internals
import androidx.core.net.toUri
import chat.stoat.api.STOAT_MARKETING
import chat.stoat.api.StoatCbor
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlin.io.encoding.Base64

View File

@ -41,10 +41,10 @@ import chat.stoat.api.realtime.frames.sendable.BeginTypingFrame
import chat.stoat.api.realtime.frames.sendable.EndTypingFrame
import chat.stoat.api.realtime.frames.sendable.PingFrame
import chat.stoat.api.routes.server.fetchMember
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.ChannelVoiceState
import chat.stoat.api.schemas.Role
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.util.ChannelVoiceState
import chat.stoat.core.model.schemas.Role
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.SyncedSettings
import chat.stoat.c2dm.ChannelRegistrator
@ -180,9 +180,9 @@ object RealtimeSocket {
}
database.serverQueries.upsert(
it.id,
it.owner,
it.name,
it.id!!,
it.owner!!,
it.name!!,
it.description,
it.icon?.id,
it.banner?.id,
@ -216,7 +216,7 @@ object RealtimeSocket {
}
database.channelQueries.upsert(
it.id,
it.id!!,
it.channelType?.value ?: ChannelType.TextChannel.value,
it.user,
it.name,
@ -274,7 +274,7 @@ object RealtimeSocket {
return
}
StoatAPI.messageCache[messageFrame.id] = messageFrame
StoatAPI.messageCache[messageFrame.id!!] = messageFrame
messageFrame.channel?.let {
if (StoatAPI.channelCache[it] == null) {
@ -472,7 +472,7 @@ object RealtimeSocket {
val existing = StoatAPI.userCache[userRelationshipFrame.user.id]
if (existing == null && userRelationshipFrame.user.id != null) {
StoatAPI.userCache[userRelationshipFrame.user.id] =
StoatAPI.userCache[userRelationshipFrame.user.id!!] =
userRelationshipFrame.user.copy(
relationship = userRelationshipFrame.status ?: "None"
)
@ -480,7 +480,7 @@ object RealtimeSocket {
val merged = existing.mergeWithPartial(userRelationshipFrame.user).copy(
relationship = userRelationshipFrame.status ?: "None"
)
StoatAPI.userCache[userRelationshipFrame.user.id] = merged
StoatAPI.userCache[userRelationshipFrame.user.id!!] = merged
} else {
Log.w("RealtimeSocket", "Invalid UserRelationship frame: $rawFrame")
}
@ -523,7 +523,7 @@ object RealtimeSocket {
StoatAPI.channelCache[channelCreateFrame.id!!] = channelCreateFrame
database.channelQueries.upsert(
channelCreateFrame.id,
channelCreateFrame.id!!,
channelCreateFrame.channelType?.value ?: ChannelType.TextChannel.value,
channelCreateFrame.user,
channelCreateFrame.name,
@ -569,7 +569,7 @@ object RealtimeSocket {
return
}
StoatAPI.serverCache[currentChannel.server] = existingServer.copy(
StoatAPI.serverCache[currentChannel.server!!] = existingServer.copy(
channels = existingServer.channels?.filter { it != channelDeleteFrame.id }
?: emptyList()
)
@ -601,14 +601,14 @@ object RealtimeSocket {
serverCreateFrame.channels.forEach { channel ->
if (channel.id == null) return@forEach
StoatAPI.channelCache[channel.id] = channel
StoatAPI.channelCache[channel.id!!] = channel
}
if (serverCreateFrame.server.owner != null && serverCreateFrame.server.name != null) {
database.serverQueries.upsert(
serverCreateFrame.id,
serverCreateFrame.server.owner,
serverCreateFrame.server.name,
serverCreateFrame.server.owner!!,
serverCreateFrame.server.name!!,
serverCreateFrame.server.description,
serverCreateFrame.server.icon?.id,
serverCreateFrame.server.banner?.id,
@ -788,7 +788,7 @@ object RealtimeSocket {
)
val updatedRole = existingRole.mergeWithPartial(serverRoleUpdateFrame.data)
val newServer = server.copy(
roles = server.roles.plus(
roles = server.roles!!.plus(
Pair(serverRoleUpdateFrame.roleId, updatedRole)
)
)

View File

@ -1,17 +1,17 @@
package chat.stoat.api.realtime.frames.receivable
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.ChannelVoiceState
import chat.stoat.api.schemas.Embed
import chat.stoat.api.schemas.Emoji
import chat.stoat.api.schemas.Member
import chat.stoat.api.schemas.Message
import chat.stoat.api.schemas.PartialUserVoiceState
import chat.stoat.api.schemas.Role
import chat.stoat.api.schemas.Server
import chat.stoat.api.schemas.ServerUserChoice
import chat.stoat.api.schemas.User
import chat.stoat.api.schemas.UserVoiceState
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.util.ChannelVoiceState
import chat.stoat.core.model.schemas.Embed
import chat.stoat.core.model.schemas.Emoji
import chat.stoat.core.model.schemas.Member
import chat.stoat.core.model.schemas.Message
import chat.stoat.core.model.util.PartialUserVoiceState
import chat.stoat.core.model.schemas.Role
import chat.stoat.core.model.schemas.Server
import chat.stoat.core.model.schemas.ServerUserChoice
import chat.stoat.core.model.schemas.User
import chat.stoat.core.model.util.UserVoiceState
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject

View File

@ -3,7 +3,7 @@ package chat.stoat.api.routes.account
import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.schemas.RsResult
import chat.stoat.core.model.util.RsResult
import chat.stoat.api.api
import io.ktor.client.request.post
import io.ktor.client.request.setBody

View File

@ -3,7 +3,7 @@ package chat.stoat.api.routes.auth
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Session
import chat.stoat.core.model.schemas.Session
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.parameter

View File

@ -6,10 +6,10 @@ import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.internals.ULID
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.Message
import chat.stoat.api.schemas.MessagesInChannel
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.Message
import chat.stoat.core.model.schemas.MessagesInChannel
import chat.stoat.core.model.schemas.User
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.header

View File

@ -4,7 +4,7 @@ import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Channel
import chat.stoat.core.model.schemas.Channel
import chat.stoat.screens.create.MAX_ADDABLE_PEOPLE_IN_GROUP
import io.ktor.client.request.delete
import io.ktor.client.request.post

View File

@ -3,7 +3,7 @@ package chat.stoat.api.routes.custom
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Emoji
import chat.stoat.core.model.schemas.Emoji
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText

View File

@ -4,9 +4,9 @@ import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Invite
import chat.stoat.api.schemas.InviteJoined
import chat.stoat.api.schemas.RsResult
import chat.stoat.core.model.schemas.Invite
import chat.stoat.core.model.schemas.InviteJoined
import chat.stoat.core.model.util.RsResult
import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.statement.bodyAsText

View File

@ -5,8 +5,8 @@ import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPI
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.schemas.AutumnError
import chat.stoat.api.schemas.AutumnId
import chat.stoat.core.model.schemas.AutumnError
import chat.stoat.core.model.schemas.AutumnId
import io.ktor.client.plugins.onUpload
import io.ktor.client.request.forms.MultiPartFormDataContent
import io.ktor.client.request.forms.formData

View File

@ -2,7 +2,7 @@ package chat.stoat.api.routes.microservices.health
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.schemas.HealthNotice
import chat.stoat.core.model.schemas.HealthNotice
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText

View File

@ -6,7 +6,7 @@ import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.RsResult
import chat.stoat.core.model.util.RsResult
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.post

View File

@ -3,14 +3,14 @@ package chat.stoat.api.routes.safety
import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.schemas.ContentReportReason
import chat.stoat.api.schemas.FullMessageReport
import chat.stoat.api.schemas.FullServerReport
import chat.stoat.api.schemas.FullUserReport
import chat.stoat.api.schemas.MessageReport
import chat.stoat.api.schemas.ServerReport
import chat.stoat.api.schemas.UserReport
import chat.stoat.api.schemas.UserReportReason
import chat.stoat.core.model.schemas.ContentReportReason
import chat.stoat.core.model.schemas.FullMessageReport
import chat.stoat.core.model.schemas.FullServerReport
import chat.stoat.core.model.schemas.FullUserReport
import chat.stoat.core.model.schemas.MessageReport
import chat.stoat.core.model.schemas.ServerReport
import chat.stoat.core.model.schemas.UserReport
import chat.stoat.core.model.schemas.UserReportReason
import chat.stoat.api.api
import io.ktor.client.request.post
import io.ktor.client.request.setBody

View File

@ -5,9 +5,9 @@ import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Member
import chat.stoat.api.schemas.ServerWithChannelObjects
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Member
import chat.stoat.core.model.schemas.ServerWithChannelObjects
import chat.stoat.core.model.schemas.User
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.parameter

View File

@ -3,7 +3,7 @@ package chat.stoat.api.routes.sync
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.ChannelUnreadResponse
import chat.stoat.core.model.schemas.ChannelUnreadResponse
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import kotlinx.serialization.builtins.ListSerializer

View File

@ -4,7 +4,7 @@ import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Channel
import chat.stoat.core.model.schemas.Channel
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import kotlinx.serialization.SerializationException

View File

@ -5,9 +5,9 @@ import chat.stoat.api.StoatAPIError
import chat.stoat.api.StoatHttp
import chat.stoat.api.StoatJson
import chat.stoat.api.api
import chat.stoat.api.schemas.Profile
import chat.stoat.api.schemas.Status
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Profile
import chat.stoat.core.model.schemas.Status
import chat.stoat.core.model.schemas.User
import io.ktor.client.request.get
import io.ktor.client.request.patch
import io.ktor.client.request.setBody
@ -37,7 +37,7 @@ suspend fun fetchSelf(): User {
throw Exception("Self user ID is null")
}
StoatAPI.userCache[user.id] = user
StoatAPI.userCache[user.id!!] = user
StoatAPI.selfId = user.id
return user

View File

@ -4,7 +4,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import chat.stoat.api.schemas.AndroidSpecificSettingsSpecialEmbedSettings
import chat.stoat.core.model.schemas.AndroidSpecificSettingsSpecialEmbedSettings
import chat.stoat.ui.theme.Theme
import chat.stoat.ui.theme.getDefaultTheme

View File

@ -5,10 +5,10 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.StoatJson
import chat.stoat.api.routes.sync.getKeys
import chat.stoat.api.routes.sync.setKey
import chat.stoat.api.schemas.AndroidSpecificSettings
import chat.stoat.api.schemas.NotificationSettings
import chat.stoat.api.schemas.OrderingSettings
import chat.stoat.api.schemas._NotificationSettingsToParse
import chat.stoat.core.model.schemas.AndroidSpecificSettings
import chat.stoat.core.model.schemas.NotificationSettings
import chat.stoat.core.model.schemas.OrderingSettings
import chat.stoat.core.model.schemas._NotificationSettingsToParse
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.jsonPrimitive
import logcat.LogPriority

View File

@ -8,8 +8,8 @@ import chat.stoat.api.internals.ULID
import chat.stoat.api.routes.channel.ackChannel
import chat.stoat.api.routes.server.ackServer
import chat.stoat.api.routes.sync.syncUnreads
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.ChannelUnread
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.ChannelUnread
import chat.stoat.api.settings.NotificationSettingsProvider
class Unreads {

View File

@ -21,8 +21,8 @@ import chat.stoat.api.STOAT_BASE
import chat.stoat.api.StoatJson
import chat.stoat.api.internals.ULID
import chat.stoat.api.routes.push.subscribePush
import chat.stoat.api.schemas.Message
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Message
import chat.stoat.core.model.schemas.User
import chat.stoat.c2dm.ChannelRegistrator.Companion.CHANNEL_ID_GROUP_CONVERSATIONS_MESSAGES
import chat.stoat.persistence.Database
import chat.stoat.persistence.SqlStorage

View File

@ -26,11 +26,11 @@ import androidx.compose.ui.unit.dp
import chat.stoat.api.internals.BrushCompat
import chat.stoat.api.internals.solidColor
import chat.stoat.api.routes.microservices.january.asJanuaryProxyUrl
import chat.stoat.api.schemas.Embed
import chat.stoat.composables.chat.specialembeds.SpecialEmbedSwitch
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.markdown.RichMarkdown
import chat.stoat.api.schemas.Embed as EmbedSchema
import chat.stoat.core.model.schemas.Embed
import chat.stoat.core.model.schemas.Embed as EmbedSchema
@Composable
fun RegularEmbed(
@ -68,7 +68,7 @@ fun RegularEmbed(
if (embed.originalURL != null) {
Modifier
.clickable {
onLinkClick(embed.originalURL)
onLinkClick(embed.originalURL!!)
}
} else {
Modifier
@ -106,11 +106,11 @@ fun RegularEmbed(
// Image
embed.image?.let {
if (it.url == null || it.url.endsWith(".svg")) return@let
if (it.url == null || it.url?.endsWith(".svg") == true) return@let
Spacer(modifier = Modifier.height(8.dp))
RemoteImage(
url = asJanuaryProxyUrl(it.url),
url = asJanuaryProxyUrl(it.url!!),
width = (it.width ?: 48).toInt(),
height = (it.height ?: 48).toInt(),
modifier = Modifier
@ -118,7 +118,7 @@ fun RegularEmbed(
.then(
if (embed.originalURL != null) {
Modifier.clickable {
onLinkClick(embed.originalURL)
onLinkClick(embed.originalURL!!)
}
} else {
Modifier

View File

@ -30,9 +30,9 @@ import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.solidColor
import chat.stoat.api.routes.channel.fetchSingleMessage
import chat.stoat.api.schemas.User
import chat.stoat.api.settings.Experiments
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.core.model.schemas.User
import chat.stoat.markdown.jbm.JBM
import chat.stoat.markdown.jbm.JBMRenderer
import chat.stoat.markdown.jbm.LocalJBMarkdownTreeState
@ -142,11 +142,11 @@ fun InReplyTo(
LocalContentColor provides contentColor.copy(alpha = 0.7f),
LocalTextStyle provides LocalTextStyle.current.copy(fontSize = 12.sp)
) {
JBMRenderer(message.content)
JBMRenderer(message.content!!)
}
} else {
Text(
text = message.content,
text = message.content!!,
fontSize = 12.sp,
color = contentColor.copy(alpha = 0.7f),
maxLines = 1,

View File

@ -12,8 +12,8 @@ import chat.stoat.api.STOAT_FILES
import chat.stoat.api.internals.BrushCompat
import chat.stoat.api.internals.Roles
import chat.stoat.api.internals.solidColor
import chat.stoat.api.schemas.Member
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.Member
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.composables.generic.presenceFromStatus
import chat.stoat.internals.extensions.TransparentListItemColours

View File

@ -1,6 +1,5 @@
package chat.stoat.composables.chat
import android.R.id.message
import android.annotation.SuppressLint
import android.content.Intent
import android.icu.text.DateFormat
@ -75,8 +74,8 @@ import chat.stoat.api.internals.solidColor
import chat.stoat.api.routes.channel.react
import chat.stoat.api.routes.channel.unreact
import chat.stoat.api.routes.microservices.january.asJanuaryProxyUrl
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.core.model.schemas.User
import chat.stoat.api.settings.Experiments
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.MessageReplyStyle
@ -94,12 +93,12 @@ import chat.stoat.markdown.jbm.JBMRenderer
import chat.stoat.markdown.jbm.LocalJBMarkdownTreeState
import chat.stoat.persistence.KVStorage
import kotlinx.coroutines.launch
import chat.stoat.api.schemas.Message as MessageSchema
import chat.stoat.core.model.schemas.Message as MessageSchema
@Composable
fun authorColour(message: MessageSchema): Brush {
return if (message.masquerade?.colour != null) {
BrushCompat.parseColour(message.masquerade.colour)
BrushCompat.parseColour(message.masquerade!!.colour!!)
} else {
val defaultColour = Brush.solidColor(LocalContentColor.current)
@ -131,7 +130,7 @@ fun displayNameInChannel(userId: String, channelId: String): String {
@Composable
fun authorName(message: MessageSchema): String {
if (message.masquerade?.name != null) {
return message.masquerade.name
return message.masquerade!!.name!!
}
val serverId =
@ -149,7 +148,7 @@ fun authorName(message: MessageSchema): String {
@Composable
fun authorAvatarUrl(message: MessageSchema): String? {
if (message.masquerade?.avatar != null) {
return asJanuaryProxyUrl(message.masquerade.avatar)
return asJanuaryProxyUrl(message.masquerade!!.avatar!!)
}
val serverId =
@ -441,14 +440,14 @@ fun Message(
key(message.content) {
message.content?.let {
if (message.content.isBlank()) return@let // if only an attachment is sent
if (message.content!!.isBlank()) return@let // if only an attachment is sent
if (Experiments.useKotlinBasedMarkdownRenderer.isEnabled) {
CompositionLocalProvider(
LocalJBMarkdownTreeState provides LocalJBMarkdownTreeState.current.copy(
currentServer = StoatAPI.channelCache[message.channel]?.server,
fontSizeMultiplier = Gigamoji.useGigamojiForMessage(
message.content
message.content!!
)
.let {
if (it) 2f else 1f
@ -456,14 +455,14 @@ fun Message(
)
) {
Spacer(modifier = Modifier.height(2.dp))
JBMRenderer(message.content)
JBMRenderer(message.content!!)
}
} else {
CompositionLocalProvider(
LocalMarkdownTreeConfig provides LocalMarkdownTreeConfig.current.copy(
currentServer = StoatAPI.channelCache[message.channel]?.server,
fontSizeMultiplier = Gigamoji.useGigamojiForMessage(
message.content
message.content!!
)
.let {
if (it) 2f else 1f
@ -471,14 +470,14 @@ fun Message(
)
) {
Spacer(modifier = Modifier.height(2.dp))
RichMarkdown(input = message.content)
RichMarkdown(input = message.content!!)
}
}
}
}
message.attachments?.let {
message.attachments.forEach { attachment ->
it.forEach { attachment ->
Spacer(modifier = Modifier.height(2.dp))
MessageAttachment(attachment) {
when (attachment.metadata?.type) {
@ -518,7 +517,7 @@ fun Message(
}
message.embeds?.let {
message.embeds.forEach { embed ->
it.forEach { embed ->
when (embed.type) {
"Website", "Text" -> {
val embedIsEmpty =

View File

@ -34,9 +34,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.media.AudioPlayer
import chat.stoat.core.model.schemas.AutumnResource
import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.hazeSource
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
@ -95,7 +95,7 @@ fun ImageAttachment(attachment: AutumnResource) {
modifier = Modifier
.width(attachment.metadata?.width?.toInt()?.dp ?: maxWidth)
.aspectRatio(
attachment.metadata!!.width!!.toFloat() / attachment.metadata.height!!.toFloat()
attachment.metadata!!.width!!.toFloat() / attachment.metadata!!.height!!.toFloat()
)
.then(
if (hazeState != null) Modifier.hazeSource(state = hazeState)
@ -109,7 +109,7 @@ fun ImageAttachment(attachment: AutumnResource) {
.hazeEffect(state = hazeState, style = HazeMaterials.ultraThin())
.width(attachment.metadata?.width?.toInt()?.dp ?: maxWidth)
.aspectRatio(
attachment.metadata!!.width!!.toFloat() / attachment.metadata.height!!.toFloat()
attachment.metadata!!.width!!.toFloat() / attachment.metadata!!.height!!.toFloat()
)
.clickable { spoilerShown = true },
contentAlignment = Alignment.Center
@ -157,7 +157,7 @@ fun VideoAttachment(attachment: AutumnResource) {
modifier = Modifier
.width(attachment.metadata?.width?.toInt()?.dp ?: maxWidth)
.aspectRatio(
attachment.metadata!!.width!!.toFloat() / attachment.metadata.height!!.toFloat()
attachment.metadata!!.width!!.toFloat() / attachment.metadata!!.height!!.toFloat()
)
) {
// Turns out that when you give Glide a video URL, you get a perfectly cromulent thumbnail.
@ -167,7 +167,7 @@ fun VideoAttachment(attachment: AutumnResource) {
modifier = Modifier
.fillMaxWidth()
.aspectRatio(
attachment.metadata.width!!.toFloat() / attachment.metadata.height.toFloat()
attachment.metadata!!.width!!.toFloat() / attachment.metadata!!.height!!.toFloat()
),
description = attachment.filename ?: "Video"
)
@ -205,7 +205,7 @@ fun MessageAttachment(attachment: AutumnResource, onAttachmentClick: (AutumnReso
return
}
when (attachment.metadata.type) {
when (attachment.metadata!!.type) {
"Image" -> ImageAttachment(attachment)
"Video" -> VideoAttachment(attachment)
"Audio" -> AudioAttachment(attachment)

View File

@ -84,8 +84,8 @@ import chat.stoat.activities.StoatTweenFloat
import chat.stoat.activities.StoatTweenInt
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.internals.BrushCompat
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.Member
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.Member
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.composables.screens.chat.ChannelIcon
@ -111,25 +111,25 @@ private fun CharSequence.lastWordStartsAt(): Int {
sealed class AutocompleteSuggestion {
data class User(
val user: chat.stoat.api.schemas.User,
val user: chat.stoat.core.model.schemas.User,
val member: Member?,
val query: String
) : AutocompleteSuggestion()
data class Channel(
val channel: chat.stoat.api.schemas.Channel,
val channel: chat.stoat.core.model.schemas.Channel,
val query: String
) : AutocompleteSuggestion()
data class Emoji(
val shortcode: String,
val unicode: String?,
val custom: chat.stoat.api.schemas.Emoji?,
val custom: chat.stoat.core.model.schemas.Emoji?,
val query: String
) : AutocompleteSuggestion()
data class Role(
val role: chat.stoat.api.schemas.Role,
val role: chat.stoat.core.model.schemas.Role,
val id: String,
val query: String
) : AutocompleteSuggestion()

View File

@ -28,8 +28,8 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.schemas.Message
import chat.stoat.composables.markdown.RichMarkdown
import chat.stoat.core.model.schemas.Message
enum class SystemMessageType(val type: String) {
CHANNEL_OWNERSHIP_CHANGED("channel_ownership_changed"),
@ -54,10 +54,10 @@ fun SystemMessage(message: Message) {
if (message.system == null) return
val systemMessageType =
SystemMessageType.entries.firstOrNull { it.type == message.system.type }
SystemMessageType.entries.firstOrNull { it.type == message.system!!.type }
if (systemMessageType == null) {
UnsupportedMessage(context = message.system.type)
UnsupportedMessage(context = message.system!!.type)
return
}
@ -82,8 +82,8 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_ownership_changed,
message.system.from.mention(),
message.system.to.mention()
message.system!!.from.mention(),
message.system!!.to.mention()
)
)
}
@ -92,7 +92,7 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_channel_icon_changed,
message.system.by.mention()
message.system!!.by.mention()
)
)
}
@ -101,7 +101,7 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_channel_description_changed,
message.system.by.mention()
message.system!!.by.mention()
)
)
}
@ -110,8 +110,8 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_channel_renamed,
message.system.by.mention(),
"**${message.system.name ?: stringResource(R.string.unknown)}**"
message.system!!.by.mention(),
"**${message.system!!.name ?: stringResource(R.string.unknown)}**"
)
)
}
@ -120,8 +120,8 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_user_removed,
message.system.by.mention(),
message.system.id.mention()
message.system!!.by.mention(),
message.system!!.id.mention()
)
)
}
@ -130,8 +130,8 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_user_added,
message.system.by.mention(),
message.system.id.mention()
message.system!!.by.mention(),
message.system!!.id.mention()
)
)
}
@ -140,7 +140,7 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_user_banned,
message.system.id.mention()
message.system!!.id.mention()
)
)
}
@ -149,7 +149,7 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_user_kicked,
message.system.id.mention()
message.system!!.id.mention()
)
)
}
@ -158,7 +158,7 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_user_left,
message.system.id.mention()
message.system!!.id.mention()
)
)
}
@ -167,13 +167,13 @@ fun SystemMessage(message: Message) {
RichMarkdown(
stringResource(
R.string.system_message_user_joined,
message.system.id.mention()
message.system!!.id.mention()
)
)
}
SystemMessageType.TEXT -> {
message.system.content?.let { RichMarkdown(it) }
message.system!!.content?.let { RichMarkdown(it) }
}
}
}

View File

@ -18,8 +18,8 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.schemas.UserBadges
import chat.stoat.api.schemas.has
import chat.stoat.core.model.schemas.UserBadges
import chat.stoat.core.model.schemas.has
@Composable
fun BadgeListEntryTemplate(

View File

@ -11,7 +11,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import chat.stoat.api.schemas.Special
import chat.stoat.core.model.schemas.Special
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.ui.theme.isThemeDark

View File

@ -2,7 +2,7 @@ package chat.stoat.composables.chat.specialembeds
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import chat.stoat.api.schemas.Special
import chat.stoat.core.model.schemas.Special
import chat.stoat.api.settings.LoadedSettings
@Composable

View File

@ -22,9 +22,9 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.viewinterop.AndroidView
import chat.stoat.R
import chat.stoat.api.schemas.Special
import chat.stoat.composables.chat.VideoPlayButton
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.core.model.schemas.Special
import org.intellij.lang.annotations.Language
@Language("HTML")
@ -94,7 +94,7 @@ fun YouTubeEmbed(special: Special, modifier: Modifier = Modifier) {
it.loadDataWithBaseURL(
null,
YOUTUBE_EMBED_TEMPLATE
.replace("{{videoId}}", special.id)
.replace("{{videoId}}", special.id!!)
.replace("{{useTimestamp}}", (special.timestamp != null).toString())
.replace("{{timestamp}}", special.timestamp ?: ""),
"text/html",

View File

@ -401,7 +401,7 @@ fun EmojiPicker(
)
} else {
RemoteImage(
url = "$STOAT_FILES/icons/${server.icon.id}",
url = "$STOAT_FILES/icons/${server.icon!!.id}",
allowAnimation = false,
description = server.name,
modifier = Modifier

View File

@ -12,7 +12,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.net.toUri
import chat.stoat.R
import chat.stoat.api.schemas.HealthNotice
import chat.stoat.core.model.schemas.HealthNotice
@Composable
fun HealthAlert(notice: HealthNotice, onDismiss: () -> Unit) {

View File

@ -25,7 +25,7 @@ import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.STOAT_BASE
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.api.settings.LoadedSettings
enum class Presence {

View File

@ -38,7 +38,7 @@ import chat.stoat.activities.InviteActivity
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.custom.fetchEmoji
import chat.stoat.api.schemas.isInviteUri
import chat.stoat.core.model.schemas.isInviteUri
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel
import chat.stoat.composables.generic.RemoteImage

View File

@ -56,11 +56,10 @@ import chat.stoat.R
import chat.stoat.api.internals.ResourceLocations
import chat.stoat.api.internals.ULID
import chat.stoat.api.internals.UserQR
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.ui.theme.FragmentMono
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.GlideException
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.qrcode.QRCodeWriter

View File

@ -22,8 +22,8 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.internals.ChannelUtils
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.ChannelType
@Composable
fun ChannelHeader(

View File

@ -9,7 +9,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import chat.stoat.R
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.ChannelType
@Composable
fun ChannelIcon(channelType: ChannelType, modifier: Modifier = Modifier) {

View File

@ -27,9 +27,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.composables.markdown.MarkdownTree

View File

@ -29,18 +29,18 @@ import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.ULID
import chat.stoat.api.routes.channel.SendMessageReply
import chat.stoat.api.schemas.Message
import chat.stoat.composables.chat.authorAvatarUrl
import chat.stoat.composables.chat.authorColour
import chat.stoat.composables.chat.authorName
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.core.model.schemas.Message
@Composable
fun replyContentText(message: Message): String {
return if (message.content.isNullOrBlank()) {
stringResource(id = R.string.reply_message_empty_has_attachments)
} else {
message.content
message.content!!
}
}

View File

@ -26,7 +26,7 @@ import chat.stoat.activities.StoatTweenFloat
import chat.stoat.activities.StoatTweenInt
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.generic.UserAvatar
@Composable

View File

@ -43,8 +43,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.min
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.Message
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.Message
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.api.settings.MessageReplyStyle
import chat.stoat.callbacks.Action

View File

@ -81,12 +81,6 @@ import chat.stoat.api.internals.CategorisedChannelList
import chat.stoat.api.internals.ChannelUtils
import chat.stoat.api.internals.DirectMessages
import chat.stoat.api.internals.FriendRequests
import chat.stoat.api.schemas.Category
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.ServerFlags
import chat.stoat.api.schemas.User
import chat.stoat.api.schemas.has
import chat.stoat.api.settings.GeoStateProvider
import chat.stoat.api.settings.NotificationSettingsProvider
import chat.stoat.api.settings.SyncedSettings
@ -96,6 +90,12 @@ import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.composables.generic.presenceFromStatus
import chat.stoat.composables.screens.chat.ChannelIcon
import chat.stoat.core.model.schemas.Category
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.ServerFlags
import chat.stoat.core.model.schemas.User
import chat.stoat.core.model.schemas.has
import chat.stoat.screens.chat.ChatRouterDestination
import chat.stoat.screens.chat.LocalIsConnected
import chat.stoat.sheets.ChannelContextSheet
@ -476,7 +476,7 @@ fun ChannelSideDrawer(
) {
if (server?.banner != null) {
RemoteImage(
url = "$STOAT_FILES/banners/${server.banner.id}",
url = "$STOAT_FILES/banners/${server.banner!!.id}",
description = null,
contentScale = ContentScale.Crop,
modifier = Modifier

View File

@ -20,7 +20,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel
import chat.stoat.composables.screens.chat.StackedUserAvatars

View File

@ -28,9 +28,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.stoat.R
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.schemas.Server
import chat.stoat.api.schemas.ServerFlags
import chat.stoat.api.schemas.has
import chat.stoat.core.model.schemas.Server
import chat.stoat.core.model.schemas.ServerFlags
import chat.stoat.core.model.schemas.has
import chat.stoat.composables.generic.IconPlaceholder
import chat.stoat.composables.generic.RemoteImage

View File

@ -39,9 +39,9 @@ import chat.stoat.api.routes.user.friendUser
import chat.stoat.api.routes.user.openDM
import chat.stoat.api.routes.user.unblockUser
import chat.stoat.api.routes.user.unfriendUser
import chat.stoat.api.schemas.User
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel
import chat.stoat.core.model.schemas.User
import chat.stoat.internals.Platform
import kotlinx.coroutines.launch
import logcat.LogPriority
@ -153,11 +153,11 @@ fun UserButtons(
FilledTonalButton(
onClick = {
scope.launch {
val dm = openDM(user.id)
val dm = openDM(user.id!!)
if (dm.id != null) {
if (StoatAPI.channelCache[dm.id] == null)
StoatAPI.channelCache[dm.id] = dm
ActionChannel.send(Action.SwitchChannel(dm.id))
StoatAPI.channelCache[dm.id!!] = dm
ActionChannel.send(Action.SwitchChannel(dm.id!!))
dismissSheet()
} else {
Toast.makeText(
@ -180,7 +180,7 @@ fun UserButtons(
onClick = {
scope.launch {
try {
unfriendUser(user.id)
unfriendUser(user.id!!)
} catch (e: Exception) {
if (e.message == "NoEffect") return@launch
logcat(LogPriority.ERROR) { e.asLog() }
@ -198,7 +198,7 @@ fun UserButtons(
onClick = {
scope.launch {
try {
acceptFriendRequest(user.id)
acceptFriendRequest(user.id!!)
} catch (e: Exception) {
if (e.message == "NoEffect") return@launch
logcat(LogPriority.ERROR) { e.asLog() }
@ -213,7 +213,7 @@ fun UserButtons(
onClick = {
scope.launch {
try {
unfriendUser(user.id)
unfriendUser(user.id!!)
} catch (e: Exception) {
if (e.message == "NoEffect") return@launch
logcat(LogPriority.ERROR) { e.asLog() }
@ -235,7 +235,7 @@ fun UserButtons(
onClick = {
scope.launch {
try {
unblockUser(user.id)
unblockUser(user.id!!)
} catch (e: Exception) {
if (e.message == "NoEffect") return@launch
logcat(LogPriority.ERROR) { e.asLog() }
@ -266,7 +266,7 @@ fun UserButtons(
onClick = {
scope.launch {
try {
unfriendUser(user.id)
unfriendUser(user.id!!)
} catch (e: Exception) {
if (e.message == "NoEffect") return@launch
logcat(LogPriority.ERROR) { e.asLog() }
@ -287,7 +287,7 @@ fun UserButtons(
onClick = {
scope.launch {
try {
blockUser(user.id)
blockUser(user.id!!)
} catch (e: Exception) {
if (e.message == "NoEffect") return@launch
logcat(LogPriority.ERROR) { e.asLog() }
@ -303,7 +303,7 @@ fun UserButtons(
},
onClick = {
scope.launch {
clipboard.setText(AnnotatedString(user.id))
clipboard.setText(AnnotatedString(user.id!!))
}
}
)
@ -314,7 +314,7 @@ fun UserButtons(
},
onClick = {
scope.launch {
ActionChannel.send(Action.ReportUser(user.id))
ActionChannel.send(Action.ReportUser(user.id!!))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(

View File

@ -37,12 +37,12 @@ import chat.stoat.api.internals.SpecialUsers
import chat.stoat.api.internals.ULID
import chat.stoat.api.internals.solidColor
import chat.stoat.api.routes.user.fetchUserProfile
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.api.schemas.Profile
import chat.stoat.api.schemas.User
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.composables.generic.presenceFromStatus
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.core.model.schemas.Profile
import chat.stoat.core.model.schemas.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@ -168,7 +168,7 @@ fun RawUserOverview(
// make sure
// - the display name is not null or blank
// - the display name is not the same as the username; both trimmed
if (!user.displayName.isNullOrBlank() && ((user.displayName.trim() == user.username?.trim()) == false)) {
if (!user.displayName.isNullOrBlank() && user.displayName!!.trim() != user.username?.trim()) {
pushStyle(SpanStyle(fontWeight = FontWeight.Bold))
append(user.displayName)
pop()

View File

@ -15,7 +15,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import chat.stoat.R
import chat.stoat.api.internals.ULID
import chat.stoat.api.schemas.Session
import chat.stoat.core.model.schemas.Session
@Composable
fun SessionItem(

View File

@ -11,7 +11,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.UserVoiceState
import chat.stoat.core.model.util.UserVoiceState
import chat.stoat.composables.chat.displayNameInChannel
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.internals.extensions.TransparentListItemColours

View File

@ -22,7 +22,7 @@ import androidx.webkit.WebViewAssetLoader
import chat.stoat.R
import chat.stoat.activities.InviteActivity
import chat.stoat.api.STOAT_WEB_APP
import chat.stoat.api.schemas.isInviteUri
import chat.stoat.core.model.schemas.isInviteUri
import chat.stoat.databinding.SheetChangelogBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.color.MaterialColors

View File

@ -4,9 +4,9 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.PermissionBit
import chat.stoat.api.internals.Roles
import chat.stoat.api.internals.has
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.settings.FeatureFlags
import chat.stoat.composables.chat.AutocompleteSuggestion
import chat.stoat.core.model.schemas.ChannelType
object Autocomplete {
private val emojiImpl = EmojiImpl()
@ -133,10 +133,10 @@ object Autocomplete {
ignoreCase = true
) == true
}.mapNotNull {
it.id?.let { _ ->
it.id?.let { id ->
StoatAPI.members.getMember(
serverId,
it.id
id
) to it
}
}.filter { (member, _) ->

View File

@ -5,7 +5,7 @@ import chat.stoat.R
import chat.stoat.StoatApplication
import chat.stoat.api.StoatAPI
import chat.stoat.api.StoatJson
import chat.stoat.api.schemas.Server
import chat.stoat.core.model.schemas.Server
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ListSerializer
@ -58,7 +58,7 @@ sealed class EmojiPickerItem {
val alternates: List<List<Long>>
) : EmojiPickerItem()
data class ServerEmote(val emote: chat.stoat.api.schemas.Emoji) : EmojiPickerItem()
data class ServerEmote(val emote: chat.stoat.core.model.schemas.Emoji) : EmojiPickerItem()
}
class EmojiImpl {

View File

@ -1,7 +1,7 @@
package chat.stoat.internals.text
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.internals.EmojiImpl
object MessageProcessor {

View File

@ -21,7 +21,7 @@ import chat.stoat.api.STOAT_FILES
import chat.stoat.api.STOAT_WEB_APP
import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.ResourceLocations
import chat.stoat.api.schemas.isInviteUri
import chat.stoat.core.model.schemas.isInviteUri
import chat.stoat.markdown.jbm.LocalJBMarkdownTreeState
import chat.stoat.markdown.jbm.MentionResolver
import chat.stoat.markdown.jbm.asHexString

View File

@ -79,7 +79,7 @@ import chat.stoat.api.internals.BrushCompat
import chat.stoat.api.internals.InstancedBrushCompat
import chat.stoat.api.internals.isUlid
import chat.stoat.api.routes.custom.fetchEmoji
import chat.stoat.api.schemas.isInviteUri
import chat.stoat.core.model.schemas.isInviteUri
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel

View File

@ -21,7 +21,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.webkit.WebViewAssetLoader
import chat.stoat.activities.InviteActivity
import chat.stoat.api.STOAT_WEB_APP
import chat.stoat.api.schemas.isInviteUri
import chat.stoat.core.model.schemas.isInviteUri
internal fun Color.asHexString(includeAlphaComponent: Boolean = true): String {
val argb = toArgb()

View File

@ -41,7 +41,7 @@ import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.safety.putMessageReport
import chat.stoat.api.routes.user.blockUser
import chat.stoat.api.schemas.ContentReportReason
import chat.stoat.core.model.schemas.ContentReportReason
import chat.stoat.composables.chat.Message
import chat.stoat.composables.generic.FormTextField
import kotlinx.coroutines.launch

View File

@ -32,7 +32,7 @@ import androidx.compose.ui.unit.sp
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.safety.putServerReport
import chat.stoat.api.schemas.ContentReportReason
import chat.stoat.core.model.schemas.ContentReportReason
import chat.stoat.composables.generic.FormTextField
import chat.stoat.composables.screens.settings.ServerOverview
import kotlinx.coroutines.launch

View File

@ -34,7 +34,7 @@ import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.safety.putUserReport
import chat.stoat.api.routes.user.blockUser
import chat.stoat.api.schemas.UserReportReason
import chat.stoat.core.model.schemas.UserReportReason
import chat.stoat.composables.generic.FormTextField
import chat.stoat.composables.screens.settings.UserOverview
import kotlinx.coroutines.launch

View File

@ -40,7 +40,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.ChannelUnread
import chat.stoat.core.model.schemas.ChannelUnread
import logcat.LogPriority
import logcat.logcat

View File

@ -87,8 +87,8 @@ import chat.stoat.api.internals.UserQR
import chat.stoat.api.internals.UserQRContents
import chat.stoat.api.routes.user.friendUser
import chat.stoat.api.routes.user.unfriendUser
import chat.stoat.api.schemas.AutumnResource
import chat.stoat.api.schemas.Metadata
import chat.stoat.core.model.schemas.AutumnResource
import chat.stoat.core.model.schemas.Metadata
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel

View File

@ -61,7 +61,7 @@ import androidx.navigation.NavController
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.user.fetchSelf
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.generic.NonIdealState
import chat.stoat.composables.screens.settings.UserOverview
import chat.stoat.composables.skeletons.UserOverviewSkeleton

View File

@ -116,8 +116,8 @@ import chat.stoat.api.internals.PermissionBit
import chat.stoat.api.internals.has
import chat.stoat.api.routes.channel.react
import chat.stoat.api.routes.microservices.autumn.FileArgs
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.Message
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.Message
import chat.stoat.api.settings.Experiments
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel

View File

@ -41,8 +41,8 @@ import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.api.routes.server.fetchMember
import chat.stoat.api.routes.user.addUserIfUnknown
import chat.stoat.api.routes.user.fetchUser
import chat.stoat.api.schemas.Channel
import chat.stoat.api.schemas.Message
import chat.stoat.core.model.schemas.Channel
import chat.stoat.core.model.schemas.Message
import chat.stoat.api.settings.GeoStateProvider
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel
@ -58,7 +58,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -185,7 +184,7 @@ class ChannelScreenViewModel @Inject constructor(
try {
StoatAPI.members.getMember(serverId, selfUser.id!!) ?: fetchMember(
serverId,
selfUser.id
selfUser.id!!
)
} catch (e: Exception) {
Log.e("ChannelScreenViewModel", "Failed to fetch member", e)
@ -436,7 +435,7 @@ class ChannelScreenViewModel @Inject constructor(
val messages = arrayListOf<Message>()
fetchMessagesFromChannel(channelId, amount, true, before, after, around).let {
if (it.messages.isNullOrEmpty() || it.messages.size < 50) {
if (it.messages.isNullOrEmpty() || it.messages!!.size < 50) {
endOfChannel = true
}
@ -455,8 +454,8 @@ class ChannelScreenViewModel @Inject constructor(
}
it.members?.forEach { member ->
if (!StoatAPI.members.hasMember(member.id!!.server, member.id.user)) {
StoatAPI.members.setMember(member.id.server, member)
if (!StoatAPI.members.hasMember(member.id!!.server, member.id!!.user)) {
StoatAPI.members.setMember(member.id!!.server, member)
}
}
@ -580,7 +579,7 @@ class ChannelScreenViewModel @Inject constructor(
if (currentMessage == null) return@onEach
if (messageFrame.author != null) {
addUserIfUnknown(messageFrame.author)
addUserIfUnknown(messageFrame.author!!)
}
updateItems(

View File

@ -72,8 +72,8 @@ class CreateGroupScreenViewModel : ViewModel() {
return@filter false
}
it.displayName.contains(friendSearchQuery, ignoreCase = true) ||
it.username.contains(friendSearchQuery, ignoreCase = true)
it.displayName!!.contains(friendSearchQuery, ignoreCase = true) ||
it.username!!.contains(friendSearchQuery, ignoreCase = true)
}.map { it.id!! })
}
@ -203,7 +203,7 @@ fun CreateGroupScreen(
viewModel.groupMembers.remove(friend.id)
} else {
if (viewModel.groupMembers.size < MAX_ADDABLE_PEOPLE_IN_GROUP) {
viewModel.groupMembers.add(friend.id)
viewModel.groupMembers.add(friend.id!!)
}
}
},

View File

@ -31,8 +31,8 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.ChannelType
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.core.model.schemas.User
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.composables.generic.UserAvatar
import chat.stoat.internals.extensions.zero

View File

@ -72,12 +72,15 @@ import chat.stoat.api.settings.UserInterfaceFont
import chat.stoat.composables.generic.ListHeader
import chat.stoat.composables.screens.settings.appearance.ColourChip
import chat.stoat.composables.screens.settings.appearance.CornerRadiusPicker
import chat.stoat.core.model.data.OverridableColourScheme
import chat.stoat.sheets.ColourPickerSheet
import chat.stoat.ui.theme.GoogleSansFlex
import chat.stoat.ui.theme.Inter
import chat.stoat.ui.theme.OverridableColourScheme
import chat.stoat.ui.theme.Theme
import chat.stoat.ui.theme.applyFromKeyValueMap
import chat.stoat.ui.theme.getFieldByName
import chat.stoat.ui.theme.overridableColourSchemeFieldNameToResource
import chat.stoat.ui.theme.overridableColourSchemeFieldNames
import chat.stoat.ui.theme.systemSupportsDynamicColors
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
@ -167,7 +170,7 @@ class AppearanceSettingsScreenViewModel @Inject constructor(
SyncedSettings.updateAndroid(
SyncedSettings.android.copy(
colourOverrides = existingOverrides
.applyFromKeyValueMap(overrides.filterKeys { it in OverridableColourScheme.fieldNames })
.applyFromKeyValueMap(overrides.filterKeys { it in overridableColourSchemeFieldNames })
)
)
}
@ -544,14 +547,14 @@ fun AppearanceSettingsScreen(
Spacer(modifier = Modifier.height(10.dp))
OverridableColourScheme.fieldNames.forEach { fieldName ->
overridableColourSchemeFieldNames.forEach { fieldName ->
val value =
SyncedSettings.android.colourOverrides?.getFieldByName(fieldName)
?: MaterialTheme.colorScheme.getFieldByName(fieldName)
ColourChip(
color = Color(value ?: 0),
text = OverridableColourScheme.fieldNameToResource[fieldName]
text = overridableColourSchemeFieldNameToResource[fieldName]
?.let { context.getString(it) }
?: fieldName,
modifier = Modifier

View File

@ -52,7 +52,7 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.api.routes.user.fetchUserProfile
import chat.stoat.api.routes.user.patchSelf
import chat.stoat.api.schemas.Profile
import chat.stoat.core.model.schemas.Profile
import chat.stoat.composables.generic.InlineMediaPicker
import chat.stoat.composables.screens.settings.RawUserOverview
import dagger.hilt.android.lifecycle.HiltViewModel

View File

@ -51,7 +51,7 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.auth.fetchAllSessions
import chat.stoat.api.routes.auth.logoutAllSessions
import chat.stoat.api.routes.auth.logoutSessionById
import chat.stoat.api.schemas.Session
import chat.stoat.core.model.schemas.Session
import chat.stoat.composables.generic.ListHeader
import chat.stoat.composables.markdown.RichMarkdown
import chat.stoat.composables.settings.sessions.SessionItem

View File

@ -41,7 +41,7 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.PermissionBit
import chat.stoat.api.internals.hasPermission
import chat.stoat.api.routes.channel.leaveDeleteOrCloseChannel
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.api.settings.FeatureFlags
import chat.stoat.internals.extensions.rememberChannelPermissions
import chat.stoat.screens.settings.SettingsIcon

View File

@ -57,7 +57,7 @@ import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.channel.patchChannel
import chat.stoat.api.routes.microservices.autumn.uploadToAutumn
import chat.stoat.api.schemas.Channel
import chat.stoat.core.model.schemas.Channel
import chat.stoat.composables.generic.InlineMediaPicker
import chat.stoat.composables.generic.ListHeader
import dagger.hilt.android.lifecycle.HiltViewModel

View File

@ -58,7 +58,7 @@ fun ChannelContextSheet(channelId: String, onHideSheet: suspend () -> Unit) {
onClick = {
if (channel.id == null) return@SheetButton
clipboardManager.setText(AnnotatedString(channel.id))
clipboardManager.setText(AnnotatedString(channel.id!!))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(

View File

@ -31,7 +31,7 @@ import chat.stoat.api.internals.ChannelUtils
import chat.stoat.api.internals.PermissionBit
import chat.stoat.api.internals.Roles
import chat.stoat.api.internals.has
import chat.stoat.api.schemas.ChannelType
import chat.stoat.core.model.schemas.ChannelType
import chat.stoat.callbacks.Action
import chat.stoat.callbacks.ActionChannel
import chat.stoat.composables.generic.SheetButton

View File

@ -34,8 +34,8 @@ import chat.stoat.R
import chat.stoat.api.STOAT_FILES
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.custom.fetchEmoji
import chat.stoat.api.schemas.Emoji
import chat.stoat.api.schemas.Server
import chat.stoat.core.model.schemas.Emoji
import chat.stoat.core.model.schemas.Server
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.composables.generic.SheetButton
import chat.stoat.internals.Platform

View File

@ -39,13 +39,13 @@ import chat.stoat.api.internals.Roles
import chat.stoat.api.internals.hasPermission
import chat.stoat.api.routes.channel.fetchGroupParticipants
import chat.stoat.api.routes.server.fetchMembers
import chat.stoat.api.schemas.Member
import chat.stoat.api.schemas.User
import chat.stoat.composables.chat.MemberListItem
import chat.stoat.composables.generic.CountableListHeader
import chat.stoat.composables.generic.Presence
import chat.stoat.composables.generic.SheetHeaderPadding
import chat.stoat.composables.generic.presenceFromStatus
import chat.stoat.core.model.schemas.Member
import chat.stoat.core.model.schemas.User
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.distinctUntilChanged
@ -86,7 +86,7 @@ class MemberListSheetViewModel @Inject constructor(
val user = StoatAPI.userCache[member.id!!.user] ?: run {
Log.w(
"MemberListSheet",
"User ${member.id.user} found in member list of server $serverId but not in user cache"
"User ${member.id!!.user} found in member list of server $serverId but not in user cache"
)
return@forEach
}
@ -98,7 +98,7 @@ class MemberListSheetViewModel @Inject constructor(
}
val highestHoistedRole =
Roles.resolveHighestRole(serverId, member.id.user, hoisted = true)
Roles.resolveHighestRole(serverId, member.id!!.user, hoisted = true)
val category = if (highestHoistedRole != null) {
highestHoistedRole.name ?: context.getString(R.string.unknown)
@ -319,19 +319,19 @@ fun MemberListSheet(
is MemberListSheetItem.MemberItem -> item(key = item.member.id!!.user) {
MemberListItem(
user = StoatAPI.userCache[item.member.id.user],
user = StoatAPI.userCache[item.member.id!!.user],
member = item.member,
serverId = serverId,
userId = item.member.id.user,
userId = item.member.id!!.user,
modifier = Modifier
.combinedClickable(
onClick = {
userInfoSheetTarget = item.member.id.user
userInfoSheetTarget = item.member.id!!.user
showUserInfoSheet = true
},
onClickLabel = stringResource(R.string.user_info_sheet_open),
onLongClick = {
memberContextSheetTarget = item.member.id.user
memberContextSheetTarget = item.member.id!!.user
showMemberContextSheet = true
},
onLongClickLabel = stringResource(R.string.member_context_sheet_open)
@ -344,15 +344,15 @@ fun MemberListSheet(
user = item.user,
member = null,
serverId = serverId,
userId = item.user.id,
userId = item.user.id!!,
modifier = Modifier.combinedClickable(
onClick = {
userInfoSheetTarget = item.user.id
userInfoSheetTarget = item.user.id!!
showUserInfoSheet = true
},
onClickLabel = stringResource(R.string.user_info_sheet_open),
onLongClick = {
memberContextSheetTarget = item.user.id
memberContextSheetTarget = item.user.id!!
showMemberContextSheet = true
},
onLongClickLabel = stringResource(R.string.member_context_sheet_open)

View File

@ -132,7 +132,7 @@ fun MessageContextSheet(
shareSheetState.hide()
}
coroutineScope.launch {
clipboardManager.setText(AnnotatedString(message.content))
clipboardManager.setText(AnnotatedString(message.content!!))
onHideSheet()
}
}
@ -215,7 +215,7 @@ fun MessageContextSheet(
onClick = {
if (message.id == null) return@SheetButton
clipboardManager.setText(AnnotatedString(message.id))
clipboardManager.setText(AnnotatedString(message.id!!))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(

View File

@ -49,11 +49,11 @@ import chat.stoat.api.StoatAPI
import chat.stoat.api.internals.isUlid
import chat.stoat.api.routes.custom.fetchEmoji
import chat.stoat.api.routes.user.fetchUser
import chat.stoat.api.schemas.Emoji
import chat.stoat.api.schemas.User
import chat.stoat.api.settings.LoadedSettings
import chat.stoat.composables.chat.MemberListItem
import chat.stoat.composables.generic.RemoteImage
import chat.stoat.core.model.schemas.Emoji
import chat.stoat.core.model.schemas.User
import chat.stoat.internals.text.MessageProcessor
import chat.stoat.persistence.KVStorage
import kotlinx.coroutines.launch
@ -288,8 +288,8 @@ fun ReactionInfoSheet(messageId: String, emoji: String, onDismiss: () -> Unit) {
text = if (current.isUlid()) {
val cached = extendedEmojiInfo.find { it.id == current }
if (cached?.parent != null) {
when (cached.parent.type) {
"Server" -> StoatAPI.serverCache[cached.parent.id]?.name?.let {
when (cached.parent!!.type) {
"Server" -> StoatAPI.serverCache[cached.parent!!.id]?.name?.let {
stringResource(
id = R.string.emote_info_from_server,
it
@ -320,7 +320,7 @@ fun ReactionInfoSheet(messageId: String, emoji: String, onDismiss: () -> Unit) {
val userOrNull = StoatAPI.userCache[reaction]
val user = userOrNull ?: User.getPlaceholder(reaction)
val member = if (channel.server != null && user.id != null) {
StoatAPI.members.getMember(channel.server, user.id)
StoatAPI.members.getMember(channel.server!!, user.id!!)
} else {
null
}

View File

@ -161,7 +161,7 @@ fun ServerContextSheet(
SelectionContainer {
RichMarkdown(
input = if (server.description?.isBlank() == false) {
server.description
server.description!!
} else {
stringResource(
R.string.server_context_sheet_description_empty
@ -220,7 +220,7 @@ fun ServerContextSheet(
onClick = {
if (server.id == null) return@SheetButton
clipboardManager.setText(AnnotatedString(server.id))
clipboardManager.setText(AnnotatedString(server.id!!))
if (Platform.needsShowClipboardNotification()) {
Toast.makeText(

View File

@ -37,7 +37,7 @@ import androidx.compose.ui.unit.dp
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.routes.user.patchSelf
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.generic.SheetButton
import chat.stoat.composables.generic.asApiName
import chat.stoat.composables.generic.presenceFromStatus

View File

@ -39,7 +39,7 @@ import androidx.core.content.FileProvider
import chat.stoat.BuildConfig
import chat.stoat.R
import chat.stoat.api.StoatAPI
import chat.stoat.api.schemas.User
import chat.stoat.core.model.schemas.User
import chat.stoat.composables.profile.UserCard
import chat.stoat.internals.Platform
import kotlinx.coroutines.Dispatchers

View File

@ -44,7 +44,6 @@ import chat.stoat.api.internals.BrushCompat
import chat.stoat.api.internals.ULID
import chat.stoat.api.internals.solidColor
import chat.stoat.api.routes.user.fetchUserProfile
import chat.stoat.api.schemas.Profile
import chat.stoat.api.settings.Experiments
import chat.stoat.api.settings.FeatureFlags
import chat.stoat.composables.chat.RoleListEntry
@ -56,6 +55,7 @@ import chat.stoat.composables.markdown.RichMarkdown
import chat.stoat.composables.screens.settings.RawUserOverview
import chat.stoat.composables.screens.settings.UserButtons
import chat.stoat.composables.sheets.SheetTile
import chat.stoat.core.model.schemas.Profile
import kotlinx.datetime.Instant
@OptIn(ExperimentalMaterial3Api::class)
@ -216,14 +216,14 @@ fun UserInfoSheet(
}
val accountAt = user.id?.let {
DateUtils.getRelativeTimeSpanString(
ULID.asTimestamp(user.id),
ULID.asTimestamp(user.id!!),
System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS
).toString()
}
val joinedAt = member?.joinedAt?.let {
DateUtils.getRelativeTimeSpanString(
Instant.parse(member.joinedAt).toEpochMilliseconds(),
Instant.parse(member.joinedAt!!).toEpochMilliseconds(),
System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS
).toString()
@ -242,7 +242,7 @@ fun UserInfoSheet(
)
Text(
text = server.name,
text = server.name!!,
style = MaterialTheme.typography.labelMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis
@ -271,7 +271,7 @@ fun UserInfoSheet(
)
Text(
text = server.name,
text = server.name!!,
style = MaterialTheme.typography.labelMedium
)
@ -315,7 +315,7 @@ fun UserInfoSheet(
},
contentPreview = {
Text(
text = user.status.text,
text = user.status!!.text!!,
fontSize = 14.sp,
maxLines = 5,
overflow = TextOverflow.Ellipsis
@ -323,7 +323,7 @@ fun UserInfoSheet(
}
) {
Text(
text = user.status.text,
text = user.status!!.text!!,
style = MaterialTheme.typography.bodyMedium
)
}
@ -331,7 +331,7 @@ fun UserInfoSheet(
}
if (user.bot != null) {
val resolvedOwner = user.bot.owner?.let { StoatAPI.userCache[it] }
val resolvedOwner = user.bot!!.owner?.let { StoatAPI.userCache[it] }
item(key = "bot-owner") {
SheetTile(

View File

@ -4,252 +4,237 @@ import androidx.compose.material3.ColorScheme
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import chat.stoat.R
import kotlinx.serialization.Serializable
import chat.stoat.core.model.data.OverridableColourScheme
// Word of warning, this file is ugly, because I've had to fight a bit with the Compose compiler,
// namely native Kotlin (not Java) reflection seems to consistently break it.
// So I've had to resort to... methods like this. I'm sorry.
// If you've been linked to this file, I promise the rest of the codebase is not like this.
// Original comments during research and development preserved.
@Serializable
data class OverridableColourScheme(
val primary: Int? = null,
val onPrimary: Int? = null,
val primaryContainer: Int? = null,
val onPrimaryContainer: Int? = null,
val inversePrimary: Int? = null,
val secondary: Int? = null,
val onSecondary: Int? = null,
val secondaryContainer: Int? = null,
val onSecondaryContainer: Int? = null,
val tertiary: Int? = null,
val onTertiary: Int? = null,
val tertiaryContainer: Int? = null,
val onTertiaryContainer: Int? = null,
val background: Int? = null,
val onBackground: Int? = null,
val surface: Int? = null,
val onSurface: Int? = null,
val surfaceVariant: Int? = null,
val onSurfaceVariant: Int? = null,
val surfaceTint: Int? = null,
val inverseSurface: Int? = null,
val inverseOnSurface: Int? = null,
val error: Int? = null,
val onError: Int? = null,
val errorContainer: Int? = null,
val onErrorContainer: Int? = null,
val outline: Int? = null,
val outlineVariant: Int? = null,
val scrim: Int? = null
) {
fun applyTo(colorScheme: ColorScheme): ColorScheme {
var newScheme = colorScheme.copy()
fun OverridableColourScheme.applyTo(colorScheme: ColorScheme): ColorScheme {
var newScheme = colorScheme.copy()
// This is SLOW. It is also STUPID. But using reflection breaks the Compose compiler.
// Another piece of trash from Google. This company should go bankrupt already, what a
// joke.
if (primary != null) newScheme = newScheme.copy(primary = Color(primary))
if (onPrimary != null) newScheme = newScheme.copy(onPrimary = Color(onPrimary))
if (primaryContainer != null) newScheme =
newScheme.copy(primaryContainer = Color(primaryContainer))
if (onPrimaryContainer != null) newScheme =
newScheme.copy(onPrimaryContainer = Color(onPrimaryContainer))
if (inversePrimary != null) newScheme =
newScheme.copy(inversePrimary = Color(inversePrimary))
if (secondary != null) newScheme = newScheme.copy(secondary = Color(secondary))
if (onSecondary != null) newScheme = newScheme.copy(onSecondary = Color(onSecondary))
if (secondaryContainer != null) newScheme =
newScheme.copy(secondaryContainer = Color(secondaryContainer))
if (onSecondaryContainer != null) newScheme =
newScheme.copy(onSecondaryContainer = Color(onSecondaryContainer))
if (tertiary != null) newScheme = newScheme.copy(tertiary = Color(tertiary))
if (onTertiary != null) newScheme = newScheme.copy(onTertiary = Color(onTertiary))
if (tertiaryContainer != null) newScheme =
newScheme.copy(tertiaryContainer = Color(tertiaryContainer))
if (onTertiaryContainer != null) newScheme =
newScheme.copy(onTertiaryContainer = Color(onTertiaryContainer))
if (background != null) newScheme = newScheme.copy(background = Color(background))
if (onBackground != null) newScheme = newScheme.copy(onBackground = Color(onBackground))
if (surface != null) newScheme = newScheme.copy(surface = Color(surface))
if (onSurface != null) newScheme = newScheme.copy(onSurface = Color(onSurface))
if (surfaceVariant != null) newScheme =
newScheme.copy(surfaceVariant = Color(surfaceVariant))
if (onSurfaceVariant != null) newScheme =
newScheme.copy(onSurfaceVariant = Color(onSurfaceVariant))
if (surfaceTint != null) newScheme = newScheme.copy(surfaceTint = Color(surfaceTint))
if (inverseSurface != null) newScheme =
newScheme.copy(inverseSurface = Color(inverseSurface))
if (inverseOnSurface != null) newScheme =
newScheme.copy(inverseOnSurface = Color(inverseOnSurface))
if (error != null) newScheme = newScheme.copy(error = Color(error))
if (onError != null) newScheme = newScheme.copy(onError = Color(onError))
if (errorContainer != null) newScheme =
newScheme.copy(errorContainer = Color(errorContainer))
if (onErrorContainer != null) newScheme =
newScheme.copy(onErrorContainer = Color(onErrorContainer))
if (outline != null) newScheme = newScheme.copy(outline = Color(outline))
if (outlineVariant != null) newScheme =
newScheme.copy(outlineVariant = Color(outlineVariant))
if (scrim != null) newScheme = newScheme.copy(scrim = Color(scrim))
return newScheme
primary?.let { newScheme = newScheme.copy(primary = Color(it)) }
onPrimary?.let { newScheme = newScheme.copy(onPrimary = Color(it)) }
primaryContainer?.let {
newScheme =
newScheme.copy(primaryContainer = Color(it))
}
fun applyFromKeyValueMap(map: Map<String, Int>): OverridableColourScheme {
var newScheme = this
map.filterKeys { it in fieldNames }.forEach { (key, value) ->
when (key) {
"primary" -> newScheme = newScheme.copy(primary = value)
"onPrimary" -> newScheme = newScheme.copy(onPrimary = value)
"primaryContainer" -> newScheme = newScheme.copy(primaryContainer = value)
"onPrimaryContainer" -> newScheme =
newScheme.copy(onPrimaryContainer = value)
"inversePrimary" -> newScheme = newScheme.copy(inversePrimary = (value))
"secondary" -> newScheme = newScheme.copy(secondary = (value))
"onSecondary" -> newScheme = newScheme.copy(onSecondary = (value))
"secondaryContainer" -> newScheme =
newScheme.copy(secondaryContainer = (value))
"onSecondaryContainer" -> newScheme =
newScheme.copy(onSecondaryContainer = (value))
"tertiary" -> newScheme = newScheme.copy(tertiary = (value))
"onTertiary" -> newScheme = newScheme.copy(onTertiary = (value))
"tertiaryContainer" -> newScheme = newScheme.copy(tertiaryContainer = (value))
"onTertiaryContainer" -> newScheme =
newScheme.copy(onTertiaryContainer = (value))
"background" -> newScheme = newScheme.copy(background = (value))
"onBackground" -> newScheme = newScheme.copy(onBackground = (value))
"surface" -> newScheme = newScheme.copy(surface = (value))
"onSurface" -> newScheme = newScheme.copy(onSurface = (value))
"surfaceVariant" -> newScheme = newScheme.copy(surfaceVariant = (value))
"onSurfaceVariant" -> newScheme = newScheme.copy(onSurfaceVariant = (value))
"surfaceTint" -> newScheme = newScheme.copy(surfaceTint = (value))
"inverseSurface" -> newScheme = newScheme.copy(inverseSurface = (value))
"inverseOnSurface" -> newScheme = newScheme.copy(inverseOnSurface = (value))
"error" -> newScheme = newScheme.copy(error = (value))
"onError" -> newScheme = newScheme.copy(onError = (value))
"errorContainer" -> newScheme = newScheme.copy(errorContainer = (value))
"onErrorContainer" -> newScheme = newScheme.copy(onErrorContainer = (value))
"outline" -> newScheme = newScheme.copy(outline = (value))
"outlineVariant" -> newScheme = newScheme.copy(outlineVariant = (value))
"scrim" -> newScheme = newScheme.copy(scrim = (value))
}
}
return newScheme
onPrimaryContainer?.let {
newScheme =
newScheme.copy(onPrimaryContainer = Color(it))
}
inversePrimary?.let {
newScheme =
newScheme.copy(inversePrimary = Color(it))
}
secondary?.let { newScheme = newScheme.copy(secondary = Color(it)) }
onSecondary?.let { newScheme = newScheme.copy(onSecondary = Color(it)) }
secondaryContainer?.let {
newScheme =
newScheme.copy(secondaryContainer = Color(it))
}
onSecondaryContainer?.let {
newScheme =
newScheme.copy(onSecondaryContainer = Color(it))
}
tertiary?.let { newScheme = newScheme.copy(tertiary = Color(it)) }
onTertiary?.let { newScheme = newScheme.copy(onTertiary = Color(it)) }
tertiaryContainer?.let {
newScheme =
newScheme.copy(tertiaryContainer = Color(it))
}
onTertiaryContainer?.let {
newScheme =
newScheme.copy(onTertiaryContainer = Color(it))
}
background?.let { newScheme = newScheme.copy(background = Color(it)) }
onBackground?.let { newScheme = newScheme.copy(onBackground = Color(it)) }
surface?.let { newScheme = newScheme.copy(surface = Color(it)) }
onSurface?.let { newScheme = newScheme.copy(onSurface = Color(it)) }
surfaceVariant?.let {
newScheme =
newScheme.copy(surfaceVariant = Color(it))
}
onSurfaceVariant?.let {
newScheme =
newScheme.copy(onSurfaceVariant = Color(it))
}
surfaceTint?.let { newScheme = newScheme.copy(surfaceTint = Color(it)) }
inverseSurface?.let {
newScheme =
newScheme.copy(inverseSurface = Color(it))
}
inverseOnSurface?.let {
newScheme =
newScheme.copy(inverseOnSurface = Color(it))
}
error?.let { newScheme = newScheme.copy(error = Color(it)) }
onError?.let { newScheme = newScheme.copy(onError = Color(it)) }
errorContainer?.let {
newScheme =
newScheme.copy(errorContainer = Color(it))
}
onErrorContainer?.let {
newScheme =
newScheme.copy(onErrorContainer = Color(it))
}
outline?.let { newScheme = newScheme.copy(outline = Color(it)) }
outlineVariant?.let {
newScheme =
newScheme.copy(outlineVariant = Color(it))
}
scrim?.let { newScheme = newScheme.copy(scrim = Color(it)) }
fun getFieldByName(name: String): Int? {
return when (name) {
"primary" -> primary
"onPrimary" -> onPrimary
"primaryContainer" -> primaryContainer
"onPrimaryContainer" -> onPrimaryContainer
"inversePrimary" -> inversePrimary
"secondary" -> secondary
"onSecondary" -> onSecondary
"secondaryContainer" -> secondaryContainer
"onSecondaryContainer" -> onSecondaryContainer
"tertiary" -> tertiary
"onTertiary" -> onTertiary
"tertiaryContainer" -> tertiaryContainer
"onTertiaryContainer" -> onTertiaryContainer
"background" -> background
"onBackground" -> onBackground
"surface" -> surface
"onSurface" -> onSurface
"surfaceVariant" -> surfaceVariant
"onSurfaceVariant" -> onSurfaceVariant
"surfaceTint" -> surfaceTint
"inverseSurface" -> inverseSurface
"inverseOnSurface" -> inverseOnSurface
"error" -> error
"onError" -> onError
"errorContainer" -> errorContainer
"onErrorContainer" -> onErrorContainer
"outline" -> outline
"outlineVariant" -> outlineVariant
"scrim" -> scrim
else -> null
return newScheme
}
fun OverridableColourScheme.applyFromKeyValueMap(map: Map<String, Int>): OverridableColourScheme {
var newScheme = this
map.filterKeys { it in overridableColourSchemeFieldNames }.forEach { (key, value) ->
when (key) {
"primary" -> newScheme = newScheme.copy(primary = value)
"onPrimary" -> newScheme = newScheme.copy(onPrimary = value)
"primaryContainer" -> newScheme = newScheme.copy(primaryContainer = value)
"onPrimaryContainer" -> newScheme =
newScheme.copy(onPrimaryContainer = value)
"inversePrimary" -> newScheme = newScheme.copy(inversePrimary = (value))
"secondary" -> newScheme = newScheme.copy(secondary = (value))
"onSecondary" -> newScheme = newScheme.copy(onSecondary = (value))
"secondaryContainer" -> newScheme =
newScheme.copy(secondaryContainer = (value))
"onSecondaryContainer" -> newScheme =
newScheme.copy(onSecondaryContainer = (value))
"tertiary" -> newScheme = newScheme.copy(tertiary = (value))
"onTertiary" -> newScheme = newScheme.copy(onTertiary = (value))
"tertiaryContainer" -> newScheme = newScheme.copy(tertiaryContainer = (value))
"onTertiaryContainer" -> newScheme =
newScheme.copy(onTertiaryContainer = (value))
"background" -> newScheme = newScheme.copy(background = (value))
"onBackground" -> newScheme = newScheme.copy(onBackground = (value))
"surface" -> newScheme = newScheme.copy(surface = (value))
"onSurface" -> newScheme = newScheme.copy(onSurface = (value))
"surfaceVariant" -> newScheme = newScheme.copy(surfaceVariant = (value))
"onSurfaceVariant" -> newScheme = newScheme.copy(onSurfaceVariant = (value))
"surfaceTint" -> newScheme = newScheme.copy(surfaceTint = (value))
"inverseSurface" -> newScheme = newScheme.copy(inverseSurface = (value))
"inverseOnSurface" -> newScheme = newScheme.copy(inverseOnSurface = (value))
"error" -> newScheme = newScheme.copy(error = (value))
"onError" -> newScheme = newScheme.copy(onError = (value))
"errorContainer" -> newScheme = newScheme.copy(errorContainer = (value))
"onErrorContainer" -> newScheme = newScheme.copy(onErrorContainer = (value))
"outline" -> newScheme = newScheme.copy(outline = (value))
"outlineVariant" -> newScheme = newScheme.copy(outlineVariant = (value))
"scrim" -> newScheme = newScheme.copy(scrim = (value))
}
}
companion object {
// I am genuinely going to go to Google's office and hand them this code and tell them
// to fix their garbage Gradle plugin
val fieldNames = listOf(
"primary",
"onPrimary",
"primaryContainer",
"onPrimaryContainer",
"inversePrimary",
"secondary",
"onSecondary",
"secondaryContainer",
"onSecondaryContainer",
"tertiary",
"onTertiary",
"tertiaryContainer",
"onTertiaryContainer",
"background",
"onBackground",
"surface",
"onSurface",
"surfaceVariant",
"onSurfaceVariant",
"surfaceTint",
"inverseSurface",
"inverseOnSurface",
"error",
"onError",
"errorContainer",
"onErrorContainer",
"outline",
"outlineVariant",
"scrim"
)
return newScheme
}
// See above comment HOLY SHIT i am genuinely going insane
val fieldNameToResource = mapOf(
"primary" to R.string.settings_appearance_colour_overrides_primary,
"onPrimary" to R.string.settings_appearance_colour_overrides_on_primary,
"primaryContainer" to R.string.settings_appearance_colour_overrides_primary_container,
"onPrimaryContainer" to R.string.settings_appearance_colour_overrides_on_primary_container,
"inversePrimary" to R.string.settings_appearance_colour_overrides_inverse_primary,
"secondary" to R.string.settings_appearance_colour_overrides_secondary,
"onSecondary" to R.string.settings_appearance_colour_overrides_on_secondary,
"secondaryContainer" to R.string.settings_appearance_colour_overrides_secondary_container,
"onSecondaryContainer" to R.string.settings_appearance_colour_overrides_on_secondary_container,
"tertiary" to R.string.settings_appearance_colour_overrides_tertiary,
"onTertiary" to R.string.settings_appearance_colour_overrides_on_tertiary,
"tertiaryContainer" to R.string.settings_appearance_colour_overrides_tertiary_container,
"onTertiaryContainer" to R.string.settings_appearance_colour_overrides_on_tertiary_container,
"background" to R.string.settings_appearance_colour_overrides_background,
"onBackground" to R.string.settings_appearance_colour_overrides_on_background,
"surface" to R.string.settings_appearance_colour_overrides_surface,
"onSurface" to R.string.settings_appearance_colour_overrides_on_surface,
"surfaceVariant" to R.string.settings_appearance_colour_overrides_surface_variant,
"onSurfaceVariant" to R.string.settings_appearance_colour_overrides_on_surface_variant,
"surfaceTint" to R.string.settings_appearance_colour_overrides_surface_tint,
"inverseSurface" to R.string.settings_appearance_colour_overrides_inverse_surface,
"inverseOnSurface" to R.string.settings_appearance_colour_overrides_inverse_on_surface,
"error" to R.string.settings_appearance_colour_overrides_error,
"onError" to R.string.settings_appearance_colour_overrides_on_error,
"errorContainer" to R.string.settings_appearance_colour_overrides_error_container,
"onErrorContainer" to R.string.settings_appearance_colour_overrides_on_error_container,
"outline" to R.string.settings_appearance_colour_overrides_outline,
"outlineVariant" to R.string.settings_appearance_colour_overrides_outline_variant,
"scrim" to R.string.settings_appearance_colour_overrides_scrim
)
fun OverridableColourScheme.getFieldByName(name: String): Int? {
return when (name) {
"primary" -> primary
"onPrimary" -> onPrimary
"primaryContainer" -> primaryContainer
"onPrimaryContainer" -> onPrimaryContainer
"inversePrimary" -> inversePrimary
"secondary" -> secondary
"onSecondary" -> onSecondary
"secondaryContainer" -> secondaryContainer
"onSecondaryContainer" -> onSecondaryContainer
"tertiary" -> tertiary
"onTertiary" -> onTertiary
"tertiaryContainer" -> tertiaryContainer
"onTertiaryContainer" -> onTertiaryContainer
"background" -> background
"onBackground" -> onBackground
"surface" -> surface
"onSurface" -> onSurface
"surfaceVariant" -> surfaceVariant
"onSurfaceVariant" -> onSurfaceVariant
"surfaceTint" -> surfaceTint
"inverseSurface" -> inverseSurface
"inverseOnSurface" -> inverseOnSurface
"error" -> error
"onError" -> onError
"errorContainer" -> errorContainer
"onErrorContainer" -> onErrorContainer
"outline" -> outline
"outlineVariant" -> outlineVariant
"scrim" -> scrim
else -> null
}
}
val overridableColourSchemeFieldNames: List<String>
get() = listOf(
"primary",
"onPrimary",
"primaryContainer",
"onPrimaryContainer",
"inversePrimary",
"secondary",
"onSecondary",
"secondaryContainer",
"onSecondaryContainer",
"tertiary",
"onTertiary",
"tertiaryContainer",
"onTertiaryContainer",
"background",
"onBackground",
"surface",
"onSurface",
"surfaceVariant",
"onSurfaceVariant",
"surfaceTint",
"inverseSurface",
"inverseOnSurface",
"error",
"onError",
"errorContainer",
"onErrorContainer",
"outline",
"outlineVariant",
"scrim"
)
val overridableColourSchemeFieldNameToResource: Map<String, Int>
get() = mapOf(
"primary" to R.string.settings_appearance_colour_overrides_primary,
"onPrimary" to R.string.settings_appearance_colour_overrides_on_primary,
"primaryContainer" to R.string.settings_appearance_colour_overrides_primary_container,
"onPrimaryContainer" to R.string.settings_appearance_colour_overrides_on_primary_container,
"inversePrimary" to R.string.settings_appearance_colour_overrides_inverse_primary,
"secondary" to R.string.settings_appearance_colour_overrides_secondary,
"onSecondary" to R.string.settings_appearance_colour_overrides_on_secondary,
"secondaryContainer" to R.string.settings_appearance_colour_overrides_secondary_container,
"onSecondaryContainer" to R.string.settings_appearance_colour_overrides_on_secondary_container,
"tertiary" to R.string.settings_appearance_colour_overrides_tertiary,
"onTertiary" to R.string.settings_appearance_colour_overrides_on_tertiary,
"tertiaryContainer" to R.string.settings_appearance_colour_overrides_tertiary_container,
"onTertiaryContainer" to R.string.settings_appearance_colour_overrides_on_tertiary_container,
"background" to R.string.settings_appearance_colour_overrides_background,
"onBackground" to R.string.settings_appearance_colour_overrides_on_background,
"surface" to R.string.settings_appearance_colour_overrides_surface,
"onSurface" to R.string.settings_appearance_colour_overrides_on_surface,
"surfaceVariant" to R.string.settings_appearance_colour_overrides_surface_variant,
"onSurfaceVariant" to R.string.settings_appearance_colour_overrides_on_surface_variant,
"surfaceTint" to R.string.settings_appearance_colour_overrides_surface_tint,
"inverseSurface" to R.string.settings_appearance_colour_overrides_inverse_surface,
"inverseOnSurface" to R.string.settings_appearance_colour_overrides_inverse_on_surface,
"error" to R.string.settings_appearance_colour_overrides_error,
"onError" to R.string.settings_appearance_colour_overrides_on_error,
"errorContainer" to R.string.settings_appearance_colour_overrides_error_container,
"onErrorContainer" to R.string.settings_appearance_colour_overrides_on_error_container,
"outline" to R.string.settings_appearance_colour_overrides_outline,
"outlineVariant" to R.string.settings_appearance_colour_overrides_outline_variant,
"scrim" to R.string.settings_appearance_colour_overrides_scrim
)
fun ColorScheme.getFieldByName(name: String): Int? {
return when (name) {
"primary" -> primary.toArgb()

View File

@ -18,6 +18,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.ViewCompat
import chat.stoat.api.settings.UserInterfaceFont
import chat.stoat.core.model.data.OverridableColourScheme
val LightColorScheme = lightColorScheme(
primary = Colour.PrimaryLight,

View File

@ -1,6 +1,8 @@
plugins {
id("java-library")
id("org.jetbrains.kotlin.jvm")
alias(libs.plugins.android.library)
id("kotlin-parcelize")
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
}
java {
sourceCompatibility = JavaVersion.VERSION_11
@ -11,3 +13,21 @@ kotlin {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}
}
android {
namespace = "chat.stoat.core.model"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
dependencies {
implementation(libs.kotlin.serialization.json)
implementation(libs.kotlin.datetime)
compileOnly(libs.android.core.ktx)
}

View File

@ -1,4 +0,0 @@
package chat.stoat.core.model
class CoreModel {
}

View File

@ -0,0 +1,11 @@
package chat.stoat.core.model.data
const val STOAT_BASE = "https://api.stoat.chat/0.8"
const val STOAT_SUPPORT = "https://support.stoat.chat"
const val STOAT_MARKETING = "https://stoat.chat"
const val STOAT_FILES = "https://cdn.stoatusercontent.com"
const val STOAT_PROXY = "https://proxy.stoatusercontent.com"
const val STOAT_WEB_APP = "https://stoat.chat"
const val STOAT_INVITES = "https://stt.gg"
const val STOAT_WEBSOCKET = "wss://events.stoat.chat"
const val STOAT_KJBOOK = "https://stoatchat.github.io/for-android"

Some files were not shown because too many files have changed in this diff Show More