Merge branch 'develop' into feature/bma/lang

This commit is contained in:
Benoit Marty 2021-02-16 11:40:24 +01:00 committed by GitHub
commit 3ac3f09df0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
80 changed files with 1981 additions and 482 deletions

View file

@ -27,6 +27,7 @@ Test:
-
Other changes:
- New Dev Tools panel for developers
- Fix typos in CHANGES.md (#2811)
Changes in Element 1.0.17 (2021-02-09)

View file

@ -0,0 +1,2 @@
يحتوي هذا الإصدار الجديد بشكل أساسي على إصلاحات للأخطاء وتحسينات. إرسال الرسالة أصبح الآن أسرع بكثير.
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View file

@ -0,0 +1,2 @@
يحتوي هذا الإصدار الجديد بشكل أساسي على تحسينات في واجهة المستخدم وتجربة المستخدم. يُمكنك الآن دعوة الأصدقاء وإنشاء رسالة مُباشرة بسرعة كبيرة عن طريق مسح رموز الاستجابة السريعة.
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View file

@ -0,0 +1,2 @@
التغييرات الرئيسة في هذا الإصدار: مُعاينة URL، لوحة مفاتيح Emoji جديدة، إمكانيات جديدة لإعدادات الغرفة والثلج لميلاد المسيح!
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.12

View file

@ -0,0 +1,2 @@
التغييرات الرئيسة في هذا الإصدار: مُعاينة URL، لوحة مفاتيح Emoji جديدة، إمكانيات جديدة لإعدادات الغرفة والثلج لميلاد المسيح!
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.13

View file

@ -0,0 +1,2 @@
التغييرات الرئيسة في هذا الإصدار: تحرير أذونات الغُرفة، السِّمة التلقائية الفاتحة/الداكنة، ومجموعة من إصلاحات الأخطاء.
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.14

View file

@ -0,0 +1,2 @@
التغييرات الرئيسة في هذا الإصدار: دعم تسجيل الدخول الاجتماعي.
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.15

View file

@ -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

View file

@ -0,0 +1,2 @@
التغييرات الرئيسة في هذا الإصدار: إصلاحات الأخطاء!
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.17

View file

@ -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
<b> لماذا تختار Element؟</b>
<b>تملَّك بياناتك</b>: أنت من تُقرر أين تحتفظ ببياناتك ورسائلك. أنت تمتلكها وتتحكم فيها، وليس بعض الشركات الكُبرى الإحتكارية التي تُنقِّب عن بياناتك أو تُتيح الوصول إلى أطراف ثالثة.
<b>تراسُل وتعاون مفتوح</b>: يُمكنك مُحادثة أي شخص آخر على شبكة Matrix، سواء كانوا يستخدمون Element أو تطبيق Matrix آخر، وحتى إذا كانوا يستخدمون نظام مُراسلة مُختلف مثل Slack أو IRC أو XMPP.
<b>الأمان-الخارق</b>: تشفير حقيقي من النهاية إلى النهاية (فقط أطراف المُحادثة مَن يُمكنهم فك تشفير الرسائل)، والتوقيع المُتبادل للتحقق من أجهزة المُشاركين في المُحادثة.
<b>التواصل الكامل</b>: المُراسلة، المُكالمات الصوتية والمرئية، مُشاركة الملفات، مُشاركة الشاشة، مجموعة كاملة وكبيرة من عمليات التكامُل، الروبوتات والأدوات. بناء الغُرف، المُجتمعات، ابق على اتصال وأنجز المهام.
<b>أين ما كُنت</b>: ابق على اتصال أينما كنت مع سجل الرسائل المتزامن بالكامل عبر جميع أجهزتك وفي الويب على https://app.element.io.

View file

@ -0,0 +1 @@
مُحادثة آمنة لا مركزية و VoIP. حافظ على بياناتك آمنة من الأطراف الثالثة.

View file

@ -0,0 +1 @@
Element (سابقاً Riot.im)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -0,0 +1,2 @@
Основні зміни у цій версії: Виправлення помилок!
Повний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.0.17

View file

@ -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<PublicKeys> = emptyList()
@Json(name = "public_keys") val publicKeys: List<PublicKeys>? = emptyList()
)
@JsonClass(generateAdapter = true)

View file

