Browse Source

Merge pull request #1731 from vector-im/feature/bma/variousCleanup

Konsist: check if sealed class could be sealed interface
pull/1742/head
Benoit Marty 11 months ago committed by GitHub
parent
commit
fe69db397f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/model/PinDigit.kt
  2. 9
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt
  3. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt
  4. 10
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt
  5. 3
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStateContent.kt
  6. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt
  7. 6
      libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/throttler/FirstThrottler.kt
  8. 4
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/ButtonVisuals.kt
  9. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/ListItemContent.kt
  10. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt
  11. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListItem.kt
  12. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListSupportingText.kt
  13. 2
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt
  14. 2
      libraries/matrix/api/build.gradle.kts
  15. 10
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkData.kt
  16. 3
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomMembersState.kt
  17. 6
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomList.kt
  18. 16
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt
  19. 6
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/WriteToFilesConfiguration.kt
  20. 2
      libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerType.kt
  21. 2
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/MessageComposerMode.kt
  22. 8
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/PressEvent.kt
  23. 8
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/VoiceMessagePlayerEvent.kt
  24. 10
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/VoiceMessageState.kt
  25. 10
      libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/utils/PressState.kt
  26. 8
      libraries/voicerecorder/api/src/main/kotlin/io/element/android/libraries/voicerecorder/api/VoiceRecorderState.kt
  27. 26
      libraries/voicerecorder/impl/src/main/kotlin/io/element/android/libraries/voicerecorder/impl/audio/Audio.kt
  28. 2
      services/apperror/api/build.gradle.kts
  29. 3
      services/apperror/api/src/main/kotlin/io/element/android/services/apperror/api/AppErrorState.kt
  30. 36
      tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistArchitectureTest.kt

3
features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/pin/model/PinDigit.kt

