Browse Source

Merge remote-tracking branch 'origin/develop' into develop

feature/bma/flipper
Benoit Marty 2 years ago
parent
commit
3ceae18521
  1. 29
      .idea/inspectionProfiles/Project_Default.xml
  2. 25
      .idea/jarRepositories.xml
  3. 3
      .idea/misc.xml
  4. 42
      app/build.gradle
  5. 2
      app/src/main/java/io/element/android/x/ElementXApplication.kt
  6. 46
      app/src/main/java/io/element/android/x/MainActivity.kt
  7. 2
      app/src/main/java/io/element/android/x/MainViewModel.kt
  8. 28
      app/src/main/java/io/element/android/x/Navigation.kt
  9. 0
      app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  10. 0
      app/src/main/res/drawable/ic_launcher_background.xml
  11. 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  12. 0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  13. 0
      app/src/main/res/mipmap-hdpi/ic_launcher.webp
  14. 0
      app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
  15. 0
      app/src/main/res/mipmap-mdpi/ic_launcher.webp
  16. 0
      app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
  17. 0
      app/src/main/res/mipmap-xhdpi/ic_launcher.webp
  18. 0
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
  19. 0
      app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
  20. 0
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
  21. 0
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
  22. 0
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
  23. 0
      app/src/main/res/values/colors.xml
  24. 0
      app/src/main/res/values/strings.xml
  25. 0
      app/src/main/res/values/themes.xml
  26. 0
      app/src/main/res/xml/backup_rules.xml
  27. 0
      app/src/main/res/xml/data_extraction_rules.xml
  28. 8
      build.gradle
  29. 1
      features/login/.gitignore
  30. 18
      features/login/build.gradle.kts
  31. 0
      features/login/consumer-rules.pro
  32. 21
      features/login/proguard-rules.pro
  33. 24
      features/login/src/androidTest/java/io/element/android/x/features/login/ExampleInstrumentedTest.kt
  34. 0
      features/login/src/main/AndroidManifest.xml
  35. 2
      features/login/src/main/java/io/element/android/x/features/login/LoginActions.kt
  36. 133
      features/login/src/main/java/io/element/android/x/features/login/LoginScreen.kt
  37. 51
      features/login/src/main/java/io/element/android/x/features/login/LoginViewModel.kt
  38. 10
      features/login/src/main/java/io/element/android/x/features/login/LoginViewState.kt
  39. 22
      features/login/src/main/res/drawable/element_logo_green.xml
  40. 17
      features/login/src/test/java/io/element/android/x/features/login/ExampleUnitTest.kt
  41. 1
      features/messages/.gitignore
  42. 41
      features/messages/build.gradle
  43. 0
      features/messages/consumer-rules.pro
  44. 21
      features/messages/proguard-rules.pro
  45. 24
      features/messages/src/androidTest/java/io/element/android/x/features/messages/ExampleInstrumentedTest.kt
  46. 4
      features/messages/src/main/AndroidManifest.xml
  47. 17
      features/messages/src/test/java/io/element/android/x/features/messages/ExampleUnitTest.kt
  48. 1
      features/roomlist/.gitignore
  49. 18
      features/roomlist/build.gradle.kts
  50. 0
      features/roomlist/consumer-rules.pro
  51. 21
      features/roomlist/proguard-rules.pro
  52. 24
      features/roomlist/src/androidTest/java/io/element/android/x/features/roomlist/ExampleInstrumentedTest.kt
  53. 4
      features/roomlist/src/main/AndroidManifest.xml
  54. 2
      features/roomlist/src/main/java/io/element/android/x/features/roomlist/MatrixUser.kt
  55. 3
      features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListActions.kt
  56. 70
      features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListScreen.kt
  57. 11
      features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewModel.kt
  58. 2
      features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewState.kt
  59. 17
      features/roomlist/src/test/java/io/element/android/x/features/roomlist/ExampleUnitTest.kt
  60. 67
      gradle/libs.versions.toml
  61. 8
      libraries/core/build.gradle
  62. 1
      libraries/designsystem/.gitignore
  63. 12
      libraries/designsystem/build.gradle.kts
  64. 0
      libraries/designsystem/consumer-rules.pro
  65. 21
      libraries/designsystem/proguard-rules.pro
  66. 4
      libraries/designsystem/src/main/AndroidManifest.xml
  67. 2
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/Color.kt
  68. 2
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/Theme.kt
  69. 2
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/Type.kt
  70. 0
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/Avatar.kt
  71. 2
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/VectorButton.kt
  72. 2
      libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/VectorTextField.kt
  73. 0
      libraries/matrix/build.gradle
  74. 0
      libraries/matrix/src/main/AndroidManifest.xml
  75. 3
      libraries/matrix/src/main/java/io/element/android/x/matrix/LogTag.kt
  76. 6
      libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt
  77. 4
      libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixClient.kt
  78. 2
      libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixInstance.kt
  79. 2
      libraries/matrix/src/main/java/io/element/android/x/matrix/RoomWrapper.kt
  80. 10
      libraries/matrix/src/main/java/io/element/android/x/matrix/store/SessionStore.kt
  81. 4
      libraries/matrix/src/main/java/io/element/android/x/matrix/util/Error.kt
  82. 3
      libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/LogTag.kt
  83. 61
      libraries/ui/screens/login/build.gradle
  84. 129
      libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActivity.kt
  85. 22
      libraries/ui/screens/login/src/main/res/drawable/element_logo_green.xml
  86. 62
      libraries/ui/screens/roomlist/build.gradle
  87. 126
      libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActivity.kt
  88. 52
      libraries/ui/theme/build.gradle
  89. 14
      plugins/build.gradle.kts
  90. 10
      plugins/settings.gradle.kts
  91. 17
      plugins/src/main/java/Versions.kt
  92. 50
      plugins/src/main/java/extension/CommonExtension.kt
  93. 29
      plugins/src/main/java/io.element.android-compose.gradle.kts
  94. 12
      plugins/src/main/java/io.element.android-library.gradle.kts
  95. 16
      settings.gradle.kts