@ -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<Optional<Event>>
/**
* Get state events of the room
* @param eventTypes Set of eventType. If empty, all state events will be returned
*/
fun getStateEvents(eventTypes: Set<String>, stateKey: QueryStringValue = QueryStringValue.NoCondition): List<Event>
/**
* 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<String>, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData<List<Event>>
}

View file

@ -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
}
}

View file

@ -80,7 +80,11 @@ internal class StateEventDataSource @Inject constructor(@SessionDatabase private
): RealmQuery<CurrentStateEventEntity> {
return realm.where<CurrentStateEventEntity>()
.equalTo(CurrentStateEventEntityFields.ROOM_ID, roomId)
.`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
.apply {
if (eventTypes.isNotEmpty()) {
`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
}
}
.process(CurrentStateEventEntityFields.STATE_KEY, stateKey)
}
}

View file

@ -1,147 +1,150 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="summary_user_sent_image">أرسل %1$s صورة.</string>
<string name="notice_room_invite_no_invitee">دعوة من %s</string>
<string name="notice_room_invite">دعى %1$s %2$s</string>
<string name="notice_room_invite_you">دعاك %1$s</string>
<string name="notice_room_join">انضمّ %1$s إلى الغرفة</string>
<string name="notice_room_leave">غادر %1$s الغرفة</string>
<string name="notice_room_reject">رفض %1$s الدعوة</string>
<string name="notice_room_kick">طرد %1$s %2$s</string>
<string name="notice_room_unban">رفع %1$s المنع عن %2$s</string>
<string name="notice_room_ban">منع %1$s %2$s</string>
<string name="notice_avatar_url_changed">غيّر %1$s صورته</string>
<string name="notice_display_name_set">ضبط %1$s اسم العرض على %2$s</string>
<string name="notice_display_name_changed_from">غيّر %1$s اسم العرض من %2$s إلى %3$s</string>
<string name="notice_display_name_removed">أزال %1$s اسم العرض (⁨كان %2$s)</string>
<string name="notice_room_topic_changed">غيّر %1$s الموضوع إلى: %2$s</string>
<string name="notice_room_name_changed">غيّر %1$s اسم الغرفة إلى: %2$s</string>
<string name="notice_answered_call">ردّ %s على المكالمة.</string>
<string name="notice_ended_call">أنهى %s المكالمة.</string>
<string name="notice_made_future_room_visibility">جعل %1$s تأريخ الغرفة مستقبلًا ظاهرًا على %2$s</string>
<string name="notice_room_visibility_invited">كل أعضاء الغرفة من لحظة دعوتهم.</string>
<string name="notice_room_visibility_joined">كل أعضاء الغرفة من لحظة انضمامهم.</string>
<string name="notice_room_visibility_shared">كل أعضاء الغرفة.</string>
<string name="notice_room_visibility_world_readable">الكل.</string>
<string name="notice_room_visibility_unknown">المجهول (%s).</string>
<string name="notice_end_to_end">فعّل %1$s تعمية الطرفين (%2$s)</string>
<string name="notice_requested_voip_conference">طلب %1$s اجتماع VoIP</string>
<string name="notice_voip_started">بدأ اجتماع VoIP</string>
<string name="notice_voip_finished">انتهى اجتماع VoIP</string>
<string name="notice_room_name_removed">أزال %1$s اسم الغرفة</string>
<string name="notice_room_topic_removed">أزال %1$s موضوع الغرفة</string>
<string name="summary_user_sent_image">%1$s قد أرسل صورة.</string>
<string name="notice_room_invite_no_invitee">دعوة من %s</string>
<string name="notice_room_invite">%1$s قد دعى %2$s</string>
<string name="notice_room_invite_you">%1$s قد دعاك أنت</string>
<string name="notice_room_join">%1$s قد إنضّم إلى الغرفة</string>
<string name="notice_room_leave">%1$s قد غادر الغرفة</string>
<string name="notice_room_reject">%1$s قد رفض الدعوة</string>
<string name="notice_room_kick">%1$s قد طرد %2$s</string>
<string name="notice_room_unban">%1$s قد رفع الحظر عن %2$s</string>
<string name="notice_room_ban">%1$s قد حظر %2$s</string>
<string name="notice_avatar_url_changed">%1$s قد غيّر صورته الشخصية</string>
<string name="notice_display_name_set">%1$s قد عيّن اسمه الظاهر إلى %2$s</string>
<string name="notice_display_name_changed_from">%1$s قد غيّر اسمه الظاهر من %2$s إلى %3$s</string>
<string name="notice_display_name_removed">%1$s قد أزال اسمه الظاهر (لقد كان %2$s)</string>
<string name="notice_room_topic_changed">%1$s قد غيّر الموضوع إلى: %2$s</string>
<string name="notice_room_name_changed">%1$s قد غيّر اسم الغرفة إلى: %2$s</string>
<string name="notice_answered_call">%s قد أجاب على المُكالمة.</string>
<string name="notice_ended_call">%s قد أنهى المُكالمة.</string>
<string name="notice_made_future_room_visibility">%1$s قد جعل التأريخ المُستقبلي للغرفة مرئيًا لـ %2$s</string>
<string name="notice_room_visibility_invited">جميع أعضاء الغرفة، من اللحظة التي تمت دعوتهم.</string>
<string name="notice_room_visibility_joined">جميع أعضاء الغرفة، من لحظة انضمامهم.</string>
<string name="notice_room_visibility_shared">جميع أعضاء الغرفة.</string>
<string name="notice_room_visibility_world_readable">أيُّ شخص.</string>
<string name="notice_room_visibility_unknown">غير معروف (%s).</string>
<string name="notice_end_to_end">%1$s قد فعّل تعمية النهاية-إلى-النهاية (%2$s)</string>
<string name="notice_requested_voip_conference">%1$s قد طلب اجتماع VoIP</string>
<string name="notice_voip_started">اجتماع VoIP قد بدأ</string>
<string name="notice_voip_finished">اجتماع VoIP قد انتهى</string>
<string name="notice_room_name_removed">%1$s قد أزال اسم الغرفة</string>
<string name="notice_room_topic_removed">%1$s قد أزال موضوع الغرفة</string>
<string name="notice_profile_change_redacted">حدّث %1$s اللاحة %2$s</string>
<string name="notice_room_third_party_invite">أرسل %1$s دعوة إلى %2$s للانضمام إلى الغرفة</string>
<string name="notice_crypto_unable_to_decrypt">** تعذّر فك التعمية: %s **</string>
<string name="notice_crypto_error_unkwown_inbound_session_id">لم يُرسل جهاز المرسل مفاتيح هذه الرسالة.</string>
<string name="unable_to_send_message">تعذّر إرسال الرسالة</string>
<string name="message_failed_to_upload">فشل رفع الصورة</string>
<string name="network_error">خطأ في الشبكة</string>
<string name="matrix_error">خطأ في «ماترِكس»</string>
<string name="room_error_join_failed_empty_room">لا يمكنك حاليًا الانضمام ثانيةً إلى غرفة فارغة.</string>
<string name="encrypted_message">رسالة معمّاة</string>
<string name="medium_email">عنوان البريد الإلكتروني</string>
<string name="medium_phone_number">رقم الهاتف</string>
<string name="summary_message">%1$s: %2$s</string>
<string name="notice_room_withdraw">انسحب %1$s من دعوة %2$s</string>
<string name="notice_placed_video_call">أجرى %s مكالمة مرئية.</string>
<string name="notice_placed_voice_call">أجرى %s مكالمة صوتية.</string>
<string name="notice_room_withdraw">%1$s قد سحب دعوة %2$s</string>
<string name="notice_placed_video_call">%s قد أجرى مُكالمة مرئية.</string>
<string name="notice_placed_voice_call">%s قد أجرى مُكالمة صوتية.</string>
<string name="notice_room_third_party_registered_invite">قَبِل %1$s دعوة %2$s</string>
<string name="could_not_redact">تعذر التهذيب</string>
<string name="summary_user_sent_sticker">أرسل %1$s ملصقًا.</string>
<string name="notice_avatar_changed_too">(تغيّرت الصورة أيضا)</string>
<string name="summary_user_sent_sticker">%1$s قد أرسل مُلصقًا.</string>
<string name="notice_avatar_changed_too">(تمَّ تغيير الصورة أيضًا)</string>
<string name="room_displayname_invite_from">دعوة من %s</string>
<string name="room_displayname_empty_room">غرفة فارغة</string>
<string name="room_displayname_two_members">%1$s و %2$s</string>
<string name="room_displayname_room_invite">دعوة إلى غرفة</string>
<plurals name="room_displayname_three_and_more_members">
<item quantity="zero"></item>
<item quantity="one"></item>
<item quantity="two"></item>
<item quantity="few"></item>
<item quantity="many"></item>
<item quantity="other"></item>
<item quantity="zero"/>
<item quantity="one"/>
<item quantity="two"/>
<item quantity="few"/>
<item quantity="many"/>
<item quantity="other"/>
</plurals>
<string name="summary_you_sent_image">أرسلت صورة.</string>
<string name="summary_you_sent_sticker">أرسلت ملصقًا.</string>
<string name="summary_you_sent_image">أنت قد أرسلت صورة.</string>
<string name="summary_you_sent_sticker">أنت قد أرسلت مُلصقًا.</string>
<string name="notice_room_invite_no_invitee_by_you">دعوة منك أنت</string>
<string name="notice_room_created">أنشأ %1$s الغرفة</string>
<string name="notice_room_created_by_you">أنشأت الغرفة</string>
<string name="notice_room_invite_by_you">دعوت %1$s</string>
<string name="notice_room_join_by_you">انضممت إلى الغرفة</string>
<string name="notice_room_leave_by_you">غادرت الغرفة</string>
<string name="notice_room_reject_by_you">رفضت الدعوة</string>
<string name="notice_room_kick_by_you">طردت %1$s</string>
<string name="notice_room_unban_by_you">رفعت المنع عن %1$s</string>
<string name="notice_room_ban_by_you">منعت %1$s</string>
<string name="notice_room_withdraw_by_you">انسحبت من دعوة %1$s</string>
<string name="notice_avatar_url_changed_by_you">غيّرت صورتك</string>
<string name="notice_display_name_set_by_you">ضبطت اسم العرض على %1$s</string>
<string name="notice_display_name_changed_from_by_you">غيّرت اسم العرض من %1$s إلى %2$s</string>
<string name="notice_display_name_removed_by_you">أزلت اسم العرض (كان %1$s)</string>
<string name="notice_room_topic_changed_by_you">غيّرت الموضوع إلى: %1$s</string>
<string name="notice_room_avatar_changed">غيّر %1$s صورة الغرفة</string>
<string name="notice_room_avatar_changed_by_you">غيّرت صورة الغرفة</string>
<string name="notice_room_name_changed_by_you">غيّرت اسم الغرفة إلى: %1$s</string>
<string name="notice_placed_video_call_by_you">أجريت مكالمة مرئية.</string>
<string name="notice_placed_voice_call_by_you">أجريت مكالمة صوتية.</string>
<string name="notice_call_candidates">أرسل %s البيانات لإعداد المكالمة.</string>
<string name="notice_call_candidates_by_you">أرسلت البيانات لإعداد المكالمة.</string>
<string name="notice_answered_call_by_you">رددت على المكالمة.</string>
<string name="notice_ended_call_by_you">أنهيت المكالمة.</string>
<string name="notice_made_future_room_visibility_by_you">جعلت تأريخ الغرفة مستقبلًا ظاهرًا على %1$s</string>
<string name="notice_end_to_end_by_you">فعّلت تعمية الطرفين (%1$s)</string>
<string name="notice_room_update">رقّى %s هذه الغرفة.</string>
<string name="notice_room_update_by_you">رقّيت هذه الغرفة.</string>
<string name="notice_requested_voip_conference_by_you">طلبت اجتماع VoIP</string>
<string name="notice_room_name_removed_by_you">أزلت اسم الغرفة</string>
<string name="notice_room_topic_removed_by_you">أزلت موضوع الغرفة</string>
<string name="notice_room_avatar_removed">أزال %1$s صورة الغرفة</string>
<string name="notice_room_avatar_removed_by_you">أزلت صورة الغرفة</string>
<string name="notice_event_redacted">أُزيلت الرسالة</string>
<string name="notice_event_redacted_by">أزال %1$s الرسالة</string>
<string name="notice_room_created">%1$s قد أنشأ الغرفة</string>
<string name="notice_room_created_by_you">أنت قد أنشأت الغرفة</string>
<string name="notice_room_invite_by_you">أنت قد دعوت %1$s</string>
<string name="notice_room_join_by_you">أنت قد انضممت إلى الغرفة</string>
<string name="notice_room_leave_by_you">أنت قد غادرت الغرفة</string>
<string name="notice_room_reject_by_you">أنت قد رفضت الدعوة</string>
<string name="notice_room_kick_by_you">أنت قد طردت %1$s</string>
<string name="notice_room_unban_by_you">أنت قد رفعت الحظر عن %1$s</string>
<string name="notice_room_ban_by_you">أنت قد حظرت %1$s</string>
<string name="notice_room_withdraw_by_you">أنت قد سحبت دعوة %1$s</string>
<string name="notice_avatar_url_changed_by_you">أنت قد غيّرت صورتك الشخصية</string>
<string name="notice_display_name_set_by_you">أنت قد عيّنت اسمك الظاهر إلى %1$s</string>
<string name="notice_display_name_changed_from_by_you">أنت قد غيّرت اسمك الظاهر من %1$s إلى %2$s</string>
<string name="notice_display_name_removed_by_you">أنت قد أزلت اسمك الظاهر (لقد كان %1$s)</string>
<string name="notice_room_topic_changed_by_you">أنت قد غيّرت الموضوع إلى: %1$s</string>
<string name="notice_room_avatar_changed">%1$s قد غيّر صورة الغرفة</string>
<string name="notice_room_avatar_changed_by_you">أنت قد غيّرت صورة الغرفة</string>
<string name="notice_room_name_changed_by_you">أنت قد غيّرت اسم الغرفة إلى: %1$s</string>
<string name="notice_placed_video_call_by_you">أنت قد أجريت مُكالمة مرئية.</string>
<string name="notice_placed_voice_call_by_you">أنت قد أجريت مُكالمة صوتية.</string>
<string name="notice_call_candidates">%s قد أرسل بيانات لإعداد مُكالمة.</string>
<string name="notice_call_candidates_by_you">أنت قد أرسلت بيانات لإعداد مُكالمة.</string>
<string name="notice_answered_call_by_you">أنت قد أجبت على المُكالمة.</string>
<string name="notice_ended_call_by_you">أنت قد أنهيت المُكالمة.</string>
<string name="notice_made_future_room_visibility_by_you">أنت قد جعلت التأريخ المُستقبلي للغرفة مرئيًا لـ %1$s</string>
<string name="notice_end_to_end_by_you">أنت قد فعّلت تعيمية النهاية-إلى-النهاية (%1$s)</string>
<string name="notice_room_update">%s قد قام بترقية هذه الغرفة.</string>
<string name="notice_room_update_by_you">أنت قد رقّيتَ هذه الغرفة.</string>
<string name="notice_requested_voip_conference_by_you">أنت قد طلبت اجتماع VoIP</string>
<string name="notice_room_name_removed_by_you">أنت قد أزلت اسم الغرفة</string>
<string name="notice_room_topic_removed_by_you">أنت قد أزلت موضوع الغرفة</string>
<string name="notice_room_avatar_removed">%1$s قد أزال صورة الغرفة</string>
<string name="notice_room_avatar_removed_by_you">أنت قد أزلت صورة الغرفة</string>
<string name="notice_event_redacted">تمت إزالة الرسالة</string>
<string name="notice_event_redacted_by">الرسالة قد أُزيلت بواسطة %1$s</string>
<string name="notice_event_redacted_with_reason">أُزيلت الرسالة [السبب: %1$s]</string>
<string name="notice_event_redacted_by_with_reason">أزال %1$s الرسالة [السبب: %2$s]</string>
<string name="notice_room_third_party_invite_by_you">أرسلت دعوة إلى %1$s للانضمام إلى الغرفة</string>
<string name="notice_room_third_party_revoked_invite">سحب %1$s دعوة %2$s للانضمام إلى الغرفة</string>
<string name="notice_room_third_party_revoked_invite_by_you">سحبت دعوة %1$s للانضمام إلى الغرفة</string>
<string name="notice_room_third_party_registered_invite_by_you">قَبِلت دعوة %1$s</string>
<string name="notice_widget_added">أضاف %1$s الودجة %2$s</string>
<string name="notice_widget_added_by_you">أضفت الودجة %1$s</string>
<string name="notice_widget_removed">أزال %1$s الودجة %2$s</string>
<string name="notice_widget_removed_by_you">أزلت الودجة %1$s</string>
<string name="notice_widget_modified">عدّل %1$s الودجة %2$s</string>
<string name="notice_widget_modified_by_you">عدّلت الودجة %1$s</string>
<string name="power_level_admin">مدير</string>
<string name="power_level_default">المبدئي</string>
<string name="power_level_custom">مخصّص (%1$d)</string>
<string name="power_level_custom_no_value">مخصّص</string>
<string name="notice_power_level_changed_by_you">غيّرت مستوى قوّة %1$s.</string>
<string name="notice_power_level_changed">غيّر %1$s مستوى قوّة %2$s.</string>
<string name="notice_power_level_diff">%1$s من %2$s إلى %3$s</string>
<string name="initial_sync_start_importing_account">المزامنة الأولية:
\nيستورد الحساب…</string>
</resources>
<string name="notice_room_server_acl_allow_is_empty">🎉 جميع الخوادم محظورة من المُشاركة! لم يعُد من الممكن استخدام هذه الغرفة.</string>
<string name="notice_room_server_acl_updated_no_change">لا تغيير.</string>
<string name="notice_room_server_acl_updated_ip_literals_not_allowed">• خوادم مُطابقة IP الحرفية محظورة الآن.</string>
<string name="notice_room_server_acl_updated_was_allowed">• الخادم المُطابق لـ %s قد أُزيل من قائمة السماح.</string>
<string name="notice_room_server_acl_updated_allowed">• الخادم المُطابق لـ %s مسموح الآن.</string>
<string name="notice_room_server_acl_updated_was_banned">• الخادم المُطابق لـ %s قد أُزيل من قائمة الحظر.</string>
<string name="notice_room_server_acl_updated_banned">• الخادم المُطابق لـ %s محظور الآن.</string>
<string name="notice_room_server_acl_updated_ip_literals_allowed">• خوادم مُطابقة IP الحرفية مسموحة الآن.</string>
<string name="notice_room_server_acl_updated_title_by_you">أنت قد غيّرت خادم الـACLs لهذه الغرفة.</string>
<string name="notice_room_server_acl_updated_title">%s قد غيّر خادم الـACLs لهذه الغرفة.</string>
<string name="notice_room_server_acl_set_ip_literals_not_allowed">• الخادم يحظر مُطابقة القيم الحرفية للـIP.</string>
<string name="notice_room_server_acl_set_allowed">• الخادم المُطابق لـ %s مسموح.</string>
<string name="notice_room_server_acl_set_banned">• الخادم المُطابق لـ %s محظور.</string>
<string name="notice_room_server_acl_set_ip_literals_allowed">• الخادم يسمح بمُطابقة القيم الحرفية للـIP.</string>
<string name="notice_room_server_acl_set_title_by_you">أنت قد عيّنت خادم الـACLs لهذه الغرفة.</string>
<string name="notice_room_server_acl_set_title">%s قد عيّن خادم الـACLs لهذه الغرفة.</string>
<string name="notice_direct_room_update_by_you">أنت قد قمت بالترقية هُنا.</string>
<string name="notice_direct_room_update">%s قد قام بالترقية هُنا.</string>
<string name="notice_made_future_direct_room_visibility_by_you">أنت قد جعلت الرسائل المُستقبلية مرئية لـ %1$s</string>
<string name="notice_made_future_direct_room_visibility">%1$s قد جعل الرسائل المُستقبلية مرئية لـ %2$s</string>
<string name="notice_direct_room_leave_by_you">أنت قد غادرت الغرفة</string>
<string name="notice_direct_room_leave">%1$s قد غادر الغرفة</string>
<string name="notice_direct_room_join_by_you">أنت قد انضممت</string>
<string name="notice_direct_room_join">%1$s قد انضم</string>
<string name="notice_direct_room_created_by_you">أنت قد أنشأت المُناقشة</string>
<string name="notice_direct_room_created">%1$s قد أنشأ المُناقشة</string>
</resources>

View file

@ -259,4 +259,10 @@
<string name="notice_room_server_acl_updated_title">%s ha canviat les ACLs de servidor d\'aquesta sala.</string>
<string name="notice_room_server_acl_set_title_by_you">Has establert les ACLs de servidor per aquesta sala.</string>
<string name="notice_room_server_acl_set_title">%s ha establert les ACLs de servidor d\'aquesta sala.</string>
<string name="notice_widget_jitsi_modified_by_you">Has modificat la videoconferència</string>
<string name="notice_widget_jitsi_modified">%1$s ha modificat la videoconferència</string>
<string name="notice_widget_jitsi_removed_by_you">Has finalitzat la videoconferència</string>
<string name="notice_widget_jitsi_added">%1$s ha iniciat una videoconferència</string>
<string name="notice_widget_jitsi_added_by_you">Has iniciat una videoconferència</string>
<string name="notice_widget_jitsi_removed">%1$s ha finalitzat la videoconferència</string>
</resources>

View file

@ -266,4 +266,10 @@
<string name="notice_room_server_acl_set_banned">• Server, die mit %s übereinstimmen, sind gesperrt.</string>
<string name="notice_room_server_acl_set_title_by_you">Du hast die Server-ACL für diesen Raum gesetzt.</string>
<string name="notice_room_server_acl_set_title">%s hat die Server-Zugriffssteuerungsliste (ACL) für diesen Raum gesetzt.</string>
<string name="notice_widget_jitsi_modified_by_you">Du hast eine Videokonferenz geändert</string>
<string name="notice_widget_jitsi_modified">Videokonferenz von %1$s geändert</string>
<string name="notice_widget_jitsi_removed">Videokonferenz von %1$s beendet</string>
<string name="notice_widget_jitsi_removed_by_you">Du hast eine Videokonferenz beendet</string>
<string name="notice_widget_jitsi_added_by_you">Du hast eine Videokonferenz gestartet</string>
<string name="notice_widget_jitsi_added">Videokonferenz von %1$s gestartet</string>
</resources>

View file

@ -258,4 +258,10 @@
<item quantity="other">%1$s lisas sellele jututoale täiendavad aadressid %2$s.</item>
</plurals>
<string name="notice_room_canonical_alias_no_change_by_you">Sa muutsid selle jututoa aadresse.</string>
<string name="notice_widget_jitsi_modified_by_you">Sina muutsid videokoosolekut</string>
<string name="notice_widget_jitsi_removed_by_you">Sina lõpetasid videokoosoleku</string>
<string name="notice_widget_jitsi_removed">%1$s lõpetas videokoosoleku</string>
<string name="notice_widget_jitsi_added_by_you">Sina algatasid videokoosoleku</string>
<string name="notice_widget_jitsi_added">%1$s algatas videokoosoleku</string>
<string name="notice_widget_jitsi_modified">%1$s muutis videokoosolekut</string>
</resources>

View file

@ -259,4 +259,10 @@
<item quantity="one">%1$s ha aggiunto l\'indirizzo alternativo %2$s per questa stanza.</item>
<item quantity="other">%1$s ha aggiunto gli indirizzi alternativi %2$s per questa stanza.</item>
</plurals>
<string name="notice_widget_jitsi_modified_by_you">Hai modificato la video conferenza</string>
<string name="notice_widget_jitsi_modified">Video conferenza modificata da %1$s</string>
<string name="notice_widget_jitsi_added_by_you">Hai iniziato la video conferenza</string>
<string name="notice_widget_jitsi_removed_by_you">Hai terminato la video conferenza</string>
<string name="notice_widget_jitsi_removed">Video conferenza terminata da %1$s</string>
<string name="notice_widget_jitsi_added">Video conferenza iniziata da %1$s</string>
</resources>

View file

@ -268,4 +268,10 @@
<item quantity="few">%1$s уклони %2$s као адресе ове собе.</item>
<item quantity="other">%1$s уклони %2$s као адресе ове собе.</item>
</plurals>
<string name="notice_widget_jitsi_modified_by_you">Изменили сте видео конференцију</string>
<string name="notice_widget_jitsi_modified">%1$s измени видео конференцију</string>
<string name="notice_widget_jitsi_removed_by_you">Завршили сте видео конференцију</string>
<string name="notice_widget_jitsi_removed">%1$s заврши видео конференцију</string>
<string name="notice_widget_jitsi_added_by_you">Покренули сте видео конференцију</string>
<string name="notice_widget_jitsi_added">%1$s покрену видео конференцију</string>
</resources>

View file

@ -267,6 +267,7 @@
<!-- </intent-filter>-->
</activity>
<activity android:name=".features.devtools.RoomDevToolActivity"/>
<!-- Services -->
<service

View file

@ -45,6 +45,10 @@ import im.vector.app.features.crypto.verification.emoji.VerificationEmojiCodeFra
import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQRWaitingFragment
import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQrScannedByOtherFragment
import im.vector.app.features.crypto.verification.request.VerificationRequestFragment
import im.vector.app.features.devtools.RoomDevToolEditFragment
import im.vector.app.features.devtools.RoomDevToolFragment
import im.vector.app.features.devtools.RoomDevToolSendFormFragment
import im.vector.app.features.devtools.RoomDevToolStateEventListFragment
import im.vector.app.features.discovery.DiscoverySettingsFragment
import im.vector.app.features.discovery.change.SetIdentityServerFragment
import im.vector.app.features.grouplist.GroupListFragment
@ -594,4 +598,24 @@ interface FragmentModule {
@IntoMap
@FragmentKey(ShowUserCodeFragment::class)
fun bindShowUserCodeFragment(fragment: ShowUserCodeFragment): Fragment
@Binds
@IntoMap
@FragmentKey(RoomDevToolFragment::class)
fun bindRoomDevToolFragment(fragment: RoomDevToolFragment): Fragment
@Binds
@IntoMap
@FragmentKey(RoomDevToolStateEventListFragment::class)
fun bindRoomDevToolStateEventListFragment(fragment: RoomDevToolStateEventListFragment): Fragment
@Binds
@IntoMap
@FragmentKey(RoomDevToolEditFragment::class)
fun bindRoomDevToolEditFragment(fragment: RoomDevToolEditFragment): Fragment
@Binds
@IntoMap
@FragmentKey(RoomDevToolSendFormFragment::class)
fun bindRoomDevToolSendFormFragment(fragment: RoomDevToolSendFormFragment): Fragment
}

View file

@ -36,6 +36,7 @@ import im.vector.app.features.crypto.quads.SharedSecureStorageActivity
import im.vector.app.features.crypto.recover.BootstrapBottomSheet
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.HomeActivity
import im.vector.app.features.home.HomeModule
import im.vector.app.features.home.room.detail.RoomDetailActivity
@ -149,6 +150,7 @@ interface ScreenComponent {
fun inject(activity: UserCodeActivity)
fun inject(activity: CallTransferActivity)
fun inject(activity: ReAuthActivity)
fun inject(activity: RoomDevToolActivity)
/* ==========================================================================================
* BottomSheets

View file

@ -48,7 +48,7 @@ abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
}
@EpoxyAttribute
var title: String? = null
var title: CharSequence? = null
@EpoxyAttribute
var description: CharSequence? = null

View file

@ -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)
}

View file

@ -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()
}

View file

@ -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()
}

View file

@ -0,0 +1,256 @@
/*
* 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.exhaustive
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
private 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()
Unit
}
is DevToolsViewEvents.ShowSnackMessage -> showSnackbar(it.message)
}.exhaustive
}
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(
jsonString = it.selectedEventJson ?: "",
initialOpenDepth = -1,
wrap = true,
styleProvider = 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(context: Context, roomId: String): 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 -> {
getString(R.string.dev_tools_state_event)
}
RoomDevToolViewState.Mode.StateEventDetail -> {
state.selectedEvent?.type
}
RoomDevToolViewState.Mode.EditEventContent -> {
getString(R.string.dev_tools_edit_content)
}
RoomDevToolViewState.Mode.StateEventListByType -> {
state.currentStateType ?: ""
}
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
)
}
}
supportActionBar?.let {
it.title = title
} ?: run {
setTitle(title)
}
invalidateOptionsMenu()
}
}

View file

@ -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 com.jakewharton.rxbinding3.widget.textChanges
import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentDevtoolsEditorBinding
import javax.inject.Inject
class RoomDevToolEditFragment @Inject constructor()
: VectorBaseFragment<FragmentDevtoolsEditorBinding>() {
private 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 onResume() {
super.onResume()
views.editText.requestFocus()
}
override fun onStop() {
super.onStop()
views.editText.hideKeyboard()
}
}

View file

@ -0,0 +1,66 @@
/*
* 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 im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentGenericRecyclerBinding
import javax.inject.Inject
class RoomDevToolFragment @Inject constructor(
private val epoxyController: RoomDevToolRootController
) : VectorBaseFragment<FragmentGenericRecyclerBinding>(),
DevToolsInteractionListener {
private 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 processAction(action: RoomDevToolAction) {
sharedViewModel.handle(action)
}
}

View file

@ -0,0 +1,59 @@
/*
* 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.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
) : EpoxyController() {
init {
requestModelBuild()
}
var interactionListener: DevToolsInteractionListener? = null
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))
})
}
}
}

View file

@ -0,0 +1,75 @@
/*
* 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.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(
private val stringProvider: StringProvider
) : TypedEpoxyController<RoomDevToolViewState>() {
var interactionListener: DevToolsInteractionListener? = null
override fun buildModels(data: RoomDevToolViewState?) {
val sendEventForm = (data?.displayMode as? RoomDevToolViewState.Mode.SendEventForm) ?: return
genericFooterItem {
id("topSpace")
text("")
}
formEditTextItem {
id("event_type")
enabled(true)
value(data.sendEventDraft?.type)
hint(stringProvider.getString(R.string.dev_tools_form_hint_type))
showBottomSeparator(false)
onTextChange { text ->
interactionListener?.processAction(RoomDevToolAction.CustomEventTypeChange(text))
}
}
if (sendEventForm.isState) {
formEditTextItem {
id("state_key")
enabled(true)
value(data.sendEventDraft?.stateKey)
hint(stringProvider.getString(R.string.dev_tools_form_hint_state_key))
showBottomSeparator(false)
onTextChange { text ->
interactionListener?.processAction(RoomDevToolAction.CustomEventStateKeyChange(text))
}
}
}
formMultiLineEditTextItem {
id("event_content")
enabled(true)
value(data.sendEventDraft?.content)
hint(stringProvider.getString(R.string.dev_tools_form_hint_event_content))
showBottomSeparator(false)
onTextChange { text ->
interactionListener?.processAction(RoomDevToolAction.CustomEventContentChange(text))
}
}
}
}

View file

@ -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.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.databinding.FragmentGenericRecyclerBinding
import javax.inject.Inject
class RoomDevToolSendFormFragment @Inject constructor(
private val epoxyController: RoomDevToolSendFormController
) : VectorBaseFragment<FragmentGenericRecyclerBinding>(), DevToolsInteractionListener {
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)
}
}

View file

@ -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.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.databinding.FragmentGenericRecyclerBinding
import javax.inject.Inject
class RoomDevToolStateEventListFragment @Inject constructor(
private val epoxyController: RoomStateListController
) : VectorBaseFragment<FragmentGenericRecyclerBinding>(), DevToolsInteractionListener {
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)
}
}

View file

@ -0,0 +1,304 @@
/*
* 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.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
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 stringProvider: StringProvider,
private val session: Session
) : VectorViewModel<RoomDevToolViewState, RoomDevToolAction, DevToolsViewEvents>(initialState) {
@AssistedFactory
interface Factory {
fun create(initialState: RoomDevToolViewState): RoomDevToolViewModel
}
companion object : MvRxViewModelFactory<RoomDevToolViewModel, RoomDevToolViewState> {
@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(EventType.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 { state ->
when (state.displayMode) {
RoomDevToolViewState.Mode.EditEventContent -> editEventContent(state)
is RoomDevToolViewState.Mode.SendEventForm -> sendEventContent(state, state.displayMode.isState)
else -> Unit
}
}
private fun editEventContent(state: RoomDevToolViewState) {
setState { copy(modalLoading = Loading()) }
viewModelScope.launch {
try {
val room = session.getRoom(initialState.roomId)
?: throw IllegalArgumentException(stringProvider.getString(R.string.room_error_not_found))
val adapter = MoshiProvider.providesMoshi()
.adapter<JsonDict>(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)) }
}
}
}
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 adapter = MoshiProvider.providesMoshi()
.adapter<JsonDict>(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))
val eventType = state.sendEventDraft?.type
?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_message_type))
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<MessageContent>(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 -> {
_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
)
}
}
}
}
}

View file

@ -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<List<Event>> = Uninitialized,
val currentStateType: String? = null,
val selectedEvent: Event? = null,
val selectedEventJson: String? = null,
val editedContent: String? = null,
val modalLoading: Async<Unit> = 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?
)
}

View file

@ -0,0 +1,109 @@
/*
* 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<RoomDevToolViewState>() {
var interactionListener: DevToolsInteractionListener? = null
override fun buildModels(data: RoomDevToolViewState?) {
when (data?.displayMode) {
RoomDevToolViewState.Mode.StateEventList -> {
val stateEventsGroups = data.stateEvents.invoke().orEmpty().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(stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size))
itemClickAction(GenericItem.Action("view").apply {
perform = Runnable {
interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key))
}
})
}
}
}
}
RoomDevToolViewState.Mode.StateEventListByType -> {
val stateEvents = data.stateEvents.invoke().orEmpty().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 contentJson = JSONObject(stateEvent.content.orEmpty()).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(contentJson)
itemClickAction(GenericItem.Action("view").apply {
perform = Runnable {
interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent))
}
})
}
}
}
}
else -> {
// nop
}
}
}
}

View file

@ -0,0 +1,101 @@
/*
* 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.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<FormMultiLineEditTextItem.Holder>() {
@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<TextInputLayout>(R.id.formMultiLineTextInputLayout)
val textInputEditText by bind<TextInputEditText>(R.id.formMultiLineEditText)
val bottomSeparator by bind<View>(R.id.formTextInputDivider)
}
}

View file

@ -798,6 +798,10 @@ class RoomDetailFragment @Inject constructor(
handleSearchAction()
true
}
R.id.dev_tools -> {
navigator.openDevTools(requireContext(), roomDetailArgs.roomId)
true
}
else -> super.onOptionsItemSelected(item)
}
}

View file

@ -624,10 +624,11 @@ class RoomDetailViewModel @AssistedInject constructor(
R.id.clear_all -> state.asyncRoomSummary()?.hasFailedSending == true
R.id.open_matrix_apps -> true
R.id.voice_call,
R.id.video_call -> callManager.getCallsByRoomId(state.roomId).isEmpty()
R.id.hangup_call -> callManager.getCallsByRoomId(state.roomId).isNotEmpty()
R.id.search -> true
else -> false
R.id.video_call -> callManager.getCallsByRoomId(state.roomId).isEmpty()
R.id.hangup_call -> callManager.getCallsByRoomId(state.roomId).isNotEmpty()
R.id.search -> true
R.id.dev_tools -> vectorPreferences.developerMode()
else -> false
}
}

View file

@ -45,6 +45,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
@ -357,6 +358,10 @@ class DefaultNavigator @Inject constructor(
context.startActivity(intent)
}
override fun openDevTools(context: Context, roomId: String) {
context.startActivity(RoomDevToolActivity.intent(context, roomId))
}
override fun openCallTransfer(context: Context, callId: String) {
val intent = CallTransferActivity.newIntent(context, callId)
context.startActivity(intent)

View file

@ -118,5 +118,7 @@ interface Navigator {
fun openSearch(context: Context, roomId: String)
fun openDevTools(context: Context, roomId: String)
fun openCallTransfer(context: Context, callId: String)
}

View file

@ -63,7 +63,7 @@ class RoomMemberListController @Inject constructor(
?.filter { event ->
event.content.toModel<RoomThirdPartyInviteContent>()
?.takeIf {
data.filter.isEmpty() || it.displayName.contains(data.filter, ignoreCase = true)
data.filter.isEmpty() || it.displayName?.contains(data.filter, ignoreCase = true) == true
} != null
}
.orEmpty()

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="monospace"
android:gravity="top|start"
android:inputType="textMultiLine"
android:scrollHorizontally="true"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?riotx_background"
android:minHeight="@dimen/item_form_min_height">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/formMultiLineTextInputLayout"
style="@style/VectorTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/layout_horizontal_margin"
android:layout_marginEnd="@dimen/layout_horizontal_margin"
app:errorEnabled="true"
app:layout_constraintBottom_toTopOf="@+id/formTextInputDivider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<!-- android:imeOptions="actionDone" to fix a crash -->
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/formMultiLineEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="top|start"
android:imeOptions="actionDone"
android:inputType="textMultiLine"
android:minLines="4"
tools:hint="@string/create_room_name_hint" />
</com.google.android.material.textfield.TextInputLayout>
<View
android:id="@+id/formTextInputDivider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="?riotx_header_panel_border_mobile"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -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">
<ImageView

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menuItemEdit"
android:visible="false"
tools:visible="true"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_edit"
android:title="@string/edit" />
<item
android:id="@+id/menuItemSend"
android:visible="false"
tools:visible="true"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_send"
android:title="@string/send" />
</menu>

View file

@ -68,4 +68,12 @@
app:showAsAction="never"
tools:visible="true" />
<item
android:id="@+id/dev_tools"
android:icon="@drawable/ic_settings_root_general"
android:title="@string/dev_tools_menu_name"
android:visible="false"
app:showAsAction="never"
tools:visible="true" />
</menu>

View file

@ -1,22 +1,18 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="light_theme">Svijetla Tema</string>
<string name="dark_theme">Tamna Tema</string>
<string name="black_them">Crna Tema</string>
<string name="notification_sync_in_progress">Sinkronizacija</string>
<string name="notification_listening_for_events">Budući Događaji</string>
<string name="notification_noisy_notifications">Glasne notifikacije</string>
<string name="notification_silent_notifications">Nečujne notifikiacije</string>
<string name="title_activity_home">Poruke</string>
<string name="title_activity_room">Soba</string>
<string name="title_activity_settings">Postavke</string>
<string name="title_activity_member_details">Detalji o Članu</string>
<string name="title_activity_historical">Istorijski</string>
<string name="title_activity_bug_report">Izvještaj o Greški</string>
<string name="ok">OK</string>
<string name="cancel">Otkaži</string>
<string name="save">Snimi</string>
@ -48,7 +44,6 @@
<string name="or">ili</string>
<string name="invite">Pozovi</string>
<string name="offline">Offline</string>
<string name="action_sign_out">Odjavi se</string>
<string name="action_voice_call">Glasovni Poziv</string>
<string name="action_video_call">Video Poziv</string>
@ -60,23 +55,18 @@
<string name="action_close">Zatvori</string>
<string name="copied_to_clipboard">Kopirano</string>
<string name="disable">Isključi</string>
<string name="dialog_title_confirmation">Potvrda</string>
<string name="dialog_title_warning">Upozorenje</string>
<string name="bottom_action_home">Naslovna</string>
<string name="bottom_action_favourites">Omiljeni</string>
<string name="bottom_action_people">Ljudi</string>
<string name="bottom_action_rooms">Sobe</string>
<string name="home_filter_placeholder_home">Traži sobe</string>
<string name="home_filter_placeholder_favorites">Traži favorite</string>
<string name="home_filter_placeholder_people">Traži ljude</string>
<string name="home_filter_placeholder_rooms">Traži sobe</string>
<string name="invitations_header">Pozivi</string>
<string name="low_priority_header">Niski prioritet</string>
<string name="direct_chats_header">Razgovori</string>
<string name="local_address_book_header">Lokalni adresar</string>
<string name="user_directory_header">Imenik korisnika</string>
@ -84,12 +74,10 @@
<string name="no_conversation_placeholder">Nema razgovora</string>
<string name="no_contact_access_placeholder">Niste omogućili Elementu pristup vašim lokalnim kontaktima</string>
<string name="no_result_placeholder">Nema rezultata</string>
<string name="rooms_header">Sobe</string>
<string name="rooms_directory_header">Imenik soba</string>
<string name="no_room_placeholder">Nema soba</string>
<string name="no_public_room_placeholder">Nema dostupnih javnih soba</string>
<string name="send_bug_report_include_logs">Pošaljite zapise</string>
<string name="send_bug_report_include_crash_logs">Pošaljite keš zapise</string>
<string name="send_bug_report_include_screenshot">Pošalji sliku ekrana</string>
@ -99,14 +87,11 @@
<string name="send_bug_report_logs_description">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:</string>
<string name="send_bug_report_alert_message">Čini se da frustrirani. Želite li poslati izvještaj o pogrešci?</string>
<string name="send_bug_report_app_crashed">Aplikacija se srušila posljednji put. Želite li poslati izvještaj o rušenju?</string>
<string name="send_bug_report_sent">Izvješće o greški je uspješno poslano</string>
<string name="send_bug_report_failed">Izvještaj o greški nije uspješno poslan (%s)</string>
<string name="send_bug_report_progress">Napredak (%s%%)</string>
<string name="send_files_in">Poslane informacije</string>
<string name="read_receipt">Čitaj</string>
<string name="join_room">Pridruži se u sobu</string>
<string name="username">Korisničko ime</string>
<string name="create_account">Registruj se</string>
@ -115,16 +100,13 @@
<string name="hs_url">URL lokalnog servera</string>
<string name="identity_url">URL identitet servera</string>
<string name="search">Traži</string>
<string name="start_new_chat">Započni Novi Razgovor</string>
<string name="start_voice_call">Započni Glasnovni Poziv</string>
<string name="start_video_call">Započni Video Poziv</string>
<string name="option_send_files">Pošalji fajlove</string>
<string name="option_take_photo_video">Napravi fotografiju ili videozapis</string>
<string name="option_take_photo">Napravi fotografiju</string>
<string name="option_take_video">Napravi video</string>
<string name="auth_login">Prijavi se</string>
<string name="auth_register">Registruj se</string>
<string name="auth_submit">Pošalji</string>
@ -172,7 +154,6 @@ Možete dodati vašu email adresu na svoj profil u postavkama.</string>
<string name="auth_reset_password_success_message">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.</string>
<string name="login_error_must_start_http">URL mora početi sa http[s]://</string>
<string name="login_error_network_error">Nemoguća prijava: Greška na mreži</string>
<string name="login_error_unable_login">Nemoguća prijava</string>
@ -180,7 +161,6 @@ Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste pon
<string name="login_error_unable_register">Nemoguća registracija</string>
<string name="login_error_unable_register_mail_ownership">Nemoguća registracija : problem sa vlasništvom email adrese</string>
<string name="login_error_invalid_home_server">Unesite ispravan URL</string>
<string name="login_error_forbidden">Netačno korisničko ime/lozinka</string>
<string name="login_error_unknown_token">Navedeni pristupni token nije prepoznat</string>
<string name="login_error_bad_json">Neispravno formatiran JSON</string>
@ -188,23 +168,18 @@ Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste pon
<string name="login_error_limit_exceeded">Previše zahtjeva je poslano</string>
<string name="login_error_user_in_use">Ovo korisničko ime se već koristi</string>
<string name="login_error_login_email_not_yet">Link email adrese koji još uvijek nije kliknut</string>
<string name="read_receipts_list">Čitajte Listu Primalaca</string>
<string name="compression_options">"Pošalji kao "</string>
<string name="compression_opt_list_original">Orginal</string>
<string name="compression_opt_list_large">Veliko</string>
<string name="compression_opt_list_medium">Srednje</string>
<string name="compression_opt_list_small">Malo</string>
<string name="attachment_cancel_download">Otkazi preuzimanje?</string>
<string name="attachment_cancel_upload">Otkaži prijenos?</string>
<string name="yesterday">Jučer</string>
<string name="today">Danas</string>
<string name="room_info_room_name">Ime sobe</string>
<string name="room_info_room_topic">Tema sobe</string>
<string name="call">Poziv</string>
<string name="call_connected">Poziv uspostavljen</string>
<string name="call_connecting">Poziv se uspostavlja…</string>
@ -214,15 +189,12 @@ Odjavljeni ste sa svih uređaja i više nećete primati obavijesti. Da biste pon
<string name="incoming_video_call">Dolazni Video Poziv</string>
<string name="incoming_voice_call">Dolazni Glasovni Poziv</string>
<string name="call_in_progress">Poziv u Toku</string>
<string name="call_error_user_not_responding">Daljinska strana nije uspjela pokupiti.</string>
<string name="call_error_ice_failed">Medijska veza nije uspjela</string>
<string name="call_error_camera_init_failed">Kamera se ne moze inicijalizirati</string>
<string name="call_error_answered_elsewhere">poziv je odgovoren na drugom mjestu</string>
<string name="media_picker_both_capture_title">Snimi fotografiju ili video</string>
<string name="media_picker_cannot_record_video">Nije moguće snimiti video</string>
<string name="permissions_rationale_popup_title">Informacije</string>
<string name="permissions_rationale_msg_storage">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
<string name="permissions_msg_contacts_warning_other_androids">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?</string>
<string name="permissions_action_not_performed_missing_permissions">Nažalost, akcija nije izvršena zbog nedostatka dozvola</string>
<string name="media_slider_saved">Snimljeno</string>
<string name="media_slider_saved_message">Snimi u preuzimanja</string>
<string name="yes">DA</string>
<string name="no">NE</string>
<string name="_continue">Nastavi</string>
<string name="remove">Ukloni</string>
<string name="join">Spoji</string>
<string name="preview">Pregled</string>
<string name="reject">Odbij</string>
<string name="room_jump_to_first_unread">Idi na prvu nepročitanu poruku.</string>
<string name="room_preview_invitation_format">Pozvani ste da %s se pridružite u ovu sobu</string>
<string name="room_preview_unlinked_email_warning">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.</string>
<string name="room_preview_try_join_an_unknown_room">Pokušavate pristupiti usluzi %s. Želite li se pridružiti kako biste sudjelovali u razgovoru?</string>
<string name="room_preview_try_join_an_unknown_room_default">soba</string>
<string name="room_preview_room_interactions_disabled">Ovo je pregled ove sobe. Razgovori u sobi su onemoguceni.</string>
<string name="room_creation_title">Novi Razgovor</string>
<string name="room_creation_add_member">Dodaj člana</string>
<string name="room_title_one_member">1 član</string>
<string name="room_participants_leave_prompt_title">Napusti sobu</string>
<string name="room_participants_leave_prompt_msg">Da li ste sigurni da želite napustiti sobu?</string>
<string name="room_participants_remove_prompt_msg">Da li ste sigurni da želite ukloniti % iz ovog razgovora?</string>
<string name="room_participants_remove_prompt_msg">Da li ste sigurni da želite ukloniti %s iz ovog razgovora\?</string>
<string name="room_participants_create">Kreiraj</string>
<string name="room_participants_online">Online</string>
<string name="room_participants_offline">Offline</string>
<string name="room_participants_idle">Idle</string>
<string name="room_participants_header_admin_tools">ADMINISTRATORSKI ALATI</string>
<string name="room_participants_header_call">POZIV</string>
<string name="room_participants_header_direct_chats">DIREKTNI RAZGOVORI</string>
<string name="room_participants_header_devices">UREĐAJI</string>
<string name="room_participants_action_invite">Pozovi</string>
<string name="room_participants_action_leave">Napusti ovu sobu</string>
<string name="room_participants_action_remove">Ukloni iz ove sobe</string>
@ -300,18 +262,14 @@ Možda se želite prijaviti s nekim drugim računom ili dodati ovu poruku email
<string name="room_participants_action_devices_list">Prikaži listu uređaja</string>
<string name="room_participants_power_level_prompt">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?</string>
<string name="room_participants_invite_prompt_msg">Da li ste sigurni da želite pozvati% u ovaj razgovor?</string>
<string name="room_participants_invite_prompt_msg">Da li ste sigurni da želite pozvati %s u ovaj razgovor\?</string>
<string name="people_search_invite_by_id"><u>Pozovi preko ID-a</u></string>
<string name="people_search_local_contacts">LOKALNI KONTAKTI (%d)</string>
<string name="people_search_user_directory">KORISNIČKI IMENIK (%s)</string>
<string name="people_search_filter_text">Samo Matrix korisnici</string>
<string name="people_search_invite_by_id_dialog_title">Pozovi korisnika preko ID-a</string>
<string name="people_search_invite_by_id_dialog_description">Unesite jednu ili više email adresa ili Matrix ID</string>
<string name="people_search_invite_by_id_dialog_hint">Email il Matrix ID</string>
<string name="room_menu_search">Pretraga</string>
<string name="room_one_user_is_typing">%s tipka…</string>
<string name="room_two_users_are_typing">%1$s &amp; %2$s tipkaju…</string>
@ -327,7 +285,6 @@ Da li ste sigurani?</string>
<string name="room_delete_unsent_messages">Izbriši neposlane poruke</string>
<string name="room_message_file_not_found">Datoteka nije pronađena</string>
<string name="room_do_not_have_permission_to_post">Nemate dopuštenje da komunicirate u ovoj sobi</string>
<string name="ssl_trust">Povjerenje</string>
<string name="ssl_do_not_trust">Ne vjerujte</string>
<string name="ssl_logout_account">Odjava</string>
@ -339,7 +296,6 @@ Da li ste sigurani?</string>
<string name="ssl_unexpected_existing_expl">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.</string>
<string name="ssl_expected_existing_expl">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.</string>
<string name="ssl_only_accept">SAMO prihvatiti certifikat ako je administrator servera objavio otisak prsta koji odgovara gore navedenom.</string>
<string name="room_details_title">Detalji Sobe</string>
<string name="room_details_people">Ljudi</string>
<string name="room_details_files">Fajlovi</string>
@ -347,12 +303,10 @@ Da li ste sigurani?</string>
<string name="malformed_id">Malformirani ID. Trebao bi biti email adresa ili Matrix ID poput \"@localpart: domain\"</string>
<string name="room_details_people_invited_group_name">POZVAN</string>
<string name="room_details_people_present_group_name">PRIKLJUČEN</string>
<string name="room_event_action_report_prompt_reason">Razlog za prijavljivanje ovog sadržaja</string>
<string name="room_event_action_report_prompt_ignore_user">Želite li sakriti sve poruke tog korisnika?</string>
<string name="room_event_action_cancel_upload">Otkaži Prijenos</string>
<string name="room_event_action_cancel_download">Otkaži Preuzimanje</string>
<string name="search_hint">Pretraga</string>
<string name="search_members_hint">Filtriraj članove sobe</string>
<string name="search_no_results">Nema rezultata</string>
@ -360,7 +314,6 @@ Da li ste sigurani?</string>
<string name="tab_title_search_messages">PORUKE</string>
<string name="tab_title_search_people">LJUDI</string>
<string name="tab_title_search_files">FAJLOVI</string>
<string name="room_recents_join">PRIDRUŽI SE</string>
<string name="room_recents_directory">DIREKTORIJ</string>
<string name="room_recents_favourites">FAVORITI</string>
@ -372,16 +325,13 @@ Da li ste sigurani?</string>
<string name="room_recents_join_room">Pridruži se sobi</string>
<string name="room_recents_join_room_title">Pridriži se u sobu</string>
<string name="room_recents_join_room_prompt">Upišite ID sobe ili alias sobe</string>
<string name="directory_search_results_title">Pretražite imenik</string>
<string name="directory_searching_title">Traži direktorij..</string>
<string name="room_settings_favourite">Favorit</string>
<string name="room_settings_de_prioritize">De-prioritiziraj</string>
<string name="room_settings_direct_chat">Direktni Razgovor</string>
<string name="room_settings_leave_conversation">Napusti Razgovor</string>
<string name="room_settings_forget">Zaboravi</string>
<string name="room_sliding_menu_messages">Poruke</string>
<string name="room_sliding_menu_settings">Postavke</string>
<string name="room_sliding_menu_version">"Verzija "</string>
@ -389,7 +339,6 @@ Da li ste sigurani?</string>
<string name="room_sliding_menu_third_party_notices">Obavijesti treće strane</string>
<string name="room_sliding_menu_copyright">Copyright</string>
<string name="room_sliding_menu_privacy_policy">Privatnost</string>
<string name="settings_profile_picture">Profilna Slika</string>
<string name="settings_display_name">Ime</string>
<string name="settings_email_address">Email</string>
@ -398,12 +347,10 @@ Da li ste sigurani?</string>
<string name="settings_add_phone_number">Dodaj broj telefona</string>
<string name="settings_app_info_link_summary">Infomacije o aplikacijskom sustavu</string>
<string name="settings_app_info_link_title">Informacije o aplikaciji</string>
<string name="settings_notification_ringtone">Zvuk notifikacije</string>
<string name="settings_enable_all_notif">Omogući obavijesti za ovaj račun</string>
<string name="settings_enable_this_device">Omogući obavijesti za ovaj uređaj</string>
<string name="settings_turn_screen_on">Uključite zaslon na 3 sekunde</string>
<string name="settings_containing_my_display_name">Poruke sadrže moje ime</string>
<string name="settings_containing_my_user_name">Poruke sadrže moje koristničko ime</string>
<string name="settings_messages_in_one_to_one">Poruke u jedan-na-jedan razgovorima</string>
@ -411,13 +358,11 @@ Da li ste sigurani?</string>
<string name="settings_invited_to_room">Kada sam pozvan u sobu</string>
<string name="settings_call_invitations">Pozivnice za poziv</string>
<string name="settings_messages_sent_by_bot">Poruke koje šalje bot</string>
<string name="settings_start_on_boot">Započni na boot</string>
<string name="settings_background_sync">Pozadinska sinkronizacija</string>
<string name="settings_enable_background_sync">Omogući pozadinsku sinkronizaciju</string>
<string name="settings_set_sync_timeout">Sinkronizacijski zahtjev istekao</string>
<string name="settings_set_sync_delay">Napravi pauzu između dva sinkronizacijska zahtjeva</string>
<string name="settings_version">Verzija</string>
<string name="settings_olm_version">olm verzija</string>
<string name="settings_app_term_conditions">Uvjeti korištenja</string>
@ -427,7 +372,6 @@ Da li ste sigurani?</string>
<string name="settings_clear_cache">Očisti keš</string>
<string name="settings_clear_media_cache">Očisti medija keš</string>
<string name="settings_keep_media">Dodaj medij</string>
<string name="settings_user_settings">Korisničke postavke</string>
<string name="settings_notifications">Notifikacije</string>
<string name="settings_ignored_users">Ignorisani korisnici</string>
@ -444,13 +388,10 @@ Da li ste sigurani?</string>
<string name="settings_devices_list">Uređaj</string>
<string name="settings_always_show_timestamps">Uvijek prikažite vremenske oznake poruka</string>
<string name="settings_12_24_timestamps">Prikaži vremenske oznake u 12-satnom obliku (npr. 14:30)</string>
<string name="settings_analytics">Analiza</string>
<string name="attachment_remaining_time_seconds">%d s</string>
<string name="attachment_remaining_time_minutes">%1$a %2$i</string>
<string name="settings_data_save_mode">Način spremanja podataka</string>
<string name="devices_details_dialog_title">Pojedinosti uređaja</string>
<string name="devices_details_id_title">ID</string>
<string name="devices_details_name_title">Ime</string>
@ -462,22 +403,18 @@ Da biste nastavili, unesite lozinku.</string>
<string name="devices_delete_dialog_title">Ovjera</string>
<string name="devices_delete_pswd">Lozinka:</string>
<string name="devices_delete_submit_button_label">Pošalji</string>
<string name="settings_logged_in">Prijavljen kao</string>
<string name="settings_home_server">Lokalni Server</string>
<string name="settings_identity_server">Identifikacioni Server</string>
<string name="settings_user_interface">Korisnički interfejs</string>
<string name="settings_interface_language">Jezik interfejsa</string>
<string name="settings_select_language">Izaberi jezik</string>
<string name="account_email_validation_title">Čekanje na verifikaciju</string>
<string name="account_email_validation_message">Proverite svoj email i kliknite na link u email-u. Nakon što to učinite, kliknite na dugme nastavi.</string>
<string name="account_email_validation_error">Nije moguće proveriti email adresu. Proverite svoj email i kliknite na link u emailu. Nakon što to uradite, kliknite na dugme nastavi</string>
<string name="account_email_already_used_error">Ova email adresa je već u upotrebi</string>
<string name="account_email_not_found_error">Neuspješno slanje emaila: Ova adresa email adresa nije pronađena</string>
<string name="account_phone_number_already_used_error">Ovaj telefonski broj je već u upotrebi</string>
<string name="settings_change_password">Promenite lozinku</string>
<string name="settings_old_password">stara lozinka</string>
<string name="settings_new_password">nova lozinka</string>
@ -485,15 +422,11 @@ Da biste nastavili, unesite lozinku.</string>
<string name="settings_fail_to_update_password">Neuspešno ažuriranje lozinke</string>
<string name="settings_password_updated">Vaša lozinka je ažurirana</string>
<string name="settings_unignore_user">Prikaži sve poruke iz %s?</string>
<string name="settings_delete_notification_targets_confirmation">Da li ste sigurni da želite ukloniti ovaj cilj obaveštenja?</string>
<string name="settings_delete_threepid_confirmation">Da li ste sigurni da želite ukloniti %1$s %2$s?</string>
<string name="settings_select_country">Izaberite zemlju</string>
<string name="settings_phone_number_country_label">Zemlja</string>
<string name="settings_phone_number_country_error">Izaberite zemlju</string>
<string name="settings_phone_number_label">Broj telefona</string>
<string name="settings_phone_number_error">Nevažeći broj telefona za izabranu zemlju</string>
</resources>
</resources>

View file

@ -2387,4 +2387,32 @@
<string name="settings_export_trail">Exporta informe</string>
<string name="verify_cannot_cross_sign">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ó.</string>
<string name="call_transfer_users_tab_title">Usuaris</string>
<string name="call_transfer_failure">S\'ha produït un error al transferir la trucada</string>
<string name="call_transfer_title">Transferència</string>
<string name="call_transfer_connect_action">Connecta</string>
<string name="call_transfer_consult_first">Consulta primer</string>
<plurals name="call_one_active_and_other_paused">
<item quantity="one">1 trucada activa (%1$s) · 1 trucada en pausa</item>
<item quantity="other">1 trucada activa (%1$s) · %2$d trucades en pausa</item>
</plurals>
<plurals name="call_only_paused">
<item quantity="one">Trucada en pausa</item>
<item quantity="other">%1$d trucades en pausa</item>
</plurals>
<string name="call_only_active">Trucada activa (%1$s)</string>
<string name="call_dial_pad_lookup_error">S\'ha produït un error al cercar el número de telèfon</string>
<string name="call_dial_pad_title">Teclat</string>
<string name="call_tile_call_back">Torna la trucada</string>
<string name="call_tile_ended">La trucada ha finalitzat</string>
<string name="call_tile_other_declined">%1$s ha rebutjat la trucada</string>
<string name="call_tile_you_declined">Has rebutjat la trucada %1$s</string>
<string name="call_tile_in_call">Ets dins aquesta trucada</string>
<string name="call_tile_other_started_call">%1$s ha iniciat la trucada</string>
<string name="call_tile_you_started_call">Has iniciat la trucada</string>
<string name="call_held_by_you">Has posat la trucada en espera</string>
<string name="call_hold_action">Posa en espera</string>
<string name="call_held_by_user">%s ha posat la trucada en espera</string>
<string name="call_resume_action">Continua</string>
<string name="action_return">Torna</string>
</resources>

View file

@ -2358,4 +2358,34 @@
<string name="re_authentication_activity_title">Je nutné opětovné ověření</string>
<string name="failed_to_initialize_cross_signing">Nastavení křížového podepisování se nezdařilo</string>
<string name="error_unauthorized">Neautorizováno, chybí platné ověřovací údaje</string>
<string name="call_transfer_title">Přepojit</string>
<string name="call_transfer_users_tab_title">Uživatelé</string>
<string name="call_transfer_failure">Při přepojování hovoru došlo k chybě</string>
<string name="call_transfer_connect_action">Připojit</string>
<string name="call_transfer_consult_first">Nejprve se poraďte</string>
<plurals name="call_one_active_and_other_paused">
<item quantity="one">1 probíhající hovor (%1$s) · 1 pozastavený hovor</item>
<item quantity="few">1 probíhající hovor (%1$s) · %2$d pozastavené hovory</item>
<item quantity="other">1 probíhající hovor (%1$s) · %2$d pozastavených hovorů</item>
</plurals>
<plurals name="call_only_paused">
<item quantity="one">Pozastavený hovor</item>
<item quantity="few">%1$d pozastavené hovory</item>
<item quantity="other">%1$d pozastavených hovorů</item>
</plurals>
<string name="call_only_active">Probíhající hovor (%1$s)</string>
<string name="call_dial_pad_lookup_error">Při vyhledávání telefonního čísla došlo k chybě</string>
<string name="call_dial_pad_title">Číselník</string>
<string name="call_tile_call_back">Zavolat zpět</string>
<string name="call_tile_ended">Tento hovor skončil</string>
<string name="call_tile_other_declined">%1$s odmítl tento hovor</string>
<string name="call_tile_you_declined">Odmítli jste tento hovor %1$s</string>
<string name="call_tile_in_call">Aktuálně jste v tomto hovoru</string>
<string name="call_tile_other_started_call">%1$s zahájil hovor</string>
<string name="call_tile_you_started_call">Zahájili jste hovor</string>
<string name="call_held_by_you">Podrželi jste hovor</string>
<string name="call_held_by_user">%s podržel hovor</string>
<string name="call_hold_action">Přidržet</string>
<string name="call_resume_action">Pokračovat</string>
<string name="action_return">Návrat</string>
</resources>

View file

@ -285,7 +285,7 @@
<string name="people_search_invite_by_id"><u>Mit ID einladen</u></string>
<string name="people_search_local_contacts">LOKALE KONTAKTE (%d)</string>
<string name="people_search_filter_text">Nur Matrix-Benutzer</string>
<string name="people_search_invite_by_id_dialog_title">Benutzer per ID einladen</string>
<string name="people_search_invite_by_id_dialog_title">Benutzer:in per ID einladen</string>
<string name="people_search_invite_by_id_dialog_description">Bitte gib eine oder mehrere E-Mail-Adressen oder eine Matrix-ID ein</string>
<string name="people_search_invite_by_id_dialog_hint">E-Mail or Matrix-ID</string>
<!-- Chat -->
@ -797,15 +797,15 @@
<string name="settings_without_flair">Du bist aktuell kein Mitglied einer Community.</string>
<string name="settings_labs_keyboard_options_to_send_message">Benutze die Enter-Taste der Tastatur zum Senden</string>
<string name="command_description_emote">Zeigt Aktionen</string>
<string name="command_description_ban_user">Bannt Benutzer mit angegebener ID</string>
<string name="command_description_ban_user">Bannt Benutzer:in mit angegebener ID</string>
<string name="command_description_unban_user">Hebt die Verbannung des Benutzers mit angegebener ID auf</string>
<string name="command_description_op_user">Bestimmt das Berechtigungslevel des Benutzers</string>
<string name="command_description_deop_user">Setzt Berechtigungen des Benutzers zurück</string>
<string name="command_description_invite_user">Lädt Benutzer mit angegebener Kennung in den aktuellen Raum ein</string>
<string name="command_description_invite_user">Lädt Benutzer:in mit angegebener Kennung in den aktuellen Raum ein</string>
<string name="command_description_join_room">Tritt dem Raum mit angegebenen Alias bei</string>
<string name="command_description_part_room">Verlasse Raum</string>
<string name="command_description_topic">Setzt das Raum-Thema</string>
<string name="command_description_kick_user">Kickt Benutzer mit angegebener ID</string>
<string name="command_description_kick_user">Kickt Benutzer:in mit angegebener ID</string>
<string name="command_description_nick">Ändert deinen Anzeigenamen</string>
<string name="command_description_markdown">(De-)Aktiviert Markdown</string>
<string name="command_description_clear_scalar_token">Um das Matrix-App-Management zu reparieren</string>
@ -882,7 +882,7 @@
<string name="reason_hint">Grund</string>
<string name="settings_inline_url_preview_summary">Linkvorschau im Chat aktivieren, falls dein Home-Server diese Funktion unterstützt.</string>
<string name="settings_send_typing_notifs">Sende Schreibbenachrichtigungen</string>
<string name="settings_send_typing_notifs_summary">Lasse andere Benutzer wissen, dass du tippst.</string>
<string name="settings_send_typing_notifs_summary">Lasse andere Benutzer:innen wissen, dass du tippst.</string>
<string name="settings_send_markdown">Markdown-Formatierung</string>
<string name="settings_send_markdown_summary">Formatiere Nachrichten mittels Markdown-Syntax, bevor sie gesendet werden. Dies erlaubt erweiterte Formatierungen, etwa Sternchen (*) um kursiven Text anzuzeigen.</string>
<string name="settings_show_read_receipts">Zeige Lesebestätigungen</string>
@ -960,7 +960,7 @@
<string name="settings_troubleshoot_test_play_services_title">Prüfung der Play-Dienste</string>
<string name="settings_troubleshoot_test_play_services_success">Google Play-Dienste-APK ist verfügbar und aktuell.</string>
<string name="settings_troubleshoot_test_token_registration_title">Token-Registrierung</string>
<string name="settings_troubleshoot_test_battery_failed">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.</string>
<string name="settings_troubleshoot_test_battery_failed">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.</string>
<string name="settings_troubleshoot_test_battery_quickfix">Ignoriere Optimierungen</string>
<string name="startup_notification_fdroid_battery_optim_title">Hintergrundverbindung</string>
<string name="startup_notification_fdroid_battery_optim_message">Element muss eine Hintergrundverbindung (nur geringe Belastung) aufrechterhalten, um verlässliche Benachrichtigungen zu erhalten.
@ -1014,7 +1014,7 @@
<string name="keys_backup_settings_delete_confirm_title">Lösche Sicherung</string>
<string name="settings_notification_by_event">Präferenz der Benachrichtigungen nach Ereignis</string>
<string name="settings_troubleshoot_test_fcm_failed_too_many_registration">[%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.</string>
\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.</string>
<string name="settings_troubleshoot_test_fcm_failed_service_not_available">[%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.</string>
<string name="settings_troubleshoot_test_fcm_failed_account_missing">[%1$s]
@ -1182,7 +1182,7 @@
<string name="sas_waiting_for_partner">Warte auf Bestätigung des/r anderen Nutzer*in…</string>
<string name="sas_verified">Verifiziert!</string>
<string name="sas_verified_successful">Du hast diese Sitzung erfolgreich verifiziert.</string>
<string name="sas_verified_successful_description">Sichere Nachrichten mit diesem Benutzer sind Ende-zu-Ende verschlüsselt und können nicht von Dritten mitgelesen werden.</string>
<string name="sas_verified_successful_description">Sichere Nachrichten mit diesem/r Benutzer:in sind Ende-zu-Ende verschlüsselt und können nicht von Dritten mitgelesen werden.</string>
<string name="sas_got_it">Verstanden</string>
<string name="sas_verification_request_notification_channel_title">Schlüssel-Verifizierung</string>
<string name="sas_cancelled_dialog_title">Anfrage abgebrochen</string>
@ -1191,7 +1191,7 @@
<string name="sas_verification_request_notification_channel">Interaktive Sitzungs-Verifizierung</string>
<string name="sas_incoming_request_notif_title">Verifizierungsanfrage</string>
<string name="sas_incoming_request_notif_content">%s möchte deine Sitzung verifizieren</string>
<string name="sas_error_m_user">Der Benutzer hat die Verifizierung abgebrochen</string>
<string name="sas_error_m_user">Der/die Benutzer:in hat die Verifizierung abgebrochen</string>
<string name="sas_error_m_timeout">Der Verifizierungsprozess ist abgelaufen</string>
<string name="sas_error_m_unexpected_message">Die Sitzung hat eine unerwartete Nachricht erhalten</string>
<string name="sas_error_m_invalid_message">Eine ungültige Nachricht wurde empfangen</string>
@ -1214,7 +1214,7 @@
<string name="message_add_reaction">Reaktion hinzufügen</string>
<string name="message_view_reaction">Reaktionen ansehen</string>
<string name="reactions">Reaktionen</string>
<string name="event_redacted_by_user_reason">Ereignis von Benutzer gelöscht</string>
<string name="event_redacted_by_user_reason">Ereignis von Benutzer:in gelöscht</string>
<string name="event_redacted_by_admin_reason">Ereignis moderiert durch Raum-Administrator</string>
<string name="last_edited_info_message">Zuletzt bearbeitet von %1$s am %2$s</string>
<string name="create_new_room">Neuen Raum erstellen</string>
@ -1440,7 +1440,7 @@
<string name="report_content_custom_title">Diesen Inhalt melden</string>
<string name="report_content_custom_hint">Meldegrund</string>
<string name="report_content_custom_submit">MELDEN</string>
<string name="block_user">NUTZER IGNORIEREN</string>
<string name="block_user">NUTZER:IN IGNORIEREN</string>
<string name="content_reported_title">Inhalt gemeldet</string>
<string name="content_reported_content">Dieser Inhalt wurde gemeldet.
\n
@ -1795,8 +1795,8 @@
<string name="verify_new_session_notice">Benutze diese Sitzung um deine neue zu verfizieren, damit sie auf verschlüsselte Nachrichten zugreifen kann.</string>
<string name="verify_new_session_was_not_me">Das war ich nicht</string>
<string name="verify_new_session_compromized">Dein Account ist möglicherweise komprimittiert</string>
<string name="verify_cancel_self_verification_from_untrusted">Wenn du abbrichst, wirst du auf diesem Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer werden ihm nicht vertrauen</string>
<string name="verify_cancel_self_verification_from_trusted">Wenn du abbrichst, wirst du auf deinem neuen Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer werden ihm nicht vertrauen</string>
<string name="verify_cancel_self_verification_from_untrusted">Wenn du abbrichst, wirst du auf diesem Gerät keine verschlüsselten Nachrichten lesen können, und andere Benutzer:innen werden ihm nicht vertrauen</string>
<string name="verify_cancel_self_verification_from_trusted">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</string>
<string name="verify_cancel_other">Du wirst %1$s (%2$s) nicht verifizieren, wenn du jetzt abbrichst. Beginne in deren Nutzerprofil erneut.</string>
<string name="verify_not_me_self_verification">Eines der folgenden könnte kom­pro­mit­tie­rt sein:
\n
@ -1847,7 +1847,7 @@
<string name="auth_flow_not_supported">Dies kann nicht von einem mobilen Gerät erfolgen</string>
<string name="settings_when_rooms_are_upgraded">Wenn Räume verbessert werden</string>
<string name="encryption_enabled">Verschlüsselung aktiviert</string>
<string name="encryption_enabled_tile_description">Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr &amp; verifiziere Benutzer in deren Profil.</string>
<string name="encryption_enabled_tile_description">Nachrichten in diesem Raum sind Ende-zu-Ende verschlüsselt. Erfahre mehr &amp; verifiziere Benutzer:innen in deren Profil.</string>
<string name="encryption_unknown_algorithm_tile_description">Die Verschlüsselung in diesem Raum wird nicht unterstützt</string>
<string name="qr_code_scanned_verif_waiting">Warte auf %s…</string>
<string name="set_recovery_passphrase">%s setzen</string>
@ -1922,15 +1922,15 @@
<string name="notification_ticker_text_group">%1$s: %2$s %3$s</string>
<string name="add_members_to_room">Nutzer!n hinzufügen</string>
<string name="invite_users_to_room_action_invite">EINLADEN</string>
<string name="inviting_users_to_room">Benutzer werden eingeladen…</string>
<string name="invite_users_to_room_title">Benutzer einladen</string>
<string name="inviting_users_to_room">Benutzer:innen werden eingeladen…</string>
<string name="invite_users_to_room_title">Benutzer:innen einladen</string>
<string name="invitation_sent_to_one_user">Einladung gesendet an %1$s</string>
<string name="invitations_sent_to_two_users">Einladungen gesendet an %1$s und %2$s</string>
<plurals name="invitations_sent_to_one_and_more_users">
<item quantity="one">Einladungen gesendet an %1$s und einen weiteren Benutzer</item>
<item quantity="other">Einladungen gesendet an %1$s und %2$d weitere Benutzer</item>
</plurals>
<string name="invite_users_to_room_failure">Wir konnten den Benutzer nicht einladen. Bitte überprüfe den Benutzernamen, welchen du einladen möchtest und versuche es erneut.</string>
<string name="invite_users_to_room_failure">Wir konnten die Benutzer:innen nicht einladen. Bitte überprüfe die Benutzer:innen, welchen du einladen möchtest, und versuche es erneut.</string>
<string name="pause_video">Pause</string>
<string name="action_copy">Kopieren</string>
<string name="bottom_action_notification">Benachrichtigungen</string>
@ -1956,25 +1956,25 @@
<string name="return_to_call">Zum Anruf zurückkehren</string>
<string name="room_participants_action_cancel_invite">Einladung zurückziehen</string>
<string name="room_participants_power_level_demote_warning_title">Möchtest du dich zurückstufen\?</string>
<string name="room_participants_power_level_demote_warning_prompt">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.</string>
<string name="room_participants_power_level_demote_warning_prompt">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.</string>
<string name="room_participants_power_level_demote">Zurückstufen</string>
<string name="room_participants_action_ignore_title">Benutzer ignorieren</string>
<string name="room_participants_action_ignore_title">Benutzer:in ignorieren</string>
<string name="room_participants_action_ignore_prompt_msg">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.</string>
<string name="room_participants_action_unignore_title">Ignorieren des Benutzers rückgängig machen</string>
<string name="room_participants_action_unignore_prompt_msg">Das Aufheben der Ignorierung wird alle Nachrichten des Benutzers wieder einblenden.</string>
<string name="room_participants_action_cancel_invite_title">Einladung zurückziehen</string>
<string name="room_participants_action_cancel_invite_prompt_msg">Bist du dir sicher, dass du die Einladung für diesen Benutzer zurückziehen möchtest\?</string>
<string name="room_participants_kick_title">Benutzer entfernen</string>
<string name="room_participants_action_cancel_invite_prompt_msg">Bist du dir sicher, dass du die Einladung für diese:n Benutzer:in zurückziehen möchtest\?</string>
<string name="room_participants_kick_title">Benutzer:in entfernen</string>
<string name="room_participants_kick_reason">Grund für das Entfernen</string>
<string name="room_participants_kick_prompt_msg">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.</string>
<string name="room_participants_ban_title">Benutzer bannen</string>
<string name="room_participants_ban_title">Benutzer:in bannen</string>
<string name="room_participants_ban_reason">Grund für den Bann</string>
<string name="room_participants_unban_title">Bann des Benutzers aufheben</string>
<string name="room_participants_unban_prompt_msg">Das Aufheben des Bannes wird dem Benutzer erlauben dem Raum wieder beizutreten.</string>
<string name="room_participants_unban_prompt_msg">Das Aufheben des Bannes wird dem/r Benutzer:in erlauben dem Raum wieder beizutreten.</string>
<string name="settings_secure_backup_section_title">Sicheres Backup</string>
<string name="settings_secure_backup_manage">Verwalten</string>
<string name="settings_secure_backup_setup">Backup einrichten</string>
@ -2375,4 +2375,31 @@
<string name="re_authentication_activity_title">Erneute Authentifizierung erforderlich</string>
<string name="failed_to_initialize_cross_signing">Cross Signing konnte nicht eingerichtet werden</string>
<string name="error_unauthorized">Nicht autorisierte, fehlende gültige Authentifizierungsdaten</string>
<string name="call_transfer_users_tab_title">Nutzer:innen</string>
<string name="call_transfer_failure">Beim Übertragen des Anrufs ist ein Fehler aufgetreten</string>
<string name="call_transfer_title">Übertragen</string>
<string name="call_transfer_connect_action">Verbinden</string>
<plurals name="call_one_active_and_other_paused">
<item quantity="one">1 aktiver Anruf (%1$s) · 1 pausierter Anruf</item>
<item quantity="other">1 aktiver Anruf (%1$s) · %2$d pausierte Anrufe</item>
</plurals>
<plurals name="call_only_paused">
<item quantity="one">Pausierter Anruf</item>
<item quantity="other">%1$d pausierte Anrufe</item>
</plurals>
<string name="call_only_active">Aktiver Anruf (%1$s)</string>
<string name="call_dial_pad_lookup_error">Beim Suchen der Telefonnummer ist ein Fehler aufgetreten</string>
<string name="call_dial_pad_title">Wähltastatur</string>
<string name="call_tile_call_back">Zurückrufen</string>
<string name="call_tile_ended">Dieser Anruf wurde beendet</string>
<string name="call_tile_other_declined">%1$s hat diesen Anruf abgelehnt</string>
<string name="call_tile_you_declined">Du hast diesen Anruf %1$s abgelehnt</string>
<string name="call_tile_in_call">Du nimmst zur Zeit an diesem Anruf teil</string>
<string name="call_tile_other_started_call">%1$s hat einen Anruf gestartet</string>
<string name="call_tile_you_started_call">Du hast einen Anruf gestartet</string>
<string name="call_held_by_you">Du hältst den Anruf</string>
<string name="call_held_by_user">%s hält den Anruf</string>
<string name="call_hold_action">Halten</string>
<string name="call_resume_action">Fortsetzen</string>
<string name="action_return">Zurück</string>
</resources>

View file

@ -1549,8 +1549,8 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua
<string name="invitation_sent_to_one_user">Invitación enviada a %1$s</string>
<string name="invitations_sent_to_two_users">Invitación enviada a %1$s y %2$s</string>
<plurals name="invitations_sent_to_one_and_more_users">
<item quantity="one">Invitaciones enviadas a % $s y a uno más</item>
<item quantity="other">Invitaciones enviadas a %$s y a %2$d más</item>
<item quantity="one">Invitaciones enviadas a %1$s y a uno más</item>
<item quantity="other">Invitaciones enviadas a %1$s y a %2$d más</item>
</plurals>
<string name="invite_users_to_room_failure">No se pudo invitar el usuario. Por favor, intente nuevamente.</string>
<string name="choose_locale_current_locale_title">Idioma actual</string>
@ -2291,7 +2291,7 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua
<string name="direct_room_user_list_contacts_title">Contactos</string>
<string name="direct_room_user_list_known_title">Usuarios conocidos</string>
<string name="settings_chat_effects_title">Mostrar efectos de chat</string>
<string name="permissions_denied_qr_code">Para escanear el codigo QR , necesita darle permisos a su camara.</string>
<string name="permissions_denied_qr_code">Para escanear el codigo QR , necesita darle permisos a su cámara.</string>
<string name="invite_friends">Invitar contactos</string>
<string name="room_settings_permissions_subtitle">Modifique los roles y privilegios de la sala.</string>
<string name="room_participants_leave_private_warning">Sala no pública. No puede acceder sin una invitacion.</string>
@ -2301,5 +2301,5 @@ Por favor permite el acceso en la próxima ventana emergente para descubrir usua
<string name="room_permissions_change_history_visibility">Editar historial de visibilidad</string>
<string name="room_permissions_change_permissions">Editar permisos</string>
<string name="room_permissions_change_room_name">Cambiar el nombre de la sala</string>
<string name="room_settings_permissions_title">Administracion de sala</string>
<string name="room_settings_permissions_title">Administración de sala</string>
</resources>

View file

@ -2320,4 +2320,32 @@
<string name="re_authentication_activity_title">Palun korda autentimist</string>
<string name="failed_to_initialize_cross_signing">Risttunnustamise alustamine ei õnnestunud</string>
<string name="error_unauthorized">Volitused puuduvad, kasutajakonto ja/või salasõna on valed</string>
<string name="call_transfer_users_tab_title">Kasutajad</string>
<string name="call_transfer_failure">Kõne suunamisel tekkis viga</string>
<string name="call_transfer_title">Suuna</string>
<string name="call_transfer_connect_action">Ühenda</string>
<string name="call_transfer_consult_first">Pea esmalt nõu</string>
<plurals name="call_one_active_and_other_paused">
<item quantity="one">Käsil on üks kõne (%1$s) · üks kõne on ootel</item>
<item quantity="other">Käsil on üks kõne (%1$s) · %2$d kõnet on ootel</item>
</plurals>
<plurals name="call_only_paused">
<item quantity="one">Pooleli kõne</item>
<item quantity="other">%1$d pooleli kõnet</item>
</plurals>
<string name="call_only_active">Kõne on pooleli (%1$s)</string>
<string name="call_dial_pad_lookup_error">Telefoninumbri otsimisel tekkis viga</string>
<string name="call_dial_pad_title">Numbriklahvistik</string>
<string name="call_tile_call_back">Helista tagasi</string>
<string name="call_tile_ended">See kõne on lõppenud</string>
<string name="call_tile_other_declined">%1$s keeldus kõnest</string>
<string name="call_tile_you_declined">Sa keeldusid %1$s kõnest</string>
<string name="call_tile_in_call">Sul on parasjagu see mõne pooleli</string>
<string name="call_tile_other_started_call">%1$s alustas kõnet</string>
<string name="call_tile_you_started_call">Sa alustasid kõnet</string>
<string name="call_held_by_you">Sina panid kõne ootele</string>
<string name="call_held_by_user">%s pani kõne ootele</string>
<string name="call_hold_action">Pane ootele</string>
<string name="call_resume_action">Jätka</string>
<string name="action_return">Pöördu tagasi</string>
</resources>

File diff suppressed because it is too large Load diff

View file

@ -2376,4 +2376,37 @@
<string name="room_settings_permissions_title">Autorizzazioni stanza</string>
<string name="room_participants_leave_private_warning">Questa stanza non è pubblica. Non potrai rientrare senza un invito.</string>
<string name="system_theme">Predefinito di sistema</string>
<string name="authentication_error">Autenticazione fallita</string>
<string name="re_authentication_default_confirm_text">Element richiede di reinserire le credenziali per eseguire questa azione.</string>
<string name="re_authentication_activity_title">Necessario riautenticarsi</string>
<string name="call_transfer_users_tab_title">Utenti</string>
<string name="call_transfer_failure">Si è verificato un errore trasferendo la chiamata</string>
<string name="call_transfer_title">Trasferisci</string>
<string name="call_transfer_connect_action">Connetti</string>
<string name="call_transfer_consult_first">Prima consulta</string>
<plurals name="call_one_active_and_other_paused">
<item quantity="one">1 chiamata attiva (%1$s) · 1 chiamata in pausa</item>
<item quantity="other">1 chiamata attiva (%1$s) · %2$d chiamate in pausa</item>
</plurals>
<plurals name="call_only_paused">
<item quantity="one">Chiamata in pausa</item>
<item quantity="other">%1$d chiamate in pausa</item>
</plurals>
<string name="call_only_active">Chiamata attiva (%1$s)</string>
<string name="call_dial_pad_lookup_error">Si è verificato un errore cercando il numero di telefono</string>
<string name="call_dial_pad_title">Tastierino numerico</string>
<string name="call_tile_call_back">Richiama</string>
<string name="call_tile_ended">Questa chiamata è terminata</string>
<string name="call_tile_other_declined">%1$s ha rifiutato questa chiamata</string>
<string name="call_tile_you_declined">Hai rifiutato questa chiamata %1$s</string>
<string name="call_tile_in_call">Sei attualmente in questa chiamata</string>
<string name="call_tile_other_started_call">%1$s ha iniziato una chiamata</string>
<string name="call_tile_you_started_call">Hai iniziato una chiamata</string>
<string name="failed_to_initialize_cross_signing">Impostazione della firma incrociata fallita</string>
<string name="call_held_by_you">Hai messo la chiamata in attesa</string>
<string name="call_held_by_user">%s ha messo la chiamata in attesa</string>
<string name="call_hold_action">In attesa</string>
<string name="call_resume_action">Riprendi</string>
<string name="error_unauthorized">Non autorizzato, credenziali di autenticazione valide mancanti</string>
<string name="action_return">Torna</string>
</resources>

View file

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="keys_backup_settings_delete_backup_button">ബാക്കപ്പ് ഇല്ലാതാക്കൂ</string>
<string name="keys_backup_settings_deleting_backup">ബാക്കപ്പ് ഇല്ലാതാക്കുന്നൂ…</string>
<string name="keys_backup_settings_delete_confirm_title">ബാക്കപ്പ് ഇല്ലാതാക്കൂ</string>
<string name="room_list_quick_actions_settings">ക്രമീകരണങ്ങൾ</string>
<string name="room_list_quick_actions_notifications_mentions">സൂചനകൾ മാത്രം</string>
<string name="room_list_quick_actions_notifications_all">എല്ലാ സന്ദേശങ്ങളും</string>
<string name="notice_member_no_changes_by_you">നിങ്ങൾ മാറ്റങ്ങളൊന്നും വരുത്തിയില്ല</string>
<string name="timeline_unread_messages">വായിക്കാത്ത സന്ദേശങ്ങൾ</string>
<string name="media_file_added_to_gallery">മീഡിയ ഫയൽ ഗാലറിയിലേക്ക് ചേർത്തു</string>
<string name="unencrypted">എൻ‌ക്രിപ്റ്റ് ചെയ്യാത്തത്</string>
<string name="default_message_emote_snow">മഞ്ഞ് അയയ്ക്കുന്നു ❄️</string>
<string name="crosssigning_verify_session">പ്രവേശനം ഉറപ്പാക്കൂ</string>
<string name="error_empty_field_choose_password">ഒരു രഹസ്യവാക്ക് തിരഞ്ഞെടുക്കുക.</string>
<string name="error_empty_field_choose_user_name">ഒരു ഉപയോക്തൃനാമം തിരഞ്ഞെടുക്കുക.</string>
<string name="add_people">ആളുകളെ ചേർക്കൂ</string>
<string name="invite_users_to_room_title">ഉപയോക്താക്കളെ ക്ഷണിക്കുക</string>
<string name="invite_friends">സുഹൃത്തുക്കളെ ക്ഷണിക്കുക</string>
<string name="user_code_share">എന്റെ കോഡ് പങ്കിടുക</string>
<string name="user_code_my_code">എന്റെ കോഡ്</string>
<string name="invite_friends_rich_title">🔐️ element-ൽ എന്നോടൊപ്പം ചേരുക</string>
<string name="identity_server_set_alternative_submit">സമർപ്പിക്കൂ</string>
<string name="a11y_open_chat">ചാറ്റ് തുറക്കുക</string>
<string name="a11y_stop_camera">ക്യാമറ നിർത്തുക</string>
<string name="room_settings_topic_hint">വിഷയം</string>
<string name="room_settings_name_hint">മുറിയുടെ പേര്</string>
<string name="room_settings_set_avatar">അവതാർ സജ്ജമാക്കുക</string>
<string name="loading_contact_book">നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ലഭ്യമാക്കുന്നൂ…</string>
<string name="auth_pin_forgot">പിൻ മറന്നോ\?</string>
<string name="auth_pin_title">നിങ്ങളുടെ പിൻ നൽകുക</string>
<string name="settings_security_pin_code_notifications_title">ഉള്ളടക്കം അറിയിപ്പുകളിൽ കാണിക്കൂ</string>
<string name="settings_security_pin_code_change_pin_title">പിൻ മാറ്റുക</string>
<string name="call_tile_ended">ഈ കോൾ അവസാനിച്ചു</string>
<string name="call_tile_other_started_call">%1$s ഒരു കോൾ ആരംഭിച്ചൂ</string>
<string name="call_tile_you_started_call">നിങ്ങൾ ഒരു കോൾ ആരംഭിച്ചൂ</string>
<string name="warning_unsaved_change_discard">മാറ്റങ്ങൾ ഉപേക്ഷിക്കുക</string>
<string name="call_tile_call_back">തിരിച്ചു വിളിക്കുക</string>
<string name="call_transfer_users_tab_title">ഉപയോക്താക്കൾ</string>
<string name="no_result_placeholder">ഫലങ്ങളൊന്നുമില്ല</string>
<string name="no_conversation_placeholder">സംഭാഷണങ്ങളൊന്നുമില്ല</string>
<string name="direct_chats_header">സംഭാഷണങ്ങൾ</string>
<string name="invitations_header">കഷണങ്ങൾ</string>
<string name="bottom_action_rooms">മുറികൾ</string>
<string name="bottom_action_people">ആളുകൾ</string>
<string name="bottom_action_favourites">പ്രിയപ്പെട്ടവ</string>
<string name="bottom_action_notification">അറിയിപ്പുകൾ</string>
<string name="dialog_title_success">വിജയകരം</string>
<string name="dialog_title_warning">മുന്നറിയിപ്പ്</string>
<string name="action_add">ചേർക്കുക</string>
<string name="action_copy">പകർത്തുക</string>
<string name="action_close">അടയ്ക്കുക</string>
<string name="action_open">തുറക്കുക</string>
<string name="action_mark_room_read">വായിച്ചതായി കാണിക്കൂ</string>
<string name="action_historical">ചരിത്രപരമായ</string>
<string name="action_mark_all_as_read">എല്ലാം വായിച്ചതായി കാണിക്കൂ</string>
<string name="action_video_call">വീഡിയോ കോൾ</string>
<string name="action_voice_call">വോയ്സ് കോൾ</string>
<string name="actions">പ്രവർത്തനങ്ങൾ</string>
<string name="action_exit">പുറത്തുകടക്കുക</string>
<string name="ignore">അവഗണിക്കൂ</string>
<string name="done">ചെയ്‌തു</string>
<string name="skip">ഒഴിവാക്കൂ</string>
<string name="offline">ഓഫ്‌ലൈൻ</string>
<string name="invite">ക്ഷണിക്കുക</string>
<string name="or">അല്ലെങ്കിൽ</string>
<string name="device_information">സെഷൻ വിശദാംശങ്ങൾ</string>
<string name="audio_meeting">ഓഡിയോ മീറ്റിംഗ് ആരംഭിക്കുക</string>
<string name="video_meeting">വീഡിയോ മീറ്റിംഗ് ആരംഭിക്കുക</string>
<string name="conference_call_in_progress">ഒരു കോൺഫറൻസ് ഇതിനകം പുരോഗമിക്കുന്നു!</string>
<string name="no_permissions_to_start_conf_call_in_direct_room">ഒരു കോൺഫറൻസ് കോൾ ആരംഭിക്കാൻ നിങ്ങൾക്ക് അനുവാദമില്ല</string>
<string name="cannot_start_call">കോൾ ആരംഭിക്കാൻ കഴിയില്ല, ദയവായി പിന്നീട് ശ്രമിക്കുക</string>
<string name="ongoing_conference_call_video">വീഡിയോ</string>
<string name="start_chatting">ചാറ്റിംഗ് ആരംഭിക്കുക</string>
<string name="delete">ഇല്ലാതാക്കൂ</string>
<string name="clear">മായ്ക്കുക</string>
<string name="download">ഡൌൺലോഡ് ചെയ്യൂ</string>
<string name="share">പങ്കിടുക</string>
<string name="resend">വീണ്ടും അയയ്ക്കൂ</string>
<string name="send">അയയ്ക്കൂ</string>
<string name="save">സംരക്ഷിക്കൂ</string>
<string name="cancel">റദ്ദാക്കൂ</string>
<string name="ok">ശരി</string>
<string name="loading">ലഭ്യമാക്കുന്നു…</string>
<string name="are_you_sure">നിങ്ങൾക്കു ഉറപ്പാണോ\?</string>
<string name="sign_out_bottom_sheet_dont_want_secure_messages">എന്റെ എൻക്രിപ്റ്റ് ചെയ്ത സന്ദേശങ്ങളൊന്നും എനിക്ക് വേണ്ട</string>
<string name="title_activity_verify_device">സെഷൻ ഉറപ്പാക്കൂ</string>
<string name="title_activity_choose_sticker">ഒരു സ്റ്റിക്കർ അയയ്‌ക്കുക</string>
<string name="title_activity_group_details">കമ്മ്യൂണിറ്റി വിശദാംശങ്ങൾ</string>
<string name="title_activity_historical">ചരിത്രപരമായ</string>
<string name="title_activity_settings">ക്രമീകരണങ്ങൾ</string>
<string name="title_activity_room">മുറി</string>
<string name="title_activity_home">സന്ദേശങ്ങൾ</string>
<string name="notification_silent_notifications">നിശബ്‌ദ അറിയിപ്പുകൾ</string>
<string name="notification_sync_in_progress">സമന്വയിപ്പിക്കുന്നു</string>
</resources>

View file

@ -791,10 +791,10 @@ Widoczność wiadomości w Matrix jest podobna do wiadomości e-mail. Nasze zapo
<item quantity="other"/>
</plurals>
<plurals name="format_time_h">
<item quantity="one">% godzina</item>
<item quantity="few">%s godz.</item>
<item quantity="many"/>
<item quantity="other"/>
<item quantity="one">%d godzina</item>
<item quantity="few">%d godz.</item>
<item quantity="many"></item>
<item quantity="other"></item>
</plurals>
<plurals name="format_time_d">
<item quantity="one">%d dzień</item>
@ -2211,8 +2211,8 @@ Spróbuj uruchomić ponownie aplikację.</string>
<plurals name="two_and_some_others_read">
<item quantity="one">%1$s, %2$s i %3$d czyta</item>
<item quantity="few">%1$s, %2$s i %3$d czytają</item>
<item quantity="many"></item>
<item quantity="other"></item>
<item quantity="many"/>
<item quantity="other"/>
</plurals>
<string name="room_alias_publish_to_directory_error">Nie udało się uzyskać widoczności katalogu bieżącego pokoju (%1$s).</string>
<string name="settings_secure_backup_enter_to_setup">Skonfiguruj na tym urządzeniu</string>

View file

@ -1751,7 +1751,7 @@
<string name="set_recovery_passphrase">Caktoni një %s</string>
<string name="generate_message_key">Prodhoni një Kyç Mesazhesh</string>
<string name="confirm_recovery_passphrase">Ripohoni %s</string>
<string name="enter_account_password">Që të vazhdohet, jepni % tuaj.</string>
<string name="enter_account_password">Që të vazhdohet, jepni %s tuaj.</string>
<string name="bootstrap_info_text">Siguroni &amp; shkyçni mesazhet tuaj të fshehtëzuar dhe besim me një %s.</string>
<string name="bootstrap_info_confirm_text">Për ta ripohuar, rijepni %s tuaj.</string>
<string name="bootstrap_dont_reuse_pwd">Mos ripërdorni fjalëkalimin e llogarisë tuaj.</string>

View file

@ -1891,7 +1891,7 @@
<string name="room_member_power_level_users">Användare</string>
<string name="room_member_power_level_admin_in">Administratör i %1$s</string>
<string name="room_member_power_level_moderator_in">Moderator i %1$s</string>
<string name="room_member_power_level_default_in">Standard i %1$s</string>
<string name="room_member_power_level_default_in">Standardbehörig i %1$s</string>
<string name="room_member_power_level_custom_in">Anpassad (%1$d) i %2$s</string>
<string name="room_member_jump_to_read_receipt">Hoppa till läskvitto</string>
<string name="rendering_event_error_type_of_event_not_handled">Element hanterar inte händelser av typen \'%1$s\'</string>

View file

@ -2752,6 +2752,10 @@
<item quantity="one">Wrong code, %d remaining attempt</item>
<item quantity="other">Wrong code, %d remaining attempts</item>
</plurals>
<plurals name="entries">
<item quantity="one">%d entry"</item>
<item quantity="other">%d entries"</item>
</plurals>
<string name="wrong_pin_message_last_remaining_attempt">Warning! Last remaining attempt before logout!</string>
<string name="too_many_pin_failures">Too many errors, you\'ve been logged out</string>
<string name="create_pin_title">Choose a PIN for security</string>
@ -2851,4 +2855,20 @@
<string name="a11y_rule_notify_silent">Notify without sound</string>
<string name="a11y_rule_notify_off">Do not notify</string>
<string name="a11y_view_read_receipts">View read receipts</string>
<string name="dev_tools_menu_name">Dev Tools</string>
<string name="dev_tools_explore_room_state">Explore Room State</string>
<string name="dev_tools_send_custom_event">Send Custom Event</string>
<string name="dev_tools_send_state_event">Send State Event</string>
<string name="dev_tools_state_event">State Events</string>
<string name="dev_tools_edit_content">Edit Content</string>
<string name="dev_tools_send_custom_state_event">Send Custom State Event</string>
<string name="dev_tools_form_hint_type">Type</string>
<string name="dev_tools_form_hint_state_key">State Key</string>
<string name="dev_tools_form_hint_event_content">Event Content</string>
<string name="dev_tools_error_no_content">No content</string>
<string name="dev_tools_error_no_message_type">Missing message type</string>
<string name="dev_tools_error_malformed_event">Malformed event</string>
<string name="dev_tools_success_event">Event sent!</string>
<string name="dev_tools_success_state_event">State event sent!</string>
</resources>