diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f5a0799676..fdae68aef4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -38,9 +38,9 @@ android { defaultConfig { applicationId = "io.element.android.x" - targetSdk = 33 // TODO Use Versions.targetSdk - versionCode = 1 - versionName = "1.0" + targetSdk = Versions.targetSdk + versionCode = Versions.versionCode + versionName = Versions.versionName vectorDrawables { useSupportLibrary = true @@ -109,25 +109,9 @@ android { } } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } kotlinOptions { jvmTarget = "1.8" } - buildFeatures { - compose = true - } - composeOptions { - kotlinCompilerExtensionVersion = "1.4.0" - } - packagingOptions { - resources { - excludes += "/META-INF/{AL2.0,LGPL2.1}" - } - } - // Waiting for https://github.com/google/ksp/issues/37 applicationVariants.all { kotlin.sourceSets { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index aa64ea3f53..31033b0500 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -34,8 +34,7 @@ android:theme="@style/Theme.ElementX.Splash" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|uiMode" android:exported="true" - android:windowSoftInputMode="adjustResize" - tools:ignore="LockedOrientationActivity"> + android:windowSoftInputMode="adjustResize"> diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index 217a3318fa..64267a3bd4 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -18,7 +18,7 @@ import org.gradle.api.JavaVersion import org.gradle.jvm.toolchain.JavaLanguageVersion object Versions { - const val versionCode = 100100 + const val versionCode = 1 const val versionName = "0.1.0" const val compileSdk = 33 diff --git a/plugins/src/main/kotlin/extension/CommonExtension.kt b/plugins/src/main/kotlin/extension/CommonExtension.kt index f3ba843ab7..615ce6b440 100644 --- a/plugins/src/main/kotlin/extension/CommonExtension.kt +++ b/plugins/src/main/kotlin/extension/CommonExtension.kt @@ -18,6 +18,7 @@ package extension import Versions import com.android.build.api.dsl.CommonExtension +import org.gradle.api.JavaVersion import org.gradle.api.Project import java.io.File @@ -30,6 +31,8 @@ fun CommonExtension<*, *, *, *>.androidConfig(project: Project) { compileOptions { isCoreLibraryDesugaringEnabled = true + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } testOptions { diff --git a/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts b/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts index 9bf88cc2c9..cceb1cfb36 100644 --- a/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts +++ b/plugins/src/main/kotlin/io.element.android-compose-application.gradle.kts @@ -15,7 +15,7 @@ */ /** - * This will generate the plugin "io.element.android-compose-application", used only in the module `app`. + * This will generate the plugin "io.element.android-compose-application" to use by app and samples modules */ import extension.androidConfig import extension.commonDependencies diff --git a/samples/minimal/.gitignore b/samples/minimal/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/samples/minimal/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/samples/minimal/build.gradle.kts b/samples/minimal/build.gradle.kts new file mode 100644 index 0000000000..79a05a89fd --- /dev/null +++ b/samples/minimal/build.gradle.kts @@ -0,0 +1,58 @@ + +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("io.element.android-compose-application") + alias(libs.plugins.kotlin.android) +} + +android { + namespace = "io.element.android.samples.minimal" + + defaultConfig { + applicationId = "io.element.android.samples.minimal" + targetSdk = Versions.targetSdk + versionCode = Versions.versionCode + versionName = Versions.versionName + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } +} + +dependencies { + implementation(libs.androidx.activity.compose) + implementation(projects.libraries.matrix) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.architecture) + implementation(projects.libraries.core) + implementation(projects.features.roomlist) + implementation(projects.features.login) + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2") + +} diff --git a/samples/minimal/proguard-rules.pro b/samples/minimal/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/samples/minimal/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/samples/minimal/src/main/AndroidManifest.xml b/samples/minimal/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..fc217a8cf1 --- /dev/null +++ b/samples/minimal/src/main/AndroidManifest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/LoginScreen.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/LoginScreen.kt new file mode 100644 index 0000000000..a6a28ed9d0 --- /dev/null +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/LoginScreen.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.samples.minimal + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import io.element.android.features.login.root.LoginRootPresenter +import io.element.android.features.login.root.LoginRootScreen +import io.element.android.libraries.matrix.auth.MatrixAuthenticationService + +class LoginScreen(private val authenticationService: MatrixAuthenticationService) { + + @Composable + fun Content(modifier: Modifier = Modifier) { + val presenter = remember { + LoginRootPresenter(authenticationService = authenticationService) + } + val state = presenter.present() + LoginRootScreen( + state = state, + modifier = modifier + ) + } +} diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt new file mode 100644 index 0000000000..c6c34612d3 --- /dev/null +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalMaterial3Api::class) + +package io.element.android.samples.minimal + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.core.view.WindowCompat +import io.element.android.libraries.designsystem.ElementXTheme +import io.element.android.libraries.matrix.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.auth.RustMatrixAuthenticationService +import io.element.android.libraries.matrix.session.PreferencesSessionStore +import kotlinx.coroutines.runBlocking +import org.matrix.rustcomponents.sdk.AuthenticationService +import java.io.File + +class MainActivity : ComponentActivity() { + + private val matrixAuthenticationService: MatrixAuthenticationService by lazy { + val baseDirectory = File(applicationContext.filesDir, "sessions") + + RustMatrixAuthenticationService( + baseDirectory = baseDirectory, + coroutineScope = Singleton.appScope, + coroutineDispatchers = Singleton.coroutineDispatchers, + sessionStore = PreferencesSessionStore(applicationContext), + authService = AuthenticationService(baseDirectory.absolutePath, null, null), + ) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + WindowCompat.setDecorFitsSystemWindows(window, false) + setContent { + ElementXTheme { + val isLoggedIn by matrixAuthenticationService.isLoggedIn().collectAsState(initial = false) + Content(isLoggedIn = isLoggedIn, modifier = Modifier.fillMaxSize()) + } + + } + } + + @Composable + fun Content( + isLoggedIn: Boolean, + modifier: Modifier = Modifier + ) { + if (!isLoggedIn) { + LoginScreen(authenticationService = matrixAuthenticationService).Content(modifier) + } else { + val matrixClient = runBlocking { + val sessionId = matrixAuthenticationService.getLatestSessionId()!! + matrixAuthenticationService.restoreSession(sessionId) + } + RoomListScreen(matrixClient = matrixClient!!).Content(modifier) + } + } +} diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt new file mode 100644 index 0000000000..5d34d66c4b --- /dev/null +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/RoomListScreen.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.samples.minimal + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import io.element.android.features.roomlist.LastMessageFormatter +import io.element.android.features.roomlist.RoomListPresenter +import io.element.android.features.roomlist.RoomListView +import io.element.android.libraries.matrix.MatrixClient +import io.element.android.libraries.matrix.core.RoomId +import kotlinx.coroutines.launch + +class RoomListScreen(private val matrixClient: MatrixClient) { + + @Composable + fun Content(modifier: Modifier = Modifier) { + fun onRoomClicked(roomId: RoomId) { + val room = matrixClient.getRoom(roomId)!! + val timeline = room.timeline() + Singleton.appScope.launch { + timeline.apply { + initialize() + paginateBackwards(20, 50) + dispose() + } + } + } + + val presenter = remember { + RoomListPresenter(matrixClient, LastMessageFormatter()) + } + val state = presenter.present() + RoomListView( + state = state, + modifier = modifier, + onRoomClicked = ::onRoomClicked, + ) + + DisposableEffect(Unit) { + matrixClient.startSync() + onDispose { + matrixClient.stopSync() + } + } + } +} diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt new file mode 100644 index 0000000000..fb74d2bacb --- /dev/null +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.samples.minimal + +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.matrix.tracing.TracingConfigurations +import io.element.android.libraries.matrix.tracing.setupTracing +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.asCoroutineDispatcher +import kotlinx.coroutines.plus +import timber.log.Timber +import java.util.concurrent.Executors + +object Singleton { + + init { + Timber.plant(Timber.DebugTree()) + setupTracing(TracingConfigurations.debug) + } + + val appScope = MainScope() + CoroutineName("Minimal Scope") + val coroutineDispatchers = CoroutineDispatchers( + io = Dispatchers.IO, + computation = Dispatchers.Default, + main = Dispatchers.Main, + diffUpdateDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher(), + ) +} diff --git a/samples/minimal/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/minimal/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000..c546f8e888 --- /dev/null +++ b/samples/minimal/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + diff --git a/samples/minimal/src/main/res/drawable/ic_launcher_background.xml b/samples/minimal/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000..1c13e421f6 --- /dev/null +++ b/samples/minimal/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/minimal/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/samples/minimal/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..3b15aca222 --- /dev/null +++ b/samples/minimal/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/samples/minimal/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/samples/minimal/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..3b15aca222 --- /dev/null +++ b/samples/minimal/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/samples/minimal/src/main/res/mipmap-hdpi/ic_launcher.webp b/samples/minimal/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000..c209e78ecd Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/samples/minimal/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/samples/minimal/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..b2dfe3d1ba Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/samples/minimal/src/main/res/mipmap-mdpi/ic_launcher.webp b/samples/minimal/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000..4f0f1d64e5 Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/samples/minimal/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/samples/minimal/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..62b611da08 Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/samples/minimal/src/main/res/mipmap-xhdpi/ic_launcher.webp b/samples/minimal/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000000..948a3070fe Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/samples/minimal/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/samples/minimal/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..1b9a6956b3 Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/samples/minimal/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/samples/minimal/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000..28d4b77f9f Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/samples/minimal/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/samples/minimal/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..9287f50836 Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/samples/minimal/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/samples/minimal/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000000..aa7d6427e6 Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/samples/minimal/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/samples/minimal/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..9126ae37cb Binary files /dev/null and b/samples/minimal/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/samples/minimal/src/main/res/values/colors.xml b/samples/minimal/src/main/res/values/colors.xml new file mode 100644 index 0000000000..94c3262e21 --- /dev/null +++ b/samples/minimal/src/main/res/values/colors.xml @@ -0,0 +1,26 @@ + + + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + diff --git a/samples/minimal/src/main/res/values/strings.xml b/samples/minimal/src/main/res/values/strings.xml new file mode 100644 index 0000000000..5b70784037 --- /dev/null +++ b/samples/minimal/src/main/res/values/strings.xml @@ -0,0 +1,19 @@ + + + + EAX-Sample + diff --git a/samples/minimal/src/main/res/values/themes.xml b/samples/minimal/src/main/res/values/themes.xml new file mode 100644 index 0000000000..8b9418d552 --- /dev/null +++ b/samples/minimal/src/main/res/values/themes.xml @@ -0,0 +1,21 @@ + + + + + +