From 6e8d0ded36f4223f3dc2fc4ee830ba59493f19c5 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 20 Mar 2024 12:59:02 +0100 Subject: [PATCH] Room Directory Search : setup the feature --- features/roomdirectory/api/build.gradle.kts | 28 ++++++++ .../api/RoomDirectoryEntryPoint.kt | 38 +++++++++++ features/roomdirectory/impl/build.gradle.kts | 52 +++++++++++++++ .../impl/DefaultRoomDirectoryEntryPoint.kt | 46 +++++++++++++ .../impl/RoomDirectoryFlowNode.kt | 66 +++++++++++++++++++ .../impl/search/RoomDirectorySearchEvents.kt | 25 +++++++ .../impl/search/RoomDirectorySearchNode.kt | 44 +++++++++++++ .../search/RoomDirectorySearchPresenter.kt | 40 +++++++++++ .../impl/search/RoomDirectorySearchState.kt | 21 ++++++ .../RoomDirectorySearchStateProvider.kt | 31 +++++++++ .../impl/search/RoomDirectorySearchView.kt | 48 ++++++++++++++ .../libraries/featureflag/api/FeatureFlags.kt | 7 ++ .../impl/StaticFeatureFlagProvider.kt | 1 + 13 files changed, 447 insertions(+) create mode 100644 features/roomdirectory/api/build.gradle.kts create mode 100644 features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDirectoryEntryPoint.kt create mode 100644 features/roomdirectory/impl/build.gradle.kts create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/DefaultRoomDirectoryEntryPoint.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/RoomDirectoryFlowNode.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchEvents.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchNode.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchPresenter.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchState.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchStateProvider.kt create mode 100644 features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchView.kt diff --git a/features/roomdirectory/api/build.gradle.kts b/features/roomdirectory/api/build.gradle.kts new file mode 100644 index 0000000000..c55c647e24 --- /dev/null +++ b/features/roomdirectory/api/build.gradle.kts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 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. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.features.roomdirectory.api" +} + +dependencies { + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) +} diff --git a/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDirectoryEntryPoint.kt b/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDirectoryEntryPoint.kt new file mode 100644 index 0000000000..033ec67b33 --- /dev/null +++ b/features/roomdirectory/api/src/main/kotlin/io/element/android/features/roomdirectory/api/RoomDirectoryEntryPoint.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 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.roomdirectory.api + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import io.element.android.libraries.architecture.FeatureEntryPoint +import io.element.android.libraries.matrix.api.core.RoomId + +interface RoomDirectoryEntryPoint : FeatureEntryPoint { + + fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder + + interface NodeBuilder { + fun callback(callback: Callback): NodeBuilder + fun build(): Node + } + + interface Callback : Plugin { + fun onRoomJoined(roomId: RoomId) + } +} + diff --git a/features/roomdirectory/impl/build.gradle.kts b/features/roomdirectory/impl/build.gradle.kts new file mode 100644 index 0000000000..0e35623401 --- /dev/null +++ b/features/roomdirectory/impl/build.gradle.kts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024 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.anvil) + alias(libs.plugins.ksp) + id("kotlin-parcelize") +} + +android { + namespace = "io.element.android.features.roomdirectory.impl" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + implementation(projects.anvilannotations) + anvil(projects.anvilcodegen) + api(projects.features.roomdirectory.api) + implementation(projects.libraries.core) + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.matrixui) + implementation(projects.libraries.designsystem) + + testImplementation(libs.test.junit) + testImplementation(libs.coroutines.test) + testImplementation(libs.molecule.runtime) + testImplementation(libs.test.truth) + testImplementation(libs.test.turbine) + testImplementation(projects.libraries.matrix.test) + + ksp(libs.showkase.processor) +} diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/DefaultRoomDirectoryEntryPoint.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/DefaultRoomDirectoryEntryPoint.kt new file mode 100644 index 0000000000..ac085b4d03 --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/DefaultRoomDirectoryEntryPoint.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.AppScope +import javax.inject.Inject + +@ContributesBinding(AppScope::class) +class DefaultRoomDirectoryEntryPoint @Inject constructor() : RoomDirectoryEntryPoint { + + override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomDirectoryEntryPoint.NodeBuilder { + val plugins = ArrayList() + + return object : RoomDirectoryEntryPoint.NodeBuilder { + + override fun callback(callback: RoomDirectoryEntryPoint.Callback): RoomDirectoryEntryPoint.NodeBuilder { + plugins += callback + return this + } + + override fun build(): Node { + return parentNode.createNode(buildContext, plugins) + } + } + } +} diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/RoomDirectoryFlowNode.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/RoomDirectoryFlowNode.kt new file mode 100644 index 0000000000..e053fa6c58 --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/RoomDirectoryFlowNode.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl + +import android.os.Parcelable +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 com.bumble.appyx.navmodel.backstack.BackStack +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.features.roomdirectory.impl.search.RoomDirectorySearchNode +import io.element.android.libraries.architecture.BackstackView +import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.SessionScope +import kotlinx.parcelize.Parcelize + +@ContributesNode(SessionScope::class) +class RoomDirectoryFlowNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, +) : BaseFlowNode( + backstack = BackStack( + initialElement = NavTarget.Root, + savedStateMap = buildContext.savedStateMap, + ), + buildContext = buildContext, + plugins = plugins, +) { + + sealed interface NavTarget : Parcelable { + @Parcelize + data object Root : NavTarget + } + + override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { + return when (navTarget) { + NavTarget.Root -> { + createNode(buildContext) + } + } + } + + @Composable + override fun View(modifier: Modifier) { + BackstackView() + } +} diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchEvents.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchEvents.kt new file mode 100644 index 0000000000..f7212529b2 --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchEvents.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl.search + +import io.element.android.libraries.matrix.api.core.RoomId + +sealed interface RoomDirectorySearchEvents { + data class Search(val query: String) : RoomDirectorySearchEvents + data object LoadMore : RoomDirectorySearchEvents + data class JoinRoom(val roomId: RoomId) : RoomDirectorySearchEvents +} diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchNode.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchNode.kt new file mode 100644 index 0000000000..1f459f404c --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchNode.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl.search + +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 RoomDirectorySearchNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: RoomDirectorySearchPresenter, +) : Node(buildContext, plugins = plugins) { + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + RoomDirectorySearchView( + state = state, + modifier = modifier + ) + } +} diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchPresenter.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchPresenter.kt new file mode 100644 index 0000000000..d0cc6d47c4 --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchPresenter.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl.search + +import androidx.compose.runtime.Composable +import io.element.android.libraries.architecture.Presenter +import javax.inject.Inject + +class RoomDirectorySearchPresenter @Inject constructor() : Presenter { + + @Composable + override fun present(): RoomDirectorySearchState { + + fun handleEvents(event: RoomDirectorySearchEvents) { + when (event) { + is RoomDirectorySearchEvents.JoinRoom -> TODO() + RoomDirectorySearchEvents.LoadMore -> TODO() + is RoomDirectorySearchEvents.Search -> TODO() + } + } + + return RoomDirectorySearchState( + eventSink = ::handleEvents + ) + } +} diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchState.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchState.kt new file mode 100644 index 0000000000..0e77801e12 --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchState.kt @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl.search + +data class RoomDirectorySearchState( + val eventSink: (RoomDirectorySearchEvents) -> Unit +) diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchStateProvider.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchStateProvider.kt new file mode 100644 index 0000000000..31464fd17c --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchStateProvider.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl.search + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +open class RoomDirectorySearchStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aRoomDirectorySearchState(), + // Add other states here + ) +} + +fun aRoomDirectorySearchState() = RoomDirectorySearchState( + eventSink = {} +) diff --git a/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchView.kt b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchView.kt new file mode 100644 index 0000000000..d2e3ad1ec9 --- /dev/null +++ b/features/roomdirectory/impl/src/main/kotlin/io/element/android/features/roomdirectory/impl/search/RoomDirectorySearchView.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 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.roomdirectory.impl.search + +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.PreviewParameter +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Text + +@Composable +fun RoomDirectorySearchView( + state: RoomDirectorySearchState, + modifier: Modifier = Modifier, +) { + Box(modifier, contentAlignment = Alignment.Center) { + Text( + "RoomDirectorySearch feature view", + color = MaterialTheme.colorScheme.primary, + ) + } +} + +@PreviewsDayNight +@Composable +fun RoomDirectorySearchViewLightPreview(@PreviewParameter(RoomDirectorySearchStateProvider::class) state: RoomDirectorySearchState) = ElementPreview { + RoomDirectorySearchView( + state = state, + ) +} diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index a242d014d1..7140a89064 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -89,4 +89,11 @@ enum class FeatureFlags( defaultValue = true, isFinished = false, ), + RoomDirectorySearch( + key = "feature.roomdirectorysearch", + title = "Room directory search", + description = "Allow user to search for public rooms in his homeserver", + defaultValue = true, + isFinished = false, + ) } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt index 13cc7da462..5b6ee3bc03 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt @@ -42,6 +42,7 @@ class StaticFeatureFlagProvider @Inject constructor() : FeatureFlags.MarkAsUnread -> true FeatureFlags.RoomListFilters -> false FeatureFlags.RoomModeration -> false + FeatureFlags.RoomDirectorySearch -> false } } else { false