@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
package io.element.android.features.lockscreen.impl.pin.model
import androidx.compose.runtime.Immutable
@Immutable
sealed interface PinDigit {
data object Empty : PinDigit
data class Filled(val value: Char) : PinDigit

9
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt

@ -170,9 +170,8 @@ private fun CustomSheetState.getIntOffset(): Int? = try { @@ -170,9 +170,8 @@ private fun CustomSheetState.getIntOffset(): Int? = try {
null
}
private sealed class Slot {
data class SheetContent(val key: Int?) : Slot()
data object DragHandle : Slot()
data object Scaffold : Slot()
private sealed interface Slot {
data class SheetContent(val key: Int?) : Slot
data object DragHandle : Slot
data object Scaffold : Slot
}

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt

@ -20,6 +20,7 @@ import android.Manifest @@ -20,6 +20,7 @@ import android.Manifest
import android.annotation.SuppressLint
import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
@ -409,6 +410,7 @@ class MessageComposerPresenter @Inject constructor( @@ -409,6 +410,7 @@ class MessageComposerPresenter @Inject constructor(
}
}
@Immutable
sealed interface RoomMemberSuggestion {
data object Room : RoomMemberSuggestion
data class Member(val roomMember: RoomMember) : RoomMemberSuggestion

10
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt

@ -32,6 +32,7 @@ import androidx.compose.foundation.shape.CornerSize @@ -32,6 +32,7 @@ import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -103,11 +104,12 @@ fun MessagesReactionButton( @@ -103,11 +104,12 @@ fun MessagesReactionButton(
}
}
sealed class MessagesReactionsButtonContent {
data class Text(val text: String) : MessagesReactionsButtonContent()
data class Icon(@DrawableRes val resourceId: Int) : MessagesReactionsButtonContent()
@Immutable
sealed interface 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
}

3
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStateContent.kt

@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
package io.element.android.features.messages.impl.timeline.model.event
import androidx.compose.runtime.Immutable
@Immutable
sealed interface TimelineItemStateContent : TimelineItemEventContent {
val body: String
}

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt

@ -16,8 +16,10 @@ @@ -16,8 +16,10 @@
package io.element.android.features.messages.impl.timeline.model.event
import androidx.compose.runtime.Immutable
import org.jsoup.nodes.Document
@Immutable
sealed interface TimelineItemTextBasedContent : TimelineItemEventContent {
val body: String
val htmlDocument: Document?

6
libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/throttler/FirstThrottler.kt

@ -24,9 +24,9 @@ import android.os.SystemClock @@ -24,9 +24,9 @@ import android.os.SystemClock
class FirstThrottler(private val minimumInterval: Long = 800) {
private var lastDate = 0L
sealed class CanHandleResult {
data object Yes : CanHandleResult()
data class No(val shouldWaitMillis: Long) : CanHandleResult()
sealed interface CanHandleResult {
data object Yes : CanHandleResult
data class No(val shouldWaitMillis: Long) : CanHandleResult
fun waitMillis(): Long {
return when (this) {

4
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/button/ButtonVisuals.kt

@ -18,14 +18,16 @@ package io.element.android.libraries.designsystem.components.button @@ -18,14 +18,16 @@ package io.element.android.libraries.designsystem.components.button
import androidx.compose.material3.Icon
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.IconButton
import io.element.android.libraries.designsystem.theme.components.IconSource
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 {
val action: () -> Unit

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/list/ListItemContent.kt

@ -19,6 +19,7 @@ package io.element.android.libraries.designsystem.components.list @@ -19,6 +19,7 @@ package io.element.android.libraries.designsystem.components.list
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.DpSize
@ -34,6 +35,7 @@ import io.element.android.libraries.designsystem.theme.components.Text as TextCo @@ -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.
*/
@Immutable
sealed interface ListItemContent {
/**
* Default Switch content for [ListItem].

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt

@ -37,6 +37,7 @@ import androidx.compose.material3.ButtonDefaults @@ -37,6 +37,7 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -238,6 +239,7 @@ private fun ButtonInternal( @@ -238,6 +239,7 @@ private fun ButtonInternal(
}
}
@Immutable
sealed interface IconSource {
val contentDescription: String?

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListItem.kt

@ -23,6 +23,7 @@ import androidx.compose.material3.LocalContentColor @@ -23,6 +23,7 @@ import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -134,6 +135,7 @@ fun ListItem( @@ -134,6 +135,7 @@ fun ListItem(
/**
* The style to use for a [ListItem].
*/
@Immutable
sealed interface ListItemStyle {
data object Default : ListItemStyle
data object Primary : ListItemStyle

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ListSupportingText.kt

@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.Column @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ExperimentalTextApi
@ -82,6 +83,7 @@ fun ListSupportingText( @@ -82,6 +83,7 @@ fun ListSupportingText(
object ListSupportingTextDefaults {
/** Specifies the padding to use for the supporting text. */
@Immutable
sealed interface Padding {
/** No padding. */
data object None : Padding

2
libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt

@ -30,6 +30,7 @@ import androidx.compose.material3.SearchBarColors @@ -30,6 +30,7 @@ import androidx.compose.material3.SearchBarColors
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -180,6 +181,7 @@ object ElementSearchBarDefaults { @@ -180,6 +181,7 @@ object ElementSearchBarDefaults {
)
}
@Immutable
sealed interface SearchBarResultState<in T> {
/** No search results are available yet (e.g. because the user hasn't entered a search term). */
class NotSearching<T> : SearchBarResultState<T>

2
libraries/matrix/api/build.gradle.kts

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
*/
plugins {
id("io.element.android-library")
id("io.element.android-compose-library")
id("kotlin-parcelize")
alias(libs.plugins.anvil)
kotlin("plugin.serialization") version "1.9.10"

10
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkData.kt

@ -22,14 +22,14 @@ import android.net.Uri @@ -22,14 +22,14 @@ import android.net.Uri
* This sealed class represents all the permalink cases.
* You don't have to instantiate yourself but should use [PermalinkParser] instead.
*/
sealed class PermalinkData {
sealed interface PermalinkData {
data class RoomLink(
val roomIdOrAlias: String,
val isRoomAlias: Boolean,
val eventId: String?,
val viaParameters: List<String>
) : PermalinkData()
) : PermalinkData
/*
* &room_name=Team2
@ -47,9 +47,9 @@ sealed class PermalinkData { @@ -47,9 +47,9 @@ sealed class PermalinkData {
val token: String,
val privateKey: 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
}

3
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomMembersState.kt

@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
package io.element.android.libraries.matrix.api.room
import androidx.compose.runtime.Immutable
@Immutable
sealed interface MatrixRoomMembersState {
data object Unknown : MatrixRoomMembersState
data class Pending(val prevRoomMembers: List<RoomMember>? = null) : MatrixRoomMembersState

6
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomList.kt

@ -28,9 +28,9 @@ import kotlin.time.Duration @@ -28,9 +28,9 @@ import kotlin.time.Duration
* Can be retrieved from [RoomListService] methods.
*/
interface RoomList {
sealed class LoadingState {
data object NotLoaded : LoadingState()
data class Loaded(val numberOfRooms: Int) : LoadingState()
sealed interface LoadingState {
data object NotLoaded : LoadingState
data class Loaded(val numberOfRooms: Int) : LoadingState
}
/**

16
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomListService.kt

@ -25,16 +25,16 @@ import kotlinx.coroutines.flow.StateFlow @@ -25,16 +25,16 @@ import kotlinx.coroutines.flow.StateFlow
*/
interface RoomListService {
sealed class State {
data object Idle : State()
data object Running : State()
data object Error : State()
data object Terminated : State()
sealed interface State {
data object Idle : State
data object Running : State
data object Error : State
data object Terminated : State
}
sealed class SyncIndicator {
data object Show : SyncIndicator()
data object Hide : SyncIndicator()
sealed interface SyncIndicator {
data object Show : SyncIndicator
data object Hide : SyncIndicator
}
/**

6
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/WriteToFilesConfiguration.kt

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
package io.element.android.libraries.matrix.api.tracing
sealed class WriteToFilesConfiguration {
data object Disabled : WriteToFilesConfiguration()
data class Enabled(val directory: String, val filenamePrefix: String) : WriteToFilesConfiguration()
sealed interface WriteToFilesConfiguration {
data object Disabled : WriteToFilesConfiguration
data class Enabled(val directory: String, val filenamePrefix: String) : WriteToFilesConfiguration
}

2
libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerType.kt

@ -20,8 +20,10 @@ import android.net.Uri @@ -20,8 +20,10 @@ import android.net.Uri
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.Immutable
import io.element.android.libraries.core.mimetype.MimeTypes
@Immutable
sealed interface PickerType<Input, Output> {
fun getContract(): ActivityResultContract<Input, Output>
fun getDefaultRequest(): Input

2
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/MessageComposerMode.kt

@ -17,11 +17,13 @@ @@ -17,11 +17,13 @@
package io.element.android.libraries.textcomposer.model
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.TransactionId
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
import kotlinx.parcelize.Parcelize
@Immutable
sealed interface MessageComposerMode : Parcelable {
@Parcelize
data object Normal: MessageComposerMode

8
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/PressEvent.kt

@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
package io.element.android.libraries.textcomposer.model
sealed class PressEvent {
data object PressStart: PressEvent()
data object Tapped: PressEvent()
data object LongPressEnd: PressEvent()
sealed interface PressEvent {
data object PressStart: PressEvent
data object Tapped: PressEvent
data object LongPressEnd: PressEvent
}

8
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/VoiceMessagePlayerEvent.kt

@ -16,11 +16,11 @@ @@ -16,11 +16,11 @@
package io.element.android.libraries.textcomposer.model
sealed class VoiceMessagePlayerEvent {
data object Play: VoiceMessagePlayerEvent()
data object Pause: VoiceMessagePlayerEvent()
sealed interface VoiceMessagePlayerEvent {
data object Play: VoiceMessagePlayerEvent
data object Pause: VoiceMessagePlayerEvent
data class Seek(
val position: Float
): VoiceMessagePlayerEvent()
): VoiceMessagePlayerEvent
}

10
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/VoiceMessageState.kt

@ -16,11 +16,13 @@ @@ -16,11 +16,13 @@
package io.element.android.libraries.textcomposer.model
import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.ImmutableList
import kotlin.time.Duration
sealed class VoiceMessageState {
data object Idle: VoiceMessageState()
@Immutable
sealed interface VoiceMessageState {
data object Idle: VoiceMessageState
data class Preview(
val isSending: Boolean,
@ -29,10 +31,10 @@ sealed class VoiceMessageState { @@ -29,10 +31,10 @@ sealed class VoiceMessageState {
val playbackProgress: Float,
val time: Duration,
val waveform: ImmutableList<Float>,
): VoiceMessageState()
): VoiceMessageState
data class Recording(
val duration: Duration,
val levels: ImmutableList<Float>,
): VoiceMessageState()
): VoiceMessageState
}

10
libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/utils/PressState.kt

@ -19,13 +19,13 @@ package io.element.android.libraries.textcomposer.utils @@ -19,13 +19,13 @@ package io.element.android.libraries.textcomposer.utils
/**
* State of a press gesture.
*/
internal sealed class PressState {
internal sealed interface PressState {
data class Idle(
val lastPress: Pressing?
) : PressState()
) : PressState
sealed class Pressing : PressState()
data object Tapping : Pressing()
data object LongPressing : Pressing()
sealed interface Pressing : PressState
data object Tapping : Pressing
data object LongPressing : Pressing
}

8
libraries/voicerecorder/api/src/main/kotlin/io/element/android/libraries/voicerecorder/api/VoiceRecorderState.kt

@ -19,11 +19,11 @@ package io.element.android.libraries.voicerecorder.api @@ -19,11 +19,11 @@ package io.element.android.libraries.voicerecorder.api
import java.io.File
import kotlin.time.Duration
sealed class VoiceRecorderState {
sealed interface VoiceRecorderState {
/**
* The recorder is idle and not recording.
*/
data object Idle : VoiceRecorderState()
data object Idle : VoiceRecorderState
/**
* The recorder is currently recording.
@ -31,7 +31,7 @@ sealed class VoiceRecorderState { @@ -31,7 +31,7 @@ sealed class VoiceRecorderState {
* @property elapsedTime The elapsed time since the recording started.
* @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.
@ -46,5 +46,5 @@ sealed class VoiceRecorderState { @@ -46,5 +46,5 @@ sealed class VoiceRecorderState {
val mimeType: String,
val waveform: List<Float>,
val duration: Duration,
) : VoiceRecorderState()
) : VoiceRecorderState
}

26
libraries/voicerecorder/impl/src/main/kotlin/io/element/android/libraries/voicerecorder/impl/audio/Audio.kt

@ -16,13 +16,31 @@ @@ -16,13 +16,31 @@
package io.element.android.libraries.voicerecorder.impl.audio
sealed class Audio {
class Data(
sealed interface Audio {
data class Data(
val readSize: Int,
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(
val audioRecordErrorCode: Int
) : Audio()
) : Audio
}

2
services/apperror/api/build.gradle.kts

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
*/
plugins {
id("io.element.android-library")
id("io.element.android-compose-library")
}
android {

3
services/apperror/api/src/main/kotlin/io/element/android/services/apperror/api/AppErrorState.kt

@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
package io.element.android.services.apperror.api
import androidx.compose.runtime.Immutable
@Immutable
sealed interface AppErrorState {
data object NoError : AppErrorState

36
tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistArchitectureTest.kt

@ -16,12 +16,19 @@ @@ -16,12 +16,19 @@
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.ext.list.constructors
import com.lemonappdev.konsist.api.ext.list.modifierprovider.withSealedModifier
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.withoutAnnotationOf
import com.lemonappdev.konsist.api.ext.list.withoutConstructors
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.assertTrue
import org.junit.Test
@ -55,4 +62,33 @@ class KonsistArchitectureTest { @@ -55,4 +62,33 @@ class KonsistArchitectureTest {
.withNameEndingWith("Events")
.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…
Cancel
Save