From e5da026f1f20aed42cd291ee08a82668f514e7a3 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 10 Feb 2021 10:05:41 +0100 Subject: [PATCH 01/29] Dev tools initial commit --- CHANGES.md | 2 +- .../room/model/RoomThirdPartyInviteContent.kt | 8 +- .../room/send/queue/EventSenderProcessor.kt | 1 + .../room/state/StateEventDataSource.kt | 6 +- vector/src/main/AndroidManifest.xml | 1 + .../im/vector/app/core/di/FragmentModule.kt | 24 ++ .../im/vector/app/core/di/ScreenComponent.kt | 2 + .../im/vector/app/core/ui/list/GenericItem.kt | 2 +- .../features/devtools/DevToolsViewEvents.kt | 27 ++ .../features/devtools/RoomDevToolAction.kt | 34 ++ .../features/devtools/RoomDevToolActivity.kt | 247 +++++++++++++++ .../devtools/RoomDevToolEditFragment.kt | 72 +++++ .../features/devtools/RoomDevToolFragment.kt | 72 +++++ .../devtools/RoomDevToolRootController.kt | 60 ++++ .../devtools/RoomDevToolSendFormController.kt | 76 +++++ .../devtools/RoomDevToolSendFormFragment.kt | 62 ++++ .../RoomDevToolStateEventListFragment.kt | 62 ++++ .../features/devtools/RoomDevToolViewModel.kt | 293 ++++++++++++++++++ .../features/devtools/RoomDevToolViewState.kt | 52 ++++ .../devtools/RoomStateListController.kt | 113 +++++++ .../form/FormMultiLineEditTextItem.kt | 101 ++++++ .../home/room/detail/RoomDetailFragment.kt | 5 + .../home/room/detail/RoomDetailViewModel.kt | 1 + .../members/RoomMemberListController.kt | 3 +- .../res/layout/fragment_devtools_editor.xml | 16 + .../layout/item_form_multiline_text_input.xml | 45 +++ .../src/main/res/layout/item_generic_list.xml | 1 + vector/src/main/res/menu/menu_devtools.xml | 22 ++ vector/src/main/res/menu/menu_timeline.xml | 8 + vector/src/main/res/values/strings.xml | 1 + 30 files changed, 1411 insertions(+), 8 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolAction.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewState.kt create mode 100644 vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt create mode 100644 vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt create mode 100644 vector/src/main/res/layout/fragment_devtools_editor.xml create mode 100644 vector/src/main/res/layout/item_form_multiline_text_input.xml create mode 100644 vector/src/main/res/menu/menu_devtools.xml diff --git a/CHANGES.md b/CHANGES.md index df4728c634..c1d7998e78 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,7 +23,7 @@ Test: - Other changes: - - + - New Dev Tools panel for developers Changes in Element 1.0.17 (2020-02-09) =================================================== diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt index 776acbd8ea..56503e3e35 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomThirdPartyInviteContent.kt @@ -30,24 +30,24 @@ data class RoomThirdPartyInviteContent( * This should not contain the user's third party ID, as otherwise when the invite * is accepted it would leak the association between the matrix ID and the third party ID. */ - @Json(name = "display_name") val displayName: String, + @Json(name = "display_name") val displayName: String?, /** * Required. A URL which can be fetched, with querystring public_key=public_key, to validate * whether the key has been revoked. The URL must return a JSON object containing a boolean property named 'valid'. */ - @Json(name = "key_validity_url") val keyValidityUrl: String, + @Json(name = "key_validity_url") val keyValidityUrl: String?, /** * Required. A base64-encoded ed25519 key with which token must be signed (though a signature from any entry in * public_keys is also sufficient). This exists for backwards compatibility. */ - @Json(name = "public_key") val publicKey: String, + @Json(name = "public_key") val publicKey: String?, /** * Keys with which the token may be signed. */ - @Json(name = "public_keys") val publicKeys: List = emptyList() + @Json(name = "public_keys") val publicKeys: List? = emptyList() ) @JsonClass(generateAdapter = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt index 5014d94558..62338a1d07 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/EventSenderProcessor.kt @@ -196,6 +196,7 @@ internal class EventSenderProcessor @Inject constructor( else -> { Timber.v("## SendThread retryLoop Un-Retryable error, try next task") // this task is in error, check next one? + task.onTaskFailed() break@retryLoop } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt index d0f6f8050e..a25a362bfa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt @@ -80,7 +80,11 @@ internal class StateEventDataSource @Inject constructor(@SessionDatabase private ): RealmQuery { return realm.where() .equalTo(CurrentStateEventEntityFields.ROOM_ID, roomId) - .`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray()) + .apply { + if (eventTypes.isNotEmpty()) { + `in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray()) + } + } .process(CurrentStateEventEntityFields.STATE_KEY, stateKey) } } diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index bfaea39cc6..6f2ff4e8ca 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -262,6 +262,7 @@ + () { } @EpoxyAttribute - var title: String? = null + var title: CharSequence? = null @EpoxyAttribute var description: CharSequence? = null diff --git a/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt b/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt new file mode 100644 index 0000000000..615144aaf6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt @@ -0,0 +1,27 @@ +/* + * 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.devtools + +import im.vector.app.core.platform.VectorViewEvents + +sealed class DevToolsViewEvents : VectorViewEvents { + object Dismiss : DevToolsViewEvents() + + // object ShowStateList : DevToolsViewEvents() + data class showAlertMessage(val message: String) : DevToolsViewEvents() + data class showSnackMessage(val message: String) : DevToolsViewEvents() +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolAction.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolAction.kt new file mode 100644 index 0000000000..c6246bbe08 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolAction.kt @@ -0,0 +1,34 @@ +/* + * 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.devtools + +import im.vector.app.core.platform.VectorViewModelAction +import org.matrix.android.sdk.api.session.events.model.Event + +sealed class RoomDevToolAction : VectorViewModelAction { + object ExploreRoomState : RoomDevToolAction() + object OnBackPressed : RoomDevToolAction() + object MenuEdit : RoomDevToolAction() + object MenuItemSend : RoomDevToolAction() + data class ShowStateEvent(val event: Event) : RoomDevToolAction() + data class ShowStateEventType(val stateEventType: String) : RoomDevToolAction() + data class UpdateContentText(val contentJson: String) : RoomDevToolAction() + data class SendCustomEvent(val isStateEvent: Boolean) : RoomDevToolAction() + data class CustomEventTypeChange(val type: String) : RoomDevToolAction() + data class CustomEventContentChange(val content: String) : RoomDevToolAction() + data class CustomEventStateKeyChange(val stateKey: String) : RoomDevToolAction() +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt new file mode 100644 index 0000000000..fe6d684474 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt @@ -0,0 +1,247 @@ +/* + * 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.devtools + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.Parcelable +import android.view.Menu +import android.view.MenuItem +import androidx.appcompat.app.AlertDialog +import androidx.core.view.forEach +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import com.airbnb.mvrx.Fail +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.MvRx +import com.airbnb.mvrx.Success +import com.airbnb.mvrx.Uninitialized +import com.airbnb.mvrx.viewModel +import com.airbnb.mvrx.withState +import im.vector.app.R +import im.vector.app.core.di.ScreenComponent +import im.vector.app.core.extensions.replaceFragment +import im.vector.app.core.extensions.toMvRxBundle +import im.vector.app.core.platform.SimpleFragmentActivity +import im.vector.app.core.resources.ColorProvider +import im.vector.app.core.utils.createJSonViewerStyleProvider +import kotlinx.parcelize.Parcelize +import org.billcarsonfr.jsonviewer.JSonViewerFragment +import javax.inject.Inject + +class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Factory, + FragmentManager.OnBackStackChangedListener { + + @Inject lateinit var viewModelFactory: RoomDevToolViewModel.Factory + @Inject lateinit var colorProvider: ColorProvider + + // private lateinit var viewModel: RoomDevToolViewModel + private val viewModel: RoomDevToolViewModel by viewModel() + + override fun getTitleRes() = R.string.dev_tools_menu_name + + override fun getMenuRes() = R.menu.menu_devtools + + var currentDisplayMode: RoomDevToolViewState.Mode? = null + + @Parcelize + data class Args( + val roomId: String + ) : Parcelable + + override fun injectWith(injector: ScreenComponent) { + super.injectWith(injector) + injector.inject(this) + } + + override fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel { + return viewModelFactory.create(initialState) + } + + override fun initUiAndData() { + super.initUiAndData() + viewModel.subscribe(this) { + renderState(it) + } + + viewModel.observeViewEvents { + when (it) { + DevToolsViewEvents.Dismiss -> finish() + is DevToolsViewEvents.showAlertMessage -> { + AlertDialog.Builder(this) + .setMessage(it.message) + .setPositiveButton(R.string.ok, null) + .show() + } + is DevToolsViewEvents.showSnackMessage -> showSnackbar(it.message) + } + } + supportFragmentManager.addOnBackStackChangedListener(this) + } + + private fun renderState(it: RoomDevToolViewState) { + if (it.displayMode != currentDisplayMode) { + when (it.displayMode) { + RoomDevToolViewState.Mode.Root -> { + val classJava = RoomDevToolFragment::class.java + val tag = classJava.name + if (supportFragmentManager.findFragmentByTag(tag) == null) { + replaceFragment(R.id.container, RoomDevToolFragment::class.java) + } else { + supportFragmentManager.popBackStack() + } + } + RoomDevToolViewState.Mode.StateEventDetail -> { + val frag = JSonViewerFragment.newInstance(it.selectedEventJson ?: "", -1, true, createJSonViewerStyleProvider(colorProvider)) + navigateTo(frag) + } + RoomDevToolViewState.Mode.StateEventList, + RoomDevToolViewState.Mode.StateEventListByType -> { + val frag = createFragment(RoomDevToolStateEventListFragment::class.java, Bundle().toMvRxBundle()) + navigateTo(frag) + } + RoomDevToolViewState.Mode.EditEventContent -> { + val frag = createFragment(RoomDevToolEditFragment::class.java, Bundle().toMvRxBundle()) + navigateTo(frag) + } + is RoomDevToolViewState.Mode.SendEventForm -> { + val frag = createFragment(RoomDevToolSendFormFragment::class.java, Bundle().toMvRxBundle()) + navigateTo(frag) + } + } + currentDisplayMode = it.displayMode + invalidateOptionsMenu() + } + + when (it.modalLoading) { + is Loading -> showWaitingView() + is Success -> hideWaitingView() + is Fail -> { + hideWaitingView() + } + Uninitialized -> { + } + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + onBackPressed() + return true + } + if (item.itemId == R.id.menuItemEdit) { + viewModel.handle(RoomDevToolAction.MenuEdit) + return true + } + if (item.itemId == R.id.menuItemSend) { + viewModel.handle(RoomDevToolAction.MenuItemSend) + return true + } + return super.onOptionsItemSelected(item) + } + + override fun onBackPressed() { + viewModel.handle(RoomDevToolAction.OnBackPressed) + } + + private fun navigateTo(fragment: Fragment) { + val tag = fragment.javaClass.name + if (supportFragmentManager.findFragmentByTag(tag) == null) { + supportFragmentManager.beginTransaction() + .setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out) + .replace(R.id.container, fragment, tag) + .addToBackStack(tag) + .commit() + } else { + if (!supportFragmentManager.popBackStackImmediate(tag, 0)) { + supportFragmentManager.beginTransaction() + .setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out) + .replace(R.id.container, fragment, tag) + .addToBackStack(tag) + .commit() + } + } + } + + override fun onDestroy() { + supportFragmentManager.removeOnBackStackChangedListener(this) + currentDisplayMode = null + super.onDestroy() + } + + override fun onPrepareOptionsMenu(menu: Menu?): Boolean = withState(viewModel) { state -> + menu?.forEach { + val isVisible = when (it.itemId) { + R.id.menuItemEdit -> { + state.displayMode is RoomDevToolViewState.Mode.StateEventDetail + } + R.id.menuItemSend -> { + state.displayMode is RoomDevToolViewState.Mode.EditEventContent + || state.displayMode is RoomDevToolViewState.Mode.SendEventForm + } + else -> true + } + it.isVisible = isVisible + } + return@withState true + } + + companion object { + + fun intent(roomId: String, context: Context): Intent { + return Intent(context, RoomDevToolActivity::class.java).apply { + putExtra(MvRx.KEY_ARG, Args(roomId)) + } + } + } + + override fun onBackStackChanged() = withState(viewModel) { state -> + updateToolBar(state) + } + + private fun updateToolBar(state: RoomDevToolViewState) { + val title = when (state.displayMode) { + RoomDevToolViewState.Mode.Root -> { + getString(getTitleRes()) + } + RoomDevToolViewState.Mode.StateEventList -> { + "State Events" + } + RoomDevToolViewState.Mode.StateEventDetail -> { + state.selectedEvent?.type + } + RoomDevToolViewState.Mode.EditEventContent -> { + "Edit Content" + } + RoomDevToolViewState.Mode.StateEventListByType -> { + state.currentStateType ?: "" + } + is RoomDevToolViewState.Mode.SendEventForm -> { + if (state.displayMode.isState) "Send Custom State Event" + else "Send Custom Event" + } + } + + supportActionBar?.let { + it.title = title + } ?: run { + setTitle(title) + } + invalidateOptionsMenu() + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt new file mode 100644 index 0000000000..cbb85f5ee6 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt @@ -0,0 +1,72 @@ +/* + * 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.devtools + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.activityViewModel +import com.airbnb.mvrx.withState +import com.jakewharton.rxbinding3.widget.textChanges +import im.vector.app.core.extensions.hideKeyboard +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.resources.ColorProvider +import im.vector.app.databinding.FragmentDevtoolsEditorBinding +import javax.inject.Inject + +class RoomDevToolEditFragment @Inject constructor( + val epoxyController: RoomDevToolRootController, + private val colorProvider: ColorProvider +) : VectorBaseFragment(), RoomDevToolRootController.InteractionListener { + + val sharedViewModel: RoomDevToolViewModel by activityViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDevtoolsEditorBinding { + return FragmentDevtoolsEditorBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + withState(sharedViewModel) { + views.editText.setText(it.editedContent ?: "{}") + } + views.editText.textChanges() + .skipInitialValue() + .subscribe { + sharedViewModel.handle(RoomDevToolAction.UpdateContentText(it.toString())) + } + .disposeOnDestroyView() + } + + override fun invalidate() = withState(sharedViewModel) { _ -> + } + + override fun processAction(action: RoomDevToolAction) { + sharedViewModel.handle(action) + } + + override fun onResume() { + super.onResume() + views.editText.requestFocus() + } + + override fun onStop() { + super.onStop() + views.editText.hideKeyboard() + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt new file mode 100644 index 0000000000..36c1142bc2 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt @@ -0,0 +1,72 @@ +/* + * 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.devtools + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.activityViewModel +import com.airbnb.mvrx.withState +import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.resources.ColorProvider +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import javax.inject.Inject + +class RoomDevToolFragment @Inject constructor( + val epoxyController: RoomDevToolRootController, + private val colorProvider: ColorProvider +) : VectorBaseFragment(), RoomDevToolRootController.InteractionListener { + + val sharedViewModel: RoomDevToolViewModel by activityViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) + epoxyController.interactionListener = this + +// sharedViewModel.observeViewEvents { +// when (it) { +// is DevToolsViewEvents.showJson -> { +// JSonViewerDialog.newInstance(it.jsonString, -1, createJSonViewerStyleProvider(colorProvider)) +// .show(childFragmentManager, "JSON_VIEWER") +// +// } +// } +// } + } + + override fun onDestroyView() { + views.genericRecyclerView.cleanup() + epoxyController.interactionListener = null + super.onDestroyView() + } + + override fun invalidate() = withState(sharedViewModel) { state -> + epoxyController.setData(state) + } + + override fun processAction(action: RoomDevToolAction) { + sharedViewModel.handle(action) + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt new file mode 100644 index 0000000000..48f74eaaa5 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt @@ -0,0 +1,60 @@ +/* + * 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.devtools + +import android.view.View +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.ui.list.genericButtonItem +import javax.inject.Inject + +class RoomDevToolRootController @Inject constructor( + private val stringProvider: StringProvider +) : TypedEpoxyController() { + + interface InteractionListener { + fun processAction(action: RoomDevToolAction) + } + + var interactionListener: InteractionListener? = null + + override fun buildModels(data: RoomDevToolViewState?) { + if (data?.displayMode == RoomDevToolViewState.Mode.Root) { + genericButtonItem { + id("explore") + text("Explore Room State") + buttonClickAction(View.OnClickListener { + interactionListener?.processAction(RoomDevToolAction.ExploreRoomState) + }) + } + genericButtonItem { + id("send") + text("Send Custom Event") + buttonClickAction(View.OnClickListener { + interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false)) + }) + } + genericButtonItem { + id("send_state") + text("Send State Event") + buttonClickAction(View.OnClickListener { + interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true)) + }) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt new file mode 100644 index 0000000000..c6e9e37e9f --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt @@ -0,0 +1,76 @@ +/* + * 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.devtools + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.core.ui.list.genericFooterItem +import im.vector.app.features.form.formEditTextItem +import im.vector.app.features.form.formMultiLineEditTextItem +import javax.inject.Inject + +class RoomDevToolSendFormController @Inject constructor() : TypedEpoxyController() { + + interface InteractionListener { + fun processAction(action: RoomDevToolAction) + } + + var interactionListener: InteractionListener? = null + + override fun buildModels(data: RoomDevToolViewState?) { + val sendMode = (data?.displayMode as? RoomDevToolViewState.Mode.SendEventForm) + ?: return + + genericFooterItem { + id("topSpace") + text("") + } + formEditTextItem { + id("event_type") + enabled(true) + value(data.sendEventDraft?.type) + hint("Type") + showBottomSeparator(false) + onTextChange { text -> + interactionListener?.processAction(RoomDevToolAction.CustomEventTypeChange(text)) + } + } + + if (sendMode.isState) { + formEditTextItem { + id("state_key") + enabled(true) + value(data.sendEventDraft?.stateKey) + hint("State Key") + showBottomSeparator(false) + onTextChange { text -> + interactionListener?.processAction(RoomDevToolAction.CustomEventStateKeyChange(text)) + } + } + } + + formMultiLineEditTextItem { + id("event_content") + enabled(true) + value(data.sendEventDraft?.content) + hint("Event Content") + showBottomSeparator(false) + onTextChange { text -> + interactionListener?.processAction(RoomDevToolAction.CustomEventContentChange(text)) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt new file mode 100644 index 0000000000..d9e6f911c9 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt @@ -0,0 +1,62 @@ +/* + * 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.devtools + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.activityViewModel +import com.airbnb.mvrx.withState +import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.resources.ColorProvider +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import javax.inject.Inject + +class RoomDevToolSendFormFragment @Inject constructor( + val epoxyController: RoomDevToolSendFormController, + private val colorProvider: ColorProvider +) : VectorBaseFragment(), RoomDevToolSendFormController.InteractionListener { + + val sharedViewModel: RoomDevToolViewModel by activityViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + views.genericRecyclerView.configureWith(epoxyController, showDivider = false) + epoxyController.interactionListener = this + } + + override fun onDestroyView() { + views.genericRecyclerView.cleanup() + epoxyController.interactionListener = null + super.onDestroyView() + } + + override fun invalidate() = withState(sharedViewModel) { state -> + epoxyController.setData(state) + } + + override fun processAction(action: RoomDevToolAction) { + sharedViewModel.handle(action) + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt new file mode 100644 index 0000000000..f2425b9713 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt @@ -0,0 +1,62 @@ +/* + * 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.devtools + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.activityViewModel +import com.airbnb.mvrx.withState +import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.resources.ColorProvider +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import javax.inject.Inject + +class RoomDevToolStateEventListFragment @Inject constructor( + val epoxyController: RoomStateListController, + private val colorProvider: ColorProvider +) : VectorBaseFragment(), RoomStateListController.InteractionListener { + + val sharedViewModel: RoomDevToolViewModel by activityViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) + epoxyController.interactionListener = this + } + + override fun onDestroyView() { + views.genericRecyclerView.cleanup() + epoxyController.interactionListener = null + super.onDestroyView() + } + + override fun invalidate() = withState(sharedViewModel) { state -> + epoxyController.setData(state) + } + + override fun processAction(action: RoomDevToolAction) { + sharedViewModel.handle(action) + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt new file mode 100644 index 0000000000..7c847be3b1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt @@ -0,0 +1,293 @@ +/* + * 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.devtools + +import androidx.lifecycle.viewModelScope +import com.airbnb.mvrx.ActivityViewModelContext +import com.airbnb.mvrx.Fail +import com.airbnb.mvrx.FragmentViewModelContext +import com.airbnb.mvrx.Loading +import com.airbnb.mvrx.MvRxViewModelFactory +import com.airbnb.mvrx.Success +import com.airbnb.mvrx.ViewModelContext +import com.squareup.moshi.Types +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.error.ErrorFormatter +import im.vector.app.core.platform.VectorViewModel +import kotlinx.coroutines.launch +import org.json.JSONObject +import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.rx.rx + +class RoomDevToolViewModel @AssistedInject constructor( + @Assisted val initialState: RoomDevToolViewState, + private val errorFormatter: ErrorFormatter, + private val session: Session +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory { + fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel + } + + companion object : MvRxViewModelFactory { + + @JvmStatic + override fun create(viewModelContext: ViewModelContext, state: RoomDevToolViewState): RoomDevToolViewModel { + val factory = when (viewModelContext) { + is FragmentViewModelContext -> viewModelContext.fragment as? Factory + is ActivityViewModelContext -> viewModelContext.activity as? Factory + } + return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface") + } + } + + init { + + session.getRoom(initialState.roomId)?.rx() + ?.liveStateEvents(emptySet()) + ?.execute { async -> + copy(stateEvents = async) + } + } + + override fun handle(action: RoomDevToolAction) { + when (action) { + RoomDevToolAction.ExploreRoomState -> { + setState { + copy( + displayMode = RoomDevToolViewState.Mode.StateEventList, + selectedEvent = null + ) + } + } + is RoomDevToolAction.ShowStateEvent -> { + val jsonString = MoshiProvider.providesMoshi() + .adapter(Event::class.java) + .toJson(action.event) + + setState { + copy( + displayMode = RoomDevToolViewState.Mode.StateEventDetail, + selectedEvent = action.event, + selectedEventJson = jsonString + ) + } + } + RoomDevToolAction.OnBackPressed -> { + handleBack() + } + RoomDevToolAction.MenuEdit -> { + withState { + if (it.displayMode == RoomDevToolViewState.Mode.StateEventDetail) { + // we want to edit it + val content = it.selectedEvent?.content?.let { JSONObject(it).toString(4) } ?: "{\n\t\n}" + setState { + copy( + editedContent = content, + displayMode = RoomDevToolViewState.Mode.EditEventContent + ) + } + } + } + } + is RoomDevToolAction.ShowStateEventType -> { + setState { + copy( + displayMode = RoomDevToolViewState.Mode.StateEventListByType, + currentStateType = action.stateEventType + ) + } + } + RoomDevToolAction.MenuItemSend -> { + handleMenuItemSend() + } + is RoomDevToolAction.UpdateContentText -> { + setState { + copy(editedContent = action.contentJson) + } + } + is RoomDevToolAction.SendCustomEvent -> { + setState { + copy( + displayMode = RoomDevToolViewState.Mode.SendEventForm(action.isStateEvent), + sendEventDraft = RoomDevToolViewState.SendEventDraft("m.room.message", null, "{\n}") + ) + } + } + is RoomDevToolAction.CustomEventTypeChange -> { + setState { + copy( + sendEventDraft = sendEventDraft?.copy(type = action.type) + ) + } + } + is RoomDevToolAction.CustomEventStateKeyChange -> { + setState { + copy( + sendEventDraft = sendEventDraft?.copy(stateKey = action.stateKey) + ) + } + } + is RoomDevToolAction.CustomEventContentChange -> { + setState { + copy( + sendEventDraft = sendEventDraft?.copy(content = action.content) + ) + } + } + } + } + + private fun handleMenuItemSend() = withState { + when (it.displayMode) { + RoomDevToolViewState.Mode.EditEventContent -> { + setState { copy(modalLoading = Loading()) } + viewModelScope.launch { + try { + val room = session.getRoom(initialState.roomId) + ?: throw IllegalArgumentException("Room not found") + + val adapter = MoshiProvider.providesMoshi() + .adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) + val json = adapter.fromJson(it.editedContent ?: "") + ?: throw IllegalArgumentException("No content") + + room.sendStateEvent( + it.selectedEvent?.type ?: "", + it.selectedEvent?.stateKey, + json + + ) + _viewEvents.post(DevToolsViewEvents.showSnackMessage("State event sent!")) + setState { + copy( + modalLoading = Success(Unit), + selectedEventJson = null, + editedContent = null, + displayMode = RoomDevToolViewState.Mode.StateEventListByType + ) + } + } catch (failure: Throwable) { + _viewEvents.post(DevToolsViewEvents.showAlertMessage(errorFormatter.toHumanReadable(failure))) + setState { copy(modalLoading = Fail(failure)) } + } + } + } + is RoomDevToolViewState.Mode.SendEventForm -> { + setState { copy(modalLoading = Loading()) } + viewModelScope.launch { + try { + val room = session.getRoom(initialState.roomId) + ?: throw IllegalArgumentException("Room not found") + + val adapter = MoshiProvider.providesMoshi() + .adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) + val json = adapter.fromJson(it.sendEventDraft?.content ?: "") + ?: throw IllegalArgumentException("No content") + + val eventType = it.sendEventDraft?.type ?: throw IllegalArgumentException("Missing message type") + if (it.displayMode.isState) { + room.sendStateEvent( + eventType, + it.sendEventDraft.stateKey, + json + + ) + } else { + // can we try to do some validation?? + // val validParse = MoshiProvider.providesMoshi().adapter(MessageContent::class.java).fromJson(it.sendEventDraft.content ?: "") + json.toModel(catchError = false) + ?: throw IllegalArgumentException("Malformed event") + room.sendEvent( + eventType, + json + ) + } + + _viewEvents.post(DevToolsViewEvents.showSnackMessage("Event sent!")) + setState { + copy( + modalLoading = Success(Unit), + sendEventDraft = null, + displayMode = RoomDevToolViewState.Mode.Root + ) + } + } catch (failure: Throwable) { + _viewEvents.post(DevToolsViewEvents.showAlertMessage(errorFormatter.toHumanReadable(failure))) + setState { copy(modalLoading = Fail(failure)) } + } + } + } + } + } + + private fun handleBack() = withState { + when (it.displayMode) { + RoomDevToolViewState.Mode.Root -> { + _viewEvents.post(DevToolsViewEvents.Dismiss) + } + RoomDevToolViewState.Mode.StateEventList -> { + setState { + copy( + selectedEvent = null, + selectedEventJson = null, + displayMode = RoomDevToolViewState.Mode.Root + ) + } + } + RoomDevToolViewState.Mode.StateEventDetail -> { + setState { + copy( + selectedEvent = null, + selectedEventJson = null, + displayMode = RoomDevToolViewState.Mode.StateEventListByType + ) + } + } + RoomDevToolViewState.Mode.EditEventContent -> { + setState { + copy( + displayMode = RoomDevToolViewState.Mode.StateEventDetail + ) + } + } + RoomDevToolViewState.Mode.StateEventListByType -> { + setState { + copy( + currentStateType = null, + displayMode = RoomDevToolViewState.Mode.StateEventList + ) + } + } + is RoomDevToolViewState.Mode.SendEventForm -> { + setState { + copy( + displayMode = RoomDevToolViewState.Mode.Root + ) + } + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewState.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewState.kt new file mode 100644 index 0000000000..885de005b0 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewState.kt @@ -0,0 +1,52 @@ +/* + * 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.devtools + +import com.airbnb.mvrx.Async +import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized +import org.matrix.android.sdk.api.session.events.model.Event + +data class RoomDevToolViewState( + val roomId: String = "", + val displayMode: Mode = Mode.Root, + val stateEvents: Async> = Uninitialized, + val currentStateType: String? = null, + val selectedEvent: Event? = null, + val selectedEventJson: String? = null, + val editedContent: String? = null, + val modalLoading: Async = Uninitialized, + val sendEventDraft: SendEventDraft? = null +) : MvRxState { + + constructor(args: RoomDevToolActivity.Args) : this(roomId = args.roomId, displayMode = Mode.Root) + + sealed class Mode { + object Root : Mode() + object StateEventList : Mode() + object StateEventListByType : Mode() + object StateEventDetail : Mode() + object EditEventContent : Mode() + data class SendEventForm(val isState: Boolean) : Mode() + } + + data class SendEventDraft( + val type: String?, + val stateKey: String?, + val content: String? + ) +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt new file mode 100644 index 0000000000..844ed9be20 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt @@ -0,0 +1,113 @@ +/* + * 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.devtools + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R +import im.vector.app.core.epoxy.noResultItem +import im.vector.app.core.resources.ColorProvider +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.ui.list.GenericItem +import im.vector.app.core.ui.list.genericItem +import me.gujun.android.span.span +import org.json.JSONObject +import javax.inject.Inject + +class RoomStateListController @Inject constructor( + private val stringProvider: StringProvider, + private val colorProvider: ColorProvider +) : TypedEpoxyController() { + + interface InteractionListener { + fun processAction(action: RoomDevToolAction) + } + + var interactionListener: InteractionListener? = null + + override fun buildModels(data: RoomDevToolViewState?) { + when (data?.displayMode) { + RoomDevToolViewState.Mode.StateEventList -> { + val stateEventsGroups = (data.stateEvents.invoke() ?: emptyList()).groupBy { + it.type + } + + if (stateEventsGroups.isEmpty()) { + noResultItem { + id("no state events") + text(stringProvider.getString(R.string.no_result_placeholder)) + } + } else { + stateEventsGroups.forEach { entry -> + genericItem { + id(entry.key) + title(entry.key) + description("${entry.value.size} entries") + itemClickAction(GenericItem.Action("view").apply { + perform = Runnable { + interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key)) + } + }) + } + } + } + } + RoomDevToolViewState.Mode.StateEventListByType -> { + val stateEvents = (data.stateEvents.invoke() ?: emptyList()).filter { it.type == data.currentStateType } + if (stateEvents.isEmpty()) { + noResultItem { + id("no state events") + text(stringProvider.getString(R.string.no_result_placeholder)) + } + } else { + stateEvents.forEach { stateEvent -> + val contentMap = JSONObject(stateEvent.content ?: emptyMap()).toString().let { + if (it.length > 140) { + it.take(140) + Typography.ellipsis + } else it.take(140) + } + genericItem { + id(stateEvent.eventId) + title(span { + +"Type: " + span { + textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary) + text = "\"${stateEvent.type}\"" + textStyle = "normal" + } + +"\nState Key: " + span { + textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary) + text = stateEvent.stateKey.let { "\"$it\"" } + textStyle = "normal" + } + }) + description(contentMap) + itemClickAction(GenericItem.Action("view").apply { + perform = Runnable { + interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent)) + } + }) + } + } + } + } + else -> { + // nop + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt new file mode 100644 index 0000000000..974d2594ee --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt @@ -0,0 +1,101 @@ +/* + * 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.form + +import android.graphics.Typeface +import android.text.Editable +import android.view.View +import androidx.core.view.isVisible +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.google.android.material.textfield.TextInputEditText +import com.google.android.material.textfield.TextInputLayout +import im.vector.app.R +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.extensions.setTextSafe +import im.vector.app.core.platform.SimpleTextWatcher + +@EpoxyModelClass(layout = R.layout.item_form_multiline_text_input) +abstract class FormMultiLineEditTextItem : VectorEpoxyModel() { + + @EpoxyAttribute + var hint: String? = null + + @EpoxyAttribute + var value: String? = null + + @EpoxyAttribute + var showBottomSeparator: Boolean = true + + @EpoxyAttribute + var errorMessage: String? = null + + @EpoxyAttribute + var enabled: Boolean = true + + @EpoxyAttribute + var textSizeSp: Int? = null + + @EpoxyAttribute + var minLines: Int = 3 + + @EpoxyAttribute + var typeFace: Typeface = Typeface.DEFAULT + + @EpoxyAttribute + var onTextChange: ((String) -> Unit)? = null + + private val onTextChangeListener = object : SimpleTextWatcher() { + override fun afterTextChanged(s: Editable) { + onTextChange?.invoke(s.toString()) + } + } + + override fun bind(holder: Holder) { + super.bind(holder) + holder.textInputLayout.isEnabled = enabled + holder.textInputLayout.hint = hint + holder.textInputLayout.error = errorMessage + + holder.textInputEditText.typeface = typeFace + holder.textInputEditText.textSize = textSizeSp?.toFloat() ?: 12f + holder.textInputEditText.minLines = minLines + + // Update only if text is different and value is not null + holder.textInputEditText.setTextSafe(value) + holder.textInputEditText.isEnabled = enabled + + holder.textInputEditText.addTextChangedListener(onTextChangeListener) + holder.bottomSeparator.isVisible = showBottomSeparator + } + + override fun shouldSaveViewState(): Boolean { + return false + } + + override fun unbind(holder: Holder) { + super.unbind(holder) + holder.textInputEditText.removeTextChangedListener(onTextChangeListener) + } + + class Holder : VectorEpoxyHolder() { + val textInputLayout by bind(R.id.formMultiLineTextInputLayout) + val textInputEditText by bind(R.id.formMultiLineEditText) + val bottomSeparator by bind(R.id.formTextInputDivider) + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index aeb1c30f4b..8347735d0a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -128,6 +128,7 @@ import im.vector.app.features.command.Command import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.util.toImageRes import im.vector.app.features.crypto.verification.VerificationBottomSheet +import im.vector.app.features.devtools.RoomDevToolActivity import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.composer.TextComposerView import im.vector.app.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet @@ -767,6 +768,10 @@ class RoomDetailFragment @Inject constructor( handleSearchAction() true } + R.id.dev_tools -> { + startActivity(RoomDevToolActivity.intent(roomDetailArgs.roomId, requireContext())) + true + } else -> super.onOptionsItemSelected(item) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 7eedd5ca8e..f7299363a3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -606,6 +606,7 @@ class RoomDetailViewModel @AssistedInject constructor( R.id.video_call -> true // always show for discoverability R.id.hangup_call -> webRtcPeerConnectionManager.currentCall != null R.id.search -> true + R.id.dev_tools -> vectorPreferences.developerMode() else -> false } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt index 71ac7fcec4..86146e7d3a 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt @@ -63,7 +63,8 @@ class RoomMemberListController @Inject constructor( ?.filter { event -> event.content.toModel() ?.takeIf { - data.filter.isEmpty() || it.displayName.contains(data.filter, ignoreCase = true) + it.displayName != null + && (data.filter.isEmpty() || it.displayName!!.contains(data.filter, ignoreCase = true)) } != null } .orEmpty() diff --git a/vector/src/main/res/layout/fragment_devtools_editor.xml b/vector/src/main/res/layout/fragment_devtools_editor.xml new file mode 100644 index 0000000000..98682a1b65 --- /dev/null +++ b/vector/src/main/res/layout/fragment_devtools_editor.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_form_multiline_text_input.xml b/vector/src/main/res/layout/item_form_multiline_text_input.xml new file mode 100644 index 0000000000..f844f91a5a --- /dev/null +++ b/vector/src/main/res/layout/item_form_multiline_text_input.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + diff --git a/vector/src/main/res/layout/item_generic_list.xml b/vector/src/main/res/layout/item_generic_list.xml index f89413f15f..5535ab4549 100644 --- a/vector/src/main/res/layout/item_generic_list.xml +++ b/vector/src/main/res/layout/item_generic_list.xml @@ -5,6 +5,7 @@ android:id="@+id/item_generic_root" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" android:minHeight="50dp"> + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/menu/menu_timeline.xml b/vector/src/main/res/menu/menu_timeline.xml index 72b4a00682..1f4e2736b1 100644 --- a/vector/src/main/res/menu/menu_timeline.xml +++ b/vector/src/main/res/menu/menu_timeline.xml @@ -68,4 +68,12 @@ app:showAsAction="never" tools:visible="true" /> + + \ No newline at end of file diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index cfcbd157f3..c2677bf89e 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2792,4 +2792,5 @@ Re-Authentication Needed Element requires you to enter your credentials to perform this action. Failed to authenticate + Dev Tools From 7d4123c955fe6d7a6a43580ce923c512f455d7a4 Mon Sep 17 00:00:00 2001 From: vachan-maker Date: Sun, 14 Feb 2021 08:44:35 +0000 Subject: [PATCH 02/29] Added translation using Weblate (Malayalam) --- vector/src/main/res/values-ml/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 vector/src/main/res/values-ml/strings.xml diff --git a/vector/src/main/res/values-ml/strings.xml b/vector/src/main/res/values-ml/strings.xml new file mode 100644 index 0000000000..a6b3daec93 --- /dev/null +++ b/vector/src/main/res/values-ml/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From 6c50342535bb71928003a105deac271fbb1c6ec3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 Feb 2021 12:02:09 +0000 Subject: [PATCH 03/29] Translated using Weblate (Bosnian) Currently translated at 19.7% (410 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/bs/ --- vector/src/main/res/values-bs/strings.xml | 75 ++--------------------- 1 file changed, 4 insertions(+), 71 deletions(-) diff --git a/vector/src/main/res/values-bs/strings.xml b/vector/src/main/res/values-bs/strings.xml index f914536288..21c429d69c 100644 --- a/vector/src/main/res/values-bs/strings.xml +++ b/vector/src/main/res/values-bs/strings.xml @@ -1,22 +1,18 @@ - + - Svijetla Tema Tamna Tema Crna Tema - Sinkronizacija Budući Događaji Glasne notifikacije Nečujne notifikiacije - Poruke Soba Postavke Detalji o Članu Istorijski Izvještaj o Greški - OK Otkaži Snimi @@ -48,7 +44,6 @@ ili Pozovi Offline - Odjavi se Glasovni Poziv Video Poziv @@ -60,23 +55,18 @@ Zatvori Kopirano Isključi - Potvrda Upozorenje - Naslovna Omiljeni Ljudi Sobe - Traži sobe Traži favorite Traži ljude Traži sobe - Pozivi Niski prioritet - Razgovori Lokalni adresar Imenik korisnika @@ -84,12 +74,10 @@ Nema razgovora Niste omogućili Elementu pristup vašim lokalnim kontaktima Nema rezultata - Sobe Imenik soba Nema soba Nema dostupnih javnih soba - Pošaljite zapise Pošaljite keš zapise Pošalji sliku ekrana @@ -99,14 +87,11 @@ Da bi dijagnosticirali probleme, zapisi ovog klijenta bit će poslani s ovim izvještajem o greški. Ako želite poslati samo gore navedeni tekst, uklonite oznaku: Čini se da frustrirani. Želite li poslati izvještaj o pogrešci? Aplikacija se srušila posljednji put. Želite li poslati izvještaj o rušenju? - Izvješće o greški je uspješno poslano Izvještaj o greški nije uspješno poslan (%s) Napredak (%s%%) - Poslane informacije Čitaj - Pridruži se u sobu Korisničko ime Registruj se @@ -115,16 +100,13 @@ URL lokalnog servera URL identitet servera Traži - Započni Novi Razgovor Započni Glasnovni Poziv Započni Video Poziv - Pošalji fajlove Napravi fotografiju ili videozapis Napravi fotografiju Napravi video - Prijavi se Registruj se Pošalji @@ -172,7 +154,6 @@ Možete dodati vašu email adresu na svoj profil u postavkama. Vaša lozinka je resetovana. Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste ponovno omogućili obavijesti, ponovo se prijavite na svaki uređaj. - URL mora početi sa http[s]:// Nemoguća prijava: Greška na mreži Nemoguća prijava @@ -180,7 +161,6 @@ Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste pon Nemoguća registracija Nemoguća registracija : problem sa vlasništvom email adrese Unesite ispravan URL - Netačno korisničko ime/lozinka Navedeni pristupni token nije prepoznat Neispravno formatiran JSON @@ -188,23 +168,18 @@ Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste pon Previše zahtjeva je poslano Ovo korisničko ime se već koristi Link email adrese koji još uvijek nije kliknut - Čitajte Listu Primalaca - "Pošalji kao " Orginal Veliko Srednje Malo - Otkazi preuzimanje? Otkaži prijenos? Jučer Danas - Ime sobe Tema sobe - Poziv Poziv uspostavljen Poziv se uspostavlja… @@ -214,15 +189,12 @@ Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste pon Dolazni Video Poziv Dolazni Glasovni Poziv Poziv u Toku - Daljinska strana nije uspjela pokupiti. Medijska veza nije uspjela Kamera se ne moze inicijalizirati poziv je odgovoren na drugom mjestu - Snimi fotografiju ili video Nije moguće snimiti video - Informacije Hepek treba dopuštenje za pristup vašoj biblioteci fotografija i videozapisa za slanje i spremanje privitaka. @@ -244,47 +216,37 @@ Dopustite pristup sljedećem skočnom prozoru da biste otkrili kontakte koji kor Hepek treba dopuštenje za pristup kontaktima kako bi pronašao druge Matrix korisnike na temelju njihove email adrese i telefonskih brojeva. Želite li dopustiti da Hepek pristupi vašim kontaktima? - Nažalost, akcija nije izvršena zbog nedostatka dozvola - Snimljeno Snimi u preuzimanja DA NE Nastavi - Ukloni Spoji Pregled Odbij - Idi na prvu nepročitanu poruku. - Pozvani ste da %s se pridružite u ovu sobu Ova je pozivnica poslana na%, koja nije povezana s ovim računom. Možda se želite prijaviti s nekim drugim računom ili dodati ovu poruku email adresu svom računu. Pokušavate pristupiti usluzi %s. Želite li se pridružiti kako biste sudjelovali u razgovoru? soba Ovo je pregled ove sobe. Razgovori u sobi su onemoguceni. - Novi Razgovor Dodaj člana 1 član - Napusti sobu Da li ste sigurni da želite napustiti sobu? - Da li ste sigurni da želite ukloniti % iz ovog razgovora? + Da li ste sigurni da želite ukloniti %s iz ovog razgovora\? Kreiraj - Online Offline Idle - ADMINISTRATORSKI ALATI POZIV DIREKTNI RAZGOVORI UREĐAJI - Pozovi Napusti ovu sobu Ukloni iz ove sobe @@ -300,18 +262,14 @@ Možda se želite prijaviti s nekim drugim računom ili dodati ovu poruku email Prikaži listu uređaja Nećete moći poništiti ovu promjenu jer će te korisniku dati ista dopuštenja kao što imate i vi. Da li ste sigurani? - - Da li ste sigurni da želite pozvati% u ovaj razgovor? - + Da li ste sigurni da želite pozvati %s u ovaj razgovor\? Pozovi preko ID-a LOKALNI KONTAKTI (%d) KORISNIČKI IMENIK (%s) Samo Matrix korisnici - Pozovi korisnika preko ID-a Unesite jednu ili više email adresa ili Matrix ID Email il Matrix ID - Pretraga %s tipka… %1$s & %2$s tipkaju… @@ -327,7 +285,6 @@ Da li ste sigurani? Izbriši neposlane poruke Datoteka nije pronađena Nemate dopuštenje da komunicirate u ovoj sobi - Povjerenje Ne vjerujte Odjava @@ -339,7 +296,6 @@ Da li ste sigurani? Certifikat je promijenjen s onoga koji vaš telefon smatra pouzdanim. Ovo je VRLO NEUBIČAJENO. Preporučuje se da NE PRIHVAĆATE ovaj novi certifikat. Potvrda se promijenila s prethodno pouzdane u onu koja nije pouzdana. Postoji mogučnost da je server obnovio svoj certifikat. Obratite se administratoru servera za očekivani otisak prsta. SAMO prihvatiti certifikat ako je administrator servera objavio otisak prsta koji odgovara gore navedenom. - Detalji Sobe Ljudi Fajlovi @@ -347,12 +303,10 @@ Da li ste sigurani? Malformirani ID. Trebao bi biti email adresa ili Matrix ID poput \"@localpart: domain\" POZVAN PRIKLJUČEN - Razlog za prijavljivanje ovog sadržaja Želite li sakriti sve poruke tog korisnika? Otkaži Prijenos Otkaži Preuzimanje - Pretraga Filtriraj članove sobe Nema rezultata @@ -360,7 +314,6 @@ Da li ste sigurani? PORUKE LJUDI FAJLOVI - PRIDRUŽI SE DIREKTORIJ FAVORITI @@ -372,16 +325,13 @@ Da li ste sigurani? Pridruži se sobi Pridriži se u sobu Upišite ID sobe ili alias sobe - Pretražite imenik Traži direktorij.. - Favorit De-prioritiziraj Direktni Razgovor Napusti Razgovor Zaboravi - Poruke Postavke "Verzija " @@ -389,7 +339,6 @@ Da li ste sigurani? Obavijesti treće strane Copyright Privatnost - Profilna Slika Ime Email @@ -398,12 +347,10 @@ Da li ste sigurani? Dodaj broj telefona Infomacije o aplikacijskom sustavu Informacije o aplikaciji - Zvuk notifikacije Omogući obavijesti za ovaj račun Omogući obavijesti za ovaj uređaj Uključite zaslon na 3 sekunde - Poruke sadrže moje ime Poruke sadrže moje koristničko ime Poruke u jedan-na-jedan razgovorima @@ -411,13 +358,11 @@ Da li ste sigurani? Kada sam pozvan u sobu Pozivnice za poziv Poruke koje šalje bot - Započni na boot Pozadinska sinkronizacija Omogući pozadinsku sinkronizaciju Sinkronizacijski zahtjev istekao Napravi pauzu između dva sinkronizacijska zahtjeva - Verzija olm verzija Uvjeti korištenja @@ -427,7 +372,6 @@ Da li ste sigurani? Očisti keš Očisti medija keš Dodaj medij - Korisničke postavke Notifikacije Ignorisani korisnici @@ -444,13 +388,10 @@ Da li ste sigurani? Uređaj Uvijek prikažite vremenske oznake poruka Prikaži vremenske oznake u 12-satnom obliku (npr. 14:30) - Analiza %d s %1$a %2$i - Način spremanja podataka - Pojedinosti uređaja ID Ime @@ -462,22 +403,18 @@ Da biste nastavili, unesite lozinku. Ovjera Lozinka: Pošalji - Prijavljen kao Lokalni Server Identifikacioni Server - Korisnički interfejs Jezik interfejsa Izaberi jezik - Čekanje na verifikaciju Proverite svoj email i kliknite na link u email-u. Nakon što to učinite, kliknite na dugme nastavi. Nije moguće proveriti email adresu. Proverite svoj email i kliknite na link u emailu. Nakon što to uradite, kliknite na dugme nastavi Ova email adresa je već u upotrebi Neuspješno slanje emaila: Ova adresa email adresa nije pronađena Ovaj telefonski broj je već u upotrebi - Promenite lozinku stara lozinka nova lozinka @@ -485,15 +422,11 @@ Da biste nastavili, unesite lozinku. Neuspešno ažuriranje lozinke Vaša lozinka je ažurirana Prikaži sve poruke iz %s? - Da li ste sigurni da želite ukloniti ovaj cilj obaveštenja? - Da li ste sigurni da želite ukloniti %1$s %2$s? - Izaberite zemlju - Zemlja Izaberite zemlju Broj telefona Nevažeći broj telefona za izabranu zemlju - + \ No newline at end of file From eff0a701d8bd16eed236498e6c7d73a26b66039f Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Sun, 14 Feb 2021 18:06:44 +0000 Subject: [PATCH 04/29] Translated using Weblate (Catalan) Currently translated at 100.0% (2081 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ca/ --- vector/src/main/res/values-ca/strings.xml | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/vector/src/main/res/values-ca/strings.xml b/vector/src/main/res/values-ca/strings.xml index e78fa6cd81..20eb222f83 100644 --- a/vector/src/main/res/values-ca/strings.xml +++ b/vector/src/main/res/values-ca/strings.xml @@ -2387,4 +2387,32 @@ Exporta informe Aquesta sessió no pot compartir la verificació amb les teves altres sessions. \nLa verificació es desarà localment i es compartirà més endavant en noves versions de l\'aplicació. + Usuaris + S\'ha produït un error al transferir la trucada + Transferència + Connecta + Consulta primer + + 1 trucada activa (%1$s) · 1 trucada en pausa + 1 trucada activa (%1$s) · %2$d trucades en pausa + + + Trucada en pausa + %1$d trucades en pausa + + Trucada activa (%1$s) + S\'ha produït un error al cercar el número de telèfon + Teclat + Torna la trucada + La trucada ha finalitzat + %1$s ha rebutjat la trucada + Has rebutjat la trucada %1$s + Ets dins aquesta trucada + %1$s ha iniciat la trucada + Has iniciat la trucada + Has posat la trucada en espera + Posa en espera + %s ha posat la trucada en espera + Continua + Torna \ No newline at end of file From 9bb216618a9ad59be630bd5dadfbc24ec620f2fb Mon Sep 17 00:00:00 2001 From: waclaw66 Date: Mon, 15 Feb 2021 07:32:42 +0000 Subject: [PATCH 05/29] Translated using Weblate (Czech) Currently translated at 100.0% (2081 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/ --- vector/src/main/res/values-cs/strings.xml | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index 0edb6a69db..4fe9a905aa 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2358,4 +2358,34 @@ Je nutné opětovné ověření Nastavení křížového podepisování se nezdařilo Neautorizováno, chybí platné ověřovací údaje + Přepojit + Uživatelé + Při přepojování hovoru došlo k chybě + Připojit + Nejprve se poraďte + + 1 probíhající hovor (%1$s) · 1 pozastavený hovor + 1 probíhající hovor (%1$s) · %2$d pozastavené hovory + 1 probíhající hovor (%1$s) · %2$d pozastavených hovorů + + + Pozastavený hovor + %1$d pozastavené hovory + %1$d pozastavených hovorů + + Probíhající hovor (%1$s) + Při vyhledávání telefonního čísla došlo k chybě + Číselník + Zavolat zpět + Tento hovor skončil + %1$s odmítl tento hovor + Odmítli jste tento hovor %1$s + Aktuálně jste v tomto hovoru + %1$s zahájil hovor + Zahájili jste hovor + Podrželi jste hovor + %s podržel hovor + Přidržet + Pokračovat + Návrat \ No newline at end of file From e79657232aded597e5234fc05bf6b92813bb9f97 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Sat, 13 Feb 2021 17:15:45 +0000 Subject: [PATCH 06/29] Translated using Weblate (German) Currently translated at 99.9% (2080 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/de/ --- vector/src/main/res/values-de/strings.xml | 73 ++++++++++++++++------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 07ba05fcd2..43eef6909f 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -285,7 +285,7 @@ Mit ID einladen LOKALE KONTAKTE (%d) Nur Matrix-Benutzer - Benutzer per ID einladen + Benutzer:in per ID einladen Bitte gib eine oder mehrere E-Mail-Adressen oder eine Matrix-ID ein E-Mail or Matrix-ID @@ -797,15 +797,15 @@ Du bist aktuell kein Mitglied einer Community. Benutze die Enter-Taste der Tastatur zum Senden Zeigt Aktionen - Bannt Benutzer mit angegebener ID + Bannt Benutzer:in mit angegebener ID Hebt die Verbannung des Benutzers mit angegebener ID auf Bestimmt das Berechtigungslevel des Benutzers Setzt Berechtigungen des Benutzers zurück - Lädt Benutzer mit angegebener Kennung in den aktuellen Raum ein + Lädt Benutzer:in mit angegebener Kennung in den aktuellen Raum ein Tritt dem Raum mit angegebenen Alias bei Verlasse Raum Setzt das Raum-Thema - Kickt Benutzer mit angegebener ID + Kickt Benutzer:in mit angegebener ID Ändert deinen Anzeigenamen (De-)Aktiviert Markdown Um das Matrix-App-Management zu reparieren @@ -882,7 +882,7 @@ Grund Linkvorschau im Chat aktivieren, falls dein Home-Server diese Funktion unterstützt. Sende Schreibbenachrichtigungen - Lasse andere Benutzer wissen, dass du tippst. + Lasse andere Benutzer:innen wissen, dass du tippst. Markdown-Formatierung Formatiere Nachrichten mittels Markdown-Syntax, bevor sie gesendet werden. Dies erlaubt erweiterte Formatierungen, etwa Sternchen (*) um kursiven Text anzuzeigen. Zeige Lesebestätigungen @@ -960,7 +960,7 @@ Prüfung der Play-Dienste Google Play-Dienste-APK ist verfügbar und aktuell. Token-Registrierung - Wenn ein Benutzer ein abgestecktes Gerät mit ausgeschaltetem Bildschirm eine Weile nicht bewegt, wechselt es in den Doze-Modus. Dies hindert Apps daran, auf das Netzwerk zuzugreifen und verzögert die Ausführung von Aufgaben, Synchronisierungen und Standard-Alarmen. + Wenn ein:e Benutzer:in ein abgestecktes Gerät mit ausgeschaltetem Bildschirm eine Weile nicht bewegt, wechselt es in den Bereitschaftsmodus. Dies hindert Apps daran, auf das Netzwerk zuzugreifen und verzögert die Ausführung von Aufgaben, Synchronisierungen und Standard-Alarmen. Ignoriere Optimierungen Hintergrundverbindung Element muss eine Hintergrundverbindung (nur geringe Belastung) aufrechterhalten, um verlässliche Benachrichtigungen zu erhalten. @@ -1014,7 +1014,7 @@ Lösche Sicherung Präferenz der Benachrichtigungen nach Ereignis [%1$s] -\nDieser Fehler ist außerhalb von Element passiert. Google sagt, dass dieses Gerät zu viele Apps registriert hat um FCM zu nutzen. Der Fehler taucht nur auf, wenn sehr viele Apps installiert sind. Er sollte also den Durchschnittsnutzer nicht betreffen. +\nDieser Fehler ist außerhalb von Element passiert. Google sagt, dass dieses Gerät zu viele Apps registriert hat um FCM zu nutzen. Der Fehler taucht nur auf, wenn sehr viele Apps installiert sind. Er sollte also den/die Durchschnittsnutzer:in nicht betreffen. [%1$s] \nDieser Fehler liegt nicht unter der Kontrolle von Element. Er kann aus verschiedenen Gründen auftreten. Vielleicht wird es funktionieren, wenn du es später noch einmal probierst. Außerdem kannst Du prüfen, ob die Datennutzung der Google Play-Dienste unbeschränkt ist und die Geräteuhr richtig eingestellt ist. Der Fehler kann aber auch unter Custom-ROMs auftreten. [%1$s] @@ -1182,7 +1182,7 @@ Warte auf Bestätigung des/r anderen Nutzer*in… Verifiziert! Du hast diese Sitzung erfolgreich verifiziert. - Sichere Nachrichten mit diesem Benutzer sind Ende-zu-Ende verschlüsselt und können nicht von Dritten mitgelesen werden. + Sichere Nachrichten mit diesem/r Benutzer:in sind Ende-zu-Ende verschlüsselt und können nicht von Dritten mitgelesen werden. Verstanden Schlüssel-Verifizierung Anfrage abgebrochen @@ -1191,7 +1191,7 @@ Interaktive Sitzungs-Verifizierung Verifizierungsanfrage %s möchte deine Sitzung verifizieren - Der Benutzer hat die Verifizierung abgebrochen + Der/die Benutzer:in hat die Verifizierung abgebrochen Der Verifizierungsprozess ist abgelaufen Die Sitzung hat eine unerwartete Nachricht erhalten Eine ungültige Nachricht wurde empfangen @@ -1214,7 +1214,7 @@ Reaktion hinzufügen Reaktionen ansehen Reaktionen - Ereignis von Benutzer gelöscht + Ereignis von Benutzer:in gelöscht Ereignis moderiert durch Raum-Administrator Zuletzt bearbeitet von %1$s am %2$s Neuen Raum erstellen @@ -1440,7 +1440,7 @@ Diesen Inhalt melden Meldegrund MELDEN - NUTZER IGNORIEREN + NUTZER:IN IGNORIEREN Inhalt gemeldet Dieser Inhalt wurde gemeldet. \n @@ -1795,8 +1795,8 @@ Benutze diese Sitzung um deine neue zu verfizieren, damit sie auf verschlüsselte Nachrichten zugreifen kann. Das war ich nicht Dein Account ist möglicherweise komprimittiert - Wenn du abbrichst, wirst du auf diesem Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer werden ihm nicht vertrauen - Wenn du abbrichst, wirst du auf deinem neuen Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer werden ihm nicht vertrauen + Wenn du abbrichst, wirst du auf diesem Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer:innen werden ihm nicht vertrauen + Wenn du abbrichst, wirst du auf deinem neuen Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer:innen werden ihm nicht vertrauen Du wirst %1$s (%2$s) nicht verifizieren, wenn du jetzt abbrichst. Beginne in deren Nutzerprofil erneut. Eines der folgenden könnte kom­pro­mit­tie­rt sein: \n @@ -1847,7 +1847,7 @@ Dies kann nicht von einem mobilen Gerät erfolgen Wenn Räume verbessert werden Verschlüsselung aktiviert - Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr & verifiziere Benutzer in deren Profil. + Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr & verifiziere Benutzer:innen in deren Profil. Die Verschlüsselung in diesem Raum wird nicht unterstützt Warte auf %s… %s setzen @@ -1922,15 +1922,15 @@ %1$s: %2$s %3$s Nutzer!n hinzufügen EINLADEN - Benutzer werden eingeladen… - Benutzer einladen + Benutzer:innen werden eingeladen… + Benutzer:innen einladen Einladung gesendet an %1$s Einladungen gesendet an %1$s und %2$s Einladungen gesendet an %1$s und einen weiteren Benutzer Einladungen gesendet an %1$s und %2$d weitere Benutzer - Wir konnten den Benutzer nicht einladen. Bitte überprüfe den Benutzernamen, welchen du einladen möchtest und versuche es erneut. + Wir konnten die Benutzer:innen nicht einladen. Bitte überprüfe die Benutzer:innen, welchen du einladen möchtest, und versuche es erneut. Pause Kopieren Benachrichtigungen @@ -1956,25 +1956,25 @@ Zum Anruf zurückkehren Einladung zurückziehen Möchtest du dich zurückstufen\? - Du kannst die Zurückstufung nicht rückgängig machen und du wirst die Rechte nur mit einem anderen berechtigten Benutzer im Raum zurückerlangen können. + Du kannst die Zurückstufung nicht rückgängig machen und du wirst die Rechte nur mit einem/r anderen berechtigten Benutzer:in im Raum zurückerlangen können. Zurückstufen - Benutzer ignorieren + Benutzer:in ignorieren Durch das Ignorieren werden für dich alle Nachrichten des/r Nutzers/in ausgeblendet. \n \nDu kannst die Aktion jederzeit in den allgemeinen Einstellungen rückgängig machen. Ignorieren des Benutzers rückgängig machen Das Aufheben der Ignorierung wird alle Nachrichten des Benutzers wieder einblenden. Einladung zurückziehen - Bist du dir sicher, dass du die Einladung für diesen Benutzer zurückziehen möchtest\? - Benutzer entfernen + Bist du dir sicher, dass du die Einladung für diese:n Benutzer:in zurückziehen möchtest\? + Benutzer:in entfernen Grund für das Entfernen Das Entfernen wird den/die Benutzer!n von diesem Raum ausschließen. \n \nUm einen erneuten Beitritt zu verhindern, solltest du ihn/sie stattdessen bannen. - Benutzer bannen + Benutzer:in bannen Grund für den Bann Bann des Benutzers aufheben - Das Aufheben des Bannes wird dem Benutzer erlauben dem Raum wieder beizutreten. + Das Aufheben des Bannes wird dem/r Benutzer:in erlauben dem Raum wieder beizutreten. Sicheres Backup Verwalten Backup einrichten @@ -2375,4 +2375,31 @@ Erneute Authentifizierung erforderlich Cross Signing konnte nicht eingerichtet werden Nicht autorisierte, fehlende gültige Authentifizierungsdaten + Nutzer:innen + Beim Übertragen des Anrufs ist ein Fehler aufgetreten + Übertragen + Verbinden + + 1 aktiver Anruf (%1$s) · 1 pausierter Anruf + 1 aktiver Anruf (%1$s) · %2$d pausierte Anrufe + + + Pausierter Anruf + %1$d pausierte Anrufe + + Aktiver Anruf (%1$s) + Beim Suchen der Telefonnummer ist ein Fehler aufgetreten + Wähltastatur + Zurückrufen + Dieser Anruf wurde beendet + %1$s hat diesen Anruf abgelehnt + Du hast diesen Anruf %1$s abgelehnt + Du nimmst zur Zeit an diesem Anruf teil + %1$s hat einen Anruf gestartet + Du hast einen Anruf gestartet + Du hältst den Anruf + %s hält den Anruf + Halten + Fortsetzen + Zurück \ No newline at end of file From e43b31ef2bb298809b01c059e79af259f139c696 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 Feb 2021 12:03:47 +0000 Subject: [PATCH 07/29] Translated using Weblate (Spanish) Currently translated at 95.2% (1982 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/es/ --- vector/src/main/res/values-es/strings.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vector/src/main/res/values-es/strings.xml b/vector/src/main/res/values-es/strings.xml index 1dbba1c25c..8a05b0dfd3 100644 --- a/vector/src/main/res/values-es/strings.xml +++ b/vector/src/main/res/values-es/strings.xml @@ -1549,8 +1549,8 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Invitación enviada a %1$s Invitación enviada a %1$s y %2$s - Invitaciones enviadas a % $s y a uno más - Invitaciones enviadas a %$s y a %2$d más + Invitaciones enviadas a %1$s y a uno más + Invitaciones enviadas a %1$s y a %2$d más No se pudo invitar el usuario. Por favor, intente nuevamente. Idioma actual @@ -2291,7 +2291,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Contactos Usuarios conocidos Mostrar efectos de chat - Para escanear el codigo QR , necesita darle permisos a su camara. + Para escanear el codigo QR , necesita darle permisos a su cámara. Invitar contactos Modifique los roles y privilegios de la sala. Sala no pública. No puede acceder sin una invitacion. @@ -2301,5 +2301,5 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua Editar historial de visibilidad Editar permisos Cambiar el nombre de la sala - Administracion de sala + Administración de sala \ No newline at end of file From 099600f665387b9fdd674651e60e367339fa7d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 12 Feb 2021 18:10:21 +0000 Subject: [PATCH 08/29] Translated using Weblate (Estonian) Currently translated at 100.0% (2081 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/et/ --- vector/src/main/res/values-et/strings.xml | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index cd643eccd6..539d5d4017 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -2320,4 +2320,32 @@ Palun korda autentimist Risttunnustamise alustamine ei õnnestunud Volitused puuduvad, kasutajakonto ja/või salasõna on valed + Kasutajad + Kõne suunamisel tekkis viga + Suuna + Ühenda + Pea esmalt nõu + + Käsil on üks kõne (%1$s) · üks kõne on ootel + Käsil on üks kõne (%1$s) · %2$d kõnet on ootel + + + Pooleli kõne + %1$d pooleli kõnet + + Kõne on pooleli (%1$s) + Telefoninumbri otsimisel tekkis viga + Numbriklahvistik + Helista tagasi + See kõne on lõppenud + %1$s keeldus kõnest + Sa keeldusid %1$s kõnest + Sul on parasjagu see mõne pooleli + %1$s alustas kõnet + Sa alustasid kõnet + Sina panid kõne ootele + %s pani kõne ootele + Pane ootele + Jätka + Pöördu tagasi \ No newline at end of file From 3740997b2ef5301a4fb2a6dab25b184ecfb8cc1a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 Feb 2021 10:00:52 +0000 Subject: [PATCH 09/29] Translated using Weblate (Croatian) Currently translated at 57.1% (1190 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/hr/ --- vector/src/main/res/values-hr/strings.xml | 268 +--------------------- 1 file changed, 8 insertions(+), 260 deletions(-) diff --git a/vector/src/main/res/values-hr/strings.xml b/vector/src/main/res/values-hr/strings.xml index 9013b8fd65..3feac0f644 100644 --- a/vector/src/main/res/values-hr/strings.xml +++ b/vector/src/main/res/values-hr/strings.xml @@ -1,16 +1,14 @@ - + Svijetla tema Tamna tema Crna tema Tema Status.im-a - Inicijalizacija servisa Sinkronizacija u tijeku… Osluškivanje događaja Bučne obavijesti Tihe obavijesti - Poruke Soba Postavke @@ -22,7 +20,6 @@ Pričuvni ključevi Koristi pričuvne ključeve Potvrdi sesiju - Izrada pričuvnih ključeva je u tijeku, pričekajte… Izgubit ćete Vaše šifrirane poruke ukoliko se sada odjavite Izrada pričuvnih ključeva je u tijeku. Ukoliko se sada odjavite, izgubit ćete pristup Vašim šifriranim porukama. @@ -33,11 +30,8 @@ Jeste li sigurni\? Izradi pričuvu Izgubit ćete pristup Vašim šifriranim porukama ukoliko prije odjave ne izradite pričuvne ključeve. - Licence trećih strana - Učitavanje… - U redu Odustani Spremi @@ -86,7 +80,6 @@ Zanemari Pregledaj Odbij - Izađi Radnje Odjavi se @@ -102,27 +95,22 @@ Zatvori Kopirano u spremnik Onemogući - Potvrda Upozorenje Greška - Početna Omiljeno Osobe Sobe Zajednice - Izdvoji nazive soba Izdvoji među omiljenim Izdvoji osobe Izdvoji nazive soba Izdvoji nazive zajednica - Pozivnice Nizak prioritet Upozorenja sustava - Razgovori Lokalni imenik Popis korisnika @@ -131,7 +119,6 @@ Niste Elementu omogućili pristup Vašim lokalnim kontaktima Nema rezultata Nije podešen poslužitelj identiteta. - Sobe Popis soba Nema soba @@ -141,11 +128,9 @@ %d korisnika %d korisnika - Pozovi Zajednice Nema grupa - Pošalji zapise Pošalji zapise o rušenju Pošalji sliku zaslona @@ -157,14 +142,11 @@ Čini se da usred razočaranja tresete telefonom. Želite li otvoriti zaslon za prijavu grešaka\? Zadnji se puta aplikacija srušila. Želite li otvoriti zaslon za prijavu rušenja\? Jako drmanje za prijavu greške - Prijava greške je uspješno poslana Prijava greške nije poslana (%s) Tijek (%s%%) - Pošalji u Pročitano - Pridruži se u sobu Korisničko ime Otvori račun @@ -173,13 +155,10 @@ URL Vašeg poslužitelja URL poslužitelja identiteta Traži - Započni novo ćaskanje Započni glasovni poziv Započni video poziv - Šalji glas - Jeste li sigurni da s %s želite započeti novo ćaskanje\? Jeste li sigurni da želite započeti novi glasovni poziv\? Jeste li sigurni da želite započeti novi video poziv\? @@ -189,20 +168,16 @@ \nDruga je opcija da koristite javni poslužitelj pri %2$s, no ovo neće biti jednako pouzdano i Vaša će IP adresa biti poznata tom poslužitelju. Ovo možete podešavati u postavkama. Pokušaj pomoću %s Nemoj me ponovno pitati - Pošalji datoteke Pošalji naljepnicu Napravi fotografiju ili video zapis Napravi fotografiju Napravi video zapis - Trenutno nemate omogućene ni jedan paket naljepnica. \n \nŽelite li ih sada dodati\? - nastavi s… Nažalost nije pronađena vanjska aplikacija za dovršetak ove radnje. - Prijavi se Otvori račun Pošalji @@ -252,7 +227,6 @@ \n \nOdjavljeni ste iz svih sesija i više nećete primati obavijesti. Kako biste ponovno omogućili obavijesti, ponovno se prijavite na svakom uređaju. Pročitajte i prihvatite pravila ovog poslužitelja: - URL mora početi s http[s]:// Neuspjela prijava: mrežna greška Neuspjela prijava @@ -264,7 +238,6 @@ Ovo nije ispravna adresa poslužitelja Matrixa Poslužitelj na ovom URL-u je nedostupan, provjerite ga Vaš uređaj koristi zastario sigurnosni protokol TLS podložan napadima pa se nećete moći spojiti radi vlastite sigurnosti - Neispravno korisničko ime/lozinka Navedena pristupna oznaka nije prepoznata Izobličen JSON @@ -272,48 +245,36 @@ Poslano je previše zahtjeva Ovo se korisničko ime već koristi Još uvijek niste kliknuli na poveznicu u e-pošti - Ponovno zatražite ključeve za šifriranje od Vaših drugih sesija. - Zahtjev za ključ je poslan. - Zahtjev poslan Pokrenite Element na nekom drugom uređaju koji može dešifrirati poruku kako bi poslao ključeve ovoj sesiji. - Popis potvrda o pročitanim porukama - Popis grupa - %d promjena u članstvu %d promjene u članstvu %d promjena u članstvu - Pošalji kao Izvorno Veliko Srednje Malo - Otkaži preuzimanje\? Otkaži slanje\? %d s %1$d m %2$d s - Jučer Danas - Naziv sobe Tema sobe - Pozivi Koristi zadan zvuk tona Elementa za dolazne pozive Dozvoli rezervnog poslužitelja za pozivnog pomoćnika Koristit će se %s kao pomoćnik u slučaju da ga Vaš poslužitelj nema (Vaša IP adresa će biti podijeljena tijekom poziva) Zvuk tona dolaznog poziva Izaberite zvuk tona za pozive: - Poziv Poziv uspostavljen Poziv se uspostavlja… @@ -324,15 +285,12 @@ Dolazni glasovni poziv Poziv u tijeku… Video poziv u tijeku… - Druga strana se nije javila. Medijska veza nije uspjela Nije moguće inicijalizirati kameru poziv je drugdje preuzet - Napravi fotografiju ili video zapis Nije moguće snimiti video zapis - Informacije Element treba dozvolu pristupa Vašoj kolekciji fotografija i video zapisa za slanje i spremanje privitaka. \n @@ -352,25 +310,20 @@ Element može provjeriti Vaš imenik kako bi našao druge korisnike Matrixa temeljem njihove e-pošte i telefonskih brojeva. \n \nŽelite li podijeliti imenik u ove svrhe\? - Nažalost, radnja nije izvršena zbog nedostatka dozvola - Spremljeno Spremiti u preuzimanja\? DA NE Nastavi - Ukloni Pridruži se Pregledaj Odbij - Nabroji članove Otvori zaglavlje Sinkroniziranje… Idi na prvu nepročitanu poruku. - %s Vas je pozvao/la da se pridružite u ovu sobu Pozivnica je poslana na adresu %s koja nije povezana s ovim računom. \nMožete se prijaviti s drugim računom ili dodati ovu e-poštu Vašem računu. @@ -391,7 +344,6 @@ %d članova 1 član - %d s %d s @@ -412,23 +364,19 @@ %d d %d d - Napusti sobu Jeste li sigurni da želite napustiti sobu\? Jeste li sigurni da iz ovog ćaskanja želite ukloniti %s\? Izradi - Na vezi Odspojen u dokolici Sada %1$s %1$s %2$s - ADMINISTRATORSKI ALATI POZIV IZRAVNA ĆASKANJA SESIJE - Pozovi Napusti ovu sobu Izbaci iz ove sobe @@ -444,19 +392,15 @@ Spomeni Prikaži listu sesija Razlog - "%1$s, " %1$s i %2$s %1$s%2$s - Pozovi koristeći identitet LOKALNI KONTAKTI (%d) POPIS KORISNIKA (%s) Samo korisnici Matrixa - Pozovi korisnika koristeći identitet E-pošta ili identitet u Matrixu - Pretraga %s tipka… %1$s i %2$s tipkaju… @@ -479,7 +423,6 @@ %d nove poruke %d novih poruka - Vjeruj Ne vjeruj Odjavi se @@ -499,14 +442,12 @@ Izobličeni identitet. Trebalo bi se raditi o adresi e-pošte ili identitetu u Matrixu poput \'@lokalni_dio:domena\' POZVANI PRIDRUŽILI SE - Razlog za prijavu ovog sadržaja Želite li sakriti sve poruke ovog korisnika\? \n \nOva radnja će ponovno pokrenuti aplikaciju i to bi moglo potrajati. Otkaži slanje Otkaži preuzimanje - Traži Izdvoji članove sobe Nema rezultata @@ -514,7 +455,6 @@ PORUKE OSOBE DATOTEKE - PRIDRUŽILI SE POPIS OMILJENO @@ -526,7 +466,6 @@ Pridruži se sobi Pridruži se sobi Unesite identitet ili alternativni naziv sobe - Pregledaj popis %d soba @@ -539,7 +478,6 @@ Pronađeno %1$s soba za %2$s Pretražujem popis… - Sve poruke (bučno) Sve poruke Samo sa spomenom @@ -549,7 +487,6 @@ Napusti razgovor Zaboravi Dodaj prečac na početni zaslon - Poruke Postavke Inačica @@ -558,7 +495,6 @@ Obavijesti trećih strana Autorsko pravo Pravila privatnosti - Profilna slika Ime za prikaz E-pošta @@ -569,7 +505,6 @@ Prikaži informacije o aplikaciji u postavkama sustava. Nećete moći poništiti ovu izmjenu jer dotičnom korisniku dajete istu razinu upravljanja kao Vaša. \nJeste li sigurni\? - Jeste li sigurni da želite zabraniti korisniku pristup ovom razgovoru\? Jeste li sigurni da želite pozvati %s u ovoj razgovor\? Unesite jednu ili više adresa e-pošte ili identitet u Matrixu @@ -577,16 +512,12 @@ Certifikat se promijenio u odnosu na onaj kojeg Vaš uređaj smatra pouzdanim. Ovo je VRLO NEOBIČNO. Preporuka je NE PRIHVATITI ovaj novi certifikat. Došlo je do promjene od certifikata kojem vjerujete do certifikata kojem ne vjerujete. Moguće je da je došlo do obnavljanja certifikata na poslužitelju. Tražite od poslužiteljskog administratora očekivani otisak prsta. Prihvatite certifikat samo ako je poslužiteljski administrator objavio otisak prsta koji odgovara gore navedenom otisku. - Smanji prioritet Potvrdite Vašu lozinku Ovo nije moguće napraviti iz mobilne inačice Elementa Potrebna je ovjera - - Napredne postavke obavijesti Važnost obavijesti po događajima - Privatnost obavještavanja Rješavanje problema s obavijestima Tehnička dijagnostika u rješavanju problema @@ -595,37 +526,31 @@ Osnovna dijagnostika je uredna. Ako i dalje ne dobivate obavijesti, pošaljite izvješće o grešci kako bi se mogao utvrditi problem. Jedan ili više testova nisu uspjeli pa pokušajte s predloženim ispravkom/ama. Jedan ili više testova nije uspjelo, pošaljite izvješće o grešci kako bi se mogao utvrditi problem. - Postavke sustava. Obavijesti se uključuju u postavkama sustava. Obavijesti se isključuju u postavkama sustava. \nProvjerite postavke sustava. Otvori postavke - Postavke računa. Obavijesti su uključene za Vaš račun. Obavijesti su isključene za Vaš račun. \nProvjerite postavke računa. Uključi - Postavke sesije. Obavijesti su uključene za ovu sesiju. Obavijesti su isključene za ovu sesiju. \nProvjerite postavke Elementa. Uključi - Prilagođene postavke. Uočite da su neke poruke postavljene na tiho (doći će do obavijesti bez zvuka). Neke obavijesti su isključene u prilagođenim postavkama. Neuspjelo učitavanje prilagođenih pravila, pokušajte ponovno. Provjeri postavke - Provjera Usluga za Play APK Usluga za Google Play je dostupan i ažuriran. Element koristi Usluge za Google Play kako bi isporučio poruke, no čini se da nisu ispravno podešene. \n%1$s Popravi Usluge za Play - Firebaseova oznaka Oznaka FCM-a je uspješno dohvaćena: \n%1$s @@ -638,27 +563,22 @@ [%1$s] \nElement nema kontrolu nad ovom greškom. Na uređaju ne postoji račun pri Googleu. Možete otvoriti upravitelja računima i dodati račun pri Googleu. Dodaj račun - Registracija oznake Oznaka FCM-a je uspješno registrirana pri Vašem poslužitelju. Neuspjela registracija oznake FCM-a pri Vašem poslužitelju: \n%1$s - Servis za obavijesti Servis za obavijesti je pokrenut. Servis za obavijesti nije pokrenut. \nPokušajte ponovno pokrenuti aplikaciju. Pokreni servis - Automatsko ponovno pokretanje Servisa za obavijesti Servis je zaustavljen i automatski ponovno pokrenut. Neuspjelo ponovno pokretanje servisa - Pokreni pri podizanju sustava Servis će se pokrenuti prilikom ponovnog pokretanja uređaja. Servis se neće pokrenuti sa ponovnim pokretanjem uređaja pa nećete primati obavijesti sve dok ne otvorite Element. Omogući pokretanje pri podizanju sustava - Provjeri pozadinska ograničenja Pozadinska su ograničenja onemogućena za Element. Ovaj test trebate izvršiti putem podatkovne veze (bez WIFI-ja). \n%1$s @@ -666,12 +586,10 @@ \nRadnje koje aplikacija pokušava napraviti su bitno ograničene dok je u pozadini i ovo možete utjecati na obavijesti. \n%1$s Onemogući ograničenja - Optimiranje baterije Optimiranje baterije ne utječe na Element. Ako korisnik uz ugašen zaslon ostavi uređaj nepriključenog i u mirovanju tijekom nekog vremena, uređaj će ući u način drijemanja. Ovo aplikacijama onemogućuje pristup mreži i odgađa njihove zadatke, sinkronizaciju i uobičajene alarme. Zanemari optimiranje - Obično Umanjena privatnost Aplikaciji treba dozvola za rad u pozadini @@ -681,7 +599,6 @@ • Sadržaj obavijesti je sigurno pohranjen na Vašem poslužitelju Matrixa • Obavijesti sadrže poruku i metapodatke • Obavijesti neće prikazivati sadržaj poruke - Zvuk obavijesti Isključi obavijesti za ovaj račun Uključi obavijesti za ovu sesiju @@ -690,8 +607,6 @@ Podesi obavijesti o pozivima Podesi tihe obavijesti Odaberite boju indikatorske lampice, vibriranje, zvuk… - - Poruke koje sadrže moje ime za prikaz Poruke koje sadrže moje korisničko ime Poruke u individualnim razgovorima @@ -699,7 +614,6 @@ Kad sam pozvan/a u sobu Pozivnice za pozive Poruke koje je poslao bot - Pozadinska sinkronizacija Način pozadinske sinkronizacije (eksperimentalno) Optimirano za bateriju @@ -711,8 +625,6 @@ Bez pozadinske sinkronizacije Nećete primati obavijesti o dolaznim porukama kada je aplikacija u pozadini. Neuspjela promjena postavki. - - Pokreni pri podizanju sustava Omogući pozadinsku sinkronizaciju Istekao je sinkronizacijski zahtjev @@ -720,7 +632,6 @@ %s \nSinkronizacija može biti odgođena ovisno o sredstvima (baterija) ili stanju uređaja (spavanje). Razmak između dvije sinkronizacije - Inačica Inačica olm-a Uvjeti korištenja @@ -730,7 +641,6 @@ Zadrži medijske datoteke Izbriši priručnu memoriju Izbriši medijsku priručnu memoriju - Korisničke postavke Obavijesti Ignorirani korisnici @@ -765,7 +675,6 @@ Pregledaj medij prije slanja Pošalji poruku pritiskom tipke Enter Tipka Enter na softverskoj tipkovnici će poslati poruku umjesto dodavanja novog retka - Deaktiviraj račun Deaktiviraj moj račun Pronalaženje @@ -774,21 +683,17 @@ Element se može izvršavati u pozadini kako bi sigurno i privatno upravljao Vašim obavijestima. Ovo može utjecati na potrošnju baterije. Dozvoli Izaberi drugu opciju - Pozadinska veza Element treba održati pozadinsku vezu s malim utjecajem kako bi imao pouzdane obavijesti. \nNa sljedećem zaslonu potvrdite Elementov zahtjev za stalnim izvršavanjem u pozadini. Dozvoli - Analitika Pošalji analitičke podatke Element skuplja anonimnu analitiku kako bi se unaprijedila aplikacija. Omogućite analitiku ako želite pomoći unaprijediti Element. Da, želim pomoći! - Način uštede podataka Način uštede podataka primjenjuje određeno izdvajanje u kojem se ne navode novosti o prisutnosti i obavijesti o tipkanju. - Pojedinosti sesije Identitet Javno ime @@ -800,17 +705,14 @@ Ovjera Lozinka: Pošalji - Prijavljen/a kao Vaš poslužitelj Poslužitelj identiteta Omogući integracije Upravitelj integracijama - Korisničko sučelje Jezik Izaberi jezik - Čeka se potvrda Provjerite Vašu e-poštu i kliknite na sadržanu poveznicu. Nakon što ovo učinite, kliknite za nastavak. Nije moguće potvrditi adresu e-pošte. Provjerite Vašu e-poštu i kliknite na sadržanu poveznicu. Nakon što ovo učinite, kliknite za nastavak. @@ -818,7 +720,6 @@ Nije pronađena ova adresa e-pošte. Ovaj se telefonski broj već koristi. Došlo je do greške tijekom potvrde Vaše adrese e-pošte. - Lozinka Promijenite lozinku Sadašnja lozinka @@ -832,13 +733,9 @@ \n \nOva će radnja ponovno pokrenuti aplikaciju i to bi moglo potrajati. Lozinke se ne podudaraju - Jeste li sigurni da želite ukloniti ovo obavijesno odredište\? - Jeste li sigurni da želite ukloniti %1$s %2$s\? - Odaberite državu - Država Odaberite državu Telefonski broj @@ -850,27 +747,22 @@ Kôd Došlo je do greške tijekom potvrde Vašeg telefonskog broja. Dodatne informacije: %s - Mediji Zadano komprimiranje Izaberite Zadani izvor medija Izaberite Reproduciraj zvuk poklopca - Trenutno niste član ni jedne zajednice. - Tri dana Jedan tjedan Jedan mjesec Zauvijek - Sobna fotografija Naziv sobe Tema Oznaka sobe Označena kao: - Omiljeno Nizak prioritet Ovaj grafički element želi koristiti sljedeća sredstva: @@ -879,11 +771,9 @@ Koristi kameru Koristi mikrofon Čitaj medije ograničene DRM-om - Prekoračeno ograničenje sredstava Ovaj poslužitelj je prekoračio jedno od ograničenja sredstava pa se neki korisnici neće moći prijaviti. Ovaj je poslužitelj prekoračio jedno od ograničenja sredstava. - Neuspjela izrada grafičkog elementa. Neuspjelo slanje zahtjeva. Razina upravljanja treba biti pozitivan cijeli broj. @@ -902,7 +792,6 @@ Šalji glasovne poruke Ova opcija zahtijeva aplikaciju treće strane za snimanje poruka. Za nastavak trebate prihvatiti Uvjete korištenja ovog servisa. - Dodali ste novu sesiju \'%s\' koja zahtijeva ključeve za šifriranje. Nova sesija zahtijeva ključeve za šifriranje. Naziv sesije: %1$s \nZadnji puta viđena: %2$s @@ -912,7 +801,6 @@ \nNaziv sesije: %1$s \nZadnji puta viđena: %2$s \nAko se niste prijavili u drugoj sesiji, zanemarite ovaj zahtjev. - Započni potvrdu Potvrdi Dijeli bez potvrđivanja @@ -920,10 +808,8 @@ Zahtjev za dijeljenje ključeva Zanemari zahtjev Zanemari - Upozorenje! Konferencijsko zvanje je u razvoju i potencijalno nepouzdano. - Naredbena greška Nepoznata naredba: %s Naredba \"%s\" treba više parametara ili su neki parametri netočni. @@ -941,109 +827,85 @@ Uključi/isključi Markdown Markdown je omogućen. Markdown je onemogućen. - Isključeno Tiho Bučno - Šifrirana poruka - Formiraj Formiraj zajednicu Naziv zajednice Primjer Identitet zajednice primjer - Osobe Sobe Nema korisnika - Sobe Pridružen/a Pozvan/a Izdvoji članove grupe Izdvoji grupne sobe - - %1 član - %1 člana - %1 članova + %d član + %d člana + %d članova - - %1 soba - %1 sobe - %1 soba + %d soba + %d sobe + %d soba Administrator zajednice nije dao dugačak opis ove zajednice. - Izbačeni ste iz %1$s od strane %2$s Korisnik %2$s Vam je zabranio pristup sobi %1$s Razlog: %1$s Ponovno se pridruži Zaboravi sobu - Avatar za potvrde Obavijesni avatar Avatar - Za nastavak korištenja %1$s kao Vašeg poslužitelja ćete morati pročitati i složiti se s uvjetima korištenja. Sada pročitaj - Deaktiviraj račun Neka sve poruke koje sam poslao/la budu zaboravljene kada deaktiviram svoj račun (upozorenje: zbog ovoga će budući korisnici imati nepotpun uvid u razgovore) Za nastavak unesite Vašu lozinku: Deaktiviraj račun - Unesite korisničko ime. Unesite Vašu lozinku. Ova je soba zamijenjena i više nije aktivna Razgovor se ovdje nastavlja Ova je soba nastavak drugog razgovora Ovdje kliknite kako biste vidjeli starije poruke - Obratite se administratoru - obratite se administratoru Vašeg servisa - Vaš je poslužitelj dosegao svoje ograničenje mjesečno aktivnih korisnika pa se neki korisnici neće moći prijaviti. Vaš je poslužitelj dosegao svoje ograničenje mjesečno aktivnih korisnika. - Molimo %s za povećanje ovog ograničenja. Molimo %s za nastavak korištenja ovog servisa. - Lijeno učitavanje članova soba Povećaj performanse učitavanjem članova soba tek na prvo otvaranje. Vaš poslužitelj ne podržava lijeno učitavanje članova soba. Pokušajte kasnije. - Nažalost je došlo do greške - proširi sažmi - Prikaži ovu informativnu zonu Uvijek Za poruke i greške Samo za greške - %1$s: %1$s: %2$s +%d %d+ Nije pronađen valjajući APK Usluga za Google Play. Moguće je da obavijesti neće ispravno raditi. - Napravi fraza-lozinku Potvrdi fraza-lozinku Unesite fraza-lozinku Fraza-lozinka se ne podudara Unesite fraza-lozinku Fraza-lozinka je preslaba - Izbrišite fraza-lozinku ako želite da Element generira ključ za obnovu. Zahtjev za potvrdom %s želi potvrditi Vašu sesiju - Korisnik je prekinuo potvrdu Isteklo je vrijeme za proces potvrde Sesija nije upoznata s tom transakcijom @@ -1055,20 +917,15 @@ Nepodudaranje u ključevima Nepodudaranje u korisnicima Nepoznata greška - Ne koristite poslužitelja identiteta Nije podešen poslužitelj identiteta. Potreban je za poništavanje Vaše lozinke. - Čini se da se pokušavate spojiti na drugi poslužitelj. Želite li se odjaviti\? - Uredi Odgovori - Pokušaj ponovno Pridružite se sobi kako biste počeli koristiti aplikaciju. Poslana Vam je pozivnica Pozvan/a od %s - Sve ste pročitali! Više nemate nepročitanih poruka Dobrodošli! @@ -1077,19 +934,15 @@ Poruke Vaših izravnih razgovora ovdje će biti prikazane Sobe Ovdje će biti prikazane Vaše sobe - Reakcije Složi se Sviđa mi se Dodaj reakciju Pogledaj reakcije Reakcije - Događaj je izbrisao korisnik Sobni administrator je moderirao događaj %1$s zadnji/a uredio/la dana %2$s - - Nije moguće prikazati izobličen događaj Izradi novu sobu Nema mreže. Provjerite Vašu vezu na Internet. @@ -1097,48 +950,33 @@ Promijeni mrežu Pričekajte… Sve zajednice - Nije moguće pregledati sobu Pregled sobe u koju svatko ima uvid još nije podržan u Element-u - Sobe Izravne poruke - Nova soba IZRADI - - Uređivanja poruka Nisu pronađena uređivanja - Izdvoji razgovore… Ne možete naći što tražite\? Izradi novu sobu Pošalji novu izravnu poruku Prikaži popis soba - Naziv ili identitet (#primjer:matrix.org) - Omogući povlačenje za odgovaranje u vremenskoj crti - Poveznica kopirana u spremnik - Dodaj po identitetu u Matrixu Izrađuje se soba… Nema rezultata. Koristite Dodaj po identitetu u Matrixu za pretraživanje poslužitelja. Počnite tipkati za prikaz rezultata Izdvoji po korisničkom imenu ili identitetu… - Pridruživanje sobi u tijeku… - Prikaži povijest uređivanja - Uvjeti korištenja Pregledaj uvjete Budite drugima vidljivi Pročitano u - - Poslužitelj identiteta Prekini vezu s poslužiteljem identiteta Podesi poslužitelja identiteta @@ -1152,27 +990,19 @@ Vidljivi telefonski brojevi Poslan Vam je potvrdna e-pošta na %s. Provjerite Vašu poštu i kliknite na potvrdnu poveznicu Na čekanju - Unesite novog poslužitelja identiteta Nije moguće spojiti se na poslužitelja identiteta Unesite URL poslužitelja identiteta Poslužitelj identiteta nema uvjete korištenja Odabrani poslužitelj identiteta nema uvjete korištenja. Nastavite samo ako vjerujete vlasniku servisa Tekstualna poruka je poslana na %s. Unesite potvrdni kȏd iz poruke. - Trenutno dijelite adrese e-pošte ili telefonske brojeve s poslužiteljem identiteta %1$s. Ponovno se spojite na %2$s kako biste ih prestali dijeliti. Prihvatite uvjete korištenja poslužitelja identiteta (%s) kako biste bili vidljivi temeljem adrese e-pošte ili telefonskog broja. - Omogući opširne zapise. Opširni zapisi pomažu razvijateljima u vidu detaljnih informacija kada pošaljete Gnjevno drmanje. Čak i kada su omogućeni, aplikacija ne zapisuje sadržaj poruka ili bilo koje druge privatne podatke. - - Pokušajte ponovno nakon što prihvatite uvjete korištenja Vašeg poslužitelja. - Čini se da poslužitelju treba previše vremena za odgovor. Mogući uzroci su loša povezivost ili greška na poslužitelju. Kasnije pokušajte ponovno. - Pošalji privitak - Otvori navigacijski pretinac Otvori izbornik za izradu soba Zatvori izbornik za izradu soba… @@ -1186,7 +1016,6 @@ \nUpravitelji integracijama primaju konfiguracijske podatke i mogu mijenjati grafičke elemente, slati pozivnice za pridruživanje u sobe i postavljati razine upravljanja u Vaše ime. Sklonost Ništa - Pristup i vidljivost Prikaži ovu sobu u popisu soba Obavijesti @@ -1194,19 +1023,15 @@ Čitljivost sobne povijesti Tko može čitati povijest\? Tko može pristupiti ovoj sobi\? - Bilo tko Samo članovi (od trenutka odabira ove opcije) Samo članovi (od trenutka kad su pozvani) Samo članovi (od trenutka kad su se pridružili) - Soba mora imati adresu kako bi se za nju mogla ponuditi poveznica. Samo osobe koje su pozvane Bilo tko osim gostiju, a da zna sobnu poveznicu Bilo tko, uključujući goste, a da zna sobnu poveznicu - Korisnici sa zabranom pristupa - Napredno Interni identitet sobe Adrese @@ -1217,44 +1042,33 @@ Potrebno je odjaviti se da bi se moglo omogućiti šifriranje. Šifriraj samo za potvrđene sesije Nikada iz ove sesije ne šaljite šifrirane poruke nepotvrđenim sesijama u ovoj sobi. - Ova soba nema lokalnih adresa Nova adresa (npr. #foo:matrix.org) - Ova soba ne pokazuje sklonost bilo kojoj zajednici Novi identitet zajednice (npr. +foo:matrix.org) Neispravan identitet zajednice \'%s\' nije ispravan identitet zajednice - - Neispravni oblik za alternativni naziv \'%s\' nije ispravni oblik za alternativni naziv Neće postojati glavna adresa za ovu sobu. Upozorenja za glavnu adresu - Postavi za glavnu adresu Izbriši glavnu adresu Kopiraj identitet sobe Kopiraj adresu sobe - Šifriranje je omogućeno u ovoj sobi. Šifriranje je onemogućeno u ovoj sobi. Omogući šifriranje (upozorenje: ovo nije moguće naknadno onemogućiti!) - Popis Tema - %s je pokušavao učitati određenu točku s vremenske crte ove sobe, no nije ju mogao naći. - Informacije o šifriranju s kraja na kraj - Informacije o događaju Korisnički identitet Identitetski ključ za Curve25519 Algoritam Identitet sesije Greška u dešifriranju - Informacije o sesiji pošiljatelja Javni naziv Javni naziv (vidljivo osobama s kojima komunicirate) @@ -1271,7 +1085,6 @@ Sobni ključevi za E2E su spremljeni u \'%s\'. \n \nUpozorenje: moguće je da će ova datoteka biti izbrisana uklanjanjem aplikacije. - Povrat šifriranih poruka Uvezi sobne ključeve za E2E Uvezi sobne ključeve @@ -1279,25 +1092,20 @@ Uvezi Šifriraj samo ka potvrđenim sesijama Nikada iz ove sesije ne šalji šifrirane poruke nepotvrđenim sesijama. - Nije potvrđeno Potvrđeno Na crnoj listi - Nepoznata sesija nepoznata IP adresa ništa - Potvrdi Ukloni potvrdu Stav na crnu listu Ukloni s crne liste - Potvrdi sesiju Potvrdite usporedbom sljedećeg s korisničkim postavkama u Vašoj drugoj sesiji: Ako se ne podudaraju, sigurnost Vaše komunikacije može biti narušena. Potvrđujem da ključevi odgovaraju - Soba sadrži nepoznate sesije Odaberite popis soba Moguće je da je poslužitelj nedostupan ili preopterećen @@ -1305,9 +1113,7 @@ URL poslužitelja Sve sobe na poslužitelju %s Sve izvorne sobe s %s - Ovdje tipkajte… - %d nepročitana obavijesna poruka %d nepročitane obavijesne poruke @@ -1323,7 +1129,6 @@ %d sobe %d soba - %1$s: %2$d poruka %1$s: %2$d poruke @@ -1334,7 +1139,6 @@ %d obavijesti %d obavijesti - %1$s u %2$s Novi događaj Soba @@ -1344,9 +1148,7 @@ ** Neuspjelo slanje - otvorite sobu %1$s: %2$s %1$s: %2$s %3$s - Traži prijašnje - Veličina pisma Sićušna Mala @@ -1355,7 +1157,6 @@ Veća Najveća Ogromna - Potrebna Vam je dozvola za upravljanje grafičkim elementima u ovoj sobi Stvaranje grafičkog elementa nije uspjelo Uspostavljanje konferencijskih poziva kroz Jitsi @@ -1365,8 +1166,6 @@ %d aktivna grafička elementa %d aktivnih grafičkih elemenata - - Grafički element Učitaj grafički element Ovaj je grafički element dodao/la: @@ -1377,28 +1176,22 @@ Ponovno učitaj grafički element Otvori u web pregledniku Opozovi moj pristup - Vaše ime za prikaz URL Vašeg avatara Vaš korisnički identitet Vaša tema Identitet grafičkog elementa Identitet sobe - - Nažalost konferencijski pozivi kroz Jitsi nisu podržani na starim uređajima (uređaji s Androidom inačice manje od 6.0) Za popravak upravljanja aplikacijama unutar Matrixa - Početna Nije dostupna ni jedna sesija Matrixa - Nikada ne izgubite šifrirane poruke Poruke u šifriranim sobama su osigurane šifriranjem s kraja na kraj. Samo Vi i primatelj(i) imate ključeve za čitanje ovih poruka. \n \nNapravite sigurnosnu kopiju Vaših ključeva kako ih ne biste izgubili. (Napredno) Ručno izvezi ključeve - Zaštitite svoju sigurnosnu kopiju rečeničnom lozinkom. Šifriran primjerak Vaših ključeva bit će spremljen na Vašem poslužitelju. Zaštitite Vašu sigurnosnu kopiju fraza-lozinkom. \n @@ -1414,18 +1207,14 @@ Utišano Napusti sobu Napravite dugi klik na sobu za više opcija - - %1$s je učinio/la sobu javnom svakome tko zna poveznicu. %1$s je učinio/la sobu dostupnom samo putem pozivnice. Nepročitane poruke - Oslobodite svoju komunikaciju Ćaskajte s ljudima izravno ili u grupama Neka razgovori budu privatni uz šifriranje Proširite i podesite Vaše iskustvo Započni - Odaberite poslužitelja Poput e-pošte, računi imaju jedan dom, no možete razgovarati s bilo kime Pridružite se milijunima koji su slobodni na najvećem javnom poslužitelju @@ -1433,7 +1222,6 @@ Naučite više Drugo Prilagođene i napredne postavke - Nastavi Spoji se na %1$s Spoji se na Element Matrix Services @@ -1442,13 +1230,11 @@ Otvori račun Prijavi se Nastavi sa SSO-om - Adresa u Element Matrix Services u Adresa Plaćeno gošćenje za organizacije Unesite adresu Modular Elementa ili poslužitelja koji želite koristiti Unesite adresu poslužitelja ili Elementa na koji se želite spojiti - Došlo je do greške pri učitavanju stranice: %1$s (%2$d) Aplikacija se ne može prijaviti na ovog poslužitelja. Poslužitelj podržava sljedeće vrste prijava: %1$s. \n @@ -1457,40 +1243,30 @@ Aplikacija ne može otvoriti račun na ovom poslužitelju. \n \nŽelite li otvoriti račun pomoću web-klijenta\? - Ova e-pošta nije vezana ni uz koji račun. - Poništi lozinku na %1$s Bit će Vam poslana kontrolna e-pošta u Vaš sandučić radi potvrde postavljanja nove lozinke. Dalje E-pošta Nova lozinka - Upozorenje! Promjena lozinke će poništiti sve ključeve za šifriranje od kraja do kraja u svim Vašim sesijama, zbog čega će šifrirana povijest ćaskanja biti nečitljiva. Podesite pričuvu ključeva ili izvezite ključeve Vaših soba pomoću druge sesije prije nego poništite Vašu lozinku. Nastavi - Ova e-pošta nije povezana ni sa kojim računom - Provjerite Vaš sandučić Kontrolna e-pošta poslana je na adresu %1$s. Pritisnite poveznicu za potvrdu Vaše nove lozinke. Nakon što ste slijedili sadržanu poveznicu, kliknite ispod. Potvrdio/la sam svoju adresu e-pošte - Uspješno provedeno! Vaša je lozinka poništena. Odjavljeni ste iz svih sesija i više nećete primati obavijesti. Kako biste ponovno omogućili obavijesti, ponovno se prijavite na svakom uređaju. Povratak na prijavu - Upozorenje Vaša lozinka nije promijenjena. \n \nŽelite li zaustaviti proces promjene lozinke\? - Opis je prekratak - Ubacuje ¯\\_(ツ)_/¯ prije početka tekstualne poruke - %s potvrđen/a Čekanje na %s… Za dodatnu sigurnost, potvrdite korisnika/cu %s provjerom jednokratnog kôda na oba uređaja. @@ -1513,64 +1289,45 @@ Slanja Napusti sobu Napuštanje sobe… - Administratori Moderatori Prilagođeno Pozivnice Korisnici - Administrator u %1$s Moderator u %1$s Prilagođeno (%1$d) u %2$s - Skoči na potvrdu o pročitanoj poruci - Element ne podržava događaje tipa \'%1$s\' Element ne podržava poruke tipa \'%1$s\' Element je naišao na problem pri prikazu sadržaja događaja s identitetom \'%1$s\' - Ukloni zanemarivanje - Nedavne sobe Druge sobe - Šalje danu poruku obojanu duginim bojama Vremenska crta - Uređivač poruka - Omogući šifriranje s kraja na kraj Šifriranje nije moguće onemogućiti jednom kad se omogući. - Omogućiti šifriranje\? Šifriranje nije moguće onemogućiti jednom kad se omogući. Poslužitelj ne može vidjeti poruke koje su poslane u šifriranu sobu, već ih mogu vidjeti samo sudionici u sobi. Omogućavanje šifriranja može uzrokovati poteškoće u radu mnogim botovima i mostovima. Omogući šifriranje - Kako biste bili sigurni, potvrdite %s provjerom jednokratnog kôda. Kako biste bili sigurni, ovo učinite osobno ili koristite drugi način komuniciranja. - Usporedite jedinstvene emojije i potvrdite da se pojavljuju istim redoslijedom. Usporedite kôd s onim prikazanim na zaslonu drugog korisnika. Poruke s ovim korisnikom su šifrirane s kraja na kraj te ih ne mogu pročitati treće strane. Vaša je nova sesija sada potvrđena. Sesija ima pristup Vašim šifriranim porukama te će ju drugi korisnici vidjeti kao pouzdanu. - - Aktivne sesije Prikaži sve sesije Upravljanje sesijama Odjavi se iz ove sesije - Nisu dostupne kriptografske informacije - Ova je sesija pouzdana za sigurno dopisivanje jer ste ju Vi potvrdili: Ključ za poruke Generiraj ključ za poruke - Šalje poruku u jasnom tekstu bez interpretacije u Markdownu - Poruka… - Uspješno dovršeno! Izrada sigurnosne kopije ključeva je u tijeku. Dovršeno @@ -1586,17 +1343,12 @@ Bilo tko moći će se pridružiti sobi Popis soba Objavi ovu sobu u popisu soba - Došlo je do greške pri dohvaćanju podataka iz sigurnosne kopije ključeva - Uvezi ključeve za E2E iz datoteke \"%1$s\". - Inačica Matrix SDK-a Druge obavijesti trećih strana Već se nalazite u toj sobi! - Brze reakcije - Općenito Postavke Sigurnost i privatnost @@ -1609,14 +1361,10 @@ session_name: URL: Oblik: - Glas i video Pomoć i o aplikaciji - - Izravne poruke - Ukloni… Potvrda uklanjanja Jeste li sigurni da želite ukloniti (izbrisati) ovaj događaj\? Ukoliko izbrišete naziv sobe ili promjenu teme, to može poništiti promjenu. - + \ No newline at end of file From 848ff5b806a566253e1e9a55409cd3ea79d99e44 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 15 Feb 2021 10:34:15 +0000 Subject: [PATCH 10/29] Translated using Weblate (Italian) Currently translated at 100.0% (2081 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/it/ --- vector/src/main/res/values-it/strings.xml | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index c5db349d35..b3e6992439 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -2376,4 +2376,37 @@ Autorizzazioni stanza Questa stanza non è pubblica. Non potrai rientrare senza un invito. Predefinito di sistema + Autenticazione fallita + Element richiede di reinserire le credenziali per eseguire questa azione. + Necessario riautenticarsi + Utenti + Si è verificato un errore trasferendo la chiamata + Trasferisci + Connetti + Prima consulta + + 1 chiamata attiva (%1$s) · 1 chiamata in pausa + 1 chiamata attiva (%1$s) · %2$d chiamate in pausa + + + Chiamata in pausa + %1$d chiamate in pausa + + Chiamata attiva (%1$s) + Si è verificato un errore cercando il numero di telefono + Tastierino numerico + Richiama + Questa chiamata è terminata + %1$s ha rifiutato questa chiamata + Hai rifiutato questa chiamata %1$s + Sei attualmente in questa chiamata + %1$s ha iniziato una chiamata + Hai iniziato una chiamata + Impostazione della firma incrociata fallita + Hai messo la chiamata in attesa + %s ha messo la chiamata in attesa + In attesa + Riprendi + Non autorizzato, credenziali di autenticazione valide mancanti + Torna \ No newline at end of file From acc03abd033c3ae6dab9d97f689feecff37f1940 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 Feb 2021 12:05:35 +0000 Subject: [PATCH 11/29] Translated using Weblate (Polish) Currently translated at 95.3% (1985 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/ --- vector/src/main/res/values-pl/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index c336c9882c..f69dc1d5d2 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -791,10 +791,10 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo - % godzina - %s godz. - - + %d godzina + %d godz. + + %d dzień @@ -2211,8 +2211,8 @@ Spróbuj uruchomić ponownie aplikację. %1$s, %2$s i %3$d czyta %1$s, %2$s i %3$d czytają - - + + Nie udało się uzyskać widoczności katalogu bieżącego pokoju (%1$s). Skonfiguruj na tym urządzeniu From efeb41151c15038299f7f8032fe428ccc731488a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 Feb 2021 12:06:54 +0000 Subject: [PATCH 12/29] Translated using Weblate (Albanian) Currently translated at 96.4% (2007 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/ --- vector/src/main/res/values-sq/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index 9cc4d6ad7c..27245ea122 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -1751,7 +1751,7 @@ Caktoni një %s Prodhoni një Kyç Mesazhesh Ripohoni %s - Që të vazhdohet, jepni % tuaj. + Që të vazhdohet, jepni %s tuaj. Siguroni & shkyçni mesazhet tuaj të fshehtëzuar dhe besim me një %s. Për ta ripohuar, rijepni %s tuaj. Mos ripërdorni fjalëkalimin e llogarisë tuaj. From 8b862e917ac6681f63996330e495627ff25a425f Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Fri, 12 Feb 2021 14:49:47 +0000 Subject: [PATCH 13/29] Translated using Weblate (Swedish) Currently translated at 98.9% (2059 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/ --- vector/src/main/res/values-sv/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 36d4ea69ad..c203e48839 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -1891,7 +1891,7 @@ Användare Administratör i %1$s Moderator i %1$s - Standard i %1$s + Standardbehörig i %1$s Anpassad (%1$d) i %2$s Hoppa till läskvitto Element hanterar inte händelser av typen \'%1$s\' From 60041d433ead8b5cdab5ba6531dafd654b85b062 Mon Sep 17 00:00:00 2001 From: zer0-x <1rn0kmrwo@relay.firefox.com> Date: Sun, 14 Feb 2021 10:46:00 +0000 Subject: [PATCH 14/29] Translated using Weblate (Arabic) Currently translated at 55.7% (126 of 226 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.element.io/projects/element-android/element-sdk/ar/ --- .../src/main/res/values-ar/strings.xml | 209 +++++++++--------- 1 file changed, 106 insertions(+), 103 deletions(-) diff --git a/matrix-sdk-android/src/main/res/values-ar/strings.xml b/matrix-sdk-android/src/main/res/values-ar/strings.xml index 0fc7bd1b49..0da4dc8f8e 100644 --- a/matrix-sdk-android/src/main/res/values-ar/strings.xml +++ b/matrix-sdk-android/src/main/res/values-ar/strings.xml @@ -1,147 +1,150 @@ - + - - أرسل ⁨%1$s⁩ صورة. - - دعوة من ⁨%s⁩ - دعى ⁨%1$s⁩ ⁨%2$s⁩ - دعاك ⁨%1$s⁩ - انضمّ ⁨%1$s⁩ إلى الغرفة - غادر ⁨%1$s⁩ الغرفة - رفض ⁨%1$s⁩ الدعوة - طرد ⁨%1$s⁩ ⁨%2$s⁩ - رفع ⁨%1$s⁩ المنع عن ⁨%2$s⁩ - منع ⁨%1$s⁩ ⁨%2$s⁩ - غيّر ⁨%1$s⁩ صورته - ضبط ⁨%1$s⁩ اسم العرض على ⁨%2$s⁩ - غيّر ⁨%1$s⁩ اسم العرض من ⁨%2$s⁩ إلى ⁨%3$s⁩ - أزال ⁨%1$s⁩ اسم العرض (⁨كان ⁨%2$s⁩) - غيّر ⁨%1$s⁩ الموضوع إلى: ⁨%2$s⁩ - غيّر ⁨%1$s⁩ اسم الغرفة إلى: ⁨%2$s⁩ - ردّ ⁨%s⁩ على المكالمة. - أنهى ⁨%s⁩ المكالمة. - جعل ⁨%1$s⁩ تأريخ الغرفة مستقبلًا ظاهرًا على ⁨%2$s⁩ - كل أعضاء الغرفة من لحظة دعوتهم. - كل أعضاء الغرفة من لحظة انضمامهم. - كل أعضاء الغرفة. - الكل. - المجهول (⁨%s⁩). - فعّل ⁨%1$s⁩ تعمية الطرفين (⁨%2$s⁩) - - طلب ⁨%1$s⁩ اجتماع VoIP - بدأ اجتماع VoIP - انتهى اجتماع VoIP - - أزال ⁨%1$s⁩ اسم الغرفة - أزال ⁨%1$s⁩ موضوع الغرفة + %1$s قد أرسل صورة. + دعوة من %s + %1$s قد دعى %2$s + %1$s قد دعاك أنت + %1$s قد إنضّم إلى الغرفة + %1$s قد غادر الغرفة + %1$s قد رفض الدعوة + %1$s قد طرد %2$s + %1$s قد رفع الحظر عن %2$s + %1$s قد حظر %2$s + %1$s قد غيّر صورته الشخصية + %1$s قد عيّن اسمه الظاهر إلى %2$s + %1$s قد غيّر اسمه الظاهر من %2$s إلى %3$s + %1$s قد أزال اسمه الظاهر (لقد كان %2$s) + %1$s قد غيّر الموضوع إلى: %2$s + %1$s قد غيّر اسم الغرفة إلى: %2$s + %s قد أجاب على المُكالمة. + %s قد أنهى المُكالمة. + %1$s قد جعل التأريخ المُستقبلي للغرفة مرئيًا لـ %2$s + جميع أعضاء الغرفة، من اللحظة التي تمت دعوتهم. + جميع أعضاء الغرفة، من لحظة انضمامهم. + جميع أعضاء الغرفة. + أيُّ شخص. + غير معروف (%s). + %1$s قد فعّل تعمية النهاية-إلى-النهاية (%2$s) + %1$s قد طلب اجتماع VoIP + اجتماع VoIP قد بدأ + اجتماع VoIP قد انتهى + %1$s قد أزال اسم الغرفة + %1$s قد أزال موضوع الغرفة حدّث ⁨%1$s⁩ اللاحة ⁨%2$s⁩ أرسل ⁨%1$s⁩ دعوة إلى ⁨%2$s⁩ للانضمام إلى الغرفة ** تعذّر فك التعمية: ⁨%s⁩ ** لم يُرسل جهاز المرسل مفاتيح هذه الرسالة. - تعذّر إرسال الرسالة - فشل رفع الصورة - خطأ في الشبكة خطأ في «ماترِكس» - لا يمكنك حاليًا الانضمام ثانيةً إلى غرفة فارغة. - رسالة معمّاة - عنوان البريد الإلكتروني رقم الهاتف - ‏‏⁨%1$s⁩: ‏⁨%2$s⁩ - انسحب ⁨%1$s⁩ من دعوة ⁨%2$s⁩ - أجرى ⁨%s⁩ مكالمة مرئية. - أجرى ⁨%s⁩ مكالمة صوتية. + %1$s قد سحب دعوة %2$s + %s قد أجرى مُكالمة مرئية. + %s قد أجرى مُكالمة صوتية. قَبِل ⁨%1$s⁩ دعوة ⁨%2$s⁩ - تعذر التهذيب - أرسل ⁨%1$s⁩ ملصقًا. - - (تغيّرت الصورة أيضا) - + %1$s قد أرسل مُلصقًا. + (تمَّ تغيير الصورة أيضًا) دعوة من ⁨%s⁩ غرفة فارغة - ‏⁨%1$s⁩ و ⁨%2$s⁩ دعوة إلى غرفة - - - - - - - + + + + + + - - أرسلت صورة. - أرسلت ملصقًا. - + أنت قد أرسلت صورة. + أنت قد أرسلت مُلصقًا. دعوة منك أنت - أنشأ ⁨%1$s⁩ الغرفة - أنشأت الغرفة - دعوت ⁨%1$s⁩ - انضممت إلى الغرفة - غادرت الغرفة - رفضت الدعوة - طردت ⁨%1$s⁩ - رفعت المنع عن ⁨%1$s⁩ - منعت ⁨%1$s⁩ - انسحبت من دعوة ⁨%1$s⁩ - غيّرت صورتك - ضبطت اسم العرض على ⁨%1$s⁩ - غيّرت اسم العرض من ⁨%1$s⁩ إلى ⁨%2$s⁩ - أزلت اسم العرض (كان ⁨%1$s⁩) - غيّرت الموضوع إلى: ⁨%1$s⁩ - غيّر ⁨%1$s⁩ صورة الغرفة - غيّرت صورة الغرفة - غيّرت اسم الغرفة إلى: ⁨%1$s⁩ - أجريت مكالمة مرئية. - أجريت مكالمة صوتية. - أرسل ⁨%s⁩ البيانات لإعداد المكالمة. - أرسلت البيانات لإعداد المكالمة. - رددت على المكالمة. - أنهيت المكالمة. - جعلت تأريخ الغرفة مستقبلًا ظاهرًا على ⁨%1$s⁩ - فعّلت تعمية الطرفين (⁨%1$s⁩) - رقّى ⁨%s⁩ هذه الغرفة. - رقّيت هذه الغرفة. - - طلبت اجتماع VoIP - أزلت اسم الغرفة - أزلت موضوع الغرفة - أزال ⁨%1$s⁩ صورة الغرفة - أزلت صورة الغرفة - أُزيلت الرسالة - أزال ⁨%1$s⁩ الرسالة + %1$s قد أنشأ الغرفة + أنت قد أنشأت الغرفة + أنت قد دعوت %1$s + أنت قد انضممت إلى الغرفة + أنت قد غادرت الغرفة + أنت قد رفضت الدعوة + أنت قد طردت %1$s + أنت قد رفعت الحظر عن %1$s + أنت قد حظرت %1$s + أنت قد سحبت دعوة %1$s + أنت قد غيّرت صورتك الشخصية + أنت قد عيّنت اسمك الظاهر إلى %1$s + أنت قد غيّرت اسمك الظاهر من ⁨%1$s⁩ إلى ⁨%2$s⁩ + أنت قد أزلت اسمك الظاهر (لقد كان ⁨%1$s⁩) + أنت قد غيّرت الموضوع إلى: ⁨%1$s⁩ + %1$s قد غيّر صورة الغرفة + أنت قد غيّرت صورة الغرفة + أنت قد غيّرت اسم الغرفة إلى: %1$s + أنت قد أجريت مُكالمة مرئية. + أنت قد أجريت مُكالمة صوتية. + %s قد أرسل بيانات لإعداد مُكالمة. + أنت قد أرسلت بيانات لإعداد مُكالمة. + أنت قد أجبت على المُكالمة. + أنت قد أنهيت المُكالمة. + أنت قد جعلت التأريخ المُستقبلي للغرفة مرئيًا لـ %1$s + أنت قد فعّلت تعيمية النهاية-إلى-النهاية (%1$s) + %s قد قام بترقية هذه الغرفة. + أنت قد رقّيتَ هذه الغرفة. + أنت قد طلبت اجتماع VoIP + أنت قد أزلت اسم الغرفة + أنت قد أزلت موضوع الغرفة + %1$s قد أزال صورة الغرفة + أنت قد أزلت صورة الغرفة + تمت إزالة الرسالة + الرسالة قد أُزيلت بواسطة %1$s أُزيلت الرسالة [السبب: ⁨%1$s⁩] أزال ⁨%1$s⁩ الرسالة [السبب: ⁨%2$s⁩] أرسلت دعوة إلى ⁨%1$s⁩ للانضمام إلى الغرفة سحب ⁨%1$s⁩ دعوة ⁨%2$s⁩ للانضمام إلى الغرفة سحبت دعوة ⁨%1$s⁩ للانضمام إلى الغرفة قَبِلت دعوة ⁨%1$s⁩ - أضاف ⁨%1$s⁩ الودجة ⁨%2$s⁩ أضفت الودجة ⁨%1$s⁩ أزال ⁨%1$s⁩ الودجة ⁨%2$s⁩ أزلت الودجة ⁨%1$s⁩ عدّل ⁨%1$s⁩ الودجة ⁨%2$s⁩ عدّلت الودجة ⁨%1$s⁩ - مدير المبدئي مخصّص (⁨%1$d⁩) مخصّص - غيّرت مستوى قوّة %1$s⁩. غيّر ⁨%1$s⁩ مستوى قوّة %2$s⁩. ‏⁨%1$s⁩ من ⁨%2$s⁩ إلى ⁨%3$s⁩ - المزامنة الأولية: \nيستورد الحساب… - + 🎉 جميع الخوادم محظورة من المُشاركة! لم يعُد من الممكن استخدام هذه الغرفة. + لا تغيير. + • خوادم مُطابقة IP الحرفية محظورة الآن. + • الخادم المُطابق لـ %s قد أُزيل من قائمة السماح. + • الخادم المُطابق لـ %s مسموح الآن. + • الخادم المُطابق لـ %s قد أُزيل من قائمة الحظر. + • الخادم المُطابق لـ %s محظور الآن. + • خوادم مُطابقة IP الحرفية مسموحة الآن. + أنت قد غيّرت خادم الـACLs لهذه الغرفة. + %s قد غيّر خادم الـACLs لهذه الغرفة. + • الخادم يحظر مُطابقة القيم الحرفية للـIP. + • الخادم المُطابق لـ %s مسموح. + • الخادم المُطابق لـ %s محظور. + • الخادم يسمح بمُطابقة القيم الحرفية للـIP. + أنت قد عيّنت خادم الـACLs لهذه الغرفة. + %s قد عيّن خادم الـACLs لهذه الغرفة. + أنت قد قمت بالترقية هُنا. + %s قد قام بالترقية هُنا. + أنت قد جعلت الرسائل المُستقبلية مرئية لـ %1$s + %1$s قد جعل الرسائل المُستقبلية مرئية لـ %2$s + أنت قد غادرت الغرفة + %1$s قد غادر الغرفة + أنت قد انضممت + %1$s قد انضم + أنت قد أنشأت المُناقشة + %1$s قد أنشأ المُناقشة + \ No newline at end of file From a41b4a36218ae3255d9c3bd7a1133aca12d56615 Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Sun, 14 Feb 2021 18:09:58 +0000 Subject: [PATCH 15/29] Translated using Weblate (Catalan) Currently translated at 100.0% (226 of 226 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.element.io/projects/element-android/element-sdk/ca/ --- matrix-sdk-android/src/main/res/values-ca/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-ca/strings.xml b/matrix-sdk-android/src/main/res/values-ca/strings.xml index 728c4f6f60..98bda2c4ed 100644 --- a/matrix-sdk-android/src/main/res/values-ca/strings.xml +++ b/matrix-sdk-android/src/main/res/values-ca/strings.xml @@ -259,4 +259,10 @@ %s ha canviat les ACLs de servidor d\'aquesta sala. Has establert les ACLs de servidor per aquesta sala. %s ha establert les ACLs de servidor d\'aquesta sala. + Has modificat la videoconferència + %1$s ha modificat la videoconferència + Has finalitzat la videoconferència + %1$s ha iniciat una videoconferència + Has iniciat una videoconferència + %1$s ha finalitzat la videoconferència \ No newline at end of file From 1f92e61d3c7a9e1f6c818704c252ea50685a87c1 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Sat, 13 Feb 2021 16:39:23 +0000 Subject: [PATCH 16/29] Translated using Weblate (German) Currently translated at 100.0% (226 of 226 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.element.io/projects/element-android/element-sdk/de/ --- matrix-sdk-android/src/main/res/values-de/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-de/strings.xml b/matrix-sdk-android/src/main/res/values-de/strings.xml index dfe29100c4..81cf01983d 100644 --- a/matrix-sdk-android/src/main/res/values-de/strings.xml +++ b/matrix-sdk-android/src/main/res/values-de/strings.xml @@ -266,4 +266,10 @@ • Server, die mit %s übereinstimmen, sind gesperrt. Du hast die Server-ACL für diesen Raum gesetzt. %s hat die Server-Zugriffssteuerungsliste (ACL) für diesen Raum gesetzt. + Du hast eine Videokonferenz geändert + Videokonferenz von %1$s geändert + Videokonferenz von %1$s beendet + Du hast eine Videokonferenz beendet + Du hast eine Videokonferenz gestartet + Videokonferenz von %1$s gestartet \ No newline at end of file From b3a9e2088533e2d8056af4fdd561b81b5dcb9499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 12 Feb 2021 17:37:36 +0000 Subject: [PATCH 17/29] Translated using Weblate (Estonian) Currently translated at 100.0% (226 of 226 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.element.io/projects/element-android/element-sdk/et/ --- matrix-sdk-android/src/main/res/values-et/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-et/strings.xml b/matrix-sdk-android/src/main/res/values-et/strings.xml index af2cc33b99..0cf5c3e438 100644 --- a/matrix-sdk-android/src/main/res/values-et/strings.xml +++ b/matrix-sdk-android/src/main/res/values-et/strings.xml @@ -258,4 +258,10 @@ %1$s lisas sellele jututoale täiendavad aadressid %2$s. Sa muutsid selle jututoa aadresse. + Sina muutsid videokoosolekut + Sina lõpetasid videokoosoleku + %1$s lõpetas videokoosoleku + Sina algatasid videokoosoleku + %1$s algatas videokoosoleku + %1$s muutis videokoosolekut \ No newline at end of file From 96b46af9f5085dac120c0d353841a02105b9e69a Mon Sep 17 00:00:00 2001 From: random Date: Mon, 15 Feb 2021 10:36:10 +0000 Subject: [PATCH 18/29] Translated using Weblate (Italian) Currently translated at 100.0% (226 of 226 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.element.io/projects/element-android/element-sdk/it/ --- matrix-sdk-android/src/main/res/values-it/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-it/strings.xml b/matrix-sdk-android/src/main/res/values-it/strings.xml index ec19cd5c17..e1f57ddac0 100644 --- a/matrix-sdk-android/src/main/res/values-it/strings.xml +++ b/matrix-sdk-android/src/main/res/values-it/strings.xml @@ -259,4 +259,10 @@ %1$s ha aggiunto l\'indirizzo alternativo %2$s per questa stanza. %1$s ha aggiunto gli indirizzi alternativi %2$s per questa stanza. + Hai modificato la video conferenza + Video conferenza modificata da %1$s + Hai iniziato la video conferenza + Hai terminato la video conferenza + Video conferenza terminata da %1$s + Video conferenza iniziata da %1$s \ No newline at end of file From 6fdbb91ccb5ae99d50132c920a9a51e4b51b4815 Mon Sep 17 00:00:00 2001 From: "@a2sc:matrix.org" Date: Sat, 13 Feb 2021 16:36:35 +0000 Subject: [PATCH 19/29] Translated using Weblate (German) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/de/ --- fastlane/metadata/android/de/changelogs/40100170.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de/changelogs/40100170.txt diff --git a/fastlane/metadata/android/de/changelogs/40100170.txt b/fastlane/metadata/android/de/changelogs/40100170.txt new file mode 100644 index 0000000000..2ea20cf3ce --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Hauptänderungen in dieser Version: Fehlerkorrekturen +Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases/tag/v1.0.17 From 30e5e15245cb187fd496a501a18f5ebea57c9b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Fri, 12 Feb 2021 19:40:00 +0000 Subject: [PATCH 20/29] Translated using Weblate (Slovak) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/ --- fastlane/metadata/android/sk/changelogs/40100120.txt | 2 ++ fastlane/metadata/android/sk/changelogs/40100130.txt | 2 ++ fastlane/metadata/android/sk/changelogs/40100140.txt | 2 ++ fastlane/metadata/android/sk/changelogs/40100150.txt | 2 ++ fastlane/metadata/android/sk/changelogs/40100160.txt | 2 ++ fastlane/metadata/android/sk/changelogs/40100170.txt | 2 ++ fastlane/metadata/android/sk/short_description.txt | 2 +- 7 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/sk/changelogs/40100120.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40100130.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40100140.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40100150.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40100160.txt create mode 100644 fastlane/metadata/android/sk/changelogs/40100170.txt diff --git a/fastlane/metadata/android/sk/changelogs/40100120.txt b/fastlane/metadata/android/sk/changelogs/40100120.txt new file mode 100644 index 0000000000..46d39ad9e7 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40100120.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Ukážka URL, nová klávesnica Emoji, nové možnosti nastavenia miestnosti a sneh na Vianoce! +Celý zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.12 diff --git a/fastlane/metadata/android/sk/changelogs/40100130.txt b/fastlane/metadata/android/sk/changelogs/40100130.txt new file mode 100644 index 0000000000..6dc39b44f1 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40100130.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Ukážka URL, nová klávesnica Emoji, nové možnosti nastavenia miestnosti a sneh na Vianoce! +Celý zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.13 diff --git a/fastlane/metadata/android/sk/changelogs/40100140.txt b/fastlane/metadata/android/sk/changelogs/40100140.txt new file mode 100644 index 0000000000..22db5f972f --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40100140.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Úpravy povolení miestnosti, automatický svetlý / tmavý motív a veľa opráv chýb. +Celý zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.14 diff --git a/fastlane/metadata/android/sk/changelogs/40100150.txt b/fastlane/metadata/android/sk/changelogs/40100150.txt new file mode 100644 index 0000000000..ca26356e8a --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40100150.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Podpora sociálneho prihlásenia. +Celý zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.15 diff --git a/fastlane/metadata/android/sk/changelogs/40100160.txt b/fastlane/metadata/android/sk/changelogs/40100160.txt new file mode 100644 index 0000000000..28cd4b52c9 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40100160.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Podpora sociálneho prihlásenia. +Celý zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16 diff --git a/fastlane/metadata/android/sk/changelogs/40100170.txt b/fastlane/metadata/android/sk/changelogs/40100170.txt new file mode 100644 index 0000000000..41336e7700 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Opravy chýb! +Celý zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.17 diff --git a/fastlane/metadata/android/sk/short_description.txt b/fastlane/metadata/android/sk/short_description.txt index 7d352942bf..0744f4a617 100644 --- a/fastlane/metadata/android/sk/short_description.txt +++ b/fastlane/metadata/android/sk/short_description.txt @@ -1 +1 @@ -Zabezpečené konverzácie a VoIP. Ochráňte vaše údaje pred zhromažďovaním. +Zabezpečené konverzácie a VoIP. Ochráňte vaše údaje pred tretími stranami. From f3cbc18b5099536f8c8f1fb587a34d6974adf9fb Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 12 Feb 2021 13:32:13 +0000 Subject: [PATCH 21/29] Translated using Weblate (Ukrainian) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/ --- fastlane/metadata/android/uk/changelogs/40100170.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/40100170.txt diff --git a/fastlane/metadata/android/uk/changelogs/40100170.txt b/fastlane/metadata/android/uk/changelogs/40100170.txt new file mode 100644 index 0000000000..c4b1bcc8e0 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Основні зміни у цій версії: Виправлення помилок! +Повний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.0.17 From 1d0eb1e92600e72bb51e9fa411ca518d0e5aef53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Fri, 12 Feb 2021 17:38:45 +0000 Subject: [PATCH 22/29] Translated using Weblate (Estonian) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/et/ --- fastlane/metadata/android/et/changelogs/40100170.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/40100170.txt diff --git a/fastlane/metadata/android/et/changelogs/40100170.txt b/fastlane/metadata/android/et/changelogs/40100170.txt new file mode 100644 index 0000000000..3c565c011c --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Olulisemad muutused selles versioonis: Veaparandused! +Muudatuste logi täismahus: https://github.com/vector-im/element-android/releases/tag/v1.0.17 From a86405fb01bda5301a9354922286605d54198413 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 15 Feb 2021 11:03:27 +0000 Subject: [PATCH 23/29] Translated using Weblate (Italian) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/it/ --- fastlane/metadata/android/it/changelogs/40100130.txt | 2 +- fastlane/metadata/android/it/changelogs/40100140.txt | 2 ++ fastlane/metadata/android/it/changelogs/40100150.txt | 2 ++ fastlane/metadata/android/it/changelogs/40100160.txt | 2 ++ fastlane/metadata/android/it/changelogs/40100170.txt | 2 ++ 5 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/it/changelogs/40100140.txt create mode 100644 fastlane/metadata/android/it/changelogs/40100150.txt create mode 100644 fastlane/metadata/android/it/changelogs/40100160.txt create mode 100644 fastlane/metadata/android/it/changelogs/40100170.txt diff --git a/fastlane/metadata/android/it/changelogs/40100130.txt b/fastlane/metadata/android/it/changelogs/40100130.txt index fcf8ca0f4e..ef27be9e1e 100644 --- a/fastlane/metadata/android/it/changelogs/40100130.txt +++ b/fastlane/metadata/android/it/changelogs/40100130.txt @@ -1,2 +1,2 @@ Modifiche principali in questa versione: anteprima URL, nuova tastiera emoji, nuove impostazioni stanza e neve per Natale! -Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.12 +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.13 diff --git a/fastlane/metadata/android/it/changelogs/40100140.txt b/fastlane/metadata/android/it/changelogs/40100140.txt new file mode 100644 index 0000000000..0bf5c1b085 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/40100140.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: modifica autorizzazioni stanza, tema chiaro/scuro automatico e varie correzioni di errori. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.14 diff --git a/fastlane/metadata/android/it/changelogs/40100150.txt b/fastlane/metadata/android/it/changelogs/40100150.txt new file mode 100644 index 0000000000..5df2a0d650 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/40100150.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: supporto all'accesso dai social. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.15 diff --git a/fastlane/metadata/android/it/changelogs/40100160.txt b/fastlane/metadata/android/it/changelogs/40100160.txt new file mode 100644 index 0000000000..9177421e44 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/40100160.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: supporto all'accesso dai social. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16 diff --git a/fastlane/metadata/android/it/changelogs/40100170.txt b/fastlane/metadata/android/it/changelogs/40100170.txt new file mode 100644 index 0000000000..b2a8424497 --- /dev/null +++ b/fastlane/metadata/android/it/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: correzioni di errori! +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.17 From 11e5df1007bbdacd99071dead440920e3e54b0c1 Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Sun, 14 Feb 2021 18:07:45 +0000 Subject: [PATCH 24/29] Translated using Weblate (Catalan) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ca/ --- fastlane/metadata/android/ca/changelogs/40100170.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/ca/changelogs/40100170.txt diff --git a/fastlane/metadata/android/ca/changelogs/40100170.txt b/fastlane/metadata/android/ca/changelogs/40100170.txt new file mode 100644 index 0000000000..8a208b66f7 --- /dev/null +++ b/fastlane/metadata/android/ca/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Canvis principals d'aquesta versió: correcció d'errors! +Registre de canvis complet: https://github.com/vector-im/element-android/releases/tag/v1.0.17 From 68ef369adcb1a887029cc4bb3bd177306669f2bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Slobodan=20Simi=C4=87?= Date: Fri, 12 Feb 2021 19:01:08 +0000 Subject: [PATCH 25/29] Translated using Weblate (Serbian) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/sr/ --- fastlane/metadata/android/sr/changelogs/40100170.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sr/changelogs/40100170.txt diff --git a/fastlane/metadata/android/sr/changelogs/40100170.txt b/fastlane/metadata/android/sr/changelogs/40100170.txt new file mode 100644 index 0000000000..51d332a5ea --- /dev/null +++ b/fastlane/metadata/android/sr/changelogs/40100170.txt @@ -0,0 +1,2 @@ +Главна измена у овој верзији: сређене грешке! +Цео дневник измена: https://github.com/vector-im/element-android/releases/tag/v1.0.15 и https://github.com/vector-im/element-android/releases/tag/v1.0.17 From adea3ab7758e20050c9e3cf6f54a5d41d5ca8a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Slobodan=20Simi=C4=87?= Date: Fri, 12 Feb 2021 18:59:51 +0000 Subject: [PATCH 26/29] Translated using Weblate (Serbian) Currently translated at 100.0% (226 of 226 strings) Translation: Element Android/Element Android Sdk Translate-URL: https://translate.element.io/projects/element-android/element-sdk/sr/ --- matrix-sdk-android/src/main/res/values-sr/strings.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/matrix-sdk-android/src/main/res/values-sr/strings.xml b/matrix-sdk-android/src/main/res/values-sr/strings.xml index 5e0a72a4ea..c55c92d58a 100644 --- a/matrix-sdk-android/src/main/res/values-sr/strings.xml +++ b/matrix-sdk-android/src/main/res/values-sr/strings.xml @@ -268,4 +268,10 @@ %1$s уклони %2$s као адресе ове собе. %1$s уклони %2$s као адресе ове собе. + Изменили сте видео конференцију + %1$s измени видео конференцију + Завршили сте видео конференцију + %1$s заврши видео конференцију + Покренули сте видео конференцију + %1$s покрену видео конференцију \ No newline at end of file From e01899ce8fb72d1e06a3837aa241678a97cd08ec Mon Sep 17 00:00:00 2001 From: zer0-x <1rn0kmrwo@relay.firefox.com> Date: Sun, 14 Feb 2021 07:44:16 +0000 Subject: [PATCH 27/29] Translated using Weblate (Arabic) Currently translated at 100.0% (11 of 11 strings) Translation: Element Android/Element Android Store Translate-URL: https://translate.element.io/projects/element-android/element-store/ar/ --- .../android/ar/changelogs/40100100.txt | 2 ++ .../android/ar/changelogs/40100110.txt | 2 ++ .../android/ar/changelogs/40100120.txt | 2 ++ .../android/ar/changelogs/40100130.txt | 2 ++ .../android/ar/changelogs/40100140.txt | 2 ++ .../android/ar/changelogs/40100150.txt | 2 ++ .../android/ar/changelogs/40100160.txt | 2 ++ .../android/ar/changelogs/40100170.txt | 2 ++ .../metadata/android/ar/full_description.txt | 31 +++++++++++++++++++ .../metadata/android/ar/short_description.txt | 1 + fastlane/metadata/android/ar/title.txt | 1 + 11 files changed, 49 insertions(+) create mode 100644 fastlane/metadata/android/ar/changelogs/40100100.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100110.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100120.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100130.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100140.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100150.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100160.txt create mode 100644 fastlane/metadata/android/ar/changelogs/40100170.txt create mode 100644 fastlane/metadata/android/ar/full_description.txt create mode 100644 fastlane/metadata/android/ar/short_description.txt create mode 100644 fastlane/metadata/android/ar/title.txt diff --git a/fastlane/metadata/android/ar/changelogs/40100100.txt b/fastlane/metadata/android/ar/changelogs/40100100.txt new file mode 100644 index 0000000000..25fc9c9058 --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100100.txt @@ -0,0 +1,2 @@ +يحتوي هذا الإصدار الجديد بشكل أساسي على إصلاحات للأخطاء وتحسينات. إرسال الرسالة أصبح الآن أسرع بكثير. +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.10 diff --git a/fastlane/metadata/android/ar/changelogs/40100110.txt b/fastlane/metadata/android/ar/changelogs/40100110.txt new file mode 100644 index 0000000000..1258ba323a --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100110.txt @@ -0,0 +1,2 @@ +يحتوي هذا الإصدار الجديد بشكل أساسي على تحسينات في واجهة المستخدم وتجربة المستخدم. يُمكنك الآن دعوة الأصدقاء وإنشاء رسالة مُباشرة بسرعة كبيرة عن طريق مسح رموز الاستجابة السريعة. +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.11 diff --git a/fastlane/metadata/android/ar/changelogs/40100120.txt b/fastlane/metadata/android/ar/changelogs/40100120.txt new file mode 100644 index 0000000000..18abe163dd --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100120.txt @@ -0,0 +1,2 @@ +التغييرات الرئيسة في هذا الإصدار: مُعاينة URL، لوحة مفاتيح Emoji جديدة، إمكانيات جديدة لإعدادات الغرفة والثلج لميلاد المسيح! +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.12 diff --git a/fastlane/metadata/android/ar/changelogs/40100130.txt b/fastlane/metadata/android/ar/changelogs/40100130.txt new file mode 100644 index 0000000000..eb50cdd31a --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100130.txt @@ -0,0 +1,2 @@ +التغييرات الرئيسة في هذا الإصدار: مُعاينة URL، لوحة مفاتيح Emoji جديدة، إمكانيات جديدة لإعدادات الغرفة والثلج لميلاد المسيح! +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.13 diff --git a/fastlane/metadata/android/ar/changelogs/40100140.txt b/fastlane/metadata/android/ar/changelogs/40100140.txt new file mode 100644 index 0000000000..d3b0dc2dbc --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100140.txt @@ -0,0 +1,2 @@ +التغييرات الرئيسة في هذا الإصدار: تحرير أذونات الغُرفة، السِّمة التلقائية الفاتحة/الداكنة، ومجموعة من إصلاحات الأخطاء. +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.14 diff --git a/fastlane/metadata/android/ar/changelogs/40100150.txt b/fastlane/metadata/android/ar/changelogs/40100150.txt new file mode 100644 index 0000000000..ba77aa0b1c --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100150.txt @@ -0,0 +1,2 @@ +التغييرات الرئيسة في هذا الإصدار: دعم تسجيل الدخول الاجتماعي. +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.15 diff --git a/fastlane/metadata/android/ar/changelogs/40100160.txt b/fastlane/metadata/android/ar/changelogs/40100160.txt new file mode 100644 index 0000000000..b52a902cfa --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100160.txt @@ -0,0 +1,2 @@ +التغييرات الرئيسة في هذا الإصدار: دعم تسجيل الدخول الاجتماعي. +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16 diff --git a/fastlane/metadata/android/ar/changelogs/40100170.txt b/fastlane/metadata/android/ar/changelogs/40100170.txt new file mode 100644 index 0000000000..8f2226ae0e --- /dev/null +++ b/fastlane/metadata/android/ar/changelogs/40100170.txt @@ -0,0 +1,2 @@ +التغييرات الرئيسة في هذا الإصدار: إصلاحات الأخطاء! +سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.17 diff --git a/fastlane/metadata/android/ar/full_description.txt b/fastlane/metadata/android/ar/full_description.txt new file mode 100644 index 0000000000..c0baa7d709 --- /dev/null +++ b/fastlane/metadata/android/ar/full_description.txt @@ -0,0 +1,31 @@ +Element هو نوع جديد من تطبيقات المُراسلة والتعاون الذي: + +1. يمنحك التحكم في المُحافضة على خصوصيتك +2. يُتيح لك التواصل مع أي شخص على شبكة Matrix ، وحتى خارجها من خلال التكامل مع التطبيقات مثل Slack +3. يحميك من الإعلانات والتنقيب عن البيانات وعمليات الحدائق المُسورة +4. يؤمنك من خلال تعمية النهاية-إلى-النهاية، مع التوقيع المُتبادل للتحقق من الآخرين + +يختلف Element تمامًا عن تطبيقات المُراسلة والتعاون الأُخرى لأنه لا مركزي ومفتوح المصدر. + +يُتيح لك Element إمكانية الاستضافة الذاتية -أو اختيار مُضيف- بحيث تتمتع بالخصوصية والمُلكية والتحكم في بياناتك ومُحادثاتك. يُتيح لك الوصول إلى شبكة مفتوحة؛ لذلك لا يقتصر الأمر على التحدث إلى مستخدمي Element الآخرين فقط. كما انه آمن للغاية. + +Element قادر على القيام بكل ذلك لأنه يعمل على Matrix -مِعيار التواصل المفتوح اللامركزي. + +Element يمنحك زمام التحكم من خلال السماح لك باختيار من يستضيف المُحادثات الخاصة بك. من تطبيق Element، يُمكنك اختيار الاستضافة بطرق مختلفة: + +1. الحُصول على حساب مجاني على الخادِم العام matrix.org الذي يستضيفه مطورو Matrix، أو اختر من بين آلاف الخوادِم العامة التي يستضيفها متطوعون +2. استضافة حسابك بنفسك عن طريق تشغيل خادِم على أجهزتك الخاصة +3. التسجيل للحصول على حساب على خادِم مُخصص بمُجرد الاشتراك في منصة استضافة Element Matrix Services + + لماذا تختار Element؟ + +تملَّك بياناتك: أنت من تُقرر أين تحتفظ ببياناتك ورسائلك. أنت تمتلكها وتتحكم فيها، وليس بعض الشركات الكُبرى الإحتكارية التي تُنقِّب عن بياناتك أو تُتيح الوصول إلى أطراف ثالثة. + + +تراسُل وتعاون مفتوح: يُمكنك مُحادثة أي شخص آخر على شبكة Matrix، سواء كانوا يستخدمون Element أو تطبيق Matrix آخر، وحتى إذا كانوا يستخدمون نظام مُراسلة مُختلف مثل Slack أو IRC أو XMPP. + +الأمان-الخارق: تشفير حقيقي من النهاية إلى النهاية (فقط أطراف المُحادثة مَن يُمكنهم فك تشفير الرسائل)، والتوقيع المُتبادل للتحقق من أجهزة المُشاركين في المُحادثة. + +التواصل الكامل: المُراسلة، المُكالمات الصوتية والمرئية، مُشاركة الملفات، مُشاركة الشاشة، مجموعة كاملة وكبيرة من عمليات التكامُل، الروبوتات والأدوات. بناء الغُرف، المُجتمعات، ابق على اتصال وأنجز المهام. + +أين ما كُنت: ابق على اتصال أينما كنت مع سجل الرسائل المتزامن بالكامل عبر جميع أجهزتك وفي الويب على https://app.element.io. diff --git a/fastlane/metadata/android/ar/short_description.txt b/fastlane/metadata/android/ar/short_description.txt new file mode 100644 index 0000000000..48df6f2b0c --- /dev/null +++ b/fastlane/metadata/android/ar/short_description.txt @@ -0,0 +1 @@ +مُحادثة آمنة لا مركزية و VoIP. حافظ على بياناتك آمنة من الأطراف الثالثة. diff --git a/fastlane/metadata/android/ar/title.txt b/fastlane/metadata/android/ar/title.txt new file mode 100644 index 0000000000..9b382729c8 --- /dev/null +++ b/fastlane/metadata/android/ar/title.txt @@ -0,0 +1 @@ +Element (سابقاً Riot.im) From a604e2974428be83d372afe07d3b013040c4b146 Mon Sep 17 00:00:00 2001 From: vachan-maker Date: Mon, 15 Feb 2021 07:37:38 +0000 Subject: [PATCH 28/29] Translated using Weblate (Malayalam) Currently translated at 4.4% (93 of 2081 strings) Translation: Element Android/Element Android App Translate-URL: https://translate.element.io/projects/element-android/element-app/ml/ --- vector/src/main/res/values-ml/strings.xml | 96 ++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/vector/src/main/res/values-ml/strings.xml b/vector/src/main/res/values-ml/strings.xml index a6b3daec93..64a5cfbe7b 100644 --- a/vector/src/main/res/values-ml/strings.xml +++ b/vector/src/main/res/values-ml/strings.xml @@ -1,2 +1,96 @@ - \ No newline at end of file + + ബാക്കപ്പ് ഇല്ലാതാക്കൂ + ബാക്കപ്പ് ഇല്ലാതാക്കുന്നൂ… + ബാക്കപ്പ് ഇല്ലാതാക്കൂ + ക്രമീകരണങ്ങൾ + സൂചനകൾ മാത്രം + എല്ലാ സന്ദേശങ്ങളും + നിങ്ങൾ മാറ്റങ്ങളൊന്നും വരുത്തിയില്ല + വായിക്കാത്ത സന്ദേശങ്ങൾ + മീഡിയ ഫയൽ ഗാലറിയിലേക്ക് ചേർത്തു + എൻ‌ക്രിപ്റ്റ് ചെയ്യാത്തത് + മഞ്ഞ് അയയ്ക്കുന്നു ❄️ + പ്രവേശനം ഉറപ്പാക്കൂ + ഒരു രഹസ്യവാക്ക് തിരഞ്ഞെടുക്കുക. + ഒരു ഉപയോക്തൃനാമം തിരഞ്ഞെടുക്കുക. + ആളുകളെ ചേർക്കൂ + ഉപയോക്താക്കളെ ക്ഷണിക്കുക + സുഹൃത്തുക്കളെ ക്ഷണിക്കുക + എന്റെ കോഡ് പങ്കിടുക + എന്റെ കോഡ് + 🔐️ element-ൽ എന്നോടൊപ്പം ചേരുക + സമർപ്പിക്കൂ + ചാറ്റ് തുറക്കുക + ക്യാമറ നിർത്തുക + വിഷയം + മുറിയുടെ പേര് + അവതാർ സജ്ജമാക്കുക + നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ലഭ്യമാക്കുന്നൂ… + പിൻ മറന്നോ\? + നിങ്ങളുടെ പിൻ നൽകുക + ഉള്ളടക്കം അറിയിപ്പുകളിൽ കാണിക്കൂ + പിൻ മാറ്റുക + ഈ കോൾ അവസാനിച്ചു + %1$s ഒരു കോൾ ആരംഭിച്ചൂ + നിങ്ങൾ ഒരു കോൾ ആരംഭിച്ചൂ + മാറ്റങ്ങൾ ഉപേക്ഷിക്കുക + തിരിച്ചു വിളിക്കുക + ഉപയോക്താക്കൾ + ഫലങ്ങളൊന്നുമില്ല + സംഭാഷണങ്ങളൊന്നുമില്ല + സംഭാഷണങ്ങൾ + കഷണങ്ങൾ + മുറികൾ + ആളുകൾ + പ്രിയപ്പെട്ടവ + അറിയിപ്പുകൾ + വിജയകരം + മുന്നറിയിപ്പ് + ചേർക്കുക + പകർത്തുക + അടയ്ക്കുക + തുറക്കുക + വായിച്ചതായി കാണിക്കൂ + ചരിത്രപരമായ + എല്ലാം വായിച്ചതായി കാണിക്കൂ + വീഡിയോ കോൾ + വോയ്സ് കോൾ + പ്രവർത്തനങ്ങൾ + പുറത്തുകടക്കുക + അവഗണിക്കൂ + ചെയ്‌തു + ഒഴിവാക്കൂ + ഓഫ്‌ലൈൻ + ക്ഷണിക്കുക + അല്ലെങ്കിൽ + സെഷൻ വിശദാംശങ്ങൾ + ഓഡിയോ മീറ്റിംഗ് ആരംഭിക്കുക + വീഡിയോ മീറ്റിംഗ് ആരംഭിക്കുക + ഒരു കോൺഫറൻസ് ഇതിനകം പുരോഗമിക്കുന്നു! + ഒരു കോൺഫറൻസ് കോൾ ആരംഭിക്കാൻ നിങ്ങൾക്ക് അനുവാദമില്ല + കോൾ ആരംഭിക്കാൻ കഴിയില്ല, ദയവായി പിന്നീട് ശ്രമിക്കുക + വീഡിയോ + ചാറ്റിംഗ് ആരംഭിക്കുക + ഇല്ലാതാക്കൂ + മായ്ക്കുക + ഡൌൺലോഡ് ചെയ്യൂ + പങ്കിടുക + വീണ്ടും അയയ്ക്കൂ + അയയ്ക്കൂ + സംരക്ഷിക്കൂ + റദ്ദാക്കൂ + ശരി + ലഭ്യമാക്കുന്നു… + നിങ്ങൾക്കു ഉറപ്പാണോ\? + എന്റെ എൻക്രിപ്റ്റ് ചെയ്ത സന്ദേശങ്ങളൊന്നും എനിക്ക് വേണ്ട + സെഷൻ ഉറപ്പാക്കൂ + ഒരു സ്റ്റിക്കർ അയയ്‌ക്കുക + കമ്മ്യൂണിറ്റി വിശദാംശങ്ങൾ + ചരിത്രപരമായ + ക്രമീകരണങ്ങൾ + മുറി + സന്ദേശങ്ങൾ + നിശബ്‌ദ അറിയിപ്പുകൾ + സമന്വയിപ്പിക്കുന്നു + \ No newline at end of file From 59634753b38792cd9b2fae2ca35ea2a56b6479f7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 Feb 2021 14:50:26 +0100 Subject: [PATCH 29/29] Code review --- .../api/session/room/state/StateService.kt | 17 ++ .../devtools/DevToolsInteractionListener.kt | 21 ++ .../features/devtools/DevToolsViewEvents.kt | 4 +- .../features/devtools/RoomDevToolActivity.kt | 55 +++--- .../devtools/RoomDevToolEditFragment.kt | 16 +- .../features/devtools/RoomDevToolFragment.kt | 14 +- .../devtools/RoomDevToolRootController.kt | 55 +++--- .../devtools/RoomDevToolSendFormController.kt | 23 ++- .../devtools/RoomDevToolSendFormFragment.kt | 6 +- .../RoomDevToolStateEventListFragment.kt | 6 +- .../features/devtools/RoomDevToolViewModel.kt | 185 ++++++++++-------- .../devtools/RoomStateListController.kt | 22 +-- .../form/FormMultiLineEditTextItem.kt | 2 +- .../home/room/detail/RoomDetailFragment.kt | 3 +- .../features/navigation/DefaultNavigator.kt | 5 + .../app/features/navigation/Navigator.kt | 2 + .../members/RoomMemberListController.kt | 3 +- .../res/layout/fragment_devtools_editor.xml | 14 +- .../layout/item_form_multiline_text_input.xml | 4 +- vector/src/main/res/values/strings.xml | 19 ++ 20 files changed, 268 insertions(+), 208 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/devtools/DevToolsInteractionListener.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt index 444366e912..e614ea91d6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt @@ -65,13 +65,30 @@ interface StateService { */ suspend fun deleteAvatar() + /** + * Send a state event to the room + */ suspend fun sendStateEvent(eventType: String, stateKey: String?, body: JsonDict) + /** + * Get a state event of the room + */ fun getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event? + /** + * Get a live state event of the room + */ fun getStateEventLive(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData> + /** + * Get state events of the room + * @param eventTypes Set of eventType. If empty, all state events will be returned + */ fun getStateEvents(eventTypes: Set, stateKey: QueryStringValue = QueryStringValue.NoCondition): List + /** + * Get live state events of the room + * @param eventTypes Set of eventType to observe. If empty, all state events will be observed + */ fun getStateEventsLive(eventTypes: Set, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData> } diff --git a/vector/src/main/java/im/vector/app/features/devtools/DevToolsInteractionListener.kt b/vector/src/main/java/im/vector/app/features/devtools/DevToolsInteractionListener.kt new file mode 100644 index 0000000000..e1e6f6b7cb --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/devtools/DevToolsInteractionListener.kt @@ -0,0 +1,21 @@ +/* + * 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.devtools + +interface DevToolsInteractionListener { + fun processAction(action: RoomDevToolAction) +} diff --git a/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt b/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt index 615144aaf6..96aed20dc4 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/DevToolsViewEvents.kt @@ -22,6 +22,6 @@ sealed class DevToolsViewEvents : VectorViewEvents { object Dismiss : DevToolsViewEvents() // object ShowStateList : DevToolsViewEvents() - data class showAlertMessage(val message: String) : DevToolsViewEvents() - data class showSnackMessage(val message: String) : DevToolsViewEvents() + data class ShowAlertMessage(val message: String) : DevToolsViewEvents() + data class ShowSnackMessage(val message: String) : DevToolsViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt index fe6d684474..31b495a4d4 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolActivity.kt @@ -35,6 +35,7 @@ import com.airbnb.mvrx.viewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.di.ScreenComponent +import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.extensions.toMvRxBundle import im.vector.app.core.platform.SimpleFragmentActivity @@ -57,7 +58,7 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto override fun getMenuRes() = R.menu.menu_devtools - var currentDisplayMode: RoomDevToolViewState.Mode? = null + private var currentDisplayMode: RoomDevToolViewState.Mode? = null @Parcelize data class Args( @@ -81,15 +82,16 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto viewModel.observeViewEvents { when (it) { - DevToolsViewEvents.Dismiss -> finish() - is DevToolsViewEvents.showAlertMessage -> { + DevToolsViewEvents.Dismiss -> finish() + is DevToolsViewEvents.ShowAlertMessage -> { AlertDialog.Builder(this) .setMessage(it.message) .setPositiveButton(R.string.ok, null) .show() + Unit } - is DevToolsViewEvents.showSnackMessage -> showSnackbar(it.message) - } + is DevToolsViewEvents.ShowSnackMessage -> showSnackbar(it.message) + }.exhaustive } supportFragmentManager.addOnBackStackChangedListener(this) } @@ -97,7 +99,7 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto private fun renderState(it: RoomDevToolViewState) { if (it.displayMode != currentDisplayMode) { when (it.displayMode) { - RoomDevToolViewState.Mode.Root -> { + RoomDevToolViewState.Mode.Root -> { val classJava = RoomDevToolFragment::class.java val tag = classJava.name if (supportFragmentManager.findFragmentByTag(tag) == null) { @@ -106,8 +108,13 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto supportFragmentManager.popBackStack() } } - RoomDevToolViewState.Mode.StateEventDetail -> { - val frag = JSonViewerFragment.newInstance(it.selectedEventJson ?: "", -1, true, createJSonViewerStyleProvider(colorProvider)) + RoomDevToolViewState.Mode.StateEventDetail -> { + val frag = JSonViewerFragment.newInstance( + jsonString = it.selectedEventJson ?: "", + initialOpenDepth = -1, + wrap = true, + styleProvider = createJSonViewerStyleProvider(colorProvider) + ) navigateTo(frag) } RoomDevToolViewState.Mode.StateEventList, @@ -115,11 +122,11 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto val frag = createFragment(RoomDevToolStateEventListFragment::class.java, Bundle().toMvRxBundle()) navigateTo(frag) } - RoomDevToolViewState.Mode.EditEventContent -> { + RoomDevToolViewState.Mode.EditEventContent -> { val frag = createFragment(RoomDevToolEditFragment::class.java, Bundle().toMvRxBundle()) navigateTo(frag) } - is RoomDevToolViewState.Mode.SendEventForm -> { + is RoomDevToolViewState.Mode.SendEventForm -> { val frag = createFragment(RoomDevToolSendFormFragment::class.java, Bundle().toMvRxBundle()) navigateTo(frag) } @@ -129,9 +136,9 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto } when (it.modalLoading) { - is Loading -> showWaitingView() - is Success -> hideWaitingView() - is Fail -> { + is Loading -> showWaitingView() + is Success -> hideWaitingView() + is Fail -> { hideWaitingView() } Uninitialized -> { @@ -203,7 +210,7 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto companion object { - fun intent(roomId: String, context: Context): Intent { + fun intent(context: Context, roomId: String): Intent { return Intent(context, RoomDevToolActivity::class.java).apply { putExtra(MvRx.KEY_ARG, Args(roomId)) } @@ -216,24 +223,26 @@ class RoomDevToolActivity : SimpleFragmentActivity(), RoomDevToolViewModel.Facto private fun updateToolBar(state: RoomDevToolViewState) { val title = when (state.displayMode) { - RoomDevToolViewState.Mode.Root -> { + RoomDevToolViewState.Mode.Root -> { getString(getTitleRes()) } - RoomDevToolViewState.Mode.StateEventList -> { - "State Events" + RoomDevToolViewState.Mode.StateEventList -> { + getString(R.string.dev_tools_state_event) } - RoomDevToolViewState.Mode.StateEventDetail -> { + RoomDevToolViewState.Mode.StateEventDetail -> { state.selectedEvent?.type } - RoomDevToolViewState.Mode.EditEventContent -> { - "Edit Content" + RoomDevToolViewState.Mode.EditEventContent -> { + getString(R.string.dev_tools_edit_content) } RoomDevToolViewState.Mode.StateEventListByType -> { state.currentStateType ?: "" } - is RoomDevToolViewState.Mode.SendEventForm -> { - if (state.displayMode.isState) "Send Custom State Event" - else "Send Custom Event" + is RoomDevToolViewState.Mode.SendEventForm -> { + getString( + if (state.displayMode.isState) R.string.dev_tools_send_custom_state_event + else R.string.dev_tools_send_custom_event + ) } } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt index cbb85f5ee6..98fe19a765 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolEditFragment.kt @@ -25,16 +25,13 @@ import com.airbnb.mvrx.withState import com.jakewharton.rxbinding3.widget.textChanges import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.FragmentDevtoolsEditorBinding import javax.inject.Inject -class RoomDevToolEditFragment @Inject constructor( - val epoxyController: RoomDevToolRootController, - private val colorProvider: ColorProvider -) : VectorBaseFragment(), RoomDevToolRootController.InteractionListener { +class RoomDevToolEditFragment @Inject constructor() + : VectorBaseFragment() { - val sharedViewModel: RoomDevToolViewModel by activityViewModel() + private val sharedViewModel: RoomDevToolViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDevtoolsEditorBinding { return FragmentDevtoolsEditorBinding.inflate(inflater, container, false) @@ -53,13 +50,6 @@ class RoomDevToolEditFragment @Inject constructor( .disposeOnDestroyView() } - override fun invalidate() = withState(sharedViewModel) { _ -> - } - - override fun processAction(action: RoomDevToolAction) { - sharedViewModel.handle(action) - } - override fun onResume() { super.onResume() views.editText.requestFocus() diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt index 36c1142bc2..0cc2a69bcf 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolFragment.kt @@ -21,20 +21,18 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel -import com.airbnb.mvrx.withState import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.FragmentGenericRecyclerBinding import javax.inject.Inject class RoomDevToolFragment @Inject constructor( - val epoxyController: RoomDevToolRootController, - private val colorProvider: ColorProvider -) : VectorBaseFragment(), RoomDevToolRootController.InteractionListener { + private val epoxyController: RoomDevToolRootController +) : VectorBaseFragment(), + DevToolsInteractionListener { - val sharedViewModel: RoomDevToolViewModel by activityViewModel() + private val sharedViewModel: RoomDevToolViewModel by activityViewModel() override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { return FragmentGenericRecyclerBinding.inflate(inflater, container, false) @@ -62,10 +60,6 @@ class RoomDevToolFragment @Inject constructor( super.onDestroyView() } - override fun invalidate() = withState(sharedViewModel) { state -> - epoxyController.setData(state) - } - override fun processAction(action: RoomDevToolAction) { sharedViewModel.handle(action) } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt index 48f74eaaa5..785e0140ac 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt @@ -17,44 +17,43 @@ package im.vector.app.features.devtools import android.view.View -import com.airbnb.epoxy.TypedEpoxyController +import com.airbnb.epoxy.EpoxyController +import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.core.ui.list.genericButtonItem import javax.inject.Inject class RoomDevToolRootController @Inject constructor( private val stringProvider: StringProvider -) : TypedEpoxyController() { +) : EpoxyController() { - interface InteractionListener { - fun processAction(action: RoomDevToolAction) + init { + requestModelBuild() } - var interactionListener: InteractionListener? = null + var interactionListener: DevToolsInteractionListener? = null - override fun buildModels(data: RoomDevToolViewState?) { - if (data?.displayMode == RoomDevToolViewState.Mode.Root) { - genericButtonItem { - id("explore") - text("Explore Room State") - buttonClickAction(View.OnClickListener { - interactionListener?.processAction(RoomDevToolAction.ExploreRoomState) - }) - } - genericButtonItem { - id("send") - text("Send Custom Event") - buttonClickAction(View.OnClickListener { - interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false)) - }) - } - genericButtonItem { - id("send_state") - text("Send State Event") - buttonClickAction(View.OnClickListener { - interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true)) - }) - } + override fun buildModels() { + genericButtonItem { + id("explore") + text(stringProvider.getString(R.string.dev_tools_explore_room_state)) + buttonClickAction(View.OnClickListener { + interactionListener?.processAction(RoomDevToolAction.ExploreRoomState) + }) + } + genericButtonItem { + id("send") + text(stringProvider.getString(R.string.dev_tools_send_custom_event)) + buttonClickAction(View.OnClickListener { + interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false)) + }) + } + genericButtonItem { + id("send_state") + text(stringProvider.getString(R.string.dev_tools_send_state_event)) + buttonClickAction(View.OnClickListener { + interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true)) + }) } } } diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt index c6e9e37e9f..e5b3fb737e 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt @@ -17,22 +17,21 @@ package im.vector.app.features.devtools import com.airbnb.epoxy.TypedEpoxyController +import im.vector.app.R +import im.vector.app.core.resources.StringProvider import im.vector.app.core.ui.list.genericFooterItem import im.vector.app.features.form.formEditTextItem import im.vector.app.features.form.formMultiLineEditTextItem import javax.inject.Inject -class RoomDevToolSendFormController @Inject constructor() : TypedEpoxyController() { +class RoomDevToolSendFormController @Inject constructor( + private val stringProvider: StringProvider +) : TypedEpoxyController() { - interface InteractionListener { - fun processAction(action: RoomDevToolAction) - } - - var interactionListener: InteractionListener? = null + var interactionListener: DevToolsInteractionListener? = null override fun buildModels(data: RoomDevToolViewState?) { - val sendMode = (data?.displayMode as? RoomDevToolViewState.Mode.SendEventForm) - ?: return + val sendEventForm = (data?.displayMode as? RoomDevToolViewState.Mode.SendEventForm) ?: return genericFooterItem { id("topSpace") @@ -42,19 +41,19 @@ class RoomDevToolSendFormController @Inject constructor() : TypedEpoxyController id("event_type") enabled(true) value(data.sendEventDraft?.type) - hint("Type") + hint(stringProvider.getString(R.string.dev_tools_form_hint_type)) showBottomSeparator(false) onTextChange { text -> interactionListener?.processAction(RoomDevToolAction.CustomEventTypeChange(text)) } } - if (sendMode.isState) { + if (sendEventForm.isState) { formEditTextItem { id("state_key") enabled(true) value(data.sendEventDraft?.stateKey) - hint("State Key") + hint(stringProvider.getString(R.string.dev_tools_form_hint_state_key)) showBottomSeparator(false) onTextChange { text -> interactionListener?.processAction(RoomDevToolAction.CustomEventStateKeyChange(text)) @@ -66,7 +65,7 @@ class RoomDevToolSendFormController @Inject constructor() : TypedEpoxyController id("event_content") enabled(true) value(data.sendEventDraft?.content) - hint("Event Content") + hint(stringProvider.getString(R.string.dev_tools_form_hint_event_content)) showBottomSeparator(false) onTextChange { text -> interactionListener?.processAction(RoomDevToolAction.CustomEventContentChange(text)) diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt index d9e6f911c9..abda6104cd 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormFragment.kt @@ -25,14 +25,12 @@ import com.airbnb.mvrx.withState import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.FragmentGenericRecyclerBinding import javax.inject.Inject class RoomDevToolSendFormFragment @Inject constructor( - val epoxyController: RoomDevToolSendFormController, - private val colorProvider: ColorProvider -) : VectorBaseFragment(), RoomDevToolSendFormController.InteractionListener { + private val epoxyController: RoomDevToolSendFormController +) : VectorBaseFragment(), DevToolsInteractionListener { val sharedViewModel: RoomDevToolViewModel by activityViewModel() diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt index f2425b9713..600464bb6d 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolStateEventListFragment.kt @@ -25,14 +25,12 @@ import com.airbnb.mvrx.withState import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.core.resources.ColorProvider import im.vector.app.databinding.FragmentGenericRecyclerBinding import javax.inject.Inject class RoomDevToolStateEventListFragment @Inject constructor( - val epoxyController: RoomStateListController, - private val colorProvider: ColorProvider -) : VectorBaseFragment(), RoomStateListController.InteractionListener { + private val epoxyController: RoomStateListController +) : VectorBaseFragment(), DevToolsInteractionListener { val sharedViewModel: RoomDevToolViewModel by activityViewModel() diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt index 7c847be3b1..9fffe70872 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt @@ -28,12 +28,15 @@ import com.squareup.moshi.Types import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.R import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorViewModel +import im.vector.app.core.resources.StringProvider import kotlinx.coroutines.launch import org.json.JSONObject import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.util.JsonDict @@ -43,6 +46,7 @@ import org.matrix.android.sdk.rx.rx class RoomDevToolViewModel @AssistedInject constructor( @Assisted val initialState: RoomDevToolViewState, private val errorFormatter: ErrorFormatter, + private val stringProvider: StringProvider, private val session: Session ) : VectorViewModel(initialState) { @@ -64,8 +68,8 @@ class RoomDevToolViewModel @AssistedInject constructor( } init { - - session.getRoom(initialState.roomId)?.rx() + session.getRoom(initialState.roomId) + ?.rx() ?.liveStateEvents(emptySet()) ?.execute { async -> copy(stateEvents = async) @@ -74,7 +78,7 @@ class RoomDevToolViewModel @AssistedInject constructor( override fun handle(action: RoomDevToolAction) { when (action) { - RoomDevToolAction.ExploreRoomState -> { + RoomDevToolAction.ExploreRoomState -> { setState { copy( displayMode = RoomDevToolViewState.Mode.StateEventList, @@ -82,7 +86,7 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - is RoomDevToolAction.ShowStateEvent -> { + is RoomDevToolAction.ShowStateEvent -> { val jsonString = MoshiProvider.providesMoshi() .adapter(Event::class.java) .toJson(action.event) @@ -95,10 +99,10 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - RoomDevToolAction.OnBackPressed -> { + RoomDevToolAction.OnBackPressed -> { handleBack() } - RoomDevToolAction.MenuEdit -> { + RoomDevToolAction.MenuEdit -> { withState { if (it.displayMode == RoomDevToolViewState.Mode.StateEventDetail) { // we want to edit it @@ -112,7 +116,7 @@ class RoomDevToolViewModel @AssistedInject constructor( } } } - is RoomDevToolAction.ShowStateEventType -> { + is RoomDevToolAction.ShowStateEventType -> { setState { copy( displayMode = RoomDevToolViewState.Mode.StateEventListByType, @@ -120,23 +124,23 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - RoomDevToolAction.MenuItemSend -> { + RoomDevToolAction.MenuItemSend -> { handleMenuItemSend() } - is RoomDevToolAction.UpdateContentText -> { + is RoomDevToolAction.UpdateContentText -> { setState { copy(editedContent = action.contentJson) } } - is RoomDevToolAction.SendCustomEvent -> { + is RoomDevToolAction.SendCustomEvent -> { setState { copy( displayMode = RoomDevToolViewState.Mode.SendEventForm(action.isStateEvent), - sendEventDraft = RoomDevToolViewState.SendEventDraft("m.room.message", null, "{\n}") + sendEventDraft = RoomDevToolViewState.SendEventDraft(EventType.MESSAGE, null, "{\n}") ) } } - is RoomDevToolAction.CustomEventTypeChange -> { + is RoomDevToolAction.CustomEventTypeChange -> { setState { copy( sendEventDraft = sendEventDraft?.copy(type = action.type) @@ -150,7 +154,7 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - is RoomDevToolAction.CustomEventContentChange -> { + is RoomDevToolAction.CustomEventContentChange -> { setState { copy( sendEventDraft = sendEventDraft?.copy(content = action.content) @@ -160,95 +164,102 @@ class RoomDevToolViewModel @AssistedInject constructor( } } - private fun handleMenuItemSend() = withState { - when (it.displayMode) { - RoomDevToolViewState.Mode.EditEventContent -> { - setState { copy(modalLoading = Loading()) } - viewModelScope.launch { - try { - val room = session.getRoom(initialState.roomId) - ?: throw IllegalArgumentException("Room not found") + private fun handleMenuItemSend() = withState { state -> + when (state.displayMode) { + RoomDevToolViewState.Mode.EditEventContent -> editEventContent(state) + is RoomDevToolViewState.Mode.SendEventForm -> sendEventContent(state, state.displayMode.isState) + else -> Unit + } + } - val adapter = MoshiProvider.providesMoshi() - .adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) - val json = adapter.fromJson(it.editedContent ?: "") - ?: throw IllegalArgumentException("No content") + private fun editEventContent(state: RoomDevToolViewState) { + setState { copy(modalLoading = Loading()) } - room.sendStateEvent( - it.selectedEvent?.type ?: "", - it.selectedEvent?.stateKey, - json + viewModelScope.launch { + try { + val room = session.getRoom(initialState.roomId) + ?: throw IllegalArgumentException(stringProvider.getString(R.string.room_error_not_found)) - ) - _viewEvents.post(DevToolsViewEvents.showSnackMessage("State event sent!")) - setState { - copy( - modalLoading = Success(Unit), - selectedEventJson = null, - editedContent = null, - displayMode = RoomDevToolViewState.Mode.StateEventListByType - ) - } - } catch (failure: Throwable) { - _viewEvents.post(DevToolsViewEvents.showAlertMessage(errorFormatter.toHumanReadable(failure))) - setState { copy(modalLoading = Fail(failure)) } - } + val adapter = MoshiProvider.providesMoshi() + .adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) + val json = adapter.fromJson(state.editedContent ?: "") + ?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_content)) + + room.sendStateEvent( + state.selectedEvent?.type ?: "", + state.selectedEvent?.stateKey, + json + + ) + _viewEvents.post(DevToolsViewEvents.ShowSnackMessage(stringProvider.getString(R.string.dev_tools_success_state_event))) + setState { + copy( + modalLoading = Success(Unit), + selectedEventJson = null, + editedContent = null, + displayMode = RoomDevToolViewState.Mode.StateEventListByType + ) } + } catch (failure: Throwable) { + _viewEvents.post(DevToolsViewEvents.ShowAlertMessage(errorFormatter.toHumanReadable(failure))) + setState { copy(modalLoading = Fail(failure)) } } - is RoomDevToolViewState.Mode.SendEventForm -> { - setState { copy(modalLoading = Loading()) } - viewModelScope.launch { - try { - val room = session.getRoom(initialState.roomId) - ?: throw IllegalArgumentException("Room not found") + } + } - val adapter = MoshiProvider.providesMoshi() - .adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) - val json = adapter.fromJson(it.sendEventDraft?.content ?: "") - ?: throw IllegalArgumentException("No content") + private fun sendEventContent(state: RoomDevToolViewState, isState: Boolean) { + setState { copy(modalLoading = Loading()) } + viewModelScope.launch { + try { + val room = session.getRoom(initialState.roomId) + ?: throw IllegalArgumentException(stringProvider.getString(R.string.room_error_not_found)) - val eventType = it.sendEventDraft?.type ?: throw IllegalArgumentException("Missing message type") - if (it.displayMode.isState) { - room.sendStateEvent( - eventType, - it.sendEventDraft.stateKey, - json + val adapter = MoshiProvider.providesMoshi() + .adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) + val json = adapter.fromJson(state.sendEventDraft?.content ?: "") + ?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_content)) - ) - } else { - // can we try to do some validation?? - // val validParse = MoshiProvider.providesMoshi().adapter(MessageContent::class.java).fromJson(it.sendEventDraft.content ?: "") - json.toModel(catchError = false) - ?: throw IllegalArgumentException("Malformed event") - room.sendEvent( - eventType, - json - ) - } + val eventType = state.sendEventDraft?.type + ?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_message_type)) - _viewEvents.post(DevToolsViewEvents.showSnackMessage("Event sent!")) - setState { - copy( - modalLoading = Success(Unit), - sendEventDraft = null, - displayMode = RoomDevToolViewState.Mode.Root - ) - } - } catch (failure: Throwable) { - _viewEvents.post(DevToolsViewEvents.showAlertMessage(errorFormatter.toHumanReadable(failure))) - setState { copy(modalLoading = Fail(failure)) } - } + if (isState) { + room.sendStateEvent( + eventType, + state.sendEventDraft.stateKey, + json + ) + } else { + // can we try to do some validation?? + // val validParse = MoshiProvider.providesMoshi().adapter(MessageContent::class.java).fromJson(it.sendEventDraft.content ?: "") + json.toModel(catchError = false) + ?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_malformed_event)) + room.sendEvent( + eventType, + json + ) } + + _viewEvents.post(DevToolsViewEvents.ShowSnackMessage(stringProvider.getString(R.string.dev_tools_success_event))) + setState { + copy( + modalLoading = Success(Unit), + sendEventDraft = null, + displayMode = RoomDevToolViewState.Mode.Root + ) + } + } catch (failure: Throwable) { + _viewEvents.post(DevToolsViewEvents.ShowAlertMessage(errorFormatter.toHumanReadable(failure))) + setState { copy(modalLoading = Fail(failure)) } } } } private fun handleBack() = withState { when (it.displayMode) { - RoomDevToolViewState.Mode.Root -> { + RoomDevToolViewState.Mode.Root -> { _viewEvents.post(DevToolsViewEvents.Dismiss) } - RoomDevToolViewState.Mode.StateEventList -> { + RoomDevToolViewState.Mode.StateEventList -> { setState { copy( selectedEvent = null, @@ -257,7 +268,7 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - RoomDevToolViewState.Mode.StateEventDetail -> { + RoomDevToolViewState.Mode.StateEventDetail -> { setState { copy( selectedEvent = null, @@ -266,7 +277,7 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - RoomDevToolViewState.Mode.EditEventContent -> { + RoomDevToolViewState.Mode.EditEventContent -> { setState { copy( displayMode = RoomDevToolViewState.Mode.StateEventDetail @@ -281,7 +292,7 @@ class RoomDevToolViewModel @AssistedInject constructor( ) } } - is RoomDevToolViewState.Mode.SendEventForm -> { + is RoomDevToolViewState.Mode.SendEventForm -> { setState { copy( displayMode = RoomDevToolViewState.Mode.Root diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt index 844ed9be20..69070c509b 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt @@ -32,18 +32,12 @@ class RoomStateListController @Inject constructor( private val colorProvider: ColorProvider ) : TypedEpoxyController() { - interface InteractionListener { - fun processAction(action: RoomDevToolAction) - } - - var interactionListener: InteractionListener? = null + var interactionListener: DevToolsInteractionListener? = null override fun buildModels(data: RoomDevToolViewState?) { when (data?.displayMode) { RoomDevToolViewState.Mode.StateEventList -> { - val stateEventsGroups = (data.stateEvents.invoke() ?: emptyList()).groupBy { - it.type - } + val stateEventsGroups = data.stateEvents.invoke().orEmpty().groupBy { it.type } if (stateEventsGroups.isEmpty()) { noResultItem { @@ -55,7 +49,7 @@ class RoomStateListController @Inject constructor( genericItem { id(entry.key) title(entry.key) - description("${entry.value.size} entries") + description(stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size)) itemClickAction(GenericItem.Action("view").apply { perform = Runnable { interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key)) @@ -66,7 +60,7 @@ class RoomStateListController @Inject constructor( } } RoomDevToolViewState.Mode.StateEventListByType -> { - val stateEvents = (data.stateEvents.invoke() ?: emptyList()).filter { it.type == data.currentStateType } + val stateEvents = data.stateEvents.invoke().orEmpty().filter { it.type == data.currentStateType } if (stateEvents.isEmpty()) { noResultItem { id("no state events") @@ -74,10 +68,12 @@ class RoomStateListController @Inject constructor( } } else { stateEvents.forEach { stateEvent -> - val contentMap = JSONObject(stateEvent.content ?: emptyMap()).toString().let { + val contentJson = JSONObject(stateEvent.content.orEmpty()).toString().let { if (it.length > 140) { it.take(140) + Typography.ellipsis - } else it.take(140) + } else { + it.take(140) + } } genericItem { id(stateEvent.eventId) @@ -95,7 +91,7 @@ class RoomStateListController @Inject constructor( textStyle = "normal" } }) - description(contentMap) + description(contentJson) itemClickAction(GenericItem.Action("view").apply { perform = Runnable { interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent)) diff --git a/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt b/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt index 974d2594ee..4ba668a051 100644 --- a/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/form/FormMultiLineEditTextItem.kt @@ -1,5 +1,5 @@ /* - * Copyright 2019 New Vector Ltd + * 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. diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 8347735d0a..fc380193d1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -128,7 +128,6 @@ import im.vector.app.features.command.Command import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.util.toImageRes import im.vector.app.features.crypto.verification.VerificationBottomSheet -import im.vector.app.features.devtools.RoomDevToolActivity import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.composer.TextComposerView import im.vector.app.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet @@ -769,7 +768,7 @@ class RoomDetailFragment @Inject constructor( true } R.id.dev_tools -> { - startActivity(RoomDevToolActivity.intent(roomDetailArgs.roomId, requireContext())) + navigator.openDevTools(requireContext(), roomDetailArgs.roomId) true } else -> super.onOptionsItemSelected(item) diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 43a3f748a5..c802a5f65c 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -42,6 +42,7 @@ import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.crypto.verification.SupportedVerificationMethodsProvider import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.debug.DebugMenuActivity +import im.vector.app.features.devtools.RoomDevToolActivity import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailArgs import im.vector.app.features.home.room.detail.search.SearchActivity @@ -345,6 +346,10 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } + override fun openDevTools(context: Context, roomId: String) { + context.startActivity(RoomDevToolActivity.intent(context, roomId)) + } + private fun startActivity(context: Context, intent: Intent, buildTask: Boolean) { if (buildTask) { val stackBuilder = TaskStackBuilder.create(context) diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index dda071795b..4d09bde93c 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -117,4 +117,6 @@ interface Navigator { options: ((MutableList>) -> Unit)?) fun openSearch(context: Context, roomId: String) + + fun openDevTools(context: Context, roomId: String) } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt index 86146e7d3a..eda461de14 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt @@ -63,8 +63,7 @@ class RoomMemberListController @Inject constructor( ?.filter { event -> event.content.toModel() ?.takeIf { - it.displayName != null - && (data.filter.isEmpty() || it.displayName!!.contains(data.filter, ignoreCase = true)) + data.filter.isEmpty() || it.displayName?.contains(data.filter, ignoreCase = true) == true } != null } .orEmpty() diff --git a/vector/src/main/res/layout/fragment_devtools_editor.xml b/vector/src/main/res/layout/fragment_devtools_editor.xml index 98682a1b65..eaa7399279 100644 --- a/vector/src/main/res/layout/fragment_devtools_editor.xml +++ b/vector/src/main/res/layout/fragment_devtools_editor.xml @@ -1,16 +1,20 @@ + android:textSize="12sp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> \ No newline at end of file diff --git a/vector/src/main/res/layout/item_form_multiline_text_input.xml b/vector/src/main/res/layout/item_form_multiline_text_input.xml index f844f91a5a..aaad0826ef 100644 --- a/vector/src/main/res/layout/item_form_multiline_text_input.xml +++ b/vector/src/main/res/layout/item_form_multiline_text_input.xml @@ -25,9 +25,9 @@ android:id="@+id/formMultiLineEditText" android:layout_width="match_parent" android:layout_height="wrap_content" - android:inputType="textMultiLine" - android:imeOptions="actionDone" android:gravity="top|start" + android:imeOptions="actionDone" + android:inputType="textMultiLine" android:minLines="4" tools:hint="@string/create_room_name_hint" /> diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index c2677bf89e..2d54948116 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2745,6 +2745,10 @@ Wrong code, %d remaining attempt Wrong code, %d remaining attempts + + %d entry" + %d entries" + Warning! Last remaining attempt before logout! Too many errors, you\'ve been logged out Choose a PIN for security @@ -2793,4 +2797,19 @@ Element requires you to enter your credentials to perform this action. Failed to authenticate Dev Tools + Explore Room State + Send Custom Event + Send State Event + State Events + Edit Content + Send Custom State Event + Type + State Key + Event Content + No content + Missing message type + Malformed event + Event sent! + State event sent! +