From fa32770e9661d0383ff6e18344e32ade6ccb22bf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 20 Oct 2020 09:25:51 +0200 Subject: [PATCH 01/18] Add --ignoreErrors argument to be able to bypass some errors --- tools/release/download_buildkite_artifacts.py | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tools/release/download_buildkite_artifacts.py b/tools/release/download_buildkite_artifacts.py index 4439c2fb8c..067a1a4dfe 100755 --- a/tools/release/download_buildkite_artifacts.py +++ b/tools/release/download_buildkite_artifacts.py @@ -45,6 +45,10 @@ parser.add_argument('-e', '--expecting', type=int, help='the expected number of artifacts. If omitted, no check will be done.') +parser.add_argument('-i', + '--ignoreErrors', + help='Ignore errors that can be ignored. Build state and number of artifacts.', + action="store_true") parser.add_argument('-d', '--directory', default="", @@ -91,9 +95,14 @@ print(" git commit : \"%s\"" % data0.get('commit')) print(" git commit message : \"%s\"" % data0.get('message')) print(" build state : %s" % data0.get('state')) +error = False + if data0.get('state') != 'passed': print("❌ Error, the build is in state '%s', and not 'passed'" % data0.get('state')) - exit(1) + if args.ignoreErrors: + error = True + else: + exit(1) ### Fetch artifacts list @@ -110,8 +119,11 @@ data = json.loads(r.content.decode()) print(" %d artifact(s) found." % len(data)) if args.expecting is not None and args.expecting != len(data): - print("Error, expecting %d artifacts and found %d." % (args.expecting, len(data))) - exit(1) + print("❌ Error, expecting %d artifacts and found %d." % (args.expecting, len(data))) + if args.ignoreErrors: + error = True + else: + exit(1) if args.verbose: print("Json data:") @@ -128,8 +140,6 @@ else: if not args.simulate: os.mkdir(targetDir) -error = False - for elt in data: if args.verbose: print() @@ -157,7 +167,7 @@ for elt in data: print("❌ Checksum mismatch: expecting %s and get %s" % (elt.get("sha1sum"), hash)) if error: - print("❌ Error(s) occurred, check the log") + print("❌ Error(s) occurred, please check the log") exit(1) else: print("Done!") From 0667c0ce49b636c03f408e4fa1d1a837a70f4847 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 20 Oct 2020 10:01:24 +0200 Subject: [PATCH 02/18] Never show the green gear in production --- .../java/im/vector/app/features/home/HomeDrawerFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt index 12689cd983..e267248fc3 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt @@ -19,6 +19,7 @@ package im.vector.app.features.home import android.os.Bundle import android.view.View import androidx.core.view.isVisible +import im.vector.app.BuildConfig import im.vector.app.R import im.vector.app.core.extensions.observeK import im.vector.app.core.extensions.replaceChildFragment @@ -75,7 +76,7 @@ class HomeDrawerFragment @Inject constructor( } // Debug menu - homeDrawerHeaderDebugView.isVisible = vectorPreferences.developerMode() + homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode() homeDrawerHeaderDebugView.debouncedClicks { sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) navigator.openDebug(requireActivity()) From 99e8f9c6cd86497948d8b3d6b1c4f03e9169bac8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 20 Oct 2020 10:40:44 +0200 Subject: [PATCH 03/18] Room creation: add topic (#2078) --- .../createroom/CreateRoomAction.kt | 1 + .../createroom/CreateRoomController.kt | 24 +++++++++++++++++++ .../createroom/CreateRoomFragment.kt | 8 ++++++- .../createroom/CreateRoomViewModel.kt | 7 +++++- .../createroom/CreateRoomViewState.kt | 1 + vector/src/main/res/values/strings.xml | 6 ++++- 6 files changed, 44 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomAction.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomAction.kt index 3b687395fd..22a963b525 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomAction.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomAction.kt @@ -20,6 +20,7 @@ import im.vector.app.core.platform.VectorViewModelAction sealed class CreateRoomAction : VectorViewModelAction { data class SetName(val name: String) : CreateRoomAction() + data class SetTopic(val topic: String) : CreateRoomAction() data class SetIsPublic(val isPublic: Boolean) : CreateRoomAction() data class SetIsInRoomDirectory(val isInRoomDirectory: Boolean) : CreateRoomAction() data class SetIsEncrypted(val isEncrypted: Boolean) : CreateRoomAction() diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt index ba7c5ca083..9585932da2 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt @@ -26,6 +26,7 @@ import im.vector.app.core.epoxy.errorWithRetryItem import im.vector.app.core.epoxy.loadingItem import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.resources.StringProvider +import im.vector.app.features.discovery.settingsSectionTitleItem import im.vector.app.features.form.formEditTextItem import im.vector.app.features.form.formSwitchItem import javax.inject.Inject @@ -67,6 +68,10 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin } private fun buildForm(viewState: CreateRoomViewState, enableFormElement: Boolean) { + settingsSectionTitleItem { + id("nameSection") + titleResId(R.string.create_room_name_section) + } formEditTextItem { id("name") enabled(enableFormElement) @@ -77,6 +82,24 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin listener?.onNameChange(text) } } + settingsSectionTitleItem { + id("topicSection") + titleResId(R.string.create_room_topic_section) + } + formEditTextItem { + id("topic") + enabled(enableFormElement) + value(viewState.roomTopic) + hint(stringProvider.getString(R.string.create_room_topic_hint)) + + onTextChange { text -> + listener?.onTopicChange(text) + } + } + settingsSectionTitleItem { + id("settingsSection") + titleResId(R.string.create_room_settings_section) + } formSwitchItem { id("public") enabled(enableFormElement) @@ -120,6 +143,7 @@ class CreateRoomController @Inject constructor(private val stringProvider: Strin interface Listener { fun onNameChange(newName: String) + fun onTopicChange(newTopic: String) fun setIsPublic(isPublic: Boolean) fun setIsInRoomDirectory(isInRoomDirectory: Boolean) fun setIsEncrypted(isEncrypted: Boolean) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt index f3be178e64..ff20ceae6b 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -32,7 +32,9 @@ import kotlinx.android.synthetic.main.fragment_create_room.* import timber.log.Timber import javax.inject.Inject -class CreateRoomFragment @Inject constructor(private val createRoomController: CreateRoomController) : VectorBaseFragment(), CreateRoomController.Listener { +class CreateRoomFragment @Inject constructor( + private val createRoomController: CreateRoomController +) : VectorBaseFragment(), CreateRoomController.Listener { private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel private val viewModel: CreateRoomViewModel by activityViewModel() @@ -77,6 +79,10 @@ class CreateRoomFragment @Inject constructor(private val createRoomController: C viewModel.handle(CreateRoomAction.SetName(newName)) } + override fun onTopicChange(newTopic: String) { + viewModel.handle(CreateRoomAction.SetTopic(newTopic)) + } + override fun setIsPublic(isPublic: Boolean) { viewModel.handle(CreateRoomAction.SetIsPublic(isPublic)) } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt index c213992258..d160f46472 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewModel.kt @@ -26,6 +26,7 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject +import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import im.vector.app.features.raw.wellknown.getElementWellknown @@ -91,15 +92,18 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr override fun handle(action: CreateRoomAction) { when (action) { is CreateRoomAction.SetName -> setName(action) + is CreateRoomAction.SetTopic -> setTopic(action) is CreateRoomAction.SetIsPublic -> setIsPublic(action) is CreateRoomAction.SetIsInRoomDirectory -> setIsInRoomDirectory(action) is CreateRoomAction.SetIsEncrypted -> setIsEncrypted(action) is CreateRoomAction.Create -> doCreateRoom() - } + }.exhaustive } private fun setName(action: CreateRoomAction.SetName) = setState { copy(roomName = action.name) } + private fun setTopic(action: CreateRoomAction.SetTopic) = setState { copy(roomTopic = action.topic) } + private fun setIsPublic(action: CreateRoomAction.SetIsPublic) = setState { copy( isPublic = action.isPublic, @@ -123,6 +127,7 @@ class CreateRoomViewModel @AssistedInject constructor(@Assisted initialState: Cr val createRoomParams = CreateRoomParams() .apply { name = state.roomName.takeIf { it.isNotBlank() } + topic = state.roomTopic.takeIf { it.isNotBlank() } // Directory visibility visibility = if (state.isInRoomDirectory) RoomDirectoryVisibility.PUBLIC else RoomDirectoryVisibility.PRIVATE // Public room diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt index a49473b16e..3398a37361 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomViewState.kt @@ -22,6 +22,7 @@ import com.airbnb.mvrx.Uninitialized data class CreateRoomViewState( val roomName: String = "", + val roomTopic: String = "", val isPublic: Boolean = false, val isInRoomDirectory: Boolean = false, val isEncrypted: Boolean = false, diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index ec916d1daf..349698cb31 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -1675,7 +1675,11 @@ "New Room" "CREATE" - "Room name" + "Room name" + "Name" + "Room topic (optional)" + "Topic" + "Room settings" "Public" "Anyone will be able to join this room" "Room Directory" From aaa772c74981a4878ce1e930c2caf655a255a2ee Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 20 Oct 2020 11:00:15 +0200 Subject: [PATCH 04/18] Android style to validate form --- .../app/features/form/FormSubmitButtonItem.kt | 60 +++++++++++++++++++ .../createroom/CreateRoomController.kt | 8 +++ .../createroom/CreateRoomFragment.kt | 17 ++---- .../res/layout/item_form_submit_button.xml | 18 ++++++ 4 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/form/FormSubmitButtonItem.kt create mode 100644 vector/src/main/res/layout/item_form_submit_button.xml diff --git a/vector/src/main/java/im/vector/app/features/form/FormSubmitButtonItem.kt b/vector/src/main/java/im/vector/app/features/form/FormSubmitButtonItem.kt new file mode 100644 index 0000000000..2d2a5e7aec --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/form/FormSubmitButtonItem.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 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.form + +import android.widget.Button +import androidx.annotation.StringRes +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.airbnb.epoxy.EpoxyModelWithHolder +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.setTextOrHide + +@EpoxyModelClass(layout = R.layout.item_form_submit_button) +abstract class FormSubmitButtonItem : EpoxyModelWithHolder() { + + @EpoxyAttribute + var enabled: Boolean = true + + @EpoxyAttribute + var buttonTitle: String? = null + + @EpoxyAttribute + @StringRes + var buttonTitleId: Int? = null + + @EpoxyAttribute + var buttonClickListener: ClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + if (buttonTitleId != null) { + holder.button.setText(buttonTitleId!!) + } else { + holder.button.setTextOrHide(buttonTitle) + } + + holder.button.isEnabled = enabled + holder.button.onClick(buttonClickListener) + } + + class Holder : VectorEpoxyHolder() { + val button by bind