From a0a0fae6ed1d23f2cbf35a899b0d88a83879af88 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 28 Feb 2023 16:18:44 +0100 Subject: [PATCH] Init create room module --- features/createroom/.gitignore | 1 + features/createroom/build.gradle.kts | 55 ++++++++++++++++++ features/createroom/consumer-rules.pro | 0 features/createroom/proguard-rules.pro | 21 +++++++ .../createroom/src/main/AndroidManifest.xml | 20 +++++++ .../features/createroom/CreateRoomEvents.kt | 22 +++++++ .../features/createroom/CreateRoomNode.kt | 44 ++++++++++++++ .../createroom/CreateRoomPresenter.kt | 38 ++++++++++++ .../features/createroom/CreateRoomState.kt | 23 ++++++++ .../createroom/CreateRoomStateProvider.kt | 31 ++++++++++ .../features/createroom/CreateRoomView.kt | 58 +++++++++++++++++++ .../createroom/CreateRoomPresenterTests.kt | 52 +++++++++++++++++ .../kotlin/extension/DependencyHandleScope.kt | 1 + settings.gradle.kts | 1 + 14 files changed, 367 insertions(+) create mode 100644 features/createroom/.gitignore create mode 100644 features/createroom/build.gradle.kts create mode 100644 features/createroom/consumer-rules.pro create mode 100644 features/createroom/proguard-rules.pro create mode 100644 features/createroom/src/main/AndroidManifest.xml create mode 100644 features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomEvents.kt create mode 100644 features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomNode.kt create mode 100644 features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomPresenter.kt create mode 100644 features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomState.kt create mode 100644 features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomStateProvider.kt create mode 100644 features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomView.kt create mode 100644 features/createroom/src/test/kotlin/io/element/android/features/createroom/CreateRoomPresenterTests.kt diff --git a/features/createroom/.gitignore b/features/createroom/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/features/createroom/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/features/createroom/build.gradle.kts b/features/createroom/build.gradle.kts new file mode 100644 index 0000000000..853783fa97 --- /dev/null +++ b/features/createroom/build.gradle.kts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed +@Suppress("DSL_SCOPE_VIOLATION") +plugins { + id("io.element.android-compose-library") + alias(libs.plugins.ksp) + alias(libs.plugins.anvil) +} + +android { + namespace = "io.element.android.features.createroom" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + anvil(projects.anvilcodegen) + implementation(projects.anvilannotations) + + implementation(projects.libraries.core) + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix) + implementation(projects.libraries.matrixui) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.elementresources) + implementation(projects.libraries.uiStrings) + + testImplementation(libs.test.junit) + testImplementation(libs.coroutines.test) + testImplementation(libs.molecule.runtime) + testImplementation(libs.test.truth) + testImplementation(libs.test.turbine) + testImplementation(projects.libraries.matrixtest) + + androidTestImplementation(libs.test.junitext) + + ksp(libs.showkase.processor) +} diff --git a/features/createroom/consumer-rules.pro b/features/createroom/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/features/createroom/proguard-rules.pro b/features/createroom/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/features/createroom/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/features/createroom/src/main/AndroidManifest.xml b/features/createroom/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..86d497f107 --- /dev/null +++ b/features/createroom/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomEvents.kt b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomEvents.kt new file mode 100644 index 0000000000..616d6d9881 --- /dev/null +++ b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomEvents.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom + +// TODO Add your events or remove the file completely if no events +sealed interface CreateRoomEvents { + object MyEvent : CreateRoomEvents +} diff --git a/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomNode.kt b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomNode.kt new file mode 100644 index 0000000000..584e4ddf1d --- /dev/null +++ b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomNode.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +class CreateRoomNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: CreateRoomPresenter, +) : Node(buildContext, plugins = plugins) { + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + CreateRoomView( + state = state, + modifier = modifier + ) + } +} diff --git a/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomPresenter.kt b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomPresenter.kt new file mode 100644 index 0000000000..bebff13d1f --- /dev/null +++ b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomPresenter.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom + +import androidx.compose.runtime.Composable +import io.element.android.libraries.architecture.Presenter +import javax.inject.Inject + +class CreateRoomPresenter @Inject constructor() : Presenter { + + @Composable + override fun present(): CreateRoomState { + + fun handleEvents(event: CreateRoomEvents) { + when (event) { + CreateRoomEvents.MyEvent -> Unit + } + } + + return CreateRoomState( + eventSink = ::handleEvents + ) + } +} diff --git a/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomState.kt b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomState.kt new file mode 100644 index 0000000000..57cdbdb394 --- /dev/null +++ b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomState.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom + +// TODO add your ui models. Remove the eventSink if you don't have events. +// Do not use default value, so no member get forgotten in the presenters. +data class CreateRoomState( + val eventSink: (CreateRoomEvents) -> Unit +) diff --git a/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomStateProvider.kt b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomStateProvider.kt new file mode 100644 index 0000000000..86118f2800 --- /dev/null +++ b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomStateProvider.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +open class CreateRoomStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aCreateRoomState(), + // Add other state here + ) +} + +fun aCreateRoomState() = CreateRoomState( + eventSink = {} +) diff --git a/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomView.kt b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomView.kt new file mode 100644 index 0000000000..3b5ea6c20c --- /dev/null +++ b/features/createroom/src/main/kotlin/io/element/android/features/createroom/CreateRoomView.kt @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom + +import androidx.compose.foundation.layout.Box +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.Text + +@Composable +fun CreateRoomView( + state: CreateRoomState, + modifier: Modifier = Modifier, +) { + Box(modifier, contentAlignment = Alignment.Center) { + Text( + "CreateRoom feature view", + color = MaterialTheme.colorScheme.primary, + ) + } +} + +@Preview +@Composable +fun CreateRoomViewLightPreview(@PreviewParameter(CreateRoomStateProvider::class) state: CreateRoomState) = + ElementPreviewLight { ContentToPreview(state) } + +@Preview +@Composable +fun CreateRoomViewDarkPreview(@PreviewParameter(CreateRoomStateProvider::class) state: CreateRoomState) = + ElementPreviewDark { ContentToPreview(state) } + +@Composable +private fun ContentToPreview(state: CreateRoomState) { + CreateRoomView( + state = state, + ) +} diff --git a/features/createroom/src/test/kotlin/io/element/android/features/createroom/CreateRoomPresenterTests.kt b/features/createroom/src/test/kotlin/io/element/android/features/createroom/CreateRoomPresenterTests.kt new file mode 100644 index 0000000000..bd19a67ab0 --- /dev/null +++ b/features/createroom/src/test/kotlin/io/element/android/features/createroom/CreateRoomPresenterTests.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.features.createroom + +import app.cash.molecule.RecompositionClock +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class CreateRoomPresenterTests { + + @Test + fun `present - initial state`() = runTest { + val presenter = CreateRoomPresenter() + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState) + } + } + + @Test + fun `present - send event`() = runTest { + val presenter = CreateRoomPresenter() + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + initialState.eventSink.invoke(CreateRoomEvents.MyEvent) + } + } +} diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 87e6b41094..4e58d0bf0d 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -67,4 +67,5 @@ fun DependencyHandlerScope.allFeatures() { implementation(project(":features:messages")) implementation(project(":features:rageshake")) implementation(project(":features:preferences")) + implementation(project(":features:createroom")) } diff --git a/settings.gradle.kts b/settings.gradle.kts index 77751aeda1..de1417131e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -57,6 +57,7 @@ include(":features:roomlist") include(":features:messages") include(":features:rageshake") include(":features:preferences") +include(":features:createroom") include(":libraries:designsystem") include(":libraries:di") include(":tests:uitests")