29
.idea/inspectionProfiles/Project_Default.xml

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
</profile>
</component>

25
.idea/jarRepositories.xml

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

3
.idea/misc.xml

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

42
app/build.gradle

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.devtools.ksp' version '1.7.20-1.0.7'
}
android {
@ -36,7 +37,7 @@ android { @@ -36,7 +37,7 @@ android {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerExtensionVersion "1.3.2"
}
packagingOptions {
resources {
@ -44,6 +45,14 @@ android { @@ -44,6 +45,14 @@ android {
}
}
applicationVariants.all { variant ->
kotlin.sourceSets {
getByName(variant.name) {
kotlin.srcDir("build/generated/ksp/${variant.name}/kotlin")
}
}
}
signingConfigs {
debug {
keyAlias 'androiddebugkey'
@ -55,19 +64,26 @@ android { @@ -55,19 +64,26 @@ android {
}
dependencies {
implementation project(":libraries:ui:theme")
implementation project(":libraries:ui:screens:login")
implementation project(":libraries:ui:screens:roomlist")
implementation project(":libraries:sdk:matrix")
implementation project(":libraries:designsystem")
implementation project(":libraries:matrix")
implementation project(":features:login")
implementation project(":features:roomlist")
implementation 'io.github.raamcosta.compose-destinations:core:1.7.23-beta'
ksp 'io.github.raamcosta.compose-destinations:ksp:1.7.23-beta'
def composeBom = platform('androidx.compose:compose-bom:2022.10.00')
implementation composeBom
androidTestImplementation composeBom
implementation 'androidx.core:core-ktx:1.9.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.0.0-rc01'
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.ui:ui"
implementation 'androidx.compose.material3:material3'
implementation "androidx.compose.ui:ui-tooling-preview"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.6.0'
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation 'com.airbnb.android:mavericks-compose:2.7.0'
implementation 'androidx.activity:activity-compose:1.6.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1'
debugImplementation "androidx.compose.ui:ui-tooling"
debugImplementation "androidx.compose.ui:ui-test-manifest"
implementation 'com.airbnb.android:mavericks-compose:3.0.1'
}

2
app/src/main/java/io/element/android/x/ElementXApplication.kt

@ -2,7 +2,7 @@ package io.element.android.x @@ -2,7 +2,7 @@ package io.element.android.x
import android.app.Application
import com.airbnb.mvrx.Mavericks
import io.element.android.x.sdk.matrix.MatrixInstance
import io.element.android.x.matrix.MatrixInstance
class ElementXApplication : Application() {

46
app/src/main/java/io/element/android/x/MainActivity.kt

@ -1,41 +1,41 @@ @@ -1,41 +1,41 @@
package io.element.android.x
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope
import io.element.android.x.ui.screen.login.LoginActivity
import io.element.android.x.ui.screen.roomlist.RoomListActivity
import kotlinx.coroutines.launch
import androidx.compose.runtime.Composable
import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.rememberNavHostEngine
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.destinations.LoginScreenNavigationDestination
import kotlinx.coroutines.runBlocking
class MainActivity : ComponentActivity() {
private val launcher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == RESULT_OK) {
// Launch the room Activity and finish
startRoomActivityAndFinish()
} else {
finish()
}
}
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
if (viewModel.hasSession()) {
startRoomActivityAndFinish()
} else {
launcher.launch(Intent(this@MainActivity, LoginActivity::class.java))
setContent {
ElementXTheme {
MainScreen(viewModel = viewModel)
}
}
}
}
private fun startRoomActivityAndFinish() {
startActivity(Intent(this, RoomListActivity::class.java))
finish()
@Composable
private fun MainScreen(viewModel: MainViewModel) {
val engine = rememberNavHostEngine()
val navController = engine.rememberNavController()
val startRoute = runBlocking {
if (!viewModel.hasSession()) LoginScreenNavigationDestination else NavGraphs.root.startRoute
}
DestinationsNavHost(
engine = engine,
navController = navController,
navGraph = NavGraphs.root,
startRoute = startRoute
)
}

2
app/src/main/java/io/element/android/x/MainViewModel.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package io.element.android.x
import androidx.lifecycle.ViewModel
import io.element.android.x.sdk.matrix.MatrixInstance
import io.element.android.x.matrix.MatrixInstance
class MainViewModel : ViewModel() {
private val matrix = MatrixInstance.getInstance()

28
app/src/main/java/io/element/android/x/Navigation.kt

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
package io.element.android.x
import androidx.compose.runtime.Composable
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import io.element.android.x.destinations.RoomListScreenNavigationDestination
import io.element.android.x.features.login.LoginScreen
import io.element.android.x.features.roomlist.RoomListScreen
@Destination
@Composable
fun LoginScreenNavigation(navigator: DestinationsNavigator) {
LoginScreen(
onLoginWithSuccess = {
navigator.clearBackStack(RoomListScreenNavigationDestination)
}
)
}
@RootNavGraph(start = true)
@Destination
@Composable
fun RoomListScreenNavigation() {
RoomListScreen()
}

0
libraries/ui/theme/src/main/res/drawable-v24/ic_launcher_foreground.xml → app/src/main/res/drawable-v24/ic_launcher_foreground.xml

0
libraries/ui/theme/src/main/res/drawable/ic_launcher_background.xml → app/src/main/res/drawable/ic_launcher_background.xml

0
libraries/ui/theme/src/main/res/mipmap-anydpi-v26/ic_launcher.xml → app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

0
libraries/ui/theme/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml → app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

0
libraries/ui/theme/src/main/res/mipmap-hdpi/ic_launcher.webp → app/src/main/res/mipmap-hdpi/ic_launcher.webp

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

0
libraries/ui/theme/src/main/res/mipmap-hdpi/ic_launcher_round.webp → app/src/main/res/mipmap-hdpi/ic_launcher_round.webp

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

0
libraries/ui/theme/src/main/res/mipmap-mdpi/ic_launcher.webp → app/src/main/res/mipmap-mdpi/ic_launcher.webp

Before

Width:  |  Height:  |  Size: 982 B

After

Width:  |  Height:  |  Size: 982 B

0
libraries/ui/theme/src/main/res/mipmap-mdpi/ic_launcher_round.webp → app/src/main/res/mipmap-mdpi/ic_launcher_round.webp

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

0
libraries/ui/theme/src/main/res/mipmap-xhdpi/ic_launcher.webp → app/src/main/res/mipmap-xhdpi/ic_launcher.webp

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

0
libraries/ui/theme/src/main/res/mipmap-xhdpi/ic_launcher_round.webp → app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

0
libraries/ui/theme/src/main/res/mipmap-xxhdpi/ic_launcher.webp → app/src/main/res/mipmap-xxhdpi/ic_launcher.webp

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

0
libraries/ui/theme/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp → app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

0
libraries/ui/theme/src/main/res/mipmap-xxxhdpi/ic_launcher.webp → app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

0
libraries/ui/theme/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp → app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

0
libraries/ui/theme/src/main/res/values/colors.xml → app/src/main/res/values/colors.xml

0
libraries/ui/theme/src/main/res/values/strings.xml → app/src/main/res/values/strings.xml

0
libraries/ui/theme/src/main/res/values/themes.xml → app/src/main/res/values/themes.xml

0
libraries/ui/theme/src/main/res/xml/backup_rules.xml → app/src/main/res/xml/backup_rules.xml

0
libraries/ui/theme/src/main/res/xml/data_extraction_rules.xml → app/src/main/res/xml/data_extraction_rules.xml

8
build.gradle

@ -1,12 +1,8 @@ @@ -1,12 +1,8 @@
buildscript {
ext {
compose_version = '1.3.0-rc01'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.3.0' apply false
id 'com.android.library' version '7.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
}
task clean(type: Delete) {

1
features/login/.gitignore vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
/build

18
features/login/build.gradle.kts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
plugins {
id("io.element.android-compose")
}
android {
namespace = "io.element.android.x.features.login"
}
dependencies {
implementation(project(":libraries:core"))
implementation(project(":libraries:matrix"))
implementation(project(":libraries:designsystem"))
implementation("com.airbnb.android:mavericks-compose:3.0.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
}

0
features/login/consumer-rules.pro

21
features/login/proguard-rules.pro vendored

@ -0,0 +1,21 @@ @@ -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.kts.
#
# 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

24
features/login/src/androidTest/java/io/element/android/x/features/login/ExampleInstrumentedTest.kt

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
package io.element.android.x.features.login
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("io.element.android.x.features.login.test", appContext.packageName)
}
}

0
libraries/ui/theme/src/main/AndroidManifest.xml → features/login/src/main/AndroidManifest.xml

2
libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActions.kt → features/login/src/main/java/io/element/android/x/features/login/LoginActions.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.screen.login
package io.element.android.x.features.login
sealed interface LoginActions {
data class SetHomeserver(val homeserver: String) : LoginActions

133
features/login/src/main/java/io/element/android/x/features/login/LoginScreen.kt

@ -0,0 +1,133 @@ @@ -0,0 +1,133 @@
@file:OptIn(ExperimentalMaterial3Api::class)
package io.element.android.x.features.login
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.designsystem.components.VectorButton
@Composable
fun LoginScreen(
viewModel: LoginViewModel = mavericksViewModel(),
onLoginWithSuccess: () -> Unit = { }
) {
val state: LoginViewState by viewModel.collectAsState()
LoginContent(
state = state,
onHomeserverChanged = { viewModel.handle(LoginActions.SetHomeserver(it)) },
onLoginChanged = { viewModel.handle(LoginActions.SetLogin(it)) },
onPasswordChanged = { viewModel.handle(LoginActions.SetPassword(it)) },
onSubmitClicked = { viewModel.handle(LoginActions.Submit) },
onLoginWithSuccess = onLoginWithSuccess
)
}
@Composable
fun LoginContent(
state: LoginViewState,
onHomeserverChanged: (String) -> Unit,
onLoginChanged: (String) -> Unit,
onPasswordChanged: (String) -> Unit,
onSubmitClicked: () -> Unit,
onLoginWithSuccess: () -> Unit
) {
Surface(color = MaterialTheme.colorScheme.background) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Column(
modifier = Modifier.fillMaxSize(),
) {
val isError = state.isLoggedIn is Fail
Image(
painterResource(id = R.drawable.element_logo_green),
contentDescription = null,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(40.dp)
)
OutlinedTextField(
value = state.homeserver,
modifier = Modifier.fillMaxWidth(),
onValueChange = {
onHomeserverChanged(it)
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Uri,
),
)
OutlinedTextField(
value = state.login,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
onValueChange = {
onLoginChanged(it)
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
),
)
OutlinedTextField(
value = state.password,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
onValueChange = {
onPasswordChanged(it)
},
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Send,
),
)
if (isError) {
Text(
text = (state.isLoggedIn as? Fail)?.toString().orEmpty(),
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(start = 16.dp)
)
}
VectorButton(
text = "Submit",
onClick = {
onSubmitClicked()
},
enabled = state.submitEnabled,
modifier = Modifier
.align(Alignment.End)
.padding(top = 16.dp)
)
if (state.isLoggedIn is Loading) {
// FIXME This does not work, we never enter this if block
CircularProgressIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally)
)
}
if (state.isLoggedIn is Success) {
onLoginWithSuccess()
}
}
}
}
}

51
libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewModel.kt → features/login/src/main/java/io/element/android/x/features/login/LoginViewModel.kt

@ -1,11 +1,11 @@ @@ -1,11 +1,11 @@
package io.element.android.x.ui.screen.login
package io.element.android.x.features.login
import android.util.Log
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.Success
import io.element.android.x.sdk.matrix.MatrixInstance
import io.element.android.x.matrix.MatrixInstance
import kotlinx.coroutines.launch
class LoginViewModel(initialState: LoginViewState) :
@ -13,28 +13,6 @@ class LoginViewModel(initialState: LoginViewState) : @@ -13,28 +13,6 @@ class LoginViewModel(initialState: LoginViewState) :
private val matrix = MatrixInstance.getInstance()
init {
observeState()
}
private fun observeState() {
onEach(
LoginViewState::homeserver,
LoginViewState::login,
LoginViewState::password,
LoginViewState::isLoggedIn,
) { homeserver, login, password, isLoggedIn ->
setState {
copy(
submitEnabled = homeserver.isNotEmpty() &&
login.isNotEmpty() &&
password.isNotEmpty() &&
isLoggedIn !is Loading
)
}
}
}
fun handle(action: LoginActions) {
when (action) {
is LoginActions.SetHomeserver -> handleSetHomeserver(action)
@ -44,14 +22,6 @@ class LoginViewModel(initialState: LoginViewState) : @@ -44,14 +22,6 @@ class LoginViewModel(initialState: LoginViewState) :
}
}
private fun handleSetHomeserver(action: LoginActions.SetHomeserver) {
setState {
copy(
homeserver = action.homeserver
)
}
}
private fun handleSubmit() = withState { state ->
viewModelScope.launch {
setState { copy(isLoggedIn = Loading()) }
@ -65,20 +35,15 @@ class LoginViewModel(initialState: LoginViewState) : @@ -65,20 +35,15 @@ class LoginViewModel(initialState: LoginViewState) :
}
}
private fun handleSetPassword(action: LoginActions.SetPassword) {
setState {
copy(
password = action.password
)
private fun handleSetHomeserver(action: LoginActions.SetHomeserver) {
setState { copy(homeserver = action.homeserver) }
}
private fun handleSetPassword(action: LoginActions.SetPassword) {
setState { copy(password = action.password) }
}
private fun handleSetName(action: LoginActions.SetLogin) {
setState {
copy(
login = action.login
)
}
setState { copy(login = action.login) }
}
}

10
libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewState.kt → features/login/src/main/java/io/element/android/x/features/login/LoginViewState.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.screen.login
package io.element.android.x.features.login
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState
@ -8,6 +8,10 @@ data class LoginViewState( @@ -8,6 +8,10 @@ data class LoginViewState(
val homeserver: String = "matrix.org",
val login: String = "",
val password: String = "",
val submitEnabled: Boolean = false,
val isLoggedIn: Async<Unit> = Uninitialized,
) : MavericksState
) : MavericksState {
val submitEnabled = homeserver.isNotEmpty() && login.isNotEmpty() && password.isNotEmpty()
}

22
features/login/src/main/res/drawable/element_logo_green.xml

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M23.04,3.84C23.04,1.7192 24.7593,0 26.88,0C41.0185,0 52.48,11.4615 52.48,25.6C52.48,27.7208 50.7608,29.44 48.64,29.44C46.5193,29.44 44.8,27.7208 44.8,25.6C44.8,15.7031 36.777,7.68 26.88,7.68C24.7593,7.68 23.04,5.9608 23.04,3.84Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
<path
android:pathData="M40.96,60.16C40.96,62.2808 39.2407,64 37.12,64C22.9815,64 11.52,52.5385 11.52,38.4C11.52,36.2792 13.2392,34.56 15.36,34.56C17.4807,34.56 19.2,36.2792 19.2,38.4C19.2,48.2969 27.223,56.32 37.12,56.32C39.2407,56.32 40.96,58.0392 40.96,60.16Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
<path
android:pathData="M3.84,40.96C1.7192,40.96 -0,39.2407 -0,37.12C-0,22.9815 11.4615,11.52 25.6,11.52C27.7208,11.52 29.44,13.2392 29.44,15.36C29.44,17.4807 27.7208,19.2 25.6,19.2C15.7031,19.2 7.68,27.223 7.68,37.12C7.68,39.2407 5.9608,40.96 3.84,40.96Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
<path
android:pathData="M60.16,23.04C62.2808,23.04 64,24.7593 64,26.88C64,41.0185 52.5385,52.48 38.4,52.48C36.2792,52.48 34.56,50.7608 34.56,48.64C34.56,46.5193 36.2792,44.8 38.4,44.8C48.2969,44.8 56.32,36.777 56.32,26.88C56.32,24.7593 58.0392,23.04 60.16,23.04Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
</vector>

17
features/login/src/test/java/io/element/android/x/features/login/ExampleUnitTest.kt

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
package io.element.android.x.features.login
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

1
features/messages/.gitignore vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
/build

41
features/messages/build.gradle

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'io.element.android.x.features.messages'
compileSdk 32
defaultConfig {
minSdk 24
targetSdk 32
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

0
features/messages/consumer-rules.pro

21
features/messages/proguard-rules.pro vendored

@ -0,0 +1,21 @@ @@ -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

24
features/messages/src/androidTest/java/io/element/android/x/features/messages/ExampleInstrumentedTest.kt

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
package io.element.android.x.features.messages
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("io.element.android.x.features.messages.test", appContext.packageName)
}
}

4
libraries/ui/screens/login/src/main/AndroidManifest.xml → features/messages/src/main/AndroidManifest.xml

@ -1,8 +1,4 @@ @@ -1,8 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name="LoginActivity" />
</application>
</manifest>

17
features/messages/src/test/java/io/element/android/x/features/messages/ExampleUnitTest.kt

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
package io.element.android.x.features.messages
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

1
features/roomlist/.gitignore vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
/build

18
features/roomlist/build.gradle.kts

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
plugins {
id("io.element.android-compose")
}
android {
namespace = "io.element.android.x.features.roomlist"
}
dependencies {
implementation(project(":libraries:core"))
implementation(project(":libraries:matrix"))
implementation(project(":libraries:designsystem"))
implementation("com.airbnb.android:mavericks-compose:3.0.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
}

0
features/roomlist/consumer-rules.pro

21
features/roomlist/proguard-rules.pro vendored

@ -0,0 +1,21 @@ @@ -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

24
features/roomlist/src/androidTest/java/io/element/android/x/features/roomlist/ExampleInstrumentedTest.kt

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
package io.element.android.x.features.roomlist
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("io.element.android.x.features.roomlist.test", appContext.packageName)
}
}

4
libraries/ui/screens/roomlist/src/main/AndroidManifest.xml → features/roomlist/src/main/AndroidManifest.xml

@ -1,8 +1,4 @@ @@ -1,8 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name="RoomListActivity" />
</application>
</manifest>

2
libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/MatrixUser.kt → features/roomlist/src/main/java/io/element/android/x/features/roomlist/MatrixUser.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.screen.roomlist
package io.element.android.x.features.roomlist
data class MatrixUser(
val username: String? = null,

3
libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActions.kt → features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListActions.kt

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
package io.element.android.x.ui.screen.roomlist
package io.element.android.x.features.roomlist
sealed interface RoomListActions {
object Init : RoomListActions
object LoadMore : RoomListActions
object Logout : RoomListActions
}

70
features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListScreen.kt

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
package io.element.android.x.features.roomlist
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import org.matrix.rustcomponents.sdk.Room
@Composable
fun RoomListScreen(
viewModel: RoomListViewModel = mavericksViewModel(),
onRoomClicked: (String) -> Unit = { }
) {
val state by viewModel.collectAsState()
RoomListContent(state, onRoomClicked)
}
@Composable
fun RoomListContent(
state: RoomListViewState,
onRoomClicked: (String) -> Unit
) {
Surface(color = MaterialTheme.colorScheme.background) {
Column(
modifier = Modifier.fillMaxSize()
) {
val rooms = state.rooms
if (rooms is Success) {
LazyColumn {
items(rooms()) { room ->
RoomItem(room = room) {
onRoomClicked(it)
}
}
}
}
}
}
}
@Composable
private fun RoomItem(
modifier: Modifier = Modifier,
room: Room,
onClick: (String) -> Unit
) {
Row(verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.clickable {
onClick(room.id())
}
.fillMaxWidth()
) {
Column(modifier = modifier.padding(8.dp)) {
Text(text = "Room: ${room.name() ?: room.id()}")
Text(text = if (room.isDirect()) "Direct" else "Room")
}
}
}

11
libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListViewModel.kt → features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewModel.kt

@ -1,12 +1,12 @@ @@ -1,12 +1,12 @@
package io.element.android.x.ui.screen.roomlist
package io.element.android.x.features.roomlist
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.Success
import io.element.android.x.core.data.tryOrNull
import io.element.android.x.sdk.matrix.MatrixClient
import io.element.android.x.sdk.matrix.MatrixInstance
import io.element.android.x.matrix.MatrixClient
import io.element.android.x.matrix.MatrixInstance
import kotlinx.coroutines.launch
import org.matrix.rustcomponents.sdk.Room
import org.matrix.rustcomponents.sdk.StoppableSpawn
@ -19,9 +19,12 @@ class RoomListViewModel(initialState: RoomListViewState) : @@ -19,9 +19,12 @@ class RoomListViewModel(initialState: RoomListViewState) :
private var sync: StoppableSpawn? = null
private val matrix = MatrixInstance.getInstance()
init {
handleInit()
}
fun handle(action: RoomListActions) {
when (action) {
RoomListActions.Init -> handleInit()
RoomListActions.LoadMore -> TODO()
RoomListActions.Logout -> handleLogout()
}

2
libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListViewState.kt → features/roomlist/src/main/java/io/element/android/x/features/roomlist/RoomListViewState.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.screen.roomlist
package io.element.android.x.features.roomlist
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MavericksState

17
features/roomlist/src/test/java/io/element/android/x/features/roomlist/ExampleUnitTest.kt

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
package io.element.android.x.features.roomlist
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

67
gradle/libs.versions.toml

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
[versions]
# Project
android_gradle_plugin = "7.3.1"
kotlin = "1.7.20"
# AndroidX
material = "1.6.1"
corektx = "1.9.0"
datastore = "1.0.0"
# Compose
compose_compiler = "1.3.2"
compose_bom = "2022.10.00"
# Coroutines
coroutines = "1.6.4"
# Accompanist
accompanist = "0.27.0"
# Test
test_junit = "4.13.2"
test_runner = "1.4.0"
test_core = "1.4.0"
test_mockk = "1.13.2"
test_uiautomator = "2.2.0"
test_junitext = "1.1.3"
test_barista = "4.2.0"
test_hamcrest = "2.2"
test_orchestrator = "1.4.1"
[libraries]
# Project
android_gradle_plugin = { module = "com.android.tools.build:gradle", version.ref = "android_gradle_plugin" }
kotlin_gradle_plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
# AndroidX
androidx_material = { module = "com.google.android.material:material", version.ref = "material" }
androidx_corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" }
androidx_datastore = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" }
androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" }
androidx_compose_foundation = { group = "androidx.compose.foundation", name = "foundation" }
# Coroutines
coroutines_core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
coroutines_test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
# Accompanist
accompanist_animation = { module = "com.google.accompanist:accompanist-navigation-animation", version.ref = "accompanist" }
accompanist_permission = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
accompanist_material = { module = "com.google.accompanist:accompanist-navigation-material", version.ref = "accompanist" }
# Test
test_junit = { module = "junit:junit", version.ref = "test_junit" }
test_runner = { module = "androidx.test:runner", version.ref = "test_runner" }
test_core = { module = "androidx.test:core", version.ref = "test_core" }
test_corektx = { module = "androidx.test:core-ktx", version.ref = "test_core" }
test_uiautomator = { module = "androidx.test.uiautomator:uiautomator", version.ref = "test_uiautomator" }
test_junitext = { module = "androidx.test.ext:junit", version.ref = "test_junitext" }
test_mockk = { module = "io.mockk:mockk", version.ref = "test_mockk" }
test_barista = { module = "com.adevinta.android:barista", version.ref = "test_barista" }
test_hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "test_hamcrest" }
test_orchestrator = { module = "androidx.test:orchestrator", version.ref = "test_orchestrator" }
[bundles]

8
libraries/core/build.gradle

@ -28,7 +28,7 @@ android { @@ -28,7 +28,7 @@ android {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerExtensionVersion "1.3.2"
}
kotlinOptions {
jvmTarget = '1.8'
@ -39,13 +39,13 @@ dependencies { @@ -39,13 +39,13 @@ dependencies {
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation 'androidx.activity:activity-compose:1.6.0'
implementation 'androidx.activity:activity-compose:1.6.1'
implementation 'androidx.fragment:fragment-ktx:1.5.3'
implementation 'com.airbnb.android:mavericks-compose:2.7.0'
implementation 'com.airbnb.android:mavericks-compose:3.0.1'
}

1
libraries/designsystem/.gitignore vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
/build

12
libraries/designsystem/build.gradle.kts

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
plugins {
id("io.element.android-compose")
}
android {
namespace = "io.element.android.x.libraries.designsystem"
dependencies {
// Should not be there, but this is a POC
implementation("io.coil-kt:coil-compose:2.2.1")
}
}

0
libraries/designsystem/consumer-rules.pro

21
libraries/designsystem/proguard-rules.pro vendored

@ -0,0 +1,21 @@ @@ -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.kts.
#
# 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

4
libraries/designsystem/src/main/AndroidManifest.xml

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

2
libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/Color.kt → libraries/designsystem/src/main/java/io/element/android/x/designsystem/Color.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.theme
package io.element.android.x.designsystem
import androidx.compose.ui.graphics.Color

2
libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/Theme.kt → libraries/designsystem/src/main/java/io/element/android/x/designsystem/Theme.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.theme
package io.element.android.x.designsystem
import android.app.Activity
import android.os.Build

2
libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/Type.kt → libraries/designsystem/src/main/java/io/element/android/x/designsystem/Type.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.theme
package io.element.android.x.designsystem
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle

0
libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/Avatar.kt → libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/Avatar.kt

2
libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/VectorButton.kt → libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/VectorButton.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.theme.components
package io.element.android.x.designsystem.components
import androidx.compose.material3.Button
import androidx.compose.material3.Text

2
libraries/ui/theme/src/main/java/io/element/android/x/ui/theme/components/VectorTextField.kt → libraries/designsystem/src/main/java/io/element/android/x/designsystem/components/VectorTextField.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.ui.theme.components
package io.element.android.x.designsystem.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.ExperimentalMaterial3Api

0
libraries/sdk/matrix/build.gradle → libraries/matrix/build.gradle

0
libraries/sdk/matrix/src/main/AndroidManifest.xml → libraries/matrix/src/main/AndroidManifest.xml

3
libraries/matrix/src/main/java/io/element/android/x/matrix/LogTag.kt

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
package io.element.android.x.matrix
internal const val LOG_TAG = "Matrix"

6
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/Matrix.kt → libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package io.element.android.x.sdk.matrix
package io.element.android.x.matrix
import android.content.Context
import io.element.android.x.sdk.matrix.store.SessionStore
import io.element.android.x.sdk.matrix.util.logError
import io.element.android.x.matrix.store.SessionStore
import io.element.android.x.matrix.util.logError
import org.matrix.rustcomponents.sdk.AuthenticationService
import org.matrix.rustcomponents.sdk.ClientBuilder
import java.io.File

4
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt → libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixClient.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package io.element.android.x.sdk.matrix
package io.element.android.x.matrix
import android.util.Log
import io.element.android.x.sdk.matrix.store.SessionStore
import io.element.android.x.matrix.store.SessionStore
import org.matrix.rustcomponents.sdk.*
class MatrixClient internal constructor(

2
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixInstance.kt → libraries/matrix/src/main/java/io/element/android/x/matrix/MatrixInstance.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.sdk.matrix
package io.element.android.x.matrix
import android.annotation.SuppressLint
import android.content.Context

2
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/RoomWrapper.kt → libraries/matrix/src/main/java/io/element/android/x/matrix/RoomWrapper.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.sdk.matrix
package io.element.android.x.matrix
import android.util.Log
import org.matrix.rustcomponents.sdk.Client

10
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/store/SessionStore.kt → libraries/matrix/src/main/java/io/element/android/x/matrix/store/SessionStore.kt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
package io.element.android.x.sdk.matrix.store
package io.element.android.x.matrix.store
import android.content.Context
import androidx.datastore.core.DataStore
@ -10,6 +10,10 @@ import kotlinx.coroutines.flow.firstOrNull @@ -10,6 +10,10 @@ import kotlinx.coroutines.flow.firstOrNull
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "elementx_sessions")
private val userIdPreference = stringPreferencesKey("userId")
// TODO It contains the access token, so it has to be stored in a more secured storage.
// I would expect the Rust SDK to provide a more obscure token.
private val restoreTokenPreference = stringPreferencesKey("restoreToken")
internal class SessionStore(
context: Context
@ -21,10 +25,6 @@ internal class SessionStore( @@ -21,10 +25,6 @@ internal class SessionStore(
private val store = context.dataStore
private val userIdPreference = stringPreferencesKey("userId")
// TODO It contains the access token, so it has to be stored in a more secured storage.
// I would expect the Rust SDK to provide a more obscure token.
private val restoreTokenPreference = stringPreferencesKey("restoreToken")
suspend fun storeData(sessionData: SessionData) {
store.edit { prefs ->

4
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/util/Error.kt → libraries/matrix/src/main/java/io/element/android/x/matrix/util/Error.kt

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
package io.element.android.x.sdk.matrix.util
package io.element.android.x.matrix.util
import android.util.Log
import io.element.android.x.sdk.matrix.LOG_TAG
import io.element.android.x.matrix.LOG_TAG
import org.matrix.rustcomponents.sdk.ClientException
fun logError(throwable: Throwable) {

3
libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/LogTag.kt

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
package io.element.android.x.sdk.matrix
internal const val LOG_TAG = "Matrix"

61
libraries/ui/screens/login/build.gradle

@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'io.element.android.x.ui.screen.login'
compileSdk 33
defaultConfig {
minSdk 29
targetSdk 33
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation project(":libraries:core")
implementation project(":libraries:ui:theme")
implementation project(":libraries:sdk:matrix")
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.0.0-rc01'
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation 'androidx.activity:activity-compose:1.6.0'
implementation 'androidx.fragment:fragment-ktx:1.5.3'
implementation 'com.airbnb.android:mavericks-compose:2.7.0'
}

129
libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActivity.kt

@ -1,129 +0,0 @@ @@ -1,129 +0,0 @@
package io.element.android.x.ui.screen.login
import android.app.Activity
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.ui.theme.ElementXTheme
import io.element.android.x.ui.theme.components.VectorButton
class LoginActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ElementXTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
color = MaterialTheme.colorScheme.background
) {
Box(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier.fillMaxSize(),
) {
val viewModel: LoginViewModel = mavericksViewModel()
val state by viewModel.collectAsState()
val isError = state.isLoggedIn is Fail
Image(
painterResource(id = R.drawable.element_logo_green),
contentDescription = null,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(40.dp)
)
OutlinedTextField(
value = state.homeserver,
modifier = Modifier.fillMaxWidth(),
onValueChange = {
viewModel.handle(LoginActions.SetHomeserver(it))
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Uri,
),
)
OutlinedTextField(
value = state.login,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
onValueChange = {
viewModel.handle(LoginActions.SetLogin(it))
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
),
)
OutlinedTextField(
value = state.password,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
onValueChange = {
viewModel.handle(LoginActions.SetPassword(it))
},
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Send,
),
)
if (isError) {
Text(
text = (state.isLoggedIn as? Fail)?.toString().orEmpty(),
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(start = 16.dp)
)
}
VectorButton(
text = "Submit",
onClick = {
viewModel.handle(LoginActions.Submit)
},
enabled = state.submitEnabled,
modifier = Modifier
.align(Alignment.End)
.padding(top = 16.dp)
)
if (state.isLoggedIn is Loading) {
// FIXME This does not work, we never enter this if block
CircularProgressIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally)
)
}
if (state.isLoggedIn is Success) {
openRoomList()
}
}
}
}
}
}
}
private fun openRoomList() {
setResult(Activity.RESULT_OK)
finish()
}
}

22
libraries/ui/screens/login/src/main/res/drawable/element_logo_green.xml

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="64"
android:viewportHeight="64">
<path
android:pathData="M23.04,3.84C23.04,1.7192 24.7593,0 26.88,0C41.0185,0 52.48,11.4615 52.48,25.6C52.48,27.7208 50.7608,29.44 48.64,29.44C46.5193,29.44 44.8,27.7208 44.8,25.6C44.8,15.7031 36.777,7.68 26.88,7.68C24.7593,7.68 23.04,5.9608 23.04,3.84Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
<path
android:pathData="M40.96,60.16C40.96,62.2808 39.2407,64 37.12,64C22.9815,64 11.52,52.5385 11.52,38.4C11.52,36.2792 13.2392,34.56 15.36,34.56C17.4807,34.56 19.2,36.2792 19.2,38.4C19.2,48.2969 27.223,56.32 37.12,56.32C39.2407,56.32 40.96,58.0392 40.96,60.16Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
<path
android:pathData="M3.84,40.96C1.7192,40.96 -0,39.2407 -0,37.12C-0,22.9815 11.4615,11.52 25.6,11.52C27.7208,11.52 29.44,13.2392 29.44,15.36C29.44,17.4807 27.7208,19.2 25.6,19.2C15.7031,19.2 7.68,27.223 7.68,37.12C7.68,39.2407 5.9608,40.96 3.84,40.96Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
<path
android:pathData="M60.16,23.04C62.2808,23.04 64,24.7593 64,26.88C64,41.0185 52.5385,52.48 38.4,52.48C36.2792,52.48 34.56,50.7608 34.56,48.64C34.56,46.5193 36.2792,44.8 38.4,44.8C48.2969,44.8 56.32,36.777 56.32,26.88C56.32,24.7593 58.0392,23.04 60.16,23.04Z"
android:fillColor="#0DBD8B"
android:fillType="evenOdd"/>
</vector>

62
libraries/ui/screens/roomlist/build.gradle

@ -1,62 +0,0 @@ @@ -1,62 +0,0 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'io.element.android.x.ui.screen.roomlist'
compileSdk 33
defaultConfig {
minSdk 29
targetSdk 33
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation project(":libraries:core")
implementation project(":libraries:ui:theme")
implementation project(":libraries:sdk:matrix")
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.0.0-rc01'
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation 'androidx.activity:activity-compose:1.6.0'
implementation 'androidx.fragment:fragment-ktx:1.5.3'
implementation 'com.airbnb.android:mavericks-compose:2.7.0'
implementation 'io.coil-kt:coil-compose:2.2.1'
}

126
libraries/ui/screens/roomlist/src/main/java/io/element/android/x/ui/screen/roomlist/RoomListActivity.kt

@ -1,126 +0,0 @@ @@ -1,126 +0,0 @@
package io.element.android.x.ui.screen.roomlist
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExitToApp
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import coil.compose.rememberAsyncImagePainter
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.ui.theme.ElementXTheme
import io.element.android.x.ui.theme.components.Avatar
import org.matrix.rustcomponents.sdk.Room
class RoomListActivity : ComponentActivity() {
private var initDone = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ElementXTheme {
val viewModel: RoomListViewModel = mavericksViewModel()
if (!initDone) {
initDone = true
viewModel.handle(RoomListActions.Init)
}
val state = viewModel.collectAsState()
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
color = MaterialTheme.colorScheme.background
) {
Column(
modifier = Modifier.fillMaxSize()
) {
OptionMenu(state.value.user, viewModel)
val rooms = state.value.rooms
if (rooms is Success) {
LazyColumn {
items(rooms()) { room ->
RoomCompose(room) {
Toast.makeText(
this@RoomListActivity,
"Room $it clicked!",
Toast.LENGTH_SHORT
).show()
}
}
}
}
}
}
if (state.value.logoutAction is Success) {
finish()
}
}
}
}
@Composable
private fun RoomCompose(room: Room, onClick: (String) -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable { onClick.invoke(room.id()) },
) {
Image(
painter = rememberAsyncImagePainter(model = room.avatarUrl()),
contentDescription = null,
modifier = Modifier.size(32.dp),
)
Spacer(modifier = Modifier.width(8.dp))
Column(
modifier = Modifier
.fillMaxWidth()
.height(32.dp),
) {
Text(text = "Room: ${room.name() ?: room.id()}")
Text(text = if (room.isDirect()) "Direct" else "Room")
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun OptionMenu(matrixUser: MatrixUser, viewModel: RoomListViewModel) {
TopAppBar(
title = {
Row(
modifier = Modifier.fillMaxWidth()
) {
Avatar(data = matrixUser.avatarData)
Spacer(modifier = Modifier.width(8.dp))
Text("${matrixUser.username}")
}
},
actions = {
IconButton(
onClick = { viewModel.handle(RoomListActions.Logout) }
) {
Icon(Icons.Default.ExitToApp, contentDescription = "logout")
}
}
)
}
}

52
libraries/ui/theme/build.gradle

@ -1,52 +0,0 @@ @@ -1,52 +0,0 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'io.element.android.x.theme'
compileSdk 33
defaultConfig {
minSdk 29
targetSdk 33
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation 'androidx.compose.material3:material3:1.0.0-rc01'
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation 'io.coil-kt:coil-compose:2.2.1'
}

14
plugins/build.gradle.kts

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
plugins {
`kotlin-dsl`
`kotlin-dsl-precompiled-script-plugins`
}
repositories {
mavenCentral()
google()
}
dependencies {
implementation(libs.android.gradle.plugin)
implementation(libs.kotlin.gradle.plugin)
}

10
plugins/settings.gradle.kts

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
dependencyResolutionManagement {
repositories {
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}

17
plugins/src/main/java/Versions.kt

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
import org.gradle.api.JavaVersion
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.jvm.toolchain.JavaLanguageVersion
val VersionCatalog.composeVersion: String
get() = findVersion("compose_compiler").get().requiredVersion
object Versions {
const val versionCode = 100100
const val versionName = "0.1.0"
const val compileSdk = 33
const val targetSdk = 33
const val minSdk = 24
val javaCompileVersion = JavaVersion.VERSION_11
val javaLanguageVersion: JavaLanguageVersion = JavaLanguageVersion.of(11)
}

50
plugins/src/main/java/extension/CommonExtension.kt

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
package extension
import Versions
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.LibraryExtension
import composeVersion
import org.gradle.api.artifacts.VersionCatalog
fun CommonExtension<*, *, *, *>.androidConfig() {
defaultConfig {
compileSdk = Versions.compileSdk
minSdk = Versions.minSdk
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
testOptions {
unitTests.isReturnDefaultValues = true
}
}
fun CommonExtension<*, *, *, *>.composeConfig() {
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.3.2"
}
packagingOptions {
resources.excludes.apply {
add("META-INF/AL2.0")
add("META-INF/LGPL2.1")
}
}
}
fun LibraryExtension.proguardConfig() {
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles("proguard-android.txt", "proguard-rules.pro")
consumerProguardFiles("proguard-rules.pro")
}
}
}

29
plugins/src/main/java/io.element.android-compose.gradle.kts

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
import extension.androidConfig
import extension.composeConfig
import extension.proguardConfig
plugins {
id("com.android.library")
id("kotlin-android")
}
android {
androidConfig()
proguardConfig()
composeConfig()
}
dependencies {
implementation(platform("androidx.compose:compose-bom:2022.10.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1")
implementation("androidx.activity:activity-compose:1.6.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1")
implementation("com.airbnb.android:mavericks-compose:3.0.1")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}

12
plugins/src/main/java/io.element.android-library.gradle.kts

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
import extension.androidConfig
import extension.proguardConfig
plugins {
id("com.android.library")
id("kotlin-android")
}
android {
androidConfig()
proguardConfig()
}

16
settings.gradle → settings.gradle.kts

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
pluginManagement {
repositories {
includeBuild("plugins")
gradlePluginPortal()
google()
mavenCentral()
@ -11,14 +12,15 @@ dependencyResolutionManagement { @@ -11,14 +12,15 @@ dependencyResolutionManagement {
google()
mavenCentral()
flatDir {
dirs 'libraries/sdk/matrix/libs'
dirs("libraries/matrix/libs")
}
}
}
rootProject.name = "ElementX"
include ':app'
include ':libraries:core'
include ':libraries:ui:theme'
include ':libraries:ui:screens:login'
include ':libraries:ui:screens:roomlist'
include ':libraries:sdk:matrix'
include(":app")
include(":libraries:core")
include(":libraries:matrix")
include(":features:login")
include(":features:roomlist")
include(":features:messages")
include(":libraries:designsystem")
Loading…
Cancel
Save