Merge branch 'develop' into feature/create_direct_room

This commit is contained in:
ganfra 2019-07-19 18:18:22 +02:00
commit 2c81e41288
47 changed files with 758 additions and 180 deletions

View File

@ -1,9 +1,34 @@
Changes in RiotX 0.2.1 (2019-XX-XX)
Changes in RiotX 0.3.0 (2019-XX-XX)
===================================================

Features:
-

Improvements:
-

Other changes:
-

Bugfix:
- Edited message: link confusion when (edited) appears in body (#398)
- Close detail room screen when the room is left with another client (#256)
- Clear notification for a room left on another client

Translations:
-

Build:
-


Changes in RiotX 0.2.0 (2019-07-18)
===================================================

Features:
- Message Editing: View edit history (#121)
- Rooms filtering (#304)
- Edit in encrypted room

Improvements:
- Handle click on redacted events: view source and create permalink
@ -22,14 +47,6 @@ Bugfix:
- Fix bad layout for room directory filter (#349)
- Fix Copying link from a message shouldn't open context menu (#364)

Translations:
-

Build:
-



Changes in RiotX 0.1.0 (2019-07-11)
===================================================

@ -43,7 +60,7 @@ Mode details here: https://medium.com/@RiotChat/introducing-the-riotx-beta-for-a
=======================================================


Changes in RiotX 0.XX (2019-XX-XX)
Changes in RiotX 0.0.0 (2019-XX-XX)
===================================================

Features:

View File

@ -1,4 +1,4 @@
This document aims to describe how Riot X android displays notifications to the end user. It also clarifies notifications and background settings in the app.
This document aims to describe how RiotX android displays notifications to the end user. It also clarifies notifications and background settings in the app.

# Table of Contents
1. [Prerequisites Knowledge](#prerequisites-knowledge)
@ -50,7 +50,7 @@ By default, this is 0, so the server will return immediately even if the respons

**delay** is a client preference. When the server responds to a sync request, the client waits for `delay`before calling a new sync.

When the Riot X Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0.
When the RiotX Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0.

## How does a mobile app receives push notification

@ -86,7 +86,7 @@ This need some disambiguation, because it is the source of common confusion:
In order to send a push to a mobile, App developers need to have a server that will use the FCM APIs, and these APIs requires authentication!
This server is called a **Push Gateway** in the matrix world

That means that Riot X Android, a matrix client created by New Vector, is using a **Push Gateway** with the needed credentials (FCM API secret Key) in order to send push to the New Vector client.
That means that RiotX Android, a matrix client created by New Vector, is using a **Push Gateway** with the needed credentials (FCM API secret Key) in order to send push to the New Vector client.

If you create your own matrix client, you will also need to deploy an instance of a **Push Gateway** with the credentials needed to use FCM for your app.

@ -223,7 +223,7 @@ Upon reception of the FCM push, RiotX will perform a sync call to the Home Serve
* The sync generates additional notifications (e.g an encrypted message where the user is mentioned detected locally)
* The sync takes too long and the process is killed before completion, or network is not reliable and the sync fails.

Riot X implements several strategies in these cases (TODO document)
RiotX implements several strategies in these cases (TODO document)

## FCM Fallback mode


View File

@ -42,6 +42,7 @@ interface PushRuleService {

interface PushRuleListener {
fun onMatchRule(event: Event, actions: List<Action>)
fun onRoomLeft(roomId: String)
fun batchFinish()
}
}

View File

@ -85,14 +85,12 @@ interface RelationService {
* Edit a reply. This is a special case because replies contains fallback text as a prefix.
* This method will take the new body (stripped from fallbacks) and re-add them before sending.
* @param replyToEdit The event to edit
* @param originalSenderId the sender of the message that this reply (being edited) is relating to
* @param originalEventId the event id that this reply (being edited) is relating to
* @param originalTimelineEvent the message that this reply (being edited) is relating to
* @param newBodyText The edited body (stripped from in reply to content)
* @param compatibilityBodyText The text that will appear on clients that don't support yet edition
*/
fun editReply(replyToEdit: TimelineEvent,
originalSenderId: String?,
originalEventId : String,
originalTimelineEvent: TimelineEvent,
newBodyText: String,
compatibilityBodyText: String = "* $newBodyText"): Cancelable


View File

@ -24,6 +24,7 @@ import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.isReply
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent

/**
* This data class is a wrapper around an Event. It allows to get useful data in the context of a timeline.
@ -94,7 +95,7 @@ fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSu

fun TimelineEvent.getTextEditableContent(): String? {
val originalContent = root.getClearContent().toModel<MessageContent>() ?: return null
val isReply = originalContent.isReply()
val isReply = originalContent.isReply() || root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId != null
val lastContent = getLastMessageContent()
return if (isReply) {
return extractUsefulTextFromReply(lastContent?.body ?: "")

View File

@ -18,7 +18,7 @@ package im.vector.matrix.android.api.session.sync

sealed class SyncState {
object IDLE : SyncState()
data class RUNNING(val catchingUp: Boolean) : SyncState()
data class RUNNING(val afterPause: Boolean) : SyncState()
object PAUSED : SyncState()
object KILLING : SyncState()
object KILLED : SyncState()

View File

@ -17,6 +17,7 @@ package im.vector.matrix.android.internal.crypto.model.event

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent

/**
* Class representing an encrypted event content
@ -52,5 +53,8 @@ data class EncryptedEventContent(
* The session id
*/
@Json(name = "session_id")
val sessionId: String? = null
val sessionId: String? = null,

//Relation context is in clear in encrypted message
@Json(name = "m.relates_to") val relatesTo: RelationDefaultContent? = null
)

View File

@ -20,13 +20,11 @@ import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.pushrules.Action
import im.vector.matrix.android.api.pushrules.PushRuleService
import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
import im.vector.matrix.android.api.pushrules.rest.PushRule
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
import im.vector.matrix.android.internal.database.model.PushRulesEntity
import im.vector.matrix.android.internal.database.model.PusherEntityFields
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.session.SessionScope
import im.vector.matrix.android.internal.session.pushers.GetPushRulesTask
@ -123,13 +121,23 @@ internal class DefaultPushRuleService @Inject constructor(
}
}

fun dispatchRoomLeft(roomid: String) {
try {
listeners.forEach {
it.onRoomLeft(roomid)
}
} catch (e: Throwable) {
Timber.e(e, "Error while dispatching room left")
}
}

fun dispatchFinish() {
try {
listeners.forEach {
it.batchFinish()
}
} catch (e: Throwable) {

Timber.e(e, "Error while dispatching finish")
}
}
}

View File

@ -44,6 +44,10 @@ internal class DefaultProcessEventForPushTask @Inject constructor(

override suspend fun execute(params: ProcessEventForPushTask.Params): Try<Unit> {
return Try {
// Handle left rooms
params.syncResponse.leave.keys.forEach {
defaultPushRuleService.dispatchRoomLeft(it)
}
val newJoinEvents = params.syncResponse.join
.map { entries ->
entries.value.timeline?.events?.map { it.copy(roomId = entries.key) }

View File

@ -17,9 +17,13 @@ package im.vector.matrix.android.internal.session.room

import arrow.core.Try
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.events.model.*
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.relation.ReactionContent
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
import im.vector.matrix.android.internal.database.mapper.ContentMapper
import im.vector.matrix.android.internal.database.mapper.EventMapper
import im.vector.matrix.android.internal.database.model.*
@ -43,7 +47,9 @@ internal interface EventRelationsAggregationTask : Task<EventRelationsAggregatio
/**
* Called by EventRelationAggregationUpdater, when new events that can affect relations are inserted in base.
*/
internal class DefaultEventRelationsAggregationTask @Inject constructor(private val monarchy: Monarchy) : EventRelationsAggregationTask {
internal class DefaultEventRelationsAggregationTask @Inject constructor(
private val monarchy: Monarchy,
private val cryptoService: CryptoService) : EventRelationsAggregationTask {

//OPT OUT serer aggregation until API mature enough
private val SHOULD_HANDLE_SERVER_AGREGGATION = false
@ -86,14 +92,43 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(private
}
}

EventAnnotationsSummaryEntity.where(realm, event.eventId ?: "").findFirst()?.let {
TimelineEventEntity.where(realm,eventId = event.eventId ?: "").findFirst()?.let { tet ->
EventAnnotationsSummaryEntity.where(realm, event.eventId
?: "").findFirst()?.let {
TimelineEventEntity.where(realm, eventId = event.eventId
?: "").findFirst()?.let { tet ->
tet.annotations = it
}
}


}

EventType.ENCRYPTED -> {
//Relation type is in clear
val encryptedEventContent = event.content.toModel<EncryptedEventContent>()
if (encryptedEventContent?.relatesTo?.type == RelationType.REPLACE) {
//we need to decrypt if needed
if (event.mxDecryptionResult == null) {
try {
val result = cryptoService.decryptEvent(event, event.roomId)
event.mxDecryptionResult = OlmDecryptionResult(
payload = result.clearEvent,
senderKey = result.senderCurve25519Key,
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
)
} catch (e: MXCryptoError) {
Timber.w("Failed to decrypt e2e replace")
//TODO -> we should keep track of this and retry, or aggregation will be broken
}
}
event.getClearContent().toModel<MessageContent>()?.let {
Timber.v("###REPLACE in room $roomId for event ${event.eventId}")
//A replace!
handleReplace(realm, event, it, roomId, isLocalEcho, encryptedEventContent.relatesTo.eventId)
}
}
}
EventType.REDACTION -> {
val eventToPrune = event.redacts?.let { EventEntity.where(realm, eventId = it).findFirst() }
?: return@forEach
@ -125,9 +160,9 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(private

}

private fun handleReplace(realm: Realm, event: Event, content: MessageContent, roomId: String, isLocalEcho: Boolean) {
private fun handleReplace(realm: Realm, event: Event, content: MessageContent, roomId: String, isLocalEcho: Boolean, relatedEventId: String? = null) {
val eventId = event.eventId ?: return
val targetEventId = content.relatesTo?.eventId ?: return
val targetEventId = relatedEventId ?: content.relatesTo?.eventId ?: return
val newContent = content.newContent ?: return
//ok, this is a replace
var existing = EventAnnotationsSummaryEntity.where(realm, targetEventId).findFirst()

View File

@ -61,13 +61,13 @@ internal class DefaultPruneEventTask @Inject constructor(private val monarchy: M
}

val redactionEventEntity = EventEntity.where(realm, eventId = redactionEvent.eventId
?: "").findFirst()
?: return
?: "").findFirst()
?: return
val isLocalEcho = redactionEventEntity.sendState == SendState.UNSENT
Timber.v("Redact event for ${redactionEvent.redacts} localEcho=$isLocalEcho")

val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()
?: return
?: return

val allowedKeys = computeAllowedKeys(eventToPrune.type)
if (allowedKeys.isNotEmpty()) {
@ -75,10 +75,11 @@ internal class DefaultPruneEventTask @Inject constructor(private val monarchy: M
eventToPrune.content = ContentMapper.map(prunedContent)
} else {
when (eventToPrune.type) {
EventType.ENCRYPTED,
EventType.MESSAGE -> {
Timber.d("REDACTION for message ${eventToPrune.eventId}")
val unsignedData = EventMapper.map(eventToPrune).unsignedData
?: UnsignedData(null, null)
?: UnsignedData(null, null)

//was this event a m.replace
// val contentModel = ContentMapper.map(eventToPrune.content)?.toModel<MessageContent>()
@ -89,6 +90,8 @@ internal class DefaultPruneEventTask @Inject constructor(private val monarchy: M
val modified = unsignedData.copy(redactedEvent = redactionEvent)
eventToPrune.content = ContentMapper.map(emptyMap())
eventToPrune.unsignedData = MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(modified)
eventToPrune.decryptionResultJson = null
eventToPrune.decryptionErrorCode = null

}
// EventType.REACTION -> {
@ -112,14 +115,14 @@ internal class DefaultPruneEventTask @Inject constructor(private val monarchy: M
EventType.STATE_ROOM_CREATE -> listOf("creator")
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
EventType.STATE_ROOM_POWER_LEVELS -> listOf("users",
"users_default",
"events",
"events_default",
"state_default",
"ban",
"kick",
"redact",
"invite")
"users_default",
"events",
"events_default",
"state_default",
"ban",
"kick",
"redact",
"invite")
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
EventType.STATE_CANONICAL_ALIAS -> listOf("alias")
EventType.FEEDBACK -> listOf("type", "target_event_id")

View File

@ -127,32 +127,47 @@ internal class DefaultRelationService @Inject constructor(private val context: C
.also {
saveLocalEcho(it)
}
val workRequest = createSendEventWork(event)
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
return CancelableWork(context, workRequest.id)
if (cryptoService.isRoomEncrypted(roomId)) {
val encryptWork = createEncryptEventWork(event, listOf("m.relates_to"))
val workRequest = createSendEventWork(event)
TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest)
return CancelableWork(context, encryptWork.id)

} else {
val workRequest = createSendEventWork(event)
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
return CancelableWork(context, workRequest.id)
}

}

override fun editReply(replyToEdit: TimelineEvent,
originalSenderId: String?,
originalEventId: String,
originalEvent: TimelineEvent,
newBodyText: String,
compatibilityBodyText: String): Cancelable {
val event = eventFactory
.createReplaceTextOfReply(roomId,
replyToEdit,
originalSenderId, originalEventId,
originalEvent,
newBodyText, true, MessageType.MSGTYPE_TEXT, compatibilityBodyText)
.also {
saveLocalEcho(it)
}
val workRequest = createSendEventWork(event)
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
return CancelableWork(context, workRequest.id)
if (cryptoService.isRoomEncrypted(roomId)) {
val encryptWork = createEncryptEventWork(event, listOf("m.relates_to"))
val workRequest = createSendEventWork(event)
TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest)
return CancelableWork(context, encryptWork.id)

} else {
val workRequest = createSendEventWork(event)
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
return CancelableWork(context, workRequest.id)
}
}

override fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>) {
val params = FetchEditHistoryTask.Params(roomId, eventId)
val params = FetchEditHistoryTask.Params(roomId, cryptoService.isRoomEncrypted(roomId), eventId)
fetchEditHistoryTask.configureWith(params)
.dispatchTo(callback)
.executeBy(taskExecutor)

View File

@ -29,6 +29,7 @@ internal interface FetchEditHistoryTask : Task<FetchEditHistoryTask.Params, List

data class Params(
val roomId: String,
val isRoomEncrypted: Boolean,
val eventId: String
)
}
@ -40,9 +41,14 @@ internal class DefaultFetchEditHistoryTask @Inject constructor(

override suspend fun execute(params: FetchEditHistoryTask.Params): Try<List<Event>> {
return executeRequest<RelationsResponse> {
apiCall = roomAPI.getRelations(params.roomId, params.eventId, RelationType.REPLACE, EventType.MESSAGE)
apiCall = roomAPI.getRelations(params.roomId,
params.eventId,
RelationType.REPLACE,
if (params.isRoomEncrypted) EventType.ENCRYPTED else EventType.MESSAGE)
}.map { resp ->
resp.chunks
val events = resp.chunks.toMutableList()
resp.originalEvent?.let { events.add(it) }
events
}
}
}

View File

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.events.model.Event
@JsonClass(generateAdapter = true)
internal data class RelationsResponse(
@Json(name = "chunk") val chunks: List<Event>,
@Json(name = "original_event") val originalEvent: Event?,
@Json(name = "next_batch") val nextBatch: String?,
@Json(name = "prev_batch") val prevBatch: String?
)

View File

@ -105,28 +105,28 @@ internal class LocalEchoEventFactory @Inject constructor(private val credentials
}

fun createReplaceTextOfReply(roomId: String, eventReplaced: TimelineEvent,
originalSenderId: String?,
originalEventId: String,
originalEvent: TimelineEvent,
newBodyText: String,
newBodyAutoMarkdown: Boolean,
msgType: String,
compatibilityText: String): Event {
val permalink = PermalinkFactory.createPermalink(roomId, originalEventId)
val userLink = originalSenderId?.let { PermalinkFactory.createPermalink(it) } ?: ""
val permalink = PermalinkFactory.createPermalink(roomId, originalEvent.root.eventId ?: "")
val userLink = originalEvent.root.senderId?.let { PermalinkFactory.createPermalink(it) }
?: ""

val body = bodyForReply(eventReplaced.getLastMessageContent(), eventReplaced.root.getClearContent().toModel())
val body = bodyForReply(originalEvent.getLastMessageContent(), originalEvent.root.getClearContent().toModel())
val replyFormatted = REPLY_PATTERN.format(
permalink,
stringProvider.getString(R.string.message_reply_to_prefix),
userLink,
originalSenderId,
originalEvent.senderName ?: originalEvent.root.senderId,
body.takeFormatted(),
createTextContent(newBodyText, newBodyAutoMarkdown).takeFormatted()
)
//
// > <@alice:example.org> This is the original body
//
val replyFallback = buildReplyFallback(body, originalSenderId, newBodyText)
val replyFallback = buildReplyFallback(body, originalEvent.root.senderId ?: "", newBodyText)

return createEvent(roomId,
MessageTextContent(

View File

@ -37,7 +37,6 @@ import javax.inject.Inject

private const val RETRY_WAIT_TIME_MS = 10_000L
private const val DEFAULT_LONG_POOL_TIMEOUT = 30_000L
private const val DEFAULT_LONG_POOL_DELAY = 0L

internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
private val networkConnectivityChecker: NetworkConnectivityChecker,
@ -54,14 +53,15 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
updateStateTo(SyncState.IDLE)
}

fun setInitialForeground(initialForground : Boolean) {
updateStateTo(if (initialForground) SyncState.IDLE else SyncState.PAUSED)
fun setInitialForeground(initialForeground: Boolean) {
val newState = if (initialForeground) SyncState.IDLE else SyncState.PAUSED
updateStateTo(newState)
}

fun restart() = synchronized(lock) {
if (state is SyncState.PAUSED) {
Timber.v("Resume sync...")
updateStateTo(SyncState.RUNNING(catchingUp = true))
updateStateTo(SyncState.RUNNING(afterPause = true))
lock.notify()
}
}
@ -96,7 +96,9 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
lock.wait()
}
} else {
updateStateTo(SyncState.RUNNING(catchingUp = true))
if (state !is SyncState.RUNNING) {
updateStateTo(SyncState.RUNNING(afterPause = true))
}
Timber.v("[$this] Execute sync request with timeout $DEFAULT_LONG_POOL_TIMEOUT")
val latch = CountDownLatch(1)
val params = SyncTask.Params(DEFAULT_LONG_POOL_TIMEOUT)
@ -137,11 +139,9 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,

latch.await()
if (state is SyncState.RUNNING) {
updateStateTo(SyncState.RUNNING(catchingUp = false))
updateStateTo(SyncState.RUNNING(afterPause = false))
}

Timber.v("Waiting for $DEFAULT_LONG_POOL_DELAY delay before new pool...")
if (DEFAULT_LONG_POOL_DELAY > 0) sleep(DEFAULT_LONG_POOL_DELAY)
Timber.v("...Continue")
}
}

View File

@ -119,7 +119,7 @@
<string name="verification_emoji_robot">Robota</string>
<string name="verification_emoji_hat">Txanoa</string>
<string name="verification_emoji_glasses">Betaurrekoak</string>
<string name="verification_emoji_wrench">Giltza ingelesa</string>
<string name="verification_emoji_wrench">Giltza</string>
<string name="verification_emoji_santa">Santa</string>
<string name="verification_emoji_thumbsup">Ederto</string>
<string name="verification_emoji_umbrella">Aterkia</string>

View File

@ -2,4 +2,5 @@
<resources>
<string name="summary_message">%1$s: %2$s</string>
<string name="notice_room_invite_no_invitee">%s\'의 초대</string>
<string name="verification_emoji_headphone">헤드폰</string>
</resources>

View File

@ -228,4 +228,14 @@
<!-- All translations should be the same across all Riot clients, please use the same translation than RiotWeb -->
<string name="verification_emoji_pin">Pin</string>

<!-- Strings for RiotX -->
<string name="initial_sync_start_importing_account">Initial Sync:\nImporting account…</string>
<string name="initial_sync_start_importing_account_crypto">Initial Sync:\nImporting crypto</string>
<string name="initial_sync_start_importing_account_rooms">Initial Sync:\nImporting Rooms</string>
<string name="initial_sync_start_importing_account_joined_rooms">Initial Sync:\nImporting Joined Rooms</string>
<string name="initial_sync_start_importing_account_invited_rooms">Initial Sync:\nImporting Invited Rooms</string>
<string name="initial_sync_start_importing_account_left_rooms">Initial Sync:\nImporting Left Rooms</string>
<string name="initial_sync_start_importing_account_groups">Initial Sync:\nImporting Communities</string>
<string name="initial_sync_start_importing_account_data">Initial Sync:\nImporting Account Data</string>

</resources>

View File

@ -1,10 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="initial_sync_start_importing_account">Initial Sync:\nImporting account…</string>
<string name="initial_sync_start_importing_account_crypto">Initial Sync:\nImporting crypto</string>
<string name="initial_sync_start_importing_account_rooms">Initial Sync:\nImporting Rooms</string>
<string name="initial_sync_start_importing_account_joined_rooms">Initial Sync:\nImporting Joined Rooms</string>
<string name="initial_sync_start_importing_account_invited_rooms">Initial Sync:\nImporting Invited Rooms</string>
<string name="initial_sync_start_importing_account_left_rooms">Initial Sync:\nImporting Left Rooms</string>
<string name="initial_sync_start_importing_account_groups">Initial Sync:\nImporting Communities</string>
<string name="initial_sync_start_importing_account_data">Initial Sync:\nImporting Account Data</string>

</resources>

View File

@ -13,7 +13,7 @@ androidExtensions {
}

ext.versionMajor = 0
ext.versionMinor = 2
ext.versionMinor = 3
ext.versionPatch = 0

static def getGitTimestamp() {
@ -66,9 +66,9 @@ android {

// For release, use generateVersionCodeFromVersionName()
versionCode generateVersionCodeFromTimestamp()
// versionCode generateVersionCodeFromVersionName()
//versionCode generateVersionCodeFromVersionName()

versionName "${versionMajor}.${versionMinor}.${versionPatch}"
versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev"

buildConfigField "String", "GIT_REVISION", "\"${gitRevision()}\""
resValue "string", "git_revision", "\"${gitRevision()}\""

View File

@ -209,7 +209,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
unreadCounterBadgeViews[INDEX_PEOPLE].render(UnreadCounterBadgeView.State(it.notificationCountPeople, it.notificationHighlightPeople))
unreadCounterBadgeViews[INDEX_ROOMS].render(UnreadCounterBadgeView.State(it.notificationCountRooms, it.notificationHighlightRooms))
syncProgressBar.visibility = when (it.syncState) {
is SyncState.RUNNING -> if (it.syncState.catchingUp) View.VISIBLE else View.GONE
is SyncState.RUNNING -> if (it.syncState.afterPause) View.VISIBLE else View.GONE
else -> View.GONE
}
syncProgressBarWrap.visibility = syncProgressBar.visibility

View File

@ -18,10 +18,6 @@ package im.vector.riotx.features.home

import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotx.core.utils.RxStore
import im.vector.riotx.features.home.room.list.RoomListDisplayModeFilter
import im.vector.riotx.features.home.room.list.RoomListFragment
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject
import javax.inject.Singleton


View File

@ -270,8 +270,10 @@ class RoomDetailFragment :

composerLayout.composerEditText.setSelection(composerLayout.composerEditText.text.length)
composerLayout.expand {
//need to do it here also when not using quick reply
focusComposerAndShowKeyboard()
}
focusComposerAndShowKeyboard()
}

override fun onResume() {
@ -534,9 +536,14 @@ class RoomDetailFragment :

private fun renderRoomSummary(state: RoomDetailViewState) {
state.asyncRoomSummary()?.let {
roomToolbarTitleView.text = it.displayName
avatarRenderer.render(it, roomToolbarAvatarImageView)
roomToolbarSubtitleView.setTextOrHide(it.topic)
if (it.membership.isLeft()) {
Timber.w("The room has been left")
activity?.finish()
} else {
roomToolbarTitleView.text = it.displayName
avatarRenderer.render(it, roomToolbarAvatarImageView)
roomToolbarSubtitleView.setTextOrHide(it.topic)
}
}
}


View File

@ -38,6 +38,7 @@ import im.vector.matrix.android.api.session.room.model.message.MessageType
import im.vector.matrix.android.api.session.room.model.message.getFileUrl
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
import im.vector.matrix.rx.rx
import im.vector.riotx.core.intent.getFilenameFromUri
import im.vector.riotx.core.platform.VectorViewModel
@ -230,9 +231,12 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro

//is original event a reply?
val inReplyTo = state.sendMode.timelineEvent.root.getClearContent().toModel<MessageContent>()?.relatesTo?.inReplyTo?.eventId
?: state.sendMode.timelineEvent.root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId
if (inReplyTo != null) {
//TODO check if same content?
room.editReply(state.sendMode.timelineEvent, room.getTimeLineEvent(inReplyTo)?.root?.senderId, inReplyTo, action.text)
room.getTimeLineEvent(inReplyTo)?.let {
room.editReply(state.sendMode.timelineEvent, it, action.text)
}
} else {
val messageContent: MessageContent? =
state.sendMode.timelineEvent.annotations?.editSummary?.aggregatedContent.toModel()

View File

@ -57,6 +57,7 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib

var currentConstraintSetId: Int = -1

private val animationDuration = 100L

init {
inflate(context, R.layout.merge_composer_layout, this)
@ -73,7 +74,7 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib
currentConstraintSetId = R.layout.constraint_set_composer_layout_compact
if (animate) {
val transition = AutoTransition()
// transition.duration = 5000
transition.duration = animationDuration
transition.addListener(object : Transition.TransitionListener {

override fun onTransitionEnd(transition: Transition) {
@ -105,7 +106,7 @@ class TextComposerView @JvmOverloads constructor(context: Context, attrs: Attrib
currentConstraintSetId = R.layout.constraint_set_composer_layout_expanded
if (animate) {
val transition = AutoTransition()
// transition.duration = 5000
transition.duration = animationDuration
transition.addListener(object : Transition.TransitionListener {

override fun onTransitionEnd(transition: Transition) {

View File

@ -244,7 +244,7 @@ class MessageMenuViewModel @AssistedInject constructor(@Assisted initialState: M
//Only event of type Event.EVENT_TYPE_MESSAGE are supported for the moment
if (event.root.getClearType() != EventType.MESSAGE) return false
//TODO if user is admin or moderator
val messageContent = event.root.content.toModel<MessageContent>()
val messageContent = event.root.getClearContent().toModel<MessageContent>()
return event.root.senderId == myUserId && (
messageContent?.type == MessageType.MSGTYPE_TEXT
|| messageContent?.type == MessageType.MSGTYPE_EMOTE

View File

@ -75,9 +75,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
}
} else {
var lastDate: Calendar? = null
sourceEvents.sortedByDescending {
it.originServerTs ?: 0
}.forEachIndexed { index, timelineEvent ->
sourceEvents.forEachIndexed { index, timelineEvent ->

val evDate = Calendar.getInstance().apply {
timeInMillis = timelineEvent.originServerTs

View File

@ -20,12 +20,16 @@ import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.isReply
import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDateFormatter
import timber.log.Timber
import java.util.*


data class ViewEditHistoryViewState(
@ -79,16 +83,36 @@ class ViewEditHistoryViewModel @AssistedInject constructor(@Assisted
}

override fun onSuccess(data: List<Event>) {
//TODO until supported by API Add original event manually
val withOriginal = data.toMutableList()
var originalIsReply = false
room.getTimeLineEvent(eventId)?.let {
withOriginal.add(it.root)
originalIsReply = it.root.getClearContent().toModel<MessageContent>().isReply()

val events = data.map { event ->
val timelineID = event.roomId + UUID.randomUUID().toString()
event.also {
//We need to check encryption
if (it.isEncrypted() && it.mxDecryptionResult == null) {
//for now decrypt sync
try {
val result = session.decryptEvent(it, timelineID)
it.mxDecryptionResult = OlmDecryptionResult(
payload = result.clearEvent,
senderKey = result.senderCurve25519Key,
keysClaimed = result.claimedEd25519Key?.let { k -> mapOf("ed25519" to k) },
forwardingCurve25519KeyChain = result.forwardingCurve25519KeyChain
)
} catch (e: MXCryptoError) {
Timber.w("Failed to decrypt event in history")
}
}

if (event.eventId == it.eventId) {
originalIsReply = it.getClearContent().toModel<MessageContent>().isReply()
}
}

}
setState {
copy(
editList = Success(withOriginal),
editList = Success(events),
isOriginalAReply = originalIsReply
)
}

View File

@ -27,12 +27,14 @@ import dagger.Lazy
import im.vector.matrix.android.api.permalinks.MatrixLinkify
import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
import im.vector.matrix.android.api.session.events.model.RelationType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.api.session.room.send.SendState
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
import im.vector.riotx.EmojiCompatFontProvider
import im.vector.riotx.R
import im.vector.riotx.core.epoxy.VectorEpoxyModel
@ -83,7 +85,9 @@ class MessageItemFactory @Inject constructor(
?: //Malformed content, we should echo something on screen
return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))

if (messageContent.relatesTo?.type == RelationType.REPLACE) {
if (messageContent.relatesTo?.type == RelationType.REPLACE
|| event.isEncrypted() && event.root.content.toModel<EncryptedEventContent>()?.relatesTo?.type == RelationType.REPLACE
) {
// ignore replace event, the targeted id is already edited
return BlankItem_()
}
@ -229,7 +233,8 @@ class MessageItemFactory @Inject constructor(
val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize()
val thumbnailData = ImageContentRenderer.Data(
filename = messageContent.body,
url = messageContent.videoInfo?.thumbnailFile?.url ?: messageContent.videoInfo?.thumbnailUrl,
url = messageContent.videoInfo?.thumbnailFile?.url
?: messageContent.videoInfo?.thumbnailUrl,
elementToDecrypt = messageContent.videoInfo?.thumbnailFile?.toElementToDecrypt(),
height = messageContent.videoInfo?.height,
maxHeight = maxHeight,
@ -318,7 +323,7 @@ class MessageItemFactory @Inject constructor(
val editedSuffix = stringProvider.getString(R.string.edited_suffix)
spannable.append(" ").append(editedSuffix)
val color = colorProvider.getColorFromAttribute(R.attr.vctr_list_header_secondary_text_color)
val editStart = spannable.indexOf(editedSuffix)
val editStart = spannable.lastIndexOf(editedSuffix)
val editEnd = editStart + editedSuffix.length
spannable.setSpan(
ForegroundColorSpan(color),

View File

@ -18,8 +18,9 @@ package im.vector.riotx.features.home.room.list

import im.vector.matrix.android.api.session.room.model.RoomSummary
import io.reactivex.functions.Predicate
import javax.inject.Inject

class RoomListNameFilter : Predicate<RoomSummary> {
class RoomListNameFilter @Inject constructor() : Predicate<RoomSummary> {

var filter: String = ""


View File

@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.list

import androidx.annotation.StringRes
import com.airbnb.epoxy.TypedEpoxyController
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.features.home.room.filtered.FilteredRoomFooterItem
@ -25,13 +26,12 @@ import im.vector.riotx.features.home.room.filtered.filteredRoomFooterItem
import javax.inject.Inject

class RoomSummaryController @Inject constructor(private val stringProvider: StringProvider,
private val roomSummaryItemFactory: RoomSummaryItemFactory
private val roomSummaryItemFactory: RoomSummaryItemFactory,
private val roomListNameFilter: RoomListNameFilter
) : TypedEpoxyController<RoomListViewState>() {

var listener: Listener? = null

private val roomListNameFilter = RoomListNameFilter()

override fun buildModels(viewState: RoomListViewState) {
if (viewState.displayMode == RoomListFragment.DisplayMode.FILTERED) {
buildFilteredRooms(viewState)
@ -62,7 +62,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri

roomListNameFilter.filter = viewState.roomFilter

val filteredSummaries = summaries.filter { roomListNameFilter.test(it) }
val filteredSummaries = summaries
.filter { it.membership == Membership.JOIN && roomListNameFilter.test(it) }

buildRoomModels(filteredSummaries,
viewState.joiningRoomsIds,

View File

@ -56,6 +56,10 @@ class PushRuleTriggerListener @Inject constructor(
}
}

override fun onRoomLeft(roomId: String) {
notificationDrawerManager.clearMessageEventOfRoom(roomId)
}

override fun batchFinish() {
notificationDrawerManager.refreshNotificationDrawer()
}

View File

@ -17,7 +17,6 @@ package im.vector.riotx.features.settings

import android.content.Context
import android.content.Intent
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
@ -75,32 +74,30 @@ class VectorSettingsActivity : VectorBaseActivity(),
}
}

override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat?, pref: Preference?): Boolean {
var oFragment: Fragment? = null

if (VectorPreferences.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref?.key) {
oFragment = VectorSettingsNotificationsTroubleshootFragment.newInstance(session.myUserId)
} else if (VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref?.key) {
oFragment = VectorSettingsAdvancedNotificationPreferenceFragment.newInstance(session.myUserId)
} else {
try {
pref?.fragment?.let {
oFragment = supportFragmentManager.fragmentFactory
.instantiate(classLoader, it)
override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
val oFragment = when {
VectorPreferences.SETTINGS_NOTIFICATION_TROUBLESHOOT_PREFERENCE_KEY == pref.key ->
VectorSettingsNotificationsTroubleshootFragment.newInstance(session.myUserId)
VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY == pref.key ->
VectorSettingsAdvancedNotificationPreferenceFragment.newInstance(session.myUserId)
else ->
try {
pref.fragment?.let {
supportFragmentManager.fragmentFactory.instantiate(classLoader, it)
}
} catch (e: Throwable) {
showSnackbar(getString(R.string.not_implemented))
Timber.e(e)
null
}
} catch (e: Throwable) {
showSnackbar(getString(R.string.not_implemented))
Timber.e(e)
}
}

if (oFragment != null) {
oFragment!!.setTargetFragment(caller, 0)
oFragment.setTargetFragment(caller, 0)
// Replace the existing Fragment with the new Fragment
supportFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.right_in, R.anim.fade_out,
R.anim.fade_in, R.anim.right_out)
.replace(R.id.vector_settings_page, oFragment!!, pref?.title.toString())
.setCustomAnimations(R.anim.right_in, R.anim.fade_out, R.anim.fade_in, R.anim.right_out)
.replace(R.id.vector_settings_page, oFragment, pref.title.toString())
.addToBackStack(null)
.commit()
return true

View File

@ -9,8 +9,10 @@
android:layout_height="match_parent"
android:orientation="vertical">

<!-- Use VectorToolbarStyleWithPadding on this screen for better alignment with setting items -->
<androidx.appcompat.widget.Toolbar
android:id="@+id/settingsToolbar"
style="@style/VectorToolbarStyleWithPadding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp" />
@ -19,7 +21,7 @@
android:id="@+id/vector_settings_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground" />
android:background="?riotx_background" />

</LinearLayout>


View File

@ -1515,4 +1515,57 @@
<string name="keys_backup_unable_to_get_trust_info">Случи се грешка при извличане на информацията за довереността</string>
<string name="keys_backup_unable_to_get_keys_backup_data">Случи се грешка при извличане на резервните данни за ключовете</string>

<string name="alpha_disclaimer_title">Добре дошли в beta версията!</string>
<string name="alpha_disclaimer_content_line_1">Докато RiotX е в ранен стадий на разработка някои функции може да липсват или да има бъгове.</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">Play Store описание</string>
<string name="alpha_disclaimer_content_line_2_fdroid">Ако намерите бъгове, моля докладвайте ги от най-горното ляво меню на началния екран и ще ги разрешим възможно най-бързо.</string>

<string name="import_e2e_keys_from_file">Импортирай e2e ключове от файл \"%1$s\".</string>

<string name="settings_sdk_version">Matrix SDK версия</string>
<string name="navigate_to_room_when_already_in_the_room">Вече гледате тази стая!</string>

<string name="quick_reactions">Бързи реакции</string>

<string name="settings_general_title">Основни</string>
<string name="settings_preferences">Настройки</string>
<string name="settings_security_and_privacy">Сигурност и поверителност</string>
<string name="settings_expert">Експертни</string>
<string name="settings_push_rules">Правила за уведомление</string>
<string name="settings_push_rules_no_rules">Не са дефинирани правила за уведомление</string>
<string name="alpha_disclaimer_content_line_2_gplay">Списъкът с последни функции винаги е в %1$s. Ако намерите бъг, изпратете доклад за грешка от менюто горе в ляво, и ще го поправим възможно най-скоро.</string>
<string name="settings_other_third_party_notices">Други известия</string>
<string name="settings_push_gateway_no_pushers">Не са регистрирани адреси за push уведомления</string>

<string name="push_gateway_item_app_id">app_id:</string>
<string name="push_gateway_item_push_key">push_key:</string>
<string name="push_gateway_item_app_display_name">app_display_name:</string>
<string name="push_gateway_item_device_name">device_name:</string>
<string name="push_gateway_item_url">Адрес:</string>
<string name="push_gateway_item_format">Формат:</string>

<string name="preference_voice_and_video">Глас и Видео</string>
<string name="preference_root_help_about">Помощ и Относно</string>


<string name="settings_troubleshoot_test_token_registration_quick_fix">Регистрирай токен</string>

<string name="send_suggestion">Направи предложение</string>
<string name="send_suggestion_content">Напишете предложението си долу.</string>
<string name="send_suggestion_report_placeholder">Опишете предложението тук</string>
<string name="send_suggestion_sent">Благодаря! Предложението ви беше изпратено</string>
<string name="send_suggestion_failed">Предложението не беше изпратено (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">Показвай скрити събития в чата</string>

<string name="store_riotx_title">RiotX - следващо поколение Matrix клиент</string>
<string name="store_riotx_short_description">По-бърз и по-лек Matrix клиент, използващ последните Android технологии</string>
<string name="store_riotx_full_description">RiotX в нов клиент за Matrix протокола (Matrix.org): отворена мрежа за сигурна, децентрализирана комуникация. RiotX е изцяло пренаписан Riot Android клиент, базиран на изцяло пренаписан Matrix Android SDK.
\n
\nЗабележка: Това е бета версия. RiotX в момента се разработва активно и все още има ограничения и (надяваме се не прекалено много) бъгове. Всякаква обратна връзка е добре дошла!
\n
\nRiotX поддържа: • Вход в съществуващ акаунт • Създаване на стая и влизане в публични стаи • Приемане и отхвърляне на покани • Показване на списък със стаите • Преглеждане на информация за стая • Изпращане на текстови съобщения • Изпращане на прикачени файлове • Четене и писане на съобщения в шифровани стаи • Шифроване: резервни копия на E2E ключове, потвърждение на устройства, заявяване и отговаряне на заявки за споделяне на ключове • Уведомления • Светла, Тъмна и Черна тема
\n
\nЗасега не всички функции на Riot са налични в RiotX. Основни липсващи (и скоро пристигащи!) функции са: • Създаване на нов профил • Настройки на стаи (показване на членове и т.н.) • Създаване на директни чатове • Обаждания • Приспособления • …</string>

</resources>

View File

@ -1476,7 +1476,7 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
<string name="send_you_invite">Gonbidapen bat bidali dizu</string>
<string name="invited_by">%s erabiltzaileak gonbidatuta</string>

<string name="room_list_catchup_empty_title">Arrapatu zaituztete!</string>
<string name="room_list_catchup_empty_title">Egunean zaude!</string>
<string name="room_list_catchup_empty_body">Ez duzu irakurri gabeko mezu gehiagorik</string>
<string name="room_list_catchup_welcome_title">Ongi etorri etxera!</string>
<string name="room_list_catchup_welcome_body">Jarri egunean hemengo irakurri gabeko mezuekin</string>
@ -1522,4 +1522,57 @@ Abisua: Fitxategi hau ezabatu daiteke aplikazioa desinstalatzen bada.</string>
<string name="keys_backup_unable_to_get_trust_info">Errore bat gertatu da konfiantzazko informazioa jasotzean</string>
<string name="keys_backup_unable_to_get_keys_backup_data">Errore bat gertatu da gakoen babes-kopiaren datuak jasotzean</string>

<string name="alpha_disclaimer_title">Ongi etorri betara!</string>
<string name="alpha_disclaimer_content_line_1">RiotX oraindik garapenean dagoenez, ezaugarri batzuk faltan bota ditzakezu eta akatsen bat aurkitu dezakezu.</string>
<string name="alpha_disclaimer_content_line_2_gplay">Azken ezaugarrien zerrenda hemen dago beti : %1$s, eta akatsak aurkitzen badituzu bidali mesedez akatsen txosten bat Hasiera pantailako goi ezkerreko menua erabiliz, eta ahalik eta lasterren konponduko dugu.</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">Play Store-ko deskripzioa</string>
<string name="alpha_disclaimer_content_line_2_fdroid">Akatsak aurkitzen badituzu bidali mesedez akatsen txosten bat Hasiera pantailako goi ezkerreko menua erabiliz, eta ahalik eta lasterren konponduko dugu.</string>

<string name="import_e2e_keys_from_file">"Inportatu e2e gakoak \"%1$s\" fitxategitik."</string>

<string name="settings_sdk_version">Matrix SDK bertsioa</string>
<string name="settings_other_third_party_notices">Beste hirugarrengoen adierazpenak</string>
<string name="navigate_to_room_when_already_in_the_room">Gela hau ikusten ari zara dagoeneko!</string>

<string name="quick_reactions">Erreakzio azkarrak</string>

<string name="settings_general_title">Orokorra</string>
<string name="settings_preferences">Hobespenak</string>
<string name="settings_security_and_privacy">Segurtasuna eta pribatutasuna</string>
<string name="settings_expert">Aditua</string>
<string name="settings_push_rules">Push arauak</string>
<string name="settings_push_rules_no_rules">Ez da push araurik zehaztu</string>
<string name="settings_push_gateway_no_pushers">Ez dago push arauentzako erregistratutako atebiderik</string>

<string name="push_gateway_item_app_id">app_id:</string>
<string name="push_gateway_item_push_key">push_gakoa:</string>
<string name="push_gateway_item_device_name">gailu_izena:</string>
<string name="push_gateway_item_url">Url-a:</string>
<string name="push_gateway_item_format">Formatua:</string>

<string name="preference_voice_and_video">Ahotsa eta bideoa</string>
<string name="preference_root_help_about">Laguntza eta honi buruz</string>


<string name="settings_troubleshoot_test_token_registration_quick_fix">Erregistratu token-a</string>

<string name="send_suggestion">Egin iradokizun bat</string>
<string name="send_suggestion_content">Idatzi zure iradokizuna azpian.</string>
<string name="send_suggestion_report_placeholder">Deskribatu zure iradokizuna hemen</string>
<string name="send_suggestion_sent">Eskerrik asko, iradokizuna ongi bidali da</string>
<string name="send_suggestion_failed">Huts egin su iradokizuna bidaltzean (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">Erakutsi ezkutatutako gertaerak denbora lerroan</string>

<string name="store_riotx_title">RiotX - Hurrengo belaunaldiko Matrix bezeroa</string>
<string name="store_riotx_short_description">Matrix-erako bezero azkarrago eta arinago bat azken Android tresnak erabiliz eginak</string>
<string name="store_riotx_full_description">RiotX bezero berri bat da Matrix protokoloarentzako (Matrix.org): komunikazioa seguru eta deszentralizatuarentzako sare libre bat. RiotX Android plataformarako Riot bezeroaren berridazketa oso bat da, erabat berridatzitako Android SDK-n oinarritua.
\n
\nAbisua: hau beta bertsio bat da. RiotX garapen aktiboan dago eta baditu mugak zein akatsak (gehiegi ez espero dugu). Iruzkin guztiak ongi etorriak dira!
\n
\nRiotX bezeroak honakoa ahalbidetzen du: • Badagoen kontu batean saioa hasi • Gelak sortu eta gela publikoetara elkartu • Gonbidapenak onartu edo ukatu • Erabiltzailearen gelak zerrendatu • Gelaren xehetasunak ikusi • Testuzko mezuak bidali • Eranskinak bidali • Zifratutako geletan mezuak irakurri eta idatzi • Zifratzea: E2Egakoen babeskopia, gailuaren egiaztaketa aurreratua, gakoa partekatzeko eskaria eta erantzuna • Push jakinarazpena • Gai argia, iluna eta beltza
\n
\nEz dira oraindik Riot bezeroaren ezaugarri guztiak ezarri RiotX bezeroan. Falta diren (eta laster etorriko direnen) artean nabarmenak dira: • Kontua sortzea • Gelaren ezarpenak (gelako kideak zerrendatzea, eta abar.) • Txat zuzenerako gelak sortzea • Deiak • Trepetak • …</string>

<string name="push_gateway_item_app_display_name">app_display_name:</string>
</resources>

View File

@ -768,10 +768,10 @@

<!-- conference call -->
<string name="conference_call_warning_title">Varoitus!</string>
<string name="conference_call_warning_message">Konferenssipuhelu on yhtä kehitysvaiheessa eikä välttämättä ole luotettava.</string>
<string name="conference_call_warning_message">Konferenssipuhelut ovat kehitysvaiheessa eivätkä välttämättä luotettavia.</string>

<!-- slash commands -->
<string name="command_error">Virheellinen komento</string>
<string name="command_error">Komentovirhe</string>
<string name="unrecognized_command">Tuntematon komento: %s</string>

<!-- notification statuses -->
@ -1166,7 +1166,7 @@ Haluatko lisätä paketteja?</string>
<string name="settings_labs_keyboard_options_to_send_message">Käytä näppäimistön rivinvaihtopainiketta viestin lähettämiseen</string>
<string name="settings_labs_enable_send_voice_summary">Tämä vaihtoehto vaatii kolmannen osapuolen sovelluksen viestien tallennukseen.</string>

<string name="command_problem_with_parameters">Komento ”%s” vaatii enemmän parametreja, tai jotkinparametrit ovat väärin.</string>
<string name="command_problem_with_parameters">Komento ”%s” vaatii enemmän parametreja, tai jotkin parametrit ovat virheellisiä.</string>
<string name="command_description_emote">Näyttää toiminnon</string>
<string name="command_description_ban_user">Estää käyttäjän annetulla id:llä</string>
<string name="command_description_unban_user">Sallii käyttäjän annetulla id:llä</string>
@ -1520,4 +1520,17 @@ Jotta et menetä mitään, automaattiset päivitykset kannattaa pitää käytös
<string name="keys_backup_unable_to_get_trust_info">Luottamustietoa haettaessa tapahtui virhe</string>
<string name="keys_backup_unable_to_get_keys_backup_data">Avainten varmuuskopioinnin tietoja haettaessa tapahtui virhe</string>

<string name="your_unverified_device_requesting_with_info">Tuntematon laite pyytää salausavaimia
\nLaitteen nimi: %1$s
\nViimeksi nähty: %2$s
\nJos et kirjautunut toisella laitteella, voit jättää tämän pyynnön huomiotta.</string>

<string name="alpha_disclaimer_title">Tervetuloa beetaan!</string>
<string name="alpha_disclaimer_content_line_1">RiotX on varhaisessa kehitysvaiheessa, mistä johtuen osa ominaisuuksista puuttuu ja saatat kohdata virheitä.</string>
<string name="settings_sdk_version">Matrix SDK:n versio</string>
<string name="settings_other_third_party_notices">Muut kolmansien osapuolten huomautukset</string>
<string name="quick_reactions">Pikareaktiot</string>

<string name="settings_preferences">Asetukset</string>
<string name="settings_security_and_privacy">Tietoturva ja yksityisyys</string>
</resources>

View File

@ -1527,4 +1527,57 @@ Si vous navez pas configuré de nouvelle méthode de récupération, un attaq
<string name="keys_backup_unable_to_get_trust_info">Une erreur est survenue lors de la récupération des informations de confiance</string>
<string name="keys_backup_unable_to_get_keys_backup_data">Une erreur est survenue lors de la récupération des données de sauvegarde de clés</string>

<string name="alpha_disclaimer_title">Bienvenue à la bêta !</string>
<string name="alpha_disclaimer_content_line_1">Comme RiotX est au début de son développement, il se peut que certaines fonctionnalités soient manquantes et que vous rencontriez quelques anomalies.</string>
<string name="alpha_disclaimer_content_line_2_gplay">La dernière liste de fonctionnalités est toujours dans la %1$s, et si vous rencontrez des anomalies, envoyez un rapport dans le menu en haut à gauche de laccueil et nous les règlerons aussi vite que possible.</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">description du Play Store</string>
<string name="alpha_disclaimer_content_line_2_fdroid">Si vous rencontrez des anomalies, envoyez un rapport dans le menu en haut à gauche de laccueil et nous les règlerons aussi vite que possible.</string>

<string name="import_e2e_keys_from_file">Importer les clés de chiffrement depuis le fichier « %1$s ».</string>

<string name="settings_sdk_version">Version du SDK de Matrix</string>
<string name="settings_other_third_party_notices">Licences tierces</string>
<string name="navigate_to_room_when_already_in_the_room">Vous êtes déjà en train de visualiser ce salon !</string>

<string name="quick_reactions">Réactions rapides</string>

<string name="settings_general_title">Général</string>
<string name="settings_preferences">Préférences</string>
<string name="settings_security_and_privacy">Sécurité &amp; vie privée</string>
<string name="settings_expert">Expert</string>
<string name="settings_push_rules">Règles de notification</string>
<string name="settings_push_rules_no_rules">Aucune règle de notification définie</string>
<string name="settings_push_gateway_no_pushers">Aucune passerelle de notification enregistrée</string>

<string name="push_gateway_item_app_id">app_id :</string>
<string name="push_gateway_item_push_key">push_key :</string>
<string name="push_gateway_item_app_display_name">app_display_name :</string>
<string name="push_gateway_item_device_name">device_name :</string>
<string name="push_gateway_item_url">URL :</string>
<string name="push_gateway_item_format">Format :</string>

<string name="preference_voice_and_video">Voix &amp; vidéo</string>
<string name="preference_root_help_about">Aide &amp; à propos</string>


<string name="settings_troubleshoot_test_token_registration_quick_fix">Inscrire le jeton</string>

<string name="send_suggestion">Faire une suggestion</string>
<string name="send_suggestion_content">Saisissez votre suggestion ci-dessous.</string>
<string name="send_suggestion_report_placeholder">Décrivez votre suggestion ici</string>
<string name="send_suggestion_sent">Merci, la suggestion a bien été envoyée</string>
<string name="send_suggestion_failed">Échec denvoi de la suggestion (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">Afficher les évènements cachés dans lhistorique</string>

<string name="store_riotx_title">RiotX Client Matrix nouvelle génération</string>
<string name="store_riotx_short_description">Un client pour Matrix plus rapide et plus léger utilisant les derniers frameworks Android</string>
<string name="store_riotx_full_description">RiotX est un nouveau client pour le protocole Matrix (Matrix.org) : un réseau ouvert pour des communications sécurisées et décentralisées. RiotX est une réécriture complète du client Android Riot, basée sur une réécriture complète du SDK Android de Matrix.
\n
\nMise en garde : Ceci est une version bêta. RiotX est actuellement en plein développement et a des limites et (peu, nous lespérons) des anomalies. Tout commentaire est le bienvenu !
\n
\nRiotX prend en charge : • Se connecter à un compte existant • Créer de salons et rejoindre des salons publics • Accepter et refuser des invitations • Lister les salons des utilisateurs • Voir les informations des salons • Envoyer des messages texte • Envoyer des pièces jointes • Lire et écrire des messages dans les salons chiffrés • Chiffrement : sauvegarde des clés de chiffrement, vérification avancée des appareils, demande et réponse de partage de clé • Notifications • Thèmes clair, sombre et noir
\n
\nToutes les fonctionnalités de Riot ne sont pas encore implémentées dans RiotX. Principales fonctionnalités manquantes (et qui arrivent bientôt !) : • Création de compte • Réglages des salons (lister les membres du salon etc.) • Création de salons de discussion directe • Appels • Widgets • …</string>

</resources>

View File

@ -1526,4 +1526,57 @@ Ha nem te állítottad be a visszaállítási metódust, akkor egy támadó pró
<string name="keys_backup_unable_to_get_trust_info">A megbízhatósági információ beszerzésekor hiba történt</string>
<string name="keys_backup_unable_to_get_keys_backup_data">A kulcs mentés adatainak beszerzésekor hiba történt</string>

<string name="alpha_disclaimer_title">Üdv a béta verzióban!</string>
<string name="alpha_disclaimer_content_line_1">Amíg a RiotX újdonsült fejlesztés, néhány funkció hiányozhat és találkozhatsz hibákkal.</string>
<string name="alpha_disclaimer_content_line_2_gplay">A legfrissebb funkciók listáját itt találod: %1$s, és ha hibát találsz kérlek küldj egy jelentést róla a Kezdő oldal bal felső sarkában lévő menüvel és ahogy tudjuk javítjuk.</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">Play áruház leírás</string>
<string name="alpha_disclaimer_content_line_2_fdroid">Ha hibát találsz kérlek küldj egy jelentést róla a Kezdő oldal bal felső sarkában lévő menüvel és ahogy tudjuk javítjuk.</string>

<string name="import_e2e_keys_from_file">Végponttól végpontig titkosítás kulcsainak betöltése ebből a fájlból: \"%1$s\".</string>

<string name="settings_sdk_version">Matrix SDK Verzió</string>
<string name="settings_other_third_party_notices">Harmadik fél megjegyzések</string>
<string name="navigate_to_room_when_already_in_the_room">Már nézed ezt a szobát!</string>

<string name="quick_reactions">Gyors Reakció</string>

<string name="settings_general_title">Általános</string>
<string name="settings_preferences">Beállítások</string>
<string name="settings_security_and_privacy">Biztonság &amp; Adatvédelem</string>
<string name="settings_expert">Haladó</string>
<string name="settings_push_rules">„Push” szabályok</string>
<string name="settings_push_rules_no_rules">„Push” szabályok nincsenek</string>
<string name="settings_push_gateway_no_pushers">„Push” átjárók nincsenek regisztrálva</string>

<string name="push_gateway_item_app_id">app_id:</string>
<string name="push_gateway_item_push_key">push_key:</string>
<string name="push_gateway_item_app_display_name">app_display_name:</string>
<string name="push_gateway_item_device_name">device_name:</string>
<string name="push_gateway_item_url">Url:</string>
<string name="push_gateway_item_format">Formátum:</string>

<string name="preference_voice_and_video">Hang &amp; Videó</string>
<string name="preference_root_help_about">Segítség &amp; Névjegy</string>


<string name="settings_troubleshoot_test_token_registration_quick_fix">„Token” regisztrálás</string>

<string name="send_suggestion">Javaslat tétel</string>
<string name="send_suggestion_content">A javaslatodat kérlek ír le alulra.</string>
<string name="send_suggestion_report_placeholder">Ír le a javaslatodat ide</string>
<string name="send_suggestion_sent">Köszönjük, a javaslatodat sikeresen elküldtük</string>
<string name="send_suggestion_failed">A javaslatot nem sikerült elküldeni (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">Rejtett események megjelenítése az idővonalon</string>

<string name="store_riotx_title">RiotX - Matrix Kliens Új Nemzedéke</string>
<string name="store_riotx_short_description">A gyorsabb és kisebb Matrix kliens ami a legfrissebb Android keretrendszert használja</string>
<string name="store_riotx_full_description">RiotX a Matrix protokollhoz (Matrix.org) készült új kliens: nyílt hálózat biztonságos és decentralizált kommunikációhoz. RiotX a Riot Android kliens teljesen újraírt változata ami a teljesen újraírt Matrix Android SDK-ra épül.
\n
\nFigyelmeztetés: Ez egy béta verzió. RiotX aktív fejlesztés alatt áll és vannak korlátai és (reméljük nem olyan sok) hibái. Minden visszajelzést szívesen fogadunk!
\n
\nRiotX ezeket támogatja: • Bejelentkezés létező fiókba • Szoba készítés és nyilvános szobába való belépés • Meghívók fogadása és elutasítás • Felhasználók szobáinak listázása • Szoba adatainak megtekintése • Szöveges üzenet küldése • Csatolmány küldése • Titkosított szobákban üzenetek olvasása és írása • Titkosítás: Végponttól végpontig titkosító kulcsok mentése, fejlett eszköz ellenőrzés, kulcs megosztás kérése és válasz • „Push” értesítések • Világos, sötét és fekete téma
\n
\nNem minden Riot funkció támogatott a RiotX-ben jelenleg. A fő hiányzó (és hamarosan elérhető!) funkciók: • Felhasználói fiók létrehozása • Szoba beállítások (szoba tagság mutatása, stb…) • Közvetlen beszélgetések indítása • Hívások • Kisalkalmazások • …</string>

</resources>

View File

@ -1570,4 +1570,57 @@ Per essere certo di non perdere nulla, mantieni gli aggiornamenti attivi."</stri
<string name="keys_backup_unable_to_get_trust_info">Si è verificato un errore nell\'ottenere informazioni sulla fiducia</string>
<string name="keys_backup_unable_to_get_keys_backup_data">Si è verificato un errore nell\'ottenere i dati del backup chiavi</string>

<string name="alpha_disclaimer_title">Benvenuti nella beta!</string>
<string name="alpha_disclaimer_content_line_1">Mentre RiotX si trova nella fase iniziale dello sviluppo, potrebbero mancare alcune funzioni e potrebbero verificarsi errori.</string>
<string name="alpha_disclaimer_content_line_2_gplay">L\'elenco di funzioni più recenti è sempre nel %1$s, se trovi errori ti preghiamo segnalarli nel menu in alto a sinistra della Pagina Iniziale e noi li correggeremo appena possibile.</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">Descrizione nel Play Store</string>
<string name="alpha_disclaimer_content_line_2_fdroid">Se trovi errori ti preghiamo segnalarli nel menu in alto a sinistra della Pagina Iniziale e noi li correggeremo appena possibile.</string>

<string name="import_e2e_keys_from_file">Importa chiavi e2e dal file \"%1$s\".</string>

<string name="settings_sdk_version">Versione SDK Matrix</string>
<string name="settings_other_third_party_notices">Altre note di terze parti</string>
<string name="navigate_to_room_when_already_in_the_room">Stai già visualizzando questa stanza!</string>

<string name="quick_reactions">Reazioni rapide</string>

<string name="settings_general_title">Generali</string>
<string name="settings_preferences">Preferenze</string>
<string name="settings_security_and_privacy">Sicurezza e privacy</string>
<string name="settings_expert">Esperto</string>
<string name="settings_push_rules">Regole di push</string>
<string name="settings_push_rules_no_rules">Nessuna regola di push definita</string>
<string name="settings_push_gateway_no_pushers">Nessun gateway di push registrato</string>

<string name="push_gateway_item_app_id">id_app:</string>
<string name="push_gateway_item_push_key">chiave_push:</string>
<string name="push_gateway_item_app_display_name">nome_visualizzato_app:</string>
<string name="push_gateway_item_device_name">nome_dispositivo:</string>
<string name="push_gateway_item_url">Url:</string>
<string name="push_gateway_item_format">Formato:</string>

<string name="preference_voice_and_video">Voce e video</string>
<string name="preference_root_help_about">Aiuto e informazioni</string>


<string name="settings_troubleshoot_test_token_registration_quick_fix">Registra token</string>

<string name="send_suggestion">Suggerisci qualcosa</string>
<string name="send_suggestion_content">Scrivi qua sotto il tuo suggerimento.</string>
<string name="send_suggestion_report_placeholder">Descrivi qui il tuo suggerimento</string>
<string name="send_suggestion_sent">Grazie, il suggerimento è stato inviato correttamente</string>
<string name="send_suggestion_failed">L\'invio del suggerimento è fallito (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">Mostra eventi nascosti nella cronologia</string>

<string name="store_riotx_title">RiotX - Client Matrix di nuova generazione</string>
<string name="store_riotx_short_description">Un client per Matrix più veloce e leggero usando gli ultimi framework di Android</string>
<string name="store_riotx_full_description">RiotX è un nuovo client per il protocollo Matrix (Matrix.org): una rete aperta per comunicazioni sicure e decentralizzate. RiotX è una riscrittura totale del client Riot Android, basata su una riscrittura completa dell\'SDK Android di Matrix.
\n
\nDisclaimer: questa è una versione beta. RiotX è attualmente in uno sviluppo attivo e contiene limitazioni ed errori (speriamo non troppi). I suggerimenti sono ben accetti!
\n
\nRiotX supporta: • Accesso ad account esistente • Crea stanze ed entra in stanze pubbliche • Accetta e rifiuta inviti • Elenca stanze utenti • Vedi dettagli stanza • Invia messaggi di testo • Invia allegati • Leggi e scrivi messaggi in stanze cifrate • Crypto: backup chiavi E2E, verifica avanzata dispositivi, richiesta e risposta condivisione chiavi • Notifiche push • Tema chiaro, scuro e nero
\n
\nNon tutte le funzioni di Riot sono già implementate in RiotX. Principali funzioni mancanti (prossimamente!): • Creazione account • Impostazioni stanza (elenca membri stanza, ecc.) • Creazione di stanze di chat diretta • Chiamate • Widget • …</string>

</resources>

View File

@ -7,7 +7,7 @@
<string name="dark_theme">어두운 테마</string>
<string name="black_them">검정 테마</string>

<string name="notification_sync_in_progress">동기화</string>
<string name="notification_sync_in_progress">동기화하는중…</string>
<string name="title_activity_home">메시지</string>
<string name="title_activity_room">방</string>
<string name="title_activity_settings">설정</string>
@ -26,7 +26,7 @@
<string name="send">보내기</string>
<string name="copy">복사</string>
<string name="resend">다시 보내기</string>
<string name="redact">삭제하기</string>
<string name="redact">지우기</string>
<string name="quote">인용</string>
<string name="download">받기</string>
<string name="share">공유</string>
@ -38,7 +38,7 @@
<string name="report_content">컨텐츠 신고</string>
<string name="ongoing_conference_call_voice">음성</string>
<string name="ongoing_conference_call_video">영상</string>
<string name="cannot_start_call">전화를 걸 수 없습니다, 나중에 다시 시도해주세요.</string>
<string name="cannot_start_call">전화를 걸 수 없습니다, 나중에 다시 시도해주세요</string>
<string name="missing_permissions_warning">권한이 없어졌기 때문에, 일부 기능이 빠졌을 수 있습니다…</string>
<string name="missing_permissions_error">권한이 없어졌기 때문에, 이 행동을 할 수 없습니다.</string>
<string name="missing_permissions_title_to_start_conf_call">전화를 걸 수 없습니다</string>
@ -80,13 +80,13 @@
<string name="send_bug_report_include_logs">로그 보내기</string>
<string name="send_bug_report_include_crash_logs">충돌 로그 보내기</string>
<string name="send_bug_report_include_screenshot">스크린샷 보내기</string>
<string name="send_bug_report">버그 보고서</string>
<string name="send_bug_report">버그 보고하기</string>
<string name="send_bug_report_description">버그에 대해 설명해주세요. 무엇을 했나요? 어떤 일이 일어나길 바라고 한 건가요? 실제로는 어떤 일이 일어났나요?</string>
<string name="send_bug_report_description_in_english">가능하다면, 영어로 설명해주세요.</string>
<string name="send_bug_report_placeholder">여기에 문제를 설명해주세요</string>
<string name="send_bug_report_sent">버그 보고서를 보내는데 성공했습니다</string>
<string name="send_bug_report_failed">버그 보고서를 보내는데 실패했습니다 (%s)</string>
<string name="create_account">등록하기</string>
<string name="create_account">계정 만들기</string>
<string name="login">로그인</string>
<string name="logout">로그아웃</string>
<string name="hs_url">홈서버 URL</string>
@ -108,7 +108,7 @@
<string name="option_take_video">영상 찍기</string>

<string name="auth_login">로그인</string>
<string name="auth_register">등록하기</string>
<string name="auth_register">계정 만들기</string>
<string name="auth_submit">제출하기</string>
<string name="auth_skip">건너뛰기</string>
<string name="auth_user_id_placeholder">이메일이나 이용자 이름</string>
@ -117,4 +117,65 @@
<string name="auth_user_name_placeholder">이용자 이름</string>
<string name="auth_add_email_message">이용자가 당신을 찾고 재설정 비밀번호를 보낼 수 있게 이메일 주소를 적어주세요.</string>
<string name="auth_add_phone_message">이용자가 당신을 찾을 수 있게 계정에 전화번호를 추가해주세요.</string>
<string name="status_theme">Status.im 테마</string>

<string name="notification_sync_init">서비스 초기화 중</string>
<string name="notification_noisy_notifications">소리로 알림</string>
<string name="notification_silent_notifications">소리 없이 알림</string>

<string name="title_activity_member_details">구성원 정보</string>
<string name="title_activity_group_details">커뮤니티 정보</string>
<string name="title_activity_keys_backup_setup">키 백업</string>
<string name="title_activity_keys_backup_restore">키 백업하기</string>
<string name="title_activity_verify_device">인증 기기</string>

<string name="keys_backup_is_not_finished_please_wait">키 백업이 끝나지 않았습니다, 기다려주세요…</string>
<string name="sign_out_bottom_sheet_warning_no_backup">지금 로그아웃하면 암호화된 메세지가 사라집니다</string>
<string name="keys_backup_activate">키 백업하기</string>
<string name="are_you_sure">정말이세요\?</string>
<string name="backup">백업</string>
<string name="stay">머물기</string>
<string name="skip">넘기기</string>
<string name="done">완료</string>
<string name="action_sign_out_confirmation_simple">정말 로그아웃하시겠어요\?</string>
<string name="action_mark_room_read">읽었다고 표시</string>
<string name="no_contact_access_placeholder">Riot이 주소록에 접근할 수 없게 되어 있습니다</string>
<plurals name="public_room_nb_users">
<item quantity="other">%d 사람들</item>
</plurals>

<string name="groups_invite_header">초대</string>
<string name="groups_header">커뮤니티</string>
<string name="send_bug_report_app_crashed">최근에 애플리케이션이 충돌한 것 같습니다. 충돌 보고서를 열까요\?</string>
<string name="read_receipt">읽기</string>

<string name="username">사용자 이름</string>
<string name="option_send_voice">음성 보내기</string>

<string name="no_sticker_application_dialog_content">스티커팩이 하나도 없습니다.
\n
\n뭐라도 추가할까요\?</string>

<string name="auth_return_to_login">로그인 화면으로 돌아가기</string>
<string name="auth_email_placeholder">이메일 주소</string>
<string name="auth_opt_email_placeholder">이메일 주소 (선택)</string>
<string name="auth_phone_number_placeholder">전화번호</string>
<string name="auth_opt_phone_number_placeholder">전화번호 (선택)</string>
<string name="auth_repeat_password_placeholder">비밀번호 확인</string>
<string name="auth_repeat_new_password_placeholder">새 비밀번호 확인</string>
<string name="auth_invalid_login_param">알맞지 않은 사용자 이름이나 비밀번호</string>
<string name="auth_invalid_password">비밀번호가 너무 짧아요 (최소 6자)</string>
<string name="auth_invalid_email">유효한 이메일 주소가 아닌 것 같아요</string>
<string name="auth_invalid_phone">유효한 전화번호가 아닌 것 같아요</string>
<string name="auth_password_dont_match">비밀번호가 맞지 않아요</string>
<string name="auth_forgot_password">비밀번호를 잊어버리셨나요\?</string>
<string name="auth_username_in_use">사용중인 사용자 이름입니다</string>
<string name="auth_home_server">홈서버:</string>
<string name="auth_reset_password_message">비밀번호를 초기화하려면, 계정에 이메일을 등록해야합니다:</string>
<string name="auth_reset_password_missing_password">새 비밀번호를 입력해야합니다.</string>
<string name="auth_reset_password_success_message">비밀번호가 초기화되었습니다.
\n
\n모든 기기에서 로그아웃되고 알림도 가지 않을 거에요. 다시 알림을 받으려면, 각 기기에 다시 로그인하세요.</string>
<string name="login_mobile_device">모바일</string>

</resources>

View File

@ -1484,4 +1484,51 @@ Që të garantoni se sju shpëton gjë, thjesht mbajeni të aktivizuar mekani
<string name="keys_backup_unable_to_get_trust_info">Ndodhi një gabim gjatë marrjes së të dhënave të besueshmërisë</string>
<string name="keys_backup_unable_to_get_keys_backup_data">Ndodhi një gabim teksa merreshin të dhëna kopjeruajtjeje kyçesh</string>

<string name="alpha_disclaimer_title">Mirë se vini në beta!</string>
<string name="alpha_disclaimer_content_line_1">Teksa RiotX është në fillimet e zhvillimit, disa veçori mund të mos jenë gati dhe mund të hasni të meta.</string>
<string name="alpha_disclaimer_content_line_2_gplay">Lista e veçorive më të reja gjendet te %1$s, dhe nëse gjeni të meta, ju lutemi, parashtroni një njoftim te menuja majtas sipër te Home, dhe do ti ndreqim sa më shpejt të mundemi.</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">Përshkrim në Play Store</string>
<string name="alpha_disclaimer_content_line_2_fdroid">Nëse gjeni të meta, ju lutemi, parashtroni një njoftim te menuja majtas sipër te Home, dhe do ti ndreqim sa më shpejt të mundemi.</string>

<string name="import_e2e_keys_from_file">Importo kyçe e2e prej kartelës \"%1$s\".</string>

<string name="settings_sdk_version">Versioni Matrix SDK</string>
<string name="settings_other_third_party_notices">Shënime të tjera palësh të treta</string>
<string name="navigate_to_room_when_already_in_the_room">Po e shihni tashmë këtë dhomë!</string>

<string name="quick_reactions">Reagime të Shpejta</string>

<string name="settings_general_title">Të përgjithshme</string>
<string name="settings_preferences">Parapëlqime</string>
<string name="settings_security_and_privacy">Siguri &amp; Privatësi</string>
<string name="settings_expert">Ekspert</string>
<string name="settings_push_rules">Rregulla për Push</string>
<string name="settings_push_rules_no_rules">Ska të përcaktuara rregulla për push</string>
<string name="settings_push_gateway_no_pushers">Pa kanale push të regjistruar</string>

<string name="push_gateway_item_url">Url:</string>
<string name="push_gateway_item_format">Format:</string>

<string name="preference_voice_and_video">Zë &amp; Video</string>
<string name="preference_root_help_about">Ndihmë &amp; Mbi</string>


<string name="send_suggestion">Bëni një sugjerim</string>
<string name="send_suggestion_content">Ju lutemi, shkruajeni sugjerimin tuaj më poshtë.</string>
<string name="send_suggestion_report_placeholder">Përshkruani këtu sugjerimin tuaj</string>
<string name="send_suggestion_sent">Faleminderit, sugjerimi u dërgua me sukses</string>
<string name="send_suggestion_failed">Su arrit të dërgohej sugjerimi (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">Shfaq te rrjedha kohore akte të fshehura</string>

<string name="store_riotx_title">RiotX - Klient Matrix i Brezit të Ardhshëm</string>
<string name="store_riotx_short_description">Një klient më i shpejtë dhe më i lehtë për Matrix, që përdor mekanizmat më të rinj Android</string>
<string name="store_riotx_full_description">RiotX është një klient i ri për protokollin Matrix (Matrix.org): një rrjet i hapur për komunikim të sigurt, të centralizuar. RiotX është një rishkrim i plotë i klientit Riot Android, bazuar në një rishkrim të plotë të Matrix Android SDK-së.
\n
\nKlauzolë: Ky është një version beta. RiotX-i është ende nën zhivillim aktiv dhe përmban kufizime dhe (shpresojmë të mos jenë shumë) të meta. Mirëpresim krejt përshtypjet dhe sugjerimet!
\n
\nRiotX-i mbulon: • Hyrje në një llogari ekzistuese • Krijim dhome dhe pjesëmarrje në dhoma publike • Pranim dhe hedhje poshtë ftesash • Njohje të dhomave të përdoruesve • Parje hollësish dhome • Dërgim mesazhesh tekst • Dërgim bashkëngjitjesh • Lexim dhe shkrim mesazhesh në dhoma të fshehtëzuara • Kriptografi: kopjeruajtje kyçesh E2E, verifikim i thelluar pajisjesh, kërkesa dhe përgjigje për ndarje kyçesh • Njoftime push • Tema të Çelëta, të Errëta dhe të Zeza
\n
\nNë RiotX sjanë sendërtuar ende krejt veçoritë e Riot-it. Veçori kryesore që mungojnë (dhe që do të vijnë së shpejti!): • Krijim llogarish • Rregullime dhome (shfaqje anëtarësh dhome, etj.) • Krijim dhomash fjalosjeje të drejtpërdrejtë • Thirrje • Widget-es • …</string>

</resources>

View File

@ -1479,4 +1479,57 @@ Matrix 中的消息可見度類似于電子郵件。我們忘記您的郵件意
<string name="keys_backup_unable_to_get_trust_info">取得信任資訊時發生錯誤</string>
<string name="keys_backup_unable_to_get_keys_backup_data">取得金鑰備份資料時發生錯誤</string>

<string name="alpha_disclaimer_title">歡迎使用測試版!</string>
<string name="alpha_disclaimer_content_line_1">RiotX 還在早期開發階段,可能會缺少某些功能,您可能會遇到臭蟲。</string>
<string name="alpha_disclaimer_content_line_2_gplay">最新的功能清單一直都會在 %1$s如果您發現臭蟲請在首頁左上角的選單中遞交回報我們將會盡快修復。</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">Play 商店描述</string>
<string name="alpha_disclaimer_content_line_2_fdroid">如果您發現臭蟲,請在首頁左上角的選單中遞交回報,我們將會盡快修復。</string>

<string name="import_e2e_keys_from_file">從檔案「%1$s」匯入 e2e 金鑰。</string>

<string name="settings_sdk_version">Matrix SDK 版本</string>
<string name="settings_other_third_party_notices">其他第三方提醒</string>
<string name="navigate_to_room_when_already_in_the_room">您已在檢視此聊天室了!</string>

<string name="quick_reactions">快速反應</string>

<string name="settings_general_title">一般</string>
<string name="settings_preferences">偏好設定</string>
<string name="settings_security_and_privacy">安全與隱私</string>
<string name="settings_expert">專家</string>
<string name="settings_push_rules">推送規則</string>
<string name="settings_push_rules_no_rules">未定義通送規則</string>
<string name="settings_push_gateway_no_pushers">沒有已註冊的推送閘道</string>

<string name="push_gateway_item_app_id">app_id</string>
<string name="push_gateway_item_push_key">push_key</string>
<string name="push_gateway_item_app_display_name">app_display_name</string>
<string name="push_gateway_item_device_name">device_name</string>
<string name="push_gateway_item_url">Url</string>
<string name="push_gateway_item_format">格式:</string>

<string name="preference_voice_and_video">音訊與視訊</string>
<string name="preference_root_help_about">說明與關於</string>


<string name="settings_troubleshoot_test_token_registration_quick_fix">註冊代符</string>

<string name="send_suggestion">建議</string>
<string name="send_suggestion_content">請在下面編寫您的建議。</string>
<string name="send_suggestion_report_placeholder">在此描述您的建議</string>
<string name="send_suggestion_sent">感謝,建議已成功傳送</string>
<string name="send_suggestion_failed">建議傳送失敗 (%s)</string>

<string name="settings_labs_show_hidden_events_in_timeline">在時間軸中顯示隱藏的活動</string>

<string name="store_riotx_title">RiotX - 下一代的 Matrix 客戶端</string>
<string name="store_riotx_short_description">使用最新 Android 框架的 Matrix 較快且輕量的客戶端</string>
<string name="store_riotx_full_description">RiotX 是 Matrix 協定 (Matrix.org) 的新客戶端安全、去中心化通訊的開放網路。RiotX 是 Riot Android 客戶端的完全重寫,以 Matrix Android SDK 的完全重寫為基礎。
\n
\n免責聲明這是測試版。RiotX 目前仍在積極開發中,包含限制與(我們希望不多的)臭蟲。所有的回饋都很歡迎!
\n
\nRiotX 支援:• 登入到既有的帳號 • 建立聊天室與加入公開聊天室 • 接受與回絕邀請 • 列出使用者聊天室 • 檢視聊天室詳細資訊 • 傳送文字訊息 • 傳送附件 • 讀取與編寫已加密的聊天室 • 加密E2E 金鑰備份、進階裝置驗證、金鑰分享請求與回應 • 推送通知 • 亮、暗與黑色主題
\n
\n不是所有 Riot 的功能都已在 RiotX 中實作。主要缺少(會在稍後到來!)的功能:• 建立帳號 • 聊天室設定(列出聊天室成員等) • 直接聊天室建立 • 通話 • 小工具 • …</string>

</resources>

View File

@ -1522,7 +1522,7 @@ Why choose Riot.im?
<string name="keys_backup_unable_to_get_keys_backup_data">"An error occurred getting keys backup data"</string>

<string name="alpha_disclaimer_title">Welcome to the beta!</string>
<string name="alpha_disclaimer_content_line_1">"While Riot X is in early development, some features may be missing and you may experience bugs."</string>
<string name="alpha_disclaimer_content_line_1">"While RiotX is in early development, some features may be missing and you may experience bugs."</string>
<!-- The parameter will be replaced by the value of string alpha_disclaimer_content_line_2_gplay_colored_part -->
<string name="alpha_disclaimer_content_line_2_gplay">"The latest feature list is always in the %1$s, and if you find bugs please submit a report in the top left menu of Home, and well fix them as quickly as we can."</string>
<string name="alpha_disclaimer_content_line_2_gplay_colored_part">"Play Store description"</string>
@ -1534,6 +1534,7 @@ Why choose Riot.im?
<string name="settings_other_third_party_notices">Other third party notices</string>
<string name="navigate_to_room_when_already_in_the_room">You are already viewing this room!</string>

<string name="quick_reactions">Quick Reactions</string>

<!-- Settings -->
<string name="settings_general_title">General</string>
@ -1593,4 +1594,38 @@ Not all features in Riot are implemented in RiotX yet. Main missing (and coming
• Widgets
• …"</string>

<string name="bottom_action_people_x">Direct Messages</string>

<string name="send_file_step_idle">Waiting…</string>
<string name="send_file_step_encrypting_thumbnail">Encrypting thumbnail…</string>
<string name="send_file_step_sending_thumbnail">Sending thumbnail (%1$s / %2$s)</string>
<string name="send_file_step_encrypting_file">Encrypting file…</string>
<string name="send_file_step_sending_file">Sending file (%1$s / %2$s)</string>

<string name="downloading_file">Downloading file %1$s…</string>
<string name="downloaded_file">File %1$s has been downloaded!</string>

<string name="edited_suffix">"(edited)"</string>

<!-- param will be replaced by the value of riotx_no_registration_notice_colored_part -->
<string name="riotx_no_registration_notice">%1$s to create an account.</string>
<string name="riotx_no_registration_notice_colored_part">Use the old app</string>


<string name="message_edits">Message Edits</string>
<string name="no_message_edits_found">No edits found</string>

<!-- Room filtering -->
<string name="room_filtering_filter_hint">Filter conversations…</string>
<string name="room_filtering_footer_title">Cant find what youre looking for?</string>
<string name="room_filtering_footer_create_new_room">Create a new room</string>
<string name="room_filtering_footer_create_new_direct_message">Send a new direct message</string>
<string name="room_filtering_footer_open_room_directory">View the room directory</string>

<string name="room_directory_search_hint">Name or ID (#example:matrix.org)</string>

<string name="labs_swipe_to_reply_in_timeline">Enable swipe to reply in timeline</string>

<string name="link_copied_to_clipboard">Link copied to clipboard</string>

</resources>

View File

@ -2,43 +2,6 @@
<resources>

<!-- Strings not defined in Riot -->

<string name="bottom_action_people_x">Direct Messages</string>

<string name="send_file_step_idle">Waiting…</string>
<string name="send_file_step_encrypting_thumbnail">Encrypting thumbnail…</string>
<string name="send_file_step_sending_thumbnail">Sending thumbnail (%1$s / %2$s)</string>
<string name="send_file_step_encrypting_file">Encrypting file…</string>
<string name="send_file_step_sending_file">Sending file (%1$s / %2$s)</string>

<string name="downloading_file">Downloading file %1$s…</string>
<string name="downloaded_file">File %1$s has been downloaded!</string>

<string name="edited_suffix">"(edited)"</string>

<!-- param will be replaced by the value of riotx_no_registration_notice_colored_part -->
<string name="riotx_no_registration_notice">%1$s to create an account.</string>
<string name="riotx_no_registration_notice_colored_part">Use the old app</string>



<string name="message_edits">Message Edits</string>
<string name="no_message_edits_found">No edits found</string>

<!-- Room filtering -->
<string name="room_filtering_filter_hint">Filter conversations…</string>
<string name="room_filtering_footer_title">Cant find what youre looking for?</string>
<string name="room_filtering_footer_create_new_room">Create a new room</string>
<string name="room_filtering_footer_create_new_direct_message">Send a new direct message</string>
<string name="room_filtering_footer_open_room_directory">View the room directory</string>

<string name="room_directory_search_hint">Name or ID (#example:matrix.org)</string>


<string name="labs_swipe_to_reply_in_timeline">Enable swipe to reply in timeline</string>

<string name="link_copied_to_clipboard">Link copied to clipboard</string>

<string name="add_by_matrix_id">Add by matrix ID</string>

</resources>

View File

@ -4,11 +4,14 @@
<!-- ************************ Common items ************************ -->

<!-- toolbar styles-->
<style name="VectorToolbarStyle" parent="Widget.MaterialComponents.Toolbar">
<style name="VectorToolbarStyleWithPadding" parent="Widget.MaterialComponents.Toolbar">
<!-- main text -->
<item name="titleTextAppearance">@style/Vector.Toolbar.Title</item>
<item name="subtitleTextAppearance">@style/Vector.Toolbar.SubTitle</item>
<item name="android:background">?riotx_background</item>
</style>

<style name="VectorToolbarStyle" parent="VectorToolbarStyleWithPadding">
<item name="contentInsetStartWithNavigation">0dp</item>
</style>