0
0
mirror of https://github.com/thunderbird/thunderbird-android.git synced 2024-09-20 12:12:15 +02:00

Merge branch 'main' into message-view-redesign

This commit is contained in:
cketti 2022-10-31 12:48:21 +01:00
commit 60c29b6e07
131 changed files with 2118 additions and 2980 deletions

View File

@ -4,13 +4,7 @@ import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
interface ConnectionSettingsDiscovery {
fun discover(email: String, target: DiscoveryTarget): DiscoveryResults?
}
enum class DiscoveryTarget(val outgoing: Boolean, val incoming: Boolean) {
OUTGOING(true, false),
INCOMING(false, true),
INCOMING_AND_OUTGOING(true, true)
fun discover(email: String): DiscoveryResults?
}
data class DiscoveryResults(val incoming: List<DiscoveredServerSettings>, val outgoing: List<DiscoveredServerSettings>)

View File

@ -5,7 +5,6 @@ import android.net.Uri
import com.fsck.k9.autodiscovery.api.ConnectionSettingsDiscovery
import com.fsck.k9.autodiscovery.api.DiscoveredServerSettings
import com.fsck.k9.autodiscovery.api.DiscoveryResults
import com.fsck.k9.autodiscovery.api.DiscoveryTarget
import com.fsck.k9.helper.EmailHelper
import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
@ -19,7 +18,7 @@ class ProvidersXmlDiscovery(
private val oAuthConfigurationProvider: OAuthConfigurationProvider
) : ConnectionSettingsDiscovery {
override fun discover(email: String, target: DiscoveryTarget): DiscoveryResults? {
override fun discover(email: String): DiscoveryResults? {
val domain = EmailHelper.getDomainFromEmailAddress(email) ?: return null
val provider = findProviderForDomain(domain) ?: return null

View File

@ -2,7 +2,6 @@ package com.fsck.k9.autodiscovery.providersxml
import androidx.test.core.app.ApplicationProvider
import com.fsck.k9.RobolectricTest
import com.fsck.k9.autodiscovery.api.DiscoveryTarget
import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
import com.fsck.k9.oauth.OAuthConfiguration
@ -17,7 +16,7 @@ class ProvidersXmlDiscoveryTest : RobolectricTest() {
@Test
fun discover_withGmailDomain_shouldReturnCorrectSettings() {
val connectionSettings = providersXmlDiscovery.discover("user@gmail.com", DiscoveryTarget.INCOMING_AND_OUTGOING)
val connectionSettings = providersXmlDiscovery.discover("user@gmail.com")
assertThat(connectionSettings).isNotNull()
with(connectionSettings!!.incoming.first()) {
@ -37,7 +36,7 @@ class ProvidersXmlDiscoveryTest : RobolectricTest() {
@Test
fun discover_withUnknownDomain_shouldReturnNull() {
val connectionSettings = providersXmlDiscovery.discover(
"user@not.present.in.providers.xml.example", DiscoveryTarget.INCOMING_AND_OUTGOING
"user@not.present.in.providers.xml.example"
)
assertThat(connectionSettings).isNull()

View File

@ -3,7 +3,6 @@ package com.fsck.k9.autodiscovery.srvrecords
import com.fsck.k9.autodiscovery.api.ConnectionSettingsDiscovery
import com.fsck.k9.autodiscovery.api.DiscoveredServerSettings
import com.fsck.k9.autodiscovery.api.DiscoveryResults
import com.fsck.k9.autodiscovery.api.DiscoveryTarget
import com.fsck.k9.helper.EmailHelper
import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
@ -12,19 +11,19 @@ class SrvServiceDiscovery(
private val srvResolver: MiniDnsSrvResolver
) : ConnectionSettingsDiscovery {
override fun discover(email: String, target: DiscoveryTarget): DiscoveryResults? {
override fun discover(email: String): DiscoveryResults? {
val domain = EmailHelper.getDomainFromEmailAddress(email) ?: return null
val mailServicePriority = compareBy<MailService> { it.priority }.thenByDescending { it.security }
val outgoingSettings = if (target.outgoing)
listOf(SrvType.SUBMISSIONS, SrvType.SUBMISSION).flatMap { srvResolver.lookup(domain, it) }
.sortedWith(mailServicePriority).map { newServerSettings(it, email) }
else listOf()
val outgoingSettings = listOf(SrvType.SUBMISSIONS, SrvType.SUBMISSION)
.flatMap { srvResolver.lookup(domain, it) }
.sortedWith(mailServicePriority)
.map { newServerSettings(it, email) }
val incomingSettings = if (target.incoming)
listOf(SrvType.IMAPS, SrvType.IMAP).flatMap { srvResolver.lookup(domain, it) }
.sortedWith(mailServicePriority).map { newServerSettings(it, email) }
else listOf()
val incomingSettings = listOf(SrvType.IMAPS, SrvType.IMAP)
.flatMap { srvResolver.lookup(domain, it) }
.sortedWith(mailServicePriority)
.map { newServerSettings(it, email) }
return DiscoveryResults(incoming = incomingSettings, outgoing = outgoingSettings)
}

View File

@ -1,15 +1,11 @@
package com.fsck.k9.autodiscovery.srvrecords
import com.fsck.k9.autodiscovery.api.DiscoveredServerSettings
import com.fsck.k9.autodiscovery.api.DiscoveryResults
import com.fsck.k9.autodiscovery.api.DiscoveryTarget
import com.fsck.k9.mail.ConnectionSecurity
import org.junit.Assert.assertEquals
import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
class SrvServiceDiscoveryTest {
@ -18,7 +14,7 @@ class SrvServiceDiscoveryTest {
val srvResolver = newMockSrvResolver()
val srvServiceDiscovery = SrvServiceDiscovery(srvResolver)
val result = srvServiceDiscovery.discover("test@example.com", DiscoveryTarget.INCOMING_AND_OUTGOING)
val result = srvServiceDiscovery.discover("test@example.com")
assertEquals(DiscoveryResults(listOf(), listOf()), result)
}
@ -33,7 +29,7 @@ class SrvServiceDiscoveryTest {
)
val srvServiceDiscovery = SrvServiceDiscovery(srvResolver)
val result = srvServiceDiscovery.discover("test@example.com", DiscoveryTarget.INCOMING_AND_OUTGOING)
val result = srvServiceDiscovery.discover("test@example.com")
assertEquals(2, result!!.incoming.size)
assertEquals(0, result.outgoing.size)
@ -57,7 +53,7 @@ class SrvServiceDiscoveryTest {
)
val srvServiceDiscovery = SrvServiceDiscovery(srvResolver)
val result = srvServiceDiscovery.discover("test@example.com", DiscoveryTarget.INCOMING_AND_OUTGOING)
val result = srvServiceDiscovery.discover("test@example.com")
assertEquals(0, result!!.incoming.size)
assertEquals(2, result.outgoing.size)
@ -133,7 +129,7 @@ class SrvServiceDiscoveryTest {
)
val srvServiceDiscovery = SrvServiceDiscovery(srvResolver)
val result = srvServiceDiscovery.discover("test@example.com", DiscoveryTarget.INCOMING_AND_OUTGOING)
val result = srvServiceDiscovery.discover("test@example.com")
assertEquals(
listOf(
@ -155,54 +151,6 @@ class SrvServiceDiscoveryTest {
)
}
@Test
fun discover_whenOnlyOutgoingTrue_shouldOnlyFetchOutgoing() {
val srvResolver = newMockSrvResolver(
submissionServices = listOf(
newMailService(
host = "smtp.example.com",
port = 465,
srvType = SrvType.SUBMISSIONS,
security = ConnectionSecurity.SSL_TLS_REQUIRED,
priority = 0
)
)
)
val srvServiceDiscovery = SrvServiceDiscovery(srvResolver)
val result = srvServiceDiscovery.discover("test@example.com", DiscoveryTarget.OUTGOING)
verify(srvResolver).lookup("example.com", SrvType.SUBMISSIONS)
verify(srvResolver).lookup("example.com", SrvType.SUBMISSION)
verifyNoMoreInteractions(srvResolver)
assertEquals(1, result!!.outgoing.size)
assertEquals(listOf<DiscoveredServerSettings>(), result.incoming)
}
@Test
fun discover_whenOnlyIncomingTrue_shouldOnlyFetchIncoming() {
val srvResolver = newMockSrvResolver(
imapsServices = listOf(
newMailService(
host = "imaps.example.com",
port = 993,
srvType = SrvType.IMAPS,
security = ConnectionSecurity.SSL_TLS_REQUIRED,
priority = 0
)
)
)
val srvServiceDiscovery = SrvServiceDiscovery(srvResolver)
val result = srvServiceDiscovery.discover("test@example.com", DiscoveryTarget.INCOMING)
verify(srvResolver).lookup("example.com", SrvType.IMAPS)
verify(srvResolver).lookup("example.com", SrvType.IMAP)
verifyNoMoreInteractions(srvResolver)
assertEquals(1, result!!.incoming.size)
assertEquals(listOf<DiscoveredServerSettings>(), result.outgoing)
}
private fun newMailService(
host: String = "example.com",
priority: Int = 0,

View File

@ -1,6 +1,5 @@
package com.fsck.k9.autodiscovery.thunderbird
import com.fsck.k9.helper.EmailHelper
import java.io.InputStream
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
@ -8,8 +7,7 @@ import okhttp3.Request
class ThunderbirdAutoconfigFetcher(private val okHttpClient: OkHttpClient) {
fun fetchAutoconfigFile(email: String): InputStream? {
val url = getAutodiscoveryAddress(email)
fun fetchAutoconfigFile(url: HttpUrl): InputStream? {
val request = Request.Builder().url(url).build()
val response = okHttpClient.newCall(request).execute()
@ -20,20 +18,4 @@ class ThunderbirdAutoconfigFetcher(private val okHttpClient: OkHttpClient) {
null
}
}
companion object {
// address described at:
// https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration#Configuration_server_at_ISP
internal fun getAutodiscoveryAddress(email: String): HttpUrl {
val domain = EmailHelper.getDomainFromEmailAddress(email)
requireNotNull(domain) { "Couldn't extract domain from email address: $email" }
return HttpUrl.Builder()
.scheme("https")
.host(domain)
.addEncodedPathSegments(".well-known/autoconfig/mail/config-v1.1.xml")
.addQueryParameter("emailaddress", email)
.build()
}
}
}

View File

@ -0,0 +1,47 @@
package com.fsck.k9.autodiscovery.thunderbird
import com.fsck.k9.helper.EmailHelper
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
class ThunderbirdAutoconfigUrlProvider {
fun getAutoconfigUrls(email: String): List<HttpUrl> {
val domain = EmailHelper.getDomainFromEmailAddress(email)
requireNotNull(domain) { "Couldn't extract domain from email address: $email" }
return listOf(
createProviderUrl(domain, email),
createDomainUrl(scheme = "https", domain),
createDomainUrl(scheme = "http", domain),
createIspDbUrl(domain)
)
}
private fun createProviderUrl(domain: String?, email: String): HttpUrl {
// https://autoconfig.{domain}/mail/config-v1.1.xml?emailaddress={email}
return HttpUrl.Builder()
.scheme("https")
.host("autoconfig.$domain")
.addEncodedPathSegments("mail/config-v1.1.xml")
.addQueryParameter("emailaddress", email)
.build()
}
private fun createDomainUrl(scheme: String, domain: String): HttpUrl {
// https://{domain}/.well-known/autoconfig/mail/config-v1.1.xml
// http://{domain}/.well-known/autoconfig/mail/config-v1.1.xml
return HttpUrl.Builder()
.scheme(scheme)
.host(domain)
.addEncodedPathSegments(".well-known/autoconfig/mail/config-v1.1.xml")
.build()
}
private fun createIspDbUrl(domain: String): HttpUrl {
// https://autoconfig.thunderbird.net/v1.1/{domain}
return "https://autoconfig.thunderbird.net/v1.1/".toHttpUrl()
.newBuilder()
.addPathSegment(domain)
.build()
}
}

View File

@ -2,19 +2,26 @@ package com.fsck.k9.autodiscovery.thunderbird
import com.fsck.k9.autodiscovery.api.ConnectionSettingsDiscovery
import com.fsck.k9.autodiscovery.api.DiscoveryResults
import com.fsck.k9.autodiscovery.api.DiscoveryTarget
class ThunderbirdDiscovery(
private val urlProvider: ThunderbirdAutoconfigUrlProvider,
private val fetcher: ThunderbirdAutoconfigFetcher,
private val parser: ThunderbirdAutoconfigParser
) : ConnectionSettingsDiscovery {
override fun discover(email: String, target: DiscoveryTarget): DiscoveryResults? {
val autoconfigInputStream = fetcher.fetchAutoconfigFile(email) ?: return null
override fun discover(email: String): DiscoveryResults? {
val autoconfigUrls = urlProvider.getAutoconfigUrls(email)
return autoconfigInputStream.use {
parser.parseSettings(it, email)
}
return autoconfigUrls
.asSequence()
.mapNotNull { autoconfigUrl ->
fetcher.fetchAutoconfigFile(autoconfigUrl)?.use { inputStream ->
parser.parseSettings(inputStream, email)
}
}
.firstOrNull { result ->
result.incoming.isNotEmpty() || result.outgoing.isNotEmpty()
}
}
override fun toString(): String = "Thunderbird autoconfig"

View File

@ -169,13 +169,4 @@ class ThunderbirdAutoconfigTest {
)
)
}
@Test
fun generatedUrls() {
val autoDiscoveryAddress = ThunderbirdAutoconfigFetcher.getAutodiscoveryAddress("test@metacode.biz")
assertThat(autoDiscoveryAddress.toString()).isEqualTo(
"https://metacode.biz/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=test%40metacode.biz"
)
}
}

View File

@ -0,0 +1,20 @@
package com.fsck.k9.autodiscovery.thunderbird
import com.google.common.truth.Truth.assertThat
import org.junit.Test
class ThunderbirdAutoconfigUrlProviderTest {
private val urlProvider = ThunderbirdAutoconfigUrlProvider()
@Test
fun `getAutoconfigUrls with ASCII email address`() {
val autoconfigUrls = urlProvider.getAutoconfigUrls("test@domain.example")
assertThat(autoconfigUrls.map { it.toString() }).containsExactly(
"https://autoconfig.domain.example/mail/config-v1.1.xml?emailaddress=test%40domain.example",
"https://domain.example/.well-known/autoconfig/mail/config-v1.1.xml",
"http://domain.example/.well-known/autoconfig/mail/config-v1.1.xml",
"https://autoconfig.thunderbird.net/v1.1/domain.example"
)
}
}

View File

@ -75,8 +75,10 @@ internal class DraftOperations(
messagingController.queuePendingCommand(account, command)
} else {
val fakeMessageServerId = messageStore.getMessageServerId(messageId)
val command = PendingAppend.create(folderId, fakeMessageServerId)
messagingController.queuePendingCommand(account, command)
if (fakeMessageServerId != null) {
val command = PendingAppend.create(folderId, fakeMessageServerId)
messagingController.queuePendingCommand(account, command)
}
}
messagingController.processPendingCommands(account)

View File

@ -91,7 +91,6 @@ import static com.fsck.k9.K9.MAX_SEND_ATTEMPTS;
import static com.fsck.k9.helper.ExceptionHelper.getRootCauseMessage;
import static com.fsck.k9.helper.Preconditions.checkNotNull;
import static com.fsck.k9.mail.Flag.X_REMOTE_COPY_STARTED;
import static com.fsck.k9.search.LocalSearchExtensions.getAccountsFromLocalSearch;
/**
@ -393,27 +392,6 @@ public class MessagingController {
}
}
/**
* Find all messages in any local account which match the query 'query'
*/
public List<LocalMessage> searchLocalMessages(final LocalSearch search) {
List<Account> searchAccounts = getAccountsFromLocalSearch(search, preferences);
List<LocalMessage> messages = new ArrayList<>();
for (final Account account : searchAccounts) {
try {
LocalStore localStore = localStoreProvider.getInstance(account);
List<LocalMessage> localMessages = localStore.searchForMessages(search);
messages.addAll(localMessages);
} catch (Exception e) {
Timber.e(e);
}
}
return messages;
}
public Future<?> searchRemoteMessages(String acctUuid, long folderId, String query, Set<Flag> requiredFlags,
Set<Flag> forbiddenFlags, MessagingListener listener) {
Timber.i("searchRemoteMessages (acct = %s, folderId = %d, query = %s)", acctUuid, folderId, query);
@ -1637,9 +1615,11 @@ public class MessagingController {
if (!sentFolder.isLocalOnly()) {
String destinationUid = messageStore.getMessageServerId(destinationMessageId);
PendingCommand command = PendingAppend.create(sentFolderId, destinationUid);
queuePendingCommand(account, command);
processPendingCommands(account);
if (destinationUid != null) {
PendingCommand command = PendingAppend.create(sentFolderId, destinationUid);
queuePendingCommand(account, command);
processPendingCommands(account);
}
}
}
@ -1923,9 +1903,10 @@ public class MessagingController {
MessageStore messageStore = messageStoreManager.getMessageStore(account);
String messageServerId = messageStore.getMessageServerId(messageId);
MessageReference messageReference = new MessageReference(account.getUuid(), folderId, messageServerId);
deleteMessage(messageReference);
if (messageServerId != null) {
MessageReference messageReference = new MessageReference(account.getUuid(), folderId, messageServerId);
deleteMessage(messageReference);
}
}
public void deleteThreads(final List<MessageReference> messages) {
@ -2673,7 +2654,6 @@ public class MessagingController {
LocalFolder localFolder = message.getFolder();
if (!suppressNotifications &&
notificationStrategy.shouldNotifyForMessage(account, localFolder, message, isOldMessage)) {
Timber.v("Creating notification for message %s:%s", localFolder.getName(), message.getUid());
// Notify with the localMessage so that we don't have to recalculate the content preview.
boolean silent = notificationState.wasNotified();
notificationController.addNewMailNotification(account, message, silent);

View File

@ -35,3 +35,7 @@ fun Cursor.getIntOrThrow(columnName: String): Int {
fun Cursor.getLongOrThrow(columnName: String): Long {
return getLongOrNull(columnName) ?: error("Column $columnName must not be null")
}
fun Cursor.getBoolean(columnIndex: Int): Boolean {
return getString(columnIndex).toBoolean()
}

View File

@ -194,10 +194,6 @@ public class LocalMessage extends MimeMessage {
return (attachmentCount > 0);
}
public int getAttachmentCount() {
return attachmentCount;
}
@Override
public void setFrom(Address from) {
this.mFrom = new Address[] { from };
@ -388,10 +384,6 @@ public class LocalMessage extends MimeMessage {
return mFolder;
}
public String getUri() {
return "k9mail://messages/" + getAccount().getAccountNumber() + "/" + getFolder().getDatabaseId() + "/" + getUid();
}
@Override
public void writeTo(OutputStream out) throws IOException, MessagingException {
if (headerNeedsUpdating) {

View File

@ -5,19 +5,32 @@ import java.util.concurrent.CopyOnWriteArraySet
class MessageListRepository(
private val messageStoreManager: MessageStoreManager
) {
private val listeners = CopyOnWriteArraySet<Pair<String, MessageListChangedListener>>()
private val globalListeners = CopyOnWriteArraySet<MessageListChangedListener>()
private val accountListeners = CopyOnWriteArraySet<Pair<String, MessageListChangedListener>>()
fun addListener(listener: MessageListChangedListener) {
globalListeners.add(listener)
}
fun addListener(accountUuid: String, listener: MessageListChangedListener) {
listeners.add(accountUuid to listener)
accountListeners.add(accountUuid to listener)
}
fun removeListener(listener: MessageListChangedListener) {
val entries = listeners.filter { it.second == listener }.toSet()
listeners.removeAll(entries)
globalListeners.remove(listener)
val accountEntries = accountListeners.filter { it.second == listener }.toSet()
if (accountEntries.isNotEmpty()) {
accountListeners.removeAll(accountEntries)
}
}
fun notifyMessageListChanged(accountUuid: String) {
for (listener in listeners) {
for (listener in globalListeners) {
listener.onMessageListChanged()
}
for (listener in accountListeners) {
if (listener.first == accountUuid) {
listener.second.onMessageListChanged()
}

View File

@ -91,7 +91,7 @@ interface MessageStore {
/**
* Retrieve the server ID for a given message.
*/
fun getMessageServerId(messageId: Long): String
fun getMessageServerId(messageId: Long): String?
/**
* Retrieve the server IDs for the given messages.

View File

@ -4,6 +4,7 @@ import com.fsck.k9.Account
import com.fsck.k9.controller.MessageReference
import com.fsck.k9.mailstore.LocalFolder
import com.fsck.k9.mailstore.LocalMessage
import timber.log.Timber
class NotificationController internal constructor(
private val certificateErrorNotificationController: CertificateErrorNotificationController,
@ -61,20 +62,33 @@ class NotificationController internal constructor(
}
fun addNewMailNotification(account: Account, message: LocalMessage, silent: Boolean) {
Timber.v(
"Creating notification for message %s:%s:%s",
message.account.uuid,
message.folder.databaseId,
message.uid
)
newMailNotificationController.addNewMailNotification(account, message, silent)
}
fun removeNewMailNotification(account: Account, messageReference: MessageReference) {
Timber.v("Removing notification for message %s", messageReference)
newMailNotificationController.removeNewMailNotifications(account, clearNewMessageState = true) {
listOf(messageReference)
}
}
fun clearNewMailNotifications(account: Account, selector: (List<MessageReference>) -> List<MessageReference>) {
Timber.v("Removing some notifications for account %s", account.uuid)
newMailNotificationController.removeNewMailNotifications(account, clearNewMessageState = false, selector)
}
fun clearNewMailNotifications(account: Account, clearNewMessageState: Boolean) {
Timber.v("Removing all notifications for account %s", account.uuid)
newMailNotificationController.clearNewMailNotifications(account, clearNewMessageState)
}
}

View File

@ -19,7 +19,6 @@ import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mailstore.LocalFolder;
@ -35,15 +34,12 @@ import com.fsck.k9.mailstore.SpecialLocalFoldersCreator;
import com.fsck.k9.notification.NotificationController;
import com.fsck.k9.notification.NotificationStrategy;
import com.fsck.k9.preferences.Protocols;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@ -52,7 +48,6 @@ import org.mockito.stubbing.Answer;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowLog;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.ArgumentMatchers.eq;
@ -90,8 +85,6 @@ public class MessagingControllerTest extends K9RobolectricTest {
@Mock
private SimpleMessagingListener listener;
@Mock
private LocalSearch search;
@Mock
private LocalFolder localFolder;
@Mock
private LocalFolder sentFolder;
@ -101,8 +94,6 @@ public class MessagingControllerTest extends K9RobolectricTest {
private NotificationController notificationController;
@Mock
private NotificationStrategy notificationStrategy;
@Captor
private ArgumentCaptor<MessageRetrievalListener<LocalMessage>> messageRetrievalListenerCaptor;
private Context appContext;
private Set<Flag> reqFlags;
@ -178,20 +169,6 @@ public class MessagingControllerTest extends K9RobolectricTest {
verify(backend).refreshFolderList();
}
@Test
public void searchLocalMessages_shouldIgnoreExceptions()
throws Exception {
LocalMessage localMessage = mock(LocalMessage.class);
when(localMessage.getFolder()).thenReturn(localFolder);
when(search.searchAllAccounts()).thenReturn(true);
when(search.getAccountUuids()).thenReturn(new String[0]);
when(localStore.searchForMessages(search)).thenThrow(new MessagingException("Test"));
List<LocalMessage> messages = controller.searchLocalMessages(search);
assertThat(messages).isEmpty();
}
private void setupRemoteSearch() throws Exception {
remoteMessages = new ArrayList<>();
Collections.addAll(remoteMessages, "oldMessageUid", "newMessageUid1", "newMessageUid2");

View File

@ -13,7 +13,7 @@ internal class BodyCleaner {
init {
val allowList = Safelist.relaxed()
.addTags("font", "hr", "ins", "del", "center", "map", "area", "title")
.addTags("font", "hr", "ins", "del", "center", "map", "area", "title", "tt", "kbd", "samp", "var")
.addAttributes("font", "color", "face", "size")
.addAttributes("a", "name")
.addAttributes("div", "align")

View File

@ -445,6 +445,43 @@ class HtmlSanitizerTest {
)
}
@Test
fun `should keep 'tt' element`() {
assertTagsNotStripped("tt")
}
@Test
fun `should keep 'kbd' element`() {
assertTagsNotStripped("kbd")
}
@Test
fun `should keep 'samp' element`() {
assertTagsNotStripped("samp")
}
@Test
fun `should keep 'var' element`() {
assertTagsNotStripped("var")
}
private fun assertTagsNotStripped(element: String) {
val html = """<$element>some text</$element>"""
val result = htmlSanitizer.sanitize(html)
assertThat(result.toCompactString()).isEqualTo(
"""
<html>
<head></head>
<body>
<$element>some text</$element>
</body>
</html>
""".trimIndent().trimLineBreaks()
)
}
private fun Document.toCompactString(): String {
outputSettings()
.prettyPrint(false)

View File

@ -7,6 +7,7 @@ if (rootProject.testCoverage) {
dependencies {
implementation project(":app:ui:legacy")
implementation project(":app:ui:message-list-widget")
implementation project(":app:core")
implementation project(":app:storage")
implementation project(":app:crypto-openpgp")
@ -50,8 +51,8 @@ android {
applicationId "com.fsck.k9"
testApplicationId "com.fsck.k9.tests"
versionCode 33009
versionName '6.310-SNAPSHOT'
versionCode 33010
versionName '6.311-SNAPSHOT'
// Keep in sync with the resource string array 'supported_languages'
resConfigs "in", "br", "ca", "cs", "cy", "da", "de", "et", "en", "en_GB", "es", "eo", "eu", "fr", "gd", "gl",

View File

@ -59,13 +59,6 @@
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
<!-- activity-alias so old launcher shortcuts work -->
<!-- TODO: Remove after 2020-12-31 -->
<activity-alias
android:name=".activity.Accounts"
android:targetActivity=".activity.MessageList"
android:exported="true" />
<activity
android:name=".ui.onboarding.OnboardingActivity"
android:label="@string/welcome_message_title" />
@ -158,13 +151,6 @@
android:label="@string/ac_transfer_title"
/>
<!-- activity-alias so old launcher shortcuts work -->
<!-- TODO: Remove after 2020-12-31 -->
<activity-alias
android:name=".activity.FolderList"
android:targetActivity=".activity.MessageList"
android:exported="true" />
<activity
android:name=".activity.MessageList"
android:launchMode="singleTop"
@ -336,11 +322,6 @@
</intent-filter>
</receiver>
<service
android:name=".widget.list.MessageListWidgetService"
android:enabled="true"
android:permission="android.permission.BIND_REMOTEVIEWS" />
<service
android:name=".notification.NotificationActionService"
android:enabled="true"/>
@ -381,11 +362,6 @@
</provider>
<provider
android:name=".external.MessageProvider"
android:authorities="${applicationId}.messageprovider"
android:exported="false" />
<provider
android:name=".provider.DecryptedFileProvider"
android:authorities="${applicationId}.decryptedfileprovider"

View File

@ -3,9 +3,9 @@ package com.fsck.k9
import android.app.Application
import android.content.res.Configuration
import android.content.res.Resources
import app.k9mail.ui.widget.list.MessageListWidgetManager
import com.fsck.k9.activity.MessageCompose
import com.fsck.k9.controller.MessagingController
import com.fsck.k9.external.MessageProvider
import com.fsck.k9.notification.NotificationChannelManager
import com.fsck.k9.ui.base.AppLanguageManager
import com.fsck.k9.ui.base.ThemeManager
@ -28,6 +28,7 @@ class App : Application() {
private val themeManager: ThemeManager by inject()
private val appLanguageManager: AppLanguageManager by inject()
private val notificationChannelManager: NotificationChannelManager by inject()
private val messageListWidgetManager: MessageListWidgetManager by inject()
private val appCoroutineScope: CoroutineScope = GlobalScope + Dispatchers.Main
private var appLanguageManagerInitialized = false
@ -40,10 +41,10 @@ class App : Application() {
K9.init(this)
Core.init(this)
MessageProvider.init()
initializeAppLanguage()
updateNotificationChannelsOnAppLanguageChanges()
themeManager.init()
messageListWidgetManager.init()
messagingListenerProvider.listeners.forEach { listener ->
messagingController.addListener(listener)

View File

@ -1,5 +1,6 @@
package com.fsck.k9
import app.k9mail.ui.widget.list.messageListWidgetModule
import com.fsck.k9.auth.createOAuthConfigurationProvider
import com.fsck.k9.backends.backendsModule
import com.fsck.k9.controller.ControllerExtension
@ -10,8 +11,7 @@ import com.fsck.k9.preferences.K9StoragePersister
import com.fsck.k9.preferences.StoragePersister
import com.fsck.k9.resources.resourcesModule
import com.fsck.k9.storage.storageModule
import com.fsck.k9.widget.list.MessageListWidgetUpdateListener
import com.fsck.k9.widget.list.messageListWidgetModule
import com.fsck.k9.widget.list.messageListWidgetConfigModule
import com.fsck.k9.widget.unread.UnreadWidgetUpdateListener
import com.fsck.k9.widget.unread.unreadWidgetModule
import org.koin.core.qualifier.named
@ -23,7 +23,6 @@ private val mainAppModule = module {
MessagingListenerProvider(
listOf(
get<UnreadWidgetUpdateListener>(),
get<MessageListWidgetUpdateListener>()
)
)
}
@ -35,6 +34,7 @@ private val mainAppModule = module {
val appModules = listOf(
mainAppModule,
messageListWidgetConfigModule,
messageListWidgetModule,
unreadWidgetModule,
notificationModule,

View File

@ -1,81 +0,0 @@
package com.fsck.k9.external;
import java.util.Date;
import android.content.Context;
import android.text.SpannableStringBuilder;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.MessageHelper;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.ui.R;
class MessageInfoHolder {
public Date compareDate;
public CharSequence sender;
public String senderAddress;
public String uid;
public boolean read;
public LocalMessage message;
public String uri;
public static MessageInfoHolder create(Context context, LocalMessage message,
Account account) {
Contacts contactHelper = K9.isShowContactName() ? Contacts.getInstance(context) : null;
MessageInfoHolder target = new MessageInfoHolder();
target.message = message;
target.compareDate = message.getSentDate();
if (target.compareDate == null) {
target.compareDate = message.getInternalDate();
}
target.read = message.isSet(Flag.SEEN);
Address[] addrs = message.getFrom();
String counterParty;
if (addrs.length > 0 && account.isAnIdentity(addrs[0])) {
CharSequence to = MessageHelper.toFriendly(message.getRecipients(RecipientType.TO), contactHelper);
counterParty = to.toString();
target.sender = new SpannableStringBuilder(context.getString(R.string.message_to_label)).append(to);
} else {
target.sender = MessageHelper.toFriendly(addrs, contactHelper);
counterParty = target.sender.toString();
}
if (addrs.length > 0) {
target.senderAddress = addrs[0].getAddress();
} else {
// a reasonable fallback "whomever we were corresponding with
target.senderAddress = counterParty;
}
target.uid = message.getUid();
target.uri = message.getUri();
return target;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MessageInfoHolder)) {
return false;
}
MessageInfoHolder other = (MessageInfoHolder)o;
return message.equals(other.message);
}
@Override
public int hashCode() {
return uid.hashCode();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
package com.fsck.k9.widget.list
import app.k9mail.ui.widget.list.MessageListWidgetConfig
import org.koin.dsl.module
val messageListWidgetModule = module {
single { MessageListWidgetUpdateListener(get()) }
val messageListWidgetConfigModule = module {
single<MessageListWidgetConfig> { K9MessageListWidgetConfig() }
}

View File

@ -1,217 +0,0 @@
package com.fsck.k9.widget.list;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Binder;
import androidx.core.content.ContextCompat;
import android.text.SpannableString;
import android.text.style.StyleSpan;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.external.MessageProvider;
public class MessageListRemoteViewFactory implements RemoteViewsService.RemoteViewsFactory {
private static final String[] MAIL_LIST_PROJECTIONS = {
MessageProvider.MessageColumns.SENDER,
MessageProvider.MessageColumns.SEND_DATE,
MessageProvider.MessageColumns.SUBJECT,
MessageProvider.MessageColumns.PREVIEW,
MessageProvider.MessageColumns.UNREAD,
MessageProvider.MessageColumns.HAS_ATTACHMENTS,
MessageProvider.MessageColumns.URI,
MessageProvider.MessageColumns.ACCOUNT_COLOR,
};
private final Context context;
private final Calendar calendar;
private final ArrayList<MailItem> mailItems = new ArrayList<>(25);
private boolean senderAboveSubject;
private int readTextColor;
private int unreadTextColor;
public MessageListRemoteViewFactory(Context context) {
this.context = context;
calendar = Calendar.getInstance();
}
@Override
public void onCreate() {
senderAboveSubject = K9.isMessageListSenderAboveSubject();
readTextColor = ContextCompat.getColor(context, R.color.message_list_widget_text_read);
unreadTextColor = ContextCompat.getColor(context, R.color.message_list_widget_text_unread);
}
@Override
public void onDataSetChanged() {
long identityToken = Binder.clearCallingIdentity();
try {
loadMessageList();
} finally {
Binder.restoreCallingIdentity(identityToken);
}
}
private void loadMessageList() {
mailItems.clear();
Uri unifiedInboxUri = MessageProvider.CONTENT_URI.buildUpon().appendPath("inbox_messages").build();
Cursor cursor = context.getContentResolver().query(unifiedInboxUri, MAIL_LIST_PROJECTIONS, null, null, null);
if (cursor == null) {
return;
}
try {
while (cursor.moveToNext()) {
String sender = cursor.getString(0);
long date = cursor.isNull(1) ? 0L : cursor.getLong(1);
String subject = cursor.getString(2);
String preview = cursor.getString(3);
boolean unread = toBoolean(cursor.getString(4));
boolean hasAttachment = toBoolean(cursor.getString(5));
Uri viewUri = Uri.parse(cursor.getString(6));
int color = cursor.getInt(7);
mailItems.add(new MailItem(sender, date, subject, preview, unread, hasAttachment, viewUri, color));
}
} finally {
cursor.close();
}
}
@Override
public void onDestroy() {
// Implement interface
}
@Override
public int getCount() {
return mailItems.size();
}
@Override
public RemoteViews getViewAt(int position) {
RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.message_list_widget_list_item);
MailItem item = mailItems.get(position);
CharSequence sender = item.unread ? bold(item.sender) : item.sender;
CharSequence subject = item.unread ? bold(item.subject) : item.subject;
if (senderAboveSubject) {
remoteView.setTextViewText(R.id.sender, sender);
remoteView.setTextViewText(R.id.mail_subject, subject);
} else {
remoteView.setTextViewText(R.id.sender, subject);
remoteView.setTextViewText(R.id.mail_subject, sender);
}
remoteView.setTextViewText(R.id.mail_date, item.getDateFormatted("%d %s"));
remoteView.setTextViewText(R.id.mail_preview, item.preview);
int textColor = item.getTextColor();
remoteView.setTextColor(R.id.sender, textColor);
remoteView.setTextColor(R.id.mail_subject, textColor);
remoteView.setTextColor(R.id.mail_date, textColor);
remoteView.setTextColor(R.id.mail_preview, textColor);
if (item.hasAttachment) {
remoteView.setInt(R.id.attachment, "setVisibility", View.VISIBLE);
} else {
remoteView.setInt(R.id.attachment, "setVisibility", View.GONE);
}
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setData(item.uri);
remoteView.setOnClickFillInIntent(R.id.mail_list_item, intent);
remoteView.setInt(R.id.chip, "setBackgroundColor", item.color);
return remoteView;
}
@Override
public RemoteViews getLoadingView() {
RemoteViews loadingView = new RemoteViews(context.getPackageName(), R.layout.message_list_widget_loading);
loadingView.setTextViewText(R.id.loadingText, context.getString(com.fsck.k9.ui.R.string.mail_list_widget_loading));
loadingView.setViewVisibility(R.id.loadingText, View.VISIBLE);
return loadingView;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
private CharSequence bold(String text) {
SpannableString spannableString = new SpannableString(text);
spannableString.setSpan(new StyleSpan(Typeface.BOLD), 0, text.length(), 0);
return spannableString;
}
private boolean toBoolean(String value) {
return Boolean.valueOf(value);
}
private class MailItem {
final long date;
final String sender;
final String preview;
final String subject;
final boolean unread;
final boolean hasAttachment;
final Uri uri;
final int color;
MailItem(String sender, long date, String subject, String preview, boolean unread, boolean hasAttachment,
Uri viewUri, int color) {
this.sender = sender;
this.date = date;
this.preview = preview;
this.subject = subject;
this.unread = unread;
this.uri = viewUri;
this.hasAttachment = hasAttachment;
this.color = color;
}
int getTextColor() {
return unread ? unreadTextColor : readTextColor;
}
String getDateFormatted(String format) {
calendar.setTimeInMillis(date);
return String.format(format,
calendar.get(Calendar.DAY_OF_MONTH),
calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()));
}
}
}

View File

@ -1,101 +0,0 @@
package com.fsck.k9.widget.list;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;
import com.fsck.k9.R;
import com.fsck.k9.activity.MessageCompose;
import com.fsck.k9.activity.MessageList;
import com.fsck.k9.search.SearchAccount;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static com.fsck.k9.helper.PendingIntentCompat.FLAG_IMMUTABLE;
import static com.fsck.k9.helper.PendingIntentCompat.FLAG_MUTABLE;
public class MessageListWidgetProvider extends AppWidgetProvider {
private static final String ACTION_UPDATE_MESSAGE_LIST = "UPDATE_MESSAGE_LIST";
public static void triggerMessageListWidgetUpdate(Context context) {
Context appContext = context.getApplicationContext();
AppWidgetManager widgetManager = AppWidgetManager.getInstance(appContext);
ComponentName widget = new ComponentName(appContext, MessageListWidgetProvider.class);
int[] widgetIds = widgetManager.getAppWidgetIds(widget);
Intent intent = new Intent(context, MessageListWidgetProvider.class);
intent.setAction(ACTION_UPDATE_MESSAGE_LIST);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds);
context.sendBroadcast(intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.message_list_widget_layout);
views.setTextViewText(R.id.folder, context.getString(com.fsck.k9.ui.R.string.integrated_inbox_title));
Intent intent = new Intent(context, MessageListWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
views.setRemoteAdapter(R.id.listView, intent);
PendingIntent viewAction = viewActionTemplatePendingIntent(context);
views.setPendingIntentTemplate(R.id.listView, viewAction);
PendingIntent composeAction = composeActionPendingIntent(context);
views.setOnClickPendingIntent(R.id.new_message, composeAction);
PendingIntent headerClickAction = viewUnifiedInboxPendingIntent(context);
views.setOnClickPendingIntent(R.id.top_controls, headerClickAction);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
String action = intent.getAction();
if (action.equals(ACTION_UPDATE_MESSAGE_LIST)) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.listView);
}
}
private PendingIntent viewActionTemplatePendingIntent(Context context) {
Intent intent = new Intent(context, MessageList.class);
intent.setAction(Intent.ACTION_VIEW);
return PendingIntent.getActivity(context, 0, intent, FLAG_UPDATE_CURRENT | FLAG_MUTABLE);
}
private PendingIntent viewUnifiedInboxPendingIntent(Context context) {
SearchAccount unifiedInboxAccount = SearchAccount.createUnifiedInboxAccount();
Intent intent = MessageList.intentDisplaySearch(
context, unifiedInboxAccount.getRelatedSearch(), true, true, true);
return PendingIntent.getActivity(context, -1, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE);
}
private PendingIntent composeActionPendingIntent(Context context) {
Intent intent = new Intent(context, MessageCompose.class);
intent.setAction(MessageCompose.ACTION_COMPOSE);
return PendingIntent.getActivity(context, 0, intent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE);
}
}

View File

@ -0,0 +1,9 @@
package com.fsck.k9.widget.list
import app.k9mail.ui.widget.list.MessageListWidgetConfig
class MessageListWidgetProvider : app.k9mail.ui.widget.list.MessageListWidgetProvider()
internal class K9MessageListWidgetConfig : MessageListWidgetConfig {
override val providerClass = MessageListWidgetProvider::class.java
}

View File

@ -1,13 +0,0 @@
package com.fsck.k9.widget.list;
import android.content.Intent;
import android.widget.RemoteViewsService;
public class MessageListWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new MessageListRemoteViewFactory(getApplicationContext());
}
}

View File

@ -1,35 +0,0 @@
package com.fsck.k9.widget.list
import android.content.Context
import com.fsck.k9.Account
import com.fsck.k9.controller.SimpleMessagingListener
import com.fsck.k9.core.BuildConfig
import com.fsck.k9.mail.Message
import timber.log.Timber
class MessageListWidgetUpdateListener(private val context: Context) : SimpleMessagingListener() {
private fun updateMailListWidget() {
try {
MessageListWidgetProvider.triggerMessageListWidgetUpdate(context)
} catch (e: RuntimeException) {
if (BuildConfig.DEBUG) {
throw e
} else {
Timber.e(e, "Error while updating message list widget")
}
}
}
override fun synchronizeMailboxRemovedMessage(account: Account, folderServerId: String, messageServerId: String) {
updateMailListWidget()
}
override fun synchronizeMailboxNewMessage(account: Account, folderServerId: String, message: Message) {
updateMailListWidget()
}
override fun folderStatusChanged(account: Account, folderId: Long) {
updateMailListWidget()
}
}

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/loadingText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@android:color/black"
android:textSize="18sp" />
</LinearLayout>

View File

@ -78,7 +78,7 @@ class K9MessageStore(
updateMessageOperations.clearNewMessageState()
}
override fun getMessageServerId(messageId: Long): String {
override fun getMessageServerId(messageId: Long): String? {
return retrieveMessageOperations.getMessageServerId(messageId)
}

View File

@ -4,7 +4,6 @@ import androidx.core.database.getLongOrNull
import com.fsck.k9.K9
import com.fsck.k9.mail.Flag
import com.fsck.k9.mail.Header
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.internet.MimeHeader
import com.fsck.k9.mail.message.MessageHeaderParser
import com.fsck.k9.mailstore.LockableDatabase
@ -13,7 +12,7 @@ import java.util.Date
internal class RetrieveMessageOperations(private val lockableDatabase: LockableDatabase) {
fun getMessageServerId(messageId: Long): String {
fun getMessageServerId(messageId: Long): String? {
return lockableDatabase.execute(false) { database ->
database.query(
"messages",
@ -25,7 +24,7 @@ internal class RetrieveMessageOperations(private val lockableDatabase: LockableD
if (cursor.moveToFirst()) {
cursor.getString(0)
} else {
throw MessagingException("Message [ID: $messageId] not found in database")
null
}
}
}

View File

@ -2,7 +2,6 @@ package com.fsck.k9.storage.messages
import com.fsck.k9.mail.Flag
import com.fsck.k9.mail.Header
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mail.crlf
import com.fsck.k9.storage.RobolectricTest
import com.google.common.truth.Truth.assertThat
@ -14,9 +13,11 @@ class RetrieveMessageOperationsTest : RobolectricTest() {
private val lockableDatabase = createLockableDatabaseMock(sqliteDatabase)
private val retrieveMessageOperations = RetrieveMessageOperations(lockableDatabase)
@Test(expected = MessagingException::class)
@Test
fun `get message server id of non-existent message`() {
retrieveMessageOperations.getMessageServerId(42)
val messageServerId = retrieveMessageOperations.getMessageServerId(42)
assertThat(messageServerId).isNull()
}
@Test

View File

@ -696,6 +696,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
ComposeCryptoStatus cryptoStatus = recipientPresenter.getCurrentCachedCryptoStatus();
if (cryptoStatus == null) {
Timber.w("Couldn't retrieve crypto status; not creating MessageBuilder!");
return null;
}
@ -803,10 +804,9 @@ public class MessageCompose extends K9Activity implements OnClickListener,
return;
}
sendMessageHasBeenTriggered = true;
currentMessageBuilder = createMessageBuilder(false);
if (currentMessageBuilder != null) {
sendMessageHasBeenTriggered = true;
changesMadeSinceLastSave = false;
setProgressBarIndeterminateVisibility(true);
currentMessageBuilder.buildAsync(this);
@ -1701,7 +1701,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
@Override
public void startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent,
public boolean startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent,
int flagsMask, int flagValues, int extraFlags) {
try {
requestCode |= REQUEST_MASK_LOADER_HELPER;
@ -1709,6 +1709,8 @@ public class MessageCompose extends K9Activity implements OnClickListener,
} catch (SendIntentException e) {
Timber.e(e, "Irrecoverable error calling PendingIntent!");
}
return true;
}
@Override

View File

@ -424,31 +424,31 @@ open class MessageList :
private fun decodeExtrasToLaunchData(intent: Intent): LaunchData {
val action = intent.action
val data = intent.data
val queryString = intent.getStringExtra(SearchManager.QUERY)
if (action == Intent.ACTION_VIEW && data != null && data.pathSegments.size >= 3) {
val segmentList = data.pathSegments
val accountId = segmentList[0]
for (account in preferences.accounts) {
if (account.accountNumber.toString() == accountId) {
val folderId = segmentList[1].toLong()
val messageUid = segmentList[2]
val messageReference = MessageReference(account.uuid, folderId, messageUid)
return LaunchData(
search = messageReference.toLocalSearch(),
messageReference = messageReference,
messageViewOnly = true
)
}
}
} else if (action == ACTION_SHORTCUT) {
if (action == ACTION_SHORTCUT) {
// Handle shortcut intents
val specialFolder = intent.getStringExtra(EXTRA_SPECIAL_FOLDER)
if (SearchAccount.UNIFIED_INBOX == specialFolder) {
if (specialFolder == SearchAccount.UNIFIED_INBOX) {
return LaunchData(search = SearchAccount.createUnifiedInboxAccount().relatedSearch)
}
val accountUuid = intent.getStringExtra(EXTRA_ACCOUNT)
if (accountUuid != null) {
val account = preferences.getAccount(accountUuid)
if (account == null) {
Timber.d("Account %s not found.", accountUuid)
return LaunchData(createDefaultLocalSearch())
}
val folderId = defaultFolderProvider.getDefaultFolder(account)
val search = LocalSearch().apply {
addAccountUuid(accountUuid)
addAllowedFolder(folderId)
}
return LaunchData(search = search)
}
} else if (action == Intent.ACTION_SEARCH && queryString != null) {
// Query was received from Search Dialog
val query = queryString.trim()
@ -492,7 +492,8 @@ open class MessageList :
return LaunchData(
search = search,
messageReference = messageReference
messageReference = messageReference,
messageViewOnly = intent.getBooleanExtra(EXTRA_MESSAGE_VIEW_ONLY, false)
)
}
} else if (intent.hasExtra(EXTRA_SEARCH)) {
@ -504,24 +505,6 @@ open class MessageList :
}
return LaunchData(search = search, account = account, noThreading = noThreading)
} else if (intent.hasExtra("account")) {
val accountUuid = intent.getStringExtra("account")
if (accountUuid != null) {
// We've most likely been started by an old unread widget or accounts shortcut
val account = preferences.getAccount(accountUuid)
if (account == null) {
Timber.d("Account %s not found.", accountUuid)
return LaunchData(createDefaultLocalSearch())
}
val folderId = defaultFolderProvider.getDefaultFolder(account)
val search = LocalSearch().apply {
addAccountUuid(accountUuid)
addAllowedFolder(folderId)
}
return LaunchData(search = search)
}
}
// Default action
@ -1422,6 +1405,7 @@ open class MessageList :
private const val EXTRA_ACCOUNT = "account_uuid"
private const val EXTRA_MESSAGE_REFERENCE = "message_reference"
private const val EXTRA_MESSAGE_VIEW_ONLY = "message_view_only"
// used for remote search
const val EXTRA_SEARCH_ACCOUNT = "com.fsck.k9.search_account"
@ -1511,34 +1495,51 @@ open class MessageList :
@JvmStatic
fun shortcutIntentForAccount(context: Context?, account: Account): Intent {
val folderId = defaultFolderProvider.getDefaultFolder(account)
return Intent(context, MessageList::class.java).apply {
action = ACTION_SHORTCUT
putExtra(EXTRA_ACCOUNT, account.uuid)
val search = LocalSearch().apply {
addAccountUuid(account.uuid)
addAllowedFolder(folderId)
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
return intentDisplaySearch(context, search, noThreading = false, newTask = true, clearTop = true)
}
fun actionDisplayMessageIntent(
context: Context,
messageReference: MessageReference,
openInUnifiedInbox: Boolean = false
openInUnifiedInbox: Boolean = false,
messageViewOnly: Boolean = false
): Intent {
return actionDisplayMessageTemplateIntent(context, openInUnifiedInbox, messageViewOnly).apply {
putExtra(EXTRA_MESSAGE_REFERENCE, messageReference.toIdentityString())
}
}
fun actionDisplayMessageTemplateIntent(
context: Context,
openInUnifiedInbox: Boolean,
messageViewOnly: Boolean
): Intent {
return Intent(context, MessageList::class.java).apply {
putExtra(EXTRA_MESSAGE_REFERENCE, messageReference.toIdentityString())
if (openInUnifiedInbox) {
val search = SearchAccount.createUnifiedInboxAccount().relatedSearch
putExtra(EXTRA_SEARCH, ParcelableUtil.marshall(search))
}
putExtra(EXTRA_MESSAGE_VIEW_ONLY, messageViewOnly)
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
}
fun actionDisplayMessageTemplateFillIntent(messageReference: MessageReference): Intent {
return Intent().apply {
putExtra(EXTRA_MESSAGE_REFERENCE, messageReference.toIdentityString())
}
}
@JvmStatic
fun launch(context: Context) {
val intent = Intent(context, MessageList::class.java).apply {

View File

@ -142,6 +142,12 @@ public class MessageLoaderHelper {
startOrResumeLocalMessageLoader();
}
public void resumeCryptoOperationIfNecessary() {
if (messageCryptoHelper != null) {
messageCryptoHelper.resumeCryptoOperationIfNecessary();
}
}
@UiThread
public void asyncRestartMessageCryptoProcessing() {
cancelAndClearCryptoOperation();
@ -351,13 +357,13 @@ public class MessageLoaderHelper {
}
@Override
public void startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent,
public boolean startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent,
int flagsMask, int flagValues, int extraFlags) {
if (callback == null) {
throw new IllegalStateException("unexpected call when callback is already detached");
}
callback.startIntentSenderForMessageLoaderHelper(si, requestCode, fillIntent,
return callback.startIntentSenderForMessageLoaderHelper(si, requestCode, fillIntent,
flagsMask, flagValues, extraFlags);
}
};
@ -518,8 +524,8 @@ public class MessageLoaderHelper {
void setLoadingProgress(int current, int max);
void startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent, int flagsMask,
int flagValues, int extraFlags);
boolean startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent,
int flagsMask, int flagValues, int extraFlags);
void onDownloadErrorMessageNotFound();
void onDownloadErrorNetworkError();

View File

@ -53,9 +53,7 @@ class ReplyToPresenter(private val view: ReplyToView) {
}
fun onNonRecipientFieldFocused() {
if (view.isVisible && view.getAddresses().isEmpty()) {
view.isVisible = false
}
view.hideIfBlank()
}
fun onSaveInstanceState(outState: Bundle) {

View File

@ -14,7 +14,7 @@ import com.fsck.k9.view.RecipientSelectView.Recipient
private const val VIEW_INDEX_REPLY_TO_EXPANDER_VISIBLE = 0
private const val VIEW_INDEX_REPLY_TO_EXPANDER_HIDDEN = 1
class ReplyToView(activity: MessageCompose) : View.OnClickListener {
class ReplyToView(activity: MessageCompose) {
private val replyToView: RecipientSelectView = activity.findViewById(R.id.reply_to)
private val replyToWrapper: View = activity.findViewById(R.id.reply_to_wrapper)
private val replyToDivider: View = activity.findViewById(R.id.reply_to_divider)
@ -24,29 +24,33 @@ class ReplyToView(activity: MessageCompose) : View.OnClickListener {
private val textWatchers = mutableSetOf<TextWatcher>()
init {
replyToExpander.setOnClickListener(this)
activity.findViewById<View>(R.id.reply_to_label).setOnClickListener(this)
replyToExpander.setOnClickListener {
isVisible = true
replyToView.requestFocus()
}
activity.findViewById<View>(R.id.reply_to_label).setOnClickListener {
replyToView.requestFocus()
}
}
var isVisible: Boolean
get() = replyToView.isVisible
get() = replyToWrapper.isVisible
set(visible) {
replyToDivider.isVisible = visible
replyToView.isVisible = visible
replyToWrapper.isVisible = visible
if (visible && replyToExpanderContainer.displayedChild == VIEW_INDEX_REPLY_TO_EXPANDER_VISIBLE) {
replyToView.requestFocus()
replyToExpanderContainer.displayedChild = VIEW_INDEX_REPLY_TO_EXPANDER_HIDDEN
} else if (replyToExpanderContainer.displayedChild == VIEW_INDEX_REPLY_TO_EXPANDER_HIDDEN) {
replyToExpanderContainer.displayedChild = VIEW_INDEX_REPLY_TO_EXPANDER_VISIBLE
}
}
override fun onClick(view: View) {
when (view.id) {
R.id.reply_to_expander -> isVisible = true
R.id.reply_to_label -> replyToView.requestFocus()
fun hideIfBlank() {
if (isVisible && replyToView.text.isBlank()) {
isVisible = false
}
}

View File

@ -17,7 +17,6 @@ import com.fsck.k9.Preferences
import com.fsck.k9.account.AccountCreator
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection
import com.fsck.k9.autodiscovery.api.DiscoveredServerSettings
import com.fsck.k9.autodiscovery.api.DiscoveryTarget
import com.fsck.k9.autodiscovery.providersxml.ProvidersXmlDiscovery
import com.fsck.k9.helper.SimpleTextWatcher
import com.fsck.k9.helper.Utility.requiredFieldValid
@ -311,7 +310,7 @@ class AccountSetupBasics : K9Activity() {
}
private fun providersXmlDiscoveryDiscover(email: String): ConnectionSettings? {
val discoveryResults = providersXmlDiscovery.discover(email, DiscoveryTarget.INCOMING_AND_OUTGOING)
val discoveryResults = providersXmlDiscovery.discover(email)
if (discoveryResults == null || discoveryResults.incoming.isEmpty() || discoveryResults.outgoing.isEmpty()) {
return null
}

View File

@ -10,6 +10,6 @@ import com.fsck.k9.mailstore.MessageCryptoAnnotations;
public interface MessageCryptoCallback {
void onCryptoHelperProgress(int current, int max);
void onCryptoOperationsFinished(MessageCryptoAnnotations annotations);
void startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent,
boolean startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent,
int flagsMask, int flagValues, int extraFlags);
}

View File

@ -120,6 +120,12 @@ public class MessageCryptoHelper {
nextStep();
}
public void resumeCryptoOperationIfNecessary() {
if (queuedPendingIntent != null) {
deliverResult();
}
}
private void findPartsForMultipartEncryptionPass() {
List<Part> encryptedParts = MessageCryptoStructureDetector.findMultipartEncryptedParts(currentMessage);
for (Part part : encryptedParts) {
@ -765,9 +771,11 @@ public class MessageCryptoHelper {
if (queuedResult != null) {
callback.onCryptoOperationsFinished(queuedResult);
} else if (queuedPendingIntent != null) {
callback.startPendingIntentForCryptoHelper(
boolean pendingIntentHandled = callback.startPendingIntentForCryptoHelper(
queuedPendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION, null, 0, 0, 0);
queuedPendingIntent = null;
if (pendingIntentHandled) {
queuedPendingIntent = null;
}
} else {
throw new IllegalStateException("deliverResult() called with no result!");
}

View File

@ -162,13 +162,14 @@ class MessageListAdapter internal constructor(
}
private val messageClickedListener = OnClickListener { view: View ->
val messageListItem = getItemFromView(view)
val messageListItem = getItemFromView(view) ?: return@OnClickListener
listItemListener.onMessageClicked(messageListItem)
}
private val messageLongClickedListener = OnLongClickListener { view: View ->
val messageListItem = getItemFromView(view)
listItemListener.onToggleMessageSelection(messageListItem)
getItemFromView(view)?.let { messageListItem ->
listItemListener.onToggleMessageSelection(messageListItem)
}
true
}
@ -177,13 +178,13 @@ class MessageListAdapter internal constructor(
}
private val flagClickListener = OnClickListener { view: View ->
val messageListItem = getItemFromView(view)
val messageListItem = getItemFromView(view) ?: return@OnClickListener
listItemListener.onToggleMessageFlag(messageListItem)
}
private val contactPictureClickListener = OnClickListener { view: View ->
val parentView = view.parent.parent as View
val messageListItem = getItemFromView(parentView)
val messageListItem = getItemFromView(parentView) ?: return@OnClickListener
listItemListener.onToggleMessageSelection(messageListItem)
}
@ -516,9 +517,9 @@ class MessageListAdapter internal constructor(
.sumOf { it.threadCount.coerceAtLeast(1) }
}
private fun getItemFromView(view: View): MessageListItem {
private fun getItemFromView(view: View): MessageListItem? {
val messageViewHolder = view.tag as MessageViewHolder
return getItemById(messageViewHolder.uniqueId) ?: error("Couldn't find MessageListItem by View")
return getItemById(messageViewHolder.uniqueId)
}
}

View File

@ -92,10 +92,10 @@ class MessageListSwipeCallback(
val swipeThresholdReached = abs(dX) > swipeThreshold
if (swipeThresholdReached) {
val action = if (dX > 0) swipeRightAction else swipeLeftAction
val backgroundColor = resourceProvider.getBackgroundColor(item, action)
val backgroundColor = resourceProvider.getBackgroundColor(action)
drawBackground(view, backgroundColor)
} else {
val backgroundColor = resourceProvider.getBackgroundColor(item, SwipeAction.None)
val backgroundColor = resourceProvider.getBackgroundColor(SwipeAction.None)
drawBackground(view, backgroundColor)
}
@ -137,7 +137,13 @@ class MessageListSwipeCallback(
val iconBottom = iconTop + icon.intrinsicHeight
icon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
icon.setTint(resourceProvider.getIconTint(item, swipeRightAction, swipeThresholdReached))
val iconTint = if (swipeThresholdReached) {
resourceProvider.iconTint
} else {
resourceProvider.getBackgroundColor(swipeRightAction)
}
icon.setTint(iconTint)
icon.draw(this)
}
}
@ -150,7 +156,13 @@ class MessageListSwipeCallback(
val iconBottom = iconTop + icon.intrinsicHeight
icon.setBounds(iconLeft, iconTop, iconRight, iconBottom)
icon.setTint(resourceProvider.getIconTint(item, swipeLeftAction, swipeThresholdReached))
val iconTint = if (swipeThresholdReached) {
resourceProvider.iconTint
} else {
resourceProvider.getBackgroundColor(swipeLeftAction)
}
icon.setTint(iconTint)
icon.draw(this)
}
}

View File

@ -9,7 +9,7 @@ import com.fsck.k9.ui.resolveColorAttribute
import com.fsck.k9.ui.resolveDrawableAttribute
class SwipeResourceProvider(val theme: Theme) {
private val iconTint = theme.resolveColorAttribute(R.attr.messageListSwipeIconTint)
val iconTint = theme.resolveColorAttribute(R.attr.messageListSwipeIconTint)
private val selectIcon = theme.loadDrawable(R.attr.messageListSwipeSelectIcon)
private val markAsReadIcon = theme.loadDrawable(R.attr.messageListSwipeMarkAsReadIcon)
@ -23,23 +23,13 @@ class SwipeResourceProvider(val theme: Theme) {
private val noActionColor = theme.resolveColorAttribute(R.attr.messageListSwipeDisabledBackgroundColor)
private val selectColor = theme.resolveColorAttribute(R.attr.messageListSwipeSelectBackgroundColor)
private val markAsReadColor = theme.resolveColorAttribute(R.attr.messageListSwipeMarkAsReadBackgroundColor)
private val markAsUnreadColor = theme.resolveColorAttribute(R.attr.messageListSwipeMarkAsUnreadBackgroundColor)
private val addStarColor = theme.resolveColorAttribute(R.attr.messageListSwipeAddStarBackgroundColor)
private val removeStarColor = theme.resolveColorAttribute(R.attr.messageListSwipeRemoveStarBackgroundColor)
private val toggleReadColor = theme.resolveColorAttribute(R.attr.messageListSwipeToggleReadBackgroundColor)
private val toggleStarColor = theme.resolveColorAttribute(R.attr.messageListSwipeToggleStarBackgroundColor)
private val archiveColor = theme.resolveColorAttribute(R.attr.messageListSwipeArchiveBackgroundColor)
private val deleteColor = theme.resolveColorAttribute(R.attr.messageListSwipeDeleteBackgroundColor)
private val spamColor = theme.resolveColorAttribute(R.attr.messageListSwipeSpamBackgroundColor)
private val moveColor = theme.resolveColorAttribute(R.attr.messageListSwipeMoveBackgroundColor)
fun getIconTint(item: MessageListItem, action: SwipeAction, swipeThresholdReached: Boolean): Int {
return if (swipeThresholdReached) {
iconTint
} else {
getBackgroundColor(item, action)
}
}
fun getIcon(item: MessageListItem, action: SwipeAction): Drawable? {
return when (action) {
SwipeAction.None -> null
@ -53,12 +43,12 @@ class SwipeResourceProvider(val theme: Theme) {
}
}
fun getBackgroundColor(item: MessageListItem, action: SwipeAction): Int {
fun getBackgroundColor(action: SwipeAction): Int {
return when (action) {
SwipeAction.None -> noActionColor
SwipeAction.ToggleSelection -> selectColor
SwipeAction.ToggleRead -> if (item.isRead) markAsUnreadColor else markAsReadColor
SwipeAction.ToggleStar -> if (item.isStarred) removeStarColor else addStarColor
SwipeAction.ToggleRead -> toggleReadColor
SwipeAction.ToggleStar -> toggleStarColor
SwipeAction.Archive -> archiveColor
SwipeAction.Delete -> deleteColor
SwipeAction.Spam -> spamColor

View File

@ -149,20 +149,19 @@ class MessageViewContainerFragment : Fragment() {
}
private fun setActiveMessage(position: Int) {
// If the position of current message changes (e.g. because messages were added or removed from the list), we
// keep track of the new position but otherwise ignore the event.
val newMessageReference = adapter.getMessageReference(position)
val newMessageReference = adapter.getMessageReference(position) ?: return
if (newMessageReference == activeMessageReference) {
// If the position of current message changes (e.g. because messages were added or removed from the list),
// we keep track of the new position but otherwise ignore the event.
currentPosition = position
return
}
rememberNavigationDirection(position)
messageReference = adapter.getMessageReference(position)
activeMessageReference = messageReference
fragmentListener.setActiveMessage(messageReference)
messageReference = newMessageReference
activeMessageReference = newMessageReference
fragmentListener.setActiveMessage(newMessageReference)
}
private fun rememberNavigationDirection(newPosition: Int) {
@ -176,9 +175,7 @@ class MessageViewContainerFragment : Fragment() {
val newPosition = viewPager.currentItem - 1
return if (newPosition >= 0) {
setActiveMessage(newPosition)
val smoothScroll = true
viewPager.setCurrentItem(newPosition, smoothScroll)
viewPager.setCurrentItem(newPosition, /* smoothScroll = */ false)
true
} else {
false
@ -189,9 +186,7 @@ class MessageViewContainerFragment : Fragment() {
val newPosition = viewPager.currentItem + 1
return if (newPosition < adapter.itemCount) {
setActiveMessage(newPosition)
val smoothScroll = true
viewPager.setCurrentItem(newPosition, smoothScroll)
viewPager.setCurrentItem(newPosition, /* smoothScroll = */ false)
true
} else {
false
@ -273,10 +268,8 @@ class MessageViewContainerFragment : Fragment() {
return MessageViewFragment.newInstance(messageReference, showAccountChip)
}
fun getMessageReference(position: Int): MessageReference {
check(position in messageList.indices)
return messageList[position].messageReference
fun getMessageReference(position: Int): MessageReference? {
return messageList.getOrNull(position)?.messageReference
}
fun getPosition(messageReference: MessageReference): Int {

View File

@ -92,6 +92,9 @@ class MessageViewFragment :
private var isDeleteMenuItemDisabled: Boolean = false
private var wasMessageMarkedAsOpened: Boolean = false
private var isActive: Boolean = false
private set
override fun onAttach(context: Context) {
super.onAttach(context)
@ -105,6 +108,12 @@ class MessageViewFragment :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Hide the toolbar menu when first creating this fragment. The menu will be set to visible once this fragment
// becomes the active page of the view pager in MessageViewContainerFragment.
if (savedInstanceState == null) {
setMenuVisibility(false)
}
setHasOptionsMenu(true)
messageReference = MessageReference.parse(arguments?.getString(ARG_REFERENCE))
@ -181,11 +190,15 @@ class MessageViewFragment :
}
override fun setMenuVisibility(menuVisible: Boolean) {
isActive = menuVisible
super.setMenuVisibility(menuVisible)
// When the menu is hidden, the message associated with this fragment is no longer active. If the user returns
// to it, we want to mark the message as opened again.
if (!menuVisible) {
if (menuVisible) {
messageLoaderHelper.resumeCryptoOperationIfNecessary()
} else {
// When the menu is hidden, the message associated with this fragment is no longer active. If the user returns
// to it, we want to mark the message as opened again.
wasMessageMarkedAsOpened = false
}
}
@ -207,6 +220,8 @@ class MessageViewFragment :
}
override fun onPrepareOptionsMenu(menu: Menu) {
if (!isActive) return
menu.findItem(R.id.delete).apply {
isVisible = K9.isMessageViewDeleteActionVisible
isEnabled = !isDeleteMenuItemDisabled
@ -893,7 +908,9 @@ class MessageViewFragment :
flagsMask: Int,
flagValues: Int,
extraFlags: Int
) {
): Boolean {
if (!isActive) return false
showProgressThreshold = null
try {
val maskedRequestCode = requestCode or REQUEST_MASK_LOADER_HELPER
@ -903,6 +920,8 @@ class MessageViewFragment :
} catch (e: SendIntentException) {
Timber.e(e, "Irrecoverable error calling PendingIntent!")
}
return true
}
}

View File

@ -5,6 +5,13 @@
Locale-specific versions are kept in res/raw-<locale qualifier>/changelog.xml.
-->
<changelog>
<release version="6.310" versioncode="33010" date="2022-10-24">
<change>Fixed "K-9 Accounts" shortcuts (you probably have to remove existing shortcuts and add them again)</change>
<change>Fixed a couple of bugs and display issues in the message list widget</change>
<change>Fixed bug that could lead to a crypto provider popup showing before swiping to the next/previous message was completed</change>
<change>Some other minor bug fixes</change>
<change>Updated translations</change>
</release>
<release version="6.309" versioncode="33009" date="2022-10-12">
<change>Automatically scroll to the top after using pull to refresh, so new messages are visible</change>
<change>Fixed a bug that prevented the app from establishing a connection to the outgoing server under certain circumstances</change>

View File

@ -755,7 +755,10 @@
<string name="unsigned_text_divider_label">نص غير مُوَقَّع</string>
<string name="crypto_no_provider_title">هذه الرسالة مُعماة</string>
<string name="mail_list_widget_text">قائمة رسائل K-9</string>
<string name="mail_list_widget_loading">يُحمل الرسائل…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">يُحمل…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">يُحمل…</string>
<string name="openpgp_enabled_error_title">التعمية غير ممكنة</string>
<string name="enable_encryption">تنشيط التعمية</string>
<string name="disable_encryption">تعطيل التعمية</string>

View File

@ -944,7 +944,10 @@ K-9 Mail - шматфункцыянальны свабодны паштовы к
<string name="crypto_no_provider_message">Ліст зашыфраваны OpenPGP\nКаб прачытаць, неабходна ўсталяваць і наладзіць праграму OpenPGP.</string>
<string name="crypto_no_provider_button">Перайсці ў налады</string>
<string name="mail_list_widget_text">Лісты K-9</string>
<string name="mail_list_widget_loading">Загрузка лістоў…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Загрузка…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Загрузка…</string>
<string name="openpgp_enabled_error_title">Зашыфраваць немагчыма</string>
<string name="openpgp_enabled_error_msg">Некаторыя з гэтых адрасатаў не падтрымліваюць такую функцыю!</string>
<string name="enable_encryption">Уключыць шыфраванне</string>

View File

@ -931,7 +931,10 @@ K-9 Mail е мощен, безплатен имейл клиент за Андр
<string name="crypto_no_provider_message">Този имейл е криптиран използвайки OpenPGP.\nЗа да го прочетете, трябва да инсталирате и настроите OpenPGP приложението.</string>
<string name="crypto_no_provider_button">Към настройки</string>
<string name="mail_list_widget_text">K-9 списък със собщения</string>
<string name="mail_list_widget_loading">Зареждане на съобщения…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Зареждане…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Зареждане…</string>
<string name="openpgp_enabled_error_title">Криптирането е невъзможно</string>
<string name="openpgp_enabled_error_msg">Някои от избраните получатели не поддържат тази функция!</string>
<string name="enable_encryption">Включване на криптирането</string>

View File

@ -885,7 +885,10 @@ Danevellit beugoù, kenlabourit war keweriusterioù nevez ha savit goulennoù wa
<string name="crypto_no_provider_message">Enrineget eo bet ar postel-mañ gant OpenPGP.\nEvit gallout e lenn e rankit staliañ ha kefluniañ un arload OpenPGP keverlech.</string>
<string name="crypto_no_provider_button">Mont d\'an arventennoù</string>
<string name="mail_list_widget_text">Roll kemennadennoù K-9</string>
<string name="mail_list_widget_loading">O kargañ kemennadennoù…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">O kargañ…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">O kargañ…</string>
<string name="openpgp_enabled_error_title">Neo ket posupl enrinegañ</string>
<string name="openpgp_enabled_error_msg">Ul lodenn eus an degemererien ne skoront ket ar cheweriuster-mañ!</string>
<string name="enable_encryption">Gweredekaat an enrinegañ</string>

View File

@ -218,7 +218,7 @@ Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu p
<string name="message_compose_show_quoted_text_action">Inclou el missatge citat</string>
<string name="message_compose_description_delete_quoted_text">Elimina el text citat</string>
<string name="message_compose_description_edit_quoted_text">Edita el text citat</string>
<string name="remove_attachment_action">Suprimeix l\'adjunt</string>
<string name="remove_attachment_action">Elimina l\'adjunt</string>
<string name="message_view_from_format">De: <xliff:g id="name">%1$s</xliff:g> &lt;<xliff:g id="email">%2$s</xliff:g>&gt;</string>
<string name="message_to_label">A:</string>
<string name="message_view_cc_label">A/c:</string>
@ -261,13 +261,19 @@ Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu p
<string name="global_settings_confirm_menu_mark_all_read">Marca tots els missatges com a llegits</string>
<string name="global_settings_confirm_action_delete_notif">Elimina (des de notificacions)</string>
<!--Title of the screen to configure swipe actions-->
<string name="general_settings_swipe_actions_title">Accions lliscants</string>
<!--Name of the setting to configure the right swipe action-->
<string name="general_settings_right_swipe_title">Llisca a la dreta</string>
<!--Name of the setting to configure the left swipe action-->
<string name="general_settings_left_swipe_title">Llisca a l\'esquerra</string>
<!--The list item users select to not use a swipe action for a particular direction-->
<string name="general_settings_swipe_action_none">Cap</string>
<!--Name of the swipe action to select/deselect a message-->
<string name="general_settings_swipe_action_toggle_selection">Commuta la selecció</string>
<!--Name of the swipe action to mark as message as read/unread-->
<string name="general_settings_swipe_action_toggle_read">Marca-ho com a llegit / no llegit</string>
<!--Name of the swipe action to add/remove a star-->
<string name="general_settings_swipe_action_toggle_star">Elimina / afegeix un estel</string>
<!--Name of the swipe action to archive a message-->
<string name="general_settings_swipe_action_archive">Arxiva</string>
<!--Name of the swipe action to delete a message-->
@ -277,7 +283,7 @@ Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu p
<!--Name of the swipe action to move a message to another folder-->
<string name="general_settings_swipe_action_move">Mou</string>
<string name="global_settings_privacy_hide_useragent">Amaga el client de correu</string>
<string name="global_settings_privacy_hide_useragent_detail">Suprimeix el nom K-9 User-Agent de les capçaleres del missatge</string>
<string name="global_settings_privacy_hide_useragent_detail">Elimina el nom K-9 User-Agent de les capçaleres del missatge</string>
<string name="global_settings_privacy_hide_timezone">Amaga el fus horari</string>
<string name="global_settings_privacy_hide_timezone_detail">Fes servir UTC en comptes de l\'hora local a les capçaleres dels missatges i a la capçalera de resposta</string>
<string name="global_settings_notification_quick_delete_title">Mostra el botó \"Elimina\"</string>
@ -438,8 +444,8 @@ Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu p
<string name="account_settings_ignore_chat_messages_summary">No mostris notificacions de missatges pertanyents a una conversa de correu electrònic.</string>
<string name="account_settings_mark_message_as_read_on_view_label">Marca el missatge obert com a llegit</string>
<string name="account_settings_mark_message_as_read_on_view_summary">Marca el missatge com a llegit després d\'haver-lo obert.</string>
<string name="account_settings_mark_message_as_read_on_delete_label">Marca com a llegit quan se suprimeixi</string>
<string name="account_settings_mark_message_as_read_on_delete_summary">Marca un missatge com a llegit quan se suprimeix.</string>
<string name="account_settings_mark_message_as_read_on_delete_label">Marca com a llegit quan s\'elimini.</string>
<string name="account_settings_mark_message_as_read_on_delete_summary">Marca un missatge com a llegit quan s\'elimini.</string>
<string name="account_settings_notification_channels_label">Categories de notificacions</string>
<string name="account_settings_open_notification_settings_messages_summary">Configureu les notificacions per als missatges nous</string>
<string name="account_settings_open_notification_settings_miscellaneous_summary">Configureu les notificacions per als errors i l\'estat</string>
@ -749,7 +755,7 @@ Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu p
<string name="confirm_discard_draft_message_title">Descarto el missatge?</string>
<string name="confirm_discard_draft_message">Segur que voleu descartar aquest missatge?</string>
<string name="dialog_confirm_clear_local_folder_title">Voleu netejar els missatges locals?</string>
<string name="dialog_confirm_clear_local_folder_message">Això suprimirà tots els missatges locals de la carpeta. No se suprimirà cap missatge del servidor.</string>
<string name="dialog_confirm_clear_local_folder_message">Això eliminarà tots els missatges locals de la carpeta. No s\'eliminarà cap missatge del servidor.</string>
<string name="dialog_confirm_clear_local_folder_action">Neteja els missatges</string>
<string name="dialog_confirm_delete_title">Confirmeu l\'eliminació</string>
<string name="dialog_confirm_delete_message">Voleu eliminar aquest missatge?</string>
@ -994,7 +1000,10 @@ Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu p
<string name="crypto_no_provider_message">Aquest missatge ha estat encriptat amb OpenPGP.\nPer llegir-lo, us caldrà instal·lar i configurar una aplicació d\'OpenPGP compatible.</string>
<string name="crypto_no_provider_button">Ves a la configuració</string>
<string name="mail_list_widget_text">Llista de missatges del K-9</string>
<string name="mail_list_widget_loading">S\'està carregant missatges…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">S\'està carregant…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">S\'està carregant…</string>
<string name="openpgp_enabled_error_title">Encriptació no possible</string>
<string name="openpgp_enabled_error_msg">Alguns dels destinataris seleccionats no admeten aquesta característica!</string>
<string name="enable_encryption">Habilita l\'encriptació</string>

View File

@ -1007,7 +1007,10 @@ Hlášení o chyb, úpravy pro nové funkce a dotazy zadávejte prostřednictví
<string name="crypto_no_provider_message">Tento email byl zašifrovaný pomocí OpenPGP.\nAbyste si ho mohl/a přečíst, potřebujete si nainstalovat a nakonfigurovat kompatibilní OpenPGP aplikaci.</string>
<string name="crypto_no_provider_button">Přejít do nastavení</string>
<string name="mail_list_widget_text">Seznam zpráv K-9</string>
<string name="mail_list_widget_loading">Načítání zpráv…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Načítání…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Načítání…</string>
<string name="openpgp_enabled_error_title">Šifrování není možné</string>
<string name="openpgp_enabled_error_msg">Někteří ze zvolených příjemců nepodporují tuto funkci!</string>
<string name="enable_encryption">Zapnout šifrování</string>

View File

@ -1009,7 +1009,10 @@ Plîs rho wybod am unrhyw wallau, syniadau am nodweddion newydd, neu ofyn cwesti
<string name="crypto_no_provider_message">Mae\'r neges e-bost hon wedi ei amgryptio gydag OpenPGP.\nI\'w darllen, rhaid gosod a ffurfweddu ap OpenPGP sy\'n cydweddu.</string>
<string name="crypto_no_provider_button">Mynd i Osodiadau</string>
<string name="mail_list_widget_text">Rhestr Negeseuon K-9</string>
<string name="mail_list_widget_loading">Yn llwytho negeseuon…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Yn llwytho…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Yn llwytho…</string>
<string name="openpgp_enabled_error_title">Dyw amgryptiad ddim ar gael.</string>
<string name="openpgp_enabled_error_msg">Dyw rhai o\'r derbynnwyr ddim yn cefnogi\'r nodwedd hon.</string>
<string name="enable_encryption">Galluogi amgryptio</string>

View File

@ -960,7 +960,10 @@ Rapporter venligst fejl, forslag til nye funktioner eller stil spørgsmål på:
<string name="crypto_no_provider_message">Denne email er krypteret med OpenPGP.\nFor at læse den skal du installere en kompatibel OpenPGP applikation.</string>
<string name="crypto_no_provider_button">Gå til opsætning</string>
<string name="mail_list_widget_text">K-9 Meddelelsesliste</string>
<string name="mail_list_widget_loading">Indlæser meddelelser…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Indlæser…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Indlæser…</string>
<string name="openpgp_enabled_error_title">Kryptering var ikke mulig</string>
<string name="openpgp_enabled_error_msg">Nogle af de valgte modtagere understøtter ikke denne funktion!</string>
<string name="enable_encryption">Aktivér kryptering</string>

View File

@ -254,7 +254,7 @@ Bitte senden Sie Fehlerberichte, Ideen für neue Funktionen und stellen Sie Frag
<string name="global_settings_confirm_actions_title">Bestätigungsdialog</string>
<string name="global_settings_confirm_actions_summary">Bei Ausführung der ausgewählten Aktionen einen Bestätigungsdialog anzeigen</string>
<string name="global_settings_confirm_action_delete">Löschen</string>
<string name="global_settings_confirm_action_delete_starred">Als wichtig markiert löschen (nur in Nachrichtenansicht)</string>
<string name="global_settings_confirm_action_delete_starred">Als wichtig markierte (aus Nachrichtenansicht) löschen</string>
<string name="global_settings_confirm_action_spam">Spam</string>
<string name="global_settings_confirm_menu_discard">Nachricht verwerfen</string>
<string name="global_settings_confirm_menu_mark_all_read">Alle Nachrichten als gelesen markieren</string>
@ -702,7 +702,7 @@ Bitte senden Sie Fehlerberichte, Ideen für neue Funktionen und stellen Sie Frag
<string name="account_setup_push_limit_1000">1000 Ordner</string>
<string name="animations_title">Animationen</string>
<string name="animations_summary">Aufwendige visuelle Effekte benutzen</string>
<string name="volume_navigation_title">Navigation per Lautstärketasten in der Nachrichtenansicht</string>
<string name="volume_navigation_title">Per Lautstärketasten durch Nachrichtenansicht navigieren</string>
<string name="show_unified_inbox_title">Gemeinsamen Posteingang anzeigen</string>
<string name="show_starred_count_title">Anzahl der wichtigen Nachrichten anzeigen</string>
<string name="integrated_inbox_title">Gemeinsamer Posteingang</string>
@ -1001,7 +1001,10 @@ Bitte senden Sie Fehlerberichte, Ideen für neue Funktionen und stellen Sie Frag
Um sie zu lesen, muss eine kompatible OpenPGP-App installiert und konfiguriert werden.</string>
<string name="crypto_no_provider_button">Zu den Einstellungen</string>
<string name="mail_list_widget_text">K-9 Nachrichtenliste</string>
<string name="mail_list_widget_loading">Nachrichten werden geladen…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Ladevorgang…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Ladevorgang…</string>
<string name="openpgp_enabled_error_title">Verschlüsselung nicht möglich</string>
<string name="openpgp_enabled_error_msg">Einige der ausgewählten Empfänger unterstützen diese Funktion nicht!</string>
<string name="enable_encryption">Verschlüsselung aktivieren</string>

View File

@ -995,7 +995,10 @@
<string name="crypto_no_provider_message">Αυτό το μήνυμα έχει κρυπτογραφηθεί με το OpenPGP.\nΓια να το διαβάσετε, πρέπει να εγκαταστήσετε και να ρυθμίσετε τις παραμέτρους μιας συμβατής εφαρμογής OpenPGP.</string>
<string name="crypto_no_provider_button">Μετάβαση στις Ρυθμίσεις</string>
<string name="mail_list_widget_text">Λίστα Μηνυμάτων του K-9</string>
<string name="mail_list_widget_loading">Φόρτωση μηνυμάτων…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Φόρτωση…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Φόρτωση…</string>
<string name="openpgp_enabled_error_title">Δεν είναι δυνατή η κρυπτογράφηση</string>
<string name="openpgp_enabled_error_msg">Ορισμένοι από τους επιλεγμένους παραλήπτες δεν υποστηρίζουν αυτήν τη δυνατότητα!</string>
<string name="enable_encryption">Ενεργοποίηση Κρυπτογράφησης</string>

View File

@ -46,5 +46,7 @@
<!--=== Client certificates specific ==================================================================-->
<!--Note: This references message_view_download_remainder-->
<string name="error_crypto_provider_ui_required">Failed to initialise end-to-end encryption, please check your settings</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<!--permissions-->
</resources>

View File

@ -950,7 +950,10 @@ Bonvolu raporti erarojn, kontribui novajn eblojn kaj peti pri novaj funkcioj per
<string name="crypto_no_provider_message">Tiu ĉi retletero estas ĉifrita per OpenPGP.\nPor legi ĝin, vi devas instali kaj agordi kongruan OpenPGP-aplikaĵon.</string>
<string name="crypto_no_provider_button">Iri al agordoj</string>
<string name="mail_list_widget_text">K-9 mesaĝlisto</string>
<string name="mail_list_widget_loading">Ŝargado de mesaĝoj…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Ŝargado…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Ŝargado…</string>
<string name="openpgp_enabled_error_title">Ĉifrado ne eblas</string>
<string name="openpgp_enabled_error_msg">Kelkaj da elektitaj ricevontoj ne subtenas tiun ĉi agordon!</string>
<string name="enable_encryption">Aktivigi ĉifradon</string>

View File

@ -1005,7 +1005,10 @@ Puedes informar de fallos, contribuir con su desarrollo y hacer preguntas en <a
<string name="crypto_no_provider_message">Este correo ha sido cifrado con OpenPGP.\nPara leerlo es necesario instalar y configurar una aplicación compatible con OpenPGP.</string>
<string name="crypto_no_provider_button">Ir a los ajustes</string>
<string name="mail_list_widget_text">Lista de mensajes de K-9</string>
<string name="mail_list_widget_loading">Cargando mensajes…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Cargando…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Cargando…</string>
<string name="openpgp_enabled_error_title">No es posible cifrar</string>
<string name="openpgp_enabled_error_msg">Algunos de los remitentes marcados no entienden esta característica</string>
<string name="enable_encryption">Activar cifrado</string>

View File

@ -996,7 +996,10 @@ Veateated saad saata, kaastööd teha ning küsida teavet järgmisel lehel:
<string name="crypto_no_provider_message">Selle kirja krüptimisel on kasutusel OpenPGP.\nKirjalugemsieks palun paigalda ja seadista sobilik OpenPGP rakendus.</string>
<string name="crypto_no_provider_button">Ava sätted</string>
<string name="mail_list_widget_text">K-9 kirjade loend</string>
<string name="mail_list_widget_loading">Kirjade laadimine…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Laadib…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Laadib…</string>
<string name="openpgp_enabled_error_title">Krüpteerimine poe võimalik</string>
<string name="openpgp_enabled_error_msg">Mõned kirja saajad ei saa seda funktsionaalsust kasutada!</string>
<string name="enable_encryption">Võimalda krüpteerimine</string>

View File

@ -260,13 +260,19 @@ Mesedez akatsen berri emateko, ezaugarri berriak gehitzeko eta galderak egiteko
<string name="global_settings_confirm_menu_mark_all_read">Markatu mezu guztiak irakurritako gisa</string>
<string name="global_settings_confirm_action_delete_notif">Ezabatu (jakinarazpenetatik)</string>
<!--Title of the screen to configure swipe actions-->
<string name="general_settings_swipe_actions_title">Hatza pasatzearen ekintzak </string>
<!--Name of the setting to configure the right swipe action-->
<string name="general_settings_right_swipe_title">Pasatu hatza eskubirantz</string>
<!--Name of the setting to configure the left swipe action-->
<string name="general_settings_left_swipe_title">Pasatu hatza ezkerrerantz</string>
<!--The list item users select to not use a swipe action for a particular direction-->
<string name="general_settings_swipe_action_none">Bat ere ez</string>
<!--Name of the swipe action to select/deselect a message-->
<string name="general_settings_swipe_action_toggle_selection">Alderantzizkatu hautaketa</string>
<!--Name of the swipe action to mark as message as read/unread-->
<string name="general_settings_swipe_action_toggle_read">Markatu irakurrita/irakurri gabe</string>
<!--Name of the swipe action to add/remove a star-->
<string name="general_settings_swipe_action_toggle_star">Jarri/kendu izarra</string>
<!--Name of the swipe action to archive a message-->
<string name="general_settings_swipe_action_archive">Artxibatu</string>
<!--Name of the swipe action to delete a message-->
@ -695,6 +701,7 @@ Mesedez akatsen berri emateko, ezaugarri berriak gehitzeko eta galderak egiteko
<string name="account_setup_push_limit_1000">1000 karpeta</string>
<string name="animations_title">Animazioak</string>
<string name="animations_summary">Erabili bistaratze efektu nabarmenak</string>
<string name="volume_navigation_title">Nabigatu bolumenaren botoiekin mezuak ikusterakoan</string>
<string name="show_unified_inbox_title">Erakutsi Sarrera Ontzi Bateratua</string>
<string name="show_starred_count_title">Erakutsi kontu izardunak</string>
<string name="integrated_inbox_title">Sarrerako ontzi bateratua</string>
@ -992,7 +999,10 @@ Mesedez akatsen berri emateko, ezaugarri berriak gehitzeko eta galderak egiteko
<string name="crypto_no_provider_message">Posta hau OpenPGPrekin zifratua izan da.\nIrakurtzeko, OpenPGPrekin bateragarria den aplikazio bat instalatu eta konfiguratu behar duzu.</string>
<string name="crypto_no_provider_button">Joan ezarpenetara</string>
<string name="mail_list_widget_text">K-9 Mezuen Zerrenda</string>
<string name="mail_list_widget_loading">Mezuak kargatzen…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Kargatzen…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Kargatzen…</string>
<string name="openpgp_enabled_error_title">Zifratzea ez da posible</string>
<string name="openpgp_enabled_error_msg">Hautatutako hartzaile batzuek ez dute eginbide hau onartzen!</string>
<string name="enable_encryption">Gaitu zifratzea</string>

View File

@ -993,7 +993,10 @@
<string name="crypto_no_provider_message">این رایانامه با OpenPGP رمزنگاری شده است.\nبرای خواندن آن، باید برنامه‌ای سازگار با OpenPGP را نصب و پیکربندی کنید.</string>
<string name="crypto_no_provider_button">برو به تنظیمات</string>
<string name="mail_list_widget_text">لیست پیام K-9</string>
<string name="mail_list_widget_loading">بارگیری پیام‌ها…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">بارگیری…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">بارگیری…</string>
<string name="openpgp_enabled_error_title">رمزنگاری ممکن نیست</string>
<string name="openpgp_enabled_error_msg">بعضی از گیرندگان انتخابی از این ویژگی پشتیبانی نمی‌کنند!</string>
<string name="enable_encryption">فعال‌سازی رمزنگاری</string>

View File

@ -999,7 +999,10 @@ Ilmoita virheistä, ota osaa sovelluskehitykseen ja esitä kysymyksiä osoittees
<string name="crypto_no_provider_message">Tämä viesti on salattu OpenPGP:llä.\nLukeaksesi viestin sinun tulee asentaa ja määrittää yhteensopiva OpenPGP-sovellus.</string>
<string name="crypto_no_provider_button">Siirry asetuksiin</string>
<string name="mail_list_widget_text">K-9-viestiluettelo</string>
<string name="mail_list_widget_loading">Ladataan viestejä…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Ladataan…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Ladataan…</string>
<string name="openpgp_enabled_error_title">Salaus ei ole mahdollista</string>
<string name="openpgp_enabled_error_msg">Jotkut valitut vastaanottajat eivät tue tätä ominaisuutta!</string>
<string name="enable_encryption">Käytä salausta</string>

View File

@ -264,14 +264,19 @@ Rapportez les bogues, recommandez de nouvelles fonctions et posez vos questions
<string name="global_settings_confirm_menu_mark_all_read">Marquer tous les courriels comme lus</string>
<string name="global_settings_confirm_action_delete_notif">Supprimer (dune notification)</string>
<!--Title of the screen to configure swipe actions-->
<string name="general_settings_swipe_actions_title">Actions de balayage</string>
<!--Name of the setting to configure the right swipe action-->
<string name="general_settings_right_swipe_title">Balayer vers la droite</string>
<!--Name of the setting to configure the left swipe action-->
<string name="general_settings_left_swipe_title">Balayer vers la gauche</string>
<!--The list item users select to not use a swipe action for a particular direction-->
<string name="general_settings_swipe_action_none">Aucune</string>
<!--Name of the swipe action to select/deselect a message-->
<string name="general_settings_swipe_action_toggle_selection">Sélectionner ou dessélectionner</string>
<!--Name of the swipe action to mark as message as read/unread-->
<string name="general_settings_swipe_action_toggle_read">Marquer comme lu/non lu</string>
<string name="general_settings_swipe_action_toggle_read">Marquer comme lu ou non lu</string>
<!--Name of the swipe action to add/remove a star-->
<string name="general_settings_swipe_action_toggle_star">Ajouter/supprimer l\'étoile</string>
<string name="general_settings_swipe_action_toggle_star">Ajouter ou supprimer létoile</string>
<!--Name of the swipe action to archive a message-->
<string name="general_settings_swipe_action_archive">Archiver</string>
<!--Name of the swipe action to delete a message-->
@ -700,6 +705,7 @@ Rapportez les bogues, recommandez de nouvelles fonctions et posez vos questions
<string name="account_setup_push_limit_1000">1 000 dossiers</string>
<string name="animations_title">Animation</string>
<string name="animations_summary">Utiliser des effets visuels voyants</string>
<string name="volume_navigation_title">Navigation avec la touche de volume dans la vue des courriels</string>
<string name="show_unified_inbox_title">Afficher la boîte de réception unifiée</string>
<string name="show_starred_count_title">Afficher le compte détoilés</string>
<string name="integrated_inbox_title">Boîte de réception unifiée</string>
@ -1002,7 +1008,10 @@ Rapportez les bogues, recommandez de nouvelles fonctions et posez vos questions
<string name="crypto_no_provider_message">Ce courriel a été chiffré avec OpenPGP.\nPour le lire, vous devez installer et configurer une appli compatible avec OpenPGP.</string>
<string name="crypto_no_provider_button">Aller dans Paramètres</string>
<string name="mail_list_widget_text">Liste des courriels de K-9</string>
<string name="mail_list_widget_loading">Chargement des courriels…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Chargement…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Chargement…</string>
<string name="openpgp_enabled_error_title">Le chiffrement est impossible</string>
<string name="openpgp_enabled_error_msg">Certains des destinataires sélectionnés ne prennent pas cette fonction en charge!</string>
<string name="enable_encryption">Activer le chiffrement</string>

View File

@ -995,7 +995,10 @@ Graach flaterrapporten stjoere, bydragen foar nije funksjes en fragen stelle op
<string name="crypto_no_provider_message">Dit e-mailberjocht is OpenPGP-fersifere.\nYnstallearje en stel in OpenPGP-app yn om it e-mailberjocht te lêzen.</string>
<string name="crypto_no_provider_button">Gean nei Ynstellingen</string>
<string name="mail_list_widget_text">K-9-berjochtelist</string>
<string name="mail_list_widget_loading">Berjochten oan it laden…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Lade…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Lade…</string>
<string name="openpgp_enabled_error_title">Fersifering net mooglik</string>
<string name="openpgp_enabled_error_msg">Guon fan de ûntfangers stypje dizze funksje net!</string>
<string name="enable_encryption">Fersifering ynskeakelje</string>

View File

@ -874,7 +874,10 @@
\nFeumaidh tu aplacaid a tha comasach air OpenPGP a stàladh is a rèiteachadh mus urrainn dhut a leughadh.</string>
<string name="crypto_no_provider_button">Tagh aplacaid OpenPGP</string>
<string name="mail_list_widget_text">Liosta theachdaireachdan puist</string>
<string name="mail_list_widget_loading">A luchdadh nan teachdaireachdan…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Ga luchdadh…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Ga luchdadh…</string>
<string name="openpgp_enabled_error_title">Cha ghabh a chrioptachadh</string>
<string name="openpgp_enabled_error_msg">Cha chuir gach faightear a thagh thu taic ris a ghleus seo!</string>
<string name="enable_encryption">Cuir crioptachadh an comas</string>

View File

@ -650,6 +650,10 @@
<string name="address_type_mobile">Móbil</string>
<string name="crypto_info_ok">Aceptar</string>
<string name="message_progress_text">A cargar…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">A cargar…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">A cargar…</string>
<string name="openpgp_enabled_error_back">Volver</string>
<string name="general_settings_title">Axustes xerais</string>
<!--permissions-->

View File

@ -956,7 +956,10 @@ Por favor envíen informes de fallos, contribúa con novas características e co
<string name="crypto_no_provider_message">Este correo foi cifrado con OpenPGP.\nPara lelo, precisa instalar e configurar un app compatible con OpenPGP</string>
<string name="crypto_no_provider_button">Ir a Configuración</string>
<string name="mail_list_widget_text">Lista de mensaxes K-9</string>
<string name="mail_list_widget_loading">Cargando mensaxes…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">A cargar…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">A cargar…</string>
<string name="openpgp_enabled_error_title">Cifrado non posible</string>
<string name="openpgp_enabled_error_msg">Algún dos destinatarios seleccionados non soportan esta característica!</string>
<string name="enable_encryption">Habilitar cifrado</string>

View File

@ -881,7 +881,10 @@
<string name="crypto_no_provider_message">Ova e-poruka je šifrirana korištenjem OpenPGP.\nDa bi ste je pročitali, potrebno je da instalirate i postavite odgovarajuću OpenPGP aplikaciju.</string>
<string name="crypto_no_provider_button">Idi u Postavke</string>
<string name="mail_list_widget_text">K-9 Popis Poruka</string>
<string name="mail_list_widget_loading">Učitavam poruke…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Učitavam…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Učitavam…</string>
<string name="openpgp_enabled_error_title">Šifriranje nije moguće</string>
<string name="enable_encryption">Uključi šifriranje</string>
<string name="disable_encryption">Onemogući šifriranje</string>

View File

@ -991,7 +991,10 @@ Hibajelentések beküldésével közreműködhet az új funkciókban, és kérd
<string name="crypto_no_provider_message">Az e-mail titkosítva lett OpenPGP használatával.\nAz elolvasásához egy megfelelő OpenPGP alkalmazást kell telepítenie és beállítania.</string>
<string name="crypto_no_provider_button">Ugrás a beállításokhoz</string>
<string name="mail_list_widget_text">K-9 üzenetlista</string>
<string name="mail_list_widget_loading">Üzenetek betöltése…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Betöltés…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Betöltés…</string>
<string name="openpgp_enabled_error_title">A titkosítás nem lehetséges</string>
<string name="openpgp_enabled_error_msg">Néhány kiválasztott címzett nem támogatja ezt a funkciót!</string>
<string name="enable_encryption">Titkosítás engedélyezése</string>

View File

@ -923,7 +923,10 @@ Kirimkan laporan bug, kontribusikan fitur baru dan ajukan pertanyaan di
<string name="crypto_no_provider_message">Email ini telah dienkripsi dengan OpenPGP. \nUntuk membacanya, Anda perlu menginstal dan mengkonfigurasi Aplikasi OpenPGP yang kompatibel.</string>
<string name="crypto_no_provider_button">Pergi ke pengaturan</string>
<string name="mail_list_widget_text">Daftar pesan K-9</string>
<string name="mail_list_widget_loading">Memuat pesan…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Memuat…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Memuat…</string>
<string name="openpgp_enabled_error_title">Enkripsi tidak mungkin dilakukan</string>
<string name="openpgp_enabled_error_msg">Beberapa penerima yang dipilih tidak mendukung fitur ini!</string>
<string name="enable_encryption">Aktifkan Enkripsi</string>

View File

@ -994,7 +994,10 @@ Sendu inn villuskýrslur, leggðu fram nýja eiginleika og spurðu spurninga á
<string name="crypto_no_provider_message">Þessi tölvupóstur var dulritaður með OpenPGP.\nTil að lesa hann verður þú að setja upp og stilla samhæft OpenPGP-forrit.</string>
<string name="crypto_no_provider_button">Fara í stillingar</string>
<string name="mail_list_widget_text">Skilaboðalisti K-9</string>
<string name="mail_list_widget_loading">Hleður skilaboð…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Hleður…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Hleður…</string>
<string name="openpgp_enabled_error_title">Dulritun er ekki möguleg</string>
<string name="openpgp_enabled_error_msg">Sumir valinna viðtakenda styðja ekki við þennan eiginleika!</string>
<string name="enable_encryption">Virkja dulritun</string>

View File

@ -1001,7 +1001,10 @@ Invia segnalazioni di bug, contribuisci con nuove funzionalità e poni domande s
<string name="crypto_no_provider_message">Questo messaggio è stato cifrato con OpenPGP.\nPer leggerlo, devi installare e configurare un\'applicazione compatibile con OpenPGP.</string>
<string name="crypto_no_provider_button">Vai alle impostazioni</string>
<string name="mail_list_widget_text">Elenco messaggi di K-9</string>
<string name="mail_list_widget_loading">Caricamento messaggi…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Caricamento in corso…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Caricamento in corso…</string>
<string name="openpgp_enabled_error_title">Cifratura non possibile</string>
<string name="openpgp_enabled_error_msg">Alcuni dei destinatari selezionati non supportano questa funzionalità!</string>
<string name="enable_encryption">Abilita cifratura</string>

View File

@ -614,6 +614,8 @@
<string name="address_type_other">אחר</string>
<string name="address_type_mobile">סלולרי</string>
<string name="crypto_info_ok">אישור</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="general_settings_title">הגדרות כלליות</string>
<!--permissions-->
</resources>

View File

@ -994,7 +994,10 @@ K-9 は大多数のメールクライアントと同様に、ほとんどのフ
<string name="crypto_no_provider_message">このメールは OpenPGP で暗号化されました。\n読むためには、OpenPGP と互換のアプリをインストールして設定する必要があります。</string>
<string name="crypto_no_provider_button">設定に移動</string>
<string name="mail_list_widget_text">K-9 メッセージ一覧</string>
<string name="mail_list_widget_loading">メッセージ読み込み中…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">読み込み中…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">読み込み中…</string>
<string name="openpgp_enabled_error_title">暗号化不可</string>
<string name="openpgp_enabled_error_msg">選択した受信者の一部が、この機能をサポートしていません!</string>
<string name="enable_encryption">暗号化を有効にする</string>

View File

@ -766,6 +766,10 @@
<string name="account_settings_crypto_hide_sign_only_off">모든 서명이 보일 것입니다</string>
<string name="unsigned_text_divider_label">서명되지 않은 글</string>
<string name="crypto_no_provider_button">설정으로 움직이기</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">로딩 중…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">로딩 중…</string>
<string name="openpgp_enabled_error_title">암호화가 불가능합니다</string>
<string name="openpgp_enabled_error_msg">선택된 몇몇 받는 사람들은 이 기능을 지원하지 않습니다!</string>
<string name="enable_encryption">암호화 사용</string>

View File

@ -999,7 +999,10 @@ Pateikite pranešimus apie klaidas, prisidėkite prie naujų funkcijų kūrimo i
<string name="crypto_no_provider_message">Šis el. laiškas užšifruotas naudojant OpenPGP.\nKad jį perskaitytumėte, turite įdiegti ir sukonfigūruoti suderinamą OpenPGP programėlę.</string>
<string name="crypto_no_provider_button">Eiti į Nustatymus</string>
<string name="mail_list_widget_text">K-9 laiškų sąrašas</string>
<string name="mail_list_widget_loading">Įkeliami laiškai...</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Įkeliama…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Įkeliama…</string>
<string name="openpgp_enabled_error_title">Šifravimas neįmanomas</string>
<string name="openpgp_enabled_error_msg">Kai kurie iš pasirinktų gavėjų nepalaiko šios funkcijos!</string>
<string name="enable_encryption">Įjungti šifravimą</string>

View File

@ -962,7 +962,10 @@ pat <xliff:g id="messages_to_load">%d</xliff:g> vairāk</string>
<string name="crypto_no_provider_message">Šī vēstule ir šifrēta ar OpenPGP. Lai to apskatītos, jāinstalē un jāiestata saderīga OpenPGP lietotne</string>
<string name="crypto_no_provider_button">Doties uz iestatījumiem</string>
<string name="mail_list_widget_text">K-9 Vēstuļu saraksts</string>
<string name="mail_list_widget_loading">Ielādē vēstules…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Ielādē…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Ielādē…</string>
<string name="openpgp_enabled_error_title">Nevar iešifrēt</string>
<string name="openpgp_enabled_error_msg">Daži no izvēlētajiem saņēmējiem šo iespēju neatbalsta!</string>
<string name="enable_encryption">Ieslēgt šifrēšanu</string>

View File

@ -956,7 +956,10 @@
<string name="crypto_no_provider_message">ഈ ഇമെയിൽ ഓപ്പൺപിജിപി ഉപയോഗിച്ച് എൻക്രിപ്റ്റുചെയ്‌തതാണ്.\nഇത് വായിക്കാൻ, നിങ്ങൾ ഒരു അനുയോജ്യമായ ഓപ്പൺപിജിപി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌ത് ക്രമീകരിക്കേണ്ടതുണ്ട്. </string>
<string name="crypto_no_provider_button">ക്രമീകരണങ്ങളിലേക്ക് പോകുക</string>
<string name="mail_list_widget_text">കെ-9 സന്ദേശ പട്ടിക</string>
<string name="mail_list_widget_loading">സന്ദേശങ്ങൾ ലോഡുചെയ്യുന്നു…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">ലോഡുചെയ്യുന്നു…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">ലോഡുചെയ്യുന്നു…</string>
<string name="openpgp_enabled_error_title">എൻക്രിപ്ഷൻ സാധ്യമല്ല</string>
<string name="openpgp_enabled_error_msg">തിരഞ്ഞെടുത്ത ചില സ്വീകർത്താക്കൾ ഈ സവിശേഷതയെ പിന്തുണയ്ക്കുന്നില്ല!</string>
<string name="enable_encryption">എൻക്രിപ്ഷൻ പ്രാപ്തമാക്കുക</string>

View File

@ -913,7 +913,10 @@ til <xliff:g id="messages_to_load">%d</xliff:g> flere</string>
<string name="crypto_no_provider_message">Denne e-posten har blitt kryptert med OpenPGP.\nFor å lese den, må du installere og sette opp et kompatibelt OpenPGP-program.</string>
<string name="crypto_no_provider_button">Gå til \"Innstillinger\"</string>
<string name="mail_list_widget_text">K-9 meldingsliste</string>
<string name="mail_list_widget_loading">Laster inn meldinger…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Laster…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Laster…</string>
<string name="openpgp_enabled_error_title">Kryptering er ikke mulig</string>
<string name="openpgp_enabled_error_msg">Noen av de valgte mottakerne støtter ikke denne funksjonen!</string>
<string name="enable_encryption">Skru på kryptering</string>

View File

@ -995,7 +995,10 @@ Graag foutrapporten sturen, bijdragen voor nieuwe functies en vragen stellen op
<string name="crypto_no_provider_message">Dit e-mailbericht is OpenPGP versleuteld.\nInstalleer en stel een OpenPGP-app in om het e-mailbericht te lezen.</string>
<string name="crypto_no_provider_button">Ga naar Instellingen</string>
<string name="mail_list_widget_text">K-9-berichtenlijst</string>
<string name="mail_list_widget_loading">Berichten aan het laden…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Laden…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Laden…</string>
<string name="openpgp_enabled_error_title">Versleuteling niet mogelijk</string>
<string name="openpgp_enabled_error_msg">Sommige van de ontvangers ondersteunen deze functie niet!</string>
<string name="enable_encryption">Versleuteling inschakelen</string>

View File

@ -1014,7 +1014,10 @@ Wysłane z urządzenia Android za pomocą K-9 Mail. Proszę wybaczyć moją zwi
<string name="crypto_no_provider_message">Ta wiadomość e-mail została zaszyfrowana z użyciem OpenPGP.\n Aby ją odczytać, należy zainstalować i skonfigurować zgodną aplikację OpenPGP.</string>
<string name="crypto_no_provider_button">Przejdź do ustawień</string>
<string name="mail_list_widget_text">Lista wiadomości K-9</string>
<string name="mail_list_widget_loading">Ładowanie wiadomości…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Ładowanie…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Ładowanie…</string>
<string name="openpgp_enabled_error_title">Szyfrowanie nie możliwe</string>
<string name="openpgp_enabled_error_msg">Część z wybranych odbiorców nie obsługuje tej funkcjonalności.</string>
<string name="enable_encryption">Włącz szyfrowanie</string>

View File

@ -262,15 +262,21 @@ Por favor encaminhe relatórios de bugs, contribua com novos recursos e tire dú
<string name="global_settings_confirm_menu_mark_all_read">Marcar todas as mensagens como lidas</string>
<string name="global_settings_confirm_action_delete_notif">Excluir (na notificação)</string>
<!--Title of the screen to configure swipe actions-->
<string name="general_settings_swipe_actions_title">Ações de deslizamento</string>
<!--Name of the setting to configure the right swipe action-->
<string name="general_settings_right_swipe_title">Deslizar para a direita</string>
<!--Name of the setting to configure the left swipe action-->
<string name="general_settings_left_swipe_title">Deslizar para a esquerda</string>
<!--The list item users select to not use a swipe action for a particular direction-->
<string name="general_settings_swipe_action_none">Nenhuma</string>
<!--Name of the swipe action to select/deselect a message-->
<string name="general_settings_swipe_action_toggle_selection">Alternar a seleção</string>
<!--Name of the swipe action to mark as message as read/unread-->
<string name="general_settings_swipe_action_toggle_read">Marcar como lida/não lida</string>
<!--Name of the swipe action to add/remove a star-->
<string name="general_settings_swipe_action_toggle_star">Adicionar/remover estrela</string>
<!--Name of the swipe action to archive a message-->
<string name="general_settings_swipe_action_archive">Arquivadas</string>
<string name="general_settings_swipe_action_archive">Arquivar</string>
<!--Name of the swipe action to delete a message-->
<string name="general_settings_swipe_action_delete">Excluir</string>
<!--Name of the swipe action to move a message to the spam folder-->
@ -1000,7 +1006,10 @@ Por favor encaminhe relatórios de bugs, contribua com novos recursos e tire dú
<string name="crypto_no_provider_message">Esta mensagem foi criptografada com OpenPGP.\nPara ler, precisa instalar e configurar um aplicativo OpenPGP compatível.</string>
<string name="crypto_no_provider_button">Ir para as configurações</string>
<string name="mail_list_widget_text">Lista de mensagens do K-9</string>
<string name="mail_list_widget_loading">Carregando mensagens…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Carregando…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Carregando…</string>
<string name="openpgp_enabled_error_title">Não foi possível criptografar</string>
<string name="openpgp_enabled_error_msg">Alguns dos destinatários selecionados não têm suporte a este recurso!</string>
<string name="enable_encryption">Habilitar a criptografia</string>

View File

@ -993,7 +993,10 @@ Por favor envie relatórios de falhas, contribua com novas funcionalidades e col
<string name="crypto_no_provider_message">Este email foi encriptado com OpenPGP.\nPara o ler, necessita de instalar e configurar uma aplicação OpenPGP compatível.</string>
<string name="crypto_no_provider_button">Ir para as configurações</string>
<string name="mail_list_widget_text">K-9 Lista de mensagens</string>
<string name="mail_list_widget_loading">A carregar mensagens…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">A carregar…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">A carregar…</string>
<string name="openpgp_enabled_error_title">Não é possível encriptar</string>
<string name="openpgp_enabled_error_msg">Alguns dos destinatários selecionados não suportam esta funcionalidade!</string>
<string name="enable_encryption">Ativar encriptação</string>

View File

@ -1003,7 +1003,10 @@ Uneori datorită faptului că cineva încearcă să te atace pe tine sau serveru
<string name="crypto_no_provider_message">Acest mesaj a fost criptat cu OpenPGP.\nPentru a-l citi trebuie să instalați și să configurați o aplicație OpenPGP compatibilă.</string>
<string name="crypto_no_provider_button">Mergi la Setări</string>
<string name="mail_list_widget_text">Listă mesaje K-9</string>
<string name="mail_list_widget_loading">Se încarcă mesajele…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Se încarcă…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Se încarcă…</string>
<string name="openpgp_enabled_error_title">Criptarea nu este posibilă</string>
<string name="openpgp_enabled_error_msg">Unii dintre destinatarii selectați nu suportă această facilitate!</string>
<string name="enable_encryption">Activează criptarea</string>

View File

@ -63,7 +63,7 @@ K-9 Mail — почтовый клиент для Android.
<!--=== General strings ==================================================================-->
<string name="authors">Авторы</string>
<string name="about_title">О почте K-9</string>
<string name="accounts_title">Ящики</string>
<string name="accounts_title">Учётные записи</string>
<string name="advanced">Дополнительно</string>
<string name="compose_title_compose">Новое</string>
<string name="compose_title_reply">Ответ</string>
@ -85,8 +85,8 @@ K-9 Mail — почтовый клиент для Android.
<string name="reply_action">Ответить</string>
<string name="reply_all_action">Ответить всем</string>
<string name="delete_action">Удалить</string>
<string name="archive_action">В архив</string>
<string name="spam_action">В спам</string>
<string name="archive_action">Архивировать</string>
<string name="spam_action">Отправить в спам</string>
<string name="forward_action">Переслать</string>
<string name="forward_as_attachment_action">Переслать вложением</string>
<string name="edit_as_new_message_action">Редактировать как новое сообщение</string>
@ -164,7 +164,7 @@ K-9 Mail — почтовый клиент для Android.
<string name="notification_action_delete">Удалить</string>
<string name="notification_action_delete_all">Удалить все</string>
<string name="notification_action_archive">Архив</string>
<string name="notification_action_archive_all">В архив все</string>
<string name="notification_action_archive_all">Архивировать все</string>
<string name="notification_action_spam">Спам</string>
<string name="notification_certificate_error_public">Ошибка сертификата</string>
<string name="notification_certificate_error_title">Сбой сертификата <xliff:g id="account">%s</xliff:g></string>
@ -362,11 +362,11 @@ K-9 Mail — почтовый клиент для Android.
<string name="account_setup_expunge_policy_manual">Вручную</string>
<string name="account_setup_incoming_autodetect_namespace_label">Автообласть имён IMAP</string>
<string name="account_setup_incoming_imap_path_prefix_label">Префикс пути IMAP</string>
<string name="drafts_folder_label">Папка черновиков</string>
<string name="sent_folder_label">Папка отправленных</string>
<string name="trash_folder_label">Папка удалённых</string>
<string name="archive_folder_label">Папка архивных</string>
<string name="spam_folder_label">Папка спама</string>
<string name="drafts_folder_label">Папка черновики</string>
<string name="sent_folder_label">Папка отправленные</string>
<string name="trash_folder_label">Папка корзина/удалённые</string>
<string name="archive_folder_label">Папка архив</string>
<string name="spam_folder_label">Папка спам</string>
<string name="account_setup_incoming_subscribed_folders_only_label">Только подписанные папки</string>
<string name="account_setup_auto_expand_folder">Автопереход в папку</string>
<string name="account_setup_incoming_webdav_path_prefix_label">Путь OWA</string>
@ -525,26 +525,26 @@ K-9 Mail — почтовый клиент для Android.
<string name="account_settings_message_age_1_year">1 год</string>
<string name="account_settings_folder_display_mode_label">Видимость папок</string>
<string name="account_settings_folder_display_mode_all">Все</string>
<string name="account_settings_folder_display_mode_first_class">1-й класс</string>
<string name="account_settings_folder_display_mode_first_and_second_class">1-й и 2-й классы</string>
<string name="account_settings_folder_display_mode_not_second_class">Кроме 2-го класса</string>
<string name="account_settings_folder_display_mode_first_class">Папки только 1-го класса</string>
<string name="account_settings_folder_display_mode_first_and_second_class">Папки 1-го и 2-го классов</string>
<string name="account_settings_folder_display_mode_not_second_class">Все, кроме папок 2-го класса</string>
<string name="account_settings_folder_sync_mode_label">Проверка папок</string>
<string name="account_settings_folder_sync_mode_all">Все</string>
<string name="account_settings_folder_sync_mode_first_class">1-й класс</string>
<string name="account_settings_folder_sync_mode_first_and_second_class">1-й и 2-й классы</string>
<string name="account_settings_folder_sync_mode_not_second_class">Кроме 2-го класса</string>
<string name="account_settings_folder_sync_mode_first_class">Папки только 1-го класса</string>
<string name="account_settings_folder_sync_mode_first_and_second_class">Папки 1-го и 2-го классов</string>
<string name="account_settings_folder_sync_mode_not_second_class">Все, кроме папок 2-го класса</string>
<string name="account_settings_folder_sync_mode_none">Нет</string>
<string name="account_settings_folder_push_mode_label">Push</string>
<string name="account_settings_folder_push_mode_all">Все</string>
<string name="account_settings_folder_push_mode_first_class">1-й класс</string>
<string name="account_settings_folder_push_mode_first_and_second_class">1-й и 2-й классы</string>
<string name="account_settings_folder_push_mode_not_second_class">Кроме 2-го класса</string>
<string name="account_settings_folder_push_mode_first_class">Папки только 1-го класса</string>
<string name="account_settings_folder_push_mode_first_and_second_class">Папки 1-го и 2-го классов</string>
<string name="account_settings_folder_push_mode_not_second_class">Все, кроме папок 2-го класса</string>
<string name="account_settings_folder_push_mode_none">Нет</string>
<string name="account_settings_folder_target_mode_label">Приёмник копирования</string>
<string name="account_settings_folder_target_mode_all">Все</string>
<string name="account_settings_folder_target_mode_first_class">1-й класс</string>
<string name="account_settings_folder_target_mode_first_and_second_class">1-й и 2-й классы</string>
<string name="account_settings_folder_target_mode_not_second_class">Кроме 2-го класса</string>
<string name="account_settings_folder_target_mode_first_class">Папки только 1-го класса</string>
<string name="account_settings_folder_target_mode_first_and_second_class">Папки 1-го и 2-го классов</string>
<string name="account_settings_folder_target_mode_not_second_class">Все, кроме папок 2-го класса</string>
<string name="account_settings_sync_remote_deletetions_label">Синхронное удаление</string>
<string name="account_settings_sync_remote_deletetions_summary">Удалять сообщения при удалении на сервере</string>
<string name="account_settings_openpgp_missing">Отсутствует OpenPGP-приложение было удалено?</string>
@ -661,8 +661,8 @@ K-9 Mail — почтовый клиент для Android.
<string name="folder_list_filter_hint">Поиск папки</string>
<string name="folder_list_display_mode_label">Видимость папок</string>
<string name="folder_list_display_mode_all">Все папки</string>
<string name="folder_list_display_mode_first_class">1-й класс</string>
<string name="folder_list_display_mode_first_and_second_class">1-й и 2-й класс</string>
<string name="folder_list_display_mode_first_class">Папки 1-го класса</string>
<string name="folder_list_display_mode_first_and_second_class">Папки 1-го и 2-го классов</string>
<string name="folder_list_display_mode_not_second_class">Кроме 2-го класса</string>
<string name="account_settings_signature__location_label">Размещение подписи</string>
<string name="account_settings_signature__location_before_quoted_text">Перед цитатой</string>
@ -796,8 +796,8 @@ K-9 Mail — почтовый клиент для Android.
<string name="settings_export_progress_text">Экспорт настроек…</string>
<string name="settings_export_success_generic">Настройки успешно экспортированы</string>
<string name="settings_export_failure">Сбой экспорта настроек</string>
<string name="settings_import_title">Импорт</string>
<string name="settings_import_pick_document_button">Выберите файл</string>
<string name="settings_import_title">Импортировать настройки</string>
<string name="settings_import_pick_document_button">Выбрать файл</string>
<string name="settings_import_button">Импорт</string>
<string name="settings_import_success_generic">Настройки успешно импортированы</string>
<!--Displayed after importing accounts when one or multiple accounts require entering a password-->
@ -1013,7 +1013,10 @@ K-9 Mail — почтовый клиент для Android.
<string name="crypto_no_provider_message">Сообщение зашифровано OpenPGP.\nЧтобы прочесть его, необходимо установить и настроить подходящее OpenPGP-приложение.</string>
<string name="crypto_no_provider_button">В Настройки</string>
<string name="mail_list_widget_text">Сообщения K-9</string>
<string name="mail_list_widget_loading">Загрузка сообщений…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Загрузка…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Загрузка…</string>
<string name="openpgp_enabled_error_title">Шифрование невозможно</string>
<string name="openpgp_enabled_error_msg">Не все выбранные адресаты поддерживают эту возможность!</string>
<string name="enable_encryption">Включить шифрование</string>

View File

@ -887,7 +887,10 @@ Prosím, nahlasujte prípadné chyby, prispievajte novými funkciami a pýtajte
<string name="crypto_no_provider_title">Táto správa je zašifrovaná</string>
<string name="crypto_no_provider_message">Táto správa bola zašifrovaná pomocou OpenPGP\nJe potrebné nakonfigurovať kompatibilnú OpenPGP aplikáciu.</string>
<string name="mail_list_widget_text">Zoznam správ K-9</string>
<string name="mail_list_widget_loading">Načítavajú sa správy…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Načítavam…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Načítavam…</string>
<string name="openpgp_enabled_error_back">Späť</string>
<string name="general_settings_title">Všeobecné nastavenia</string>
<!--permissions-->

View File

@ -1007,7 +1007,10 @@ dodatnih <xliff:g id="messages_to_load">%d</xliff:g> sporočil</string>
<string name="crypto_no_provider_message">Sporočilo je šifrirano s programom OpenPGP.\nZa ogled vsebine je treba namestiti ustrezen podprt program OpenPGP.</string>
<string name="crypto_no_provider_button">Pojdi v Nastavitve</string>
<string name="mail_list_widget_text">Seznami sporočil</string>
<string name="mail_list_widget_loading">Poteka nalaganje sporočil …</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Poteka nalaganje …</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Poteka nalaganje …</string>
<string name="openpgp_enabled_error_title">Šifriranje ni mogoče</string>
<string name="openpgp_enabled_error_msg">Nekateri izmed izbranih prejemnikov ne podpirajo te možnosti!</string>
<string name="enable_encryption">Omogoči šifriranje</string>

View File

@ -999,7 +999,10 @@ Ju lutemi, parashtrim njoftimesh për të meta, kontribute për veçori të reaj
<string name="crypto_no_provider_message">Ky email është fshehtëzuar me OpenPGP.\nQë ta lexoni, lypset të instaloni dhe formësoni një aplikacion të përputhshëm me OpenPGP-në.</string>
<string name="crypto_no_provider_button">Kaloni te Rregullimet</string>
<string name="mail_list_widget_text">Listë K-9 Mesazhesh</string>
<string name="mail_list_widget_loading">Po ngarkohen mesazhe…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Po ngarkohet…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Po ngarkohet…</string>
<string name="openpgp_enabled_error_title">Fshehtëzim jo i mundshëm</string>
<string name="openpgp_enabled_error_msg">Disa nga marrësit e përzgjedhur nuk e mbulojnë këtë veçori!</string>
<string name="enable_encryption">Aktivizo Fshehtëzimin</string>

View File

@ -937,7 +937,10 @@
<string name="crypto_no_provider_message">Ова е-порука је шифрована помоћу у ОпенПГП-а.\nДа бисте је прочитали, треба да инсталирате и подесите компатибилну ОпенПГП апликацију.</string>
<string name="crypto_no_provider_button">Иди на Поставке</string>
<string name="mail_list_widget_text">К-9 списак порука</string>
<string name="mail_list_widget_loading">Учитавам поруке…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Учитавам…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Учитавам…</string>
<string name="openpgp_enabled_error_title">Шифровање није могуће</string>
<string name="openpgp_enabled_error_msg">Неки од изабраних прималаца не подржавају ово!</string>
<string name="enable_encryption">Укључи шифровање</string>

View File

@ -1000,7 +1000,10 @@ Skicka in felrapporter, bidra med nya funktioner och ställ frågor på
<string name="crypto_no_provider_message">Detta e-postmeddelande har krypterats med OpenPGP.\nFör att läsa det, måste du installera och konfigurera en kompatibel OpenPGP-app.</string>
<string name="crypto_no_provider_button">Gå till inställningar</string>
<string name="mail_list_widget_text">K-9 Meddelandelista</string>
<string name="mail_list_widget_loading">Läser in meddelanden…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Läser in…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Läser in…</string>
<string name="openpgp_enabled_error_title">Kryptering inte möjligt</string>
<string name="openpgp_enabled_error_msg">Några av de valda mottagarna stöder inte denna funktion!</string>
<string name="enable_encryption">Aktivera kryptering</string>

View File

@ -974,7 +974,10 @@ Microsoft Exchange ile konuşurken bazı tuhaflıklar yaşadığını not ediniz
<string name="crypto_no_provider_message">Bu eposta OpenPGP ile şifrelendi. On okumak için uyumlu bir OpenPGP uygulaması kurup yapılandırmanız gerekir.</string>
<string name="crypto_no_provider_button">Ayarlara Git</string>
<string name="mail_list_widget_text">K-9 İleti Listesi</string>
<string name="mail_list_widget_loading">İletiler Yükleniyor…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Yükleniyor…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Yükleniyor…</string>
<string name="openpgp_enabled_error_title">Şifreleme yapılamaz</string>
<string name="openpgp_enabled_error_msg">Seçilen bazı alıcılar bu özelliği desteklemiyor!</string>
<string name="enable_encryption">Şifreleme etkin</string>

View File

@ -1008,7 +1008,10 @@ K-9 Mail — це вільний клієнт електронної пошти
<string name="crypto_no_provider_message">Цей електронний лист було зашифровано за допомогою OpenPGP.\nЩоб його прочитати, необхідно встановити та налаштувати сумісний OpenPGP-додаток.</string>
<string name="crypto_no_provider_button">Перейти до Налаштувань</string>
<string name="mail_list_widget_text">K-9 Список повідомлень</string>
<string name="mail_list_widget_loading">Завантаження листів…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">Завантаження…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">Завантаження…</string>
<string name="openpgp_enabled_error_title">Шифрування неможливе</string>
<string name="openpgp_enabled_error_msg">Деякі з вибраних адресатів не підтримують цю функцію.</string>
<string name="enable_encryption">Увімкнути шифрування</string>

View File

@ -993,7 +993,10 @@ K-9 Mail 是 Android 上一款功能强大的免费邮件客户端。
<string name="crypto_no_provider_message">这份邮件使用 OpenPGP 进行了加密。\n请安装并配置一个兼容 OpenPGP 的应用来查看邮件。</string>
<string name="crypto_no_provider_button">前往设置</string>
<string name="mail_list_widget_text">K-9消息列表</string>
<string name="mail_list_widget_loading">正在加载邮件……</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">加载中…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">加载中…</string>
<string name="openpgp_enabled_error_title">无法加密</string>
<string name="openpgp_enabled_error_msg">某些选定的收件人不支持此功能!</string>
<string name="enable_encryption">启用加密</string>

View File

@ -986,7 +986,10 @@ K-9 Mail 是 Android 上一款功能強大,免費的電子郵件用戶端。
<string name="crypto_no_provider_message">這封郵件使用 OpenPGP 進行了加密。\n請安裝並設定一個相容 OpenPGP 的應用程式來查看郵件。</string>
<string name="crypto_no_provider_button">前往設定</string>
<string name="mail_list_widget_text">K-9 訊息列表</string>
<string name="mail_list_widget_loading">正在載入郵件…</string>
<!--Displayed in the the message list widget when the app hasn't had a chance to send content to it yet-->
<string name="message_list_widget_initializing">載入中…</string>
<!--Might be displayed in the message list widget when the list is scrolled and new data can't be fetched fast enough-->
<string name="message_list_widget_list_item_loading">載入中…</string>
<string name="openpgp_enabled_error_title">無法加密</string>
<string name="openpgp_enabled_error_msg">有些已選定的收件人不支援此功能!</string>
<string name="enable_encryption">啟用加密</string>

View File

@ -83,13 +83,11 @@
<attr name="messageListSwipeSelectIcon" format="reference"/>
<attr name="messageListSwipeSelectBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeMarkAsReadIcon" format="reference"/>
<attr name="messageListSwipeMarkAsReadBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeMarkAsUnreadIcon" format="reference"/>
<attr name="messageListSwipeMarkAsUnreadBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeToggleReadBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeAddStarIcon" format="reference"/>
<attr name="messageListSwipeAddStarBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeRemoveStarIcon" format="reference"/>
<attr name="messageListSwipeRemoveStarBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeToggleStarBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeArchiveIcon" format="reference"/>
<attr name="messageListSwipeArchiveBackgroundColor" format="reference|color"/>
<attr name="messageListSwipeDeleteIcon" format="reference"/>

Some files were not shown because too many files have changed in this diff Show More