diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml index 4585842153..8299f1c4de 100644 --- a/.idea/dictionaries/bmarty.xml +++ b/.idea/dictionaries/bmarty.xml @@ -37,6 +37,7 @@ threepid unpublish unwedging + vctr \ No newline at end of file diff --git a/CHANGES.md b/CHANGES.md index 1849bde397..4dd4fd0cfd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -44,6 +44,9 @@ Other changes: - Add documentation on LoginWizard and RegistrationWizard (#3303) - Setup towncrier tool (#3293) + Security: + - Element Android shares name of E2EE files with homeserver (#3387) + Changes in Element 1.1.7 (2021-05-12) =================================================== diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b61777d3f..7e1758077b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ To install the template (to be done only once): To create a new screen: - First create a new package in your code. -- Then right click on the package, and select `New/New Vector/RiotX Feature`. +- Then right click on the package, and select `New/New Vector/Element Feature`. - Follow the Wizard, especially replace `Main` by something more relevant to your feature. - Click on `Finish`. - Remaining steps are described as TODO in the generated files, or will be pointed out by the compiler, or at runtime :) diff --git a/attachment-viewer/build.gradle b/attachment-viewer/build.gradle index 0f3817d983..c9814171d9 100644 --- a/attachment-viewer/build.gradle +++ b/attachment-viewer/build.gradle @@ -55,7 +55,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.5.0' implementation 'androidx.appcompat:appcompat:1.3.0' - implementation "androidx.recyclerview:recyclerview:1.2.0" + implementation "androidx.recyclerview:recyclerview:1.2.1" implementation 'com.google.android.material:material:1.3.0' } \ No newline at end of file diff --git a/docs/color_migration_guide.md b/docs/color_migration_guide.md new file mode 100644 index 0000000000..31a531d124 --- /dev/null +++ b/docs/color_migration_guide.md @@ -0,0 +1,85 @@ +# Color migration + +### Changes + +- use colors defined in https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=557%3A0 +- remove unused resources and code (ex: PercentView) +- split some resource files into smaller file +- rework the theme files +- ensure material theme is used everywhere in the theme and in the layout +- add default style for some views in the theme (ex: Toolbar, etc.) +- add some debug screen in the debug menu, to test the themes and the button style +- rework the button style to use `materialThemeOverlay` attribute +- custom tint icon for menu management has been removed +- comment with `riotx` has been updated + +### Main change for developers + +- Read migration guide: https://github.com/vector-im/element-android/pull/3459/files#diff-f0e52729d5e4f6eccbcf72246807aa34ed19c4ef5625ca669df998cd1022874b +- Use MaterialAlertDialogBuilder instead of AlertDialog.Builder +- some Epoxy Item included a divider. This has been removed. Use a `dividerItem` or `bottomSheetDividerItem` Epoxy items to add a divider +- RecyclerView.configureWith now take a divider drawable instead of a divider color + +### Remaining work + +- Cleanup some vector drawables and ensure a tint is always used instead of hard coded color. + +### Migration guide + +Some colors and color attribute has been removed, here is the list and what has to be used now. + +It can help Element Android forks maintainers to migrate their code. + +- riotx_text_primary -> ?vctr_content_primary +- riotx_text_secondary -> ?vctr_content_secondary +- riotx_text_tertiary -> ?vctr_content_tertiary + +- ?riotx_background -> ?android:colorBackground +- riotx_background_light -> element_background_light +- riotx_background_dark -> element_background_dark +- riotx_background_black -> element_background_black + +- riotx_accent -> ?colorPrimary +- riotx_positive_accent -> ?colorPrimary +- riotx_accent_alpha25 -> color_primary_alpha25 +- riotx_notice -> ?colorError +- riotx_destructive_accent -> ?colorError +- vector_error_color -> ?colorError +- vector_warning_color -> ?colorError + +- riotx_bottom_sheet_background -> ?colorSurface +- riotx_alerter_background -> ?colorSurface + +- riotx_username_1 -> element_name_01 +- riotx_username_2 -> element_name_02 +- riotx_username_3 -> element_name_03 +- riotx_username_4 -> element_name_04 +- riotx_username_5 -> element_name_05 +- riotx_username_6 -> element_name_06 +- riotx_username_7 -> element_name_07 +- riotx_username_8 -> element_name_08 + +- riotx_avatar_fill_1 -> element_room_01 +- riotx_avatar_fill_2 -> element_room_02 +- riotx_avatar_fill_3 -> element_room_03 + +- white -> @android:color/white +- black -> @android:color/black or emoji_color + +- riotx_list_header_background_color -> ?vctr_header_background +- riotx_header_panel_background -> ?vctr_header_background +- riotx_list_bottom_sheet_divider_color -> ?vctr_list_separator_on_surface +- riotx_list_divider_color -> ?vctr_list_separator +- list_divider_color -> ?vctr_list_separator +- riotx_header_panel_border_mobile -> ?vctr_list_separator +- riotx_bottom_nav_background_border_color -> ?vctr_list_separator +- riotx_header_panel_text_secondary -> ?vctr_content_primary + +- link_color_light -> element_link_light +- link_color_dark -> element_link_dark + +- riotx_toolbar_primary_text_color -> vctr_content_primary +- riotx_toolbar_secondary_text_color -> vctr_content_primary +- riot_primary_text_color -> vctr_content_primary + +- riotx_android_secondary -> vctr_content_secondary diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index 1b7a5243e2..e3f00a24b6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -42,7 +42,6 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody -import kotlin.jvm.Throws interface CryptoService { @@ -82,9 +81,11 @@ interface CryptoService { fun getDeviceTrackingStatus(userId: String): Int - fun importRoomKeys(roomKeysAsArray: ByteArray, password: String, progressListener: ProgressListener?, callback: MatrixCallback) + suspend fun importRoomKeys(roomKeysAsArray: ByteArray, + password: String, + progressListener: ProgressListener?): ImportRoomKeysResult - fun exportRoomKeys(password: String, callback: MatrixCallback) + suspend fun exportRoomKeys(password: String): ByteArray fun setRoomBlacklistUnverifiedDevices(roomId: String) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt index 8f8967e8fb..ae546b6cec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt @@ -35,7 +35,7 @@ interface IdentityService { /** * Check if the identity server is valid * See https://matrix.org/docs/spec/identity_service/latest#status-check - * RiotX SDK only supports identity server API v2 + * Matrix Android SDK2 only supports identity server API v2 */ suspend fun isValidIdentityServer(url: String) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 7f5cfe8df1..d170ae3dd3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -388,7 +388,7 @@ internal class DefaultCryptoService @Inject constructor( cryptoStore.close() } - // Aways enabled on RiotX + // Always enabled on Matrix Android SDK2 override fun isCryptoEnabled() = true /** @@ -928,14 +928,10 @@ internal class DefaultCryptoService @Inject constructor( * Export the crypto keys * * @param password the password - * @param callback the exported keys + * @return the exported keys */ - override fun exportRoomKeys(password: String, callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT) - }.foldToCallback(callback) - } + override suspend fun exportRoomKeys(password: String): ByteArray { + return exportRoomKeys(password, MXMegolmExportEncryption.DEFAULT_ITERATION_COUNT) } /** @@ -963,42 +959,37 @@ internal class DefaultCryptoService @Inject constructor( * @param roomKeysAsArray the room keys as array. * @param password the password * @param progressListener the progress listener - * @param callback the asynchronous callback. + * @return the result ImportRoomKeysResult */ - override fun importRoomKeys(roomKeysAsArray: ByteArray, - password: String, - progressListener: ProgressListener?, - callback: MatrixCallback) { - cryptoCoroutineScope.launch(coroutineDispatchers.main) { - runCatching { - withContext(coroutineDispatchers.crypto) { - Timber.v("## CRYPTO | importRoomKeys starts") + override suspend fun importRoomKeys(roomKeysAsArray: ByteArray, + password: String, + progressListener: ProgressListener?): ImportRoomKeysResult { + return withContext(coroutineDispatchers.crypto) { + Timber.v("## CRYPTO | importRoomKeys starts") - val t0 = System.currentTimeMillis() - val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password) - val t1 = System.currentTimeMillis() + val t0 = System.currentTimeMillis() + val roomKeys = MXMegolmExportEncryption.decryptMegolmKeyFile(roomKeysAsArray, password) + val t1 = System.currentTimeMillis() - Timber.v("## CRYPTO | importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms") + Timber.v("## CRYPTO | importRoomKeys : decryptMegolmKeyFile done in ${t1 - t0} ms") - val importedSessions = MoshiProvider.providesMoshi() - .adapter>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java)) - .fromJson(roomKeys) + val importedSessions = MoshiProvider.providesMoshi() + .adapter>(Types.newParameterizedType(List::class.java, MegolmSessionData::class.java)) + .fromJson(roomKeys) - val t2 = System.currentTimeMillis() + val t2 = System.currentTimeMillis() - Timber.v("## CRYPTO | importRoomKeys : JSON parsing ${t2 - t1} ms") + Timber.v("## CRYPTO | importRoomKeys : JSON parsing ${t2 - t1} ms") - if (importedSessions == null) { - throw Exception("Error") - } + if (importedSessions == null) { + throw Exception("Error") + } - megolmSessionDataImporter.handle( - megolmSessionsData = importedSessions, - fromBackup = false, - progressListener = progressListener - ) - } - }.foldToCallback(callback) + megolmSessionDataImporter.handle( + megolmSessionsData = importedSessions, + fromBackup = false, + progressListener = progressListener + ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index a29ac457fb..70d2022299 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -155,7 +155,7 @@ internal class MXMegolmDecryption(private val userId: String, withHeldInfo.code?.value ?: "", withHeldInfo.reason) } else { - // This is un-used in riotX SDK, not sure if needed + // This is un-used in Matrix Android SDK2, not sure if needed // addEventToPendingList(event, timeline) if (requestKeysOnFail) { requestKeysForEvent(event, false) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt index e0e2f96fa9..4586cfea1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt @@ -153,7 +153,7 @@ internal class DefaultLegacySessionImporter @Inject constructor( } private fun importCryptoDb(legacyConfig: LegacyHomeServerConnectionConfig) { - // Here we migrate the DB, we copy the crypto DB to the location specific to RiotX, and we encrypt it. + // Here we migrate the DB, we copy the crypto DB to the location specific to Matrix SDK2, and we encrypt it. val userMd5 = legacyConfig.credentials.userId.md5() val sessionId = legacyConfig.credentials.let { (if (it.deviceId.isNullOrBlank()) it.userId else "${it.userId}|${it.deviceId}").md5() } @@ -177,12 +177,12 @@ internal class DefaultLegacySessionImporter @Inject constructor( Timber.d("Migration: copy DB to encrypted DB") Realm.getInstance(realmConfiguration).use { - // Move the DB to the new location, handled by RiotX + // Move the DB to the new location, handled by Matrix SDK2 it.writeEncryptedCopyTo(File(newLocation, realmConfiguration.realmFileName), realmKeysUtils.getRealmEncryptionKey(keyAlias)) } } - // Delete all the files created by Riot Android which will not be used anymore by RiotX + // Delete all the files created by Riot Android which will not be used anymore by Element private fun clearFileSystem(legacyConfig: LegacyHomeServerConnectionConfig) { val cryptoFolder = legacyConfig.credentials.userId.md5() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt index 973c120f59..1a88404128 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UserAgentHolder.kt @@ -36,7 +36,7 @@ internal class UserAgentHolder @Inject constructor(private val context: Context, /** * Create an user agent with the application version. - * Ex: RiotX/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSDK_X 1.0) + * Ex: Element/1.0.0 (Linux; U; Android 6.0.1; SM-A510F Build/MMB29; Flavour GPlay; MatrixAndroidSDK_X 1.0) * * @param flavorDescription the flavor description */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index e230599f8f..8cc5d943b7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -24,7 +24,6 @@ import io.realm.RealmQuery import io.realm.RealmResults import io.realm.Sort import org.matrix.android.sdk.api.MatrixCallback -import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.EventType @@ -168,9 +167,7 @@ internal class DefaultTimeline( timelineEvents.addChangeListener(eventsChangeListener) handleInitialLoad() loadRoomMembersTask - .configureWith(LoadRoomMembersTask.Params(roomId)) { - this.callback = NoOpMatrixCallback() - } + .configureWith(LoadRoomMembersTask.Params(roomId)) .executeBy(taskExecutor) // Ensure ReadReceipt from init sync are loaded diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/DefaultTypingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/DefaultTypingService.kt index 39b7967bc1..b76829e893 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/DefaultTypingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/DefaultTypingService.kt @@ -18,13 +18,13 @@ package org.matrix.android.sdk.internal.session.room.typing import android.os.SystemClock import dagger.assisted.Assisted -import dagger.assisted.AssistedInject import dagger.assisted.AssistedFactory -import org.matrix.android.sdk.api.MatrixCallback +import dagger.assisted.AssistedInject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.room.typing.TypingService -import org.matrix.android.sdk.api.util.Cancelable -import org.matrix.android.sdk.internal.task.TaskExecutor -import org.matrix.android.sdk.internal.task.configureWith import timber.log.Timber /** @@ -35,7 +35,6 @@ import timber.log.Timber */ internal class DefaultTypingService @AssistedInject constructor( @Assisted private val roomId: String, - private val taskExecutor: TaskExecutor, private val sendTypingTask: SendTypingTask ) : TypingService { @@ -44,8 +43,8 @@ internal class DefaultTypingService @AssistedInject constructor( fun create(roomId: String): DefaultTypingService } - private var currentTask: Cancelable? = null - private var currentAutoStopTask: Cancelable? = null + private val coroutineScope = CoroutineScope(Job()) + private var currentTask: Job? = null // What the homeserver knows private var userIsTyping = false @@ -53,26 +52,24 @@ internal class DefaultTypingService @AssistedInject constructor( // Last time the user is typing event has been sent private var lastRequestTimestamp: Long = 0 + /** + * Notify to the server that the user is typing and schedule the auto typing off + */ override fun userIsTyping() { - scheduleAutoStop() - val now = SystemClock.elapsedRealtime() - - if (userIsTyping && now < lastRequestTimestamp + MIN_DELAY_BETWEEN_TWO_USER_IS_TYPING_REQUESTS_MILLIS) { - Timber.d("Typing: Skip start request") - return - } - - Timber.d("Typing: Send start request") - userIsTyping = true - lastRequestTimestamp = now - currentTask?.cancel() - - val params = SendTypingTask.Params(roomId, true) - currentTask = sendTypingTask - .configureWith(params) - .executeBy(taskExecutor) + currentTask = coroutineScope.launch { + if (userIsTyping && now < lastRequestTimestamp + MIN_DELAY_BETWEEN_TWO_USER_IS_TYPING_REQUESTS_MILLIS) { + Timber.d("Typing: Skip start request") + } else { + Timber.d("Typing: Send start request") + lastRequestTimestamp = now + sendRequest(true) + } + delay(MIN_DELAY_TO_SEND_STOP_TYPING_REQUEST_WHEN_NO_USER_ACTIVITY_MILLIS) + Timber.d("Typing: auto stop") + sendRequest(false) + } } override fun userStopsTyping() { @@ -82,35 +79,22 @@ internal class DefaultTypingService @AssistedInject constructor( } Timber.d("Typing: Send stop request") - userIsTyping = false lastRequestTimestamp = 0 - currentAutoStopTask?.cancel() currentTask?.cancel() - - val params = SendTypingTask.Params(roomId, false) - currentTask = sendTypingTask - .configureWith(params) - .executeBy(taskExecutor) + currentTask = coroutineScope.launch { + sendRequest(false) + } } - private fun scheduleAutoStop() { - Timber.d("Typing: Schedule auto stop") - currentAutoStopTask?.cancel() - - val params = SendTypingTask.Params( - roomId, - false, - delay = MIN_DELAY_TO_SEND_STOP_TYPING_REQUEST_WHEN_NO_USER_ACTIVITY_MILLIS) - currentAutoStopTask = sendTypingTask - .configureWith(params) { - callback = object : MatrixCallback { - override fun onSuccess(data: Unit) { - userIsTyping = false - } - } - } - .executeBy(taskExecutor) + private suspend fun sendRequest(isTyping: Boolean) { + try { + sendTypingTask.execute(SendTypingTask.Params(roomId, isTyping)) + userIsTyping = isTyping + } catch (failure: Throwable) { + // Ignore network error, etc... + Timber.w(failure, "Unable to send typing request") + } } companion object { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt index 0b0df74311..0bdceb9ade 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/SendTypingTask.kt @@ -17,11 +17,10 @@ package org.matrix.android.sdk.internal.session.room.typing import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.task.Task -import kotlinx.coroutines.delay -import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import javax.inject.Inject internal interface SendTypingTask : Task { @@ -29,9 +28,7 @@ internal interface SendTypingTask : Task { data class Params( val roomId: String, val isTyping: Boolean, - val typingTimeoutMillis: Int? = 30_000, - // Optional delay before sending the request to the homeserver - val delay: Long? = null + val typingTimeoutMillis: Int? = 30_000 ) } @@ -42,8 +39,6 @@ internal class DefaultSendTypingTask @Inject constructor( ) : SendTypingTask { override suspend fun execute(params: SendTypingTask.Params) { - delay(params.delay ?: -1) - executeRequest(globalErrorReceiver) { roomAPI.sendTypingState( params.roomId, diff --git a/newsfragment/2449.feature b/newsfragment/2449.feature new file mode 100644 index 0000000000..7fca1730b6 --- /dev/null +++ b/newsfragment/2449.feature @@ -0,0 +1 @@ +Migrate DefaultTypingService, KeysImporter and KeysExporter to coroutines \ No newline at end of file diff --git a/newsfragment/3182.feature b/newsfragment/3182.feature new file mode 100644 index 0000000000..83eee3c29c --- /dev/null +++ b/newsfragment/3182.feature @@ -0,0 +1 @@ +Update Message Composer design \ No newline at end of file diff --git a/newsfragment/3459.feature b/newsfragment/3459.feature new file mode 100644 index 0000000000..eedec1dfda --- /dev/null +++ b/newsfragment/3459.feature @@ -0,0 +1,2 @@ +Migrate to new colors and cleanup the style and theme +Ref: https://material.io/blog/migrate-android-material-components \ No newline at end of file diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 9770ed0d4d..e0645e00b3 100644 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -136,8 +136,9 @@ android\.R\.id\.home===2 ### Kotlin conversion tools introduce this, but is can be replace by trim() trim \{ it \<\= \' \' \} -### Use AlertDialog form v7 compat lib +### Use MaterialAlertDialogBuilder android\.app\.AlertDialog +androidx\.appcompat\.app\.AlertDialog===4 ### Put the operator at the beginning of next line &&$ diff --git a/tools/check/forbidden_strings_in_resources.txt b/tools/check/forbidden_strings_in_resources.txt index cefeeb6351..92eec6cdfd 100644 --- a/tools/check/forbidden_strings_in_resources.txt +++ b/tools/check/forbidden_strings_in_resources.txt @@ -84,3 +84,22 @@ layout_constraintLeft_ ### Use androidx.recyclerview.widget.RecyclerView because EpoxyRecyclerViews add behavior we do not want to + + + + + diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugBottomSheet.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugBottomSheet.kt new file mode 100644 index 0000000000..0ac9a894ae --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugBottomSheet.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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 im.vector.app.features.debug + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import im.vector.app.databinding.ActivityTestMaterialThemeBinding + +class DebugBottomSheet : BottomSheetDialogFragment() { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + // Reuse tha Activity layout + val binding = ActivityTestMaterialThemeBinding.inflate(inflater, container, false) + return binding.root + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt index 8df1feab1e..de6b981c02 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt @@ -18,9 +18,8 @@ package im.vector.app.features.debug import android.os.Bundle import android.view.Menu -import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import im.vector.app.R import im.vector.app.core.utils.toast @@ -45,7 +44,8 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() { } views.debugShowDialog.setOnClickListener { - AlertDialog.Builder(this) + MaterialAlertDialogBuilder(this) + .setTitle("Dialog title") .setMessage("Dialog content") .setIcon(R.drawable.ic_settings_x) .setPositiveButton("Positive", null) @@ -55,7 +55,7 @@ abstract class DebugMaterialThemeActivity : AppCompatActivity() { } views.debugShowBottomSheet.setOnClickListener { - BottomSheetDialogFragment().show(supportFragmentManager, "TAG") + DebugBottomSheet().show(supportFragmentManager, "TAG") } } diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkDefaultActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkDefaultActivity.kt new file mode 100644 index 0000000000..7e014577de --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkDefaultActivity.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2019 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 im.vector.app.features.debug + +class DebugMaterialThemeDarkDefaultActivity : DebugMaterialThemeActivity() diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkTestActivity.kt similarity index 89% rename from vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkActivity.kt rename to vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkTestActivity.kt index e6e1bf04ee..4a1ed04f6a 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkTestActivity.kt @@ -16,4 +16,4 @@ package im.vector.app.features.debug -class DebugMaterialThemeDarkActivity : DebugMaterialThemeActivity() +class DebugMaterialThemeDarkTestActivity : DebugMaterialThemeActivity() diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkVectorActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkVectorActivity.kt new file mode 100644 index 0000000000..6ac27aed45 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeDarkVectorActivity.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2019 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 im.vector.app.features.debug + +class DebugMaterialThemeDarkVectorActivity : DebugMaterialThemeActivity() diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightDefaultActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightDefaultActivity.kt new file mode 100644 index 0000000000..f6327e363b --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightDefaultActivity.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2019 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 im.vector.app.features.debug + +class DebugMaterialThemeLightDefaultActivity : DebugMaterialThemeActivity() diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightTestActivity.kt similarity index 89% rename from vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightActivity.kt rename to vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightTestActivity.kt index d1d3061cad..ae6c1dd68c 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightTestActivity.kt @@ -16,4 +16,4 @@ package im.vector.app.features.debug -class DebugMaterialThemeLightActivity : DebugMaterialThemeActivity() +class DebugMaterialThemeLightTestActivity : DebugMaterialThemeActivity() diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightVectorActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightVectorActivity.kt new file mode 100644 index 0000000000..b4fb3c1cc8 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeLightVectorActivity.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2019 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 im.vector.app.features.debug + +class DebugMaterialThemeLightVectorActivity : DebugMaterialThemeActivity() diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 8699b238ec..65a24c9aeb 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -71,10 +71,29 @@ class DebugMenuActivity : VectorBaseActivity() { private fun setupViews() { views.debugTestTextViewLink.setOnClickListener { testTextViewLink() } + views.debugOpenButtonStyles.setOnClickListener { + startActivity(Intent(this, DebugVectorButtonStylesActivity::class.java)) + } views.debugShowSasEmoji.setOnClickListener { showSasEmoji() } views.debugTestNotification.setOnClickListener { testNotification() } - views.debugTestMaterialThemeLight.setOnClickListener { testMaterialThemeLight() } - views.debugTestMaterialThemeDark.setOnClickListener { testMaterialThemeDark() } + views.debugTestMaterialThemeLightDefault.setOnClickListener { + startActivity(Intent(this, DebugMaterialThemeLightDefaultActivity::class.java)) + } + views.debugTestMaterialThemeLightTest.setOnClickListener { + startActivity(Intent(this, DebugMaterialThemeLightTestActivity::class.java)) + } + views.debugTestMaterialThemeLightVector.setOnClickListener { + startActivity(Intent(this, DebugMaterialThemeLightVectorActivity::class.java)) + } + views.debugTestMaterialThemeDarkDefault.setOnClickListener { + startActivity(Intent(this, DebugMaterialThemeDarkDefaultActivity::class.java)) + } + views.debugTestMaterialThemeDarkTest.setOnClickListener { + startActivity(Intent(this, DebugMaterialThemeDarkTestActivity::class.java)) + } + views.debugTestMaterialThemeDarkVector.setOnClickListener { + startActivity(Intent(this, DebugMaterialThemeDarkVectorActivity::class.java)) + } views.debugTestCrash.setOnClickListener { testCrash() } views.debugScanQrCode.setOnClickListener { scanQRCode() } } @@ -174,14 +193,6 @@ class DebugMenuActivity : VectorBaseActivity() { ) } - private fun testMaterialThemeLight() { - startActivity(Intent(this, DebugMaterialThemeLightActivity::class.java)) - } - - private fun testMaterialThemeDark() { - startActivity(Intent(this, DebugMaterialThemeDarkActivity::class.java)) - } - private fun testCrash() { throw RuntimeException("Application crashed from user demand") } diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugVectorButtonStylesActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugVectorButtonStylesActivity.kt new file mode 100644 index 0000000000..783a2a3eb5 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugVectorButtonStylesActivity.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2021 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 im.vector.app.features.debug + +import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityDebugButtonStylesBinding + +class DebugVectorButtonStylesActivity : VectorBaseActivity() { + override fun getBinding() = ActivityDebugButtonStylesBinding.inflate(layoutInflater) +} diff --git a/vector/src/debug/res/layout/activity_debug_button_styles.xml b/vector/src/debug/res/layout/activity_debug_button_styles.xml new file mode 100644 index 0000000000..3973f7cbb6 --- /dev/null +++ b/vector/src/debug/res/layout/activity_debug_button_styles.xml @@ -0,0 +1,131 @@ + + + + + +