Merge pull request #1731 from vector-im/feature/bma/variousCleanup
Konsist: check if sealed class could be sealed interface
This commit is contained in:
commit
fad35bfade
30 changed files with 148 additions and 59 deletions
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package io.element.android.features.lockscreen.impl.pin.model
|
package io.element.android.features.lockscreen.impl.pin.model
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface PinDigit {
|
sealed interface PinDigit {
|
||||||
data object Empty : PinDigit
|
data object Empty : PinDigit
|
||||||
data class Filled(val value: Char) : PinDigit
|
data class Filled(val value: Char) : PinDigit
|
||||||
|
|
|
||||||
|
|
@ -170,9 +170,8 @@ private fun CustomSheetState.getIntOffset(): Int? = try {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class Slot {
|
private sealed interface Slot {
|
||||||
data class SheetContent(val key: Int?) : Slot()
|
data class SheetContent(val key: Int?) : Slot
|
||||||
data object DragHandle : Slot()
|
data object DragHandle : Slot
|
||||||
data object Scaffold : Slot()
|
data object Scaffold : Slot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
|
@ -409,6 +410,7 @@ class MessageComposerPresenter @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface RoomMemberSuggestion {
|
sealed interface RoomMemberSuggestion {
|
||||||
data object Room : RoomMemberSuggestion
|
data object Room : RoomMemberSuggestion
|
||||||
data class Member(val roomMember: RoomMember) : RoomMemberSuggestion
|
data class Member(val roomMember: RoomMember) : RoomMemberSuggestion
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import androidx.compose.foundation.shape.CornerSize
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
|
@ -103,11 +104,12 @@ fun MessagesReactionButton(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class MessagesReactionsButtonContent {
|
@Immutable
|
||||||
data class Text(val text: String) : MessagesReactionsButtonContent()
|
sealed interface MessagesReactionsButtonContent {
|
||||||
data class Icon(@DrawableRes val resourceId: Int) : MessagesReactionsButtonContent()
|
data class Text(val text: String) : MessagesReactionsButtonContent
|
||||||
|
data class Icon(@DrawableRes val resourceId: Int) : MessagesReactionsButtonContent
|
||||||
|
|
||||||
data class Reaction(val reaction: AggregatedReaction) : MessagesReactionsButtonContent()
|
data class Reaction(val reaction: AggregatedReaction) : MessagesReactionsButtonContent
|
||||||
|
|
||||||
val isHighlighted get() = this is Reaction && reaction.isHighlighted
|
val isHighlighted get() = this is Reaction && reaction.isHighlighted
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package io.element.android.features.messages.impl.timeline.model.event
|
package io.element.android.features.messages.impl.timeline.model.event
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface TimelineItemStateContent : TimelineItemEventContent {
|
sealed interface TimelineItemStateContent : TimelineItemEventContent {
|
||||||
val body: String
|
val body: String
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@
|
||||||
|
|
||||||
package io.element.android.features.messages.impl.timeline.model.event
|
package io.element.android.features.messages.impl.timeline.model.event
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface TimelineItemTextBasedContent : TimelineItemEventContent {
|
sealed interface TimelineItemTextBasedContent : TimelineItemEventContent {
|
||||||
val body: String
|
val body: String
|
||||||
val htmlDocument: Document?
|
val htmlDocument: Document?
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ import android.os.SystemClock
|
||||||
class FirstThrottler(private val minimumInterval: Long = 800) {
|
class FirstThrottler(private val minimumInterval: Long = 800) {
|
||||||
private var lastDate = 0L
|
private var lastDate = 0L
|
||||||
|
|
||||||
sealed class CanHandleResult {
|
sealed interface CanHandleResult {
|
||||||
data object Yes : CanHandleResult()
|
data object Yes : CanHandleResult
|
||||||
data class No(val shouldWaitMillis: Long) : CanHandleResult()
|
data class No(val shouldWaitMillis: Long) : CanHandleResult
|
||||||
|
|
||||||
fun waitMillis(): Long {
|
fun waitMillis(): Long {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,16 @@ package io.element.android.libraries.designsystem.components.button
|
||||||
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.libraries.designsystem.theme.components.Button
|
import io.element.android.libraries.designsystem.theme.components.Button
|
||||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||||
import io.element.android.libraries.designsystem.theme.components.IconSource
|
import io.element.android.libraries.designsystem.theme.components.IconSource
|
||||||
import io.element.android.libraries.designsystem.theme.components.TextButton
|
import io.element.android.libraries.designsystem.theme.components.TextButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sealed class that represents the different visual styles that a button can have.
|
* A sealed interface that represents the different visual styles that a button can have.
|
||||||
*/
|
*/
|
||||||
|
@Immutable
|
||||||
sealed interface ButtonVisuals {
|
sealed interface ButtonVisuals {
|
||||||
|
|
||||||
val action: () -> Unit
|
val action: () -> Unit
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package io.element.android.libraries.designsystem.components.list
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
|
|
@ -34,6 +35,7 @@ import io.element.android.libraries.designsystem.theme.components.Text as TextCo
|
||||||
/**
|
/**
|
||||||
* This is a helper to set default leading and trailing content for [ListItem]s.
|
* This is a helper to set default leading and trailing content for [ListItem]s.
|
||||||
*/
|
*/
|
||||||
|
@Immutable
|
||||||
sealed interface ListItemContent {
|
sealed interface ListItemContent {
|
||||||
/**
|
/**
|
||||||
* Default Switch content for [ListItem].
|
* Default Switch content for [ListItem].
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
@ -238,6 +239,7 @@ private fun ButtonInternal(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface IconSource {
|
sealed interface IconSource {
|
||||||
val contentDescription: String?
|
val contentDescription: String?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
|
@ -134,6 +135,7 @@ fun ListItem(
|
||||||
/**
|
/**
|
||||||
* The style to use for a [ListItem].
|
* The style to use for a [ListItem].
|
||||||
*/
|
*/
|
||||||
|
@Immutable
|
||||||
sealed interface ListItemStyle {
|
sealed interface ListItemStyle {
|
||||||
data object Default : ListItemStyle
|
data object Default : ListItemStyle
|
||||||
data object Primary : ListItemStyle
|
data object Primary : ListItemStyle
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.ExperimentalTextApi
|
import androidx.compose.ui.text.ExperimentalTextApi
|
||||||
|
|
@ -82,6 +83,7 @@ fun ListSupportingText(
|
||||||
object ListSupportingTextDefaults {
|
object ListSupportingTextDefaults {
|
||||||
|
|
||||||
/** Specifies the padding to use for the supporting text. */
|
/** Specifies the padding to use for the supporting text. */
|
||||||
|
@Immutable
|
||||||
sealed interface Padding {
|
sealed interface Padding {
|
||||||
/** No padding. */
|
/** No padding. */
|
||||||
data object None : Padding
|
data object None : Padding
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import androidx.compose.material3.SearchBarColors
|
||||||
import androidx.compose.material3.SearchBarDefaults
|
import androidx.compose.material3.SearchBarDefaults
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
@ -180,6 +181,7 @@ object ElementSearchBarDefaults {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface SearchBarResultState<in T> {
|
sealed interface SearchBarResultState<in T> {
|
||||||
/** No search results are available yet (e.g. because the user hasn't entered a search term). */
|
/** No search results are available yet (e.g. because the user hasn't entered a search term). */
|
||||||
class NotSearching<T> : SearchBarResultState<T>
|
class NotSearching<T> : SearchBarResultState<T>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.element.android-library")
|
id("io.element.android-compose-library")
|
||||||
id("kotlin-parcelize")
|
id("kotlin-parcelize")
|
||||||
alias(libs.plugins.anvil)
|
alias(libs.plugins.anvil)
|
||||||
kotlin("plugin.serialization") version "1.9.10"
|
kotlin("plugin.serialization") version "1.9.10"
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,14 @@ import android.net.Uri
|
||||||
* This sealed class represents all the permalink cases.
|
* This sealed class represents all the permalink cases.
|
||||||
* You don't have to instantiate yourself but should use [PermalinkParser] instead.
|
* You don't have to instantiate yourself but should use [PermalinkParser] instead.
|
||||||
*/
|
*/
|
||||||
sealed class PermalinkData {
|
sealed interface PermalinkData {
|
||||||
|
|
||||||
data class RoomLink(
|
data class RoomLink(
|
||||||
val roomIdOrAlias: String,
|
val roomIdOrAlias: String,
|
||||||
val isRoomAlias: Boolean,
|
val isRoomAlias: Boolean,
|
||||||
val eventId: String?,
|
val eventId: String?,
|
||||||
val viaParameters: List<String>
|
val viaParameters: List<String>
|
||||||
) : PermalinkData()
|
) : PermalinkData
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* &room_name=Team2
|
* &room_name=Team2
|
||||||
|
|
@ -47,9 +47,9 @@ sealed class PermalinkData {
|
||||||
val token: String,
|
val token: String,
|
||||||
val privateKey: String,
|
val privateKey: String,
|
||||||
val roomType: String?
|
val roomType: String?
|
||||||
) : PermalinkData()
|
) : PermalinkData
|
||||||
|
|
||||||
data class UserLink(val userId: String) : PermalinkData()
|
data class UserLink(val userId: String) : PermalinkData
|
||||||
|
|
||||||
data class FallbackLink(val uri: Uri, val isLegacyGroupLink: Boolean = false) : PermalinkData()
|
data class FallbackLink(val uri: Uri, val isLegacyGroupLink: Boolean = false) : PermalinkData
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.room
|
package io.element.android.libraries.matrix.api.room
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface MatrixRoomMembersState {
|
sealed interface MatrixRoomMembersState {
|
||||||
data object Unknown : MatrixRoomMembersState
|
data object Unknown : MatrixRoomMembersState
|
||||||
data class Pending(val prevRoomMembers: List<RoomMember>? = null) : MatrixRoomMembersState
|
data class Pending(val prevRoomMembers: List<RoomMember>? = null) : MatrixRoomMembersState
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ import kotlin.time.Duration
|
||||||
* Can be retrieved from [RoomListService] methods.
|
* Can be retrieved from [RoomListService] methods.
|
||||||
*/
|
*/
|
||||||
interface RoomList {
|
interface RoomList {
|
||||||
sealed class LoadingState {
|
sealed interface LoadingState {
|
||||||
data object NotLoaded : LoadingState()
|
data object NotLoaded : LoadingState
|
||||||
data class Loaded(val numberOfRooms: Int) : LoadingState()
|
data class Loaded(val numberOfRooms: Int) : LoadingState
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,16 @@ import kotlinx.coroutines.flow.StateFlow
|
||||||
*/
|
*/
|
||||||
interface RoomListService {
|
interface RoomListService {
|
||||||
|
|
||||||
sealed class State {
|
sealed interface State {
|
||||||
data object Idle : State()
|
data object Idle : State
|
||||||
data object Running : State()
|
data object Running : State
|
||||||
data object Error : State()
|
data object Error : State
|
||||||
data object Terminated : State()
|
data object Terminated : State
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class SyncIndicator {
|
sealed interface SyncIndicator {
|
||||||
data object Show : SyncIndicator()
|
data object Show : SyncIndicator
|
||||||
data object Hide : SyncIndicator()
|
data object Hide : SyncIndicator
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.api.tracing
|
package io.element.android.libraries.matrix.api.tracing
|
||||||
|
|
||||||
sealed class WriteToFilesConfiguration {
|
sealed interface WriteToFilesConfiguration {
|
||||||
data object Disabled : WriteToFilesConfiguration()
|
data object Disabled : WriteToFilesConfiguration
|
||||||
data class Enabled(val directory: String, val filenamePrefix: String) : WriteToFilesConfiguration()
|
data class Enabled(val directory: String, val filenamePrefix: String) : WriteToFilesConfiguration
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,10 @@ import android.net.Uri
|
||||||
import androidx.activity.result.PickVisualMediaRequest
|
import androidx.activity.result.PickVisualMediaRequest
|
||||||
import androidx.activity.result.contract.ActivityResultContract
|
import androidx.activity.result.contract.ActivityResultContract
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface PickerType<Input, Output> {
|
sealed interface PickerType<Input, Output> {
|
||||||
fun getContract(): ActivityResultContract<Input, Output>
|
fun getContract(): ActivityResultContract<Input, Output>
|
||||||
fun getDefaultRequest(): Input
|
fun getDefaultRequest(): Input
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@
|
||||||
package io.element.android.libraries.textcomposer.model
|
package io.element.android.libraries.textcomposer.model
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import io.element.android.libraries.matrix.api.core.EventId
|
import io.element.android.libraries.matrix.api.core.EventId
|
||||||
import io.element.android.libraries.matrix.api.core.TransactionId
|
import io.element.android.libraries.matrix.api.core.TransactionId
|
||||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface MessageComposerMode : Parcelable {
|
sealed interface MessageComposerMode : Parcelable {
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data object Normal: MessageComposerMode
|
data object Normal: MessageComposerMode
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
package io.element.android.libraries.textcomposer.model
|
package io.element.android.libraries.textcomposer.model
|
||||||
|
|
||||||
sealed class PressEvent {
|
sealed interface PressEvent {
|
||||||
data object PressStart: PressEvent()
|
data object PressStart: PressEvent
|
||||||
data object Tapped: PressEvent()
|
data object Tapped: PressEvent
|
||||||
data object LongPressEnd: PressEvent()
|
data object LongPressEnd: PressEvent
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
|
|
||||||
package io.element.android.libraries.textcomposer.model
|
package io.element.android.libraries.textcomposer.model
|
||||||
|
|
||||||
sealed class VoiceMessagePlayerEvent {
|
sealed interface VoiceMessagePlayerEvent {
|
||||||
data object Play: VoiceMessagePlayerEvent()
|
data object Play: VoiceMessagePlayerEvent
|
||||||
data object Pause: VoiceMessagePlayerEvent()
|
data object Pause: VoiceMessagePlayerEvent
|
||||||
|
|
||||||
data class Seek(
|
data class Seek(
|
||||||
val position: Float
|
val position: Float
|
||||||
): VoiceMessagePlayerEvent()
|
): VoiceMessagePlayerEvent
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@
|
||||||
|
|
||||||
package io.element.android.libraries.textcomposer.model
|
package io.element.android.libraries.textcomposer.model
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
sealed class VoiceMessageState {
|
@Immutable
|
||||||
data object Idle: VoiceMessageState()
|
sealed interface VoiceMessageState {
|
||||||
|
data object Idle: VoiceMessageState
|
||||||
|
|
||||||
data class Preview(
|
data class Preview(
|
||||||
val isSending: Boolean,
|
val isSending: Boolean,
|
||||||
|
|
@ -29,10 +31,10 @@ sealed class VoiceMessageState {
|
||||||
val playbackProgress: Float,
|
val playbackProgress: Float,
|
||||||
val time: Duration,
|
val time: Duration,
|
||||||
val waveform: ImmutableList<Float>,
|
val waveform: ImmutableList<Float>,
|
||||||
): VoiceMessageState()
|
): VoiceMessageState
|
||||||
|
|
||||||
data class Recording(
|
data class Recording(
|
||||||
val duration: Duration,
|
val duration: Duration,
|
||||||
val levels: ImmutableList<Float>,
|
val levels: ImmutableList<Float>,
|
||||||
): VoiceMessageState()
|
): VoiceMessageState
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ package io.element.android.libraries.textcomposer.utils
|
||||||
/**
|
/**
|
||||||
* State of a press gesture.
|
* State of a press gesture.
|
||||||
*/
|
*/
|
||||||
internal sealed class PressState {
|
internal sealed interface PressState {
|
||||||
data class Idle(
|
data class Idle(
|
||||||
val lastPress: Pressing?
|
val lastPress: Pressing?
|
||||||
) : PressState()
|
) : PressState
|
||||||
|
|
||||||
sealed class Pressing : PressState()
|
sealed interface Pressing : PressState
|
||||||
data object Tapping : Pressing()
|
data object Tapping : Pressing
|
||||||
data object LongPressing : Pressing()
|
data object LongPressing : Pressing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ package io.element.android.libraries.voicerecorder.api
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
sealed class VoiceRecorderState {
|
sealed interface VoiceRecorderState {
|
||||||
/**
|
/**
|
||||||
* The recorder is idle and not recording.
|
* The recorder is idle and not recording.
|
||||||
*/
|
*/
|
||||||
data object Idle : VoiceRecorderState()
|
data object Idle : VoiceRecorderState
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The recorder is currently recording.
|
* The recorder is currently recording.
|
||||||
|
|
@ -31,7 +31,7 @@ sealed class VoiceRecorderState {
|
||||||
* @property elapsedTime The elapsed time since the recording started.
|
* @property elapsedTime The elapsed time since the recording started.
|
||||||
* @property levels The current audio levels of the recording as a fraction of 1.
|
* @property levels The current audio levels of the recording as a fraction of 1.
|
||||||
*/
|
*/
|
||||||
data class Recording(val elapsedTime: Duration, val levels: List<Float>) : VoiceRecorderState()
|
data class Recording(val elapsedTime: Duration, val levels: List<Float>) : VoiceRecorderState
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The recorder has finished recording.
|
* The recorder has finished recording.
|
||||||
|
|
@ -46,5 +46,5 @@ sealed class VoiceRecorderState {
|
||||||
val mimeType: String,
|
val mimeType: String,
|
||||||
val waveform: List<Float>,
|
val waveform: List<Float>,
|
||||||
val duration: Duration,
|
val duration: Duration,
|
||||||
) : VoiceRecorderState()
|
) : VoiceRecorderState
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,31 @@
|
||||||
|
|
||||||
package io.element.android.libraries.voicerecorder.impl.audio
|
package io.element.android.libraries.voicerecorder.impl.audio
|
||||||
|
|
||||||
sealed class Audio {
|
sealed interface Audio {
|
||||||
class Data(
|
data class Data(
|
||||||
val readSize: Int,
|
val readSize: Int,
|
||||||
val buffer: ShortArray,
|
val buffer: ShortArray,
|
||||||
) : Audio()
|
) : Audio {
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
||||||
|
other as Data
|
||||||
|
|
||||||
|
if (readSize != other.readSize) return false
|
||||||
|
if (!buffer.contentEquals(other.buffer)) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = readSize
|
||||||
|
result = 31 * result + buffer.contentHashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class Error(
|
data class Error(
|
||||||
val audioRecordErrorCode: Int
|
val audioRecordErrorCode: Int
|
||||||
) : Audio()
|
) : Audio
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.element.android-library")
|
id("io.element.android-compose-library")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package io.element.android.services.apperror.api
|
package io.element.android.services.apperror.api
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
sealed interface AppErrorState {
|
sealed interface AppErrorState {
|
||||||
data object NoError : AppErrorState
|
data object NoError : AppErrorState
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,19 @@
|
||||||
|
|
||||||
package io.element.android.tests.konsist
|
package io.element.android.tests.konsist
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
import com.lemonappdev.konsist.api.Konsist
|
import com.lemonappdev.konsist.api.Konsist
|
||||||
import com.lemonappdev.konsist.api.ext.list.constructors
|
import com.lemonappdev.konsist.api.ext.list.constructors
|
||||||
import com.lemonappdev.konsist.api.ext.list.modifierprovider.withSealedModifier
|
import com.lemonappdev.konsist.api.ext.list.modifierprovider.withSealedModifier
|
||||||
import com.lemonappdev.konsist.api.ext.list.parameters
|
import com.lemonappdev.konsist.api.ext.list.parameters
|
||||||
|
import com.lemonappdev.konsist.api.ext.list.withAnnotationOf
|
||||||
import com.lemonappdev.konsist.api.ext.list.withNameEndingWith
|
import com.lemonappdev.konsist.api.ext.list.withNameEndingWith
|
||||||
|
import com.lemonappdev.konsist.api.ext.list.withoutAnnotationOf
|
||||||
|
import com.lemonappdev.konsist.api.ext.list.withoutConstructors
|
||||||
import com.lemonappdev.konsist.api.ext.list.withoutName
|
import com.lemonappdev.konsist.api.ext.list.withoutName
|
||||||
|
import com.lemonappdev.konsist.api.ext.list.withoutParents
|
||||||
import com.lemonappdev.konsist.api.verify.assertEmpty
|
import com.lemonappdev.konsist.api.verify.assertEmpty
|
||||||
import com.lemonappdev.konsist.api.verify.assertTrue
|
import com.lemonappdev.konsist.api.verify.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -55,4 +62,33 @@ class KonsistArchitectureTest {
|
||||||
.withNameEndingWith("Events")
|
.withNameEndingWith("Events")
|
||||||
.assertEmpty(additionalMessage = "Events class MUST be sealed interface")
|
.assertEmpty(additionalMessage = "Events class MUST be sealed interface")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Sealed class without constructor and without parent MUST be sealed interface`() {
|
||||||
|
Konsist.scopeFromProject()
|
||||||
|
.classes()
|
||||||
|
.withSealedModifier()
|
||||||
|
.withoutConstructors()
|
||||||
|
.withoutParents()
|
||||||
|
.assertEmpty(additionalMessage = "Sealed class without constructor MUST be sealed interface")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Sealed interface used in Composable MUST be Immutable or Stable`() {
|
||||||
|
// List all sealed interface without Immutable nor Stable annotation in the project
|
||||||
|
val forbiddenInterfacesForComposableParameter = Konsist.scopeFromProject()
|
||||||
|
.interfaces()
|
||||||
|
.withSealedModifier()
|
||||||
|
.withoutAnnotationOf(Immutable::class, Stable::class)
|
||||||
|
.map { it.fullyQualifiedName }
|
||||||
|
|
||||||
|
Konsist.scopeFromProject()
|
||||||
|
.functions()
|
||||||
|
.withAnnotationOf(Composable::class)
|
||||||
|
.assertTrue(additionalMessage = "Consider adding the @Immutable or @Stable annotation to the sealed interface") {
|
||||||
|
it.parameters.all { param ->
|
||||||
|
param.type.fullyQualifiedName !in forbiddenInterfacesForComposableParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue