diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ee9ba03c0ff60d1bb6bbf9042bbc451366397f87..ac3fb49212767076c57e9b457e103a7acf8a198c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: "registry.gitlab.e.foundation:5000/e/apps/docker-android-apps-cicd:legacy"
+image: "registry.gitlab.e.foundation:5000/e/apps/docker-android-apps-cicd:latest"
stages:
- build
diff --git a/app/autodiscovery/providersxml/src/main/res/xml/providers.xml b/app/autodiscovery/providersxml/src/main/res/xml/providers.xml
index 1cd6380a958d4e99848bef769a25ed3d60ef36fc..4abee9f5ec97803533d2adda4b0c67bac7383a92 100644
--- a/app/autodiscovery/providersxml/src/main/res/xml/providers.xml
+++ b/app/autodiscovery/providersxml/src/main/res/xml/providers.xml
@@ -294,6 +294,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/core/src/main/AndroidManifest.xml b/app/core/src/main/AndroidManifest.xml
index 5900dccc24b0a8a8f7c086fc78dae3c83108a1b5..dca0147e8479133a5bf48a146db018e513b7eed9 100644
--- a/app/core/src/main/AndroidManifest.xml
+++ b/app/core/src/main/AndroidManifest.xml
@@ -7,11 +7,21 @@
+
+ tools:node="merge">
+
+
+
+
+
+
diff --git a/app/core/src/main/java/com/fsck/k9/Account.java b/app/core/src/main/java/com/fsck/k9/Account.java
index 5fabbf671688ee7e15dd25f8f922efd5e08132d8..5cf39c0ac14e6a9165ca0da39c9427d22adb221c 100644
--- a/app/core/src/main/java/com/fsck/k9/Account.java
+++ b/app/core/src/main/java/com/fsck/k9/Account.java
@@ -40,12 +40,9 @@ public class Account implements BaseAccount {
public ExpungePolicy toBackendExpungePolicy() {
switch (this) {
- case EXPUNGE_IMMEDIATELY:
- return ExpungePolicy.IMMEDIATELY;
- case EXPUNGE_MANUALLY:
- return ExpungePolicy.MANUALLY;
- case EXPUNGE_ON_POLL:
- return ExpungePolicy.ON_POLL;
+ case EXPUNGE_IMMEDIATELY: return ExpungePolicy.IMMEDIATELY;
+ case EXPUNGE_MANUALLY: return ExpungePolicy.MANUALLY;
+ case EXPUNGE_ON_POLL: return ExpungePolicy.ON_POLL;
}
throw new AssertionError("Unhandled case: " + this.name());
@@ -65,7 +62,7 @@ public class Account implements BaseAccount {
}
public static DeletePolicy fromInt(int initialSetting) {
- for (DeletePolicy policy : values()) {
+ for (DeletePolicy policy: values()) {
if (policy.setting == initialSetting) {
return policy;
}
@@ -109,7 +106,8 @@ public class Account implements BaseAccount {
private ServerSettings outgoingServerSettings;
/**
- * Storage provider ID, used to locate and manage the underlying DB/file storage
+ * Storage provider ID, used to locate and manage the underlying DB/file
+ * storage
*/
private String localStorageProviderId;
private String description;
@@ -190,7 +188,7 @@ public class Account implements BaseAccount {
/**
* Database ID of the folder that was last selected for a copy or move operation.
- *
+ *
* Note: For now this value isn't persisted. So it will be reset when K-9 Mail is restarted.
*/
private Long lastSelectedFolderId = null;
@@ -722,7 +720,7 @@ public class Account implements BaseAccount {
@Override
public boolean equals(Object o) {
if (o instanceof Account) {
- return ((Account) o).accountUuid.equals(accountUuid);
+ return ((Account)o).accountUuid.equals(accountUuid);
}
return super.equals(o);
}
@@ -824,24 +822,22 @@ public class Account implements BaseAccount {
now.set(Calendar.MILLISECOND, 0);
if (age < 28) {
now.add(Calendar.DATE, age * -1);
- } else {
- switch (age) {
- case 28:
- now.add(Calendar.MONTH, -1);
- break;
- case 56:
- now.add(Calendar.MONTH, -2);
- break;
- case 84:
- now.add(Calendar.MONTH, -3);
- break;
- case 168:
- now.add(Calendar.MONTH, -6);
- break;
- case 365:
- now.add(Calendar.YEAR, -1);
- break;
- }
+ } else switch (age) {
+ case 28:
+ now.add(Calendar.MONTH, -1);
+ break;
+ case 56:
+ now.add(Calendar.MONTH, -2);
+ break;
+ case 84:
+ now.add(Calendar.MONTH, -3);
+ break;
+ case 168:
+ now.add(Calendar.MONTH, -6);
+ break;
+ case 365:
+ now.add(Calendar.YEAR, -1);
+ break;
}
return now.getTime();
@@ -1058,7 +1054,6 @@ public class Account implements BaseAccount {
public synchronized void setAlwaysShowCcBcc(boolean show) {
alwaysShowCcBcc = show;
}
-
public boolean isRemoteSearchFullText() {
return false; // Temporarily disabled
//return remoteSearchFullText;
diff --git a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt
index 1602420bf44dfeba1981833d36bbd744e9d3db56..8a49ebf535d9e95f19502565341cc690813a92be 100644
--- a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt
+++ b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt
@@ -51,6 +51,7 @@ class AccountPreferenceSerializer(
folderNotifyNewMailMode = getEnumStringPref(storage, "$accountUuid.folderNotifyNewMailMode", FolderMode.ALL)
isNotifySelfNewMail = storage.getBoolean("$accountUuid.notifySelfNewMail", true)
isNotifyContactsMailOnly = storage.getBoolean("$accountUuid.notifyContactsMailOnly", false)
+ isIgnoreChatMessages = storage.getBoolean("$accountUuid.ignoreChatMessages", false)
isNotifySync = storage.getBoolean("$accountUuid.notifyMailCheck", false)
isIgnoreChatMessages = storage.getBoolean("$accountUuid.ignoreChatMessages", false)
deletePolicy = DeletePolicy.fromInt(storage.getInt("$accountUuid.deletePolicy", DeletePolicy.NEVER.setting))
diff --git a/app/core/src/main/java/com/fsck/k9/Clock.java b/app/core/src/main/java/com/fsck/k9/Clock.java
deleted file mode 100644
index a07841144e285579836a013843cbe2d867b87e4e..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/Clock.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.fsck.k9;
-
-/**
- * A class provide the current time (like {@link System#currentTimeMillis()}).
- * It's intended to be mocked out for unit tests.
- */
-public class Clock {
- public static final Clock INSTANCE = new Clock();
-
- protected Clock() {
- }
-
- public long getTime() {
- return System.currentTimeMillis();
- }
-}
diff --git a/app/core/src/main/java/com/fsck/k9/Clock.kt b/app/core/src/main/java/com/fsck/k9/Clock.kt
new file mode 100644
index 0000000000000000000000000000000000000000..755102351c07ac40ef80d2d6c408d655d8c645c5
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/Clock.kt
@@ -0,0 +1,13 @@
+package com.fsck.k9
+
+/**
+ * An interface to provide the current time.
+ */
+interface Clock {
+ val time: Long
+}
+
+internal class RealClock : Clock {
+ override val time: Long
+ get() = System.currentTimeMillis()
+}
diff --git a/app/core/src/main/java/com/fsck/k9/CoreKoinModules.kt b/app/core/src/main/java/com/fsck/k9/CoreKoinModules.kt
index de460da656119ce617fef30b1c02811c82dff641..d79482d55df87d0417276d70c7e5389a7e58027b 100644
--- a/app/core/src/main/java/com/fsck/k9/CoreKoinModules.kt
+++ b/app/core/src/main/java/com/fsck/k9/CoreKoinModules.kt
@@ -6,12 +6,14 @@ import com.fsck.k9.controller.push.controllerPushModule
import com.fsck.k9.crypto.openPgpModule
import com.fsck.k9.helper.helperModule
import com.fsck.k9.job.jobModule
+import com.fsck.k9.logging.loggingModule
import com.fsck.k9.mailstore.mailStoreModule
import com.fsck.k9.message.extractors.extractorModule
import com.fsck.k9.message.html.htmlModule
import com.fsck.k9.message.quote.quoteModule
import com.fsck.k9.network.connectivityModule
import com.fsck.k9.notification.coreNotificationModule
+import com.fsck.k9.power.powerModule
import com.fsck.k9.preferences.preferencesModule
import com.fsck.k9.search.searchModule
@@ -30,5 +32,7 @@ val coreModules = listOf(
jobModule,
helperModule,
preferencesModule,
- connectivityModule
+ connectivityModule,
+ powerModule,
+ loggingModule
)
diff --git a/app/core/src/main/java/com/fsck/k9/CoreResourceProvider.kt b/app/core/src/main/java/com/fsck/k9/CoreResourceProvider.kt
index 097221557bd17d58ef79c47cc51abb688dab4f11..ca191b099760b1d66e7c6f440fbb79f301a0b8ae 100644
--- a/app/core/src/main/java/com/fsck/k9/CoreResourceProvider.kt
+++ b/app/core/src/main/java/com/fsck/k9/CoreResourceProvider.kt
@@ -6,9 +6,6 @@ interface CoreResourceProvider {
fun defaultSignature(): String
fun defaultIdentityDescription(): String
- fun internalStorageProviderName(): String
- fun externalStorageProviderName(): String
-
fun contactDisplayNamePrefix(): String
fun contactUnknownSender(): String
fun contactUnknownRecipient(): String
diff --git a/app/core/src/main/java/com/fsck/k9/K9.kt b/app/core/src/main/java/com/fsck/k9/K9.kt
index 9e176d6cd0faba1121e36f14b7a17ce03d5c50da..d26cc5c66bc74d7a68f91c45399ee39d062a57f3 100644
--- a/app/core/src/main/java/com/fsck/k9/K9.kt
+++ b/app/core/src/main/java/com/fsck/k9/K9.kt
@@ -155,7 +155,7 @@ object K9 : EarlyInit {
@JvmStatic
var isConfirmMarkAllRead = true
- @JvmStatic
+ @JvmStatic
var notificationQuickDeleteBehaviour = NotificationQuickDelete.ALWAYS
@JvmStatic
@@ -271,7 +271,8 @@ object K9 : EarlyInit {
return false
}
- val quietTimeChecker = QuietTimeChecker(Clock.INSTANCE, quietTimeStarts, quietTimeEnds)
+ val clock = DI.get()
+ val quietTimeChecker = QuietTimeChecker(clock, quietTimeStarts, quietTimeEnds)
return quietTimeChecker.isQuietTime
}
diff --git a/app/core/src/main/java/com/fsck/k9/KoinModule.kt b/app/core/src/main/java/com/fsck/k9/KoinModule.kt
index 4537ac7dcba770e12cdc214053d30c9e46d83503..05c30287cc1146b04577fcce4ad85c4829eafb72 100644
--- a/app/core/src/main/java/com/fsck/k9/KoinModule.kt
+++ b/app/core/src/main/java/com/fsck/k9/KoinModule.kt
@@ -2,13 +2,11 @@ package com.fsck.k9
import android.content.Context
import com.fsck.k9.helper.Contacts
-import com.fsck.k9.mail.power.PowerManager
import com.fsck.k9.mail.ssl.DefaultTrustedSocketFactory
import com.fsck.k9.mail.ssl.LocalKeyStore
import com.fsck.k9.mail.ssl.TrustManagerFactory
import com.fsck.k9.mail.ssl.TrustedSocketFactory
import com.fsck.k9.mailstore.LocalStoreProvider
-import com.fsck.k9.power.TracingPowerManager
import com.fsck.k9.setup.ServerNameSuggester
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
@@ -27,13 +25,12 @@ val mainModule = module {
single { get().resources }
single { get().contentResolver }
single { LocalStoreProvider() }
- single { TracingPowerManager.getPowerManager(get()) }
single { Contacts.getInstance(get()) }
single { LocalKeyStore(directoryProvider = get()) }
single { TrustManagerFactory.createInstance(get()) }
single { LocalKeyStoreManager(get()) }
single { DefaultTrustedSocketFactory(get(), get()) }
- single { Clock.INSTANCE }
+ single { RealClock() }
factory { ServerNameSuggester() }
factory { EmailAddressValidator() }
factory { ServerSettingsSerializer() }
diff --git a/app/core/src/main/java/com/fsck/k9/Preferences.kt b/app/core/src/main/java/com/fsck/k9/Preferences.kt
index 549d59e7f973ed156e14bdf639b7b7624bc8c2ec..44549db552d32ee7b5d8221c681ef08ec267fb63 100644
--- a/app/core/src/main/java/com/fsck/k9/Preferences.kt
+++ b/app/core/src/main/java/com/fsck/k9/Preferences.kt
@@ -3,6 +3,7 @@ package com.fsck.k9
import android.content.Context
import androidx.annotation.GuardedBy
import androidx.annotation.RestrictTo
+import com.fsck.k9.helper.sendBlockingSilently
import com.fsck.k9.mail.MessagingException
import com.fsck.k9.mailstore.LocalStoreProvider
import com.fsck.k9.preferences.AccountManager
@@ -115,8 +116,13 @@ class Preferences internal constructor(
@OptIn(ExperimentalCoroutinesApi::class)
override fun getAccountFlow(accountUuid: String): Flow {
- return callbackFlow {
- val initialAccount = getAccount(accountUuid) ?: return@callbackFlow
+ return callbackFlow {
+ val initialAccount = getAccount(accountUuid)
+ if (initialAccount == null) {
+ close()
+ return@callbackFlow
+ }
+
send(initialAccount)
val listener = AccountsChangeListener {
@@ -124,7 +130,7 @@ class Preferences internal constructor(
if (account != null) {
sendBlockingSilently(account)
} else {
- channel.close()
+ close()
}
}
addOnAccountsChangeListener(listener)
diff --git a/app/core/src/main/java/com/fsck/k9/controller/MemorizingMessagingListener.java b/app/core/src/main/java/com/fsck/k9/controller/MemorizingMessagingListener.java
index 08d93e459c46e937271e3d302bf798336ecbcf80..20d94a2ef0ab774a7074065c32317bd098cea75e 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/MemorizingMessagingListener.java
+++ b/app/core/src/main/java/com/fsck/k9/controller/MemorizingMessagingListener.java
@@ -102,7 +102,7 @@ class MemorizingMessagingListener extends SimpleMessagingListener {
}
private static String getMemoryKey(Account account, long folderId) {
- return account.getDescription() + ":" + folderId;
+ return account.getUuid() + ":" + folderId;
}
private enum MemorizingState { STARTED, FINISHED, FAILED }
diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessageCountsProvider.kt b/app/core/src/main/java/com/fsck/k9/controller/MessageCountsProvider.kt
index 1d3764ce6a9be5a81eabd873fb01cf33f71380f4..4cfe1e1d590c4b32a8efb508e095bb4ffa43c1cb 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/MessageCountsProvider.kt
+++ b/app/core/src/main/java/com/fsck/k9/controller/MessageCountsProvider.kt
@@ -23,7 +23,6 @@ internal class DefaultMessageCountsProvider(
private val localStoreProvider: LocalStoreProvider
) : MessageCountsProvider {
override fun getMessageCounts(account: Account): MessageCounts {
-
return try {
val localStore = localStoreProvider.getInstance(account)
@@ -62,4 +61,4 @@ internal class DefaultMessageCountsProvider(
MessageCounts(0, 0)
}
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessageReference.java b/app/core/src/main/java/com/fsck/k9/controller/MessageReference.java
deleted file mode 100644
index 15701f5cae340f1f7795c6217924735d6665d2b0..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/controller/MessageReference.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.fsck.k9.controller;
-
-
-import java.util.StringTokenizer;
-
-import androidx.annotation.Nullable;
-
-import com.fsck.k9.mail.Flag;
-import com.fsck.k9.mail.filter.Base64;
-
-import org.jetbrains.annotations.NotNull;
-
-import static com.fsck.k9.helper.Preconditions.checkNotNull;
-
-
-public class MessageReference {
- private static final char IDENTITY_VERSION_2 = '#';
- private static final String IDENTITY_SEPARATOR = ":";
-
-
- private final String accountUuid;
- private final long folderId;
- private final String uid;
- private final Flag flag;
-
-
- @Nullable
- public static MessageReference parse(String identity) {
- if (identity == null || identity.length() < 1 || identity.charAt(0) != IDENTITY_VERSION_2) {
- return null;
- }
-
- StringTokenizer tokens = new StringTokenizer(identity.substring(2), IDENTITY_SEPARATOR, false);
- if (tokens.countTokens() < 3) {
- return null;
- }
-
- String accountUuid = Base64.decode(tokens.nextToken());
- long folderId = Long.parseLong(Base64.decode(tokens.nextToken()));
- String uid = Base64.decode(tokens.nextToken());
-
- if (!tokens.hasMoreTokens()) {
- return new MessageReference(accountUuid, folderId, uid, null);
- }
-
- Flag flag;
- try {
- flag = Flag.valueOf(tokens.nextToken());
- } catch (IllegalArgumentException e) {
- return null;
- }
-
- return new MessageReference(accountUuid, folderId, uid, flag);
- }
-
- public MessageReference(String accountUuid, long folderId, String uid, Flag flag) {
- this.accountUuid = checkNotNull(accountUuid);
- this.folderId = folderId;
- this.uid = checkNotNull(uid);
- this.flag = flag;
- }
-
- public String toIdentityString() {
- StringBuilder refString = new StringBuilder();
-
- refString.append(IDENTITY_VERSION_2);
- refString.append(IDENTITY_SEPARATOR);
- refString.append(Base64.encode(accountUuid));
- refString.append(IDENTITY_SEPARATOR);
- refString.append(Base64.encode(Long.toString(folderId)));
- refString.append(IDENTITY_SEPARATOR);
- refString.append(Base64.encode(uid));
- if (flag != null) {
- refString.append(IDENTITY_SEPARATOR);
- refString.append(flag.name());
- }
-
- return refString.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof MessageReference)) {
- return false;
- }
- MessageReference other = (MessageReference) o;
- return equals(other.accountUuid, other.folderId, other.uid);
- }
-
- public boolean equals(String accountUuid, long folderId, String uid) {
- return this.accountUuid.equals(accountUuid) && this.folderId == folderId && this.uid.equals(uid);
- }
-
- @Override
- public int hashCode() {
- final int MULTIPLIER = 31;
-
- int result = 1;
- result = MULTIPLIER * result + accountUuid.hashCode();
- result = MULTIPLIER * result + (int) (folderId ^ (folderId >>> 32));
- result = MULTIPLIER * result + uid.hashCode();
- return result;
- }
-
- @NotNull
- @Override
- public String toString() {
- return "MessageReference{" +
- "accountUuid='" + accountUuid + '\'' +
- ", folderId='" + folderId + '\'' +
- ", uid='" + uid + '\'' +
- ", flag=" + flag +
- '}';
- }
-
- public String getAccountUuid() {
- return accountUuid;
- }
-
- public long getFolderId() {
- return folderId;
- }
-
- public String getUid() {
- return uid;
- }
-
- public Flag getFlag() {
- return flag;
- }
-
- public MessageReference withModifiedUid(String newUid) {
- return new MessageReference(accountUuid, folderId, newUid, flag);
- }
-
- public MessageReference withModifiedFlag(Flag newFlag) {
- return new MessageReference(accountUuid, folderId, uid, newFlag);
- }
-}
diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessageReference.kt b/app/core/src/main/java/com/fsck/k9/controller/MessageReference.kt
new file mode 100644
index 0000000000000000000000000000000000000000..13ae584a8c8c483784a9702d83c6623436634756
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/controller/MessageReference.kt
@@ -0,0 +1,52 @@
+package com.fsck.k9.controller
+
+import com.fsck.k9.mail.filter.Base64
+import java.util.StringTokenizer
+
+data class MessageReference(
+ val accountUuid: String,
+ val folderId: Long,
+ val uid: String
+) {
+ fun toIdentityString(): String {
+ return buildString {
+ append(IDENTITY_VERSION_2)
+ append(IDENTITY_SEPARATOR)
+ append(Base64.encode(accountUuid))
+ append(IDENTITY_SEPARATOR)
+ append(Base64.encode(folderId.toString()))
+ append(IDENTITY_SEPARATOR)
+ append(Base64.encode(uid))
+ }
+ }
+
+ fun equals(accountUuid: String, folderId: Long, uid: String): Boolean {
+ return this.accountUuid == accountUuid && this.folderId == folderId && this.uid == uid
+ }
+
+ fun withModifiedUid(newUid: String): MessageReference {
+ return copy(uid = newUid)
+ }
+
+ companion object {
+ private const val IDENTITY_VERSION_2 = '#'
+ private const val IDENTITY_SEPARATOR = ":"
+
+ @JvmStatic
+ fun parse(identity: String?): MessageReference? {
+ if (identity == null || identity.isEmpty() || identity[0] != IDENTITY_VERSION_2) {
+ return null
+ }
+
+ val tokens = StringTokenizer(identity.substring(2), IDENTITY_SEPARATOR, false)
+ if (tokens.countTokens() < 3) {
+ return null
+ }
+
+ val accountUuid = Base64.decode(tokens.nextToken())
+ val folderId = Base64.decode(tokens.nextToken()).toLong()
+ val uid = Base64.decode(tokens.nextToken())
+ return MessageReference(accountUuid, folderId, uid)
+ }
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java
index adae60ae2d7baef62e497e8a6041ce423525846b..40905a6c51caf4f1bd5c947a67541dea0c662104 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java
+++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java
@@ -23,7 +23,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import android.annotation.SuppressLint;
import android.content.Context;
-import android.os.PowerManager;
import android.os.Process;
import android.os.SystemClock;
@@ -65,6 +64,8 @@ import com.fsck.k9.mail.MessageRetrievalListener;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Part;
import com.fsck.k9.mail.ServerSettings;
+import com.fsck.k9.mail.power.PowerManager;
+import com.fsck.k9.mail.power.WakeLock;
import com.fsck.k9.mailstore.FolderDetailsAccessor;
import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.mailstore.LocalMessage;
@@ -79,8 +80,6 @@ import com.fsck.k9.mailstore.SaveMessageDataCreator;
import com.fsck.k9.mailstore.SendState;
import com.fsck.k9.notification.NotificationController;
import com.fsck.k9.notification.NotificationStrategy;
-import com.fsck.k9.power.TracingPowerManager;
-import com.fsck.k9.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchAccount;
import org.jetbrains.annotations.NotNull;
@@ -95,17 +94,22 @@ import static com.fsck.k9.search.LocalSearchExtensions.getAccountsFromLocalSearc
/**
- * Starts a long running (application) Thread that will run through commands that require remote mailbox access. This
- * class is used to serialize and prioritize these commands. Each method that will submit a command requires a
- * MessagingListener instance to be provided. It is expected that that listener has also been added as a registered
- * listener using addListener(). When a command is to be executed, if the listener that was provided with the command is
- * no longer registered the command is skipped. The design idea for the above is that when an Activity starts it
- * registers as a listener. When it is paused it removes itself. Thus, any commands that that activity submitted are
+ * Starts a long running (application) Thread that will run through commands
+ * that require remote mailbox access. This class is used to serialize and
+ * prioritize these commands. Each method that will submit a command requires a
+ * MessagingListener instance to be provided. It is expected that that listener
+ * has also been added as a registered listener using addListener(). When a
+ * command is to be executed, if the listener that was provided with the command
+ * is no longer registered the command is skipped. The design idea for the above
+ * is that when an Activity starts it registers as a listener. When it is paused
+ * it removes itself. Thus, any commands that that activity submitted are
* removed from the queue once the activity is no longer active.
*/
public class MessagingController {
public static final Set SYNC_FLAGS = EnumSet.of(Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED);
+
private static final long FOLDER_LIST_STALENESS_THRESHOLD = 30 * 60 * 1000L;
+
private final Context context;
private final NotificationController notificationController;
private final NotificationStrategy notificationStrategy;
@@ -114,20 +118,26 @@ public class MessagingController {
private final Preferences preferences;
private final MessageStoreManager messageStoreManager;
private final SaveMessageDataCreator saveMessageDataCreator;
+
private final Thread controllerThread;
+
private final BlockingQueue queuedCommands = new PriorityBlockingQueue<>();
private final Set listeners = new CopyOnWriteArraySet<>();
private final ExecutorService threadPool = Executors.newCachedThreadPool();
private final MemorizingMessagingListener memorizingMessagingListener = new MemorizingMessagingListener();
private final MessageCountsProvider messageCountsProvider;
private final DraftOperations draftOperations;
+
+
private MessagingListener checkMailListener = null;
private volatile boolean stopped = false;
+
public static MessagingController getInstance(Context context) {
return DI.get(MessagingController.class);
}
+
MessagingController(Context context, NotificationController notificationController,
NotificationStrategy notificationStrategy, LocalStoreProvider localStoreProvider,
MessageCountsProvider messageCountsProvider, BackendManager backendManager,
@@ -142,6 +152,7 @@ public class MessagingController {
this.preferences = preferences;
this.messageStoreManager = messageStoreManager;
this.saveMessageDataCreator = saveMessageDataCreator;
+
controllerThread = new Thread(new Runnable() {
@Override
public void run() {
@@ -151,7 +162,9 @@ public class MessagingController {
controllerThread.setName("MessagingController");
controllerThread.start();
addListener(memorizingMessagingListener);
+
initializeControllerExtensions(controllerExtensions);
+
draftOperations = new DraftOperations(this, messageStoreManager, saveMessageDataCreator);
}
@@ -159,6 +172,7 @@ public class MessagingController {
if (controllerExtensions.isEmpty()) {
return;
}
+
ControllerInternals internals = new ControllerInternals() {
@Override
public void put(@NotNull String description, @Nullable MessagingListener listener,
@@ -172,6 +186,7 @@ public class MessagingController {
MessagingController.this.putBackground(description, listener, runnable);
}
};
+
for (ControllerExtension extension : controllerExtensions) {
extension.init(this, backendManager, internals);
}
@@ -190,14 +205,16 @@ public class MessagingController {
String commandDescription = null;
try {
final Command command = queuedCommands.take();
+
if (command != null) {
commandDescription = command.description;
+
Timber.i("Running command '%s', seq = %s (%s priority)",
command.description,
command.sequence,
command.isForegroundPriority ? "foreground" : "background");
- command.runnable.run();
+ command.runnable.run();
Timber.i(" Command '%s' completed", command.description);
}
@@ -248,9 +265,13 @@ public class MessagingController {
}
}
- private String getFolderServerId(Account account, long folderId) throws MessagingException {
- LocalStore localStore = getLocalStoreOrThrow(account);
- return localStore.getFolderServerId(folderId);
+ private String getFolderServerId(Account account, long folderId) {
+ MessageStore messageStore = messageStoreManager.getMessageStore(account);
+ String folderServerId = messageStore.getFolderServerId(folderId);
+ if (folderServerId == null) {
+ throw new IllegalStateException("Folder not found (ID: " + folderId + ")");
+ }
+ return folderServerId;
}
private long getFolderId(Account account, String folderServerId) {
@@ -281,15 +302,19 @@ public class MessagingController {
return listeners;
}
+
public Set getListeners(MessagingListener listener) {
if (listener == null) {
return listeners;
}
+
Set listeners = new HashSet<>(this.listeners);
listeners.add(listener);
return listeners;
+
}
+
private void suppressMessages(Account account, List messages) {
EmailProviderCache cache = EmailProviderCache.getCache(account.getUuid(), context);
cache.hideMessages(messages);
@@ -303,12 +328,14 @@ public class MessagingController {
public boolean isMessageSuppressed(LocalMessage message) {
long messageId = message.getDatabaseId();
long folderId = message.getFolder().getDatabaseId();
+
EmailProviderCache cache = EmailProviderCache.getCache(message.getFolder().getAccountUuid(), context);
return cache.isMessageHidden(messageId, folderId);
}
private void setFlagInCache(final Account account, final List messageIds,
final Flag flag, final boolean newState) {
+
EmailProviderCache cache = EmailProviderCache.getCache(account.getUuid(), context);
String columnName = LocalStore.getColumnNameForFlag(flag);
String value = Integer.toString((newState) ? 1 : 0);
@@ -317,6 +344,7 @@ public class MessagingController {
private void removeFlagFromCache(final Account account, final List messageIds,
final Flag flag) {
+
EmailProviderCache cache = EmailProviderCache.getCache(account.getUuid(), context);
String columnName = LocalStore.getColumnNameForFlag(flag);
cache.removeValueForMessages(messageIds, columnName);
@@ -324,6 +352,7 @@ public class MessagingController {
private void setFlagForThreadsInCache(final Account account, final List threadRootIds,
final Flag flag, final boolean newState) {
+
EmailProviderCache cache = EmailProviderCache.getCache(account.getUuid(), context);
String columnName = LocalStore.getColumnNameForFlag(flag);
String value = Integer.toString((newState) ? 1 : 0);
@@ -332,6 +361,7 @@ public class MessagingController {
private void removeFlagForThreadsFromCache(final Account account, final List messageIds,
final Flag flag) {
+
EmailProviderCache cache = EmailProviderCache.getCache(account.getUuid(), context);
String columnName = LocalStore.getColumnNameForFlag(flag);
cache.removeValueForThreads(messageIds, columnName);
@@ -348,10 +378,13 @@ public class MessagingController {
handleAuthenticationFailure(account, true);
return;
}
+
Backend backend = getBackend(account);
backend.refreshFolderList();
+
long now = System.currentTimeMillis();
Timber.d("Folder list successfully refreshed @ %tc", now);
+
account.setLastFolderListRefreshTime(now);
preferences.saveAccount(account);
} catch (Exception e) {
@@ -374,7 +407,9 @@ public class MessagingController {
@VisibleForTesting
void searchLocalMessagesSynchronous(final LocalSearch search, final MessagingListener listener) {
List searchAccounts = getAccountsFromLocalSearch(search, preferences);
+
for (final Account account : searchAccounts) {
+
// Collecting statistics of the search result
MessageRetrievalListener retrievalListener = new MessageRetrievalListener() {
@Override
@@ -389,6 +424,7 @@ public class MessagingController {
public void messageFinished(LocalMessage message, int number, int ofTotal) {
if (!isMessageSuppressed(message)) {
List messages = new ArrayList<>();
+
messages.add(message);
if (listener != null) {
listener.listLocalMessagesAddMessages(account, null, messages);
@@ -396,6 +432,7 @@ public class MessagingController {
}
}
};
+
// build and do the query in the localstore
try {
LocalStore localStore = localStoreProvider.getInstance(account);
@@ -404,6 +441,7 @@ public class MessagingController {
Timber.e(e);
}
}
+
if (listener != null) {
listener.listLocalMessagesFinished();
}
@@ -412,6 +450,7 @@ public class MessagingController {
public Future> searchRemoteMessages(String acctUuid, long folderId, String query, Set requiredFlags,
Set forbiddenFlags, MessagingListener listener) {
Timber.i("searchRemoteMessages (acct = %s, folderId = %d, query = %s)", acctUuid, folderId, query);
+
return threadPool.submit(() ->
searchRemoteMessagesSynchronous(acctUuid, folderId, query, requiredFlags, forbiddenFlags, listener)
);
@@ -420,35 +459,47 @@ public class MessagingController {
@VisibleForTesting
void searchRemoteMessagesSynchronous(String acctUuid, long folderId, String query, Set requiredFlags,
Set forbiddenFlags, MessagingListener listener) {
+
Account account = preferences.getAccount(acctUuid);
+
if (listener != null) {
listener.remoteSearchStarted(folderId);
}
+
List extraResults = new ArrayList<>();
try {
LocalStore localStore = localStoreProvider.getInstance(account);
+
LocalFolder localFolder = localStore.getFolder(folderId);
if (!localFolder.exists()) {
throw new MessagingException("Folder not found");
}
+
localFolder.open();
String folderServerId = localFolder.getServerId();
+
Backend backend = getBackend(account);
+
boolean performFullTextSearch = account.isRemoteSearchFullText();
List messageServerIds = backend.search(folderServerId, query, requiredFlags, forbiddenFlags,
performFullTextSearch);
+
Timber.i("Remote search got %d results", messageServerIds.size());
+
// There's no need to fetch messages already completely downloaded
messageServerIds = localFolder.extractNewMessages(messageServerIds);
+
if (listener != null) {
listener.remoteSearchServerQueryComplete(folderId, messageServerIds.size(),
account.getRemoteSearchNumResults());
}
+
int resultLimit = account.getRemoteSearchNumResults();
if (resultLimit > 0 && messageServerIds.size() > resultLimit) {
extraResults = messageServerIds.subList(resultLimit, messageServerIds.size());
messageServerIds = messageServerIds.subList(0, resultLimit);
}
+
loadSearchResultsSynchronous(account, messageServerIds, localFolder);
} catch (Exception e) {
if (Thread.currentThread().isInterrupted()) {
@@ -465,6 +516,7 @@ public class MessagingController {
listener.remoteSearchFinished(folderId, 0, account.getRemoteSearchNumResults(), extraResults);
}
}
+
}
public void loadSearchResults(Account account, long folderId, List messageServerIds,
@@ -473,13 +525,16 @@ public class MessagingController {
if (listener != null) {
listener.enableProgressIndicator(true);
}
+
try {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
if (!localFolder.exists()) {
throw new MessagingException("Folder not found");
}
+
localFolder.open();
+
loadSearchResultsSynchronous(account, messageServerIds, localFolder);
} catch (MessagingException e) {
Timber.e(e, "Exception in loadSearchResults");
@@ -493,16 +548,20 @@ public class MessagingController {
private void loadSearchResultsSynchronous(Account account, List messageServerIds, LocalFolder localFolder)
throws MessagingException {
+
Backend backend = getBackend(account);
String folderServerId = localFolder.getServerId();
+
for (String messageServerId : messageServerIds) {
LocalMessage localMessage = localFolder.getMessage(messageServerId);
+
if (localMessage == null) {
backend.downloadMessageStructure(folderServerId, messageServerId);
}
}
}
+
public void loadMoreMessages(Account account, long folderId, MessagingListener listener) {
try {
LocalStore localStore = localStoreProvider.getInstance(account);
@@ -527,6 +586,7 @@ public class MessagingController {
public void synchronizeMailboxBlocking(Account account, String folderServerId) {
long folderId = getFolderId(account, folderServerId);
+
final CountDownLatch latch = new CountDownLatch(1);
putBackground("synchronizeMailbox", null, () -> {
try {
@@ -535,6 +595,7 @@ public class MessagingController {
latch.countDown();
}
});
+
try {
latch.await();
} catch (Exception e) {
@@ -543,7 +604,8 @@ public class MessagingController {
}
/**
- * Start foreground synchronization of the specified folder. This is generally only called by synchronizeMailbox.
+ * Start foreground synchronization of the specified folder. This is generally only called
+ * by synchronizeMailbox.
*
* TODO Break this method up into smaller chunks.
*/
@@ -551,6 +613,7 @@ public class MessagingController {
void synchronizeMailboxSynchronous(Account account, long folderId, MessagingListener listener,
NotificationState notificationState) {
refreshFolderListIfStale(account);
+
Backend backend = getBackend(account);
syncFolder(account, folderId, listener, backend, notificationState);
}
@@ -558,6 +621,7 @@ public class MessagingController {
private void refreshFolderListIfStale(Account account) {
long lastFolderListRefresh = account.getLastFolderListRefreshTime();
long now = System.currentTimeMillis();
+
if (lastFolderListRefresh > now || lastFolderListRefresh + FOLDER_LIST_STALENESS_THRESHOLD <= now) {
Timber.d("Last folder list refresh @ %tc. Refreshing now…", lastFolderListRefresh);
refreshFolderListSynchronous(account);
@@ -573,6 +637,7 @@ public class MessagingController {
handleAuthenticationFailure(account, true);
return;
}
+
Exception commandException = null;
try {
processPendingCommandsSynchronous(account);
@@ -580,6 +645,7 @@ public class MessagingController {
Timber.e(e, "Failure processing command, but allow message sync attempt");
commandException = e;
}
+
LocalFolder localFolder;
try {
LocalStore localStore = localStoreProvider.getInstance(account);
@@ -589,18 +655,23 @@ public class MessagingController {
Timber.e(e, "syncFolder: Couldn't load local folder %d", folderId);
return;
}
+
// We can't sync local folders
if (localFolder.isLocalOnly()) {
return;
}
+
MessageStore messageStore = messageStoreManager.getMessageStore(account);
Long lastChecked = messageStore.getFolder(folderId, FolderDetailsAccessor::getLastChecked);
boolean suppressNotifications = lastChecked == null;
+
String folderServerId = localFolder.getServerId();
SyncConfig syncConfig = createSyncConfig(account);
ControllerSyncListener syncListener =
new ControllerSyncListener(account, listener, suppressNotifications, notificationState);
+
backend.sync(folderServerId, syncConfig, syncListener);
+
if (commandException != null && !syncListener.syncFailed) {
String rootMessage = getRootCauseMessage(commandException);
Timber.e("Root cause failure in %s:%s was '%s'", account.getDescription(), folderServerId, rootMessage);
@@ -658,6 +729,7 @@ public class MessagingController {
processPendingCommandsSynchronous(account);
} catch (MessagingException me) {
Timber.e(me, "processPendingCommands");
+
/*
* Ignore any exceptions from the commands. Commands will be processed
* on the next round.
@@ -670,12 +742,14 @@ public class MessagingController {
public void processPendingCommandsSynchronous(Account account) throws MessagingException {
LocalStore localStore = localStoreProvider.getInstance(account);
List commands = localStore.getPendingCommands();
+
PendingCommand processingCommand = null;
try {
for (PendingCommand command : commands) {
processingCommand = command;
String commandName = command.getCommandName();
Timber.d("Processing pending command '%s'", commandName);
+
/*
* We specifically do not catch any exceptions here. If a command fails it is
* most likely due to a server or IO error and it must be retried before any
@@ -683,7 +757,9 @@ public class MessagingController {
*/
try {
command.execute(this, account);
+
localStore.removePendingCommand(command);
+
Timber.d("Done processing pending command '%s'", commandName);
} catch (MessagingException me) {
if (me.isPermanentFailure()) {
@@ -695,10 +771,12 @@ public class MessagingController {
} catch (Exception e) {
Timber.e(e, "Unexpected exception with command '%s', removing command from queue", commandName);
localStore.removePendingCommand(processingCommand);
+
if (K9.DEVELOPER_MODE) {
throw new AssertionError("Unexpected exception while processing pending command", e);
}
}
+
// TODO: When removing a pending command due to an error the local changes should be reverted. Pending
// commands that depend on this command should be canceled and local changes be reverted. In most cases
// the user should be notified about the failure as well.
@@ -710,11 +788,11 @@ public class MessagingController {
}
}
-
/**
- * Process a pending append message command. This command uploads a local message to the server, first checking to
- * be sure that the server message is not newer than the local message. Once the local message is successfully
- * processed it is deleted so that the server message will be synchronized down without an additional copy being
+ * Process a pending append message command. This command uploads a local message to the
+ * server, first checking to be sure that the server message is not newer than
+ * the local message. Once the local message is successfully processed it is deleted so
+ * that the server message will be synchronized down without an additional copy being
* created.
*/
void processPendingAppend(PendingAppend command, Account account) throws MessagingException {
@@ -722,36 +800,46 @@ public class MessagingController {
long folderId = command.folderId;
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
+
String folderServerId = localFolder.getServerId();
String uid = command.uid;
+
LocalMessage localMessage = localFolder.getMessage(uid);
if (localMessage == null) {
return;
}
+
if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX)) {
//FIXME: This should never happen. Throw in debug builds.
return;
}
+
Backend backend = getBackend(account);
+
if (localMessage.isSet(Flag.X_REMOTE_COPY_STARTED)) {
Timber.w("Local message with uid %s has flag %s already set, checking for remote message with " +
"same message id", localMessage.getUid(), X_REMOTE_COPY_STARTED);
+
String messageServerId = backend.findByMessageId(folderServerId, localMessage.getMessageId());
if (messageServerId != null) {
Timber.w("Local message has flag %s already set, and there is a remote message with uid %s, " +
"assuming message was already copied and aborting this copy",
X_REMOTE_COPY_STARTED, messageServerId);
+
String oldUid = localMessage.getUid();
localMessage.setUid(messageServerId);
localFolder.changeUid(localMessage);
+
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folderId, oldUid, localMessage.getUid());
}
+
return;
} else {
Timber.w("No remote message with message-id found, proceeding with append");
}
}
+
/*
* If the message does not exist remotely we just upload it and then
* update our local copy with the new uid.
@@ -761,7 +849,9 @@ public class MessagingController {
localFolder.fetch(Collections.singletonList(localMessage), fp, null);
String oldUid = localMessage.getUid();
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
+
String messageServerId = backend.uploadMessage(folderServerId, localMessage);
+
if (messageServerId == null) {
// We didn't get the server UID of the uploaded message. Remove the local message now. The uploaded
// version will be downloaded during the next sync.
@@ -769,6 +859,7 @@ public class MessagingController {
} else {
localMessage.setUid(messageServerId);
localFolder.changeUid(localMessage);
+
for (MessagingListener l : getListeners()) {
l.messageUidChanged(account, folderId, oldUid, localMessage.getUid());
}
@@ -802,8 +893,10 @@ public class MessagingController {
long srcFolder = command.srcFolderId;
long destFolder = command.destFolderId;
MoveOrCopyFlavor operation = command.isCopy ? MoveOrCopyFlavor.COPY : MoveOrCopyFlavor.MOVE;
+
Map newUidMap = command.newUidMap;
List uids = newUidMap != null ? new ArrayList<>(newUidMap.keySet()) : command.uids;
+
processPendingMoveOrCopy(account, srcFolder, destFolder, uids, operation, newUidMap);
}
@@ -812,6 +905,7 @@ public class MessagingController {
long destFolder = command.destFolderId;
Map newUidMap = command.newUidMap;
List uids = new ArrayList<>(newUidMap.keySet());
+
processPendingMoveOrCopy(account, srcFolder, destFolder, uids,
MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ, newUidMap);
}
@@ -820,14 +914,19 @@ public class MessagingController {
void processPendingMoveOrCopy(Account account, long srcFolderId, long destFolderId, List uids,
MoveOrCopyFlavor operation, Map newUidMap) throws MessagingException {
checkNotNull(newUidMap);
+
LocalStore localStore = localStoreProvider.getInstance(account);
+
LocalFolder localSourceFolder = localStore.getFolder(srcFolderId);
localSourceFolder.open();
String srcFolderServerId = localSourceFolder.getServerId();
+
LocalFolder localDestFolder = localStore.getFolder(destFolderId);
localDestFolder.open();
String destFolderServerId = localDestFolder.getServerId();
+
Backend backend = getBackend(account);
+
Map remoteUidMap;
switch (operation) {
case COPY:
@@ -842,27 +941,32 @@ public class MessagingController {
default:
throw new RuntimeException("Unsupported messaging operation");
}
+
if (operation != MoveOrCopyFlavor.COPY) {
if (backend.getSupportsExpunge() && account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY) {
- Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(),
- srcFolderServerId);
+ Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolderServerId);
backend.expungeMessages(srcFolderServerId, uids);
}
+
destroyPlaceholderMessages(localSourceFolder, uids);
}
+
// TODO: Change Backend interface to ensure we never receive null for remoteUidMap
if (remoteUidMap == null) {
remoteUidMap = Collections.emptyMap();
}
+
// Update local messages (that currently have local UIDs) with new server IDs
for (String uid : uids) {
String localUid = newUidMap.get(uid);
String newUid = remoteUidMap.get(uid);
+
LocalMessage localMessage = localDestFolder.getMessage(localUid);
if (localMessage == null) {
// Local message no longer exists
continue;
}
+
if (newUid != null) {
// Update local message with new server ID
localMessage.setUid(newUid);
@@ -883,11 +987,13 @@ public class MessagingController {
if (placeholderMessage == null) {
continue;
}
+
if (placeholderMessage.isSet(Flag.DELETED)) {
placeholderMessage.destroy();
} else {
Timber.w("Expected local message %s in folder %s to be a placeholder, but DELETE flag wasn't set",
uid, localFolder.getServerId());
+
if (BuildConfig.DEBUG) {
throw new AssertionError("Placeholder message must have the DELETED flag set");
}
@@ -923,12 +1029,15 @@ public class MessagingController {
void processPendingDelete(PendingDelete command, Account account) throws MessagingException {
long folderId = command.folderId;
List uids = command.uids;
+
Backend backend = getBackend(account);
String folderServerId = getFolderServerId(account, folderId);
backend.deleteMessages(folderServerId, uids);
+
if (backend.getSupportsExpunge() && account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY) {
backend.expungeMessages(folderServerId, uids);
}
+
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
@@ -950,9 +1059,12 @@ public class MessagingController {
long folderId = command.folderId;
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
+
localFolder.open();
String folderServerId = localFolder.getServerId();
+
Timber.i("Marking all messages in %s:%s as read", account, folderServerId);
+
// TODO: Make this one database UPDATE operation
List messages = localFolder.getMessages(null, false);
for (Message message : messages) {
@@ -960,9 +1072,11 @@ public class MessagingController {
message.setFlag(Flag.SEEN, true);
}
}
+
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folderId);
}
+
Backend backend = getBackend(account);
if (backend.getSupportsFlags()) {
backend.markAllAsRead(folderServerId);
@@ -977,7 +1091,9 @@ public class MessagingController {
public void setFlag(final Account account, final List messageIds, final Flag flag,
final boolean newState) {
+
setFlagInCache(account, messageIds, flag, newState);
+
threadPool.execute(new Runnable() {
@Override
public void run() {
@@ -988,7 +1104,9 @@ public class MessagingController {
public void setFlagForThreads(final Account account, final List threadRootIds,
final Flag flag, final boolean newState) {
+
setFlagForThreadsInCache(account, threadRootIds, flag, newState);
+
threadPool.execute(new Runnable() {
@Override
public void run() {
@@ -999,6 +1117,7 @@ public class MessagingController {
private void setFlagSynchronous(final Account account, final List ids,
final Flag flag, final boolean newState, final boolean threadedList) {
+
LocalStore localStore;
try {
localStore = localStoreProvider.getInstance(account);
@@ -1006,6 +1125,7 @@ public class MessagingController {
Timber.e(e, "Couldn't get LocalStore instance");
return;
}
+
// Update affected messages in the database. This should be as fast as possible so the UI
// can be updated with the new state.
try {
@@ -1019,6 +1139,7 @@ public class MessagingController {
} catch (MessagingException e) {
Timber.e(e, "Couldn't set flags in local database");
}
+
// Read folder ID and UID of messages from the database
Map> folderMap;
try {
@@ -1027,15 +1148,19 @@ public class MessagingController {
Timber.e(e, "Couldn't get folder name and UID of messages");
return;
}
+
boolean accountSupportsFlags = supportsFlags(account);
+
// Loop over all folders
for (Entry> entry : folderMap.entrySet()) {
long folderId = entry.getKey();
List uids = entry.getValue();
+
// Notify listeners of changed folder status
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folderId);
}
+
if (accountSupportsFlags) {
LocalFolder localFolder = localStore.getFolder(folderId);
try {
@@ -1065,11 +1190,14 @@ public class MessagingController {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
+
// Update the messages in the local store
localFolder.setFlags(messages, Collections.singleton(flag), newState);
+
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folderId);
}
+
// Handle the remote side
if (supportsFlags(account) && !localFolder.isLocalOnly()) {
List uids = getUidsFromMessages(messages);
@@ -1089,6 +1217,7 @@ public class MessagingController {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
+
LocalMessage message = localFolder.getMessage(uid);
if (message != null) {
setFlag(account, folderId, Collections.singletonList(message), flag, newState);
@@ -1128,7 +1257,9 @@ public class MessagingController {
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
String folderServerId = localFolder.getServerId();
+
LocalMessage message = localFolder.getMessage(uid);
+
if (uid.startsWith(K9.LOCAL_UID_PREFIX)) {
Timber.w("Message has local UID so cannot download fully.");
// ASH move toast
@@ -1141,17 +1272,21 @@ public class MessagingController {
message.setFlag(Flag.X_DOWNLOADED_PARTIAL, false);
} else {
Backend backend = getBackend(account);
+
if (loadPartialFromSearch) {
SyncConfig syncConfig = createSyncConfig(account);
backend.downloadMessage(syncConfig, folderServerId, uid);
} else {
backend.downloadCompleteMessage(folderServerId, uid);
}
+
message = localFolder.getMessage(uid);
+
if (!loadPartialFromSearch) {
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
}
}
+
// now that we have the full message, refresh the headers
for (MessagingListener l : getListeners(listener)) {
l.loadMessageRemoteFinished(account, folderId, uid);
@@ -1169,16 +1304,20 @@ public class MessagingController {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
+
LocalMessage message = localFolder.getMessage(uid);
if (message == null || message.getDatabaseId() == 0) {
String folderName = localFolder.getName();
throw new IllegalArgumentException("Message not found: folder=" + folderName + ", uid=" + uid);
}
+
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.BODY);
localFolder.fetch(Collections.singletonList(message), fp, null);
+
notificationController.removeNewMailNotification(account, message.makeMessageReference());
markMessageAsReadOnView(account, message);
+
return message;
}
@@ -1186,35 +1325,43 @@ public class MessagingController {
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
+
LocalMessage message = localFolder.getMessage(uid);
if (message == null || message.getDatabaseId() == 0) {
String folderName = localFolder.getName();
throw new IllegalArgumentException("Message not found: folder=" + folderName + ", uid=" + uid);
}
+
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
localFolder.fetch(Collections.singletonList(message), fp, null);
+
return message;
}
private void markMessageAsReadOnView(Account account, LocalMessage message)
throws MessagingException {
+
if (account.isMarkMessageAsReadOnView() && !message.isSet(Flag.SEEN)) {
List messageIds = Collections.singletonList(message.getDatabaseId());
setFlag(account, messageIds, Flag.SEEN, true);
+
message.setFlagInternal(Flag.SEEN, true);
}
}
public void loadAttachment(final Account account, final LocalMessage message, final Part part,
final MessagingListener listener) {
+
put("loadAttachment", listener, new Runnable() {
@Override
public void run() {
try {
String folderServerId = message.getFolder().getServerId();
+
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderServerId);
+
ProgressBodyFactory bodyFactory = new ProgressBodyFactory(new ProgressListener() {
@Override
public void updateProgress(int progress) {
@@ -1223,14 +1370,18 @@ public class MessagingController {
}
}
});
+
Backend backend = getBackend(account);
backend.fetchPart(folderServerId, message.getUid(), part, bodyFactory);
+
localFolder.addPartToMessage(message, part);
+
for (MessagingListener l : getListeners(listener)) {
l.loadAttachmentFinished(account, message, part);
}
} catch (MessagingException me) {
Timber.v(me, "Exception loading attachment");
+
for (MessagingListener l : getListeners(listener)) {
l.loadAttachmentFailed(account, message, part, me.getMessage());
}
@@ -1250,14 +1401,18 @@ public class MessagingController {
Timber.e("Error sending message. No Outbox folder configured.");
return;
}
+
message.setFlag(Flag.SEEN, true);
+
MessageStore messageStore = messageStoreManager.getMessageStore(account);
SaveMessageData messageData = saveMessageDataCreator.createSaveMessageData(
message, MessageDownloadState.FULL, plaintextSubject);
long messageId = messageStore.saveLocalMessage(outboxFolderId, messageData, null);
+
LocalStore localStore = localStoreProvider.getInstance(account);
OutboxStateRepository outboxStateRepository = localStore.getOutboxStateRepository();
outboxStateRepository.initializeOutboxState(messageId);
+
sendPendingMessages(account, listener);
} catch (Exception e) {
Timber.e(e, "Error sending message");
@@ -1269,7 +1424,6 @@ public class MessagingController {
backend.sendMessage(message);
}
-
/**
* Attempt to send any messages that are sitting in the Outbox.
*/
@@ -1279,7 +1433,9 @@ public class MessagingController {
@Override
public void run() {
if (messagesPendingSend(account)) {
+
showSendingNotificationIfNecessary(account);
+
try {
sendPendingMessagesSynchronous(account);
} finally {
@@ -1308,6 +1464,7 @@ public class MessagingController {
Timber.w("Could not get Outbox folder ID from Account");
return false;
}
+
MessageStore messageStore = messageStoreManager.getMessageStore(account);
return messageStore.getMessageCount(outboxFolderId) > 0;
}
@@ -1325,6 +1482,7 @@ public class MessagingController {
handleAuthenticationFailure(account, false);
return;
}
+
LocalStore localStore = localStoreProvider.getInstance(account);
OutboxStateRepository outboxStateRepository = localStore.getOutboxStateRepository();
LocalFolder localFolder = localStore.getFolder(account.getOutboxFolderId());
@@ -1332,8 +1490,11 @@ public class MessagingController {
Timber.v("Outbox does not exist");
return;
}
+
localFolder.open();
+
long outboxFolderId = localFolder.getDatabaseId();
+
List localMessages = localFolder.getMessages(null);
int progress = 0;
int todo = localMessages.size();
@@ -1347,8 +1508,11 @@ public class MessagingController {
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.BODY);
+
Timber.i("Scanning Outbox folder for messages to send");
+
Backend backend = getBackend(account);
+
for (LocalMessage message : localMessages) {
if (message.isSet(Flag.DELETED)) {
//FIXME: When uploading a message to the remote Sent folder the move code creates a placeholder
@@ -1360,14 +1524,17 @@ public class MessagingController {
try {
long messageId = message.getDatabaseId();
OutboxState outboxState = outboxStateRepository.getOutboxState(messageId);
+
if (outboxState.getSendState() != SendState.READY) {
Timber.v("Skipping sending message " + message.getUid());
notificationController.showSendFailedNotification(account,
new MessagingException(message.getSubject()));
continue;
}
+
Timber.i("Send count for message %s is %d", message.getUid(),
outboxState.getNumberOfSendAttempts());
+
localFolder.fetch(Collections.singletonList(message), fp, null);
try {
if (message.getHeader(K9.IDENTITY_HEADER).length > 0 || message.isSet(Flag.DRAFT)) {
@@ -1375,10 +1542,13 @@ public class MessagingController {
"This message appears to be a draft, so K-9 will not send it");
continue;
}
+
outboxStateRepository.incrementSendAttempts(messageId);
message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
+
Timber.i("Sending message with UID %s", message.getUid());
backend.sendMessage(message);
+
message.setFlag(Flag.X_SEND_IN_PROGRESS, false);
message.setFlag(Flag.SEEN, true);
progress++;
@@ -1386,32 +1556,38 @@ public class MessagingController {
l.synchronizeMailboxProgress(account, outboxFolderId, progress, todo);
}
moveOrDeleteSentMessage(account, localStore, message);
+
outboxStateRepository.removeOutboxState(messageId);
} catch (AuthenticationFailedException e) {
outboxStateRepository.decrementSendAttempts(messageId);
lastFailure = e;
wasPermanentFailure = false;
+
handleAuthenticationFailure(account, false);
handleSendFailure(account, localFolder, message, e);
} catch (CertificateValidationException e) {
outboxStateRepository.decrementSendAttempts(messageId);
lastFailure = e;
wasPermanentFailure = false;
+
notifyUserIfCertificateProblem(account, e, false);
handleSendFailure(account, localFolder, message, e);
} catch (MessagingException e) {
lastFailure = e;
wasPermanentFailure = e.isPermanentFailure();
+
if (wasPermanentFailure) {
String errorMessage = e.getMessage();
outboxStateRepository.setSendAttemptError(messageId, errorMessage);
} else if (outboxState.getNumberOfSendAttempts() + 1 >= MAX_SEND_ATTEMPTS) {
outboxStateRepository.setSendAttemptsExceeded(messageId);
}
+
handleSendFailure(account, localFolder, message, e);
} catch (Exception e) {
lastFailure = e;
wasPermanentFailure = true;
+
handleSendFailure(account, localFolder, message, e);
}
} catch (Exception e) {
@@ -1421,6 +1597,7 @@ public class MessagingController {
notifySynchronizeMailboxFailed(account, localFolder, e);
}
}
+
if (lastFailure != null) {
if (wasPermanentFailure) {
notificationController.showSendFailedNotification(account, lastFailure);
@@ -1448,9 +1625,12 @@ public class MessagingController {
sentFolder.open();
String sentFolderServerId = sentFolder.getServerId();
Timber.i("Moving sent message to folder '%s' (%d)", sentFolderServerId, sentFolderId);
+
MessageStore messageStore = messageStoreManager.getMessageStore(account);
long destinationMessageId = messageStore.moveMessage(message.getDatabaseId(), sentFolderId);
+
Timber.i("Moved sent message to folder '%s' (%d)", sentFolderServerId, sentFolderId);
+
if (!sentFolder.isLocalOnly()) {
String destinationUid = messageStore.getMessageServerId(destinationMessageId);
PendingCommand command = PendingAppend.create(sentFolderId, destinationUid);
@@ -1462,8 +1642,10 @@ public class MessagingController {
private void handleSendFailure(Account account, LocalFolder localFolder, Message message, Exception exception)
throws MessagingException {
+
Timber.e(exception, "Failed to send message");
message.setFlag(Flag.X_SEND_FAILED, true);
+
notifySynchronizeMailboxFailed(account, localFolder, exception);
}
@@ -1539,6 +1721,7 @@ public class MessagingController {
List messageReferences, long destFolderId) {
actOnMessageGroup(srcAccount, srcFolderId, messageReferences, (account, messageFolder, messages) -> {
suppressMessages(account, messages);
+
putBackground("moveMessages", null, () ->
moveOrCopyMessageSynchronous(account, srcFolderId, messages, destFolderId, MoveOrCopyFlavor.MOVE)
);
@@ -1549,6 +1732,7 @@ public class MessagingController {
List messageReferences, long destFolderId) {
actOnMessageGroup(srcAccount, srcFolderId, messageReferences, (account, messageFolder, messages) -> {
suppressMessages(account, messages);
+
putBackground("moveMessagesInThread", null, () -> {
try {
List messagesInThreads = collectMessagesInThreads(account, messages);
@@ -1595,9 +1779,11 @@ public class MessagingController {
private void moveOrCopyMessageSynchronous(Account account, long srcFolderId, List inMessages,
long destFolderId, MoveOrCopyFlavor operation) {
+
if (operation == MoveOrCopyFlavor.MOVE_AND_MARK_AS_READ) {
throw new UnsupportedOperationException("MOVE_AND_MARK_AS_READ unsupported");
}
+
try {
LocalStore localStore = localStoreProvider.getInstance(account);
if (operation == MoveOrCopyFlavor.MOVE && !isMoveCapable(account)) {
@@ -1606,10 +1792,13 @@ public class MessagingController {
if (operation == MoveOrCopyFlavor.COPY && !isCopyCapable(account)) {
return;
}
+
LocalFolder localSrcFolder = localStore.getFolder(srcFolderId);
localSrcFolder.open();
+
LocalFolder localDestFolder = localStore.getFolder(destFolderId);
localDestFolder.open();
+
boolean unreadCountAffected = false;
List uids = new LinkedList<>();
for (Message message : inMessages) {
@@ -1617,15 +1806,19 @@ public class MessagingController {
if (!uid.startsWith(K9.LOCAL_UID_PREFIX)) {
uids.add(uid);
}
+
if (!unreadCountAffected && !message.isSet(Flag.SEEN)) {
unreadCountAffected = true;
}
}
+
List messages = localSrcFolder.getMessagesByUids(uids);
if (messages.size() > 0) {
Timber.i("moveOrCopyMessageSynchronous: source folder = %s, %d messages, destination folder = %s, " +
"operation = %s", srcFolderId, messages.size(), destFolderId, operation.name());
+
MessageStore messageStore = messageStoreManager.getMessageStore(account);
+
List messageIds = new ArrayList<>();
Map messageIdToUidMapping = new HashMap<>();
for (LocalMessage message : messages) {
@@ -1633,9 +1826,11 @@ public class MessagingController {
messageIds.add(messageId);
messageIdToUidMapping.put(messageId, message.getUid());
}
+
Map resultIdMapping;
if (operation == MoveOrCopyFlavor.COPY) {
resultIdMapping = messageStore.copyMessages(messageIds, destFolderId);
+
if (unreadCountAffected) {
// If this copy operation changes the unread count in the destination
// folder, notify the listeners.
@@ -1645,7 +1840,9 @@ public class MessagingController {
}
} else {
resultIdMapping = messageStore.moveMessages(messageIds, destFolderId);
+
unsuppressMessages(account, messages);
+
if (unreadCountAffected) {
// If this move operation changes the unread count, notify the listeners
// that the unread count changed in both the source and destination folder.
@@ -1655,25 +1852,30 @@ public class MessagingController {
}
}
}
+
Map destinationMapping = messageStore.getMessageServerIds(resultIdMapping.values());
+
Map uidMap = new HashMap<>();
for (Entry entry : resultIdMapping.entrySet()) {
long sourceMessageId = entry.getKey();
long destinationMessageId = entry.getValue();
+
String sourceUid = messageIdToUidMapping.get(sourceMessageId);
String destinationUid = destinationMapping.get(destinationMessageId);
uidMap.put(sourceUid, destinationUid);
}
+
queueMoveOrCopy(account, localSrcFolder.getDatabaseId(), localDestFolder.getDatabaseId(),
operation, uidMap);
}
+
processPendingCommands(account);
} catch (MessagingException me) {
throw new RuntimeException("Error moving message", me);
}
}
- public void moveToDraftsFolder(Account account, long folderId, List messages) {
+ public void moveToDraftsFolder(Account account, long folderId, List messages){
putBackground("moveToDrafts", null, () -> moveToDraftsFolderInBackground(account, folderId, messages));
}
@@ -1682,10 +1884,12 @@ public class MessagingController {
try {
Message message = loadMessage(account, folderId, messageReference.getUid());
Long draftMessageId = saveDraft(account, message, null, message.getSubject());
+
boolean draftSavedSuccessfully = draftMessageId != null;
if (draftSavedSuccessfully) {
message.destroy();
}
+
for (MessagingListener listener : getListeners()) {
listener.folderStatusChanged(account, folderId);
}
@@ -1709,12 +1913,13 @@ public class MessagingController {
Timber.w("No Drafts folder configured. Can't delete draft.");
return;
}
+
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
String uid = localFolder.getMessageUidById(id);
if (uid != null) {
- MessageReference messageReference = new MessageReference(account.getUuid(), folderId, uid, null);
+ MessageReference messageReference = new MessageReference(account.getUuid(), folderId, uid);
deleteMessage(messageReference);
}
} catch (MessagingException me) {
@@ -1742,14 +1947,19 @@ public class MessagingController {
private List collectMessagesInThreads(Account account, List messages)
throws MessagingException {
+
LocalStore localStore = localStoreProvider.getInstance(account);
+
List messagesInThreads = new ArrayList<>();
for (LocalMessage localMessage : messages) {
long rootId = localMessage.getRootId();
long threadId = (rootId == -1) ? localMessage.getThreadId() : rootId;
+
List messagesInThread = localStore.getMessagesInThread(threadId);
+
messagesInThreads.addAll(messagesInThread);
}
+
return messagesInThreads;
}
@@ -1771,10 +1981,13 @@ public class MessagingController {
if (!K9.DEVELOPER_MODE) {
throw new AssertionError("method must only be used in developer mode!");
}
+
actOnMessagesGroupedByAccountAndFolder(messages, new MessageActor() {
+
@Override
public void act(final Account account, final LocalFolder messageFolder,
final List accountMessages) {
+
putBackground("debugClearLocalMessages", null, new Runnable() {
@Override
public void run() {
@@ -1789,6 +2002,7 @@ public class MessagingController {
});
}
});
+
}
private void deleteMessagesSynchronous(Account account, long folderId, List messages) {
@@ -1805,16 +2019,20 @@ public class MessagingController {
syncedMessageUids.add(uid);
}
}
+
Backend backend = getBackend(account);
+
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(folderId);
localFolder.open();
+
Map uidMap = null;
Long trashFolderId = account.getTrashFolderId();
LocalFolder localTrashFolder = null;
if (!account.hasTrashFolder() || folderId == trashFolderId ||
(backend.getSupportsTrashFolder() && !backend.isDeleteMoveToTrash())) {
Timber.d("Not moving deleted messages to local Trash folder. Removing local copies.");
+
if (!localOnlyMessages.isEmpty()) {
localFolder.destroyMessages(localOnlyMessages);
}
@@ -1824,7 +2042,9 @@ public class MessagingController {
} else {
Timber.d("Deleting messages in normal folder, moving");
localTrashFolder = localStore.getFolder(trashFolderId);
+
MessageStore messageStore = messageStoreManager.getMessageStore(account);
+
List messageIds = new ArrayList<>();
Map messageIdToUidMapping = new HashMap<>();
for (LocalMessage message : messages) {
@@ -1832,28 +2052,35 @@ public class MessagingController {
messageIds.add(messageId);
messageIdToUidMapping.put(messageId, message.getUid());
}
+
Map moveMessageIdMapping = messageStore.moveMessages(messageIds, trashFolderId);
+
Map destinationMapping = messageStore.getMessageServerIds(moveMessageIdMapping.values());
uidMap = new HashMap<>();
for (Entry entry : moveMessageIdMapping.entrySet()) {
long sourceMessageId = entry.getKey();
long destinationMessageId = entry.getValue();
+
String sourceUid = messageIdToUidMapping.get(sourceMessageId);
String destinationUid = destinationMapping.get(destinationMessageId);
uidMap.put(sourceUid, destinationUid);
}
+
if (account.isMarkMessageAsReadOnDelete()) {
Collection destinationMessageIds = moveMessageIdMapping.values();
messageStore.setFlag(destinationMessageIds, Flag.SEEN, true);
}
}
+
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folderId);
if (localTrashFolder != null) {
l.folderStatusChanged(account, trashFolderId);
}
}
+
Timber.d("Delete policy for account %s is %s", account.getDescription(), account.getDeletePolicy());
+
Long outboxFolderId = account.getOutboxFolderId();
if (outboxFolderId != null && folderId == outboxFolderId && supportsUpload(account)) {
for (String destinationUid : uidMap.values()) {
@@ -1885,6 +2112,7 @@ public class MessagingController {
Timber.d("Delete policy %s prevents delete from server", account.getDeletePolicy());
}
}
+
unsuppressMessages(account, messages);
} catch (MessagingException me) {
throw new RuntimeException("Error deleting message from local store.", me);
@@ -1903,18 +2131,23 @@ public class MessagingController {
if (!account.hasTrashFolder()) {
return;
}
+
long trashFolderId = account.getTrashFolderId();
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder folder = localStore.getFolder(trashFolderId);
folder.open();
String trashFolderServerId = folder.getServerId();
+
Backend backend = getBackend(account);
backend.deleteAllMessages(trashFolderServerId);
+
if (account.getExpungePolicy() == Expunge.EXPUNGE_IMMEDIATELY && backend.getSupportsExpunge()) {
backend.expunge(trashFolderServerId);
}
+
// Remove all messages marked as deleted
folder.destroyDeletedMessages();
+
compact(account, null);
}
@@ -1928,9 +2161,11 @@ public class MessagingController {
Timber.w("No Trash folder configured. Can't empty trash.");
return;
}
+
LocalStore localStore = localStoreProvider.getInstance(account);
LocalFolder localFolder = localStore.getFolder(trashFolderId);
localFolder.open();
+
boolean isTrashLocalOnly = isTrashLocalOnly(account);
if (isTrashLocalOnly) {
localFolder.clearAllMessages();
@@ -1938,9 +2173,11 @@ public class MessagingController {
localFolder.destroyLocalOnlyMessages();
localFolder.setFlags(Collections.singleton(Flag.DELETED), true);
}
+
for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, trashFolderId);
}
+
if (!isTrashLocalOnly) {
PendingCommand command = PendingEmptyTrash.create();
queuePendingCommand(account, command);
@@ -1970,14 +2207,17 @@ public class MessagingController {
}
}
+
/**
* Find out whether the account type only supports a local Trash folder.
*
*
Note: Currently this is only the case for POP3 accounts.
*
- * @param account The account to check.
- * @return {@code true} if the account only has a local Trash folder that is not synchronized with a folder on the
- * server. {@code false} otherwise.
+ * @param account
+ * The account to check.
+ *
+ * @return {@code true} if the account only has a local Trash folder that is not synchronized
+ * with a folder on the server. {@code false} otherwise.
*/
private boolean isTrashLocalOnly(Account account) {
Backend backend = getBackend(account);
@@ -1998,13 +2238,16 @@ public class MessagingController {
syncError.setValue(true);
}
});
+
Timber.v("performPeriodicMailSync(%s) about to await latch release", account.getDescription());
+
try {
latch.await();
Timber.v("performPeriodicMailSync(%s) got latch release", account.getDescription());
} catch (Exception e) {
Timber.e(e, "Interrupted while awaiting latch release");
}
+
boolean success = !syncError.getValue();
if (success) {
long now = System.currentTimeMillis();
@@ -2012,32 +2255,40 @@ public class MessagingController {
account.setLastSyncTime(now);
preferences.saveAccount(account);
}
+
return success;
}
/**
- * Checks mail for one or multiple accounts. If account is null all accounts are checked.
+ * Checks mail for one or multiple accounts. If account is null all accounts
+ * are checked.
*/
public void checkMail(final Account account,
final boolean ignoreLastCheckedTime,
final boolean useManualWakeLock,
final MessagingListener listener) {
- TracingWakeLock twakeLock = null;
+
+ final WakeLock wakeLock;
if (useManualWakeLock) {
- TracingPowerManager pm = TracingPowerManager.getPowerManager(context);
- twakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "K9 MessagingController.checkMail");
- twakeLock.setReferenceCounted(false);
- twakeLock.acquire(K9.MANUAL_WAKE_LOCK_TIMEOUT);
+ PowerManager pm = DI.get(PowerManager.class);
+
+ wakeLock = pm.newWakeLock("K9 MessagingController.checkMail");
+ wakeLock.setReferenceCounted(false);
+ wakeLock.acquire(K9.MANUAL_WAKE_LOCK_TIMEOUT);
+ } else {
+ wakeLock = null;
}
- final TracingWakeLock wakeLock = twakeLock;
+
for (MessagingListener l : getListeners(listener)) {
l.checkMailStarted(context, account);
}
putBackground("checkMail", listener, new Runnable() {
@Override
public void run() {
+
try {
Timber.i("Starting mail check");
+
Collection accounts;
if (account != null) {
accounts = new ArrayList<>(1);
@@ -2045,22 +2296,27 @@ public class MessagingController {
} else {
accounts = preferences.getAccounts();
}
+
for (final Account account : accounts) {
checkMailForAccount(context, account, ignoreLastCheckedTime, listener);
}
+
} catch (Exception e) {
Timber.e(e, "Unable to synchronize mail");
}
putBackground("finalize sync", null, new Runnable() {
@Override
public void run() {
+
Timber.i("Finished mail sync");
+
if (wakeLock != null) {
wakeLock.release();
}
for (MessagingListener l : getListeners(listener)) {
l.checkMailFinished(context, account);
}
+
}
}
);
@@ -2068,22 +2324,29 @@ public class MessagingController {
});
}
+
private void checkMailForAccount(final Context context, final Account account,
final boolean ignoreLastCheckedTime,
final MessagingListener listener) {
-
Timber.i("Synchronizing account %s", account.getDescription());
+
NotificationState notificationState = new NotificationState();
+
sendPendingMessages(account, listener);
+
refreshFolderListIfStale(account);
+
try {
Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
Account.FolderMode aSyncMode = account.getFolderSyncMode();
+
LocalStore localStore = localStoreProvider.getInstance(account);
for (final LocalFolder folder : localStore.getPersonalNamespaces(false)) {
folder.open();
+
FolderClass fDisplayClass = folder.getDisplayClass();
FolderClass fSyncClass = folder.getSyncClass();
+
if (LocalFolder.isModeMismatch(aDisplayMode, fDisplayClass)) {
// Never sync a folder that isn't displayed
/*
@@ -2092,8 +2355,10 @@ public class MessagingController {
" which is in display mode " + fDisplayClass + " while account is in display mode " + aDisplayMode);
}
*/
+
continue;
}
+
if (LocalFolder.isModeMismatch(aSyncMode, fSyncClass)) {
// Do not sync folders in the wrong class
/*
@@ -2102,6 +2367,7 @@ public class MessagingController {
" which is in sync mode " + fSyncClass + " while account is in sync mode " + aSyncMode);
}
*/
+
continue;
}
synchronizeFolder(account, folder, ignoreLastCheckedTime, listener, notificationState);
@@ -2123,6 +2389,8 @@ public class MessagingController {
}
);
}
+
+
}
private void synchronizeFolder(Account account, LocalFolder folder, boolean ignoreLastCheckedTime,
@@ -2135,9 +2403,11 @@ public class MessagingController {
private void synchronizeFolderInBackground(Account account, LocalFolder folder, boolean ignoreLastCheckedTime,
MessagingListener listener, NotificationState notificationState) {
Timber.v("Folder %s was last synced @ %tc", folder.getServerId(), folder.getLastChecked());
+
if (!ignoreLastCheckedTime) {
long lastCheckedTime = folder.getLastChecked();
long now = System.currentTimeMillis();
+
if (lastCheckedTime > now) {
// The time this folder was last checked lies in the future. We better ignore this and sync now.
} else {
@@ -2150,6 +2420,7 @@ public class MessagingController {
}
}
}
+
try {
showFetchingMailNotificationIfNecessary(account, folder);
try {
@@ -2197,7 +2468,6 @@ public class MessagingController {
});
}
-
public void deleteAccount(Account account) {
notificationController.clearNewMailNotifications(account);
memorizingMessagingListener.removeAccount(account);
@@ -2226,6 +2496,7 @@ public class MessagingController {
public MessagingListener listener;
public String description;
boolean isForegroundPriority;
+
int sequence = sequencing.getAndIncrement();
@Override
@@ -2270,18 +2541,22 @@ public class MessagingController {
if (!(exception instanceof CertificateValidationException)) {
return;
}
+
CertificateValidationException cve = (CertificateValidationException) exception;
if (!cve.needsUserAttention()) {
return;
}
+
notificationController.showCertificateErrorNotification(account, incoming);
}
private void actOnMessagesGroupedByAccountAndFolder(List messages, MessageActor actor) {
Map>> accountMap = groupMessagesByAccountAndFolder(messages);
+
for (Map.Entry>> entry : accountMap.entrySet()) {
String accountUuid = entry.getKey();
Account account = preferences.getAccount(accountUuid);
+
Map> folderMap = entry.getValue();
for (Map.Entry> folderEntry : folderMap.entrySet()) {
long folderId = folderEntry.getKey();
@@ -2295,12 +2570,14 @@ public class MessagingController {
private Map>> groupMessagesByAccountAndFolder(
List messages) {
Map>> accountMap = new HashMap<>();
+
for (MessageReference message : messages) {
if (message == null) {
continue;
}
String accountUuid = message.getAccountUuid();
long folderId = message.getFolderId();
+
Map> folderMap = accountMap.get(accountUuid);
if (folderMap == null) {
folderMap = new HashMap<>();
@@ -2311,6 +2588,7 @@ public class MessagingController {
messageList = new LinkedList<>();
folderMap.put(folderId, messageList);
}
+
messageList.add(message);
}
return accountMap;
@@ -2325,6 +2603,7 @@ public class MessagingController {
} catch (MessagingException e) {
Timber.e(e, "Error loading account?!");
}
+
}
private interface MessageActor {
@@ -2335,11 +2614,11 @@ public class MessagingController {
private final Account account;
private final MessagingListener listener;
private final LocalStore localStore;
- private final int previousUnreadMessageCount;
private final boolean suppressNotifications;
private final NotificationState notificationState;
boolean syncFailed = false;
+
ControllerSyncListener(Account account, MessagingListener listener, boolean suppressNotifications,
NotificationState notificationState) {
this.account = account;
@@ -2347,7 +2626,6 @@ public class MessagingController {
this.suppressNotifications = suppressNotifications;
this.notificationState = notificationState;
this.localStore = getLocalStoreOrThrow(account);
- previousUnreadMessageCount = getUnreadMessageCount(account);
}
@Override
@@ -2397,6 +2675,7 @@ public class MessagingController {
@Override
public void syncNewMessage(@NotNull String folderServerId, @NotNull String messageServerId,
boolean isOldMessage) {
+
// Send a notification of this message
LocalMessage message = loadMessage(folderServerId, messageServerId);
LocalFolder localFolder = message.getFolder();
@@ -2405,9 +2684,10 @@ public class MessagingController {
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, previousUnreadMessageCount, silent);
+ notificationController.addNewMailNotification(account, message, silent);
notificationState.setWasNotified(true);
}
+
if (!message.isSet(Flag.SEEN)) {
for (MessagingListener messagingListener : getListeners(listener)) {
messagingListener.synchronizeMailboxNewMessage(account, folderServerId, message);
@@ -2420,9 +2700,10 @@ public class MessagingController {
for (MessagingListener messagingListener : getListeners(listener)) {
messagingListener.synchronizeMailboxRemovedMessage(account, folderServerId, messageServerId);
}
+
String accountUuid = account.getUuid();
long folderId = getFolderId(account, folderServerId);
- MessageReference messageReference = new MessageReference(accountUuid, folderId, messageServerId, null);
+ MessageReference messageReference = new MessageReference(accountUuid, folderId, messageServerId);
notificationController.removeNewMailNotification(account, messageReference);
}
@@ -2438,6 +2719,7 @@ public class MessagingController {
shouldBeNotifiedOf = true;
}
}
+
// we're only interested in messages that need removing
if (!shouldBeNotifiedOf) {
MessageReference messageReference = message.makeMessageReference();
@@ -2445,7 +2727,6 @@ public class MessagingController {
}
}
-
@Override
public void syncFinished(@NotNull String folderServerId) {
long folderId = getFolderId(account, folderServerId);
@@ -2457,18 +2738,19 @@ public class MessagingController {
@Override
public void syncFailed(@NotNull String folderServerId, @NotNull String message, Exception exception) {
syncFailed = true;
+
if (exception instanceof AuthenticationFailedException) {
handleAuthenticationFailure(account, true);
} else {
notifyUserIfCertificateProblem(account, exception, true);
}
+
long folderId = getFolderId(account, folderServerId);
for (MessagingListener messagingListener : getListeners(listener)) {
messagingListener.synchronizeMailboxFailed(account, folderId, message);
}
}
-
@Override
public void folderStatusChanged(@NotNull String folderServerId) {
long folderId = getFolderId(account, folderServerId);
@@ -2491,4 +2773,4 @@ public class MessagingController {
private enum MoveOrCopyFlavor {
MOVE, COPY, MOVE_AND_MARK_AS_READ
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/controller/NotificationState.kt b/app/core/src/main/java/com/fsck/k9/controller/NotificationState.kt
index f9878abfb020bc99b3b797d9852695a41c258cff..32306f5b25379b6df311dd7cdb8dd87967239b31 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/NotificationState.kt
+++ b/app/core/src/main/java/com/fsck/k9/controller/NotificationState.kt
@@ -3,4 +3,4 @@ package com.fsck.k9.controller
class NotificationState {
@get:JvmName("wasNotified")
var wasNotified: Boolean = false
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/controller/ProgressBodyFactory.java b/app/core/src/main/java/com/fsck/k9/controller/ProgressBodyFactory.java
index 606541f27fa7baebc58e501affacd6ffa649dc2e..4fe052cd54f4165019236bff992a29907355778a 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/ProgressBodyFactory.java
+++ b/app/core/src/main/java/com/fsck/k9/controller/ProgressBodyFactory.java
@@ -21,10 +21,8 @@ class ProgressBodyFactory extends DefaultBodyFactory {
@Override
protected void copyData(InputStream inputStream, OutputStream outputStream) throws IOException {
- final CountingOutputStream countingOutputStream = new CountingOutputStream(outputStream);
-
Timer timer = new Timer();
- try {
+ try (CountingOutputStream countingOutputStream = new CountingOutputStream(outputStream)) {
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
diff --git a/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushController.kt b/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushController.kt
index 9688b95db8336277f963eda610f3f1a09411a361..c735c20bc6787ac251b3db3b37785739cc8f3d39 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushController.kt
+++ b/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushController.kt
@@ -7,13 +7,12 @@ import com.fsck.k9.backend.BackendManager
import com.fsck.k9.backend.api.BackendPusher
import com.fsck.k9.backend.api.BackendPusherCallback
import com.fsck.k9.controller.MessagingController
-import com.fsck.k9.mailstore.FolderRepositoryManager
+import com.fsck.k9.mailstore.FolderRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collect
-import com.fsck.k9.mailstore.FolderRepository
import kotlinx.coroutines.launch
import timber.log.Timber
@@ -101,4 +100,4 @@ internal class AccountPushController(
account.folderPushMode = FolderMode.NONE
preferences.saveAccount(account)
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushControllerFactory.kt b/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushControllerFactory.kt
index edadccbda4080b1aaff59675adcfb889878e7931..7091496d69ae22a5b744dcc7443cc79cf806bfbf 100644
--- a/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushControllerFactory.kt
+++ b/app/core/src/main/java/com/fsck/k9/controller/push/AccountPushControllerFactory.kt
@@ -1,9 +1,9 @@
package com.fsck.k9.controller.push
import com.fsck.k9.Account
+import com.fsck.k9.Preferences
import com.fsck.k9.backend.BackendManager
import com.fsck.k9.controller.MessagingController
-import com.fsck.k9.Preferences
import com.fsck.k9.mailstore.FolderRepository
internal class AccountPushControllerFactory(
diff --git a/app/core/src/main/java/com/fsck/k9/helper/MessageHelper.java b/app/core/src/main/java/com/fsck/k9/helper/MessageHelper.java
index 11abdaeb8229ecf9b38b0d871d6280136bf007a3..d87c02a6b743fcb2aee7c9c25df169933607b3fc 100644
--- a/app/core/src/main/java/com/fsck/k9/helper/MessageHelper.java
+++ b/app/core/src/main/java/com/fsck/k9/helper/MessageHelper.java
@@ -2,6 +2,8 @@ package com.fsck.k9.helper;
import java.util.regex.Pattern;
+import java.util.regex.Pattern;
+
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableString;
diff --git a/app/core/src/main/java/com/fsck/k9/job/KoinModule.kt b/app/core/src/main/java/com/fsck/k9/job/KoinModule.kt
index 4bf3a7002f7e89663ed3ae854cd3a9ff82855ee0..4dd6f0e8fa3e15d5916db695765b0a70583fd8fa 100644
--- a/app/core/src/main/java/com/fsck/k9/job/KoinModule.kt
+++ b/app/core/src/main/java/com/fsck/k9/job/KoinModule.kt
@@ -1,7 +1,6 @@
package com.fsck.k9.job
import androidx.work.WorkerFactory
-import com.fsck.k9.Clock
import org.koin.dsl.module
val jobModule = module {
@@ -9,5 +8,5 @@ val jobModule = module {
single { K9WorkerFactory(get(), get()) }
single { get().getWorkManager() }
single { K9JobManager(get(), get(), get()) }
- factory { MailSyncWorkerManager(get(), Clock.INSTANCE) }
+ factory { MailSyncWorkerManager(workManager = get(), clock = get()) }
}
diff --git a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt
index 249cc7b2baf41b6fb467b29986e8fa488bae3638..d0a7ef0f8c31859bc974f6631b253f5c456daafd 100644
--- a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt
+++ b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt
@@ -43,6 +43,11 @@ class MailSyncWorker(
return Result.success()
}
+ if (account.incomingServerSettings.isMissingCredentials) {
+ Timber.d("Password for this account is missing. Skipping mail sync.")
+ return Result.success()
+ }
+
val success = messagingController.performPeriodicMailSync(account)
return if (success) Result.success() else Result.retry()
diff --git a/app/core/src/main/java/com/fsck/k9/logging/KoinModule.kt b/app/core/src/main/java/com/fsck/k9/logging/KoinModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4f0cf6048020b5116756408dac2be607dca44f12
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/logging/KoinModule.kt
@@ -0,0 +1,8 @@
+package com.fsck.k9.logging
+
+import org.koin.dsl.module
+
+val loggingModule = module {
+ factory { RealProcessExecutor() }
+ factory { LogcatLogFileWriter(contentResolver = get(), processExecutor = get()) }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/logging/LogFileWriter.kt b/app/core/src/main/java/com/fsck/k9/logging/LogFileWriter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d81c9e16611ab7b3507d66392440b0b572e1c67a
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/logging/LogFileWriter.kt
@@ -0,0 +1,38 @@
+package com.fsck.k9.logging
+
+import android.content.ContentResolver
+import android.net.Uri
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import org.apache.commons.io.IOUtils
+import timber.log.Timber
+
+interface LogFileWriter {
+ suspend fun writeLogTo(contentUri: Uri)
+}
+
+class LogcatLogFileWriter(
+ private val contentResolver: ContentResolver,
+ private val processExecutor: ProcessExecutor,
+ private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO
+) : LogFileWriter {
+ override suspend fun writeLogTo(contentUri: Uri) {
+ return withContext(coroutineDispatcher) {
+ writeLogBlocking(contentUri)
+ }
+ }
+
+ private fun writeLogBlocking(contentUri: Uri) {
+ Timber.v("Writing logcat output to content URI: %s", contentUri)
+
+ val outputStream = contentResolver.openOutputStream(contentUri)
+ ?: error("Error opening contentUri for writing")
+
+ outputStream.use {
+ processExecutor.exec("logcat -d").use { inputStream ->
+ IOUtils.copy(inputStream, outputStream)
+ }
+ }
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/logging/ProcessExecutor.kt b/app/core/src/main/java/com/fsck/k9/logging/ProcessExecutor.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cfa2ff653fc425eacc0774815cfd76c9009dfb90
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/logging/ProcessExecutor.kt
@@ -0,0 +1,14 @@
+package com.fsck.k9.logging
+
+import java.io.InputStream
+
+interface ProcessExecutor {
+ fun exec(command: String): InputStream
+}
+
+class RealProcessExecutor : ProcessExecutor {
+ override fun exec(command: String): InputStream {
+ val process = Runtime.getRuntime().exec(command)
+ return process.inputStream
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/FolderRepository.kt b/app/core/src/main/java/com/fsck/k9/mailstore/FolderRepository.kt
index 4629003a5a612e08507170d173af98eeda1dee21..f40136d34cc92743470f5526862f172d02815d64 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/FolderRepository.kt
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/FolderRepository.kt
@@ -2,6 +2,10 @@ package com.fsck.k9.mailstore
import com.fsck.k9.Account
import com.fsck.k9.Account.FolderMode
+import com.fsck.k9.DI
+import com.fsck.k9.controller.MessagingController
+import com.fsck.k9.controller.SimpleMessagingListener
+import com.fsck.k9.helper.sendBlockingSilently
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.preferences.AccountManager
import kotlinx.coroutines.CoroutineDispatcher
@@ -17,16 +21,11 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import com.fsck.k9.mail.FolderType as RemoteFolderType
-import com.fsck.k9.DI
-import com.fsck.k9.controller.MessagingController
-import com.fsck.k9.controller.SimpleMessagingListener
-import com.fsck.k9.helper.sendBlockingSilently
@OptIn(ExperimentalCoroutinesApi::class)
class FolderRepository(
private val messageStoreManager: MessageStoreManager,
private val accountManager: AccountManager,
- private val account: Account,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {
private val sortForDisplay =
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorage.kt b/app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorage.kt
index 5fc159cbab12bf7c4de63a68bdd3a88d9a8b93bc..566a13ca454e32939123b73d77559417c19ab0d2 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorage.kt
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/K9BackendStorage.kt
@@ -60,7 +60,9 @@ class K9BackendStorage(
}
override fun deleteFolders(folderServerIds: List) {
- messageStore.deleteFolders(folderServerIds)
+ if (folderServerIds.isNotEmpty()) {
+ messageStore.deleteFolders(folderServerIds)
+ }
}
override fun changeFolder(folderServerId: String, name: String, type: RemoteFolderType) {
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java b/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java
index 337492294a630bad6f4fb849dc61ca4c8db9f773..94d653c9dd6f12c86ec39db3dcad94eb6f79f2ea 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java
@@ -213,7 +213,6 @@ public class LocalFolder {
}
this.name = name;
-
updateFolderColumn("name", name);
}
@@ -247,11 +246,6 @@ public class LocalFolder {
});
}
-
- public MessageCounts getMessageCounts() throws MessagingException {
- return new MessageCounts(getUnreadMessageCount(), getStarredMessageCount());
- }
-
public int getUnreadMessageCount() throws MessagingException {
if (databaseId == -1L) {
open();
@@ -273,36 +267,11 @@ public class LocalFolder {
cursor.close();
}
-
return unreadMessageCount;
}
});
}
- private int getStarredMessageCount() throws MessagingException {
- if (databaseId == -1L) {
- open();
- }
-
- return this.localStore.getDatabase().execute(false, new DbCallback() {
- @Override
- public Integer doDbWork(final SQLiteDatabase db) {
- int starredMessageCount = 0;
- Cursor cursor = db.query("messages", new String[] { "COUNT(id)" },
- "folder_id = ? AND empty = 0 AND deleted = 0 AND flagged = 1",
- new String[] { Long.toString(databaseId) }, null, null, null);
- try {
- if (cursor.moveToFirst()) {
- starredMessageCount = cursor.getInt(0);
- }
- } finally {
- cursor.close();
- }
- return starredMessageCount;
- }
- });
- }
-
public int getVisibleLimit() throws MessagingException {
open();
return visibleLimit;
@@ -351,26 +320,14 @@ public class LocalFolder {
return (FolderClass.INHERITED == syncClass) ? getDisplayClass() : syncClass;
}
- public FolderClass getRawSyncClass() {
- return syncClass;
- }
-
public FolderClass getNotifyClass() {
return (FolderClass.INHERITED == notifyClass) ? getPushClass() : notifyClass;
}
- public FolderClass getRawNotifyClass() {
- return notifyClass;
- }
-
public FolderClass getPushClass() {
return (FolderClass.INHERITED == pushClass) ? getSyncClass() : pushClass;
}
- public FolderClass getRawPushClass() {
- return pushClass;
- }
-
public void setDisplayClass(FolderClass displayClass) throws MessagingException {
this.displayClass = displayClass;
updateFolderColumn("display_class", this.displayClass.name());
@@ -572,11 +529,11 @@ public class LocalFolder {
try {
cursor = db.rawQuery(
"SELECT " +
- LocalStore.GET_MESSAGES_COLS +
- "FROM messages " +
- "LEFT JOIN message_parts ON (message_parts.id = messages.message_part_id) " +
- "LEFT JOIN threads ON (threads.message_id = messages.id) " +
- "WHERE uid = ? AND folder_id = ?",
+ LocalStore.GET_MESSAGES_COLS +
+ "FROM messages " +
+ "LEFT JOIN message_parts ON (message_parts.id = messages.message_part_id) " +
+ "LEFT JOIN threads ON (threads.message_id = messages.id) " +
+ "WHERE uid = ? AND folder_id = ?",
new String[] { message.getUid(), Long.toString(databaseId) });
if (!cursor.moveToNext()) {
@@ -633,12 +590,12 @@ public class LocalFolder {
open();
return LocalFolder.this.localStore.getMessages(listener, LocalFolder.this,
"SELECT " + LocalStore.GET_MESSAGES_COLS +
- "FROM messages " +
- "LEFT JOIN message_parts ON (message_parts.id = messages.message_part_id) " +
- "LEFT JOIN threads ON (threads.message_id = messages.id) " +
- "WHERE empty = 0 AND " +
- (includeDeleted ? "" : "deleted = 0 AND ") +
- "folder_id = ? ORDER BY date DESC",
+ "FROM messages " +
+ "LEFT JOIN message_parts ON (message_parts.id = messages.message_part_id) " +
+ "LEFT JOIN threads ON (threads.message_id = messages.id) " +
+ "WHERE empty = 0 AND " +
+ (includeDeleted ? "" : "deleted = 0 AND ") +
+ "folder_id = ? ORDER BY date DESC",
new String[] { Long.toString(databaseId) });
}
});
@@ -832,20 +789,15 @@ public class LocalFolder {
}
private long decodeAndCountBytes(InputStream rawInputStream, String encoding, long fallbackValue) {
- InputStream decodingInputStream = localStore.getDecodingInputStream(rawInputStream, encoding);
- try {
- CountingOutputStream countingOutputStream = new CountingOutputStream();
- try {
- IOUtils.copy(decodingInputStream, countingOutputStream);
+ try (InputStream decodingInputStream = localStore.getDecodingInputStream(rawInputStream, encoding)) {
+ try (CountingOutputStream countingOutputStream = new CountingOutputStream()) {
+ IOUtils.copy(decodingInputStream, countingOutputStream);
return countingOutputStream.getCount();
- } catch (IOException e) {
- return fallbackValue;
}
- } finally {
- try {
- decodingInputStream.close();
- } catch (IOException e) { /* ignore */ }
+
+ } catch (IOException e) {
+ return fallbackValue;
}
}
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/LocalMessage.java b/app/core/src/main/java/com/fsck/k9/mailstore/LocalMessage.java
index ca429acffc8818298d7de1b30232347376c0d45a..aad983dc93158540aff773d191f4ad69c2d60084 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/LocalMessage.java
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/LocalMessage.java
@@ -24,7 +24,6 @@ import com.fsck.k9.mail.internet.AddressHeaderBuilder;
import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.message.MessageHeaderParser;
import com.fsck.k9.mailstore.LockableDatabase.DbCallback;
-import com.fsck.k9.mailstore.LockableDatabase.WrappedException;
import com.fsck.k9.message.extractors.PreviewResult.PreviewType;
import timber.log.Timber;
@@ -380,7 +379,7 @@ public class LocalMessage extends MimeMessage {
if (messageReference == null) {
String accountUuid = getFolder().getAccountUuid();
long folderId = getFolder().getDatabaseId();
- messageReference = new MessageReference(accountUuid, folderId, mUid, null);
+ messageReference = new MessageReference(accountUuid, folderId, mUid);
}
return messageReference;
}
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java b/app/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java
index bdeed866f5e6bf33decd7b6b2ed1e5248a95b8c4..98c3c8a90fae5b3ee27bc9ff81179c626147b04d 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/LocalStore.java
@@ -1,3 +1,4 @@
+
package com.fsck.k9.mailstore;
@@ -31,7 +32,7 @@ import android.text.TextUtils;
import com.fsck.k9.Account;
import com.fsck.k9.Clock;
import com.fsck.k9.DI;
-import com.fsck.k9.K9;
+import com.fsck.k9.controller.MessageCounts;
import com.fsck.k9.Preferences;
import com.fsck.k9.controller.MessageCounts;
import com.fsck.k9.controller.MessagingControllerCommands.PendingCommand;
@@ -54,8 +55,6 @@ import com.fsck.k9.mailstore.LockableDatabase.SchemaDefinition;
import com.fsck.k9.mailstore.StorageManager.InternalStorageProvider;
import com.fsck.k9.message.extractors.AttachmentCounter;
import com.fsck.k9.message.extractors.AttachmentInfoExtractor;
-import com.fsck.k9.message.extractors.MessageFulltextCreator;
-import com.fsck.k9.message.extractors.MessagePreviewCreator;
import com.fsck.k9.provider.EmailProvider;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.search.LocalSearch;
@@ -183,8 +182,8 @@ public class LocalStore {
}
/**
- * local://localhost/path/to/database/uuid.db This constructor is only used by {@link
- * LocalStoreProvider#getInstance(Account)}
+ * local://localhost/path/to/database/uuid.db
+ * This constructor is only used by {@link LocalStoreProvider#getInstance(Account)}
*/
private LocalStore(final Account account, final Context context) throws MessagingException {
this.context = context;
@@ -276,7 +275,6 @@ public class LocalStore {
} finally {
Utility.closeQuietly(cursor);
}
-
}
});
@@ -696,22 +694,6 @@ public class LocalStore {
return new File(attachmentDirectory, attachmentId);
}
- public String getFolderServerId(long folderId) throws MessagingException {
- return database.execute(false, db -> {
- try (Cursor cursor = db.query("folders", new String[] { "server_id" },
- "id = ?", new String[] { Long.toString(folderId) },
- null, null, null)
- ) {
- if (cursor.moveToFirst() && !cursor.isNull(0)) {
- return cursor.getString(0);
- } else {
- throw new MessagingException("Folder not found by database ID: " + folderId, true);
- }
- }
- });
- }
-
-
public static class AttachmentInfo {
public String name;
public long size;
@@ -809,7 +791,10 @@ public class LocalStore {
database.execute(true, new DbCallback() {
@Override
public Void doDbWork(final SQLiteDatabase db) {
- selectionArgs.toArray(new String[selectionArgs.size()]);
+
+ selectionCallback.doDbWork(db, selection.toString(),
+ selectionArgs.toArray(new String[selectionArgs.size()]));
+
return null;
}
});
@@ -1086,7 +1071,6 @@ public class LocalStore {
return new MessageCounts(getUnreadMessageCount(search), getStarredMessageCount(search));
}
-
public static String getColumnNameForFlag(Flag flag) {
switch (flag) {
case SEEN: {
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/LockableDatabase.java b/app/core/src/main/java/com/fsck/k9/mailstore/LockableDatabase.java
index e46b83333a2999d0637785993855d363a70ef2ba..bce1ec9b88252d809fe4614295bff9d9e5ed5b76 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/LockableDatabase.java
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/LockableDatabase.java
@@ -240,7 +240,6 @@ public class LockableDatabase {
}
private void openOrCreateDataspace() {
-
lockWrite();
try {
final File databaseFile = prepareStorage(mStorageProviderId);
@@ -276,11 +275,7 @@ public class LockableDatabase {
}
}
- /**
- * @param providerId Never null.
- * @return DB file.
- */
- protected File prepareStorage(final String providerId){
+ protected File prepareStorage(final String providerId) {
final StorageManager storageManager = getStorageManager();
final File databaseFile = storageManager.getDatabase(uUid, providerId);
@@ -292,7 +287,6 @@ public class LockableDatabase {
}
if (!databaseParentDir.exists()) {
if (!databaseParentDir.mkdirs()) {
- // Android seems to be unmounting the storage...
throw new RuntimeException("Unable to access: " + databaseParentDir);
}
FileHelper.touchFile(databaseParentDir, ".nomedia");
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/MessageStore.kt b/app/core/src/main/java/com/fsck/k9/mailstore/MessageStore.kt
index 6225792a9a60c9786246619db489ed85302f0d65..c7f290f47c30d03b9e7e3cf2b9fa9c2be2b5ef68 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/MessageStore.kt
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/MessageStore.kt
@@ -176,6 +176,11 @@ interface MessageStore {
*/
fun getFolderId(folderServerId: String): Long?
+ /**
+ * Find a folder with the given store ID and return its server ID.
+ */
+ fun getFolderServerId(folderId: Long): String?
+
/**
* Retrieve the number of messages in a folder.
*/
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java b/app/core/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java
index 35795fff237fdf17b5b5073c14d10b68a4dce8af..74e66529b86ee4407b6468dad3e222bcc0b18b6d 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java
@@ -66,7 +66,8 @@ public class MessageViewInfo {
}
public static MessageViewInfo createForMetadataOnly(Message message, boolean isMessageIncomplete) {
- return new MessageViewInfo(message, isMessageIncomplete, null, null, false, null, null, null, null, null, null);
+ String subject = message.getSubject();
+ return new MessageViewInfo(message, isMessageIncomplete, null, subject, false, null, null, null, null, null, null);
}
MessageViewInfo withCryptoData(CryptoResultAnnotation rootPartAnnotation, String extraViewableText,
diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/StorageManager.java b/app/core/src/main/java/com/fsck/k9/mailstore/StorageManager.java
index 92dcc381a16e0860ad1b62a9ed7f6fa58d634171..6aece52ec306c41a7142228f1f6e6ef5f45899ce 100644
--- a/app/core/src/main/java/com/fsck/k9/mailstore/StorageManager.java
+++ b/app/core/src/main/java/com/fsck/k9/mailstore/StorageManager.java
@@ -6,27 +6,26 @@ import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import android.content.Context;
import android.os.Environment;
-import com.fsck.k9.CoreResourceProvider;
-import com.fsck.k9.DI;
-
/**
- * Manager for different {@link StorageProvider} -classes that abstract access to sd-cards, additional internal memory
- * and other storage-locations.
+ * Manager for different {@link StorageProvider} -classes that abstract access
+ * to sd-cards, additional internal memory and other storage-locations.
*/
public class StorageManager {
/**
- * Provides entry points (File objects) to an underlying storage, alleviating the caller from having to know where
- * that storage is located.
+ * Provides entry points (File objects) to an underlying storage,
+ * alleviating the caller from having to know where that storage is located.
*
*
- * Allow checking for the denoted storage availability since its lifecycle can evolving (a storage might become
- * unavailable at some time and be back online later).
+ * Allow checking for the denoted storage availability since its lifecycle
+ * can evolving (a storage might become unavailable at some time and be back
+ * online later).
*
*/
public interface StorageProvider {
@@ -35,8 +34,9 @@ public class StorageManager {
* Retrieve the uniquely identifier for the current implementation.
*
*
- * It is expected that the identifier doesn't change over reboots since it'll be used to save settings and
- * retrieve the provider at a later time.
+ * It is expected that the identifier doesn't change over reboots since
+ * it'll be used to save settings and retrieve the provider at a later
+ * time.
*
*
*
@@ -50,56 +50,58 @@ public class StorageManager {
/**
* Hook point for provider initialization.
*
- * @param context Never null.
+ * @param context
+ * Never null.
*/
void init(Context context);
/**
- * @param context Never null.
- * @return A user displayable, localized name for this provider. Never
- * null.
- */
- String getName(Context context);
-
- /**
- * Some implementations may not be able to return valid File handles because the device doesn't provide the
- * denoted storage. You can check the provider compatibility with this method to prevent from having to invoke
- * this provider ever again.
+ * Some implementations may not be able to return valid File handles
+ * because the device doesn't provide the denoted storage. You can check
+ * the provider compatibility with this method to prevent from having to
+ * invoke this provider ever again.
*
- * @param context TODO
+ * @param context
+ * TODO
* @return Whether this provider supports the current device.
* @see StorageManager#getAvailableProviders()
*/
boolean isSupported(Context context);
/**
- * Return the {@link File} to the chosen email database file. The resulting {@link File} doesn't necessarily
- * match an existing file on the filesystem.
+ * Return the {@link File} to the chosen email database file. The
+ * resulting {@link File} doesn't necessarily match an existing file on
+ * the filesystem.
*
- * @param context Never null.
- * @param id Never null.
+ * @param context
+ * Never null.
+ * @param id
+ * Never null.
* @return Never null.
*/
File getDatabase(Context context, String id);
/**
- * Return the {@link File} to the chosen attachment directory. The resulting {@link File} doesn't necessarily
- * match an existing directory on the filesystem.
+ * Return the {@link File} to the chosen attachment directory. The
+ * resulting {@link File} doesn't necessarily match an existing
+ * directory on the filesystem.
*
- * @param context Never null.
- * @param id Never null.
+ * @param context
+ * Never null.
+ * @param id
+ * Never null.
* @return Never null.
*/
File getAttachmentDirectory(Context context, String id);
-
}
/**
* Strategy to access the always available internal storage.
*
*
- * This implementation is expected to work on every device since it's based on the regular Android API {@link
- * Context#getDatabasePath(String)} and uses the result to retrieve the DB path and the attachment directory path.
+ * This implementation is expected to work on every device since it's based
+ * on the regular Android API {@link Context#getDatabasePath(String)} and
+ * uses the result to retrieve the DB path and the attachment directory path.
*
*
*
@@ -109,12 +111,6 @@ public class StorageManager {
public static class InternalStorageProvider implements StorageProvider {
public static final String ID = "InternalStorage";
- private final CoreResourceProvider resourceProvider;
-
- public InternalStorageProvider(CoreResourceProvider resourceProvider) {
- this.resourceProvider = resourceProvider;
- }
-
@Override
public String getId() {
return ID;
@@ -122,12 +118,6 @@ public class StorageManager {
@Override
public void init(Context context) {
-
- }
-
- @Override
- public String getName(Context context) {
- return resourceProvider.internalStorageProviderName();
}
@Override
@@ -145,14 +135,14 @@ public class StorageManager {
// we store attachments in the database directory
return context.getDatabasePath(id + ".db_att");
}
-
-
}
/**
- * Strategy for accessing the storage as returned by {@link Environment#getExternalStorageDirectory()}. In order to
- * be compliant with Android recommendation regarding application uninstalling and to prevent from cluttering the
- * storage root, the chosen directory will be
+ * Strategy for accessing the storage as returned by
+ * {@link Environment#getExternalStorageDirectory()}. In order to be
+ * compliant with Android recommendation regarding application uninstalling
+ * and to prevent from cluttering the storage root, the chosen directory
+ * will be
* <STORAGE_ROOT>/Android/data/<APPLICATION_PACKAGE_NAME>/files/
*
*
@@ -160,25 +150,20 @@ public class StorageManager {
*
*
*
- * This provider is expected to work on all devices but the returned underlying storage might not be always
- * available, due to mount/unmount/USB share events.
+ * This provider is expected to work on all devices but the returned
+ * underlying storage might not be always available, due to
+ * mount/unmount/USB share events.
*
*/
public static class ExternalStorageProvider implements StorageProvider {
public static final String ID = "ExternalStorage";
- private final CoreResourceProvider resourceProvider;
-
/**
* Chosen base directory.
*/
private File mApplicationDirectory;
- public ExternalStorageProvider(CoreResourceProvider resourceProvider) {
- this.resourceProvider = resourceProvider;
- }
-
@Override
public String getId() {
return ID;
@@ -189,11 +174,6 @@ public class StorageManager {
mApplicationDirectory = context.getExternalFilesDir(null);
}
- @Override
- public String getName(Context context) {
- return resourceProvider.externalStorageProviderName();
- }
-
@Override
public boolean isSupported(Context context) {
return true;
@@ -208,8 +188,6 @@ public class StorageManager {
public File getAttachmentDirectory(Context context, String id) {
return new File(mApplicationDirectory, id + ".db_att");
}
-
-
}
/**
@@ -217,7 +195,6 @@ public class StorageManager {
*/
private final Map mProviders = new LinkedHashMap<>();
-
protected final Context context;
private static transient StorageManager instance;
@@ -225,18 +202,18 @@ public class StorageManager {
public static synchronized StorageManager getInstance(final Context context) {
if (instance == null) {
Context applicationContext = context.getApplicationContext();
- CoreResourceProvider resourceProvider = DI.get(CoreResourceProvider.class);
- instance = new StorageManager(applicationContext, resourceProvider);
+ instance = new StorageManager(applicationContext);
}
return instance;
}
-
/**
- * @param context Never null.
- * @throws NullPointerException If context is null.
+ * @param context
+ * Never null.
+ * @throws NullPointerException
+ * If context is null.
*/
- protected StorageManager(final Context context, CoreResourceProvider resourceProvider) throws NullPointerException {
+ protected StorageManager(final Context context) throws NullPointerException {
if (context == null) {
throw new NullPointerException("No Context given");
}
@@ -253,8 +230,9 @@ public class StorageManager {
* be considered as the default provider !!!
*/
final List allProviders = Arrays.asList(
- new InternalStorageProvider(resourceProvider),
- new ExternalStorageProvider(resourceProvider));
+ new InternalStorageProvider(),
+ new ExternalStorageProvider()
+ );
for (final StorageProvider provider : allProviders) {
// check for provider compatibility
if (provider.isSupported(context)) {
@@ -276,7 +254,8 @@ public class StorageManager {
}
/**
- * @param providerId Never null.
+ * @param providerId
+ * Never null.
* @return null if not found.
*/
protected StorageProvider getProvider(final String providerId) {
@@ -284,8 +263,10 @@ public class StorageManager {
}
/**
- * @param dbName Never null.
- * @param providerId Never null.
+ * @param dbName
+ * Never null.
+ * @param providerId
+ * Never null.
* @return The resolved database file for the given provider ID.
*/
public File getDatabase(final String dbName, final String providerId) {
@@ -295,8 +276,10 @@ public class StorageManager {
}
/**
- * @param dbName Never null.
- * @param providerId Never null.
+ * @param dbName
+ * Never null.
+ * @param providerId
+ * Never null.
* @return The resolved attachment directory for the given provider ID.
*/
public File getAttachmentDirectory(final String dbName, final String providerId) {
@@ -305,18 +288,7 @@ public class StorageManager {
return provider.getAttachmentDirectory(context, dbName);
}
-
- /**
- * @return A map of available providers names, indexed by their ID. Never
- * null.
- * @see StorageManager
- * @see StorageProvider#isSupported(Context)
- */
- public Map getAvailableProviders() {
- final Map result = new LinkedHashMap<>();
- for (final Map.Entry entry : mProviders.entrySet()) {
- result.put(entry.getKey(), entry.getValue().getName(context));
- }
- return result;
+ public Set getAvailableProviders() {
+ return mProviders.keySet();
}
}
diff --git a/app/core/src/main/java/com/fsck/k9/message/IdentityHeaderBuilder.java b/app/core/src/main/java/com/fsck/k9/message/IdentityHeaderBuilder.java
index a8f4472bf5fc37223172424e2b145452710086b7..92f1020bbc188a3ba4a849d5073c15930bda45be 100644
--- a/app/core/src/main/java/com/fsck/k9/message/IdentityHeaderBuilder.java
+++ b/app/core/src/main/java/com/fsck/k9/message/IdentityHeaderBuilder.java
@@ -9,9 +9,11 @@ import timber.log.Timber;
import com.fsck.k9.Account.QuoteStyle;
import com.fsck.k9.Identity;
+import com.fsck.k9.K9;
import com.fsck.k9.controller.MessageReference;
import com.fsck.k9.mail.internet.TextBody;
import com.fsck.k9.message.quote.InsertableHtmlContent;
+import timber.log.Timber;
public class IdentityHeaderBuilder {
@@ -125,6 +127,7 @@ public class IdentityHeaderBuilder {
headerValue.append(input, start, end);
start = end;
}
+
return headerValue.toString();
}
diff --git a/app/core/src/main/java/com/fsck/k9/message/extractors/BasicPartInfoExtractor.kt b/app/core/src/main/java/com/fsck/k9/message/extractors/BasicPartInfoExtractor.kt
index d8b2d830cedeaecec90189e1dd15a28cdf4411f8..6992a87a4a1bd344786e1e913afb5fd74f76f898 100644
--- a/app/core/src/main/java/com/fsck/k9/message/extractors/BasicPartInfoExtractor.kt
+++ b/app/core/src/main/java/com/fsck/k9/message/extractors/BasicPartInfoExtractor.kt
@@ -4,7 +4,6 @@ import com.fsck.k9.mail.Part
import com.fsck.k9.mail.internet.MimeParameterDecoder
import com.fsck.k9.mail.internet.MimeUtility
import com.fsck.k9.mail.internet.MimeValue
-import java.util.Locale
private const val FALLBACK_NAME = "noname"
diff --git a/app/core/src/main/java/com/fsck/k9/message/html/HtmlToPlainText.kt b/app/core/src/main/java/com/fsck/k9/message/html/HtmlToPlainText.kt
index 191270718c05c1cb2520e76985861ba88b8900fb..9ea06eafe74b8c8152699a19d0ec6144bc15820d 100644
--- a/app/core/src/main/java/com/fsck/k9/message/html/HtmlToPlainText.kt
+++ b/app/core/src/main/java/com/fsck/k9/message/html/HtmlToPlainText.kt
@@ -22,7 +22,6 @@ object HtmlToPlainText {
}
private class FormattingVisitor : NodeVisitor {
- private var width = 0
private val output = StringBuilder()
private var collectLinkText = false
private var linkText = StringBuilder()
@@ -73,36 +72,11 @@ private class FormattingVisitor : NodeVisitor {
}
private fun append(text: String) {
- if (text.startsWith("\n")) {
- width = 0
- }
-
if (text == " " && (output.isEmpty() || output.last() in listOf(' ', '\n'))) {
return
}
- if (text.length + width > MAX_WIDTH) {
- val words = text.split(Regex("\\s+"))
- for (i in words.indices) {
- var word = words[i]
-
- val last = i == words.size - 1
- if (!last) {
- word = "$word "
- }
-
- if (word.length + width > MAX_WIDTH) {
- output.append("\n").append(word)
- width = word.length
- } else {
- output.append(word)
- width += word.length
- }
- }
- } else {
- output.append(text)
- width += text.length
- }
+ output.append(text)
}
private fun startNewLine() {
@@ -134,8 +108,4 @@ private class FormattingVisitor : NodeVisitor {
return output.substring(0, lastIndex + 1)
}
-
- companion object {
- private const val MAX_WIDTH = 76
- }
}
diff --git a/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt b/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt
index 4051fb352159e6e19d0c6d41d355e303156c0123..dd19edb4b3dc5411fa35c31e8d1c0645ef0f0a48 100644
--- a/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt
+++ b/app/core/src/main/java/com/fsck/k9/message/html/UriMatcher.kt
@@ -1,7 +1,5 @@
package com.fsck.k9.message.html
-import java.util.Locale
-
object UriMatcher {
private val SUPPORTED_URIS = run {
val httpUriParser = HttpUriParser()
diff --git a/app/core/src/main/java/com/fsck/k9/notification/AuthenticationErrorNotificationController.kt b/app/core/src/main/java/com/fsck/k9/notification/AuthenticationErrorNotificationController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..949994b52f9cd6f388333debb74ea0e5eb3fc7fd
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/AuthenticationErrorNotificationController.kt
@@ -0,0 +1,59 @@
+package com.fsck.k9.notification
+
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.Account
+
+internal open class AuthenticationErrorNotificationController(
+ private val notificationHelper: NotificationHelper,
+ private val actionCreator: NotificationActionCreator,
+ private val resourceProvider: NotificationResourceProvider
+) {
+ fun showAuthenticationErrorNotification(account: Account, incoming: Boolean) {
+ val notificationId = NotificationIds.getAuthenticationErrorNotificationId(account, incoming)
+ val editServerSettingsPendingIntent = createContentIntent(account, incoming)
+ val title = resourceProvider.authenticationErrorTitle()
+ val text = resourceProvider.authenticationErrorBody(account.description)
+
+ val notificationBuilder = notificationHelper
+ .createNotificationBuilder(account, NotificationChannelManager.ChannelType.MISCELLANEOUS)
+ .setSmallIcon(resourceProvider.iconWarning)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .setTicker(title)
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(editServerSettingsPendingIntent)
+ .setStyle(NotificationCompat.BigTextStyle().bigText(text))
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setCategory(NotificationCompat.CATEGORY_ERROR)
+
+ notificationHelper.configureNotification(
+ builder = notificationBuilder,
+ ringtone = null,
+ vibrationPattern = null,
+ ledColor = NotificationHelper.NOTIFICATION_LED_FAILURE_COLOR,
+ ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_FAST,
+ ringAndVibrate = true
+ )
+
+ notificationManager.notify(notificationId, notificationBuilder.build())
+ }
+
+ fun clearAuthenticationErrorNotification(account: Account, incoming: Boolean) {
+ val notificationId = NotificationIds.getAuthenticationErrorNotificationId(account, incoming)
+ notificationManager.cancel(notificationId)
+ }
+
+ protected open fun createContentIntent(account: Account, incoming: Boolean): PendingIntent {
+ return if (incoming) {
+ actionCreator.getEditIncomingServerSettingsIntent(account)
+ } else {
+ actionCreator.getEditOutgoingServerSettingsIntent(account)
+ }
+ }
+
+ private val notificationManager: NotificationManagerCompat
+ get() = notificationHelper.getNotificationManager()
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6b4501e9dda235b8182f9896c72bfc2cfd2fd9df
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/BaseNotificationDataCreator.kt
@@ -0,0 +1,52 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.K9
+import com.fsck.k9.K9.LockScreenNotificationVisibility
+
+private const val MAX_NUMBER_OF_SENDERS_IN_LOCK_SCREEN_NOTIFICATION = 5
+
+internal class BaseNotificationDataCreator {
+
+ fun createBaseNotificationData(notificationData: NotificationData): BaseNotificationData {
+ val account = notificationData.account
+ return BaseNotificationData(
+ account = account,
+ groupKey = NotificationGroupKeys.getGroupKey(account),
+ accountName = getAccountName(account),
+ color = account.chipColor,
+ newMessagesCount = notificationData.newMessagesCount,
+ lockScreenNotificationData = createLockScreenNotificationData(notificationData),
+ appearance = createNotificationAppearance(account)
+ )
+ }
+
+ private fun getAccountName(account: Account): String {
+ val accountDescription = account.description?.takeIf { it.isNotEmpty() }
+ return accountDescription ?: account.email
+ }
+
+ private fun createLockScreenNotificationData(data: NotificationData): LockScreenNotificationData {
+ return when (K9.lockScreenNotificationVisibility) {
+ LockScreenNotificationVisibility.NOTHING -> LockScreenNotificationData.None
+ LockScreenNotificationVisibility.APP_NAME -> LockScreenNotificationData.AppName
+ LockScreenNotificationVisibility.EVERYTHING -> LockScreenNotificationData.Public
+ LockScreenNotificationVisibility.MESSAGE_COUNT -> LockScreenNotificationData.MessageCount
+ LockScreenNotificationVisibility.SENDERS -> LockScreenNotificationData.SenderNames(getSenderNames(data))
+ }
+ }
+
+ private fun getSenderNames(data: NotificationData): String {
+ return data.getContentForSummaryNotification().asSequence()
+ .map { it.sender }
+ .distinct()
+ .take(MAX_NUMBER_OF_SENDERS_IN_LOCK_SCREEN_NOTIFICATION)
+ .joinToString()
+ }
+
+ private fun createNotificationAppearance(account: Account): NotificationAppearance {
+ return with(account.notificationSetting) {
+ NotificationAppearance(ringtone = ringtone, vibrationPattern = vibration, ledColor = ledColor)
+ }
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/CertificateErrorNotificationController.kt b/app/core/src/main/java/com/fsck/k9/notification/CertificateErrorNotificationController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5dff412d39a7d5d8980595e99b0b879edca4b945
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/CertificateErrorNotificationController.kt
@@ -0,0 +1,59 @@
+package com.fsck.k9.notification
+
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.Account
+
+internal open class CertificateErrorNotificationController(
+ private val notificationHelper: NotificationHelper,
+ private val actionCreator: NotificationActionCreator,
+ private val resourceProvider: NotificationResourceProvider
+) {
+ fun showCertificateErrorNotification(account: Account, incoming: Boolean) {
+ val notificationId = NotificationIds.getCertificateErrorNotificationId(account, incoming)
+ val editServerSettingsPendingIntent = createContentIntent(account, incoming)
+ val title = resourceProvider.certificateErrorTitle(account.description)
+ val text = resourceProvider.certificateErrorBody()
+
+ val notificationBuilder = notificationHelper
+ .createNotificationBuilder(account, NotificationChannelManager.ChannelType.MISCELLANEOUS)
+ .setSmallIcon(resourceProvider.iconWarning)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .setTicker(title)
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(editServerSettingsPendingIntent)
+ .setStyle(NotificationCompat.BigTextStyle().bigText(text))
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setCategory(NotificationCompat.CATEGORY_ERROR)
+
+ notificationHelper.configureNotification(
+ builder = notificationBuilder,
+ ringtone = null,
+ vibrationPattern = null,
+ ledColor = NotificationHelper.NOTIFICATION_LED_FAILURE_COLOR,
+ ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_FAST,
+ ringAndVibrate = true
+ )
+
+ notificationManager.notify(notificationId, notificationBuilder.build())
+ }
+
+ fun clearCertificateErrorNotifications(account: Account, incoming: Boolean) {
+ val notificationId = NotificationIds.getCertificateErrorNotificationId(account, incoming)
+ notificationManager.cancel(notificationId)
+ }
+
+ protected open fun createContentIntent(account: Account, incoming: Boolean): PendingIntent {
+ return if (incoming) {
+ actionCreator.getEditIncomingServerSettingsIntent(account)
+ } else {
+ actionCreator.getEditOutgoingServerSettingsIntent(account)
+ }
+ }
+
+ private val notificationManager: NotificationManagerCompat
+ get() = notificationHelper.getNotificationManager()
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt b/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt
index 6904c91255921af2b0857da4dc647a9d04091690..928a2d6fee675ccfdabe99d6b62fd60d5c135651 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/CoreKoinModule.kt
@@ -8,15 +8,23 @@ import java.util.concurrent.Executors
import org.koin.dsl.module
val coreNotificationModule = module {
- single { NotificationController(get(), get(), get(), get(), get()) }
+ single {
+ NotificationController(
+ certificateErrorNotificationController = get(),
+ authenticationErrorNotificationController = get(),
+ syncNotificationController = get(),
+ sendFailedNotificationController = get(),
+ newMailNotificationController = get()
+ )
+ }
single { NotificationManagerCompat.from(get()) }
- single { NotificationHelper(get(), get(), get()) }
+ single { NotificationHelper(context = get(), notificationManager = get(), channelUtils = get()) }
single {
NotificationChannelManager(
- get(),
- Executors.newSingleThreadExecutor(),
- get().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager,
- get()
+ preferences = get(),
+ backgroundExecutor = Executors.newSingleThreadExecutor(),
+ notificationManager = get().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager,
+ resourceProvider = get()
)
}
single {
@@ -26,15 +34,67 @@ val coreNotificationModule = module {
serverSettingsSerializer = get()
)
}
- single { CertificateErrorNotifications(get(), get(), get()) }
- single { AuthenticationErrorNotifications(get(), get(), get()) }
- single { SyncNotifications(get(), get(), get()) }
- single { SendFailedNotifications(get(), get(), get()) }
- single { NewMailNotifications(get(), get(), get(), get()) }
- single { NotificationContentCreator(get(), get()) }
- single { WearNotifications(get(), get(), get()) }
- single { DeviceNotifications(get(), get(), get(), get(), get()) }
- single { LockScreenNotification(get(), get()) }
+ single {
+ CertificateErrorNotificationController(
+ notificationHelper = get(),
+ actionCreator = get(),
+ resourceProvider = get()
+ )
+ }
+ single {
+ AuthenticationErrorNotificationController(
+ notificationHelper = get(),
+ actionCreator = get(),
+ resourceProvider = get()
+ )
+ }
+ single {
+ SyncNotificationController(notificationHelper = get(), actionBuilder = get(), resourceProvider = get())
+ }
+ single {
+ SendFailedNotificationController(notificationHelper = get(), actionBuilder = get(), resourceProvider = get())
+ }
+ single {
+ NewMailNotificationController(
+ notificationManager = get(),
+ newMailNotificationManager = get(),
+ summaryNotificationCreator = get(),
+ singleMessageNotificationCreator = get()
+ )
+ }
+ single {
+ NewMailNotificationManager(
+ contentCreator = get(),
+ baseNotificationDataCreator = get(),
+ singleMessageNotificationDataCreator = get(),
+ summaryNotificationDataCreator = get(),
+ clock = get()
+ )
+ }
+ factory { NotificationContentCreator(context = get(), resourceProvider = get()) }
+ factory { BaseNotificationDataCreator() }
+ factory { SingleMessageNotificationDataCreator() }
+ factory { SummaryNotificationDataCreator(singleMessageNotificationDataCreator = get()) }
+ factory {
+ SingleMessageNotificationCreator(
+ notificationHelper = get(),
+ actionCreator = get(),
+ resourceProvider = get(),
+ lockScreenNotificationCreator = get(),
+ notificationManager = get()
+ )
+ }
+ factory {
+ SummaryNotificationCreator(
+ notificationHelper = get(),
+ actionCreator = get(),
+ lockScreenNotificationCreator = get(),
+ singleMessageNotificationCreator = get(),
+ resourceProvider = get(),
+ notificationManager = get()
+ )
+ }
+ factory { LockScreenNotificationCreator(notificationHelper = get(), resourceProvider = get()) }
single {
PushNotificationManager(
context = get(),
diff --git a/app/core/src/main/java/com/fsck/k9/notification/DeviceNotifications.kt b/app/core/src/main/java/com/fsck/k9/notification/DeviceNotifications.kt
deleted file mode 100644
index 5a6315be3d486a6ce93727cee5115dc9fe67317d..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/notification/DeviceNotifications.kt
+++ /dev/null
@@ -1,210 +0,0 @@
-package com.fsck.k9.notification
-
-import android.app.KeyguardManager
-import android.app.Notification
-import android.content.Context
-import androidx.core.app.NotificationCompat
-import com.fsck.k9.Account
-import com.fsck.k9.K9
-import com.fsck.k9.K9.NotificationHideSubject
-import com.fsck.k9.K9.NotificationQuickDelete
-import com.fsck.k9.notification.NotificationGroupKeys.getGroupKey
-import com.fsck.k9.notification.NotificationIds.getNewMailSummaryNotificationId
-
-internal open class DeviceNotifications(
- notificationHelper: NotificationHelper,
- actionCreator: NotificationActionCreator,
- private val lockScreenNotification: LockScreenNotification,
- private val wearNotifications: WearNotifications,
- resourceProvider: NotificationResourceProvider
-) : BaseNotifications(notificationHelper, actionCreator, resourceProvider) {
-
- fun buildSummaryNotification(account: Account, notificationData: NotificationData, silent: Boolean): Notification {
- val unreadMessageCount = notificationData.unreadMessageCount
-
- val builder = when {
- isPrivacyModeActive -> {
- createSimpleSummaryNotification(account, unreadMessageCount)
- }
- notificationData.isSingleMessageNotification -> {
- val holder = notificationData.holderForLatestNotification
- createBigTextStyleSummaryNotification(account, holder)
- }
- else -> {
- createInboxStyleSummaryNotification(account, notificationData, unreadMessageCount)
- }
- }
-
- if (notificationData.containsStarredMessages()) {
- builder.priority = NotificationCompat.PRIORITY_HIGH
- }
- val notificationId = getNewMailSummaryNotificationId(account)
- val deletePendingIntent = actionCreator.createDismissAllMessagesPendingIntent(account, notificationId)
- builder.setDeleteIntent(deletePendingIntent)
-
- lockScreenNotification.configureLockScreenNotification(builder, notificationData)
-
- val notificationSetting = account.notificationSetting
- notificationHelper.configureNotification(
- builder = builder,
- ringtone = if (notificationSetting.isRingEnabled) notificationSetting.ringtone else null,
- vibrationPattern = if (notificationSetting.isVibrateEnabled) notificationSetting.vibration else null,
- ledColor = if (notificationSetting.isLedEnabled) notificationSetting.ledColor else null,
- ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_SLOW,
- ringAndVibrate = !silent
- )
-
- return builder.build()
- }
-
- private fun createSimpleSummaryNotification(account: Account, unreadMessageCount: Int): NotificationCompat.Builder {
- val accountName = notificationHelper.getAccountName(account)
- val newMailText = resourceProvider.newMailTitle()
- val unreadMessageCountText = resourceProvider.newMailUnreadMessageCount(unreadMessageCount, accountName)
- val notificationId = getNewMailSummaryNotificationId(account)
- val contentIntent = actionCreator.createViewFolderListPendingIntent(account, notificationId)
-
- return createAndInitializeNotificationBuilder(account)
- .setNumber(unreadMessageCount)
- .setTicker(newMailText)
- .setContentTitle(unreadMessageCountText)
- .setContentText(newMailText)
- .setContentIntent(contentIntent)
- }
-
- private fun createBigTextStyleSummaryNotification(
- account: Account,
- holder: NotificationHolder
- ): NotificationCompat.Builder {
- val notificationId = getNewMailSummaryNotificationId(account)
- val builder = createBigTextStyleNotification(account, holder, notificationId)
- builder.setGroupSummary(true)
-
- val content = holder.content
- addReplyAction(builder, content, notificationId)
- addMarkAsReadAction(builder, content, notificationId)
- addDeleteAction(builder, content, notificationId)
-
- return builder
- }
-
- private fun createInboxStyleSummaryNotification(
- account: Account,
- notificationData: NotificationData,
- unreadMessageCount: Int
- ): NotificationCompat.Builder {
- val latestNotification = notificationData.holderForLatestNotification
- val newMessagesCount = notificationData.newMessagesCount
- val accountName = notificationHelper.getAccountName(account)
- val title = resourceProvider.newMessagesTitle(newMessagesCount)
- val summary = if (notificationData.hasSummaryOverflowMessages()) {
- resourceProvider.additionalMessages(notificationData.getSummaryOverflowMessagesCount(), accountName)
- } else {
- accountName
- }
- val groupKey = getGroupKey(account)
-
- val builder = createAndInitializeNotificationBuilder(account)
- .setNumber(unreadMessageCount)
- .setTicker(latestNotification.content.summary)
- .setGroup(groupKey)
- .setGroupSummary(true)
- .setContentTitle(title)
- .setSubText(accountName)
-
- val style = createInboxStyle(builder)
- .setBigContentTitle(title)
- .setSummaryText(summary)
-
- for (content in notificationData.getContentForSummaryNotification()) {
- style.addLine(content.summary)
- }
- builder.setStyle(style)
- addMarkAllAsReadAction(builder, notificationData)
- addDeleteAllAction(builder, notificationData)
- wearNotifications.addSummaryActions(builder, notificationData)
- val notificationId = getNewMailSummaryNotificationId(account)
- val messageReferences = notificationData.getAllMessageReferences()
- val contentIntent = actionCreator.createViewMessagesPendingIntent(account, messageReferences, notificationId)
- builder.setContentIntent(contentIntent)
-
- return builder
- }
-
- private fun addMarkAsReadAction(
- builder: NotificationCompat.Builder,
- content: NotificationContent,
- notificationId: Int
- ) {
- val icon = resourceProvider.iconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val messageReference = content.messageReference
- val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
-
- builder.addAction(icon, title, action)
- }
-
- private fun addMarkAllAsReadAction(builder: NotificationCompat.Builder, notificationData: NotificationData) {
- val icon = resourceProvider.iconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val markAllAsReadPendingIntent =
- actionCreator.createMarkAllAsReadPendingIntent(account, messageReferences, notificationId)
-
- builder.addAction(icon, title, markAllAsReadPendingIntent)
- }
-
- private fun addDeleteAllAction(builder: NotificationCompat.Builder, notificationData: NotificationData) {
- if (K9.notificationQuickDeleteBehaviour !== NotificationQuickDelete.ALWAYS) {
- return
- }
- val icon = resourceProvider.iconDelete
- val title = resourceProvider.actionDelete()
- val account = notificationData.account
- val notificationId = getNewMailSummaryNotificationId(account)
- val messageReferences = notificationData.getAllMessageReferences()
- val action = actionCreator.createDeleteAllPendingIntent(account, messageReferences, notificationId)
- builder.addAction(icon, title, action)
- }
-
- private fun addDeleteAction(
- builder: NotificationCompat.Builder,
- content: NotificationContent,
- notificationId: Int
- ) {
- if (!isDeleteActionEnabled()) {
- return
- }
- val icon = resourceProvider.iconDelete
- val title = resourceProvider.actionDelete()
- val messageReference = content.messageReference
- val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
-
- builder.addAction(icon, title, action)
- }
-
- private fun addReplyAction(builder: NotificationCompat.Builder, content: NotificationContent, notificationId: Int) {
- val icon = resourceProvider.iconReply
- val title = resourceProvider.actionReply()
- val messageReference = content.messageReference
- val replyToMessagePendingIntent = actionCreator.createReplyPendingIntent(messageReference, notificationId)
-
- builder.addAction(icon, title, replyToMessagePendingIntent)
- }
-
- private val isPrivacyModeActive: Boolean
- get() {
- val keyguardService = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
- val privacyModeAlwaysEnabled = K9.notificationHideSubject === NotificationHideSubject.ALWAYS
- val privacyModeEnabledWhenLocked = K9.notificationHideSubject === NotificationHideSubject.WHEN_LOCKED
- val screenLocked = keyguardService.inKeyguardRestrictedInputMode()
- return privacyModeAlwaysEnabled || privacyModeEnabledWhenLocked && screenLocked
- }
-
- protected open fun createInboxStyle(builder: NotificationCompat.Builder?): NotificationCompat.InboxStyle {
- return NotificationCompat.InboxStyle(builder)
- }
-}
-
diff --git a/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotification.kt b/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotification.kt
index f13e21f3150e661c8f011fd65799b3270a6aca37..cc0462b72c8077942222505440718a10fef4966d 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotification.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotification.kt
@@ -57,14 +57,13 @@ internal class LockScreenNotification(
private fun createPublicNotification(notificationData: NotificationData): NotificationCompat.Builder {
val account = notificationData.account
- val newMessages = notificationData.newMessagesCount
- val unreadCount = notificationData.unreadMessageCount
- val title = resourceProvider.newMessagesTitle(newMessages)
+ val newMessagesCount = notificationData.newMessagesCount
+ val title = resourceProvider.newMessagesTitle(newMessagesCount)
return notificationHelper.createNotificationBuilder(account, NotificationChannelManager.ChannelType.MESSAGES)
.setSmallIcon(resourceProvider.iconNewMail)
.setColor(account.chipColor)
- .setNumber(unreadCount)
+ .setNumber(newMessagesCount)
.setContentTitle(title)
.setCategory(NotificationCompat.CATEGORY_EMAIL)
}
@@ -80,4 +79,4 @@ internal class LockScreenNotification(
companion object {
const val MAX_NUMBER_OF_SENDERS_IN_LOCK_SCREEN_NOTIFICATION = 5
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotificationCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotificationCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e071201c0dac8659ebff93614f9a332094354f85
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/LockScreenNotificationCreator.kt
@@ -0,0 +1,60 @@
+package com.fsck.k9.notification
+
+import android.app.Notification
+import androidx.core.app.NotificationCompat
+
+internal class LockScreenNotificationCreator(
+ private val notificationHelper: NotificationHelper,
+ private val resourceProvider: NotificationResourceProvider
+) {
+ fun configureLockScreenNotification(
+ builder: NotificationCompat.Builder,
+ baseNotificationData: BaseNotificationData
+ ) {
+ when (baseNotificationData.lockScreenNotificationData) {
+ LockScreenNotificationData.None -> {
+ builder.setVisibility(NotificationCompat.VISIBILITY_SECRET)
+ }
+ LockScreenNotificationData.AppName -> {
+ builder.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
+ }
+ LockScreenNotificationData.Public -> {
+ builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+ is LockScreenNotificationData.SenderNames -> {
+ val publicNotification = createPublicNotificationWithSenderList(baseNotificationData)
+ builder.setPublicVersion(publicNotification)
+ }
+ LockScreenNotificationData.MessageCount -> {
+ val publicNotification = createPublicNotificationWithNewMessagesCount(baseNotificationData)
+ builder.setPublicVersion(publicNotification)
+ }
+ }
+ }
+
+ private fun createPublicNotificationWithSenderList(baseNotificationData: BaseNotificationData): Notification {
+ val notificationData = baseNotificationData.lockScreenNotificationData as LockScreenNotificationData.SenderNames
+ return createPublicNotification(baseNotificationData)
+ .setContentText(notificationData.senderNames)
+ .build()
+ }
+
+ private fun createPublicNotificationWithNewMessagesCount(baseNotificationData: BaseNotificationData): Notification {
+ return createPublicNotification(baseNotificationData)
+ .setContentText(baseNotificationData.accountName)
+ .build()
+ }
+
+ private fun createPublicNotification(baseNotificationData: BaseNotificationData): NotificationCompat.Builder {
+ val account = baseNotificationData.account
+ val newMessagesCount = baseNotificationData.newMessagesCount
+ val title = resourceProvider.newMessagesTitle(newMessagesCount)
+
+ return notificationHelper.createNotificationBuilder(account, NotificationChannelManager.ChannelType.MESSAGES)
+ .setSmallIcon(resourceProvider.iconNewMail)
+ .setColor(baseNotificationData.color)
+ .setNumber(newMessagesCount)
+ .setContentTitle(title)
+ .setCategory(NotificationCompat.CATEGORY_EMAIL)
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/MessageSummaryNotifications.kt b/app/core/src/main/java/com/fsck/k9/notification/MessageSummaryNotifications.kt
deleted file mode 100644
index d83d2913feaa3f2adfaf8475d98beaa6adc5f774..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/notification/MessageSummaryNotifications.kt
+++ /dev/null
@@ -1,187 +0,0 @@
-package com.fsck.k9.notification
-
-import android.app.Notification
-import androidx.core.app.NotificationCompat
-import com.fsck.k9.Account
-import com.fsck.k9.K9
-import com.fsck.k9.K9.NotificationQuickDelete
-import com.fsck.k9.notification.NotificationGroupKeys.getGroupKey
-import com.fsck.k9.notification.NotificationIds.getNewMailSummaryNotificationId
-
-internal open class MessageSummaryNotifications(
- notificationHelper: NotificationHelper,
- actionCreator: NotificationActionCreator,
- private val lockScreenNotification: LockScreenNotification,
- private val singleMessageNotifications: SingleMessageNotifications,
- resourceProvider: NotificationResourceProvider
-) : BaseNotifications(notificationHelper, actionCreator, resourceProvider) {
- fun buildSummaryNotification(account: Account, notificationData: NotificationData, silent: Boolean): Notification {
- val unreadMessageCount = notificationData.unreadMessageCount
-
- val builder = when {
- notificationData.isSingleMessageNotification -> {
- val holder = notificationData.holderForLatestNotification
- createSingleMessageNotification(account, holder)
- }
- else -> {
- createInboxStyleSummaryNotification(account, notificationData, unreadMessageCount)
- }
- }
- if (notificationData.containsStarredMessages()) {
- builder.priority = NotificationCompat.PRIORITY_HIGH
- }
- val notificationId = getNewMailSummaryNotificationId(account)
- val deletePendingIntent = actionCreator.createDismissAllMessagesPendingIntent(account, notificationId)
- builder.setDeleteIntent(deletePendingIntent)
- lockScreenNotification.configureLockScreenNotification(builder, notificationData)
- val notificationSetting = account.notificationSetting
- notificationHelper.configureNotification(
- builder = builder,
- ringtone = if (notificationSetting.isRingEnabled) notificationSetting.ringtone else null,
- vibrationPattern = if (notificationSetting.isVibrateEnabled) notificationSetting.vibration else null,
- ledColor = if (notificationSetting.isLedEnabled) notificationSetting.ledColor else null,
- ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_SLOW,
- ringAndVibrate = !silent
- )
- return builder.build()
- }
-
- private fun createSingleMessageNotification(
- account: Account,
- holder: NotificationHolder
- ): NotificationCompat.Builder {
- val notificationId = getNewMailSummaryNotificationId(account)
- val builder = singleMessageNotifications.createSingleMessageNotificationBuilder(account, holder, notificationId)
- builder.setGroupSummary(true)
- return builder
- }
-
- private fun createInboxStyleSummaryNotification(
- account: Account,
- notificationData: NotificationData,
- unreadMessageCount: Int
- ): NotificationCompat.Builder {
- val latestNotification = notificationData.holderForLatestNotification
- val newMessagesCount = notificationData.newMessagesCount
- val accountName = notificationHelper.getAccountName(account)
- val title = resourceProvider.newMessagesTitle(newMessagesCount)
- val summary = if (notificationData.hasSummaryOverflowMessages()) {
- resourceProvider.additionalMessages(notificationData.getSummaryOverflowMessagesCount(), accountName)
- } else {
- accountName
- }
- val groupKey = getGroupKey(account)
- val builder = createAndInitializeNotificationBuilder(account)
- .setNumber(unreadMessageCount)
- .setTicker(latestNotification.content.summary)
- .setGroup(groupKey)
- .setGroupSummary(true)
- .setContentTitle(title)
- .setSubText(accountName)
- val style = createInboxStyle(builder)
- .setBigContentTitle(title)
- .setSummaryText(summary)
- for (content in notificationData.getContentForSummaryNotification()) {
- style.addLine(content.summary)
- }
- builder.setStyle(style)
- addMarkAllAsReadAction(builder, notificationData)
- addDeleteAllAction(builder, notificationData)
- addWearActions(builder, notificationData)
- val notificationId = getNewMailSummaryNotificationId(account)
- val messageReferences = notificationData.getAllMessageReferences()
- val contentIntent = actionCreator.createViewMessagesPendingIntent(account, messageReferences, notificationId)
- builder.setContentIntent(contentIntent)
- return builder
- }
-
- private fun addMarkAllAsReadAction(builder: NotificationCompat.Builder, notificationData: NotificationData) {
- val icon = resourceProvider.iconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val markAllAsReadPendingIntent =
- actionCreator.createMarkAllAsReadPendingIntent(account, messageReferences, notificationId)
- builder.addAction(icon, title, markAllAsReadPendingIntent)
- }
-
- private fun addDeleteAllAction(builder: NotificationCompat.Builder, notificationData: NotificationData) {
- if (K9.notificationQuickDeleteBehaviour !== NotificationQuickDelete.ALWAYS) {
- return
- }
- val icon = resourceProvider.iconDelete
- val title = resourceProvider.actionDelete()
- val account = notificationData.account
- val notificationId = getNewMailSummaryNotificationId(account)
- val messageReferences = notificationData.getAllMessageReferences()
- val action = actionCreator.createDeleteAllPendingIntent(account, messageReferences, notificationId)
- builder.addAction(icon, title, action)
- }
-
- private fun addWearActions(builder: NotificationCompat.Builder, notificationData: NotificationData) {
- val wearableExtender = NotificationCompat.WearableExtender()
- addMarkAllAsReadWearAction(wearableExtender, notificationData)
- if (isDeleteActionAvailableForWear()) {
- addDeleteAllWearAction(wearableExtender, notificationData)
- }
- if (isArchiveActionAvailableForWear(notificationData.account)) {
- addArchiveAllWearAction(wearableExtender, notificationData)
- }
- builder.extend(wearableExtender)
- }
-
- private fun addMarkAllAsReadWearAction(
- wearableExtender: NotificationCompat.WearableExtender,
- notificationData: NotificationData
- ) {
- val icon = resourceProvider.wearIconMarkAsRead
- val title = resourceProvider.actionMarkAllAsRead()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val action = actionCreator.createMarkAllAsReadPendingIntent(account, messageReferences, notificationId)
- val markAsReadAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(markAsReadAction)
- }
-
- private fun addDeleteAllWearAction(
- wearableExtender: NotificationCompat.WearableExtender,
- notificationData: NotificationData
- ) {
- val icon = resourceProvider.wearIconDelete
- val title = resourceProvider.actionDeleteAll()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val action = actionCreator.createDeleteAllPendingIntent(account, messageReferences, notificationId)
- val deleteAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(deleteAction)
- }
-
- private fun addArchiveAllWearAction(
- wearableExtender: NotificationCompat.WearableExtender,
- notificationData: NotificationData
- ) {
- val icon = resourceProvider.wearIconArchive
- val title = resourceProvider.actionArchiveAll()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val action = actionCreator.createArchiveAllPendingIntent(account, messageReferences, notificationId)
- val archiveAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(archiveAction)
- }
-
- private fun isDeleteActionAvailableForWear(): Boolean {
- return isDeleteActionEnabled() && !K9.isConfirmDeleteFromNotification
- }
-
- private fun isArchiveActionAvailableForWear(account: Account): Boolean {
- return account.archiveFolderId != null
- }
-
- protected open fun createInboxStyle(builder: NotificationCompat.Builder?): NotificationCompat.InboxStyle {
- return NotificationCompat.InboxStyle(builder)
- }
-}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationController.kt b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f6ecbd510ff727725f7a0a6043ab4158be72eda6
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationController.kt
@@ -0,0 +1,68 @@
+package com.fsck.k9.notification
+
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.Account
+import com.fsck.k9.controller.MessageReference
+import com.fsck.k9.mailstore.LocalMessage
+
+/**
+ * Handle notifications for new messages.
+ */
+internal class NewMailNotificationController(
+ private val notificationManager: NotificationManagerCompat,
+ private val newMailNotificationManager: NewMailNotificationManager,
+ private val summaryNotificationCreator: SummaryNotificationCreator,
+ private val singleMessageNotificationCreator: SingleMessageNotificationCreator
+) {
+ fun addNewMailNotification(account: Account, message: LocalMessage, silent: Boolean) {
+ val notificationData = newMailNotificationManager.addNewMailNotification(account, message, silent)
+
+ processNewMailNotificationData(notificationData)
+ }
+
+ fun removeNewMailNotification(account: Account, messageReference: MessageReference) {
+ val notificationData = newMailNotificationManager.removeNewMailNotification(account, messageReference)
+
+ if (notificationData != null) {
+ processNewMailNotificationData(notificationData)
+ }
+ }
+
+ fun clearNewMailNotifications(account: Account) {
+ val cancelNotificationIds = newMailNotificationManager.clearNewMailNotifications(account)
+
+ cancelNotifications(cancelNotificationIds)
+ }
+
+ private fun processNewMailNotificationData(notificationData: NewMailNotificationData) {
+ cancelNotifications(notificationData.cancelNotificationIds)
+
+ for (singleNotificationData in notificationData.singleNotificationData) {
+ createSingleNotification(notificationData.baseNotificationData, singleNotificationData)
+ }
+
+ notificationData.summaryNotificationData?.let { summaryNotificationData ->
+ createSummaryNotification(notificationData.baseNotificationData, summaryNotificationData)
+ }
+ }
+
+ private fun cancelNotifications(notificationIds: List) {
+ for (notificationId in notificationIds) {
+ notificationManager.cancel(notificationId)
+ }
+ }
+
+ private fun createSingleNotification(
+ baseNotificationData: BaseNotificationData,
+ singleNotificationData: SingleNotificationData
+ ) {
+ singleMessageNotificationCreator.createSingleNotification(baseNotificationData, singleNotificationData)
+ }
+
+ private fun createSummaryNotification(
+ baseNotificationData: BaseNotificationData,
+ summaryNotificationData: SummaryNotificationData
+ ) {
+ summaryNotificationCreator.createSummaryNotification(baseNotificationData, summaryNotificationData)
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationData.kt b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationData.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9069b4f85ada8b1d1e66f855afff48b7df5df598
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationData.kt
@@ -0,0 +1,87 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.controller.MessageReference
+
+internal data class NewMailNotificationData(
+ val cancelNotificationIds: List,
+ val baseNotificationData: BaseNotificationData,
+ val singleNotificationData: List,
+ val summaryNotificationData: SummaryNotificationData?
+)
+
+internal data class BaseNotificationData(
+ val account: Account,
+ val accountName: String,
+ val groupKey: String,
+ val color: Int,
+ val newMessagesCount: Int,
+ val lockScreenNotificationData: LockScreenNotificationData,
+ val appearance: NotificationAppearance
+)
+
+internal sealed interface LockScreenNotificationData {
+ object None : LockScreenNotificationData
+ object AppName : LockScreenNotificationData
+ object Public : LockScreenNotificationData
+ object MessageCount : LockScreenNotificationData
+ data class SenderNames(val senderNames: String) : LockScreenNotificationData
+}
+
+internal data class NotificationAppearance(
+ val ringtone: String?,
+ val vibrationPattern: LongArray?,
+ val ledColor: Int?
+)
+
+internal data class SingleNotificationData(
+ val notificationId: Int,
+ val isSilent: Boolean,
+ val timestamp: Long,
+ val content: NotificationContent,
+ val actions: List,
+ val wearActions: List,
+ val addLockScreenNotification: Boolean
+)
+
+internal sealed interface SummaryNotificationData
+
+internal data class SummarySingleNotificationData(
+ val singleNotificationData: SingleNotificationData
+) : SummaryNotificationData
+
+internal data class SummaryInboxNotificationData(
+ val notificationId: Int,
+ val isSilent: Boolean,
+ val timestamp: Long,
+ val content: List,
+ val additionalMessagesCount: Int,
+ val messageReferences: List,
+ val actions: List,
+ val wearActions: List
+) : SummaryNotificationData
+
+internal enum class NotificationAction {
+ Reply,
+ MarkAsRead,
+ Delete
+}
+
+internal enum class WearNotificationAction {
+ Reply,
+ MarkAsRead,
+ Delete,
+ Archive,
+ Spam
+}
+
+internal enum class SummaryNotificationAction {
+ MarkAsRead,
+ Delete
+}
+
+internal enum class SummaryWearNotificationAction {
+ MarkAsRead,
+ Delete,
+ Archive
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..99796dc9b4c911b6a6feeb7215d9149a32db2ef3
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotificationManager.kt
@@ -0,0 +1,143 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.Clock
+import com.fsck.k9.controller.MessageReference
+import com.fsck.k9.mailstore.LocalMessage
+
+/**
+ * Manages notifications for new messages
+ */
+internal class NewMailNotificationManager(
+ private val contentCreator: NotificationContentCreator,
+ private val baseNotificationDataCreator: BaseNotificationDataCreator,
+ private val singleMessageNotificationDataCreator: SingleMessageNotificationDataCreator,
+ private val summaryNotificationDataCreator: SummaryNotificationDataCreator,
+ private val clock: Clock
+) {
+ private val notifications = mutableMapOf()
+ private val lock = Any()
+
+ fun addNewMailNotification(account: Account, message: LocalMessage, silent: Boolean): NewMailNotificationData {
+ val content = contentCreator.createFromMessage(account, message)
+
+ synchronized(lock) {
+ val notificationData = getOrCreateNotificationData(account)
+ val result = notificationData.addNotificationContent(content)
+
+ val singleNotificationData = createSingleNotificationData(
+ account = account,
+ notificationId = result.notificationHolder.notificationId,
+ content = result.notificationHolder.content,
+ addLockScreenNotification = notificationData.isSingleMessageNotification
+ )
+
+ return NewMailNotificationData(
+ cancelNotificationIds = if (result.shouldCancelNotification) {
+ listOf(result.notificationId)
+ } else {
+ emptyList()
+ },
+ baseNotificationData = createBaseNotificationData(notificationData),
+ singleNotificationData = listOf(singleNotificationData),
+ summaryNotificationData = createSummaryNotificationData(notificationData, silent)
+ )
+ }
+ }
+
+ fun removeNewMailNotification(account: Account, messageReference: MessageReference): NewMailNotificationData? {
+ synchronized(lock) {
+ val notificationData = getNotificationData(account) ?: return null
+
+ val result = notificationData.removeNotificationForMessage(messageReference)
+ if (result.isUnknownNotification) return null
+
+ if (notificationData.newMessagesCount == 0) {
+ return NewMailNotificationData(
+ cancelNotificationIds = listOf(
+ NotificationIds.getNewMailSummaryNotificationId(account),
+ result.notificationId
+ ),
+ baseNotificationData = createBaseNotificationData(notificationData),
+ singleNotificationData = emptyList(),
+ summaryNotificationData = null
+ )
+ }
+
+ val singleNotificationData = if (result.shouldCreateNotification) {
+ val singleNotificationData = createSingleNotificationData(
+ account = account,
+ notificationId = result.notificationHolder.notificationId,
+ content = result.notificationHolder.content,
+ addLockScreenNotification = notificationData.isSingleMessageNotification
+ )
+ listOf(singleNotificationData)
+ } else {
+ emptyList()
+ }
+
+ return NewMailNotificationData(
+ cancelNotificationIds = listOf(result.notificationId),
+ baseNotificationData = createBaseNotificationData(notificationData),
+ singleNotificationData = singleNotificationData,
+ summaryNotificationData = createSummaryNotificationData(notificationData, silent = true)
+ )
+ }
+ }
+
+ fun clearNewMailNotifications(account: Account): List {
+ synchronized(lock) {
+ val notificationData = removeNotificationData(account) ?: return emptyList()
+ return notificationData.getActiveNotificationIds() +
+ NotificationIds.getNewMailSummaryNotificationId(account)
+ }
+ }
+
+ private fun createBaseNotificationData(notificationData: NotificationData): BaseNotificationData {
+ return baseNotificationDataCreator.createBaseNotificationData(notificationData)
+ }
+
+ private fun createSingleNotificationData(
+ account: Account,
+ notificationId: Int,
+ content: NotificationContent,
+ addLockScreenNotification: Boolean
+ ): SingleNotificationData {
+ return singleMessageNotificationDataCreator.createSingleNotificationData(
+ account,
+ notificationId,
+ content,
+ timestamp = now(),
+ addLockScreenNotification
+ )
+ }
+
+ private fun createSummaryNotificationData(data: NotificationData, silent: Boolean): SummaryNotificationData {
+ return summaryNotificationDataCreator.createSummaryNotificationData(data, timestamp = now(), silent)
+ }
+
+ private fun getOrCreateNotificationData(account: Account): NotificationData {
+ val notificationData = getNotificationData(account)
+ if (notificationData != null) return notificationData
+
+ val accountNumber = account.accountNumber
+ val newNotificationHolder = NotificationData(account)
+ notifications[accountNumber] = newNotificationHolder
+
+ return newNotificationHolder
+ }
+
+ private fun getNotificationData(account: Account): NotificationData? {
+ val accountNumber = account.accountNumber
+ return notifications[accountNumber]
+ }
+
+ private fun removeNotificationData(account: Account): NotificationData? {
+ val accountNumber = account.accountNumber
+ val notificationData = notifications[accountNumber]
+ notifications.remove(accountNumber)
+ return notificationData
+ }
+
+ private fun now(): Long = clock.time
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NewMailNotifications.kt b/app/core/src/main/java/com/fsck/k9/notification/NewMailNotifications.kt
deleted file mode 100644
index 42170c4baf8b9209c09dfa35a521be5785584f2f..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/notification/NewMailNotifications.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.fsck.k9.notification
-
-import android.util.SparseArray
-import androidx.core.app.NotificationManagerCompat
-import com.fsck.k9.Account
-import com.fsck.k9.controller.MessageReference
-import com.fsck.k9.mailstore.LocalMessage
-
-/**
- * Handle notifications for new messages.
- */
-internal open class NewMailNotifications(
- private val notificationHelper: NotificationHelper,
- private val contentCreator: NotificationContentCreator,
- private val messageSummaryNotifications: MessageSummaryNotifications,
- private val singleMessageNotifications: SingleMessageNotifications
-) {
- private val notifications = SparseArray()
- private val lock = Any()
- fun addNewMailNotification(account: Account, message: LocalMessage, unreadMessageCount: Int, silent: Boolean) {
- val content = contentCreator.createFromMessage(account, message)
- synchronized(lock) {
- val notificationData = getOrCreateNotificationData(account, unreadMessageCount)
- val result = notificationData.addNotificationContent(content)
- if (result.shouldCancelNotification) {
- val notificationId = result.notificationId
- cancelNotification(notificationId)
- }
- createSingleMessageNotification(account, result.notificationHolder)
- createSummaryNotification(account, notificationData, silent)
- }
- }
-
- fun removeNewMailNotification(account: Account, messageReference: MessageReference) {
- synchronized(lock) {
- val notificationData = getNotificationData(account) ?: return
- val result = notificationData.removeNotificationForMessage(messageReference)
- if (result.isUnknownNotification) return
- cancelNotification(result.notificationId)
- if (result.shouldCreateNotification) {
- createSingleMessageNotification(account, result.notificationHolder)
- }
- updateSummaryNotification(account, notificationData)
- }
- }
-
- fun clearNewMailNotifications(account: Account) {
- val notificationData = synchronized(lock) { removeNotificationData(account) } ?: return
- for (notificationId in notificationData.getActiveNotificationIds()) {
- cancelNotification(notificationId)
- }
- val notificationId = NotificationIds.getNewMailSummaryNotificationId(account)
- cancelNotification(notificationId)
- }
-
- private fun getOrCreateNotificationData(account: Account, unreadMessageCount: Int): NotificationData {
- val notificationData = getNotificationData(account)
- if (notificationData != null) return notificationData
- val accountNumber = account.accountNumber
- val newNotificationHolder = createNotificationData(account, unreadMessageCount)
- notifications.put(accountNumber, newNotificationHolder)
- return newNotificationHolder
- }
-
- private fun getNotificationData(account: Account): NotificationData? {
- val accountNumber = account.accountNumber
- return notifications[accountNumber]
- }
-
- private fun removeNotificationData(account: Account): NotificationData? {
- val accountNumber = account.accountNumber
- val notificationData = notifications[accountNumber]
- notifications.remove(accountNumber)
- return notificationData
- }
-
- protected open fun createNotificationData(account: Account, unreadMessageCount: Int): NotificationData {
- return NotificationData(account, unreadMessageCount)
- }
-
- private fun cancelNotification(notificationId: Int) {
- notificationManager.cancel(notificationId)
- }
-
- private fun updateSummaryNotification(account: Account, notificationData: NotificationData) {
- if (notificationData.newMessagesCount == 0) {
- clearNewMailNotifications(account)
- } else {
- createSummaryNotification(account, notificationData, silent = true)
- }
- }
-
- private fun createSummaryNotification(account: Account, notificationData: NotificationData, silent: Boolean) {
- val notification = messageSummaryNotifications.buildSummaryNotification(account, notificationData, silent)
- val notificationId = NotificationIds.getNewMailSummaryNotificationId(account)
- notificationManager.notify(notificationId, notification)
- }
-
- private fun createSingleMessageNotification(account: Account, holder: NotificationHolder) {
- val notification = singleMessageNotifications.buildSingleMessageNotification(account, holder)
- val notificationId = holder.notificationId
- notificationManager.notify(notificationId, notification)
- }
-
- private val notificationManager: NotificationManagerCompat
- get() = notificationHelper.getNotificationManager()
-}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationActionCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationActionCreator.kt
index 851cfec33f8071eda9d8927eccf5a51e64ae64b6..d7e403b8c315bbd1d65326ab97bddfd161bbc6d0 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationActionCreator.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationActionCreator.kt
@@ -1,23 +1,25 @@
package com.fsck.k9.notification
import android.app.PendingIntent
-import android.content.Context
import com.fsck.k9.Account
import com.fsck.k9.controller.MessageReference
interface NotificationActionCreator {
fun createViewMessagePendingIntent(messageReference: MessageReference, notificationId: Int): PendingIntent
+
fun createViewFolderPendingIntent(account: Account, folderId: Long, notificationId: Int): PendingIntent
+
fun createViewMessagesPendingIntent(
account: Account,
messageReferences: List,
notificationId: Int
): PendingIntent
+ fun createViewFolderListPendingIntent(account: Account, notificationId: Int): PendingIntent
+
fun createDismissAllMessagesPendingIntent(account: Account, notificationId: Int): PendingIntent
fun createDismissMessagePendingIntent(
- context: Context,
messageReference: MessageReference,
notificationId: Int
): PendingIntent
@@ -54,4 +56,3 @@ interface NotificationActionCreator {
fun createMarkMessageAsSpamPendingIntent(messageReference: MessageReference, notificationId: Int): PendingIntent
}
-
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationActionService.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationActionService.kt
index a91bf70439edc0da6a3eac738d2c40cd595d2011..d70ea87778326e3c891c99868bf21dc387dd459c 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationActionService.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationActionService.kt
@@ -36,6 +36,7 @@ class NotificationActionService : Service() {
ACTION_SPAM -> markMessageAsSpam(intent, account)
ACTION_DISMISS -> Timber.i("Notification dismissed")
}
+
cancelNotifications(intent, account)
return START_NOT_STICKY
@@ -47,8 +48,10 @@ class NotificationActionService : Service() {
private fun markMessagesAsRead(intent: Intent, account: Account) {
Timber.i("NotificationActionService marking messages as read")
+
val messageReferenceStrings = intent.getStringArrayListExtra(EXTRA_MESSAGE_REFERENCES)
val messageReferences = MessageReferenceHelper.toMessageReferenceList(messageReferenceStrings)
+
for (messageReference in messageReferences) {
val folderId = messageReference.folderId
val uid = messageReference.uid
@@ -58,16 +61,22 @@ class NotificationActionService : Service() {
private fun deleteMessages(intent: Intent) {
Timber.i("NotificationActionService deleting messages")
+
+ val messageReferenceStrings = intent.getStringArrayListExtra(EXTRA_MESSAGE_REFERENCES)
+ val messageReferences = MessageReferenceHelper.toMessageReferenceList(messageReferenceStrings)
+
messagingController.deleteMessages(messageReferences)
}
private fun archiveMessages(intent: Intent, account: Account) {
Timber.i("NotificationActionService archiving messages")
+
val archiveFolderId = account.archiveFolderId
if (archiveFolderId == null || !messagingController.isMoveCapable(account)) {
Timber.w("Cannot archive messages")
return
}
+
val messageReferenceStrings = intent.getStringArrayListExtra(EXTRA_MESSAGE_REFERENCES)
val messageReferences = MessageReferenceHelper.toMessageReferenceList(messageReferenceStrings)
@@ -81,6 +90,7 @@ class NotificationActionService : Service() {
private fun markMessageAsSpam(intent: Intent, account: Account) {
Timber.i("NotificationActionService moving messages to spam")
+
val messageReferenceString = intent.getStringExtra(EXTRA_MESSAGE_REFERENCE)
val messageReference = MessageReference.parse(messageReferenceString)
@@ -88,6 +98,7 @@ class NotificationActionService : Service() {
Timber.w("Invalid message reference: %s", messageReferenceString)
return
}
+
val spamFolderId = account.spamFolderId
if (spamFolderId == null) {
Timber.w("No spam folder configured")
@@ -104,6 +115,7 @@ class NotificationActionService : Service() {
if (intent.hasExtra(EXTRA_MESSAGE_REFERENCE)) {
val messageReferenceString = intent.getStringExtra(EXTRA_MESSAGE_REFERENCE)
val messageReference = MessageReference.parse(messageReferenceString)
+
if (messageReference != null) {
messagingController.cancelNotificationForMessage(account, messageReference)
} else {
@@ -112,6 +124,7 @@ class NotificationActionService : Service() {
} else if (intent.hasExtra(EXTRA_MESSAGE_REFERENCES)) {
val messageReferenceStrings = intent.getStringArrayListExtra(EXTRA_MESSAGE_REFERENCES)
val messageReferences = MessageReferenceHelper.toMessageReferenceList(messageReferenceStrings)
+
for (messageReference in messageReferences) {
messagingController.cancelNotificationForMessage(account, messageReference)
}
@@ -229,4 +242,3 @@ class NotificationActionService : Service() {
}
}
}
-
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationContent.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationContent.kt
index 715317387c264f6bac0e2727b816f9b55c8a1f06..374979d2e101a7d45b7a878d7d0244b1646bf318 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationContent.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationContent.kt
@@ -2,11 +2,10 @@ package com.fsck.k9.notification
import com.fsck.k9.controller.MessageReference
-internal class NotificationContent(
+internal data class NotificationContent(
val messageReference: MessageReference,
val sender: String,
val subject: String,
val preview: CharSequence,
- val summary: CharSequence,
- val isStarred: Boolean
-)
\ No newline at end of file
+ val summary: CharSequence
+)
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationContentCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationContentCreator.kt
index 3685c31ab948ad484409098a5676bc7b455da127..86d85b8efa8e3e81e06f079752228d61a40d2286 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationContentCreator.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationContentCreator.kt
@@ -6,7 +6,6 @@ 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.Flag
import com.fsck.k9.mail.Message
import com.fsck.k9.mailstore.LocalMessage
import com.fsck.k9.message.extractors.PreviewResult.PreviewType
@@ -23,8 +22,7 @@ internal class NotificationContentCreator(
sender = getMessageSenderForDisplay(sender),
subject = getMessageSubject(message),
preview = getMessagePreview(message),
- summary = buildMessageSummary(sender, getMessageSubject(message)),
- isStarred = message.isSet(Flag.FLAGGED)
+ summary = buildMessageSummary(sender, getMessageSubject(message))
)
}
@@ -74,6 +72,7 @@ internal class NotificationContentCreator(
private fun getMessageSender(account: Account, message: Message): String? {
val contacts = if (K9.isShowContactName) Contacts.getInstance(context) else null
var isSelf = false
+
val fromAddresses = message.from
if (!fromAddresses.isNullOrEmpty()) {
isSelf = account.isAnIdentity(fromAddresses)
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationController.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationController.kt
index 4fa4c0c4f4b2a56606166f57c2ef76cc4f24afa0..d915648dc0c4fca96e5280290d511139b246a509 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationController.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationController.kt
@@ -6,70 +6,65 @@ import com.fsck.k9.mailstore.LocalFolder
import com.fsck.k9.mailstore.LocalMessage
class NotificationController internal constructor(
- private val certificateErrorNotifications: CertificateErrorNotifications,
- private val authenticationErrorNotifications: AuthenticationErrorNotifications,
- private val syncNotifications: SyncNotifications,
- private val sendFailedNotifications: SendFailedNotifications,
- private val newMailNotifications: NewMailNotifications
+ private val certificateErrorNotificationController: CertificateErrorNotificationController,
+ private val authenticationErrorNotificationController: AuthenticationErrorNotificationController,
+ private val syncNotificationController: SyncNotificationController,
+ private val sendFailedNotificationController: SendFailedNotificationController,
+ private val newMailNotificationController: NewMailNotificationController
) {
fun showCertificateErrorNotification(account: Account, incoming: Boolean) {
- certificateErrorNotifications.showCertificateErrorNotification(account, incoming)
+ certificateErrorNotificationController.showCertificateErrorNotification(account, incoming)
}
fun clearCertificateErrorNotifications(account: Account, incoming: Boolean) {
- certificateErrorNotifications.clearCertificateErrorNotifications(account, incoming)
+ certificateErrorNotificationController.clearCertificateErrorNotifications(account, incoming)
}
fun showAuthenticationErrorNotification(account: Account, incoming: Boolean) {
- authenticationErrorNotifications.showAuthenticationErrorNotification(account, incoming)
+ authenticationErrorNotificationController.showAuthenticationErrorNotification(account, incoming)
}
fun clearAuthenticationErrorNotification(account: Account, incoming: Boolean) {
- authenticationErrorNotifications.clearAuthenticationErrorNotification(account, incoming)
+ authenticationErrorNotificationController.clearAuthenticationErrorNotification(account, incoming)
}
fun showSendingNotification(account: Account) {
- syncNotifications.showSendingNotification(account)
+ syncNotificationController.showSendingNotification(account)
}
fun clearSendingNotification(account: Account) {
- syncNotifications.clearSendingNotification(account)
+ syncNotificationController.clearSendingNotification(account)
}
fun showSendFailedNotification(account: Account, exception: Exception) {
- sendFailedNotifications.showSendFailedNotification(account, exception)
+ sendFailedNotificationController.showSendFailedNotification(account, exception)
}
fun clearSendFailedNotification(account: Account) {
- sendFailedNotifications.clearSendFailedNotification(account)
+ sendFailedNotificationController.clearSendFailedNotification(account)
}
fun showFetchingMailNotification(account: Account, folder: LocalFolder) {
- syncNotifications.showFetchingMailNotification(account, folder)
+ syncNotificationController.showFetchingMailNotification(account, folder)
}
fun showEmptyFetchingMailNotification(account: Account) {
- syncNotifications.showEmptyFetchingMailNotification(account)
+ syncNotificationController.showEmptyFetchingMailNotification(account)
}
fun clearFetchingMailNotification(account: Account) {
- syncNotifications.clearFetchingMailNotification(account)
+ syncNotificationController.clearFetchingMailNotification(account)
}
- fun addNewMailNotification(
- account: Account,
- message: LocalMessage,
- previousUnreadMessageCount: Int,
- silent: Boolean
- ) {
- newMailNotifications.addNewMailNotification(account, message, previousUnreadMessageCount, silent)
+ fun addNewMailNotification(account: Account, message: LocalMessage, silent: Boolean) {
+ newMailNotificationController.addNewMailNotification(account, message, silent)
}
fun removeNewMailNotification(account: Account, messageReference: MessageReference) {
- newMailNotifications.removeNewMailNotification(account, messageReference)
+ newMailNotificationController.removeNewMailNotification(account, messageReference)
}
fun clearNewMailNotifications(account: Account) {
- newMailNotifications.clearNewMailNotifications(account)
+ newMailNotificationController.clearNewMailNotifications(account)
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationData.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationData.kt
index c153ed9cd30c98446549f964e3bc0cb6abfad9e3..9487b1fe901b679723f35b2316a6184391385322 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationData.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationData.kt
@@ -1,17 +1,16 @@
package com.fsck.k9.notification
-import android.util.SparseBooleanArray
import com.fsck.k9.Account
import com.fsck.k9.controller.MessageReference
import java.util.LinkedList
-internal class NotificationData(val account: Account, private val initialUnreadMessageCount: Int) {
+/**
+ * A holder class for pending new mail notifications.
+ */
+internal class NotificationData(val account: Account) {
private val activeNotifications = LinkedList()
private val additionalNotifications = LinkedList()
- private val notificationIdsInUse = SparseBooleanArray()
-
- val unreadMessageCount: Int
- get() = initialUnreadMessageCount + newMessagesCount
+ private val notificationIdsInUse = mutableMapOf()
val newMessagesCount: Int
get() = activeNotifications.size + additionalNotifications.size
@@ -23,7 +22,7 @@ internal class NotificationData(val account: Account, private val initialUnreadM
get() = activeNotifications.first
private val isMaxNumberOfActiveNotificationsReached: Boolean
- get() = activeNotifications.size == MAX_NUMBER_OF_STACKED_NOTIFICATIONS
+ get() = activeNotifications.size == MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS
fun addNotificationContent(content: NotificationContent): AddNotificationResult {
val notificationId: Int
@@ -53,8 +52,8 @@ internal class NotificationData(val account: Account, private val initialUnreadM
}
private fun getNewNotificationId(): Int {
- for (index in 0 until MAX_NUMBER_OF_STACKED_NOTIFICATIONS) {
- val notificationId = NotificationIds.getNewMailStackedNotificationId(account, index)
+ for (index in 0 until MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS) {
+ val notificationId = NotificationIds.getSingleMessageNotificationId(account, index)
if (!isNotificationInUse(notificationId)) {
markNotificationIdAsInUse(notificationId)
return notificationId
@@ -65,25 +64,21 @@ internal class NotificationData(val account: Account, private val initialUnreadM
}
private fun isNotificationInUse(notificationId: Int): Boolean {
- return notificationIdsInUse[notificationId]
+ return notificationIdsInUse[notificationId] ?: false
}
private fun markNotificationIdAsInUse(notificationId: Int) {
- notificationIdsInUse.put(notificationId, true)
+ notificationIdsInUse[notificationId] = true
}
private fun markNotificationIdAsFree(notificationId: Int) {
- notificationIdsInUse.delete(notificationId)
+ notificationIdsInUse.remove(notificationId)
}
private fun createNotificationHolder(notificationId: Int, content: NotificationContent): NotificationHolder {
return NotificationHolder(notificationId, content)
}
- fun containsStarredMessages(): Boolean {
- return activeNotifications.any { it.content.isStarred } || additionalNotifications.any { it.isStarred }
- }
-
fun hasSummaryOverflowMessages(): Boolean {
return activeNotifications.size > MAX_NUMBER_OF_MESSAGES_FOR_SUMMARY_NOTIFICATION
}
@@ -104,8 +99,8 @@ internal class NotificationData(val account: Account, private val initialUnreadM
.toList()
}
- fun getActiveNotificationIds(): IntArray {
- return activeNotifications.map { it.notificationId }.toIntArray()
+ fun getActiveNotificationIds(): List {
+ return activeNotifications.map { it.notificationId }
}
fun removeNotificationForMessage(messageReference: MessageReference): RemoveNotificationResult {
@@ -116,6 +111,7 @@ internal class NotificationData(val account: Account, private val initialUnreadM
val notificationId = holder.notificationId
markNotificationIdAsFree(notificationId)
+
return if (additionalNotifications.isEmpty()) {
RemoveNotificationResult.cancelNotification(notificationId)
} else {
@@ -137,15 +133,20 @@ internal class NotificationData(val account: Account, private val initialUnreadM
for (holder in activeNotifications) {
messageReferences.add(holder.content.messageReference)
}
+
for (content in additionalNotifications) {
messageReferences.add(content.messageReference)
}
+
return messageReferences
}
companion object {
// Note: As of Jellybean, phone notifications show a maximum of 5 lines, while tablet notifications show 7 lines.
const val MAX_NUMBER_OF_MESSAGES_FOR_SUMMARY_NOTIFICATION = 5
- const val MAX_NUMBER_OF_STACKED_NOTIFICATIONS = 8
+
+ // Note: This class assumes that
+ // MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS >= MAX_NUMBER_OF_MESSAGES_FOR_SUMMARY_NOTIFICATION
+ const val MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS = 8
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationGroupKeys.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationGroupKeys.kt
index 8aa3255f660680dc4fe9aab3b2a1874e0ed3e292..14c150cd27f39c63ef98ac34177ba43f828bbfa8 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationGroupKeys.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationGroupKeys.kt
@@ -9,4 +9,4 @@ object NotificationGroupKeys {
fun getGroupKey(account: Account): String {
return NOTIFICATION_GROUP_KEY_PREFIX + account.accountNumber
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt
index e8045884ff0ca3d87647321aee0c418863d71dee..9199fa7ad08dd15ac8700c9c2ff05639d55084b4 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationHelper.kt
@@ -35,7 +35,7 @@ class NotificationHelper(
if (vibrationPattern != null) {
builder.setVibrate(vibrationPattern)
}
- }else {
+ } else {
builder.setNotificationSilent()
}
@@ -78,8 +78,8 @@ class NotificationHelper(
}
companion object {
- private const val NOTIFICATION_LED_ON_TIME = 500
- private const val NOTIFICATION_LED_OFF_TIME = 2000
+ internal const val NOTIFICATION_LED_ON_TIME = 500
+ internal const val NOTIFICATION_LED_OFF_TIME = 2000
private const val NOTIFICATION_LED_FAST_ON_TIME = 100
private const val NOTIFICATION_LED_FAST_OFF_TIME = 100
@@ -88,3 +88,28 @@ class NotificationHelper(
internal const val NOTIFICATION_LED_FAILURE_COLOR = -0x10000
}
}
+
+internal fun NotificationCompat.Builder.setAppearance(
+ silent: Boolean,
+ appearance: NotificationAppearance
+): NotificationCompat.Builder = apply {
+ if (silent) {
+ setSilent(true)
+ } else {
+ if (!appearance.ringtone.isNullOrEmpty()) {
+ setSound(Uri.parse(appearance.ringtone))
+ }
+
+ if (appearance.vibrationPattern != null) {
+ setVibrate(appearance.vibrationPattern)
+ }
+
+ if (appearance.ledColor != null) {
+ setLights(
+ appearance.ledColor,
+ NotificationHelper.NOTIFICATION_LED_ON_TIME,
+ NotificationHelper.NOTIFICATION_LED_OFF_TIME
+ )
+ }
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationHolder.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationHolder.kt
index d89293576465bad98eaf4d1827076209628d9b49..d60dfb635abc9e7a971f02bb8c8c96e585f49b29 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationHolder.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationHolder.kt
@@ -3,4 +3,4 @@ package com.fsck.k9.notification
internal class NotificationHolder(
val notificationId: Int,
val content: NotificationContent
-)
\ No newline at end of file
+)
diff --git a/app/core/src/main/java/com/fsck/k9/notification/NotificationIds.kt b/app/core/src/main/java/com/fsck/k9/notification/NotificationIds.kt
index fd0c5d2cba53ce5e5b0bf339f461dafd1bebe595..9a2504b193d5f780224159f90fbb405d2bb30baf 100644
--- a/app/core/src/main/java/com/fsck/k9/notification/NotificationIds.kt
+++ b/app/core/src/main/java/com/fsck/k9/notification/NotificationIds.kt
@@ -13,11 +13,11 @@ internal object NotificationIds {
private const val OFFSET_AUTHENTICATION_ERROR_OUTGOING = 4
private const val OFFSET_FETCHING_MAIL = 5
private const val OFFSET_NEW_MAIL_SUMMARY = 6
- private const val OFFSET_NEW_MAIL_STACKED = 7
- private const val NUMBER_OF_DEVICE_NOTIFICATIONS = 7
- private const val NUMBER_OF_STACKED_NOTIFICATIONS = NotificationData.MAX_NUMBER_OF_STACKED_NOTIFICATIONS
+ private const val OFFSET_NEW_MAIL_SINGLE = 7
+ private const val NUMBER_OF_MISC_ACCOUNT_NOTIFICATIONS = 7
+ private const val NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS = NotificationData.MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS
private const val NUMBER_OF_NOTIFICATIONS_PER_ACCOUNT =
- NUMBER_OF_DEVICE_NOTIFICATIONS + NUMBER_OF_STACKED_NOTIFICATIONS
+ NUMBER_OF_MISC_ACCOUNT_NOTIFICATIONS + NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS
@JvmStatic
fun getNewMailSummaryNotificationId(account: Account): Int {
@@ -25,10 +25,10 @@ internal object NotificationIds {
}
@JvmStatic
- fun getNewMailStackedNotificationId(account: Account, index: Int): Int {
- require(index in 0 until NUMBER_OF_STACKED_NOTIFICATIONS) { "Invalid index: $index" }
+ fun getSingleMessageNotificationId(account: Account, index: Int): Int {
+ require(index in 0 until NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS) { "Invalid index: $index" }
- return getBaseNotificationId(account) + OFFSET_NEW_MAIL_STACKED + index
+ return getBaseNotificationId(account) + OFFSET_NEW_MAIL_SINGLE + index
}
@JvmStatic
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SendFailedNotificationController.kt b/app/core/src/main/java/com/fsck/k9/notification/SendFailedNotificationController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..957c3be0d1ff4d9737a0f4b357c25e0b7df22bc3
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/SendFailedNotificationController.kt
@@ -0,0 +1,54 @@
+package com.fsck.k9.notification
+
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.Account
+import com.fsck.k9.helper.ExceptionHelper
+
+internal class SendFailedNotificationController(
+ private val notificationHelper: NotificationHelper,
+ private val actionBuilder: NotificationActionCreator,
+ private val resourceProvider: NotificationResourceProvider
+) {
+ fun showSendFailedNotification(account: Account, exception: Exception) {
+ val title = resourceProvider.sendFailedTitle()
+ val text = ExceptionHelper.getRootCauseMessage(exception)
+
+ val notificationId = NotificationIds.getSendFailedNotificationId(account)
+ val folderListPendingIntent = actionBuilder.createViewFolderListPendingIntent(
+ account, notificationId
+ )
+
+ val notificationBuilder = notificationHelper
+ .createNotificationBuilder(account, NotificationChannelManager.ChannelType.MISCELLANEOUS)
+ .setSmallIcon(resourceProvider.iconWarning)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .setTicker(title)
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(folderListPendingIntent)
+ .setStyle(NotificationCompat.BigTextStyle().bigText(text))
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setCategory(NotificationCompat.CATEGORY_ERROR)
+
+ notificationHelper.configureNotification(
+ builder = notificationBuilder,
+ ringtone = null,
+ vibrationPattern = null,
+ ledColor = NotificationHelper.NOTIFICATION_LED_FAILURE_COLOR,
+ ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_FAST,
+ ringAndVibrate = true
+ )
+
+ notificationManager.notify(notificationId, notificationBuilder.build())
+ }
+
+ fun clearSendFailedNotification(account: Account) {
+ val notificationId = NotificationIds.getSendFailedNotificationId(account)
+ notificationManager.cancel(notificationId)
+ }
+
+ private val notificationManager: NotificationManagerCompat
+ get() = notificationHelper.getNotificationManager()
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..46635307a418863fb74749631861464da3d8384b
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationCreator.kt
@@ -0,0 +1,185 @@
+package com.fsck.k9.notification
+
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationCompat.WearableExtender
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.notification.NotificationChannelManager.ChannelType
+import androidx.core.app.NotificationCompat.Builder as NotificationBuilder
+
+internal class SingleMessageNotificationCreator(
+ private val notificationHelper: NotificationHelper,
+ private val actionCreator: NotificationActionCreator,
+ private val resourceProvider: NotificationResourceProvider,
+ private val lockScreenNotificationCreator: LockScreenNotificationCreator,
+ private val notificationManager: NotificationManagerCompat
+) {
+ fun createSingleNotification(
+ baseNotificationData: BaseNotificationData,
+ singleNotificationData: SingleNotificationData,
+ isGroupSummary: Boolean = false
+ ) {
+ val account = baseNotificationData.account
+ val notificationId = singleNotificationData.notificationId
+ val content = singleNotificationData.content
+
+ val notification = notificationHelper.createNotificationBuilder(account, ChannelType.MESSAGES)
+ .setCategory(NotificationCompat.CATEGORY_EMAIL)
+ .setAutoCancel(true)
+ .setGroup(baseNotificationData.groupKey)
+ .setGroupSummary(isGroupSummary)
+ .setSmallIcon(resourceProvider.iconNewMail)
+ .setColor(baseNotificationData.color)
+ .setWhen(singleNotificationData.timestamp)
+ .setTicker(content.summary)
+ .setContentTitle(content.sender)
+ .setContentText(content.subject)
+ .setSubText(baseNotificationData.accountName)
+ .setBigText(content.preview)
+ .setContentIntent(createViewIntent(content, notificationId))
+ .setDeleteIntent(createDismissIntent(content, notificationId))
+ .setDeviceActions(singleNotificationData)
+ .setWearActions(singleNotificationData)
+ .setAppearance(singleNotificationData.isSilent, baseNotificationData.appearance)
+ .setLockScreenNotification(baseNotificationData, singleNotificationData.addLockScreenNotification)
+ .build()
+
+ notificationManager.notify(notificationId, notification)
+ }
+
+ private fun NotificationBuilder.setBigText(text: CharSequence) = apply {
+ setStyle(NotificationCompat.BigTextStyle().bigText(text))
+ }
+
+ private fun createViewIntent(content: NotificationContent, notificationId: Int): PendingIntent {
+ return actionCreator.createViewMessagePendingIntent(content.messageReference, notificationId)
+ }
+
+ private fun createDismissIntent(content: NotificationContent, notificationId: Int): PendingIntent {
+ return actionCreator.createDismissMessagePendingIntent(content.messageReference, notificationId)
+ }
+
+ private fun NotificationBuilder.setDeviceActions(notificationData: SingleNotificationData) = apply {
+ val actions = notificationData.actions
+ for (action in actions) {
+ when (action) {
+ NotificationAction.Reply -> addReplyAction(notificationData)
+ NotificationAction.MarkAsRead -> addMarkAsReadAction(notificationData)
+ NotificationAction.Delete -> addDeleteAction(notificationData)
+ }
+ }
+ }
+
+ private fun NotificationBuilder.addReplyAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.iconReply
+ val title = resourceProvider.actionReply()
+ val content = notificationData.content
+ val messageReference = content.messageReference
+ val replyToMessagePendingIntent =
+ actionCreator.createReplyPendingIntent(messageReference, notificationData.notificationId)
+
+ addAction(icon, title, replyToMessagePendingIntent)
+ }
+
+ private fun NotificationBuilder.addMarkAsReadAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.iconMarkAsRead
+ val title = resourceProvider.actionMarkAsRead()
+ val content = notificationData.content
+ val notificationId = notificationData.notificationId
+ val messageReference = content.messageReference
+ val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
+
+ addAction(icon, title, action)
+ }
+
+ private fun NotificationBuilder.addDeleteAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.iconDelete
+ val title = resourceProvider.actionDelete()
+ val content = notificationData.content
+ val notificationId = notificationData.notificationId
+ val messageReference = content.messageReference
+ val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
+
+ addAction(icon, title, action)
+ }
+
+ private fun NotificationBuilder.setWearActions(notificationData: SingleNotificationData) = apply {
+ val wearableExtender = WearableExtender().apply {
+ for (action in notificationData.wearActions) {
+ when (action) {
+ WearNotificationAction.Reply -> addReplyAction(notificationData)
+ WearNotificationAction.MarkAsRead -> addMarkAsReadAction(notificationData)
+ WearNotificationAction.Delete -> addDeleteAction(notificationData)
+ WearNotificationAction.Archive -> addArchiveAction(notificationData)
+ WearNotificationAction.Spam -> addMarkAsSpamAction(notificationData)
+ }
+ }
+ }
+
+ extend(wearableExtender)
+ }
+
+ private fun WearableExtender.addReplyAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.wearIconReplyAll
+ val title = resourceProvider.actionReply()
+ val messageReference = notificationData.content.messageReference
+ val notificationId = notificationData.notificationId
+ val action = actionCreator.createReplyPendingIntent(messageReference, notificationId)
+ val replyAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(replyAction)
+ }
+
+ private fun WearableExtender.addMarkAsReadAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.wearIconMarkAsRead
+ val title = resourceProvider.actionMarkAsRead()
+ val messageReference = notificationData.content.messageReference
+ val notificationId = notificationData.notificationId
+ val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
+ val markAsReadAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(markAsReadAction)
+ }
+
+ private fun WearableExtender.addDeleteAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.wearIconDelete
+ val title = resourceProvider.actionDelete()
+ val messageReference = notificationData.content.messageReference
+ val notificationId = notificationData.notificationId
+ val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
+ val deleteAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(deleteAction)
+ }
+
+ private fun WearableExtender.addArchiveAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.wearIconArchive
+ val title = resourceProvider.actionArchive()
+ val messageReference = notificationData.content.messageReference
+ val notificationId = notificationData.notificationId
+ val action = actionCreator.createArchiveMessagePendingIntent(messageReference, notificationId)
+ val archiveAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(archiveAction)
+ }
+
+ private fun WearableExtender.addMarkAsSpamAction(notificationData: SingleNotificationData) {
+ val icon = resourceProvider.wearIconMarkAsSpam
+ val title = resourceProvider.actionMarkAsSpam()
+ val messageReference = notificationData.content.messageReference
+ val notificationId = notificationData.notificationId
+ val action = actionCreator.createMarkMessageAsSpamPendingIntent(messageReference, notificationId)
+ val spamAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(spamAction)
+ }
+
+ private fun NotificationBuilder.setLockScreenNotification(
+ notificationData: BaseNotificationData,
+ addLockScreenNotification: Boolean
+ ) = apply {
+ if (addLockScreenNotification) {
+ lockScreenNotificationCreator.configureLockScreenNotification(this, notificationData)
+ }
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..904e7ffcfadc6ce250accc7857c06a5d53438574
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotificationDataCreator.kt
@@ -0,0 +1,89 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.K9
+
+internal class SingleMessageNotificationDataCreator {
+
+ fun createSingleNotificationData(
+ account: Account,
+ notificationId: Int,
+ content: NotificationContent,
+ timestamp: Long,
+ addLockScreenNotification: Boolean
+ ): SingleNotificationData {
+ return SingleNotificationData(
+ notificationId = notificationId,
+ isSilent = true,
+ timestamp = timestamp,
+ content = content,
+ actions = createSingleNotificationActions(),
+ wearActions = createSingleNotificationWearActions(account),
+ addLockScreenNotification = addLockScreenNotification
+ )
+ }
+
+ fun createSummarySingleNotificationData(
+ data: NotificationData,
+ timestamp: Long,
+ silent: Boolean
+ ): SummarySingleNotificationData {
+ return SummarySingleNotificationData(
+ SingleNotificationData(
+ notificationId = NotificationIds.getNewMailSummaryNotificationId(data.account),
+ isSilent = silent,
+ timestamp = timestamp,
+ content = data.holderForLatestNotification.content,
+ actions = createSingleNotificationActions(),
+ wearActions = createSingleNotificationWearActions(data.account),
+ addLockScreenNotification = false,
+ ),
+ )
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ private fun createSingleNotificationActions(): List {
+ return buildList {
+ add(NotificationAction.Reply)
+ add(NotificationAction.MarkAsRead)
+
+ if (isDeleteActionEnabled()) {
+ add(NotificationAction.Delete)
+ }
+ }
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ private fun createSingleNotificationWearActions(account: Account): List {
+ return buildList {
+ add(WearNotificationAction.Reply)
+ add(WearNotificationAction.MarkAsRead)
+
+ if (isDeleteActionAvailableForWear()) {
+ add(WearNotificationAction.Delete)
+ }
+
+ if (account.hasArchiveFolder()) {
+ add(WearNotificationAction.Archive)
+ }
+
+ if (isSpamActionAvailableForWear(account)) {
+ add(WearNotificationAction.Spam)
+ }
+ }
+ }
+
+ private fun isDeleteActionEnabled(): Boolean {
+ return K9.notificationQuickDeleteBehaviour != K9.NotificationQuickDelete.NEVER
+ }
+
+ // We don't support confirming actions on Wear devices. So don't show the action when confirmation is enabled.
+ private fun isDeleteActionAvailableForWear(): Boolean {
+ return isDeleteActionEnabled() && !K9.isConfirmDeleteFromNotification
+ }
+
+ // We don't support confirming actions on Wear devices. So don't show the action when confirmation is enabled.
+ private fun isSpamActionAvailableForWear(account: Account): Boolean {
+ return account.hasSpamFolder() && !K9.isConfirmSpam
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotifications.kt b/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotifications.kt
deleted file mode 100644
index c4a518654287a050216e878ca269d00cc403a7a8..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/notification/SingleMessageNotifications.kt
+++ /dev/null
@@ -1,158 +0,0 @@
-package com.fsck.k9.notification
-
-import android.app.Notification
-import androidx.core.app.NotificationCompat
-import com.fsck.k9.Account
-import com.fsck.k9.K9
-
-internal open class SingleMessageNotifications(
- notificationHelper: NotificationHelper,
- actionCreator: NotificationActionCreator,
- resourceProvider: NotificationResourceProvider
-) : BaseNotifications(notificationHelper, actionCreator, resourceProvider) {
-
- fun buildSingleMessageNotification(account: Account, holder: NotificationHolder): Notification {
- val notificationId = holder.notificationId
- return createSingleMessageNotificationBuilder(account, holder, notificationId)
- .setNotificationSilent()
- .build()
- }
-
- fun createSingleMessageNotificationBuilder(
- account: Account,
- holder: NotificationHolder,
- notificationId: Int
- ): NotificationCompat.Builder {
- val content = holder.content
- val builder = createBigTextStyleNotification(account, holder, notificationId)
-
- val deletePendingIntent = actionCreator.createDismissMessagePendingIntent(
- context, content.messageReference, holder.notificationId
- )
- builder.setDeleteIntent(deletePendingIntent)
- addActions(builder, account, holder)
- return builder
- }
-
- private fun addActions(builder: NotificationCompat.Builder, account: Account, holder: NotificationHolder) {
- addDeviceActions(builder, holder)
- addWearActions(builder, account, holder)
- }
-
- private fun addDeviceActions(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- addDeviceReplyAction(builder, holder)
- addDeviceMarkAsReadAction(builder, holder)
- addDeviceDeleteAction(builder, holder)
- }
-
- private fun addDeviceReplyAction(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- val icon = resourceProvider.iconReply
- val title = resourceProvider.actionReply()
- val content = holder.content
- val messageReference = content.messageReference
- val replyToMessagePendingIntent =
- actionCreator.createReplyPendingIntent(messageReference, holder.notificationId)
- builder.addAction(icon, title, replyToMessagePendingIntent)
- }
-
- private fun addDeviceMarkAsReadAction(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- val icon = resourceProvider.iconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val content = holder.content
- val notificationId = holder.notificationId
- val messageReference = content.messageReference
- val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
- builder.addAction(icon, title, action)
- }
-
- private fun addDeviceDeleteAction(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- if (!isDeleteActionEnabled()) {
- return
- }
- val icon = resourceProvider.iconDelete
- val title = resourceProvider.actionDelete()
- val content = holder.content
- val notificationId = holder.notificationId
- val messageReference = content.messageReference
- val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
- builder.addAction(icon, title, action)
- }
-
- private fun addWearActions(builder: NotificationCompat.Builder, account: Account, holder: NotificationHolder) {
- val wearableExtender = NotificationCompat.WearableExtender()
- addReplyAction(wearableExtender, holder)
- addMarkAsReadAction(wearableExtender, holder)
- if (isDeleteActionAvailableForWear()) {
- addDeleteAction(wearableExtender, holder)
- }
- if (isArchiveActionAvailableForWear(account)) {
- addArchiveAction(wearableExtender, holder)
- }
- if (isSpamActionAvailableForWear(account)) {
- addMarkAsSpamAction(wearableExtender, holder)
- }
- builder.extend(wearableExtender)
- }
-
- private fun addReplyAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconReplyAll
- val title = resourceProvider.actionReply()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createReplyPendingIntent(messageReference, notificationId)
- val replyAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(replyAction)
- }
-
- private fun addMarkAsReadAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
- val markAsReadAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(markAsReadAction)
- }
-
- private fun addDeleteAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconDelete
- val title = resourceProvider.actionDelete()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
- val deleteAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(deleteAction)
- }
-
- private fun addArchiveAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconArchive
- val title = resourceProvider.actionArchive()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createArchiveMessagePendingIntent(messageReference, notificationId)
- val archiveAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(archiveAction)
- }
-
- private fun addMarkAsSpamAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconMarkAsSpam
- val title = resourceProvider.actionMarkAsSpam()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createMarkMessageAsSpamPendingIntent(messageReference, notificationId)
- val spamAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(spamAction)
- }
-
- private fun isDeleteActionAvailableForWear(): Boolean {
- return isDeleteActionEnabled() && !K9.isConfirmDeleteFromNotification
- }
-
- private fun isArchiveActionAvailableForWear(account: Account): Boolean {
- return account.archiveFolderId != null
- }
-
- private fun isSpamActionAvailableForWear(account: Account): Boolean {
- return account.spamFolderId != null && !K9.isConfirmSpam
- }
-}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SummaryNotificationCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/SummaryNotificationCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d6b85a3aef2bb2e41718d2e71d16fad9fbf7a5cb
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/SummaryNotificationCreator.kt
@@ -0,0 +1,210 @@
+package com.fsck.k9.notification
+
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationCompat.WearableExtender
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.Account
+import com.fsck.k9.notification.NotificationChannelManager.ChannelType
+import com.fsck.k9.notification.NotificationIds.getNewMailSummaryNotificationId
+import androidx.core.app.NotificationCompat.Builder as NotificationBuilder
+
+internal class SummaryNotificationCreator(
+ private val notificationHelper: NotificationHelper,
+ private val actionCreator: NotificationActionCreator,
+ private val lockScreenNotificationCreator: LockScreenNotificationCreator,
+ private val singleMessageNotificationCreator: SingleMessageNotificationCreator,
+ private val resourceProvider: NotificationResourceProvider,
+ private val notificationManager: NotificationManagerCompat
+) {
+ fun createSummaryNotification(
+ baseNotificationData: BaseNotificationData,
+ summaryNotificationData: SummaryNotificationData
+ ) {
+ when (summaryNotificationData) {
+ is SummarySingleNotificationData -> {
+ createSingleMessageNotification(baseNotificationData, summaryNotificationData.singleNotificationData)
+ }
+ is SummaryInboxNotificationData -> {
+ createInboxStyleSummaryNotification(baseNotificationData, summaryNotificationData)
+ }
+ }
+ }
+
+ private fun createSingleMessageNotification(
+ baseNotificationData: BaseNotificationData,
+ singleNotificationData: SingleNotificationData
+ ) {
+ singleMessageNotificationCreator.createSingleNotification(
+ baseNotificationData,
+ singleNotificationData,
+ isGroupSummary = true
+ )
+ }
+
+ private fun createInboxStyleSummaryNotification(
+ baseNotificationData: BaseNotificationData,
+ notificationData: SummaryInboxNotificationData
+ ) {
+ val account = baseNotificationData.account
+ val accountName = baseNotificationData.accountName
+ val newMessagesCount = baseNotificationData.newMessagesCount
+ val title = resourceProvider.newMessagesTitle(newMessagesCount)
+ val summary = buildInboxSummaryText(accountName, notificationData)
+
+ val notification = notificationHelper.createNotificationBuilder(account, ChannelType.MESSAGES)
+ .setCategory(NotificationCompat.CATEGORY_EMAIL)
+ .setAutoCancel(true)
+ .setGroup(baseNotificationData.groupKey)
+ .setGroupSummary(true)
+ .setSmallIcon(resourceProvider.iconNewMail)
+ .setColor(baseNotificationData.color)
+ .setWhen(notificationData.timestamp)
+ .setNumber(notificationData.additionalMessagesCount)
+ .setTicker(notificationData.content.firstOrNull())
+ .setContentTitle(title)
+ .setSubText(accountName)
+ .setInboxStyle(title, summary, notificationData.content)
+ .setContentIntent(createViewIntent(account, notificationData))
+ .setDeleteIntent(createDismissIntent(account, notificationData.notificationId))
+ .setDeviceActions(account, notificationData)
+ .setWearActions(account, notificationData)
+ .setAppearance(notificationData.isSilent, baseNotificationData.appearance)
+ .setLockScreenNotification(baseNotificationData)
+ .build()
+
+ notificationManager.notify(notificationData.notificationId, notification)
+ }
+
+ private fun buildInboxSummaryText(accountName: String, notificationData: SummaryInboxNotificationData): String {
+ return if (notificationData.additionalMessagesCount > 0) {
+ resourceProvider.additionalMessages(notificationData.additionalMessagesCount, accountName)
+ } else {
+ accountName
+ }
+ }
+
+ private fun NotificationBuilder.setInboxStyle(
+ title: String,
+ summary: String,
+ contentLines: List
+ ) = apply {
+ val style = NotificationCompat.InboxStyle()
+ .setBigContentTitle(title)
+ .setSummaryText(summary)
+
+ for (line in contentLines) {
+ style.addLine(line)
+ }
+
+ setStyle(style)
+ }
+
+ private fun createViewIntent(account: Account, notificationData: SummaryInboxNotificationData): PendingIntent {
+ return actionCreator.createViewMessagesPendingIntent(
+ account = account,
+ messageReferences = notificationData.messageReferences,
+ notificationId = notificationData.notificationId
+ )
+ }
+
+ private fun createDismissIntent(account: Account, notificationId: Int): PendingIntent {
+ return actionCreator.createDismissAllMessagesPendingIntent(account, notificationId)
+ }
+
+ private fun NotificationBuilder.setDeviceActions(
+ account: Account,
+ notificationData: SummaryInboxNotificationData
+ ) = apply {
+ for (action in notificationData.actions) {
+ when (action) {
+ SummaryNotificationAction.MarkAsRead -> addMarkAllAsReadAction(account, notificationData)
+ SummaryNotificationAction.Delete -> addDeleteAllAction(account, notificationData)
+ }
+ }
+ }
+
+ private fun NotificationBuilder.addMarkAllAsReadAction(
+ account: Account,
+ notificationData: SummaryInboxNotificationData
+ ) {
+ val icon = resourceProvider.iconMarkAsRead
+ val title = resourceProvider.actionMarkAsRead()
+ val messageReferences = notificationData.messageReferences
+ val notificationId = notificationData.notificationId
+ val markAllAsReadPendingIntent =
+ actionCreator.createMarkAllAsReadPendingIntent(account, messageReferences, notificationId)
+
+ addAction(icon, title, markAllAsReadPendingIntent)
+ }
+
+ private fun NotificationBuilder.addDeleteAllAction(
+ account: Account,
+ notificationData: SummaryInboxNotificationData
+ ) {
+ val icon = resourceProvider.iconDelete
+ val title = resourceProvider.actionDelete()
+ val notificationId = getNewMailSummaryNotificationId(account)
+ val messageReferences = notificationData.messageReferences
+ val action = actionCreator.createDeleteAllPendingIntent(account, messageReferences, notificationId)
+
+ addAction(icon, title, action)
+ }
+
+ private fun NotificationBuilder.setWearActions(
+ account: Account,
+ notificationData: SummaryInboxNotificationData
+ ) = apply {
+ val wearableExtender = WearableExtender().apply {
+ for (action in notificationData.wearActions) {
+ when (action) {
+ SummaryWearNotificationAction.MarkAsRead -> addMarkAllAsReadAction(account, notificationData)
+ SummaryWearNotificationAction.Delete -> addDeleteAllAction(account, notificationData)
+ SummaryWearNotificationAction.Archive -> addArchiveAllAction(account, notificationData)
+ }
+ }
+ }
+
+ extend(wearableExtender)
+ }
+
+ private fun WearableExtender.addMarkAllAsReadAction(
+ account: Account,
+ notificationData: SummaryInboxNotificationData
+ ) {
+ val icon = resourceProvider.wearIconMarkAsRead
+ val title = resourceProvider.actionMarkAllAsRead()
+ val messageReferences = notificationData.messageReferences
+ val notificationId = getNewMailSummaryNotificationId(account)
+ val action = actionCreator.createMarkAllAsReadPendingIntent(account, messageReferences, notificationId)
+ val markAsReadAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(markAsReadAction)
+ }
+
+ private fun WearableExtender.addDeleteAllAction(account: Account, notificationData: SummaryInboxNotificationData) {
+ val icon = resourceProvider.wearIconDelete
+ val title = resourceProvider.actionDeleteAll()
+ val messageReferences = notificationData.messageReferences
+ val notificationId = getNewMailSummaryNotificationId(account)
+ val action = actionCreator.createDeleteAllPendingIntent(account, messageReferences, notificationId)
+ val deleteAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(deleteAction)
+ }
+
+ private fun WearableExtender.addArchiveAllAction(account: Account, notificationData: SummaryInboxNotificationData) {
+ val icon = resourceProvider.wearIconArchive
+ val title = resourceProvider.actionArchiveAll()
+ val messageReferences = notificationData.messageReferences
+ val notificationId = getNewMailSummaryNotificationId(account)
+ val action = actionCreator.createArchiveAllPendingIntent(account, messageReferences, notificationId)
+ val archiveAction = NotificationCompat.Action.Builder(icon, title, action).build()
+
+ addAction(archiveAction)
+ }
+
+ private fun NotificationBuilder.setLockScreenNotification(notificationData: BaseNotificationData) = apply {
+ lockScreenNotificationCreator.configureLockScreenNotification(this, notificationData)
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SummaryNotificationDataCreator.kt b/app/core/src/main/java/com/fsck/k9/notification/SummaryNotificationDataCreator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..50d853c6b6f410e5b1e691fc4d798692a4bbf492
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/SummaryNotificationDataCreator.kt
@@ -0,0 +1,85 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.K9
+
+internal class SummaryNotificationDataCreator(
+ private val singleMessageNotificationDataCreator: SingleMessageNotificationDataCreator
+) {
+ fun createSummaryNotificationData(
+ data: NotificationData,
+ timestamp: Long,
+ silent: Boolean
+ ): SummaryNotificationData {
+ val shouldBeSilent = silent || K9.isQuietTime
+ return if (data.isSingleMessageNotification) {
+ createSummarySingleNotificationData(data, timestamp, shouldBeSilent)
+ } else {
+ createSummaryInboxNotificationData(data, timestamp, shouldBeSilent)
+ }
+ }
+
+ private fun createSummarySingleNotificationData(
+ data: NotificationData,
+ timestamp: Long,
+ silent: Boolean
+ ): SummaryNotificationData {
+ return singleMessageNotificationDataCreator.createSummarySingleNotificationData(data, timestamp, silent)
+ }
+
+ private fun createSummaryInboxNotificationData(
+ data: NotificationData,
+ timestamp: Long,
+ silent: Boolean
+ ): SummaryNotificationData {
+ return SummaryInboxNotificationData(
+ notificationId = NotificationIds.getNewMailSummaryNotificationId(data.account),
+ isSilent = silent,
+ timestamp = timestamp,
+ content = getSummaryContent(data),
+ additionalMessagesCount = data.getSummaryOverflowMessagesCount(),
+ messageReferences = data.getAllMessageReferences(),
+ actions = createSummaryNotificationActions(),
+ wearActions = createSummaryWearNotificationActions(data.account)
+ )
+ }
+
+ private fun getSummaryContent(data: NotificationData): List {
+ return data.getContentForSummaryNotification().map { it.summary }
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ private fun createSummaryNotificationActions(): List {
+ return buildList {
+ add(SummaryNotificationAction.MarkAsRead)
+
+ if (isDeleteActionEnabled()) {
+ add(SummaryNotificationAction.Delete)
+ }
+ }
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ private fun createSummaryWearNotificationActions(account: Account): List {
+ return buildList {
+ add(SummaryWearNotificationAction.MarkAsRead)
+
+ if (isDeleteActionAvailableForWear()) {
+ add(SummaryWearNotificationAction.Delete)
+ }
+
+ if (account.hasArchiveFolder()) {
+ add(SummaryWearNotificationAction.Archive)
+ }
+ }
+ }
+
+ private fun isDeleteActionEnabled(): Boolean {
+ return K9.notificationQuickDeleteBehaviour == K9.NotificationQuickDelete.ALWAYS
+ }
+
+ // We don't support confirming actions on Wear devices. So don't show the action when confirmation is enabled.
+ private fun isDeleteActionAvailableForWear(): Boolean {
+ return isDeleteActionEnabled() && !K9.isConfirmDeleteFromNotification
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/SyncNotificationController.kt b/app/core/src/main/java/com/fsck/k9/notification/SyncNotificationController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f7bebe91cdd204788b2b22cf1e40f0db2f6888a5
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/notification/SyncNotificationController.kt
@@ -0,0 +1,133 @@
+package com.fsck.k9.notification
+
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import com.fsck.k9.Account
+import com.fsck.k9.mailstore.LocalFolder
+
+private const val NOTIFICATION_LED_WHILE_SYNCING = false
+
+internal class SyncNotificationController(
+ private val notificationHelper: NotificationHelper,
+ private val actionBuilder: NotificationActionCreator,
+ private val resourceProvider: NotificationResourceProvider
+) {
+ fun showSendingNotification(account: Account) {
+ val accountName = notificationHelper.getAccountName(account)
+ val title = resourceProvider.sendingMailTitle()
+ val tickerText = resourceProvider.sendingMailBody(accountName)
+
+ val notificationId = NotificationIds.getFetchingMailNotificationId(account)
+ val outboxFolderId = account.outboxFolderId ?: error("Outbox folder not configured")
+ val showMessageListPendingIntent = actionBuilder.createViewFolderPendingIntent(
+ account, outboxFolderId, notificationId
+ )
+
+ val notificationBuilder = notificationHelper
+ .createNotificationBuilder(account, NotificationChannelManager.ChannelType.MISCELLANEOUS)
+ .setSmallIcon(resourceProvider.iconSendingMail)
+ .setWhen(System.currentTimeMillis())
+ .setOngoing(true)
+ .setTicker(tickerText)
+ .setContentTitle(title)
+ .setContentText(accountName)
+ .setContentIntent(showMessageListPendingIntent)
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+
+ if (NOTIFICATION_LED_WHILE_SYNCING) {
+ notificationHelper.configureNotification(
+ builder = notificationBuilder,
+ ringtone = null,
+ vibrationPattern = null,
+ ledColor = account.notificationSetting.ledColor,
+ ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_FAST,
+ ringAndVibrate = true
+ )
+ }
+
+ notificationManager.notify(notificationId, notificationBuilder.build())
+ }
+
+ fun clearSendingNotification(account: Account) {
+ val notificationId = NotificationIds.getFetchingMailNotificationId(account)
+ notificationManager.cancel(notificationId)
+ }
+
+ fun showFetchingMailNotification(account: Account, folder: LocalFolder) {
+ val accountName = account.description
+ val folderId = folder.databaseId
+ val folderName = folder.name
+ val tickerText = resourceProvider.checkingMailTicker(accountName, folderName)
+ val title = resourceProvider.checkingMailTitle()
+
+ // TODO: Use format string from resources
+ val text = accountName + resourceProvider.checkingMailSeparator() + folderName
+
+ val notificationId = NotificationIds.getFetchingMailNotificationId(account)
+ val showMessageListPendingIntent = actionBuilder.createViewFolderPendingIntent(
+ account, folderId, notificationId
+ )
+
+ val notificationBuilder = notificationHelper
+ .createNotificationBuilder(account, NotificationChannelManager.ChannelType.MISCELLANEOUS)
+ .setSmallIcon(resourceProvider.iconCheckingMail)
+ .setWhen(System.currentTimeMillis())
+ .setOngoing(true)
+ .setTicker(tickerText)
+ .setContentTitle(title)
+ .setContentText(text)
+ .setContentIntent(showMessageListPendingIntent)
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setCategory(NotificationCompat.CATEGORY_SERVICE)
+
+ if (NOTIFICATION_LED_WHILE_SYNCING) {
+ notificationHelper.configureNotification(
+ builder = notificationBuilder,
+ ringtone = null,
+ vibrationPattern = null,
+ ledColor = account.notificationSetting.ledColor,
+ ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_FAST,
+ ringAndVibrate = true
+ )
+ }
+
+ notificationManager.notify(notificationId, notificationBuilder.build())
+ }
+
+ fun showEmptyFetchingMailNotification(account: Account) {
+ val title = resourceProvider.checkingMailTitle()
+ val text = account.description
+ val notificationId = NotificationIds.getFetchingMailNotificationId(account)
+
+ val notificationBuilder = notificationHelper
+ .createNotificationBuilder(account, NotificationChannelManager.ChannelType.MISCELLANEOUS)
+ .setSmallIcon(resourceProvider.iconCheckingMail)
+ .setWhen(System.currentTimeMillis())
+ .setOngoing(true)
+ .setContentTitle(title)
+ .setContentText(text)
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ .setCategory(NotificationCompat.CATEGORY_SERVICE)
+
+ if (NOTIFICATION_LED_WHILE_SYNCING) {
+ notificationHelper.configureNotification(
+ builder = notificationBuilder,
+ ringtone = null,
+ vibrationPattern = null,
+ ledColor = account.notificationSetting.ledColor,
+ ledSpeed = NotificationHelper.NOTIFICATION_LED_BLINK_FAST,
+ ringAndVibrate = true
+ )
+ }
+
+ notificationManager.notify(notificationId, notificationBuilder.build())
+ }
+
+ fun clearFetchingMailNotification(account: Account) {
+ val notificationId = NotificationIds.getFetchingMailNotificationId(account)
+ notificationManager.cancel(notificationId)
+ }
+
+ private val notificationManager: NotificationManagerCompat
+ get() = notificationHelper.getNotificationManager()
+}
diff --git a/app/core/src/main/java/com/fsck/k9/notification/WearNotifications.kt b/app/core/src/main/java/com/fsck/k9/notification/WearNotifications.kt
deleted file mode 100644
index b6df3fe506c0d61c3066963770ce63159a874de1..0000000000000000000000000000000000000000
--- a/app/core/src/main/java/com/fsck/k9/notification/WearNotifications.kt
+++ /dev/null
@@ -1,232 +0,0 @@
-package com.fsck.k9.notification
-
-import android.app.Notification
-import androidx.core.app.NotificationCompat
-import com.fsck.k9.Account
-import com.fsck.k9.K9
-import com.fsck.k9.controller.MessagingController
-import com.fsck.k9.notification.NotificationIds.getNewMailSummaryNotificationId
-
-internal open class WearNotifications(
- notificationHelper: NotificationHelper,
- actionCreator: NotificationActionCreator,
- resourceProvider: NotificationResourceProvider
-) : BaseNotifications(notificationHelper, actionCreator, resourceProvider) {
- fun buildStackedNotification(account: Account, holder: NotificationHolder): Notification {
- val notificationId = holder.notificationId
- val content = holder.content
- val builder = createBigTextStyleNotification(account, holder, notificationId)
- builder.setNotificationSilent()
-
- val deletePendingIntent = actionCreator.createDismissMessagePendingIntent(
- context, content.messageReference, holder.notificationId
- )
- builder.setDeleteIntent(deletePendingIntent)
-
- addActions(builder, account, holder)
-
- return builder.build()
- }
-
- fun addSummaryActions(builder: NotificationCompat.Builder, notificationData: NotificationData) {
- val wearableExtender = NotificationCompat.WearableExtender()
-
- addMarkAllAsReadAction(wearableExtender, notificationData)
- if (isDeleteActionAvailableForWear()) {
- addDeleteAllAction(wearableExtender, notificationData)
- }
- if (isArchiveActionAvailableForWear(notificationData.account)) {
- addArchiveAllAction(wearableExtender, notificationData)
- }
- builder.extend(wearableExtender)
- }
-
- private fun addMarkAllAsReadAction(
- wearableExtender: NotificationCompat.WearableExtender,
- notificationData: NotificationData
- ) {
- val icon = resourceProvider.wearIconMarkAsRead
- val title = resourceProvider.actionMarkAllAsRead()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val action = actionCreator.createMarkAllAsReadPendingIntent(account, messageReferences, notificationId)
- val markAsReadAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(markAsReadAction)
- }
-
- private fun addDeleteAllAction(
- wearableExtender: NotificationCompat.WearableExtender,
- notificationData: NotificationData
- ) {
- val icon = resourceProvider.wearIconDelete
- val title = resourceProvider.actionDeleteAll()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val action = actionCreator.createDeleteAllPendingIntent(account, messageReferences, notificationId)
- val deleteAction = NotificationCompat.Action.Builder(icon, title, action).build()
-
- wearableExtender.addAction(deleteAction);
- wearableExtender.addAction(deleteAction)
- }
-
- private fun addArchiveAllAction(
- wearableExtender: NotificationCompat.WearableExtender,
- notificationData: NotificationData
- ) {
- val icon = resourceProvider.wearIconArchive
- val title = resourceProvider.actionArchiveAll()
- val account = notificationData.account
- val messageReferences = notificationData.getAllMessageReferences()
- val notificationId = getNewMailSummaryNotificationId(account)
- val action = actionCreator.createArchiveAllPendingIntent(account, messageReferences, notificationId)
- val archiveAction = NotificationCompat.Action.Builder(icon, title, action).build()
-
- wearableExtender.addAction(archiveAction)
- }
-
- private fun addActions(builder: NotificationCompat.Builder, account: Account, holder: NotificationHolder) {
- addDeviceActions(builder, holder)
- addWearActions(builder, account, holder)
- }
-
- private fun addDeviceActions(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- addDeviceReplyAction(builder, holder)
- addDeviceMarkAsReadAction(builder, holder)
- addDeviceDeleteAction(builder, holder)
- }
-
- private fun addDeviceReplyAction(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- val icon = resourceProvider.iconReply
- val title = resourceProvider.actionReply()
- val content = holder.content
- val messageReference = content.messageReference
- val replyToMessagePendingIntent =
- actionCreator.createReplyPendingIntent(messageReference, holder.notificationId)
-
- builder.addAction(icon, title, replyToMessagePendingIntent)
- }
-
- private fun addDeviceMarkAsReadAction(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- val icon = resourceProvider.iconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val content = holder.content
- val notificationId = holder.notificationId
- val messageReference = content.messageReference
- val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
- builder.addAction(icon, title, action)
- }
-
- private fun addDeviceDeleteAction(builder: NotificationCompat.Builder, holder: NotificationHolder) {
- if (!isDeleteActionEnabled()) {
- return
- }
-
- val icon = resourceProvider.iconDelete
- val title = resourceProvider.actionDelete()
- val content = holder.content
- val notificationId = holder.notificationId
- val messageReference = content.messageReference
- val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
- builder.addAction(icon, title, action)
- }
-
- private fun addWearActions(builder: NotificationCompat.Builder, account: Account, holder: NotificationHolder) {
- val wearableExtender = NotificationCompat.WearableExtender()
-
- addReplyAction(wearableExtender, holder)
- addMarkAsReadAction(wearableExtender, holder)
- if (isDeleteActionAvailableForWear()) {
- addDeleteAction(wearableExtender, holder)
- }
-
- if (isArchiveActionAvailableForWear(account)) {
- addArchiveAction(wearableExtender, holder)
- }
-
- if (isSpamActionAvailableForWear(account)) {
- addMarkAsSpamAction(wearableExtender, holder)
- }
-
- builder.extend(wearableExtender)
- }
-
- private fun addReplyAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconReplyAll
- val title = resourceProvider.actionReply()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createReplyPendingIntent(messageReference, notificationId)
- val replyAction = NotificationCompat.Action.Builder(icon, title, action).build()
- wearableExtender.addAction(replyAction)
- }
-
- private fun addMarkAsReadAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconMarkAsRead
- val title = resourceProvider.actionMarkAsRead()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createMarkMessageAsReadPendingIntent(messageReference, notificationId)
- val markAsReadAction = NotificationCompat.Action.Builder(icon, title, action).build()
-
- wearableExtender.addAction(markAsReadAction)
- }
-
- private fun addDeleteAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconDelete
- val title = resourceProvider.actionDelete()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createDeleteMessagePendingIntent(messageReference, notificationId)
- val deleteAction = NotificationCompat.Action.Builder(icon, title, action).build()
-
- wearableExtender.addAction(deleteAction)
- }
-
- private fun addArchiveAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconArchive
- val title = resourceProvider.actionArchive()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createArchiveMessagePendingIntent(messageReference, notificationId)
- val archiveAction = NotificationCompat.Action.Builder(icon, title, action).build()
-
- wearableExtender.addAction(archiveAction)
- }
-
- private fun addMarkAsSpamAction(wearableExtender: NotificationCompat.WearableExtender, holder: NotificationHolder) {
- val icon = resourceProvider.wearIconMarkAsSpam
- val title = resourceProvider.actionMarkAsSpam()
- val messageReference = holder.content.messageReference
- val notificationId = holder.notificationId
- val action = actionCreator.createMarkMessageAsSpamPendingIntent(messageReference, notificationId)
- val spamAction = NotificationCompat.Action.Builder(icon, title, action).build()
-
- wearableExtender.addAction(spamAction)
- }
-
- private fun isDeleteActionAvailableForWear(): Boolean {
- return isDeleteActionEnabled() && !K9.isConfirmDeleteFromNotification
- }
-
- private fun isArchiveActionAvailableForWear(account: Account): Boolean {
- return isMovePossible(account, account.archiveFolderId)
- }
-
- private fun isSpamActionAvailableForWear(account: Account): Boolean {
- return !K9.isConfirmSpam && isMovePossible(account, account.spamFolderId)
- }
-
- private fun isMovePossible(account: Account, destinationFolderId: Long?): Boolean {
- if (destinationFolderId == null) {
- return false
- }
- val controller = createMessagingController()
- return controller.isMoveCapable(account)
- }
-
- protected open fun createMessagingController(): MessagingController {
- return MessagingController.getInstance(context)
- }
-}
\ No newline at end of file
diff --git a/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt b/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fbf30c048d2b0b3ce931e008eeabe8158e8ab951
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/power/AndroidPowerManager.kt
@@ -0,0 +1,90 @@
+package com.fsck.k9.power
+
+import android.annotation.SuppressLint
+import android.os.SystemClock
+import com.fsck.k9.mail.power.PowerManager
+import com.fsck.k9.mail.power.WakeLock
+import java.util.concurrent.atomic.AtomicInteger
+import timber.log.Timber
+import android.os.PowerManager as SystemPowerManager
+import android.os.PowerManager.WakeLock as SystemWakeLock
+
+internal class AndroidPowerManager(private val systemPowerManager: SystemPowerManager) : PowerManager {
+ override fun newWakeLock(tag: String): WakeLock {
+ return AndroidWakeLock(SystemPowerManager.PARTIAL_WAKE_LOCK, tag)
+ }
+
+ inner class AndroidWakeLock(flags: Int, val tag: String?) : WakeLock {
+ private val wakeLock: SystemWakeLock = systemPowerManager.newWakeLock(flags, tag)
+ private val id = wakeLockId.getAndIncrement()
+
+ @Volatile
+ private var startTime: Long? = null
+
+ @Volatile
+ private var timeout: Long? = null
+
+ init {
+ Timber.v("AndroidWakeLock for tag %s / id %d: Create", tag, id)
+ }
+
+ override fun acquire(timeout: Long) {
+ synchronized(wakeLock) {
+ wakeLock.acquire(timeout)
+ }
+
+ Timber.v("AndroidWakeLock for tag %s / id %d for %d ms: acquired", tag, id, timeout)
+
+ if (startTime == null) {
+ startTime = SystemClock.elapsedRealtime()
+ }
+
+ this.timeout = timeout
+ }
+
+ @SuppressLint("WakelockTimeout")
+ override fun acquire() {
+ synchronized(wakeLock) {
+ wakeLock.acquire()
+ }
+
+ Timber.v("AndroidWakeLock for tag %s / id %d: acquired with no timeout.", tag, id)
+
+ if (startTime == null) {
+ startTime = SystemClock.elapsedRealtime()
+ }
+
+ timeout = null
+ }
+
+ override fun setReferenceCounted(counted: Boolean) {
+ synchronized(wakeLock) {
+ wakeLock.setReferenceCounted(counted)
+ }
+ }
+
+ override fun release() {
+ val startTime = this.startTime
+ if (startTime != null) {
+ val endTime = SystemClock.elapsedRealtime()
+
+ Timber.v(
+ "AndroidWakeLock for tag %s / id %d: releasing after %d ms, timeout = %d ms",
+ tag, id, endTime - startTime, timeout
+ )
+ } else {
+ Timber.v("AndroidWakeLock for tag %s / id %d, timeout = %d ms: releasing", tag, id, timeout)
+ }
+
+ synchronized(wakeLock) {
+ wakeLock.release()
+ }
+
+ this.startTime = null
+ }
+ }
+
+ companion object {
+ private val wakeLockId = AtomicInteger(0)
+ }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/power/KoinModule.kt b/app/core/src/main/java/com/fsck/k9/power/KoinModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e5e01228bcf618fb703902f54c03f2fb17a22008
--- /dev/null
+++ b/app/core/src/main/java/com/fsck/k9/power/KoinModule.kt
@@ -0,0 +1,10 @@
+package com.fsck.k9.power
+
+import android.content.Context
+import com.fsck.k9.mail.power.PowerManager
+import org.koin.dsl.module
+
+val powerModule = module {
+ factory { get().getSystemService(Context.POWER_SERVICE) as android.os.PowerManager }
+ single { AndroidPowerManager(systemPowerManager = get()) }
+}
diff --git a/app/core/src/main/java/com/fsck/k9/preferences/AccountSettingsDescriptions.java b/app/core/src/main/java/com/fsck/k9/preferences/AccountSettingsDescriptions.java
index f5b371d9ce0f9ad55d02e4194124fc835a548c4e..6e5101d6b365d5c4e1713fcbf2772b38114c57f5 100644
--- a/app/core/src/main/java/com/fsck/k9/preferences/AccountSettingsDescriptions.java
+++ b/app/core/src/main/java/com/fsck/k9/preferences/AccountSettingsDescriptions.java
@@ -413,8 +413,8 @@ public class AccountSettingsDescriptions {
@Override
public String fromString(String value) {
StorageManager storageManager = StorageManager.getInstance(context);
- Map providers = storageManager.getAvailableProviders();
- if (providers.containsKey(value)) {
+ Set providers = storageManager.getAvailableProviders();
+ if (providers.contains(value)) {
return value;
}
throw new RuntimeException("Validation failed");
diff --git a/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java b/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java
index a31e9917897099ae6f65fb4b7216995bd919c5cb..e7b7f920a7894307453e9c16fb9c9db22a5aa625 100644
--- a/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java
+++ b/app/core/src/main/java/com/fsck/k9/preferences/GeneralSettingsDescriptions.java
@@ -36,7 +36,7 @@ import com.fsck.k9.preferences.Settings.WebFontSizeSetting;
import static com.fsck.k9.K9.LockScreenNotificationVisibility;
-public class GeneralSettingsDescriptions {
+public class GeneralSettingsDescriptions {
static final Map> SETTINGS;
private static final Map UPGRADERS;
diff --git a/app/core/src/main/java/com/fsck/k9/preferences/ServerTypeConverter.kt b/app/core/src/main/java/com/fsck/k9/preferences/ServerTypeConverter.kt
index 7f2c77eb3f234db2fdd86445242993b15ccba6d3..9d64def8b3dbe7be3f969c19572faa67accc43d6 100644
--- a/app/core/src/main/java/com/fsck/k9/preferences/ServerTypeConverter.kt
+++ b/app/core/src/main/java/com/fsck/k9/preferences/ServerTypeConverter.kt
@@ -1,7 +1,5 @@
package com.fsck.k9.preferences
-import java.util.Locale
-
object ServerTypeConverter {
@JvmStatic
fun toServerSettingsType(exportType: String): String = exportType.lowercase()
diff --git a/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt b/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt
index 35db0adecfde78b63a9c88b1a4437ffc07556589..f8f09c264b80160021ee69684fabb34861d211dc 100644
--- a/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt
+++ b/app/core/src/main/java/com/fsck/k9/preferences/SettingsExporter.kt
@@ -210,7 +210,6 @@ class SettingsExporter(
}
}
- val folderRepository = folderRepositoryManager.getFolderRepository(account)
writeFolderNameSettings(account, folderRepository, serializer)
serializer.endTag(null, SETTINGS_ELEMENT)
diff --git a/app/core/src/main/java/com/fsck/k9/provider/RawMessageProvider.java b/app/core/src/main/java/com/fsck/k9/provider/RawMessageProvider.java
index 1f80af69d61c7317b2ab3afe9b611bee86a5a2ac..37fcfddeb1a9da163ff2edcfc33569231bc6e7fd 100644
--- a/app/core/src/main/java/com/fsck/k9/provider/RawMessageProvider.java
+++ b/app/core/src/main/java/com/fsck/k9/provider/RawMessageProvider.java
@@ -99,8 +99,7 @@ public class RawMessageProvider extends ContentProvider {
private long computeMessageSize(LocalMessage message) {
// TODO: Store message size in database when saving message so this can be a simple lookup instead.
- try {
- CountingOutputStream countingOutputStream = new CountingOutputStream();
+ try (CountingOutputStream countingOutputStream = new CountingOutputStream()) {
message.writeTo(countingOutputStream);
return countingOutputStream.getCount();
} catch (IOException | MessagingException e) {
diff --git a/app/core/src/main/java/com/fsck/k9/service/DatabaseUpgradeService.java b/app/core/src/main/java/com/fsck/k9/service/DatabaseUpgradeService.java
index a630594561586bb1fc8966b8d72c7d0012498e2b..790be15076dabf219e8afbbcdf326e8150887662 100644
--- a/app/core/src/main/java/com/fsck/k9/service/DatabaseUpgradeService.java
+++ b/app/core/src/main/java/com/fsck/k9/service/DatabaseUpgradeService.java
@@ -8,13 +8,14 @@ import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
-import android.os.PowerManager;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.fsck.k9.Account;
import com.fsck.k9.DI;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
+import com.fsck.k9.mail.power.PowerManager;
+import com.fsck.k9.mail.power.WakeLock;
import com.fsck.k9.mailstore.LocalStoreProvider;
import com.fsck.k9.power.TracingPowerManager;
import com.fsck.k9.power.TracingPowerManager.TracingWakeLock;
@@ -102,7 +103,7 @@ public class DatabaseUpgradeService extends Service {
private int mProgress;
private int mProgressEnd;
- private TracingWakeLock mWakeLock;
+ private WakeLock mWakeLock;
@Override
@@ -139,8 +140,8 @@ public class DatabaseUpgradeService extends Service {
* Acquire a partial wake lock so the CPU won't go to sleep when the screen is turned off.
*/
private void acquireWakelock() {
- TracingPowerManager pm = TracingPowerManager.getPowerManager(this);
- mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
+ PowerManager pm = DI.get(PowerManager.class);
+ mWakeLock = pm.newWakeLock(WAKELOCK_TAG);
mWakeLock.setReferenceCounted(false);
mWakeLock.acquire(WAKELOCK_TIMEOUT);
}
diff --git a/app/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt b/app/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt
index f1ca422f2d5e0bbe20c312d60fde199e09f2a860..19c67aced53a62d8751f454dc1f8fdf56f284978 100644
--- a/app/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/QuietTimeCheckerTest.kt
@@ -4,11 +4,9 @@ import java.util.Calendar
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
-import org.mockito.Mockito.mock
-import org.mockito.kotlin.whenever
class QuietTimeCheckerTest {
- private val clock = mock(Clock::class.java)
+ private val clock = TestClock()
@Test
fun endTimeBeforeStartTime_timeIsBeforeEndOfQuietTime() {
@@ -113,7 +111,6 @@ class QuietTimeCheckerTest {
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
calendar.set(Calendar.MINUTE, minute)
- val timeInMillis = calendar.timeInMillis
- whenever(clock.time).thenReturn(timeInMillis)
+ clock.time = calendar.timeInMillis
}
}
diff --git a/app/core/src/test/java/com/fsck/k9/TestCoreResourceProvider.kt b/app/core/src/test/java/com/fsck/k9/TestCoreResourceProvider.kt
index d3052bf46448bca22653ae3badefe6f4b4650e0b..36e47248d865305ccc8263b358f5df133e3e533d 100644
--- a/app/core/src/test/java/com/fsck/k9/TestCoreResourceProvider.kt
+++ b/app/core/src/test/java/com/fsck/k9/TestCoreResourceProvider.kt
@@ -7,14 +7,6 @@ class TestCoreResourceProvider : CoreResourceProvider {
override fun defaultIdentityDescription() = "initial identity"
- override fun internalStorageProviderName(): String {
- throw UnsupportedOperationException("not implemented")
- }
-
- override fun externalStorageProviderName(): String {
- throw UnsupportedOperationException("not implemented")
- }
-
override fun contactDisplayNamePrefix() = "To:"
override fun contactUnknownSender() = ""
override fun contactUnknownRecipient() = ""
diff --git a/app/core/src/test/java/com/fsck/k9/controller/MessageReferenceTest.java b/app/core/src/test/java/com/fsck/k9/controller/MessageReferenceTest.java
deleted file mode 100644
index 97f5166a2b4f152e749339c377eebc727c9d0cf2..0000000000000000000000000000000000000000
--- a/app/core/src/test/java/com/fsck/k9/controller/MessageReferenceTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package com.fsck.k9.controller;
-
-
-import com.fsck.k9.mail.Flag;
-import org.junit.Test;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
-
-
-public class MessageReferenceTest {
-
- @Test
- public void checkIdentityStringFromMessageReferenceWithoutFlag() {
- MessageReference messageReference = createMessageReference("o hai!", 2, "10101010");
-
- assertEquals("#:byBoYWkh:Mg==:MTAxMDEwMTA=", messageReference.toIdentityString());
- }
-
- @Test
- public void checkIdentityStringFromMessageReferenceWithFlag() {
- MessageReference messageReference = createMessageReferenceWithFlag("o hai!", 2, "10101010", Flag.ANSWERED);
-
- assertEquals("#:byBoYWkh:Mg==:MTAxMDEwMTA=:ANSWERED", messageReference.toIdentityString());
- }
-
- @Test
- public void parseIdentityStringWithoutFlag() {
- MessageReference messageReference = MessageReference.parse("#:byBoYWkh:Mg==:MTAxMDEwMTA=");
-
- assertNotNull(messageReference);
- assertEquals("o hai!", messageReference.getAccountUuid());
- assertEquals(2, messageReference.getFolderId());
- assertEquals("10101010", messageReference.getUid());
- assertNull(messageReference.getFlag());
- }
-
- @Test
- public void parseIdentityStringWithFlag() {
- MessageReference messageReference = MessageReference.parse("#:byBoYWkh:Mg==:MTAxMDEwMTA=:ANSWERED");
-
- assertNotNull(messageReference);
- assertEquals("o hai!", messageReference.getAccountUuid());
- assertEquals(2, messageReference.getFolderId());
- assertEquals("10101010", messageReference.getUid());
- assertEquals(Flag.ANSWERED, messageReference.getFlag());
- }
-
- @Test
- public void checkMessageReferenceWithChangedUid() {
- MessageReference messageReferenceOne = createMessageReferenceWithFlag("account", 1, "uid", Flag.SEEN);
-
- MessageReference messageReferenceTwo = messageReferenceOne.withModifiedUid("---");
-
- assertEquals("account", messageReferenceTwo.getAccountUuid());
- assertEquals(1, messageReferenceTwo.getFolderId());
- assertEquals("---", messageReferenceTwo.getUid());
- assertEquals(Flag.SEEN, messageReferenceTwo.getFlag());
- }
-
- @Test
- public void checkMessageReferenceWithChangedFlag() {
- MessageReference messageReferenceOne = createMessageReferenceWithFlag("account", 1, "uid", Flag.ANSWERED);
-
- MessageReference messageReferenceTwo = messageReferenceOne.withModifiedFlag(Flag.DELETED);
-
- assertEquals("account", messageReferenceTwo.getAccountUuid());
- assertEquals(1, messageReferenceTwo.getFolderId());
- assertEquals("uid", messageReferenceTwo.getUid());
- assertEquals(Flag.DELETED, messageReferenceTwo.getFlag());
- }
-
- @Test
- public void parseIdentityStringContainingBadVersionNumber() {
- MessageReference messageReference = MessageReference.parse("@:byBoYWkh:MTAxMDEwMTA=:ANSWERED");
-
- assertNull(messageReference);
- }
-
- @SuppressWarnings("ConstantConditions")
- @Test
- public void parseNullIdentityString() {
- MessageReference messageReference = MessageReference.parse(null);
-
- assertNull(messageReference);
- }
-
- @Test
- public void parseIdentityStringWithCorruptFlag() {
- MessageReference messageReference =
- MessageReference.parse("!:%^&%^*$&$by&(BYWkh:Zm9%^@sZGVy:MT-35#$AxMDEwMTA=:ANSWE!RED");
-
- assertNull(messageReference);
- }
-
- @Test
- public void equalsWithAnObjectShouldReturnFalse() {
- MessageReference messageReference = new MessageReference("a", 1, "c", null);
- Object object = new Object();
-
- assertFalse(messageReference.equals(object));
- }
-
- @SuppressWarnings({"ObjectEqualsNull", "ConstantConditions"})
- @Test
- public void equalsWithNullShouldReturnFalse() {
- MessageReference messageReference = createMessageReference("account", 1, "uid");
-
- assertFalse(messageReference.equals(null));
- }
-
- @SuppressWarnings("EqualsWithItself")
- @Test
- public void equalsWithSameMessageReferenceShouldReturnTrue() {
- MessageReference messageReference = createMessageReference("account", 1, "uid");
-
- assertTrue(messageReference.equals(messageReference));
- }
-
- @Test
- public void equalsWithMessageReferenceContainingSameDataShouldReturnTrue() {
- MessageReference messageReferenceOne = createMessageReference("account", 1, "uid");
- MessageReference messageReferenceTwo = createMessageReference("account", 1, "uid");
-
- assertEqualsReturnsTrueSymmetrically(messageReferenceOne, messageReferenceTwo);
- }
-
- @Test
- public void equalsWithMessageReferenceContainingDifferentAccountUuidShouldReturnFalse() {
- MessageReference messageReferenceOne = createMessageReference("account", 1, "uid");
- MessageReference messageReferenceTwo = createMessageReference("-------", 1, "uid");
-
- assertEqualsReturnsFalseSymmetrically(messageReferenceOne, messageReferenceTwo);
- }
-
- @Test
- public void equalsWithMessageReferenceContainingDifferentFolderNameShouldReturnFalse() {
- MessageReference messageReferenceOne = createMessageReference("account", 1, "uid");
- MessageReference messageReferenceTwo = createMessageReference("account", 8, "uid");
-
- assertEqualsReturnsFalseSymmetrically(messageReferenceOne, messageReferenceTwo);
- }
-
- @Test
- public void equalsWithMessageReferenceContainingDifferentUidShouldReturnFalse() {
- MessageReference messageReferenceOne = createMessageReference("account", 1, "uid");
- MessageReference messageReferenceTwo = createMessageReference("account", 1, "---");
-
- assertEqualsReturnsFalseSymmetrically(messageReferenceOne, messageReferenceTwo);
- }
-
- @Test
- public void alternativeEquals() {
- MessageReference messageReference = createMessageReference("account", 1, "uid");
-
- boolean equalsResult = messageReference.equals("account", 1, "uid");
-
- assertTrue(equalsResult);
- }
-
- @Test
- public void equals_withNullAccount_shouldReturnFalse() {
- MessageReference messageReference = createMessageReference("account", 1, "uid");
-
- boolean equalsResult = messageReference.equals(null, 1, "uid");
-
- assertFalse(equalsResult);
- }
-
- @Test
- public void equals_withNullUid_shouldReturnFalse() {
- MessageReference messageReference = createMessageReference("account", 1, "uid");
-
- boolean equalsResult = messageReference.equals("account", 1, null);
-
- assertFalse(equalsResult);
- }
-
- @Test(expected = NullPointerException.class)
- public void constructor_withNullAccount_shouldThrow() {
- createMessageReference(null, 1, "uid");
- }
-
- @Test(expected = NullPointerException.class)
- public void constructor_withNullUid_shouldThrow() {
- createMessageReference("account", 1, null);
- }
-
- private MessageReference createMessageReference(String accountUuid, long folderId, String uid) {
- return new MessageReference(accountUuid, folderId, uid, null);
- }
-
- private MessageReference createMessageReferenceWithFlag(String accountUuid, long folderId, String uid, Flag flag) {
- return new MessageReference(accountUuid, folderId, uid, flag);
- }
-
- private void assertEqualsReturnsTrueSymmetrically(MessageReference referenceOne, MessageReference referenceTwo) {
- assertTrue(referenceOne.equals(referenceTwo));
- assertTrue(referenceTwo.equals(referenceOne));
- }
-
- private void assertEqualsReturnsFalseSymmetrically(MessageReference referenceOne, MessageReference referenceTwo) {
- assertFalse(referenceOne.equals(referenceTwo));
- assertFalse(referenceTwo.equals(referenceOne));
- }
-}
diff --git a/app/core/src/test/java/com/fsck/k9/controller/MessageReferenceTest.kt b/app/core/src/test/java/com/fsck/k9/controller/MessageReferenceTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..495f053c19eccce707cc5e82bb5e1ef919bc8561
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/controller/MessageReferenceTest.kt
@@ -0,0 +1,61 @@
+package com.fsck.k9.controller
+
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertNotNull
+import org.junit.Test
+
+class MessageReferenceTest {
+ @Test
+ fun checkIdentityStringFromMessageReference() {
+ val messageReference = MessageReference("o hai!", 2, "10101010")
+
+ val serialized = messageReference.toIdentityString()
+
+ assertThat(serialized).isEqualTo("#:byBoYWkh:Mg==:MTAxMDEwMTA=")
+ }
+
+ @Test
+ fun parseIdentityString() {
+ val result = MessageReference.parse("#:byBoYWkh:Mg==:MTAxMDEwMTA=")
+
+ assertNotNull(result) { messageReference ->
+ assertThat(messageReference.accountUuid).isEqualTo("o hai!")
+ assertThat(messageReference.folderId).isEqualTo(2)
+ assertThat(messageReference.uid).isEqualTo("10101010")
+ }
+ }
+
+ @Test
+ fun parseIdentityStringContainingBadVersionNumber() {
+ val messageReference = MessageReference.parse("@:byBoYWkh:MTAxMDEwMTA=")
+
+ assertThat(messageReference).isNull()
+ }
+
+ @Test
+ fun parseNullIdentityString() {
+ val messageReference = MessageReference.parse(null)
+
+ assertThat(messageReference).isNull()
+ }
+
+ @Test
+ fun checkMessageReferenceWithChangedUid() {
+ val messageReferenceOne = MessageReference("account", 1, "uid")
+
+ val messageReference = messageReferenceOne.withModifiedUid("---")
+
+ assertThat(messageReference.accountUuid).isEqualTo("account")
+ assertThat(messageReference.folderId).isEqualTo(1)
+ assertThat(messageReference.uid).isEqualTo("---")
+ }
+
+ @Test
+ fun alternativeEquals() {
+ val messageReference = MessageReference("account", 1, "uid")
+
+ val equalsResult = messageReference.equals("account", 1, "uid")
+
+ assertThat(equalsResult).isTrue()
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java b/app/core/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java
index e810f1d9db821e4b7018845cf7c18131784b5065..e07dfc540ae516960e4296ae551a10e2c9e68b8a 100644
--- a/app/core/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java
+++ b/app/core/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java
@@ -53,14 +53,14 @@ import org.robolectric.shadows.ShadowLog;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -140,6 +140,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
controller = new MessagingController(appContext, notificationController, notificationStrategy,
localStoreProvider, messageCountsProvider, backendManager, preferences, messageStoreManager,
saveMessageDataCreator, Collections.emptyList());
+
configureAccount();
configureBackendManager();
configureLocalStore();
@@ -166,7 +167,6 @@ public class MessagingControllerTest extends K9RobolectricTest {
verify(localFolder).clearAllMessages();
}
-
@Test
public void refreshRemoteSynchronous_shouldCallBackend() throws MessagingException {
controller.refreshFolderListSynchronous(account);
@@ -219,11 +219,11 @@ public class MessagingControllerTest extends K9RobolectricTest {
new Answer() {
@Override
public LocalMessage answer(InvocationOnMock invocation) throws Throwable {
- if (hasFetchedMessage) {
+ if(hasFetchedMessage) {
return localNewMessage2;
- } else {
- return null;
}
+ else
+ return null;
}
}
);
@@ -330,7 +330,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
controller.sendPendingMessagesSynchronous(account);
- verifyZeroInteractions(listener);
+ verifyNoMoreInteractions(listener);
}
@Test
@@ -373,8 +373,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
}
@Test
- public void sendPendingMessagesSynchronous_whenMessageSentSuccesfully_shouldUpdateProgress()
- throws MessagingException {
+ public void sendPendingMessagesSynchronous_whenMessageSentSuccesfully_shouldUpdateProgress() throws MessagingException {
setupAccountWithMessageToSend();
controller.sendPendingMessagesSynchronous(account);
@@ -420,7 +419,7 @@ public class MessagingControllerTest extends K9RobolectricTest {
when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localMessageToSend1));
when(localMessageToSend1.getUid()).thenReturn("localMessageToSend1");
when(localMessageToSend1.getDatabaseId()).thenReturn(42L);
- when(localMessageToSend1.getHeader(K9.IDENTITY_HEADER)).thenReturn(new String[] {});
+ when(localMessageToSend1.getHeader(K9.IDENTITY_HEADER)).thenReturn(new String[]{});
OutboxState outboxState = new OutboxState(SendState.READY, 0, null, 0);
OutboxStateRepository outboxStateRepository = mock(OutboxStateRepository.class);
@@ -442,7 +441,6 @@ public class MessagingControllerTest extends K9RobolectricTest {
ConnectionSecurity.SSL_TLS_REQUIRED, AuthType.PLAIN, "username", "password", null));
account.setOutgoingServerSettings(new ServerSettings(Protocols.SMTP, "host", 465,
ConnectionSecurity.SSL_TLS_REQUIRED, AuthType.PLAIN, "username", "password", null));
-
account.setMaximumAutoDownloadMessageSize(MAXIMUM_SMALL_MESSAGE_SIZE);
account.setEmail("user@host.com");
}
diff --git a/app/core/src/test/java/com/fsck/k9/helper/ReplyToParserTest.java b/app/core/src/test/java/com/fsck/k9/helper/ReplyToParserTest.java
index d612a7413ab2f3c60db27a8e5e2505aaa75b565c..501b2731b965eb759a871ff1604915109a80719d 100644
--- a/app/core/src/test/java/com/fsck/k9/helper/ReplyToParserTest.java
+++ b/app/core/src/test/java/com/fsck/k9/helper/ReplyToParserTest.java
@@ -17,8 +17,8 @@ import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
diff --git a/app/core/src/test/java/com/fsck/k9/logging/LogcatLogFileWriterTest.kt b/app/core/src/test/java/com/fsck/k9/logging/LogcatLogFileWriterTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2fcc6e93ff9ebc590d804dd821a2a79ef2a1b473
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/logging/LogcatLogFileWriterTest.kt
@@ -0,0 +1,85 @@
+package com.fsck.k9.logging
+
+import android.content.ContentResolver
+import android.net.Uri
+import com.google.common.truth.Truth.assertThat
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.FileNotFoundException
+import java.io.IOException
+import java.io.InputStream
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+class LogcatLogFileWriterTest {
+ private val contentUri = mock()
+ private val outputStream = ByteArrayOutputStream()
+
+ @Test
+ fun `write log to contentUri`() = runBlocking {
+ val logData = "a".repeat(10_000)
+ val logFileWriter = LogcatLogFileWriter(
+ contentResolver = createContentResolver(),
+ processExecutor = createProcessExecutor(logData),
+ coroutineDispatcher = Dispatchers.Unconfined
+ )
+
+ logFileWriter.writeLogTo(contentUri)
+
+ assertThat(outputStream.toByteArray().decodeToString()).isEqualTo(logData)
+ }
+
+ @Test(expected = FileNotFoundException::class)
+ fun `contentResolver throws`() = runBlocking {
+ val logFileWriter = LogcatLogFileWriter(
+ contentResolver = createThrowingContentResolver(FileNotFoundException()),
+ processExecutor = createProcessExecutor("irrelevant"),
+ coroutineDispatcher = Dispatchers.Unconfined
+ )
+
+ logFileWriter.writeLogTo(contentUri)
+ }
+
+ @Test(expected = IOException::class)
+ fun `processExecutor throws`() = runBlocking {
+ val logFileWriter = LogcatLogFileWriter(
+ contentResolver = createContentResolver(),
+ processExecutor = ThrowingProcessExecutor(IOException()),
+ coroutineDispatcher = Dispatchers.Unconfined
+ )
+
+ logFileWriter.writeLogTo(contentUri)
+ }
+
+ private fun createContentResolver(): ContentResolver {
+ return mock {
+ on { openOutputStream(contentUri) } doReturn outputStream
+ }
+ }
+
+ private fun createThrowingContentResolver(exception: Exception): ContentResolver {
+ return mock {
+ on { openOutputStream(contentUri) } doAnswer { throw exception }
+ }
+ }
+
+ private fun createProcessExecutor(logData: String): DataProcessExecutor {
+ return DataProcessExecutor(logData.toByteArray(charset = Charsets.US_ASCII))
+ }
+}
+
+private class DataProcessExecutor(val data: ByteArray) : ProcessExecutor {
+ override fun exec(command: String): InputStream {
+ return ByteArrayInputStream(data)
+ }
+}
+
+private class ThrowingProcessExecutor(val exception: Exception) : ProcessExecutor {
+ override fun exec(command: String): InputStream {
+ throw exception
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java b/app/core/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java
index a8b128547d8702331fc5fbd8c4637adadae2967d..563286c8e552601eee6ffb27e46cb7c93c6f08cd 100644
--- a/app/core/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java
+++ b/app/core/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java
@@ -50,7 +50,7 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
diff --git a/app/core/src/test/java/com/fsck/k9/message/IdentityHeaderBuilderTest.kt b/app/core/src/test/java/com/fsck/k9/message/IdentityHeaderBuilderTest.kt
index 6cefafcdee154f26302d6b5f3c0ec2ededd6157f..2be6075663d483c2f0daaf0a17703bfd3f99f70f 100644
--- a/app/core/src/test/java/com/fsck/k9/message/IdentityHeaderBuilderTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/message/IdentityHeaderBuilderTest.kt
@@ -53,4 +53,4 @@ class IdentityHeaderBuilderTest : RobolectricTest() {
): Identity {
return Identity(description, name, email, signature, signatureUse, replyTo)
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/test/java/com/fsck/k9/message/MessageBuilderTest.java b/app/core/src/test/java/com/fsck/k9/message/MessageBuilderTest.java
index f94c6fa39d21a13812523e422876298fa870ce28..267e448b838175f89a82242ecbc3b221fb5b901d 100644
--- a/app/core/src/test/java/com/fsck/k9/message/MessageBuilderTest.java
+++ b/app/core/src/test/java/com/fsck/k9/message/MessageBuilderTest.java
@@ -38,8 +38,8 @@ import org.robolectric.annotation.LooperMode;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
diff --git a/app/core/src/test/java/com/fsck/k9/message/html/HtmlConverterTest.java b/app/core/src/test/java/com/fsck/k9/message/html/HtmlConverterTest.java
index 8dfbbaacdea71b8e48566e33fa78509b5f2d7d18..d7c34f9fb7308985a15fe6559d430baaaebda237 100644
--- a/app/core/src/test/java/com/fsck/k9/message/html/HtmlConverterTest.java
+++ b/app/core/src/test/java/com/fsck/k9/message/html/HtmlConverterTest.java
@@ -306,4 +306,24 @@ public class HtmlConverterTest {
assertEquals("https://domain.example/path/", result);
}
+
+ @Test
+ public void htmlToText_withLineBreaksInHtml() {
+ String input = "One\nTwo\r\nThree";
+
+ String result = HtmlConverter.htmlToText(input);
+
+ assertEquals("One Two Three", result);
+ }
+
+ @Test
+ public void htmlToText_withLongTextLine_shouldNotAddLineBreaksToOutput() {
+ String input = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sit amet finibus felis, " +
+ "viverra ullamcorper justo. Suspendisse potenti. Etiam erat sem, interdum a condimentum quis, " +
+ "fringilla quis orci.";
+
+ String result = HtmlConverter.htmlToText(input);
+
+ assertEquals(input, result);
+ }
}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/AddNotificationResultTest.kt b/app/core/src/test/java/com/fsck/k9/notification/AddNotificationResultTest.kt
index 50a1b3fd1c1f2dbd1c7ca31230367bb41f30588d..e6597aca41fcd3af8a87926d130c46969510b12e 100644
--- a/app/core/src/test/java/com/fsck/k9/notification/AddNotificationResultTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/notification/AddNotificationResultTest.kt
@@ -10,12 +10,11 @@ class AddNotificationResultTest {
private val notificationHolder = NotificationHolder(
notificationId = NOTIFICATION_ID,
content = NotificationContent(
- messageReference = MessageReference("irrelevant", 1, "irrelevant", null),
+ messageReference = MessageReference("irrelevant", 1, "irrelevant"),
sender = "irrelevant",
subject = "irrelevant",
preview = "irrelevant",
- summary = "irrelevant",
- isStarred = false
+ summary = "irrelevant"
)
)
@@ -48,7 +47,6 @@ class AddNotificationResultTest {
}
@Test
-
fun getNotificationHolder_shouldReturnNotificationHolder() {
val result = AddNotificationResult.replaceNotification(notificationHolder)
diff --git a/app/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f53b9fae77d77f6e004c1d1c272b29a3de77df59
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/AuthenticationErrorNotificationControllerTest.kt
@@ -0,0 +1,110 @@
+package com.fsck.k9.notification
+
+import android.app.Notification
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.test.core.app.ApplicationProvider
+import com.fsck.k9.Account
+import com.fsck.k9.RobolectricTest
+import com.fsck.k9.testing.MockHelper.mockBuilder
+import org.junit.Test
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+private const val INCOMING = true
+private const val OUTGOING = false
+private const val ACCOUNT_NUMBER = 1
+private const val ACCOUNT_NAME = "TestAccount"
+
+class AuthenticationErrorNotificationControllerTest : RobolectricTest() {
+ private val resourceProvider = TestNotificationResourceProvider()
+ private val notification = mock()
+ private val notificationManager = mock()
+ private val builder = createFakeNotificationBuilder(notification)
+ private val notificationHelper = createFakeNotificationHelper(notificationManager, builder)
+ private val account = createFakeAccount()
+ private val controller = TestAuthenticationErrorNotificationController()
+ private val contentIntent = mock()
+
+ @Test
+ fun showAuthenticationErrorNotification_withIncomingServer_shouldCreateNotification() {
+ val notificationId = NotificationIds.getAuthenticationErrorNotificationId(account, INCOMING)
+
+ controller.showAuthenticationErrorNotification(account, INCOMING)
+
+ verify(notificationManager).notify(notificationId, notification)
+ assertAuthenticationErrorNotificationContents()
+ }
+
+ @Test
+ fun clearAuthenticationErrorNotification_withIncomingServer_shouldCancelNotification() {
+ val notificationId = NotificationIds.getAuthenticationErrorNotificationId(account, INCOMING)
+
+ controller.clearAuthenticationErrorNotification(account, INCOMING)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ @Test
+ fun showAuthenticationErrorNotification_withOutgoingServer_shouldCreateNotification() {
+ val notificationId = NotificationIds.getAuthenticationErrorNotificationId(account, OUTGOING)
+
+ controller.showAuthenticationErrorNotification(account, OUTGOING)
+
+ verify(notificationManager).notify(notificationId, notification)
+ assertAuthenticationErrorNotificationContents()
+ }
+
+ @Test
+ fun clearAuthenticationErrorNotification_withOutgoingServer_shouldCancelNotification() {
+ val notificationId = NotificationIds.getAuthenticationErrorNotificationId(account, OUTGOING)
+
+ controller.clearAuthenticationErrorNotification(account, OUTGOING)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ private fun assertAuthenticationErrorNotificationContents() {
+ verify(builder).setSmallIcon(resourceProvider.iconWarning)
+ verify(builder).setTicker("Authentication failed")
+ verify(builder).setContentTitle("Authentication failed")
+ verify(builder).setContentText("Authentication failed for $ACCOUNT_NAME. Update your server settings.")
+ verify(builder).setContentIntent(contentIntent)
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ private fun createFakeNotificationBuilder(notification: Notification): NotificationCompat.Builder {
+ return mockBuilder {
+ on { build() } doReturn notification
+ }
+ }
+
+ private fun createFakeNotificationHelper(
+ notificationManager: NotificationManagerCompat,
+ builder: NotificationCompat.Builder
+ ): NotificationHelper {
+ return mock {
+ on { getContext() } doReturn ApplicationProvider.getApplicationContext()
+ on { getNotificationManager() } doReturn notificationManager
+ on { createNotificationBuilder(any(), any()) } doReturn builder
+ }
+ }
+
+ private fun createFakeAccount(): Account {
+ return mock {
+ on { accountNumber } doReturn ACCOUNT_NUMBER
+ on { description } doReturn ACCOUNT_NAME
+ }
+ }
+
+ internal inner class TestAuthenticationErrorNotificationController :
+ AuthenticationErrorNotificationController(notificationHelper, mock(), resourceProvider) {
+
+ override fun createContentIntent(account: Account, incoming: Boolean): PendingIntent {
+ return contentIntent
+ }
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt b/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..772dc2b96daa483244d6f4bebf1534b244dc1c4e
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/BaseNotificationDataCreatorTest.kt
@@ -0,0 +1,197 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.Identity
+import com.fsck.k9.K9
+import com.fsck.k9.K9.LockScreenNotificationVisibility
+import com.fsck.k9.NotificationSetting
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.mockito.kotlin.mock
+
+class BaseNotificationDataCreatorTest {
+ private val account = createAccount()
+ private val notificationDataCreator = BaseNotificationDataCreator()
+
+ @Test
+ fun `account instance`() {
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.account).isSameInstanceAs(account)
+ }
+
+ @Test
+ fun `account name from description property`() {
+ account.description = "description"
+ account.email = "irrelevant@k9mail.example"
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.accountName).isEqualTo("description")
+ }
+
+ @Test
+ fun `account description is blank`() {
+ account.description = ""
+ account.email = "test@k9mail.example"
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.accountName).isEqualTo("test@k9mail.example")
+ }
+
+ @Test
+ fun `account description is null`() {
+ account.description = null
+ account.email = "test@k9mail.example"
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.accountName).isEqualTo("test@k9mail.example")
+ }
+
+ @Test
+ fun `group key`() {
+ account.accountNumber = 42
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.groupKey).isEqualTo("newMailNotifications-42")
+ }
+
+ @Test
+ fun `notification color`() {
+ account.chipColor = 0xFF0000
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.color).isEqualTo(0xFF0000)
+ }
+
+ @Test
+ fun `new messages count`() {
+ val notificationData = createNotificationData(senders = listOf("irrelevant", "irrelevant"))
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.newMessagesCount).isEqualTo(2)
+ }
+
+ @Test
+ fun `do not display notification on lock screen`() {
+ setLockScreenMode(LockScreenNotificationVisibility.NOTHING)
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.lockScreenNotificationData).isEqualTo(LockScreenNotificationData.None)
+ }
+
+ @Test
+ fun `display application name on lock screen`() {
+ setLockScreenMode(LockScreenNotificationVisibility.APP_NAME)
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.lockScreenNotificationData).isEqualTo(LockScreenNotificationData.AppName)
+ }
+
+ @Test
+ fun `display new message count on lock screen`() {
+ setLockScreenMode(LockScreenNotificationVisibility.MESSAGE_COUNT)
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.lockScreenNotificationData).isEqualTo(LockScreenNotificationData.MessageCount)
+ }
+
+ @Test
+ fun `display message sender names on lock screen`() {
+ setLockScreenMode(LockScreenNotificationVisibility.SENDERS)
+ val notificationData = createNotificationData(senders = listOf("Sender One", "Sender Two", "Sender Three"))
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.lockScreenNotificationData).isInstanceOf(LockScreenNotificationData.SenderNames::class.java)
+ val senderNamesData = result.lockScreenNotificationData as LockScreenNotificationData.SenderNames
+ assertThat(senderNamesData.senderNames).isEqualTo("Sender Three, Sender Two, Sender One")
+ }
+
+ @Test
+ fun `display notification on lock screen`() {
+ setLockScreenMode(LockScreenNotificationVisibility.EVERYTHING)
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.lockScreenNotificationData).isEqualTo(LockScreenNotificationData.Public)
+ }
+
+ @Test
+ fun ringtone() {
+ account.notificationSetting.ringtone = "content://ringtone/1"
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.appearance.ringtone).isEqualTo("content://ringtone/1")
+ }
+
+ @Test
+ fun `vibration pattern`() {
+ account.notificationSetting.vibratePattern = 3
+ account.notificationSetting.vibrateTimes = 2
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.appearance.vibrationPattern).isEqualTo(NotificationSetting.getVibration(3, 2))
+ }
+
+ @Test
+ fun `led color`() {
+ account.notificationSetting.ledColor = 0x00FF00
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createBaseNotificationData(notificationData)
+
+ assertThat(result.appearance.ledColor).isEqualTo(0x00FF00)
+ }
+
+ private fun setLockScreenMode(mode: LockScreenNotificationVisibility) {
+ K9.lockScreenNotificationVisibility = mode
+ }
+
+ private fun createNotificationData(senders: List = emptyList()): NotificationData {
+ val notificationData = NotificationData(account)
+ for (sender in senders) {
+ notificationData.addNotificationContent(
+ NotificationContent(
+ messageReference = mock(),
+ sender = sender,
+ preview = "irrelevant",
+ summary = "irrelevant",
+ subject = "irrelevant"
+ )
+ )
+ }
+ return notificationData
+ }
+
+ private fun createAccount(): Account {
+ return Account("00000000-0000-4000-0000-000000000000").apply {
+ description = "account name"
+ identities = listOf(Identity())
+ notificationSetting.vibrateTimes = 1
+ }
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ea55fd8044cf572903a213354808632c3dc35986
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/CertificateErrorNotificationControllerTest.kt
@@ -0,0 +1,111 @@
+package com.fsck.k9.notification
+
+import android.app.Notification
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.test.core.app.ApplicationProvider
+import com.fsck.k9.Account
+import com.fsck.k9.RobolectricTest
+import com.fsck.k9.testing.MockHelper.mockBuilder
+import org.junit.Test
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+private const val INCOMING = true
+private const val OUTGOING = false
+private const val ACCOUNT_NUMBER = 1
+private const val ACCOUNT_NAME = "TestAccount"
+
+class CertificateErrorNotificationControllerTest : RobolectricTest() {
+ private val resourceProvider: NotificationResourceProvider = TestNotificationResourceProvider()
+ private val notification = mock()
+ private val notificationManager = mock()
+ private val builder = createFakeNotificationBuilder(notification)
+ private val notificationHelper = createFakeNotificationHelper(notificationManager, builder)
+ private val account = createFakeAccount()
+ private val controller = TestCertificateErrorNotificationController()
+ private val contentIntent = mock()
+
+ @Test
+ fun testShowCertificateErrorNotificationForIncomingServer() {
+ val notificationId = NotificationIds.getCertificateErrorNotificationId(account, INCOMING)
+
+ controller.showCertificateErrorNotification(account, INCOMING)
+
+ verify(notificationManager).notify(notificationId, notification)
+ assertCertificateErrorNotificationContents()
+ }
+
+ @Test
+ fun testClearCertificateErrorNotificationsForIncomingServer() {
+ val notificationId = NotificationIds.getCertificateErrorNotificationId(account, INCOMING)
+
+ controller.clearCertificateErrorNotifications(account, INCOMING)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ @Test
+ fun testShowCertificateErrorNotificationForOutgoingServer() {
+ val notificationId = NotificationIds.getCertificateErrorNotificationId(account, OUTGOING)
+
+ controller.showCertificateErrorNotification(account, OUTGOING)
+
+ verify(notificationManager).notify(notificationId, notification)
+ assertCertificateErrorNotificationContents()
+ }
+
+ @Test
+ fun testClearCertificateErrorNotificationsForOutgoingServer() {
+ val notificationId = NotificationIds.getCertificateErrorNotificationId(account, OUTGOING)
+
+ controller.clearCertificateErrorNotifications(account, OUTGOING)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ private fun assertCertificateErrorNotificationContents() {
+ verify(builder).setSmallIcon(resourceProvider.iconWarning)
+ verify(builder).setTicker("Certificate error for $ACCOUNT_NAME")
+ verify(builder).setContentTitle("Certificate error for $ACCOUNT_NAME")
+ verify(builder).setContentText("Check your server settings")
+ verify(builder).setContentIntent(contentIntent)
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ private fun createFakeNotificationBuilder(notification: Notification): NotificationCompat.Builder {
+ return mockBuilder {
+ on { build() } doReturn notification
+ }
+ }
+
+ private fun createFakeNotificationHelper(
+ notificationManager: NotificationManagerCompat,
+ builder: NotificationCompat.Builder
+ ): NotificationHelper {
+ return mock {
+ on { getContext() } doReturn ApplicationProvider.getApplicationContext()
+ on { getNotificationManager() } doReturn notificationManager
+ on { createNotificationBuilder(any(), any()) } doReturn builder
+ }
+ }
+
+ private fun createFakeAccount(): Account {
+ return mock {
+ on { accountNumber } doReturn ACCOUNT_NUMBER
+ on { description } doReturn ACCOUNT_NAME
+ on { uuid } doReturn "test-uuid"
+ }
+ }
+
+ internal inner class TestCertificateErrorNotificationController : CertificateErrorNotificationController(
+ notificationHelper, mock(), resourceProvider
+ ) {
+ override fun createContentIntent(account: Account, incoming: Boolean): PendingIntent {
+ return contentIntent
+ }
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/LockScreenNotificationCreatorTest.kt b/app/core/src/test/java/com/fsck/k9/notification/LockScreenNotificationCreatorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f92ec2a8662769c88ba96d5725eca65c37fec990
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/LockScreenNotificationCreatorTest.kt
@@ -0,0 +1,116 @@
+package com.fsck.k9.notification
+
+import androidx.core.app.NotificationCompat
+import androidx.test.core.app.ApplicationProvider
+import com.fsck.k9.Account
+import com.fsck.k9.RobolectricTest
+import com.fsck.k9.testing.MockHelper.mockBuilder
+import org.junit.Test
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+class LockScreenNotificationCreatorTest : RobolectricTest() {
+ private val account = Account("00000000-0000-0000-0000-000000000000")
+ private val resourceProvider = TestNotificationResourceProvider()
+ private val builder = createFakeNotificationBuilder()
+ private val publicBuilder = createFakeNotificationBuilder()
+ private var notificationCreator = LockScreenNotificationCreator(
+ notificationHelper = createFakeNotificationHelper(publicBuilder),
+ resourceProvider = resourceProvider
+ )
+
+ @Test
+ fun `no lock screen notification`() {
+ val baseNotificationData = createBaseNotificationData(LockScreenNotificationData.None)
+
+ notificationCreator.configureLockScreenNotification(builder, baseNotificationData)
+
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_SECRET)
+ }
+
+ @Test
+ fun `app name`() {
+ val baseNotificationData = createBaseNotificationData(LockScreenNotificationData.AppName)
+
+ notificationCreator.configureLockScreenNotification(builder, baseNotificationData)
+
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
+ }
+
+ @Test
+ fun `regular notification on lock screen`() {
+ val baseNotificationData = createBaseNotificationData(LockScreenNotificationData.Public)
+
+ notificationCreator.configureLockScreenNotification(builder, baseNotificationData)
+
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ @Test
+ fun `list of sender names`() {
+ val baseNotificationData = createBaseNotificationData(
+ lockScreenNotificationData = LockScreenNotificationData.SenderNames("Alice, Bob"),
+ newMessagesCount = 2
+ )
+
+ notificationCreator.configureLockScreenNotification(builder, baseNotificationData)
+
+ verify(publicBuilder).setSmallIcon(resourceProvider.iconNewMail)
+ verify(publicBuilder).setNumber(2)
+ verify(publicBuilder).setContentTitle("2 new messages")
+ verify(publicBuilder).setContentText("Alice, Bob")
+ verify(builder).setPublicVersion(publicBuilder.build())
+ }
+
+ @Test
+ fun `new message count`() {
+ val baseNotificationData = createBaseNotificationData(
+ lockScreenNotificationData = LockScreenNotificationData.MessageCount,
+ accountName = "Account name",
+ newMessagesCount = 23
+ )
+
+ notificationCreator.configureLockScreenNotification(builder, baseNotificationData)
+
+ verify(publicBuilder).setSmallIcon(resourceProvider.iconNewMail)
+ verify(publicBuilder).setNumber(23)
+ verify(publicBuilder).setContentTitle("23 new messages")
+ verify(publicBuilder).setContentText("Account name")
+ verify(builder).setPublicVersion(publicBuilder.build())
+ }
+
+ private fun createFakeNotificationBuilder(): NotificationCompat.Builder {
+ return mockBuilder {
+ on { build() } doReturn mock()
+ }
+ }
+
+ private fun createFakeNotificationHelper(builder: NotificationCompat.Builder): NotificationHelper {
+ return mock {
+ on { getContext() } doReturn ApplicationProvider.getApplicationContext()
+ on { createNotificationBuilder(any(), any()) } doReturn builder
+ }
+ }
+
+ private fun createBaseNotificationData(
+ lockScreenNotificationData: LockScreenNotificationData,
+ accountName: String = "irrelevant",
+ newMessagesCount: Int = 0
+ ): BaseNotificationData {
+ return BaseNotificationData(
+ account = account,
+ accountName = accountName,
+ groupKey = "irrelevant",
+ color = 0,
+ newMessagesCount = newMessagesCount,
+ lockScreenNotificationData = lockScreenNotificationData,
+ appearance = NotificationAppearance(
+ ringtone = null,
+ vibrationPattern = longArrayOf(),
+ ledColor = 0
+ )
+ )
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..085043eaaf278d450bc6fe4a6b2e441b11be74fa
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/NewMailNotificationManagerTest.kt
@@ -0,0 +1,291 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.TestClock
+import com.fsck.k9.controller.MessageReference
+import com.fsck.k9.mailstore.LocalMessage
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertNotNull
+import org.junit.Test
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stubbing
+
+private const val ACCOUNT_UUID = "00000000-0000-4000-0000-000000000000"
+private const val ACCOUNT_NAME = "Personal"
+private const val ACCOUNT_COLOR = 0xFF112233L.toInt()
+private const val FOLDER_ID = 42L
+private const val TIMESTAMP = 23L
+
+class NewMailNotificationManagerTest {
+ private val account = createAccount()
+ private val notificationContentCreator = mock()
+ private val clock = TestClock(TIMESTAMP)
+ private val manager = NewMailNotificationManager(
+ notificationContentCreator,
+ BaseNotificationDataCreator(),
+ SingleMessageNotificationDataCreator(),
+ SummaryNotificationDataCreator(SingleMessageNotificationDataCreator()),
+ clock
+ )
+
+ @Test
+ fun `add first notification`() {
+ val message = addMessageToNotificationContentCreator(
+ sender = "sender",
+ subject = "subject",
+ preview = "preview",
+ summary = "summary",
+ messageUid = "msg-1"
+ )
+
+ val result = manager.addNewMailNotification(account, message, silent = false)
+
+ assertThat(result.singleNotificationData.first().content).isEqualTo(
+ NotificationContent(
+ messageReference = createMessageReference("msg-1"),
+ sender = "sender",
+ subject = "subject",
+ preview = "preview",
+ summary = "summary"
+ )
+ )
+ assertThat(result.summaryNotificationData).isInstanceOf(SummarySingleNotificationData::class.java)
+ val summaryNotificationData = result.summaryNotificationData as SummarySingleNotificationData
+ assertThat(summaryNotificationData.singleNotificationData.isSilent).isFalse()
+ }
+
+ @Test
+ fun `add second notification`() {
+ val messageOne = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Hi Bob",
+ preview = "How are you?",
+ summary = "Alice Hi Bob",
+ messageUid = "msg-1"
+ )
+ val messageTwo = addMessageToNotificationContentCreator(
+ sender = "Zoe",
+ subject = "Meeting",
+ preview = "We need to talk",
+ summary = "Zoe Meeting",
+ messageUid = "msg-2"
+ )
+ manager.addNewMailNotification(account, messageOne, silent = false)
+ val timestamp = TIMESTAMP + 1000
+ clock.time = timestamp
+
+ val result = manager.addNewMailNotification(account, messageTwo, silent = false)
+
+ assertThat(result.singleNotificationData.first().content).isEqualTo(
+ NotificationContent(
+ messageReference = createMessageReference("msg-2"),
+ sender = "Zoe",
+ subject = "Meeting",
+ preview = "We need to talk",
+ summary = "Zoe Meeting"
+ )
+ )
+ assertThat(result.baseNotificationData.newMessagesCount).isEqualTo(2)
+ assertThat(result.summaryNotificationData).isInstanceOf(SummaryInboxNotificationData::class.java)
+ val summaryNotificationData = result.summaryNotificationData as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.content).isEqualTo(listOf("Zoe Meeting", "Alice Hi Bob"))
+ assertThat(summaryNotificationData.messageReferences).isEqualTo(
+ listOf(
+ createMessageReference("msg-2"),
+ createMessageReference("msg-1")
+ )
+ )
+ assertThat(summaryNotificationData.additionalMessagesCount).isEqualTo(0)
+ assertThat(summaryNotificationData.isSilent).isFalse()
+ }
+
+ @Test
+ fun `add one more notification when already displaying the maximum number of notifications`() {
+ addMaximumNumberOfNotifications()
+ val message = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Another one",
+ preview = "Are you tired of me yet?",
+ summary = "Alice Another one",
+ messageUid = "msg-x"
+ )
+
+ val result = manager.addNewMailNotification(account, message, silent = false)
+
+ val notificationId = NotificationIds.getSingleMessageNotificationId(account, index = 0)
+ assertThat(result.cancelNotificationIds).isEqualTo(listOf(notificationId))
+ assertThat(result.singleNotificationData.first().notificationId).isEqualTo(notificationId)
+ }
+
+ @Test
+ fun `remove notification when none was added before should return null`() {
+ val result = manager.removeNewMailNotification(account, createMessageReference("any"))
+
+ assertThat(result).isNull()
+ }
+
+ @Test
+ fun `remove notification with untracked notification ID should return null`() {
+ val message = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Another one",
+ preview = "Are you tired of me yet?",
+ summary = "Alice Another one",
+ messageUid = "msg-x"
+ )
+ manager.addNewMailNotification(account, message, silent = false)
+
+ val result = manager.removeNewMailNotification(account, createMessageReference("untracked"))
+
+ assertThat(result).isNull()
+ }
+
+ @Test
+ fun `remove last remaining notification`() {
+ val message = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Hello",
+ preview = "How are you?",
+ summary = "Alice Hello",
+ messageUid = "msg-1"
+ )
+ manager.addNewMailNotification(account, message, silent = false)
+
+ val result = manager.removeNewMailNotification(account, createMessageReference("msg-1"))
+
+ assertNotNull(result) { data ->
+ assertThat(data.cancelNotificationIds).containsExactly(
+ NotificationIds.getNewMailSummaryNotificationId(account),
+ NotificationIds.getSingleMessageNotificationId(account, 0)
+ )
+ assertThat(data.singleNotificationData).isEmpty()
+ assertThat(data.summaryNotificationData).isNull()
+ }
+ }
+
+ @Test
+ fun `remove one of three notifications`() {
+ val messageOne = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "One",
+ preview = "preview",
+ summary = "Alice One",
+ messageUid = "msg-1"
+ )
+ manager.addNewMailNotification(account, messageOne, silent = false)
+ val messageTwo = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Two",
+ preview = "preview",
+ summary = "Alice Two",
+ messageUid = "msg-2"
+ )
+ val dataTwo = manager.addNewMailNotification(account, messageTwo, silent = true)
+ val notificationIdTwo = dataTwo.singleNotificationData.first().notificationId
+ val messageThree = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Three",
+ preview = "preview",
+ summary = "Alice Three",
+ messageUid = "msg-3"
+ )
+ manager.addNewMailNotification(account, messageThree, silent = true)
+
+ val result = manager.removeNewMailNotification(account, createMessageReference("msg-2"))
+
+ assertNotNull(result) { data ->
+ assertThat(data.cancelNotificationIds).isEqualTo(listOf(notificationIdTwo))
+ assertThat(data.singleNotificationData).isEmpty()
+ assertThat(data.baseNotificationData.newMessagesCount).isEqualTo(2)
+ assertThat(data.summaryNotificationData).isInstanceOf(SummaryInboxNotificationData::class.java)
+ val summaryNotificationData = data.summaryNotificationData as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.content).isEqualTo(listOf("Alice Three", "Alice One"))
+ assertThat(summaryNotificationData.messageReferences).isEqualTo(
+ listOf(
+ createMessageReference("msg-3"),
+ createMessageReference("msg-1")
+ )
+ )
+ }
+ }
+
+ @Test
+ fun `remove notification when additional notifications are available`() {
+ val message = addMessageToNotificationContentCreator(
+ sender = "Alice",
+ subject = "Another one",
+ preview = "Are you tired of me yet?",
+ summary = "Alice Another one",
+ messageUid = "msg-restore"
+ )
+ manager.addNewMailNotification(account, message, silent = false)
+ addMaximumNumberOfNotifications()
+
+ val result = manager.removeNewMailNotification(account, createMessageReference("msg-1"))
+
+ assertNotNull(result) { data ->
+ assertThat(data.cancelNotificationIds).hasSize(1)
+ assertThat(data.baseNotificationData.newMessagesCount)
+ .isEqualTo(NotificationData.MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS)
+
+ val singleNotificationData = data.singleNotificationData.first()
+ assertThat(singleNotificationData.notificationId).isEqualTo(data.cancelNotificationIds.first())
+ assertThat(singleNotificationData.isSilent).isTrue()
+ assertThat(singleNotificationData.content).isEqualTo(
+ NotificationContent(
+ messageReference = createMessageReference("msg-restore"),
+ sender = "Alice",
+ subject = "Another one",
+ preview = "Are you tired of me yet?",
+ summary = "Alice Another one"
+ )
+ )
+ }
+ }
+
+ private fun createAccount(): Account {
+ return Account(ACCOUNT_UUID).apply {
+ description = ACCOUNT_NAME
+ chipColor = ACCOUNT_COLOR
+ notificationSetting.vibrateTimes = 1
+ }
+ }
+
+ private fun addMaximumNumberOfNotifications() {
+ repeat(NotificationData.MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS) { index ->
+ val message = addMessageToNotificationContentCreator(
+ sender = "sender",
+ subject = "subject",
+ preview = "preview",
+ summary = "summary",
+ messageUid = "msg-$index"
+ )
+ manager.addNewMailNotification(account, message, silent = true)
+ }
+ }
+
+ private fun addMessageToNotificationContentCreator(
+ sender: String,
+ subject: String,
+ preview: String,
+ summary: String,
+ messageUid: String
+ ): LocalMessage {
+ val message = mock()
+
+ stubbing(notificationContentCreator) {
+ on { createFromMessage(account, message) } doReturn
+ NotificationContent(
+ messageReference = createMessageReference(messageUid),
+ sender, subject, preview, summary
+ )
+ }
+
+ return message
+ }
+
+ private fun createMessageReference(messageUid: String): MessageReference {
+ return MessageReference(ACCOUNT_UUID, FOLDER_ID, messageUid)
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt b/app/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt
index 17a5aceebb2e10aa7b41c9681fe027c9069943dd..c706443137b72cee6e002e7857d4b386697c7ebc 100644
--- a/app/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/notification/NotificationContentCreatorTest.kt
@@ -5,7 +5,6 @@ import com.fsck.k9.Account
import com.fsck.k9.RobolectricTest
import com.fsck.k9.controller.MessageReference
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.message.extractors.PreviewResult.PreviewType
@@ -42,7 +41,6 @@ class NotificationContentCreatorTest : RobolectricTest() {
assertThat(content.subject).isEqualTo(SUBJECT)
assertThat(content.preview.toString()).isEqualTo("$SUBJECT\n$PREVIEW")
assertThat(content.summary.toString()).isEqualTo("$SENDER_NAME $SUBJECT")
- assertThat(content.isStarred).isFalse()
}
@Test
@@ -50,7 +48,9 @@ class NotificationContentCreatorTest : RobolectricTest() {
stubbing(message) {
on { subject } doReturn null
}
+
val content = contentCreator.createFromMessage(account, message)
+
assertThat(content.subject).isEqualTo("(No subject)")
assertThat(content.preview.toString()).isEqualTo(PREVIEW)
assertThat(content.summary.toString()).isEqualTo("$SENDER_NAME (No subject)")
@@ -62,7 +62,9 @@ class NotificationContentCreatorTest : RobolectricTest() {
on { previewType } doReturn PreviewType.NONE
on { preview } doReturn null
}
+
val content = contentCreator.createFromMessage(account, message)
+
assertThat(content.subject).isEqualTo(SUBJECT)
assertThat(content.preview.toString()).isEqualTo(SUBJECT)
}
@@ -73,7 +75,9 @@ class NotificationContentCreatorTest : RobolectricTest() {
on { previewType } doReturn PreviewType.ERROR
on { preview } doReturn null
}
+
val content = contentCreator.createFromMessage(account, message)
+
assertThat(content.subject).isEqualTo(SUBJECT)
assertThat(content.preview.toString()).isEqualTo(SUBJECT)
}
@@ -84,7 +88,9 @@ class NotificationContentCreatorTest : RobolectricTest() {
on { previewType } doReturn PreviewType.ENCRYPTED
on { preview } doReturn null
}
+
val content = contentCreator.createFromMessage(account, message)
+
assertThat(content.subject).isEqualTo(SUBJECT)
assertThat(content.preview.toString()).isEqualTo("$SUBJECT\n*Encrypted*")
}
@@ -94,7 +100,9 @@ class NotificationContentCreatorTest : RobolectricTest() {
stubbing(message) {
on { from } doReturn null
}
+
val content = contentCreator.createFromMessage(account, message)
+
assertThat(content.sender).isEqualTo("No sender")
assertThat(content.summary.toString()).isEqualTo(SUBJECT)
}
@@ -111,15 +119,6 @@ class NotificationContentCreatorTest : RobolectricTest() {
assertThat(content.summary.toString()).isEqualTo("To:Bob $SUBJECT")
}
- @Test
- fun createFromMessage_withStarredMessage() {
- stubbing(message) {
- on { isSet(Flag.FLAGGED) } doReturn true
- }
- val content = contentCreator.createFromMessage(account, message)
- assertThat(content.isStarred).isTrue()
- }
-
@Test
fun createFromMessage_withoutEmptyMessage() {
stubbing(message) {
@@ -144,7 +143,7 @@ class NotificationContentCreatorTest : RobolectricTest() {
private fun createFakeAccount(): Account = mock()
private fun createMessageReference(): MessageReference {
- return MessageReference(ACCOUNT_UUID, FOLDER_ID, UID, null)
+ return MessageReference(ACCOUNT_UUID, FOLDER_ID, UID)
}
private fun createFakeLocalMessage(messageReference: MessageReference): LocalMessage {
@@ -158,4 +157,3 @@ class NotificationContentCreatorTest : RobolectricTest() {
}
}
}
-
diff --git a/app/core/src/test/java/com/fsck/k9/notification/NotificationDataTest.kt b/app/core/src/test/java/com/fsck/k9/notification/NotificationDataTest.kt
index 989048e5f8801250d527cc7bb421b6bfe51a81dd..03310ddc727be75ef761f7b71492352c6f1076e4 100644
--- a/app/core/src/test/java/com/fsck/k9/notification/NotificationDataTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/notification/NotificationDataTest.kt
@@ -15,7 +15,7 @@ private const val FOLDER_ID = 42L
class NotificationDataTest : RobolectricTest() {
private val account = createFakeAccount()
- private val notificationData = NotificationData(account, 0)
+ private val notificationData = NotificationData(account)
@Test
fun testAddNotificationContent() {
@@ -28,7 +28,7 @@ class NotificationDataTest : RobolectricTest() {
val holder = result.notificationHolder
assertThat(holder).isNotNull()
- assertThat(holder.notificationId).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 0))
+ assertThat(holder.notificationId).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 0))
assertThat(holder.content).isEqualTo(content)
}
@@ -46,16 +46,18 @@ class NotificationDataTest : RobolectricTest() {
val result = notificationData.addNotificationContent(createNotificationContent("9"))
assertThat(result.shouldCancelNotification).isTrue()
- assertThat(result.notificationId).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 0))
+ assertThat(result.notificationId).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 0))
}
@Test
fun testRemoveNotificationForMessage() {
val content = createNotificationContent("1")
notificationData.addNotificationContent(content)
+
val result = notificationData.removeNotificationForMessage(content.messageReference)
+
assertThat(result.isUnknownNotification).isFalse()
- assertThat(result.notificationId).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 0))
+ assertThat(result.notificationId).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 0))
assertThat(result.shouldCreateNotification).isFalse()
}
@@ -77,17 +79,17 @@ class NotificationDataTest : RobolectricTest() {
val result = notificationData.removeNotificationForMessage(latestContent.messageReference)
assertThat(result.isUnknownNotification).isFalse()
- assertThat(result.notificationId).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 1))
+ assertThat(result.notificationId).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 1))
assertThat(result.shouldCreateNotification).isTrue()
assertNotNull(result.notificationHolder) { holder ->
- assertThat(holder.notificationId).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 1))
+ assertThat(holder.notificationId).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 1))
assertThat(holder.content).isEqualTo(content)
}
}
@Test
fun testRemoveDoesNotLeakNotificationIds() {
- for (i in 1..NotificationData.MAX_NUMBER_OF_STACKED_NOTIFICATIONS + 1) {
+ for (i in 1..NotificationData.MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS + 1) {
val content = createNotificationContent(i.toString())
notificationData.addNotificationContent(content)
notificationData.removeNotificationForMessage(content.messageReference)
@@ -97,55 +99,23 @@ class NotificationDataTest : RobolectricTest() {
@Test
fun testNewMessagesCount() {
assertThat(notificationData.newMessagesCount).isEqualTo(0)
+
val contentOne = createNotificationContent("1")
notificationData.addNotificationContent(contentOne)
assertThat(notificationData.newMessagesCount).isEqualTo(1)
- val contentTwo = createNotificationContent("2")
- notificationData.addNotificationContent(contentTwo)
- assertThat(notificationData.newMessagesCount).isEqualTo(2)
- }
- @Test
- fun testUnreadMessagesCount() {
- val notificationData = NotificationData(account, 42)
- assertThat(notificationData.unreadMessageCount).isEqualTo(42)
- val content = createNotificationContent("1")
- notificationData.addNotificationContent(content)
- assertThat(notificationData.unreadMessageCount).isEqualTo(43)
val contentTwo = createNotificationContent("2")
notificationData.addNotificationContent(contentTwo)
- assertThat(notificationData.unreadMessageCount).isEqualTo(44)
- }
-
- @Test
- fun testContainsStarredMessages() {
- assertThat(notificationData.containsStarredMessages()).isFalse()
- notificationData.addNotificationContent(createNotificationContentForStarredMessage())
- assertThat(notificationData.containsStarredMessages()).isTrue()
- }
-
- @Test
- fun testContainsStarredMessagesWithAdditionalMessages() {
- notificationData.addNotificationContent(createNotificationContent("1"))
- notificationData.addNotificationContent(createNotificationContent("2"))
- notificationData.addNotificationContent(createNotificationContent("3"))
- notificationData.addNotificationContent(createNotificationContent("4"))
- notificationData.addNotificationContent(createNotificationContent("5"))
- notificationData.addNotificationContent(createNotificationContent("6"))
- notificationData.addNotificationContent(createNotificationContent("7"))
- notificationData.addNotificationContent(createNotificationContent("8"))
- assertThat(notificationData.containsStarredMessages()).isFalse()
-
- notificationData.addNotificationContent(createNotificationContentForStarredMessage())
-
- assertThat(notificationData.containsStarredMessages()).isTrue()
+ assertThat(notificationData.newMessagesCount).isEqualTo(2)
}
@Test
fun testIsSingleMessageNotification() {
assertThat(notificationData.isSingleMessageNotification).isFalse()
+
notificationData.addNotificationContent(createNotificationContent("1"))
assertThat(notificationData.isSingleMessageNotification).isTrue()
+
notificationData.addNotificationContent(createNotificationContent("2"))
assertThat(notificationData.isSingleMessageNotification).isFalse()
}
@@ -154,7 +124,9 @@ class NotificationDataTest : RobolectricTest() {
fun testGetHolderForLatestNotification() {
val content = createNotificationContent("1")
val addResult = notificationData.addNotificationContent(content)
+
val holder = notificationData.holderForLatestNotification
+
assertThat(holder).isEqualTo(addResult.notificationHolder)
}
@@ -186,10 +158,12 @@ class NotificationDataTest : RobolectricTest() {
fun testGetActiveNotificationIds() {
notificationData.addNotificationContent(createNotificationContent("1"))
notificationData.addNotificationContent(createNotificationContent("2"))
+
val notificationIds = notificationData.getActiveNotificationIds()
+
assertThat(notificationIds.size).isEqualTo(2)
- assertThat(notificationIds[0]).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 1))
- assertThat(notificationIds[1]).isEqualTo(NotificationIds.getNewMailStackedNotificationId(account, 0))
+ assertThat(notificationIds[0]).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 1))
+ assertThat(notificationIds[1]).isEqualTo(NotificationIds.getSingleMessageNotificationId(account, 0))
}
@Test
@@ -267,7 +241,7 @@ class NotificationDataTest : RobolectricTest() {
}
private fun createMessageReference(uid: String): MessageReference {
- return MessageReference(ACCOUNT_UUID, FOLDER_ID, uid, null)
+ return MessageReference(ACCOUNT_UUID, FOLDER_ID, uid)
}
private fun createNotificationContent(uid: String): NotificationContent {
@@ -276,11 +250,12 @@ class NotificationDataTest : RobolectricTest() {
}
private fun createNotificationContent(messageReference: MessageReference): NotificationContent {
- return NotificationContent(messageReference, "", "", "", "", false)
- }
-
- private fun createNotificationContentForStarredMessage(): NotificationContent {
- val messageReference = createMessageReference("42")
- return NotificationContent(messageReference, "", "", "", "", true)
+ return NotificationContent(
+ messageReference = messageReference,
+ sender = "irrelevant",
+ subject = "irrelevant",
+ preview = "irrelevant",
+ summary = "irrelevant"
+ )
}
-}
\ No newline at end of file
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt b/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt
index 4a39e06dc98720a25ca6a6c56914f87c2f50a013..c9f9dafcd38c575c1967b48cadb0826c962ba1dc 100644
--- a/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/notification/NotificationIdsTest.kt
@@ -94,8 +94,8 @@ class NotificationIdsTest {
NotificationIds.getAuthenticationErrorNotificationId(account, false),
NotificationIds.getFetchingMailNotificationId(account),
NotificationIds.getNewMailSummaryNotificationId(account),
- ) + (0 until NotificationData.MAX_NUMBER_OF_STACKED_NOTIFICATIONS).map { index ->
- NotificationIds.getNewMailStackedNotificationId(account, index)
+ ) + (0 until NotificationData.MAX_NUMBER_OF_NEW_MESSAGE_NOTIFICATIONS).map { index ->
+ NotificationIds.getSingleMessageNotificationId(account, index)
}
}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/RemoveNotificationResultTest.kt b/app/core/src/test/java/com/fsck/k9/notification/RemoveNotificationResultTest.kt
index 2bda81a6098dc6c8a6baaaac0232de9f49a0dde2..ad283570f025259af69d86d646f3e9cc0e01907b 100644
--- a/app/core/src/test/java/com/fsck/k9/notification/RemoveNotificationResultTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/notification/RemoveNotificationResultTest.kt
@@ -13,12 +13,11 @@ class RemoveNotificationResultTest {
private val notificationHolder = NotificationHolder(
notificationId = NOTIFICATION_ID,
content = NotificationContent(
- messageReference = MessageReference("irrelevant", 1, "irrelevant", null),
+ messageReference = MessageReference("irrelevant", 1, "irrelevant"),
sender = "irrelevant",
subject = "irrelevant",
preview = "irrelevant",
- summary = "irrelevant",
- isStarred = false
+ summary = "irrelevant"
)
)
diff --git a/app/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..39611110e3bdaa0665b788a7990cc36e42ddbf59
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/SendFailedNotificationControllerTest.kt
@@ -0,0 +1,86 @@
+package com.fsck.k9.notification
+
+import android.app.Notification
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.test.core.app.ApplicationProvider
+import com.fsck.k9.Account
+import com.fsck.k9.RobolectricTest
+import com.fsck.k9.testing.MockHelper.mockBuilder
+import org.junit.Test
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+
+private const val ACCOUNT_NUMBER = 1
+private const val ACCOUNT_NAME = "TestAccount"
+
+class SendFailedNotificationControllerTest : RobolectricTest() {
+ private val resourceProvider: NotificationResourceProvider = TestNotificationResourceProvider()
+ private val notification = mock()
+ private val notificationManager = mock()
+ private val builder = createFakeNotificationBuilder(notification)
+ private val account = createFakeAccount()
+ private val contentIntent = mock()
+ private val notificationId = NotificationIds.getSendFailedNotificationId(account)
+ private val controller = SendFailedNotificationController(
+ notificationHelper = createFakeNotificationHelper(notificationManager, builder),
+ actionBuilder = createActionBuilder(contentIntent),
+ resourceProvider = resourceProvider
+ )
+
+ @Test
+ fun testShowSendFailedNotification() {
+ val exception = Exception()
+
+ controller.showSendFailedNotification(account, exception)
+
+ verify(notificationManager).notify(notificationId, notification)
+ verify(builder).setSmallIcon(resourceProvider.iconWarning)
+ verify(builder).setTicker("Failed to send some messages")
+ verify(builder).setContentTitle("Failed to send some messages")
+ verify(builder).setContentText("Exception")
+ verify(builder).setContentIntent(contentIntent)
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ @Test
+ fun testClearSendFailedNotification() {
+ controller.clearSendFailedNotification(account)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ private fun createFakeNotificationBuilder(notification: Notification): NotificationCompat.Builder {
+ return mockBuilder {
+ on { build() } doReturn notification
+ }
+ }
+
+ private fun createFakeNotificationHelper(
+ notificationManager: NotificationManagerCompat,
+ builder: NotificationCompat.Builder
+ ): NotificationHelper {
+ return mock {
+ on { getContext() } doReturn ApplicationProvider.getApplicationContext()
+ on { getNotificationManager() } doReturn notificationManager
+ on { createNotificationBuilder(any(), any()) } doReturn builder
+ }
+ }
+
+ private fun createFakeAccount(): Account {
+ return mock {
+ on { accountNumber } doReturn ACCOUNT_NUMBER
+ on { description } doReturn ACCOUNT_NAME
+ }
+ }
+
+ private fun createActionBuilder(contentIntent: PendingIntent): NotificationActionCreator {
+ return mock {
+ on { createViewFolderListPendingIntent(any(), anyInt()) } doReturn contentIntent
+ }
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/SingleMessageNotificationDataCreatorTest.kt b/app/core/src/test/java/com/fsck/k9/notification/SingleMessageNotificationDataCreatorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..499dcf0233539875330cbb22e33b80e39798285d
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/SingleMessageNotificationDataCreatorTest.kt
@@ -0,0 +1,274 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.K9
+import com.fsck.k9.K9.NotificationQuickDelete
+import com.fsck.k9.controller.MessageReference
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class SingleMessageNotificationDataCreatorTest {
+ private val account = createAccount()
+ private val notificationDataCreator = SingleMessageNotificationDataCreator()
+
+ @Test
+ fun `base properties`() {
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 23,
+ content = content,
+ timestamp = 9000,
+ addLockScreenNotification = true
+ )
+
+ assertThat(result.notificationId).isEqualTo(23)
+ assertThat(result.isSilent).isTrue()
+ assertThat(result.timestamp).isEqualTo(9000)
+ assertThat(result.content).isEqualTo(content)
+ assertThat(result.addLockScreenNotification).isTrue()
+ }
+
+ @Test
+ fun `summary notification base properties`() {
+ val content = createNotificationContent()
+ val notificationData = createNotificationData(content)
+
+ val result = notificationDataCreator.createSummarySingleNotificationData(
+ timestamp = 9000,
+ silent = false,
+ data = notificationData
+ )
+
+ assertThat(result.singleNotificationData.notificationId).isEqualTo(
+ NotificationIds.getNewMailSummaryNotificationId(account)
+ )
+ assertThat(result.singleNotificationData.isSilent).isFalse()
+ assertThat(result.singleNotificationData.timestamp).isEqualTo(9000)
+ assertThat(result.singleNotificationData.content).isEqualTo(content)
+ assertThat(result.singleNotificationData.addLockScreenNotification).isFalse()
+ }
+
+ @Test
+ fun `default actions`() {
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.actions).contains(NotificationAction.Reply)
+ assertThat(result.actions).contains(NotificationAction.MarkAsRead)
+ assertThat(result.wearActions).contains(WearNotificationAction.Reply)
+ assertThat(result.wearActions).contains(WearNotificationAction.MarkAsRead)
+ }
+
+ @Test
+ fun `always show delete action without confirmation`() {
+ setDeleteAction(NotificationQuickDelete.ALWAYS)
+ setConfirmDeleteFromNotification(false)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.actions).contains(NotificationAction.Delete)
+ assertThat(result.wearActions).contains(WearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `always show delete action with confirmation`() {
+ setDeleteAction(NotificationQuickDelete.ALWAYS)
+ setConfirmDeleteFromNotification(true)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.actions).contains(NotificationAction.Delete)
+ assertThat(result.wearActions).doesNotContain(WearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `show delete action for single notification without confirmation`() {
+ setDeleteAction(NotificationQuickDelete.FOR_SINGLE_MSG)
+ setConfirmDeleteFromNotification(false)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.actions).contains(NotificationAction.Delete)
+ assertThat(result.wearActions).contains(WearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `show delete action for single notification with confirmation`() {
+ setDeleteAction(NotificationQuickDelete.FOR_SINGLE_MSG)
+ setConfirmDeleteFromNotification(true)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.actions).contains(NotificationAction.Delete)
+ assertThat(result.wearActions).doesNotContain(WearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `never show delete action`() {
+ setDeleteAction(NotificationQuickDelete.NEVER)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.actions).doesNotContain(NotificationAction.Delete)
+ assertThat(result.wearActions).doesNotContain(WearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `archive action with archive folder`() {
+ account.archiveFolderId = 1
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.wearActions).contains(WearNotificationAction.Archive)
+ }
+
+ @Test
+ fun `archive action without archive folder`() {
+ account.archiveFolderId = null
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.wearActions).doesNotContain(WearNotificationAction.Archive)
+ }
+
+ @Test
+ fun `spam action with spam folder and without spam confirmation`() {
+ account.spamFolderId = 1
+ setConfirmSpam(false)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.wearActions).contains(WearNotificationAction.Spam)
+ }
+
+ @Test
+ fun `spam action with spam folder and with spam confirmation`() {
+ account.spamFolderId = 1
+ setConfirmSpam(true)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.wearActions).doesNotContain(WearNotificationAction.Spam)
+ }
+
+ @Test
+ fun `spam action without spam folder and without spam confirmation`() {
+ account.spamFolderId = null
+ setConfirmSpam(false)
+ val content = createNotificationContent()
+
+ val result = notificationDataCreator.createSingleNotificationData(
+ account = account,
+ notificationId = 0,
+ content = content,
+ timestamp = 0,
+ addLockScreenNotification = false
+ )
+
+ assertThat(result.wearActions).doesNotContain(WearNotificationAction.Spam)
+ }
+
+ private fun setDeleteAction(mode: NotificationQuickDelete) {
+ K9.notificationQuickDeleteBehaviour = mode
+ }
+
+ private fun setConfirmDeleteFromNotification(confirm: Boolean) {
+ K9.isConfirmDeleteFromNotification = confirm
+ }
+
+ private fun setConfirmSpam(confirm: Boolean) {
+ K9.isConfirmSpam = confirm
+ }
+
+ private fun createAccount(): Account {
+ return Account("00000000-0000-0000-0000-000000000000").apply {
+ accountNumber = 42
+ }
+ }
+
+ private fun createNotificationContent() = NotificationContent(
+ messageReference = MessageReference("irrelevant", 1, "irrelevant"),
+ sender = "irrelevant",
+ subject = "irrelevant",
+ preview = "irrelevant",
+ summary = "irrelevant"
+ )
+
+ private fun createNotificationData(content: NotificationContent): NotificationData {
+ return NotificationData(account).apply {
+ addNotificationContent(content)
+ }
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt b/app/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..39e78c465b3cab76b2d11f1a9a2b23d25272b498
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/SummaryNotificationDataCreatorTest.kt
@@ -0,0 +1,289 @@
+package com.fsck.k9.notification
+
+import com.fsck.k9.Account
+import com.fsck.k9.Clock
+import com.fsck.k9.K9
+import com.fsck.k9.TestClock
+import com.fsck.k9.controller.MessageReference
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.koin.core.context.startKoin
+import org.koin.core.context.stopKoin
+import org.koin.dsl.module
+
+class SummaryNotificationDataCreatorTest {
+ private val account = createAccount()
+ private val notificationDataCreator = SummaryNotificationDataCreator(SingleMessageNotificationDataCreator())
+
+ @Before
+ fun setUp() {
+ startKoin {
+ modules(
+ module {
+ single { TestClock() }
+ }
+ )
+ }
+ }
+
+ @After
+ fun tearDown() {
+ stopKoin()
+ setQuietTime(false)
+ }
+
+ @Test
+ fun `single new message`() {
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = false
+ )
+
+ assertThat(result).isInstanceOf(SummarySingleNotificationData::class.java)
+ }
+
+ @Test
+ fun `single notification during quiet time`() {
+ setQuietTime(true)
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = false
+ )
+
+ val summaryNotificationData = result as SummarySingleNotificationData
+ assertThat(summaryNotificationData.singleNotificationData.isSilent).isTrue()
+ }
+
+ @Test
+ fun `single notification with quiet time disabled`() {
+ setQuietTime(false)
+ val notificationData = createNotificationData()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = false
+ )
+
+ val summaryNotificationData = result as SummarySingleNotificationData
+ assertThat(summaryNotificationData.singleNotificationData.isSilent).isFalse()
+ }
+
+ @Test
+ fun `inbox-style notification during quiet time`() {
+ setQuietTime(true)
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = false
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.isSilent).isTrue()
+ }
+
+ @Test
+ fun `inbox-style notification with quiet time disabled`() {
+ setQuietTime(false)
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = false
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.isSilent).isFalse()
+ }
+
+ @Test
+ fun `inbox-style base properties`() {
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.notificationId).isEqualTo(
+ NotificationIds.getNewMailSummaryNotificationId(account)
+ )
+ assertThat(summaryNotificationData.isSilent).isTrue()
+ assertThat(summaryNotificationData.timestamp).isEqualTo(9000)
+ }
+
+ @Test
+ fun `default actions`() {
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.actions).contains(SummaryNotificationAction.MarkAsRead)
+ assertThat(summaryNotificationData.wearActions).contains(SummaryWearNotificationAction.MarkAsRead)
+ }
+
+ @Test
+ fun `always show delete action without confirmation`() {
+ setDeleteAction(K9.NotificationQuickDelete.ALWAYS)
+ setConfirmDeleteFromNotification(false)
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.actions).contains(SummaryNotificationAction.Delete)
+ assertThat(summaryNotificationData.wearActions).contains(SummaryWearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `always show delete action with confirmation`() {
+ setDeleteAction(K9.NotificationQuickDelete.ALWAYS)
+ setConfirmDeleteFromNotification(true)
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.actions).contains(SummaryNotificationAction.Delete)
+ assertThat(summaryNotificationData.wearActions).doesNotContain(SummaryWearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `show delete action for single notification without confirmation`() {
+ setDeleteAction(K9.NotificationQuickDelete.FOR_SINGLE_MSG)
+ setConfirmDeleteFromNotification(false)
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.actions).doesNotContain(SummaryNotificationAction.Delete)
+ assertThat(summaryNotificationData.wearActions).doesNotContain(SummaryWearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `never show delete action`() {
+ setDeleteAction(K9.NotificationQuickDelete.NEVER)
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.actions).doesNotContain(SummaryNotificationAction.Delete)
+ assertThat(summaryNotificationData.wearActions).doesNotContain(SummaryWearNotificationAction.Delete)
+ }
+
+ @Test
+ fun `archive action with archive folder`() {
+ account.archiveFolderId = 1
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.wearActions).contains(SummaryWearNotificationAction.Archive)
+ }
+
+ @Test
+ fun `archive action without archive folder`() {
+ account.archiveFolderId = null
+ val notificationData = createNotificationDataWithMultipleMessages()
+
+ val result = notificationDataCreator.createSummaryNotificationData(
+ notificationData,
+ timestamp = 9000,
+ silent = true
+ )
+
+ val summaryNotificationData = result as SummaryInboxNotificationData
+ assertThat(summaryNotificationData.wearActions).doesNotContain(SummaryWearNotificationAction.Archive)
+ }
+
+ private fun setQuietTime(quietTime: Boolean) {
+ K9.isQuietTimeEnabled = quietTime
+ if (quietTime) {
+ K9.quietTimeStarts = "0:00"
+ K9.quietTimeEnds = "23:59"
+ }
+ }
+
+ private fun setDeleteAction(mode: K9.NotificationQuickDelete) {
+ K9.notificationQuickDeleteBehaviour = mode
+ }
+
+ private fun setConfirmDeleteFromNotification(confirm: Boolean) {
+ K9.isConfirmDeleteFromNotification = confirm
+ }
+
+ private fun createAccount(): Account {
+ return Account("00000000-0000-0000-0000-000000000000").apply {
+ accountNumber = 42
+ }
+ }
+
+ private fun createNotificationContent() = NotificationContent(
+ messageReference = MessageReference("irrelevant", 1, "irrelevant"),
+ sender = "irrelevant",
+ subject = "irrelevant",
+ preview = "irrelevant",
+ summary = "irrelevant"
+ )
+
+ private fun createNotificationData(
+ contentList: List = listOf(createNotificationContent())
+ ): NotificationData {
+ return NotificationData(account).apply {
+ for (content in contentList) {
+ addNotificationContent(content)
+ }
+ }
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ private fun createNotificationDataWithMultipleMessages(times: Int = 2): NotificationData {
+ val contentList = buildList {
+ repeat(times) {
+ add(createNotificationContent())
+ }
+ }
+ return createNotificationData(contentList)
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/notification/SyncNotificationControllerTest.kt b/app/core/src/test/java/com/fsck/k9/notification/SyncNotificationControllerTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9354ed4de63fc4e148c1bd66f119c47ebed8b21a
--- /dev/null
+++ b/app/core/src/test/java/com/fsck/k9/notification/SyncNotificationControllerTest.kt
@@ -0,0 +1,140 @@
+package com.fsck.k9.notification
+
+import android.app.Notification
+import android.app.PendingIntent
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.test.core.app.ApplicationProvider
+import com.fsck.k9.Account
+import com.fsck.k9.RobolectricTest
+import com.fsck.k9.mailstore.LocalFolder
+import com.fsck.k9.notification.NotificationIds.getFetchingMailNotificationId
+import com.fsck.k9.testing.MockHelper.mockBuilder
+import org.junit.Test
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+
+private const val ACCOUNT_NUMBER = 1
+private const val ACCOUNT_NAME = "TestAccount"
+private const val FOLDER_SERVER_ID = "INBOX"
+private const val FOLDER_NAME = "Inbox"
+
+class SyncNotificationControllerTest : RobolectricTest() {
+ private val resourceProvider: NotificationResourceProvider = TestNotificationResourceProvider()
+ private val notification = mock()
+ private val notificationManager = mock()
+ private val builder = createFakeNotificationBuilder(notification)
+ private val account = createFakeAccount()
+ private val contentIntent = mock()
+ private val controller = SyncNotificationController(
+ notificationHelper = createFakeNotificationHelper(notificationManager, builder),
+ actionBuilder = createActionBuilder(contentIntent),
+ resourceProvider = resourceProvider
+ )
+
+ @Test
+ fun testShowSendingNotification() {
+ val notificationId = getFetchingMailNotificationId(account)
+
+ controller.showSendingNotification(account)
+
+ verify(notificationManager).notify(notificationId, notification)
+ verify(builder).setSmallIcon(resourceProvider.iconSendingMail)
+ verify(builder).setTicker("Sending mail: $ACCOUNT_NAME")
+ verify(builder).setContentTitle("Sending mail")
+ verify(builder).setContentText(ACCOUNT_NAME)
+ verify(builder).setContentIntent(contentIntent)
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ @Test
+ fun testClearSendingNotification() {
+ val notificationId = getFetchingMailNotificationId(account)
+
+ controller.clearSendingNotification(account)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ @Test
+ fun testGetFetchingMailNotificationId() {
+ val localFolder = createFakeLocalFolder()
+ val notificationId = getFetchingMailNotificationId(account)
+
+ controller.showFetchingMailNotification(account, localFolder)
+
+ verify(notificationManager).notify(notificationId, notification)
+ verify(builder).setSmallIcon(resourceProvider.iconCheckingMail)
+ verify(builder).setTicker("Checking mail: $ACCOUNT_NAME:$FOLDER_NAME")
+ verify(builder).setContentTitle("Checking mail")
+ verify(builder).setContentText("$ACCOUNT_NAME:$FOLDER_NAME")
+ verify(builder).setContentIntent(contentIntent)
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ @Test
+ fun testShowEmptyFetchingMailNotification() {
+ val notificationId = getFetchingMailNotificationId(account)
+
+ controller.showEmptyFetchingMailNotification(account)
+
+ verify(notificationManager).notify(notificationId, notification)
+ verify(builder).setSmallIcon(resourceProvider.iconCheckingMail)
+ verify(builder).setContentTitle("Checking mail")
+ verify(builder).setContentText(ACCOUNT_NAME)
+ verify(builder).setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
+ }
+
+ @Test
+ fun testClearSendFailedNotification() {
+ val notificationId = getFetchingMailNotificationId(account)
+
+ controller.clearFetchingMailNotification(account)
+
+ verify(notificationManager).cancel(notificationId)
+ }
+
+ private fun createFakeNotificationBuilder(notification: Notification): NotificationCompat.Builder {
+ return mockBuilder {
+ on { build() } doReturn notification
+ }
+ }
+
+ private fun createFakeNotificationHelper(
+ notificationManager: NotificationManagerCompat,
+ builder: NotificationCompat.Builder
+ ): NotificationHelper {
+ return mock {
+ on { getContext() } doReturn ApplicationProvider.getApplicationContext()
+ on { getNotificationManager() } doReturn notificationManager
+ on { createNotificationBuilder(any(), any()) } doReturn builder
+ on { getAccountName(any()) } doReturn ACCOUNT_NAME
+ }
+ }
+
+ private fun createFakeAccount(): Account {
+ return mock {
+ on { accountNumber } doReturn ACCOUNT_NUMBER
+ on { description } doReturn ACCOUNT_NAME
+ on { outboxFolderId } doReturn 33L
+ }
+ }
+
+ private fun createActionBuilder(contentIntent: PendingIntent): NotificationActionCreator {
+ return mock {
+ on { createViewFolderPendingIntent(eq(account), anyLong(), anyInt()) } doReturn contentIntent
+ }
+ }
+
+ private fun createFakeLocalFolder(): LocalFolder {
+ return mock {
+ on { serverId } doReturn FOLDER_SERVER_ID
+ on { name } doReturn FOLDER_NAME
+ }
+ }
+}
diff --git a/app/core/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.kt b/app/core/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.kt
index d29f4cd9f9ecdd75b51c87d8aff215d783119b5b..b92e017ba347e0ca4f0e637474d8893e2b3d7fe2 100644
--- a/app/core/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.kt
+++ b/app/core/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.kt
@@ -2,10 +2,10 @@ package com.fsck.k9.preferences
import com.fsck.k9.K9RobolectricTest
import com.fsck.k9.Preferences
+import com.fsck.k9.mailstore.FolderRepository
import java.io.ByteArrayOutputStream
import org.jdom2.Document
import org.jdom2.input.SAXBuilder
-import com.fsck.k9.mailstore.FolderRepository
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
diff --git a/app/k9mail-jmap/build.gradle b/app/k9mail-jmap/build.gradle
index b6a3cf29f34f3bf367f6eeb4ec5dcc53bfc4b2e8..7f4cb270d43dfcc4a690360321d6254fe9d311b3 100644
--- a/app/k9mail-jmap/build.gradle
+++ b/app/k9mail-jmap/build.gradle
@@ -38,7 +38,6 @@ dependencies {
testImplementation "org.mockito.kotlin:mockito-kotlin:${versions.mockitoKotlin}"
testImplementation "org.koin:koin-test:${versions.koin}"
}
-
android {
compileSdkVersion buildConfig.compileSdk
buildToolsVersion buildConfig.buildTools
diff --git a/app/k9mail-jmap/src/main/AndroidManifest.xml b/app/k9mail-jmap/src/main/AndroidManifest.xml
index 02d83ec046ba8005262d70f62075f3bc895729d7..5ec0d38397f71c3f8eef0881987dad897cca8c64 100644
--- a/app/k9mail-jmap/src/main/AndroidManifest.xml
+++ b/app/k9mail-jmap/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
@@ -32,7 +33,7 @@
android:theme="@style/Theme.K9.Startup"
android:usesCleartextTraffic="true">
-
diff --git a/app/k9mail-jmap/src/main/java/com/fsck/k9/notification/K9NotificationActionCreator.kt b/app/k9mail-jmap/src/main/java/com/fsck/k9/notification/K9NotificationActionCreator.kt
index ce5bb48dd8f6f4e1366729287d31dcdc793563df..a18f1ddf58033ad19db1628ef99822409eff6fe1 100644
--- a/app/k9mail-jmap/src/main/java/com/fsck/k9/notification/K9NotificationActionCreator.kt
+++ b/app/k9mail-jmap/src/main/java/com/fsck/k9/notification/K9NotificationActionCreator.kt
@@ -69,7 +69,6 @@ internal class K9NotificationActionCreator(
}
override fun createDismissMessagePendingIntent(
- context: Context,
messageReference: MessageReference,
notificationId: Int
): PendingIntent {
diff --git a/app/k9mail-jmap/src/main/java/com/fsck/k9/resources/K9CoreResourceProvider.kt b/app/k9mail-jmap/src/main/java/com/fsck/k9/resources/K9CoreResourceProvider.kt
index 8f2f61fa2ab55d5abf4fa5ff7634ca1655825575..5a11b2251cbf39782649c6337b22acf8311cc134 100644
--- a/app/k9mail-jmap/src/main/java/com/fsck/k9/resources/K9CoreResourceProvider.kt
+++ b/app/k9mail-jmap/src/main/java/com/fsck/k9/resources/K9CoreResourceProvider.kt
@@ -9,12 +9,6 @@ class K9CoreResourceProvider(private val context: Context) : CoreResourceProvide
override fun defaultSignature(): String = context.getString(R.string.default_signature)
override fun defaultIdentityDescription(): String = context.getString(R.string.default_identity_description)
- override fun internalStorageProviderName(): String =
- context.getString(R.string.local_storage_provider_internal_label)
-
- override fun externalStorageProviderName(): String =
- context.getString(R.string.local_storage_provider_external_label)
-
override fun contactDisplayNamePrefix(): String = context.getString(R.string.message_to_label)
override fun contactUnknownSender(): String = context.getString(R.string.unknown_sender)
override fun contactUnknownRecipient(): String = context.getString(R.string.unknown_recipient)
diff --git a/app/k9mail-jmap/src/main/res/values/themes.xml b/app/k9mail-jmap/src/main/res/values/themes.xml
index 7489edf82a645f2b8457e285aad7062d361a5d9c..700b046c83e1ea06bdcda35a463f0209ef1f4e38 100644
--- a/app/k9mail-jmap/src/main/res/values/themes.xml
+++ b/app/k9mail-jmap/src/main/res/values/themes.xml
@@ -53,6 +53,7 @@
@drawable/ic_file_upload@drawable/ic_select_all@drawable/ic_floppy
+ @drawable/ic_download@drawable/ic_clear@drawable/ic_action_request_read_receipt_light@drawable/ic_chevron_down
@@ -92,6 +93,7 @@
@drawable/ic_messagelist_forwarded@drawable/ic_messagelist_answered_forwarded@drawable/btn_check_star
+ #fbbc04#ffffffff@drawable/ic_person_plus#e8e8e8
@@ -170,6 +172,7 @@
@drawable/ic_file_upload@drawable/ic_select_all@drawable/ic_floppy
+ @drawable/ic_download@drawable/ic_clear@drawable/ic_action_request_read_receipt_dark@drawable/ic_chevron_down
@@ -209,6 +212,7 @@
@drawable/ic_messagelist_forwarded@drawable/ic_messagelist_answered_forwarded@drawable/btn_check_star
+ #fdd663#000000@drawable/ic_person_plus#313131
diff --git a/app/k9mail-jmap/src/test/java/com/fsck/k9/DependencyInjectionTest.kt b/app/k9mail-jmap/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
index 880498b6405b33cf5f0c0f8a40e5a7557d88417a..02c8408aab323e7a0efdbc3a034358fc76cb346c 100644
--- a/app/k9mail-jmap/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
+++ b/app/k9mail-jmap/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
@@ -44,4 +44,4 @@ class DependencyInjectionTest : AutoCloseKoinTest() {
create { parametersOf(ChangeLogMode.CHANGE_LOG) }
}
}
-}
+}
\ No newline at end of file
diff --git a/app/k9mail/build.gradle b/app/k9mail/build.gradle
index 4fe29b4a318db7a2c7ade850227c2d7633ac80e2..bcec5ff80db4ab0bf669862bfcbe5619b204598e 100644
--- a/app/k9mail/build.gradle
+++ b/app/k9mail/build.gradle
@@ -47,8 +47,8 @@ android {
applicationId "foundation.e.mail"
testApplicationId "foundation.e.mail.tests"
- versionCode 29002
- versionName '5.903-SNAPSHOT'
+ versionCode 29005
+ versionName '5.905'
// 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",
diff --git a/app/k9mail/src/main/AndroidManifest.xml b/app/k9mail/src/main/AndroidManifest.xml
index 106f66347ad2f05f586d354d9c816eb2701e6175..3c819e4a11d654cef7cfe15c408e3226456a7047 100644
--- a/app/k9mail/src/main/AndroidManifest.xml
+++ b/app/k9mail/src/main/AndroidManifest.xml
@@ -1,125 +1,126 @@
-
+
+ android:required="false" />
+ android:smallScreens="true" />
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+ android:protectionLevel="dangerous" />
+
-
+ android:protectionLevel="dangerous" />
+
+ android:roundIcon="@mipmap/icon_e"
+ android:theme="@style/Theme.K9.Startup"
+ android:usesCleartextTraffic="true">
+ android:value="com.fsck.k9.activity.Search" />
+ android:value="true" />
+ android:required="false" />
+
+ android:value="true" />
-
+
+ android:exported="true"
+ android:targetActivity=".activity.MessageList" />
+ android:theme="@style/Theme.K9.Dialog.Translucent.DayNight" />
+ android:label="@string/account_setup_basics_title" />
+ android:label="@string/account_setup_account_type_title" />
+ android:label="@string/account_setup_incoming_title" />
+ android:label="@string/account_settings_composition_title" />
+ android:label="@string/account_setup_outgoing_title" />
+ android:label="@string/account_setup_options_title" />
+ android:label="@string/account_setup_names_title" />
+ android:label="@string/manage_identities_title" />
+ android:label="@string/edit_identity_title" />
+ android:theme="@style/Theme.K9.Dialog.Translucent.DayNight" />
+ android:label="@string/account_setup_check_settings_title" />
+ android:label="@string/ac_transfer_title" />
+ android:exported="true"
+ android:targetActivity=".activity.MessageList" />
-
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+ android:scheme="k9mail" />
+
@@ -202,30 +202,30 @@
android:enabled="false"
android:label="@string/app_name">
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+ android:resource="@xml/searchable" />
-
-
+
+
-
+
+ android:label="@string/upgrade_databases_title" />
-
-
-
-
-
-
-
-
-
-
+
+ android:resource="@xml/unread_widget_info" />
+ android:enabled="false"
+ android:exported="false">
-
+
@@ -368,16 +344,16 @@
+ android:enabled="true" />
+ android:exported="false" />
+ android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
@@ -385,7 +361,7 @@
+ android:permission="android.permission.BIND_JOB_SERVICE" />
+ android:writePermission="${applicationId}.permission.DELETE_MESSAGES" />
+ android:exported="false" />
+ android:orientation="vertical"
+ tools:context=".widget.unread.UnreadWidgetConfigurationActivity">
diff --git a/app/k9mail/src/main/res/values/themes.xml b/app/k9mail/src/main/res/values/themes.xml
index 3d9a2729b7f1a752c257b657506cf28f88ba6fd9..becc4383ee63f95d2675850a82ae71c91f63dde0 100644
--- a/app/k9mail/src/main/res/values/themes.xml
+++ b/app/k9mail/src/main/res/values/themes.xml
@@ -50,7 +50,7 @@
@lineageos.platform:drawable/ic_star_filled@lineageos.platform:drawable/ic_star@drawable/ic_opened_envelope
- @lineageos.platform:@drawable/ic_mark_new
+ @drawable/ic_mark_new@drawable/ic_magnify_cloud@lineageos.platform:drawable/ic_add@drawable/ic_arrow_up_down
@@ -169,7 +169,7 @@
@lineageos.platform:drawable/ic_star_filled@lineageos.platform:drawable/ic_star@drawable/ic_opened_envelope
- @lineageos.platform:drawable/ic_mark_new
+ @drawable/ic_mark_new@drawable/ic_magnify_cloud@lineageos.platform:drawable/ic_add@drawable/ic_arrow_up_down
diff --git a/app/k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt b/app/k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt
new file mode 100644
index 0000000000000000000000000000000000000000..930bc8a3fdbe1fac00513e39ce8d35bd2699bd38
--- /dev/null
+++ b/app/k9mail/src/release/java/app/k9mail/dev/ReleaseConfig.kt
@@ -0,0 +1,9 @@
+package app.k9mail.dev
+
+import com.fsck.k9.backend.BackendFactory
+import org.koin.core.module.Module
+import org.koin.core.scope.Scope
+
+fun Scope.developmentBackends() = emptyMap()
+
+fun Module.developmentModuleAdditions() = Unit
diff --git a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
index 880498b6405b33cf5f0c0f8a40e5a7557d88417a..02c8408aab323e7a0efdbc3a034358fc76cb346c 100644
--- a/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
+++ b/app/k9mail/src/test/java/com/fsck/k9/DependencyInjectionTest.kt
@@ -44,4 +44,4 @@ class DependencyInjectionTest : AutoCloseKoinTest() {
create { parametersOf(ChangeLogMode.CHANGE_LOG) }
}
}
-}
+}
\ No newline at end of file
diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/K9MessageStore.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/K9MessageStore.kt
index 210f905bbe2dcfbf5929a1ff9978fe972e4abd9f..abfc6a72df4368b649687d9f3ea5b2bbccfcb20c 100644
--- a/app/storage/src/main/java/com/fsck/k9/storage/messages/K9MessageStore.kt
+++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/K9MessageStore.kt
@@ -134,6 +134,10 @@ class K9MessageStore(
return retrieveFolderOperations.getFolderId(folderServerId)
}
+ override fun getFolderServerId(folderId: Long): String? {
+ return retrieveFolderOperations.getFolderServerId(folderId)
+ }
+
override fun getMessageCount(folderId: Long): Int {
return retrieveFolderOperations.getMessageCount(folderId)
}
@@ -175,7 +179,7 @@ class K9MessageStore(
}
override fun setLastChecked(folderId: Long, timestamp: Long) {
- TODO("Not yet implemented")
+ updateFolderOperations.setLastChecked(folderId, timestamp)
}
override fun setStatus(folderId: Long, status: String?) {
diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveFolderOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveFolderOperations.kt
index 37e5e49cae4c733b81d7b138356cc67955a24a59..eacaed3ab812218bd0943272fcdd8ba2cb428596 100644
--- a/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveFolderOperations.kt
+++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/RetrieveFolderOperations.kt
@@ -1,6 +1,7 @@
package com.fsck.k9.storage.messages
import android.database.Cursor
+import androidx.core.database.getLongOrNull
import com.fsck.k9.Account.FolderMode
import com.fsck.k9.helper.map
import com.fsck.k9.mail.FolderClass
@@ -131,6 +132,22 @@ internal class RetrieveFolderOperations(private val lockableDatabase: LockableDa
}
}
+ fun getFolderServerId(folderId: Long): String? {
+ return lockableDatabase.execute(false) { db ->
+ db.query(
+ "folders",
+ arrayOf("server_id"),
+ "id = ?",
+ arrayOf(folderId.toString()),
+ null,
+ null,
+ null
+ ).use { cursor ->
+ if (cursor.moveToFirst()) cursor.getString(0) else null
+ }
+ }
+ }
+
fun getMessageCount(folderId: Long): Int {
return lockableDatabase.execute(false) { db ->
db.rawQuery(
diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/SaveMessageOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/SaveMessageOperations.kt
index 827644bfcc9df3891009e37d146e8805ab5a3324..c6e95bc7b2094b316a80f98ea60f31526fb13920 100644
--- a/app/storage/src/main/java/com/fsck/k9/storage/messages/SaveMessageOperations.kt
+++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/SaveMessageOperations.kt
@@ -28,7 +28,6 @@ import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
-import java.util.Locale
import java.util.Stack
import java.util.UUID
import org.apache.commons.io.IOUtils
@@ -306,9 +305,10 @@ internal class SaveMessageOperations(
private fun decodeAndCountBytes(rawInputStream: InputStream, encoding: String, fallbackValue: Long): Long {
return try {
getDecodingInputStream(rawInputStream, encoding).use { decodingInputStream ->
- val countingOutputStream = CountingOutputStream()
- IOUtils.copy(decodingInputStream, countingOutputStream)
- countingOutputStream.count
+ CountingOutputStream().use { countingOutputStream ->
+ IOUtils.copy(decodingInputStream, countingOutputStream)
+ countingOutputStream.count
+ }
}
} catch (e: IOException) {
fallbackValue
diff --git a/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt b/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt
index cb503dd65ad0f4754b32a39bef2559311da12547..52544b1f4b4fc9b2ea569170b5caacbabd9ee584 100644
--- a/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt
+++ b/app/storage/src/main/java/com/fsck/k9/storage/messages/ThreadMessageOperations.kt
@@ -5,7 +5,6 @@ import android.database.sqlite.SQLiteDatabase
import com.fsck.k9.helper.Utility
import com.fsck.k9.mail.Message
import com.fsck.k9.mail.message.MessageHeaderParser
-import java.util.Locale
internal class ThreadMessageOperations {
diff --git a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo80.kt b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo80.kt
index 3cc4cc30c34d618ffed99877f730e85363b6d6e0..c435d9ead49f9714e232022db17aa6b825fbf0f0 100644
--- a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo80.kt
+++ b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo80.kt
@@ -9,4 +9,4 @@ internal class MigrationTo80(private val db: SQLiteDatabase) {
fun rewriteLastUpdatedColumn() {
db.execSQL("UPDATE folders SET last_updated = NULL WHERE last_updated = 0")
}
-}
\ No newline at end of file
+}
diff --git a/app/storage/src/test/java/com/fsck/k9/storage/StoreSchemaDefinitionTest.java b/app/storage/src/test/java/com/fsck/k9/storage/StoreSchemaDefinitionTest.java
index c7e4b0e88c52ffaeb7abd3dc12f5b3e3622ca6b7..7d103d3378357d9069191208dab00f584cf78635 100644
--- a/app/storage/src/test/java/com/fsck/k9/storage/StoreSchemaDefinitionTest.java
+++ b/app/storage/src/test/java/com/fsck/k9/storage/StoreSchemaDefinitionTest.java
@@ -31,8 +31,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
diff --git a/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt b/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt
index 45b47396884c90733f882d66fa5c25464521e4a0..69fc55cbb5860e55b68f831ce86584d0602dc337 100644
--- a/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt
+++ b/app/storage/src/test/java/com/fsck/k9/storage/messages/RetrieveFolderOperationsTest.kt
@@ -302,6 +302,25 @@ class RetrieveFolderOperationsTest : RobolectricTest() {
assertThat(result).isNull()
}
+ @Test
+ fun `get folder server id`() {
+ val (_, folderId2) = listOf(
+ sqliteDatabase.createFolder(serverId = "folder1"),
+ sqliteDatabase.createFolder(serverId = "folder2"),
+ )
+
+ val result = retrieveFolderOperations.getFolderServerId(folderId2)
+
+ assertThat(result).isEqualTo("folder2")
+ }
+
+ @Test
+ fun `get folder server id should return null if no folder was found`() {
+ val result = retrieveFolderOperations.getFolderServerId(folderId = 1)
+
+ assertThat(result).isNull()
+ }
+
@Test
fun `get message count from empty folder`() {
val folderId = sqliteDatabase.createFolder()
diff --git a/app/testing/src/main/java/com/fsck/k9/TestClock.kt b/app/testing/src/main/java/com/fsck/k9/TestClock.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3421c3e24e533ac4451c03c401d4104c444a086f
--- /dev/null
+++ b/app/testing/src/main/java/com/fsck/k9/TestClock.kt
@@ -0,0 +1,5 @@
+package com.fsck.k9
+
+class TestClock(initialTime: Long = 0L) : Clock {
+ override var time: Long = initialTime
+}
diff --git a/app/testing/src/main/java/com/fsck/k9/testing/MockHelper.kt b/app/testing/src/main/java/com/fsck/k9/testing/MockHelper.kt
index 3334063d6182a7723b74f2142d627a6a28097814..17e9e6986e5e593d195b2ed95a3aa6377e9b1e8b 100644
--- a/app/testing/src/main/java/com/fsck/k9/testing/MockHelper.kt
+++ b/app/testing/src/main/java/com/fsck/k9/testing/MockHelper.kt
@@ -20,4 +20,4 @@ object MockHelper {
inline fun mockBuilder(stubbing: KStubbing.(T) -> Unit = {}): T {
return mockBuilder(T::class.java).apply { KStubbing(this).stubbing(this) }
}
-}
\ No newline at end of file
+}
diff --git a/app/ui/base/build.gradle b/app/ui/base/build.gradle
index eb7661cc2e74d5d3034427adf2ba9b481376ff15..6b94ff2b65c822963c0c1a44d42e06b049ef0c0a 100644
--- a/app/ui/base/build.gradle
+++ b/app/ui/base/build.gradle
@@ -5,6 +5,7 @@ dependencies {
implementation project(":app:core")
api "androidx.appcompat:appcompat:${versions.androidxAppCompat}"
+ api "androidx.activity:activity:${versions.androidxActivity}"
api "com.google.android.material:material:${versions.materialComponents}"
api "androidx.navigation:navigation-fragment-ktx:${versions.androidxNavigation}"
api "androidx.navigation:navigation-ui-ktx:${versions.androidxNavigation}"
diff --git a/app/ui/base/src/main/res/color/star_color.xml b/app/ui/base/src/main/res/color/star_color.xml
index 63583273b80eaaa76baf7748d04e9cbf1c1ba338..ac2f37f0598e8dde66726391099e19195d9422b3 100644
--- a/app/ui/base/src/main/res/color/star_color.xml
+++ b/app/ui/base/src/main/res/color/star_color.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/app/ui/base/src/main/res/values/styles.xml b/app/ui/base/src/main/res/values/styles.xml
index 72ac1768599686230cd9a4cfe7e38bb990d4bff5..004d8134bc3285ef961210e0101d60c53152f75d 100644
--- a/app/ui/base/src/main/res/values/styles.xml
+++ b/app/ui/base/src/main/res/values/styles.xml
@@ -1,6 +1,7 @@
+
\ No newline at end of file
diff --git a/app/ui/legacy/build.gradle b/app/ui/legacy/build.gradle
index 6805546bd650957e5e565606f55d429c6f5c2e18..8e14957d3b6703a1d241db8fa333e145eca4de21 100644
--- a/app/ui/legacy/build.gradle
+++ b/app/ui/legacy/build.gradle
@@ -23,6 +23,7 @@ dependencies {
implementation "com.takisoft.preferencex:preferencex-colorpicker:${versions.preferencesFix}"
implementation "com.takisoft.preferencex:preferencex-ringtone:${versions.preferencesFix}"
implementation "androidx.recyclerview:recyclerview:${versions.androidxRecyclerView}"
+ implementation "androidx.lifecycle:lifecycle-runtime-ktx:${versions.androidxLifecycle}"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidxLifecycle}"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.androidxLifecycle}"
implementation "androidx.constraintlayout:constraintlayout:${versions.androidxConstraintLayout}"
@@ -63,6 +64,8 @@ dependencies {
testImplementation "org.mockito:mockito-core:${versions.mockito}"
testImplementation "org.mockito.kotlin:mockito-kotlin:${versions.mockitoKotlin}"
testImplementation "org.koin:koin-test:${versions.koin}"
+ testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:${versions.kotlinCoroutines}"
+ testImplementation "app.cash.turbine:turbine:${versions.turbine}"
}
android {
diff --git a/app/ui/legacy/sampledata/accounts.json b/app/ui/legacy/sampledata/accounts.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f5102272cf5bd4e6f0cdf7c1c84af807968572b
--- /dev/null
+++ b/app/ui/legacy/sampledata/accounts.json
@@ -0,0 +1,19 @@
+{
+ "data": [
+ {
+ "name": "Personal",
+ "email": "user@domain.example",
+ "color": "#FF1976D2"
+ },
+ {
+ "name": "Work",
+ "email": "firstname.lastname@work.example",
+ "color": "#FFE91E63"
+ },
+ {
+ "name": "Club",
+ "email": "name@sportsclub.example",
+ "color": "#FFFFB300"
+ }
+ ]
+}
diff --git a/app/ui/legacy/sampledata/folders.json b/app/ui/legacy/sampledata/folders.json
new file mode 100644
index 0000000000000000000000000000000000000000..e02d14f4e6793ae3c0544874633ddfcbb2c3bdce
--- /dev/null
+++ b/app/ui/legacy/sampledata/folders.json
@@ -0,0 +1,48 @@
+{
+ "data": [
+ {
+ "name": "Inbox",
+ "icon": "?attr/iconFolderInbox"
+ },
+ {
+ "name": "Outbox",
+ "icon": "?attr/iconFolderOutbox"
+ },
+ {
+ "name": "Archive",
+ "icon": "?attr/iconFolderArchive"
+ },
+ {
+ "name": "Drafts",
+ "icon": "?attr/iconFolderDrafts"
+ },
+ {
+ "name": "Sent",
+ "icon": "?attr/iconFolderSent"
+ },
+ {
+ "name": "Spam",
+ "icon": "?attr/iconFolderSpam"
+ },
+ {
+ "name": "Trash",
+ "icon": "?attr/iconFolderTrash"
+ },
+ {
+ "name": "Regular folder",
+ "icon": "?attr/iconFolder"
+ },
+ {
+ "name": "Another folder",
+ "icon": "?attr/iconFolder"
+ },
+ {
+ "name": "And yet another folder",
+ "icon": "?attr/iconFolder"
+ },
+ {
+ "name": "Folder",
+ "icon": "?attr/iconFolder"
+ }
+ ]
+}
diff --git a/app/ui/legacy/src/debug/java/com/fsck/k9/ui/settings/ExtraAccountDiscovery.kt b/app/ui/legacy/src/debug/java/com/fsck/k9/ui/settings/ExtraAccountDiscovery.kt
new file mode 100644
index 0000000000000000000000000000000000000000..df09c4e2607075d25dc05aa52b017dd5bdd8a0af
--- /dev/null
+++ b/app/ui/legacy/src/debug/java/com/fsck/k9/ui/settings/ExtraAccountDiscovery.kt
@@ -0,0 +1,27 @@
+package com.fsck.k9.ui.settings
+
+import com.fsck.k9.mail.AuthType
+import com.fsck.k9.mail.ConnectionSecurity
+import com.fsck.k9.mail.ServerSettings
+import com.fsck.k9.ui.ConnectionSettings
+
+object ExtraAccountDiscovery {
+ @JvmStatic
+ fun discover(email: String): ConnectionSettings? {
+ return if (email.endsWith("@k9mail.example")) {
+ val serverSettings = ServerSettings(
+ type = "demo",
+ host = "irrelevant",
+ port = 23,
+ connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
+ authenticationType = AuthType.AUTOMATIC,
+ username = "irrelevant",
+ password = "irrelevant",
+ clientCertificateAlias = null
+ )
+ ConnectionSettings(incoming = serverSettings, outgoing = serverSettings)
+ } else {
+ null
+ }
+ }
+}
diff --git a/app/ui/legacy/src/main/AndroidManifest.xml b/app/ui/legacy/src/main/AndroidManifest.xml
index e734d8075cd250490df6c415276aac7f1003c85e..3b37d7b533c23dc642e59b4b5918de44027d7600 100644
--- a/app/ui/legacy/src/main/AndroidManifest.xml
+++ b/app/ui/legacy/src/main/AndroidManifest.xml
@@ -2,6 +2,13 @@
+
+
+
+
+
+
+
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountCreator.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountCreator.kt
index 7c1e18ecde7e3af66b2b70fd038d6a3a968eb465..e3f49d16a919d845d5ffe629692dad9846768ae2 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountCreator.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountCreator.kt
@@ -20,6 +20,7 @@ class AccountCreator(private val preferences: Preferences, private val resources
Protocols.IMAP -> DeletePolicy.ON_DELETE
Protocols.POP3 -> DeletePolicy.NEVER
Protocols.WEBDAV -> DeletePolicy.ON_DELETE
+ "demo" -> DeletePolicy.ON_DELETE
else -> throw AssertionError("Unhandled case: $type")
}
}
@@ -60,10 +61,10 @@ class AccountCreator(private val preferences: Preferences, private val resources
return accountColors.random()
}
- return availableColors.shuffled().minOf { color ->
+ return availableColors.shuffled().minByOrNull { color ->
val index = DEFAULT_COLORS.indexOf(color)
if (index != -1) index else DEFAULT_COLORS.size
- }
+ } ?: error("availableColors must not be empty")
}
companion object {
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/EditIdentity.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/EditIdentity.kt
index a7935fe22366b22efa28cc56e21f0e7e6ee975e4..1992c1cb27ef6c52370c183332f2863a9eabe15d 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/EditIdentity.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/EditIdentity.kt
@@ -101,7 +101,7 @@ class EditIdentity : K9Activity() {
outState.putParcelable(EXTRA_IDENTITY, identity)
}
- override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.edit_identity_menu, menu)
return true
}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java
index 3a8ae301a42f54d95814ed0a25418ef0b15380b3..89998ed4d2faf518694b781aee6234e1b6034f95 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageCompose.java
@@ -25,11 +25,9 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
-
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
-
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
@@ -69,6 +67,8 @@ import com.fsck.k9.activity.compose.PgpInlineDialog.OnOpenPgpInlineChangeListene
import com.fsck.k9.activity.compose.PgpSignOnlyDialog.OnOpenPgpSignOnlyChangeListener;
import com.fsck.k9.activity.compose.RecipientMvpView;
import com.fsck.k9.activity.compose.RecipientPresenter;
+import com.fsck.k9.activity.compose.ReplyToPresenter;
+import com.fsck.k9.activity.compose.ReplyToView;
import com.fsck.k9.activity.compose.SaveMessageTask;
import com.fsck.k9.activity.misc.Attachment;
import com.fsck.k9.autocrypt.AutocryptDraftStateHeaderParser;
@@ -205,6 +205,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
// relates to the message being replied to, forwarded, or edited TODO split up?
private MessageReference relatedMessageReference;
+ private Flag relatedFlag = null;
/**
* Indicates that the source message has been processed at least once and should not be processed on any subsequent
* loads. This protects us from adding attachments that have already been added from the restore of the view state.
@@ -313,7 +314,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
ReplyToView replyToView = new ReplyToView(this);
replyToPresenter = new ReplyToPresenter(replyToView);
-
RecipientMvpView recipientMvpView = new RecipientMvpView(this);
ComposePgpInlineDecider composePgpInlineDecider = new ComposePgpInlineDecider();
ComposePgpEnableByDefaultDecider composePgpEnableByDefaultDecider = new ComposePgpEnableByDefaultDecider();
@@ -449,7 +449,9 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
if (action == Action.REPLY || action == Action.REPLY_ALL) {
- relatedMessageReference = relatedMessageReference.withModifiedFlag(Flag.ANSWERED);
+ relatedFlag = Flag.ANSWERED;
+ } else if (action == Action.FORWARD || action == Action.FORWARD_AS_ATTACHMENT) {
+ relatedFlag = Flag.FORWARDED;
}
if (action == Action.REPLY || action == Action.REPLY_ALL ||
@@ -461,10 +463,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
recipientMvpView.requestFocusOnToField();
}
- if (action == Action.FORWARD || action == Action.FORWARD_AS_ATTACHMENT) {
- relatedMessageReference = relatedMessageReference.withModifiedFlag(Flag.FORWARDED);
- }
-
updateMessageFormat();
// Set font size of input controls
@@ -1234,10 +1232,11 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
/**
- * Pull out the parts of the now loaded source message and apply them to the new message depending on the type of
- * message being composed.
+ * Pull out the parts of the now loaded source message and apply them to the new message
+ * depending on the type of message being composed.
*
- * @param messageViewInfo The source message used to populate the various text fields.
+ * @param messageViewInfo
+ * The source message used to populate the various text fields.
*/
private void processSourceMessage(MessageViewInfo messageViewInfo) {
try {
@@ -1458,10 +1457,11 @@ public class MessageCompose extends K9Activity implements OnClickListener,
final Long draftId;
final String plaintextSubject;
final MessageReference messageReference;
+ final Flag flag;
SendMessageTask(MessagingController messagingController, Preferences preferences, Account account,
Contacts contacts, Message message, Long draftId, String plaintextSubject,
- MessageReference messageReference) {
+ MessageReference messageReference, Flag flag) {
this.messagingController = messagingController;
this.preferences = preferences;
this.account = account;
@@ -1470,6 +1470,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
this.draftId = draftId;
this.plaintextSubject = plaintextSubject;
this.messageReference = messageReference;
+ this.flag = flag;
}
@Override
@@ -1478,7 +1479,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
contacts.markAsContacted(message.getRecipients(RecipientType.TO));
contacts.markAsContacted(message.getRecipients(RecipientType.CC));
contacts.markAsContacted(message.getRecipients(RecipientType.BCC));
- updateReferencedMessage();
+ addFlagToReferencedMessage();
} catch (Exception e) {
Timber.e(e, "Failed to mark contact as contacted.");
}
@@ -1495,13 +1496,12 @@ public class MessageCompose extends K9Activity implements OnClickListener,
/**
* Set the flag on the referenced message(indicated we replied / forwarded the message)
**/
- private void updateReferencedMessage() {
- if (messageReference != null && messageReference.getFlag() != null) {
+ private void addFlagToReferencedMessage() {
+ if (messageReference != null && flag != null) {
String accountUuid = messageReference.getAccountUuid();
Account account = preferences.getAccount(accountUuid);
long folderId = messageReference.getFolderId();
String sourceMessageUid = messageReference.getUid();
- Flag flag = messageReference.getFlag();
Timber.d("Setting referenced message (%d, %s) flag to %s", folderId, sourceMessageUid, flag);
@@ -1511,10 +1511,11 @@ public class MessageCompose extends K9Activity implements OnClickListener,
}
/**
- * When we are launched with an intent that includes a mailto: URI, we can actually gather quite a few of our
- * message fields from it.
+ * When we are launched with an intent that includes a mailto: URI, we can actually
+ * gather quite a few of our message fields from it.
*
- * @param mailTo The MailTo object we use to initialize message field
+ * @param mailTo
+ * The MailTo object we use to initialize message field
*/
private void initializeFromMailto(MailTo mailTo) {
recipientPresenter.initFromMailto(mailTo);
@@ -1594,7 +1595,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
} else {
currentMessageBuilder = null;
new SendMessageTask(messagingController, preferences, account, contacts, message,
- draftMessageId, plaintextSubject, relatedMessageReference).execute();
+ draftMessageId, plaintextSubject, relatedMessageReference, relatedFlag).execute();
finish();
}
}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt
index 5d5e51f81bfb5972e1644f3c71a8808b7b557597..d209c12170fc1e90e93902e3b6dc971f153c3bf5 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt
@@ -1,5 +1,6 @@
package com.fsck.k9.activity
+import android.accounts.AccountManager
import android.annotation.SuppressLint
import android.app.SearchManager
import android.content.Context
@@ -32,6 +33,10 @@ import com.fsck.k9.Preferences
import com.fsck.k9.account.BackgroundAccountRemover
import com.fsck.k9.activity.compose.MessageActions
import com.fsck.k9.activity.setup.AccountSetupBasics
+import com.fsck.k9.activity.setup.accountmanager.AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY
+import com.fsck.k9.activity.setup.accountmanager.AccountManagerConstants.EELO_ACCOUNT_TYPE
+import com.fsck.k9.activity.setup.accountmanager.AccountManagerConstants.GOOGLE_ACCOUNT_TYPE
+import com.fsck.k9.activity.setup.accountmanager.EeloAccountCreator
import com.fsck.k9.controller.MessageReference
import com.fsck.k9.fragment.MessageListFragment
import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener
@@ -69,6 +74,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import timber.log.Timber
+import androidx.appcompat.widget.SearchView
/**
* MessageList is the primary user interface for the program. This Activity shows a list of messages.
@@ -85,6 +91,9 @@ open class MessageList :
private val recentChangesViewModel: RecentChangesViewModel by viewModel()
+ private lateinit var accountManager: AccountManager
+ private lateinit var searchView: SearchView
+
protected val searchStatusManager: SearchStatusManager by inject()
private val preferences: Preferences by inject()
private val channelUtils: NotificationChannelManager by inject()
@@ -139,7 +148,15 @@ open class MessageList :
finish()
return
}
- val accounts = preferences.accounts
+ var accounts = preferences.accounts
+
+ accountManager = AccountManager.get(this)
+
+// TODO remove old accounts automatically
+ if (addNewAccountsAutomatically(accounts)) {
+ accounts = preferences.accounts
+ }
+
deleteIncompleteAccounts(accounts)
val hasAccountSetup = accounts.any { it.isFinishedSetup }
if (!hasAccountSetup) {
@@ -390,7 +407,6 @@ open class MessageList :
noThreading = launchData.noThreading
messageReference = launchData.messageReference
-
return true
}
@@ -406,7 +422,7 @@ open class MessageList :
if (account.accountNumber.toString() == accountId) {
val folderId = segmentList[1].toLong()
val messageUid = segmentList[2]
- val messageReference = MessageReference(account.uuid, folderId, messageUid, null)
+ val messageReference = MessageReference(account.uuid, folderId, messageUid)
return LaunchData(
search = messageReference.toLocalSearch(),
@@ -850,10 +866,6 @@ open class MessageList :
return super.onKeyUp(keyCode, event)
}
- override fun onSearchRequested(): Boolean {
- return messageListFragment!!.onSearchRequested()
- }
-
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == android.R.id.home) {
@@ -901,9 +913,6 @@ open class MessageList :
} else if (id == R.id.select_all) {
messageListFragment!!.selectAll()
return true
- } else if (id == R.id.search) {
- messageListFragment!!.onSearchRequested()
- return true
} else if (id == R.id.search_remote) {
messageListFragment!!.onRemoteSearch()
return true
@@ -999,6 +1008,25 @@ open class MessageList :
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.message_list_option, menu)
this.menu = menu
+
+ // setup search view
+ val searchItem = menu.findItem(R.id.search)
+ searchView = searchItem.actionView as SearchView
+ searchView.maxWidth = Int.MAX_VALUE
+ searchView.queryHint = resources.getString(R.string.search_action)
+ val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
+ searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))
+ searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+ override fun onQueryTextSubmit(query: String): Boolean {
+ messageListFragment?.onSearchRequested(query)
+ return true
+ }
+
+ override fun onQueryTextChange(s: String): Boolean {
+ return false
+ }
+ })
+
return true
}
@@ -1165,7 +1193,6 @@ open class MessageList :
}
}
-
fun setActionBarTitle(title: String, subtitle: String? = null) {
actionBar.title = title
actionBar.subtitle = subtitle
@@ -1267,19 +1294,24 @@ open class MessageList :
}
}
- override fun startSearch(account: Account?, folderId: Long?): Boolean {
+ override fun startSearch(query: String, account: Account?, folderId: Long?): Boolean {
// If this search was started from a MessageList of a single folder, pass along that folder info
// so that we can enable remote search.
- if (account != null && folderId != null) {
- val appData = Bundle().apply {
+ val appData = if (account != null && folderId != null) {
+ Bundle().apply {
putString(EXTRA_SEARCH_ACCOUNT, account.uuid)
putLong(EXTRA_SEARCH_FOLDER, folderId)
}
- startSearch(null, false, appData, false)
} else {
// TODO Handle the case where we're searching from within a search result.
- startSearch(null, false, null, false)
+ null
}
+ val searchIntent = Intent(this, Search::class.java).apply {
+ action = Intent.ACTION_SEARCH
+ putExtra(SearchManager.QUERY, query)
+ putExtra(SearchManager.APP_DATA, appData)
+ }
+ startActivity(searchIntent)
return true
}
@@ -1588,6 +1620,86 @@ open class MessageList :
val noThreading: Boolean = false
)
+ private fun addNewAccountsAutomatically(accounts: List): Boolean {
+ return try {
+ val eeloAccounts: Array = getEeloAccountsOnDevice()
+ val googleAccounts: Array = getGoogleAccountsOnDevice()
+ var accountWasAdded = false
+ for (eeloAccount in eeloAccounts) {
+ val emailId: String = accountManager.getUserData(eeloAccount, ACCOUNT_EMAIL_ADDRESS_KEY)
+ if (!emailId.contains("@")) continue
+ var accountIsSignedIn = false
+ for (account in accounts) {
+ if (emailId == account.email) {
+ accountIsSignedIn = true
+ break
+ }
+ }
+ if (!accountIsSignedIn) {
+ val password: String = accountManager.getPassword(eeloAccount)
+ EeloAccountCreator.createAccount(this, emailId, password)
+ accountWasAdded = true
+ }
+ }
+// for (googleAccount in googleAccounts) {
+// val emailId: String = accountManager.getUserData(
+// googleAccount,
+// ACCOUNT_EMAIL_ADDRESS_KEY
+// )
+// var accountIsSignedIn = false
+// for (account in accounts) {
+// if (emailId == account.email) {
+// if (account.name == null) { // we need to fix an old bug
+// account.name = emailId
+// account.save(Preferences.getPreferences(this))
+// }
+// accountIsSignedIn = true
+// break
+// }
+// }
+// if (!accountIsSignedIn) {
+// GoogleAccountCreator.createAccount(this, emailId)
+// accountWasAdded = true
+// }
+// }
+ for (googleAccount in googleAccounts) {
+ val emailId: String = accountManager.getUserData(googleAccount, ACCOUNT_EMAIL_ADDRESS_KEY)
+ var accountIsSignedIn = false
+ for (account in accounts) {
+ if (emailId == account.email) {
+ if (account.name == null) { // we need to fix an old bug
+ account.name = emailId
+ Preferences.getPreferences(this).saveAccount(account)
+ }
+ accountIsSignedIn = true
+ break
+ }
+ }
+ if (!accountIsSignedIn) {
+// GoogleAccountCreator.createAccount(this, emailId)
+// accountWasAdded = true
+// }
+// }
+ EeloAccountCreator.createAccount(this, emailId, "")
+ accountWasAdded = true
+ }
+ }
+
+ accountWasAdded
+ } catch (e: SecurityException) {
+ e.printStackTrace()
+ false
+ }
+ }
+
+ private fun getEeloAccountsOnDevice(): Array {
+ return accountManager.getAccountsByType(EELO_ACCOUNT_TYPE)
+ }
+
+ private fun getGoogleAccountsOnDevice(): Array {
+ return accountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE)
+ }
+
companion object : KoinComponent {
private const val EXTRA_SEARCH = "search_bytes"
private const val EXTRA_NO_THREADING = "no_threading"
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java
index b75c011f9fe9820dfc97d89d6f6414abf22857f4..35c692cf06ead108d896ddb11452efe2c5e0113e 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientLoader.java
@@ -110,8 +110,12 @@ public class RecipientLoader extends AsyncTaskLoader> {
return timesContactedDiff;
}
- if (lhs.sortKey == null || rhs.sortKey == null) {
+ if (lhs.sortKey == null && rhs.sortKey == null) {
return 0;
+ } else if (lhs.sortKey == null) {
+ return 1;
+ } else if (rhs.sortKey == null) {
+ return -1;
}
return CASE_INSENSITIVE_ORDER.compare(lhs.sortKey, rhs.sortKey);
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientMvpView.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientMvpView.kt
index f88fc6f3f0313fd199c04778e5f2e2e51781bb72..60f5b84f62b902e206980874e5ccff7962e1b9fc 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientMvpView.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientMvpView.kt
@@ -76,6 +76,7 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
this.presenter = presenter
toView.setTokenListener(object : RecipientSelectView.TokenListener {
override fun onTokenAdded(recipient: Recipient) = presenter.onToTokenAdded()
+
override fun onTokenRemoved(recipient: Recipient) = presenter.onToTokenRemoved()
override fun onTokenChanged(recipient: Recipient) = presenter.onToTokenChanged()
@@ -130,7 +131,7 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
}
fun setCryptoProvider(openPgpProvider: String?) {
-// TODO move "show advanced" into settings, or somewhere?
+ // TODO move "show advanced" into settings, or somewhere?
toView.setCryptoProvider(openPgpProvider, false)
ccView.setCryptoProvider(openPgpProvider, false)
bccView.setCryptoProvider(openPgpProvider, false)
@@ -190,6 +191,7 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
fun silentlyRemoveBccAddresses(addresses: Array) {
if (addresses.isEmpty()) return
+
val addressesToRemove = addresses.toSet()
for (recipient in bccRecipients.toList()) {
removeAllTextChangedListeners(bccView)
@@ -197,6 +199,7 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
if (recipient.address in addressesToRemove) {
bccView.removeObjectSync(recipient)
}
+
addAllTextChangedListeners(bccView)
}
}
@@ -214,7 +217,6 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
fun setRecipientExpanderVisibility(visible: Boolean) {
val childToDisplay = if (visible) VIEW_INDEX_BCC_EXPANDER_VISIBLE else VIEW_INDEX_BCC_EXPANDER_HIDDEN
-
if (recipientExpanderContainer.displayedChild != childToDisplay) {
recipientExpanderContainer.displayedChild = childToDisplay
}
@@ -263,7 +265,6 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
fun showCryptoSpecialMode(cryptoSpecialModeDisplayType: CryptoSpecialModeDisplayType) {
val shouldBeHidden = cryptoSpecialModeDisplayType.childIdToDisplay == VIEW_INDEX_HIDDEN
if (shouldBeHidden) {
-
cryptoSpecialModeIndicator.isGone = true
return
}
@@ -286,6 +287,7 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
return
}
+
cryptoStatusView.isVisible = true
cryptoStatusView.displayedChildId = cryptoStatusDisplayType.childIdToDisplay
cryptoStatusView.animate()
@@ -383,6 +385,9 @@ class RecipientMvpView(private val activity: MessageCompose) : View.OnFocusChang
UNCONFIGURED(VIEW_INDEX_HIDDEN),
UNINITIALIZED(VIEW_INDEX_HIDDEN),
SIGN_ONLY(R.id.crypto_status_disabled),
+ UNAVAILABLE(VIEW_INDEX_HIDDEN),
+ ENABLED(R.id.crypto_status_enabled),
+ ENABLED_ERROR(R.id.crypto_status_error),
ENABLED_TRUSTED(R.id.crypto_status_trusted),
AVAILABLE(R.id.crypto_status_disabled),
ERROR(R.id.crypto_status_error);
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt
index 7cffd00c61f7243c7d75b88efa7ac02aaa409c29..b849cf7beb35c3702f2bd02bc4a68d6fb820d5e4 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.kt
@@ -112,6 +112,7 @@ class RecipientPresenter(
recipientMvpView.showCcUncompletedError()
return true
}
+
if (recipientMvpView.recipientBccHasUncompletedText()) {
recipientMvpView.showBccUncompletedError()
return true
@@ -131,8 +132,10 @@ class RecipientPresenter(
} else {
replyToParser.getRecipientsToReplyTo(message, account)
}
+
addToAddresses(*replyToAddresses.to)
addCcAddresses(*replyToAddresses.cc)
+
val shouldSendAsPgpInline = composePgpInlineDecider.shouldReplyInline(message)
if (shouldSendAsPgpInline) {
isForceTextMessageFormat = true
@@ -190,6 +193,7 @@ class RecipientPresenter(
fun initFromDraftMessage(message: Message) {
initRecipientsFromDraftMessage(message)
+
val draftStateHeader = message.getHeader(AutocryptDraftStateHeader.AUTOCRYPT_DRAFT_STATE_HEADER)
if (draftStateHeader.size == 1) {
initEncryptionStateFromDraftStateHeader(draftStateHeader.first())
@@ -256,7 +260,6 @@ class RecipientPresenter(
this.alwaysBccAddresses = alwaysBccAddresses
if (alwaysBccAddresses.isEmpty()) return
-
object : RecipientLoader(context, account.openPgpProvider, *alwaysBccAddresses) {
override fun deliverResult(result: List?) {
val recipientArray = result!!.toTypedArray()
@@ -321,7 +324,7 @@ class RecipientPresenter(
}
fun onSwitchIdentity(identity: Identity) {
-// TODO decide what actually to do on identity switch?
+ // TODO decide what actually to do on identity switch?
asyncUpdateCryptoStatus()
}
@@ -357,6 +360,7 @@ class RecipientPresenter(
lastFocusedType = RecipientType.TO
}
}
+
updateRecipientExpanderVisibility()
}
@@ -367,6 +371,7 @@ class RecipientPresenter(
fun asyncUpdateCryptoStatus() {
currentCachedCryptoStatus = null
+
val openPgpProviderState = openPgpApiManager.openPgpProviderState
var accountCryptoKey: Long? = account.openPgpKey
if (accountCryptoKey == Account.NO_OPENPGP_KEY) {
@@ -404,6 +409,7 @@ class RecipientPresenter(
} else {
composeCryptoStatus
}
+
redrawCachedCryptoStatusIcon()
}
}.execute()
@@ -411,6 +417,7 @@ class RecipientPresenter(
private fun redrawCachedCryptoStatusIcon() {
val cryptoStatus = checkNotNull(currentCachedCryptoStatus) { "must have cached crypto status to redraw it!" }
+
recipientMvpView.setRecipientTokensShowCryptoEnabled(cryptoStatus.isEncryptionEnabled)
recipientMvpView.showCryptoStatus(cryptoStatus.displayType)
recipientMvpView.showCryptoSpecialMode(cryptoStatus.specialModeDisplayType)
@@ -477,14 +484,15 @@ class RecipientPresenter(
private fun addRecipientFromContactUri(recipientType: RecipientType, uri: Uri?) {
object : RecipientLoader(context, account.openPgpProvider, uri, false) {
override fun deliverResult(result: List?) {
-// TODO handle multiple available mail addresses for a contact?
-
+ // TODO handle multiple available mail addresses for a contact?
if (result!!.isEmpty()) {
recipientMvpView.showErrorContactNoAddress()
return
}
+
val recipient = result[0]
recipientMvpView.addRecipients(recipientType, recipient)
+
stopLoading()
abandon()
}
@@ -512,6 +520,7 @@ class RecipientPresenter(
when (requestCode) {
CONTACT_PICKER_TO, CONTACT_PICKER_CC, CONTACT_PICKER_BCC -> {
if (resultCode != Activity.RESULT_OK || data == null) return
+
val recipientType = requestCode.toRecipientType()
addRecipientFromContactUri(recipientType, data.data)
}
@@ -519,7 +528,6 @@ class RecipientPresenter(
OPENPGP_USER_INTERACTION -> {
openPgpApiManager.onUserInteractionResult()
}
-
REQUEST_CODE_AUTOCRYPT -> {
asyncUpdateCryptoStatus()
}
@@ -541,8 +549,7 @@ class RecipientPresenter(
toggleEncryptionState(false)
}
OpenPgpProviderState.UI_REQUIRED -> {
-// TODO show openpgp settings
-
+ // TODO show openpgp settings
val pendingIntent = openPgpApiManager.userInteractionPendingIntent
recipientMvpView.launchUserInteractionPendingIntent(pendingIntent, OPENPGP_USER_INTERACTION)
}
@@ -564,7 +571,6 @@ class RecipientPresenter(
return
}
-
if (currentCryptoMode == CryptoMode.SIGN_ONLY) {
recipientMvpView.showErrorIsSignOnly()
return
@@ -584,7 +590,6 @@ class RecipientPresenter(
} else {
onCryptoModeChanged(CryptoMode.CHOICE_ENABLED)
if (showGotIt) {
- recipientMvpView.showOpenPgpEncryptExplanationDialog();
recipientMvpView.showOpenPgpEncryptExplanationDialog()
}
}
@@ -634,6 +639,7 @@ class RecipientPresenter(
require(messageBuilder !is PgpMessageBuilder) {
"PpgMessageBuilder must be called with ComposeCryptoStatus argument!"
}
+
messageBuilder.setTo(toAddresses)
messageBuilder.setCc(ccAddresses)
messageBuilder.setBcc(bccAddresses)
@@ -692,8 +698,6 @@ class RecipientPresenter(
return true
}
-
-
return false
}
@@ -704,6 +708,7 @@ class RecipientPresenter(
K9.saveSettingsAsync()
return true
}
+
return false
}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToPresenter.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToPresenter.kt
index 63099f0995b908c6b244415a1e8ca3461b3459b4..c8f33e0075ae1ce036a3c9d5a73eba0e866cd3a7 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToPresenter.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToPresenter.kt
@@ -5,11 +5,9 @@ import com.fsck.k9.Identity
import com.fsck.k9.mail.Address
import com.fsck.k9.mail.Message
-
private const val STATE_KEY_REPLY_TO_SHOWN = "com.fsck.k9.activity.compose.ReplyToPresenter.replyToShown"
class ReplyToPresenter(private val view: ReplyToView) {
-
private lateinit var identity: Identity
private var identityReplyTo: Array? = null
@@ -20,7 +18,6 @@ class ReplyToPresenter(private val view: ReplyToView) {
}
}
-
fun getAddresses(): Array {
return view.getAddresses()
}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToView.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToView.kt
index 2ddb9402d4f63c0582e01dd65fac48e035dacd52..76297080e585b7aef131c9abd7cf1e393a4285b3 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToView.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/compose/ReplyToView.kt
@@ -122,4 +122,4 @@ class ReplyToView(activity: MessageCompose) : View.OnClickListener {
replyToView.addTextChangedListener(textWatcher)
}
}
-}
\ No newline at end of file
+}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupBasics.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupBasics.java
index abf985c11bcf01785911862c0d4d23f2492b3f2a..ee56958a5aa58be0cd7ad0c2b14a7834d77ceee1 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupBasics.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupBasics.java
@@ -33,6 +33,7 @@ import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mailstore.SpecialLocalFoldersCreator;
import com.fsck.k9.ui.R;
import com.fsck.k9.ui.ConnectionSettings;
+import com.fsck.k9.ui.settings.ExtraAccountDiscovery;
import com.fsck.k9.view.ClientCertificateSpinner;
import com.fsck.k9.view.ClientCertificateSpinner.OnClientCertificateChangedListener;
import com.google.android.material.textfield.TextInputEditText;
@@ -301,6 +302,12 @@ public class AccountSetupBasics extends K9Activity
String email = mEmailView.getText().toString();
+ ConnectionSettings extraConnectionSettings = ExtraAccountDiscovery.discover(email);
+ if (extraConnectionSettings != null) {
+ finishAutoSetup(extraConnectionSettings);
+ return;
+ }
+
ConnectionSettings connectionSettings = providersXmlDiscoveryDiscover(email, DiscoveryTarget.INCOMING_AND_OUTGOING);
if (connectionSettings != null) {
finishAutoSetup(connectionSettings);
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
index a58531c76a6ba188b0fc147179351f0146d9c713..00522035b5c10df7efe4975b143eaf0a363f063e 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java
@@ -45,6 +45,7 @@ import com.fsck.k9.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmen
import com.fsck.k9.mail.AuthenticationFailedException;
import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.MailServerDirection;
+
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.filter.Hex;
import com.fsck.k9.preferences.Protocols;
@@ -213,33 +214,33 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
Object value = subjectAlternativeName.get(1);
String name;
switch (type) {
- case 0:
- Timber.w("SubjectAltName of type OtherName not supported.");
- continue;
- case 1: // RFC822Name
- name = (String)value;
- break;
- case 2: // DNSName
- name = (String)value;
- break;
- case 3:
- Timber.w("unsupported SubjectAltName of type x400Address");
- continue;
- case 4:
- Timber.w("unsupported SubjectAltName of type directoryName");
- continue;
- case 5:
- Timber.w("unsupported SubjectAltName of type ediPartyName");
- continue;
- case 6: // Uri
- name = (String)value;
- break;
- case 7: // ip-address
- name = (String)value;
- break;
- default:
- Timber.w("unsupported SubjectAltName of unknown type");
- continue;
+ case 0:
+ Timber.w("SubjectAltName of type OtherName not supported.");
+ continue;
+ case 1: // RFC822Name
+ name = (String)value;
+ break;
+ case 2: // DNSName
+ name = (String)value;
+ break;
+ case 3:
+ Timber.w("unsupported SubjectAltName of type x400Address");
+ continue;
+ case 4:
+ Timber.w("unsupported SubjectAltName of type directoryName");
+ continue;
+ case 5:
+ Timber.w("unsupported SubjectAltName of type ediPartyName");
+ continue;
+ case 6: // Uri
+ name = (String)value;
+ break;
+ case 7: // ip-address
+ name = (String)value;
+ break;
+ default:
+ Timber.w("unsupported SubjectAltName of unknown type");
+ continue;
}
// if some of the SubjectAltNames match the store or transport -host,
@@ -248,8 +249,8 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
//TODO: localize this string
altNamesText.append("Subject(alt): ").append(name).append(",...\n");
} else if (name.startsWith("*.") && (
- incomingServerHost.endsWith(name.substring(2)) ||
- outgoingServerHost.endsWith(name.substring(2)))) {
+ incomingServerHost.endsWith(name.substring(2)) ||
+ outgoingServerHost.endsWith(name.substring(2)))) {
//TODO: localize this string
altNamesText.append("Subject(alt): ").append(name).append(",...\n");
}
@@ -287,27 +288,27 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
// TODO: refactor with DialogFragment.
// This is difficult because we need to pass through chain[0] for onClick()
new AlertDialog.Builder(AccountSetupCheckSettings.this)
- .setTitle(getString(R.string.account_setup_failed_dlg_invalid_certificate_title))
- //.setMessage(getString(R.string.account_setup_failed_dlg_invalid_certificate)
- .setMessage(getString(msgResId, exMessage)
- + " " + chainInfo.toString()
- )
- .setCancelable(true)
- .setPositiveButton(
- getString(R.string.account_setup_failed_dlg_invalid_certificate_accept),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- acceptCertificate(chain[0]);
- }
- })
- .setNegativeButton(
- getString(R.string.account_setup_failed_dlg_invalid_certificate_reject),
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- })
- .show();
+ .setTitle(getString(R.string.account_setup_failed_dlg_invalid_certificate_title))
+ //.setMessage(getString(R.string.account_setup_failed_dlg_invalid_certificate)
+ .setMessage(getString(msgResId, exMessage)
+ + " " + chainInfo.toString()
+ )
+ .setCancelable(true)
+ .setPositiveButton(
+ getString(R.string.account_setup_failed_dlg_invalid_certificate_accept),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ acceptCertificate(chain[0]);
+ }
+ })
+ .setNegativeButton(
+ getString(R.string.account_setup_failed_dlg_invalid_certificate_reject),
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ })
+ .show();
}
});
}
@@ -315,7 +316,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
/**
* Permanently accepts a certificate for the INCOMING or OUTGOING direction
* by adding it to the local key store.
- *
+ *
* @param certificate
*/
private void acceptCertificate(X509Certificate certificate) {
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java
index 6299df3af64833543a6fe6ea05c7caa350392d72..b2c1323a5fd8a989996af0fc40d669354edc5e70 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java
@@ -22,7 +22,6 @@ import android.widget.Spinner;
import android.widget.Toast;
import com.fsck.k9.Account;
-import com.fsck.k9.Account.FolderMode;
import com.fsck.k9.DI;
import com.fsck.k9.LocalKeyStoreManager;
import com.fsck.k9.Preferences;
@@ -181,6 +180,15 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
}
boolean editSettings = Intent.ACTION_EDIT.equals(getIntent().getAction());
+ if (editSettings) {
+ TextInputLayoutHelper.configureAuthenticatedPasswordToggle(
+ mPasswordLayoutView,
+ this,
+ getString(R.string.account_setup_basics_show_password_biometrics_title),
+ getString(R.string.account_setup_basics_show_password_biometrics_subtitle),
+ getString(R.string.account_setup_basics_show_password_need_lock)
+ );
+ }
if (editSettings) {
TextInputLayoutHelper.configureAuthenticatedPasswordToggle(
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupOutgoing.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
index a183cacc5b2ee44d4865eb288623b6e68f58c32f..56ad5cdf2dbfb84998fc75e481b9af5e27faff36 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/AccountSetupOutgoing.java
@@ -1,3 +1,4 @@
+
package com.fsck.k9.activity.setup;
@@ -148,7 +149,6 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
}
boolean editSettings = Intent.ACTION_EDIT.equals(getIntent().getAction());
-
if (editSettings) {
TextInputLayoutHelper.configureAuthenticatedPasswordToggle(
mPasswordLayoutView,
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8e3c3065fdd549deed67e32c45543ce361437881
--- /dev/null
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt
@@ -0,0 +1,8 @@
+package com.fsck.k9.activity.setup.accountmanager
+
+object AccountManagerConstants {
+ const val EELO_ACCOUNT_TYPE = "e.foundation.webdav.eelo"
+ const val GOOGLE_ACCOUNT_TYPE = "foundation.e.accountmanager.google"
+ const val ACCOUNT_EMAIL_ADDRESS_KEY = "email_address"
+ const val MAIL_CONTENT_AUTHORITY = "foundation.e.mail.provider.AppContentProvider"
+}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..223884b5edc1a423b3826386b08299cdc42e9532
--- /dev/null
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java
@@ -0,0 +1,90 @@
+package com.fsck.k9.activity.setup.accountmanager;
+
+
+import android.content.Context;
+
+import com.fsck.k9.Account;
+import com.fsck.k9.Account.DeletePolicy;
+import com.fsck.k9.Core;
+import com.fsck.k9.DI;
+import com.fsck.k9.Preferences;
+import com.fsck.k9.account.AccountCreator;
+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.autodiscovery.providersxml.ProvidersXmlDiscovery;
+import com.fsck.k9.mail.ServerSettings;
+import com.fsck.k9.ui.ConnectionSettings;
+import com.fsck.k9.mailstore.SpecialLocalFoldersCreator;
+import timber.log.Timber;
+
+
+public class EeloAccountCreator {
+ private static final ProvidersXmlDiscovery providersXmlDiscovery = DI.get(ProvidersXmlDiscovery.class);
+ private static final AccountCreator accountCreator = DI.get(AccountCreator.class);
+ private static final SpecialLocalFoldersCreator localFoldersCreator = DI.get(SpecialLocalFoldersCreator.class);
+
+ public static void createAccount(Context context, String emailId, String password) {
+ Preferences preferences = Preferences.getPreferences(context);
+
+ Account account = preferences.newAccount();
+ account.setChipColor(accountCreator.pickColor());
+ account.setEmail(emailId);
+ account.setDescription(emailId);
+
+ ConnectionSettings connectionSettings = providersXmlDiscoveryDiscover(emailId);
+ if (connectionSettings == null) {
+ Timber.e("Error while trying to initialise account configuration.");
+ return;
+ }
+ ServerSettings incomingSettings = connectionSettings.getIncoming().newPassword(password);
+ account.setIncomingServerSettings(incomingSettings);
+ ServerSettings outgoingSettings = connectionSettings.getOutgoing().newPassword(password);
+ account.setOutgoingServerSettings(outgoingSettings);
+
+ DeletePolicy deletePolicy = accountCreator.getDefaultDeletePolicy(incomingSettings.type);
+ account.setDeletePolicy(deletePolicy);
+
+ localFoldersCreator.createSpecialLocalFolders(account);
+ account.markSetupFinished();
+
+ preferences.saveAccount(account);
+ Core.setServicesEnabled(context);
+ }
+
+
+
+ private static ConnectionSettings providersXmlDiscoveryDiscover(String email) {
+ DiscoveryResults discoveryResults =
+ providersXmlDiscovery.discover(email, DiscoveryTarget.INCOMING_AND_OUTGOING);
+ if (discoveryResults == null ||
+ (discoveryResults.getIncoming().size() < 1 || discoveryResults.getOutgoing().size() < 1)) {
+ return null;
+ }
+ DiscoveredServerSettings incoming = discoveryResults.getIncoming().get(0);
+ DiscoveredServerSettings outgoing = discoveryResults.getOutgoing().get(0);
+ return new ConnectionSettings(
+ new ServerSettings(
+ incoming.getProtocol(),
+ incoming.getHost(),
+ incoming.getPort(),
+ incoming.getSecurity(),
+ incoming.getAuthType(),
+ incoming.getUsername(),
+ null,
+ null
+ ),
+ new ServerSettings(
+ outgoing.getProtocol(),
+ outgoing.getHost(),
+ outgoing.getPort(),
+ outgoing.getSecurity(),
+ outgoing.getAuthType(),
+ outgoing.getUsername(),
+ null,
+ null
+ )
+ );
+ }
+}
+
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterExtractor.kt b/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterExtractor.kt
index 3d6e29b44bcfe6b87741f48f684024f08dcdb7e3..3b387a678ac622f0008d215bab205d3de6547805 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterExtractor.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/contacts/ContactLetterExtractor.kt
@@ -1,7 +1,6 @@
package com.fsck.k9.contacts
import com.fsck.k9.mail.Address
-import java.util.Locale
class ContactLetterExtractor {
fun extractContactLetter(address: Address): String {
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/fragment/MessageListFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/fragment/MessageListFragment.kt
index b745e67d9192ed7d5c551e17b7c059db0839bc4e..04e7e0b7e1f62dd3a8a96414e506b39d2463734d 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/fragment/MessageListFragment.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/fragment/MessageListFragment.kt
@@ -70,6 +70,7 @@ class MessageListFragment :
private val folderNameFormatter: FolderNameFormatter by lazy { folderNameFormatterFactory.create(requireContext()) }
private val messagingController: MessagingController by inject()
private val preferences: Preferences by inject()
+ private val clock: Clock by inject()
private val handler = MessageListHandler(this)
private val activityListener = MessageListActivityListener()
@@ -252,7 +253,7 @@ class MessageListFragment :
contactsPictureLoader = ContactPicture.getContactPictureLoader(),
listItemListener = this,
appearance = messageListAppearance,
- relativeDateTimeFormatter = RelativeDateTimeFormatter(requireContext(), Clock.INSTANCE)
+ relativeDateTimeFormatter = RelativeDateTimeFormatter(requireContext(), clock)
)
adapter.activeMessage = activeMessage
@@ -985,7 +986,14 @@ class MessageListFragment :
else -> null
}
- displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_MOVE, folderId, messages.first().accountUuid, null, messages)
+ displayFolderChoice(
+ operation = FolderOperation.MOVE,
+ requestCode = ACTIVITY_CHOOSE_FOLDER_MOVE,
+ sourceFolderId = folderId,
+ accountUuid = messages.first().accountUuid,
+ lastSelectedFolderId = null,
+ messages = messages
+ )
}
private fun onCopy(message: MessageReference) {
@@ -1001,18 +1009,31 @@ class MessageListFragment :
else -> null
}
- displayFolderChoice(ACTIVITY_CHOOSE_FOLDER_COPY, folderId, messages.first().accountUuid, null, messages)
+ displayFolderChoice(
+ operation = FolderOperation.COPY,
+ requestCode = ACTIVITY_CHOOSE_FOLDER_COPY,
+ sourceFolderId = folderId,
+ accountUuid = messages.first().accountUuid,
+ lastSelectedFolderId = null,
+ messages = messages
+ )
}
private fun displayFolderChoice(
+ operation: FolderOperation,
requestCode: Int,
sourceFolderId: Long?,
accountUuid: String,
lastSelectedFolderId: Long?,
messages: List
) {
+ val action = when (operation) {
+ FolderOperation.COPY -> ChooseFolderActivity.Action.COPY
+ FolderOperation.MOVE -> ChooseFolderActivity.Action.MOVE
+ }
val intent = ChooseFolderActivity.buildLaunchIntent(
context = requireContext(),
+ action = action,
accountUuid = accountUuid,
currentFolderId = sourceFolderId,
scrollToFolderId = lastSelectedFolderId,
@@ -1254,7 +1275,7 @@ class MessageListFragment :
private fun getReferenceForPosition(position: Int): MessageReference {
val item = adapter.getItem(position)
- return MessageReference(item.account.uuid, item.folderId, item.messageUid, null)
+ return MessageReference(item.account.uuid, item.folderId, item.messageUid)
}
private fun openMessageAtPosition(position: Int) {
@@ -1309,7 +1330,7 @@ class MessageListFragment :
return adapter.messages
.asSequence()
.filter { it.uniqueId in selected }
- .map { MessageReference(it.account.uuid, it.folderId, it.messageUid, null) }
+ .map { MessageReference(it.account.uuid, it.folderId, it.messageUid) }
.toList()
}
@@ -1413,9 +1434,9 @@ class MessageListFragment :
val isRemoteSearchAllowed: Boolean
get() = isManualSearch && !isRemoteSearch && isSingleFolderMode && account?.isAllowRemoteSearch == true
- fun onSearchRequested(): Boolean {
+ fun onSearchRequested(query: String): Boolean {
val folderId = currentFolder?.databaseId
- return fragmentListener.startSearch(account, folderId)
+ return fragmentListener.startSearch(query, account, folderId)
}
fun setMessageList(messageListInfo: MessageListInfo) {
@@ -1851,12 +1872,13 @@ class MessageListFragment :
R.id.unflag -> setFlagForSelected(Flag.FLAGGED, false)
R.id.select_all -> selectAll()
R.id.archive -> {
- // only if the account supports this
onArchive(checkedMessages)
+ // TODO: Only finish action mode if all messages have been moved.
selectedCount = 0
}
R.id.spam -> {
onSpam(checkedMessages)
+ // TODO: Only finish action mode if all messages have been moved.
selectedCount = 0
}
R.id.move -> {
@@ -1896,7 +1918,7 @@ class MessageListFragment :
fun openMessage(messageReference: MessageReference)
fun setMessageListTitle(title: String, subtitle: String?)
fun onCompose(account: Account?)
- fun startSearch(account: Account?, folderId: Long?): Boolean
+ fun startSearch(query: String, account: Account?, folderId: Long?): Boolean
fun remoteSearchStarted()
fun goBack()
fun updateMenu()
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/FlowExtensions.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/FlowExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..61689a8e5de118020667f655eae0e9ad4a33025e
--- /dev/null
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/FlowExtensions.kt
@@ -0,0 +1,17 @@
+package com.fsck.k9.ui
+
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+
+fun Flow.observe(lifecycleOwner: LifecycleOwner, action: suspend (T) -> Unit) {
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ collect(action)
+ }
+ }
+}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt
index 631035cbf60b6d2c73bb0eef843645d092ca6908..6974dc861e8b163090cb4ae3606cda3684f46e3c 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/K9Drawer.kt
@@ -28,7 +28,9 @@ import com.fsck.k9.ui.account.AccountsViewModel
import com.fsck.k9.ui.account.DisplayAccount
import com.fsck.k9.ui.base.Theme
import com.fsck.k9.ui.base.ThemeManager
+import com.fsck.k9.ui.folders.DisplayUnifiedInbox
import com.fsck.k9.ui.folders.FolderIconProvider
+import com.fsck.k9.ui.folders.FolderList
import com.fsck.k9.ui.folders.FolderNameFormatter
import com.fsck.k9.ui.folders.FoldersViewModel
import com.fsck.k9.ui.settings.SettingsActivity
@@ -56,8 +58,6 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.parameter.parametersOf
-import com.fsck.k9.ui.folders.FolderList
-import com.fsck.k9.ui.folders.DisplayUnifiedInbox
private const val UNREAD_SYMBOL = "\u2B24"
private const val STARRED_SYMBOL = "\u2605"
@@ -178,21 +178,18 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
}
}
- /**
- * Format the unread and starred counts for display in the fragment Badge box
- */
private fun buildBadgeText(displayAccount: DisplayAccount): String? {
return buildBadgeText(displayAccount.unreadMessageCount, displayAccount.starredMessageCount)
}
- private fun buildBadgeText(unifiedInbox: DisplayUnifiedInbox): String? {
- return buildBadgeText(unifiedInbox.unreadMessageCount, unifiedInbox.starredMessageCount)
- }
-
private fun buildBadgeText(displayFolder: DisplayFolder): String? {
return buildBadgeText(displayFolder.unreadMessageCount, displayFolder.starredMessageCount)
}
+ private fun buildBadgeText(unifiedInbox: DisplayUnifiedInbox): String? {
+ return buildBadgeText(unifiedInbox.unreadMessageCount, unifiedInbox.starredMessageCount)
+ }
+
private fun buildBadgeText(unreadCount: Int, starredCount: Int): String? {
return if (K9.isShowStarredCount) {
buildBadgeTextWithStarredCount(unreadCount, starredCount)
@@ -263,7 +260,6 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
var newActiveProfile: IProfile? = null
val accountItems = displayAccounts.map { displayAccount ->
val account = displayAccount.account
- val drawerId = (account.accountNumber + 1 shl DRAWER_ACCOUNT_SHIFT).toLong()
val drawerColors = getDrawerColorsForAccount(account)
val selectedTextColor = drawerColors.accentColor.toSelectedColorStateList()
@@ -272,7 +268,7 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
isNameShown = true
nameText = account.description ?: ""
descriptionText = account.email
- identifier = drawerId
+ identifier = account.drawerId
tag = account
textColor = selectedTextColor
descriptionTextColor = selectedTextColor
@@ -314,11 +310,10 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
fun updateUserAccountsAndFolders(account: Account?) {
if (account != null) {
initializeWithAccountColor(account)
- headerView.setActiveProfile((account.accountNumber + 1 shl DRAWER_ACCOUNT_SHIFT).toLong())
+ headerView.setActiveProfile(account.drawerId)
foldersViewModel.loadFolders(account)
}
- // Account can be null to refresh all (unified inbox or account list).
swipeRefreshLayout.setOnRefreshListener {
refreshAndShowProgress(if (headerView.selectionListShown) null else account)
}
@@ -385,7 +380,6 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
badgeText = text
badgeStyle = folderBadgeStyle
}
-
}
sliderView.addItems(unifiedInboxItem)
@@ -396,9 +390,10 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
}
}
+ val accountOffset = folderList.accountId.toLong() shl DRAWER_ACCOUNT_SHIFT
for (displayFolder in folderList.folders) {
val folder = displayFolder.folder
- val drawerId = folder.id shl DRAWER_FOLDER_SHIFT
+ val drawerId = accountOffset + folder.id
val drawerItem = FolderDrawerItem().apply {
iconRes = folderIconProvider.getFolderIcon(folder.type)
@@ -409,7 +404,6 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
badgeText = text
badgeStyle = folderBadgeStyle
}
-
selectedColorInt = selectedBackgroundColor
textColor = selectedTextColor
}
@@ -530,10 +524,12 @@ class K9Drawer(private val parent: MessageList, savedInstanceState: Bundle?) : K
private val IProfile.accountUuid: String?
get() = (this.tag as? Account)?.uuid
+ private val Account.drawerId: Long
+ get() = (accountNumber + 1).toLong()
+
companion object {
- // Bit shift for identifiers of user folders items, to leave space for other items
- private const val DRAWER_FOLDER_SHIFT: Int = 20
- private const val DRAWER_ACCOUNT_SHIFT: Int = 3
+ // Use the lower 48 bits for the folder ID, the upper bits for the account's drawer ID
+ private const val DRAWER_ACCOUNT_SHIFT: Int = 48
private const val DRAWER_ID_UNIFIED_INBOX: Long = 0
private const val DRAWER_ID_DIVIDER: Long = 1
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageLoader.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageLoader.kt
index 5097a21bad88610ee7e1b34aa572a9f5cc726aef..c13617b47d99fe6f9b2433829b8555590f926fcc 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageLoader.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountImageLoader.kt
@@ -1,10 +1,10 @@
package com.fsck.k9.ui.account
-import android.app.Activity
import android.content.Context
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
+import com.fsck.k9.ui.helper.findActivity
/**
* Load the account image into an [ImageView].
@@ -28,7 +28,7 @@ class AccountImageLoader(private val accountFallbackImageProvider: AccountFallba
}
private inline fun Context.ifNotDestroyed(block: (Context) -> Unit) {
- if ((this as? Activity)?.isDestroyed == true) {
+ if (findActivity()?.isDestroyed == true) {
// Do nothing because Glide would throw an exception
} else {
block(this)
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountsLiveData.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountsLiveData.kt
deleted file mode 100644
index 0346fe52dfbca5ac2ac7e13d9a0d56fc0e6cc2dd..0000000000000000000000000000000000000000
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/AccountsLiveData.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.fsck.k9.ui.account
-
-import androidx.lifecycle.LiveData
-import com.fsck.k9.Account
-import com.fsck.k9.AccountsChangeListener
-import com.fsck.k9.Preferences
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-
-class AccountsLiveData(val preferences: Preferences) : LiveData>(), AccountsChangeListener {
-
- private fun loadAccountsAsync() {
- GlobalScope.launch(Dispatchers.Main) {
- value = withContext(Dispatchers.IO) {
- loadAccounts()
- }
- }
- }
-
- override fun onAccountsChanged() {
- loadAccountsAsync()
- }
-
- private fun loadAccounts(): List {
- return preferences.accounts
- }
-
- override fun onActive() {
- super.onActive()
- preferences.addOnAccountsChangeListener(this)
- loadAccountsAsync()
- }
-
- override fun onInactive() {
- super.onInactive()
- preferences.removeOnAccountsChangeListener(this)
- }
-}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/DisplayAccount.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/DisplayAccount.kt
index 982a5af3f860ffab071ea386470cbc6a5b8491a6..62de252f80b42c5cd02d61e6e5a8eca3ea958d10 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/DisplayAccount.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/account/DisplayAccount.kt
@@ -7,4 +7,4 @@ data class DisplayAccount(
val account: Account,
val unreadMessageCount: Int,
val starredMessageCount: Int
-)
\ No newline at end of file
+)
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt
index b351d7bad409691b45c3a5231f2f28722a8f70a6..e6e77e3f0f74f3b73fb08533e1c3712f5c568508 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderActivity.kt
@@ -36,6 +36,7 @@ class ChooseFolderActivity : K9Activity() {
private lateinit var recyclerView: RecyclerView
private lateinit var itemAdapter: ItemAdapter
private lateinit var account: Account
+ private lateinit var action: Action
private var currentFolderId: Long? = null
private var scrollToFolderId: Long? = null
private var messageReference: String? = null
@@ -44,13 +45,19 @@ class ChooseFolderActivity : K9Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setLayout(R.layout.folder_list)
- setTitle(R.string.choose_folder_title)
if (!decodeArguments(savedInstanceState)) {
finish()
return
}
+ when (action) {
+ Action.MOVE -> setTitle(R.string.choose_folder_move_title)
+ Action.COPY -> setTitle(R.string.choose_folder_copy_title)
+ else -> setTitle(R.string.choose_folder_title)
+ }
+
+ initializeActionBar()
initializeFolderList()
viewModel.getFolders().observe(this) { folders ->
@@ -64,6 +71,8 @@ class ChooseFolderActivity : K9Activity() {
}
private fun decodeArguments(savedInstanceState: Bundle?): Boolean {
+ action = intent.action?.toAction() ?: error("Missing Intent action")
+
val accountUuid = intent.getStringExtra(EXTRA_ACCOUNT) ?: return false
account = preferences.getAccount(accountUuid) ?: return false
@@ -84,6 +93,12 @@ class ChooseFolderActivity : K9Activity() {
return if (showDisplayableOnly) account.folderDisplayMode else account.folderTargetMode
}
+ private fun initializeActionBar() {
+ val actionBar = supportActionBar ?: error("Action bar missing")
+ actionBar.setDisplayHomeAsUpEnabled(true)
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_close)
+ }
+
private fun initializeFolderList() {
itemAdapter = ItemAdapter()
itemAdapter.itemFilter.filterPredicate = ::folderListFilter
@@ -161,6 +176,7 @@ class ChooseFolderActivity : K9Activity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
+ android.R.id.home -> finish()
R.id.display_1st_class -> setDisplayMode(FolderMode.FIRST_CLASS)
R.id.display_1st_and_2nd_class -> setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS)
R.id.display_not_second_class -> setDisplayMode(FolderMode.NOT_SECOND_CLASS)
@@ -211,6 +227,14 @@ class ChooseFolderActivity : K9Activity() {
return if (containsKey(name)) getLong(name) else null
}
+ private fun String.toAction() = Action.valueOf(this)
+
+ enum class Action {
+ MOVE,
+ COPY,
+ CHOOSE
+ }
+
companion object {
private const val STATE_SCROLL_TO_FOLDER_ID = "scrollToFolderId"
private const val STATE_DISPLAY_MODE = "displayMode"
@@ -226,6 +250,7 @@ class ChooseFolderActivity : K9Activity() {
@JvmStatic
fun buildLaunchIntent(
context: Context,
+ action: Action,
accountUuid: String,
currentFolderId: Long? = null,
scrollToFolderId: Long? = null,
@@ -233,6 +258,7 @@ class ChooseFolderActivity : K9Activity() {
messageReference: MessageReference? = null
): Intent {
return Intent(context, ChooseFolderActivity::class.java).apply {
+ this.action = action.toString()
putExtra(EXTRA_ACCOUNT, accountUuid)
currentFolderId?.let { putExtra(EXTRA_CURRENT_FOLDER_ID, currentFolderId) }
scrollToFolderId?.let { putExtra(EXTRA_SCROLL_TO_FOLDER_ID, scrollToFolderId) }
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderViewModel.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderViewModel.kt
index 2007ba05c91d8ee70f8fe8e31f0bf3475250a39f..ab9a4b9372ee93612d793bf57fafadab80947433 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderViewModel.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/choosefolder/ChooseFolderViewModel.kt
@@ -20,6 +20,7 @@ class ChooseFolderViewModel(private val folderRepository: FolderRepository) : Vi
.flatMapLatest { (account, displayMode) ->
folderRepository.getDisplayFoldersFlow(account, displayMode)
}
+
var currentDisplayMode: FolderMode? = null
private set
@@ -35,4 +36,4 @@ class ChooseFolderViewModel(private val folderRepository: FolderRepository) : Vi
}
}
-private data class DisplayMode(val account: Account, val displayMode: FolderMode)
\ No newline at end of file
+private data class DisplayMode(val account: Account, val displayMode: FolderMode)
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/FoldersViewModel.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/FoldersViewModel.kt
index 7a42b42da69d2e1da533d1870ae9bb68d2a03f41..ef66e21cd4a6f78dbd703bd4b26f1cd60c965324 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/FoldersViewModel.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/folders/FoldersViewModel.kt
@@ -1,25 +1,24 @@
package com.fsck.k9.ui.folders
import androidx.lifecycle.LiveData
-import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.ViewModel
-import com.fsck.k9.Account
-import com.fsck.k9.mailstore.DisplayFolder
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
+import com.fsck.k9.Account
+import com.fsck.k9.K9
+import com.fsck.k9.controller.MessageCountsProvider
+import com.fsck.k9.mailstore.DisplayFolder
import com.fsck.k9.mailstore.FolderRepository
+import com.fsck.k9.search.SearchAccount
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
-import com.fsck.k9.search.SearchAccount
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.Dispatchers
-import com.fsck.k9.K9
-import com.fsck.k9.controller.MessageCountsProvider
+import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class)
class FoldersViewModel(
@@ -31,13 +30,20 @@ class FoldersViewModel(
private val foldersFlow = inputFlow
.flatMapLatest { account ->
if (account == null) {
- flowOf(emptyList())
+ flowOf(0 to emptyList())
} else {
folderRepository.getDisplayFoldersFlow(account)
+ .map { displayFolders ->
+ account.accountNumber to displayFolders
+ }
}
}
- .map { displayFolders ->
- FolderList(unifiedInbox = createDisplayUnifiedInbox(), folders = displayFolders)
+ .map { (accountNumber, displayFolders) ->
+ FolderList(
+ unifiedInbox = createDisplayUnifiedInbox(),
+ accountId = accountNumber + 1,
+ folders = displayFolders
+ )
}
.flowOn(backgroundDispatcher)
@@ -61,16 +67,19 @@ class FoldersViewModel(
// When switching accounts we want to remove the old list right away, not keep it until the new list
// has been loaded.
inputFlow.emit(null)
+
inputFlow.emit(account)
}
}
}
+
data class FolderList(
val unifiedInbox: DisplayUnifiedInbox?,
+ val accountId: Int,
val folders: List
)
data class DisplayUnifiedInbox(
val unreadMessageCount: Int,
val starredMessageCount: Int
-)
\ No newline at end of file
+)
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..08b8115fe29c20b29bf0a29948f519b66c1e4dbc
--- /dev/null
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/helper/ContextExtensions.kt
@@ -0,0 +1,11 @@
+@file:JvmName("ContextHelper")
+package com.fsck.k9.ui.helper
+
+import android.app.Activity
+import android.content.Context
+import android.content.ContextWrapper
+
+// Source: https://stackoverflow.com/a/58249983
+tailrec fun Context.findActivity(): Activity? {
+ return this as? Activity ?: (this as? ContextWrapper)?.baseContext?.findActivity()
+}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/FolderSettingsDataStore.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/FolderSettingsDataStore.kt
index d6938b94c80387718e4a62ad76b1c2715bfc96a7..4775b493a9e1733084947a2c1b9893a41c7970dc 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/FolderSettingsDataStore.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/managefolders/FolderSettingsDataStore.kt
@@ -1,19 +1,19 @@
package com.fsck.k9.ui.managefolders
import androidx.preference.PreferenceDataStore
+import com.fsck.k9.Account
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.mailstore.FolderDetails
import com.fsck.k9.mailstore.FolderRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
-import com.fsck.k9.Account
import kotlinx.coroutines.launch
class FolderSettingsDataStore(
private val folderRepository: FolderRepository,
- private var folder: FolderDetails,
- private val account: Account
+ private val account: Account,
+ private var folder: FolderDetails
) : PreferenceDataStore() {
private val saveScope = CoroutineScope(GlobalScope.coroutineContext + Dispatchers.IO)
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/AttachmentView.java b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/AttachmentView.java
index 8e7934b59a6bd6c345a3da9571860239549df9b0..30e4c686f058665c6e388e7af27815cc00948ab7 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/AttachmentView.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/AttachmentView.java
@@ -14,6 +14,7 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.fsck.k9.K9;
import com.fsck.k9.ui.R;
+import com.fsck.k9.ui.helper.ContextHelper;
import com.fsck.k9.ui.helper.SizeFormatter;
import com.fsck.k9.mailstore.AttachmentViewInfo;
@@ -122,12 +123,13 @@ public class AttachmentView extends FrameLayout implements OnClickListener {
public void refreshThumbnail() {
Context context = getContext();
- if (context instanceof Activity && ((Activity) context).isDestroyed()) {
+ Activity activity = ContextHelper.findActivity(context);
+ if (activity != null && activity.isDestroyed()) {
// Do nothing because Glide would throw an exception
return;
}
preview.setVisibility(View.VISIBLE);
- Glide.with(context)
+ Glide.with(getContext())
.load(attachment.internalUri)
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.NONE)
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java
index 7d62b76aaa0a7e47abf84697f9c1d16b9498e8ee..d38cbab8c146cdcb6917ad3c0caebfa9b88e3eca 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java
@@ -385,7 +385,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
return;
}
- startRefileActivity(ACTIVITY_CHOOSE_FOLDER_MOVE);
+ startRefileActivity(FolderOperation.MOVE, ACTIVITY_CHOOSE_FOLDER_MOVE);
}
@@ -400,7 +400,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
return;
}
- startRefileActivity(ACTIVITY_CHOOSE_FOLDER_COPY);
+ startRefileActivity(FolderOperation.COPY, ACTIVITY_CHOOSE_FOLDER_COPY);
}
public void onMoveToDrafts() {
@@ -421,11 +421,18 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
onRefile(mAccount.getSpamFolderId());
}
- private void startRefileActivity(int requestCode) {
+ private void startRefileActivity(FolderOperation operation, int requestCode) {
String accountUuid = mAccount.getUuid();
long currentFolderId = mMessageReference.getFolderId();
Long scrollToFolderId = mAccount.getLastSelectedFolderId();
- Intent intent = ChooseFolderActivity.buildLaunchIntent(requireActivity(), accountUuid, currentFolderId,
+ final ChooseFolderActivity.Action action;
+ if (operation == FolderOperation.MOVE) {
+ action = ChooseFolderActivity.Action.MOVE;
+ } else {
+ action = ChooseFolderActivity.Action.COPY;
+ }
+
+ Intent intent = ChooseFolderActivity.buildLaunchIntent(requireActivity(), action, accountUuid, currentFolderId,
scrollToFolderId, false, mMessageReference);
startActivityForResult(intent, requestCode);
@@ -853,4 +860,8 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
private AttachmentController getAttachmentController(AttachmentViewInfo attachment) {
return new AttachmentController(mController, this, attachment);
}
+
+ private enum FolderOperation {
+ COPY, MOVE
+ }
}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt
index 771081230a0592f9175787de5056975b2cb3fe37..c76fd9a8c6927719c457feabd337caf268b78090 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt
@@ -1,11 +1,11 @@
package com.fsck.k9.ui.settings
import com.fsck.k9.helper.NamedThreadFactory
-import com.fsck.k9.ui.account.AccountsLiveData
import com.fsck.k9.ui.settings.account.AccountSettingsDataStoreFactory
import com.fsck.k9.ui.settings.account.AccountSettingsViewModel
import com.fsck.k9.ui.settings.export.SettingsExportViewModel
import com.fsck.k9.ui.settings.general.GeneralSettingsDataStore
+import com.fsck.k9.ui.settings.general.GeneralSettingsViewModel
import com.fsck.k9.ui.settings.import.AccountActivator
import com.fsck.k9.ui.settings.import.SettingsImportResultViewModel
import com.fsck.k9.ui.settings.import.SettingsImportViewModel
@@ -15,9 +15,9 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module
val settingsUiModule = module {
- factory { AccountsLiveData(get()) }
- viewModel { SettingsViewModel(accountManager = get(), accounts = get()) }
+ viewModel { SettingsViewModel(accountManager = get()) }
+ viewModel { GeneralSettingsViewModel(logFileWriter = get()) }
factory { GeneralSettingsDataStore(jobManager = get(), themeManager = get(), appLanguageManager = get()) }
single(named("SaveSettingsExecutorService")) {
Executors.newSingleThreadExecutor(NamedThreadFactory("SaveSettings"))
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt
index 80d29fb3c002a7cf31f20baf6852450905c5601d..5036cd72a7ff2e84f41c50caa28069d97e7833a8 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/SettingsViewModel.kt
@@ -1,9 +1,9 @@
package com.fsck.k9.ui.settings
import androidx.lifecycle.ViewModel
+import androidx.lifecycle.asLiveData
import com.fsck.k9.Account
import com.fsck.k9.preferences.AccountManager
-import com.fsck.k9.ui.account.AccountsLiveData
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -15,8 +15,8 @@ internal class SettingsViewModel(
private val accountManager: AccountManager,
private val coroutineScope: CoroutineScope = GlobalScope,
private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO,
- val accounts: AccountsLiveData
) : ViewModel() {
+ val accounts = accountManager.getAccountsFlow().asLiveData()
fun moveAccount(account: Account, newPosition: Int) {
coroutineScope.launch(coroutineDispatcher) {
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt
index 35363db1406cb9297d6893554d878687eb60e4db..6721ba79acbeb206aee514b6d1f1797b121f254d 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsFragment.kt
@@ -409,4 +409,4 @@ class AccountSettingsFragment : PreferenceFragmentCompat(), ConfirmationDialogFr
PreferenceFragmentCompat.ARG_PREFERENCE_ROOT to rootKey
)
}
-}
\ No newline at end of file
+}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsViewModel.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsViewModel.kt
index dc1c2c44b5fa55c946bb69f41c3e8b28e1f7ea60..e35317c60137af889c266cb670101dc45a80dd3b 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsViewModel.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/account/AccountSettingsViewModel.kt
@@ -3,35 +3,37 @@ package com.fsck.k9.ui.settings.account
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
+import androidx.lifecycle.asLiveData
+import androidx.lifecycle.viewModelScope
import com.fsck.k9.Account
-import com.fsck.k9.Preferences
import com.fsck.k9.mailstore.FolderRepository
import com.fsck.k9.mailstore.FolderType
import com.fsck.k9.mailstore.RemoteFolder
import com.fsck.k9.mailstore.SpecialFolderSelectionStrategy
-import com.fsck.k9.ui.account.AccountsLiveData
+import com.fsck.k9.preferences.AccountManager
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class AccountSettingsViewModel(
- private val preferences: Preferences,
+ private val accountManager: AccountManager,
private val folderRepository: FolderRepository,
- private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy
+ private val specialFolderSelectionStrategy: SpecialFolderSelectionStrategy,
+ private val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO
) : ViewModel() {
- val accounts = AccountsLiveData(preferences)
- private val accountLiveData = MutableLiveData()
+ val accounts = accountManager.getAccountsFlow().asLiveData()
+ private var accountUuid: String? = null
+ private val accountLiveData = MutableLiveData()
private val foldersLiveData = MutableLiveData()
- fun getAccount(accountUuid: String): LiveData {
- if (accountLiveData.value == null) {
-
- GlobalScope.launch(Dispatchers.Main) {
- val account = withContext(Dispatchers.IO) {
+ fun getAccount(accountUuid: String): LiveData {
+ if (this.accountUuid != accountUuid) {
+ this.accountUuid = accountUuid
+ viewModelScope.launch {
+ val account = withContext(backgroundDispatcher) {
loadAccount(accountUuid)
}
- accountLiveData.value = account
}
}
@@ -43,13 +45,16 @@ class AccountSettingsViewModel(
* doesn't support asynchronous preference loading.
*/
fun getAccountBlocking(accountUuid: String): Account {
- return accountLiveData.value ?: loadAccount(accountUuid).also {
- accountLiveData.value = it
- }
+ return accountLiveData.value
+ ?: loadAccount(accountUuid).also { account ->
+ this.accountUuid = accountUuid
+ accountLiveData.value = account
+ }
+ ?: error("Account $accountUuid not found")
}
- private fun loadAccount(accountUuid: String): Account {
- return preferences.getAccount(accountUuid) ?: error("Account $accountUuid not found")
+ private fun loadAccount(accountUuid: String): Account? {
+ return accountManager.getAccount(accountUuid)
}
fun getFolders(account: Account): LiveData {
@@ -61,8 +66,8 @@ class AccountSettingsViewModel(
}
private fun loadFolders(account: Account) {
- GlobalScope.launch(Dispatchers.Main) {
- val remoteFolderInfo = withContext(Dispatchers.IO) {
+ viewModelScope.launch {
+ val remoteFolderInfo = withContext(backgroundDispatcher) {
val folders = folderRepository.getRemoteFolders(account)
val automaticSpecialFolders = getAutomaticSpecialFolders(folders)
RemoteFolderInfo(folders, automaticSpecialFolders)
@@ -70,7 +75,6 @@ class AccountSettingsViewModel(
foldersLiveData.value = remoteFolderInfo
}
}
- }
private fun getAutomaticSpecialFolders(folders: List): Map {
return mapOf(
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt
index 7fab73307a71fd35dc2b04d9478638430c54c678..f8d31ccab3d0f6b41c01b2df12c02b297e2f04d6 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt
@@ -2,21 +2,49 @@ package com.fsck.k9.ui.settings.general
import android.os.Build
import android.os.Bundle
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
import androidx.preference.ListPreference
import com.fsck.k9.ui.R
+import com.fsck.k9.ui.observe
import com.fsck.k9.ui.withArguments
+import com.google.android.material.snackbar.Snackbar
import com.takisoft.preferencex.PreferenceFragmentCompat
import org.koin.android.ext.android.inject
+import org.koin.androidx.viewmodel.ext.android.viewModel
class GeneralSettingsFragment : PreferenceFragmentCompat() {
+ private val viewModel: GeneralSettingsViewModel by viewModel()
private val dataStore: GeneralSettingsDataStore by inject()
+ private var rootKey: String? = null
+ private var currentUiState: GeneralSettingsUiState? = null
+ private var snackbar: Snackbar? = null
+
+ private val exportLogsResultContract = registerForActivityResult(CreateDocument()) { contentUri ->
+ if (contentUri != null) {
+ viewModel.exportLogs(contentUri)
+ }
+ }
+
override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) {
preferenceManager.preferenceDataStore = dataStore
-
+ this.rootKey = rootKey
+ setHasOptionsMenu(true)
setPreferencesFromResource(R.xml.general_settings, rootKey)
initializeTheme()
+
+ viewModel.uiState.observe(this) { uiState ->
+ updateUiState(uiState)
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ dismissSnackbar()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@@ -24,6 +52,24 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
activity?.title = preferenceScreen.title
}
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ if (rootKey == PREFERENCE_SCREEN_DEBUGGING) {
+ inflater.inflate(R.menu.debug_settings_option, menu)
+ currentUiState?.let { uiState ->
+ menu.findItem(R.id.exportLogs).isEnabled = uiState.isExportLogsMenuEnabled
+ }
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == R.id.exportLogs) {
+ exportLogsResultContract.launch(GeneralSettingsViewModel.DEFAULT_FILENAME)
+ return true
+ }
+
+ return super.onOptionsItemSelected(item)
+ }
+
private fun initializeTheme() {
(findPreference(PREFERENCE_THEME) as? ListPreference)?.apply {
if (Build.VERSION.SDK_INT < 28) {
@@ -33,8 +79,45 @@ class GeneralSettingsFragment : PreferenceFragmentCompat() {
}
}
+ private fun updateUiState(uiState: GeneralSettingsUiState) {
+ val oldUiState = currentUiState
+ currentUiState = uiState
+
+ if (oldUiState?.isExportLogsMenuEnabled != uiState.isExportLogsMenuEnabled) {
+ setExportLogsMenuEnabled()
+ }
+
+ if (oldUiState?.snackbarState != uiState.snackbarState) {
+ setSnackbarState(uiState.snackbarState)
+ }
+ }
+
+ private fun setExportLogsMenuEnabled() {
+ requireActivity().invalidateOptionsMenu()
+ }
+
+ private fun setSnackbarState(snackbarState: SnackbarState) {
+ when (snackbarState) {
+ SnackbarState.Hidden -> dismissSnackbar()
+ SnackbarState.ExportLogSuccess -> showSnackbar(R.string.debug_export_logs_success)
+ SnackbarState.ExportLogFailure -> showSnackbar(R.string.debug_export_logs_failure)
+ }
+ }
+
+ private fun dismissSnackbar() {
+ snackbar?.dismiss()
+ snackbar = null
+ }
+
+ private fun showSnackbar(message: Int) {
+ Snackbar.make(requireView(), message, Snackbar.LENGTH_INDEFINITE)
+ .also { snackbar = it }
+ .show()
+ }
+
companion object {
private const val PREFERENCE_THEME = "theme"
+ private const val PREFERENCE_SCREEN_DEBUGGING = "debug_preferences"
fun create(rootKey: String? = null) = GeneralSettingsFragment().withArguments(ARG_PREFERENCE_ROOT to rootKey)
}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsViewModel.kt b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..91407bb039c1d2439ea070861fe2c445a77a7078
--- /dev/null
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsViewModel.kt
@@ -0,0 +1,91 @@
+package com.fsck.k9.ui.settings.general
+
+import android.net.Uri
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.fsck.k9.logging.LogFileWriter
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.launch
+import timber.log.Timber
+
+class GeneralSettingsViewModel(private val logFileWriter: LogFileWriter) : ViewModel() {
+ private var snackbarJob: Job? = null
+ private val uiStateFlow = MutableStateFlow(GeneralSettingsUiState.Idle)
+ val uiState: Flow = uiStateFlow
+
+ fun exportLogs(contentUri: Uri) {
+ viewModelScope.launch {
+ setExportingState()
+
+ try {
+ logFileWriter.writeLogTo(contentUri)
+ showSnackbar(GeneralSettingsUiState.Success)
+ } catch (e: Exception) {
+ Timber.e(e, "Failed to write log to URI: %s", contentUri)
+ showSnackbar(GeneralSettingsUiState.Failure)
+ }
+ }
+ }
+
+ private fun setExportingState() {
+ // If an export was triggered before and the success/failure Snackbar is still showing, cancel the coroutine
+ // that resets the state to Idle after SNACKBAR_DURATION
+ snackbarJob?.cancel()
+ snackbarJob = null
+
+ sendUiState(GeneralSettingsUiState.Exporting)
+ }
+
+ private fun showSnackbar(uiState: GeneralSettingsUiState) {
+ snackbarJob?.cancel()
+ snackbarJob = viewModelScope.launch {
+ sendUiState(uiState)
+ delay(SNACKBAR_DURATION)
+ sendUiState(GeneralSettingsUiState.Idle)
+ snackbarJob = null
+ }
+ }
+
+ private fun sendUiState(uiState: GeneralSettingsUiState) {
+ uiStateFlow.value = uiState
+ }
+
+ companion object {
+ const val DEFAULT_FILENAME = "k9mail-logs.txt"
+ const val SNACKBAR_DURATION = 3000L
+ }
+}
+
+sealed interface GeneralSettingsUiState {
+ val isExportLogsMenuEnabled: Boolean
+ val snackbarState: SnackbarState
+
+ object Idle : GeneralSettingsUiState {
+ override val isExportLogsMenuEnabled = true
+ override val snackbarState = SnackbarState.Hidden
+ }
+
+ object Exporting : GeneralSettingsUiState {
+ override val isExportLogsMenuEnabled = false
+ override val snackbarState = SnackbarState.Hidden
+ }
+
+ object Success : GeneralSettingsUiState {
+ override val isExportLogsMenuEnabled = true
+ override val snackbarState = SnackbarState.ExportLogSuccess
+ }
+
+ object Failure : GeneralSettingsUiState {
+ override val isExportLogsMenuEnabled = true
+ override val snackbarState = SnackbarState.ExportLogFailure
+ }
+}
+
+enum class SnackbarState {
+ Hidden,
+ ExportLogSuccess,
+ ExportLogFailure
+}
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageHeader.java b/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageHeader.java
index 46b0b9633b14e772fe42a04515686ee152376f94..9d494a54fbabbf344999e94808608c90019e21f5 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageHeader.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageHeader.java
@@ -2,28 +2,15 @@ package com.fsck.k9.view;
import java.util.Arrays;
-import java.util.List;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener;
import android.content.Context;
-import android.graphics.Typeface;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.PopupMenu;
-import androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener;
-
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.format.DateUtils;
-import android.text.style.StyleSpan;
import android.util.AttributeSet;
-import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
@@ -33,6 +20,9 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.PopupMenu;
+import androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener;
import com.fsck.k9.Account;
import com.fsck.k9.DI;
import com.fsck.k9.FontSizes;
@@ -44,9 +34,7 @@ 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.Header;
import com.fsck.k9.mail.Message;
-import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.ui.ContactBadge;
import com.fsck.k9.ui.R;
import com.fsck.k9.ui.messageview.OnCryptoClickListener;
@@ -160,7 +148,7 @@ public class MessageHeader extends LinearLayout implements OnClickListener, OnLo
} else if (id == R.id.from) {
onAddSenderToContacts();
} else if (id == R.id.to || id == R.id.cc || id == R.id.bcc) {
- expand((TextView) view, ((TextView) view).getEllipsize() != null);
+ expand((TextView)view, ((TextView)view).getEllipsize() != null);
} else if (id == R.id.crypto_status_icon) {
onCryptoClickListener.onCryptoClick();
} else if (id == R.id.icon_single_message_options) {
@@ -214,7 +202,7 @@ public class MessageHeader extends LinearLayout implements OnClickListener, OnLo
}
public String createMessageForSubject() {
- return mContext.getResources().getString(R.string.copy_subject_to_clipboard);
+ return mContext.getResources().getString(R.string.copy_subject_to_clipboard);
}
public String createMessage(int addressesCount) {
diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageWebView.java b/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageWebView.java
index c0069bf373f43676569f54ba09a54095694a8aca..206785237fa09824a23419d4176408d0c56d1bb4 100644
--- a/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageWebView.java
+++ b/app/ui/legacy/src/main/java/com/fsck/k9/view/MessageWebView.java
@@ -45,7 +45,11 @@ public class MessageWebView extends WebView {
* will network images that are already in the WebView cache.
*
*/
- getSettings().setBlockNetworkLoads(shouldBlockNetworkData);
+ try {
+ getSettings().setBlockNetworkLoads(shouldBlockNetworkData);
+ } catch (SecurityException e) {
+ Timber.e(e, "Failed to unblock network loads. Missing INTERNET permission?");
+ }
}
diff --git a/app/ui/legacy/src/main/res/drawable/btn_check_star.xml b/app/ui/legacy/src/main/res/drawable/btn_check_star.xml
index 339bb252837165e0634daf2ded1dc805e41f9175..575615eed5ea729415b463daf3c7c40df61ee5f9 100644
--- a/app/ui/legacy/src/main/res/drawable/btn_check_star.xml
+++ b/app/ui/legacy/src/main/res/drawable/btn_check_star.xml
@@ -1,5 +1,5 @@
-
-
+
diff --git a/app/ui/legacy/src/main/res/drawable/ic_download.xml b/app/ui/legacy/src/main/res/drawable/ic_download.xml
index 2ac322d22a595641c0572eef99f902f27e02ebd2..0964bd62dbdbbc9b97dc3070c88e04e3b5ca1052 100644
--- a/app/ui/legacy/src/main/res/drawable/ic_download.xml
+++ b/app/ui/legacy/src/main/res/drawable/ic_download.xml
@@ -7,4 +7,4 @@
-
\ No newline at end of file
+
diff --git a/app/ui/legacy/src/main/res/drawable/ic_mark_new.xml b/app/ui/legacy/src/main/res/drawable/ic_mark_new.xml
index a543fba47f5a44cc0efd4d0fc5b34a3df609cbdb..de26f783aac2336fe6ea1373161490e29ac770a3 100644
--- a/app/ui/legacy/src/main/res/drawable/ic_mark_new.xml
+++ b/app/ui/legacy/src/main/res/drawable/ic_mark_new.xml
@@ -7,4 +7,4 @@
-
\ No newline at end of file
+
diff --git a/app/ui/legacy/src/main/res/drawable/ic_refresh_all.xml b/app/ui/legacy/src/main/res/drawable/ic_refresh_all.xml
index 16ecaa0e8f1f9b58cafee407c961585e4b8bef6f..f0721d991595c492169dbd00ccce9f656b69320a 100644
--- a/app/ui/legacy/src/main/res/drawable/ic_refresh_all.xml
+++ b/app/ui/legacy/src/main/res/drawable/ic_refresh_all.xml
@@ -7,4 +7,4 @@
-
\ No newline at end of file
+
diff --git a/app/ui/legacy/src/main/res/layout/account_list.xml b/app/ui/legacy/src/main/res/layout/account_list.xml
index 891dfbfd1737000fc60c4ab7c43f5229dc6130d0..b435cb655fcd487089bbf4506c7fc6e9fba51c28 100644
--- a/app/ui/legacy/src/main/res/layout/account_list.xml
+++ b/app/ui/legacy/src/main/res/layout/account_list.xml
@@ -1,8 +1,10 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.AccountList">
@@ -14,7 +16,8 @@
+ android:layout_height="match_parent"
+ tools:listitem="@layout/accounts_item" />
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupAccountType">
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_basics.xml b/app/ui/legacy/src/main/res/layout/account_setup_basics.xml
index fceab80e056f12f3432fe805c83e892b47494848..f0cf0371a7d02eeef95020e337ef1fa14803d490 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_basics.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_basics.xml
@@ -4,7 +4,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_height="match_parent"
- android:layout_width="match_parent">
+ android:layout_width="match_parent"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupBasics">
@@ -95,4 +96,4 @@
-
\ No newline at end of file
+
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_check_settings.xml b/app/ui/legacy/src/main/res/layout/account_setup_check_settings.xml
index 48aead19660c0856e2eb6332adbb49a514573097..e2a68d363ad573322054d4e4af4b456c2e2b8f9b 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_check_settings.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_check_settings.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupCheckSettings">
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_composition.xml b/app/ui/legacy/src/main/res/layout/account_setup_composition.xml
index d04b9f0d2e430713ecf87d683c6139be23e3a8d9..58340ecb1d491cde0c9421e61bb65837edd530a5 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_composition.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_composition.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupComposition">
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_incoming.xml b/app/ui/legacy/src/main/res/layout/account_setup_incoming.xml
index 5179cdd140c9bc1f54b8a38d78ebf4029ebd8487..c4cfee4fdc8962a2e1a6162115b3a9f720db9f42 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_incoming.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_incoming.xml
@@ -2,215 +2,216 @@
-
+
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:padding="6dip"
+ android:fadingEdge="none"
+ android:scrollbarStyle="outsideInset">
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
-
-
+ android:layout_marginTop="@dimen/account_setup_margin_between_items_incoming_and_outgoing">
+
+
+ android:text="@string/account_setup_incoming_security_label"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ style="@style/InputLabel"
+ android:layout_marginTop="6dp"/>
+ android:id="@+id/account_security_type"
+ android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:contentDescription="@string/account_setup_incoming_security_label"/>
-
-
+ android:layout_marginTop="@dimen/account_setup_margin_between_items_incoming_and_outgoing">
+
+
-
-
+ android:layout_marginTop="@dimen/account_setup_margin_between_items_incoming_and_outgoing">
+
+
+ android:id="@+id/account_auth_type_label"
+ android:text="@string/account_setup_incoming_auth_type_label"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginTop="6dp"
+ style="@style/InputLabel"/>
+ android:id="@+id/account_auth_type"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:contentDescription="@string/account_setup_incoming_auth_type_label"/>
-
-
-
+ android:layout_marginTop="@dimen/account_setup_margin_between_items_incoming_and_outgoing"
+ app:endIconMode="password_toggle">
-
-
-
+
+
+
+ style="@style/InputLabel"/>
-
-
+ android:layout_width="match_parent"/>
+
+ android:id="@+id/imap_path_prefix_section"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="6dp"
+ android:orientation="vertical">
+ android:id="@+id/imap_autodetect_namespace"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/account_setup_incoming_autodetect_namespace_label"/>
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ android:id="@+id/imap_path_prefix"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/account_setup_incoming_imap_path_prefix_label"
+ android:singleLine="true" />
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/imap_folder_setup_section"
+ android:orientation="vertical">
+ android:id="@+id/subscribed_folders_only"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/account_setup_incoming_subscribed_folders_only_label"
+ />
-
-
+ android:orientation="vertical">
+
+
+ android:id="@+id/webdav_mailbox_alias_section"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ android:id="@+id/webdav_mailbox_path"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/account_setup_incoming_webdav_mailbox_path_label"
+ android:singleLine="true" />
+ android:id="@+id/webdav_owa_path_section"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ android:id="@+id/webdav_auth_path_section"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ android:id="@+id/compression_label"
+ android:text="@string/account_setup_incoming_compression_label"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginTop="6dp"
+ style="@style/InputLabel"/>
+ android:id="@+id/compression_section"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ android:id="@+id/compression_mobile"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/account_setup_incoming_mobile_label"
+ />
+ android:id="@+id/compression_wifi"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/account_setup_incoming_wifi_label"
+ android:contentDescription="@string/account_setup_incoming_compression_label"
+ />
+ android:id="@+id/compression_other"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/account_setup_incoming_other_label"
+ android:contentDescription="@string/account_setup_incoming_compression_label"
+ />
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"/>
-
+
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_names.xml b/app/ui/legacy/src/main/res/layout/account_setup_names.xml
index 4b9e5d662b780843a5402cd3507297bea8907958..2a9f68c12b26aa2d9f4e0e853f50aa8d07762966 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_names.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_names.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupNames">
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_options.xml b/app/ui/legacy/src/main/res/layout/account_setup_options.xml
index 3e51349b7b18e0fe446eba9c89b5d943b873b960..d15bc14c906db7d72b20f260535f1a3d2181eb67 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_options.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_options.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupOptions">
diff --git a/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml b/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml
index 16b3a6ed492953f43e7e0d38d1355f8b20011140..bdf554681ab152fbc0fdea51dbd5e070033b48cc 100644
--- a/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml
+++ b/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml
@@ -5,7 +5,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_height="match_parent"
- android:layout_width="match_parent">
+ android:layout_width="match_parent"
+ tools:context="com.fsck.k9.activity.setup.AccountSetupOutgoing">
diff --git a/app/ui/legacy/src/main/res/layout/accounts_item.xml b/app/ui/legacy/src/main/res/layout/accounts_item.xml
index f40046c000eaecce4b57fc5b46f6b032f58fe341..df4b6b4e163a484e070ab1412b055eedd4a08a4f 100644
--- a/app/ui/legacy/src/main/res/layout/accounts_item.xml
+++ b/app/ui/legacy/src/main/res/layout/accounts_item.xml
@@ -1,19 +1,22 @@
-
+
+ android:id="@+id/chip"
+ android:layout_height="match_parent"
+ android:layout_width="8dip"
+ android:layout_marginRight="8dip"
+ tools:background="@sample/accounts.json/data/color"
+ />
+ android:id="@+id/description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.K9.Medium"
+ tools:text="@sample/accounts.json/data/name"/>
+ android:id="@+id/email"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textAppearance="@style/TextAppearance.K9.Small"
+ tools:text="@sample/accounts.json/data/email"/>
diff --git a/app/ui/legacy/src/main/res/layout/activity_account_settings.xml b/app/ui/legacy/src/main/res/layout/activity_account_settings.xml
index 3883c497497700bc9c6cd2775d0bd0b72ebf68c8..50494fbf33129b4f1904f9111fc9c55ce65b605d 100644
--- a/app/ui/legacy/src/main/res/layout/activity_account_settings.xml
+++ b/app/ui/legacy/src/main/res/layout/activity_account_settings.xml
@@ -1,20 +1,24 @@
+ android:orientation="vertical"
+ tools:context=".settings.account.AccountSettingsActivity">
+ android:elevation="4dp"
+ tools:navigationIcon="@drawable/ic_arrow_back">
+ android:layout_height="wrap_content"
+ tools:listitem="@layout/account_spinner_item"/>
diff --git a/app/ui/legacy/src/main/res/layout/activity_manage_folders.xml b/app/ui/legacy/src/main/res/layout/activity_manage_folders.xml
index 383163e67f02325e74f942d887a6cb0c4f929851..4264fe093a4ceaa5f8370162b59ccf27f10e650c 100644
--- a/app/ui/legacy/src/main/res/layout/activity_manage_folders.xml
+++ b/app/ui/legacy/src/main/res/layout/activity_manage_folders.xml
@@ -2,9 +2,11 @@
+ android:orientation="vertical"
+ tools:context=".managefolders.ManageFoldersActivity">
@@ -14,6 +16,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- app:defaultNavHost="true" />
+ app:defaultNavHost="true"
+ tools:layout="@layout/fragment_manage_folders"/>
diff --git a/app/ui/legacy/src/main/res/layout/activity_push_info.xml b/app/ui/legacy/src/main/res/layout/activity_push_info.xml
index ae38f5ac311c19007e6e2deb6461dbb269dad722..93ed22be13ad2f387614563eedf2bae7e703626e 100644
--- a/app/ui/legacy/src/main/res/layout/activity_push_info.xml
+++ b/app/ui/legacy/src/main/res/layout/activity_push_info.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context=".push.PushInfoActivity">
@@ -11,6 +13,7 @@
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_weight="1" />
+ android:layout_weight="1"
+ tools:layout="@layout/fragment_push_info" />
diff --git a/app/ui/legacy/src/main/res/layout/activity_recent_changes.xml b/app/ui/legacy/src/main/res/layout/activity_recent_changes.xml
index ae38f5ac311c19007e6e2deb6461dbb269dad722..62ea850fdb1f0f7cd1d696e391181468d42777dd 100644
--- a/app/ui/legacy/src/main/res/layout/activity_recent_changes.xml
+++ b/app/ui/legacy/src/main/res/layout/activity_recent_changes.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context=".changelog.RecentChangesActivity">
@@ -11,6 +13,7 @@
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_weight="1" />
+ android:layout_weight="1"
+ tools:layout="@layout/fragment_changelog" />
diff --git a/app/ui/legacy/src/main/res/layout/activity_settings.xml b/app/ui/legacy/src/main/res/layout/activity_settings.xml
index 491048ad3d46ae9275d8de55c08790085efcca51..ecfaf19a42acb8477f21778bf9066c0d25ded7f7 100644
--- a/app/ui/legacy/src/main/res/layout/activity_settings.xml
+++ b/app/ui/legacy/src/main/res/layout/activity_settings.xml
@@ -1,10 +1,11 @@
-
+ android:orientation="vertical"
+ tools:context=".settings.SettingsActivity">
diff --git a/app/ui/legacy/src/main/res/layout/choose_account_item.xml b/app/ui/legacy/src/main/res/layout/choose_account_item.xml
index 5bcf7a58d91fa25351890ad8932bee0353b579a3..64136c807151474d98393706c3a9d001d237e096 100644
--- a/app/ui/legacy/src/main/res/layout/choose_account_item.xml
+++ b/app/ui/legacy/src/main/res/layout/choose_account_item.xml
@@ -1,6 +1,7 @@
+ android:layout_width="6dp"
+ tools:background="@sample/accounts.json/data/color"/>
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ tools:text="@sample/accounts.json/data/name"/>
diff --git a/app/ui/legacy/src/main/res/layout/choose_identity_item.xml b/app/ui/legacy/src/main/res/layout/choose_identity_item.xml
index e641a4025ef4efee31496a4c90995cd7177608d5..fd420f09c72917e7e4b0e1dfbb3d0fce8409b215 100644
--- a/app/ui/legacy/src/main/res/layout/choose_identity_item.xml
+++ b/app/ui/legacy/src/main/res/layout/choose_identity_item.xml
@@ -1,6 +1,7 @@
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ tools:text="Initial identity" />
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ tools:text="Firstname Lastname <user@domain.example>" />
diff --git a/app/ui/legacy/src/main/res/layout/client_certificate_spinner.xml b/app/ui/legacy/src/main/res/layout/client_certificate_spinner.xml
index fdfda026b056f25f39509f91a60bcdabae527ca0..063942285f6f1e882341458c994dcab85ad96647 100644
--- a/app/ui/legacy/src/main/res/layout/client_certificate_spinner.xml
+++ b/app/ui/legacy/src/main/res/layout/client_certificate_spinner.xml
@@ -1,7 +1,12 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:parentTag="LinearLayout"
+ tools:orientation="horizontal">
diff --git a/app/ui/legacy/src/main/res/layout/crypto_key_transfer.xml b/app/ui/legacy/src/main/res/layout/crypto_key_transfer.xml
index ec32fbad177200680d8c6ebe6073e88fac697ce3..23a49a3f6d6618257241644700658ef62d6ed5b2 100644
--- a/app/ui/legacy/src/main/res/layout/crypto_key_transfer.xml
+++ b/app/ui/legacy/src/main/res/layout/crypto_key_transfer.xml
@@ -5,7 +5,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical">
+ android:orientation="vertical"
+ tools:context=".endtoend.AutocryptKeyTransferActivity">
diff --git a/app/ui/legacy/src/main/res/layout/dialog_apg_deprecated.xml b/app/ui/legacy/src/main/res/layout/dialog_apg_deprecated.xml
index 105e5f348194598c1be1d80c99ca48158016fa66..beb54758ec1d5f522a59e5399aba2c67fe3d13c6 100644
--- a/app/ui/legacy/src/main/res/layout/dialog_apg_deprecated.xml
+++ b/app/ui/legacy/src/main/res/layout/dialog_apg_deprecated.xml
@@ -1,7 +1,9 @@
+ android:layout_width="match_parent"
+ tools:context=".dialog.ApgDeprecationWarningDialog">
+ android:layout_width="match_parent"
+ tools:context=".settings.account.AutocryptPreferEncryptDialogFragment">
+ android:padding="24dp"
+ tools:context=".settings.account.OpenPgpAppSelectDialog$OpenKeychainInfoFragment">
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.EditIdentity">
diff --git a/app/ui/legacy/src/main/res/layout/foldable_linearlayout.xml b/app/ui/legacy/src/main/res/layout/foldable_linearlayout.xml
index 7b684afdd9c03add8507196cc4907523abd331c0..9028fce5f54ec597098646ce301b6787638fba93 100644
--- a/app/ui/legacy/src/main/res/layout/foldable_linearlayout.xml
+++ b/app/ui/legacy/src/main/res/layout/foldable_linearlayout.xml
@@ -1,9 +1,11 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.view.FoldableLinearLayout">
+ android:orientation="vertical"
+ tools:context=".choosefolder.ChooseFolderActivity">
diff --git a/app/ui/legacy/src/main/res/layout/folder_list_item.xml b/app/ui/legacy/src/main/res/layout/folder_list_item.xml
index 3e7955c37f3eaae0f29a2e70e36f01a063c2be91..6a040f4359d9861ec7a19f0fd6335ee12a997be0 100644
--- a/app/ui/legacy/src/main/res/layout/folder_list_item.xml
+++ b/app/ui/legacy/src/main/res/layout/folder_list_item.xml
@@ -18,7 +18,7 @@
android:layout_height="24dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="32dp"
- tools:src="@drawable/ic_drafts_folder" />
+ tools:srcCompat="@sample/folders.json/data/icon" />
+ tools:text="@sample/folders.json/data/name" />
diff --git a/app/ui/legacy/src/main/res/layout/fragment_about.xml b/app/ui/legacy/src/main/res/layout/fragment_about.xml
index 1e8a47b2754fb4a956d34e260a88fdc1a4443de1..ea16719dc09d45c2c866aa062d2a8383c1954a9a 100644
--- a/app/ui/legacy/src/main/res/layout/fragment_about.xml
+++ b/app/ui/legacy/src/main/res/layout/fragment_about.xml
@@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ tools:context=".settings.AboutFragment">
+ android:layout_height="match_parent"
+ tools:showIn="@layout/activity_recent_changes"
+ tools:context=".changelog.ChangelogFragment">
+ tools:visibility="visible"
+ tools:listitem="@layout/changelog_list_release_item"/>
+ tools:listitem="@layout/folder_list_item"
+ tools:context=".managefolders.ManageFoldersFragment" />
diff --git a/app/ui/legacy/src/main/res/layout/fragment_push_info.xml b/app/ui/legacy/src/main/res/layout/fragment_push_info.xml
index 1a02e99c9a8241e24611458dbbd81ff604216ea2..6d08c169ece88966ec26c47a5671966c1669f95d 100644
--- a/app/ui/legacy/src/main/res/layout/fragment_push_info.xml
+++ b/app/ui/legacy/src/main/res/layout/fragment_push_info.xml
@@ -4,7 +4,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fillViewport="true">
+ android:fillViewport="true"
+ tools:context=".push.PushInfoFragment">
+ android:layout_height="match_parent"
+ tools:context=".settings.export.SettingsExportFragment">
+ tools:listitem="@layout/settings_export_account_list_item"
+ tools:itemCount="3"/>
+ android:layout_height="match_parent"
+ tools:context=".settings.import.SettingsImportFragment">
+ tools:visibility="visible"
+ tools:listitem="@layout/settings_import_account_list_item"
+ tools:itemCount="3" />
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
@@ -91,10 +90,10 @@
diff --git a/app/ui/legacy/src/main/res/layout/message_compose.xml b/app/ui/legacy/src/main/res/layout/message_compose.xml
index d76749a8a5b629ccc7d600b494c3630007eaa4c6..f52e063b1475fefe0d21763c4af99a44eea3aac5 100644
--- a/app/ui/legacy/src/main/res/layout/message_compose.xml
+++ b/app/ui/legacy/src/main/res/layout/message_compose.xml
@@ -1,8 +1,10 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.MessageCompose">
@@ -11,6 +13,7 @@
android:layout="@layout/message_compose_content"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_weight="1"/>
+ android:layout_weight="1"
+ tools:visibility="visible"/>
diff --git a/app/ui/legacy/src/main/res/layout/message_list.xml b/app/ui/legacy/src/main/res/layout/message_list.xml
index c13f19ef8c5f1d09c819b9d78cc54bbfb35a07db..cd6ed7d98b800e9e6b4233d7f35478a67833c51e 100644
--- a/app/ui/legacy/src/main/res/layout/message_list.xml
+++ b/app/ui/legacy/src/main/res/layout/message_list.xml
@@ -1,8 +1,10 @@
+ android:layout_height="match_parent"
+ tools:context="com.fsck.k9.activity.MessageList">
+ android:layout_height="fill_parent"
+ tools:layout="@layout/message_list_fragment" />
+ android:layout_height="fill_parent"
+ tools:layout="@layout/message" />
-
-
-
\ No newline at end of file
+
+
+
diff --git a/app/ui/legacy/src/main/res/layout/message_list_fragment.xml b/app/ui/legacy/src/main/res/layout/message_list_fragment.xml
index ce0d99a526246c2268e4c8f2297112837da07936..f4baa830a92b8e54b78abdc15e3ef78ed601bc74 100644
--- a/app/ui/legacy/src/main/res/layout/message_list_fragment.xml
+++ b/app/ui/legacy/src/main/res/layout/message_list_fragment.xml
@@ -2,14 +2,17 @@
+ android:layout_height="match_parent"
+ tools:context="com.fsck.k9.fragment.MessageListFragment">
+ android:layout_weight="5"
+ tools:listitem="@layout/message_list_item"/>
diff --git a/app/ui/legacy/src/main/res/layout/message_list_item.xml b/app/ui/legacy/src/main/res/layout/message_list_item.xml
index 204ecd434e86f62b8f42dc189e2ea4e3439de4df..a0e8e48d7c78817ad83aa20cf46d3f304437ce3d 100644
--- a/app/ui/legacy/src/main/res/layout/message_list_item.xml
+++ b/app/ui/legacy/src/main/res/layout/message_list_item.xml
@@ -1,11 +1,13 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_gravity="center_vertical"
+ tools:layout_height="?android:attr/listPreferredItemHeight"
+ >
+ android:id="@+id/preview"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@+id/star"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="3dip"
+ android:bufferType="spannable"
+ android:layout_below="@+id/subject_wrapper"
+ android:singleLine="false"
+ android:textAppearance="@style/TextAppearance.K9.Small"
+ android:textColor="?android:attr/textColorPrimary"
+ android:longClickable="false"
+ android:layout_alignWithParentIfMissing="false"
+ android:gravity="top"
+ android:layout_alignParentBottom="false"
+ tools:text="Message preview"/>
+ app:srcCompat="@drawable/ic_account_color"
+ tools:tint="#FF1976D2"/>
+ android:id="@+id/subject"
+ android:layout_width="0dp"
+ android:layout_weight="0.7"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="1dip"
+ android:layout_marginLeft="1dip"
+ android:ellipsize="marquee"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.K9.MediumSmall"
+ android:textColor="?android:attr/textColorPrimary"
+ tools:text="Subject"
+ />
+ android:id="@+id/thread_count"
+ android:textAppearance="@style/TextAppearance.K9.MediumSmall"
+ android:textColor="?attr/messageListThreadCountForegroundColor"
+ android:background="?attr/messageListThreadCountBackground"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="3dip"
+ android:layout_marginRight="4dip"
+ android:paddingRight="4dip"
+ android:paddingBottom="1dip"
+ android:paddingLeft="4dip"
+ android:focusable="false"
+ tools:text="3"
+ />
+ android:id="@+id/attachment"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignTop="@+id/date"
+ android:layout_alignBottom="@+id/date"
+ app:srcCompat="?attr/messageListAttachment"
+ android:layout_alignWithParentIfMissing="true"
+ android:layout_toStartOf="@+id/date" />
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignTop="@+id/subject_wrapper"
+ android:layout_alignWithParentIfMissing="true"
+ android:layout_centerVertical="true"
+ android:layout_alignParentRight="true"
+ android:paddingLeft="3dip"
+ android:paddingRight="8dip"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.K9.Small"
+ android:textColor="?android:attr/textColorSecondary"
+ tools:text="Oct 27"/>
+ android:id="@+id/star"
+ style="@style/MessageStarStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_below="@+id/date"
+ android:layout_alignParentRight="true"
+ android:paddingTop="5dip"
+ android:paddingLeft="2dip"
+ android:paddingRight="4dip"
+ android:focusable="false"
+ android:visibility="visible"
+ android:gravity="center_vertical"
+ tools:text=""/>
diff --git a/app/ui/legacy/src/main/res/layout/message_list_item_footer.xml b/app/ui/legacy/src/main/res/layout/message_list_item_footer.xml
index 019a94c834b938ba45f09db6adddd01069a0d011..bb118bf7804afd7cc934e9fa8edb9f6b074531e5 100644
--- a/app/ui/legacy/src/main/res/layout/message_list_item_footer.xml
+++ b/app/ui/legacy/src/main/res/layout/message_list_item_footer.xml
@@ -1,6 +1,7 @@
diff --git a/app/ui/legacy/src/main/res/layout/message_view_attachment.xml b/app/ui/legacy/src/main/res/layout/message_view_attachment.xml
index fc829248e80f3633bb84fa77274b5b1e7292f407..8a7c3656501841d994283d898e9b3c80f9fd61c9 100644
--- a/app/ui/legacy/src/main/res/layout/message_view_attachment.xml
+++ b/app/ui/legacy/src/main/res/layout/message_view_attachment.xml
@@ -43,10 +43,10 @@
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:contentDescription="@null"
+ app:srcCompat="@drawable/ic_attachment_generic"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/attachment_preview"
- app:srcCompat="@drawable/ic_attachment_generic"
app:tint="?attr/colorAccent" />
+ android:layout_height="match_parent"
+ tools:background="#FF1976D2" />
@@ -81,7 +81,8 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="8dp"
- android:layout_marginTop="8dp" />
+ android:layout_marginTop="8dp"
+ tools:src="@drawable/ic_contact_picture" />
+ android:layout_height="match_parent"
+ tools:context=".messagesource.MessageHeadersFragment">
-
+ android:orientation="vertical"
+ tools:context=".messagesource.MessageSourceActivity">
+ android:layout_height="match_parent"
+ tools:layout="@layout/message_view_headers"/>
diff --git a/app/ui/legacy/src/main/res/layout/openpgp_enabled_error_dialog.xml b/app/ui/legacy/src/main/res/layout/openpgp_enabled_error_dialog.xml
index 4b46ee98f95b3db7a837a4c25687d1f4da9279d9..9b03f94b9db6d7b10a62a0248db8b03087166143 100644
--- a/app/ui/legacy/src/main/res/layout/openpgp_enabled_error_dialog.xml
+++ b/app/ui/legacy/src/main/res/layout/openpgp_enabled_error_dialog.xml
@@ -1,12 +1,14 @@
+ android:paddingBottom="24dp"
+ tools:context="com.fsck.k9.activity.compose.PgpEnabledErrorDialog">
-
\ No newline at end of file
+
diff --git a/app/ui/legacy/src/main/res/layout/openpgp_encrypt_description_dialog.xml b/app/ui/legacy/src/main/res/layout/openpgp_encrypt_description_dialog.xml
index 6825c4dadb56063c3a0596ca5de0930d75aa62b5..7294398ce9c949920d2b1751e387c70e7c6511da 100644
--- a/app/ui/legacy/src/main/res/layout/openpgp_encrypt_description_dialog.xml
+++ b/app/ui/legacy/src/main/res/layout/openpgp_encrypt_description_dialog.xml
@@ -8,7 +8,8 @@
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="14dp"
- android:paddingBottom="14dp">
+ android:paddingBottom="14dp"
+ tools:context="com.fsck.k9.activity.compose.PgpEncryptDescriptionDialog">
+ android:padding="10dp"
+ tools:context="com.fsck.k9.activity.compose.PgpInlineDialog">
+ app:tint="@color/light_black" />
+ android:paddingBottom="14dp"
+ tools:context="com.fsck.k9.activity.compose.PgpSignOnlyDialog">
+ android:layout_height="match_parent"
+ tools:context=".settings.import.PasswordPromptDialogFragment">
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="" />
+ tools:text="@sample/accounts.json/data/name" />
+ tools:text="@sample/accounts.json/data/email" />
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="" />
+ tools:text="@sample/accounts.json/data/name" />
+ android:layout_height="match_parent"
+ tools:context="com.fsck.k9.activity.MessageList">
+ android:orientation="horizontal"
+ android:layout_below="@id/toolbar">
+ android:layout_weight="5"
+ tools:layout="@layout/message_list_fragment" />
+ tools:ignore="PxUsage"/>
+ android:layout_weight="3"
+ tools:layout="@layout/message" />
-
+
+
diff --git a/app/ui/legacy/src/main/res/layout/upgrade_databases.xml b/app/ui/legacy/src/main/res/layout/upgrade_databases.xml
index cfca14db6c143993900932414df46c1395ced7ac..259a1980007d81575494530a7195496b28684397 100644
--- a/app/ui/legacy/src/main/res/layout/upgrade_databases.xml
+++ b/app/ui/legacy/src/main/res/layout/upgrade_databases.xml
@@ -1,8 +1,10 @@
+ android:orientation="vertical"
+ tools:context="com.fsck.k9.activity.UpgradeDatabases">
diff --git a/app/ui/legacy/src/main/res/menu/debug_settings_option.xml b/app/ui/legacy/src/main/res/menu/debug_settings_option.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7d88cae2988fd4a487dced4ce0d994bb7e16f5ec
--- /dev/null
+++ b/app/ui/legacy/src/main/res/menu/debug_settings_option.xml
@@ -0,0 +1,10 @@
+
+
diff --git a/app/ui/legacy/src/main/res/menu/message_list_option.xml b/app/ui/legacy/src/main/res/menu/message_list_option.xml
index 38a179c272df1d111b26a875455c65b999165d88..04e246279701fd91b79e8240044661f7e06a008d 100644
--- a/app/ui/legacy/src/main/res/menu/message_list_option.xml
+++ b/app/ui/legacy/src/main/res/menu/message_list_option.xml
@@ -16,6 +16,7 @@
android:id="@+id/search"
android:icon="?attr/iconActionSearch"
app:showAsAction="always"
+ app:actionViewClass="androidx.appcompat.widget.SearchView"
android:title="@string/search_action"/>
diff --git a/app/ui/legacy/src/main/res/raw/changelog_master.xml b/app/ui/legacy/src/main/res/raw/changelog_master.xml
index d04e49affa7f0a8110b8df208bf3698cfbf96650..1b8110647a94184b1abbe8ba374fd5ecb68d1323 100644
--- a/app/ui/legacy/src/main/res/raw/changelog_master.xml
+++ b/app/ui/legacy/src/main/res/raw/changelog_master.xml
@@ -3,13 +3,46 @@
Locale-specific versions are kept in res/raw-/changelog.xml.
-->
+
+ Set subject when forwarding a message as attachment
+ Added a menu option to export the debug log under Settings → General settings → Debugging
+ Don't display "unread count" in notifications; only number of new messages
+ Properly decode multiple encoded words using the ISO-2022-JP charset (e.g. in subjects)
+ Fixed a crash when users left the message view screen before the download of an image attachment was complete
+ Don't crash when loading images without internet permission (could only happen with custom ROMs)
+ Fixed a rare crash when auto-completing email addresses in the compose screen
+ A lot of internal changes and cleanup
+ Updated translations
+
+
+ Tweaked toolbar in move/copy screens
+ Fixed a bug where line breaks were added when editing a draft
+ Fixed animation when switching accounts
+ Fixed crash that could occur when deleting an account
+ Updated translations
+
+
+ Removed the "default account" setting; the first account in the list is now automatically the default
+ account
+
+ Removed the "hide subject in notifications" setting; use the "lock screen notifications" setting
+ instead
+
+ Fixed bug where the list of displayed folders wasn't updated when a folder was added or removed from the
+ server
+
+ Fixed lock screen notification when there's only one new message
+ Fixed bug that lead to newly created accounts not having an account color
+ Fixed missing notification sound
-
Fixed the check for missing outgoing server credentials, again… hopefully 🤞
-
Fixed crypto status icons not being clickable
Updated translations
-
فريق The K-9 Dog Walkersحقوق النشر محفوظة 2008 - %s The K-9 Dog Walkers. جزء من حقوق النشر محفوظة 2006 - %s the Android Open Source Project.
- Apache License, Version 2.0الكود المصدري
+ Apache License, Version 2.0مشروع مفتوح المصدرالموقع الإلكترونيالمكتبات
@@ -122,672 +122,663 @@
خطأ في تحميل الرسالةتحميل
باقي %d
- %.1f جيجا
- %.1f ميجا
- %.1f كيلو
- %d بايت
- تم تقليص الحساب \"%s من %s الى %s
- يتم ضغط \"%s\"
- رسالة جديدة
-
- %d ﻻ رسائل
- %d رسالة واحدة
- %d رسالتان
- %d رسائل
- %d رسالة
- %d رسالة جديدة
-
- %d غير مقروئة (%s)
- رُد
- إعتبارها مقروءة
- إعتبار الكل كمقروء
- احذف
- احذف الكل
- أرشيف
- أرشفة الكل
- بريد مُزعج
- خطأ في شهادة %s
- تأكد من إعدادات الخادم
- فشل المصادقة
- فشل مصادقة %s. يرجى تحديث إعدادات الخادم.
- تفقد البريد: %s:%s
- التحقق من البريد
- إرسال البريد: %s
- إرسال البريد
- :
- الرسائل
- إشعارات ذات علاقة بالرسائل
- مُتنوع
- تنبيهات متفرقة مثل الأخطاء وغيرها من الأمور.
- الوارد
- الصادر
- المسودات
- المهملات
- المُرسَل
- فشِلَت عملية إرسال بعض الرسائل
- الإصدار
- تمكين تسجيل التحاليل
- عمل سجل ببيانات تشخيصية إضافية
- إضافة البيانات الحساسة إلى السجل
- يمكن أن يُظهر الكلمات السرية في السجلّات.
- تحميل رسائل إضافية
- إلى:%s
- الموضوع
- نصّ الرسالة
- التوقيع
- -------- الرسالة الأصلية --------
- الموضوع :
- المُرسل:
- مِن :
- إلى :
- نسخة كربونية :
- %s كَتَب :
- بتاريخ %1$s، %2$s الرسالة:
- يجب إضافة عنوان مُتَلقٍ واحد على الأقل.
- لم نتمكن من العثور على أي عنوان بريد إلكتروني لجهة الإتصال هذه.
- لا يمكن إعادة توجيه بعض المُرفَقات لأنه لم يتم تنزيلها بعد.
- لا يمكن إعادة توجيه الرسالة لوجود بعض المُرفَقات التي يتم تنزيلها.
- إدماج نص الرسالة المُقتبَس
- حذف النص المقتبَس
- تعديل النص المقتبَس
- إزالة المُرفَق
- من: %s <%s>
- إلى :
- نسخة كربونية :
- نسخة مخفية:
- افتح
- احفظ
- غير قادر على حفظ المُرفَق.
- اظهر الصور
- يتعذر إيجاب تطبيق لعرض %s.
- تنزيل الرسالة كاملةً
- ﻻ يُمكن عرض الرسالة
- عبر %1$s
-
- تم تنزيل جميع الترويسات ولكن لا يوجد ترويسات إضافية لعرضها.
- فشل استرداد الترويسات الإضافية من قاعدة بيانات أو من الخادم.
- المزيد من هذا المُرسِل
- مِن طرف %s
- تشخيص \ حذف محتويات الرسالة
- تم إلغاء الرسالة
- تم الإحتفاظ بالرسالة كمسودة
- إظهار النجوم
- معاينة الخطوط
- أظهر أسماء مُراسِليك
- إظهار أسماء المُراسلين بدلًا مِن عناوين بريدهم الإلكترونية
- المُراسل فوق موضوع الرسالة
- اظهر أسماء المتراسيلن
- تلوين المُتراسِلين
- تلوين أسماء جهات الإتصال
- حجم خط ثابت
- ﻻئم الرسالة تلقائيًا
- تقليص الرسالة لتناسب الشاشة
- عودة إلى اللائحة بعد الحذف
- عودة إلى لائحة الرسائل بعد حذف الرسالة
- إظهار الرسالة التالية بعد الحذف
- إظهار الرسالة التالية دائمًا بعد حذف الرسالة
- أكّد الإجاءات
- احذف
- احذف الرسائل المميزة بنجمة (في لائحة الرسائل)
- بريد مُزعج
- إلغاء الرسالة
- جعل كل الرسائل مقروءة
- احذف (من الإشعارات)
- إخفاء عميل البريد
- احذف مُعرف بريد كية-9 من ترويسات الرسالة
- احذف التوقيت
- إخفاء العنوان في الإشعارات
- أبدًا
- عندما يكون الجهاز مغلقًا
- دائمًا
- إظهار زر ’الحذف‘
- أبدًا
- للإشعارات ذات الرسالة الواحدة
- دائمًا
- إشعارات الشاشة المقفلة
- لا إشعارات في قفل الشاشة
- اسم التطبيق
- تعداد الرسائل غير المقروءة
- تعداد الرسائل و المُرسِلين
- الشيء نفسه عندما تكون الشاشة غير مقفلة
- وقت الهدوء
- عطل التنبيهات
- عطل التنبيهات بشكل كلي أثناء وقت الهدوء
- وقت الهدوء يبدأ من
- وقت الهدوء ينتهي عند
- إعداد حساب جديد
- عنوان البريد الإليكتروني
- كلمة السِّر
- اظهر كلمة السِّر
- الإعداد يدويا
-
- المصادقة \u2026
- جارٍ الإلغاء\u2026
- لقد انتهيت تقريبًا
- اَعطِ هذا الحساب اسمًا (اختياري):
- اكتب اسمك (تظهر في الرسائل الصادرة):
- نوع الحساب
- ما نوع هذا الحساب؟
- POP3
- IMAP
- كلمة مرور عادية
- كلمة السر، مُرسَلَة بشكل غير آمن
- كلمة سِّر مُعماة
- شهادة العميل
- إعدادات الخادم الوارد
- اسم المُستخدم
- كلمة السِّر
- شهادة العميل
- خادم POP3
- خادم IMAP
- خادم إكستشينج
- المَنفذ
- الأمان
- المصادقة
- بدون
- SSL/TLS
- STARTTLS
- عندما أحذف رسالة
- ﻻ تحذفها على الخادم
- احذفها على الخادم
- إعتبارها كمقروءة على السيرفر
- إستخدام الضغط على شبكة :
- الجوال
- الواي فاي
- أخرى
- التخزين الخارجي (بطاقة الذاكرة)
- ذاكرة التخزين العادي الداخلية
- إزالة الرسائل المحذوفة من الخادوم أيضا
- فورًا
- عند الإستجواب
- يدوي
- بادئة مسار IMAP
- مجلد المسودات
- مجلد الرسائل المرسَلة
- مجلد المهملات
- مجلد الأرشيف
- مجلد البريد المزعج
- توسيع المجلد تلقائيا
- مسار OWA
- اختياري
- مسار المصادقة
- اختياري
- علبة بريد التحويل
- اختياري
- إعدادات الخادم الخارج
- خادم SMTP
- المَنفذ
- الأمان
- يتطلب تسجيل الدخول
- اسم المُستخدم
- كلمة السِّر
- المصادقة
- خيارات الحساب
- تضغيط الحساب
- أبدًا
- كل 15 دقيقة
- كل 30 دقيقة
- كل ساعة
- كل ساعتين
- كل 3 ساعات
- كل 6 ساعات
- كل 12 ساعة
- كل 24 ساعة
- كل دقيقتين
- كل 3 دقائق
- كل 6 دقائق
- كل 12 دقيقة
- كل 24 دقيقة
- كل 36 دقيقة
- كل 48 دقيقة
- كل 60 دقيقة
- نبهني عند وصول رسالة
- عدد الرسائل التي ستظهر
- 10 رسائل
- 25 رسالة
- 50 رسالة
- 100 رسالة
- 250 رسالة
- 500 رسالة
- 1000 رسالة
- 2500 رسالة
- 5000 رسالة
- 10000 رسالة
- كل الرسائل
- تعذرت مواصلة عملية إتمام الإعداد
- إسم المستخدم أو كلمة السر خاطئة.\n(%s)
- تعديل التفاصيل
- مواصلة
- متقدمة
- إعدادات الحساب
- الحساب الإفتراضي
- إبعث الرسائل من هذا الحساب افتراضيا
- إشعارات البريد الجديد
- مجلد الإخطارات
- الكل
- المجلدات من الفئة الأولى فقط
- المجلدات من الفئة الأولى و الثانية
- الكل عدا مجلدات الفئة الثانية
- بدون
- إخطارات المزامنة
- بريدك الإليكتروني
- إظهار إشعارات على شريط الحالة عند تلقي بريد جديد
- إضافة البريد الصادر
- إظهار إشعارات للرسائل التي أبعثُها
- جهات الإتصال فقط
- إظهار الإشعارات فقط عند تلقي رسائل مِن طرف مراسلين معروفين
- تحديد الرسالة كمقروءة بعد فتحها
- تحديد الرسالة كمقروءة بعد فتحها الإطلاع عليها
- إعدادات الإشعار
- دائمًا اظهر الصور
- لا
- من المُتراسِلين
- من أي أحد
- إرسال البريد
- إقتباس نص الرسالة عند الإجابة
- إدماج نص الرسالة الأصلية ضمن إجابتك.
- الإجابة تحت النص المقتبَس
- ستظهر الرسالة الأصلية فوق ردّك
- التجريد مِن التوقيعات عند الرد
- يحذف التوقيعات مِن نص الرسائل المُقتبَسة
- تنسيق الرسالة
- نص صِرفْ (احذف الصُور و التنسيقات)
- HTML (ابقي على الصُور و التنسيقات)
- آلي
- اشعار قراءة
- أطلب دائما إشعارا عند القراءة
- أسلوب الإقتباس عند الإجابة
- البادئة (مثلَ بريد جي مايل)
- الرأسية (مِثل آوتلوك)
- الإعدادات العامة
- قراءة البريد
- جلب البريد
- المجلدات
- بادئة النص المُقتَبَس
- التعمية مِن الطرف إلى نهاية الطرف
- تنشيط دعم أوبن بي جي بي
- إختيار تطبيق أوبن بي جي بي
- متصل بـ %s
- الضبط جارٍ...
- لون الحساب
- مِن دون لون
- لون ضوء التنبيهات
- حجم المجلد المحلي
- أي حجم (بدون حَدْ)
- 1 KiB
- 2 KiB
- 4 KiB
- 8 KiB
- 16 KiB
- 32 KiB
- 64 KiB
- 128 KiB
- 256 KiB
- 512 KiB
- 1 MiB
- 2 MiB
- 5 MiB
- 10 MiB
- زَامن الرسائل مع
- أي وقت (بدون حَدْ)
- اليوم
- خلال اليومين الفارطين
- خلال الأيام الـ 3 الماضية
- خلال الأسبوع الماضي
- خلال الأسبوعين الفارطين
- خلال الأسابيع الـ 3 الماضية
- خلال الشهر الماضي
- خلال الشهرين الفارطين
- خلال الأشهر الـ 3 الماضية
- خلال الأشهر الـ 6 الماضية
- خلال العام الماضي
- المجلدات التي تود إظهارها
- الكل
- المجلدات من الفئة الأولى فقط
- المجلدات من الفئة الأولى و الثانية
- الكل عدا مجلدات الفئة الثانية
- مجلدات الإستجواب
- الكل
- المجلدات من الفئة الأولى فقط
- المجلدات من الفئة الأولى و الثانية
- الكل عدا مجلدات الفئة الثانية
- بدون
- الكل
- المجلدات من الفئة الأولى فقط
- المجلدات من الفئة الأولى و الثانية
- الكل عدا مجلدات الفئة الثانية
- بدون
- الكل
- المجلدات من الفئة الأولى فقط
- المجلدات من الفئة الأولى و الثانية
- الكل عدا مجلدات الفئة الثانية
- احذف الرسائل عند حذفها على الخادم
- إعدادات المجلد
- العرض في قمة المجموعة
- فئة عرض المجلد
- دون تصنيف
- الفئة الأولى
- الفئة الثانية
- بدون
- الفئة الأولى
- الفئة الثانية
- دون تصنيف
- الفئة الأولى
- الفئة الثانية
- فئة تنبيهات المجلد
- دون تصنيف
- الفئة الأولى
- الفئة الثانية
- امحوا الرسائل المحلية
- خادم الوارد
- إعداد خادم البريد الوارد
- خادم الصادر
- إعداد خادم البريد الصادر SMTP
- اسم الحساب
- اسمك
- التنبيهات
- الاهتزاز
- الهتزاز عند وصول البريد
- نمط الإهتزاز
- الإفتراضي
- النمط ١
- النمط ٢
- النمط ٣
- النمط ٤
- النمط ٥
- مُعاودة الإهتزاز
- نغمة البريد الجديد
- وميض ضوء التنبيهات
- خيارات تحرير الرسائل
- الخيارات الإفتراضية للتحرير
- إدارة الهويات
- إدارة الهويات
- إدارة الهوية
- تعديل الهوية
- احفظ
- هوية جديدة
- حرر
- إلى الأعلى
- إلى الأسفل
- احذف
- وصف الهوية
- (اختياري)
- اسمك
- (اختياري)
- عنوان البريد الإليكتروني
- (ضروري)
- عنوان تلقّي الردود
- (اختياري)
- التوقيع
- (اختياري)
- إستخدم التوقيع
- التوقيع
- الهوية الأصلية
- إختيار هوية
- قم بالإرسال كـ
- لا يمكنك حذف هويتك الوحيدة
- لا يمكنك استعمال هوية غير مربوطة بعنوان بريد إلكتروني
- الرسائل القديمة أولًا
- الرسائل الجديدة أولًا
- حسب المواضيع أبجديا
- حسب الأبجدية العكسية للمواضيع
- حسب المرسلون أبجديا
- الرسائل المحددة بنجمة أولا
- الرسائل غير المحددة بنجمة أولا
- الرسائل غير المقروءة أولا
- الرسائل المقروءة أولا
- الرسائل التي تحتوي على مُرفَقات أولاً
- الرسائل التي لا تحتوي على مُرفَقات أولاً
- رتب مستخدمًا…
- التاريخ
- العنوان
- المُرسِل
- نجمة
- مقروء/غير مقروء
- المُرفَقات
- احذف الحساب
- الشهادة غير معترف بها
- اقبل المفتاح
- ارفض المفتاح
- إسم المجلد يحتوي
- اظهر المجلدات…
- كل المجلدات
- المجلدات من الفئة الأولى فقط
- المجلدات من الفئة الأولى و الثانية
- اخفي المجلدات من الفئة الثانية
- وضعية التوقيع
- قبل النص المُقتبَس
- بعدَ النص المُقتبَس
- إستخدم سمة التطبيق
- مظلِم
- مضيئ
- المظهر
- العامة
- التنقيح
- الخصوصية
- الشبكة
- التفاعل
- قائمة الحساب
- قوائم الرسالة
- الرسائل
- السمة
- سمة المحرر
- اللغة
- الإفتراضي في النظام
- المزامنة في الخلفية
- أبدًا
- دائمًا
- حدد الكل
- 5 مجلدات
- 10 مجلدات
- 25 مجلدا
- 50 مجلدا
- 100 مجلد
- 250 مجلدا
- 500 مجلد
- 1000 مجلد
- الحركة
- التصفح عبر أزرار التحكم في الصوت
- %s%s
- - غير المقروءة
- كل الرسائل
- البريد الوارد الموحَّد
- كل الرسائل في مجلدات موحَّدة
- التوحيد
- حسابات البحث
- الكل
- بدون
- بدون
- حجم الخط
- إختيار حجم الخط
- قائمة الحساب
- اسم الحساب
- وصف الحساب
- مجلد القوائم
- اسم المجلد
- حالة المجلد
- قوائم الرسالة
- العنوان
- مُرسِل
- تاريخ
- معاينة
- رسائل
- مُرسِل
- إلى
- نسخة
- ترويسات إضافية
- العنوان
- الوقت والتاريخ
- نصّ الرسالة
- %d%%
- %1$s: %2$s
- إنشاء الرسالة
- حقول إدخال النص
- الإفتراضي
- أصغر شيء
- ضئيل
- أصغر
- صغير
- وسط
- كبير
- أكبر
- فشل الإرسال : %s
- احفظ مسودة الرسالة؟
- احفظ أو إلغ الرسالة؟
- هل تريد إلغاء الرسالة ؟
- هل أنت متأكد من أنك تود إلغاء هذه الرسالة ؟
- حدّد النص للنسخ
- تأكيد الحذف
- أتريد حذف هذه الرسالة؟
- نعم
- لا
- أتريد جعل كل الرسائل مقروءة؟
- تأكيد إفراغ المهملات
- أتريد إفراغ مجلد المهملات؟
- نعم
- لا
- تأكيد النقل إلى مجلد البريد المزعج
- نعم
- لا
- يتم تنزيل المُرفَقات
- »
- ›
- النسخ الاحتياطي
- مُتنوع
- تصدير الإعدادات
- تصدير
- شارك
- تصدير الإعدادات…
- تمت عملية تصدير الإعدادات بنجاح
- فشل تصدير الإعدادات
- استيراد الإعدادات
- اختيار ملف
- استيراد
- لاحقًا
- استيراد الإعدادات
- استيراد الإعدادات…
- اسم الخادم: %s
- الحساب
- البريد الوارد الموحَّد
- تعداد المجلدات
- مجلد
- تم
- لم يتم اختيار أي حساب
- لم يتم اختيار أي مجلد
- دون نص
- افتح الرابط
- شارك الرابط
- انسخ الرابط إلى الحافظة
- الرابط
- صورة
- أظهر الصورة
- احفظ الصورة
- نزل صورة
- انسخ رابط الصورة إلى الحافظة
- رابط الصورة
- اطلب رقم
- احفظ في جهات الاتصال
- انسخ الرسالة إلى الحافظة
- رقم الهاتف
- إرسل رسالة
- احفظ في جهات الاتصال
- انسخ العنوان إلى الحافظة
- عناوين البريد
- الكل
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- إرسال الطلب إلى الخادوم
- ابحث
- تمكين البحث في الخادوم
- ابحث عن الرسائل في الخادم
- تغيير لون الرسالة بعد قراءتها
- إجمع الرسائل في محادثات
- تحديث قواعد البيانات
- يُحدث قواعد البيانات…
- تحديث قاعدة بيانات الحساب \"%s\"
- دائمًا
- أبدًا
- اظهر صورة المُتراسل
- علم الكل كمقروئين
- تلوين صور جهات الاتصال
- تلوين صور الناقصة لجهات الاتصال
- يتم تحميل المُرفَقات…
- يُرسل رسالة
- جارٍ حفظ المسودّة
- يتم جلب المُرفَقات…
-
- إستخدم شهادة عميل
- بدون شهادة عميل
- خيارات متقدمة
-
- *مشفّرة*
- نسخة
- إلى
- مِن
- المنزل
- العمل
- أخرى
- الجوال
- الملفات المُرفقة غير مدعومة
- حسنًا !
- إلغ التفعيل
- إتركها مُفعلة
- حسنًا !
- إلغ التفعيل
- إتركها مُفعلة
- التواقيع قد تظهر كمرفقات \'signature.asc\' في بعض برامج البريد.
- الرسالة المُعماة \"المشفرة\" دائمًا ما تحتوي على توقيع.
- نص مُجرّد
- يجب تنزيل الرسالة كاملة ليتم معالجة التوقيع
- مِن طرف مُوقِّع مُؤكَّد
- نص مُجرَّد مُوَقَّع
- مُعَمّى
- مُعَمّى
- مُعَمّى
- حسنًا
- البحث عن مفتاح
- إظهار المُوَقِّع
- إظهار المُرسِل
- التفاصيل
- فك القفل
- مُرفق غير محمي
- يُحمل…
- تم إلغاء فك التعمية.
- إعادة المحاولة
- خطأ أنثاء عملية فك تعمية الرسالة الإلكترونية
- نص غير مُوَقَّع
- لذلك فإن دعم برنامج APG قد حُذف من بريد كيه-٩.
- توقف تطويره في بداية ٢٠١٤
- تحتوي على مشكلة أمنية غير محلولة.
- لمعرفة المزيد يمكنك الضغط هنا.
- حسنًا !
- APG
- هذه الرسالة مُعماة
- Mail Message List
- يُحمل الرسائل…
- فشلت عملية جلب قائمة المجلدات
- التعمية غير ممكنة
- تنشيط التعمية
- تعطيل التعمية
- حسناً
- العودة
- تعطيل التعمية
- تعمية أوبن بي جي بي OpenPGP
- لمعرفة المزيد يمكنك النقر هنا.
- الإعدادات العامة
- ليس هناك أي تطبيق أوبن بي جي بي مُثبّت
- تثبيت
- رسالة مشفّرة
- إرسال رسالة إلى:
- مُفعّل
- مُوقّف
- افتح
- اغلق
-
- لمعرفة المزيد
+ %.1f جيجا
+ %.1f ميجا
+ %.1f كيلو
+ %d بايت
+ تم تقليص الحساب \"%s من %s الى %s
+ يتم ضغط \"%s\"
+ رسالة جديدة
+
+ %d ﻻ رسائل
+ %d رسالة واحدة
+ %d رسالتان
+ %d رسائل
+ %d رسالة
+ %d رسالة جديدة
+
+ %d غير مقروئة (%s)
+ رُد
+ إعتبارها مقروءة
+ إعتبار الكل كمقروء
+ احذف
+ احذف الكل
+ أرشيف
+ أرشفة الكل
+ بريد مُزعج
+ خطأ في شهادة %s
+ تأكد من إعدادات الخادم
+ فشل المصادقة
+ فشل مصادقة %s. يرجى تحديث إعدادات الخادم.
+ تفقد البريد: %s:%s
+ التحقق من البريد
+ إرسال البريد: %s
+ إرسال البريد
+ :
+ الرسائل
+ إشعارات ذات علاقة بالرسائل
+ مُتنوع
+ تنبيهات متفرقة مثل الأخطاء وغيرها من الأمور.
+ الوارد
+ الصادر
+ المسودات
+ المهملات
+ المُرسَل
+ فشِلَت عملية إرسال بعض الرسائل
+ الإصدار
+ تمكين تسجيل التحاليل
+ عمل سجل ببيانات تشخيصية إضافية
+ إضافة البيانات الحساسة إلى السجل
+ يمكن أن يُظهر الكلمات السرية في السجلّات.
+ تحميل رسائل إضافية
+ إلى:%s
+ الموضوع
+ نصّ الرسالة
+ التوقيع
+ -------- الرسالة الأصلية --------
+ الموضوع :
+ المُرسل:
+ مِن :
+ إلى :
+ نسخة كربونية :
+ %s كَتَب :
+ بتاريخ %1$s، %2$s الرسالة:
+ يجب إضافة عنوان مُتَلقٍ واحد على الأقل.
+ لم نتمكن من العثور على أي عنوان بريد إلكتروني لجهة الإتصال هذه.
+ لا يمكن إعادة توجيه بعض المُرفَقات لأنه لم يتم تنزيلها بعد.
+ لا يمكن إعادة توجيه الرسالة لوجود بعض المُرفَقات التي يتم تنزيلها.
+ إدماج نص الرسالة المُقتبَس
+ حذف النص المقتبَس
+ تعديل النص المقتبَس
+ إزالة المُرفَق
+ من: %s <%s>
+ إلى :
+ نسخة كربونية :
+ نسخة مخفية:
+ افتح
+ احفظ
+ غير قادر على حفظ المُرفَق.
+ اظهر الصور
+ يتعذر إيجاب تطبيق لعرض %s.
+ تنزيل الرسالة كاملةً
+ ﻻ يُمكن عرض الرسالة
+ عبر %1$s
+
+ تم تنزيل جميع الترويسات ولكن لا يوجد ترويسات إضافية لعرضها.
+ فشل استرداد الترويسات الإضافية من قاعدة بيانات أو من الخادم.
+ المزيد من هذا المُرسِل
+ مِن طرف %s
+ تشخيص \ حذف محتويات الرسالة
+ تم إلغاء الرسالة
+ تم الإحتفاظ بالرسالة كمسودة
+ إظهار النجوم
+ معاينة الخطوط
+ أظهر أسماء مُراسِليك
+ إظهار أسماء المُراسلين بدلًا مِن عناوين بريدهم الإلكترونية
+ المُراسل فوق موضوع الرسالة
+ اظهر أسماء المتراسيلن
+ تلوين المُتراسِلين
+ تلوين أسماء جهات الإتصال
+ حجم خط ثابت
+ ﻻئم الرسالة تلقائيًا
+ تقليص الرسالة لتناسب الشاشة
+ عودة إلى اللائحة بعد الحذف
+ عودة إلى لائحة الرسائل بعد حذف الرسالة
+ إظهار الرسالة التالية بعد الحذف
+ إظهار الرسالة التالية دائمًا بعد حذف الرسالة
+ أكّد الإجاءات
+ احذف
+ احذف الرسائل المميزة بنجمة (في لائحة الرسائل)
+ بريد مُزعج
+ إلغاء الرسالة
+ جعل كل الرسائل مقروءة
+ احذف (من الإشعارات)
+ إخفاء عميل البريد
+ احذف مُعرف بريد كية-9 من ترويسات الرسالة
+ احذف التوقيت
+ إظهار زر ’الحذف‘
+ أبدًا
+ للإشعارات ذات الرسالة الواحدة
+ دائمًا
+ إشعارات الشاشة المقفلة
+ لا إشعارات في قفل الشاشة
+ اسم التطبيق
+ تعداد الرسائل و المُرسِلين
+ الشيء نفسه عندما تكون الشاشة غير مقفلة
+ وقت الهدوء
+ عطل التنبيهات
+ عطل التنبيهات بشكل كلي أثناء وقت الهدوء
+ وقت الهدوء يبدأ من
+ وقت الهدوء ينتهي عند
+ إعداد حساب جديد
+ عنوان البريد الإليكتروني
+ كلمة السِّر
+ اظهر كلمة السِّر
+
+ الإعداد يدويا
+
+ المصادقة \u2026
+ جارٍ الإلغاء\u2026
+ لقد انتهيت تقريبًا
+ اَعطِ هذا الحساب اسمًا (اختياري):
+ اكتب اسمك (تظهر في الرسائل الصادرة):
+ نوع الحساب
+ ما نوع هذا الحساب؟
+ POP3
+ IMAP
+ كلمة مرور عادية
+ كلمة السر، مُرسَلَة بشكل غير آمن
+ كلمة سِّر مُعماة
+ شهادة العميل
+ إعدادات الخادم الوارد
+ اسم المُستخدم
+ كلمة السِّر
+ شهادة العميل
+ خادم POP3
+ خادم IMAP
+ خادم إكستشينج
+ المَنفذ
+ الأمان
+ المصادقة
+ بدون
+ SSL/TLS
+ STARTTLS
+ عندما أحذف رسالة
+ ﻻ تحذفها على الخادم
+ احذفها على الخادم
+ إعتبارها كمقروءة على السيرفر
+ إستخدام الضغط على شبكة :
+ الجوال
+ الواي فاي
+ أخرى
+ إزالة الرسائل المحذوفة من الخادوم أيضا
+ فورًا
+ عند الإستجواب
+ يدوي
+ بادئة مسار IMAP
+ مجلد المسودات
+ مجلد الرسائل المرسَلة
+ مجلد المهملات
+ مجلد الأرشيف
+ مجلد البريد المزعج
+ توسيع المجلد تلقائيا
+ مسار OWA
+ اختياري
+ مسار المصادقة
+ اختياري
+ علبة بريد التحويل
+ اختياري
+ إعدادات الخادم الخارج
+ خادم SMTP
+ المَنفذ
+ الأمان
+ يتطلب تسجيل الدخول
+ اسم المُستخدم
+ كلمة السِّر
+ المصادقة
+ خيارات الحساب
+ تضغيط الحساب
+ أبدًا
+ كل 15 دقيقة
+ كل 30 دقيقة
+ كل ساعة
+ كل ساعتين
+ كل 3 ساعات
+ كل 6 ساعات
+ كل 12 ساعة
+ كل 24 ساعة
+ كل دقيقتين
+ كل 3 دقائق
+ كل 6 دقائق
+ كل 12 دقيقة
+ كل 24 دقيقة
+ كل 36 دقيقة
+ كل 48 دقيقة
+ كل 60 دقيقة
+ نبهني عند وصول رسالة
+ عدد الرسائل التي ستظهر
+ 10 رسائل
+ 25 رسالة
+ 50 رسالة
+ 100 رسالة
+ 250 رسالة
+ 500 رسالة
+ 1000 رسالة
+ 2500 رسالة
+ 5000 رسالة
+ 10000 رسالة
+ كل الرسائل
+ تعذرت مواصلة عملية إتمام الإعداد
+ إسم المستخدم أو كلمة السر خاطئة.\n(%s)
+ تعديل التفاصيل
+ مواصلة
+ متقدمة
+ إعدادات الحساب
+ إشعارات البريد الجديد
+ مجلد الإخطارات
+ الكل
+ المجلدات من الفئة الأولى فقط
+ المجلدات من الفئة الأولى و الثانية
+ الكل عدا مجلدات الفئة الثانية
+ بدون
+ إخطارات المزامنة
+ بريدك الإليكتروني
+ إظهار إشعارات على شريط الحالة عند تلقي بريد جديد
+ إضافة البريد الصادر
+ إظهار إشعارات للرسائل التي أبعثُها
+ جهات الإتصال فقط
+ إظهار الإشعارات فقط عند تلقي رسائل مِن طرف مراسلين معروفين
+ تحديد الرسالة كمقروءة بعد فتحها
+ تحديد الرسالة كمقروءة بعد فتحها الإطلاع عليها
+ دائمًا اظهر الصور
+ لا
+ من المُتراسِلين
+ من أي أحد
+ إرسال البريد
+ إقتباس نص الرسالة عند الإجابة
+ إدماج نص الرسالة الأصلية ضمن إجابتك.
+ الإجابة تحت النص المقتبَس
+ ستظهر الرسالة الأصلية فوق ردّك
+ التجريد مِن التوقيعات عند الرد
+ يحذف التوقيعات مِن نص الرسائل المُقتبَسة
+ تنسيق الرسالة
+ نص صِرفْ (احذف الصُور و التنسيقات)
+ HTML (ابقي على الصُور و التنسيقات)
+ آلي
+ اشعار قراءة
+ أطلب دائما إشعارا عند القراءة
+ أسلوب الإقتباس عند الإجابة
+ البادئة (مثلَ بريد جي مايل)
+ الرأسية (مِثل آوتلوك)
+ الإعدادات العامة
+ قراءة البريد
+ جلب البريد
+ المجلدات
+ بادئة النص المُقتَبَس
+ التعمية مِن الطرف إلى نهاية الطرف
+ تنشيط دعم أوبن بي جي بي
+ إختيار تطبيق أوبن بي جي بي
+ متصل بـ %s
+ الضبط جارٍ...
+ لون الحساب
+ مِن دون لون
+ لون ضوء التنبيهات
+ حجم المجلد المحلي
+ 1 KiB
+ 2 KiB
+ 4 KiB
+ 8 KiB
+ 16 KiB
+ 32 KiB
+ 64 KiB
+ 128 KiB
+ 256 KiB
+ 512 KiB
+ 1 MiB
+ 2 MiB
+ 5 MiB
+ 10 MiB
+ أي حجم (بدون حَدْ)
+ زَامن الرسائل مع
+ أي وقت (بدون حَدْ)
+ اليوم
+ خلال اليومين الفارطين
+ خلال الأيام الـ 3 الماضية
+ خلال الأسبوع الماضي
+ خلال الأسبوعين الفارطين
+ خلال الأسابيع الـ 3 الماضية
+ خلال الشهر الماضي
+ خلال الشهرين الفارطين
+ خلال الأشهر الـ 3 الماضية
+ خلال الأشهر الـ 6 الماضية
+ خلال العام الماضي
+ المجلدات التي تود إظهارها
+ الكل
+ المجلدات من الفئة الأولى فقط
+ المجلدات من الفئة الأولى و الثانية
+ الكل عدا مجلدات الفئة الثانية
+ مجلدات الإستجواب
+ الكل
+ المجلدات من الفئة الأولى فقط
+ المجلدات من الفئة الأولى و الثانية
+ الكل عدا مجلدات الفئة الثانية
+ بدون
+ الكل
+ المجلدات من الفئة الأولى فقط
+ المجلدات من الفئة الأولى و الثانية
+ الكل عدا مجلدات الفئة الثانية
+ بدون
+ الكل
+ المجلدات من الفئة الأولى فقط
+ المجلدات من الفئة الأولى و الثانية
+ الكل عدا مجلدات الفئة الثانية
+ احذف الرسائل عند حذفها على الخادم
+ إعدادات المجلد
+ العرض في قمة المجموعة
+ فئة عرض المجلد
+ دون تصنيف
+ الفئة الأولى
+ الفئة الثانية
+ بدون
+ الفئة الأولى
+ الفئة الثانية
+ دون تصنيف
+ الفئة الأولى
+ الفئة الثانية
+ فئة تنبيهات المجلد
+ دون تصنيف
+ الفئة الأولى
+ الفئة الثانية
+ امحوا الرسائل المحلية
+ خادم الوارد
+ إعداد خادم البريد الوارد
+ خادم الصادر
+ إعداد خادم البريد الصادر SMTP
+ اسم الحساب
+ اسمك
+ التنبيهات
+ الاهتزاز
+ الهتزاز عند وصول البريد
+ نمط الإهتزاز
+ الإفتراضي
+ النمط ١
+ النمط ٢
+ النمط ٣
+ النمط ٤
+ النمط ٥
+ مُعاودة الإهتزاز
+ نغمة البريد الجديد
+ وميض ضوء التنبيهات
+ خيارات تحرير الرسائل
+ الخيارات الإفتراضية للتحرير
+ إدارة الهويات
+ إدارة الهويات
+ إدارة الهوية
+ تعديل الهوية
+ احفظ
+ هوية جديدة
+ حرر
+ إلى الأعلى
+ إلى الأسفل
+ احذف
+ وصف الهوية
+ (اختياري)
+ اسمك
+ (اختياري)
+ عنوان البريد الإليكتروني
+ (ضروري)
+ عنوان تلقّي الردود
+ (اختياري)
+ التوقيع
+ (اختياري)
+ إستخدم التوقيع
+ التوقيع
+ الهوية الأصلية
+ إختيار هوية
+ قم بالإرسال كـ
+ لا يمكنك حذف هويتك الوحيدة
+ لا يمكنك استعمال هوية غير مربوطة بعنوان بريد إلكتروني
+ الرسائل القديمة أولًا
+ الرسائل الجديدة أولًا
+ حسب المواضيع أبجديا
+ حسب الأبجدية العكسية للمواضيع
+ حسب المرسلون أبجديا
+ الرسائل المحددة بنجمة أولا
+ الرسائل غير المحددة بنجمة أولا
+ الرسائل غير المقروءة أولا
+ الرسائل المقروءة أولا
+ الرسائل التي تحتوي على مُرفَقات أولاً
+ الرسائل التي لا تحتوي على مُرفَقات أولاً
+ رتب مستخدمًا…
+ التاريخ
+ العنوان
+ المُرسِل
+ نجمة
+ مقروء/غير مقروء
+ المُرفَقات
+ احذف الحساب
+ الشهادة غير معترف بها
+ اقبل المفتاح
+ ارفض المفتاح
+ إسم المجلد يحتوي
+ اظهر المجلدات…
+ كل المجلدات
+ المجلدات من الفئة الأولى فقط
+ المجلدات من الفئة الأولى و الثانية
+ اخفي المجلدات من الفئة الثانية
+ وضعية التوقيع
+ قبل النص المُقتبَس
+ بعدَ النص المُقتبَس
+ إستخدم سمة التطبيق
+ مظلِم
+ مضيئ
+ المظهر
+ العامة
+ التنقيح
+ الخصوصية
+ الشبكة
+ التفاعل
+ قائمة الحساب
+ قوائم الرسالة
+ الرسائل
+ السمة
+ سمة المحرر
+ اللغة
+ الإفتراضي في النظام
+ المزامنة في الخلفية
+ أبدًا
+ دائمًا
+ حدد الكل
+ 5 مجلدات
+ 10 مجلدات
+ 25 مجلدا
+ 50 مجلدا
+ 100 مجلد
+ 250 مجلدا
+ 500 مجلد
+ 1000 مجلد
+ الحركة
+ التصفح عبر أزرار التحكم في الصوت
+ %s%s
+ - غير المقروءة
+ كل الرسائل
+ البريد الوارد الموحَّد
+ كل الرسائل في مجلدات موحَّدة
+ التوحيد
+ حسابات البحث
+ الكل
+ بدون
+ بدون
+ حجم الخط
+ إختيار حجم الخط
+ قائمة الحساب
+ اسم الحساب
+ وصف الحساب
+ مجلد القوائم
+ اسم المجلد
+ حالة المجلد
+ قوائم الرسالة
+ العنوان
+ مُرسِل
+ تاريخ
+ معاينة
+ رسائل
+ مُرسِل
+ إلى
+ نسخة
+ ترويسات إضافية
+ العنوان
+ الوقت والتاريخ
+ نصّ الرسالة
+ %d%%
+ %1$s: %2$s
+ إنشاء الرسالة
+ حقول إدخال النص
+ الإفتراضي
+ أصغر شيء
+ ضئيل
+ أصغر
+ صغير
+ وسط
+ كبير
+ أكبر
+ فشل الإرسال : %s
+ احفظ مسودة الرسالة؟
+ احفظ أو إلغ الرسالة؟
+ هل تريد إلغاء الرسالة ؟
+ هل أنت متأكد من أنك تود إلغاء هذه الرسالة ؟
+ حدّد النص للنسخ
+ تأكيد الحذف
+ أتريد حذف هذه الرسالة؟
+ نعم
+ لا
+ أتريد جعل كل الرسائل مقروءة؟
+ تأكيد إفراغ المهملات
+ أتريد إفراغ مجلد المهملات؟
+ نعم
+ لا
+ تأكيد النقل إلى مجلد البريد المزعج
+ نعم
+ لا
+ يتم تنزيل المُرفَقات
+ »
+ ›
+ النسخ الاحتياطي
+ مُتنوع
+ تصدير الإعدادات
+ تصدير
+ شارك
+ تصدير الإعدادات…
+ تمت عملية تصدير الإعدادات بنجاح
+ فشل تصدير الإعدادات
+ استيراد الإعدادات
+ اختيار ملف
+ استيراد
+ لاحقًا
+ استيراد الإعدادات
+ استيراد الإعدادات…
+ اسم الخادم: %s
+ الحساب
+ البريد الوارد الموحَّد
+ تعداد المجلدات
+ مجلد
+ تم
+ لم يتم اختيار أي حساب
+ لم يتم اختيار أي مجلد
+ دون نص
+ افتح الرابط
+ شارك الرابط
+ انسخ الرابط إلى الحافظة
+ الرابط
+ صورة
+ أظهر الصورة
+ احفظ الصورة
+ نزل صورة
+ انسخ رابط الصورة إلى الحافظة
+ رابط الصورة
+ اطلب رقم
+ احفظ في جهات الاتصال
+ انسخ الرسالة إلى الحافظة
+ رقم الهاتف
+ إرسل رسالة
+ احفظ في جهات الاتصال
+ انسخ العنوان إلى الحافظة
+ عناوين البريد
+ الكل
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ إرسال الطلب إلى الخادوم
+ ابحث
+ تمكين البحث في الخادوم
+ ابحث عن الرسائل في الخادم
+ تغيير لون الرسالة بعد قراءتها
+ إجمع الرسائل في محادثات
+ تحديث قواعد البيانات
+ يُحدث قواعد البيانات…
+ تحديث قاعدة بيانات الحساب \"%s\"
+ دائمًا
+ أبدًا
+ اظهر صورة المُتراسل
+ علم الكل كمقروئين
+ تلوين صور جهات الاتصال
+ تلوين صور الناقصة لجهات الاتصال
+ يتم تحميل المُرفَقات…
+ يُرسل رسالة
+ جارٍ حفظ المسودّة
+ يتم جلب المُرفَقات…
+
+ إستخدم شهادة عميل
+ بدون شهادة عميل
+ خيارات متقدمة
+
+ *مشفّرة*
+ نسخة
+ إلى
+ مِن
+ المنزل
+ العمل
+ أخرى
+ الجوال
+ الملفات المُرفقة غير مدعومة
+ حسنًا !
+ إلغ التفعيل
+ إتركها مُفعلة
+ حسنًا !
+ إلغ التفعيل
+ إتركها مُفعلة
+ التواقيع قد تظهر كمرفقات \'signature.asc\' في بعض برامج البريد.
+ الرسالة المُعماة \"المشفرة\" دائمًا ما تحتوي على توقيع.
+ نص مُجرّد
+ يجب تنزيل الرسالة كاملة ليتم معالجة التوقيع
+ مِن طرف مُوقِّع مُؤكَّد
+ نص مُجرَّد مُوَقَّع
+ مُعَمّى
+ مُعَمّى
+ مُعَمّى
+ حسنًا
+ البحث عن مفتاح
+ إظهار المُوَقِّع
+ إظهار المُرسِل
+ التفاصيل
+ فك القفل
+ مُرفق غير محمي
+ يُحمل…
+ تم إلغاء فك التعمية.
+ إعادة المحاولة
+ خطأ أنثاء عملية فك تعمية الرسالة الإلكترونية
+ نص غير مُوَقَّع
+ لذلك فإن دعم برنامج APG قد حُذف من بريد كيه-٩.
+ توقف تطويره في بداية ٢٠١٤
+ تحتوي على مشكلة أمنية غير محلولة.
+ لمعرفة المزيد يمكنك الضغط هنا.
+ حسنًا !
+ APG
+ هذه الرسالة مُعماة
+ قائمة رسائل K-9
+ يُحمل الرسائل…
+ فشلت عملية جلب قائمة المجلدات
+ التعمية غير ممكنة
+ تنشيط التعمية
+ تعطيل التعمية
+ حسناً
+ العودة
+ تعطيل التعمية
+ تعمية أوبن بي جي بي OpenPGP
+ لمعرفة المزيد يمكنك النقر هنا.
+ الإعدادات العامة
+ ليس هناك أي تطبيق أوبن بي جي بي مُثبّت
+ تثبيت
+ رسالة مشفّرة
+ إرسال رسالة إلى:
+ مُفعّل
+ مُوقّف
+ افتح
+ اغلق
+
+ لمعرفة المزيد
diff --git a/app/ui/legacy/src/main/res/values-be/strings.xml b/app/ui/legacy/src/main/res/values-be/strings.xml
index 277238ef4b5313e63b8819a65c995e293351916b..8d86cb7475545b979415a5745d4e00058d0a8a49 100644
--- a/app/ui/legacy/src/main/res/values-be/strings.xml
+++ b/app/ui/legacy/src/main/res/values-be/strings.xml
@@ -243,10 +243,6 @@
Remove Mail User-Agent from mail headersСхаваць часавы поясВыкарыстоўваць у загалоўках лістоў UTC замест мясцовага часу
- Схаваць тэму ў апавяшчэнні
- Ніколі
- Калі прылада заблакаваная
- ЗаўсёдыПаказваць кнопку выдаленняНіколіДля аднаго ліста
@@ -254,7 +250,6 @@
Апавяшчэнні на экране блакаванняПрыбраць з экрана блакаванняНазва праграмы
- Лічыльнік непрачытаных лістоўЛічыльнік лістоў і адпраўнікіЯк без блакаванняПерыяд цішыні
@@ -267,6 +262,7 @@
Адрас электроннай поштыПарольПаказаць пароль
+
УласнаручнаАтрыманне звестак\u2026
@@ -308,8 +304,6 @@
МабільныяWi-FiІншыя
- Вонкавае сховішча (картка памяці)
- Унутранае сховішчаСціранне выдаленых лістоў з сервераНеадкладнаПадчас праверкі
@@ -385,8 +379,6 @@
ПрацягнуцьДадатковаНалады акаўнта
- Прадвызначаны акаўнт
- Прадвызначана адпраўляць пошту з гэтага акаўнтаАпавяшчэнне пра новую поштуАпавяшчэнні каталогаўУсе
@@ -406,8 +398,6 @@
Пазначаць ліст прачытаным пасля праглядуПазначаць як прачытанае пры выдаленніПазначаць ліст як прачытаны пасля яго выдалення
- Налады апавяшчэнняў
- Адкрыць сістэмныя налады апавяшчэнняўЗаўсёды паказваць выявыНеАд кантактаў
diff --git a/app/ui/legacy/src/main/res/values-bg/strings.xml b/app/ui/legacy/src/main/res/values-bg/strings.xml
index 536e913bafc4335b4ab6e77ced4cb520685b8e18..4038a58ce39f32ea632bb6437e504edb78d9a495 100644
--- a/app/ui/legacy/src/main/res/values-bg/strings.xml
+++ b/app/ui/legacy/src/main/res/values-bg/strings.xml
@@ -25,12 +25,40 @@
Показване на последните промени при обновяване на програматаРазбери какво ново в тази варсия
- Welcome to Mail
- Mail is the default mail client for /e/
+ Добре дошли в Mail
+
+ Mail е мощен, безплатен имейл клиент за Андроид.
+
+Подобрените функции включват:
+
+
+
Push mail използвайки IMAP IDLE
+
По-добра производителност
+
Преместване на съобщения
+
Имейл подписи
+
Bcc до себе си
+
Абонамент за папки
+
Синхронизиране на всички папки
+
Конфигурация на адреса за връщане
+
Кратки клавишни комбинации
+
По-добра подръжка на IMAP
+
Запазване на прикачени файлове на SD
+
Изпразване на кошчето
+
Сортиране на съобщения
+
…и още
+
+
+Моля знайте, че K-9 не подържа повечето безплатни Hotmail профили и, че както повечето имейл приложения има няколко странности, когато говори с Microsoft Exchange.
+
+Моля изпращайте доклади за бъгове, допринасяйте за нови функции и задавайте въпроси на
+https://github.com/k9mail/k-9/.
+
+ ]]>
- -- Sent from /e/ Mail.
+ -- \nИзпратено от моето Андроид у-во чрез K-9 Mail. Моля да ме извините за краткия ми изказ.
- The account \"%s\" will be removed from Mail.
+ Акаунтът \"%s\" ще бъде премахнат от K-9 Mail.АвториПреглед на информацията
@@ -38,7 +66,7 @@
Позволи на тази програма да чете вашите Писма.Изтрий ПисматаПозволи на тази програма да изтрива вашите Писма.
- About Mail
+ Относно K-9 MailПрофилиПапкиРазширени
@@ -115,7 +143,7 @@
ПрикачиИзпразни кошчетоПремахни
- About
+ ОтносноНастройки(Без тема)
@@ -125,10 +153,6 @@
Съобщението не е намереноГрешка при зареждане на съобщениетоЗареди още %d
- %.1f ГБ
- %.1f МБ
- %.1f КБ
- %d БПрофил \"%s\" се смали от %s до %sКомпресира профил \"%s\"Ново Писмо
@@ -245,10 +269,6 @@
Remove Mail User-Agent from mail headersСкриване на времевата зонаИзползване на UTC вместо локално време в header-a и reply header-a
- Скрий темата в известяванията
- Никога
- Когато у-вото е заключено
- ВинагиПоказвай бутон `Изтрий`НикогаЗа отделни съобщения
@@ -256,7 +276,6 @@
Известия при заключен екранБез известия при заключен екранИме на програмата
- Брояч на непрочетени съобщенияБрояч на съобщения и изпращачиСъщото, както когато екранът е заключенТих режим
@@ -269,6 +288,7 @@
Пощенски адресПаролаПокажи паролата
+
Ръчни настройкиПолучаване на информация за профила\u2026
@@ -310,8 +330,6 @@
МобилнаWi-FiДруга
- Външна памет (SD карта)
- Вътрешна паметПремахни изтритите от сървъра съобщенияВеднагаПри проверка
@@ -387,8 +405,6 @@
ПродължиРазширениНастройки на профила
- Профил по подразбиране
- Изпращане на поща от този профил по подразбиранеНово известие за пощаПапка с известияВсички
@@ -408,8 +424,6 @@
Маркирай съобщението като прочетено, когато се отвори за разглежданеМаркирай като прочетено при изтриванеМаркира съобщението като прочетено при изтриване
- Настройки на известия
- Отвори системните настройките за известияВинаги показвай картинкитеНеОт контактите
@@ -950,7 +964,7 @@
Имейлът е криптиранТози имейл е криптиран използвайки OpenPGP.\nЗа да го прочетете, трябва да инсталирате и настроите OpenPGP приложението.Към настройки
- Mail Message List
+ K-9 списък със собщенияЗареждане на съобщения…Неуспешно изтегляне списъка на папкиГрешка при изтегляне на статуса на получателя от OpenPGP доставчика!
@@ -973,7 +987,7 @@
Общи настройкиНяма инсталирано OpenPGP приложениеИнсталирване
- Mail requires OpenKeychain for end-to-end encryption.
+ Mail изисква OpenKeychain за криптирване от край-до-край.Криптирано съобщениеШифровай заглавиятаМоже да не се поддържа при всички получатели
diff --git a/app/ui/legacy/src/main/res/values-br/strings.xml b/app/ui/legacy/src/main/res/values-br/strings.xml
index e3d60226f84c94c81f5afcce6cbb7ba7bcce5b91..2169f23445607172d1d459414fb62a6f47b6cc9a 100644
--- a/app/ui/legacy/src/main/res/values-br/strings.xml
+++ b/app/ui/legacy/src/main/res/values-br/strings.xml
@@ -229,10 +229,6 @@
Remove Mail User-Agent from mail headersKuzhat ar gwerzhid-eurArverañ UTC e plas ar gwerzhid-eur lec’hel e talbennoù ar postel hag ar respont
- Kuzhat an danvez er rebuziñ
- Morse
- P’eo prennet an trevnad
- AtavDiskouez an afell ’Dilemel’MorseEvit ar rebuzadurioù gant ur gemennadenn
@@ -240,7 +236,6 @@
Rebuzadurioù ar skramm-prennañRebuzadur ebet er skramm prennañAnv an arload
- Niver a gemennadennoù anlennetNiver a gemennadennoù ha kaserienMemes tra ha p’eo dibrenn ar skrammPrantad didrouz
@@ -253,6 +248,7 @@
Chomlec’h postelGer-tremenDiskouez ar ger-tremen
+
Arventennañ dre zornO kerc’hat titouroù ar gont\u2026
@@ -294,8 +290,6 @@
HezougWi-FiAll
- Kadaviñ diavaez (Kartenn SD)
- Kadaviñ diabarzh ordinalDilemel ar c’hemennadennoù diverket war an dafariadDiouzhtuEn ur gerc’hat
@@ -371,8 +365,6 @@
Kenderc’helKemplezhoc’hArventennoù ar gont
- Kont dre ziouer
- Kas posteloù gant ar gont-mañ dre ziouerRebuzadurioù posteloù nevezTeuliadoù rebuzadurioùPep tra
@@ -390,8 +382,6 @@
Diskouez rebuzadurioù evit kemennadennoù darempredoù a anavezan hepkenMerkañ evel lennet pa vez digoretMerkañ ar gemennadenn evel lennet pa vez digoret anezho d’he gwelet
- Arventennoù rebuziñ
- Digeriñ arventennoù ar rebuzadurioù reizhiadDiskouez ar skeudennoù bepredKetDigant darempredoù
diff --git a/app/ui/legacy/src/main/res/values-ca/strings.xml b/app/ui/legacy/src/main/res/values-ca/strings.xml
index 41ac13446f6df61d385b4b7c8f709580dacd6f60..294034a9a29a91eb9818fb007fb47b29068236bd 100644
--- a/app/ui/legacy/src/main/res/values-ca/strings.xml
+++ b/app/ui/legacy/src/main/res/values-ca/strings.xml
@@ -1,87 +1,118 @@
-
-
-
- Mail
- Mail Accounts
- Mail Unread
-
- Els passejadors de gossos K-9
- Copyright 2008-%s The K-9 Dog Walkers. Porcions de Copyright 2006-%s Projecte de codi obert d\'Android.
- Codi font
- Llicència d\'Apache, versió 2.0
- Projecte de codi obert
- Lloc web
- Fòrum d\'usuaris
- Fediverse
- Twitter
- Biblioteques informàtiques
- Llicència
- Registre de canvis
- No s\'ha pogut carregar el registre de canvis.
- Versió %s
- Novetats
- Mostra els canvis recents quan s\'ha actualitzat l\'aplicació.
- Esbrineu les novetats d’aquesta versió.
-
- Welcome to Mail
- Mail is the default mail client for /e/
-
- -- Sent from /e/ Mail.
-
- The account \"%s\" will be removed from Mail.
-
- Autors
- Informació de la revisió
- Llegeix els correus
- Permet a aquesta aplicació llegir els correus.
- Elimina correus
- Permet que aquesta aplicació elimini correus.
- About Mail
- Comptes
- Carpetes
- Avançat
- Redacta
- Respon
- Respon a tothom
- Reenvia
- Reenvia com a adjunt
- Trieu un compte
- Tria carpeta
- Comprova %s:%s%s
- S\'estan recuperant capçaleres %s:%s%s
- S\'està enviant %s%s
- Proc %s:%s%s
- \u0020%d/%d
- Sincronització desactivada
- %d seleccionats
- Següent
- Anterior
-
- D\'acord
- Cancel·la
- Envia
- Torna a enviar
- L\'assumpte és buit, feu clic un altre cop per enviar-lo així
- Selecciona
- Desselecciona
- Respon
- Respon a tothom
- Elimina
- Arxiva
- Brossa
- Reenvia
- Reenvia com a adjunt
- Edita\'l com a missatge nou
- Mou
- Mou als esborranys
- Opcions del missatge…
- Rearxiva…
- Fet
- Descarta
- Desa com a esborrany
- Comprova el correu
+
+
+
+ K-9 Mail
+ Comptes del K-9
+ K-9 no llegits
+
+ Els passejadors de gossos K-9
+ Copyright 2008-%s The K-9 Dog Walkers. Porcions de Copyright 2006-%s Projecte de codi obert d\'Android.
+ Codi font
+ Llicència d\'Apache, versió 2.0
+ Projecte de codi obert
+ Lloc web
+ Fòrum d\'usuaris
+ Fediverse
+ Twitter
+ Biblioteques informàtiques
+ Llicència
+ Registre de canvis
+ No s\'ha pogut carregar el registre de canvis.
+ Versió %s
+ Novetats
+ Mostra els canvis recents quan s\'ha actualitzat l\'aplicació.
+ Esbrineu les novetats d’aquesta versió.
+
+ Us donem la benvinguda al K-9 Mail
+
+El K-9 Mail és un potent client de correu de codi lliure per a Android.
+
+Les característiques més destacables són les següents:
+
+
+
Tramet correu fent servir IMAP IDLE
+
Millor rendiment
+
Rearxivament de missatges
+
Signatures de correu
+
Còpia oculta a un mateix
+
Subscripció a carpetes
+
Sincronització de totes les carpetes
+
Configuració de l\'adreça de resposta
+
Dreceres de teclat
+
Millor suport per a IMAP
+
Possibilitat de desar els adjunts a la SD
+
Buidatge de la paperera
+
Ordenació de missatges
+
… i molt més
+
+
+Si us plau, tingueu en compte que el K-9 no admet la majoria de comptes gratuïts de Hotmail i que, com la majoria d\'altres clients de correu, té alguns problemes per interactuar amb el Microsoft Exchange.
+
+Si us plau, envieu informes d\'errors, contribuïu-hi amb noves millores i feu preguntes a
+https://github.com/k9mail/k-9/.
+
+]]>
+
+ -- \nEnviat des del meu dispositiu Android amb el K-9 Mail. Disculpeu la brevetat.
+
+ El compte \"%s\" s\'eliminarà del K-9 Mail.
+
+ Autors
+ Informació de la revisió
+ Llegeix els correus
+ Permet a aquesta aplicació llegir els correus.
+ Elimina correus
+ Permet que aquesta aplicació elimini correus.
+ Quant al K-9 Mail
+ Comptes
+ Carpetes
+ Avançat
+ Redacta
+ Respon
+ Respon a tothom
+ Reenvia
+ Reenvia com a adjunt
+ Trieu un compte
+ Tria carpeta
+ Mou a...
+ Copia a...
+ Comprova %s:%s%s
+ S\'estan recuperant capçaleres %s:%s%s
+ S\'està enviant %s%s
+ Proc %s:%s%s
+ \u0020%d/%d
+ Sincronització desactivada
+ %d seleccionats
+ Següent
+ Anterior
+
+ D\'acord
+ Cancel·la
+ Envia
+ Torna a enviar
+ L\'assumpte és buit, feu clic un altre cop per enviar-lo així
+ Selecciona
+ Desselecciona
+ Respon
+ Respon a tothom
+ Elimina
+ Arxiva
+ Brossa
+ Reenvia
+ Reenvia com a adjunt
+ Edita\'l com a missatge nou
+ Mou
+ Mou als esborranys
+ Opcions del missatge…
+ Rearxiva…
+ Fet
+ Descarta
+ Desa com a esborrany
+ Comprova el correu
+ Comprova els missatges de tots els comptesEnvia missatgesRefresca carpetesCerca carpetes
@@ -127,912 +158,912 @@
Hi ha hagut un error durant la càrrega del missatgeCarrega\'n
fins a %d més
- %.1f GB
- %.1f MB
- %.1f kB
- %d B
- Compte \"%s\" comprimida des de %s a %s
- S\'està compactant el compte \"%s\"
- Correu nou
-
- %d nous missatges
- %d nous missatges
-
- %d no llegit(s) (%s)
- + %1$d més sobre %2$s
- Respon
- Marca com a llegit
- Marca\'ls tots com a llegits
- Elimina
- Elimina-ho tot
- Arxiva
- Arxiva-ho tot
- Correu brossa
- Error al certificat de %s
- Comproveu la configuració del servidor.
- Ha fallat l\'autenticació
- Ha fallat l\'autenticació de %s. Actualitzeu la configuració del servidor.
- S\'està comprovant el correu: %s:%s
- S\'està comprovant el correu
- S\'està enviant correu: %s
- S\'està enviant correu
- .
- Sincronitza-ho (Empeny)
- Mostrat mentre s\'esperen missatges nous
- Missatges
- Notificacions relacionades amb missatges
- Miscel·lània
- Notificacions diverses, com ara errors, etc.
- Bústia d\'entrada
- Bústia de sortida
- Esborranys
- Paperera
- Enviat
- La tramesa d\'alguns missatges ha fallat.
- Versió
- Habilita la depuració del registre
- Registra informació extra de diagnòstic
- Registra informació sensible
- Pot mostrar les contrasenyes als registres.
- Carrega més missatges
- A: %s
- Assumpte
- Text del missatge
- Signatura
- -------- Missatge Original --------
- Assumpte:
- Enviat:
- De:
- A:
- A/c:
- %s ha escrit:
- El %1$s, %2$s ha escrit:
- Heu d\'afegir-hi, com a mínim, un destinatari.
- El camp del destinatari conté una entrada incompleta!
- No s\'ha trobat cap adreça de correu.
- Alguns adjunts no es poden reenviar perquè no s\'han baixat.
- Aquest missatge no es pot reenviar perquè alguns adjunts no s\'han baixat.
- Inclou el missatge citat
- Elimina el text citat
- Edita el text citat
- Suprimeix l\'adjunt
- De: %s <%s>
- A:
- A/c:
- Bcc:
- Obre
- Desa
- No s\'ha pogut desar l\'adjunt.
- Mostra les imatges
- No s\'ha pogut trobar un visualitzador per %s.
- Baixa el missatge complet
- No s\'ha pogut mostrar el missatge
- mitjançant %1$s
-
- S\'han baixat totes les capçaleres. No hi ha capçaleres addicionals per mostrar.
- La recuperació de capçaleres addicionals de la base de dades o del servidor de correu ha fallat.
- Més d\'aquest remitent
- De %s
- Depura / neteja el cos del missatge
- S\'ha descartat el missatge
- S\'ha desat el missatge com a esborrany
- Mostra els estels
- Els estels indiquen missatges marcats.
- Previsualització de línies
- Mostra noms dels contactes
- Mostra noms dels contactes enlloc dels correus
- Remitent damunt de l\'assumpte
- Mostra els nom del remitent damunt de l\'assumpte, en comptes de sota.
- Mostra els noms dels contactes
- Usa els noms dels destinataris segons els contactes quan estiguin disponibles
- Acoloreix els contactes
- Acoloreix els noms de la llista de contactes
- Tipus de lletra d\'amplada fixa
- Utilitza un tipus de lletra d\'amplada fixa quan es mostrin missatges de text pla.
- Ajusta l\'amplada dels missatges automàticament
- Retalla els missatges per adaptar la seva amplada a la pantalla.
- Torna a la llista després de l\'eliminació
- Torna a la llista de missatges després d\'eliminar missatges.
- Mostra el missatge següent després de l\'eliminació
- Mostra el missatge següent per defecte després d\'eliminar-ne un.
- Confirma accions
- Mostra un diàleg cada vegada que executis accions seleccionades
- Elimina
- Elimina els missatges amb estel (a la vista de missatges)
- Brossa
- Descarta el missatge
- Marca tots els missatges com a llegits
- Elimina (des de notificacions)
- Amaga el client de correu
- Remove Mail User-Agent from mail headers
- Amaga el fus horari
- Fes servir UTC en comptes de l\'hora local a les capçaleres dels missatges i a la capçalera de resposta
- Amaga l\'assumpte a les notificacions
- Mai
- Quan el telèfon està bloquejat
- Sempre
- Mostra el botó \"Elimina\"
- Mai
- Per a notificacions d\'un sol missatge
- Sempre
- Bloqueja les notificacions de pantalla
- No bloquegis les notificacions de pantalla
- Nom de l\'aplicació
- Compte de missatges no llegits
- Compte de missatges i remitents
- El mateix que amb la pantalla desbloquejada
- Mode silenciós
- Inhabilita el so de trucada, brunzit i llums durant la nit.
- Desactiva les notificacions
- Desactiva completament les notificacions durant el mode silenciós
- Comença el mode silenciós
- El mode silenciós acaba
- Configura un compte nou
- Adreça de correu electrònic
- Contrasenya
- Mostra la contrasenya
- Configuració manual
-
- S\'està recuperant la informació del compte\u2026
- S\'està comprovant la configuració del servidor d\'entrada\u2026
- S\'està comprovant la configuració del servidor de sortida\u2026
- S\'està autenticant\u2026
- S\'està recuperant la configuració del compte\u2026
- S\'està cancel·lant\u2026
- Ja gairebé hem acabat!
- Dóna un nom a aquest compte (opcional):
- Escriviu el nom (és el que es mostrarà als missatges sortints):
- Tipus de compte
- Quin tipus de compte és?
- POP3
- IMAP
- Contrasenya normal
- Contrasenya, transmesa de forma no segura
- Contrasenya encriptada
- Certificat del client
- Configuració del servidor d\'entrada
- Nom d\'usuari
- Contrasenya
- Certificat del client
- Servidor POP3
- Servidor IMAP
- Servidor WebDAV (Exchange)
- Port
- Tipus de seguretat
- Tipus d\'autenticació
- Cap
- SSL/TLS
- STARTTLS
- \"%1$s = %2$s\" no és vàlid amb \"%3$s = %4$s\"
- Quan elimino un missatge
- No l\'eliminis del servidor
- Elimina\'l del servidor
- Marca\'ls com a llegits al servidor
- Utilitza compressió a la xarxa:
- Mòbil
- Wi-Fi
- Altres
- Emmagatzematge extern (targeta SD)
- Emmagatzematge intern
- Elimina missatges esborrats al servidor
- Immediatament
- Quan es comprova
- Només manualment
- Autodetecció de l\'espai de noms IMAP
- Prefix del camí IMAP
- Carpeta d\'esborranys
- Carpeta d\'enviats
- Carpeta paperera
- Carpeta d\'arxiu
- Carpeta brossa
- Només mostra carpetes subscrites
- Autoexpandeix la carpeta
- Camí OWA
- Opcional
- Camí d\'autenticació
- Opcional
- Àlies de la bústia
- Opcional
- Configuració del servidor de sortida
- Servidor SMTP
- Port
- Tipus de seguretat
- Requereix inici de sessió.
- Nom d\'usuari
- Contrasenya
- Tipus d\'autenticació
- \"%1$s = %2$s\" no és vàlid amb \"%3$s = %4$s\"
- Configuració no vàlida: %s
- Opcions del compte
- Compacta el compte
- Freqüència de comprovació
- Mai
- Cada 15 minuts
- Cada 30 minuts
- Cada hora
- Cada 2 hores
- Cada 3 hores
- Cada 6 hores
- Cada 12 hores
- Cada 24 hores
- Habilita la tramesa de correu per a aquest compte
- Si el vostre servidor ho admet, els missatges arribaran automàticament. Aquesta opció pot millorar o empitjorar el rendiment.
- Refresca la connexió IDLE
- Cada 2 minuts
- Cada 3 minuts
- Cada 6 minuts
- Cada 12 minuts
- Cada 24 minuts
- Cada 36 minuts
- Cada 48 minuts
- Cada 60 minuts
- Avisa\'m quan arribi correu
- Avisa\'m mentre es comprova el correu
- Nombre de missatges a mostrar
- 10 missatges
- 25 missatges
- 50 missatges
- 100 missatges
- 250 missatges
- 500 missatges
- 1000 missatges
- 2500 missatges
- 5000 missatges
- 10000 missatges
- Tots els missatges
- No es pot copiar o moure un missatge que no està sincronitzat amb el servidor
- No s\'ha pogut acabar la configuració
- Nom d\'usuari o contrasenya incorrectes.\n(%s)
- El servidor ha mostrat un certificat SSL no vàlid. A vegades això és degut a una mala configuració del servidor. També pot ser degut que algú estigui intentant atacar-vos o al vostre servidor. Si no n\'esteu segurs feu clic a Rebutja i contacteu amb la gent que us administra el vostre servidor.\n\n(%s)
- No s\'ha pogut connectar amb el servidor.\n(%s)
- Edita els detalls
- Continua
- Avançat
- Configuració del compte
- Compte per defecte
- Envia el correu per defecte des d\'aquest compte.
- Notificacions noves de correu
- Carpetes de notificacions
- Tot
- Només carpetes de 1a classe
- Carpetes de 1a i 2a classe
- Totes les carpetes excepte de 2a classe
- Cap
- Notificacions de sincronització
- La vostra adreça de correu
- Notifica-ho a la barra d\'estat quan arribi correu
- Notifica-ho a la barra d\'estat mentre es comprova el correu
- Inclou correu de sortida
- Mostra una notificació per als missatges que enviïs
- Només els contactes
- Mostra notificacions només per als missatges de contactes coneguts
- Marca el missatge obert com a llegit
- Marca el missatge com a llegit després d\'haver-lo obert.
- Marca com a llegit quan se suprimeixi
- Marca un missatge com a llegit quan se suprimeix.
- Configuració de les notificacions
- Obre la configuració de les notificacions del sistema
- Sempre mostra les imatges
- No
- Dels contactes
- De qualsevol
- S\'està enviant el correu
- Cita el missatge original en respondre\'l.
- Afegeix el missatge original a les vostres respostes.
- Contesta després del text citat.
- Quan contestis, el missatge original apareixerà abans de la contesta.
- Elimina la signatura dels missatges citats.
- S\'eliminaran les signatures dels missatges citats a les respostes.
- Format del missatge
- Text pla (se\'n trauran el format i les imatges)
- HTML (se\'n conservaran el format i les imatges)
- Automàtic (text pla excepte per a missatges HTML)
- Mostra sempre C/a i C/a ocults
- Confirmació de lectura
- Demana sempre una confirmació de lectura
- Contesta amb estil de citació
- Prefix (com a Gmail)
- Capçalera (com a l\'Outlook)
- Carrega els missatges enviats
- Carrega els missatges a la carpeta d\'enviats després d\'enviar-los
- Configuració general
- S\'està llegint el correu
- S\'està recuperant el correu
- Carpetes
- Prefix de citació del text
- Encriptació d\'extrem a extrem
- Habilita el suport d\'OpenPGP
- Trieu una aplicació d\'OpenPGP
- Configureu la clau d\'extrem a extrem
- No hi ha cap aplicació d\'OpenPGP configurada.
- Connectat a %s
- Es configura...
- Desa tots els esborranys encriptats
- Tots els esborranys es desaran encriptats
- Encripta els esborranys només si l\'encriptació està habilitada
- Freqüència de comprovació de les carpetes
- Color del compte
- Tria el color del compte utilitzat a la llista de carpetes i de comptes
- Sense color
- Color del LED de notificació
- El color en què ha de fer pampallugues el LED del telèfon per a aquest compte
- Mida de la carpeta local
- Recupera missatges fins a...
- 1 KiB
- 2 KiB
- 4 KiB
- 8 KiB
- 16 KiB
- 32 KiB
- 64 KiB
- 128 KiB
- 256 KiB
- 512 KiB
- 1 MiB
- 2 MiB
- 5 MiB
- 10 MiB
- qualsevol mida (sense límit)
- Sincronitza missatges des
- de qualsevol data (sense límit)
- d\'avui
- dels darrers 2 dies
- dels darrers 3 dies
- de la darrera setmana
- de les 2 darreres setmanes
- de les 3 darreres setmanes
- del darrer mes
- dels darrers 2 mesos
- dels darrers 3 mesos
- dels darrers 6 mesos
- del darrer any
- Carpetes a mostrar
- Tot
- Només carpetes de 1a classe
- Carpetes de 1a i 2a classe
- Tot excepte carpetes de 2a classe
- Comprova les carpetes
- Tot
- Només carpetes de 1a classe
- Carpetes de 1a i 2a classe
- Tot excepte carpetes de 2a classe
- Cap
- Tramet carpetes
- Tot
- Només carpetes de 1a classe
- Carpetes de 1a i 2a classe
- Tot excepte carpetes de 2a classe
- Cap
- Mou / copia carpetes de destinació
- Tot
- Només carpetes de 1a classe
- Carpetes de 1a i 2a classe
- Totes les carpetes excepte 2a classe
- Sincronitza els elements eliminats al servidor
- Elimina els missatges quan s\'esborrin al servidor
- Falta una aplicació d\'OpenPGP. S\'ha desinstal·lat?
- Configuració de les carpetes
- Mostra al grup superior
- Mostra a prop del capdamunt de la llista de carpetes
- Classe de vista de carpetes
- Sense classe
- 1a classe
- 2a classe
- Classe de comprovació de la carpeta
- Cap
- 1a classe
- 2a classe
- El mateix que a la forma de vista
- Classe de tramesa de la carpeta
- Sense classe
- 1a classe
- 2a classe
- Igual que la classe de comprovació
- Classe de notificació de la carpeta
- Sense classe
- 1a classe
- 2a classe
- El mateix que la classe de tramesa
- Neteja els missatges locals
- Servidor d\'entrada
- Configura el servidor d\'entrada
- Servidor de sortida
- Configura el servidor del correu de sortida (SMTP)
- Nom del compte
- El vostre nom
- Notificacions
- Vibra
- Vibra quan arribi correu
- Tipus de vibració
- per defecte
- Tipus 1
- Tipus 2
- Tipus 3
- Tipus 4
- Tipus 5
- Repeteix la vibració
- So de correu nou
- LED intermitent
- Que el LED faci pampallugues quan arribi correu
- Opcions de composició del missatge
- Composició per defecte
- Configura per defecte De, A/c i signatura
- Gestiona les identitats
- Configura adreces i signatures \"From\" alternatives
- Gestiona identitats
- Gestiona la identitat
- Edita la identitat
- Desa
- Nova identitat
- A/c tots els missatges a
- Edita
- Mou amunt
- Mou avall
- Mou al capdamunt / fes predeterminat
- Elimina
- Descripció de la identitat
- (Opcional)
- El vostre nom
- (Opcional)
- Adreça de correu
- (Requerit)
- Respon a l\'adreça
- (Opcional)
- Signatura
- (Opcional)
- Utilitza la signatura
- Signatura
- Identitat inicial
- Trieu la identitat
- Envia com a
- No podeu eliminar una identitat si només en teniu una.
- No podeu utilitzar una identitat sense una adreça de correu
- Missatges més antics primer
- Darrers missatges primer
- Assumpte en ordre alfabètic
- Assumpte en ordre alfabètic invers
- Remitent A-Z
- Remitent Z-A
- Missatges marcats primer
- Missatges no marcats primer
- Missatges no llegits primer
- Missatges llegits primer
- Missatges amb adjunt primer
- Missatges sense adjunt primer
- Ordenat per…
- Data
- Arribada
- Assumpte
- Remitent
- Estel
- Llegit / no llegit
- Adjunts
- Elimina el compte
- Certificat no reconegut
- Accepta la clau
- Rebutja la clau
- Del (o D) - Elimina\nR - Respon\nA - Respon a tothom\nC - Escriu\nF - Reenvia\nM - Mou\nV - Arxiva\nY - Copia\nZ - Marca com a (no) llegit\nG - Estel\nO - Per tipus\nI - Per ordre\nQ - Torna a les carpetes\nS - Selecciona / desmarca\nJ o P - Missatge anterior n\K o N - Missatge següent
- Del (o D) - Elimina\nC - Escriu\nM - Mou\nV - Arxiva\nY - Copia\nZ - Marca com a (no) llegit\nG - Estel\nO - Tipus de classificació\nI - Ordre de classificació\nQ - Torna a les carpetes\nS - Selecciona / desmarca
- El nom de carpeta conté
- Carpetes...
- Mostra totes les carpetes
- Mostra només carpetes de 1a classe
- Mostra carpetes de 1a i 2a classe
- Mostra-ho tot excepte carpetes de 2a classe
- Posició de la signatura
- Abans del text citat
- Després del text citat
- Utilitza el tema de l\'aplicació
- Fosc
- Clar
- Fes servir el valor per defecte del sistema
- Visualització
- Global
- Depura
- Privadesa
- Xarxa
- Interacció
- Llista de comptes
- Llista de missatges
- Missatges
- Tema
- Tema de vista de missatge
- Tema de vista del redactor
- Llengua
- No s\'ha trobat la configuració.
- Tema de missatge fix
- Selecciona el tema de la vista de missatge en mostrar-lo.
- Utilitza un tema fix per a tots els missatges.
- El predeterminat del sistema
- Sincronització en 2n pla
- Mai
- Sempre
- Quan la sincronització automàtica estigui activada
- Selecciona-ho tot
- Nombre màxim de carpetes a comprovar amb tramesa
- 5 carpetes
- 10 carpetes
- 25 carpetes
- 50 carpetes
- 100 carpetes
- 250 carpetes
- 500 carpetes
- 1000 carpetes
- Animació
- Utilitza efectes visuals cridaners
- Navegació amb botons de volum
- Vista del missatge
- A la vista de llistes
- Mostra la safata d\'entrada unificada
- %s%s
- - No llegit
- Tots els missatges
- Tots els missatges en carpetes cercables
- Bústia unificada
- Tots els missatges en carpetes unificades
- Unifica
- Tots els missatges es mostren a la bústia unificada
- Carpetes per cercar
- Tot
- Mostrable
- Cap
- Cap
- Automàtic (%s)
- Mida de la lletra
- Configura la mida de la lletra
- Llista de compte
- Nom del compte
- Descripció del compte
- Llista de carpetes
- Nom de les carpetes
- Estat de la carpeta
- Llista de missatges
- Assumpte
- Remitent
- Data
- Vista prèvia
- Missatges
- Remitent
- A
- A/c
- C/o
- Capçaleres addicionals
- Assumpte
- Data i hora
- Cos del missatge
- %d%%
- %1$s: %2$s
- Redacció de missatges
- Camps d\'entrada de text
- Per defecte
- El més petit
- Molt més petit
- Més petit
- Petit
- Mitjà
- Gros
- Més gros
- No s\'ha trobat cap aplicació idònia per a aquesta acció.
- Ha fallat l\'enviament: %s
- Deso l\'esborrany?
- Deso o descarto aquest missatge?
- Voleu desar o descartar els canvis?
- Descarto el missatge?
- Segur que voleu descartar aquest missatge?
- Seleccioneu el text a copiar.
- Voleu netejar els missatges locals?
- Això suprimirà tots els missatges locals de la carpeta. No se suprimirà cap missatge del servidor.
- Neteja els missatges
- Confirmeu l\'eliminació
- Voleu eliminar aquest missatge?
-
- Voleu eliminar aquest missatge?
- Voleu eliminar %1$d missatges?
-
- Sí
- No
- Confirmeu marcar-ho tot com a llegit
- Voleu marcar tots els missatges com a llegits?
- Confirmeu buidar la paperera
- Voleu buidar la carpeta de la paperera?
- Sí
- No
- Confirmeu moure\'l a la carpeta brossa
-
- Realment voleu moure aquest missatge a la carpeta brossa?
- Realment voleu moure aquests missatges a la carpeta brossa?
-
- Sí
- No
- S\'està baixant l\'adjunt
- »
- ›
- Còpia de seguretat
- Miscel·lània
- Exporta la configuració
- Exporta
- Comparteix
- S\'està exportant la configuració...
- La configuració s\'ha exportat correctament.
- Ha fallat exportar la configuració.
- Importa la configuració
- Seleccioneu un fitxer
- Importa
- La configuració s\'ha importat correctament.
- Si us plau, escriviu les contrasenyes.
- Ha fallat importar la configuració.
- Ha fallat llegir els fitxer de configuració.
- Ha fallat importar alguns paràmetres.
- Importació correcta
- Cal la contrasenya.
- No importat
- Fallada d\'importació
- Més tard
- Importa la configuració
- S\'està important la configuració...
-
- Per poder usar el compte %s heu de proporcionar la contrasenya del servidor.
- Per poder fer servir el compte %s heu de proporcionar les contrasenyes del servidor.
-
- Contrasenya del servidor d\'entrada
- Contrasenya del servidor de sortida
- Fes servir la mateixa contrasenya per al servidor de sortida.
- Nom del servidor: %s
- Mostra el recompte de no llegits per a...
- Compte
- El compte per al qual s\'ha de mostrar el nombre de missatges no llegits.
- Bústia unificada
- Compte de carpetes
- Mostra el nombre de missatges no llegits de només una carpeta.
- Carpeta
- La carpeta per a la qual s\'ha de mostrar el nombre de missatges no llegits.
- Fet
- %1$s - %2$s
- No hi ha cap compte seleccionat
- No hi ha cap carpeta seleccionada
- Sense text
- Obre l\'enllaç
- Comparteix l\'enllaç
- Copia l\'enllaç
- Enllaç
- Copia el text de l\'enllaç
- Text de l\'enllaç
- Imatge
- Mostra la imatge
- Desa la imatge
- Baixa la imatge
- Copia l\'adreça de la imatge
- Adreça de la imatge
- Marca aquest número
- Desa\'l a contactes
- Copia el número de telèfon
- Número de telèfon
- Envia un correu electrònic
- Desa a Contactes
- Copia l\'adreça electrònica
- Envia un correu electrònic a aquesta adreça
- Tots
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- Límit de resultats de la cerca del servidor
- S\'està enviant la consulta al servidor
-
- Recuperant %d resultat
- S\'està recuperant %d resultats
-
-
- Recuperant %1$d de %2$d resultats
- S\'està recuperant %1$dde %2$dresultats
-
- No s\'ha pogut fer la cerca remota.
- Cerca
- Activa la cerca del servidor
- Es cerquen els missatges al vostre dispositiu així com al servidor.
- Cerca missatges al servidor
- No es pot fer la cerca sense connectivitat a la xarxa.
- Canvia el color quan s\'hagi llegit
- Un fons diferent mostrarà que el missatge s\'ha llegit
- Vista de fil de discussió
- Recull els missatges del mateix fil de discussió
- Actualització de les bases de dades
- S\'estan actualitzant les bases de dades...
- S\'està actualitzant la base de dades del compte \"%s\"
- Mostra amb pantalla dividida
- Sempre
- Mai
- Només en mode horitzontal
- Seleccioneu un misssatge a l\'esquerra
- Mostra les imatges dels contactes
- Mostra les imatges dels contactes a la llista de missatges.
- Marca\'ls tots com a llegits
- Acoloreix les imatges del contacte
- Acoloreix les imatges de contactes absents
- Accions de missatge visibles
- Mostra les accions seleccionades al menú de vista de missatge
- S\'està carregant l\'adjunt…
- S\'està enviant el missatge
- S\'està desant l\'esborrany
- S\'està recuperant l\'adjunt…
- No s\'ha pogut autenticar. El servidor no ha mostrat l\'opció SASL EXTERNAL. Això podria ser degut a un problema amb el certificat del client (caducat, o autoritat del certificat desconeguda) o algun altre problema de configuració.
-
- Fes servir el certificat de client
- Sense certificat de client
- Elimina la selecció de certificat de client
- No s\'ha pogut recuperar el certificat de client per a l\'àlies \"%s\"
- Opcions avançades
- El certificat de client \"%1$s\" ha caducat o encara no és vàlid (%2$s)
-
- *Encriptat*
- Afegeix dels contactes
- A/c
- C/o
- A
- De:
- <Destinatari desconegut>
- <Remitent desconegut>
- Casa
- Feina
- Altres
- Mòbil
- No s\'ha configurat la carpeta d\'esborranys en aquest compte!
- No hi ha cap clau configurada per a aquest compte! Comproveu la configuració.
- El proveïdor de criptografia fa servir una versió no compatible. Si us plau, comproveu la configuració!
- No es pot connectar al proveïdor de criptografia, comproveu la configuració o cliqueu a la icona de criptografia per tornar-ho a provar!
- Ha fallat iniciar l\'encriptació d\'extrem a extrem. Si us plau, comproveu-ne la configuració.
- El mode PGP/INLINE no admet adjunts!
- Habilita PGP/INLINE
- Inhabilita PGP/INLINE
- Habilita PGP de només signar
- Inhabilita PGP de només signar
- Mode PGP/INLINE
- El missatge s\'envia en el format PGP/INLINE.\nAixò només s\'hauria de fer servir per a compatibilitat:
- Alguns clients només admeten aquest format
- Les signatures es poden trencar durant el trànsit
- Els adjunts no s\'admeten
- Ja ho tinc!
- Desactiva
- Mantén activat
- Ja ho tinc!
- Desactiva
- Mantén activat
- Mode PGP de només signar
- En aquest mode, la clau PGP es farà servir per crear una signatura criptogràfica d\'un missatge no encriptat.
- Això no encripta el missatge, però verifica que s\'ha enviat des de la vostra clau.
- Les signatures es poden trencar quan s\'envien a llistes de correu.
- Les signatures es poden mostrar com a adjunts \"signature.asc\" en alguns clients.
- Els missatges encriptats sempre inclouen una signatura.
- Text pla
- La signatura d\'extrem a extrem contenia un error.
- cal baixar completament el missatge per processar-ne la signatura
- conté una signatura d\'extrem a extrem no admesa
- El missatge està encriptat, però en un format no admès.
- El missatge està encriptat, però se n\'ha cancel·lat la desencriptació.
- Text pla signat d\'extrem a extrem
- des d\'un signant verificat
- Text pla signat
- però la clau d\'extrem a extrem no ha coincidit amb el remitent
- però la clau d\'extrem a extrem ha caducat
- però la clau d\'extrem a extrem està revocada
- però la clau d\'extrem a extrem no es considera segura
- des d\'una clau d\'extrem a extrem desconeguda
- Encriptat
- però hi ha hagut un error de desencriptació
- cal descarregar completament el missatge per a la desencriptació
- però no hi ha cap aplicació d\'encriptació configurada
- Encriptat
- però no d\'extrem a extrem
- Encriptat d\'extrem a extrem
- des d\'un remitent verificat
- Encriptat
- des d\'una clau d\'extrem a extrem desconeguda
- però la clau d\'extrem a extrem no ha coincidit amb el remitent
- però la clau d\'extrem a extrem ha caducat
- però la clau d\'extrem a extrem està revocada
- però la clau d\'extrem a extrem no es considera segura
- però les dades d\'extrem a extrem tenen errors
- però l\'encriptació no es considera segura
- D\'acord
- Clau de cerca
- Mostra qui signa
- Mostra el remitent
- Detalls
- Desbloqueja
- Aquesta part no estava encriptada i pot no ser segura.
- Adjunt no protegit
- S\'està carregant...
- S\'ha cancel·lat la desencriptació.
- Torna-hi
- Cal baixar el missatge encriptat per desencriptar-lo.
- Error en desencriptar el correu
- Els caràcters especials no s\'admeten actualment!
- Error analitzant l\'adreça!
- Amaga les signatures no encriptades
- Només es mostraran les signatures encriptades
- Es mostraran totes les signatures
- Encriptació no disponible en mode de només signar!
- Text no signat
- Avís d\'obsolescència d\'APG
- APG ja no es manté!
- A causa d\'això, el suport d\'APG s\'ha eliminat del K-9 Mail.
- El desenvolupament es va aturar a principis de 2014.
- Conté problemes de seguretat no corregits.
- Podeu fer clic aquí per saber-ne més.
- Ja ho tinc!
- APG
- Aquest missatge està encriptat.
- Aquest missatge ha estat encriptat amb OpenPGP.\nPer llegir-lo, us caldrà instal·lar i configurar una aplicació d\'OpenPGP compatible.
- Ves a la configuració
- Llista de missatges del MAIL
- S\'està carregant missatges...
- Ha fallat recuperar la llista de carpetes.
- Error en recuperar l\'estat del destinatari del proveïdor d\'OpenPGP!
- Encriptació no possible
- Alguns dels destinataris seleccionats no admeten aquesta característica!
- Habilita l\'encriptació
- Inhabilita l\'encriptació
- Encriptar els missatges assegura que els pugui llegir el destinatari i ningú més.
- L\'encriptació només es mostrarà si tots els destinataris l\'admeten i us han d\'haver enviat un missatge abans.
- Commuteu l\'encriptació clicant en aquesta icona.
- Ja ho tinc
- Enrere
- Inhabilita l\'encriptació
- Encriptació d\'OpenPGP
- Mode mutu d\'autoencriptació
- Mode mutu d\'autoencriptació
- Els missatges s\'encriptaran normalment per selecció o en respondre un missatge encriptat.
- Si tant el remitent com el destinatari habiliten el mode mutu, l\'encriptació s\'habilitarà per defecte.
- Podeu fer clic aquí per saber-ne més.
- Configuració general
- No hi ha cap aplicació d\'OpenPGP instal·lada.
- Instal·la
- Mail requires OpenKeychain for end-to-end encryption.
- Missatge encriptat
- Encripta l\'assumpte dels missatges.
- Pot no ser admès per alguns destinataris.
- Error intern: compte no vàlid!
- Error en connectar a %s!
- Envia un missatge de configuració d\'autoencriptació
- Compartiu amb seguretat la configuració d\'extrem a extrem amb altres dispositius.
- Missatge de configuració d\'autoencriptació
- Un missatge de configuració d\'autoencriptació comparteix amb seguretat la configuració d\'extrem a extrem amb altres dispositius.
- Envia un missatge de configuració
- El missatge s\'enviarà a la vostra adreça:
- Es genera el missatge de configuració...
- S\'envia el missatge a:
- Per acabar, obriu el missatge a l\'altre dispositiu i introduïu-hi el codi de configuració.
- Mostra el codi de configuració
- Missatge de configuració d\'autoencriptació
- Aquest missatge conté tota la informació per transferir la configuració d\'autoencriptació i la vostra clau secreta amb seguretat des del dispositiu original.
+ %.1f GB
+ %.1f MB
+ %.1f kB
+ %d B
+ Compte \"%s\" comprimida des de %s a %s
+ S\'està compactant el compte \"%s\"
+ Correu nou
+
+ %d nous missatges
+ %d nous missatges
+
+ %d no llegit(s) (%s)
+ + %1$d més sobre %2$s
+ Respon
+ Marca com a llegit
+ Marca\'ls tots com a llegits
+ Elimina
+ Elimina-ho tot
+ Arxiva
+ Arxiva-ho tot
+ Correu brossa
+ Error al certificat de %s
+ Comproveu la configuració del servidor.
+ Ha fallat l\'autenticació
+ Ha fallat l\'autenticació de %s. Actualitzeu la configuració del servidor.
+ S\'està comprovant el correu: %s:%s
+ S\'està comprovant el correu
+ S\'està enviant correu: %s
+ S\'està enviant correu
+ .
+ Sincronitza-ho (Empeny)
+ Mostrat mentre s\'esperen missatges nous
+ Missatges
+ Notificacions relacionades amb missatges
+ Miscel·lània
+ Notificacions diverses, com ara errors, etc.
+ Bústia d\'entrada
+ Bústia de sortida
+ Esborranys
+ Paperera
+ Enviat
+ La tramesa d\'alguns missatges ha fallat.
+ Versió
+ Habilita la depuració del registre
+ Registra informació extra de diagnòstic
+ Registra informació sensible
+ Pot mostrar les contrasenyes als registres.
+ Carrega més missatges
+ A: %s
+ Assumpte
+ Text del missatge
+ Signatura
+ -------- Missatge Original --------
+ Assumpte:
+ Enviat:
+ De:
+ A:
+ A/c:
+ %s ha escrit:
+ El %1$s, %2$s ha escrit:
+ Heu d\'afegir-hi, com a mínim, un destinatari.
+ El camp del destinatari conté una entrada incompleta!
+ No s\'ha trobat cap adreça de correu.
+ Alguns adjunts no es poden reenviar perquè no s\'han baixat.
+ Aquest missatge no es pot reenviar perquè alguns adjunts no s\'han baixat.
+ Inclou el missatge citat
+ Elimina el text citat
+ Edita el text citat
+ Suprimeix l\'adjunt
+ De: %s <%s>
+ A:
+ A/c:
+ Bcc:
+ Obre
+ Desa
+ No s\'ha pogut desar l\'adjunt.
+ Mostra les imatges
+ No s\'ha pogut trobar un visualitzador per %s.
+ Baixa el missatge complet
+ No s\'ha pogut mostrar el missatge
+ mitjançant %1$s
+
+ S\'han baixat totes les capçaleres. No hi ha capçaleres addicionals per mostrar.
+ La recuperació de capçaleres addicionals de la base de dades o del servidor de correu ha fallat.
+ Més d\'aquest remitent
+ De %s
+ Depura / neteja el cos del missatge
+ S\'ha descartat el missatge
+ S\'ha desat el missatge com a esborrany
+ Mostra els estels
+ Els estels indiquen missatges marcats.
+ Previsualització de línies
+ Mostra noms dels contactes
+ Mostra noms dels contactes enlloc dels correus
+ Remitent damunt de l\'assumpte
+ Mostra els nom del remitent damunt de l\'assumpte, en comptes de sota.
+ Mostra els noms dels contactes
+ Usa els noms dels destinataris segons els contactes quan estiguin disponibles
+ Acoloreix els contactes
+ Acoloreix els noms de la llista de contactes
+ Tipus de lletra d\'amplada fixa
+ Utilitza un tipus de lletra d\'amplada fixa quan es mostrin missatges de text pla.
+ Ajusta l\'amplada dels missatges automàticament
+ Retalla els missatges per adaptar la seva amplada a la pantalla.
+ Torna a la llista després de l\'eliminació
+ Torna a la llista de missatges després d\'eliminar missatges.
+ Mostra el missatge següent després de l\'eliminació
+ Mostra el missatge següent per defecte després d\'eliminar-ne un.
+ Confirma accions
+ Mostra un diàleg cada vegada que executis accions seleccionades
+ Elimina
+ Elimina els missatges amb estel (a la vista de missatges)
+ Brossa
+ Descarta el missatge
+ Marca tots els missatges com a llegits
+ Elimina (des de notificacions)
+ Amaga el client de correu
+ Suprimeix el nom K-9 User-Agent de les capçaleres del missatge
+ Amaga el fus horari
+ Fes servir UTC en comptes de l\'hora local a les capçaleres dels missatges i a la capçalera de resposta
+ Mostra el botó \"Elimina\"
+ Mai
+ Per a notificacions d\'un sol missatge
+ Sempre
+ Bloqueja les notificacions de pantalla
+ No bloquegis les notificacions de pantalla
+ Nom de l\'aplicació
+ Compte de missatges nou
+ Compte de missatges i remitents
+ El mateix que amb la pantalla desbloquejada
+ Mode silenciós
+ Inhabilita el so de trucada, brunzit i llums durant la nit.
+ Desactiva les notificacions
+ Desactiva completament les notificacions durant el mode silenciós
+ Comença el mode silenciós
+ El mode silenciós acaba
+ Configura un compte nou
+ Adreça de correu electrònic
+ Contrasenya
+ Mostra la contrasenya
+
+ Per veure la contrasenya aquí, activeu el bloqueig de pantalla en aquest dispositiu.
+ Verifiqueu la identitat
+ Desbloqueu-ho per veure la contrasenya.
+ Configuració manual
+
+ S\'està recuperant la informació del compte\u2026
+ S\'està comprovant la configuració del servidor d\'entrada\u2026
+ S\'està comprovant la configuració del servidor de sortida\u2026
+ S\'està autenticant\u2026
+ S\'està recuperant la configuració del compte\u2026
+ S\'està cancel·lant\u2026
+ Ja gairebé hem acabat!
+ Dóna un nom a aquest compte (opcional):
+ Escriviu el nom (és el que es mostrarà als missatges sortints):
+ Tipus de compte
+ Quin tipus de compte és?
+ POP3
+ IMAP
+ Contrasenya normal
+ Contrasenya, transmesa de forma no segura
+ Contrasenya encriptada
+ Certificat del client
+ Configuració del servidor d\'entrada
+ Nom d\'usuari
+ Contrasenya
+ Certificat del client
+ Servidor POP3
+ Servidor IMAP
+ Servidor WebDAV (Exchange)
+ Port
+ Tipus de seguretat
+ Tipus d\'autenticació
+ Cap
+ SSL/TLS
+ STARTTLS
+ \"%1$s = %2$s\" no és vàlid amb \"%3$s = %4$s\"
+ Quan elimino un missatge
+ No l\'eliminis del servidor
+ Elimina\'l del servidor
+ Marca\'ls com a llegits al servidor
+ Utilitza compressió a la xarxa:
+ Mòbil
+ Wi-Fi
+ Altres
+ Elimina missatges esborrats al servidor
+ Immediatament
+ Quan es comprova
+ Només manualment
+ Autodetecció de l\'espai de noms IMAP
+ Prefix del camí IMAP
+ Carpeta d\'esborranys
+ Carpeta d\'enviats
+ Carpeta paperera
+ Carpeta d\'arxiu
+ Carpeta brossa
+ Només mostra carpetes subscrites
+ Autoexpandeix la carpeta
+ Camí OWA
+ Opcional
+ Camí d\'autenticació
+ Opcional
+ Àlies de la bústia
+ Opcional
+ Configuració del servidor de sortida
+ Servidor SMTP
+ Port
+ Tipus de seguretat
+ Requereix inici de sessió.
+ Nom d\'usuari
+ Contrasenya
+ Tipus d\'autenticació
+ \"%1$s = %2$s\" no és vàlid amb \"%3$s = %4$s\"
+ Configuració no vàlida: %s
+ Opcions del compte
+ Compacta el compte
+ Freqüència de comprovació
+ Mai
+ Cada 15 minuts
+ Cada 30 minuts
+ Cada hora
+ Cada 2 hores
+ Cada 3 hores
+ Cada 6 hores
+ Cada 12 hores
+ Cada 24 hores
+ Habilita la tramesa de correu per a aquest compte
+ Si el vostre servidor ho admet, els missatges arribaran automàticament. Aquesta opció pot millorar o empitjorar el rendiment.
+ Refresca la connexió IDLE
+ Cada 2 minuts
+ Cada 3 minuts
+ Cada 6 minuts
+ Cada 12 minuts
+ Cada 24 minuts
+ Cada 36 minuts
+ Cada 48 minuts
+ Cada 60 minuts
+ Avisa\'m quan arribi correu
+ Avisa\'m mentre es comprova el correu
+ Nombre de missatges a mostrar
+ 10 missatges
+ 25 missatges
+ 50 missatges
+ 100 missatges
+ 250 missatges
+ 500 missatges
+ 1000 missatges
+ 2500 missatges
+ 5000 missatges
+ 10000 missatges
+ Tots els missatges
+ No es pot copiar o moure un missatge que no està sincronitzat amb el servidor
+ No s\'ha pogut acabar la configuració
+ Nom d\'usuari o contrasenya incorrectes.\n(%s)
+ El servidor ha mostrat un certificat SSL no vàlid. A vegades això és degut a una mala configuració del servidor. També pot ser degut que algú estigui intentant atacar-vos o al vostre servidor. Si no n\'esteu segurs feu clic a Rebutja i contacteu amb la gent que us administra el vostre servidor.\n\n(%s)
+ No s\'ha pogut connectar amb el servidor.\n(%s)
+ Edita els detalls
+ Continua
+ Avançat
+ Configuració del compte
+ Notificacions noves de correu
+ Carpetes de notificacions
+ Tot
+ Només carpetes de 1a classe
+ Carpetes de 1a i 2a classe
+ Totes les carpetes excepte de 2a classe
+ Cap
+ Notificacions de sincronització
+ La vostra adreça de correu
+ Notifica-ho a la barra d\'estat quan arribi correu
+ Notifica-ho a la barra d\'estat mentre es comprova el correu
+ Inclou correu de sortida
+ Mostra una notificació per als missatges que enviïs
+ Només els contactes
+ Mostra notificacions només per als missatges de contactes coneguts
+ Ignora els missatges de conversa
+ No mostris notificacions de missatges pertanyents a una conversa de correu electrònic.
+ Marca el missatge obert com a llegit
+ Marca el missatge com a llegit després d\'haver-lo obert.
+ Marca com a llegit quan se suprimeixi
+ Marca un missatge com a llegit quan se suprimeix.
+ Categories de notificacions
+ Configureu les notificacions per als missatges nous
+ Configureu les notificacions per als errors i l\'estat
+ Sempre mostra les imatges
+ No
+ Dels contactes
+ De qualsevol
+ S\'està enviant el correu
+ Cita el missatge original en respondre\'l.
+ Afegeix el missatge original a les vostres respostes.
+ Contesta després del text citat.
+ Quan contestis, el missatge original apareixerà abans de la contesta.
+ Elimina la signatura dels missatges citats.
+ S\'eliminaran les signatures dels missatges citats a les respostes.
+ Format del missatge
+ Text pla (se\'n trauran el format i les imatges)
+ HTML (se\'n conservaran el format i les imatges)
+ Automàtic (text pla excepte per a missatges HTML)
+ Mostra sempre C/a i C/a ocults
+ Confirmació de lectura
+ Demana sempre una confirmació de lectura
+ Contesta amb estil de citació
+ Prefix (com a Gmail)
+ Capçalera (com a l\'Outlook)
+ Carrega els missatges enviats
+ Carrega els missatges a la carpeta d\'enviats després d\'enviar-los
+ Configuració general
+ S\'està llegint el correu
+ S\'està recuperant el correu
+ Carpetes
+ Prefix de citació del text
+ Encriptació d\'extrem a extrem
+ Habilita el suport d\'OpenPGP
+ Trieu una aplicació d\'OpenPGP
+ Configureu la clau d\'extrem a extrem
+ No hi ha cap aplicació d\'OpenPGP configurada.
+ Connectat a %s
+ Es configura...
+ Desa tots els esborranys encriptats
+ Tots els esborranys es desaran encriptats
+ Encripta els esborranys només si l\'encriptació està habilitada
+ Freqüència de comprovació de les carpetes
+ Color del compte
+ Tria el color del compte utilitzat a la llista de carpetes i de comptes
+ Sense color
+ Color del LED de notificació
+ El color en què ha de fer pampallugues el LED del telèfon per a aquest compte
+ Mida de la carpeta local
+ Recupera missatges fins a...
+ 1 KiB
+ 2 KiB
+ 4 KiB
+ 8 KiB
+ 16 KiB
+ 32 KiB
+ 64 KiB
+ 128 KiB
+ 256 KiB
+ 512 KiB
+ 1 MiB
+ 2 MiB
+ 5 MiB
+ 10 MiB
+ qualsevol mida (sense límit)
+ Sincronitza missatges des
+ de qualsevol data (sense límit)
+ d\'avui
+ dels darrers 2 dies
+ dels darrers 3 dies
+ de la darrera setmana
+ de les 2 darreres setmanes
+ de les 3 darreres setmanes
+ del darrer mes
+ dels darrers 2 mesos
+ dels darrers 3 mesos
+ dels darrers 6 mesos
+ del darrer any
+ Carpetes a mostrar
+ Tot
+ Només carpetes de 1a classe
+ Carpetes de 1a i 2a classe
+ Tot excepte carpetes de 2a classe
+ Comprova les carpetes
+ Tot
+ Només carpetes de 1a classe
+ Carpetes de 1a i 2a classe
+ Tot excepte carpetes de 2a classe
+ Cap
+ Tramet carpetes
+ Tot
+ Només carpetes de 1a classe
+ Carpetes de 1a i 2a classe
+ Tot excepte carpetes de 2a classe
+ Cap
+ Mou / copia carpetes de destinació
+ Tot
+ Només carpetes de 1a classe
+ Carpetes de 1a i 2a classe
+ Totes les carpetes excepte 2a classe
+ Sincronitza els elements eliminats al servidor
+ Elimina els missatges quan s\'esborrin al servidor
+ Falta una aplicació d\'OpenPGP. S\'ha desinstal·lat?
+ Configuració de les carpetes
+ Mostra al grup superior
+ Mostra a prop del capdamunt de la llista de carpetes
+ Classe de vista de carpetes
+ Sense classe
+ 1a classe
+ 2a classe
+ Classe de comprovació de la carpeta
+ Cap
+ 1a classe
+ 2a classe
+ El mateix que a la forma de vista
+ Classe de tramesa de la carpeta
+ Sense classe
+ 1a classe
+ 2a classe
+ Igual que la classe de comprovació
+ Classe de notificació de la carpeta
+ Sense classe
+ 1a classe
+ 2a classe
+ El mateix que la classe de tramesa
+ Neteja els missatges locals
+ Servidor d\'entrada
+ Configura el servidor d\'entrada
+ Servidor de sortida
+ Configura el servidor del correu de sortida (SMTP)
+ Nom del compte
+ El vostre nom
+ Notificacions
+ Vibra
+ Vibra quan arribi correu
+ Tipus de vibració
+ per defecte
+ Tipus 1
+ Tipus 2
+ Tipus 3
+ Tipus 4
+ Tipus 5
+ Repeteix la vibració
+ So de correu nou
+ LED intermitent
+ Que el LED faci pampallugues quan arribi correu
+ Opcions de composició del missatge
+ Composició per defecte
+ Configura per defecte De, A/c i signatura
+ Gestiona les identitats
+ Configura adreces i signatures \"From\" alternatives
+ Gestiona identitats
+ Gestiona la identitat
+ Edita la identitat
+ Desa
+ Nova identitat
+ A/c tots els missatges a
+ Edita
+ Mou amunt
+ Mou avall
+ Mou al capdamunt / fes predeterminat
+ Elimina
+ Descripció de la identitat
+ (Opcional)
+ El vostre nom
+ (Opcional)
+ Adreça de correu
+ (Requerit)
+ Respon a l\'adreça
+ (Opcional)
+ Signatura
+ (Opcional)
+ Utilitza la signatura
+ Signatura
+ Identitat inicial
+ Trieu la identitat
+ Envia com a
+ No podeu eliminar una identitat si només en teniu una.
+ No podeu utilitzar una identitat sense una adreça de correu
+ Missatges més antics primer
+ Darrers missatges primer
+ Assumpte en ordre alfabètic
+ Assumpte en ordre alfabètic invers
+ Remitent A-Z
+ Remitent Z-A
+ Missatges marcats primer
+ Missatges no marcats primer
+ Missatges no llegits primer
+ Missatges llegits primer
+ Missatges amb adjunt primer
+ Missatges sense adjunt primer
+ Ordenat per…
+ Data
+ Arribada
+ Assumpte
+ Remitent
+ Estel
+ Llegit / no llegit
+ Adjunts
+ Elimina el compte
+ Certificat no reconegut
+ Accepta la clau
+ Rebutja la clau
+ Del (o D) - Elimina\nR - Respon\nA - Respon a tothom\nC - Escriu\nF - Reenvia\nM - Mou\nV - Arxiva\nY - Copia\nZ - Marca com a (no) llegit\nG - Estel\nO - Per tipus\nI - Per ordre\nQ - Torna a les carpetes\nS - Selecciona / desmarca\nJ o P - Missatge anterior n\K o N - Missatge següent
+ Del (o D) - Elimina\nC - Escriu\nM - Mou\nV - Arxiva\nY - Copia\nZ - Marca com a (no) llegit\nG - Estel\nO - Tipus de classificació\nI - Ordre de classificació\nQ - Torna a les carpetes\nS - Selecciona / desmarca
+ El nom de carpeta conté
+ Carpetes...
+ Mostra totes les carpetes
+ Mostra només carpetes de 1a classe
+ Mostra carpetes de 1a i 2a classe
+ Mostra-ho tot excepte carpetes de 2a classe
+ Posició de la signatura
+ Abans del text citat
+ Després del text citat
+ Utilitza el tema de l\'aplicació
+ Fosc
+ Clar
+ Fes servir el valor per defecte del sistema
+ Visualització
+ Global
+ Depura
+ Privadesa
+ Xarxa
+ Interacció
+ Llista de comptes
+ Llista de missatges
+ Missatges
+ Tema
+ Tema de vista de missatge
+ Tema de vista del redactor
+ Llengua
+ No s\'ha trobat la configuració.
+ Tema de missatge fix
+ Selecciona el tema de la vista de missatge en mostrar-lo.
+ Utilitza un tema fix per a tots els missatges.
+ El predeterminat del sistema
+ Sincronització en 2n pla
+ Mai
+ Sempre
+ Quan la sincronització automàtica estigui activada
+ Selecciona-ho tot
+ Nombre màxim de carpetes a comprovar amb tramesa
+ 5 carpetes
+ 10 carpetes
+ 25 carpetes
+ 50 carpetes
+ 100 carpetes
+ 250 carpetes
+ 500 carpetes
+ 1000 carpetes
+ Animació
+ Utilitza efectes visuals cridaners
+ Navegació amb botons de volum
+ Vista del missatge
+ A la vista de llistes
+ Mostra la safata d\'entrada unificada
+ Mostra el recompte de destacats.
+ %s%s
+ - No llegit
+ Tots els missatges
+ Tots els missatges en carpetes cercables
+ Bústia unificada
+ Tots els missatges en carpetes unificades
+ Unifica
+ Tots els missatges es mostren a la bústia unificada
+ Carpetes per cercar
+ Tot
+ Mostrable
+ Cap
+ Cap
+ Automàtic (%s)
+ Mida de la lletra
+ Configura la mida de la lletra
+ Llista de compte
+ Nom del compte
+ Descripció del compte
+ Llista de carpetes
+ Nom de les carpetes
+ Estat de la carpeta
+ Llista de missatges
+ Assumpte
+ Remitent
+ Data
+ Vista prèvia
+ Missatges
+ Remitent
+ A
+ A/c
+ C/o
+ Capçaleres addicionals
+ Assumpte
+ Data i hora
+ Cos del missatge
+ %d%%
+ %1$s: %2$s
+ Redacció de missatges
+ Camps d\'entrada de text
+ Per defecte
+ El més petit
+ Molt més petit
+ Més petit
+ Petit
+ Mitjà
+ Gros
+ Més gros
+ No s\'ha trobat cap aplicació idònia per a aquesta acció.
+ Ha fallat l\'enviament: %s
+ Deso l\'esborrany?
+ Deso o descarto aquest missatge?
+ Voleu desar o descartar els canvis?
+ Descarto el missatge?
+ Segur que voleu descartar aquest missatge?
+ Seleccioneu el text a copiar.
+ Voleu netejar els missatges locals?
+ Això suprimirà tots els missatges locals de la carpeta. No se suprimirà cap missatge del servidor.
+ Neteja els missatges
+ Confirmeu l\'eliminació
+ Voleu eliminar aquest missatge?
+
+ Voleu eliminar aquest missatge?
+ Voleu eliminar %1$d missatges?
+
+ Sí
+ No
+ Confirmeu marcar-ho tot com a llegit
+ Voleu marcar tots els missatges com a llegits?
+ Confirmeu buidar la paperera
+ Voleu buidar la carpeta de la paperera?
+ Sí
+ No
+ Confirmeu moure\'l a la carpeta brossa
+
+ Realment voleu moure aquest missatge a la carpeta brossa?
+ Realment voleu moure aquests missatges a la carpeta brossa?
+
+ Sí
+ No
+ S\'està baixant l\'adjunt
+ »
+ ›
+ Còpia de seguretat
+ Miscel·lània
+ Exporta la configuració
+ Exporta
+ Comparteix
+ S\'està exportant la configuració...
+ La configuració s\'ha exportat correctament.
+ Ha fallat exportar la configuració.
+ Importa la configuració
+ Seleccioneu un fitxer
+ Importa
+ La configuració s\'ha importat correctament.
+ Si us plau, escriviu les contrasenyes.
+ Ha fallat importar la configuració.
+ Ha fallat llegir els fitxer de configuració.
+ Ha fallat importar alguns paràmetres.
+ Importació correcta
+ Cal la contrasenya.
+ No importat
+ Fallada d\'importació
+ Més tard
+ Importa la configuració
+ S\'està important la configuració...
+
+ Per poder usar el compte %s heu de proporcionar la contrasenya del servidor.
+ Per poder fer servir el compte %s heu de proporcionar les contrasenyes del servidor.
+
+ Contrasenya del servidor d\'entrada
+ Contrasenya del servidor de sortida
+ Fes servir la mateixa contrasenya per al servidor de sortida.
+ Nom del servidor: %s
+ Mostra el recompte de no llegits per a...
+ Compte
+ El compte per al qual s\'ha de mostrar el nombre de missatges no llegits.
+ Bústia unificada
+ Compte de carpetes
+ Mostra el nombre de missatges no llegits de només una carpeta.
+ Carpeta
+ La carpeta per a la qual s\'ha de mostrar el nombre de missatges no llegits.
+ Fet
+ %1$s - %2$s
+ No hi ha cap compte seleccionat
+ No hi ha cap carpeta seleccionada
+ Sense text
+ Obre l\'enllaç
+ Comparteix l\'enllaç
+ Copia l\'enllaç
+ Enllaç
+ Copia el text de l\'enllaç
+ Text de l\'enllaç
+ Imatge
+ Mostra la imatge
+ Desa la imatge
+ Baixa la imatge
+ Copia l\'adreça de la imatge
+ Adreça de la imatge
+ Marca aquest número
+ Desa\'l a contactes
+ Copia el número de telèfon
+ Número de telèfon
+ Envia un correu electrònic
+ Desa a Contactes
+ Copia l\'adreça electrònica
+ Envia un correu electrònic a aquesta adreça
+ Tots
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Límit de resultats de la cerca del servidor
+ S\'està enviant la consulta al servidor
+
+ Recuperant %d resultat
+ S\'està recuperant %d resultats
+
+
+ Recuperant %1$d de %2$d resultats
+ S\'està recuperant %1$dde %2$dresultats
+
+ No s\'ha pogut fer la cerca remota.
+ Cerca
+ Activa la cerca del servidor
+ Es cerquen els missatges al vostre dispositiu així com al servidor.
+ Cerca missatges al servidor
+ No es pot fer la cerca sense connectivitat a la xarxa.
+ Canvia el color quan s\'hagi llegit
+ Un fons diferent mostrarà que el missatge s\'ha llegit
+ Vista de fil de discussió
+ Recull els missatges del mateix fil de discussió
+ Actualització de les bases de dades
+ S\'estan actualitzant les bases de dades...
+ S\'està actualitzant la base de dades del compte \"%s\"
+ Mostra amb pantalla dividida
+ Sempre
+ Mai
+ Només en mode horitzontal
+ Seleccioneu un misssatge a l\'esquerra
+ Mostra les imatges dels contactes
+ Mostra les imatges dels contactes a la llista de missatges.
+ Marca\'ls tots com a llegits
+ Acoloreix les imatges del contacte
+ Acoloreix les imatges de contactes absents
+ Accions de missatge visibles
+ Mostra les accions seleccionades al menú de vista de missatge
+ S\'està carregant l\'adjunt…
+ S\'està enviant el missatge
+ S\'està desant l\'esborrany
+ S\'està recuperant l\'adjunt…
+ No s\'ha pogut autenticar. El servidor no ha mostrat l\'opció SASL EXTERNAL. Això podria ser degut a un problema amb el certificat del client (caducat, o autoritat del certificat desconeguda) o algun altre problema de configuració.
+
+ Fes servir el certificat de client
+ Sense certificat de client
+ Elimina la selecció de certificat de client
+ No s\'ha pogut recuperar el certificat de client per a l\'àlies \"%s\"
+ Opcions avançades
+ El certificat de client \"%1$s\" ha caducat o encara no és vàlid (%2$s)
+
+ *Encriptat*
+ Afegeix dels contactes
+ A/c
+ C/o
+ A
+ De:
+ Respon a
+ <Destinatari desconegut>
+ <Remitent desconegut>
+ Casa
+ Feina
+ Altres
+ Mòbil
+ No s\'ha configurat la carpeta d\'esborranys en aquest compte!
+ No hi ha cap clau configurada per a aquest compte! Comproveu la configuració.
+ El proveïdor de criptografia fa servir una versió no compatible. Si us plau, comproveu la configuració!
+ No es pot connectar al proveïdor de criptografia, comproveu la configuració o cliqueu a la icona de criptografia per tornar-ho a provar!
+ Ha fallat iniciar l\'encriptació d\'extrem a extrem. Si us plau, comproveu-ne la configuració.
+ El mode PGP/INLINE no admet adjunts!
+ Habilita PGP/INLINE
+ Inhabilita PGP/INLINE
+ Habilita PGP de només signar
+ Inhabilita PGP de només signar
+ Mode PGP/INLINE
+ El missatge s\'envia en el format PGP/INLINE.\nAixò només s\'hauria de fer servir per a compatibilitat:
+ Alguns clients només admeten aquest format
+ Les signatures es poden trencar durant el trànsit
+ Els adjunts no s\'admeten
+ Ja ho tinc!
+ Desactiva
+ Mantén activat
+ Ja ho tinc!
+ Desactiva
+ Mantén activat
+ Mode PGP de només signar
+ En aquest mode, la clau PGP es farà servir per crear una signatura criptogràfica d\'un missatge no encriptat.
+ Això no encripta el missatge, però verifica que s\'ha enviat des de la vostra clau.
+ Les signatures es poden trencar quan s\'envien a llistes de correu.
+ Les signatures es poden mostrar com a adjunts \"signature.asc\" en alguns clients.
+ Els missatges encriptats sempre inclouen una signatura.
+ Text pla
+ La signatura d\'extrem a extrem contenia un error.
+ cal baixar completament el missatge per processar-ne la signatura
+ conté una signatura d\'extrem a extrem no admesa
+ El missatge està encriptat, però en un format no admès.
+ El missatge està encriptat, però se n\'ha cancel·lat la desencriptació.
+ Text pla signat d\'extrem a extrem
+ des d\'un signant verificat
+ Text pla signat
+ però la clau d\'extrem a extrem no ha coincidit amb el remitent
+ però la clau d\'extrem a extrem ha caducat
+ però la clau d\'extrem a extrem està revocada
+ però la clau d\'extrem a extrem no es considera segura
+ des d\'una clau d\'extrem a extrem desconeguda
+ Encriptat
+ però hi ha hagut un error de desencriptació
+ cal descarregar completament el missatge per a la desencriptació
+ però no hi ha cap aplicació d\'encriptació configurada
+ Encriptat
+ però no d\'extrem a extrem
+ Encriptat d\'extrem a extrem
+ des d\'un remitent verificat
+ Encriptat
+ des d\'una clau d\'extrem a extrem desconeguda
+ però la clau d\'extrem a extrem no ha coincidit amb el remitent
+ però la clau d\'extrem a extrem ha caducat
+ però la clau d\'extrem a extrem està revocada
+ però la clau d\'extrem a extrem no es considera segura
+ però les dades d\'extrem a extrem tenen errors
+ però l\'encriptació no es considera segura
+ D\'acord
+ Clau de cerca
+ Mostra qui signa
+ Mostra el remitent
+ Detalls
+ Desbloqueja
+ Aquesta part no estava encriptada i pot no ser segura.
+ Adjunt no protegit
+ S\'està carregant...
+ S\'ha cancel·lat la desencriptació.
+ Torna-hi
+ Cal baixar el missatge encriptat per desencriptar-lo.
+ Error en desencriptar el correu
+ Els caràcters especials no s\'admeten actualment!
+ Error analitzant l\'adreça!
+ Amaga les signatures no encriptades
+ Només es mostraran les signatures encriptades
+ Es mostraran totes les signatures
+ Encriptació no disponible en mode de només signar!
+ Text no signat
+ Avís d\'obsolescència d\'APG
+ APG ja no es manté!
+ A causa d\'això, el suport d\'APG s\'ha eliminat del K-9 Mail.
+ El desenvolupament es va aturar a principis de 2014.
+ Conté problemes de seguretat no corregits.
+ Podeu fer clic aquí per saber-ne més.
+ Ja ho tinc!
+ APG
+ Aquest missatge està encriptat.
+ Aquest missatge ha estat encriptat amb OpenPGP.\nPer llegir-lo, us caldrà instal·lar i configurar una aplicació d\'OpenPGP compatible.
+ Ves a la configuració
+ Llista de missatges del K-9
+ S\'està carregant missatges...
+ Ha fallat recuperar la llista de carpetes.
+ Error en recuperar l\'estat del destinatari del proveïdor d\'OpenPGP!
+ Encriptació no possible
+ Alguns dels destinataris seleccionats no admeten aquesta característica!
+ Habilita l\'encriptació
+ Inhabilita l\'encriptació
+ L\'encriptació dels missatges assegura que els pugui llegir el destinatari i ningú més.
+ L\'encriptació només es mostrarà si tots els destinataris l\'admeten i us han d\'haver enviat un missatge abans.
+ Commuteu l\'encriptació fent clic en aquesta icona.
+ Ja ho tinc
+ Enrere
+ Inhabilita l\'encriptació
+ Encriptació d\'OpenPGP
+ Mode mutu d\'autoencriptació
+ Mode mutu d\'autoencriptació
+ Els missatges s\'encriptaran normalment per selecció o en respondre un missatge encriptat.
+ Si tant el remitent com el destinatari habiliten el mode mutu, l\'encriptació s\'habilitarà per defecte.
+ Podeu fer clic aquí per saber-ne més.
+ Configuració general
+ No hi ha cap aplicació d\'OpenPGP instal·lada.
+ Instal·la
+ El K-9 Mail requereix OpenKeychain per a l\'encriptació d\'extrem a extrem.
+ Missatge encriptat
+ Encripta l\'assumpte dels missatges.
+ Pot no ser admès per alguns destinataris.
+ Error intern: compte no vàlid!
+ Error en connectar a %s!
+ Envia un missatge de configuració d\'autoencriptació
+ Compartiu amb seguretat la configuració d\'extrem a extrem amb altres dispositius.
+ Missatge de configuració d\'autoencriptació
+ Un missatge de configuració d\'autoencriptació comparteix amb seguretat la configuració d\'extrem a extrem amb altres dispositius.
+ Envia un missatge de configuració
+ El missatge s\'enviarà a la vostra adreça:
+ Es genera el missatge de configuració...
+ S\'envia el missatge a:
+ Per acabar, obriu el missatge a l\'altre dispositiu i introduïu-hi el codi de configuració.
+ Mostra el codi de configuració
+ Missatge de configuració d\'autoencriptació
+ Aquest missatge conté tota la informació per transferir la configuració d\'autoencriptació i la vostra clau secreta amb seguretat des del dispositiu original.
Per configurar el vostre dispositiu nou per a l\'autoencriptació, si us plau, seguiu les instruccions que es mostraran al dispositiu nou.
Podeu desar aquest missatge i fer-lo servir com a còpia de seguretat per a la vostra clau secreta. Si ho voleu fer, hauríeu d\'anotar-vos la contrasenya i desar-la amb seguretat.
-
- Hi ha hagut un error mentre s\'enviava el missatge. Si us plau, comproveu la connexió de xarxa i la configuració del servidor de sortida.
- Actiu
- Inactiu
- Obre
- Tanca
-
- Permet l\'accés als contactes
- Per poder proporcionar suggeriments de contactes i mostrar-ne els noms i fotografies, l\'aplicació necessita accés als vostres contactes.
- S\'ha produït un error en carregar les dades
- S\'inicia...
- S\'està esperant nous correus electrònics
- Inactiu fins que es permeti la sincronització
- Inactiu fins que la xarxa estigui disponible
- Toca per obtenir més informació.
- Informació de Tramesa
- Quan es fa servir Tramesa, K-9 Mail manté una connexió amb el servidor de correu. L\'Android requereix mostrar una notificació en curs mentre l’aplicació estigui activa en segon pla. %s
- Tot i això, l\'Android també us permet ocultar la notificació.
- Apreneu-ne més
- Configureu la notificació
- Si no necessiteu notificacions instantànies sobre missatges nous, haureu de desactivar Tramesa i utilitzar Sondeig. El sondeig comprova si hi ha correus nous a intervals regulars i no necessita la notificació.
- Desactiva la Tramesa
+ Hi ha hagut un error mentre s\'enviava el missatge. Si us plau, comproveu la connexió de xarxa i la configuració del servidor de sortida.
+ Actiu
+ Inactiu
+ Obre
+ Tanca
+
+ Permet l\'accés als contactes
+ Per poder proporcionar suggeriments de contactes i mostrar-ne els noms i fotografies, l\'aplicació necessita accés als vostres contactes.
+ S\'ha produït un error en carregar les dades
+ S\'inicia...
+ S\'està esperant nous correus electrònics
+ Inactiu fins que es permeti la sincronització
+ Inactiu fins que la xarxa estigui disponible
+ Toca per obtenir més informació.
+ Informació de Tramesa
+ Quan es fa servir Tramesa, K-9 Mail manté una connexió amb el servidor de correu. L\'Android requereix mostrar una notificació en curs mentre l’aplicació estigui activa en segon pla. %s
+ Tot i això, l\'Android també us permet ocultar la notificació.
+ Apreneu-ne més
+ Configureu la notificació
+ Si no necessiteu notificacions instantànies sobre missatges nous, haureu de desactivar Tramesa i utilitzar Sondeig. El sondeig comprova si hi ha correus nous a intervals regulars i no necessita la notificació.
+ Desactiva la Tramesa
diff --git a/app/ui/legacy/src/main/res/values-cs/strings.xml b/app/ui/legacy/src/main/res/values-cs/strings.xml
index efd20c3a6402b0133ea7025a1fbb215592392d7e..7a079337a0546ec87bbca0601a825ec75a29055e 100644
--- a/app/ui/legacy/src/main/res/values-cs/strings.xml
+++ b/app/ui/legacy/src/main/res/values-cs/strings.xml
@@ -128,899 +128,903 @@
Chyba při načítání zprávyNačti až
o %d více
- %.1f GB
- %.1f MB
- %.1f kB
- %d B
- Účet „%s“ byl zmenšen z %s na %s
- Komprimuje se účet „%s“
- Nová zpráva
-
- %d nová zpráva
- %d nové zprávy
- %d nových zpráv
- %d nové zprávy
-
- %d Nepřečteno (%s)
- + %1$d více na %2$s
- Odpovědět
- Přečteno
- Označit vše jako přečtené
- Smazat
- Smazat vše
- Archivovat
- Archivovat vše
- Nevyžádaná
- Chyba certifikátu pro %s
- Zkontrolujte nastavení serveru
- Přihlášení se nezdařilo
- Přihlášení k %s se nezdařilo. Aktualizujte svá nastavení pro server.
- Zjišťování pošty: %s:%s
- Zjišťování pošty
- Odesílání pošty: %s
- Odesílání pošty
- :
- Synchronizovat (Push)
- Zobrazeno po dobu čekání na nové zprávy
- Zpráva
- Oznámení související se zprávami
- Různé
- Různá oznámení, jako chyby atd.
- Doručená
- K odeslání
- Koncepty
- Koš
- Odeslaná
- Selhalo odeslání některých zpráv
- Verze
- Povolit ladící záznam
- Zaznamenávat rozšířené diagnostické informace
- Záznamenávat citlivé informace
- V záznamech mohou být zobrazena hesla
- Načti více zpráv
- Komu:%s
- Předmět
- Text zprávy
- Podpis
- -------- Původní zpráva --------
- Předmět:
- Odesláno:
- Odesílatel:
- Komu:
- Kopie:
- %s napsal(a):
- %1$s, %2$s napsal:
- Musíte přidat alespoň jednoho příjemce.
- Kolonka příjemce neobsahuje úplnou informaci!
- Adresa tohoto kontaktu nebyla nalezena.
- Některé přílohy nelze přeposlat, protože nebyly staženy.
- Zprávu není možné přeposlat, protože nebyly staženy některé přílohy.
- Zahrnout citovanou zprávu
- Odstranit citovaný text
- Upravit citovaný text
- Odebrat přílohu
- Odesílatel: %s <%s>
- Komu:
- Kopie:
- Skrytá kopie (Bcc):
- Otevřít
- Uložit
- Přílohu se nedaří uložit.
- Zobrazovat obrázky
- Nelze nalézt prohlížeč pro %s.
- Stáhnout úplnou zprávu
- Zprávu se nedaří zobrazit
- přes %1$s
-
- Všechna záhlaví byla stažena, ale nejsou dostupná žádná další k zobrazení.
- Načtení dalších záhlaví z databáze nebo poštovního serveru selhalo.
- Více od tohoto odesílatele
- Od %s
- Ladění / tělo zprávy bez zpracování
- Zpráva byla zrušena
- Zpráva byla uložena jako koncept
- Zprávy s \u2605
- Hvězdička indikuje označenou zprávu
- Počet řádků náhledu
- Zobraz jméno odesílatele
- Zobraz jméno odesílatele raději než adresu
- Odesílatel nad předmětem
- Zobraz odesílatele nad řádkem předmětu spíše než pod ním
- Zobrazit jména kontaktů
- Použít jména příjemců ze Seznamu kontaktů, je-li to možné
- Obarvit kontakty
- Obarvit jména v seznamu kontaktů
- Písma s pevnou šířkou
- Pro zobrazování neformátovaných textových zpráv použít písmo s pevnou šířkou
- Automatické přizpůsobení zpráv
- Zmenšit zprávy aby se vešly na obrazovku
- Návrat do seznamu po smazání
- Vrátit se do seznamu zpráv po smazání zprávy
- Zobraz další zprávu po smazání
- Zobraz další zprávu automaticky po smazání
- Potvrzování akcí
- Zobrazit dialog, když provádíte zvolené akce
- Smazat
- Smaž zprávy s hvězdičkou (v zobrazení zpráv)
- Nevyžádaná
- Zahodit zprávu
- Označit všechny zprávy jako přečtené
- Smazat (z oznámení)
- Skrýt e-mailového klienta
- Remove Mail User-Agent from mail headers
- Skrýt časovou zónu
- Používat v hlavičkách e-mailů a odpovědí univerzální čas (UTC) namísto toho místního
- Schovej předmet v upozorněních
- Nikdy
- Když je telefon uzamčený
- Vždy
- Zobrazit tlačítko \'Smazat\'
- Nikdy
- Pro mazaní jedné zprávy
- Vždy
- Oznámení na uzamčené obrazovce
- Žádná oznámení na uzamčené obrazovce
- Jméno aplikace
- Počet nepřečtených zpráv
- Počet zpráv a odesilatelů
- Stejné jako při odemčené obrazovce
- Doba klidu
- Zakázat v noci zvonění, vibrace a blikání
- Vypnout oznamování
- Kompletně vypnout oznamování v režimu nevyrušování
- Doba klidu začíná
- Doba klidu končí
- Založit nový účet
- Emailová adresa
- Heslo
- Zobrazit heslo
- Ruční nastavení
-
- Získávání informací o účtu\u2026
- Kontrola nastavení serveru příchozí pošty\u2026
- Kontrola nastavení serveru odchozí pošty\u2026
- Přihlašuji se\u2026
- Stahuji nastavení účtu\u2026
- Rušení\u2026
- Téměř hotovo!
- Pojmenujte tento účet (volitelné):
- Zadejte své jméno (zobrazuje se v odchozích zprávách):
- Typ účtu
- O jaký typ účtu jde?
- POP3
- IMAP
- Normální heslo
- Heslo přenášeno bez zabezpečení
- Zašifrované heslo
- Klientský certifikát
- Nastavení serveru příchozí pošty
- Uživatelské jméno
- Heslo
- Klientský certifikát
- Server POP3
- Server IMAP
- Server Exchange (WebDAV)
- Port
- Typ zabezpečení
- Typ ověření
- Žádné
- SSL/TLS
- STARTTLS
- „%1$s = %2$s“ není platný s „%3$s = %4$s“
- Když smažu zprávu
- Nemazat ji na serveru
- Smazat na serveru
- Označit jako přečtenou na serveru
- Používat v síti kompresi:
- Mobilní
- Wi-Fi
- Jiná
- Externí úložiště (SD karta)
- Obvyklé vnitřní úložiště
- Odstranit smazané zprávy
- Ihned
- Při dotazování
- Pouze ručně
- Zjistit automaticky IMAP namespace
- Předpona cesty IMAP
- Název složky Koncepty
- Název složky Odeslaná
- Název složky Koš
- Název složky Archív
- Název složky Nevyžádaná
- Zobrazit jen odebírané složky
- Aut. rozbalená složka
- OWA cesta
- Volitelné
- Ověřovací cesta
- Volitelné
- Alternativní název schránky
- Volitelné
- Nastavení serveru odchozí pošty
- Server SMTP
- Port
- Typ zabezpečení
- Požadovat přihlášení.
- Uživatelské jméno
- Heslo
- Typ ověření
- „%1$s = %2$s“ není platný s „%3$s = %4$s“
- Neplatné nastavení: %s
- Možnosti účtu
- Zkomprimovat účet
- Frekvence dotazování složky
- Nikdy
- Každých 15 minut
- Každých 30 minut
- Každou hodinu
- Každé 2 hodiny
- Každé 3 hodiny
- Každých 6 hodin
- Každých 12 hodin
- Každé 24 hodiny
- Povolit připojení PUSH pro tento účet
- Pokud to váš server podporuje, nové zprávy se objeví okamžitě. Tato volba může dramaticky zlepšit nebo zhoršit výkon.
- Obnovit připojení IDLE
- Každé 2 minuty
- Každé 3 minuty
- Každých 6 minut
- Každých 12 minut
- Každé 24 minuty
- Každých 36 minut
- Každých 48 minut
- Každých 60 minut
- Oznamuj mi příchod nové pošty
- Informuj mě o zjišťování pošty
- Počet zobrazených zpráv
- 10 zpráv
- 25 zpráv
- 50 zpráv
- 100 zpráv
- 250 zpráv
- 500 zpráv
- 1000 zpráv
- 2500 zpráv
- 5000 zpráv
- 10000 zpráv
- všechny zprávy
- Nelze kopírovat nebo přesunovat zprávu, která není synchronizována se serverem
- Konfiguraci nastavení nelze dokončit
- Uživatelské jméno nebo heslo není správné.\n(%s)
- Server nabízí neplatný SSL certifikát. Někdy může jít o chybu nastavení serveru, někdy o pokus útoku na vás nebo e-mailový server. Pokud nevíte o co jde, ťukněte na odmítnout a obraťte se na správce dotyčného e-mailového serveru.\n\n(%s)
- Nedaří se připojit k serveru. (%s)
- Upravit podrobnosti
- Pokračovat
- Rozšířené
- Nastavení účtu
- Výchozí účet
- Tento účet jako výchozí pro odesílání
- Oznamování nové pošty
- Složky oznámení
- Všechny
- Jen složky 1. třídy
- Složky 1. a 2. třídy
- Všechny vyjma složek 2. třídy
- Žádné
- Synchronizovat oznámení
- Vaše emailová adresa
- Oznamovat došlou poštu ve stavovém řádku
- Oznamovat zjišťování pošty ve stavovém řádku
- Zahrnout odchozí poštu
- Zobrazovat oznámení pro vlastní odeslanou poštu
- Pouze kontakty
- Zobrazovat oznámení pouze na zprávy od známých kontaktů
- Označit jako přečtenou po otevření
- Označit zprávu jako přečtenou po otevření
- Při smazání označit jako přečtené
- Při jejím mazání, označit zprávu jako přečtenou
- Nastavení oznamování
- Nastavení oznamování v operačním systému
- Vždy zobrazovat obrázky
- Ne
- Jen od kontaktů
- Od kohokoli
- Odesílání zpráv
- Citovat původní zprávu když odpovídám
- Zahrnout původní zprávu v odpovědi.
- Odpovědět za citovaným textem
- Původní zprávu zobrazit nad textem odpovědi.
- Odstranit podpis z citované odpovědi
- Budou odstraněny podpisy z citovaných zpráv
- Formát zprávy
- Prostý text (odstraní obrázky a formátování)
- HTML (zachová obrázky a formátování)
- Automaticky
- Vždy zobrazit kopie/skrytá
- Potvrzení o přečtení
- Vždy požadovat potvrzení o přečtení
- Styl citace odpovědi
- Prefix (jako Gmail)
- Záhlaví (jako Outlook)
- Nahrát odeslané zprávy
- Po odeslání nahrát zprávy do složky Odesláno
- Hlavní nastavení
- Čtení zprávy
- Stahování pošty
- Složky
- Předpona citovaného textu
- Šifrování mezi odesilatelem a příjemcem
- Zapnout podporu OpenPGP
- Vybrat OpenPGP aplikaci
- Nastavit klíč pro šifrování mezi odesilatelem a příjemcem
- Není nastavená žádná OpenPGP aplikace
- Připojeno k %s
- Nastavování…
- Ukládat veškeré koncepty šifrovaně
- Všechny koncepty budou ukládány šifrovaně
- Šifrovat koncepty pouze pokud je zapnuté šifrování
- Frekvence dotazování složky
- Barva účtu
- Vyberte barvu pro tento účet, používanou v seznamech složek a zpráv
- Žádná barva
- Barva oznamovací LED
- Barva, kterou má telefon blikat pro tento účet
- Velikost místního adresáře
- Stahovat zprávy až do
- 1 KiB
- 2 KiB
- 4 KiB
- 8 KiB
- 16 KiB
- 32 KiB
- 64 KiB
- 128 KiB
- 256 KiB
- 512 KiB
- 1 MiB
- 2 MiB
- 5 MiB
- 10 MiB
- jakékoli velikosti (bez omezení)
- Synchronizovat odeslané zprávy
- kdykoliv (bez omezení)
- dnešní
- za poslední 2 dny
- za poslední 3 dny
- za poslední týden
- za poslední 2 týdny
- za poslední 3 týdny
- za poslední měsíc
- za poslední 2 měsíce
- za poslední 3 měsíce
- za posledních 6 měsíců
- za poslední rok
- Zobrazované složky
- Všechny
- Jen složky 1. třídy
- Složky 1. a 2. třídy
- Všechny vyjma složek 2. třídy
- Složky řízené dotazováním
- Všechny
- Jen složky 1. třídy
- Stejné jako třída fondu
- Složky 1. a 2. třídy
- Všechny vyjma složek 2. třídy
- Žádné
- Složky řízené serverem (PUSH)
- Všechny
- Jen složky 1. třídy
- Složky 1. a 2. třídy
- Všechny vyjma složek 2. třídy
- Žádné
- Cílové složky pro přesun/kopii
- Všechny
- Jen složky 1. třídy
- Složky 1. a 2. třídy
- Všechny vyjma složek 2. třídy
- Synchronizace mazání serveru
- Odstranit zprávy, když je smaže server
- Chybí OpenPGP aplikace – byla odinstalována?
- Nastavení složky
- Zobrazit v nejvyšší skupině
- Zobrazit blízko špičky seznamu složek
- Třída zobrazování složky
- Žádná třída
- 1. třída
- 2. třída
- Třída fondu složky
- Žádné
- 1. třída
- 2. třída
- Stejná jako třída zobrazení
- Třída složky rozšíření PUSH
- Žádná třída
- 1. třída
- 2. třída
- Třída oznámení složky
- Žádná třída
- 1. třída
- 2. třída
- Stejná jako třída PUSH
- Vyčistit místní zprávy
- Server příchozí pošty
- Konfigurace serveru příchozí pošty
- Server odchozí pošty
- Konfigurace serveru odchozí pošty (SMTP)
- Název účtu
- Vaše jméno
- Oznámení
- Vibrovat
- Vibrovat při příchodu zpráv
- Vzory vibrování
- výchozí
- vzorek 1
- vzorek 2
- vzorek 3
- vzorek 4
- vzorek 5
- Opakovat vibrace
- Zvuk při nové poště
- Blikání LED
- Blikat LED, když přijde pošta
- Možnosti tvorby nových zpráv
- Výchozí položky nové zprávy
- Nastavit výchozí hodnoty Odesílatele, Skryté a podpisu
- Správa identit
- Nastavte alternativní adresy \'Od\' a podpisy
- Správa identit
- Spravovat identitu
- Upravit identitu
- Uložit
- Nová identita
- Kopii všech zpráv na adresu
- Upravit
- Posunout nahoru
- Posunout dolů
- Posunout do čela/nastavit jako výchozí
- Odstranit
- Popis identity
- (Volitelné)
- Vaše jméno
- (Volitelné)
- Emailová adresa
- (Vyžadováno)
- Adresa pro odpověď
- (Volitelné)
- Podpis
- (Volitelné)
- Používat podpis
- Podpis
- Výchozí identita
- Vybrat identitu
- Odeslat jako
- Nelze odebrat jedinou zbývající identitu
- Nelze použít identitu bez e-mailové adresy
- Nejstarší zprávy první
- Nejnovější zprávy první
- Předmět abecedně A-Z
- Předmět abecedně Z-A
- Odesílatel A-Z
- Odesílatel Z-A
- S \u2605 první
- Bez \u2606 první
- Nepřečtené první
- Přečtené první
- S přílohou první
- Bez přílohy první
- Třídit podle položky…
- Datum
- Příchodu
- Předmět
- Odesílatel
- Hvězdička
- Přečtená/Nepřečtená
- Příloha
- Odstranit účet
- Nerozpoznaný certifikát
- Přijmout klíč
- Odmítnout klíč
- Delete (nebo D) – Smazat\nR – Odpovědět\nA – Odpovědět všem\nC – Vytvořit\nF – Přeposlat\nM – Přesunout\nV - Archivovat\nY – Kopírovat\nZ – Označit (Ne)přečtené\nG – Hvězdička\nO – Uspořádat podle typu\nI – Uspořádat podle pořadí\nQ – Zpět ke složkám\nS – Označit/odznačit\nJ nebo P – Předešlá zpráva\nK nebo N – Další zpráva
- Delete (nebo D) – Smazat\nC – Vytvořit\nM – Přesunout\nV – Archivovat\nY – Zkopírovat\nZ – Označit jako (ne)přečtené\nG – Označit hvězdičkou\nO – Typ řazení\nI – Pořadí řazení\nQ – Návrat na složky\nS – Označit / zrušit označení
- Název složky obsahuje
- Zobrazit složky…
- Všechny složky
- Složky 1. třídy
- Složky 1. & 2. třídy
- Skrýt složky 2. třídy
- Umístění podpisu
- Před citovanými textem
- Za citovanými textem
- Použít vzhled aplikace
- Tmavé
- Světlé
- Použít systémové výchozí
- Zobrazení
- Globální
- Ladění
- Soukromí
- Síť
- Ovládání
- Seznam účtů
- Seznam zpráv
- Zprávy
- Vzhled
- Vzhled náhledu zprávy
- Vzhled psaní zprávy
- Jazyk
- Nenalezena žádná nastavení
- Neměnný vzhled zpráv
- Lze vybrat vzhled při prohlížení zprávy
- Použít neměnný vzhled při prohlížení zprávy
- Výchozí nastavení systému
- Synchronizace na pozadí
- Nikdy
- Vždy
- Když je zaškrtnutá „Aut. synchronizace“
- Vybrat vše
- Max. počet složek řízených PUSH
- 5 složek
- 10 složek
- 25 složek
- 50 složek
- 100 složek
- 250 složek
- 500 složek
- 1000 složek
- Animace
- Používat okázalé vizuální efekty
- Navigace tlačítky hlasitosti
- Zobrazení zpráv
- Různá zobrazení seznamů
- Ukázat sjednocený pohled na doručenou poštu
- %s%s
- - Nepřečtené
- Všechny zprávy
- Všechny zprávy v prohledávaných složkách
- Integrovaná doručená pošta
- Všechny zprávy v integrovaných složkách
- Integrovat
- Všechny zprávy jsou zobrazeny v Integrované doručené poště
- Prohledávané složky
- Všechny
- Zobrazitelné
- Žádné
- Žádné
- Automaticky (%s)
- Velikost písma
- Konfigurovat velikost písma
- Seznam účtů
- Název účtu
- Popis účtu
- Seznam složek
- Název složky
- Stav složky
- Seznam zpráv
- Předmět
- Odesílatel
- Datum
- Náhled
- Zpráva
- Odesílatel
- Příjemce (Komu)
- Příjemce (Kopie)
- Skrytá kopie
- Další záhlaví
- Předmět
- Datum a čas
- Tělo
- %d%%
- %1$s: %2$s
- Psaní zprávy
- Pole zadávaní textu
- Standardní
- Nejdrobnější
- Drobný
- Menší
- Malý
- Střední
- Velký
- Největší
- Pro tuto akci nebyla nalezena žádná vhodná aplikace.
- Odeslání se nezdařilo: %s
- Uložit koncept zprávy?
- Uložit nebo zahodit tuto zprávu?
- Uložit nebo zahodit změny?
- Zahodit zprávu?
- Opravdu chcete tuto zprávu zahodit?
- Vyberte text pro kopírování.
- Vymazat zprávy uložené lokálně?
- Toto ze složky odebere všechny lokálně uložené zprávy. Ze serveru nebudou vymazány žádné zprávy.
- Vyčistit zprávy
- Potvrzení mazání
- Chcete smazat tuto zprávu?
-
- Opravdu si přejete smazat tuto zprávu?
- Opravdu si přejete smazat %1$d zprávy?
- Opravdu si přejete smazat %1$d zpráv?
- Opravdu si přejete smazat %1$d zpráv?
-
- Ano
- Ne
- Potvrdit označení všech jako přečtené
- Opravdu chcete označit všechny zprávy jako přečtené?
- Potvrdit vyprázdnění koše
- Opravdu chcete vyprázdnit složku Koš?
- Ano
- Ne
- Potvrzení přesunu do nevyžádané pošty
-
- Opravdu chcete přesunout tuto zprávy do nevyžádané pošty?
- Opravdu chcete přesunout %1$d zprávy do nevyžádané pošty?
- Opravdu chcete přesunout %1$d zpráv do nevyžádané pošty?
- Opravdu chcete přesunout %1$d zpráv do nevyžádané pošty?
-
- Ano
- Ne
- Stahuji přílohy
- »
- ›
- Záloha
- Různé
- Exportovat nastavení
- Export
- Sdílet
- Exportování nastavení…
- Nastavení úspěšně exportována
- Export nastavení se nezdařil
- Importovat nastavení
- Vybrat soubor
- Import
- Nastavení úspěšně importována
- Zadejte hesla
- Nepodařilo se importovat nastavení
- Nepodařilo se číst soubor s nastaveními
- Nepodařilo se naimportovat některá nastavení
- Úspěšně naimportováno
- Vyžadováno hesl
- Nenaimportováno
- Nezdar při importu
- Později
- Importovat nastavení
- Importování nastavení…
-
- Abyste mohli používat účet „%s“, je třeba zadat heslo k serveru.
- Abyste mohli používat účty „%s“, je třeba zadat heslo k serveru.
- Abyste mohli používat účty „%s“, je třeba zadat heslo k serveru.
- Abyste mohli používat účty „%s“, je třeba zadat heslo k serveru.
-
- Heslo pro server pro příchozí
- Heslo pro server pro odchozí
- Použít stejné heslo jako pro server pro odchozí
- Název serveru: %s
- Zobrazit počet nepřečtených pro…
- Účet
- Účet pro který má být zobrazen počet nepřečtených
- Sjednocená doručená pošta
- Počet ve složce
- Zobrazit počet nepřečtených pouze pro jedinou složku
- Složka
- Složka pro kterou má být zobrazen počet nepřečtených
- Hotovo
- %1$s – %2$s
- Nebyl vybrán žádný účet
- Nebyla vybrána žádná složka
- Žádný text
- Otevřít odkaz
- Sdílet odkaz
- Zkopírovat odkaz do schránky
- Odkaz
- Zkopírovat text odkazu do schránky
- Text odkazu
- Obrázek
- Zobrazit obrázek
- Uložit obrázek
- Stáhnout obrázek
- Zkopírovat adresu obrázku do schránky
- Adresa obrázku
- Volat číslo
- Uložit do kontaktů
- Zkopírovat číslo do schránky
- Telefonní číslo
- Odeslat zprávu
- Uložit do kontaktů
- Zkopírovat e-mailovou adresu do schránky
- E-mailová adresa
- Vše
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- Limit počtu výsledků prohledávání serveru
- Odeslání dotazu na server
-
- Načítání %d výsledku
- Načítání %d výsledků
- Načítání %d výsledků
- Načítání %d výsledků
-
-
- Stahování %1$d z %2$d výsledků
- Stahování %1$d z %2$d výsledků
- Stahování %1$d z %2$d výsledků
- Stahování %1$d z %2$d výsledků
-
- Vzdálené vyhledávání se nezdařilo
- Hledání
- Povolit vyhledávání na serveru
- Hledat zprávy na serveru navíc k těm v zařízení
- Hledat zprávy na serveru
- Vzdálené vyhledávání není k dispozici bez připojení k síti.
- Ztmavit zprávy po přečtení
- Prečtená zpráva bude mít jiné pozadí.
- Zobrazit vlákna
- Sjednotit zprávy patřící ke stejnému vláknu
- Aktualizace databází
- Aktualizuji databáze…
- Přechod na novější verzi databáze účtu „%s“
- Zobraz rozdělení obrazovky
- Vždy
- Nikdy
- Při orientaci na šířku
- Prosím zvolte zprávu vlevo
- Zobraz obrázky u kontaktů
- V seznamu zpráv, zobrazovat u kontaktů jejich fotky
- Označ vše jako přečtené
- Obarvit obrázky kontaktů
- Obarví chybějící obrázky u kontaktů
- Zobrazení funkcí zpráv
- Zobrazí vybrané funkce v dolním menu u zpráv
- Nahrávám přílohu…
- Odesílám zprávu
- Ukládám koncept
- Stahuji přílohu…
- Nelze ověřit. Server neuvádí možnost SASL EXTERNAL. To by mohlo být kvůli problému s klientským certifikátem (vypršel, neznámá certifikační autorita), nebo nějaký jiný problém konfigurace.
-
- Použít klientský certifikát
- Žádný klientský certifikát
- Odstranit výběr klientského certifikátu
- Chyba při získání klientského certifikátu pro alias \"%s\"
- Pokročilé možnosti
- Klientský certifikát \"%1$s\" vypršel nebo ještě není platný (%2$s)
-
- *Zašifrováno*
- Přidat z kontaktů
- Kopie
- Skrytá kopie
- Komu
- Odesílatel
- <Neznámý příjemce>
- <Neznámý odesilatel>
- Domov
- Práce
- Ostatní
- Mobilní
- Tento účet nemá nastavenou žádnou složku pro koncepty!
- Pro tento účet není nastaven žádný klíč! Zkontrolujte nastavení.
- Poskytovatel šifrování používá neslučitelnou verzi. Zkontrolujte svá nastavení!
- Nelze se spojit se službou šifrování, zkontrolujte své nastavení nebo ťukněte na ikonu šifrování pro nový pokus.
- Nepodařilo se inicializovat šifrování mezi odesílatelem a příjemcem – zkontrolujte svá nastavení
- PGP/INLINE mód nepodporuje přílohy!
- Povolit PGP/INLINE
- Zakázat PGP/INLINE
- Povolit PGP podpisový mód
- Zakázat jen PGP podpis
- PGP/INLINE mód
- Email je odeslán v PGP/INLINE formátu.\nToto má být použito pouze pro kompatibilitu:
- Některé klientské aplikace podporují pouze tento formát
- Může dojít k poškození podpisu v průběhu přenosu
- Přílohy nejsou podporovány
- Rozumím!
- Vypnout
- Ponechat zapnuté
- Rozumím!
- Vypnout
- Ponechat zapnuté
- Pouze PGP podpisový režim
- V tomto módu bude váš PGP klíč použit k vytvoření kryptografického podpisu nešifrovaného emailu.
- Toto nezašifruje text emailu, ale poskytne ověření, že byl email podepsán vaším klíčem.
- Může dojít k poškození podpisu při odeslání emailu na mailing list.
- Podpisy mohou být v některých klientských aplikacích zobrazeny jako soubor přílohy „signature.asc“.
- Šifrované zprávy vždy obsahují podpis.
- Holý text
- podpis autora obsahoval chybu
- podpis bude možné zpracovat až po úplném stažení zprávy
- obsahuje nepodporovaný podpis
- Zpráva je zašifrována, ale v nepodporovaném formátu.
- Zpráva je zašifrována, ale dešifrování bylo zrušeno.
- Holý text podepsaný přímo autorem
- od ověřeného podepisujícího
- Podepsaný čitelný text
- ale klíč neodpovídá autorovi
- ale platnost podpisového klíče autora skončila
- ale platnost autorova klíče byla odvolána
- ale klíč autora není považován za bezpečný
- podepsáno neznámým klíčem
- Šifrováno
- ale vyskytla se chyba při rozšifrovávání
- pro rozšifrování je třeba zprávu napřed celou stáhnout
- ale není nastavena žádná šifrovací aplikace
- Šifrováno
- není podepsáno přímo autorem
- Podepsáno přímo autorem
- od ověřeného odesilatele
- Šifrováno
- podepsáno neznámým klíčem
- klíč neodpovídá autorovi
- ale platnost podpisového klíče autora skončila
- ale platnost autorova klíče byla odvolána
- ale klíč autora není považován za bezpečný
- ale podepsaná data mají chyby
- ale šifra není považovaná za bezpečnou
- OK
- Hledat klíč
- Zobrazit podepisujícího
- Zobrazit odesilatele
- Podrobnosti
- Odemknout
- Tato část nebyla zašifrovaná a nemusí proto být bezpečná.
- Nechráněná příloha
- Načítání…
- Rozšifrování zrušeno.
- Opakovat
- Zašifrovaná zpráva musí být stažena pro dešifrování.
- Chyba při rozšifrovávání e-mailu
- Speciální znaky nejsou momentálně podporovány!
- Chyba zpracovávání adresy!
- Skrýt nezašifrované podpisy
- Budou zobrazeny pouze zašifrované podpisy
- Budou zobrazeny všechny podpisy
- Šifrování nedostupné v podpisovém módu!
- Nepodepsaný text
- Varování o ukončení podpory APG
- APG už není udržováno!
- Kvůli tomuto jsme odstranili podporu pro APG z K-9 Mailu.
- Vývoj skončil na začátku roku 2014
- Obsahuje neopravené bezpečnostní chyby
- Kliknutím sem se můžete dozvědět více.
- Rozumím!
- APG
- Tento e-mail je šifrovaný
- Tento email byl zašifrovaný pomocí OpenPGP.\nAbyste si ho mohl/a přečíst, potřebujete si nainstalovat a nakonfigurovat kompatibilní OpenPGP aplikaci.
- Přejít do nastavení
- Mail Message List
- Načítání zpráv…
- Nepodařilo se načíst seznam složek
- Chyba při získávání stavu příjemce z poskytovatele OpenPGP!
- Šifrování není možné
- Někteří ze zvolených příjemců nepodporují tuto funkci!
- Zapnout šifrování
- Vypnout šifrování
- Šifrování zpráv zajistí, že budou čitelné pouze pro příjemce a nikoho jiného.
- Šifrování se zobrazí pouze tehdy, pokud je podporováno všemi příjemci a je třeba, aby vám už dříve poslali nějaký e-mail.
- Přepněte šifrování kliknutím na tuto ikonu.
- Rozumím
- Zpět
- Vypnout šifrování
- Šifrování OpenGPG
- Vzájemný režim automatického šifrování
- Vzájemný režim automatického šifrování
- Normálně budou zprávy šifrovány volitelně, nebo při odpovědi na šifrovanou zprávu.
- Pokud jak odesilatel, tak příjemce zapnou vzájemný režim, šifrování bude ve výchozím stavu zapnuté.
- Více informací je možné zjistit kliknutím sem.
- Hlavní nastavení
- Není nainstalovaná žádná OpenPGP aplikace
- Nainstalovat
- Mail requires OpenKeychain for end-to-end encryption.
- Zašifrovaná zpráva
- Šifrovat předměty e-mailů
- Nemusí být podporováno některými příjemci
- Vnitřní chyba: neplatný účet!
- Chyba při připojování k %s!
- Poslat Autocrypt nastavovací zprávu
- Zabezpečeně sdílet nastavení s ostatními zařízeními
- Autocrypt nastavovací zpráva
- Autocrypt nastavovací zpráva zabezpečeně sdílí vaše nastavení s ostatními zařízeními.
- Poslat nastavovací zprávu
- Tato zpráva bude odeslána na vaši adresu:
- Vytváření nastavovací zprávy…
- Odesílání zprávy na:
- Pro dokončení otevřete zprávu na svém dalším zařízení a zadejte nastavovací kód.
- Zobrazit nastavovací kód
- Autocrypt nastavovací správa
- Tato zpráva obsahuje všechny údaje pro zabezpečené přenesení vašich nastavení Autocrypt společně s tajným klíčem z původního zařízení.
+ %.1f GB
+ %.1f MB
+ %.1f kB
+ %d B
+ Účet „%s“ byl zmenšen z %s na %s
+ Komprimuje se účet „%s“
+ Nová zpráva
+
+ %d nová zpráva
+ %d nové zprávy
+ %d nových zpráv
+ %d nové zprávy
+
+ %d Nepřečteno (%s)
+ + %1$d více na %2$s
+ Odpovědět
+ Přečteno
+ Označit vše jako přečtené
+ Smazat
+ Smazat vše
+ Archivovat
+ Archivovat vše
+ Nevyžádaná
+ Chyba certifikátu pro %s
+ Zkontrolujte nastavení serveru
+ Přihlášení se nezdařilo
+ Přihlášení k %s se nezdařilo. Aktualizujte svá nastavení pro server.
+ Zjišťování pošty: %s:%s
+ Zjišťování pošty
+ Odesílání pošty: %s
+ Odesílání pošty
+ :
+ Synchronizovat (Push)
+ Zobrazeno po dobu čekání na nové zprávy
+ Zpráva
+ Oznámení související se zprávami
+ Různé
+ Různá oznámení, jako chyby atd.
+ Doručená
+ K odeslání
+ Koncepty
+ Koš
+ Odeslaná
+ Selhalo odeslání některých zpráv
+ Verze
+ Povolit ladící záznam
+ Zaznamenávat rozšířené diagnostické informace
+ Záznamenávat citlivé informace
+ V záznamech mohou být zobrazena hesla
+ Exportovat záznamy událostí
+ Export úspěšný. Záznamy událostí mohou obsahovat citlivé informace. Buďte opatrní s tím, komu je pošlete.
+ Export se nezdařil.
+ Načti více zpráv
+ Komu:%s
+ Předmět
+ Text zprávy
+ Podpis
+ -------- Původní zpráva --------
+ Předmět:
+ Odesláno:
+ Odesílatel:
+ Komu:
+ Kopie:
+ %s napsal(a):
+ %1$s, %2$s napsal:
+ Musíte přidat alespoň jednoho příjemce.
+ Kolonka příjemce neobsahuje úplnou informaci!
+ Adresa tohoto kontaktu nebyla nalezena.
+ Některé přílohy nelze přeposlat, protože nebyly staženy.
+ Zprávu není možné přeposlat, protože nebyly staženy některé přílohy.
+ Zahrnout citovanou zprávu
+ Odstranit citovaný text
+ Upravit citovaný text
+ Odebrat přílohu
+ Odesílatel: %s <%s>
+ Komu:
+ Kopie:
+ Skrytá kopie (Bcc):
+ Otevřít
+ Uložit
+ Přílohu se nedaří uložit.
+ Zobrazovat obrázky
+ Nelze nalézt prohlížeč pro %s.
+ Stáhnout úplnou zprávu
+ Zprávu se nedaří zobrazit
+ přes %1$s
+
+ Všechna záhlaví byla stažena, ale nejsou dostupná žádná další k zobrazení.
+ Načtení dalších záhlaví z databáze nebo poštovního serveru selhalo.
+ Více od tohoto odesílatele
+ Od %s
+ Ladění / tělo zprávy bez zpracování
+ Zpráva byla zrušena
+ Zpráva byla uložena jako koncept
+ Zprávy s \u2605
+ Hvězdička indikuje označenou zprávu
+ Počet řádků náhledu
+ Zobraz jméno odesílatele
+ Zobraz jméno odesílatele raději než adresu
+ Odesílatel nad předmětem
+ Zobraz odesílatele nad řádkem předmětu spíše než pod ním
+ Zobrazit jména kontaktů
+ Použít jména příjemců ze Seznamu kontaktů, je-li to možné
+ Obarvit kontakty
+ Obarvit jména v seznamu kontaktů
+ Písma s pevnou šířkou
+ Pro zobrazování neformátovaných textových zpráv použít písmo s pevnou šířkou
+ Automatické přizpůsobení zpráv
+ Zmenšit zprávy aby se vešly na obrazovku
+ Návrat do seznamu po smazání
+ Vrátit se do seznamu zpráv po smazání zprávy
+ Zobraz další zprávu po smazání
+ Zobraz další zprávu automaticky po smazání
+ Potvrzování akcí
+ Zobrazit dialog, když provádíte zvolené akce
+ Smazat
+ Smaž zprávy s hvězdičkou (v zobrazení zpráv)
+ Nevyžádaná
+ Zahodit zprávu
+ Označit všechny zprávy jako přečtené
+ Smazat (z oznámení)
+ Skrýt e-mailového klienta
+ Odstraňovat z hlaviček e-mailů informaci o K-9 (user agent)
+ Skrýt časovou zónu
+ Používat v hlavičkách e-mailů a odpovědí univerzální čas (UTC) namísto toho místního
+ Zobrazit tlačítko \'Smazat\'
+ Nikdy
+ Pro mazaní jedné zprávy
+ Vždy
+ Oznámení na uzamčené obrazovce
+ Žádná oznámení na uzamčené obrazovce
+ Jméno aplikace
+ Počet nových zpráv
+ Počet zpráv a odesilatelů
+ Stejné jako při odemčené obrazovce
+ Doba klidu
+ Zakázat v noci zvonění, vibrace a blikání
+ Vypnout oznamování
+ Kompletně vypnout oznamování v režimu nevyrušování
+ Doba klidu začíná
+ Doba klidu končí
+ Založit nový účet
+ Emailová adresa
+ Heslo
+ Zobrazit heslo
+
+ Pokud si zde chcete zobrazit své heslo, zapněte zamykání obrazovky tohoto zařízení.
+ Ověřte svou identitu
+ Pokud chcete vidět své heslo, odemkněte
+ Ruční nastavení
+
+ Získávání informací o účtu\u2026
+ Kontrola nastavení serveru příchozí pošty\u2026
+ Kontrola nastavení serveru odchozí pošty\u2026
+ Přihlašuji se\u2026
+ Stahuji nastavení účtu\u2026
+ Rušení\u2026
+ Téměř hotovo!
+ Pojmenujte tento účet (volitelné):
+ Zadejte své jméno (zobrazuje se v odchozích zprávách):
+ Typ účtu
+ O jaký typ účtu jde?
+ POP3
+ IMAP
+ Normální heslo
+ Heslo přenášeno bez zabezpečení
+ Zašifrované heslo
+ Klientský certifikát
+ Nastavení serveru příchozí pošty
+ Uživatelské jméno
+ Heslo
+ Klientský certifikát
+ Server POP3
+ Server IMAP
+ Server Exchange (WebDAV)
+ Port
+ Typ zabezpečení
+ Typ ověření
+ Žádné
+ SSL/TLS
+ STARTTLS
+ „%1$s = %2$s“ není platný s „%3$s = %4$s“
+ Když smažu zprávu
+ Nemazat ji na serveru
+ Smazat na serveru
+ Označit jako přečtenou na serveru
+ Používat v síti kompresi:
+ Mobilní
+ Wi-Fi
+ Jiná
+ Odstranit smazané zprávy
+ Ihned
+ Při dotazování
+ Pouze ručně
+ Zjistit automaticky IMAP namespace
+ Předpona cesty IMAP
+ Název složky Koncepty
+ Název složky Odeslaná
+ Název složky Koš
+ Název složky Archív
+ Název složky Nevyžádaná
+ Zobrazit jen odebírané složky
+ Aut. rozbalená složka
+ OWA cesta
+ Volitelné
+ Ověřovací cesta
+ Volitelné
+ Alternativní název schránky
+ Volitelné
+ Nastavení serveru odchozí pošty
+ Server SMTP
+ Port
+ Typ zabezpečení
+ Požadovat přihlášení.
+ Uživatelské jméno
+ Heslo
+ Typ ověření
+ „%1$s = %2$s“ není platný s „%3$s = %4$s“
+ Neplatné nastavení: %s
+ Možnosti účtu
+ Zkomprimovat účet
+ Frekvence dotazování složky
+ Nikdy
+ Každých 15 minut
+ Každých 30 minut
+ Každou hodinu
+ Každé 2 hodiny
+ Každé 3 hodiny
+ Každých 6 hodin
+ Každých 12 hodin
+ Každé 24 hodiny
+ Povolit připojení PUSH pro tento účet
+ Pokud to váš server podporuje, nové zprávy se objeví okamžitě. Tato volba může dramaticky zlepšit nebo zhoršit výkon.
+ Obnovit připojení IDLE
+ Každé 2 minuty
+ Každé 3 minuty
+ Každých 6 minut
+ Každých 12 minut
+ Každé 24 minuty
+ Každých 36 minut
+ Každých 48 minut
+ Každých 60 minut
+ Oznamuj mi příchod nové pošty
+ Informuj mě o zjišťování pošty
+ Počet zobrazených zpráv
+ 10 zpráv
+ 25 zpráv
+ 50 zpráv
+ 100 zpráv
+ 250 zpráv
+ 500 zpráv
+ 1000 zpráv
+ 2500 zpráv
+ 5000 zpráv
+ 10000 zpráv
+ všechny zprávy
+ Nelze kopírovat nebo přesunovat zprávu, která není synchronizována se serverem
+ Konfiguraci nastavení nelze dokončit
+ Uživatelské jméno nebo heslo není správné.\n(%s)
+ Server nabízí neplatný SSL certifikát. Někdy může jít o chybu nastavení serveru, někdy o pokus útoku na vás nebo e-mailový server. Pokud nevíte o co jde, ťukněte na odmítnout a obraťte se na správce dotyčného e-mailového serveru.\n\n(%s)
+ Nedaří se připojit k serveru. (%s)
+ Upravit podrobnosti
+ Pokračovat
+ Rozšířené
+ Nastavení účtu
+ Oznamování nové pošty
+ Složky oznámení
+ Všechny
+ Jen složky 1. třídy
+ Složky 1. a 2. třídy
+ Všechny vyjma složek 2. třídy
+ Žádné
+ Synchronizovat oznámení
+ Vaše emailová adresa
+ Oznamovat došlou poštu ve stavovém řádku
+ Oznamovat zjišťování pošty ve stavovém řádku
+ Zahrnout odchozí poštu
+ Zobrazovat oznámení pro vlastní odeslanou poštu
+ Pouze kontakty
+ Zobrazovat oznámení pouze na zprávy od známých kontaktů
+ Ignorovat zprávy z chatů
+ Nezobrazovat upozornění na zprávy, náležející do e-mailového chatu
+ Označit jako přečtenou po otevření
+ Označit zprávu jako přečtenou po otevření
+ Při smazání označit jako přečtené
+ Při jejím mazání, označit zprávu jako přečtenou
+ Kategorie upozorňování
+ Nastavit upozornění na nové zprávy
+ Nastavit upozorňování na chyby a stavy
+ Vždy zobrazovat obrázky
+ Ne
+ Jen od kontaktů
+ Od kohokoli
+ Odesílání zpráv
+ Citovat původní zprávu když odpovídám
+ Zahrnout původní zprávu v odpovědi.
+ Odpovědět za citovaným textem
+ Původní zprávu zobrazit nad textem odpovědi.
+ Odstranit podpis z citované odpovědi
+ Budou odstraněny podpisy z citovaných zpráv
+ Formát zprávy
+ Prostý text (odstraní obrázky a formátování)
+ HTML (zachová obrázky a formátování)
+ Automaticky
+ Vždy zobrazit kopie/skrytá
+ Potvrzení o přečtení
+ Vždy požadovat potvrzení o přečtení
+ Styl citace odpovědi
+ Prefix (jako Gmail)
+ Záhlaví (jako Outlook)
+ Nahrát odeslané zprávy
+ Po odeslání nahrát zprávy do složky Odesláno
+ Hlavní nastavení
+ Čtení zprávy
+ Stahování pošty
+ Složky
+ Předpona citovaného textu
+ Šifrování mezi odesilatelem a příjemcem
+ Zapnout podporu OpenPGP
+ Vybrat OpenPGP aplikaci
+ Nastavit klíč pro šifrování mezi odesilatelem a příjemcem
+ Není nastavená žádná OpenPGP aplikace
+ Připojeno k %s
+ Nastavování…
+ Ukládat veškeré koncepty šifrovaně
+ Všechny koncepty budou ukládány šifrovaně
+ Šifrovat koncepty pouze pokud je zapnuté šifrování
+ Frekvence dotazování složky
+ Barva účtu
+ Vyberte barvu pro tento účet, používanou v seznamech složek a zpráv
+ Žádná barva
+ Barva oznamovací LED
+ Barva, kterou má telefon blikat pro tento účet
+ Velikost místního adresáře
+ Stahovat zprávy až do
+ 1 KiB
+ 2 KiB
+ 4 KiB
+ 8 KiB
+ 16 KiB
+ 32 KiB
+ 64 KiB
+ 128 KiB
+ 256 KiB
+ 512 KiB
+ 1 MiB
+ 2 MiB
+ 5 MiB
+ 10 MiB
+ jakékoli velikosti (bez omezení)
+ Synchronizovat odeslané zprávy
+ kdykoliv (bez omezení)
+ dnešní
+ za poslední 2 dny
+ za poslední 3 dny
+ za poslední týden
+ za poslední 2 týdny
+ za poslední 3 týdny
+ za poslední měsíc
+ za poslední 2 měsíce
+ za poslední 3 měsíce
+ za posledních 6 měsíců
+ za poslední rok
+ Zobrazované složky
+ Všechny
+ Jen složky 1. třídy
+ Složky 1. a 2. třídy
+ Všechny vyjma složek 2. třídy
+ Složky řízené dotazováním
+ Všechny
+ Jen složky 1. třídy
+ Složky 1. a 2. třídy
+ Všechny vyjma složek 2. třídy
+ Žádné
+ Složky řízené serverem (PUSH)
+ Všechny
+ Jen složky 1. třídy
+ Složky 1. a 2. třídy
+ Všechny vyjma složek 2. třídy
+ Žádné
+ Cílové složky pro přesun/kopii
+ Všechny
+ Jen složky 1. třídy
+ Složky 1. a 2. třídy
+ Všechny vyjma složek 2. třídy
+ Synchronizace mazání serveru
+ Odstranit zprávy, když je smaže server
+ Chybí OpenPGP aplikace – byla odinstalována?
+ Nastavení složky
+ Zobrazit v nejvyšší skupině
+ Zobrazit blízko špičky seznamu složek
+ Třída zobrazování složky
+ Žádná třída
+ 1. třída
+ 2. třída
+ Třída fondu složky
+ Žádné
+ 1. třída
+ 2. třída
+ Stejná jako třída zobrazení
+ Třída složky rozšíření PUSH
+ Žádná třída
+ 1. třída
+ 2. třída
+ Stejné jako třída fondu
+ Třída oznámení složky
+ Žádná třída
+ 1. třída
+ 2. třída
+ Stejná jako třída PUSH
+ Vyčistit místní zprávy
+ Server příchozí pošty
+ Konfigurace serveru příchozí pošty
+ Server odchozí pošty
+ Konfigurace serveru odchozí pošty (SMTP)
+ Název účtu
+ Vaše jméno
+ Oznámení
+ Vibrovat
+ Vibrovat při příchodu zpráv
+ Vzory vibrování
+ výchozí
+ vzorek 1
+ vzorek 2
+ vzorek 3
+ vzorek 4
+ vzorek 5
+ Opakovat vibrace
+ Zvuk při nové poště
+ Blikání LED
+ Blikat LED, když přijde pošta
+ Možnosti tvorby nových zpráv
+ Výchozí položky nové zprávy
+ Nastavit výchozí hodnoty Odesílatele, Skryté a podpisu
+ Správa identit
+ Nastavte alternativní adresy \'Od\' a podpisy
+ Správa identit
+ Spravovat identitu
+ Upravit identitu
+ Uložit
+ Nová identita
+ Kopii všech zpráv na adresu
+ Upravit
+ Posunout nahoru
+ Posunout dolů
+ Posunout do čela/nastavit jako výchozí
+ Odstranit
+ Popis identity
+ (Volitelné)
+ Vaše jméno
+ (Volitelné)
+ Emailová adresa
+ (Vyžadováno)
+ Adresa pro odpověď
+ (Volitelné)
+ Podpis
+ (Volitelné)
+ Používat podpis
+ Podpis
+ Výchozí identita
+ Vybrat identitu
+ Odeslat jako
+ Nelze odebrat jedinou zbývající identitu
+ Nelze použít identitu bez e-mailové adresy
+ Nejstarší zprávy první
+ Nejnovější zprávy první
+ Předmět abecedně A-Z
+ Předmět abecedně Z-A
+ Odesílatel A-Z
+ Odesílatel Z-A
+ S \u2605 první
+ Bez \u2606 první
+ Nepřečtené první
+ Přečtené první
+ S přílohou první
+ Bez přílohy první
+ Třídit podle položky…
+ Datum
+ Příchodu
+ Předmět
+ Odesílatel
+ Hvězdička
+ Přečtená/Nepřečtená
+ Příloha
+ Odstranit účet
+ Nerozpoznaný certifikát
+ Přijmout klíč
+ Odmítnout klíč
+ Delete (nebo D) – Smazat\nR – Odpovědět\nA – Odpovědět všem\nC – Vytvořit\nF – Přeposlat\nM – Přesunout\nV - Archivovat\nY – Kopírovat\nZ – Označit (Ne)přečtené\nG – Hvězdička\nO – Uspořádat podle typu\nI – Uspořádat podle pořadí\nQ – Zpět ke složkám\nS – Označit/odznačit\nJ nebo P – Předešlá zpráva\nK nebo N – Další zpráva
+ Delete (nebo D) – Smazat\nC – Vytvořit\nM – Přesunout\nV – Archivovat\nY – Zkopírovat\nZ – Označit jako (ne)přečtené\nG – Označit hvězdičkou\nO – Typ řazení\nI – Pořadí řazení\nQ – Návrat na složky\nS – Označit / zrušit označení
+ Název složky obsahuje
+ Zobrazit složky…
+ Všechny složky
+ Složky 1. třídy
+ Složky 1. & 2. třídy
+ Skrýt složky 2. třídy
+ Umístění podpisu
+ Před citovanými textem
+ Za citovanými textem
+ Použít vzhled aplikace
+ Tmavé
+ Světlé
+ Použít systémové výchozí
+ Zobrazení
+ Globální
+ Ladění
+ Soukromí
+ Síť
+ Ovládání
+ Seznam účtů
+ Seznam zpráv
+ Zprávy
+ Vzhled
+ Vzhled náhledu zprávy
+ Vzhled psaní zprávy
+ Jazyk
+ Nenalezena žádná nastavení
+ Neměnný vzhled zpráv
+ Lze vybrat vzhled při prohlížení zprávy
+ Použít neměnný vzhled při prohlížení zprávy
+ Výchozí nastavení systému
+ Synchronizace na pozadí
+ Nikdy
+ Vždy
+ Když je zaškrtnutá „Aut. synchronizace“
+ Vybrat vše
+ Max. počet složek řízených PUSH
+ 5 složek
+ 10 složek
+ 25 složek
+ 50 složek
+ 100 složek
+ 250 složek
+ 500 složek
+ 1000 složek
+ Animace
+ Používat okázalé vizuální efekty
+ Navigace tlačítky hlasitosti
+ Zobrazení zpráv
+ Různá zobrazení seznamů
+ Ukázat sjednocený pohled na doručenou poštu
+ Zobrazit počet označených hvězdičkou
+ %s%s
+ - Nepřečtené
+ Všechny zprávy
+ Všechny zprávy v prohledávaných složkách
+ Integrovaná doručená pošta
+ Všechny zprávy v integrovaných složkách
+ Integrovat
+ Všechny zprávy jsou zobrazeny v Integrované doručené poště
+ Prohledávané složky
+ Všechny
+ Zobrazitelné
+ Žádné
+ Žádné
+ Automaticky (%s)
+ Velikost písma
+ Konfigurovat velikost písma
+ Seznam účtů
+ Název účtu
+ Popis účtu
+ Seznam složek
+ Název složky
+ Stav složky
+ Seznam zpráv
+ Předmět
+ Odesílatel
+ Datum
+ Náhled
+ Zpráva
+ Odesílatel
+ Příjemce (Komu)
+ Příjemce (Kopie)
+ Skrytá kopie
+ Další záhlaví
+ Předmět
+ Datum a čas
+ Tělo
+ %d%%
+ %1$s: %2$s
+ Psaní zprávy
+ Pole zadávaní textu
+ Standardní
+ Nejdrobnější
+ Drobný
+ Menší
+ Malý
+ Střední
+ Velký
+ Největší
+ Pro tuto akci nebyla nalezena žádná vhodná aplikace.
+ Odeslání se nezdařilo: %s
+ Uložit koncept zprávy?
+ Uložit nebo zahodit tuto zprávu?
+ Uložit nebo zahodit změny?
+ Zahodit zprávu?
+ Opravdu chcete tuto zprávu zahodit?
+ Vyberte text pro kopírování.
+ Vymazat zprávy uložené lokálně?
+ Toto ze složky odebere všechny lokálně uložené zprávy. Ze serveru nebudou vymazány žádné zprávy.
+ Vyčistit zprávy
+ Potvrzení mazání
+ Chcete smazat tuto zprávu?
+
+ Opravdu si přejete smazat tuto zprávu?
+ Opravdu si přejete smazat %1$d zprávy?
+ Opravdu si přejete smazat %1$d zpráv?
+ Opravdu si přejete smazat %1$d zpráv?
+
+ Ano
+ Ne
+ Potvrdit označení všech jako přečtené
+ Opravdu chcete označit všechny zprávy jako přečtené?
+ Potvrdit vyprázdnění koše
+ Opravdu chcete vyprázdnit složku Koš?
+ Ano
+ Ne
+ Potvrzení přesunu do nevyžádané pošty
+
+ Opravdu chcete přesunout tuto zprávy do nevyžádané pošty?
+ Opravdu chcete přesunout %1$d zprávy do nevyžádané pošty?
+ Opravdu chcete přesunout %1$d zpráv do nevyžádané pošty?
+ Opravdu chcete přesunout %1$d zpráv do nevyžádané pošty?
+
+ Ano
+ Ne
+ Stahuji přílohy
+ »
+ ›
+ Záloha
+ Různé
+ Exportovat nastavení
+ Export
+ Sdílet
+ Exportování nastavení…
+ Nastavení úspěšně exportována
+ Export nastavení se nezdařil
+ Importovat nastavení
+ Vybrat soubor
+ Import
+ Nastavení úspěšně importována
+ Zadejte hesla
+ Nepodařilo se importovat nastavení
+ Nepodařilo se číst soubor s nastaveními
+ Nepodařilo se naimportovat některá nastavení
+ Úspěšně naimportováno
+ Vyžadováno hesl
+ Nenaimportováno
+ Nezdar při importu
+ Později
+ Importovat nastavení
+ Importování nastavení…
+
+ Abyste mohli používat účet „%s“, je třeba zadat heslo k serveru.
+ Abyste mohli používat účty „%s“, je třeba zadat heslo k serveru.
+ Abyste mohli používat účty „%s“, je třeba zadat heslo k serveru.
+ Abyste mohli používat účty „%s“, je třeba zadat heslo k serveru.
+
+ Heslo pro server pro příchozí
+ Heslo pro server pro odchozí
+ Použít stejné heslo jako pro server pro odchozí
+ Název serveru: %s
+ Zobrazit počet nepřečtených pro…
+ Účet
+ Účet pro který má být zobrazen počet nepřečtených
+ Sjednocená doručená pošta
+ Počet ve složce
+ Zobrazit počet nepřečtených pouze pro jedinou složku
+ Složka
+ Složka pro kterou má být zobrazen počet nepřečtených
+ Hotovo
+ %1$s – %2$s
+ Nebyl vybrán žádný účet
+ Nebyla vybrána žádná složka
+ Žádný text
+ Otevřít odkaz
+ Sdílet odkaz
+ Zkopírovat odkaz do schránky
+ Odkaz
+ Zkopírovat text odkazu do schránky
+ Text odkazu
+ Obrázek
+ Zobrazit obrázek
+ Uložit obrázek
+ Stáhnout obrázek
+ Zkopírovat adresu obrázku do schránky
+ Adresa obrázku
+ Volat číslo
+ Uložit do kontaktů
+ Zkopírovat číslo do schránky
+ Telefonní číslo
+ Odeslat zprávu
+ Uložit do kontaktů
+ Zkopírovat e-mailovou adresu do schránky
+ E-mailová adresa
+ Vše
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Limit počtu výsledků prohledávání serveru
+ Odeslání dotazu na server
+
+ Načítání %d výsledku
+ Načítání %d výsledků
+ Načítání %d výsledků
+ Načítání %d výsledků
+
+
+ Stahování %1$d z %2$d výsledků
+ Stahování %1$d z %2$d výsledků
+ Stahování %1$d z %2$d výsledků
+ Stahování %1$d z %2$d výsledků
+
+ Vzdálené vyhledávání se nezdařilo
+ Hledání
+ Povolit vyhledávání na serveru
+ Hledat zprávy na serveru navíc k těm v zařízení
+ Hledat zprávy na serveru
+ Vzdálené vyhledávání není k dispozici bez připojení k síti.
+ Ztmavit zprávy po přečtení
+ Prečtená zpráva bude mít jiné pozadí.
+ Zobrazit vlákna
+ Sjednotit zprávy patřící ke stejnému vláknu
+ Aktualizace databází
+ Aktualizuji databáze…
+ Přechod na novější verzi databáze účtu „%s“
+ Zobraz rozdělení obrazovky
+ Vždy
+ Nikdy
+ Při orientaci na šířku
+ Prosím zvolte zprávu vlevo
+ Zobraz obrázky u kontaktů
+ V seznamu zpráv, zobrazovat u kontaktů jejich fotky
+ Označ vše jako přečtené
+ Obarvit obrázky kontaktů
+ Obarví chybějící obrázky u kontaktů
+ Zobrazení funkcí zpráv
+ Zobrazí vybrané funkce v dolním menu u zpráv
+ Nahrávám přílohu…
+ Odesílám zprávu
+ Ukládám koncept
+ Stahuji přílohu…
+ Nelze ověřit. Server neuvádí možnost SASL EXTERNAL. To by mohlo být kvůli problému s klientským certifikátem (vypršel, neznámá certifikační autorita), nebo nějaký jiný problém konfigurace.
+
+ Použít klientský certifikát
+ Žádný klientský certifikát
+ Odstranit výběr klientského certifikátu
+ Chyba při získání klientského certifikátu pro alias \"%s\"
+ Pokročilé možnosti
+ Klientský certifikát \"%1$s\" vypršel nebo ještě není platný (%2$s)
+
+ *Zašifrováno*
+ Přidat z kontaktů
+ Kopie
+ Skrytá kopie
+ Komu
+ Odesílatel
+ Odpovědět komu
+ <Neznámý příjemce>
+ <Neznámý odesilatel>
+ Domov
+ Práce
+ Ostatní
+ Mobilní
+ Tento účet nemá nastavenou žádnou složku pro koncepty!
+ Pro tento účet není nastaven žádný klíč! Zkontrolujte nastavení.
+ Poskytovatel šifrování používá neslučitelnou verzi. Zkontrolujte svá nastavení!
+ Nelze se spojit se službou šifrování, zkontrolujte své nastavení nebo ťukněte na ikonu šifrování pro nový pokus.
+ Nepodařilo se inicializovat šifrování mezi odesílatelem a příjemcem – zkontrolujte svá nastavení
+ PGP/INLINE mód nepodporuje přílohy!
+ Povolit PGP/INLINE
+ Zakázat PGP/INLINE
+ Povolit PGP podpisový mód
+ Zakázat jen PGP podpis
+ PGP/INLINE mód
+ Email je odeslán v PGP/INLINE formátu.\nToto má být použito pouze pro kompatibilitu:
+ Některé klientské aplikace podporují pouze tento formát
+ Může dojít k poškození podpisu v průběhu přenosu
+ Přílohy nejsou podporovány
+ Rozumím!
+ Vypnout
+ Ponechat zapnuté
+ Rozumím!
+ Vypnout
+ Ponechat zapnuté
+ Pouze PGP podpisový režim
+ V tomto módu bude váš PGP klíč použit k vytvoření kryptografického podpisu nešifrovaného emailu.
+ Toto nezašifruje text emailu, ale poskytne ověření, že byl email podepsán vaším klíčem.
+ Může dojít k poškození podpisu při odeslání emailu na mailing list.
+ Podpisy mohou být v některých klientských aplikacích zobrazeny jako soubor přílohy „signature.asc“.
+ Šifrované zprávy vždy obsahují podpis.
+ Holý text
+ podpis autora obsahoval chybu
+ podpis bude možné zpracovat až po úplném stažení zprávy
+ obsahuje nepodporovaný podpis
+ Zpráva je zašifrována, ale v nepodporovaném formátu.
+ Zpráva je zašifrována, ale dešifrování bylo zrušeno.
+ Holý text podepsaný přímo autorem
+ od ověřeného podepisujícího
+ Podepsaný čitelný text
+ ale klíč neodpovídá autorovi
+ ale platnost podpisového klíče autora skončila
+ ale platnost autorova klíče byla odvolána
+ ale klíč autora není považován za bezpečný
+ podepsáno neznámým klíčem
+ Šifrováno
+ ale vyskytla se chyba při rozšifrovávání
+ pro rozšifrování je třeba zprávu napřed celou stáhnout
+ ale není nastavena žádná šifrovací aplikace
+ Šifrováno
+ není podepsáno přímo autorem
+ Podepsáno přímo autorem
+ od ověřeného odesilatele
+ Šifrováno
+ podepsáno neznámým klíčem
+ klíč neodpovídá autorovi
+ ale platnost podpisového klíče autora skončila
+ ale platnost autorova klíče byla odvolána
+ ale klíč autora není považován za bezpečný
+ ale podepsaná data mají chyby
+ ale šifra není považovaná za bezpečnou
+ OK
+ Hledat klíč
+ Zobrazit podepisujícího
+ Zobrazit odesilatele
+ Podrobnosti
+ Odemknout
+ Tato část nebyla zašifrovaná a nemusí proto být bezpečná.
+ Nechráněná příloha
+ Načítání…
+ Rozšifrování zrušeno.
+ Opakovat
+ Zašifrovaná zpráva musí být stažena pro dešifrování.
+ Chyba při rozšifrovávání e-mailu
+ Speciální znaky nejsou momentálně podporovány!
+ Chyba zpracovávání adresy!
+ Skrýt nezašifrované podpisy
+ Budou zobrazeny pouze zašifrované podpisy
+ Budou zobrazeny všechny podpisy
+ Šifrování nedostupné v podpisovém módu!
+ Nepodepsaný text
+ Varování o ukončení podpory APG
+ APG už není udržováno!
+ Kvůli tomuto jsme odstranili podporu pro APG z K-9 Mailu.
+ Vývoj skončil na začátku roku 2014
+ Obsahuje neopravené bezpečnostní chyby
+ Kliknutím sem se můžete dozvědět více.
+ Rozumím!
+ APG
+ Tento e-mail je šifrovaný
+ Tento email byl zašifrovaný pomocí OpenPGP.\nAbyste si ho mohl/a přečíst, potřebujete si nainstalovat a nakonfigurovat kompatibilní OpenPGP aplikaci.
+ Přejít do nastavení
+ Seznam zpráv K-9
+ Načítání zpráv…
+ Nepodařilo se načíst seznam složek
+ Chyba při získávání stavu příjemce z poskytovatele OpenPGP!
+ Šifrování není možné
+ Někteří ze zvolených příjemců nepodporují tuto funkci!
+ Zapnout šifrování
+ Vypnout šifrování
+ Šifrování zpráv zajistí, že budou čitelné pouze pro příjemce a nikoho jiného.
+ Šifrování se zobrazí pouze tehdy, pokud je podporováno všemi příjemci a je třeba, aby vám už dříve poslali nějaký e-mail.
+ Přepněte šifrování kliknutím na tuto ikonu.
+ Rozumím
+ Zpět
+ Vypnout šifrování
+ Šifrování OpenGPG
+ Vzájemný režim automatického šifrování
+ Vzájemný režim automatického šifrování
+ Normálně budou zprávy šifrovány volitelně, nebo při odpovědi na šifrovanou zprávu.
+ Pokud jak odesilatel, tak příjemce zapnou vzájemný režim, šifrování bude ve výchozím stavu zapnuté.
+ Více informací je možné zjistit kliknutím sem.
+ Hlavní nastavení
+ Není nainstalovaná žádná OpenPGP aplikace
+ Nainstalovat
+ K-9 Mail pro šifrování mezi odesilatelem a příjemcem vyžaduje OpenKeychain
+ Zašifrovaná zpráva
+ Šifrovat předměty e-mailů
+ Nemusí být podporováno některými příjemci
+ Vnitřní chyba: neplatný účet!
+ Chyba při připojování k %s!
+ Poslat Autocrypt nastavovací zprávu
+ Zabezpečeně sdílet nastavení s ostatními zařízeními
+ Autocrypt nastavovací zpráva
+ Autocrypt nastavovací zpráva zabezpečeně sdílí vaše nastavení s ostatními zařízeními.
+ Poslat nastavovací zprávu
+ Tato zpráva bude odeslána na vaši adresu:
+ Vytváření nastavovací zprávy…
+ Odesílání zprávy na:
+ Pro dokončení otevřete zprávu na svém dalším zařízení a zadejte nastavovací kód.
+ Zobrazit nastavovací kód
+ Autocrypt nastavovací správa
+ Tato zpráva obsahuje všechny údaje pro zabezpečené přenesení vašich nastavení Autocrypt společně s tajným klíčem z původního zařízení.
Pro nastavení nového zařízení pro Autocrypt, postupujte podle pokynů které by se měly zobrazit na novém zařízení.
@@ -1046,5 +1050,4 @@ Tuto zprávu si můžete ponechat a použít jí jako zálohu svého tajného kl
Nastavit upozorňováníPokud nepotřebujete okamžitá upozornění na nové zprávy, měli byste Push vypnout a použít pravidelné dotazování se. To kontroluje nové e-maily v pravidelném intervalu a nepotřebuje upozornění.Vypnout Push
-
diff --git a/app/ui/legacy/src/main/res/values-cy/strings.xml b/app/ui/legacy/src/main/res/values-cy/strings.xml
index 6b10f06289e1f008ef9d6412193e8d575e91c254..fba2619626607d1e046ca43f4b436a846b46cb1a 100644
--- a/app/ui/legacy/src/main/res/values-cy/strings.xml
+++ b/app/ui/legacy/src/main/res/values-cy/strings.xml
@@ -238,10 +238,6 @@
Remove Mail User-Agent from mail headersCuddio cylchfa amserDefnyddio amser UTC yn hytrach na chylchfa amser lleol (e.e. GMT, BST) ym mhenynnau negeseuon ac atebion
- Cuddio\'r pwnc mewn hysbysiadau
- Byth
- Pan mae\'r ddyfais ar glo
- O hydDangos y botwm \'Dileu\'BythPan fydd hysbysiad un neges
@@ -249,7 +245,6 @@
Hysbysiadau ar y Sgrin CloiDim hysbysiadau ar y sgrin cloiEnw\'r ap
- Nifer o negeseuon heb eu darllenAnfonwyr a nifer o negeseuonYr un fath a phan nad yw\'r sgrin ar gloiAmser Distawrwydd
@@ -262,6 +257,7 @@
Cyfeiriad e-bostCyfrinairDangos cyfrinair
+
Gosod â llawYn nôl manylion y cyfrif\u2026
@@ -303,8 +299,6 @@
SymudolWi-FiArall
- Storfa allanol (cerdyn SD)
- Storfa mewnol arferolDileu negeseuon sydd wedi eu dileu o\'r gweinyddYn sythWrth wirio am negeseuon
@@ -380,8 +374,6 @@
ParhauUwchGosodiadau cyfrif
- Cyfrif rhagosodedig
- Anfon negeseuon o\'r cyfrif hwn fel arferiadHysbysiadau negeseuon newyddFfolderi i hysbysu amdanyntPob un
@@ -401,8 +393,6 @@
Nodi neges fel ei bod wedi ei darllen wrth ei hagor i\'w darllen.Nodi wedi\'i darllen wrth dileuNodi neges wedi\'i darllen pan gaiff ei dileu
- Gosodiadau hysbysiadau
- Agor gosodiadau hysbysiadau\'r systemDangos delweddau pob amserNaGan gysyllteion
diff --git a/app/ui/legacy/src/main/res/values-da/strings.xml b/app/ui/legacy/src/main/res/values-da/strings.xml
index c502a0a263548cbbb121bbecf7192a5bfc9c08f2..868b072241bf58f1926265d00d6a7b6c84ca7a77 100644
--- a/app/ui/legacy/src/main/res/values-da/strings.xml
+++ b/app/ui/legacy/src/main/res/values-da/strings.xml
@@ -246,10 +246,6 @@
Remove Mail User-Agent from mail headersSkjul tidszoneBrug UTC som tidszone i mail headers og svar header
- Skjul emne i beskedbjælke
- Aldrig
- Når enhed er låst
- AltidVis \'Slet\' knapAldrigFor enkelt-meddelelsesbesked
@@ -257,7 +253,6 @@
Besked på låseskærmenIngen besked på låseskærmen Programnavn
- Antal ulæste meddelelserAntal mails og afsendereSamme som når skærmen er ulåstTidsrum med stilhed
@@ -270,6 +265,7 @@
Mail addressePasswordVis kodeord
+
Manuel opsætningHenter konto-information\u2026
@@ -311,8 +307,6 @@
Mobilt netværkWi-FiAndet
- Eksternt lager (SD kort)
- Almindelig internt lagerRyd slettede mailsUmiddelbart efter sletningI forbindelse med hentning af mails
@@ -388,8 +382,6 @@
FortsætAvanceretKonto opsætning
- Standard konto
- Send mail fra denne konto som standardVis besked når ny mail er modtagetPåmindelses mapperAlle
@@ -409,8 +401,6 @@
Marker som læst når meddelses åbnes for læsningMarker som læst ved sletningMarker en besked som læst når den bliver slettet
- Opsætning af notifikationer
- Åbn opsætning for notifikationerVis altid billederAldrigKun når afsender findes i Kontakter
diff --git a/app/ui/legacy/src/main/res/values-de/strings.xml b/app/ui/legacy/src/main/res/values-de/strings.xml
index ec51948ea3dbd428d2b3878d23f1eee238dd7777..1bc748f39c226ce5cf21403c74daabf2413c8b8b 100644
--- a/app/ui/legacy/src/main/res/values-de/strings.xml
+++ b/app/ui/legacy/src/main/res/values-de/strings.xml
@@ -1,4 +1,4 @@
-
+
@@ -26,12 +26,40 @@ Teile \u00a9 2006-%s Android Open Source Project.Zeige die neuesten Änderungen nach einem App-UpdateFinde heraus, was es Neues in diesem Release gibt
- Willkommen zu E-Mail
- Mail is the default mail client for /e/
+ Willkommen bei K-9 Mail
+
+K-9 Mail ist ein leistungsstarker, freier E-Mail-Client für Android.
+
+Seine verbesserten Funktionen beinhalten:
+
+
+
Push-Mail unter Verwendung von IMAP IDLE
+
Bessere Leistung
+
Nachrichtenneuordnung
+
E-Mail-Signaturen
+
Bcc-to-self
+
Ordnerabonnements
+
Synchronisation aller Ordner
+
Rücksendeadresskonfiguration
+
Tastaturkürzel
+
Bessere IMAP-Unterstützung
+
Speichern von Anhängen auf SD
+
Papierkorb leeren
+
Nachrichtensortierung
+
…und weitere
+
+
+Bitte beachten Sie, dass K-9 die meisten kostenlosen Hotmail-Konten nicht unterstützt und, wie viele andere E-Mail-Clients, einige Macken bei der Kommunikation mit Microsoft Exchange hat.
+
+Bitte senden Sie Fehlerberichte, Ideen für neue Funktionen und stellen Sie Fragen an
+https://github.com/k9mail/k-9/.
+
+Ten en cuenta que K-9 no funciona bien con la mayor parte de las cuentas gratuitas de Hotmail, y (como tantos otros clientes de correo) puede tener alguna dificultad al comunicarse con servidores de Microsoft Exchange.
+
+ ]]>
+
+ -- \nEnviado desde mi dispositivo Android con K-9 Mail. Por favor, disculpa mi brevedad.
+
+ La cuenta \"%s\" será eliminada de K-9 Mail.
+
+ Autores
+ Información de la revisión
+ Leer correos
+ Permitir a esta aplicación leer los correos.
+ Borrar correos
+ Permitir a esta aplicación borrar los correos.
+ Acerca de K-9 Mail
+ Cuentas
+ Carpetas
+ Avanzado
+ Redactar
+ Responder
+ Responder a todos
+ Reenviar
+ Reenviar como adjunto
+ Elige una cuenta
+ Selecciona una carpeta
+ Mover a...
+ Copiar a...
+ Comprobando %s:%s%s
+ Recuperando cabeceras %s:%s%s
+ Enviando %s%s
+ Proc %s:%s%s
+ \u0020%d/%d
+ Sincronización desactivada
+ %d seleccionados
+ Siguiente
+ Anterior
+
+ Aceptar
+ Cancelar
+ Enviar
+ Volver a enviar
+ El asunto está vacío, haz clic de nuevo para enviarlo tal cual
+ Seleccionar
+ Deseleccionar
+ Responder
+ Responder a todos
+ Borrar
+ Archivar
+ Spam
+ Reenviar
+ Reenviar como adjunto
+ Editar como nuevo mensaje
+ Mover
+ Mover a Borradores
+ Enviar…
+ Archivar…
+ Terminado
+ Descartar
+ Guardar como borrador
+ Comprobar correo
+ Comprobar el correo en todas las cuentas
+ Enviar correo
+ Recargar lista de carpetas
+ Buscar carpeta
+ Añadir cuenta
+ Redactar
+ Buscar
+ Buscar en todas partes
+ Resultados de búsqueda
+ Ajustes
+ Administrar carpetas
+ Ajustes de la cuenta
+ Eliminar cuenta
+ Marcar como leído
+ Compartir
+ Seleccionar remitente
+ Destacar el mensaje
+ No marcar como destacado
+ Copiar
+ Mostrar cabeceras
+
+ Se ha copiado la dirección al portapapeles
+ Se han copiado las direcciones al portapapeles
+
+ Texto copiado en el portapapeles
+ Cambiar al tema oscuro
+ Cambiar al tema claro
+ Marcar como no leído
+ Confirmación de lectura
+ Se solicitará una confirmación de lectura
+ No se solicitará confirmación de lectura
+ Añadir adjunto
+ Vaciar papelera
+ Purgar
+ Acerca de
+ Ajustes
+
+ (Sin asunto)
+ Sin remitente
+ Cargando mensajes\u2026
+ Error de conexión
+ Mensaje no encontrado
+ Error al cargar el mensaje
+ Cargar %d más
+ %.1f GB
+ %.1f MB
+ %.1f kB
+ %d B
+ Se ha reducido el tamaño de la cuenta «%s» de %s a %s
+ Compactando cuenta \"%s\"
+ Correo nuevo
+
+ %d mensaje nuevo
+ %d mensajes nuevos
+
+ %d Sin leer (%s)
+ + %1$d más en %2$s
+ Responder
+ Marcar como leído
+ Marcar todo como leído
+ Borrar
+ Borrar todo
+ Archivo
+ Archivar todo
+ Spam
+ Error de certificado para %s
+ Comprueba los ajustes del servidor
+ Fallo de autenticación
+ Fallo de autenticación en %s. Actualiza y revisa los ajustes del servidor.
+ Comprobando correo: %s:%s
+ Comprobando correo
+ Enviando correo: %s
+ Enviando correo
+ :
+ Sincronización rápida («push»)
+ Necesaria para buscar nuevos mensajes en segundo plano.
+ Mensajes
+ Notificaciones relacionadas con los mensajes.
+ Varios
+ Otras notificaciones, como errores y otros mensajes.
+ Bandeja de entrada
+ Bandeja de salida
+ Borradores
+ Papelera
+ Enviados
+ Error al enviar algunos mensajes
+ Versión
+ Habilitar registro de depuración
+ Registrar el estado del programa con información adicional para diagnosticar posibles problemas
+ Incluir información sensible
+ Incluir información privada (como contraseñas) en texto plano en el registro de depuración
+ Exportar registros de depuración
+ Se han exportado correctamente. Ten en cuenta que los registros pueden contener datos privados; así que ten cuidado y asegúrate de que te fias de las personas a las que se los mandas.
+ No se han podido exportar los registros.
+ Cargar más correos
+ Para:%s
+ Asunto
+ Texto del mensaje
+ Firma
+ -------- Mensaje original --------
+ Asunto:
+ Enviado:
+ De:
+ Para:
+ Cc:
+ %s escribió:
+ El %1$s, %2$s escribió:
+ El mensaje necesita algún destinatario.
+ El campo de destinatario está incompleto.
+ No se encontró la dirección de correo electrónico de este contacto.
+ Algunos adjuntos no pueden reenviarse porque no se han descargado.
+ El mensaje no puede ser reenviado porque algunos adjuntos no se han descargado.
+ Incluir mensaje original
+ No incluir el mensaje original
+ Editar el mensaje original
+ Eliminar adjunto
+ De: %s <%s>
+ Para:
+ Cc:
+ Cco:
+ Abrir
+ Guardar
+ No se puede guardar el adjunto.
+ Mostrar imágenes
+ Imposible encontrar visor de %s.
+ Descargar mensaje completo
+ No se puede mostrar el mensaje
+ vía %1$s
+
+ Se han descargado todas las cabeceras, pero no hay cabeceras adicionales que mostrar.
+ Se ha producido un error al descargar las cabeceras desde la base de datos o el servidor.
+ Más de este remitente
+ Desde %s
+ Depurar / Limpiar el cuerpo del mensaje
+ Mensaje descartado
+ Mensaje guardado como borrador
+ Mostrar mensajes destacados
+ Las estrellas indican mensajes destacados
+ Previsualizar líneas
+ Mostrar nombre asociado
+ Mostrar nombre asociado en vez de dirección de correo
+ Remitente encima de Asunto
+ Mostrar nombre del remitente sobre la línea de Asunto, en vez de por debajo
+ Mostrar nombres de contactos
+ Utilizar nombre de destinatario desde Contactos cuando esté disponible
+ Colorear contactos
+ Colorear nombres en la lista de contactos
+ Tipos de letra de ancho fijo
+ Utilizar tipos de letra de ancho fijo al mostrar mensajes en formato texto
+ Auto-ajustar los mensajes
+ Encoger los mensajes para que quepan en la pantalla
+ Volver a la lista después de borrar
+ Volver a la lista después de borrar un mensaje
+ Mostrar siguiente mensaje después de borrar
+ Mostrar de manera predeterminada el siguiente mensaje después de borrar
+ Confirmar acciones
+ Mostrar un diálogo cuando se realice una de estas acciones
+ Borrar
+ Borrar destacados (sólo en vista de mensajes)
+ Spam
+ Descartar mensaje
+ Marcar todos los mensajes como leídos
+ Borrar (de notificaciones)
+ Ocultar cliente de correo
+ Eliminar la marca con el «agente de usuario» de K-9 de las cabeceras del mensaje, el destinatario no verá qué programa de correo usas
+ Ocultar zona horaria
+ Usar UTC («tiempo universal coordinado») en lugar de la zona horaria local en las cabeceras de mensaje y cabeceras de respuesta
+ Mostrar el botón «Borrar»
+ Nunca
+ Para notificaciones de un mensaje
+ Siempre
+ Ver notificaciones al bloquear la pantalla
+ No mostrar notificaciones al bloquear
+ Nombre de la aplicación
+ Número de mensajes nuevos
+ Cuenta de mensajes y remitentes
+ Mismo comportamiento que al desbloquear
+ Horario de descanso
+ Desactivar y silenciar los sonidos, alertas y luces de notificación por la noche
+ Desactivar notificaciones
+ Desactivar completamente cualquier notificación durante el tiempo de descanso
+ El horario de descanso comienza
+ El horario de descanso termina
+ Configurar nueva cuenta
+ Dirección de correo
+ Contraseña
+ Mostrar la contraseña
+
+ Para ver tu contraseña, activa la pantalla de bloqueo en tu dispositivo.
+ Verifica tu identidad
+ Desbloquea para ver tu contraseña
+ Configuración manual
+
+ Recuperando información de cuenta\u2026
+ Comprobando configuración del servidor de entrada\u2026
+ Comprobando configuración del servidor de salida\u2026
+ Autentificando\u2026
+ Obteniendo configuración de la cuenta\u2026
+ Cancelando\u2026
+ ¡Ya casi estás!
+ Elige un nombre para esta cuenta (opcional):
+ Pon tu nombre (aparecerá en los mensajes que envíes):
+ Tipo de cuenta
+ ¿Qué tipo de cuenta es?
+ POP3
+ IMAP
+ Contraseña normal
+ Contraseña, transmitida de manera no segura
+ Contraseña cifrada
+ Certificado de cliente
+ Configuración del servidor de entrada
+ Usuario
+ Contraseña
+ Certificado de cliente
+ Servidor POP3
+ Servidor IMAP
+ Servidor WebDAV (Exchange)
+ Puerto
+ Tipo de seguridad
+ Tipo de autentificación
+ Ninguna
+ SSL/TLS
+ STARTTLS
+ La opción «%1$s = %2$s» no es compatible con «%3$s = %4$s»
+ Cuando borre un mensaje
+ No borrar del servidor
+ Borrar del servidor
+ Marcar como leído en servidor
+ Utilizar compresión en la red:
+ Móvil
+ Wi-Fi
+ Otras
+ Eliminar mensajes borrados en el servidor
+ Inmediatamente
+ Durante comprobación
+ Sólo manualmente
+ Autodetectar nombre IMAP
+ Prefijo de la dirección IMAP
+ Carpeta Borradores
+ Carpeta Enviados
+ Carpeta Papelera
+ Carpeta Archivados
+ Carpeta Spam
+ Ver sólo carpetas suscritas
+ Autoexpandir carpeta
+ Dirección WebDAV (Exchange)
+ Opcional
+ Dirección de autentificación
+ Opcional
+ Alias del buzón
+ Opcional
+ Configuración de correo saliente
+ Servidor SMTP
+ Puerto
+ Tipo de Seguridad
+ Requiere autentificación.
+ Usuario
+ Contraseña
+ Tipo de autentificación
+ La opción «%1$s = %2$s» no es compatible con «%3$s = %4$s»
+ Configuración incorrecta: %s
+ Opciones de cuenta
+ Compactar
+ Frecuencia de comprobación de correo nuevo
+ Nunca
+ Cada 15 minutos
+ Cada 30 minutos
+ Cada hora
+ Cada 2 horas
+ Cada 3 horas
+ Cada 6 horas
+ Cada 12 horas
+ Cada 24 horas
+ Activar comprobaciones rápidas «push» en la cuenta
+ Si su servidor lo permite los mensajes nuevos aparecerán de forma instantánea. Dependiendo del dispositivo esto puede mejorar o empeorar bastante el rendimiento.
+ Renovar o retomar conexión de red IDLE
+ Cada 2 minutos
+ Cada 3 minutos
+ Cada 6 minutos
+ Cada 12 minutos
+ Cada 24 minutos
+ Cada 36 minutos
+ Cada 48 minutos
+ Cada 60 minutos
+ Avisarme cuando lleguen nuevos mensajes
+ Avisarme cuando se esté comprobando el correo
+ Número de mensajes a mostrar
+ 10 mensajes
+ 25 mensajes
+ 50 mensajes
+ 100 mensajes
+ 250 mensajes
+ 500 mensajes
+ 1000 mensajes
+ 2500 mensajes
+ 5000 mensajes
+ 10000 mensajes
+ Todos los mensajes
+ No se puede copiar/mover un mensaje que no esté sincronizado con el servidor
+ No se ha podido terminar la configuración
+ Usuario o contraseña incorrectos.\n(%s)
+ El servidor ha enviado un certificado SSL incorrecto. Esto puede deberse a un problema de configuración en el propio servidor, o bien porque alguien está intentando interceptar tus comunicaciones o atacar el servidor de correo. Si no estás seguro, pulsa en «Rechazar» y contacta con quien gestiona tu servidor de correo.\n\n(%s)
+ No se pudo conectar con el servidor.\n(%s)
+ Editar detalles
+ Continuar
+ Avanzado
+ Ajustes de la cuenta
+ Notificar mensajes nuevos
+ Carpetas de notificaciones
+ Todas
+ Sólo carpetas de 1ª clase
+ Carpetas de 1ª y 2ª clase
+ Todas excepto las carpetas de 2ª clase
+ Ninguna
+ Notificar sincronización
+ Tu dirección de correo
+ Avisar cuando llegue correo nuevo
+ Mostrar la búsqueda de correos nuevos en la barra de notificaciones
+ Incluir bandeja de salida
+ Mostrar notificaciones durante el envío de correo
+ Solamente contactos
+ Mostrar notificaciones solamente para mensajes de contactos conocidos
+ Ignorar mensajes de chat
+ No mostrar notificaciones para mensajes que formen parte de un chat a través de correo electrónico
+ Marcar mensaje como leído al abrirlo
+ Marcar mensaje como leído cuando se abre para verlo
+ Marcar como leído al borrar
+ Marcar el mensaje como leído cuando se borra
+ Categorías de notificaciones
+ Configura las notificaciones para mensajes nuevos
+ Configura las notificaciones de error y estado actual
+ Mostrar imágenes siempre
+ No
+ Sólo de mis contactos
+ De cualquiera
+ Envío de mensajes
+ Incluir mensaje original al responder
+ Al responder los mensajes, el mensaje original se incluirá en su respuesta.
+ Respuesta tras mensaje original
+ Al responder un mensaje, el mensaje original aparecerá por encima de la respuesta.
+ Eliminar firma del mensaje original
+ Al responder a los mensajes se eliminará la firma del mensaje original
+ Formato del mensaje
+ Texto simple (se quitan las imágenes y el formato)
+ HTML (se mantienen las imágenes y el formato)
+ Automático
+ Mostrar siempre Cc/Cco
+ Confirmación de lectura
+ Solicitar siempre confirmación de lectura
+ Estilo de respuesta
+ Prefijo (como Gmail)
+ Cabecera (como Outlook)
+ Subir mensajes enviados
+ Subir mensajes a la carpeta Enviados luego de enviarlos
+ Ajustes generales
+ Al leer el correo
+ Comprobación de correo
+ Carpetas
+ Prefijo de texto citado
+ Cifrado de extremo a extremo
+ Activar soporte para OpenPGP
+ Elegir aplicación OpenPGP
+ Configurar clave de extremo a extremo
+ Sin aplicación OpenPGP configurada
+ Conectado a %s
+ Configurando...
+ Almacenar todos los borradores cifrados
+ Todos los borradores se guardarán de forma segura
+ Cifrar borradores solamente si está disponible el cifrado
+ Frecuencia de comprobación
+ Color de la cuenta
+ Selecciona el color a utilizar en la carpeta y en la cuenta
+ Sin color
+ Color de aviso
+ Selecciona el color del LED para los avisos de esta cuenta
+ Tamaño carpeta local
+ Obtener mensajes de hasta
+ 1 KiB
+ 2 KiB
+ 4 KiB
+ 8 KiB
+ 16 KiB
+ 32 KiB
+ 64 KiB
+ 128 KiB
+ 256 KiB
+ 512 KiB
+ 1 MiB
+ 2 MiB
+ 5 MiB
+ 10 MiB
+ cualquier tamaño (sin límite)
+ Sincronizar desde
+ Sin fecha (sin límite)
+ hoy
+ los últimos 2 días
+ los últimos 3 días
+ la última semana
+ las últimas 2 semanas
+ las últimas 3 semanas
+ el último mes
+ los últimos 2 meses
+ los últimos 3 meses
+ los últimos 6 meses
+ el último año
+ Carpetas a mostrar
+ Todas
+ Sólo 1ª clase
+ 1ª y 2ª clase
+ Todas excepto las de 2ª clase
+ Comprobación de carpetas
+ Todas
+ Sólo 1ª clase
+ 1ª y 2ª clase
+ Todas excepto las de 2ª clase
+ Ninguna
+ Carpetas de comprobaciones «push»
+ Todas
+ Sólo 1ª clase
+ 1ª y 2ª clase
+ Todas excepto las de 2ª clase
+ Ninguna
+ Mover/copiar carpetas destino
+ Todas
+ Sólo 1ª clase
+ 1ª y 2ª clase
+ Todas excepto las de 2ª clase
+ Sincronizar con el borrado remoto
+ Eliminar los mensajes cuando se borren del servidor
+ Falta la aplicación OpenPGP, ¿se ha desinstalado?
+ Ajustes de carpetas
+ Mostrar al principio
+ Mostrar cerca del principio de la lista
+ Tipos de carpeta mostrados
+ Sin clase
+ 1ª clase
+ 2ª clase
+ Tipos de carpeta con sincronización lenta («poll»)
+ Ninguna
+ 1ª clase
+ 2ª clase
+ La misma que la de visualización
+ Tipos de carpeta con sincronización rápida («push»)
+ Sin clase
+ 1ª clase
+ 2ª clase
+ La misma que con sincronización lenta («poll»)
+ Clase de la carpeta de notificaciones
+ Sin clase
+ 1ª clase
+ 2ª clase
+ La misma que con sincronización rápida («push»)
+ Borrar mensajes locales
+ Servidor de entrada
+ Configurar servidor de entrada
+ Servidor de salida
+ Configurar servidor de salida (SMTP)
+ Nombre de la cuenta
+ Tu nombre
+ Notificaciones
+ Vibrar
+ Vibrar cuando llega un correo
+ Secuencia de vibración
+ Predeterminado
+ Secuencia 1
+ Secuencia 2
+ Secuencia 3
+ Secuencia 4
+ Secuencia 5
+ Repetir vibración
+ Sonido de nuevo correo
+ Parpadeo LED
+ Parpadear el LED cuando llega nuevo correo
+ Opciones de edición de mensaje
+ Campos predeterminados
+ Configurar «De», «Cco» y firma predeterminadas
+ Identidades
+ Configurar direcciones y firmas alternativas
+ Gestionar identidades
+ Gestionar identidad
+ Editar identidad
+ Guardar
+ Nueva identidad
+ Cco en todos los mensajes para
+ Editar
+ Subir
+ Bajar
+ Al principio / hacer predeterminado
+ Eliminar
+ Descripción identidad
+ (Opcional)
+ Tu nombre
+ (Opcional)
+ Dirección de correo
+ (Necesario)
+ Responder a
+ (Opcional)
+ Firma
+ (Opcional)
+ Utilizar firma
+ Firma
+ Identidad principal
+ Seleccionar identidad
+ Enviar como
+ No puedes eliminar tu única identidad
+ No puedes utilizar una identidad sin añadir una dirección de correo
+ Nuevos mensajes primero
+ Últimos mensajes primero
+ Asunto (alfabético)
+ Asunto (alfabético inverso)
+ Remitente alfabético
+ Remitente alfabético inverso
+ Destacados primero
+ Sin destacar primero
+ Sin leer primero
+ Leídos primero
+ Con adjuntos primero
+ Sin adjuntos primero
+ Ordenado por…
+ Fecha
+ Llegada
+ Asunto
+ Remitente
+ Destacar
+ Leído/No leído
+ Adjuntos
+ Eliminar cuenta
+ Certificado desconocido
+ Aceptar clave
+ Rechazar clave
+ Supr (o D) - Borrar\nR - Responder\nA - Responder a todos\nC - Redactar\nF - Reenviar\nM - Mover\nV - Archivar\nY - Copiar\nZ - Marcar como (no) leído\nG - Destacar\nO - Tipo de ordenación\nI - Invertir orden\nQ - Volver a las carpetas\nS - Des/marcar\nJ o P - Mensaje anterior\nK o N - Siguiente mensaje
+ Supr (o D) - Borrar\nC - Redactar\nM - Mover\nV - Archivar\nY - Copiar\nZ - Marcar como (no) leído\nG - Destacar\nO - Tipo de ordenación\nI - Invertir orden\nQ - Volver a las carpetas\nS - Des/marcar
+ El nombre de la carpeta contiene
+ Mostrar carpetas…
+ Ver todas las carpetas
+ Ver sólo carpetas de 1ª clase
+ Ver carpetas de 1ª y 2ª clase
+ Ver todas excepto las de 2ª clase
+ Posición de la firma
+ Antes del mensaje original
+ Después del mensaje original
+ Usar el tema de la aplicación
+ Oscuro
+ Claro
+ Usar predeterminado del sistema
+ Visualización
+ Global
+ Depuración
+ Privacidad
+ Red
+ Interacción
+ Lista de cuentas
+ Lista de mensajes
+ Mensajes
+ Tema
+ Tema de vista de mensaje
+ Tema de redacción
+ Idioma
+ No se han encontrado ajustes
+ Tema de mensaje fijo
+ Seleccionar el tema de vista de mensaje mientras se muestra el mensaje
+ Usar un tema de vista de mensaje fijo
+ Configurado en el sistema
+ Sincronizar en segundo plano
+ Nunca
+ Siempre
+ Cuando «sincronización automática» esté activo
+ Seleccionar todos
+ Número máximo de carpetas al hacer una comprobación rápida («push»)
+ 5 carpetas
+ 10 carpetas
+ 25 carpetas
+ 50 carpetas
+ 100 carpetas
+ 250 carpetas
+ 500 carpetas
+ 1000 carpetas
+ Animaciones
+ Utilizar animaciones
+ Navegación con teclas de volumen
+ Vista de mensaje
+ Listas de mensajes
+ Mostrar bandeja de entrada unificada
+ Mostrar número de mensajes destacados
+ %s%s
+ - No leído
+ Todos los mensajes
+ Mensajes en las carpetas de búsqueda
+ Entrada unificada
+ Todos los mensajes en la Entrada unificada
+ Unificar
+ Todos los mensajes se mostrarán en una bandeja unificada
+ Carpetas para buscar
+ Todas
+ Mostradas
+ Ninguna
+ Ninguna
+ Automático (%s)
+ Tamaño de letra
+ Configurar el tamaño de letra
+ Lista de cuentas
+ Nombre de la cuenta
+ Descripción de la cuenta
+ Lista de carpetas
+ Nombre de la carpeta
+ Estado de la carpeta
+ Lista de mensajes
+ Asunto
+ Remitente
+ Fecha
+ Previsualizar
+ Mensajes
+ Remitente
+ Para
+ Cc
+ Cco
+ Encabezados adicionales
+ Asunto
+ Hora y fecha
+ Cuerpo de mensaje
+ %d%%
+ %1$s: %2$s
+ Composición mensaje
+ Campos entrada texto
+ Predeterminado
+ La más pequeña
+ Muy pequeña
+ Más pequeña
+ Pequeña
+ Mediana
+ Grande
+ Muy grande
+ No existe ninguna aplicación con la que realizar esta acción.
+ No se pudo enviar: %s
+ ¿Guardar como borrador?
+ ¿Guardar o descartar este mensaje?
+ ¿Guardar o descartar cambios?
+ ¿Descartar mensaje?
+ ¿Seguro que quieres descartar este mensaje?
+ Selecciona el texto a copiar.
+ ¿Limpiar mensajes locales?
+ Esto borrará todos los mensajes locales de la carpeta. No se eliminará ningún mensaje en el servidor.
+ Limpiar mensajes
+ Confirmar borrado
+ ¿Seguro que quieres borrar este mensaje?
+
+ ¿Seguro que quieres borrar este mensaje?
+ ¿Seguro que quieres borrar %1$d mensajes?
+
+ Sí
+ No
+ Confirmar marcar todos como leídos
+ ¿Quieres marcar todos los mensajes como leídos?
+ Confirmar vaciado de papelera
+ ¿Quieres vaciar la papelera?
+ Sí
+ No
+ Mover a la carpeta de spam
+
+ ¿Seguro que quieres mover este mensaje a la carpeta de Spam?
+ ¿Seguro que quieres mover %1$d mensajes a la carpeta de Spam?
+
+ Sí
+ No
+ Descargando adjunto
+ »
+ ›
+ Respaldo
+ Varios
+ Exportar ajustes
+ Exportar
+ Compartir
+ Exportando ajustes…
+ Se han exportado correctamente los ajustes
+ La exportación de ajustes ha fallado
+ Importar ajustes
+ Seleccionar archivo
+ Importar
+ Los ajustes se han importado correctamente
+ Introduce tus contraseñas
+ La importación de ajustes ha fallado
+ Fallo al leer el archivo de ajustes
+ La importación de algunos ajustes ha fallado
+ Importado correctamente
+ Se necesita una contraseña
+ No importado
+ La importación ha fallado
+ Más tarde
+ Importar ajustes
+ Importando ajustes…
+
+ Para poder usar la cuenta \"%s\" es necesario proporcionar la contraseña del servidor.
+ Para poder usar la cuenta \"%s\" es necesario proporcionar las contraseñas del servidor.
+
+ Contraseña del servidor de correo entrante
+ Contraseña del servidor de correo saliente
+ Usar la misma contraseña para el servidor de correo saliente
+ Nombre del servidor: %s
+ Mostrar contador de «no leídos» para…
+ Cuenta
+ La cuenta para la que se debe visualizar la cantidad de «no leídos»
+ Entrada unificada
+ Cantidad de carpetas
+ Mostrar la cantidad de «no leídos» de una sola carpeta
+ Carpeta
+ La carpeta para la que se debe visualizar la cantidad de «no leídos»
+ Listo
+ %1$s - %2$s
+ No se ha seleccionado ninguna cuenta
+ No se ha seleccionado ninguna carpeta
+ Sin texto
+ Abrir enlace
+ Compartir enlace
+ Copiar enlace al portapapeles
+ Enlace
+ Copiar texto del enlace al portapapeles
+ Texto del enlace
+ Imagen
+ Ver imagen
+ Guardar imagen
+ Descargar imagen
+ Copiar URL de imagen al portapapeles
+ URL de la imagen
+ Llamar al número de teléfono
+ Guardar en contactos
+ Copiar número de teléfono al portapapeles
+ Número de teléfono
+ Enviar mensaje
+ Guardar en contactos
+ Copiar dirección de correo al portapapeles
+ Dirección de correo
+ Todos
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Limitar resultados en búsquedas en el servidor
+ Haciendo petición al servidor
+
+ Obteniendo %d elemento
+ Obteniendo %d elementos
+
+
+ Obteniendo elemento %1$d de %2$d
+ Obteniendo elemento %1$d de %2$d
+
+ Ha fallado la búsqueda remota
+ Buscar
+ Habilitar búsqueda en servidor
+ Buscar mensajes en servidor y en dispositivo
+ Buscar mensajes en servidor
+ No se puede buscar en remoto sin conexión de red.
+ Cambiar el color al leer
+ Un fondo diferente mostrará que el mensaje se ha leído
+ Vista agrupada por conversación
+ Contraer mensajes de la misma conversación
+ Actualizando bases de datos
+ Actualizando bases de datos…
+ Actualizando base de datos de la cuenta \"%s\"
+ Mostrar pantalla dividida
+ Siempre
+ Nunca
+ Cuando esté en orientación horizontal
+ Selecciona un mensaje en la parte izquierda
+ Mostrar imágenes de contactos
+ Mostrar imágenes de contactos en la lista de mensajes
+ Marcar todo como leído
+ Colorear las imágenes de contactos
+ Colorear las imágenes de contactos no existentes
+ Acciones de mensaje visibles
+ Mostrar las acciones seleccionadas en el menú de vista de mensaje
+ Cargando adjunto…
+ Enviando mensaje
+ Guardando borrador
+ Recuperando adjunto…
+ No ha sido posible autenticarse. El servidor no parece ser compatible con SASL EXTERNAL. Esto puede deberse a un problema con el certificado cliente (expirado o de autoridad certificadora desconocida) o algún otro problema de configuración.
+
+ Usar certificado de cliente
+ Sin certificado de cliente
+ Borrar la selección de certificado de cliente
+ Fallo al recuperar certificado de cliente para el alias «%s»
+ Opciones avanzadas
+ El certificado de cliente «%1$s» ha expirado o aún no es válido (%2$s)
+
+ *Cifrado*
+ Agregar desde los contactos
+ Cc
+ Cco
+ A
+ De
+ Responder a
+ <Destinatario desconocido>
+ <Remitente desconocido>
+ Casa
+ Trabajo
+ Otro
+ Móvil
+ Parece que no se ha configurado una carpeta de borradores para esta cuenta.
+ Parece que no hay ninguna clave configurada para esta cuenta, revisa los ajustes.
+ Parece que el proveedor de cifrado utiliza una versión incompatible, revisa los ajustes.
+ No se ha podido conectar con el proveedor de cifrado, revisa los ajustes o haz clic en el icono de cifrado para probar otra vez.
+ No se ha podido establecer el cifrado de extremo a extremo, revisa los ajustes.
+ El modo PGP/INLINE no soporta adjuntos.
+ Activar modo PGP/INLINE
+ Desactivar modo PGP/INLINE
+ Activar el modo de solo-firma PGP
+ Desactivar el modo de solo-firma PGP
+ Modo PGP/INLINE
+ El correo se va a enviar en formato PGP/INLINE.\nEsto solamente debe usarse por temas de compatibilidad:
+ Algunos clientes solamente soportan este formato
+ Las firmas pueden corromperse o perderse en el tránsito
+ No es posible adjuntar archivos
+ Vale, entendido
+ Desactivar
+ Mantener activado
+ Vale, entendido
+ Desactivar
+ Mantener activado
+ Modo de solo-firma PGP
+ En este modo la clave PGP se usará para crear una firma criptográfica en un correo no cifrado.
+ Esto no cifra el correo, pero permite verificar que fue enviado con esa clave.
+ Las firmas pueden estropearse o perderse al enviarse a listas de correo.
+ Algunos clientes de correo mostrarán las firmas como adjuntos «signature.asc».
+ Los mensajes cifrados siempre incluirán una firma.
+ Texto plano
+ la firma de extremo a extremo contiene un error
+ el mensaje debe descargarse completamente para verificar su firma
+ contiene una firma de extremo a extremo incompatible
+ El mensaje está cifrado, pero en un formato no soportado.
+ El mensaje está cifrado, pero se ha cancelado el descifrado.
+ Texto plano de extremo a extremo firmado
+ del firmante verificado
+ Texto plano firmado
+ pero la clave de extremo a extremo no coincide con el remitente
+ pero la clave de extremo a extremo esta expirada
+ pero la clave de extremo a extremo esta revocada
+ pero la clave de extremo a extremo es insegura
+ desde una clave de extremo a extremo desconocida
+ Cifrado
+ pero hubo un error de descifrado
+ debe descargarse completamente el mensaje para descifrarlo
+ pero no hay aplicación de cifrado instalada
+ Cifrado
+ pero no de extremo a extremo
+ Cifrado de extremo a extremo
+ del remitente verificado
+ Cifrado
+ desde una clave de extremo a extremo desconocida
+ pero la clave de extremo a extremo no coincide con el remitente
+ pero la clave de extremo a extremo esta expirada
+ pero la clave de extremo a extremo esta revocada
+ pero la clave de extremo a extremo es insegura
+ pero los datos de extremo a extremo tienen errores
+ pero el cifrado es inseguro
+ Aceptar
+ Buscar clave
+ Ver firmante
+ Ver remitente
+ Detalles
+ Desbloquear
+ Esta parte no está cifrada, y puede ser insegura.
+ Adjunto desprotegido
+ Cargando…
+ Se ha cancelado el descifrado.
+ Reintentar
+ El mensaje cifrado debe descargarse para descifrarlo.
+ Error descifrando el correo
+ ¡Los caracteres especiales aún no están soportados!
+ Hubo un error al analizar la dirección.
+ Ocultar firmas no cifradas
+ Sólo se mostrarán firmas cifradas
+ Se mostrarán todas las firmas
+ El cifrado no está disponible en el modo de solo-firma.
+ Texto sin firmar
+ Aviso sobre el desuso y obsolescencia de APG
+ APG está obsoleto y ya no recibe actualizaciones
+ Y por ello la funcionalidad APG se ha eliminado de K-9 Mail.
+ El desarrollo se detuvo a principios de 2014
+ Contiene problemas de seguridad sin arreglar
+ Puedes pulsar aquí para leer más sobre el tema (en inglés).
+ Vale, entendido
+ APG
+ Este correo está cifrado
+ Este correo ha sido cifrado con OpenPGP.\nPara leerlo es necesario instalar y configurar una aplicación compatible con OpenPGP.
+ Ir a los ajustes
+ Lista de mensajes de K-9
+ Cargando mensajes…
+ No se ha podido recuperar la lista de carpetas
+ Hubo un error al recuperar el estado del destinatario desde el proveedor de OpenPGP.
+ No es posible cifrar
+ Algunos de los remitentes marcados no entienden esta característica
+ Activar cifrado
+ Desactivar cifrado
+ El cifrado de los mensajes asegura que solo el destinatario final pueda leer el contenido del correo.
+ El cifrado sólo estará disponible si todos los destinatarios lo admiten, y deben de haberte enviado al menos un mensaje de correo electrónico de antemano.
+ Alternar cifrado al pulsar este icono.
+ Vale, entendido
+ Atrás
+ Desactivar cifrado
+ Cifrado de OpenPGP
+ Autocifrar el modo mutuo
+ Autocifrar el modo mutuo
+ Normalmente, los mensajes se cifran por elección o cuando se responde a un mensaje cifrado.
+ Si tanto el remitente como los destinatarios activan el modo mutuo, el cifrado se activará de forma predefinida.
+ Puedes pulsar aquí para leer más sobre el tema.
+ Ajustes generales
+ Sin aplicación OpenPGP instalada
+ Instalar
+ K-9 Mail necesita OpenKeychain para el cifrado de extremo a extremo.
+ Mensaje cifrado
+ Asunto del mensaje cifrado
+ Puede ser incompatible con algunos destinatarios
+ Error interno: la cuenta no existe.
+ Error al conectarse con %s
+ Enviar mensaje de configuración de Autocrypt
+ Compartir configuración punto-a-punto con otros dispositivos de forma segura
+ Mensaje de configuración Autocrypt
+ Un mensaje de configuración Autocrypt comparte de manera segura su configuración con otros dispositivos.
+ Enviar mensaje de configuración
+ El mensaje se enviará a esta dirección:
+ Generando mensaje de configuración...
+ Enviando mensaje a:
+ Para finalizar, abra el mensaje en su otro dispositivo e introduzca el código de configuración.
+ Mostrar código de configuración
+ Mensaje de configuración Autocrypt
+ Este mensaje contiene toda la información para transferir tus ajustes de Autocrypt junto con tu clave secreta de manera segura desde tu dispositivo original.
-Para configurar su nuevo dispositivo con Autocrypt, por favor siga las instrucciones que deberían presentarse en su nuevo dispositivo.
+Para configurar tu nuevo dispositivo con Autocrypt sigue las instrucciones que deberían presentarse en tu nuevo dispositivo.
-Puede mantener este mensaje y usarlo como copia de seguridad de su clave secreta. Si desea hacer esto, debería anotar la contraseña y guardarla de manera segura.
+Puedes guardar este mensaje y usarlo como copia de seguridad de tu clave secreta. Para ello deberías anotar la contraseña y guardarla de manera segura.
Ha ocurrido un error al enviar el mensaje, por favor verifique su conexión a internet y la configuración del servidor de salida.Encendido
diff --git a/app/ui/legacy/src/main/res/values-et/strings.xml b/app/ui/legacy/src/main/res/values-et/strings.xml
index d9459edc2e0803f2f04554f4cf5e2255f0741e0c..b513e6bc3df7cfdc11b338bcb74714bddd918a9b 100644
--- a/app/ui/legacy/src/main/res/values-et/strings.xml
+++ b/app/ui/legacy/src/main/res/values-et/strings.xml
@@ -13,10 +13,13 @@
Apache litsents, versioon 2.0Avatud lähtekoodiga projektVeebileht
+ Foorum huvilistele
+ FediverseTwitterTeegidLitsentsMuudatuste logi
+ Muudatuste logi laadimine ei õnnestunudVersioon %sRakenduse muudatusedPärast rakenduse uuendamist näita viimaseid muudatusi
@@ -45,6 +48,8 @@
Saada edasi manusenaVali kontoVali kaust
+ Teisalda…
+ Kopeeri…Kontrollib olekut %s:%s%sToob pealkirju %s:%s%sSaadab %s%s
@@ -78,6 +83,7 @@
LoobuSalvesta mustandinaKontrolli e-kirju
+ Kontrolli kirju kõikidel kontodelSaada kirjadVärskenda kaustade nimekirjaLeia kaust
@@ -241,10 +247,6 @@
Remove Mail User-Agent from mail headersPeida ajavööndKasuta UTCd kohaliku ajavööndi asemel meili päistes ja vastuse päises
- Peida teadetes teema
- Mitte kunagi
- Kui seade on lukustatud
- AlatiNäita \"Kustuta\" nuppuMitte kunagiÜhest kirjast teatamiseks
@@ -252,7 +254,7 @@
Lukustuskuva teatisedÜhtegi lukustuskuva teatistRakenduse nimi
- Lugemata kirjade arv
+ Uusi sõnumeidKirjade arv ja saatjadSama, kui ekraan lukustamataVaikne aeg
@@ -265,6 +267,7 @@
E-posti aadressSalasõnaNäita parooli
+
Käsitsi seadistamineKonto info hankimine\u2026
@@ -306,8 +309,6 @@
MobiilneWiFiMuu
- Välismälu (SD-kaart)
- Tavaline sisemäluEemalda kustutatud kirjad serveristKoheseltAndmete kontrollimisel
@@ -385,8 +386,6 @@
JätkaTäpsemaltKonto sätted
- Vaikimisi konto
- Saada e-kirjad vaikimisi sellelt kontoltUue sõnumi teatedTeadete kaustKõik
@@ -405,8 +404,10 @@
Pärast avamist märgi loetuksMärgi sõnum loetuks, kui see on vaatamiseks avatudPärast kustutamist märgi loetuks
- Teadete sätted
- Ava süsteemi teadete sätted
+ Kustutamisel märgi kiri loetuks
+ Teavituste kategooriad
+ Seadista uute sõnumite teavitusi
+ Seadista vigade ja olekute teavitusiNäita alati pilteEiKontaktidelt
@@ -782,7 +783,7 @@
Jaga linkiKopeeri link lõikelaualeLink
- Kopeeri lingi tekt lõikelauale
+ Kopeeri lingi tekst lõikelaualeLingi tekstPiltVaata pilti
@@ -878,6 +879,7 @@
Blokeeri PGP ainult-allkirjastaminePGP/INLINE režiiimMõned kliendid toetavad ainult seda vormingut
+ Allkirjad võivad serverite vahel saates katki minnaManused pole toetatudArusaadav!Blokeeri
@@ -917,6 +919,7 @@
Ava sättedMail Message ListSõnumite laadimine...
+ Kaustade loendi laadimine ebaõnnestusKrüpteerimine poe võimalikVõimalda krüpteerimineBlokeeri krüpteerimine
@@ -938,4 +941,7 @@
SulgeLuba juurdepääs kontaktidele
+ Lisateabe saamiseks klõpsi
+ Lisateave
+ Seadista teavitusi
diff --git a/app/ui/legacy/src/main/res/values-eu/strings.xml b/app/ui/legacy/src/main/res/values-eu/strings.xml
index c6642fb1ffc54cf7f12adb04251b6df584b7cefc..10268e1411e02aa7e1c9afef24ff03b940c25045 100644
--- a/app/ui/legacy/src/main/res/values-eu/strings.xml
+++ b/app/ui/legacy/src/main/res/values-eu/strings.xml
@@ -245,10 +245,6 @@
Remove Mail User-Agent from mail headersEzkutatu ordu-zonaErabili UTC tokiko ordu-zonaren ordez posta goiburuetan eta erantzunen goiburuan
- Ezkutatu gaia jakinarazpenetan
- Inoiz ez
- Gailua blokeatuta dagoenean
- BetiErakutsi \'Ezabatu\' botoiaInoiz ezMezu bakarreko jakinarazpenetarako
@@ -256,7 +252,6 @@
Jakinarazpenak Blokeatutako PantailanJakinarazpenik ez blokeatutako pantailanAplikazioaren izena
- Irakurri gabeko mezuen kopuruaMezu kopurua eta bidaltzaileakPantaila desblokeatuta dagoenean bezalaAlertarik gabeko aldia
@@ -269,6 +264,7 @@
Posta helbideaPasahitzaErakutsi pasahitza
+
Eskuzko konfigurazioaKontuaren informazioa berreskuratzen\u2026
@@ -310,8 +306,6 @@
MugikorraWi-FiBestelakoak
- Kanpoko biltegia (SD txartela)
- Ohiko barne biltegiratzeaEzabatu hemen ere zerbitzaritik ezabatutako mezuakBerehalaAtzitzean
@@ -387,8 +381,6 @@
JarraituAurreratuaKontu ezarpenak
- Kontu lehenetsia
- Bidali posta kontu honetatik era lehenetsianPosta berrien jakinarazpenakJakinarazpenen karpetaGuztiak
@@ -408,8 +400,6 @@
Markatu mezua irakurritako gisa ikusteko irekitzerakoanMarkatu irakurritako gisa ezabatzeanMarkatu mezua irakurritako gisa ikusteko ezabatzean
- Jakinarazpenen ezarpenak
- Ireki sistemako jakinarazpenen ezarpenakErakutsi beti IrudiakEzKontaktuetatik
diff --git a/app/ui/legacy/src/main/res/values-fa/strings.xml b/app/ui/legacy/src/main/res/values-fa/strings.xml
index 5ab7227953daa180a5e8bc5e676249eda3afdce6..a19b1730236c002559530f48d0dbc581bc6f3837 100644
--- a/app/ui/legacy/src/main/res/values-fa/strings.xml
+++ b/app/ui/legacy/src/main/res/values-fa/strings.xml
@@ -9,9 +9,21 @@
The K-9 Dog WalkersCopyright 2008-%s The K-9 Dog Walkers. Portions Copyright 2006-%s the Android Open Source Project.
+ کد منبعمجوز آپاچی، نسخهٔ ۲٫۰
+ پروژهٔ متنباز
+ وبگاه
+ انجمن کاربری
+ فِدیوِرس
+ توئیترکتابخانههامجوز
+ گزارش تغییرات
+ گزارش تغییرات بار نشد.
+ نسخهٔ %s
+ تازهها
+ هنگامی که برنامه روزآمد شد تغییرات تازه را نشان بده
+ از تازههای این نسخه باخبر شویدWelcome to MailMail is the default mail client for /e/
@@ -37,6 +49,8 @@
هدایت بهشکل پیوستانتخاب حسابانتخاب پوشه
+ انتقال به...
+ کپی به...سرکشی به %s:%s%sواکشی سرایندها %s:%s%sدر حال ارسال %s%s
@@ -62,13 +76,15 @@
هدایتهدایت بهشکل پیوستویرایش بهعنوان پیام جدید
- انتقال به
+ انتقال
+ انتقال به پیشنویسهاارسال…ساماندهی...انجام شددورانداختنذخیره در پیشنویسبهروزآوری رایانامهها
+ بررسی رایانامهها در تمامی حسابهاارسال پیامهابازآوری لیست پوشههایافتن پوشه
@@ -86,12 +102,13 @@
انتخاب فرستندهافزودن ستارهحذف ستاره
- کپی به
+ کپینمایش سرایندهانشانیها در بریدهدان کپی شدنشانیها در بریدهدان کپی شد
+ نوشتهٔ موضوع به بریدهدان کپی شدتغییر به پوستهٔ تیرهتغییر به پوستهٔ روشنخوانده نشد
@@ -142,6 +159,8 @@
ارسال رایانامه: %sارسال رایانامه:
+ همگامسازی (پیشرانی)
+ هنگام انتظار برای پیامهای تازه نشان داده میشودپیامهااعلانهای مربوط به پیامهامتفرقه
@@ -230,10 +249,6 @@
Remove Mail User-Agent from mail headersمنطقهٔ زمانی را مخفی کندر سرایند رایانامه و سرایند پاسخ بهجای زمان محلی از UTC استفاده کن
- پنهانکردن موضوع در اعلانها
- هرگز
- هنگامی که دستگاه قفل است
- همیشهنمایش دکمهٔ «حذف»هرگزبرای اعلان پیام تکی
@@ -241,7 +256,7 @@
اعلانهای صفحهٔ قفلدر صفحهٔ قفل اعلانی نباشدنام برنامه
- تعداد پیامهای نخوانده
+ تعداد پیامهای جدیدتعداد پیام و فرستندگانهمانند زمانی که صفحه قفل نیستزمان خاموشی
@@ -254,6 +269,10 @@
نشانی رایانامه گذرواژهنمایش گذرواژه
+
+ برای دیدن گذرواژهتان در این قسمت، قفل صفحه در این دستگاه را فعال کنید.
+ هویتتان را تایید کنید
+ برای دیدن گذرواژه، قفل را باز کنیدتنظیم دستیبازیابی اطلاعات حساب کاربری\u2026
@@ -295,8 +314,6 @@
دادهٔ همراهوایفایسایر
- حافظهٔ خارجی (کارت SD)
- حافظهٔ داخلی همیشگیپیامهای حذفشده را در کارساز پاک کنفوراًدر زمان سرکشی
@@ -372,8 +389,6 @@
ادامهپیشرفتهتنظیمات حساب
- حساب پیشفرض
- بهطور پیشفرض رایانامهها را با این حساب بفرستاعلانهای رایانامهٔ جدیدپوشههای دارای اعلانهمه
@@ -389,12 +404,15 @@
برای پیامهایی که فرستادم یک اعلان نمایش بدهفقط مخاطبانفقط برای پیام مخاطبانِ شناس، اعلان بده
+ نادیده گرفتن پیامهای گفتگو
+ اعلانها مرتبط با پیامهای متعلق به یک گفتگوی رایانامهای را نمایش ندهاگر باز شد نشان بزن که خواندمزمانی که یک پیام را باز کردید بهعنوان خوانده علامت بخوردهنگام حذف، نشان بزن که خواندمپیام حذفشده را نشان بزن که خواندهام
- تنظیمات اعلان
- بازکردن تنظیمات اعلان دستگاه
+ دستهبندیهای اعلان
+ اعلان برای پیامهای جدید را پیکربندی کنید
+ اعلانهای وضعیت و خطا را پیکربندی کنیدهمیشه عکسها را نشان بدهخیراز مخاطبان
@@ -510,6 +528,7 @@
بدون سطحسطح ۱سطح ۲
+ همانند سطح سرکشیسطح اعلان پوشهبدون سطحسطح ۱
@@ -645,6 +664,8 @@
جابهجایی با کلیدهای تنظیم صدادر نماهای پیامدر نماهای لیستی
+ نمایش صندوق یکپارچه
+ نمایش تعداد ستارهدارها%s%s- نخواندههمهٔ پیامها
@@ -697,6 +718,7 @@
ارسال ناموفق بود: %sپیام پیشنویس ذخیره شود؟پیام را نگه میدارید یا دور میاندازید؟
+ تغییرات حفظ شود یا دور ریخته شود؟پیام از بین برود؟آیا از دورانداختن این پیام مطمئن هستید؟متن را انتخاب کنید تا کپی شود.
@@ -775,6 +797,8 @@
اشتراکگذاری پیوندکپیکردن پیوند در بریدهدانپیوند
+ کپیکردن نوشتهٔ پیوند به بریدهدان
+ نوشتهٔ پیوندتصویردیدن تصویرذخیرهٔ تصویر
@@ -851,6 +875,9 @@
مخفیانه بهبهاز
+ پاسخ به
+ <گیرندهٔ ناشناس>
+ <فرستندهٔ ناشناس>خانهکارسایر
@@ -997,4 +1024,17 @@
اجازهٔ دسترسی به مخاطبان را بدهیدبرای پیشنهاد مخاطب و نمایش نام و عکس مخاطب، برنامه نیاز دارد به مخاطبان شما دسترسی داشته باشد.
+ هنگام بارکردن داده، خطایی رخ داد
+ مقداردهی اولیه...
+ در انتظار رایانامههای جدید
+ میخوابد تا هنگامی که اجازهٔ همگامسازی در پسزمینه داده شود
+ میخوابد تا هنگامی که شبکه در دسترس باشد
+ لمس کنید تا بیشتر بدانید.
+ اطلاعات پیشرانی
+ هنگام استفاده از پیشرانی، K-9 Mail اتصالی به کارساز رایانامه برقرار میکند. اندروید نیاز دارد هنگامی که برنامهای در پسزمینه فعال است اعلان مداومی را نشان دهد. %s
+ البته اندروید این امکان را به شما میدهد که اعلان را پنهان کنید.
+ بیشتر بدانید
+ پیکربندی اعلان
+ اگر برای پیامهای جدید نیاز به اعلان آنی ندارید، بهتر است پیشرانی را غیرفعال کنید و سرکشی را به کار ببرید. روش سرکشی در فواصل زمانی منظم آمدن نامههای جدید را بررسی میکند و به آن اعلان نیاز ندارد.
+ غیرفعالسازی پیشرانی
diff --git a/app/ui/legacy/src/main/res/values-fi/strings.xml b/app/ui/legacy/src/main/res/values-fi/strings.xml
index 0fce66b7fcda796057689d5389d047461e27ad1a..e734f7cbf3b8ee5e08589fef195f400e5c959ead 100644
--- a/app/ui/legacy/src/main/res/values-fi/strings.xml
+++ b/app/ui/legacy/src/main/res/values-fi/strings.xml
@@ -49,6 +49,8 @@
Välitä liitteenäValitse tiliValitse kansio
+ Siirrä…
+ Kopioi…Ladataan %s:%s%sHaetaan otsikkotietoja %s:%s%sLähetetään %s%s
@@ -82,6 +84,7 @@
HylkääTallenna luonnoksenaTarkista sähköposti
+ Tarkista viestit kaikilta tileiltäLähetä viestitPäivitä kansiotEtsi kansio
@@ -172,6 +175,9 @@
Kirjoita lokiin laajempi kuvaus ongelmistaKirjaa lokiin arkaluontoisia tietojaSalasanat saattavat näkyä lokeissa.
+ Vie lokit
+ Vienti onnistui. Lokit saattavat sisältää arkaluonteista tietoa. Pidä ne tallessa ja ole varovainen sen suhteen, kenelle ne lähetät.
+ Vienti epäonnistui.Lataa lisää viestejäVastaanottaja: %s Aihe
@@ -245,10 +251,6 @@
Remove Mail User-Agent from mail headersPiilota aikavyöhykeKäytä UTC-aikaa paikallisen aikavyöhykkeen sijaan sähköpostin otsakkeissa
- Piilota aihe ilmoituksissa
- Ei koskaan
- Kun laite on lukittu
- AinaNäytä Poista-painikeEi koskaanYksittäisen viestin ilmoituksessa
@@ -256,7 +258,7 @@
Lukitusnäytön ilmoituksetEi lukitusnäytön ilmoituksiaSovelluksen nimi
- Lukemattomien viestien määrä
+ Uusien viestien määräViestien määrä ja lähettäjätSama kuin näytön ollessa lukittunaHiljainen aika
@@ -269,6 +271,10 @@
SähköpostiosoiteSalasanaNäytä salasana
+
+ Jotta näet salasanasi tässä, ota käyttöön laitteen näytön lukitus.
+ Vahvista henkilöllisyytesi
+ Avaa lukitus nähdäksesi salasanasiMääritä asetukset käsinHaetaan tilin tietoja\u2026
@@ -310,8 +316,6 @@
MobiiliWi-FiMuu
- Ulkoinen muisti (SD-kortti)
- Sisäinen muistiPoista viestitHetiTarkistettaessa
@@ -387,8 +391,6 @@
JatkaLisäasetuksetYleiset
- Oletustili
- Lähetä postit oletusarvoisesti tältä tililtäSaapuneiden viestien ilmoituksetIlmoitukset kansioistaKaikki
@@ -404,12 +406,15 @@
Näytä ilmoitus lähettämistäni viesteistäVain yhteystiedotNäytä ilmoitukset vain niistä viesteistä, jotka tulevat tunnetuilta yhteystiedoilta
+ Älä huomioi keskusteluviestejä
+ Älä näytä ilmoituksia viesteistä, jotka kuuluvat sähköpostikeskusteluunMerkitse viesti luetuksi avattaessaMerkitse viesti luetuksi, kun se avataan katseltavaksiMerkitse luetuksi poistettaessaMerkitse viesti luetuksi, kun se poistetaan
- Ilmoitusasetukset
- Avaa järjestelmän ilmoitusasetukset
+ Ilmoitusten luokat
+ Määritä uusien viestien ilmoitukset
+ Määritä virhe- ja tilailmoituksetNäytä aina kuvatEi koskaanVain yhteystiedoissa olevilta lähettäjiltä
@@ -662,6 +667,7 @@
ViestinäkymäErilaisia listanäkymiäNäytä \"Yhdistetty saapuneet\"
+ Näytä tähdellä merkittyjen viestien määrä%s%s - LukemattomatKaikki viestit
@@ -871,6 +877,7 @@
PiilokopioVastaanottajaLähettäjä
+ Vastausosoite<Tuntematon vastaanottaja><Tuntematon lähettäjä>Koti
diff --git a/app/ui/legacy/src/main/res/values-fr/strings.xml b/app/ui/legacy/src/main/res/values-fr/strings.xml
index 60a705ed4a62457c433923032d9010c0a7adf6d1..a8edee160677d76cdad399b266d235604616a664 100644
--- a/app/ui/legacy/src/main/res/values-fr/strings.xml
+++ b/app/ui/legacy/src/main/res/values-fr/strings.xml
@@ -49,6 +49,8 @@
Transférer en tant que fichier jointChoisir un compteChoisir un dossier
+ Déplacer vers…
+ Copier vers…Scrutation. %s:%s%sRécup. entêtes %s:%s%sEnvoi %s%s
@@ -81,7 +83,8 @@
TerminéAbandonnerEnregistrer comme brouillon
- Relève des courriels
+ Relever les courriels
+ Relever les courriels dans tous les comptesEnvoyer les courrielsActualiser la liste des dossiersTrouver un dossier
@@ -126,7 +129,7 @@
Courriel introuvableErreur de chargement du courrielCharger
-jusqu’à %d de plus
+ jusqu’à %d de plus
%.1f Go%.1f Mo%.1f ko
@@ -158,7 +161,7 @@ jusqu’à %d de plus
Envoi du courriel :Synchroniser (pousser)
- Affiché lors de l’attente de nouveaux messages
+ Affiché lors de l’attente de nouveaux courrielsCourrielsNotifications relatives aux courrielsDivers
@@ -174,6 +177,9 @@ jusqu’à %d de plus
Journaliser les renseignements de diagnostic supplémentairesJournaliser les renseignements délicatesPourrait inclure les mots de passe dans les journaux.
+ Exporter les journaux
+ L\'exportation est réussie. Les journaux pourraient contenir des renseignements sensibles. Faites attention à qui vous les envoyés.
+ Échec d’exportation.Charger plus de courrielsÀ : %sObjet
@@ -247,10 +253,6 @@ jusqu’à %d de plus
Remove Mail User-Agent from mail headersCacher le fuseau horaireUtiliser UTC au lieu du fuseau horaire local dans les en-têtes de courriel et de réponse
- Cacher l’objet dans les notifications
- Jamais
- Quand l’appareil est verrouillé
- ToujoursAfficher le bouton SupprimerJamaisPour une notification de courriel unique
@@ -258,7 +260,7 @@ jusqu’à %d de plus
Notifications de l’écran verrouilléAucune notification si l’écran est verrouilléNom de l’application
- Nombre de courriels non lus
+ Nombre de nouveaux courrielsNombre de courriels et expéditeursIdentiques à celles de l’écran déverrouilléPériode calme
@@ -271,6 +273,10 @@ jusqu’à %d de plus
Adresse courrielMot de passeAfficher le mot de passe
+
+ Pour visualiser votre mot de passe ici, activez le verrouillage de l’écran sur cet appareil.
+ Confirmer votre identité
+ Déverrouiller l’écran pour visualiser votre mot de passeConfiguration manuelleRécupération des renseignements de compte\u2026
@@ -312,8 +318,6 @@ jusqu’à %d de plus
mobileWi-Fiautre
- Stockage externe (carte SD)
- Stockage interne habituelEffacer les courriels supprimés du serveurImmédiatementLors de la scrutation
@@ -389,8 +393,6 @@ jusqu’à %d de plus
ContinuerAvancéParamètres du compte
- Compte par défaut
- Envoyer par défaut les courriels avec ce compteNotifications de nouveaux courrielsDossiers des notificationsTous
@@ -406,12 +408,15 @@ jusqu’à %d de plus
Afficher une notification pour les courriels que j’ai envoyésContacts seulementN’afficher des notifications que pour les courriels de contacts connus
+ Ignorer les messages de conversation
+ Ne pas afficher de notification pour les messages qui appartiennent à une conversation de courrielMarquer comme lu à l’ouvertureMarquer un courriel comme lu quand il est ouvert pour être visualiséMarquer comme lu lors de la suppression
- Marquer un message comme lu lors de la suppression
- Paramètres de notification
- Ouvrir les paramètres de notification du système
+ Marquer un courriel comme lu lors de la suppression
+ Catégories de notification
+ Configurer les notifications pour les nouveaux courriels
+ Configurer les notifications d’erreurs et d’étatsToujours afficher les imagesNonPour les contacts uniquement
@@ -664,6 +669,7 @@ jusqu’à %d de plus
Dans les vues des courrielsDans les vues en listeAfficher la boîte de réception unifiée
+ Afficher le compte d’étoilés%s%s - Non luTous les courriels
@@ -772,7 +778,7 @@ jusqu’à %d de plus
Importation des paramètres…Pour utiliser le compte « %s », vous devez indiquer le mot de passe du serveur.
- Pour utiliser le compte « %s », vous devez indiquer les mots de passe du serveur.
+ Pour utiliser le compte « %s », vous devez indiquer les mots de passe des serveurs.Mot de passe du serveur entrantMot de passe du serveur sortant
@@ -873,6 +879,7 @@ jusqu’à %d de plus
CciÀDe
+ Répondre à<Le destinataire est inconnu><L’expéditeur est inconnu>Domicile
@@ -990,25 +997,25 @@ jusqu’à %d de plus
Paramètres générauxAucune appli OpenPGP n’est installéeInstaller
- Mail requires OpenKeychain for end-to-end encryption.
- Message chiffré
+ Courriel K-9 Mail a besoin d’OpenKeychain pour le chiffrement de bout en bout.
+ Courriel chiffréChiffrer l’objet des courrielsPourrait ne pas être pris en charge par certains destinatairesErreur interne : le compte est invalide !Erreur de connexion à %s !
- Envoyer un message de configuration Autocrypt
+ Envoyer un courriel de configuration AutocryptPartager en toute sécurité la configuration du chiffrement de bout de bout avec d’autres appareils
- Message de configuration Autocrypt
- Un message de configuration Autocrypt partage en toute sécurité la configuration du chiffrement de bout en bout avec d’autres appareils.
- Envoyer le message de configuration
- Le message sera envoyé à votre adresse :
- Génération du message de configuration…
- Envoi du message :
- Pour terminer, ouvrez le message dans votre autre appareil et saisissez le code de configuration.
+ Courriel de configuration Autocrypt
+ Un courriel de configuration Autocrypt partage en toute sécurité la configuration du chiffrement de bout en bout avec d’autres appareils.
+ Envoyer le courriel de configuration
+ Le courriel sera envoyé à votre adresse :
+ Génération du courriel de configuration…
+ Envoi du courriel :
+ Pour terminer, ouvrez le courriel dans votre autre appareil et saisissez le code de configuration.Afficher le code de configuration
- Message de configuration Autocrypt
- Ce message contient tous les renseignements pour transférer vos paramètres Autocrypt ainsi que votre clé privée en toute sécurité à partir de votre appareil d’origine.
- Une erreur est survenue lors de l’envoi du message. Veuillez vérifier votre connexion connectivité réseau et la configuration du serveur sortant.
+ Courriel de configuration Autocrypt
+ Ce courriel contient tous les renseignements pour transférer vos paramètres Autocrypt ainsi que votre clé privée en toute sécurité à partir de votre appareil d’origine.
+ Une erreur est survenue lors de l’envoi du courriel. Veuillez vérifier votre connexion connectivité réseau et la configuration du serveur sortant.ActiverDésactiverOuvrir
@@ -1027,6 +1034,6 @@ jusqu’à %d de plus
Cependant, Android vous permet aussi de cacher la notification.En apprendre davantageConfigurer la notification
- Si vous n’avez pas besoin de notifications instantanées pour les nouveaux messages, vous devriez désactiver le pousser et utiliser la scrutation. La scrutation vérifie la présence de nouveaux courriels à intervalles réguliers et n’a pas besoin de notification.
+ Si vous n’avez pas besoin de notifications instantanées pour les nouveaux courriels, vous devriez désactiver le pousser et utiliser la scrutation. La scrutation vérifie la présence de nouveaux courriels à intervalles réguliers et n’a pas besoin de notification.Désactiver le pousser
diff --git a/app/ui/legacy/src/main/res/values-gd/strings.xml b/app/ui/legacy/src/main/res/values-gd/strings.xml
index ad28a0211b8b56f92e3b66ef93e849369dcac8c2..b83cabdad8799080350f536865a12e5408f1a99f 100644
--- a/app/ui/legacy/src/main/res/values-gd/strings.xml
+++ b/app/ui/legacy/src/main/res/values-gd/strings.xml
@@ -1,813 +1,971 @@
-
+
-
-
-
- Mail
- Mail Accounts
- Mail Unread
-
- Còir-lethbhreac 2008-%s Luchd-coiseachd nan con K-9. Cuid dhen chòir-lethbhreac 2006-%s Android Open Source Project.
-
- Welcome to Mail
- Mail is the default mail client for /e/
-
- -- Sent from /e/ Mail.
-
- The account \"%s\" will be removed from Mail.
-
- Puist-d a leughadh
- Leig leis an aplacaid seo na puist-d agad a leughadh.
- Puist-d a sguabadh às
- Leig leis an aplacaid seo na puist-d agad a sguabadh às.
- Cunntasan
- Pasganan
- Adhartach
- Sgrìobh
- Freagair
- Freagair na h-uile
- Sìn air adhart
- Tagh pasgan
- Ceasnaich %s:%s%s
- A’ faighinn nam bannan-cinn %s:%s%s
- A’ cur %s%s
- Proc %s:%s%s
- \u0020%d/%d
- Chaidh an sioncronachadh a chur à comas
- %d air a thaghadh
- Air adhart
- Ais ais
-
- Ceart ma-thà
- Sguir dheth
- Cuir
- Cuir a-rithist
- Cha do shònraich thu cuspair, thoir gnogag às ùr airson a chur co-dhiù
- Tagh
- Dì-thagh
- Freagair
- Freagair na h-uile
- Sguab às
- Tasg-lann
- Spama
- Sìn air adhart
- Gluais
- Cuir…
- Ath-fhaidhlich…
- Deiseil
- Tilg air falbh
- Sàbhail mar dhreachd
- Thoir sùil airson post
- Cuir na teachdaireachdan
- Ath-nuadhaich liosta nam pasgan
- Lorg pasgan
- Cuir cunntas ris
- Sgrìobh
- Lorg
- Toraidhean an luirg
- Roghainnean
- Roghainnean a’ chunntais
- Thoir an cunntas air falbh
- Comharraich gun deach a leughadh
- Co-roinn
- Tagh seòladair
- Cuir rionnag ris
- Thoir an rionnag air falbh
- Lethbhreac
- Seall na bannan-cinn
-
- Chaidh an seòladh a chur air an stòr-bhòrd
- Chaidh na seòlaidhean a chur air an stòr-bhòrd
- Chaidh na seòlaidhean a chur air an stòr-bhòrd
- Chaidh na seòlaidhean a chur air an stòr-bhòrd
-
- Cleachd ùrlar dorcha ’na àite
- Cleachd ùrlar soilleir ’na àite
- Comharraich nach deach a leughadh
- Cuidhteas-leughaidh
- Iarraidh seo cuidhteas-leughaidh
- Chan iarr seo cuidhteas-leughaidh
- Cuir ceanglachan ris
- Falamhaich an sgudal
- Thoir air falbh gu tur
- About
- Roghainnean
-
- (Gun chuspair)
- Gun seòladair
- A’ luchdadh nan teachdaireachdan…
- Mearachd leis a’ cheangal
- Cha deach an teachdaireachd a lorg
- Mearachd a’ luchdadh na teachdaireachd
- Luchdaich suas ri
- to %d a bharrachd
- Bha an cunntas “%s” %s is tha e %s a-nis
- A’ dùmhlachadh a’ chunntais “%s”
- Post ùr
-
- %d teachdaireachd ùr
- %d theachdaireachd ùr
- %d teachdaireachdan ùra
- %d teachdaireachd ùr
-
- %d gun leughadh (%s)
- ⁊ %1$d a bharrachd air %2$s
- Freagair
- Comharraich gun deach a leughadh
- Comharraich gun deach iad uile a leughadh
- Sguab às
- Sguab às na h-uile
- Tasglannaich
- Tasglannaich na h-uile
- Spama
- Mearachd an teisteanais aig %s
- Thoir sùil air roghainnean an fhrithealaiche agad
- Dh’fhàillig an dearbhadh
- Dh’fhàillig dearbhadh a’ chunntais %s. Ùraich roghainnean an fhrithealaiche agad.
- A’ toirt sùil airson post: %s:%s
- A’ toirt sùil airson post
- A’ cur a’ phuist: %s
- A’ cur a’ phuist
- :
- Teachdaireachdan
- An corr
- A-steach
- A-mach
- Dreachdan
- Sgudal
- Air a chur
- Cha deach cuid dhe na teachdaireachdan a chur
- Cuir an comas logadh airson dì-bhugachadh
- Logaich fiosrachadh diagnosachd a bharrachd
- Logaich fiosrachadh dìomhair
- Dh’fhaoidte gun leig seo ris faclan-faire sna logaichean.
- Luchdaich barrachd theachdaireachdan
- Gu:%s
- Cuspair
- Teacsa na teachdaireachd
- An t-earr-sgrìobhadh
- -------- An teachdaireachd thùsail --------
- Cuspair:
- Air a chur:
- O:
- Gu:
- Cc:
- Sgrìobh %s:
- Sgrìobh %2$s%1$s:
- Feumaidh tu co-dhiù aon neach a chur ris a gheibh e.
- Tha rud ann an raon nan daoine a gheibh e a tha leth-chrìochnaichte!
- Cha b’ urrainn dhuinn seòladh puist-d a lorg dhan neach-aithne seo.
- Chan urrainn dhuinn cuid dhe na ceanglachain a shìneadh air adhart oir cha deach an luchdadh a-nuas.
- Thoir an luaidh air falbh
- Crìoch na na luaidhe
- O: %s <%s>
- Gu:
- Cc:
- Bcc:
- Fosgail
- Sàbhail
- Seall na dealbhan
- Chan urrainn dhuinn aplacaid a lorg a sheallas %s.
- Luchdaich a-nuas an teachdaireachd shlàn
- Chan urrainn dhuinn an teachdaireachd a shealltainn
- slighe %1$s
-
- Chaidh gach bann-cinn a luchdadh a-nuas ach chan eil bann-cinn eile ann a ghabhas a shealltainn.
- Cha b’ urrainn dhuinn bannan-cinn a bharrachd fhaighinn on stòr-dàta no o fhrithealaiche a’ phuist.
- Barrachd on t-seòladair seo
- Dì-bhugaich / Falamhaich bodhaig na teachdaireachd
- Chaidh an teachdaireachd a thilgeil air falbh
- Chaidh an teachdaireachd a shàbhaladh mar dhreachd
- Seall na rionnagan
- Tha rionnagan a’ comharradh teachdaireachdan le bratach
- Loidhnichean a ro-shealladh
- Seall ainmean nan seòladairean
- Seall ainmean nan seòladairean seach na seòlaidhean puist-d aca
- An seòladair os cionn a’ chuspair
- Seall ainmean nan seòladairean os cionn a’ chuspair seach foidhe
- Seall ainmean an luchd-aithne
- Cleachd ainmean o luchd-aithne Android ma tha gin ann
- Cuir dathan air an luchd-aithne
- Cuir dathan air ainmean ann an liosta an luchd-aithne agad
- Cruthan-clò le leud socraichte
- Cleachd cruth-clò le leud socraichte nuair a thèid taisbeanadh ann an teacsa lom a shealltainn
- Fèin-fhreagair teachdaireachdan
- Crùb teachdaireachdan ach am freagair iad ris an sgrìn
- Till gun liosta an dèidh sguabaidh às
- Till gun liosta an dèidh teachdaireachd a sguabadh às
- Seall an ath-theachdaireachd an dèidh sguabaidh às
- Seall an ath-theachdaireachd a ghnàth an dèidh teachdaireachd a sguabaidh às
- Dearbh gnìomhan
- Seall còmhradh uair sam bith a nì thu gnìomh sònraichte
- Sguab às
- Sguab às an fheadhainn le rionnag (ann an sealladh nan teachdaireachdan)
- Spama
- Tilg an teachdaireachd air falbh
- Comharraich gun deach gach teachdaireachd a leughadh
- Sguab às (on bhrath)
- Falaich cliant a’ phuist
- Remove Mail User-Agent from mail headers
- Falaich an roinn-tìde
- Cleachd UTC an àite na roinn-tìde ionadail ann am bannan-cinn phost is fhreagairtean
- Falaich an cuspair ann am brathan
- Chan ann idir
- Nuair a bhios an t-uidheam glaiste
- An-còmhnaidh
- Seall am putan “Sguab às”
- Chan ann idir
- Airson brath aon teachdaireachd
- An-còmhnaidh
- Brathan air an sgrìn-ghlasaidh
- Na seall brathan air an sgrìn-ghlasaidh
- Ainm na h-aplacaid
- Co mheud teachdaireachd gun leughadh
- Co mheud teachdaireachd is seòladair
- An aon rud nuair nach bi an sgrìn glaiste
- Amannan sàmhach
- Cuir seirm, srann is boillsgeadh à comas rè na h-oidhche
- Cuir na brathan à comas
- Cuir na brathan à comas buileach rè nan amannan sàmhach
- Tòisichidh an t-àm sàmhach
- Thig an t-àm sàmhach gu crìoch
- Suidhich cunntas ùr
- Seòladh puist-d
- Facal-faire
- Seall am facal-faire
- Suidheachadh de làimh
-
- A’ faighinn fiosrachadh a’ chunntais…
- A’ sgrùdadh roghainnean an fhrithealaiche a-steach…
- A’ sgrùdadh roghainnean an fhrithealaiche a-mach…
- ’Ga dhearbhadh…
- A’ faighinn roghainnean a’ chunntais…
- A’ sgur dheth…
- Cha mhòr deiseil!
- Thoir ainm air a’ chunntas seo (roghainneil):
- Cuir a-steach d’ ainm (chithear seo ann an teachdaireachdan a thèid a-mach):
- Seòrsa a’ chunntais
- Dè seòrsa cunntas a tha seo?
- POP3
- IMAP
- Facal-faire àbhaisteach
- Facal-faire, ’ga chur gun tèarainteachd
- Facal-faire crioptaichte
- Teisteanas a’ chliant
- Roghainnean an fhrithealaiche a-steach
- Ainm-cleachdaiche
- Facal-faire
- Teisteanas a’ chliant
- Frithealaiche POP3
- Frithealaiche IMAP
- Frithealaiche Exchange
- Port
- Tèarainteachd
- Dearbhadh
- Chan eil gin
- SSL/TLS
- STARTTLS
- Chan eil “%1$s = %2$s” dligheach mu choinneamh “%3$s = %4$s”
- Nuair a sguabas mi teachdaireachd às
- na sguab às an fhrithealaiche e
- sguab às an fhrithealaiche e
- comharraich air an fhrithealaiche gun deach a leughadh
- Cleachd dùmhlachadh air lìonra:
- Mobile
- WiFi
- Eile
- Stòras air an taobh a-muigh (cairt SD)
- Stòras inntearnail àbhaisteach
- Ma sguabas mi às teachdaireachd, sguab às an fhrithealaiche e
- sa bhad
- aig an ath-cheasnachadh
- a làimh
- Mothaich dha IMAP Namespace gu fèin-obrachail
- Ro-leasachan slighe IMAP
- Pasgan nan dreachdan
- Pasgan a’ phuist chuirte
- Pasgan an sgudail
- Pasgan nan tasg-lann
- Pasgan an spama
- Na seall ach pasganan a tha fo-sgrìobhadh agam aca
- Leudaich am pasgan gu fèin-obrachail
- Slighe OWA
- Roghainneil
- Slighe an dearbhaidh
- Roghainneil
- Alias a’ bhogsa-phuist
- Roghainneil
- Roghainnean an fhrithealaiche a-mach
- Frithealaiche SMTP
- Port
- Tèarainteachd
- Iarr clàradh a-steach.
- Ainm-cleachdaiche
- Facal-faire
- Dearbhadh
- Chan eil “%1$s = %2$s” dligheach mu choinneamh “%3$s = %4$s”
- Suidheachadh mì-dhligheach: %s
- Roghainnean a’ chunntais
- Dùmhlaich an cunntas
- Dè cho tric ’s a dh’iarras sinn am post?
- Chan ann idir
- Gach cairteal na h-uarach
- Gach leth-uair a thìde
- Gach uair a thìde
- Gach 2 uair a thìde
- Gach 3 uairean a thìde
- Gach 6 uairean a thìde
- Gach 12 uair a thìde
- Gach 24 uair a thìde
- Cuir post push an comas airson a’ chunntais seo
- Ma bheir am frithealaiche agad taic dha, nochdaidh teachdaireachdan ùra sa bhad. Faodaidh buaidh mhòr (math no dona) a bhith aig an roghainn seo air dèanadas.
- Ath-nuadhaich an ceangal IDLE
- Gach 2 mhionaid
- Gach 3 mionaidean
- Gach 6 mionaidean
- Gach 12 mhionaid
- Gach 24 mionaid
- Gach 36 mionaid
- Gach 48 mionaid
- Gach uair a thìde
- Innis dhomh nuair a ruigeas post
- Innis dhomh nuair a thathar a’ toirt sùil airson post
- Co mheud teachdaireachd a thèid a shealltainn
- 10 teachdaireachdan
- 25 teachdaireachd
- 50 teachdaireachd
- 100 teachdaireachd
- 250 teachdaireachd
- 500 teachdaireachd
- 1,000 teachdaireachd
- 2.500 teachdaireachd
- 5,000 teachdaireachd
- 10,000 teachdaireachd
- na h-uile teachdaireachd
- Chan urrainn dhut lethbhreac a dhèanamh de theachdaireachd, no a ghluasad, mur eil e sioncronaichte leis an fhrithealaiche
- Cha b’ urrainn dhuinn an suidheachadh a choileanadh
- Tha an t-ainm-cleachdaiche no facal-faire cearr.\n(%s)
- Nochd am frithealaiche teisteanas SSL nach eil dligheachd. Tachraidh seo uaireannan ma chaidh am frithealaiche a dhroch-rèiteachadh. Air neo dh’fhaoidte gu bheil cuideigin airson briseadh a-steach ort no air frithealaiche a’ phuist agad. Mur eil thu cinnteach dè tha a’ tachairt, thoir gnogag air “Diùlt” is cuir fios gu na daoine a stiùireas frithealaiche a’ phuist agad.\n\n(%s)
- Chan urrainn dhuinn ceangal ris an fhrithealaiche.\n(%s)
- Deasaich am fiosrachadh
- Lean air adhart
- Adhartach
- Roghainnean a’ chunntais
- An cunntas bunaiteach
- Cuir post on chunntas seo a ghnàth
- Brathan mu phost ùr
- Pasganan a chuireas brath
- Na h-uile
- Pasganan na 1ad ìre a-mhàin
- Pasganan na 1ad is na 2na ìre
- Gach aon ach pasganan na 2na ìre
- Chan eil gin
- Brathan sioncronachaidh
- An seòladh puist-d agad
- Innis dhomh air bàr na staide nuair a ruigeas post
- Innis dhomh air bàr na staide nuair a thathar a’ toirt sùil airson post
- Gabh a-staigh post a tha a’ dol a-mach
- Seall brath nuair a bhios mi air teachdaireachd a chur
- Luchd-aithne a-mhàin
- Na seall brathan ach ma thig teachdaireachd o neach-aithne agam
- Comharraich gun deach a leughadh nuair a dh’fhosglas mi e
- Comharraich gun deach an teachdaireachd a leughadh nuair a dh’fhosglas mi e a choimhead air
- Seall dealbhan an-còmhnaidh
- Chan eil
- On luchd-aithne
- O dhuine sam bith
- A’ cur a’ phuist
- Dèan luaidh air an teachdaireachd ann am freagairt
- Gabh a-staigh an teachdaireachd thùsail ’nad theachdaireachd.
- Freagair an dèidh na luaidhe
- Nochdaidh an teachdaireachd thùsail os cionn do fhreagairt.
- Spìon earr-sgrìobhadh sam bith às ann am freagairt
- Thèid earr-sgrìobhaidhean a thoirt air falbh o theachdaireachd air a bheilear a’ dèanamh luaidh
- Fòrmat na teachdaireachd
- Teacsa lom (thoir air falbh dealbhan is fòrmatadh)
- HTMP (glèidh na dealbhan is am fòrmatadh)
- Gu fèin-obrachail
- Seall an Cc/Bcc an-còmhnaidh
- Cuidhteas-leughaidh
- Iarr cuidhteas-leughaidh an-còmhnaidh
- Stoidhle nan luaidhean ann am freagairtean
- Le ro-leasachan (mar Gmail)
- Bann-cinn (mar Outlook)
- Roghainnean coitcheann
- A’ leughadh post
- A’ faighinn post
- Pasganan
- Ro-leasachan teacsa nan luaidh
- Dè cho tric ’s a dh’iarras sinn am post?
- Dath a’ chunntais
- Dath cuideam a’ chunntais seo a chithear ann am pasganan is liosta nan cunntas
- Dath LED nam brath
- An dath a bhios air LED an uidheim agad dhan chunntas seo
- Meud a’ phasgain ionadail
- Faigh teachdaireachdan suas ri
- meud sam bith (gun chrìoch)
- Sioncronaich teachdaireachdan
- o àm sam bith (gun chrìoch)
- on diugh
- on dè
- on bhòin-dè
- on t-seachdain seo chaidh
- on chola-deug seo chaidh
- o na 3 seachdainean seo chaidh
- on mhìos seo chaidh
- on 2 mhìos seo chaidh
- o na 3 mìosan seo chaidh
- on na 6 mìosan seo chaidh
- on uraidh
- Na pasganan a thèid a shealltainn
- Na h-uile
- Pasganan na 1ad ìre a-mhàin
- Pasganan na 1ad is na 2na ìre
- Gach aon ach pasganan na 2na ìre
- Na pasganan a thèid a cheasnachadh
- Na h-uile
- Pasganan na 1ad ìre a-mhàin
- Pasganan na 1ad is na 2na ìre
- Gach aon ach pasganan na 2na ìre
- Chan eil gin
- Na pasganan push
- Na h-uile
- Pasganan na 1ad ìre a-mhàin
- Pasganan na 1ad is na 2na ìre
- Gach aon ach pasganan na 2na ìre
- Chan eil gin
- Pasganan dhan a chuirear lethbhreacan/dhan a ghluaisear
- Na h-uile
- Pasganan na 1ad ìre a-mhàin
- Pasganan na 1ad is na 2na ìre
- Gach aon ach pasganan na 2na ìre
- Sioncronaich sguabadh às air an fhrithealaiche
- Thoir air falbh teachdaireachdan a chaidh a sguabadh às an fhrithealaiche
- Roghainnean a’ phasgain
- Seall aig a’ bharr sa bhuidheann
- Seall faisg air barr liosta nam pasganan
- Ìre taisbeanadh a’ phasgain
- Gun chlas
- 1ad ìre
- 2na ìre
- Chan eil gin
- 1ad ìre
- 2na ìre
- Co-ionnann ris an ìre taisbeanaidh
- Ìre push a’ phasgain
- Gun chlas
- 1ad ìre
- 2na ìre
- Ìre brathan a’ phasgain
- Gun chlas
- 1ad ìre
- 2na ìre
- Co-ionnann ris an ìre push
- Falamhaich na teachdaireachdan ionadail
- Am frithealaiche a-steach
- Rèitich frithealaiche a’ phuist a-steach
- Am frithealaiche a-mach
- Rèitich frithealaiche a’ phuist a-mach (SMTP)
- Ainm a’ chunntais
- D’ ainm
- Brathan
- Crith
- Cuir air chrith nuair a ruigeas post
- Pàtranan crith
- bun-roghainn
- pàtran 1
- pàtran 2
- pàtran 3
- pàtran 4
- pàtran 5
- Crith a-rithist
- Seirm a’ phuist ùir
- Boillsg an LED
- Boillsg an LED nuair a ruigeas post
- Roghainnean sgrìobhadh theachdaireachdan
- Bun-roghainnean sgrìobhaidh
- Suidhich bun-roghainnean “O”, “Bcc” agus an earr-sgrìobhaidh
- Stiùirich na IDs
- Suidhich seòlaidhean “O” is earr-sgrìobhaidhean eadar-dhealaichte
- Stiùirich na IDs
- Stiùirich an ID
- Deasaich an ID
- Sàbhail
- ID ùr
- Cuir Bcc de gach teachdaireachd gu
- Deasaich
- Gluais suas
- Gluais sìos
- Gluais suas / dèan a’ bhun-roghainn dheth
- Thoir air falbh
- Tuairisgeul na ID
- (Roghainneil)
- D’ ainm
- (Roghainneil)
- Seòladh puist-d
- (Riatanach)
- An seòladh dhan chuirear freagairtean
- (Roghainneil)
- An t-earr-sgrìobhadh
- (Roghainneil)
- Cleachd earr-sgrìobhadh
- An t-earr-sgrìobhadh
- An ID tòiseachail
- Tagh ID
- Cuir mar
- Chan urrainn dhut an aon ID agad a thoirt air falbh
- Chan urrainn dhut ID a chleachdadh gun seòladh puist-d
- Na teachdaireachdan as sine an toiseach
- Na teachdaireachdan as ùire an toiseach
- Aibidileach a-rèir a’ chuspair
- Aibidileach contrarra a-rèir a’ chuspair
- Aibidileach a-rèir an t-seòladair
- Aibidileach contrarra a-rèir an t-seòladair
- Teachdaireachdan le rionnag an toiseach
- Teachdaireachdan gun rionnag an toiseach
- Teachdaireachdan gun leughadh an toiseach
- Teachdaireachdan a chaidh an leughadh an toiseach
- Teachdaireachdan le ceanglachain an toiseach
- Teachdaireachdan gun cheanglachain an toiseach
- Seòrsaich a-rèir…
- Ceann-là
- Ruigsinn
- Cuspair
- Seòladair
- Rionnag
- Air a leughadh/gun leughadh
- Ceanglachain
- Thoir an cunntas air falbh
- Teisteanas neo-aithnichte
- Gach ris an iuchair
- Diùlt an iuchair
- Seall pasganan…
- Na h-uile pasgan
- Pasganan na 1ad ìre
- Pasganan na 1ad ⁊ na 2na ìre
- Falaich pasganan na 2na ìre
- Ionad an earr-sgrìobhaidh
- Ron luaidh air an teachdaireachd
- An dèidh luaidh air an teachdaireachd
- Cleachd ùrlar na h-aplacaid
- Dorcha
- Soilleir
- Taisbeanadh
- Uile-choitcheann
- Dì-bhugachadh
- Prìobhaideachd
- Lìonra
- Eadar-ghabhail
- Liosta nan cunntasan
- Liosta nan teachdaireachdan
- Teachdaireachdan
- Ùrlar
- Ùrlar sealladh nan teachdaireachdan
- Ùrlar an sgrìobhaidh
- Ùrlair socraichte airson teachdaireachdan
- Tagh ùrlar airson na teachdaireachd is tu a’ coimhead air
- Cleachd ùrlair socraichte airson teachdaireachdan
- Sioncronachadh sa chùlaibh
- Chan ann idir
- An-còmhnaidh
- Ma tha cromag ri “Sioncronachadh fèin-obrachail”
- Tagh na h-uile
- An àireamh as motha a phasganan air an doirear sùil le push
- 10 pasganan
- 25 pasgan
- 50 pasgan
- 100 pasgan
- 250 pasgan
- 500 pasgan
- 1,000 pasgan
- Beòthachadh
- Cleachd èifeachdan lèirsinneach leòmach
- Seòladaireachd slighe putanan àirde na fuaime
- Ann an seallaidhean theachdaireachdan
- Ann an seallaidhean liostaichean
- %s%s
- - gun leughadh
- Na h-uile teachdaireachd
- Na h-uile teachdaireachd ann am pasgan so-luirg
- Am bogsa a-steach co-aonaichte
- Na h-uile teachdaireachd ann am pasganan co-aonaichte
- Co-aonaich
- Tha gach teachdaireachd ’ga shealltainn sa bhogsa a-steach cho-aonaichte
- Na pasganan san dèanar lorg
- Na h-uile
- So-thaisbeanadh
- Chan eil gin
- Chan eil gin
- Meud a’ chrutha-chlò
- Rèitich meud a’ chrutha-chlò
- Liosta nan cunntasan
- Ainm a’ chunntais
- Tuairisgeul a’ chunntais
- Liosta nam pasganan
- Ainm a’ phasgain
- Staid a’ phasgain
- Liosta nan teachdaireachdan
- Cuspair
- Seòladair
- Ceann-là
- Ro-shealladh
- Teachdaireachdan
- Seòladair
- Gu
- Cc
- Bcc
- Bannan-cinn a bharrachd
- Cuspair
- Ceann-là ’s àm
- Bodhaig na teachdaireachd
- %d%%
- %1$s: %2$s
- Sgrìobhadh theachdaireachdan
- Raointean ion-chur teacsa
- Bun-roghainn
- As lugha
- Beag bìodach
- Nas lugha
- Beag
- Meadhanach
- Mòr
- Nas motha
- Cha deach aplacaid iomchaidh a lorg dhan ghnìomh seo.
- Dh’fhàillig a chur: %s
- A bheil thu airson dreachd na teachdaireachd a shàbhaladh?
- A bheil thu airson an teachdaireachd seo a shàbhaladh no a thilgeil air falbh?
- A bheil thu airson an teachdaireachd seo a thilgeil air falbh?
- A bheil thu cinnteach gu bheil thu airson an teachdaireachd seo a thilgeil air falbh?
- Tagh teacsa airson lethbhreac a dhèanamh dheth.
- Dearbh a sguabadh às
- A bheil thu cinnteach gu bheil thu airson an teachdaireachd seo a sguabadh às?
- Tha
- Chan eil
- Comharraich gun deach gach teachdaireachd a leughadh
- A bheil thu airson comharradh gun deach na teachdaireachdan uile seo a leughadh?
- Tha
- Chan eil
- Dearbh a ghluasad do phasgan an spama
- Tha
- Chan eil
- A’ luchdadh a-nuas a’ cheanglachain
- »
- ›
- An corr
- Às-phortaich
- Co-roinn
- Ag às-phortadh nan roghainnean…
- Chaidh na roghainnean às-phortadh
- Cha b’ urrainn dhuinn na roghainnean às-phortadh
- Ion-phortaich na roghainnean
- Ion-phortaich
- Ion-phortaich na roghainnean
- Ag ion-phortadh nan roghainnean…
- Seall na tha gun leughadh ann an…
- Gun teacsa
- Fosgail an ceangal
- Co-roinn an ceangal
- Cuir lethbhreac dhen cheangal air an stòr-bhòrd
- Ceangal
- Dealbh
- Seall an dealbh
- Sàbhail an dealbh
- Luchdaich a-nuas an dealbh
- Cuir lethbhreac de URL an deilbh air an stòr-bhòrd
- URL an deilbh
- Cuir fòn gun àireamh seo
- Sàbhail san luchd-aithne
- Cuir lethbhreac dhen àireamh air an stòr-bhòrd
- Àireamh fòn
- Cuir am post
- Sàbhail san luchd-aithne
- Cuir lethbhreac dhen t-seòladh air an stòr-bhòrd
- Seòladh puist-d
- Na h-uile
- 10
- 25
- 50
- 100
- 250
- 500
- 1,000
- Crìoch lorg an fhrithealaiche
- A’ cur na ceiste dhan fhrithealaiche
-
- A’ faighinn %d toradh
- A’ faighinn %d thoradh
- A’ faighinn %d toraidhean
- A’ faighinn %d toradh
-
-
- A’ faighinn %1$d à %2$d toradh
- A’ faighinn %1$d à %2$d thoradh
- A’ faighinn %1$d à %2$d toraidhean
- A’ faighinn %1$d à %2$d toradh
-
- Dh’fhàillig an lorg cèin
- Lorg
- Cuir an comas lorg air an fhrithealaiche
- Lorg teachdaireachdan air an fhrithealaiche a bharrachd air an fheadhainn air an uidheam agad
- Lorg teachdaireachdan air an fhrithealaiche
- Feumaidh tu ceangal ris an lìonra mus urrainn dhut lorg a dhèanamh air an fhrithealaiche.
- Atharraich an dath nuair a chaidh a leughadh
- Nochdaidh cùlaibh eile a sheallas gun deach an teachdaireachd a leughadh
- Sealladh ann an snàithleanan
- Buidhnich teachdaireachdan ann an còmhraidhean
- Ag àrdachadh nan stòr-dàta
- Ag àrdachadh nan stòr-dàta…
- Ag àrdachadh nan stòr-dàta aig a’ chunntas “%s”
- Seall air sgrìn sgoilte
- An-còmhnaidh
- Chan ann idir
- Nuair a tha e ’ga shealltainn marh dreach-tìre
- Tagh teachdaireachd air an taobh chlì
- Seall dealbhan an luchd-aithne
- Seall dealbhan an luchd-aithne ann an liosta nan teachdaireachd
- Comharraich gun deach iad uile a leughadh
- Cuir dathan air dealbhan an luchd-aithne
- Cuir dathan air dealbhan an luchd-aithne a tha a dhìth
- Gnìomhan theachdaireachdan ri fhaicinn
- Seall na gnìomhan a thagh thu ann an clàr-taice sealladh na teachdaireachd
- A’ luchdadh a’ cheanglachain…
- A’ cur na teachdaireachd
- A’ sàbhaladh an dreachd
- A’ faighinn a’ cheanglachain…
- Cha b’ urrainn dhuinn dearbhadh a dhèanamh. Chan eil am frithealaiche a’ leigeil ris a bheil e comasach air SASL EXTERNAL. Dh’fhaoidte gu bheil duilgheadas le teisteanas a’ chliant (ro aosta, ùghdarras neo-aithnichte) no duilgheadas eile leis an rèiteachadh.
-
- Cleachd teisteanas a’ chliant
- Chan eil teisteanas aig a’ chliant
- Thoir air falbh taghadh teisteanas a’ chliant
- Cha b’ urrainn dhuinn teisteanas a’ chliant fhaighinn dhan alias “%s”
- Roghainnean adhartach
- Dh’fhalbh an ùine air teisteanas a’ chliant “%1$s” no chan eil e dligheachd fhathast (%2$s)
-
- *Crioptaiche*
- Cuir ris on luchd-aithne
- Cc
- Bcc
- Gu
- O
- Taigh
- Obair
- Eile
- Fòn-làimhe
- Cha deach pasgan do dhreachdan a rèiteachadh dhan chunntas seo!
- Chan urrainn dhuinn ceangal ri solaraiche a’ chrioptachaidh, thoir sùil air na roghainnean no thoir gnogag air ìomhaigheag a’ chrioptachaidh airson feuchainn ris a-rithist!
- Chan eil taic ri ceanglachain sa mhodh PGP/INLINE!
- Cuir PGP/INLINE an comas
- Cuir PGP/INLINE à comas
- Cuir PGP Sign-Only an comas
- Cuir PGP Sign-Only à comas
- Am modh PGP/INLINE
- Tha am post-d seo ’ga chur san fhòrmat PGP/INLINE.\nCha bu chòir dhut seo a dhèanamh ach airson co-chòrdalachd:
- Tha cuid a chliantan ann nach cuir taic ach ris an fhòrmat seo
- Dh’fhaoidte gum bris soidhneadh rè an tar-chuir
- Chan eil taic ri ceanglachain
- Tha mi agaibh!
- Cuir à comas
- Cum an comas
- Tha mi agaibh!
- Cuir à comas
- Cum an comas
- Am modh PGP Sign-Only
- Sa mhodh seo, thèid an iuchair PGP agad a chleachdaidh airson soidhneadh crioptografach de phost-d gun chrioptachadh a chruthachadh.
- Cha chrioptaich seo am post-d ach dearbhaidh e gun deach a chuir on iuchair agad.
- Dh’fhaoidte gum bris soidhneadh nuair a chuireas tu rud gu liosta-phuist.
- Dh’fhaoidte gun nochd soidhnidhean mar “signature.asc” ann an cuid a chliantan.
- Bidh soidhneadh am broinn teachdaireachd chrioptaichte an-còmhnaidh.
- Tha an teachdaireachd crioptaichte ach ann am fòrmat ris nach eil taic.
- Tha an teachdaireachd crioptaichte ach cha sguireadh dhen dì-chrioptachadh.
- Ceart ma-thà
- Mion-fhiosrachadh
- Thoir a’ ghlas dheth
- Cha deach a’ phàirt seo a chrioptachadh is dh’fhaoidte gu bheil e neo-thèarainte.
- Ceanglachan gun dìon
- ’Ga luchdadh…
- Sguireadh dhen dì-chrioptachadh.
- Feuch ris a-rithist
- Feumaidh tu an teachdaireachd chrioptaichte a luchdadh a-nuas mus gabh a dhì-chrioptachadh.
- Mearachd a’ dì-chrioptachadh a’ phuist-d
- Chan eil taic ri caractaran sònraichte aig an àm seo!
- Mearachd a’ pàrsadh an t-seòlaidh!
- Chan eil crioptachadh ri fhaidhinn sa mhodh anns nach dèanar ach soidhneadh!
- Teacsa gun soidhneadh
- Rabhadh mu chleachdadh APG
- Chan eilear a’ leasachadh APG tuilleadh!
- Ri linn sin, chan eil taic ri APG aig post K-9 tuilleadh.
- Sguir daoine dhen obair-leasachaidh aig toiseach 2014
- Tha duilgheadasa tèarainteachd ann nach deach an càradh
- Briog an-seo airson barrachd fiosrachaidh.
- Tha mi agaibh!
- APG
- Tha am post-d seo crioptaichte
- Chaidh am post-d seo a chrioptachadh le OpenPGP.\nFeumaidh tu aplacaid a tha comasach air OpenPGP a stàladh is a rèiteachadh mus urrainn dhut a leughadh.
- Mail Message List
- A’ luchdadh nan teachdaireachdan…
- Cha b’ urrainn dhuinn liosta nam pasgan fhaighinn
- Roghainnean coitcheann
- Fosgail
- Dùin
-
- Teirmichean na seirbheise
- Ùghdaran
-
\ No newline at end of file
+
+
+
+ Post
+ Cunntasan puist
+ Post gun leughadh
+
+ Google, luchd-coiseachd nan con .
+ Còir-lethbhreac 2008-%s Luchd-coiseachd nan con Mail. Cuid dhen chòir-lethbhreac 2006-%s Android Open Source Project.
+ An còd tùsail
+ Fo cheadachas Apache, tionndadh 2.0.
+ Pròiseact le tùs fosgailte
+ Làrach-lìn
+ Fòram an luchd-chleachdaidh
+ Fediverse
+ Twitter
+ Leabhar-lannan
+ An ceadachas
+ Loga nan atharraichean
+ Cha b’ urrainn dhuinn loga nan atharraichean a luchdadh.
+ Tionndadh %s
+ Na tha ùr
+
+ Fàilte gu aplacaid a’ phuist
+ <p> Tha aplacaid a’ phuist ’na aplacaid shaor agus chumhachdach airson post-d air Android. </p><p> Tha na gleusan leasaichte aige a’ gabhail a-staigh: </p> <ul> <li>Put post slighe IMAP IDLE</li> <li>Dèanadas nas fheàrr</li> <li>Ath-fhaidhleadh theachdaireachdan</li> <li>Eàrr-sgrìobhaidhean puist-d</li> <li>Bcc dhut fhèin</li> <li>Fo-sgrìobhaidhean phasganan</li> <li>Sioncronachadh nam pasgan air fad</li> <li>Rèiteachadh seòladh nam freagairt</li> <li>Ath-ghoiridean a’ mheur-chlàir</li> <li>Taic nas fheàrr airson IMAP</li> <li>Sàbhaladh de cheanglachain air SD</li> <li>Falamhachadh an sgudail</li> <li>Seòrsachadh theachdaireachdan</li> <li>…is mòran a bharrachd</li> </ul> <p> Thoir an aire nach cuir aplacaid a’ phuist taic ri cuid mhòr de chunntasan saora Hotmail agus mar iomadh prògram puist-d eile, tachraidh rudan neònach nuair a bhruidhneas e ri Microsoft Exchange. </p><p> Fàilte air bugaichean, com-pàirteachas, iarrtasan airson gleusan ùra is ceistean aig <a href=https://github.com/k9mail/k-9/>https://github.com/k9mail/k-9/</a>. </p>
+
+ -- Chaidh a chur le post /e/.
+
+ Thèid an cunntas “%s” a thoirt air falbh on phost.
+
+ Puist-d a leughadh
+ Leig leis an aplacaid seo na puist-d agad a leughadh.
+ Puist-d a sguabadh às
+ Leig leis an aplacaid seo na puist-d agad a sguabadh às.
+ Cunntasan
+ Pasganan
+ Adhartach
+ Sgrìobh
+ Freagair
+ Freagair na h-uile
+ Sìn air adhart
+ Sìn air adhart mar cheanglachan
+ Tagh cunntas
+ Tagh pasgan
+ Ceasnaich %s:%s%s
+ A’ faighinn nam bannan-cinn %s:%s%s
+ A’ cur %s%s
+ Pròiseas %s:%s%s
+ %d/%d
+ Chaidh an sioncronachadh a chur à comas
+ %d air a thaghadh
+ Air adhart
+ Ais ais
+
+ Ceart ma-thà
+ Sguir dheth
+ Cuir
+ Cuir a-rithist
+ Tha an cuspair falamh, thoir gnogag a-rithist airson a chur co-dhiù
+ Tagh
+ Dì-thagh
+ Freagair
+ Freagair na h-uile
+ Sguab às
+ Tasg-lann
+ Spama
+ Sìn air adhart
+ Sìn air adhart mar cheanglachan
+ Deasaich mar theachdaireachd ùr
+ Gluais
+ Gluais gu na dreachdan
+ Cuir…
+ Ath-fhaidhlich…
+ Deiseil
+ Tilg air falbh
+ Sàbhail mar dhreachd
+ Thoir sùil airson post
+ Faigh am post aig gach cunntas
+ Cuir na teachdaireachdan
+ Ath-nuadhaich liosta nam pasgan
+ Lorg sa phasgan
+ Cuir cunntas ris
+ Sgrìobh
+ Lorg sa phost
+ Lorg anns gach àite
+ Toraidhean an luirg
+ Roghainnean
+ Stiùirich na pasganan
+ Roghainnean a’ chunntais
+ Thoir an cunntas air falbh
+ Comharraich gun deach a leughadh
+ Co-roinn
+ Tagh seòladair
+ Cuir rionnag ris
+ Thoir an rionnag air falbh
+ Dèan lethbhreac
+ Seall na bannan-cinn
+
+ Chaidh an seòladh a chur air an stòr-bhòrd
+ Chaidh na seòlaidhean a chur air an stòr-bhòrd
+ Chaidh na seòlaidhean a chur air an stòr-bhòrd
+ Chaidh na seòlaidhean a chur air an stòr-bhòrd
+
+ Chaidh lethbhreac teacsa a’ chuspair a chur air an stòr-bhòrd
+ Cleachd ùrlar dorcha ’na àite
+ Cleachd ùrlar soilleir ’na àite
+ Comharraich nach deach a leughadh
+ Cuidhteas-leughaidh
+ Thèid cuidhteas-leughaidh iarraidh
+ Cha dèid cuidhteas-leughaidh iarraidh
+ Cuir ceanglachan ris
+ Falamhaich an sgudal
+ Thoir air falbh gu tur
+ Mu dhèidhinn
+ Roghainnean
+
+ (Gun chuspair)
+ Gun seòladair
+ A’ luchdadh nan teachdaireachdan…
+ Mearachd leis a’ cheangal
+ Cha deach an teachdaireachd a lorg
+ Mearachd a’ luchdadh na teachdaireachd
+ Luchdaich suas ri %d a bharrachd
+ %.1fGB
+ %.1fMB
+ %.1fkB
+ %dB
+ Bha an cunntas “%s” %s is chan eil e ach %s a-nis
+ A’ dùmhlachadh a’ chunntais “%s”
+ Post ùr
+
+ %d teachdaireachd ùr
+ %d theachdaireachd ùr
+ %d teachdaireachdan ùra
+ %d teachdaireachd ùr
+
+ %d gun leughadh (%s)
+ ⁊ %1$d a bharrachd air %2$s
+ Freagair
+ Comharraich gun deach a leughadh
+ Comharraich gun deach iad uile a leughadh
+ Sguab às
+ Sguab às na h-uile
+ Tasglannaich
+ Tasglannaich na h-uile
+ Spama
+ Mearachd an teisteanais aig %s
+ Thoir sùil air roghainnean an fhrithealaiche agad
+ Dh’fhàillig an dearbhadh
+ Dh’fhàillig dearbhadh a’ chunntais %s. Ùraich roghainnean an fhrithealaiche agad.
+ A’ toirt sùil airson post: %s:%s
+ A’ toirt sùil airson post
+ A’ cur a’ phuist: %s
+ A’ cur a’ phuist
+ :
+ Sioncronaich (Put)
+ Teachdaireachdan
+ An corr
+ A-steach
+ A-mach
+ Dreachdan
+ Sgudal
+ Air a chur
+ Cha deach cuid dhe na teachdaireachdan a chur
+ Cuir an comas logadh airson dì-bhugachadh
+ Logaich fiosrachadh diagnosachd a bharrachd
+ Logaich fiosrachadh dìomhair
+ Dh’fhaoidte gun leig seo ris faclan-faire sna logaichean.
+ Luchdaich barrachd theachdaireachdan
+ Gu:%s
+ Cuspair
+ Teacsa na teachdaireachd
+ Eàrr-sgrìobhadh
+ -------- An teachdaireachd thùsail --------
+ Cuspair:
+ Air a chur:
+ O:
+ Gu:
+ Cc:
+ Sgrìobh %s:
+ Sgrìobh %2$s%1$s:
+ Feumaidh tu co-dhiù aon neach a chur ris a gheibh e.
+ Tha rud ann an raon nam faightearan a tha leth-chrìochnaichte!
+ Cha b’ urrainn dhuinn seòladh puist-d a lorg dhan neach-aithne seo.
+ Chan urrainn dhuinn cuid dhe na ceanglachain a shìneadh air adhart oir cha deach an luchdadh a-nuas.
+ Cha ghabh an teachdaireachd a shìneadh air adhart o nach deach a h-uile ceanglachan aice a luchdadh a-nuas.
+ Gabh a-staigh às-earrann na teachdaireachd
+ Thoir an às-earrann air falbh
+ Deasaich an às-earrann
+ Thoir an ceanglachan air falbh
+ O: %s <%s>
+ Gu:
+ Cc:
+ Bcc:
+ Fosgail
+ Sàbhail
+ Cha b’ urrainn dhuinn an ceanglachan a shàbhaladh.
+ Seall na dealbhan
+ Chan urrainn dhuinn aplacaid a lorg a sheallas %s.
+ Luchdaich a-nuas an teachdaireachd shlàn
+ Chan urrainn dhuinn an teachdaireachd a shealltainn
+ slighe %1$s
+
+ Chaidh gach bann-cinn a luchdadh a-nuas ach chan eil bann-cinn eile ann a ghabhas a shealltainn.
+ Cha b’ urrainn dhuinn bannan-cinn a bharrachd fhaighinn on stòr-dàta no o fhrithealaiche a’ phuist.
+ Barrachd on t-seòladair seo
+ O %s
+ Dì-bhugaich / Falamhaich bodhaig na teachdaireachd
+ Chaidh an teachdaireachd a thilgeil air falbh
+ Chaidh an teachdaireachd a shàbhaladh mar dhreachd
+ Seall na rionnagan
+ Tha rionnagan a’ comharradh teachdaireachdan le bratach
+ Loidhnichean ro-sheallaidh
+ Seall ainmean nan seòladairean
+ Seall ainmean nan seòladairean seach na seòlaidhean puist-d aca
+ An seòladair os cionn a’ chuspair
+ Seall ainmean nan seòladairean os cionn a’ chuspair seach foidhe
+ Seall ainmean an luchd-aithne
+ Cleachd ainmean o aplacaid an luchd-aithne ma tha gin ann
+ Cuir dathan air an luchd-aithne
+ Cuir dathan air ainmean ann an liosta an luchd-aithne agad
+ Cruthan-clò le leud socraichte
+ Cleachd cruth-clò le leud socraichte nuair a thèid teachdaireachd ann an teacsa lom a shealltainn
+ Fèin-fhreagair teachdaireachdan
+ Crùb teachdaireachdan ach am freagair iad ris an sgrìn
+ Till gun liosta an dèidh sguabaidh às
+ Till gun liosta an dèidh teachdaireachd a sguabadh às
+ Seall an ath-theachdaireachd an dèidh sguabaidh às
+ Seall an ath-theachdaireachd a ghnàth an dèidh teachdaireachd a sguabadh às
+ Dearbh gnìomhan
+ Seall còmhradh uair sam bith a nì thu gnìomh sònraichte
+ Sguab às
+ Sguab às an fheadhainn le rionnag (ann an sealladh nan teachdaireachdan)
+ Spama
+ Tilg an teachdaireachd air falbh
+ Comharraich gun deach gach teachdaireachd a leughadh
+ Sguab às (on bhrath)
+ Falaich cliant a’ phuist
+ Thoir air falbh an raon Mail User-Agent o bhannan-cinn phost
+ Falaich an roinn-tìde
+ Cleachd UTC an àite na roinn-tìde ionadail ann am bannan-cinn phost is fhreagairtean
+ Seall am putan “Sguab às”
+ Chan ann idir
+ Airson brath aon teachdaireachd
+ An-còmhnaidh
+ Brathan air an sgrìn-ghlasaidh
+ Na seall brathan air an sgrìn-ghlasaidh
+ Ainm na h-aplacaid
+ Co mheud teachdaireachd is seòladair
+ An aon rud nuair nach bi an sgrìn glaiste
+ Amannan sàmhach
+ Cuir seirm, crith is boillsgeadh à comas rè na h-oidhche
+ Cuir na brathan à comas
+ Cuir na brathan à comas buileach rè nan amannan sàmhach
+ Tòisichidh an t-àm sàmhach
+ Thig an t-àm sàmhach gu crìoch
+ Suidhich cunntas ùr
+ Seòladh puist-d
+ Facal-faire
+ Seall am facal-faire
+
+ Dearbh cò thusa
+ Suidheachadh a làimh
+
+ A’ faighinn fiosrachadh a’ chunntais…
+ A’ sgrùdadh roghainnean an fhrithealaiche a-steach…
+ A’ sgrùdadh roghainnean an fhrithealaiche a-mach…
+ ’Ga dhearbhadh…
+ A’ faighinn roghainnean a’ chunntais…
+ A’ sgur dheth…
+ Cha mhòr deiseil!
+ Thoir ainm air a’ chunntas seo
+ Cuir a-steach d’ ainm (chithear seo ann an teachdaireachdan a thèid a-mach):
+ Seòrsa a’ chunntais
+ Dè seòrsa cunntas a tha seo\?
+ POP3
+ IMAP
+ Facal-faire àbhaisteach
+ Facal-faire, ’ga chur gun tèarainteachd
+ Facal-faire crioptaichte
+ Teisteanas a’ chliant
+ Roghainnean an fhrithealaiche a-steach
+ Ainm-cleachdaiche
+ Facal-faire
+ Teisteanas a’ chliant
+ Frithealaiche POP3
+ Frithealaiche IMAP
+ Frithealaiche Exchange
+ Port
+ Tèarainteachd
+ Dearbhadh
+ Chan eil gin
+ SSL/TLS
+ STARTTLS
+ Chan eil “%1$s = %2$s” dligheach mu choinneamh “%3$s = %4$s”
+ Nuair a sguabas mi teachdaireachd às
+ Na sguab às an fhrithealaiche e
+ Sguab às an fhrithealaiche e
+ Comharraich air an fhrithealaiche gun deach a leughadh
+ Cleachd dùmhlachadh air lìonra:
+ Mobile
+ WiFi
+ Eile
+ Ma sguabas mi às teachdaireachd, sguab às an fhrithealaiche e
+ Sa bhad
+ Aig an ath-cheasnachadh
+ A làimh
+ Mothaich dha ainm-spàs IMAP gu fèin-obrachail
+ Ro-leasachan slighe IMAP
+ Pasgan nan dreachdan
+ Pasgan a’ phuist chuirte
+ Pasgan an sgudail
+ Pasgan nan tasg-lann
+ Pasgan an spama
+ Na seall ach pasganan le fo-sgrìobhadh
+ Leudaich am pasgan gu fèin-obrachail
+ Slighe OWA
+ Roghainneil
+ Slighe an dearbhaidh
+ Roghainneil
+ Alias a’ bhogsa-phuist
+ Roghainneil
+ Roghainnean an fhrithealaiche a-mach
+ Frithealaiche SMTP
+ Port
+ Tèarainteachd
+ Iarr clàradh a-steach.
+ Ainm-cleachdaiche
+ Facal-faire
+ Dearbhadh
+ Chan eil “%1$s = %2$s” dligheach mu choinneamh “%3$s = %4$s”
+ Suidheachadh mì-dhligheach: %s
+ Roghainnean a’ chunntais
+ Dùmhlaich an cunntas
+ Dè cho tric ’s a dh’iarras sinn am post\?
+ Chan ann idir
+ Gach cairteal na h-uarach
+ Gach leth-uair a thìde
+ Gach uair a thìde
+ Gach 2 uair a thìde
+ Gach 3 uairean a thìde
+ Gach 6 uairean a thìde
+ Gach 12 uair a thìde
+ Gach 24 uair a thìde
+ Cuir post putaidh an comas airson a’ chunntais seo
+ Ma bheir am frithealaiche agad taic dha, nochdaidh teachdaireachdan ùra sa bhad. Faodaidh buaidh mhòr (math no dona) a bhith aig an roghainn seo air dèanadas.
+ Ath-nuadhaich an ceangal IDLE
+ Gach 2 mhionaid
+ Gach 3 mionaidean
+ Gach 6 mionaidean
+ Gach 12 mhionaid
+ Gach 24 mionaid
+ Gach 36 mionaid
+ Gach 48 mionaid
+ Gach uair a thìde
+ Thoir brath dhomh nuair a ruigeas post
+ Thoir brath dhomh nuair a thathar a’ toirt sùil airson post
+ Co mheud teachdaireachd a thèid a shealltainn
+ 10 teachdaireachdan
+ 25 teachdaireachd
+ 50 teachdaireachd
+ 100 teachdaireachd
+ 250 teachdaireachd
+ 500 teachdaireachd
+ 1,000 teachdaireachd
+ 2,500 teachdaireachd
+ 5,000 teachdaireachd
+ 10,000 teachdaireachd
+ na h-uile teachdaireachd
+ Chan urrainn dhut lethbhreac a dhèanamh de theachdaireachd, no a ghluasad, mur eil e sioncronaichte leis an fhrithealaiche
+ Cha b’ urrainn dhuinn an suidheachadh a choileanadh
+ Tha an t-ainm-cleachdaiche no facal-faire ceàrr.
+\n(%s)
+ Nochd am frithealaiche teisteanas SSL nach eil dligheach. Tachraidh seo uaireannan ma chaidh am frithealaiche a dhroch-rèiteachadh. Air neo dh’fhaoidte gu bheil cuideigin airson briseadh a-steach ort no air frithealaiche a’ phuist agad. Mur eil thu cinnteach dè tha a’ tachairt, thoir gnogag air “Diùlt” is cuir fios gu na daoine a stiùireas frithealaiche a’ phuist agad.
+\n
+\n(%s)
+ Chan urrainn dhuinn ceangal ris an fhrithealaiche.
+\n(%s)
+ Deasaich am fiosrachadh
+ Lean air adhart
+ Adhartach
+ Roghainnean a’ chunntais
+ Brathan mu phost ùr
+ Pasganan a chuireas brath
+ Na h-uile
+ Pasganan na 1ᵈ ìre a-mhàin
+ Pasganan na 1ᵈ is na 2ⁿᵃ ìre
+ Gach aon ach pasganan na 2ⁿᵃ ìre
+ Chan eil gin
+ Brathan sioncronachaidh
+ An seòladh puist-d agad
+ Thoir brath dhomh air bàr na staide nuair a ruigeas post
+ Thoir brath dhomh air bàr na staide nuair a thathar a’ toirt sùil airson post
+ Gabh a-staigh post a tha a’ dol a-mach
+ Seall brath nuair a bhios mi air teachdaireachd a chur
+ Luchd-aithne a-mhàin
+ Na seall brath ach ma thig teachdaireachd o neach-aithne agam
+ Comharraich gun deach a leughadh nuair a dh’fhosglas mi i
+ Comharraich gun deach an teachdaireachd a leughadh nuair a dh’fhosglas mi i a choimhead air
+ Seall dealbhan an-còmhnaidh
+ Na seall idir
+ On luchd-aithne
+ O dhuine sam bith
+ Cur a’ phuist
+ Cuir às-earrann dhen teachdaireachd ris an fhreagairt
+ Gabh a-staigh an teachdaireachd thùsail ’nad theachdaireachd.
+ Freagair às dèidh na h-às-earrainn
+ Nochdaidh an teachdaireachd thùsail os cionn do fhreagairt.
+ Spìon eàrr-sgrìobhadh sam bith às ann am freagairt
+ Thèid earr-sgrìobhaidhean a thoirt air falbh o às-earrannan theachdaireachdan
+ Fòrmat na teachdaireachd
+ Teacsa lom (thoir air falbh dealbhan is fòrmatadh)
+ HTMP (glèidh na dealbhan is am fòrmatadh)
+ Fèin-obrachail
+ Seall Cc/Bcc an-còmhnaidh
+ Cuidhteas-leughaidh
+ Iarr cuidhteas-leughaidh an-còmhnaidh
+ Stoidhle nan às-earrannan ann am freagairtean
+ Le ro-leasachan (mar Gmail)
+ Bann-cinn (mar Outlook)
+ Roghainnean coitcheann
+ A’ leughadh post
+ A’ faighinn post
+ Pasganan
+ Ro-leasachan na h-às-earrainn
+ Crioptografachd
+ Aplacaid OpenPGP
+ An iuchair agam
+ Dè cho tric ’s a dh’iarras sinn am post\?
+ Dath a’ chunntais
+ Dath soillearachadh a’ chunntais seo a chithear ann am pasganan is liosta nan cunntas
+ Dath LED nam brath
+ An dath a bhios air LED an uidheim agad dhan chunntas seo
+ Meud a’ phasgain ionadail
+ Faigh teachdaireachdan suas ri
+ 1KB
+ 2KB
+ 4KB
+ 8KB
+ 16KB
+ 32KB
+ 64KB
+ 128KB
+ 256KB
+ 512KB
+ 1MB
+ 2MB
+ 5MB
+ 10MB
+ meud sam bith (gun chrìoch)
+ Sioncronaich teachdaireachdan
+ o àm sam bith (gun chrìoch)
+ on diugh
+ on dè
+ on bhòin-dè
+ on t-seachdain seo chaidh
+ on chola-deug seo chaidh
+ o na 3 seachdainean seo chaidh
+ on mhìos seo chaidh
+ on 2 mhìos seo chaidh
+ o na 3 mìosan seo chaidh
+ on na 6 mìosan seo chaidh
+ on uiridh
+ Na pasganan a thèid a shealltainn
+ Na h-uile
+ Pasganan na 1ᵈ ìre a-mhàin
+ Pasganan na 1ᵈ is na 2ⁿᵃ ìre
+ Gach aon ach pasganan na 2ⁿᵃ ìre
+ Na pasganan a thèid a cheasnachadh
+ Na h-uile
+ Pasganan na 1ᵈ ìre a-mhàin
+ Pasganan na 1ᵈ is na 2ⁿᵃ ìre
+ Gach aon ach pasganan na 2ⁿᵃ ìre
+ Chan eil gin
+ Na pasganan putaidh
+ Na h-uile
+ Pasganan na 1ᵈ ìre a-mhàin
+ Pasganan na 1ᵈ is na 2ⁿᵃ ìre
+ Gach aon ach pasganan na 2ⁿᵃ ìre
+ Chan eil gin
+ Pasganan dhan a chuirear lethbhreacan/dhan a ghluaisear
+ Na h-uile
+ Pasganan na 1ᵈ ìre a-mhàin
+ Pasganan na 1ᵈ is na 2ⁿᵃ ìre
+ Gach aon ach pasganan na 2ⁿᵃ ìre
+ Sioncronaich sguabadh às air an fhrithealaiche
+ Thoir air falbh teachdaireachdan a chaidh a sguabadh às an fhrithealaiche
+ Roghainnean a’ phasgain
+ Seall aig a’ bhàrr sa bhuidheann
+ Seall faisg air bàrr liosta nam pasganan
+ Ìre taisbeanadh a’ phasgain
+ Gun ìre
+ 1ᵈ ìre
+ 2ⁿᵃ ìre
+ Ìre nam pasgan a thèid a cheasnachadh
+ Chan eil gin
+ 1ᵈ ìre
+ 2ⁿᵃ ìre
+ Co-ionnann ris an ìre taisbeanaidh
+ Ìre putadh a’ phasgain
+ Gun ìre
+ 1ᵈ ìre
+ 2ⁿᵃ ìre
+ Co-ionnann ris an ìre sioncronachaidh
+ Ìre brathan a’ phasgain
+ Gun ìre
+ 1ᵈ ìre
+ 2ⁿᵃ ìre
+ Co-ionnann ris an ìre putaidh
+ Falamhaich na teachdaireachdan ionadail
+ Am frithealaiche a-steach
+ Rèitich frithealaiche a’ phuist a-steach
+ Am frithealaiche a-mach
+ Rèitich frithealaiche a’ phuist a-mach (SMTP)
+ Ainm a’ chunntais
+ D’ ainm
+ Brathan
+ Crith
+ Dèan crith nuair a ruigeas post
+ Pàtranan crith
+ bun-roghainn
+ pàtran 1
+ pàtran 2
+ pàtran 3
+ pàtran 4
+ pàtran 5
+ Crith a-rithist
+ Seirm a’ phuist ùir
+ Boillsg an LED
+ Boillsg an LED nuair a ruigeas post
+ Roghainnean sgrìobhadh theachdaireachdan
+ Bun-roghainnean sgrìobhaidh
+ Suidhich bun-roghainnean “O”, “Bcc” agus an eàrr-sgrìobhaidh
+ Stiùirich na dearbh-aithnean
+ Suidhich seòlaidhean “O” is eàrr-sgrìobhaidhean eadar-dhealaichte
+ Stiùirich na dearbh-aithnean
+ Stiùirich an dearbh-aithne
+ Deasaich an dearbh-aithne
+ Sàbhail
+ Dearbh-aithne ùr
+ Cuir Bcc de gach teachdaireachd gu
+ Deasaich
+ Gluais suas
+ Gluais sìos
+ Gluais suas / dèan a’ bhun-roghainn dheth
+ Thoir air falbh
+ Tuairisgeul na dearbh-aithne
+ (Roghainneil)
+ D’ ainm
+ (Roghainneil)
+ Seòladh puist-d
+ (Riatanach)
+ An seòladh dhan chuirear freagairtean
+ (Roghainneil)
+ An t-eàrr-sgrìobhadh
+ (Roghainneil)
+ Cleachd eàrr-sgrìobhadh
+ An t-eàrr-sgrìobhadh
+ An dearbh-aithne thòiseachail
+ Tagh dearbh-aithne
+ Cuir mar
+ Chan urrainn dhut an aon dearbh-aithne agad a thoirt air falbh
+ Chan urrainn dhut dearbh-aithne a chleachdadh gun seòladh puist-d
+ Na teachdaireachdan as sine an toiseach
+ Na teachdaireachdan as ùire an toiseach
+ Aibidileach a-rèir a’ chuspair
+ Aibidileach contrarra a-rèir a’ chuspair
+ Aibidileach a-rèir an t-seòladair
+ Aibidileach contrarra a-rèir an t-seòladair
+ Teachdaireachdan le rionnag an toiseach
+ Teachdaireachdan gun rionnag an toiseach
+ Teachdaireachdan gun leughadh an toiseach
+ Teachdaireachdan a chaidh an leughadh an toiseach
+ Teachdaireachdan le ceanglachain an toiseach
+ Teachdaireachdan gun cheanglachain an toiseach
+ Seòrsaich a-rèir…
+ Ceann-là
+ Ruigsinn
+ Cuspair
+ Seòladair
+ Rionnag
+ Air a leughadh/gun leughadh
+ Ceanglachain
+ Thoir an cunntas air falbh
+ Teisteanas nach aithne dhuinn
+ Gabh ris an iuchair
+ Diùlt an iuchair
+ Del (no D) – Sguab às
+\nR – Freagair
+\nA – Freagair a h-uile
+\nC – Sgrìobh
+\nF – Sìn air adhart
+\nM – Gluais
+\nV – Cuir san tasg-lann
+\nY – Dèan lethbhreac
+\nZ – Cuir comharra gun deach/nach deach a leughadh
+\nG – Cuir rionnag ris
+\nO – Seòrsa an t-seòrsachaidh
+\nI – Òrdugh an t-seòrsachaidh
+\nQ – Till dha na pasganan
+\nS – Tagh/Dì-thagh
+\nJ no P – An teachdaireachd roimhpe
+\nK no N – An ath-theachdaireachd
+ Del (no D) – Sguab às
+\nC – Sgrìobh
+\nM – Gluais
+\nV – Cuir san tasg-lann
+\nY – Dèan lethbhreac
+\nZ – Cuir comharra gun deach/nach deach a leughadh
+\nG – Cuir rionnag ris
+\nO – Seòrsa an t-seòrsachaidh
+\nI – Òrdugh an t-seòrsachaidh
+\nQ – Till dha na pasganan
+\nS – Tagh/Dì-thagh
+ Ainm a’ phasgain anns a bheil
+ Seall pasganan…
+ Na h-uile pasgan
+ Pasganan na 1ᵈ ìre
+ Pasganan na 1ᵈ ⁊ na 2ⁿᵃ ìre
+ Falaich pasganan na 2ⁿᵃ ìre
+ Ionad an eàrr-sgrìobhaidh
+ Ron às-earrann dhen teachdaireachd
+ Às dèidh às-earrann dhen teachdaireachd
+ Cleachd ùrlar na h-aplacaid
+ Dorcha
+ Soilleir
+ Sealladh
+ Uile-choitcheann
+ Dì-bhugachadh
+ Prìobhaideachd
+ Lìonra
+ Eadar-ghabhail
+ Liosta nan cunntasan
+ Liostaichean theachdaireachdan
+ Teachdaireachdan
+ Ùrlar
+ Ùrlar sealladh nan teachdaireachdan
+ Ùrlar an sgrìobhaidh
+ Cànan
+ Ùrlair socraichte airson teachdaireachdan
+ Tagh ùrlar airson na teachdaireachd is tu a’ coimhead air
+ Cleachd ùrlair socraichte airson teachdaireachdan
+ Bun-roghainn an t-siostaim
+ Sioncronachadh sa chùlaibh
+ Chan ann idir
+ An-còmhnaidh
+ Ma tha cromag ri “Sioncronachadh fèin-obrachail”
+ Tagh na h-uile
+ An àireamh as motha a phasganan air an doirear sùil le putadh
+ 5 pasganan
+ 10 pasganan
+ 25 pasgan
+ 50 pasgan
+ 100 pasgan
+ 250 pasgan
+ 500 pasgan
+ 1,000 pasgan
+ Beòthachadh
+ Cleachd èifeachdan lèirsinneach leòmach
+ Seòladaireachd le putanan àirde na fuaime
+ Ann an seallaidhean theachdaireachdan
+ Ann an seallaidhean liostaichean
+ Seall an t-oll-bhogsa
+ %s%s
+ – Gun leughadh
+ Na h-uile teachdaireachd
+ Na h-uile teachdaireachd ann am pasgan so-luirg
+ An t-oll-bhogsa
+ Na h-uile teachdaireachd ann am pasganan co-aonaichte
+ Co-aonaich
+ Tha gach teachdaireachd ga shealltainn san oll-bhogsa
+ Na pasganan san dèanar lorg
+ Na h-uile
+ So-thaisbeanadh
+ Chan eil gin
+ Chan eil gin
+ Meud a’ chrutha-chlò
+ Rèitich meud a’ chrutha-chlò
+ Liosta nan cunntasan
+ Ainm a’ chunntais
+ Tuairisgeul a’ chunntais
+ Liostaichean phasganan
+ Ainm a’ phasgain
+ Staid a’ phasgain
+ Liostaichean theachdaireachdan
+ Cuspair
+ Seòladair
+ Ceann-là
+ Ro-shealladh
+ Teachdaireachdan
+ Seòladair
+ Gu
+ Cc
+ Bcc
+ Bannan-cinn a bharrachd
+ Cuspair
+ Ceann-là ’s àm
+ Bodhaig na teachdaireachd
+ %d%%
+ %1$s: %2$s
+ Sgrìobhadh theachdaireachdan
+ Raointean ion-chur teacsa
+ Bun-roghainn
+ As lugha
+ Beag bìodach
+ Nas lugha
+ Beag
+ Meadhanach
+ Mòr
+ Nas motha
+ Cha deach aplacaid iomchaidh a lorg dhan ghnìomh seo.
+ Dh’fhàillig a chur: %s
+ A bheil thu airson dreachd na teachdaireachd a shàbhaladh\?
+ A bheil thu airson an teachdaireachd seo a shàbhaladh no a thilgeil air falbh\?
+ A bheil thu airson an teachdaireachd seo a thilgeil air falbh\?
+ A bheil thu cinnteach gu bheil thu airson an teachdaireachd seo a thilgeil air falbh\?
+ Tagh teacsa airson lethbhreac a dhèanamh dheth.
+ Dearbh an sguabadh às
+ A bheil thu cinnteach gu bheil thu airson an teachdaireachd seo a sguabadh às\?
+
+ A bheil thu cinnteach gu bheil thu airson %1$d teachdaireachd a sguabadh às\?
+ A bheil thu cinnteach gu bheil thu airson %1$d theachdaireachd a sguabadh às\?
+ A bheil thu cinnteach gu bheil thu airson %1$d teachdaireachdan a sguabadh às\?
+ A bheil thu cinnteach gu bheil thu airson %1$d teachdaireachd a sguabadh às\?
+
+ Tha
+ Chan eil
+ Comharraich gun deach gach teachdaireachd a leughadh
+ A bheil thu airson comharradh gun deach na teachdaireachdan uile seo a leughadh\?
+ Tha
+ Chan eil
+ Dearbh a ghluasad do phasgan an spama
+
+ A bheil thu cinnteach gu bheil thu airson %1$d teachdaireachd a ghluasad gu pasgan an spama\?
+ A bheil thu cinnteach gu bheil thu airson %1$d theachdaireachd a ghluasad gu pasgan an spama\?
+ A bheil thu cinnteach gu bheil thu airson %1$d teachdaireachdan a ghluasad gu pasgan an spama\?
+ A bheil thu cinnteach gu bheil thu airson %1$d teachdaireachd a ghluasad gu pasgan an spama\?
+
+ Tha
+ Chan eil
+ A’ luchdadh a-nuas a’ cheanglachain
+ »
+ ›
+ An corr
+ Às-phortaich
+ Co-roinn
+ Ag às-phortadh nan roghainnean…
+ Chaidh na roghainnean às-phortadh
+ Cha b’ urrainn dhuinn na roghainnean às-phortadh
+ Ion-phortaich na roghainnean
+ Ion-phortaich
+ Cha b’ urrainn dhuinn roghainn sam bith ion-phortadh o: %s
+ Ion-phortaich na roghainnean
+ Ag ion-phortadh nan roghainnean…
+ Seall co mheud a tha gun leughadh ann an…
+ Cunntas
+ An cunntas dhan dèid na teachdaireachdan gun leughadh a chunntadh
+ An t-oll-bhogsa
+ Cunntas pasgain
+ Seall cunntas nan teachdaireachdan gun leughadh air aon phasgan a-mhàin
+ Pasgan
+ Am pasgan dhan dèid na teachdaireachdan gun leughadh a chunntadh
+ Deiseil
+ %1$s – %2$s
+ Cha deach cunntas a thaghadh
+ Cha deach pasgan a thaghadh
+ Gun teacsa
+ Fosgail an ceangal
+ Co-roinn an ceangal
+ Cuir lethbhreac dhen cheangal air an stòr-bhòrd
+ Ceangal
+ Dealbh
+ Seall an dealbh
+ Sàbhail an dealbh
+ Luchdaich a-nuas an dealbh
+ Cuir lethbhreac de URL an deilbh air an stòr-bhòrd
+ URL an deilbh
+ Cuir fòn gun àireamh seo
+ Sàbhail san luchd-aithne
+ Cuir lethbhreac dhen àireamh air an stòr-bhòrd
+ Àireamh fòn
+ Cuir am post
+ Sàbhail san luchd-aithne
+ Cuir lethbhreac dhen t-seòladh air an stòr-bhòrd
+ Seòladh puist-d
+ Na h-uile
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1,000
+ Crìoch lorg an fhrithealaiche
+ A’ cur na ceiste dhan fhrithealaiche
+
+ A’ faighinn %d toradh
+ A’ faighinn %d thoradh
+ A’ faighinn %d toraidhean
+ A’ faighinn %d toradh
+
+
+ A’ faighinn %1$d à %2$d toradh
+ A’ faighinn %1$d à %2$d thoradh
+ A’ faighinn %1$d à %2$d toraidhean
+ A’ faighinn %1$d à %2$d toradh
+
+ Dh’fhàillig an lorg cèin
+ Lorg
+ Cuir an comas lorg air an fhrithealaiche
+ Lorg teachdaireachdan air an fhrithealaiche a bharrachd air an fheadhainn air an uidheam agad
+ Lorg teachdaireachdan air an fhrithealaiche
+ Feumaidh tu ceangal ris an lìonra mus urrainn dhut lorg a dhèanamh air an fhrithealaiche.
+ Atharraich an dath nuair a chaidh a leughadh
+ Nochdaidh cùlaibh eile a sheallas gun deach an teachdaireachd a leughadh
+ Sealladh ann an snàithleanan
+ Buidhnich teachdaireachdan ann an còmhraidhean
+ Ag àrdachadh nan stòr-dàta
+ Ag àrdachadh nan stòr-dàta…
+ Ag àrdachadh stòr-dàta a’ chunntais “%s”
+ Seall air sgrìn sgoilte
+ An-còmhnaidh
+ Chan ann idir
+ Nuair a tha e ’ga shealltainn mar dreach-tìre
+ Tagh teachdaireachd air an taobh chlì
+ Seall dealbhan an luchd-aithne
+ Seall dealbhan an luchd-aithne ann an liosta nan teachdaireachd
+ Comharraich gun deach iad uile a leughadh
+ Cuir dathan air dealbhan an luchd-aithne
+ Cuir dathan air dealbhan an luchd-aithne a tha a dhìth
+ Gnìomhan theachdaireachdan ri fhaicinn
+ Seall na gnìomhan a thagh thu ann an clàr-taice sealladh na teachdaireachd
+ A’ luchdadh a’ cheanglachain…
+ A’ cur na teachdaireachd
+ A’ sàbhaladh an dreachd
+ A’ faighinn a’ cheanglachain…
+ Cha b’ urrainn dhuinn dearbhadh a dhèanamh. Chan eil am frithealaiche a’ leigeil ris a bheil e comasach air SASL EXTERNAL. Dh’fhaoidte gu bheil duilgheadas le teisteanas a’ chliant (ro aosta, ùghdarras neo-aithnichte) no duilgheadas eile leis an rèiteachadh.
+
+ Cleachd teisteanas a’ chliant
+ Chan eil teisteanas aig a’ chliant
+ Thoir air falbh taghadh teisteanas a’ chliant
+ Cha b’ urrainn dhuinn teisteanas a’ chliant fhaighinn dhan alias “%s”
+ Roghainnean adhartach
+ Dh’fhalbh an ùine air teisteanas a’ chliant “%1$s” no chan eil e dligheachd fhathast (%2$s)
+
+ *Crioptaichte*
+ Cuir ris on luchd-aithne
+ Cc
+ Bcc
+ Gu
+ O
+ <Faightear nach aithne dhuinn>
+ Dachaigh
+ Obair
+ Eile
+ Mobile
+ Cha deach pasgan do dhreachdan a rèiteachadh dhan chunntas seo!
+ Cha deach iuchair a rèiteachadh dhan chunntas seo! Thoir sùil air na roghainnean agad.
+ Tha solaraiche a’ chrioptachaidh a’ cleachdadh tionndadh nach eil co-chòrdail. Thoir sùil air na roghainnean agad!
+ Chan urrainn dhuinn ceangal ri solaraiche a’ chrioptachaidh, thoir sùil air na roghainnean no thoir gnogag air ìomhaigheag a’ chrioptachaidh airson feuchainn ris a-rithist!
+ Chaidh inntrigeadh do sholaraiche a’ chrioptachaidh a dhiùltadh, thoir gnogag air ìomhaigheag a’ chrioptachaidh airson feuchainn ris a-rithist!
+ Chan eil taic ri ceanglachain sa mhodh PGP/INLINE!
+ Cuir PGP/INLINE an comas
+ Cuir PGP/INLINE à comas
+ Cuir PGP Sign-Only an comas
+ Cuir PGP Sign-Only à comas
+ Am modh PGP/INLINE
+ Tha am post-d seo ’ga chur san fhòrmat PGP/INLINE.
+\nCha bu chòir dhut seo a dhèanamh ach airson co-chòrdalachd:
+ Tha cuid a chliantan ann nach cuir taic ach ris an fhòrmat seo
+ Dh’fhaoidte gum bris soidhneadh rè an tar-chuir
+ Chan eil taic ri ceanglachain
+ Tha mi agaibh!
+ Cuir à comas
+ Cùm an comas
+ Tha mi agaibh!
+ Cuir à comas
+ Cùm an comas
+ Am modh PGP Sign-Only
+ Sa mhodh seo, thèid an iuchair PGP agad a chleachdadh airson soidhneadh crioptografach de phost-d gun chrioptachadh a chruthachadh.
+ Cha chrioptaich seo am post-d ach dearbhaidh e gun deach a chur on iuchair agad.
+ Dh’fhaoidte gum bris soidhnidhean nuair a chuireas tu rud gu liosta-phuist.
+ Dh’fhaoidte gun nochd soidhnidhean mar “signature.asc” ann an cuid a chliantan.
+ Bidh soidhneadh am broinn teachdaireachd chrioptaichte an-còmhnaidh.
+ Teacsa lom
+ bha mearachd san t-soidhneadh ceann gu ceann
+ chan obraich pròiseasadh an t-soidhnidh mus deach an teachdaireachd a luchdadh a-nuas gu slàn
+ tha soidhneadh ceann gu ceann ’na bhroinn ris nach cuirear taic
+ Tha an teachdaireachd crioptaichte ach ann am fòrmat ris nach eil taic.
+ Tha an teachdaireachd crioptaichte ach sguireadh dhen dì-chrioptachadh.
+ Teacsa lom soidhnichte ceann gu ceann
+ o neach-soidhnidh dearbhte
+ Teacsa lom soidhnichte
+ ach cha robh an iuchair ceann gu ceann a-rèir an t-seòladair
+ ach dh’fhalbh an ùine air an iuchair ceann gu ceann
+ ach chaidh an iuchair ceann gu ceann a chùl-ghairm
+ ach chan eilear a’ meas gu bheil an iuchair ceann gu ceann tèarainte
+ o iuchair ceann gu ceann nach aithne dhuinn
+ Crioptaichte
+ ach thachair duilgheadas leis an dì-chrioptachadh
+ chan obraich an dì-chrioptachadh mus deach an teachdaireachd a luchdadh a-nuas gu slàn
+ ach cha deach aplacaid crioptachaidh a rèiteachadh
+ Crioptaichte
+ ach chan ann ceann gu ceann
+ Crioptaichte ceann gu ceann
+ o sheòladair a chaidh a dhearbhadh
+ Crioptaichte
+ o iuchair ceann gu ceann nach aithne dhuinn
+ ach cha robh an iuchair ceann gu ceann a-rèir an t-seòladair
+ ach dh’fhalbh an ùine air an iuchair ceann gu ceann
+ ach chaidh an iuchair ceann gu ceann a chùl-ghairm
+ ach chan eilear a’ meas gu bheil an iuchair ceann gu ceann tèarainte
+ ach tha mearachdan san dàta ceann gu ceann
+ ach chan eilear a’ meas gu bheil an crioptachadh tèarainte
+ Ceart ma-thà
+ Seall an neach-soidhnidh
+ Seall an seòladair
+ Mion-fhiosrachadh
+ Thoir a’ ghlas dheth
+ Cha deach a’ phàirt seo a chrioptachadh is dh’fhaoidte gu bheil e neo-thèarainte.
+ Ceanglachan gun dìon
+ ’Ga luchdadh…
+ Sguireadh dhen dì-chrioptachadh.
+ Feuch ris a-rithist
+ Feumaidh tu an teachdaireachd chrioptaichte a luchdadh a-nuas mus gabh a dhì-chrioptachadh.
+ Mearachd a’ dì-chrioptachadh a’ phuist-d
+ Chan eil taic ri caractaran sònraichte aig an àm seo!
+ Mearachd a’ parsadh an t-seòlaidh!
+ Chan eil crioptachadh ri fhaighinn sa mhodh anns nach dèanar ach soidhneadh!
+ Teacsa gun soidhneadh
+ Rabhadh mu chleachdadh APG
+ Chan eilear a’ leasachadh APG tuilleadh!
+ Ri linn sin, chan eil taic ri APG aig post K-9 tuilleadh.
+ Sguir daoine dhen obair-leasachaidh aig toiseach 2014
+ Tha duilgheadasan tèarainteachd ann nach deach an càradh
+ Briog an-seo airson barrachd fiosrachaidh.
+ Tha mi agaibh!
+ APG
+ Tha am post-d seo crioptaichte
+ Chaidh am post-d seo a chrioptachadh le OpenPGP.
+\nFeumaidh tu aplacaid a tha comasach air OpenPGP a stàladh is a rèiteachadh mus urrainn dhut a leughadh.
+ Tagh aplacaid OpenPGP
+ Liosta theachdaireachdan puist
+ A’ luchdadh nan teachdaireachdan…
+ Cha b’ urrainn dhuinn liosta nam pasgan fhaighinn
+ Mearachd a’ faighinn staid an fhaighteir on t-solaraiche OpenPGP!
+ Cha ghabh a chrioptachadh
+ Cha chuir gach faightear a thagh thu taic ris a’ ghleus seo!
+ Cuir crioptachadh an comas
+ Cuir crioptachadh à comas
+ Ma chrioptaicheas tu teachdaireachd, nì sin cinnteach nach leugh duine sam bith ach am faightear i.
+ Cha nochd an crioptachadh ach ma chuireas a h-uile faightear taic ris agus ma fhuair thu post-d uapa roimhe.
+ Toglaich an crioptachadh le briogadh air an ìomhaigheag seo.
+ Tha mi agaibh
+ Air ais
+ Cuir crioptachadh à comas
+ Crioptachadh OpenPGP
+ Modh co-dhàimh Autocrypt
+ Modh co-dhàimh Autocrypt
+ Mar as trice, thèid teachdaireachdan a chrioptachadh ma thagh thu sin no ma chuireas tu freagairt gu teachdaireachd chrioptaichte.
+ Ma chuireas an dà chuid an seòladair ’s am faightear modh na co-dhàimh air, thèid an crioptachadh mar bhun-roghainn.
+ Briog an-seo airson barrachd fiosrachaidh.
+ Roghainnean coitcheann
+ Teachdaireachd suidheachaidh Autocrypt
+ Teachdaireachd suidheachaidh Autocrypt
+ Fosgail
+ Dùin
+
+
diff --git a/app/ui/legacy/src/main/res/values-gl-rES/strings.xml b/app/ui/legacy/src/main/res/values-gl-rES/strings.xml
index e092cf44f613d9c9c9f6e7695a5a4a002642a972..442c77b2abb7025bda8ab382789671eec56abfc5 100644
--- a/app/ui/legacy/src/main/res/values-gl-rES/strings.xml
+++ b/app/ui/legacy/src/main/res/values-gl-rES/strings.xml
@@ -81,7 +81,7 @@
Engadir anexoBaleirar papeleiraPurgar
- About
+ Acerca deAxustes(sen asunto)
@@ -181,11 +181,7 @@
LixoDesbotar mensaxeEliminar (das notificacións)
- Remove Mail User-Agent from mail headers
- Agochar asunto nas notificacións
- Nunca
- Cando o dispositivo está bloqueado
- Sempre
+ Quitar o User-Agent K-9 das cabeceiras do correoMostrar botón \'Eliminar\'NuncaPara notificacións dunha mensaxe
@@ -193,7 +189,6 @@
Notificacións da pantalla de bloqueoSen notificacións na pantalla de bloqueoNome do aplicativo
- Total de mensaxes non lidasTotal de mensaxes e remitentesIgual que cando a pantalla non está bloqueadaTempo de silencio
@@ -206,6 +201,7 @@
Enderezo electrónicoContrasinalMostrar contrasinal
+
Configuración manualRecuperando información da conta\u2026
@@ -246,8 +242,6 @@
MóbilWifiOutras
- Almacenamento externo (tarxeta SD)
- Almacenamento internoEliminar mensaxes borradas no servidorInmediatamenteDurante a comprobación
@@ -321,8 +315,6 @@
ContinuarAvanzadoAxustes da conta
- Conta predefinida
- Establecer esta conta como predefinida para enviar correoNotificacións de correo novoNotificacións dos cartafolesTodo
diff --git a/app/ui/legacy/src/main/res/values-gl/strings.xml b/app/ui/legacy/src/main/res/values-gl/strings.xml
index d39611876f7c339430f9332ffb4c1c3a8b205285..5f602473c335a4250d6a89e12d943fd0e594d02c 100644
--- a/app/ui/legacy/src/main/res/values-gl/strings.xml
+++ b/app/ui/legacy/src/main/res/values-gl/strings.xml
@@ -209,10 +209,6 @@
Remove Mail User-Agent from mail headersOcultar zona horariaUtilizar UTC no lugar da hora local nos cabezallos do correo e as respostas
- Agochar asunto nas notificacións
- Nunca
- Cando o dispositivo está bloqueado
- SempreMostar botón \'Eliminar\'NuncaPara notificacións de mensaxes individuais
@@ -220,7 +216,6 @@
Notificacións en pantalla de bloqueoSen notificacións na pantalla de bloqueoNome do aplicativo
- Conta de mensaxes non lidasConta de mensaxes e remitentesIgual que cando non está bloqueada a pantallaTempo de Silencio
@@ -233,6 +228,7 @@
Enderezo de correoContrasinalMostrar contrasinal
+
Configuración ManualRecuperando información da conta\u2026
@@ -274,8 +270,6 @@
MóbilWi-FiOutras
- Almacenamento externo (SD)
- Almacenamento internoErradicar borradosInmediatamenteDurante comprobación
@@ -351,8 +345,6 @@
ContinuarAvanzadoConfiguración de conta
- Conta por defecto
- Enviar correo dende esta conta por defectoNotificar correo novoCartafoles de notificaciónsTodas
diff --git a/app/ui/legacy/src/main/res/values-hr/strings.xml b/app/ui/legacy/src/main/res/values-hr/strings.xml
index 1b3a522bee2ede47eac7e14ad2fc496b30f963bc..3230fa35a99fcb1f1998a45af3e9ce9f3c1503fb 100644
--- a/app/ui/legacy/src/main/res/values-hr/strings.xml
+++ b/app/ui/legacy/src/main/res/values-hr/strings.xml
@@ -229,10 +229,6 @@
Remove Mail User-Agent from mail headersSakrij vremensku zonuKoristi UTC umjesto lokalne vremenske zone u zaglavlju mail-a i zaglavlju odgovora
- Sakrij subjekt u obavijesti
- Nikad
- Kad je uređaj zaključan
- UvijekPrikaži gumb \'Obriši\'NikadaZa pojedinačnu obavijest poruke
@@ -240,7 +236,6 @@
Obavijesti Zaključanog ZaslonaNema obavijesti zaključanog zaslonaNaziv aplikacije
- Broj nepročitanih porukaBroj poruka i pošiljateljaIsto kao kod otključanog zaslonaTiho Vrijeme
@@ -253,6 +248,7 @@
Adresa E-PošteLozinkaPrikaži lozinku
+
Ručno postavljanjeDohvaćam informacije o računu\u2026
@@ -294,8 +290,6 @@
MobilnaWi-FiOstalo
- Vanjska pohrana (SD kartica)
- regularna unutarnja pohranaObriši izbrisane poruke sa poslužiteljaOdmahPrilikom provjere
@@ -371,8 +365,6 @@
NastaviNaprednoPostavke računa
- Zadani račun
- Pošalji poštu s ovog računa po zadanomNova obavijest pošteMapa obavijestiSvi
@@ -392,8 +384,6 @@
Označava poruke pročitanima nakon otvaranja za pregledOznači kao pročitano prilikom brisanjaOznači poruku kao pročitanu kada bude obrisana
- Postavke obavijesti
- Otvori sistemske postavke obavijestiUvijek prikaži slikeNeIz kontakata
diff --git a/app/ui/legacy/src/main/res/values-hu/strings.xml b/app/ui/legacy/src/main/res/values-hu/strings.xml
index 3b1bfeaad0b30ee94873c6f71860745c9aae2b63..d83a00eb8c8eeda90ec50bd71475a029078e9d64 100644
--- a/app/ui/legacy/src/main/res/values-hu/strings.xml
+++ b/app/ui/legacy/src/main/res/values-hu/strings.xml
@@ -1,42 +1,42 @@
-
-
-
- K-9 Mail
- K-9 fiókok
- K-9 olvasatlan
-
- The K-9 Dog Walkers
- Copyright 2008-%s The K-9 Dog Walkers. Egyes részek: Copyright 2006-%saz Android Nyílt Forráskódú Projekt.
- Forráskód
- Apache licenc, 2.0-s verzió
- Nyílt forráskódú projekt
- Weboldal
- Felhasználói fórum
- Födiverzum
- Twitter
- Programkönyvtárak
- Licenc
- Változásnapló
- A változásnapló betöltése sikertelen.
- Verzió: %s
- Újdonságok
- Friss változások megjelenítése az alkalmazás frissítésekor
- Tudja meg, hogy mik az újdonságok ebben a kiadásban
-
- Üdvözlet a K-9 Mail alkalmazásban.
-
+
+
+ Mail
+ fiókok
+ K-9 olvasatlan
+
+ The K-9 Dog Walkers
+ Copyright 2008-%s The K-9 Dog Walkers. Egyes részek: Copyright 2006-%saz Android Nyílt Forráskódú Projekt.
+ Forráskód
+ Apache licenc, 2.0-s verzió
+ Nyílt forráskódú projekt
+ Weboldal
+ Felhasználói fórum
+ Födiverzum
+ Twitter
+ Programkönyvtárak
+ Licenc
+ Változásnapló
+ A változásnapló betöltése sikertelen.
+ Verzió: %s
+ Újdonságok
+ Friss változások megjelenítése az alkalmazás frissítésekor
+ Tudja meg, hogy mik az újdonságok ebben a kiadásban
+
+ Üdvözlet a K-9 Mail alkalmazásban.
+
-A K-9 Mail egy hatékony, ingyenes e-mail alkalmazás Androidra.
+A Mail egy hatékony, ingyenes email alkalmazás Androidra.
A K-9 nem támogatja a legtöbb Hotmail-fiókot, és sok e-mail alkalmazáshoz hasonlóan, vannak furcsaságok a Microsoft Exchange kezelésében.
+
A Mail nem támogatja a legtöbb Hotmail-fiókot, és sok e-mail alkalmazáshoz hasonlóan, vannak furcsaságok a Microsoft Exchange kezelésében.
Hibajelentések beküldésével közreműködhet az új funkciókban, és kérdéseket tehet fel a
https://github.com/k9mail/k-9/ webcímen.
]]>
-
- -- \nAndroidos készülékről küldve K-9 Mail használatával. Elnézést a rövidségért.
-
- A(z) „%s” fiók eltávolításra kerül a K-9 Mail alkalmazásból.
-
- Szerzők
- Kiadási megjegyzések
- E-mailek olvasása
- Az alkalmazás olvashatja az emaileket.
- E-mailek törlése
- Az alkalmazás törölheti ez e-maileket.
- A K-9 Mail névjegye
- Fiókok
- Mappák
- Bővített
- Írás
- Válasz
- Válasz mindenkinek
- Továbbítás
- Továbbítás mellékletként
- Fiók választása
- Mappa választása
- Lekérés %s:%s%s
- Fejlécek beolvasása %s:%s%s
- %s%sküldése folyamatban van...
- Feldolgozás %s:%s%s
- \u0020%d/%d
- A szinkronizálás letiltásra került.
- %d kiválasztva
- Következő
- Előző
-
- OK
- Mégse
- Küldés
- Küldés újra
- A tárgy üres. Kattintás újra a küldés erőltetéséhez.
- Kijelölés
- Kijelölés törlése
- Válasz
- Válasz mindenkinek
- Törlés
- Archiválás
- Levélszemét
- Továbbítás
- Továbbítás mellékletként
- Szerkesztés új üzenetként
- Áthelyezés
- Áthelyezés a Piszkozatokhoz
- Küldés…
- Iktatás…
- Kész
- Elvetés
- Mentés piszkozatként
- Levél ellenőrzése
- Üzenetek küldése
- Mappalista frissítése
- Mappa keresése
- Fiók hozzáadása
- Írás
- Keresés
- Keresés mindenhol
- Keresési eredmények
- Beállítások
- Mappák kezelése
- Fiók beállításai
- Fiók eltávolítása
- Megjelölés olvasottként
- Megosztás
- Feladó kiválasztása
- Csillag hozzáadása
- Csillag eltávolítása
- Másolás
- Fejlécek megjelenítése
-
- Cím a vágólapra másolva
- A címek a vágólapra kerültek.
-
- Tárgy szöveg a vágólapra másolva
- Váltás sötét témára
- Váltás világos témára
- Megjelölés olvasatlanként
- Olvasási visszaigazolás
- Olvasási visszaigazolás lesz kérve
- Nem lesz olvasási visszaigazolás kérve
- Melléklet hozzáadása
- Lomtár ürítése
- Végleges törlés
- Névjegy
- Beállítások
-
- (Nincs tárgy)
- Nincs feladó
- Üzenetek betöltése\u2026
- Kapcsolódási hiba történt.
- Az üzenet nem található.
- Üzenetbetöltési hiba történt.
- Legfeljebb %d további betöltése
- %.1f GB
- %.1f MB
- %.1f kB
- %d B
- A(z) „%s” fiók tömörítésre került: %s=> %s
- A(z) „%s” fiók tömörítése folyamatban van.
- Új levél
-
- %d új üzenet
- %d új üzenet
-
- %d Olvasatlan (%s)
- + %1$d további: %2$s
- Válasz
- Megjelölés olvasottként
- Összes megjelölése olvasottként
- Törlés
- Összes törlése
- Archiválás
- Összes archiválása
- Levélszemét
- Tanúsítványhiba: %s
- Ellenőrizze a kiszolgálóbeállításokat.
- A hitelesítés sikertelen.
- A hitelesítés sikertelen: %s. Frissítse a kiszolgálóbeállításokat.
- Levelek ellenőrzése: %s:%s
- Levelek ellenőrzése
- Levél küldése: %s
- Levél küldése
- :
- Szinkronizálás (Leküldés)
- Az új levelekre várakozáskor jelenik meg
- Üzenetek
- Az üzenetekkel kapcsolatos értesítések
- Egyebek
- Egyéb értesítések, például hibák, stb.
- Beérkezett üzenetek
- Elküldött üzenetek
- Piszkozatok
- Kuka
- Elküldött
- Néhány üzenetet nem sikerült elküldeni
- Verzió
- Hibakeresési naplózás engedélyezése
- További diagnosztikai információk naplózása
- Érzékeny információk naplózása
- A jelszavak láthatóak lehetnek a naplókban.
- További üzenetek betöltése
- Címzett:%s
- Tárgy
- Üzenet szövege
- Aláírás
- -------- Eredeti üzenet --------
- Tárgy:
- Elküldve:
- Feladó:
- Címzett:
- Másolat:
- %s írta:
- Ekkor: %1$s, %2$s írta:
- Legalább egy címzettet hozzá kell adni.
- A címzett mező befejezetlen beviteli adatot tartalmaz.
- Nem található e-mail cím ehhez a partnerhez.
- Néhány mellékletet nem lehet továbbítani, mert nem lettek letöltve.
- Az üzenet nem továbbítható, mert egyes mellékletek nem lettek letöltve.
- Idézett üzenetet is
- Idézett szöveg eltávolítása
- Idézett szöveg szerkesztése
- Melléklet eltávolítása
- Feladó: %s <%s>
- Címzett:
- Másolat:
- Titkos másolat:
- Megnyitás
- Mentés
- Nem lehet elmenteni a mellékletet.
- Fényképek megjelenítése
- Nem sikerült megjelenítőt találni ehhez: %s.
- Teljes üzenet letöltése
- Az üzenet nem jeleníthető meg
- ezen keresztül: %1$s
-
- Az összes fejléc letöltésre került, de nincsenek további megjelenítendő fejlécek.
- A további fejlécek letöltése az adatbázisból vagy a levelezőkiszolgálóról sikertelen.
- Továbbiak ettől a feladótól
- Innen: %s
- Üzenet törzsének hibakeresése vagy kiürítése
- Az üzenet elvetésre került.
- Az üzenet vázlatként lett elmentve.
- Csillagok megjelenítése
- Csillagok jelzik a megjelölt üzeneteket
- Előnézeti sorok
- Levelezési nevek megjelenítése
- Levelezési nevek megjelenítése az e-mail-címek helyett
- Levelezési név a tárgy fölött
- Levelezési nevek megjelenítése a tárgy sora fölött, és nem alatta
- Partnernevek megjelenítése
- Címzettek neveinek használata a címjegyzékből, ha elérhető
- Partnerek színezése
- Nevek színezése a partnerlistában
- Rögzített szélességű betűk
- Rögzített szélességű betű használata az egyszerű szöveges üzeneteknél
- Üzenetek automatikus méretezése
- Üzenetek összehúzása és képernyőhöz igazítása
- Visszatérés a listához törlés után
- Visszatérés az üzenet listához az üzenet törlése után
- Következő üzenet megjelenítése törlés után
- A következő üzenet alapértelmezett megjelenítése az üzenet törlése után
- Műveletek megerősítése
- Párbeszédablak megjelenítése a kiválasztott műveletek végrehajtásakor
- Törlés
- Csillagozottak törlése (üzenet nézetben)
- Levélszemét
- Üzenet elvetése
- Összes üzenet megjelölése olvasottként
- Törlés (az értesítésekből)
- Levelező alkalmazás elrejtése
- A K-9 azonosító eltávolítása a levél fejlécéből
- Időzóna elrejtése
- UTC használata a helyi időzóna helyett a levelek fejlécében és a válasz fejlécében
- Tárgy elrejtése az értesítésekben
- Soha
- Ha a készülék zárolt
- Mindig
- „Törlés” gomb megjelenítése
- Soha
- Önálló üzenet értesítésénél
- Mindig
- Képernyőzár értesítések
- Nincsenek képernyőzár értesítések
- Alkalmazás neve
- Olvasatlan üzenetek száma
- Üzenet számlálók és feladók
- Ugyanaz, mint feloldott képernyőnél
- Csendes idő
- Csörgés, rezgés és villogás letiltása éjszakára
- Értesítések letiltása
- Értesítések teljes letiltása a csendes idő alatt
- Csendes idő kezdete
- Csendes idő vége
- Új fiók beállítása
- E-mail-cím
- Jelszó
- Jelszó megjelenítése
- Kézi beállítás
-
- Fiókinformációk beolvasása\u2026
- Bejövő kiszolgálóbeállítások ellenőrzése\u2026
- Kimenő kiszolgálóbeállítások ellenőrzése\u2026
- Hitelesítés\u2026
- Fiókbeállítások beolvasása\u2026
- Megszakítás\u2026
- Már majdnem kész.
- Fiók elnevezése (nem kötelező):
- Név megadása (kimenő üzeneteknél jelenik meg):
- Fióktípus
- Milyen fajta fiók ez?
- POP3
- IMAP
- Normál jelszó
- Nem biztonságosan átküldött jelszó
- Titkosított jelszó
- Ügyféltanúsítvány
- Bejövő kiszolgáló beállításai
- Felhasználónév
- Jelszó
- Ügyféltanúsítvány
- POP3 kiszolgáló
- IMAP kiszolgáló
- Exchange kiszolgáló
- Port
- Biztonság
- Hitelesítés
- Nincs
- SSL/TLS
- STARTTLS
- „%1$s = %2$s” nem érvényes ezzel: „%3$s = %4$s”
- Üzenet törlésekor
- Nincs törlés a kiszolgálóról
- Törlés a kiszolgálóról
- Olvasottnak jelölés a kiszolgálón
- Tömörítés használata a hálózaton:
- Mobil
- Wi-Fi
- Egyéb
- Külső tárhely (SD-kártya)
- Szabályos belső tárhely
- Törölt üzenetek végleges törlése a kiszolgálóról
- Azonnal
- Lekérdezéskor
- Kézileg
- IMAP névtér automatikus felismerése
- IMAP útvonal előtag
- Vázlatok mappa
- Elküldöttek mappa
- Lomtár mappa
- Archívum mappa
- Levélszemét mappa
- Csak feliratkozott mappák megjelenítése
- Mappa automatikus kinyitása
- OWA útvonal
- Nem kötelező
- Hitelesítési útvonal
- Nem kötelező
- Postafiók álnév
- Nem kötelező
- Kimenő kiszolgáló beállításai
- SMTP kiszolgáló
- Port
- Biztonság
- Bejelentkezés szükséges.
- Felhasználónév
- Jelszó
- Hitelesítés
- „%1$s = %2$s” nem érvényes ezzel: „%3$s = %4$s”
- Érvénytelen beállítás: %s
- Fiók beállításai
- Fiók tömörítése
- Mappa lekérdezésének gyakorisága
- Soha
- 15 percenként
- 30 percenként
- Óránként
- 2 óránként
- 3 óránként
- 6 óránként
- 12 óránként
- 24 óránként
- Levél küldésének engedélyezése ennél a fióknál
- Ha a kiszolgáló támogatja, akkor az új üzenetek azonnal megjelennek. Ez az lehetőség drámaian növelheti vagy csökkenti a teljesítményt.
- IDLE kapcsolat frissítése
- 2 percenként
- 3 percenként
- 6 percenként
- 12 percenként
- 24 percenként
- 36 percenként
- 48 percenként
- 60 percenként
- Értesítés, amikor levél érkezik
- Értesítés levél ellenőrzéskor
- Megjelenítendő üzenetek száma
- 10 üzenet
- 25 üzenet
- 50 üzenet
- 100 üzenet
- 250 üzenet
- 500 üzenet
- 1000 üzenet
- 2500 üzenet
- 5000 üzenet
- 10000 üzenet
- összes üzenet
- Nem lehet másolni vagy áthelyezni a kiszolgálóval nem szinkronizált üzenetet.
- A beállítást nem sikerült befejezni
- A felhasználónév vagy a jelszó hibás.\n(%s)
- A kiszolgáló érvénytelen SSL-tanúsítványt mutatott be. Néha ez a kiszolgáló hibás beállításából ered. Néha azért, mert valaki támadást hajtott végre Ön vagy a levelezőkiszolgálója ellen. Ha nem biztos abban, hogy mi történt, akkor kattintson az Elutasítás gombra, és vegye fel a kapcsolatot a levelezőkiszolgáló üzemeltetőivel.\n\n(%s)
- Nem lehet kapcsolódni a kiszolgálóhoz.\n(%s)
- Részletek szerkesztése
- Folytatás
- Bővített
- Fiók beállításai
- Alapértelmezett fiók
- Levél küldése alapértelmezetten ebből a fiókból
- Új levél értesítések
- Értesítések mappái
- Összes
- Csak 1. osztályú mappák
- 1. és 2. osztályú mappák
- Összes, kivéve a 2. osztályú mappákat
- Nincs
- Szinkronizációs értesítések
- Saját e-mail-cím
- Értesítés az állapotsávon új levél érkezésekor
- Értesítés az állapotsávon a levelek ellenőrzésekor
- Kimenő leveleknél is
- Értesítés megjelenítése az elküldött üzeneteknél
- Csak partnerek
- Értesítések megjelenítése csak az ismert partnerektől érkező üzeneteknél
- Megjelölés olvasottként megnyitáskor
- Üzenet megjelölése olvasottként megtekintésre megnyitáskor
- Megjelölés olvasottként törléskor
- Üzenet megjelölése olvasottként törléskor
- Képek megjelenítése mindig
- Nem
- Partnerektől
- Bárkitől
- Levél küldése
- Üzenet idézése válaszkor
- Az eredeti üzenet felvétele a válaszba.
- Válasz az idézett szöveg után
- Az eredeti üzenet a válasz fölött jelenik meg.
- Aláírások törlése válaszoláskor
- Az aláírások el lesz távolítva az idézett üzenetekből
- Üzenet formátuma
- Egyszerű szöveg (képek és formázás eltávolítása)
- HTML (képek és formázás megtartása)
- Automatikus
- A másolat és a titkos másolat mindig jelenjen meg
- Olvasási visszaigazolás
- Mindig kérjen olvasási visszaigazolást
- Válasz idézésének stílusa
- Előtag (mint például Gmail)
- Fejléc (mint például Outlook)
- Elküldött üzenetek feltöltése
- Üzenetek feltöltése az Elküldött mappába a küldés után
- Általános beállítások
- Levél olvasása
- Levél letöltése
- Mappák
- Idézett szöveg előtagja
- Végpontok közötti titkosítás
- OpenPGP támogatás engedélyezése
- OpenPGP alkalmazás kiválasztása
- Végpontok közötti kulcs beállítása
- Nincs OpenPGP alkalmazás beállítva
- Kapcsolódva: %s
- Beállítás…
- Az összes vázlat tárolása titkosítottan
- Az összes vázlat titkosítva lesz tárolva
- A vázlatok titkosítása csak a titkosítás engedélyezésekor
- Mappa lekérdezésének gyakorisága
- Fiókszín
- A fiókban és a fióklistában használt fiók kiemelt színe
- Nincs szín
- Értesítési LED színe
- Az eszköz villogó LED-ének színe ennél a fióknál
- Helyi mappa mérete
- Legfeljebb ennyi üzenet beolvasása
- 1 KiB
- 2 KiB
- 4 KiB
- 8 KiB
- 16 KiB
- 32 KiB
- 64 KiB
- 128 KiB
- 256 KiB
- 512 KiB
- 1 MiB
- 2 MiB
- 5 MiB
- 10 MiB
- bármilyen méretű (nincs korlát)
- Üzenetek szinkronizálása ekkortól
- bármely idő (nincs korlát)
- ma
- az elmúlt 2 nap
- az elmúlt 3 nap
- az elmúlt hét
- az elmúlt 2 hét
- az elmúlt 3 hét
- az elmúlt hónap
- az elmúlt 2 hónap
- az elmúlt 3 hónap
- az elmúlt 6 hónap
- az elmúlt év
- Megjelenítendő mappák
- Összes
- Csak 1. osztályú mappák
- 1. és 2. osztályú mappák
- Összes, kivéve a 2. osztályú mappákat
- Mappák lekérdezése
- Összes
- Csak 1. osztályú mappák
- 1. és 2. osztályú mappák
- Összes, kivéve a 2. osztályú mappákat
- Nincs
- Mappák küldése
- Összes
- Csak 1. osztályú mappák
- 1. és 2. osztályú mappák
- Összes, kivéve a 2. osztályú mappákat
- Nincs
- Áthelyezés vagy másolás a célmappákba
- Összes
- Csak 1. osztályú mappák
- 1. és 2. osztályú mappák
- Összes, kivéve a 2. osztályú mappákat
- Kiszolgáló törléseinek szinkronizálása
- Üzenetek eltávolítása a kiszolgálóról törléskor
- Hiányzó OpenPGP alkalmazás – talán eltávolításra került.
- Mappa beállításai
- Megjelenítés a felső csoportban
- Megjelenítés a mappalista teteje környékén
- Mappa megjelenítésnek osztálya
- Nincs osztály
- 1. osztály
- 2. osztály
- Mappa lekérésének osztálya
- Nincs
- 1. osztály
- 2. osztály
- Ugyanaz, mint a megjelenítési osztály
- Mappa küldésének osztálya
- Nincs osztály
- 1. osztály
- 2. osztály
- Ugyanaz, mint a lekérés osztálya
- Mappa értesítésének osztálya
- Nincs osztály
- 1. osztály
- 2. osztály
- Ugyanaz, mint a küldés osztálya
- Helyi üzenetek törlése
- Bejövő kiszolgáló
- A bejövő levelek kiszolgálójának beállítása
- Kimenő kiszolgáló
- A kimenő levelek (SMTP) kiszolgálójának beállítása
- Fióknév
- Saját név
- Értesítések
- Rezgés
- Rezgés, amikor levél érkezik
- Rezgés mintái
- alapértelmezett
- 1. minta
- 2. minta
- 3. minta
- 4. minta
- 5. minta
- Rezgés ismétlése
- Új levél csengőhangja
- LED villogása
- LED villogása, amikor levél érkezik
- Üzenet írásának beállításai
- Írási alapbeállítások
- Alapértelmezett feladó, titkos másolat és aláírás beállítása
- Személyazonosságok kezelése
- Alternatív „feladó” címek és aláírások beállítása
- Személyazonosságok kezelése
- Személyazonosság kezelése
- Személyazonosság szerkesztése
- Mentés
- Új személyazonosság
- Titkos másolat küldése az összes üzenetről ide
- Szerkesztés
- Mozgatás fel
- Mozgatás le
- Áthelyezés legfelülre / alapértelmezetté tétel
- Eltávolítás
- Személyazonosság leírása
- (Nem kötelező)
- Az ön neve
- (Nem kötelező)
- E-mail-cím
- (Kötelező)
- Válaszcím
- (Nem kötelező)
- Aláírás
- (Nem kötelező)
- Aláírás használata
- Aláírás
- Kezdeti személyazonosság
- Személyazonosság választása
- Küldés más néven
- Nem lehet eltávolítani az egyetlen személyazonosságát
- Nem lehet használni egy személyazonosságot e-mail-cím nélkül
- Legkorábbi üzenetek először
- Legkésőbbi üzenetek először
- Tárgy szerint betűrendben
- Tárgy szerint fordított betűrendben
- Feladó szerint betűrendben
- Feladó szerint fordított betűrendben
- Csillagozott üzenetek először
- Nem csillagozott üzenetek először
- Olvasatlan üzenetek először
- Olvasott üzenetek először
- Melléklettel rendelkező üzenetek először
- Melléklet nélküli üzenetek először
- Rendezési kritérium…
- Dátum
- Érkezés
- Tárgy
- Feladó
- Csillag
- Olvasott/olvasatlan
- Mellékletek
- Fiók eltávolítása
- Felismerhetetlen tanúsítvány
- Kulcs elfogadása
- Kulcs visszautasítása
- Del (vagy D) – Törlés\nR – Válasz\nA – Válasz mindenkinek\nC – Írás\nF – Továbbítás\nM – Áthelyezés\nV – Archiválás\nY – Másolás\nZ – Megjelölés olvasottként/olvasatlanként\nG – Csillagozás\nO – Rendezés típusa\nI – Rendezési sorrend\nQ – Visszatérés a mappákhoz\nS – Kijelölés/Kijelölés megszüntetése\nJ vagy P – Előző üzenet\nK vagy N – Következő üzenet
- Del (vagy D) – Törlés\nC – Írás\nM – Áthelyezés\nV – Archiválás\nY – Másolás\nZ – Megjelölés olvasottként/olvasatlanként\nG – Csillagozás\nO – Rendezés típusa\nI – Rendezési sorrend\nQ – Visszatérés a mappákhoz\nS – Kijelölés/Kijelölés megszüntetése
- Mappa neve tartalmazza
- Mappák megjelenítése…
- Összes mappa
- 1. osztályú mappák
- 1. és 2. osztályú mappák
- 2, osztályú mappák elrejtése
- Aláírás helyzete
- Idézett üzenet előtt
- Idézett üzenet után
- Alkalmazás témájának használata
- Sötét
- Világos
- Rendszer alapértelmezettjének használata
- Megjelenés
- Globális
- Hibakeresés
- Adatvédelem
- Hálózat
- Interakció
- Fióklista
- Üzenetlisták
- Üzenetek
- Téma
- Üzenet nézetének témája
- Üzenetírás témája
- Nyelv
- Nem találhatók beállítások
- Rögzített üzenet téma
- Az üzenetmegtekintési téma kiválasztása, miközben megtekinti az üzenetet
- Rögzített üzenetmegtekintési téma használata
- Rendszer alapértelmezettje
- Háttér-szinkronizálás
- Soha
- Mindig
- Amikor az „Automatikus szinkronizálás” be van jelölve
- Összes kijelölése
- Küldéssel ellenőrzendő mappák legnagyobb száma
- 5 mappa
- 10 mappa
- 25 mappa
- 50 mappa
- 100 mappa
- 250 mappa
- 500 mappa
- 1000 mappa
- Animációk
- Rikító látható hatások használata
- Hangerő gomb navigáció
- Üzenetnézetekben
- Listanézetekben
- Egységes beérkezett üzenetek megjelenítése
- %s%s
- – Olvasatlan
- Összes üzenet
- Az összes üzenet kereshető mappákban
- Egységes beérkezett üzenetek
- Az összes üzenet egységes mappákban
- Egyesítés
- Az összes üzenetet az egységes beérkezett üzenetekben van megjelenítve
- Keresés ezekben mappákban
- Összes
- Megjeleníthető
- Nincs
- Nincs
- Automatikus (%s)
- Betűméret
- Betűméret beállítása
- Fióklista
- Fiók neve
- Fiók leírása
- Mappalisták
- Mappa neve
- Mappa állapota
- Üzenetlisták
- Tárgy
- Feladó
- Dátum
- Előnézet
- Üzenetek
- Feladó
- Címzett
- Másolat
- Titkos másolat
- További fejlécek
- Tárgy
- Idő és dátum
- Üzenet törzse
- %d%%
- %1$s: %2$s
- Üzenet írása
- Szöveg beviteli mezők
- Alapértelmezett
- Mini
- Pici
- Kisebb
- Kicsi
- Közepes
- Nagy
- Nagyobb
- Nem található megfelelő alkalmazás ehhez a művelethez.
- A küldés sikertelen: %s
- Menti piszkozatként?
- Menti vagy elveti ezt az üzenetet?
- Menti vagy elveti a változtatásokat?
- Elveti az üzenet?
- Biztosan el szeretné vetni ezt az üzenetet?
- Szöveg kijelölése a másoláshoz.
- Helyi üzenetek kiürítése
- Ez eltávolítja az összes helyi üzenetet mappából. Az üzenetek nem kerülnek törlésre a szerverről.
- Üzenetek kiürítése
- Törlés megerősítése
- Biztosan törölni szeretné ezt az üzenetet?
-
- Valóban törölni szeretné ezt az üzenetet?
- Biztosan törölni szeretne %1$d üzenetet?
-
- Igen
- Nem
- Megerősítés, hogy az összeset olvasottként jelölje
- Szeretné megjelölni az összes üzenetet olvasottként?
- Kuka ürítésének megerősítése
- Ki szeretné üríteni a kuka mappát?
- Igen
- Nem
- Megerősítés, hogy áthelyezze a levélszemét mappába
-
- Valóban át akarja helyezni ezt a levelet a spam mappába?
- Valóban át szeretne helyezni %1$d üzenetet a levélszemét mappába?
-
- Igen
- Nem
- Melléklet letöltése
- »
- ›
- Biztonsági mentés
- Egyebek
- Beállítások exportálása
- Exportálás
- Megosztás
- Beállítások exportálása…
- A beállítások sikeresen exportálva
- A beállítások exportálása sikertelen
- Beállítások importálása
- Fájl kiválasztása
- Importálás
- A beállítások sikeresen importálva
- Adja meg a jelszavakat
- Nem sikerült importálni a beállításokat
- Nem sikerült beolvasni a beállítások fájlt
- Nem sikerült importálni néhány beállítást
- Sikeresen importálva
- Jelszó szükséges
- Nincs importálva
- Importálási hiba
- Később
- Beállítások importálása
- Beállítások importálása…
-
- Ahhoz, hogy képes legyen használni a(z) „%s” fiókot, meg kell adnia a kiszolgáló jelszavát.
- Ahhoz, hogy képes legyen használni a(z) „%s” fiókot, meg kell adnia a kiszolgáló jelszavait.
-
- Bejövő kiszolgáló jelszava
- Kimenő kiszolgáló jelszava
- Ugyanazon jelszó használata a kimenő kiszolgálónál
- Kiszolgáló neve: %s
- Olvasatlanok számának megjelenítése ennél…
- Fiók
- Az a fiók, amelynél az olvasatlanok számlálóját meg kell jeleníteni
- Egységes beérkezett üzenetek
- Mappa számláló
- Az olvasatlan számláló megjelenítése csak egy önálló mappára
- Mappa
- Az a mappa, amelynél az olvasatlanok számlálóját meg kell jeleníteni
- Kész
- %1$s – %2$s
- Nincs fiók kiválasztva
- Nincs mappa kiválasztva
- Nincs szöveg
- Hivatkozás megnyitása
- Hivatkozás megosztása
- Hivatkozás másolása a vágólapra
- Hivatkozás
- Hivatkozás szövegének másolása a vágólapra
- Hivatkozás szövege
- Kép
- Kép megtekintése
- Kép mentése
- Kép letöltése
- Kép URL-jének másolása a vágólapra
- Kép URL
- Szám hívása
- Mentés a címjegyzékbe
- Szám másolása a vágólapra
- Telefonszám
- Levél küldése
- Mentés a címjegyzékbe
- Cím másolása a vágólapra
- E-mail-cím
- Összes
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- Kiszolgáló keresési korlátja
- Lekérdezés küldése a kiszolgálónak
-
- %d találat lekérése
- %d találat lekérése
-
-
- %1$d/%2$d találat lekérése
- %1$d/%2$d találat lekérése
-
- A távoli keresés sikertelen
- Keresés
- Kiszolgálón keresés engedélyezése
- Üzenetek keresése a kiszolgálón az eszközön lévők mellett
- Üzenetek keresése a kiszolgálón
- Hálózati kapcsolat szükséges a kiszolgálón kereséshez.
- Szín megváltoztatása olvasáskor
- Az eltérő háttér azt jelzi, hogy az üzenetet elolvasták
- Beszélgetés nézet
- Üzenetek csoportosítása beszélgetés szerint
- Adatbázisok frissítése
- Adatbázisok frissítése…
- A(z) „%s” fiók adatbázisának frissítése
- Osztott képernyő megjelenítése
- Mindig
- Soha
- Amikor fekvő módban van
- Válasszon egy üzenetet a bal oldalon
- Partner képeinek megjelenítése
- Partner képeinek megjelenítése az üzenetlistában
- Összes megjelölése olvasottként
- Partnerek képeinek színezése
- Hiányzó partnerek képeinek színezése
- Látható üzenetműveletek
- A kiválasztott műveletek megjelenítése az üzenetnézet menüben
- Melléklet betöltése…
- Üzenet küldése
- Piszkozat mentése
- Melléklet letöltése…
- Nem lehet hitelesíteni. A kiszolgáló nem teszi közzé a SASL EXTERNAL képességet. Ezt okozhatja egy probléma a kliens tanúsítványával (lejárt, ismeretlen hitelesítésszolgáltató) vagy bármilyen egyéb beállítási probléma.
-
- Ügyféltanúsítvány használata
- Nincs ügyféltanúsítvány
- Ügyféltanúsítvány kiválasztásának eltávolítása
- Nem sikerült lekérni az ügyféltanúsítványt a következő álnévhez: „%s”
- Speciális beállítások
- A(z) „%1$s” ügyféltanúsítvány lejárt vagy még nem érvényes (%2$s)
-
- *Titkosított*
- Hozzáadás címjegyekből
- Másolat
- Titkos másolat
- Címzett
- Feladó
- <Címzett ismeretlen>
- <Feladó ismeretlen>
- Otthon
- Munkahely
- Egyéb
- Mobil
- Nincs piszkozatok mappa beállítva ehhez a fiókhoz!
- Nincs kulcs beállítva ehhez a fiókhoz! Ellenőrizze a beállításokat.
- A titkosításszolgáltató nem megfelelő verziót használ. Ellenőrizze a beállításokat!
- Nem sikerült kapcsolódni a titkosításszolgáltatóhoz. Ellenőrizze a beállításokat, vagy kattintson ismét a titkosítás ikonra!
- Nem sikerült előkészíteni a végpontok közötti titkosítást, ellenőrizze a beállításokat
- A PGP/INLINE mód nem támogatja a mellékleteket!
- PGP/INLINE engedélyezése
- PGP/INLINE letiltása
- Csak PGP aláírás engedélyezése
- Csak PGP aláírás letiltása
- PGP/INLINE mód
- A levél PGP/INLINE formátumban lett küldve.\nEzt csak kompatibilitás miatt kell használni:
- Néhány kliens csak ezt a formátumot támogatja
- Az aláírások sérülhetnek az átvitel során
- A mellékletek nem támogatottak
- Értem!
- Letiltás
- Engedélyezve tartás
- Értem!
- Letiltás
- Engedélyezve tartás
- Csak PGP aláírás mód
- Ebben a módban a PGP kulcs lesz használva egy titkosítatlan e-mail kriptográfiai aláírásának létrehozásához.
- Ez nem titkosítja az e-mailt, de ellenőrzi, hogy az ön kulcsából lett elküldve.
- Az aláírások sérülhetnek, ha levelezőlistákra küldi.
- Az aláírások „signature.asc” mellékletekként lehetnek megjelenítve néhány kliensprogramban.
- A titkosított üzenetek mindig tartalmaznak aláírást.
- Egyszerű szöveg
- a végpontok közötti aláírás hibát tartalmazott
- teljesen le kell tölteni az üzenetet az aláírás feldolgozásához
- nem támogatott végpontok közötti aláírást tartalmaz
- Az üzenet titkosított, de nem támogatott formátumban.
- Az üzenet titkosított, de a visszafejtést megszakították.
- Végpontok közötti aláírt egyszerű szöveg
- ellenőrzött aláírótól
- Aláírt egyszerű szöveg
- de a végpontok közötti kulcs nem egyezik a feladóval
- de a végpontok közötti kulcs lejárt
- de a végpontok közötti kulcsot visszavonták
- de a végpontok közötti kulcs nem tekinthető biztonságosnak
- ismeretlen végpontok közötti kulcstól
- Titkosított
- de visszafejtési hiba történt
- teljesen le kell tölteni az üzenetet a visszafejtéshez
- de nincs titkosító alkalmazás beállítva
- Titkosított
- de nem végpontok közötti
- Végpontok között titkosított
- ellenőrzött feladótól
- Titkosított
- ismeretlen végpontok közötti kulcstól
- de a végpontok közötti kulcs nem egyezik a feladóval
- de a végpontok közötti kulcs lejárt
- de a végpontok közötti kulcsot visszavonták
- de a végpontok közötti kulcs nem tekinthető biztonságosnak
- de a végpontok közötti adatok hibákat tartalmaznak
- de a titkosítás nem tekinthető biztonságosnak
- OK
- Kulcs keresése
- Aláíró megtekintése
- Feladó megtekintése
- Részletek
- Feloldás
- Ez a rész nem volt titkosítva, és esetleg nem biztonságos.
- Nem védett melléklet
- Betöltés…
- A visszafejtést megszakították.
- Újra
- A titkosított üzenetet le kell tölteni a visszafejtéshez.
- Hiba az e-mail visszafejtésekor
- A különleges karakterek jelenleg nem támogatottak!
- Hiba a cím feldolgozásakor!
- Titkosítatlan aláírások elrejtése
- Csak a titkosított aláírások lesznek megjelenítve
- Az összes aláírás meg lesz jelenítve
- A titkosítás nem érhető el csak aláíró módban!
- Aláíratlan szöveg
- APG elavultsági figyelmeztetés
- Az APG többé nincs karbantartva!
- Emiatt az APG támogatás eltávolításra került a K-9 Mail alkalmazásból.
- A fejlesztés 2014 elején leállt
- Javítatlan biztonsági hibákat tartalmaz
- Kattintson ide, ha többet szeretne megtudni.
- Értem!
- APG
- Ez az e-mail titkosított
- 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.
- Ugrás a beállításokhoz
- K-9 üzenetlista
- Üzenetek betöltése…
- A mappalista lekérése sikertelen
- Hiba a címzettek állapotának lekérésekor az OpenPGP szolgáltatótól!
- A titkosítás nem lehetséges
- Néhány kiválasztott címzett nem támogatja ezt a funkciót!
- Titkosítás engedélyezése
- Titkosítás letiltása
- Az üzenetek titkosítása biztosítja, hogy azokat csak a címzett olvashatja lel és senki más.
- A titkosítás csak akkor jelenik meg, ha az összes címzett támogatja, és korábban már küldtek e-mailt önnek.
- Titkosítási be- és kikapcsolása erre az ikonra kattintva.
- Értem
- Vissza
- Titkosítás letiltása
- OpenPGP titkosítás
- Autocrypt kölcsönös mód
- Autocrypt kölcsönös mód
- Az üzenetek normál esetben választás alapján lesznek titkosítva, vagy ha egy titkosított üzenetre válaszol.
- Ha mind a feladó, mind a címzettek támogatják a kölcsönös módot, akkor a titkosítás alapértelmezetten engedélyezve lesz.
- Kattintson ide, ha többet szeretne megtudni.
- Általános beállítások
- Nincs OpenPGP alkalmazás telepítve
- Telepítés
- A K-9 Mail az OpenKeychain alkalmazást igényli a végpontok közötti titkosításhoz.
- Titkosított üzenet
- Üzenet tárgyainak titkosítása
- Néhány címzett esetleg nem támogatja
- Belső hiba: érvénytelen fiók!
- Hiba a következőhöz való kapcsolódáskor: %s!
- Autocrypt beállítási üzenet küldése
- Végpontok közötti beállítás biztonságos megosztása más eszközökkel
- Autocrypt beállítási üzenet
- Egy automatikusan titkosított beállítási üzenet biztonságosan megosztja a végpontok közötti beállítást más eszközökkel.
- Beállítási üzenet küldése
- Az üzenet az ön címére lesz elküldve:
- Beállítási üzenet előállítása…
- Üzenet küldése neki:
- A befejezéshez nyissa meg az üzenetet a másik eszközén, és írja be a beállítási kódot.
- Beállítási kód megjelenítése
- Autocrypt beállítási üzenet
- Ez az üzenet minden információt tartalmaz az Autocrypt beállítások és a titkos kulcs biztonságos átviteléhez az eredeti eszközről.
+
+ -- \nAndroidos készülékről küldve K-9 Mail használatával. Elnézést a rövidségért.
+
+ A(z) „%s” fiók eltávolításra kerül a K-9 Mail alkalmazásból.
+
+ Szerzők
+ Kiadási megjegyzések
+ E-mailek olvasása
+ Az alkalmazás olvashatja az emaileket.
+ E-mailek törlése
+ Az alkalmazás törölheti ez e-maileket.
+ A Mail névjegye
+ Fiókok
+ Mappák
+ Bővített
+ Írás
+ Válasz
+ Válasz mindenkinek
+ Továbbítás
+ Továbbítás mellékletként
+ Fiók választása
+ Mappa választása
+ Áthelyezés…
+ Másolás…
+ Lekérés %s:%s%s
+ Fejlécek beolvasása %s:%s%s
+ %s%sküldése folyamatban van...
+ Feldolgozás %s:%s%s
+ \u0020%d/%d
+ A szinkronizálás letiltásra került.
+ %d kiválasztva
+ Következő
+ Előző
+
+ OK
+ Mégse
+ Küldés
+ Küldés újra
+ A tárgy üres. Kattintás újra a küldés erőltetéséhez.
+ Kijelölés
+ Kijelölés törlése
+ Válasz
+ Válasz mindenkinek
+ Törlés
+ Archiválás
+ Levélszemét
+ Továbbítás
+ Továbbítás mellékletként
+ Szerkesztés új üzenetként
+ Áthelyezés
+ Áthelyezés a Piszkozatokhoz
+ Küldés…
+ Iktatás…
+ Kész
+ Elvetés
+ Mentés piszkozatként
+ Levél ellenőrzése
+ Minden postafiók összehangolása
+ Üzenetek küldése
+ Mappalista frissítése
+ Mappa keresése
+ Fiók hozzáadása
+ Írás
+ Keresés
+ Keresés mindenhol
+ Keresési eredmények
+ Beállítások
+ Mappák kezelése
+ Fiók beállításai
+ Fiók eltávolítása
+ Megjelölés olvasottként
+ Megosztás
+ Feladó kiválasztása
+ Csillag hozzáadása
+ Csillag eltávolítása
+ Másolás
+ Fejlécek megjelenítése
+
+ Cím a vágólapra másolva
+ A címek a vágólapra kerültek.
+
+ Tárgy szöveg a vágólapra másolva
+ Váltás sötét témára
+ Váltás világos témára
+ Megjelölés olvasatlanként
+ Olvasási visszaigazolás
+ Olvasási visszaigazolás lesz kérve
+ Nem lesz olvasási visszaigazolás kérve
+ Melléklet hozzáadása
+ Lomtár ürítése
+ Végleges törlés
+ Névjegy
+ Beállítások
+
+ (Nincs tárgy)
+ Nincs feladó
+ Üzenetek betöltése\u2026
+ Kapcsolódási hiba történt.
+ Az üzenet nem található.
+ Üzenetbetöltési hiba történt.
+ Legfeljebb %d további betöltése
+ %.1f GB
+ %.1f MB
+ %.1f kB
+ %d B
+ A(z) „%s” fiók tömörítésre került: %s=> %s
+ A(z) „%s” fiók tömörítése folyamatban van.
+ Új levél
+
+ %d új üzenet
+ %d új üzenet
+
+ %d Olvasatlan (%s)
+ + %1$d további: %2$s
+ Válasz
+ Megjelölés olvasottként
+ Összes megjelölése olvasottként
+ Törlés
+ Összes törlése
+ Archiválás
+ Összes archiválása
+ Levélszemét
+ Tanúsítványhiba: %s
+ Ellenőrizze a kiszolgálóbeállításokat.
+ A hitelesítés sikertelen.
+ A hitelesítés sikertelen: %s. Frissítse a kiszolgálóbeállításokat.
+ Levelek ellenőrzése: %s:%s
+ Levelek ellenőrzése
+ Levél küldése: %s
+ Levél küldése
+ :
+ Szinkronizálás (Leküldés)
+ Az új levelekre várakozáskor jelenik meg
+ Üzenetek
+ Az üzenetekkel kapcsolatos értesítések
+ Egyebek
+ Egyéb értesítések, például hibák, stb.
+ Beérkezett üzenetek
+ Elküldött üzenetek
+ Piszkozatok
+ Kuka
+ Elküldött
+ Néhány üzenetet nem sikerült elküldeni
+ Verzió
+ Hibakeresési naplózás engedélyezése
+ További diagnosztikai információk naplózása
+ Érzékeny információk naplózása
+ A jelszavak láthatóak lehetnek a naplókban.
+ További üzenetek betöltése
+ Címzett:%s
+ Tárgy
+ Üzenet szövege
+ Aláírás
+ -------- Eredeti üzenet --------
+ Tárgy:
+ Elküldve:
+ Feladó:
+ Címzett:
+ Másolat:
+ %s írta:
+ Ekkor: %1$s, %2$s írta:
+ Legalább egy címzettet hozzá kell adni.
+ A címzett mező befejezetlen beviteli adatot tartalmaz.
+ Nem található e-mail cím ehhez a partnerhez.
+ Néhány mellékletet nem lehet továbbítani, mert nem lettek letöltve.
+ Az üzenet nem továbbítható, mert egyes mellékletek nem lettek letöltve.
+ Idézett üzenetet is
+ Idézett szöveg eltávolítása
+ Idézett szöveg szerkesztése
+ Melléklet eltávolítása
+ Feladó: %s <%s>
+ Címzett:
+ Másolat:
+ Titkos másolat:
+ Megnyitás
+ Mentés
+ Nem lehet elmenteni a mellékletet.
+ Fényképek megjelenítése
+ Nem sikerült megjelenítőt találni ehhez: %s.
+ Teljes üzenet letöltése
+ Az üzenet nem jeleníthető meg
+ ezen keresztül: %1$s
+
+ Az összes fejléc letöltésre került, de nincsenek további megjelenítendő fejlécek.
+ A további fejlécek letöltése az adatbázisból vagy a levelezőkiszolgálóról sikertelen.
+ Továbbiak ettől a feladótól
+ Innen: %s
+ Üzenet törzsének hibakeresése vagy kiürítése
+ Az üzenet elvetésre került.
+ Az üzenet vázlatként lett elmentve.
+ Csillagok megjelenítése
+ Csillagok jelzik a megjelölt üzeneteket
+ Előnézeti sorok
+ Levelezési nevek megjelenítése
+ Levelezési nevek megjelenítése az e-mail-címek helyett
+ Levelezési név a tárgy fölött
+ Levelezési nevek megjelenítése a tárgy sora fölött, és nem alatta
+ Partnernevek megjelenítése
+ Címzettek neveinek használata a címjegyzékből, ha elérhető
+ Partnerek színezése
+ Nevek színezése a partnerlistában
+ Rögzített szélességű betűk
+ Rögzített szélességű betű használata az egyszerű szöveges üzeneteknél
+ Üzenetek automatikus méretezése
+ Üzenetek összehúzása és képernyőhöz igazítása
+ Visszatérés a listához törlés után
+ Visszatérés az üzenet listához az üzenet törlése után
+ Következő üzenet megjelenítése törlés után
+ A következő üzenet alapértelmezett megjelenítése az üzenet törlése után
+ Műveletek megerősítése
+ Párbeszédablak megjelenítése a kiválasztott műveletek végrehajtásakor
+ Törlés
+ Csillagozottak törlése (üzenet nézetben)
+ Levélszemét
+ Üzenet elvetése
+ Összes üzenet megjelölése olvasottként
+ Törlés (az értesítésekből)
+ Levelező alkalmazás elrejtése
+ A K-9 azonosító eltávolítása a levél fejlécéből
+ Időzóna elrejtése
+ UTC használata a helyi időzóna helyett a levelek fejlécében és a válasz fejlécében
+ „Törlés” gomb megjelenítése
+ Soha
+ Önálló üzenet értesítésénél
+ Mindig
+ Képernyőzár értesítések
+ Nincsenek képernyőzár értesítések
+ Alkalmazás neve
+ Új üzenetek száma
+ Üzenet számlálók és feladók
+ Ugyanaz, mint feloldott képernyőnél
+ Csendes idő
+ Csörgés, rezgés és villogás letiltása éjszakára
+ Értesítések letiltása
+ Értesítések teljes letiltása a csendes idő alatt
+ Csendes idő kezdete
+ Csendes idő vége
+ Új fiók beállítása
+ E-mail-cím
+ Jelszó
+ Jelszó megjelenítése
+
+ Ha itt szeretné megtekinteni jelszavát, engedélyezze a képernyőzárat ezen az eszközön.
+ Személyazonosság ellenőrzése
+ Feloldás a jelszó megtekintéséhez
+ Kézi beállítás
+
+ Fiókinformációk beolvasása\u2026
+ Bejövő kiszolgálóbeállítások ellenőrzése\u2026
+ Kimenő kiszolgálóbeállítások ellenőrzése\u2026
+ Hitelesítés\u2026
+ Fiókbeállítások beolvasása\u2026
+ Megszakítás\u2026
+ Már majdnem kész.
+ Fiók elnevezése (nem kötelező):
+ Név megadása (kimenő üzeneteknél jelenik meg):
+ Fióktípus
+ Milyen fajta fiók ez?
+ POP3
+ IMAP
+ Normál jelszó
+ Nem biztonságosan átküldött jelszó
+ Titkosított jelszó
+ Ügyféltanúsítvány
+ Bejövő kiszolgáló beállításai
+ Felhasználónév
+ Jelszó
+ Ügyféltanúsítvány
+ POP3 kiszolgáló
+ IMAP kiszolgáló
+ Exchange kiszolgáló
+ Port
+ Biztonság
+ Hitelesítés
+ Nincs
+ SSL/TLS
+ STARTTLS
+ „%1$s = %2$s” nem érvényes ezzel: „%3$s = %4$s”
+ Üzenet törlésekor
+ Nincs törlés a kiszolgálóról
+ Törlés a kiszolgálóról
+ Olvasottnak jelölés a kiszolgálón
+ Tömörítés használata a hálózaton:
+ Mobil
+ Wi-Fi
+ Egyéb
+ Törölt üzenetek végleges törlése a kiszolgálóról
+ Azonnal
+ Lekérdezéskor
+ Kézileg
+ IMAP névtér automatikus felismerése
+ IMAP útvonal előtag
+ Vázlatok mappa
+ Elküldöttek mappa
+ Lomtár mappa
+ Archívum mappa
+ Levélszemét mappa
+ Csak feliratkozott mappák megjelenítése
+ Mappa automatikus kinyitása
+ OWA útvonal
+ Nem kötelező
+ Hitelesítési útvonal
+ Nem kötelező
+ Postafiók álnév
+ Nem kötelező
+ Kimenő kiszolgáló beállításai
+ SMTP kiszolgáló
+ Port
+ Biztonság
+ Bejelentkezés szükséges.
+ Felhasználónév
+ Jelszó
+ Hitelesítés
+ „%1$s = %2$s” nem érvényes ezzel: „%3$s = %4$s”
+ Érvénytelen beállítás: %s
+ Fiók beállításai
+ Fiók tömörítése
+ Mappa lekérdezésének gyakorisága
+ Soha
+ 15 percenként
+ 30 percenként
+ Óránként
+ 2 óránként
+ 3 óránként
+ 6 óránként
+ 12 óránként
+ 24 óránként
+ Levél küldésének engedélyezése ennél a fióknál
+ Ha a kiszolgáló támogatja, akkor az új üzenetek azonnal megjelennek. Ez az lehetőség drámaian növelheti vagy csökkenti a teljesítményt.
+ IDLE kapcsolat frissítése
+ 2 percenként
+ 3 percenként
+ 6 percenként
+ 12 percenként
+ 24 percenként
+ 36 percenként
+ 48 percenként
+ 60 percenként
+ Értesítés, amikor levél érkezik
+ Értesítés levél ellenőrzéskor
+ Megjelenítendő üzenetek száma
+ 10 üzenet
+ 25 üzenet
+ 50 üzenet
+ 100 üzenet
+ 250 üzenet
+ 500 üzenet
+ 1000 üzenet
+ 2500 üzenet
+ 5000 üzenet
+ 10000 üzenet
+ összes üzenet
+ Nem lehet másolni vagy áthelyezni a kiszolgálóval nem szinkronizált üzenetet.
+ A beállítást nem sikerült befejezni
+ A felhasználónév vagy a jelszó hibás.\n(%s)
+ A kiszolgáló érvénytelen SSL-tanúsítványt mutatott be. Néha ez a kiszolgáló hibás beállításából ered. Néha azért, mert valaki támadást hajtott végre Ön vagy a levelezőkiszolgálója ellen. Ha nem biztos abban, hogy mi történt, akkor kattintson az Elutasítás gombra, és vegye fel a kapcsolatot a levelezőkiszolgáló üzemeltetőivel.\n\n(%s)
+ Nem lehet kapcsolódni a kiszolgálóhoz.\n(%s)
+ Részletek szerkesztése
+ Folytatás
+ Bővített
+ Fiók beállításai
+ Új levél értesítések
+ Értesítések mappái
+ Összes
+ Csak 1. osztályú mappák
+ 1. és 2. osztályú mappák
+ Összes, kivéve a 2. osztályú mappákat
+ Nincs
+ Szinkronizációs értesítések
+ Saját e-mail-cím
+ Értesítés az állapotsávon új levél érkezésekor
+ Értesítés az állapotsávon a levelek ellenőrzésekor
+ Kimenő leveleknél is
+ Értesítés megjelenítése az elküldött üzeneteknél
+ Csak partnerek
+ Értesítések megjelenítése csak az ismert partnerektől érkező üzeneteknél
+ Csevegőüzenetek kihagyása
+ Ne jelenítsen meg értesítéseket az e -mail csevegéshez tartozó üzenetekről
+ Megjelölés olvasottként megnyitáskor
+ Üzenet megjelölése olvasottként megtekintésre megnyitáskor
+ Megjelölés olvasottként törléskor
+ Üzenet megjelölése olvasottként törléskor
+ Értesítési kategóriák
+ Értesítési beállítások az új üzenetekhez
+ Hiba- és állapotértesítések beállítása
+ Képek megjelenítése mindig
+ Nem
+ Partnerektől
+ Bárkitől
+ Levél küldése
+ Üzenet idézése válaszkor
+ Az eredeti üzenet felvétele a válaszba.
+ Válasz az idézett szöveg után
+ Az eredeti üzenet a válasz fölött jelenik meg.
+ Aláírások törlése válaszoláskor
+ Az aláírások el lesz távolítva az idézett üzenetekből
+ Üzenet formátuma
+ Egyszerű szöveg (képek és formázás eltávolítása)
+ HTML (képek és formázás megtartása)
+ Automatikus
+ A másolat és a titkos másolat mindig jelenjen meg
+ Olvasási visszaigazolás
+ Mindig kérjen olvasási visszaigazolást
+ Válasz idézésének stílusa
+ Előtag (mint például Gmail)
+ Fejléc (mint például Outlook)
+ Elküldött üzenetek feltöltése
+ Üzenetek feltöltése az Elküldött mappába a küldés után
+ Általános beállítások
+ Levél olvasása
+ Levél letöltése
+ Mappák
+ Idézett szöveg előtagja
+ Végpontok közötti titkosítás
+ OpenPGP támogatás engedélyezése
+ OpenPGP alkalmazás kiválasztása
+ Végpontok közötti kulcs beállítása
+ Nincs OpenPGP alkalmazás beállítva
+ Kapcsolódva: %s
+ Beállítás…
+ Az összes vázlat tárolása titkosítottan
+ Az összes vázlat titkosítva lesz tárolva
+ A vázlatok titkosítása csak a titkosítás engedélyezésekor
+ Mappa lekérdezésének gyakorisága
+ Fiókszín
+ A fiókban és a fióklistában használt fiók kiemelt színe
+ Nincs szín
+ Értesítési LED színe
+ Az eszköz villogó LED-ének színe ennél a fióknál
+ Helyi mappa mérete
+ Legfeljebb ennyi üzenet beolvasása
+ 1 KiB
+ 2 KiB
+ 4 KiB
+ 8 KiB
+ 16 KiB
+ 32 KiB
+ 64 KiB
+ 128 KiB
+ 256 KiB
+ 512 KiB
+ 1 MiB
+ 2 MiB
+ 5 MiB
+ 10 MiB
+ bármilyen méretű (nincs korlát)
+ Üzenetek szinkronizálása ekkortól
+ bármely idő (nincs korlát)
+ ma
+ az elmúlt 2 nap
+ az elmúlt 3 nap
+ az elmúlt hét
+ az elmúlt 2 hét
+ az elmúlt 3 hét
+ az elmúlt hónap
+ az elmúlt 2 hónap
+ az elmúlt 3 hónap
+ az elmúlt 6 hónap
+ az elmúlt év
+ Megjelenítendő mappák
+ Összes
+ Csak 1. osztályú mappák
+ 1. és 2. osztályú mappák
+ Összes, kivéve a 2. osztályú mappákat
+ Mappák lekérdezése
+ Összes
+ Csak 1. osztályú mappák
+ 1. és 2. osztályú mappák
+ Összes, kivéve a 2. osztályú mappákat
+ Nincs
+ Mappák küldése
+ Összes
+ Csak 1. osztályú mappák
+ 1. és 2. osztályú mappák
+ Összes, kivéve a 2. osztályú mappákat
+ Nincs
+ Áthelyezés vagy másolás a célmappákba
+ Összes
+ Csak 1. osztályú mappák
+ 1. és 2. osztályú mappák
+ Összes, kivéve a 2. osztályú mappákat
+ Kiszolgáló törléseinek szinkronizálása
+ Üzenetek eltávolítása a kiszolgálóról törléskor
+ Hiányzó OpenPGP alkalmazás – talán eltávolításra került.
+ Mappa beállításai
+ Megjelenítés a felső csoportban
+ Megjelenítés a mappalista teteje környékén
+ Mappa megjelenítésnek osztálya
+ Nincs osztály
+ 1. osztály
+ 2. osztály
+ Mappa lekérésének osztálya
+ Nincs
+ 1. osztály
+ 2. osztály
+ Ugyanaz, mint a megjelenítési osztály
+ Mappa küldésének osztálya
+ Nincs osztály
+ 1. osztály
+ 2. osztály
+ Ugyanaz, mint a lekérés osztálya
+ Mappa értesítésének osztálya
+ Nincs osztály
+ 1. osztály
+ 2. osztály
+ Ugyanaz, mint a küldés osztálya
+ Helyi üzenetek törlése
+ Bejövő kiszolgáló
+ A bejövő levelek kiszolgálójának beállítása
+ Kimenő kiszolgáló
+ A kimenő levelek (SMTP) kiszolgálójának beállítása
+ Fióknév
+ Saját név
+ Értesítések
+ Rezgés
+ Rezgés, amikor levél érkezik
+ Rezgés mintái
+ alapértelmezett
+ 1. minta
+ 2. minta
+ 3. minta
+ 4. minta
+ 5. minta
+ Rezgés ismétlése
+ Új levél csengőhangja
+ LED villogása
+ LED villogása, amikor levél érkezik
+ Üzenet írásának beállításai
+ Írási alapbeállítások
+ Alapértelmezett feladó, titkos másolat és aláírás beállítása
+ Személyazonosságok kezelése
+ Alternatív „feladó” címek és aláírások beállítása
+ Személyazonosságok kezelése
+ Személyazonosság kezelése
+ Személyazonosság szerkesztése
+ Mentés
+ Új személyazonosság
+ Titkos másolat küldése az összes üzenetről ide
+ Szerkesztés
+ Mozgatás fel
+ Mozgatás le
+ Áthelyezés legfelülre / alapértelmezetté tétel
+ Eltávolítás
+ Személyazonosság leírása
+ (Nem kötelező)
+ Az ön neve
+ (Nem kötelező)
+ E-mail-cím
+ (Kötelező)
+ Válaszcím
+ (Nem kötelező)
+ Aláírás
+ (Nem kötelező)
+ Aláírás használata
+ Aláírás
+ Kezdeti személyazonosság
+ Személyazonosság választása
+ Küldés más néven
+ Nem lehet eltávolítani az egyetlen személyazonosságát
+ Nem lehet használni egy személyazonosságot e-mail-cím nélkül
+ Legkorábbi üzenetek először
+ Legkésőbbi üzenetek először
+ Tárgy szerint betűrendben
+ Tárgy szerint fordított betűrendben
+ Feladó szerint betűrendben
+ Feladó szerint fordított betűrendben
+ Csillagozott üzenetek először
+ Nem csillagozott üzenetek először
+ Olvasatlan üzenetek először
+ Olvasott üzenetek először
+ Melléklettel rendelkező üzenetek először
+ Melléklet nélküli üzenetek először
+ Rendezési kritérium…
+ Dátum
+ Érkezés
+ Tárgy
+ Feladó
+ Csillag
+ Olvasott/olvasatlan
+ Mellékletek
+ Fiók eltávolítása
+ Felismerhetetlen tanúsítvány
+ Kulcs elfogadása
+ Kulcs visszautasítása
+ Del (vagy D) – Törlés\nR – Válasz\nA – Válasz mindenkinek\nC – Írás\nF – Továbbítás\nM – Áthelyezés\nV – Archiválás\nY – Másolás\nZ – Megjelölés olvasottként/olvasatlanként\nG – Csillagozás\nO – Rendezés típusa\nI – Rendezési sorrend\nQ – Visszatérés a mappákhoz\nS – Kijelölés/Kijelölés megszüntetése\nJ vagy P – Előző üzenet\nK vagy N – Következő üzenet
+ Del (vagy D) – Törlés\nC – Írás\nM – Áthelyezés\nV – Archiválás\nY – Másolás\nZ – Megjelölés olvasottként/olvasatlanként\nG – Csillagozás\nO – Rendezés típusa\nI – Rendezési sorrend\nQ – Visszatérés a mappákhoz\nS – Kijelölés/Kijelölés megszüntetése
+ Mappa neve tartalmazza
+ Mappák megjelenítése…
+ Összes mappa
+ 1. osztályú mappák
+ 1. és 2. osztályú mappák
+ 2, osztályú mappák elrejtése
+ Aláírás helyzete
+ Idézett üzenet előtt
+ Idézett üzenet után
+ Alkalmazás témájának használata
+ Sötét
+ Világos
+ Rendszer alapértelmezettjének használata
+ Megjelenés
+ Globális
+ Hibakeresés
+ Adatvédelem
+ Hálózat
+ Interakció
+ Fióklista
+ Üzenetlisták
+ Üzenetek
+ Téma
+ Üzenet nézetének témája
+ Üzenetírás témája
+ Nyelv
+ Nem találhatók beállítások
+ Rögzített üzenet téma
+ Az üzenetmegtekintési téma kiválasztása, miközben megtekinti az üzenetet
+ Rögzített üzenetmegtekintési téma használata
+ Rendszer alapértelmezettje
+ Háttér-szinkronizálás
+ Soha
+ Mindig
+ Amikor az „Automatikus szinkronizálás” be van jelölve
+ Összes kijelölése
+ Küldéssel ellenőrzendő mappák legnagyobb száma
+ 5 mappa
+ 10 mappa
+ 25 mappa
+ 50 mappa
+ 100 mappa
+ 250 mappa
+ 500 mappa
+ 1000 mappa
+ Animációk
+ Rikító látható hatások használata
+ Hangerő gomb navigáció
+ Üzenetnézetekben
+ Listanézetekben
+ Egységes beérkezett üzenetek megjelenítése
+ Csillagszámláló megjelenítése
+ %s%s
+ – Olvasatlan
+ Összes üzenet
+ Az összes üzenet kereshető mappákban
+ Egységes beérkezett üzenetek
+ Az összes üzenet egységes mappákban
+ Egyesítés
+ Az összes üzenetet az egységes beérkezett üzenetekben van megjelenítve
+ Keresés ezekben mappákban
+ Összes
+ Megjeleníthető
+ Nincs
+ Nincs
+ Automatikus (%s)
+ Betűméret
+ Betűméret beállítása
+ Fióklista
+ Fiók neve
+ Fiók leírása
+ Mappalisták
+ Mappa neve
+ Mappa állapota
+ Üzenetlisták
+ Tárgy
+ Feladó
+ Dátum
+ Előnézet
+ Üzenetek
+ Feladó
+ Címzett
+ Másolat
+ Titkos másolat
+ További fejlécek
+ Tárgy
+ Idő és dátum
+ Üzenet törzse
+ %d%%
+ %1$s: %2$s
+ Üzenet írása
+ Szöveg beviteli mezők
+ Alapértelmezett
+ Mini
+ Pici
+ Kisebb
+ Kicsi
+ Közepes
+ Nagy
+ Nagyobb
+ Nem található megfelelő alkalmazás ehhez a művelethez.
+ A küldés sikertelen: %s
+ Menti piszkozatként?
+ Menti vagy elveti ezt az üzenetet?
+ Menti vagy elveti a változtatásokat?
+ Elveti az üzenet?
+ Biztosan el szeretné vetni ezt az üzenetet?
+ Szöveg kijelölése a másoláshoz.
+ Helyi üzenetek kiürítése
+ Ez eltávolítja az összes helyi üzenetet mappából. Az üzenetek nem kerülnek törlésre a szerverről.
+ Üzenetek kiürítése
+ Törlés megerősítése
+ Biztosan törölni szeretné ezt az üzenetet?
+
+ Valóban törölni szeretné ezt az üzenetet?
+ Biztosan törölni szeretne %1$d üzenetet?
+
+ Igen
+ Nem
+ Megerősítés, hogy az összeset olvasottként jelölje
+ Szeretné megjelölni az összes üzenetet olvasottként?
+ Kuka ürítésének megerősítése
+ Ki szeretné üríteni a kuka mappát?
+ Igen
+ Nem
+ Megerősítés, hogy áthelyezze a levélszemét mappába
+
+ Valóban át akarja helyezni ezt a levelet a spam mappába?
+ Valóban át szeretne helyezni %1$d üzenetet a levélszemét mappába?
+
+ Igen
+ Nem
+ Melléklet letöltése
+ »
+ ›
+ Biztonsági mentés
+ Egyebek
+ Beállítások exportálása
+ Exportálás
+ Megosztás
+ Beállítások exportálása…
+ A beállítások sikeresen exportálva
+ A beállítások exportálása sikertelen
+ Beállítások importálása
+ Fájl kiválasztása
+ Importálás
+ A beállítások sikeresen importálva
+ Adja meg a jelszavakat
+ Nem sikerült importálni a beállításokat
+ Nem sikerült beolvasni a beállítások fájlt
+ Nem sikerült importálni néhány beállítást
+ Sikeresen importálva
+ Jelszó szükséges
+ Nincs importálva
+ Importálási hiba
+ Később
+ Beállítások importálása
+ Beállítások importálása…
+
+ Ahhoz, hogy képes legyen használni a(z) „%s” fiókot, meg kell adnia a kiszolgáló jelszavát.
+ Ahhoz, hogy képes legyen használni a(z) „%s” fiókot, meg kell adnia a kiszolgáló jelszavait.
+
+ Bejövő kiszolgáló jelszava
+ Kimenő kiszolgáló jelszava
+ Ugyanazon jelszó használata a kimenő kiszolgálónál
+ Kiszolgáló neve: %s
+ Olvasatlanok számának megjelenítése ennél…
+ Fiók
+ Az a fiók, amelynél az olvasatlanok számlálóját meg kell jeleníteni
+ Egységes beérkezett üzenetek
+ Mappa számláló
+ Az olvasatlan számláló megjelenítése csak egy önálló mappára
+ Mappa
+ Az a mappa, amelynél az olvasatlanok számlálóját meg kell jeleníteni
+ Kész
+ %1$s – %2$s
+ Nincs fiók kiválasztva
+ Nincs mappa kiválasztva
+ Nincs szöveg
+ Hivatkozás megnyitása
+ Hivatkozás megosztása
+ Hivatkozás másolása a vágólapra
+ Hivatkozás
+ Hivatkozás szövegének másolása a vágólapra
+ Hivatkozás szövege
+ Kép
+ Kép megtekintése
+ Kép mentése
+ Kép letöltése
+ Kép URL-jének másolása a vágólapra
+ Kép URL
+ Szám hívása
+ Mentés a címjegyzékbe
+ Szám másolása a vágólapra
+ Telefonszám
+ Levél küldése
+ Mentés a címjegyzékbe
+ Cím másolása a vágólapra
+ E-mail-cím
+ Összes
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Kiszolgáló keresési korlátja
+ Lekérdezés küldése a kiszolgálónak
+
+ %d találat lekérése
+ %d találat lekérése
+
+
+ %1$d/%2$d találat lekérése
+ %1$d/%2$d találat lekérése
+
+ A távoli keresés sikertelen
+ Keresés
+ Kiszolgálón keresés engedélyezése
+ Üzenetek keresése a kiszolgálón az eszközön lévők mellett
+ Üzenetek keresése a kiszolgálón
+ Hálózati kapcsolat szükséges a kiszolgálón kereséshez.
+ Szín megváltoztatása olvasáskor
+ Az eltérő háttér azt jelzi, hogy az üzenetet elolvasták
+ Beszélgetés nézet
+ Üzenetek csoportosítása beszélgetés szerint
+ Adatbázisok frissítése
+ Adatbázisok frissítése…
+ A(z) „%s” fiók adatbázisának frissítése
+ Osztott képernyő megjelenítése
+ Mindig
+ Soha
+ Amikor fekvő módban van
+ Válasszon egy üzenetet a bal oldalon
+ Partner képeinek megjelenítése
+ Partner képeinek megjelenítése az üzenetlistában
+ Összes megjelölése olvasottként
+ Partnerek képeinek színezése
+ Hiányzó partnerek képeinek színezése
+ Látható üzenetműveletek
+ A kiválasztott műveletek megjelenítése az üzenetnézet menüben
+ Melléklet betöltése…
+ Üzenet küldése
+ Piszkozat mentése
+ Melléklet letöltése…
+ Nem lehet hitelesíteni. A kiszolgáló nem teszi közzé a SASL EXTERNAL képességet. Ezt okozhatja egy probléma a kliens tanúsítványával (lejárt, ismeretlen hitelesítésszolgáltató) vagy bármilyen egyéb beállítási probléma.
+
+ Ügyféltanúsítvány használata
+ Nincs ügyféltanúsítvány
+ Ügyféltanúsítvány kiválasztásának eltávolítása
+ Nem sikerült lekérni az ügyféltanúsítványt a következő álnévhez: „%s”
+ Speciális beállítások
+ A(z) „%1$s” ügyféltanúsítvány lejárt vagy még nem érvényes (%2$s)
+
+ *Titkosított*
+ Hozzáadás címjegyekből
+ Másolat
+ Titkos másolat
+ Címzett
+ Feladó
+ Válasz címzettje
+ <Címzett ismeretlen>
+ <Feladó ismeretlen>
+ Otthon
+ Munkahely
+ Egyéb
+ Mobil
+ Nincs piszkozatok mappa beállítva ehhez a fiókhoz!
+ Nincs kulcs beállítva ehhez a fiókhoz! Ellenőrizze a beállításokat.
+ A titkosításszolgáltató nem megfelelő verziót használ. Ellenőrizze a beállításokat!
+ Nem sikerült kapcsolódni a titkosításszolgáltatóhoz. Ellenőrizze a beállításokat, vagy kattintson ismét a titkosítás ikonra!
+ Nem sikerült előkészíteni a végpontok közötti titkosítást, ellenőrizze a beállításokat
+ A PGP/INLINE mód nem támogatja a mellékleteket!
+ PGP/INLINE engedélyezése
+ PGP/INLINE letiltása
+ Csak PGP aláírás engedélyezése
+ Csak PGP aláírás letiltása
+ PGP/INLINE mód
+ A levél PGP/INLINE formátumban lett küldve.\nEzt csak kompatibilitás miatt kell használni:
+ Néhány kliens csak ezt a formátumot támogatja
+ Az aláírások sérülhetnek az átvitel során
+ A mellékletek nem támogatottak
+ Értem!
+ Letiltás
+ Engedélyezve tartás
+ Értem!
+ Letiltás
+ Engedélyezve tartás
+ Csak PGP aláírás mód
+ Ebben a módban a PGP kulcs lesz használva egy titkosítatlan e-mail kriptográfiai aláírásának létrehozásához.
+ Ez nem titkosítja az e-mailt, de ellenőrzi, hogy az ön kulcsából lett elküldve.
+ Az aláírások sérülhetnek, ha levelezőlistákra küldi.
+ Az aláírások „signature.asc” mellékletekként lehetnek megjelenítve néhány kliensprogramban.
+ A titkosított üzenetek mindig tartalmaznak aláírást.
+ Egyszerű szöveg
+ a végpontok közötti aláírás hibát tartalmazott
+ teljesen le kell tölteni az üzenetet az aláírás feldolgozásához
+ nem támogatott végpontok közötti aláírást tartalmaz
+ Az üzenet titkosított, de nem támogatott formátumban.
+ Az üzenet titkosított, de a visszafejtést megszakították.
+ Végpontok közötti aláírt egyszerű szöveg
+ ellenőrzött aláírótól
+ Aláírt egyszerű szöveg
+ de a végpontok közötti kulcs nem egyezik a feladóval
+ de a végpontok közötti kulcs lejárt
+ de a végpontok közötti kulcsot visszavonták
+ de a végpontok közötti kulcs nem tekinthető biztonságosnak
+ ismeretlen végpontok közötti kulcstól
+ Titkosított
+ de visszafejtési hiba történt
+ teljesen le kell tölteni az üzenetet a visszafejtéshez
+ de nincs titkosító alkalmazás beállítva
+ Titkosított
+ de nem végpontok közötti
+ Végpontok között titkosított
+ ellenőrzött feladótól
+ Titkosított
+ ismeretlen végpontok közötti kulcstól
+ de a végpontok közötti kulcs nem egyezik a feladóval
+ de a végpontok közötti kulcs lejárt
+ de a végpontok közötti kulcsot visszavonták
+ de a végpontok közötti kulcs nem tekinthető biztonságosnak
+ de a végpontok közötti adatok hibákat tartalmaznak
+ de a titkosítás nem tekinthető biztonságosnak
+ OK
+ Kulcs keresése
+ Aláíró megtekintése
+ Feladó megtekintése
+ Részletek
+ Feloldás
+ Ez a rész nem volt titkosítva, és esetleg nem biztonságos.
+ Nem védett melléklet
+ Betöltés…
+ A visszafejtést megszakították.
+ Újra
+ A titkosított üzenetet le kell tölteni a visszafejtéshez.
+ Hiba az e-mail visszafejtésekor
+ A különleges karakterek jelenleg nem támogatottak!
+ Hiba a cím feldolgozásakor!
+ Titkosítatlan aláírások elrejtése
+ Csak a titkosított aláírások lesznek megjelenítve
+ Az összes aláírás meg lesz jelenítve
+ A titkosítás nem érhető el csak aláíró módban!
+ Aláíratlan szöveg
+ APG elavultsági figyelmeztetés
+ Az APG többé nincs karbantartva!
+ Emiatt az APG támogatás eltávolításra került a K-9 Mail alkalmazásból.
+ A fejlesztés 2014 elején leállt
+ Javítatlan biztonsági hibákat tartalmaz
+ Kattintson ide, ha többet szeretne megtudni.
+ Értem!
+ APG
+ Ez az e-mail titkosított
+ 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.
+ Ugrás a beállításokhoz
+ K-9 üzenetlista
+ Üzenetek betöltése…
+ A mappalista lekérése sikertelen
+ Hiba a címzettek állapotának lekérésekor az OpenPGP szolgáltatótól!
+ A titkosítás nem lehetséges
+ Néhány kiválasztott címzett nem támogatja ezt a funkciót!
+ Titkosítás engedélyezése
+ Titkosítás letiltása
+ Az üzenetek titkosítása biztosítja, hogy azokat csak a címzett olvashatja lel és senki más.
+ A titkosítás csak akkor jelenik meg, ha az összes címzett támogatja, és korábban már küldtek e-mailt önnek.
+ Titkosítási be- és kikapcsolása erre az ikonra kattintva.
+ Értem
+ Vissza
+ Titkosítás letiltása
+ OpenPGP titkosítás
+ Autocrypt kölcsönös mód
+ Autocrypt kölcsönös mód
+ Az üzenetek normál esetben választás alapján lesznek titkosítva, vagy ha egy titkosított üzenetre válaszol.
+ Ha mind a feladó, mind a címzettek támogatják a kölcsönös módot, akkor a titkosítás alapértelmezetten engedélyezve lesz.
+ Kattintson ide, ha többet szeretne megtudni.
+ Általános beállítások
+ Nincs OpenPGP alkalmazás telepítve
+ Telepítés
+ A K-9 Mail az OpenKeychain alkalmazást igényli a végpontok közötti titkosításhoz.
+ Titkosított üzenet
+ Üzenet tárgyainak titkosítása
+ Néhány címzett esetleg nem támogatja
+ Belső hiba: érvénytelen fiók!
+ Hiba a következőhöz való kapcsolódáskor: %s!
+ Autocrypt beállítási üzenet küldése
+ Végpontok közötti beállítás biztonságos megosztása más eszközökkel
+ Autocrypt beállítási üzenet
+ Egy automatikusan titkosított beállítási üzenet biztonságosan megosztja a végpontok közötti beállítást más eszközökkel.
+ Beállítási üzenet küldése
+ Az üzenet az ön címére lesz elküldve:
+ Beállítási üzenet előállítása…
+ Üzenet küldése neki:
+ A befejezéshez nyissa meg az üzenetet a másik eszközén, és írja be a beállítási kódot.
+ Beállítási kód megjelenítése
+ Autocrypt beállítási üzenet
+ Ez az üzenet minden információt tartalmaz az Autocrypt beállítások és a titkos kulcs biztonságos átviteléhez az eredeti eszközről.
Az új eszköz Autocrypthez történő beállításához kövesse az utasításokat, amelynek az új eszközön kell megjelennie.
Megtarthatja ezt az üzenetet, és felhasználhatja a titkos kulcs biztonsági mentéséhez. Ha ezt szeretné tenni, akkor fel kell írnia a jelszót, és biztonságosan kell tárolnia.
- Hiba történt az üzenet elküldése során. Ellenőrizze a hálózati kapcsolatot és a kimenő kiszolgáló beállítását.
- Be
- Ki
- Megnyitás
- Bezárás
-
- Hozzáférés engedélyezése a partnerekhez
- Ahhoz, hogy partnerjavaslatokat tudjon tenni és meg tudja jeleníteni a partner nevét és fényképeit, az alkalmazásnak hozzáférésre van szüksége a partnereihez.
- Hiba történt az adatok betöltése során
- Előkészítés…
- Várakozás az új e-mailekre
- Alvás addig, amíg a háttérbeli szinkronizálás engedélyezésre nem kerül
- Alvás addig, amíg a hálózat elérhetővé nem válik
- Koppintson ide a további tudnivalókért.
- Leküldési információk
- Amikor leküldést használ, a K-9 Mail egy kapcsolatot tart fenn a levelezőkiszolgálóval. Az Android megköveteli, hogy értesítést jelenítsen meg az alkalmazás, ha aktív a háttérben. %s
- Viszont az Android azt is lehetővé teszi, hogy elrejtse az értesítést.
- További tudnivaló
- Értesítés beállítása
- Ha nincs szüksége azonnali értesítésekre az új levelekről, akkor letilthatja a leküldést, és használhat lekérést. A lekérés rendszeres időközönként ellenőrzi, hogy vannak-e új levelek, és nincs szüksége értesítés megjelenítésére.
- Leküldés letiltása
-
\ No newline at end of file
+ Hiba történt az üzenet elküldése során. Ellenőrizze a hálózati kapcsolatot és a kimenő kiszolgáló beállítását.
+ Be
+ Ki
+ Megnyitás
+ Bezárás
+
+ Hozzáférés engedélyezése a partnerekhez
+ Ahhoz, hogy partnerjavaslatokat tudjon tenni és meg tudja jeleníteni a partner nevét és fényképeit, az alkalmazásnak hozzáférésre van szüksége a partnereihez.
+ Hiba történt az adatok betöltése során
+ Előkészítés…
+ Várakozás az új e-mailekre
+ Alvás addig, amíg a háttérbeli szinkronizálás engedélyezésre nem kerül
+ Alvás addig, amíg a hálózat elérhetővé nem válik
+ Koppintson ide a további tudnivalókért.
+ Leküldési információk
+ Amikor leküldést használ, a K-9 Mail egy kapcsolatot tart fenn a levelezőkiszolgálóval. Az Android megköveteli, hogy értesítést jelenítsen meg az alkalmazás, ha aktív a háttérben. %s
+ Viszont az Android azt is lehetővé teszi, hogy elrejtse az értesítést.
+ További tudnivaló
+ Értesítés beállítása
+ Ha nincs szüksége azonnali értesítésekre az új levelekről, akkor letilthatja a leküldést, és használhat lekérést. A lekérés rendszeres időközönként ellenőrzi, hogy vannak-e új levelek, és nincs szüksége értesítés megjelenítésére.
+ Leküldés letiltása
+
diff --git a/app/ui/legacy/src/main/res/values-in/strings.xml b/app/ui/legacy/src/main/res/values-in/strings.xml
index 82195d13f9425c41d887dae392fffb57b2c973d4..498fca835df2acf62d255894f0798ab171b6aa9a 100644
--- a/app/ui/legacy/src/main/res/values-in/strings.xml
+++ b/app/ui/legacy/src/main/res/values-in/strings.xml
@@ -237,10 +237,6 @@
Remove Mail User-Agent from mail headersSembunyikan zona waktuGunakan UTC, bukan zona waktu lokal di header email dan header balasan
- Sembunyikan subyek dalam notifikasi
- Tidak pernah
- Ketika perangkat di kunci
- SelaluTampilkan tombol \'Hapus\'Tidak pernahUntuk notifikasi pesan tunggal
@@ -248,7 +244,6 @@
Notifikasi Layar PenguncianTidak ada pemberitahuan layar kunciNama aplikasi
- Jumlah pesan belum dibacaJumlah pesan dan pengirimSama seperti saat layar tidak dikunciWaktu Hening
@@ -261,6 +256,7 @@
Alamat surelSandiTampilkan sandi
+
ManualMengambil informasi akun\u2026
@@ -302,8 +298,6 @@
MobileWi-FiLainnya
- Penyimpanan eksternal (kartu SD)
- Penyimpanan internal umumHapus pesan yang dihapus di serverSegeraKetika menarik
@@ -379,8 +373,6 @@
LanjutkanLanjutanPengaturan akun
- Akun bawaan
- Kirim email dari akun ini secara bawaanPemberitahuan surat baruFolder notifikasiSemua
@@ -400,8 +392,6 @@
Tandai pesan sebagai telah dibaca saat dibuka untuk dilihatTandai sebagai terbaca saat dihapusTandai pesan sebagai terbaca saat dihapus
- Pengaturan notifikasi
- Buka pengaturan notifikasi sistemSelalu tampilkan gambarTidakDari kontak
diff --git a/app/ui/legacy/src/main/res/values-is/strings.xml b/app/ui/legacy/src/main/res/values-is/strings.xml
index af66ac75190f1bacd63586b22f1c9842e062beb0..89faeefc352be11c7fa9539eebb94e77562565ff 100644
--- a/app/ui/legacy/src/main/res/values-is/strings.xml
+++ b/app/ui/legacy/src/main/res/values-is/strings.xml
@@ -49,6 +49,8 @@
Áframsenda sem viðhengiVeldu aðgangVeldu möppu
+ Færa í…
+ Afrita í…Athuga %s:%s%sSæki hausa %s:%s%sSendi %s%s
@@ -82,6 +84,7 @@
HendaVista sem drögAthuga póst
+ Athuga póst á öllum aðgöngumSenda póstEndurnýja möppulistaFinna möppu
@@ -246,10 +249,6 @@
Remove Mail User-Agent from mail headersFela tímabeltiNota UTC sem staðvært tímabelti í pósthausum og svarhausum
- Fela viðfangsefni í tilkynningum
- Aldrei
- Þegar tækið er læst
- AlltafSýna \'Eyða\' hnappAldreiFyrir tilkynningu um stakan póst
@@ -257,7 +256,6 @@
Tilkynningar á skjálæsinguEngar tilkynningar á skjálæsinguNafn forritsins
- Fjöldi ólesinna skilaboðaFjöldi skilaboða og sendendaSama og þegar skjárinn er ólæsturKyrrðarstund
@@ -270,6 +268,10 @@
NetfangLykilorðSýna lykilorð
+
+ Til að skoða lykilorðið þitt hér skaltu virkja skjálæsingu á þessu tæki
+ Sannreyndu auðkennin þín
+ Aflæstu til að skoða lykilorðið þittHandvirk uppsetningNæ í upplýsingar um aðgang\u2026
@@ -311,8 +313,6 @@
FarsímakerfiÞráðlausu Wi-FiAnnað
- Ytri geymsla (SD-minniskort)
- Venjuleg innri geymslaÞurrka út eyddum skilaboðum á póstþjóniStraxVið athuganir
@@ -388,8 +388,6 @@
ÁframÍtarlegtAðgangsstillingar
- Sjálfgefinn aðgangur
- Senda póst sjálfgefið úr þessum aðgangiTilkynningar um nýjan póstTilkynningamöppurAllar
@@ -405,12 +403,15 @@
Birta tilkynningu fyrir skilaboð sem ég sendiEinungis tengiliðirEinungis birta tilkynningar fyrir skilaboð frá þekktum tengiliðum
+ Hunsa spjallskilaboð
+ Ekki birta tilkynningar vegna skilaboða sem tilheyra spjalli í tölvupóstiMerkja sem lesið þegar er opnaðMerkja skilaboð sem lesin þegar þau eru opnuð til lestrarMerkja sem lesið þegar er eyttMerkja skilaboð sem lesin þegar þeim er eytt
- Stillingar á tilkynningum
- Opna stillingar kerfisins fyrir tilkynningar
+ Flokkar tilkynninga
+ Stilla tilkynningar vegna nýrra skilaboða
+ Stilla tilkynningar vegna stöðu- og villumeldingaAlltaf sýna myndirNeiFrá tengiliðum
@@ -663,6 +664,7 @@
Í skilaboðasýnumÍ listasýnumBirta sameinað innhólf
+ Birta fjölda stjarna%s%s- ÓlesiðÖll skilaboð
@@ -872,6 +874,7 @@
Falið afritTilFrá
+ Svara<Óþekktur viðtakandi><Óþekktur sendandi>Heima
diff --git a/app/ui/legacy/src/main/res/values-it/strings.xml b/app/ui/legacy/src/main/res/values-it/strings.xml
index 8ad88c1fbf6a65b9b54040741d703b9f337ca5fa..85ae7d3023016631f3a23f46d37a738bc372c3fe 100644
--- a/app/ui/legacy/src/main/res/values-it/strings.xml
+++ b/app/ui/legacy/src/main/res/values-it/strings.xml
@@ -49,6 +49,8 @@
Inoltra come allegatoScegli accountScegli cartella
+ Sposta in...
+ Copia in...Recupero da %s: %s%sRecupero intestazioni %s:%s%sInvio %s%s
@@ -82,6 +84,7 @@
IgnoraSalva come bozzaControlla posta
+ Controlla la posta in tutti gli accountInvia messaggiAggiorna elenco cartelleTrova cartella
@@ -246,10 +249,6 @@
Remove Mail User-Agent from mail headersNascondi fuso orarioUsa UTC invece del fuso orario locale nelle intestazioni dei messaggi e nell\'intestazione delle risposte
- Nascondi l\'oggetto nelle notifiche
- Mai
- Quanto lo schermo è bloccato
- SempreMostra il pulsante \'Elimina\'MaiPer la notifica di un singolo messaggio
@@ -257,7 +256,7 @@
Notifiche schermata di bloccoNessuna notifica sulla schermata di bloccoNome applicazione
- Numero messaggi non letti
+ Numero nuovi messaggiNumero messaggi e mittentiCome quando lo schermo è sbloccatoModalità silenziosa
@@ -270,6 +269,10 @@
Indirizzo emailPasswordMostra password
+
+ Per visualizzare la tua password qui, abilita il blocco dello schermo su questo dispositivo.
+ Verifica la tua identità
+ Sblocca per visualizzare la tua passwordConfigurazione manualeRecupero delle informazioni dell\'account\u2026
@@ -311,8 +314,6 @@
CellulareWi-FiAltra
- Memoria esterna (SD card)
- Memoria interna standardCancella i messaggi eliminati sul serverImmediatamenteDurante ogni recupero
@@ -388,8 +389,6 @@
ContinuaAvanzateImpostazioni account
- Account predefinito
- Invia i messaggi da questo account in modo predefinitoNotifiche nuovi messaggiNotifiche delle cartelleTutte
@@ -405,12 +404,15 @@
Mostra una notifica per i messaggi che ho inviatoSolo contattiMostra notifiche solo per i messaggi da contatti conosciuti
+ Ignora i messaggi di chat
+ Non visualizzare notifiche per i messaggi appartenenti ad una chatMarca come letto all\'aperturaMarca un messaggio come letto quando viene aperto per la visualizzazioneMarca come letto all\'eliminazione Marca un messaggio come letto quando viene eliminato
- Impostazioni notifiche
- Apri le impostazioni di sistema delle notifiche
+ Categorie di notifiche
+ Configura le notifiche per i nuovi messaggi
+ Configura le notifiche per errori e statoMostra sempre le immaginiNoDai contatti
@@ -663,6 +665,7 @@
In visualizzazione messaggiIn visualizzazione elencoMosta posta in arrivo combinata
+ Mostra il numero dei messaggi con stella%s%s- Non lettoTutti i messaggi
@@ -872,6 +875,7 @@
CcnADa
+ Rispondi a<Destinatario sconosciuto><Mittente sconosciuto>Casa
diff --git a/app/ui/legacy/src/main/res/values-iw/strings.xml b/app/ui/legacy/src/main/res/values-iw/strings.xml
index 3cd40b69abdd2085ebf990677e26e4d61e304194..0b9dd8ffa0941804f9eae922c8ca45821607b208 100644
--- a/app/ui/legacy/src/main/res/values-iw/strings.xml
+++ b/app/ui/legacy/src/main/res/values-iw/strings.xml
@@ -192,9 +192,6 @@
מחק הודעות שמסומנות בכוכב (בתצוגת הודעה)דואר זבלמחק הודעה
- אף פעם
- כשהמכשיר נעול
- תמידהצג את הכפתור \'מחק\'אף פעםתמיד
@@ -205,6 +202,7 @@
הגדר חשבון חדשכתובת דוא\"לסיסמא
+
הוראות הגדרהמאחזר מידע חשבון …
@@ -238,8 +236,6 @@
סלולריWi-Fiאחר
- אחסון חיצוני (כרטיס SD)
- אחסון פנימי רגיללמחוק הודעות שנמחקומידWhen polling
@@ -304,8 +300,6 @@
המשךמתקדםהגדרות חשבון
- חשבון ברירת מחדל
- לשלוח דואר מחשבון זה כברירת מחדלהתראות על הודעה חדשההכלכלום
diff --git a/app/ui/legacy/src/main/res/values-ja/strings.xml b/app/ui/legacy/src/main/res/values-ja/strings.xml
index 58710e8277ba473a5434ce9fb0d09efa194a99b6..287ec1194f9b61c6a0bcc81b44ebd07a90e661a4 100644
--- a/app/ui/legacy/src/main/res/values-ja/strings.xml
+++ b/app/ui/legacy/src/main/res/values-ja/strings.xml
@@ -23,6 +23,7 @@
バージョン %s新着アプリの更新後に更新内容を表示する
+ このリリースは何が新しいのかを知るWelcome to MailMail is the default mail client for /e/
@@ -48,6 +49,8 @@
添付として転送アカウントの選択フォルダ選択
+ …へ移動
+ …へコピー受信 %s:%s%sヘッダ取込 %s:%s%s送信 %s%s
@@ -81,12 +84,14 @@
破棄下書きへ保存メール受信
+ すべてのアカウントのメールを確認するメール送信フォルダ一覧を再読込フォルダを探すアカウント追加作成検索
+ あらゆる所を検索検索結果設定フォルダ管理
@@ -151,6 +156,8 @@
メール送信中: %sメール送信中:
+ 同期(プッシュ)
+ 新着メッセージ待機中に表示されるメッセージ表示メッセージに関連した通知その他
@@ -239,10 +246,6 @@
Remove Mail User-Agent from mail headersタイムゾーンを隠すメールヘッダと返信ヘッダにローカルタイムゾーンの代わりにUTCを利用します
- 通知時にメールの題名を隠すか
- 常に表示する
- ロック時のみ隠す
- 常に隠す削除ボタンを表示常に表示しない通知メッセージが1件の場合
@@ -250,7 +253,7 @@
ロック画面通知ロック画面通知なしアプリケーション名
- 未読件数
+ 新着メッセージ件数メッセージ件数と送信者画面ロックの解除と同じ夜間時間帯
@@ -263,6 +266,10 @@
メールアドレスパスワードパスワードを表示
+
+ ここでパスワードを表示するには、このデバイスの画面ロックを有効にしてください。
+ あなたの本人確認
+ ロック解除してあなたのパスワードを表示する手動設定アカウント情報を取得中\u2026
@@ -304,8 +311,6 @@
モバイルWiFiその他
- 外部ストレージ (SDカード)
- 内部ストレージサーバから削除したメッセージを消す削除または移動後即時同期のタイミングで
@@ -381,8 +386,6 @@
続行プッシュ接続の拡張設定アカウント設定
- 標準アカウント
- このアカウントをメール送信に利用する受信メール通知通知するフォルダすべて
@@ -398,12 +401,15 @@
このアカウントからのメールも通知する連絡先のみ既知の連絡先からのメッセージのみ通知を表示します
+ チャットメッセージを無視する
+ メールチャットに属するメッセージの通知を表示しない開くと同時に既読にするメッセージを参照したときに既読にする削除時に既読にするメッセージが削除されたときに既読にします
- 通知設定
- システム通知設定を開きます
+ 通知カテゴリ
+ 新着メッセージの通知を設定
+ エラーと状態通知を設定画像を自動で表示しない連絡先に登録しているユーザからのメールのみ
@@ -519,6 +525,7 @@
クラスなし1st クラス2nd クラス
+ 受信クラスと同一設定フォルダ通知クラスクラスなし1st クラス
@@ -655,6 +662,7 @@
メッセージ表示一覧表示統合フォルダを表示
+ フラグの数を表示する%s%s - 未読全メッセージ
@@ -860,6 +868,7 @@
Bcc宛先送信者
+ 返信先<不明な受信者><不明な送信者>自宅
@@ -1010,5 +1019,15 @@
連絡先の提案をできるようにし、連絡先の名前と写真を表示するには、アプリが連絡先にアクセスする必要があります。データの読み込み中にエラーが発生しました初期化しています…
+ 新着メッセージ待機中
+ バックグラウンド同期が許可されるまでスリープ
+ ネットワークが利用可能になるまでスリープ
+ タップして詳細を表示。
+ プッシュ情報
+ プッシュを使用する場合、K-9 Mailはメールサーバーへの接続を維持します。Androidでは、アプリがバックグラウンドで動作している間、継続して通知を表示する必要があります。%s
+ しかし、Androidでは、通知を隠すこともできます。
+ 詳細を表示通知設定
+ 新しいメッセージの即時通知が不要な場合は、プッシュを無効にして同期を使用してください。同期は、一定の間隔で新着メールを確認するので、通知は必要ありません。
+ プッシュを無効にする
diff --git a/app/ui/legacy/src/main/res/values-ko/strings.xml b/app/ui/legacy/src/main/res/values-ko/strings.xml
index 59f8fefad98a0f2de47c61fef9aecf8cdd26e50e..7d3472ca12ba328ef1519dde2ae7d5ed2568c8fa 100644
--- a/app/ui/legacy/src/main/res/values-ko/strings.xml
+++ b/app/ui/legacy/src/main/res/values-ko/strings.xml
@@ -206,10 +206,6 @@
메일 클라이언트를 숨김Remove Mail User-Agent from mail headers시간 구역을 숨기기
- 알림에 제목 숨기기
- 하지 않음
- 폰이 잠겨 있을 때
- 항상\'삭제\' 버튼 보이기하지 않음알림에 메시지가 하나뿐일 때만
@@ -217,7 +213,6 @@
잠금 화면 알림잠금 화면 알림 없음앱 이름
- 읽지 않은 메세지 개수메세지 개수와 발신자화면이 잠금 해제되었을때와 동일무음 시간
@@ -229,6 +224,7 @@
이메일 주소비밀번호암호 표시
+
수동 설정계정 정보 복구\u2026
@@ -269,8 +265,6 @@
모바일 네트워크Wi-Fi기타
- 외부 저장장치(SD card)
- 일반적인 내부 저장장치삭제된 메시지를 제거즉시수신 시
@@ -345,8 +339,6 @@
계속고급계정 설정
- 기본 계정
- 보내기 기본 계정으로 사용합니다새 메일 알림알림 폴더모두
diff --git a/app/ui/legacy/src/main/res/values-lt/strings.xml b/app/ui/legacy/src/main/res/values-lt/strings.xml
index 7ca571b313eec13e628d6292ab766729af3869be..88affc322e34e5f874d3b3408f61d0b1428ae025 100644
--- a/app/ui/legacy/src/main/res/values-lt/strings.xml
+++ b/app/ui/legacy/src/main/res/values-lt/strings.xml
@@ -175,10 +175,6 @@
Pašalinti pažymėtus žvaigždute (pranešimų rodinyje)BrukalasPašalinti
- Pranešimuose slėpti temą
- Niekada
- Kai įrenginys užrakintas
- VisadaRodyti mygtuką „Šalinti“NiekadaVieno laiško pranešimui
@@ -190,6 +186,7 @@
Nustatyti naują paskyrąEl. pašto adresasSlaptažodis
+
Rankinis nustatymasGaunama paskyros informacija…
@@ -223,8 +220,6 @@
MobilusWi-FiKita
- Išorinė saugykla (SD kortelė)
- Įprasta vidinė saugyklaPašalinti ištrintus laiškus serveryjeTuojau patKai užklausiama
@@ -293,8 +288,6 @@
TęstiIšplėstinisAplanko nustatymai
- Numatytoji paskyra
- Pagal nutylėjimą laiškus siųsti iš šios paskyrosPranešimai apie naujus laiškusVisiTik 1 klasės aplankai
diff --git a/app/ui/legacy/src/main/res/values-lv/strings.xml b/app/ui/legacy/src/main/res/values-lv/strings.xml
index db6971751249ac4828ca34916641e11ba1405e61..c2f6845b7a80498d29e7ba145dfbfa81ae88a798 100644
--- a/app/ui/legacy/src/main/res/values-lv/strings.xml
+++ b/app/ui/legacy/src/main/res/values-lv/strings.xml
@@ -21,6 +21,9 @@
Izmaiņu žurnālsNevarēja ielādēt izmaiņu žurnālu.Versija %s
+ Kas jauns
+ Parādīt pēdējās izmaiņas kopš lietotnes atjaunošanas
+ Uzzināt, kas jauns šajā versijāWelcome to MailMail is the default mail client for /e/
@@ -46,6 +49,8 @@
Pārsūtīt kā pielikumuIzvēlēties kontuIzvēlēties mapi
+ Pārvietot uz ...
+ Kopēt uz ...Pārbauda %s:%s%sSaņem vēstuļu papildinformāciju %s:%s%sSūta %s%s
@@ -79,6 +84,7 @@
IzmestSaglabāt kā melnrakstuPārbaudīt pastu
+ Pārbaudīt pastu visos kontosSūtīt vēstulesAtsvaidzināt mapju sarakstuMeklēt mapi
@@ -245,10 +251,6 @@ pat %d vairāk
Remove Mail User-Agent from mail headersPaslēpt laika zonuIzmantot UTC laika zonu vēstules papildinformācijā
- Paslēpt tematu paziņojumos
- Nekad
- Kad ierīce ir bloķēta
- VienmērRādīt \'Dzēst\' poguNekadVienas vēstules paziņojumam
@@ -256,7 +258,7 @@ pat %d vairāk
Paziņojumi bloķētā ekrānāNekādus paziņojumus bloķētā ekrānāAplikācijas nosaukums
- Saskaitīt nelasītās vēstules
+ Jauno vēstuļu skaitsVēstuļu skaitīšana un sūtītājiTāds pats, kad ekrāns ir atbloķētsMiera laiks
@@ -269,6 +271,10 @@ pat %d vairāk
E-pasta adreseParoleRādīt paroli
+
+ Lai apskatītos savu paroli, ieslēdziet ekrāna bloķēšanu savā ierīcē.
+ Apstiprināt savu identitāti
+ Atbloķēt, lai varētu apskatīties savu paroliPašrocīga iestatīšanaSaņem konta informāciju\u2026
@@ -310,8 +316,6 @@ pat %d vairāk
MobilaisWi-FiCits
- Ārējā krātuve (SD karte)
- Pastāvīgā iekšējā krātuveIzdzēst vēstules arī no serveraUzreizPārbaudes laikā
@@ -387,8 +391,6 @@ pat %d vairāk
TurpinātPapildusKonta iestatījumi
- Konts pēc noklusējuma
- Sūtīt pastu no šī konta pēc noklusējumaJauna pasta paziņojumiPaziņojumu mapesVisu
@@ -404,12 +406,15 @@ pat %d vairāk
Parādīt paziņjumu par nosūtītajām vēstulēmTikai kontaktusParādīt paziņojumus par vēstulēm tikai no zināmiem kontaktiem
+ Ignorēt sarakstes ziņas
+ Nerādīt paziņojumus, kas saistīti ar šo e-pasta sarakstiAtzīmēt kā izlasītu, kad vēstule atvērtaAtzīmēt vēstuli kā izlasītu, kad tā atvērta aplūkošanaiPēc izdzēšanas atzīmēt kā izlasītuPēc izdzēšanas atzīmēt vestuli kā izlasītu
- Paziņojumu iestatījumi
- Atvērt sistēmas paziņojumu iestatījumus
+ Paziņojumu kategorijas
+ Iestatīt paziņojumus jaunām ziņām
+ Iestatīt kļūdu un statusa paziņojumusVienmēr rādīt bildesNēNo kontaktiem
@@ -525,6 +530,7 @@ pat %d vairāk
Bez kategorijas1. kategorija2. kategorija
+ Tāda pati, kā pārbaudes kategorijaMapes paziņojumu kategorijaBez kategorijas1. kategorija
@@ -661,6 +667,7 @@ pat %d vairāk
Vēstuļu skatāSaraksta skatāRādīt apvienoto pastkasti
+ Parādīt atzīmēto vēstuļu skaitu%s%s- nelasītsVisas vēstules
@@ -875,6 +882,7 @@ pat %d vairāk
BccKamNo kā
+ Atbildēt<Nezināms saņēmējs><Nezināms sūtītājs>Mājas
@@ -1025,6 +1033,15 @@ Lai jaunajā ierīcē iestatītu automātisko šifrēšanu, lūdzu sekojiet nor
Lai ieteiktu kontaktus un parādītu to vārdus un attēlus, lietotnei nepieciešama atļauja piekļūt Jūsu kontaktiem.Lejupielādējot datus notika kāda kļūdaInicializē...
+ Gaida jaunas vēstulesSnaust, kamēr atļauta fona sinhronizēšanaSnaust, kamēr pieejams tīkls
+ Pieskarieties, lai uzzinātu vairāk.
+ Pārbaudes informācija
+ Kad tiek izmantota pārbaude, K-9 Pasts saglabā savienojumu ar e-pasta serveri. Android pieprasa parādīt paziņojumu, kad lietotne fonā ir aktīva. %s
+ Taču Android arī ļauj paslēpt paziņojumu.
+ Uzzināt vairāk
+ Iestatīt paziņojumu
+ Ja nevēlaties saņemt paziņojumus par jaunām vēstulēm, atslēdziet lejupielādēšanu un izmantojiet pārbaudīšanu. Pārbaudē ik pēc noteikta laikā tiek noskaidrots, vai nav saņemts jauns pasts, un tai nav vajadzīgs paziņojums.
+ Atslēgt lejupielādēšanu
diff --git a/app/ui/legacy/src/main/res/values-ml/strings.xml b/app/ui/legacy/src/main/res/values-ml/strings.xml
index 8339c002fa7d0795ad6f19d63646a83b3c89092f..900e8dcf558ede6890624a64de7c68b39ee6f6f0 100644
--- a/app/ui/legacy/src/main/res/values-ml/strings.xml
+++ b/app/ui/legacy/src/main/res/values-ml/strings.xml
@@ -238,10 +238,6 @@
മെയിൽ തലക്കെട്ടുകളിൽ നിന്ന് കെ-9 യൂസർ-ഏജന്റിനെ നീക്കം ചെയ്യുകസമയ മേഖല മറയ്ക്കൂമെയിൽ തലക്കെട്ടുകളിലും മറുപടി ശീർഷകത്തിലും പ്രാദേശിക സമയമേഖലയ്ക്ക് പകരം യുടിസി ഉപയോഗിക്കുക,
- അറിയിപ്പുകളിൽ വിഷയം മറയ്ക്കുക
- ഒരിക്കലും
- ഉപകരണം ലോക്കുചെയ്യുമ്പോൾ
- എല്ലായ്പ്പോഴും\'ഇല്ലാതാക്കുക\' ബട്ടൺ കാണിക്കുകഒരിക്കലുംഒരൊറ്റ സന്ദേശ അറിയിപ്പിനായി
@@ -249,7 +245,6 @@
ലോക്ക് സ്ക്രീൻ അറിയിപ്പുകൾലോക്ക് സ്ക്രീൻ അറിയിപ്പുകളൊന്നുമില്ലഅപ്ലിക്കേഷന്റെ പേര്
- വായിക്കാത്ത സന്ദേശങ്ങളുടെ എണ്ണംസന്ദേശങ്ങളുടെ എണ്ണവും അയച്ചവരുംസ്ക്രീൻ അൺലോക്കുചെയ്തതിന് സമാനമാണ്ശാന്തമായ സമയം
@@ -262,6 +257,7 @@
ഇമെയിൽ വിലാസംരഹസ്യവാചകംരഹസ്യവാചകം പ്രദർശിപ്പിക്കുക
+
സ്വമേധയാലുള്ള സജ്ജീകരണംഅക്കൗണ്ട് വിവരങ്ങൾ വീണ്ടെടുക്കുന്നു\u2026
@@ -303,8 +299,6 @@
മൊബൈൽവൈഫൈമറ്റുള്ളവ
- ബാഹ്യ സംഭരണം (SD കാർഡ്)
- പതിവ് ആന്തരിക സംഭരണംസെർവറിൽ ഇല്ലാതാക്കിയ സന്ദേശങ്ങൾ മായ്ക്കുകഉടനെപോളിംഗ് നടത്തുമ്പോൾ
@@ -380,8 +374,6 @@
തുടരുകവിപുലമായത്അക്കൗണ്ട് സജ്ജീകരണങ്ങൾ
- സ്ഥിരസ്ഥിതി അക്കൗണ്ട്
- സ്ഥിരസ്ഥിതിയായി ഈ അക്കൗണ്ടിൽ നിന്ന് മെയിൽ അയയ്ക്കുകപുതിയ മെയിൽ അറിയിപ്പുകൾഅറിയിപ്പുകൾ ഫോൾഡറുകൾഎല്ലാം
@@ -401,8 +393,6 @@
ഒരു സന്ദേശം കാണാനായി തുറക്കുമ്പോൾ വായിച്ചതായി അടയാളപ്പെടുത്തുകഇല്ലാതാക്കുമ്പോൾ വായിച്ചതായി അടയാളപ്പെടുത്തുകഒരു സന്ദേശം ഇല്ലാതാക്കുമ്പോൾ വായിച്ചതായി അടയാളപ്പെടുത്തുക
- അറിയിപ്പ് ക്രമീകരണങ്ങൾ
- സിസ്റ്റം അറിയിപ്പ് ക്രമീകരണങ്ങൾ തുറക്കുകഎല്ലായ്പ്പോഴും ചിത്രങ്ങൾ കാണിക്കുകഇല്ലകോൺടാക്റ്റുകളിൽ നിന്ന്
diff --git a/app/ui/legacy/src/main/res/values-nb/strings.xml b/app/ui/legacy/src/main/res/values-nb/strings.xml
index 8c1b82ccf56dd88255b01434f620dc3f171be30a..554ba0128840e9ecd0ca4ff49a64f6cc724249cb 100644
--- a/app/ui/legacy/src/main/res/values-nb/strings.xml
+++ b/app/ui/legacy/src/main/res/values-nb/strings.xml
@@ -9,9 +9,16 @@
The K-9 Dog WalkersOpphavsrett 2008-%s The K-9 Dog Walkers. Kopirett for noen deler 2006-%s Android Open Source Project.
+ kildekodeApache License, Version 2.0
+ Åpen kildekode prosjekt
+ webside
+ brukerforum
+ TwitterBibliotekLisens
+ Endringslogg
+ Hva er nytt?Welcome to MailMail is the default mail client for /e/
@@ -230,10 +237,6 @@ til %d flere
Remove Mail User-Agent from mail headersSkjul tidssoneBruk UTC istedenfor lokal tidssone i meldings- og svar-hoder
- Skjul emner i varslinger
- Aldri
- Når enhet er låst
- AlltidVis «Slett»-knappenAldriFor enkeltmeldingsvarsel
@@ -241,7 +244,6 @@ til %d flere
Varslinger på låseskjermIngen varslinger på låseskjermProgramnavn
- Antall uleste meldingerMeldingsantall og avsendereSamme som når skjermen er ulåstStilletid
@@ -254,6 +256,7 @@ til %d flere
E-postadressePassordVis passord
+
Manuelt oppsettHenter kontoinformasjon\u2026
@@ -295,8 +298,6 @@ til %d flere
MobilWi-FiAnnet
- Ekstern lagring (SD-kort)
- Vanlig intern lagringFjern slettede meldinger på tjenerUmiddelbartI forbindelse med sjekking av e-post
@@ -372,8 +373,6 @@ til %d flere
FortsettAvansertKontoinnstillinger
- Forvalgt konto
- Send e-post i fra denne kontoen som forvalgVarsel om ny e-postMapper med varslingerAlle
@@ -393,7 +392,6 @@ til %d flere
Merk en melding som lest når den åpnes for visningMarker som lest når slettetMarker en melding som lest når den er slettet
- Innstillinger for varslerAlltid vis bilderNeiFra kontakter
diff --git a/app/ui/legacy/src/main/res/values-nl/strings.xml b/app/ui/legacy/src/main/res/values-nl/strings.xml
index d3caf766f7b1ad7ab12881e3d595352b30e378e7..68af7b53bcc9575c24c006f8b0272b02bce25bd9 100644
--- a/app/ui/legacy/src/main/res/values-nl/strings.xml
+++ b/app/ui/legacy/src/main/res/values-nl/strings.xml
@@ -1,1047 +1,1063 @@
-
+
-
-
-
- Mail
- Mail Accounts
- Ongelezen email
-
- Het K-9 ontwikkelingsteam
- Auteursrecht 2008-%s The K-9 Dog Walkers. Voor gedeeltes geldt auteursrecht 2006-%s het Android Open Source Project.
- Broncode
- Apache Licentie, versie 2.0
- Opensource project
- Website
- Gebruikersforum
- Fediverse
- Twitter
- Bibliotheken
- Licentie
- Wijzigingslog
- Het laden van het wijzigingslog is mislukt.
- Versie %s
- Wat is er nieuw
- Laat veranderingen zien als de app recent is bijgewerkt
- Ontdek wat er nieuw is in deze uitgave
-
- Welkom bij Mail
- Mail is the default mail client for /e/
-
- -- Verzonden met /e/ Mail.
-
- De account \"%s\" zal verwijderd worden van Mail.
-
- Auteurs
- Revisie informatie
- E-mails lezen
- Sta deze appicatie toe om je e-mails te lezen.
- Verwijder e-mails
- Sta deze applicatie toe om je e-mails te verwijderen.
- Over Mail
- Accounts
- Mappen
- Geavanceerd
- Nieuw bericht
- Antwoorden
- Allen antwoorden
- Doorsturen
- Doorsturen als bijlage
- Kies account
- Kies een map
- Peiling %s:%s%s
- Koppen ophalen %s:%s%s
- Verzenden %s%s
- Verw. %s:%s%s
- \u0020%d/%d
- Synchroniseren uitgeschakeld
- %d geselecteerd
- Volgende
- Vorige
-
- OK
- Annuleren
- Verzenden
- Opnieuw verzenden
- Er is geen onderwerp ingevuld. Tik nogmaals om toch te versturen
- Selecteren
- Deselecteren
- Antwoorden
- Iedereen antwoorden
- Verwijderen
- Archief
- Spam
- Doorsturen
- Doorsturen als bijlage
- Bewerken als nieuw bericht
- Verplaatsen
- Verplaatsen naar concepten
- Verzenden …
- Opnieuw opslaan …
- Klaar
- Vergeten
- Opslaan als concept
- Controleer e-mail
- Verstuur berichten
- Maplijst verversen
- Map vinden
- Account toevoegen
- Nieuw bericht
- Zoeken
- Overal zoeken
- Zoekresultaten
- Instellingen
- Beheer mappen
- Account instellingen
- Verwijder account
- Markeer als gelezen
- Delen
- Kies afzender
- Voeg ster toe
- Verwijder ster
- Kopieer
- Laat koppen zien
-
- Adres naar klembord gekopieerd
- Adressen naar klembord gekopieerd
-
- De onderwerpsregel is naar het klembord gekopieerd
- Schakel naar donker thema
- Schakel naar licht thema
- Markeer als ongelezen
- Lees rapport
- Lees rapport vragen
- Geen lees rapport vragen
- Voeg bijlage toe
- Prullenbak legen
- Wissen
- Over
- Instellingen
-
- (Geen onderwerp)
- Geen afzender
- Berichten laden\u2026
- Netwerkfout
- Bericht niet gevonden
- Bericht laden is mislukt
- Volgende %d berichten
- %.1f GB
- %.1f MB
- %.1f kB
- %d B
- Account \"%s\" verkleind van %s naar %s
- Account \"%s\" comprimeren
- Nieuw bericht
-
- %d nieuw bericht
- %d nieuwe berichten
-
- %d Ongelezen (%s)
- + %1$d meer bij %2$s
- Antwoorden
- Gelezen
- Alles als gelezen markeren
- Verwijderen
- Alles verwijderen
- Archiveren
- Alles Archiveren
- Spam
- Certificaat fout voor %s
- Controleer de server instellingen
- Authenticatie mislukt
- Authenticatie mislukt voor %s. Werk de server instellingen bij.
- Controleer berichten: %s:%s
- Controleren berichten
- Versturen van berichten: %s
- Berichten versturen
- :
- Synchroniseren (Duw)
- Wordt weergeven in afwachting op nieuwe berichten
- Beeld berichten
- Meldingen gerelateerd aan berichten
- Diversen
- Overige meldingen zoals fouten en dergelijke.
- Postvak-in
- Postvak-uit
- Concepten
- Prullenbak
- Verzonden
- Fout bij verzenden van berichten
- Versie
- Debug log toestaan
- Log extra diagnostische informatie
- Log gevoelige informatie
- Kan wachtwoorden laten zien in logs.
- Laad meer berichten
- Aan:%s
- Onderwerp
- Bericht tekst
- Handtekening
- -------- Origineel bericht --------
- Onderwerp:
- Verzonden:
- Van:
- Aan:
- CC:
- %s schreef:
- %2$s schreef op %1$s:
- Voeg minimaal 1 ontvanger toe.
- De ontvanger is niet (volledig) ingevuld!
- Geen e-mailadres gevonden.
- Sommige bijlagen kunnen niet worden doorgestuurd omdat ze niet zijn gedownload.
- Dit bericht kan niet worden doorgestuurd omdat bijlagen niet zijn gedownload.
- Geciteerd bericht bijvoegen
- Citaattekst verwijderen
- Citaattekst bewerken
- Bijlage verwijderen
- Van: %s <%s>
- Aan:
- CC:
- BCC:
- Open
- Opslaan
- Kan bijlage niet opslaan.
- Afbeeldingen weergeven
- Niet in staat viewer te vinden voor %s.
- Download compleet bericht
- Niet mogelijk om bericht te tonen
- via %1$s
-
- Alle koppen zijn gedownload, maar er zijn geen extra koppen om te tonen.
- Het ophalen van extra koppen uit de gegevensbank of e-mailserver is mislukt.
- Meer van deze afzender
- Van %s
- Debug / Bericht veld wissen
- Bericht verwijderd
- Bericht opgeslagen als concept
- Bericht sterren
- Sterren geven gemarkeerde berichten aan
- Preview regels
- Toon naam bij bericht
- Geef bij voorkeur naam van afzender/geadresseerde weer i.p.v. e-mailadres
- Correspondent boven onderwerp
- Correspondent namen boven de onderwerp-regel, niet eronder
- Toon naam uit contactenlijst
- Gebruik naam uit het adresboek
- Kleuren contacten
- Kleur de namen in uw contact lijst
- Vaste breedte lettertypen
- Gebruik een lettertype met vaste breedte bij het weergeven van plain-tekstberichten
- Berichten auto-passen
- Berichten passend maken op het scherm
- Terug naar lijst na verwijderen
- Terug naar berichtenlijst na bericht verwijderen
- Volgend bericht laten zien na verwijderen
- Standaard volgend bericht laten zien na verwijderen
- Bevestig acties
- Toon een dialoogvenster altijd wanneer u de geselecteerde acties uitvoert
- Verwijder
- Gemarkeerd verwijderen (in bericht weergave)
- Spam
- Bericht afbreken
- Markeer alles als gelezen
- Verwijder (van notificaties)
- Mail client verbergen
- Remove Mail User-Agent from mail headers
- Tijdzone verbergen
- Gebruik UTC in plaats van de lokale tijdzone in de e-mailkoppen en bij het antwoorden van e-mail
- Verberg onderwerp in notificaties
- Nooit
- Als toestel vergrendeld is
- Altijd
- Toon \'Verwijder\' knop
- Nooit
- Notificatie voor los bericht
- Altijd
- Start scherm notificatie
- Geen start scherm notificatie
- App naam
- Ongelezen berichten teller
- Berichten teller (ook verzonden)
- Hetzelfde. Ook na schermontgrendeling
- Stilteperiode
- Schakel beltoon, trillen en leds uit gedurende de nacht
- Notificaties uitzetten
- Notificaties volledig uitzetten tijdens stilteperiode
- Stilteperiode start
- Stilteperiode einde
- Een nieuw account instellen
- E-mailadres
- Wachtwoord
- Toon wachtwoord
- Handmatige setup
-
- Ophalen account informatie\u2026
- Controleren van inkomende serverinstellingen\u2026
- Controleren van uitgaande serverinstellingen\u2026
- Authenticatie\u2026
- Accountinstellingen worden opgehaald\u2026
- Annuleren\u2026
- Bijna klaar!
- Geef dit account een naam (optioneel):
- Typ je naam (zichtbaar bij uitgaande berichten):
- Account type
- Welk type account is dit?
- POP3
- IMAP
- Normaal wachtwoord
- Wachtwoord, onveilig verzonden
- Versleuteld wachtwoord
- Client certificaat
- Inkomende server instellingen
- Gebruikersnaam
- Wachtwoord
- Client certificaat
- POP3 server
- IMAP server
- WebDAV (Exchange) server
- Poort
- Beveiligingstype
- Authenticatietype
- Geen
- SSL/TLS
- STARTTLS
- \"%1$s = %2$s\" is niet geldig met \"%3$s = %4$s\"
- Wanneer ik een bericht verwijder
- Verwijder niet van server
- Verwijder van server
- Markeer als gelezen op server
- Gebruik compressie op het netwerk:
- Mobiel
- Wi-Fi
- Anders
- Externe opslag (SD-kaart)
- Reguliere interne opslag
- Wissen berichten
- Onmiddellijk na verwijderen of verplaatsen
- Tijdens iedere peiling
- Alleen handmatig
- IMAP namespace automatisch detecteren
- IMAP pad voorvoegsel
- Conceptmap
- Verzendmap
- Prullenbakmap
- Archiefmap
- Spammap
- Alleen geabonneerde mappen weergeven
- Map automatisch uitvouwen
- WebDAV (Exchange) path
- Optioneel
- Authenticatie pad
- Optioneel
- Mailbox alias
- Optioneel
- Uitgaande server instellingen
- SMTP server
- Poort
- Beveiligingstype
- Inloggen vereist.
- Gebruikersnaam
- Wachtwoord
- Authenticatietype
- \"%1$s = %2$s\" is niet geldig met \"%3$s = %4$s\"
- Ongeldige setup: %s
- Account opties
- Account comprimeren
- Map peiling-frequentie
- Nooit
- Elke 15 minuten
- Elke 30 minuten
- Elk uur
- Elke 2 uur
- Elke 3 uur
- Elke 6 uur
- Elke 12 uur
- Elke 24 uur
- Duw mail voor dit account toestaan
- Als uw server dit ondersteunt, zullen nieuwe berichten direct verschijnen. Deze optie kan drastisch verbeteringen of verslechteringen van prestaties teweeg brengen.
- Vernieuw inactieve verbinding
- Elke 2 minuten
- Elke 3 minuten
- Elke 6 minuten
- Elke 12 minuten
- Elke 24 minuten
- Elke 36 minuten
- Elke 48 minuten
- Elke 60 minuten
- Waarschuw me wanneer nieuwe e-mail binnenkomt
- Waarschuw me wanneer er op nieuwe e-mail wordt gecontroleerd
- Aantal berichten om te laten zien
- 10 berichten
- 25 berichten
- 50 berichten
- 100 berichten
- 250 berichten
- 500 berichten
- 1000 berichten
- 2500 berichten
- 5000 berichten
- 10000 berichten
- alle berichten
- Kan bericht niet kopiëren of verplaatsen omdat deze niet gesynchroniseerd is met de server
- Setup kon niet afronden
- Gebruikersnaam of wachtwoord ongeldig.\n(%s)
- De server presenteerde een ongeldig SSL certificaat. Dit kan komen door een verkeerd geconfigureerde server. Dit kan ook komen doordat iemand U of Uw mailserver aan probeert te vallen. Als U niet zeker weet wat er aan de hand is klik dan op Reject en neem contact op met de beheerder van Uw mailserver.\n\n(%s)
- Kan geen verbinding met server maken.\n(%s)
- Details aanpassen
- Doorgaan
- Geavanceerd
- Algemene instellingen
- Standaard account
- Standaard e-mail verzenden vanaf dit account
- Nieuwe e-mail notificatie
- Notificatie mappen
- Alles
- Alleen 1e klasse mappen
- 1e en 2e klasse mappen
- Alle behalve 2e klasse mappen
- Geen
- Sync notificatie
- Je e-mailadres
- Notificatie in statusbalk wanneer nieuwe e-mail binnenkomt
- Notificatie in statusbalk wanneer wordt gecontroleerd op nieuwe e-mail
- Notificatie voor e-mail welke ik verstuur
- Notificatie ook voor e-mail verzonden vanaf een identiteit
- Alleen contacten
- Notificaties alleen weergeven voor bekende contacten
- Markeer als gelezen als geopend
- Markeer als gelezen wanneer ingezien
- Als gelezen markeren bij wissen
- Markeer een bericht als gelezen wanneer die wordt gewist
- Meldingsinstellingen
- Open instellingen voor systeemmeldingen
- Laat afbeeldingen automatisch zien
- Nooit
- Alleen van contacten
- Altijd
- Berichten versturen
- Citeer bericht bij antwoorden
- Neem orginele bericht mee in het antwoord.
- Antwoorden na citaat
- Wanneer u antwoord op berichten, zal het originele bericht boven uw antwoord staan.
- Verwijder handtekening bij reactie
- Handtekeningen worden verwijderd bij geciteerde berichten
- Berichtopmaak
- Platte Tekst (plaatjes en opmaak worden verwijderd)
- HTML (plaatjes en opmaak blijven behouden)
- Automatisch
- Altijd Cc/Bcc laten zien
- Leesbevestiging
- Altijd een leesbevestiging vragen
- Quotestijl bij antwoorden
- Prefix (zoals Gmail, Pine)
- Kop (zoals Outlook)
- Upload verzonden berichten
- Upload berichten naar \'Verzonden\' map na verzenden
- Algemene instellingen
- Berichten lezen
- Berichten ophalen
- Mappen
- Citaat voorvoegsel
- Eind-tot-eind versleuteling
- OpenPGP ondersteuning inschakelen
- OpenPGP app selecteren
- Eind-tot-eind sleutel instellen
- Geen OpenPGP app ingesteld
- Verbonden met %s
- Configureren…
- Sla alle concepten versleuteld op
- Alle concepten zullen versleuteld worden opgeslagen
- Versleutel concepten alleen als versleuteling is ingeschakeld
- Map peiling-frequentie
- Account kleur
- De kleur van dit account gebruikt bij mappen en accountlijst
- Geen kleur
- Notificatie LED kleur
- Kies de LED kleur van de telefoon, welke moet knipperen voor deze account
- Lokale map grootte
- Automatisch berichten downloaden tot
- 1 KiB
- 2 KiB
- 4 KiB
- 8 KiB
- 16 KiB
- 32 KiB
- 64 KiB
- 128 KiB
- 256 KiB
- 512 KiB
- 1 MiB
- 2 MiB
- 5 MiB
- 10 MiB
- elke grootte (geen limiet)
- Sync berichten van
- alles (geen limiet)
- vandaag
- laatste 2 dagen
- laatste 3 dagen
- afgelopen week
- afgelopen 2 weken
- afgelopen 3 weken
- afgelopen maand
- afgelopen 2 maanden
- afgelopen 3 maanden
- afgelopen 6 maanden
- afgelopen jaar
- Mappen om weer te geven
- Alle
- Alleen 1e klasse mappen
- 1e en 2e klasse mappen
- Alle behalve 2e klasse mappen
- Peiling mappen
- Alle
- Alleen 1e klasse mappen
- 1e en 2e klasse mappen
- Alle behalve 2e klasse mappen
- Geen
- Duw mappen
- Alle
- Alleen 1e klasse mappen
- 1e en 2e klasse mappen
- Alle behalve 2e klasse mappen
- Geen
- Verplaats/kopieer doel mappen
- Alle
- Alleen 1e klasse mappen
- 1e en 2e klasse mappen
- Alle behalve 2e klasse mappen
- Sync verwijderingen op server
- Verwijder berichten wanneer verwijderd van server
- OpenPGP app niet aanwezig - is de app verwijderd?
- Map instellingen
- Laat zien in kopgroep
- Laat zien bij de top van de maplijst
- Map weergave klasse
- Geen klasse
- 1e klasse
- 2e klasse
- Map peiling-klasse
- Geen
- 1e klasse
- 2e klasse
- Zelfde als weergave klasse
- Duw klasse map
- Geen klasse
- 1e klasse
- 2e klasse
- Zelfde als peiling-klasse
- Map notificatie klasse
- Geen klasse
- 1e klasse
- 2e klasse
- Zelfde als duw klasse
- Lokale berichten wissen
- Inkomende server
- Instellen van de inkomende mail server
- Uitgaande server
- Configureren van de uitgaande (SMTP) server
- Account naam
- Jouw naam
- Notificaties
- Trillen
- Trillen wanneer nieuwe e-mail binnenkomt
- Tril patronen
- standaard
- patroon 1
- patroon 2
- patroon 3
- patroon 4
- patroon 5
- Aantal trillingen
- Nieuwe e-mail beltoon
- Knipper LED
- Knipper LED wanneer e-mail binnenkomt
- Bericht samenstelling opties
- Samenstelling standaarden
- Stel standaard in voor: Van, Bcc en handtekening
- Beheer identiteiten
- Instellen alternatieve \'Van\' adressen en handtekeningen
- Beheer identiteiten
- Beheer identiteit
- Identiteit aanpassen
- Opslaan
- Nieuwe identiteit
- Bcc alle berichten naar
- Aanpassen
- Verplaats ophoog
- Verplaats omlaag
- Verplaats naar top / maak standaard
- Verwijder
- Identiteit beschrijving
- (Optioneel)
- Jouw naam
- (Optioneel)
- E-mailadres
- (Vereist)
- Antwoord adres
- (Optioneel)
- Handtekening
- (Optioneel)
- Gebruik handtekening
- Handtekening
- Initiële identiteit
- Kies identiteit
- Verzenden als
- Je kunt je eigen identiteit niet verwijderen
- Je kunt een identiteit niet gebruiken zonder e-mailadres
- Oudste berichten eerst
- Nieuwste berichten eerst
- Onderwerp alfabetische volgorde
- Onderwerp omgekeerd alfabetische volgorde
- Verzender alfabetisch
- Verzender omgekeerd alfabetisch
- Berichten met ster eerst
- Berichten zonder ster eerst
- Ongelezen berichten eerst
- Gelezen berichten eerst
- Berichten met bijlagen eerst
- Berichten zonder bijlagen eerst
- Sorteren volgens …
- Datum
- Aankomst
- Onderwerp
- Verzender
- Ster
- Gelezen/ongelezen
- Bijlagen
- Account verwijderen
- Onbekend Certificaat
- Accepteer Sleutel
- Verwerp Sleutel
- Del (of D) - Verwijderen\nR - Antwoord\nA - Iedereen antwoorden\nC - Opstellen\nF - Doorsturen\nM - Verplaatsen\nV - Archiveren\nY - Kopiëren\nZ - Markeer (on)gelezen\nG - Ster\nO - Sorteer type\nI - Sorteer volgorde\nQ - Terug naar Mappen\nS - Selecteer/deselecteer\nJ of P - Vorig bericht\nK of N - Volgende bericht
- Del (of D) - Verwijderen\nC - Opstellen\nM - Verplaatsen\nV - Archiveren\nY - Kopiëren\nZ - Markeer (on)gelezen\nG - Ster\nO - Sorteer type\nI - Sorteer volgorde\nQ - Terug naar Mappen\nS - Selecteer/deselecteer
- Mapnaam bevat
- Toon mappen…
- Laat alle mappen zien
- 1e klasse mappen
- 1e & 2e klasse mappen
- 2e klasse mappen verbergen
- Positie handtekening
- Voor geciteerd bericht
- Na geciteerd bericht
- Gebruik app thema
- Donker
- Licht
- Gebruik systeemstandaard
- Algemene instellingen
- Algemeen
- Debuggen
- Privacy
- Netwerk
- Interactie
- Accountlijst
- Berichtlijsten
- Berichten
- Thema
- Thema om berichten te zien
- Thema om berichten te schrijven
- Taal
- Geen instellingen gevonden
- Vast berichten thema
- Kies het thema tijdens het bekijken van het bericht
- Gebruik een vast thema om het bericht te bekijken
- Volgens systeem
- Achtergrond sync
- Nooit
- Altijd
- Als \'Auto-sync\' geselecteerd is
- Selecteer alle
- Max mappen om te controleren met duw
- 5 mappen
- 10 mappen
- 25 mappen
- 50 mappen
- 100 mappen
- 250 mappen
- 500 mappen
- 1000 mappen
- Animatie
- Gebruik opzichtige visuele effecten
- Volume op/neer navigatie
- Bericht beeld
- Variabele lijst weergave
- Gecombineerde postvak-in weergeven
- %s%s
- - Ongelezen
- Alle berichten
- Alle berichten in doorzoekbare mappen
- Gecombineerde postvak-in
- Alle berichten in gecombineerde mappen
- Combineer
- Alle berichten worden in de gecombineerde postvak-in weergegeven
- Mappen om te doorzoeken
- Alle
- Zichtbare
- Geen
- Geen
- Automatisch (%s)
- Lettergrootte
- Instellen lettergrootte
- Account lijst
- Account naam
- Account beschrijving
- Maplijsten
- Mapnaam
- Mapstatus
- Bericht lijsten
- Bericht onderwerp
- Bericht afzender
- Bericht datum
- Voorbeeldweergave
- Beeld berichten
- Bericht afzender
- Bericht ontvanger (Aan)
- Bericht ontvanger (CC)
- Bericht ontvanger (BCC)
- Extra koppen
- Bericht onderwerp
- Bericht tijd en datum
- Bericht inhoud
- %d%%
- %1$s: %2$s
- Bericht opstellen
- Tekst invoervelden
- Standaard
- Kleinste
- Heel klein
- Kleiner
- Klein
- Gemiddeld
- Groot
- Groter
- Geen geschikte applicatie gevonden voor deze actie.
- Verzenden mislukt: %s
- Concept opslaan?
- Opslaan of negeren van dit bericht?
- Wijzigingen opslaan of verwerpen?
- Bericht afbreken?
- Weet je zeker dat je dit bericht wilt verwijderen?
- Selecteer tekst om te kopiëren.
- Lokale berichten wissen?
- Dit zal alle lokale berichten uit deze map wissen. Er worden geen berichten van de server gewist.
- Berichten wissen
- Bevestig verwijderen
- Wil je dit bericht verwijderen?
-
- Wil je dit bericht echt verwijderen?
- Wil je echt %1$d berichten verwijderen?
-
- Ja
- Nee
- Markeer alles als gelezen
- Wil je alle berichten markeren als gelezen?
- Bevestig prullenbak legen
- Wil je de prullenbak leeg maken?
- Ja
- Nee
- Bevestig verplaatsing naar spam map
-
- Wil je dit bericht echt verplaatsen naar de spam map\?
- Wil je deze %1$d berichten verplaatsen naar de spam map\?
-
- Ja
- Nee
- Bijlage wordt opgehaald
- »
- ›
- Back-up
- Diversen
- Exporteer instellingen
- Export
- Delen
- Instellingen exporteren …
- Instellingen succesvol geëxporteerd
- Instellingen exporteren mislukt
- Instellingen importeren
- Bestand selecteren
- Importeren
- Instellingen succesvol geïmporteerd
- Voer de wachtwoorden in
- Instellingen importeren mislukt
- Lezen van instellingenbestand mislukt
- Importeren van sommige instellingen mislukt
- Succesvol geïmporteerd
- Wachtwoord vereist
- Niet geïmporteerd
- Importeren mislukt
- Later
- Import instellingen
- Instellingen importeren …
-
- Om het account \"%s\" te gebruiken moet je het wachtwoord van de server opgeven.
- Om het account \"%s\" te gebruiken moet je de wachtwoorden van de server opgeven.
-
- Binnenkomendeserver-wachtwoord
- Uitgaandeserver-wachtwoord
- Gebruik het zelfde wachtwoord voor de uitgaandeserver
- Servernaam: %s
- Ongelezen aantal weergeven voor …
- Account
- Het account waarvan het aantal ongelezen berichten wordt getoond
- Gecombineerde postvak-in
- Map aantal
- Toon het aantal ongelezen berichten van een enkele map
- Map
- De map waarbij ongelezen berichten wordt getoond
- Klaar
- %1$s - %2$s
- Geen account gekozen
- Geen folder gekozen
- Geen tekst
- Open link
- Deel link
- Kopieer link naar klembord
- Link
- Verwijzingstekst naar klembord kopiëren
- Verwijzingstekst
- Afbeelding
- Afbeelding laten zien
- Afbeelding opslaan
- Afbeelding downloaden
- Kopieer afbeelding-URL naar klembord
- Afbeelding-URL
- Bel nummer
- Opslaan in contacten
- Kopieer nummer naar klembord
- Telefoonnummer
- Stuur e-mail
- Opslaan in contacten
- Kopieer adres naar klembord
- E-mailadres
- Alle
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- Server zoek limiet
- Zoekopdracht naar server sturen
-
- %d resultaat ophalen
- %d berichten ophalen
-
-
- %1$d van %2$d berichten ophalen
- %1$d van %2$d berichten ophalen
-
- Zoekopdracht mislukt
- Zoeken
- Server zoeken toestaan
- Zoek berichten op de server en op je eigen toestel
- Zoek berichten op server
- Er is een netwerk verbinding nodig voor server zoeken.
- Kleur wijzigen na lezen
- Een andere achtergrond laat zien nadat de e-mail is gelezen
- Gesprek overzicht
- Groepeer berichten per gesprek
- Gegevensbanken bijwerken
- Gegevensbanken aan het bijwerken …
- Gegevensbanken van account \"%s\" bijwerken
- Gespleten-scherm laten zien
- Altijd
- Nooit
- In landschap oriëntatie
- Selecteer een bericht aan de linker kant
- Laat contactafbeeldingen zien
- Laat contactafbeeldingen in de berichtenlijst zien
- Markeer alles als gelezen
- Contactafbeeldingen kleuren
- Voorzie afwezige contactafbeeldingen van een kleur
- Zichtbare berichtacties
- Toon de geselecteerde acties in het Berichten-menu
- Bijlage aan het laden …
- Bericht wordt verstuurd
- Concept wordt opgeslagen
- Bijlage aan het ophalen …
- Kan niet authenticeren. De server ondersteunt geen SASL EXTERNAL. Dit kan komen door een probleem met het client certificaat (verlopen of onbekende CA) of een ander configuratieprobleem.
-
- Gebruik client certificaat
- Geen client certificaat
- Verwijder client certificaat selectie
- Client certificaat niet ontvangen voor alias \"%s\"
- Geavanceerde opties
- Client certificaat \"%1$s\" is verlopen of niet geldig (%2$s)
-
- *Versleuteld*
- Toevoegen vanuit contacten
- CC
- BCC
- Aan
- Van
- <Onbekende ontvanger>
- <Onbekende verzender>
- Privé
- Werk
- Anders
- Mobiel
- Geen concepten map ingesteld voor dit account!
- Geen sleutel ingesteld voor dit account! Controleer je instellingen.
- Crypto provider gebruikt incompatibele versie. Controleer je instellingen!
- Kan geen verbinding maken met de crypto provider. Controleer de instellingen of klik op het crypto icoontje om nogmaals te proberen!
- Initialisatie van eind-tot-eind versleuteling is mislukt, controleer de instellingen
- PGP/MIME instelling ondersteund geen bijlagen!
- PGP/INLINE toestaan
- PGP/INLINE uitzetten
- PGP handtekening toestaan
- PGP handtekening stoppen
- PGP/INLINE instellingen
- De e-mail is verzonden in PGP/INLINE formaat.\nDit word alleen gebruikt voor compatibiliteit:
- Sommige clients ondersteunen alleen dit formaat
- Handtekening kan onderweg breken
- Bijlagen zijn niet ondersteund
- Begrepen!
- Uitzetten
- Keep toestaan
- Begrepen!
- Uitzetten
- Houd ingeschakeld
- alleen PGP handtekening modes
- In deze mode wordt je PGP sleutel gebruikt voor een cryptografische handtekening of een ongecodeerde email.
- Dit versleutelt niet de e-mail, maar controleert dat je eigen sleutel gebruikt is.
- Handtekening kan bij versturing naar verzendlijst breken
- Handtekening kan worden weergegeven als \'signature.asc\' bijlage bij sommige programma\'s
- Versleutelde berichten bevatten altijd een handtekening.
- Platte tekst
- eind-tot-eind handtekening bevat een fout
- moet bericht volledig downloaden om handtekening te verwerken
- bevat niet ondersteunde eind-tot-eind handtekening
- Bericht is versleuteld, maar in een niet ondersteund formaat.
- Bericht is versleuteld, maar ontsleuteling was gestopt.
- Eind-tot-eind getekende platte tekst
- van geverifieerde ondertekenaar
- Platte tekst getekend
- maar eind-tot-eind sleutel komt niet overeen met afzender
- maar eind-tot-eind sleutel is verlopen
- maar eind-tot-eind sleutel is ingetrokken
- maar eind-tot-eind sleutel is niet veilig
- van een onbekende eind-tot-eind sleutel
- Versleuteld
- maar er is een ontsleutel fout opgetreden
- moet bericht volledig downloaden voor ontsleuteling
- maar er is geen crypto app geconfigureerd
- Versleuteld
- maar niet eind-tot-eind
- Eind-tot-eind versleuteld
- van geverifieerde afzender
- Versleuteld
- van een onbekende eind-tot-eind sleutel
- maar eind-tot-eind sleutel komt niet overeen met afzender
- maar eind-tot-eind sleutel is verlopen
- maar eind-tot-eind sleutel is ingetrokken
- maar eind-tot-eind sleutel is niet veilig
- maar eind-tot-eind gegevens bevatten fouten
- maar versleuteling is niet veilig
- OK
- Zoek Sleutel
- Bekijk ondertekenaar
- Bekijk afzender
- Details
- Deblokkeer
- Dit onderdeel is niet versleuteld en is misschien niet veilig.
- Onbeveiligde Bijlage
- Laden …
- Decryptie is geannuleerd.
- Opnieuw
- Versleuteld bericht moet gedownload worden om te decrypten.
- Fout tijdens ontsleutelen e-mail
- Speciale leestekens worden nog niet ondersteund!
- Fout bij parsen van adres!
- Verberg niet-versleutelde handtekeningen
- Alleen versleutelde handtekeningen worden weergegeven
- Alle handtekeningen worden weergegeven
- Versleuteling niet mogelijk in sign-only mode!
- niet getekende tekst
- APG Deprecation Waarschuwing
- APG is niet langer beheerd!
- Hierdoor is de ondersteuning voor APG verwijderd binnen K-9 mail.
- De ontwikkeling is gestopt in 2014
- Bevat onveilige items
- Klik hier voor meer informatie.
- Begrepen!
- APG
- Deze e-mail is versleuteld
- Deze e-mail is OpenPGP versleuteld.\nInstalleer en stel een OpenPGP App in om de e-mail te lezen.
- Ga naar Instellingen
- Mail Message List
- Berichten aan het laden …
- Ophalen maplijst niet gelukt
- Fout bij ophalen status van de OpenPGP provider!
- Versleuteling niet mogelijk
- Sommige van de ontvangers ondersteunen deze functie niet!
- Versleuteling inschakelen
- Versleuteling uitschakelen
- Versleuteling maakt dat berichten alleen door de ontvanger gelezen kunnen worden, en niemand anders.
- Versleuteling is alleen beschikbaar als alle ontvangers dit ondersteunen, en zij moeten U eerder reeds een e-mail gestuurd hebben.
- Schakel versleuteling aan of uit met dit icoon.
- Ik snap het
- Terug
- Versleuteling uitschakelen
- OpenPGP-versleuteling
- Autocrypt wederzijdse modus
- Autocrypt wederzijdse modus
- Berichten worden op verzoek versleuteld, of bij beantwoorden van een versleuteld bericht.
- Als verzender en ontvanger de wederzijdse modus inschakelen dan wordt standaard versleuteling ingesteld.
- Klik hier voor meer informatie.
- Algemene instellingen
- Geen OpenPGP app geïnstalleerd
- Installeren
- Mail vereist OpenKeychain voor end-to-end encryptie.
- Versleuteld bericht
- Onderwerp van bericht versleutelen
- Mogelijk niet ondersteund door alle ontvangers
- Interne fout: Ongeldig account!
- Fout bij het verbinden met %s!
- Verstuur Autocrypt Setup bericht
- Veilig delen van eind-tot-eind instellingen met andere apparaten
- Autocrypt Setup bericht
- Een Autocrypt Setup bericht deelt uw eind-tot-eind instellingen op een beveiligde manier met andere apparaten.
- Verstuur Setup bericht
- Het bericht wordt verstuurd naar uw adres:
- Instelbericht aan het genereren…
- Bericht sturen naar:
- Om te voltooien, open het bericht op uw andere apparaat en voer de Setup Code in.
- Setup Code weergeven
- Autocrypt Setup bericht
- Dit bericht bevat alle informatie om uw Autocrypt instellingen met geheime sleutel beveiligd over te brengen vanaf uw oorspronkelijke apparaat.
+
+
+
+ Mail
+ Mail Accounts
+ Mail Ongelezen
+
+ Het K-9 ontwikkelingsteam
+ Auteursrecht 2008-%s The K-9 Dog Walkers. Voor gedeeltes geldt auteursrecht 2006-%s het Android Open Source Project.
+ Broncode
+ Apache Licentie, versie 2.0
+ Openbroncode-project
+ Website
+ Gebruikersforum
+ Fediverse
+ Twitter
+ Bibliotheken
+ Licentie
+ Wijzigingslog
+ Het laden van het wijzigingslog is mislukt.
+ Versie %s
+ Wat is er nieuw
+ Laat veranderingen zien als de app recent is bijgewerkt
+ Ontdek wat er nieuw is in deze versie
+
+ Welkom bij Mail
+ Mail is een gratis krachtige e-mail client voor Android.
De verbeterde mogelijkheden bestaan uit ondermeer:
+
+
+
Push mail middels IMAP IDLE
+
Betere prestaties
+
Bericht herclassificatie
+
E-mail handtekeningen
+
Bcc naar jezelf
+
Map abonnementen
+
Synchronisatie van alle mappen
+
Antwoord adres instellen
+
Toetsenbord snelkoppelingen
+
Betere IMAP ondersteuning
+
Bijlage opslaan naar SD
+
Prullenbak legen
+
Berichten sorteren
+
en meer …
+
+
+Houd er rekening mee dat de meeste gratis Hotmail-accounts niet ondersteund, en net als veel e-mailclients, problemen kan hebben om te verbinden met Microsoft Exchange.
+
+]]>
+
+ -- \nVerstuurd vanaf mijn Android apparaat met K-9 Mail.
+
+ Het account \"%s\" wordt verwijderd uit K-9 Mail.
+
+ Auteurs
+ Revisie informatie
+ E-mails lezen
+ Sta deze appicatie toe om je e-mails te lezen.
+ Verwijder e-mails
+ Sta deze applicatie toe om je e-mails te verwijderen.
+ Over K-9 mail
+ Accounts
+ Mappen
+ Geavanceerd
+ Nieuw bericht
+ Antwoorden
+ Allen antwoorden
+ Doorsturen
+ Doorsturen als bijlage
+ Kies account
+ Kies een map
+ Verplaatsen naar …
+ Kopiëren naar …
+ Peiling %s:%s%s
+ Koppen ophalen %s:%s%s
+ Verzenden %s%s
+ Verw. %s:%s%s
+ \u0020%d/%d
+ Synchroniseren uitgeschakeld
+ %d geselecteerd
+ Volgende
+ Vorige
+
+ OK
+ Annuleren
+ Verzenden
+ Opnieuw verzenden
+ Er is geen onderwerp ingevuld. Tik nogmaals om toch te versturen.
+ Selecteren
+ Deselecteren
+ Antwoorden
+ Iedereen antwoorden
+ Verwijderen
+ Archief
+ Spam
+ Doorsturen
+ Doorsturen als bijlage
+ Bewerken als nieuw bericht
+ Verplaatsen
+ Verplaatsen naar concepten
+ Verzenden …
+ Opnieuw opslaan …
+ Klaar
+ Vergeten
+ Opslaan als concept
+ Controleer e-mail
+ Voor alle accounts nagaan of er nieuwe e-mails zijn
+ Verstuur berichten
+ Maplijst verversen
+ Map vinden
+ Account toevoegen
+ Nieuw bericht
+ Zoeken
+ Overal zoeken
+ Zoekresultaten
+ Instellingen
+ Beheer mappen
+ Account instellingen
+ Verwijder account
+ Markeer als gelezen
+ Delen
+ Kies afzender
+ Ster toevoegen
+ Ster verwijderen
+ Kopieer
+ Laat koppen zien
+
+ Adres naar klembord gekopieerd
+ Adressen naar klembord gekopieerd
+
+ De onderwerpsregel is naar het klembord gekopieerd
+ Schakel naar donker thema
+ Schakel naar licht thema
+ Markeer als ongelezen
+ Lees rapport
+ Lees rapport vragen
+ Geen lees rapport vragen
+ Voeg bijlage toe
+ Prullenbak legen
+ Wissen
+ Over
+ Instellingen
+
+ (Geen onderwerp)
+ Geen afzender
+ Berichten laden\u2026
+ Netwerkfout
+ Bericht niet gevonden
+ Bericht laden is mislukt
+ Volgende %d berichten
+ %.1f GB
+ %.1f MB
+ %.1f kB
+ %d B
+ Account \"%s\" verkleind van %s naar %s
+ Account \"%s\" comprimeren
+ Nieuw bericht
+
+ %d nieuwe berichten
+ %d nieuwe berichten
+
+ %d Ongelezen (%s)
+ + %1$d meer bij %2$s
+ Antwoorden
+ Gelezen
+ Alles als gelezen markeren
+ Verwijderen
+ Alles verwijderen
+ Archiveren
+ Alles Archiveren
+ Spam
+ Certificaat fout voor %s
+ Controleer de server instellingen
+ Authenticatie mislukt
+ Authenticatie mislukt voor %s. Werk de server instellingen bij.
+ Controleer berichten: %s:%s
+ Controleren berichten
+ Versturen van berichten: %s
+ Berichten versturen
+ :
+ Synchroniseren (Push)
+ Wordt weergeven in afwachting op nieuwe berichten
+ Beeld berichten
+ Meldingen gerelateerd aan berichten
+ Diversen
+ Overige meldingen zoals fouten en dergelijke.
+ Postvak-in
+ Postvak-uit
+ Concepten
+ Prullenbak
+ Verzonden
+ Fout bij verzenden van berichten
+ Versie
+ Debug log toestaan
+ Log extra diagnostische informatie
+ Log gevoelige informatie
+ Kan wachtwoorden laten zien in logs.
+ Laad meer berichten
+ Aan:%s
+ Onderwerp
+ Bericht tekst
+ Handtekening
+ -------- Origineel bericht --------
+ Onderwerp:
+ Verzonden:
+ Van:
+ Aan:
+ CC:
+ %s schreef:
+ %2$s schreef op %1$s:
+ Voeg minimaal 1 ontvanger toe.
+ De ontvanger is niet (volledig) ingevuld!
+ Geen e-mailadres gevonden.
+ Sommige bijlagen kunnen niet worden doorgestuurd omdat ze niet zijn gedownload.
+ Dit bericht kan niet worden doorgestuurd omdat bijlagen niet zijn gedownload.
+ Geciteerd bericht bijvoegen
+ Citaattekst verwijderen
+ Citaattekst bewerken
+ Bijlage verwijderen
+ Van: %s <%s>
+ Aan:
+ CC:
+ BCC:
+ Open
+ Bewaar
+ Kan bijlage niet opslaan.
+ Laat afbeeldingen zien
+ Niet in staat viewer te vinden voor %s.
+ Download compleet bericht
+ Niet mogelijk om bericht te tonen
+ via %1$s
+
+ Alle koppen zijn gedownload, maar er zijn geen extra koppen om te tonen.
+ Het ophalen van extra koppen uit de gegevensbank of e-mailserver is mislukt.
+ Meer van deze afzender
+ Van %s
+ Debug / Bericht veld wissen
+ Bericht verwijderd
+ Bericht opgeslagen als concept
+ Sterren weergeven
+ Sterren geven gemarkeerde berichten aan
+ Preview regels
+ Toon naam bij bericht
+ Geef bij voorkeur naam van afzender/geadresseerde weer i.p.v. e-mailadres
+ Correspondent boven onderwerp
+ Correspondent namen boven de onderwerp-regel, niet eronder
+ Toon naam uit contactenlijst
+ Gebruik naam uit het adresboek
+ Kleuren contacten
+ Kleur de namen in jouw contact lijst
+ Vaste breedte lettertypen
+ Gebruik een lettertype met vaste breedte bij het weergeven van plain-tekstberichten
+ Berichten auto-passen
+ Berichten passend maken op het scherm
+ Terug naar lijst na verwijderen
+ Terug naar berichtenlijst na bericht verwijderen
+ Volgend bericht laten zien na verwijderen
+ Standaard volgend bericht laten zien na verwijderen
+ Bevestig acties
+ Toon een dialoogvenster altijd wanneer je de geselecteerde acties uitvoert
+ Verwijder
+ Berichten met een ster verwijderen (in berichtweergave)
+ Spam
+ Bericht afbreken
+ Markeer alles als gelezen
+ Verwijder (van notificaties)
+ Mail client verbergen
+ K-9 gebruikersagent van e-mailkoppen verwijderen
+ Tijdzone verbergen
+ Gebruik UTC in plaats van de lokale tijdzone in de e-mailkoppen en bij het antwoorden van e-mail
+ Toon \'Verwijder\' knop
+ Nooit
+ Notificatie voor los bericht
+ Altijd
+ Start scherm notificatie
+ Geen start scherm notificatie
+ App naam
+ Aantal nieuwe berichten
+ Berichten teller (ook verzonden)
+ Hetzelfde. Ook na schermontgrendeling
+ Stilteperiode
+ Schakel beltoon, trillen en leds uit gedurende de nacht
+ Notificaties uitzetten
+ Notificaties volledig uitzetten tijdens stilteperiode
+ Stilteperiode start
+ Stilteperiode einde
+ Een nieuw account instellen
+ E-mailadres
+ Wachtwoord
+ Toon wachtwoord
+
+ Schakel op dit apparaat een schermvergrendeling in om hier je wachtwoord te kunnen zien
+ Verifieer je identiteit
+ Ontgrendel om je wachtwoord te zien
+ Handmatige setup
+
+ Ophalen account informatie\u2026
+ Controleren van inkomende serverinstellingen\u2026
+ Controleren van uitgaande serverinstellingen\u2026
+ Authenticatie\u2026
+ Accountinstellingen worden opgehaald\u2026
+ Annuleren\u2026
+ Bijna klaar!
+ Geef dit account een naam (optioneel):
+ Typ je naam (zichtbaar bij uitgaande berichten):
+ Account type
+ Welk type account is dit?
+ POP3
+ IMAP
+ Normaal wachtwoord
+ Wachtwoord, onveilig verzonden
+ Versleuteld wachtwoord
+ Client certificaat
+ Inkomende server instellingen
+ Gebruikersnaam
+ Wachtwoord
+ Client certificaat
+ POP3 server
+ IMAP server
+ WebDAV (Exchange) server
+ Poort
+ Beveiligingstype
+ Authenticatietype
+ Geen
+ SSL/TLS
+ STARTTLS
+ \"%1$s = %2$s\" is niet geldig met \"%3$s = %4$s\"
+ Wanneer ik een bericht verwijder
+ Verwijder niet van server
+ Verwijder van server
+ Markeer als gelezen op server
+ Gebruik compressie op het netwerk:
+ Mobiel
+ Wi-Fi
+ Anders
+ Wissen berichten
+ Onmiddellijk na verwijderen of verplaatsen
+ Tijdens iedere peiling
+ Alleen handmatig
+ IMAP namespace automatisch detecteren
+ IMAP pad voorvoegsel
+ Conceptmap
+ Verzendmap
+ Prullenbakmap
+ Archiefmap
+ Spammap
+ Alleen geabonneerde mappen weergeven
+ Map automatisch uitvouwen
+ WebDAV (Exchange) path
+ Optioneel
+ Authenticatie pad
+ Optioneel
+ Mailbox alias
+ Optioneel
+ Uitgaande server instellingen
+ SMTP server
+ Poort
+ Beveiligingstype
+ Inloggen vereist.
+ Gebruikersnaam
+ Wachtwoord
+ Authenticatietype
+ \"%1$s = %2$s\" is niet geldig met \"%3$s = %4$s\"
+ Ongeldige setup: %s
+ Account opties
+ Account comprimeren
+ Map peiling-frequentie
+ Nooit
+ Elke 15 minuten
+ Elke 30 minuten
+ Elk uur
+ Elke 2 uur
+ Elke 3 uur
+ Elke 6 uur
+ Elke 12 uur
+ Elke 24 uur
+ Push mail voor dit account toestaan
+ Als jouw server dit ondersteunt, zullen nieuwe berichten direct verschijnen. Deze optie kan drastisch verbeteringen of verslechteringen van prestaties teweeg brengen.
+ Vernieuw inactieve verbinding
+ Elke 2 minuten
+ Elke 3 minuten
+ Elke 6 minuten
+ Elke 12 minuten
+ Elke 24 minuten
+ Elke 36 minuten
+ Elke 48 minuten
+ Elke 60 minuten
+ Waarschuw me wanneer nieuwe e-mail binnenkomt
+ Waarschuw me wanneer er op nieuwe e-mail wordt gecontroleerd
+ Aantal berichten om te laten zien
+ 10 berichten
+ 25 berichten
+ 50 berichten
+ 100 berichten
+ 250 berichten
+ 500 berichten
+ 1000 berichten
+ 2500 berichten
+ 5000 berichten
+ 10000 berichten
+ alle berichten
+ Kan bericht niet kopiëren of verplaatsen omdat deze niet gesynchroniseerd is met de server
+ Setup kon niet afronden
+ Gebruikersnaam of wachtwoord ongeldig.\n(%s)
+ De server presenteerde een ongeldig SSL certificaat. Dit kan komen door een verkeerd geconfigureerde server. Dit kan ook komen doordat iemand jouw mailserver aan probeert te vallen. Als je niet zeker weet wat er aan de hand is klik dan op Reject en neem contact op met de beheerder van de mailserver.\n\n(%s)
+ Kan geen verbinding met server maken.\n(%s)
+ Details aanpassen
+ Doorgaan
+ Geavanceerd
+ Algemene instellingen
+ Nieuwe e-mail notificatie
+ Notificatie mappen
+ Alles
+ Alleen 1e klasse mappen
+ 1e en 2e klasse mappen
+ Alle behalve 2e klasse mappen
+ Geen
+ Sync notificatie
+ Je e-mailadres
+ Notificatie in statusbalk wanneer nieuwe e-mail binnenkomt
+ Notificatie in statusbalk wanneer wordt gecontroleerd op nieuwe e-mail
+ Notificatie voor e-mail welke ik verstuur
+ Notificatie ook voor e-mail verzonden vanaf een identiteit
+ Alleen contacten
+ Notificaties alleen weergeven voor bekende contacten
+ Chatberichten negeren
+ Geef geen meldingen weer voor berichten die onderdeel zijn van een e-mail-chat
+ Markeer als gelezen als geopend
+ Markeer als gelezen wanneer ingezien
+ Als gelezen markeren bij wissen
+ Markeer een bericht als gelezen wanneer die wordt gewist
+ Meldingscategorieën
+ Meldingen instellen voor nieuwe berichten
+ Error- en statusmeldingen instellen
+ Laat afbeeldingen automatisch zien
+ Nooit
+ Alleen van contacten
+ Altijd
+ Berichten versturen
+ Citeer bericht bij antwoorden
+ Neem orginele bericht mee in het antwoord.
+ Antwoorden na citaat
+ Wanneer je antwoord op een bericht, zal het originele bericht boven jouw antwoord staan.
+ Verwijder handtekening bij reactie
+ Handtekeningen worden verwijderd bij geciteerde berichten
+ Berichtopmaak
+ Platte Tekst (plaatjes en opmaak worden verwijderd)
+ HTML (plaatjes en opmaak blijven behouden)
+ Automatisch
+ Altijd Cc/Bcc laten zien
+ Leesbevestiging
+ Altijd een leesbevestiging vragen
+ Quotestijl bij antwoorden
+ Prefix (zoals Gmail, Pine)
+ Kop (zoals Outlook)
+ Upload verzonden berichten
+ Upload berichten naar \'Verzonden\' map na verzenden
+ Algemene instellingen
+ Berichten lezen
+ Berichten ophalen
+ Mappen
+ Citaat voorvoegsel
+ Eind-tot-eind versleuteling
+ OpenPGP ondersteuning inschakelen
+ OpenPGP app selecteren
+ Eind-tot-eind sleutel instellen
+ Geen OpenPGP app ingesteld
+ Verbonden met %s
+ Aan het configureren ...
+ Sla alle concepten versleuteld op.
+ Alle concepten zullen versleuteld worden opgeslagen
+ Versleutel concepten alleen als versleuteling is ingeschakeld
+ Map peiling-frequentie
+ Account kleur
+ De kleur van dit account gebruikt bij mappen en accountlijst
+ Geen kleur
+ Notificatie LED kleur
+ Kies de LED kleur van de telefoon, welke moet knipperen voor deze account
+ Lokale map grootte
+ Automatisch berichten downloaden tot
+ 1 KiB
+ 2 KiB
+ 4 KiB
+ 8 KiB
+ 16 KiB
+ 32 KiB
+ 64 KiB
+ 128 KiB
+ 256 KiB
+ 512 KiB
+ 1 MiB
+ 2 MiB
+ 5 MiB
+ 10 MiB
+ elke grootte (geen limiet)
+ Sync berichten van
+ alles (geen limiet)
+ vandaag
+ laatste 2 dagen
+ laatste 3 dagen
+ afgelopen week
+ afgelopen 2 weken
+ afgelopen 3 weken
+ afgelopen maand
+ afgelopen 2 maanden
+ afgelopen 3 maanden
+ afgelopen 6 maanden
+ afgelopen jaar
+ Mappen om weer te geven
+ Alle
+ Alleen 1e klasse mappen
+ 1e en 2e klasse mappen
+ Alle behalve 2e klasse mappen
+ Peiling mappen
+ Alle
+ Alleen 1e klasse mappen
+ 1e en 2e klasse mappen
+ Alle behalve 2e klasse mappen
+ Geen
+ Push mappen
+ Alle
+ Alleen 1e klasse mappen
+ 1e en 2e klasse mappen
+ Alle behalve 2e klasse mappen
+ Geen
+ Verplaats/kopieer doel mappen
+ Alle
+ Alleen 1e klasse mappen
+ 1e en 2e klasse mappen
+ Alle behalve 2e klasse mappen
+ Sync verwijderingen op server
+ Verwijder berichten wanneer verwijderd van server
+ OpenPGP app niet aanwezig - is de app verwijderd?
+ Map instellingen
+ Laat zien in kopgroep
+ Laat zien bij de top van de maplijst
+ Map weergave klasse
+ Geen klasse
+ 1e klasse
+ 2e klasse
+ Map peiling-klasse
+ Geen
+ 1e klasse
+ 2e klasse
+ Zelfde als weergave klasse
+ Push klasse map
+ Geen klasse
+ 1e klasse
+ 2e klasse
+ Zelfde als peiling-klasse
+ Map notificatie klasse
+ Geen klasse
+ 1e klasse
+ 2e klasse
+ Zelfde als push klasse
+ Lokale berichten wissen
+ Inkomende server
+ Instellen van de inkomende mail server
+ Uitgaande server
+ Configureren van de uitgaande (SMTP) server
+ Account naam
+ Jouw naam
+ Notificaties
+ Trillen
+ Trillen wanneer nieuwe e-mail binnenkomt
+ Tril patronen
+ standaard
+ patroon 1
+ patroon 2
+ patroon 3
+ patroon 4
+ patroon 5
+ Aantal trillingen
+ Nieuwe e-mail beltoon
+ Knipper LED
+ Knipper LED wanneer e-mail binnenkomt
+ Bericht samenstelling opties
+ Samenstelling standaarden
+ Stel standaard in voor: Van, Bcc en handtekening
+ Beheer identiteiten
+ Instellen alternatieve \'Van\' adressen en handtekeningen
+ Beheer identiteiten
+ Beheer identiteit
+ Identiteit aanpassen
+ Bewaar
+ Nieuwe identiteit
+ Bcc alle berichten naar
+ Aanpassen
+ Verplaats ophoog
+ Verplaats omlaag
+ Verplaats naar top / maak standaard
+ Verwijder
+ Identiteit beschrijving
+ (Optioneel)
+ Jouw naam
+ (Optioneel)
+ E-mailadres
+ (Vereist)
+ Antwoord adres
+ (Optioneel)
+ Handtekening
+ (Optioneel)
+ Gebruik handtekening
+ Handtekening
+ Initiële identiteit
+ Kies identiteit
+ Verzenden als
+ Je kunt je eigen identiteit niet verwijderen
+ Je kunt een identiteit niet gebruiken zonder e-mailadres
+ Oudste berichten eerst
+ Nieuwste berichten eerst
+ Onderwerp alfabetische volgorde
+ Onderwerp omgekeerd alfabetische volgorde
+ Verzender alfabetisch
+ Verzender omgekeerd alfabetisch
+ Berichten met ster eerst
+ Berichten zonder ster eerst
+ Ongelezen berichten eerst
+ Gelezen berichten eerst
+ Berichten met bijlagen eerst
+ Berichten zonder bijlagen eerst
+ Sorteren volgens …
+ Datum
+ Aankomst
+ Onderwerp
+ Verzender
+ Ster
+ Gelezen/ongelezen
+ Bijlagen
+ Account verwijderen
+ Onbekend Certificaat
+ Accepteer Sleutel
+ Verwerp Sleutel
+ Del (of D) - Verwijderen\nR - Antwoord\nA - Iedereen antwoorden\nC - Opstellen\nF - Doorsturen\nM - Verplaatsen\nV - Archiveren\nY - Kopiëren\nZ - Markeer (on)gelezen\nG - Ster\nO - Sorteer type\nI - Sorteer volgorde\nQ - Terug naar Mappen\nS - Selecteer/deselecteer\nJ of P - Vorig bericht\nK of N - Volgende bericht
+ Del (of D) - Verwijderen\nC - Opstellen\nM - Verplaatsen\nV - Archiveren\nY - Kopiëren\nZ - Markeer (on)gelezen\nG - Ster\nO - Sorteer type\nI - Sorteer volgorde\nQ - Terug naar Mappen\nS - Selecteer/deselecteer
+ Mapnaam bevat
+ Mappen
+ Laat alle mappen zien
+ 1e klasse mappen
+ 1e & 2e klasse mappen
+ 2e klasse mappen verbergen
+ Positie handtekening
+ Voor geciteerd bericht
+ Na geciteerd bericht
+ Gebruik app thema
+ Donker
+ Licht
+ Gebruik systeemstandaard
+ Algemene instellingen
+ Algemeen
+ Debuggen
+ Privacy
+ Netwerk
+ Interactie
+ Accountlijst
+ Berichtlijsten
+ Berichten
+ Thema
+ Thema om berichten te zien
+ Thema om berichten te schrijven
+ Taal
+ Geen instellingen gevonden
+ Vast berichten thema
+ Kies het thema tijdens het bekijken van het bericht
+ Gebruik een vast thema om het bericht te bekijken
+ Volgens systeem
+ Achtergrond sync
+ Nooit
+ Altijd
+ Als \'Auto-sync\' geselecteerd is
+ Selecteer alle
+ Max mappen om te controleren met push
+ 5 mappen
+ 10 mappen
+ 25 mappen
+ 50 mappen
+ 100 mappen
+ 250 mappen
+ 500 mappen
+ 1000 mappen
+ Animatie
+ Gebruik opzichtige visuele effecten
+ Volume op/neer navigatie
+ Bericht beeld
+ Variabele lijst weergave
+ Gecombineerde postvak-in weergeven
+ Het aantal berichten met een ster weergeven
+ %s%s
+ - Ongelezen
+ Alle berichten
+ Alle berichten in doorzoekbare mappen
+ Gecombineerde postvak-in
+ Alle berichten in gecombineerde mappen
+ Combineer
+ Alle berichten worden in de gecombineerde postvak-in weergegeven
+ Mappen om te doorzoeken
+ Alle
+ Zichtbare
+ Geen
+ Geen
+ Automatisch (%s)
+ Lettergrootte
+ Instellen lettergrootte
+ Account lijst
+ Account naam
+ Account beschrijving
+ Maplijsten
+ Mapnaam
+ Mapstatus
+ Bericht lijsten
+ Bericht onderwerp
+ Bericht afzender
+ Bericht datum
+ Preview
+ Beeld berichten
+ Bericht afzender
+ Bericht ontvanger (Aan)
+ Bericht ontvanger (CC)
+ Bericht ontvanger (BCC)
+ Extra koppen
+ Bericht onderwerp
+ Bericht tijd en datum
+ Bericht inhoud
+ %d%%
+ %1$s: %2$s
+ Bericht opstellen
+ Tekst invoervelden
+ Standaard
+ Kleinste
+ Heel klein
+ Kleiner
+ Klein
+ Gemiddeld
+ Groot
+ Groter
+ Geen geschikte applicatie gevonden voor deze actie.
+ Verzenden mislukt: %s
+ Concept opslaan?
+ Opslaan of negeren van dit bericht?
+ Wijzigingen opslaan of verwerpen?
+ Bericht afbreken?
+ Weet je zeker dat je dit bericht wilt verwijderen?
+ Selecteer tekst om te kopiëren.
+ Lokale berichten wissen?
+ Dit zal alle lokale berichten uit deze map wissen. Er worden geen berichten van de server gewist.
+ Berichten wissen
+ Bevestig verwijderen
+ Wil je dit bericht verwijderen?
+
+ Wil je dit bericht echt verwijderen?
+ Wil je echt %1$d berichten verwijderen?
+
+ Ja
+ Nee
+ Markeer alles als gelezen
+ Wil je alle berichten markeren als gelezen?
+ Bevestig prullenbak legen
+ Wil je de prullenbak leeg maken?
+ Ja
+ Nee
+ Bevestig verplaatsing naar spam map
+
+ Wil je dit bericht echt verplaatsen naar de spam map?
+ Wil je dit bericht echt verplaatsen naar de spam map?
+
+ Ja
+ Nee
+ Bijlage wordt opgehaald
+ »
+ ›
+ Back-up
+ Diversen
+ Exporteer instellingen
+ Export
+ Delen
+ Instellingen exporteren …
+ Instellingen succesvol geëxporteerd
+ Instellingen exporteren mislukt
+ Instellingen importeren
+ Bestand selecteren
+ Importeren
+ Instellingen succesvol geïmporteerd
+ Voer de wachtwoorden in
+ Instellingen importeren mislukt
+ Lezen van instellingenbestand mislukt
+ Importeren van sommige instellingen mislukt
+ Succesvol geïmporteerd
+ Wachtwoord vereist
+ Niet geïmporteerd
+ Importeren mislukt
+ Later
+ Import instellingen
+ Instellingen importeren …
+
+ Om het account \"%s\" te gebruiken moet je het wachtwoord van de server opgeven.
+ Om het account \"%s\" te gebruiken moet je de wachtwoorden van de server opgeven.
+
+ Binnenkomendeserver-wachtwoord
+ Uitgaandeserver-wachtwoord
+ Gebruik het zelfde wachtwoord voor de uitgaandeserver
+ Servernaam: %s
+ Ongelezen aantal weergeven voor …
+ Account
+ Het account waarvan het aantal ongelezen berichten wordt getoond
+ Gecombineerde postvak-in
+ Map aantal
+ Toon het aantal ongelezen berichten van een enkele map
+ Map
+ De map waarbij ongelezen berichten wordt getoond
+ Klaar
+ %1$s - %2$s
+ Geen account gekozen
+ Geen folder gekozen
+ Geen tekst
+ Open link
+ Deel link
+ Kopieer link naar klembord
+ Link
+ Verwijzingstekst naar klembord kopiëren
+ Verwijzingstekst
+ Afbeelding
+ Afbeelding laten zien
+ Afbeelding opslaan
+ Afbeelding downloaden
+ Kopieer afbeelding-URL naar klembord
+ Afbeelding-URL
+ Bel nummer
+ Opslaan in contacten
+ Kopieer nummer naar klembord
+ Telefoonnummer
+ Stuur e-mail
+ Opslaan in contacten
+ Kopieer adres naar klembord
+ E-mailadres
+ Alle
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Server zoek limiet
+ Zoekopdracht naar server sturen
+
+ %d resultaat ophalen
+ %d berichten ophalen
+
+
+ %1$d van %2$d berichten ophalen
+ %1$d van %2$d berichten ophalen
+
+ Zoekopdracht mislukt
+ Zoeken
+ Server zoeken toestaan
+ Zoek berichten op de server en op je eigen toestel
+ Zoek berichten op server
+ Er is een netwerk verbinding nodig voor server zoeken.
+ Kleur wijzigen na lezen
+ Een andere achtergrond laat zien nadat de e-mail is gelezen
+ Gesprek overzicht
+ Groepeer berichten per gesprek
+ Gegevensbanken bijwerken
+ Gegevensbanken aan het bijwerken …
+ Gegevensbanken van account \"%s\" bijwerken
+ Gespleten-scherm laten zien
+ Altijd
+ Nooit
+ In landschap oriëntatie
+ Selecteer een bericht aan de linker kant
+ Laat contactafbeeldingen zien
+ Laat contactafbeeldingen in de berichtenlijst zien
+ Markeer alles als gelezen
+ Contactafbeeldingen kleuren
+ Voorzie afwezige contactafbeeldingen van een kleur
+ Zichtbare berichtacties
+ Toon de geselecteerde acties in het Berichten-menu
+ Bijlage aan het laden …
+ Bericht wordt verstuurd
+ Concept wordt opgeslagen
+ Bijlage aan het ophalen …
+ Kan niet authenticeren. De server ondersteunt geen SASL EXTERNAL. Dit kan komen door een probleem met het client certificaat (verlopen of onbekende CA) of een ander configuratieprobleem.
+
+ Gebruik client certificaat
+ Geen client certificaat
+ Verwijder client certificaat selectie
+ Client certificaat niet ontvangen voor alias \"%s\"
+ Geavanceerde opties
+ Client certificaat \"%1$s\" is verlopen of niet geldig (%2$s)
+
+ *Versleuteld*
+ Toevoegen vanuit contacten
+ CC
+ BCC
+ Aan
+ Van
+ Antwoorden aan
+ <Onbekende ontvanger>
+ <Onbekende verzender>
+ Privé
+ Werk
+ Anders
+ Mobiel
+ Geen concepten map ingesteld voor dit account!
+ Geen sleutel ingesteld voor dit account! Controleer je instellingen.
+ Crypto provider gebruikt incompatibele versie. Controleer je instellingen!
+ Kan geen verbinding maken met de crypto provider. Controleer de instellingen of klik op het crypto icoontje om nogmaals te proberen.
+ Initialisatie van eind-tot-eind versleuteling is mislukt, controleer de instellingen
+ PGP/MIME instelling ondersteund geen bijlagen!
+ PGP/INLINE toestaan
+ PGP/INLINE uitzetten
+ PGP handtekening toestaan
+ PGP handtekening stoppen
+ PGP/INLINE instellingen
+ De e-mail is verzonden in PGP/INLINE formaat.\nDit word alleen gebruikt voor compatibiliteit:
+ Sommige clients ondersteunen alleen dit formaat
+ Handtekening kan onderweg breken
+ Bijlagen zijn niet ondersteund
+ Begrepen!
+ Uitzetten
+ Keep toestaan
+ Begrepen!
+ Uitzetten
+ Houd ingeschakeld
+ alleen PGP handtekening modes
+ In deze mode wordt je PGP sleutel gebruikt voor een cryptografische handtekening of een ongecodeerde email.
+ Dit versleutelt niet de e-mail, maar controleert dat je eigen sleutel gebruikt is.
+ Handtekening kan bij versturing naar verzendlijst breken
+ Handtekening kan worden weergegeven als \'signature.asc\' bijlage bij sommige programma\'s
+ Versleutelde berichten bevatten altijd een handtekening.
+ Platte tekst
+ eind-tot-eind handtekening bevat een fout
+ moet bericht volledig downloaden om handtekening te verwerken
+ bevat niet ondersteunde eind-tot-eind handtekening
+ Bericht is versleuteld, maar in een niet ondersteund formaat.
+ Bericht is versleuteld, maar ontsleuteling was gestopt.
+ Eind-tot-eind getekende platte tekst
+ van geverifieerde ondertekenaar
+ Platte tekst getekend
+ maar eind-tot-eind sleutel komt niet overeen met afzender
+ maar eind-tot-eind sleutel is verlopen
+ maar eind-tot-eind sleutel is ingetrokken
+ maar eind-tot-eind sleutel is niet veilig
+ van een onbekende eind-tot-eind sleutel
+ Versleuteld
+ maar er is een ontsleutel fout opgetreden
+ moet bericht volledig downloaden voor ontsleuteling
+ maar er is geen crypto app geconfigureerd
+ Versleuteld
+ maar niet eind-tot-eind
+ Eind-tot-eind versleuteld
+ van geverifieerde afzender
+ Versleuteld
+ van een onbekende eind-tot-eind sleutel
+ maar eind-tot-eind sleutel komt niet overeen met afzender
+ maar eind-tot-eind sleutel is verlopen
+ maar eind-tot-eind sleutel is ingetrokken
+ maar eind-tot-eind sleutel is niet veilig
+ maar eind-tot-eind gegevens bevatten fouten
+ maar versleuteling is niet veilig
+ OK
+ Zoek Sleutel
+ Bekijk ondertekenaar
+ Bekijk afzender
+ Details
+ Deblokkeer
+ Dit onderdeel is niet versleuteld en is misschien niet veilig.
+ Onbeveiligde Bijlage
+ Aan het laden …
+ Ontsleuteling is gestopt.
+ Opnieuw
+ Versleuteld bericht moet gedownload zijn voor ontsleuteling.
+ Fout tijdens ontsleutelen e-mail
+ Speciale leestekens worden nog niet ondersteund!
+ Fout bij parsen van adres!
+ Verberg niet-versleutelde handtekeningen
+ Alleen versleutelde handtekeningen worden weergegeven
+ Alle handtekeningen worden weergegeven
+ Versleuteling niet mogelijk in sign-only mode!
+ niet getekende tekst
+ APG Deprecation Waarschuwing
+ APG is niet langer beheerd!
+ Hierdoor is de ondersteuning voor APG verwijderd binnen K-9 mail.
+ De ontwikkeling is gestopt in 2014
+ Bevat onveilige items
+ Klik hier voor meer informatie.
+ Begrepen!
+ APG
+ Deze e-mail is versleuteld
+ Deze e-mail is OpenPGP versleuteld.\nInstalleer en stel een OpenPGP App in om de e-mail te lezen.
+ Ga naar Instellingen
+ K-9 Bericht Lijst
+ Berichten aan het laden …
+ Ophalen maplijst niet gelukt
+ Fout bij ophalen status van de OpenPGP provider!
+ Versleuteling niet mogelijk
+ Sommige van de ontvangers ondersteunen deze functie niet!
+ Versleuteling inschakelen
+ Versleuteling uitschakelen
+ Versleuteling maakt dat berichten alleen door de ontvanger gelezen kunnen worden, en niemand anders.
+ Versleuteling is alleen beschikbaar als alle ontvangers dit ondersteunen, en zij moeten je reeds eerder een e-mail gestuurd hebben.
+ Schakel versleuteling aan of uit met dit icoon.
+ Ik snap het
+ Terug
+ Versleuteling uitschakelen
+ OpenPGP-versleuteling
+ Autocrypt wederzijdse modus
+ Autocrypt wederzijdse modus
+ Berichten worden op verzoek versleuteld, of bij beantwoorden van een versleuteld bericht.
+ Als verzender en ontvanger de wederzijdse modus inschakelen dan wordt standaard versleuteling ingesteld.
+ Klik hier voor meer informatie.
+ Algemene instellingen
+ Geen OpenPGP app geïnstalleerd
+ Installeren
+ K-9 Mail vereist OpenKeychain voor eind-tot-eind versleuteling.
+ Versleuteld bericht
+ Onderwerp van bericht versleutelen
+ Mogelijk niet ondersteund door alle ontvangers
+ Interne fout: Ongeldig account!
+ Fout bij het verbinden met %s!
+ Verstuur Autocrypt Setup bericht
+ Veilig delen van eind-tot-eind instellingen met andere apparaten
+ Autocrypt Setup bericht
+ Een Autocrypt Setup bericht deelt uw eind-tot-eind instellingen op een beveiligde manier met andere apparaten.
+ Verstuur Setup bericht
+ Het bericht wordt verstuurd naar jouw adres:
+ Instelbericht aan het genereren ...
+ Bericht sturen naar:
+ Om te voltooien, open het bericht op je andere apparaat en voer de Setup Code in.
+ Setup Code weergeven
+ Autocrypt Setup bericht
+ Dit bericht bevat alle informatie om jouw Autocrypt instellingen met geheime sleutel beveiligd over te brengen vanaf jouw oorspronkelijke apparaat.
-Volg de instructies op uw nieuwe apparaat om daarop Autocrypt in te stellen.
+Volg de instructies op je nieuwe apparaat om daarop Autocrypt in te stellen.
-U kunt dit bericht bewaren als backup voor uw geheime sleutel. Als u dit wilt doen, schrijf dan het wachtwoord op en bewaar het op een veilige plek.
+Je kunt dit bericht bewaren als backup voor jouw geheime sleutel. Als je dit wilt doen, schrijf dan het wachtwoord op en bewaar het op een veilige plek.
- Er is een fout opgetreden tijdens het verzenden van het bericht. Controleer uw netwerk verbinding en uitgaande server configuratie.
- Aan
- Uit
- Open
- Sluiten
-
- Sta toegang tot contacten toe
- Om contact suggesties te kunnen bieden en om namen en/of foto\'s van contacten weer te geven, heeft de app toegang nodig tot je contactenlijst.
- Er is een fout opgetreden bij het laden van de gegevens
- Aan het initialiseren …
- In afwachting van nieuwe e-mails
- Doet niets totdat achtergrondsynchronisatie wordt toegestaan
- Doet niets totdat er een netwerk beschikbaar is
- Tik hier om er meer over te leren.
- Duw informatie
- Als je duw gebruikt, dan houd K-9 mail een verbinding open met de e-mail server. Android vereist dat een app die op de achtergrond actief blijft een melding plaatst. %s
- Android maakt het echter ook mogelijk om meldingen te verbergen.
- Meer leren hierover
- Melding instellen
- Als je het niet nodig vindt om per direct meldingen te ontvangen van nieuwe berichten, dan kun je beter duw uitschakelen en in plaats daarvan kiezen voor peilen. Met peilen wordt er om de zoveel tijd gekeken of er nieuwe e-mails zijn binnengekomen. Daarvoor is het weergeven van een melding niet continu nodig.
- Duw uitschakelen
- XOauth2 (Gmail, Outlook)
- Geluid afspelen wanneer een email succesvol verzonden is
- Geluid verzonden email
- Servicevoorwaarden
- Privacybeleid
- Mail s gebaseerd op K9 Mail
- Informatie over Mail
- Auteurs
- -Mail is een open source email app voor Android.
- Broncode
- Licentie
- Versie
-
\ No newline at end of file
+ Er is een fout opgetreden tijdens het verzenden van het bericht. Controleer de netwerk verbinding en uitgaande server configuratie.
+ Aan
+ Uit
+ Open
+ Sluiten
+
+ Sta toegang tot contacten toe
+ Om contact suggesties te kunnen bieden en om namen en/of foto\'s van contacten weer te geven, heeft de app toegang nodig tot je contactenlijst.
+ Er is een fout opgetreden bij het laden van de gegevens
+ Aan het initialiseren …
+ In afwachting van nieuwe e-mails
+ Doet niets totdat achtergrondsynchronisatie wordt toegestaan
+ Doet niets totdat er een netwerk beschikbaar is
+ Tik hier om er meer over te leren.
+ Push informatie
+ Als je push gebruikt, dan houd K-9 mail een verbinding open met de e-mail server. Android vereist dat een app die op de achtergrond actief blijft een melding plaatst. %s
+ Android maakt het echter ook mogelijk om meldingen te verbergen.
+ Meer leren hierover
+ Melding instellen
+ Als je het niet nodig vindt om per direct meldingen te ontvangen van nieuwe berichten, dan kun je beter push uitschakelen en in plaats daarvan kiezen voor peilen. Met peilen wordt er om de zoveel tijd gekeken of er nieuwe e-mails zijn binnengekomen. Daarvoor is het weergeven van een melding niet continu nodig.
+ Push uitschakelen
+
diff --git a/app/ui/legacy/src/main/res/values-pl/strings.xml b/app/ui/legacy/src/main/res/values-pl/strings.xml
index bae868adee5b90041cb8429dee07b441f0ea52d9..00b26e3de0b7ee79e681048c76b4d4d5cffccab0 100644
--- a/app/ui/legacy/src/main/res/values-pl/strings.xml
+++ b/app/ui/legacy/src/main/res/values-pl/strings.xml
@@ -82,6 +82,7 @@
UsuńZapisz jako szkicSprawdź pocztę
+ Sprawdź pocztę na wszystkich kontachWyślij wiadomościOdśwież listęWyszukaj folder
@@ -249,10 +250,6 @@
Remove Mail User-Agent from mail headersUkryj strefę czasowąUżywaj czasu UTC zamiast czasu lokalnego w nagłówkach wiadomości i odpowiedzi
- Ukryj temat w powiadomieniach
- Nigdy
- Gdy urządzenie jest zablokowane
- ZawszePokazuj przycisk „Usuń”NigdyDla powiadomień o pojedynczych wiadomościach
@@ -260,7 +257,6 @@
Powiadomienia na ekranie blokadyBez powiadomień na ekranie blokadyNazwa aplikacji
- Liczba nieprzeczytanych wiadomościNadawcy i liczba wiadomościTak samo, jak przy odblokowanym ekranieOkres ciszy
@@ -273,6 +269,10 @@
Adres emailHasłoPokaż hasło
+
+ Aby zobaczyć tutaj swoje hasło, ustaw blokadę ekranu na tym urządzeniu.
+ Zweryfikuj swoją tożsamość
+ Odblokuj, aby zobaczyć swoje hasłoUstaw ręczniePobieram informacje…
@@ -314,8 +314,6 @@
2G/3GWi-FiInne
- Pamięć zewnętrzna (karta SD)
- Zwykła pamięć wewnętrznaKasowanie usuniętych wiadomości na serwerzeOd razuPodczas każdego pobrania
@@ -391,8 +389,6 @@
KontynuujZaawansowaneUstawienia ogólne
- Konto domyślne
- Domyślnie wysyłaj wiadomości z tego kontaNowe wiadomościPowiadomienia z folderówWszystkie
@@ -408,12 +404,14 @@
Pokaż powiadomienie dla wiadomości wysłanych przeze mnieTylko kontaktyPokaż powiadomienia tylko dla wiadomości od znanych kontaktów
+ Ignoruj wiadomości z czatu
+ Nie pokazuj powiadomień dla wiadomości należących do czatu e-mailOznacz jako przeczytaneOznacz wiadomość jako przeczytaną przy otwieraniuOznacz jako przeczytane po usunięciuOznacz wiadomość jako przeczytaną przy usuwaniu
- Ustawienia powiadomień
- Otwórz systemowe ustawienia powiadomień
+ Kategorie powiadomień
+ Konfiguruj powiadomienia dla nowych wiadomościZawsze pokazuj obrazkiNieOd kontaktów
@@ -666,6 +664,7 @@
Wygląd wiadomościRóżne widoki listPokaż zintegrowaną skrzynkę odbiorczą
+ Pokaż liczbę oznaczonych gwiazdką%s%s - NieprzeczytaneWszystkie wiadomości
diff --git a/app/ui/legacy/src/main/res/values-pt-rBR/strings.xml b/app/ui/legacy/src/main/res/values-pt-rBR/strings.xml
index fdfbd271afe9b21544af0599601d5573f468cc2a..d392844bf2c6cd2511f2f797be05da4622cfd4a2 100644
--- a/app/ui/legacy/src/main/res/values-pt-rBR/strings.xml
+++ b/app/ui/legacy/src/main/res/values-pt-rBR/strings.xml
@@ -49,6 +49,8 @@
Encaminhar como anexoSelecionar contaEscolher a pasta
+ Mover para...
+ Copiar para...Verificar %s:%s%sBuscando os cabeçalhos %s:%s%sEnviando %s%s
@@ -82,6 +84,7 @@
DescartarSalvar como rascunhoVerificar e-mail
+ Verificar mensagens em todas as contasEnviar mensagensAtualizar a lista de pastasEncontrar pasta
@@ -172,6 +175,9 @@
Relatar informações de diagnósticos extrasRelatar informações confidenciasPode exibir senhas nos relatórios
+ Exportar relatórios
+ Exportado com sucesso. Os relatórios podem conter informação sensível. Tome cuidado ao enviá-los para alguém.
+ Não foi possível exportar.Carregar mais mensagensPara:%sAssunto
@@ -245,10 +251,6 @@
Remove Mail User-Agent from mail headersOcultar o fuso horárioUsar UTC ao invés do fuso horário local nos cabeçalhos das mensagens e das respostas
- Ocultar o assunto nas notificações
- Nunca
- Quando o dispositivo estiver bloqueado
- SempreExibir o botão \'Excluir\'NuncaNas notificações de mensagens individuais
@@ -256,7 +258,7 @@
Notificações na tela de bloqueioSem notificações na tela de bloqueioNome do aplicativo
- Número de mensagens não lidas
+ Número de mensagens novasNúmero de mensagens e remetentesO mesmo de quando a tela está desbloqueadaPeríodo de silêncio
@@ -269,6 +271,10 @@
Endereço de e-mailSenhaExibir a senha
+
+ Para ver a sua senha aqui, habilite o bloqueio de tela neste dispositivo.
+ Verifique sua identidade
+ Desbloqueie para ver a sua senhaConfiguração manualRecuperando informações da conta\u2026
@@ -310,8 +316,6 @@
Rede móvelWi-FiOutras
- Armazenamento externo (cartão SD)
- Armazenamento interno regularApagar no servidor as mensagens excluídas localmenteImediatamenteDurante a verificação
@@ -387,8 +391,6 @@
ContinuarAvançadoConfigurações da conta
- Conta padrão
- Usar esta conta como padrão para envio de e-mailNovas notificações de e-mailNotificações de pastasTodas
@@ -404,12 +406,15 @@
Exibe uma notificação para mensagens enviadasApenas contatosExibe notificações somente para mensagens de contatos conhecidos
+ Ignorar mensagens de bate-papo
+ Não mostra notificações para mensagens pertencentes a um bate-papo por e-mailMarcar como lida ao abrirMarcar a mensagem como lida quando ela for aberta para visualizaçãoMarcar como lida ao excluirMarca uma mensagem como lida quando ela for excluída
- Configurações das notificações
- Abrir as configurações de notificações do sistema
+ Categorias de notificação
+ Configura as notificações para as novas mensagens
+ Configura as notificações de erros e statusSempre exibir imagensNãoDos contatos
@@ -662,6 +667,7 @@
Nas visualizações das mensagensNas visualizações das listasExibir a caixa de entrada unificada
+ Mostrar a contagem de sinalizadas%s%s - Não lidoTodas as mensagens
@@ -871,6 +877,7 @@
CcoParaDe
+ Responder para<Destinatário desconhecido><Remetente desconhecido>Casa
diff --git a/app/ui/legacy/src/main/res/values-pt-rPT/strings.xml b/app/ui/legacy/src/main/res/values-pt-rPT/strings.xml
index fdf2cbb92e442be6fcc05af123cb00a3018bd007..62dd9bd8d966ea9026480863df7118ed64f36211 100644
--- a/app/ui/legacy/src/main/res/values-pt-rPT/strings.xml
+++ b/app/ui/legacy/src/main/res/values-pt-rPT/strings.xml
@@ -229,10 +229,6 @@
Remove Mail User-Agent from mail headersOcultar fuso horárioUsar UTC em vez do fuso horário local nos cabeçalhos dos emails e no cabeçalho de resposta
- Ocultar assunto nas notificações
- Nunca
- Quando o dispositivo está bloqueado
- SempreMostrar botão \'Eliminar\'NuncaPara notificações de apenas uma mensagem
@@ -240,7 +236,6 @@
Notificações no ecrã de bloqueioSem notificações no ecrã de bloqueioNome da aplicação
- Número de mensagens não lidasNúmero de mensagens e remetentesO mesmo quando o ecrã está desbloqueadoPeríodo de sossego
@@ -253,6 +248,7 @@
Endereço de emailPalavra-passeMostrar palavra-passe
+
Configuração manualA obter informações da conta\u2026
@@ -294,8 +290,6 @@
MóvelWi-FiOutras
- Armazenamento externo (cartão SD)
- Armazenamento na memória internaApagar mensagens eliminadas no servidorImediatamenteNa verificação
@@ -371,8 +365,6 @@
ContinuarAvançadoConfigurações da conta
- Conta predefinida
- Enviar email a partir desta conta por predefiniçãoNotificação de novos emailsNotificações de pastasTodas
@@ -392,8 +384,6 @@
Marcar uma mensagem como lida ao abrir para visualizaçãoMarcar como lida quando apagadaMarcar a mensagem como lida quando é apagada
- Configurações de notificação
- Configurações de sistema abertoMostrar sempre as imagensNãoApenas dos contactos
diff --git a/app/ui/legacy/src/main/res/values-ro/strings.xml b/app/ui/legacy/src/main/res/values-ro/strings.xml
index 2ebe56e53ac413a364f19552a288af09d2916782..53ac05b653d312a723474cd18847ff13ba4308d6 100644
--- a/app/ui/legacy/src/main/res/values-ro/strings.xml
+++ b/app/ui/legacy/src/main/res/values-ro/strings.xml
@@ -49,6 +49,8 @@
Trimite atașatAlege contulAlege dosar
+ Mutați la...
+ Copiați la...Interogare %s:%s%sSe obțin antetele %s:%s%sSe trimite %s%s
@@ -82,6 +84,7 @@
RenunțăSalvează ca ciornăVerifică email
+ Verificarea corespondenței în toate conturileTrimite mesajeReîmprospătează lista de dosareGăsește dosar
@@ -248,10 +251,6 @@ cel mult încă %dRemove Mail User-Agent from mail headersAscunde fusul orarFolosește UTC în locul fusului orar local în antetul mesajelor și al răspunsurilor
- Ascunde subiect în notificări
- Niciodată
- Când dispozitivul este blocat
- ÎntotdeaunaArată butonul \'Ştergere\'NiciodatăPentru notificarea unui singur mesaj
@@ -259,7 +258,7 @@ cel mult încă %dNotificări în ecranul de blocareNici o notificare în ecranul de blocareNumele aplicaţiei
- Contor mesaje necitite
+ Număr de mesaje noiContor mesaje și expeditoriLa fel ca atunci când ecranul este deblocatPerioadă de liniște
@@ -272,6 +271,10 @@ cel mult încă %dAdresa e-mailParolăArată parola
+
+ Pentru a vă vedea parola aici, activați blocarea ecranului pe acest dispozitiv.
+ Verifică-ți identitatea
+ Deblocare pentru a vedea parola dumneavoastrăSetare manualăPreluarea informațiilor de cont\u2026
@@ -313,8 +316,6 @@ cel mult încă %dMobilWi-FiAltceva
- Stocare externă (card SD)
- Stocare internă normalăElimină mesajele şterse de pe serverImediatCând interoghează
@@ -392,8 +393,6 @@ Uneori datorită faptului că cineva încearcă să te atace pe tine sau serveru
ContinuăAvansatSetări cont
- Cont implicit
- Trimite mail din acest cont în mod implicitNotificări mail noiDosare notificăriToate
@@ -409,12 +408,15 @@ Uneori datorită faptului că cineva încearcă să te atace pe tine sau serveru
Arată o notificare pentru mesajele pe care le-am trimisDoar contacteArată notificări doar pentru mesaje de la persoane cunoscute
+ Ignorați mesajele de chat
+ Ignorați mesajele de chatMarchează ca citit la deschidereMarchează mesaj ca citit când e deschis pentru vizualizareMarchează ca citit la ștergereMarchează un mesaj ca citit când este șters
- Setări notificări
- Deschide setările notificărilor de sistem
+ Categorii de notificări
+ Configurați notificările pentru mesaje noi
+ Configurați notificările de eroare și de stareArată întotdeauna imaginileNuDe la contacte
@@ -667,6 +669,7 @@ Uneori datorită faptului că cineva încearcă să te atace pe tine sau serveru
Vizualizări în mesajVizualizări în listăAfișați Cutia poștală de intrare unificată
+ Afișați numărul de stele%s%s - NecititeToate mesajele
@@ -881,6 +884,7 @@ Uneori datorită faptului că cineva încearcă să te atace pe tine sau serveru
BccCătreDe la
+ Răspundeți la<Unknown Recipient><Unknown Sender>Acasă
diff --git a/app/ui/legacy/src/main/res/values-ru/strings.xml b/app/ui/legacy/src/main/res/values-ru/strings.xml
index f43c44286ff8af633913dbab2da1f31b04bca23d..58c237d412d7394c3f3d6422098b6b8661c1dfd6 100644
--- a/app/ui/legacy/src/main/res/values-ru/strings.xml
+++ b/app/ui/legacy/src/main/res/values-ru/strings.xml
@@ -1,14 +1,14 @@
-
+
- Почта
+ Почта Учетные записи почтыНепрочитанная почтаThe K-9 Dog Walkers
- Авторское право 2008-%s The K-9 Dog Walkers. Части авторского права 2006-%s the Android Open Source Project
+ Copyright 2008-%s The K-9 Dog Walkers. Portions Copyright 2006-%s the Android Open Source ProjectИсходный кодЛицензия Apache версии 2.0Проект с открытым исходным кодом
@@ -21,1043 +21,1055 @@
Список измененийНе удалось загрузить список изменений.Версия %s
+ Что нового
+ Показывать последние изменения, когда приложение было обновлено
+ Узнайте, что нового в этом выпуске
- Добро пожаловать в Почту
- Mail is the default mail client for /e/
-
- -- Отправлено из /e/ Mail.
-
- Учётная запись \"%s\" будет удалена из Почты.
-
- Авторы
- Ревизия
- Чтение почты
- Разрешить программе чтение почты.
- Удаление почты
- Разрешить программе удаление почты.
- О приложении Почта
- Ящики
- Папки
- Дополнительно
- Новое
- Ответ
- Ответить всем
- Пересылка
- Переслать вложением
- Выберите ящик
- Выбор папки
- Проверка %s:%s%s
- Просмотр %s:%s%s
- Отправка %s%s
- Обработка %s:%s%s
- \u0020%d/%d
- Синхронизация отключена
- %d выбрано
- Далее
- Назад
-
- ОК
- Отмена
- Отправить
- Редактировать
- Тема не заполнена, нажмите ещё раз для отправки без темы
- Выбрать
- Снять выбор
- Ответить
- Ответить всем
- Удалить
- В архив
- В спам
- Переслать
- Переслать вложением
- Редактировать как новое сообщение
- Переместить
- Переместить в черновики
- Отправить…
- Смена папки…
- Готово
- Отменить
- Сохранить как черновик
- Обновить
- Отправить почту
- Обновить список папок
- Поиск папки
- Добавить
- Создать
- Поиск сообщения
- Результаты поиска
- Настройки
- Выбрать папки
- Настройки ящика
- Удалить ящик
- Прочитано
- Передать
- Выбрать отправителя
- Важное
- Обычное
- Копировать
- Все заголовки
-
- Адрес скопирован в буфер
- Адреса скопированы в буфер
- Адреса скопированы в буфер
- Адреса скопированы в буфер
-
- Тёмная тема
- Светлая тема
- Не прочитано
- Уведомление
- Запросить уведомление о прочтении
- Без уведомления о прочтении
- Вложение
- Очистить корзину
- Стереть
- О действии
- Настройки
-
- (без темы)
- нет отправителя
- Проверка новых сообщений…
- Сбой подключения
- Сообщение не найдено
- Сбой загрузки сообщения
- Получить до %d следующих
- %.1f ГБ
- %.1f МБ
- %.1f кБ
- %d Б
- Ящик \"%s\" изменился с %s до %s
- Сжатие ящика \"%s\"
- Новая почта
-
- %d новое сообщение
- %d новых сообщения
- %d новых сообщений
- %d новых сообщений
-
- %d новых (%s)
- + ещё %1$d в %2$s
- Ответить
- Прочитано
- Прочитаны все
- Удалить
- Удалить все
- Архив
- В архив все
- Спам
- Сбой сертификата %s
- Проверьте настройки сервера
- Сбой аутентификации
- Сбой аутентификации для %s. Измените настройки сервера.
- Проверка %s:%s
- Проверка почты
- Отправка %s
- Отправка почты
- :
- Сообщение
- Уведомления о сообщениях
- Разное
- Различные уведомления, например, об ошибках и т.д.
- Входящие
- Исходящие
- Черновики
- Корзина
- Отправленные
- Сбой отправки почты
- Версия
- Журнал отладки
- Запись диагностических сообщений
- Личные данные
- Разрешить запись паролей в журнал.
- Получить новые сообщения
- кому:%s
- Тема
- Сообщение
- подпись
- ------ Исходное сообщение ------
- Тема:
- Отправлено:
- От:
- Кому:
- Копия:
- %s пишет:
- %1$s, %2$s пишет:
- Укажите по крайней мере одного адресата.
- Поле адресата заполнено неполностью!
- Контакт не содержит сведений о email адресе.
- Некоторые вложения не были загружены и не могут быть отправлены.
- Сообщение не может быть переслано, так как не загружены вложения.
- Включить цитируемое сообщение
- Удалить цитату
- Правка цитаты
- Удалить вложение
- от: %s <%s>
- кому:
- копия:
- Скрытая:
- Открыть
- Сохранить
- Не получается сохранить вложение.
- Изображения
- Отсутствует просмотрщик%s.
- Загрузить полностью
- Невозможно отобразить сообщение
- от %1$s
-
- Все заголовки были загружены, но нет дополнительных заголовков для показа.
- Сбой получения дополнительных заголовков из базы данных или почтового сервера.
- Вся переписка
- От %s
- Отладка / Очистка тела сообщения
- Сообщение отменено
- Черновик сохранён
- Показать важное
- Для управления важностью сообщений
- Строки предпросмотра
- Имя вместо адреса
- Показать имя отправителя вместо его адреса
- Отправитель над темой
- Показать имя отправителя над темой сообщения
- Имя из контактов
- Подбор имён отправителей из контактов
- Цвет
- Выделять цветом имена из контактов
- Моноширинный шрифт
- Показать сообщения в формате \"Только текст\" моноширинным шрифтом
- Вписать по ширине
- Подогнать текст сообщения по ширине экрана
- В список после удаления
- Перейти в список сообщений после удаления сообщения
- В следующее после удаления
- Открыть следующее сообщение после удаления сообщения
- Подтверждать действия
- Запросить подтверждение действий
- Удалить
- Удалить важное (в просмотре)
- Переместить в спам
- Отменить сообщение
- Прочитаны все
- Удалить (в уведомлении)
- Скрыть почтовый клиент
- Удалить Почтового User-Agent\'а из почтовых заголовков
- Скрыть временную зону
- Использовать UTC вместо местного времени в заголовках сообщений
- Скрыть тему в уведомлении
- Никогда
- При блокировке
- Всегда
- Кнопка \"Удалить\"
- Никогда
- Для одиночного
- Всегда
- Встроить в экран блокировки
- Убрать с экрана блокировки
- Имя приложения
- Счётчик непрочитанных
- Счётчик сообщений и отправители
- Как без блокировки
- Период тишины
- Отключить мелодию, вибрацию и индикатор на ночь
- Отключить уведомления
- Полностью, в период тишины
- Начало
- Конец
- Новый ящик
- адрес email
- Пароль
- Показать пароль
- Вручную
-
- Получение сведений\u2026
- Проверка сервера входящей почты\u2026
- Проверка сервера исходящей почты\u2026
- Аутентификация\u2026
- Получение настроек\u2026
- Отмена\u2026
- Всё почти готово!
- Имя ящика (опция):
- Ваше имя (видно адресату):
- Тип ящика
- Какой это тип учётной записи\?
- POP3
- IMAP
- Обычный пароль
- Небезопасный пароль
- Безопасный пароль
- Сертификат клиента
- Сервер входящей почты
- Логин
- Пароль
- Сертификат клиента
- Сервер POP3
- Сервер IMAP
- Сервер Exchange
- Порт
- Безопасность
- Аутентификация
- Нет
- SSL/TLS
- STARTTLS
- \"%1$s = %2$s\" недействителен для \"%3$s = %4$s\"
- Удалённое, на сервере
- Оставить
- Удалить
- Прочитано
- Сжатие в сетях:
- Мобильные
- Wi-Fi
- Прочие
- Карта памяти
- Внутренняя память
- Стирать удалённые с сервера
- Немедленно
- При проверке
- Вручную
- Автообласть имён IMAP
- Префикс пути IMAP
- Папка черновиков
- Папка отправленных
- Папка удалённых
- Папка архивных
- Папка спама
- Только подписанные папки
- Автопереход в папку
- Путь OWA
- опция
- Путь аутентификации
- опция
- Псевдоним ящика
- опция
- Сервер исходящей почты
- Сервер SMTP
- Порт
- Безопасность
- Требуется авторизация.
- Логин
- Пароль
- Аутентификация
- \"%1$s = %2$s\" недействителен для \"%3$s = %4$s\"
- Неверная настройка: %s
- Настройки ящика
- Сжать ящик
- Интервал проверки
- Вручную
- 15 минут
- 30 минут
- 1 час
- 2 часа
- 3 часа
- 6 часов
- 12 часов
- 1 сутки
- Push-уведомления
- Мгновенное извещение о новых сообщениях, при поддержке сервером. Этот параметр может значительно улучшить или ухудшить производительность.
- Интервал обновления IDLE
- 2 минуты
- 3 минуты
- 6 минут
- 12 минут
- 24 минуты
- 36 минут
- 48 минут
- 1 час
- Уведомлять о новой почте
- Уведомлять о проверке почты
- Загружать сообщений
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- 2500 сообщений
- 5000 сообщений
- 10000 сообщений
- Все
- Нельзя скопировать или переместить сообщение, не синхронизированное с сервером
- Настройка не завершена
- Неверные логин или пароль.\n(%s)
- Сервер предоставляет неверный сертификат SSL. Иногда это обусловлено неправильной настройкой. Или кто-то пытается атаковать Ваш почтовый сервер или Ваш компьютер. Если Вы не уверены в причинах, нажмите Отклонить и свяжитесь с персоналом, обслуживающим почтовый сервер.\n\n(%s)
- Не удаётся подключиться к серверу.\n(%s)
- Правка
- Продолжить
- Дополнительно
- Настройки ящика
- Ящик по умолчанию
- По умолчанию отправлять почту с этого ящика
- Уведомить о почте
- Уведомления папок
- Все
- 1 класс
- 1 и 2 классы
- Кроме 2 класса
- Нет
- Уведомить о проверке
- Ваш адрес email
- Показать уведомление о новой почте
- Показать уведомление о проверке почты
- Также об исходящей
- Показать уведомление при отправке почты
- Для контактов
- Уведомлять только о сообщениях от контактов
- Открытое прочитано
- Отметить сообщение прочитанным после просмотра
- Отметить как прочитанное при удалении
- Отметить как прочитанное при удалении
- Настройки уведомлений
- Открыть настройки уведомлений
- Показать изображения
- Никогда
- От контактов
- Всегда
- Отправка
- Цитировать при ответе
- Включать исходное сообщение в ответ.
- Цитата над ответом
- Разместить исходное сообщение над текстом ответа.
- Без подписей в цитате
- Удалять подписи из цитируемого текста
- Формат сообщений
- Только текст
- HTML
- Автоматически
- Включать Копия/Скрытая
- Уведомление о прочтении
- Всегда запрашивать уведомление о прочтении
- Стиль цитирования
- Префикс (Gmail)
- Заголовок (Outlook)
- Выгрузить отправленные
- Помещать сообщения в папку \"Отправленные\" после отправки
- Основные
- Чтение
- Получение
- Папки
- Префикс цитаты
- Сквозное шифрование
- Поддержка OpenPGP
- Приложение OpenPGP
- Настройка ключа шифрования
- OpenPGP не настроен
- соединено с %s
- Конфигурируется…
- Хранить черновики зашифрованными
- Все черновики будут зашифрованы
- Зашифровать черновики, если включено шифрование
- Интервал проверки
- Цвет
- Метка в списке ящиков и папок
- Без цвета
- Цвет LED-индикатора
- Цвет LED-индикатора для оповещений этого ящика
- Отображать сообщений
- Загружать фрагмент
- 1 КиБ
- 2 КиБ
- 4 КиБ
- 8 КиБ
- 16 КиБ
- 32 КиБ
- 64 КиБ
- 128 КиБ
- 256 КиБ
- 512 КиБ
- 1 МиБ
- 2 МиБ
- 5 МиБ
- 10 МиБ
- Полностью
- Глубина синхронизации
- Всё время
- Сегодня
- 2 дня
- 3 дня
- 1 неделя
- 2 недели
- 3 недели
- 1 месяц
- 2 месяца
- 3 месяца
- 6 месяцев
- 1 год
- Видимость папок
- Все
- 1 класс
- 1 и 2 классы
- Кроме 2 класса
- Проверка папок
- Все
- 1 класс
- 1 и 2 классы
- Кроме 2 класса
- Нет
- Push
- Все
- 1 класс
- 1 и 2 классы
- Кроме 2 класса
- Нет
- Приёмник копирования
- Все
- 1 класс
- 1 и 2 классы
- Кроме 2 класса
- Синхронное удаление
- Удалять сообщения при удалении на сервере
- Отсутствует OpenPGP-приложение – было удалено?
- Настройки папки
- Начало списка
- Отображать ближе к началу списка папок
- Видимость
- Нет класса
- 1 класс
- 2 класс
- Проверка папок
- Нет
- 1 класс
- 2 класс
- Как видимости
- Push
- Нет класса
- 1 класс
- 2 класс
- Уведомление
- Нет класса
- 1 класс
- 2 класс
- Как push
- Стереть локальные
- Сервер входящих
- Настройки сервера входящей почты
- Сервер исходящих
- Настройки сервера исходящей почты
- Имя ящика
- Ваше имя
- Уведомления
- Вибрация
- Вибрация при новой почте
- Ритм
- Обычный
- Ритм 1
- Ритм 2
- Ритм 3
- Ритм 4
- Ритм 5
- Повтор
- Мелодия
- Мигать LED-индикатором
- Мигать LED-индикатором при новой почте
- Новое сообщение
- Новое сообщение
- Отправитель, скрытая копия и подпись по умолчанию
- Управление ролями
- Альтернативные значения отправителя и подписи
- Управление ролями
- Управление
- Правка роли
- Сохранить
- Новая роль
- Скрытая копия всех сообщений
- Правка
- Выше
- Ниже
- Вверх
- Удалить
- Название роли
- опция
- Ваше имя
- опция
- Адрес email
- обязательно
- Адрес для ответа
- опция
- Подпись
- опция
- Использовать подпись
- Подпись
- Основная роль
- Выберите роль
- Отправитель
- Нельзя удалить основную роль
- Нельзя создать роль без адреса email
- Старые – новые
- Новые – старые
- Тема А – Я
- Тема Я – А
- Отправитель А – Я
- Отправитель Я – А
- Важные – обычные
- Обычные – важные
- Не прочитано – прочитано
- Прочитано – не прочитано
- С вложениями – без вложений
- Без вложений – с вложениями
- Сортировка…
- Дата
- Получено
- Тема
- Отправитель
- Важность
- Прочитано
- Вложение
- Удаление ящика
- Неверный сертификат сервера
- Принять
- Отклонить
- Del (или D) – удалить\nR – ответить\nA – ответить всем\nC – создать\nF – переслать\nM – переместить\nV – в архив\nY – копировать\nZ – (не) прочитано\nG – важное\nO – сортировка\nI – порядок\nQ – папки\nS – выбрать\nJ или P – назад\nK или N – далее
- Del (или D) – удалить\nC – создать\nM – переместить\nV – в архив\nY – копировать\nZ – (не) прочитано\nG – важное\nO – сортировка\nI – порядок\nQ – папки\nS – выбрать
- Поиск папки
- Видимость папок…
- Все папки
- 1 класс
- 1 и 2 класс
- Кроме 2 класса
- Размещение подписи
- перед цитатой
- после цитаты
- Как в приложении
- Тёмная
- Светлая
- Использовать умолчания системы
- Вид
- Общие
- Отладка
- Личное
- Сеть
- Интерфейс
- Список ящиков
- Список сообщений
- Сообщения
- Тема приложения
- Тема просмотра
- Тема редактора
- Язык
- Настройки не найдены
- Фиксированный просмотр
- Разрешить выбор темы при чтении сообщения
- Отключить выбор темы при чтении сообщения
- По умолчанию
- Фоновая синхронизация
- Никогда
- Всегда
- Если вкл. Автосинхронизация
- Выбрать все
- Лимит push-проверки
- 5 папок
- 10 папок
- 25 папок
- 50 папок
- 100 папок
- 250 папок
- 500 папок
- 1000 папок
- Анимация
- Анимация интерфейса
- Прокрутка кнопками Vol+/-
- В сообщении
- В списке
- Показывать общий ящик для входящих
- %s%s
- – не прочитано
- Вся почта
- в видимых папках
- Входящие
- из всех ящиков
- Общие \"Входящие\"
- Показать почту в общих \"Входящих\"
- Папки для поиска
- Все
- Видимые
- Нет
- Нет
- Автоматически (%s)
- Шрифт
- Настройка размера шрифтов
- Список ящиков
- Имя ящика
- Описание ящика
- Список папок
- Имя папки
- Состояние папки
- Список сообщений
- Тема
- Отправитель
- Дата
- Просмотр
- Сообщение
- Отправитель
- Кому
- Копия
- Скрытая
- Все заголовки
- Тема
- Дата и время
- Тело сообщения
- %d%%
- %1$s: %2$s
- Редактор сообщения
- Формы ввода
- По умолчанию
- Крохотный
- Маленький
- Небольшой
- Средний
- Большой
- Огромный
- Гигантский
- Подходящее приложение не найдено.
- Сбой отправки: %s
- Сохранить черновик сообщения\?
- Сохранить черновик или отменить сообщение?
- Сохранить или отменить изменения?
- Отбросить сообщение\?
- Отменить сообщение?
- Выберите текст для копирования.
- Стереть локальные сообщения?
- Это удалит все локальные сообщения из папки.Сообщения не будут удалены с сервера.
- Стереть сообщения
- Удаление
- Удалить сообщение?
-
- Вы действительно хотите удалить это сообщение\?
- Вы действительно хотите удалить эти %1$d сообщения\?
- Вы действительно хотите удалить эти %1$d сообщений\?
- Вы действительно хотите удалить эти %1$d сообщений\?
-
- ОК
- Отмена
- Подтверждение прочтения
- Отметить все сообщения прочитанными?
- Подтвердите очистку корзины
- Очистить корзину?
- Да
- Нет
- Переместить в спам
-
- Вы действительно хотите переместить сообщение в Спам\?
- Вы действительно хотите переместить %1$d сообщения в Спам\?
- Вы действительно хотите переместить %1$d сообщений в Спам\?
- Вы действительно хотите переместить %1$d сообщений в Спам\?
-
- ОК
- Отмена
- Загрузка вложения
- »
- ›
- Резервная копия
- Разное
- Экспортировать настройки
- Экспорт
- Передать
- Экспорт настроек…
- Настройки успешно экспортированы
- Сбой экспорта настроек
- Импорт
- Выберите файл
- Импорт
- Настройки успешно импортированы
- Пожалуйста, введите пароли
- Не удалось импортировать настройки
- Не удалось прочесть файл настроек
- Не удалось импортировать некоторые настройки
- Успешный импорт
- Требуется пароль
- Не импортировано
- Импорт не удался
- Позже
- Импорт
- Импорт настроек…
-
- Чтобы использовать ящик \"%s\" необходимо ввести пароль.
- Чтобы использовать ящик \"%s\" необходимо ввести пароли.
- Чтобы использовать ящик \"%s\" необходимо ввести пароли.
- Чтобы использовать ящик \"%s\" необходимо ввести пароли.
-
- Входящий пароль сервера
- Исходящий пароль сервера
- Использовать тот же пароль для исходящего сервера
- Названия серверов: %s
- Счётчик непрочитанных…
- Ящик
- Ящик для отображения счётчика непрочитанных
- Общие \"Входящие\"
- Счётчик папок
- Показывать счётчик непрочитанных только для одной папки
- Папка
- Папка для отображения счётчика непрочитанных
- Готово
- %1$s – %2$s
- Ящик не выбран
- Папка не выбрана
- Текст отсутствует
- Открыть
- Отправить
- В буфер
- Ссылка
- Копировать текст ссылки в буфер обмена
- Текст ссылки
- Изображение
- Открыть
- Сохранить
- Загрузить
- URL в буфер
- URL изображения
- Вызвать
- В контакты
- В буфер
- Номер
- Написать
- В контакты
- В буфер
- Адрес email
- Все
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- Лимит поиска на сервере
- Отправка запроса на сервер
-
- Получение %d результата
- Получение %d результатов
- Получение %d результатов
- Получение %d результатов
-
-
- Получение %1$d из %2$d результатов
- Получение %1$d из %2$d результатов
- Получение %1$d из %2$d результатов
- Получение %1$d из %2$d результатов
-
- Сбой поиска на сервере
- Поиск
- Поиск на сервере
- Искать сообщения локально и на сервере
- Поиск на сервере
- Для поиска на сервере необходимо подключение к сети.
- Менять цвет при прочтении
- Другой фон для прочитанных сообщений
- Цепочки сообщений
- Объединить сообщения, показав счётчик
- Обновление данных
- Обновление данных…
- Обновление ящика \"%s\"
- Разделить экран
- Всегда
- Нет
- Ландшафт
- Выберите сообщение
- Фото контактов
- Показать фото контактов в списке сообщений
- Прочитаны все
- Цветные места для фото
- Инициалы контактов на цветном фоне при отсутствии фото
- Действия для сообщения
- Видимость действий для открытого сообщения
- Загрузка вложений…
- Отправка сообщения
- Сохранение черновика
- Получение вложений…
- Аутентификация не удалась. Сервер не сообщает о совместимости с SASL EXTERNAL. Причиной может служить неверный сертификат клиента (просрочен, неизвестен издатель) или проблемы с настройками.
-
- Использовать сертификат клиента
- Не использовать сертификат клиента
- Отключить выбор сертификата клиента
- Не найден сертификат клиента для алиаса \"%s\"
- Дополнительно
- Срок действия сертификата клиента \"%1$s\" истёк или ещё не наступил (%2$s)
-
- *Зашифровано*
- Добавить из Контактов
- Копия
- Скрытая
- Кому
- От
- Неизвестный получатель
- Неизвестный отправитель
- Дом
- Работа
- Прочее
- Мобильный
- Для данного ящика не настроена папка Черновики!
- Для данного ящика не настроены ключи! Проверьте настройки.
- Криптопровайдер использует несовместимую версию. Проверьте настройки!
- Нет доступа к криптопровайдеру. Проверьте настройки или нажмите значок шифрования для повтора!
- Ошибка инициализации сквозного шифрования. Проверьте настройки
- Режим PGP/INLINE не поддерживает вложения!
- Включить PGP/INLINE
- Отключить PGP/INLINE
- Включить PGP \"Только подпись\"
- Отключить PGP \"Только подпись\"
- Режим PGP/INLINE
- Сообщение отправлено в формате PGP/INLINE.
-\nИспользуйте только для совместимости:
- Некоторые клиенты поддерживают только этот формат
- Подписи могут повредиться при передаче
- Вложения не поддерживаются
- Понятно!
- Отключить
- Не отключать
- Понятно!
- Отключить
- Не отключать
- Режим PGP \"Только подпись\"
- В этом режиме, ключ PGP будет использоваться для создания криптографической подписи к незашифрованному сообщению.
- Адресат сможет убедиться, что сообщение подлинное и подписано Вашим ключом.
- Подписи могут повредиться при отправке нескольким адресатам.
- Подписи могут отображаться как вложенные файлы \'signature.asc\' для некоторых клиентов.
- Всегда добавлять подпись к шифрованным сообщениям.
- Текст
- неверная подпись сквозного шифрования
- требуется полная загрузка сообщения для проверки подписи
- содержит неподдерживаемую подпись сквозного шифрования
- Сообщение зашифровано в неподдерживаемом формате.
- Сообщение зашифровано, дешифрование отменено.
- текст, подписанный ключом сквозного шифрования
- от проверенного подписанта
- Подписанный текст
- но ключ сквозного шифрования не соответствует отправителю
- но ключ сквозного шифрования просрочен
- но ключ сквозного шифрования отозван
- но ключ сквозного шифрования небезопасен
- но ключ сквозного шифрования неизвестен
- Зашифровано
- но был сбой дешифрования
- требуется полная загрузка сообщения для дешифрования
- но отсутствует настроенное криптоприложение
- Зашифровано
- но без сквозного шифрования
- со сквозным шифрованием
- от проверенного отправителя
- Зашифровано
- но ключ сквозного шифрования неизвестен
- но ключ сквозного шифрования не соответствует отправителю
- но ключ сквозного шифрования просрочен
- но ключ сквозного шифрования отозван
- но ключ сквозного шифрования небезопасен
- но произошёл сбой в данных сквозного шифрования
- но шифрование не считается безопасным
- OK
- Поиск криптоключа
- Кем подписано
- Кем отправлено
- Подробности
- Разблокировать
- Эта часть не была зашифрована и небезопасна.
- Незащищённое вложение
- Загрузка…
- Дешифрование отменено.
- Повтор
- Зашифрованное сообщение необходимо загрузить для дешифрования.
- Сбой дешифрования почты
- Спецсимволы пока не поддерживаются!
- Сбой разбора адреса!
- Скрыть подписи без шифрования
- Отображаются зашифрованные подписи
- Отображаются все подписи
- Шифрование недоступно в режиме \"Только подпись\"!
- Неподписанный текст
- Прекращение поддержки APG
- Разработка APG прекращена!
- В связи с этим, поддержка APG удалена из приложения Почты.
- Разработка прекращена в начале 2014 года
- Имеются неисправленные уязвимости
- Нажмите здесь для подробностей.
- Понятно!
- APG
- Сообщение зашифровано
- Сообщение зашифровано OpenPGP.
-\nЧтобы прочесть его, необходимо установить и настроить подходящее OpenPGP-приложение.
- В Настройки
- Mail Message List
- Загрузка сообщений…
- Сбой при получении списка папок
- Сбой получения статуса адресата у провайдера OpenPGP!
- Шифрование невозможно
- Не все выбранные адресаты поддерживают эту возможность!
- Включить шифрование
- Отключить шифрование
- Шифрование сообщений гарантирует, что никто, кроме получателя, не сможет их прочесть.
- Шифрование отображается, если поддерживается всеми адресатами и они писали Вам ранее.
- Включите шифрование, нажав этот значок.
- Понятно
- Назад
- Отключить шифрование
- Шифрование OpenPGP
- Взаимное автошифрование
- Взаимное автошифрование
- Сообщения шифруются по желанию или при ответе на шифрованное сообщение.
- Если отправитель и получатели включили режим взаимного автошифрования, включать шифрование по умолчанию.
- Нажмите здесь для подробностей.
- Основные
- OpenPGP не установлен
- Установить
- Почта требует OpenKeychain для end-to-end шифрования.
- Зашифрованное сообщение
- Шифровать темы сообщений
- Может поддерживаться не всеми адресатами
- Внутренний сбой: неверный ящик!
- Сбой подключения к %s!
- Отправка настроек автошифрования
- Передать настройки шифрования на другие устройства
- Настройки автошифрования
- Сообщение с настройками взаимного автошифрования позволяет безопасно передать эти настройки на другие устройства.
- Отправить настройки
- Сообщение будет отправлено на ваш адрес:
- Создание сообщения с настройками…
- Отправка сообщения для:
- Для завершения, откройте сообщение на новом устройстве и введите код установки.
- Показать код установки
- Настройки взаимного автошифрования
- Это сообщение содержит все сведения, необходимые для переноса настроек взаимного автошифрования вместе с секретным ключом с исходного устройства.
+ Добро пожаловать!
+
+K-9 Mail — почтовый клиент для Android.
+
+Возможности:
+
+
+
push-уведомления,
+
быстрая работа,
+
перемещение сообщений,
+
несколько подписей,
+
скрытая копия себе,
+
подписка на папки,
+
синхронизация всех папок,
+
адрес для ответа,
+
горячие клавиши,
+
улучшенная поддержка IMAP,
+
сохранение вложений,
+
очистка корзины,
+
сортировка сообщений,
+
…и многое другое!
+
+
+Отметим, что K-9 Mail не полностью совместим с MS Exchange и не поддерживает бесплатные ящики Hotmail.
+
+ ]]>
+
+ -- \nПростите за краткость, создано в K-9 Mail.
+
+ Ящик \"%s\" будет удалён из приложения K-9 Mail.
+
+ Авторы
+ Ревизия
+ Чтение почты
+ Разрешить программе чтение почты.
+ Удаление почты
+ Разрешить программе удаление почты.
+ О почте K-9
+ Ящики
+ Папки
+ Дополнительно
+ Новое
+ Ответ
+ Ответить всем
+ Пересылка
+ Переслать вложением
+ Выберите ящик
+ Выбор папки
+ Переместить в…
+ Копировать в…
+ Проверка %s:%s%s
+ Просмотр %s:%s%s
+ Отправка %s%s
+ Обработка %s:%s%s
+ \u0020%d/%d
+ Синхронизация откл.
+ %d выбрано
+ Далее
+ Назад
+
+ ОК
+ Отмена
+ Отправить
+ Отправить снова
+ Тема не заполнена, нажмите ещё раз для отправки без темы
+ Выбрать
+ Снять выбор
+ Ответить
+ Ответить всем
+ Удалить
+ В архив
+ В спам
+ Переслать
+ Переслать вложением
+ Редактировать как новое сообщение
+ Переместить
+ Переместить в черновики
+ Отправить...
+ Смена папки...
+ Готово
+ Отменить
+ Сохранить как черновик
+ Проверить почту
+ Проверить почту во всех ящиках
+ Отправить почту
+ Обновить список папок
+ Поиск папки
+ Добавить
+ Создать
+ Поиск сообщения
+ Искать везде
+ Результаты поиска
+ Настройки
+ Выбрать папки
+ Настройки ящика
+ Удалить ящик
+ Прочитано
+ Передать
+ Выбрать отправителя
+ Важное
+ Обычное
+ Копировать
+ Все заголовки
+
+ Адрес скопирован в буфер
+ Адреса скопированы в буфер
+ Адреса скопированы в буфер
+ Адреса скопированы в буфер
+
+ Текст темы скопирован в буфер обмена
+ Тёмная тема
+ Светлая тема
+ Не прочитано
+ Уведомление
+ Запросить уведомление о прочтении
+ Без уведомления о прочтении
+ Добавить вложение
+ Очистить корзину
+ Стереть
+ О программе
+ Настройки
+
+ (Без темы)
+ Нет отправителя
+ Загрузка сообщений\u2026
+ Сбой подключения
+ Сообщение не найдено
+ Сбой загрузки сообщения
+ Получить до %d следующих
+ %.1f ГБ
+ %.1f МБ
+ %.1f кБ
+ %d Б
+ Ящик \"%s\" изменился с %s до %s
+ Сжатие ящика \"%s\"
+ Новая почта
+
+ %d новое сообщение
+ %d новых сообщения
+ %d новых сообщений
+ %d новых сообщений
+
+ %d новых (%s)
+ + ещё %1$d в %2$s
+ Ответить
+ Прочитано
+ Прочитаны все
+ Удалить
+ Удалить все
+ Архив
+ В архив все
+ Спам
+ Сбой сертификата %s
+ Проверьте настройки сервера
+ Сбой аутентификации
+ Сбой аутентификации для %s. Измените настройки сервера
+ Проверка %s:%s
+ Проверка почты
+ Отправка %s
+ Отправка почты
+ :
+ Синхронизация (Push)
+ Отображается во время ожидания новых сообщений
+ Сообщение
+ Уведомления о сообщениях
+ Разное
+ Прочие уведомления
+ Входящие
+ Исходящие
+ Черновики
+ Корзина
+ Отправленные
+ Сбой отправки почты
+ Версия
+ Журнал отладки
+ Запись диагностических сообщений
+ Личные данные
+ Разрешить запись паролей в журнал
+ Получить новые сообщения
+ Кому:%s
+ Тема
+ Сообщение
+ Подпись
+ ------ Исходное сообщение ------
+ Тема:
+ Отправлено:
+ От:
+ Кому:
+ Копия:
+ %s пишет:
+ %1$s, %2$s пишет:
+ Вы должны добавить хотя бы одного адресата.
+ Поле адресата заполнено неполностью!
+ Контакт не содержит сведений о email.
+ Некоторые вложения не были загружены и не могут быть отправлены.
+ Сообщение не может быть переслано, так как не загружены вложения.
+ Включить цитируемое сообщение
+ Удалить цитату
+ Правка цитаты
+ Удалить вложение
+ От: %s <%s>
+ Кому:
+ Копия:
+ Скрытая:
+ Открыть
+ Сохранить
+ Не получается сохранить вложение.
+ Изображения
+ Отсутствует просмотрщик %s.
+ Загрузить полностью
+ Невозможно отобразить сообщение
+ от %1$s
+
+ Все дополнительные заголовки уже загружены.
+ Сбой загрузки дополнительных заголовков.
+ Вся переписка
+ От %s
+ Отладка / Очистка тела сообщения
+ Сообщение отменено
+ Черновик сохранён
+ Показать важное
+ Для управления важностью сообщений
+ Строки предпросмотра
+ Имя вместо адреса
+ Показать имя отправителя вместо его адреса
+ Отправитель над темой
+ Показать имя отправителя над темой сообщения
+ Имя из контактов
+ Подбор имён отправителей из контактов
+ Цвет
+ Выделять цветом имена из контактов
+ Моноширинный шрифт
+ Показать сообщения в формате \"Только текст\" моноширинным шрифтом
+ Вписать по ширине
+ Подогнать текст сообщения по ширине экрана
+ В список после удаления
+ Перейти в список сообщений после удаления сообщения
+ В следующее после удаления
+ Открыть следующее сообщение после удаления сообщения
+ Подтверждать действия
+ Запросить подтверждение действий
+ Удалить
+ Удалить важное (в просмотре)
+ Переместить в спам
+ Отменить сообщение
+ Прочитаны все
+ Удалить (в уведомлении)
+ Скрыть почтовый клиент
+ Убрать K-9 User-Agent из заголовков сообщений
+ Скрыть временную зону
+ Использовать UTC вместо местного времени в заголовках сообщений
+ Кнопка \"Удалить\"
+ Никогда
+ Для одиночного
+ Всегда
+ Встроить в экран блокировки
+ Убрать с экрана блокировки
+ Имя приложения
+ Счётчик сообщений и отправители
+ Как без блокировки
+ Период тишины
+ Отключить мелодию, вибрацию и индикатор на ночь
+ Отключить уведомления
+ Полностью, в период тишины
+ Начало
+ Конец
+ Новый ящик
+ Адрес email
+ Пароль
+ Показать пароль
+
+ Чтобы увидеть свой пароль, включите блокировку экрана на этом устройстве.
+ Вручную
+
+ Получение сведений\u2026
+ Проверка сервера входящей почты\u2026
+ Проверка сервера исходящей почты\u2026
+ Аутентификация\u2026
+ Получение настроек\u2026
+ Отмена\u2026
+ Всё почти готово!
+ Имя ящика (необязательно):
+ Ваше имя (видно адресату в сообщениях):
+ Тип ящика
+ Доступные протоколы
+ POP3
+ IMAP
+ Обычный пароль
+ Небезопасный пароль
+ Безопасный пароль
+ Сертификат клиента
+ Сервер входящей почты
+ Логин
+ Пароль
+ Сертификат клиента
+ Сервер POP3
+ Сервер IMAP
+ Сервер Exchange
+ Порт
+ Безопасность
+ Аутентификация
+ Нет
+ SSL/TLS
+ STARTTLS
+ \"%1$s = %2$s\" недействителен для \"%3$s = %4$s\"
+ Удалённое, на сервере
+ Оставить
+ Удалить
+ Прочитано
+ Сжатие в сетях:
+ Мобильные
+ Wi-Fi
+ Прочие
+ Стирать удалённые с сервера
+ Немедленно
+ При проверке
+ Вручную
+ Автообласть имён IMAP
+ Префикс пути IMAP
+ Папка черновиков
+ Папка отправленных
+ Папка удалённых
+ Папка архивных
+ Папка спама
+ Только подписанные папки
+ Автопереход в папку
+ Путь OWA
+ опция
+ Путь аутентификации
+ опция
+ Псевдоним ящика
+ опция
+ Сервер исходящей почты
+ Сервер SMTP
+ Порт
+ Безопасность
+ Авторизация
+ Логин
+ Пароль
+ Аутентификация
+ \"%1$s = %2$s\" недействителен для \"%3$s = %4$s\"
+ Неверная настройка: %s
+ Настройки ящика
+ Сжать ящик
+ Интервал проверки
+ Вручную
+ 15 минут
+ 30 минут
+ 1 час
+ 2 часа
+ 3 часа
+ 6 часов
+ 12 часов
+ 1 сутки
+ Push-уведомления
+ Мгновенное извещение о новых сообщениях, при поддержке сервером
+ Интервал обновления IDLE
+ 2 минуты
+ 3 минуты
+ 6 минут
+ 12 минут
+ 24 минуты
+ 36 минут
+ 48 минут
+ 1 час
+ Уведомлять о новой почте
+ Уведомлять о проверке почты
+ Загружать сообщений
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ 2500 сообщений
+ 5000 сообщений
+ 10000 сообщений
+ Все
+ Нельзя скопировать или переместить сообщение, не синхронизированное с сервером
+ Настройка не завершена
+ Неверные логин или пароль.\n(%s)
+ Сервер предоставляет неверный сертификат SSL. Иногда это обусловлено неправильной настройкой. Или кто-то пытается атаковать Ваш почтовый сервер или Ваш компьютер. Если Вы не уверены в причинах, нажмите Отклонить и свяжитесь с персоналом, обслуживающим почтовый сервер.\n\n(%s)
+ Не удаётся подключиться к серверу.\n(%s)
+ Правка
+ Продолжить
+ Дополнительно
+ Настройки ящика
+ Уведомить о почте
+ Уведомления папок
+ Все
+ 1 класс
+ 1 и 2 классы
+ Кроме 2 класса
+ Нет
+ Уведомить о проверке
+ Ваш адрес email
+ Показать уведомление о новой почте
+ Показать уведомление о проверке почты
+ Также об исходящей
+ Показать уведомление при отправке почты
+ Для контактов
+ Уведомлять только о сообщениях от контактов
+ Открытое прочитано
+ Отметить сообщение прочитанным после просмотра
+ Отметить как прочитанное при удалении
+ Отметить как прочитанное при удалении
+ Категории уведомлений
+ Настройка уведомлений о новых сообщениях
+ Настройка уведомлений об ошибках и статусе
+ Показать изображения
+ Никогда
+ От контактов
+ Всегда
+ Отправка
+ Цитировать при ответе
+ Включать исходное сообщение в ответ
+ Цитата над ответом
+ Разместить исходное сообщение над текстом ответа
+ Без подписей в цитате
+ Удалять подписи из цитируемого текста
+ Формат сообщений
+ Только текст
+ HTML
+ Автоматически
+ Включать Копия/Скрытая
+ Уведомление о прочтении
+ Всегда запрашивать уведомление о прочтении
+ Стиль цитирования
+ Префикс (Gmail)
+ Заголовок (Outlook)
+ Выгрузить отправленные
+ Помещать сообщения в папку \"Отправленные\" после отправки
+ Основные
+ Чтение
+ Получение
+ Папки
+ Префикс цитаты
+ Сквозное шифрование
+ Поддержка OpenPGP
+ Приложение OpenPGP
+ Настройка ключа шифрования
+ OpenPGP не настроен
+ Соединено с %s
+ Конфигурируется...
+ Хранить черновики зашифрованными
+ Все черновики будут зашифрованы
+ Зашифровать черновики, если включено шифрование
+ Интервал проверки
+ Цвет
+ Метка в списке ящиков и папок
+ Без цвета
+ Цвет LED-индикатора
+ Цвет LED-индикатора для оповещений этого ящика
+ Отображать сообщений
+ Загружать фрагмент
+ 1 КиБ
+ 2 КиБ
+ 4 КиБ
+ 8 КиБ
+ 16 КиБ
+ 32 КиБ
+ 64 КиБ
+ 128 КиБ
+ 256 КиБ
+ 512 КиБ
+ 1 МиБ
+ 2 МиБ
+ 5 МиБ
+ 10 МиБ
+ Полностью
+ Глубина синхронизации
+ Всё время
+ Сегодня
+ 2 дня
+ 3 дня
+ 1 неделя
+ 2 недели
+ 3 недели
+ 1 месяц
+ 2 месяца
+ 3 месяца
+ 6 месяцев
+ 1 год
+ Видимость папок
+ Все
+ 1-й класс
+ 1-й и 2-й классы
+ Кроме 2-го класса
+ Проверка папок
+ Все
+ 1-й класс
+ 1-й и 2-й классы
+ Кроме 2-го класса
+ Нет
+ Push
+ Все
+ 1-й класс
+ 1-й и 2-й классы
+ Кроме 2-го класса
+ Нет
+ Приёмник копирования
+ Все
+ 1-й класс
+ 1-й и 2-й классы
+ Кроме 2-го класса
+ Синхронное удаление
+ Удалять сообщения при удалении на сервере
+ Отсутствует OpenPGP-приложение – было удалено?
+ Настройки папки
+ Начало списка
+ Отображать ближе к началу списка папок
+ Видимость
+ Нет класса
+ 1-й класс
+ 2-й класс
+ Проверка папок
+ Нет
+ 1-й класс
+ 2-й класс
+ Как видимости
+ Push
+ Нет класса
+ 1-й класс
+ 2-й класс
+ То же, что и класс опроса
+ Уведомление
+ Нет класса
+ 1-й класс
+ 2-й класс
+ Как push
+ Стереть локальные
+ Сервер входящих
+ Настройки сервера входящей почты
+ Сервер исходящих
+ Настройки сервера исходящей почты
+ Имя ящика
+ Ваше имя
+ Уведомления
+ Вибрация
+ Вибрация при новой почте
+ Ритм
+ Обычный
+ Ритм 1
+ Ритм 2
+ Ритм 3
+ Ритм 4
+ Ритм 5
+ Повтор
+ Мелодия
+ Мигать LED-индикатором
+ Мигать LED-индикатором при новой почте
+ Новое сообщение
+ Новое сообщение
+ Отправитель, скрытая копия и подпись по умолчанию
+ Управление ролями
+ Альтернативные значения отправителя и подписи
+ Управление ролями
+ Управление
+ Правка роли
+ Сохранить
+ Новая роль
+ Скрытая копия всех сообщений
+ Правка
+ Выше
+ Ниже
+ Вверх
+ Удалить
+ Название роли
+ опция
+ Ваше имя
+ опция
+ Адрес email
+ обязательно
+ Адрес для ответа
+ опция
+ Подпись
+ опция
+ Использовать подпись
+ Подпись
+ Основная роль
+ Выберите роль
+ Отправитель
+ Нельзя удалить основную роль
+ Нельзя создать роль без адреса email
+ Старые – новые
+ Новые – старые
+ Тема А – Я
+ Тема Я – А
+ Отправитель А – Я
+ Отправитель Я – А
+ Важные – обычные
+ Обычные – важные
+ Не прочитано – прочитано
+ Прочитано – не прочитано
+ С вложениями – без вложений
+ Без вложений – с вложениями
+ Сортировка
+ Дата
+ Получено
+ Тема
+ Отправитель
+ Важность
+ Прочитано
+ Вложение
+ Удаление ящика
+ Неверный сертификат сервера
+ Принять
+ Отклонить
+ Del (или D) – удалить\nR – ответить\nA – ответить всем\nC – создать\nF – переслать\nM – переместить\nV – в архив\nY – копировать\nZ – (не) прочитано\nG – важное\nO – сортировка\nI – порядок\nQ – папки\nS – выбрать\nJ или P – назад\nK или N – далее
+ Del (или D) – удалить\nC – создать\nM – переместить\nV – в архив\nY – копировать\nZ – (не) прочитано\nG – важное\nO – сортировка\nI – порядок\nQ – папки\nS – выбрать
+ Поиск папки
+ Видимость папок
+ Все папки
+ 1-й класс
+ 1-й и 2-й класс
+ Кроме 2-го класса
+ Размещение подписи
+ Перед цитатой
+ После цитаты
+ Как в приложении
+ Тёмная
+ Светлая
+ Использовать умолчания системы
+ Вид
+ Общие
+ Отладка
+ Личное
+ Сеть
+ Интерфейс
+ Список ящиков
+ Список сообщений
+ Сообщения
+ Тема приложения
+ Тема просмотра
+ Тема редактора
+ Язык
+ Настройки не найдены
+ Фиксированный просмотр
+ Разрешить выбор темы при чтении сообщения
+ Отключить выбор темы при чтении сообщения
+ По умолчанию
+ Фоновая синхронизация
+ Никогда
+ Всегда
+ Если вкл. Автосинхронизация
+ Выбрать все
+ Лимит push-проверки
+ 5 папок
+ 10 папок
+ 25 папок
+ 50 папок
+ 100 папок
+ 250 папок
+ 500 папок
+ 1000 папок
+ Анимация
+ Анимация интерфейса
+ Прокрутка кнопками Vol+/-
+ В сообщении
+ В списке
+ Показывать общий ящик для входящих
+ %s%s
+ – не прочитано
+ Вся почта
+ в видимых папках
+ Входящие
+ из всех ящиков
+ Общие \"Входящие\"
+ Показать почту в общих \"Входящих\"
+ Папки для поиска
+ Все
+ Видимые
+ Нет
+ Нет
+ Автоматически (%s)
+ Шрифт
+ Настройка размера шрифтов
+ Список ящиков
+ Имя ящика
+ Описание ящика
+ Список папок
+ Имя папки
+ Состояние папки
+ Список сообщений
+ Тема
+ Отправитель
+ Дата
+ Просмотр
+ Сообщение
+ Отправитель
+ Кому
+ Копия
+ Скрытая
+ Все заголовки
+ Тема
+ Дата и время
+ Тело сообщения
+ %d%%
+ %1$s: %2$s
+ Редактор сообщения
+ Формы ввода
+ По умолчанию
+ Крохотный
+ Маленький
+ Небольшой
+ Средний
+ Большой
+ Огромный
+ Гигантский
+ Подходящее приложение не найдено
+ Сбой отправки: %s
+ Выберите действие
+ Сохранить черновик или отменить сообщение?
+ Сохранить или отменить изменения?
+ Удаление
+ Отменить сообщение?
+ Выберите текст длительным нажатием
+ Стереть локальные сообщения?
+ Это удалит все локальные сообщения из папки.Сообщения не будут удалены с сервера.
+ Стереть сообщения
+ Подтвердите удаление
+ Вы хотите удалить это сообщение?
+
+ Удалить сообщение?
+ Удалить %1$d сообщения?
+ Удалить %1$d сообщений?
+ Вы действительно хотите удалить %1$d сообщений?
+
+ Да
+ Нет
+ Подтверждение прочтения
+ Отметить все сообщения прочитанными?
+ Подтвердите очистку корзины
+ Вы хотите очистить корзину?
+ Да
+ Нет
+ Переместить в спам
+
+ Переместить сообщение в Спам?
+ Переместить %1$d сообщения в Спам?
+ Переместить %1$d сообщений в Спам?
+ Переместить %1$d сообщений в Спам?
+
+ Да
+ Нет
+ Загрузка вложения
+ »
+ ›
+ Резервная копия
+ Разное
+ Экспортировать настройки
+ Экспорт
+ Передать
+ Экспорт настроек…
+ Настройки успешно экспортированы
+ Сбой экспорта настроек
+ Импорт
+ Выберите файл
+ Импорт
+ Настройки успешно импортированы
+ Пожалуйста, введите пароли
+ Не удалось импортировать настройки
+ Не удалось прочесть файл настроек
+ Не удалось импортировать некоторые настройки
+ Успешный импорт
+ Требуется пароль
+ Не импортировано
+ Импорт не удался
+ Позже
+ Импорт
+ Импорт настроек…
+
+ Чтобы использовать ящик \"%s\" необходимо ввести пароль.
+ Чтобы использовать ящик \"%s\" необходимо ввести пароли.
+ Чтобы использовать ящик \"%s\" необходимо ввести пароли.
+ Чтобы использовать ящик \"%s\" необходимо ввести пароли.
+
+ Входящий пароль сервера
+ Исходящий пароль сервера
+ Использовать тот же пароль для исходящего сервера
+ Названия серверов: %s
+ Счётчик непрочитанных
+ Ящик
+ Ящик для отображения счётчика непрочитанных
+ Общие \"Входящие\"
+ Счётчик папок
+ Показывать счётчик непрочитанных только для одной папки
+ Папка
+ Папка для отображения счётчика непрочитанных
+ Готово
+ %1$s – %2$s
+ Ящик не выбран
+ Папка не выбрана
+ Текст отсутствует
+ Открыть
+ Отправить
+ В буфер
+ Ссылка
+ Копировать текст ссылки в буфер обмена
+ Текст ссылки
+ Изображение
+ Открыть
+ Сохранить
+ Загрузить
+ URL в буфер
+ URL изображения
+ Вызвать
+ В контакты
+ В буфер
+ Номер
+ Написать
+ В контакты
+ В буфер
+ Адрес email
+ Все
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Лимит поиска на сервере
+ Отправка запроса на сервер
+
+ Получение %d результата
+ Получение %d результатов
+ Получение %d результатов
+ Получение %d результатов
+
+
+ Получение %1$d из %2$d результатов
+ Получение %1$d из %2$d результатов
+ Получение %1$d из %2$d результатов
+ Получение %1$d из %2$d результатов
+
+ Сбой поиска на сервере
+ Поиск
+ Поиск на сервере
+ Искать сообщения локально и на сервере
+ Поиск на сервере
+ Для поиска на сервере необходимо подключение к сети
+ Менять цвет при прочтении
+ Другой фон для прочитанных сообщений
+ Цепочки сообщений
+ Объединить сообщения, показав счётчик
+ Обновление данных
+ Обновление данных…
+ Обновление ящика \"%s\"
+ Разделить экран
+ Всегда
+ Нет
+ Ландшафт
+ Выберите сообщение
+ Фото контактов
+ Показать фото контактов в списке сообщений
+ Прочитаны все
+ Цветные места для фото
+ Инициалы контактов на цветном фоне при отсутствии фото
+ Действия для сообщения
+ Видимость действий для открытого сообщения
+ Загрузка вложений…
+ Отправка сообщения
+ Сохранение черновика
+ Получение вложений…
+ Аутентификация не удалась. Сервер не сообщает о совместимости с SASL EXTERNAL. Причиной может служить неверный сертификат клиента (просрочен, неизвестен издатель) или проблемы с настройками
+
+ Использовать сертификат клиента
+ Не использовать сертификат клиента
+ Отключить выбор сертификата клиента
+ Не найден сертификат клиента для алиаса \"%s\"
+ Дополнительно
+ Срок действия сертификата клиента \"%1$s\" истёк или ещё не наступил (%2$s)
+
+ *Зашифровано*
+ Добавить из Контактов
+ Копия
+ Скрытая
+ Кому
+ От
+ Ответить на
+ Неизвестный получатель
+ Неизвестный отправитель
+ Дом
+ Работа
+ Прочее
+ Мобильный
+ Для данного ящика не настроена папка Черновики!
+ Для данного ящика не настроены ключи! Проверьте настройки
+ Криптопровайдер использует несовместимую версию. Проверьте настройки!
+ Нет доступа к криптопровайдеру. Проверьте настройки или нажмите значок шифрования для повтора!
+ Ошибка инициализации сквозного шифрования. Проверьте настройки
+ Режим PGP/INLINE не поддерживает вложения!
+ Включить PGP/INLINE
+ Отключить PGP/INLINE
+ Включить PGP \"Только подпись\"
+ Отключить PGP \"Только подпись\"
+ Режим PGP/INLINE
+ Сообщение отправлено в формате PGP/INLINE.\nИспользуйте только для совместимости
+ Некоторые клиенты поддерживают только этот формат
+ Подписи могут повредиться при передаче
+ Вложения не поддерживаются
+ Понятно!
+ Отключить
+ Не отключать
+ Понятно!
+ Отключить
+ Не отключать
+ Режим PGP \"Только подпись\"
+ В этом режиме, ключ PGP будет использоваться для создания криптографической подписи к незашифрованному сообщению
+ Адресат сможет убедиться, что сообщение подлинное и подписано Вашим ключом
+ Подписи могут повредиться при отправке нескольким адресатам
+ Подписи могут отображаться как вложенные файлы \'signature.asc\'
+ Всегда добавлять подпись к шифрованным сообщениям
+ Текст
+ неверная подпись сквозного шифрования
+ требуется полная загрузка сообщения для проверки подписи
+ содержит неподдерживаемую подпись сквозного шифрования
+ Сообщение зашифровано в неподдерживаемом формате
+ Сообщение зашифровано, дешифрование отменено
+ текст, подписанный ключом сквозного шифрования
+ от проверенного подписанта
+ Подписанный текст
+ но ключ сквозного шифрования не соответствует отправителю
+ но ключ сквозного шифрования просрочен
+ но ключ сквозного шифрования отозван
+ но ключ сквозного шифрования небезопасен
+ но ключ сквозного шифрования неизвестен
+ Зашифровано
+ но был сбой дешифрования
+ требуется полная загрузка сообщения для дешифрования
+ но отсутствует настроенное криптоприложение
+ Зашифровано
+ но без сквозного шифрования
+ со сквозным шифрованием
+ от проверенного отправителя
+ Зашифровано
+ но ключ сквозного шифрования неизвестен
+ но ключ сквозного шифрования не соответствует отправителю
+ но ключ сквозного шифрования просрочен
+ но ключ сквозного шифрования отозван
+ но ключ сквозного шифрования небезопасен
+ но произошёл сбой в данных сквозного шифрования
+ но шифрование не считается безопасным
+ OK
+ Поиск криптоключа
+ Кем подписано
+ Кем отправлено
+ Подробности
+ Разблокировать
+ Эта часть не была зашифрована и небезопасна
+ Незащищённое вложение
+ Загрузка…
+ Дешифрование отменено.
+ Повтор
+ Зашифрованное сообщение необходимо загрузить для дешифрования
+ Сбой дешифрования почты
+ Спецсимволы пока не поддерживаются!
+ Сбой разбора адреса!
+ Скрыть подписи без шифрования
+ Отображаются зашифрованные подписи
+ Отображаются все подписи
+ Шифрование недоступно в режиме \"Только подпись\"
+ Неподписанный текст
+ Прекращение поддержки APG
+ Разработка APG прекращена!
+ В связи с этим, поддержка APG удалена из K-9 Mail
+ Разработка прекращена в начале 2014 г.
+ Имеются неисправленные уязвимости
+ Нажмите здесь для подробностей.
+ Понятно!
+ APG
+ Сообщение зашифровано
+ Сообщение зашифровано OpenPGP.\nЧтобы прочесть его, необходимо установить и настроить подходящее OpenPGP-приложение.
+ В Настройки
+ Сообщения K-9
+ Загрузка сообщений…
+ Сбой при получении списка папок
+ Сбой получения статуса адресата у провайдера OpenPGP!
+ Шифрование невозможно
+ Не все выбранные адресаты поддерживают эту возможность!
+ Включить шифрование
+ Отключить шифрование
+ Шифрование сообщений гарантирует, что никто, кроме получателя, не сможет их прочесть.
+ Шифрование отображается, если поддерживается всеми адресатами и они писали Вам ранее.
+ Включите шифрование, нажав этот значок.
+ Понятно
+ Назад
+ Отключить шифрование
+ Шифрование OpenPGP
+ Взаимное автошифрование
+ Взаимное автошифрование
+ Сообщения шифруются по желанию или при ответе на шифрованное сообщение
+ Если отправитель и получатели включили режим взаимного автошифрования, включать шифрование по умолчанию.
+ Нажмите здесь для подробностей.
+ Основные
+ OpenPGP не установлен
+ Установить
+ Для сквозного шифрования в K-9 нужен OpenKeychain.
+ Зашифрованное сообщение
+ Шифровать темы сообщений
+ Может поддерживаться не всеми адресатами
+ Внутренний сбой: неверный ящик!
+ Сбой подключения к %s!
+ Отправка настроек автошифрования
+ Передать настройки шифрования на другие устройства
+ Настройки автошифрования
+ Сообщение с настройками взаимного автошифрования позволяет безопасно передать эти настройки на другие устройства.
+ Отправить настройки
+ Сообщение будет отправлено на ваш адрес:
+ Создание сообщения с настройками…
+ Отправка сообщения для:
+ Для завершения, откройте сообщение на новом устройстве и введите код установки.
+ Показать код установки
+ Настройки взаимного автошифрования
+ Это сообщение содержит все сведения, необходимые для переноса настроек взаимного автошифрования вместе с секретным ключом с исходного устройства.
Для настройки взаимного автошифрования на новом устройстве, следуйте инструкциям, отображаемым на новом устройстве.
Это сообщение можно сохранить и использовать в качестве резервной копии своего секретного ключа. Запишите и надёжно сохраните пароль.
- Сбой при отправке сообщения. Проверьте соединение с сетью и настройки сервера исходящей почты.
- Вкл
- Отключить
- Открыть
- Закрыть
-
- Разрешить доступ к контактам
- Чтобы подсказывать имена и показывать имена контактов и фото, приложению нужен доступ к контактам.
- При загрузке данных возникла ошибка
- Узнайте, что нового в этом выпуске
- Показывать последние изменения после того, как приложение было обновлено
- Условия предоставления услуг
- Политика конфиденциальности
- Почта является форком K9 Mail
- -Почта - это почтовый клиент для Android с открытым исходным кодом.
- Исходный код
- Лицензия
- Версия сборки
- Информация о почте
- Авторы
- Отключить push-уведомления
- Если вам не нужны мгновенные уведомления о новых сообщениях, вам следует отключить push-уведомления и использовать интервальный опрос. Интервальный опрос проверяет наличие новой почты через регулярные промежутки времени и не нуждается в уведомлениях.
- Настройка уведомления
- Узнать больше
- Однако Android также позволяет скрыть уведомление.
- При использовании push-уведомлений, K-9 Mail поддерживает соединение с почтовым сервером. Android требует отображения постоянного уведомления, пока приложение активно в фоновом режиме. %s
- Информация о push-увеломлениях
- Нажмите, чтобы узнать больше.
- Спящий режим до тех пор, пока не будет доступна сеть
- Спящий режим до тех пор, пока не будет разрешена фоновая синхронизация
- Ожидание новых email сообщений
- Инициализация…
- Такой же, как и класс опроса
- Проверка XOauth2 (для Gmail, Outlook)
- Проигрывать звук когда email успешно отправлен
- Звук отправленного email
- Показывается при ожидании новых сообщений
- Синхронизировать (Нажать)
- Предметный текст скопирован в буфер обмена
- Поиск везде
- Что нового
-
\ No newline at end of file
+ Сбой при отправке сообщения. Проверьте соединение с сетью и настройки сервера исходящей почты.
+ Вкл
+ Откл
+ Открыть
+ Закрыть
+
+ Разрешить доступ к контактам
+ Чтобы подсказывать имена и показывать фото, приложению нужен доступ к контактам
+ При загрузке данных возникла ошибка
+ Инициализация…
+ Ожидание новых писем
+ Спящий режим до тех пор, пока не будет разрешена фоновая синхронизация
+ Спящий режим до появления сети
+ Нажмите, чтобы узнать больше.
+ Информация о Push
+ При использовании Push K-9 Mail поддерживает соединение с почтовым сервером. Android требует отображения постоянного уведомления, пока приложение активно в фоновом режиме. %s
+ Однако Android также позволяет скрыть уведомление.
+ Узнать больше
+ Настроить уведомление
+ Если вам не нужны мгновенные уведомления о новых сообщениях, вам следует отключить Push и использовать Опрос. Опрос проверяет наличие новой почты через регулярные промежутки времени и не нуждается в уведомлениях.
+ Отключить Push
+
diff --git a/app/ui/legacy/src/main/res/values-sk/strings.xml b/app/ui/legacy/src/main/res/values-sk/strings.xml
index a9c3627cd2be82c5ff5504d86046babffd1e069f..eb7870d69bf7ad540a75060e3a752ca622dbae1d 100644
--- a/app/ui/legacy/src/main/res/values-sk/strings.xml
+++ b/app/ui/legacy/src/main/res/values-sk/strings.xml
@@ -242,10 +242,6 @@
Remove Mail User-Agent from mail headersSkryť časové pásmoPoužiť UTC ako časové pásmo v hlavičkách správ
- Skryť predmet v oznámení
- Nikdy
- Pri uzamknutom zariadení
- VždyZobraziť tlačidlo \'Vymazať\'NikdyOznámenie pre jednu správu
@@ -253,7 +249,6 @@
Oznámenia na obrazovke uzamknutiaŽiadne oznámenia na obrazovke uzamknutiaNázov aplikácie
- Počet neprečítaných správPočet správ a odosielateliaRovnaké ako pri odomknutej obrazovkeČas ticha
@@ -266,6 +261,7 @@
E-mailová adresaHesloZobraziť heslo
+
Ručné nastavenieNačítavanie informácií o účte\u2026
@@ -307,8 +303,6 @@
MobilnáWi-FiIná
- Externý ukladací priestor (Karta SD)
- Interný ukladací priestorOdstrániť vymazané správy zo serveraIhneďPri synchronizovaní
@@ -384,8 +378,6 @@
PokračovaťPokročiléNastavenia účtu
- Predvolený účet
- Odosielať e-maily z tohto účtuOznámenia o nových správachPriečinky oznámeníVšetky
@@ -405,8 +397,6 @@
Označiť správu ako prečítanú po jej zobrazeníPri zmazaní označiť za prečítanéPri mazaní oznaťič správu ako prečítanú
- Nastavenie notifikácií
- Nastavenie notifikácií v operačnom systémeVždy zobraziť obrázkyNieOd kontaktov
diff --git a/app/ui/legacy/src/main/res/values-sl/strings.xml b/app/ui/legacy/src/main/res/values-sl/strings.xml
index 644c88d5a22ab1ddb492e3c58486629a9e37939f..bbc7fa5142f630260231aa638241608f0c9d1c4b 100644
--- a/app/ui/legacy/src/main/res/values-sl/strings.xml
+++ b/app/ui/legacy/src/main/res/values-sl/strings.xml
@@ -49,6 +49,8 @@
Posreduj kot prilogoIzbor računaIzbor mape
+ Premakni v …
+ Kopiraj v …Izpraševanje %s:%s%sPrejemanje glav %s:%s%sPošiljanje %s%s
@@ -82,6 +84,7 @@
ZavrziShrani kot osnutekPreveri za nova sporočila
+ Preveri pošto v vseh računihPošlji sporočilaOsveži seznam mapNajdi mapo
@@ -177,6 +180,9 @@ dodatnih %d sporočil
Beleženje dodatnih podrobnosti diagnostikeBeleženje občutljivih podrobnostiV dnevnikih so lahko objavljena tudi gesla.
+ Izvozi dnevnike
+ Izvoz uspešen. Dnevniki lahko vsebujejo občutljive informacije. Bodi previden, komu jih pošlješ.
+ Izvoz je spodletel.Naloži več sporočilZa:%sZadeva
@@ -250,10 +256,6 @@ dodatnih %d sporočil
Remove Mail User-Agent from mail headersSkrij časovni pasV glavah poštnih sporočil se uporabi čas UTC in ne krajevni čas
- Skrivanje izpisa zadeve sporočila v obvestilih
- Vedno pokaži zadevo
- Skrij, ko je naprava zaklenjena
- Vedno skrij zadevoPrikaz gumba za brisanje sporočilNikoli ne pokažiLe pri obvestilih enega sporočila
@@ -261,7 +263,7 @@ dodatnih %d sporočil
Obvestila zaklenjenega zaslonaNi obvestil zaklenjenega zaslonaIme programa
- Število neprebranih sporočil
+ Število novih sporočilŠtevilo sporočil in pošiljateljevEnako kot pri odklenjenem zaslonuČas tihega delovanja
@@ -274,6 +276,10 @@ dodatnih %d sporočil
Naslov elektronske pošteGesloPokaži geslo
+
+ Če si želiš ogledati svoje geslo tukaj, omogoči zaklepanje zaslona na tej napravi.
+ Preverjanje identitete
+ Odkleni, za ogled svojega geslaRočna nastavitevPridobivanje podrobnosti računa \u2026
@@ -315,8 +321,6 @@ dodatnih %d sporočil
MobilnoWi-FiDrugo
- Zunanji pomnilnik (kartica SD)
- Notranji pomnilnik napravePočisti izbrisana sporočila na strežnikuPočisti takojPočisti med izpraševanjem
@@ -392,8 +396,6 @@ dodatnih %d sporočil
NadaljujNapredne možnostiNastavitve računa
- Privzeti račun
- Izbrana možnost določa, da bo za pošiljanje privzeto uporabljen ta računObvestila za prejem nove poštePrikaz obvestilZa vse ravni map
@@ -409,12 +411,15 @@ dodatnih %d sporočil
Pokaže obvestilo tudi za poslana sporočilaPokaži obvestila le za sporočila znanih stikovPokažejo se le obvestila za prispela sporočila od stikov, ki so v krajevnem imeniku
+ Ignoriraj sporočila klepeta
+ Ne prikazuj obvestil za sporočila, ki spadajo v e-poštni klepetOb odpiranju označi kot prebranoKo se sporočilo prvič odpre, naj bo označeno kot prebranoOb izbrisu označi kot prebranoOb izbrisu označi sporočilo tudi kot prebrano
- Nastavitve za obvestila
- Odpri nastavitve za sistemska obvestila
+ Kategorije obvestil
+ Konfiguriranje obvestil za nova sporočila
+ Konfiguriranje obvestil o napakah in stanjuPrikaz slikNe pokaži slikPokaži slike znanih stikov
@@ -667,6 +672,7 @@ dodatnih %d sporočil
V pogledu sporočilV pogledu seznamovPokaži skupno mapo prejetih sporočil
+ Pokaži število označenih z zvezdico%s%s- NeprebranoVsa sporočila
@@ -886,6 +892,7 @@ dodatnih %d sporočil
SkpZaOd
+ Odgovori na<Neznani prejemnik><Neznani pošiljatelj>Domači
diff --git a/app/ui/legacy/src/main/res/values-sq/strings.xml b/app/ui/legacy/src/main/res/values-sq/strings.xml
index aa5e3631914959824dc912daf20dfca1cba5f250..3d70f2f203f15567e82902790495eecd54cf2d1c 100644
--- a/app/ui/legacy/src/main/res/values-sq/strings.xml
+++ b/app/ui/legacy/src/main/res/values-sq/strings.xml
@@ -49,6 +49,8 @@
Përcille si bashkëngjitjeZgjidhni LlogariZgjidhni Dosje
+ Shpjereni te…
+ Kopjojeni te…Vjelje %s:%s%sPo sillen kryet %s:%s%sDërgim %s%s
@@ -82,6 +84,7 @@
Hidhe tejRuaje si skicëMerr email-et
+ Kontrollo për postë në krejt llogaritëDërgo mesazheRifresko listë dosjeshGjej në dosje
@@ -173,6 +176,9 @@
Regjistro të dhëna ekstra diagnostikimeshRegjistro të dhëna konfidencialeMund të shfaqë fjalëkalime te regjistrat
+ Eksportoni regjistra
+ Eksportim i suksesshëm. Regjistrat mund të përmbajnë të dhëna rezervat. Bëni kujdes kujt ia dërgoni.
+ Eksportimi dështoi.Ngarko më tepër mesazhePër:%sSubjekt
@@ -246,10 +252,6 @@
Remove Mail User-Agent from mail headersFshihe zonën kohorePërdorni UTC, në vend se zonën kohore vendore, te krye email-esh dhe krye përgjigjesh
- Fshihe subjektin gjatë njoftimesh
- Kurrë
- Kur pajisja është e kyçur
- PërherëShfaq butonin \'Fshije\'KurrëPër njoftim mesazhi njësh
@@ -257,7 +259,7 @@
Njoftime Nën Ekran të KyçurPa njoftime nën ekran të kyçurEmër aplikacioni
- Numër mesazhesh të palexuar
+ Numër mesazhesh të rinjNumër mesazhesh de dërguesNjësoj si kur ekrani është i kyçurQetësi
@@ -270,6 +272,10 @@
Adresë emailFjalëkalimShfaqe fjalëkalimin
+
+ Që të shihni fjalëkalimin tuaj këtu, aktivizoni kyçje ekrani në këtë pajisje.
+ Verifikoni identitetin tuaj
+ Që të shihni fjalëkalimin tuaj, shkyçeniRregullim doraziPo merren të dhëna llogarie\u2026
@@ -311,8 +317,6 @@
CelularWi-FiTjetër
- Depozitë e jashtme (Kartë SD)
- Depozitë e brendshme e rëndomtëHiqi dhe në shërbyes mesazhet e fshiraMenjëherëKur vilet
@@ -388,8 +392,6 @@
VazhdoTë mëtejshmeRregullime llogarie
- Llogaria parazgjedhje
- Si parazgjedhje, postën dërgoje nga kjo llogariNjoftime email-i të riDosje njoftimeshKrejt
@@ -405,12 +407,15 @@
Shfaq një njoftim për mesazhet që dërgojVetëm kontaktetShfaq njoftime vetëm për mesazhe nga kontakte të njohur
+ Shpërfill mesazhe fjalosjesh
+ Mos shfaq njoftime për mesazhe që u përkasin një fjalosjeje me emailShënoje si të lexuar kur hapetShënoje një mesazh të lexuar, kur hapet për parjeVëri shenjë si i lexuar, kur fshihetVërini shenjë si i lexuar një mesazhi, kur fshihet
- Rregullime njoftimesh
- Rregullime njoftimesh sistemi të hapur
+ Kategori njoftimesh
+ Formësoni njoftime për mesazhe të rinj
+ Formësoni njoftime gabimesh dhe gjendjeshShfaqi përherë figuratJoPrej kontaktesh
@@ -663,6 +668,7 @@
Në skenë mesazhiNë skenë listeShfaq Kuti Poste të Njësuar
+ Shfaq llogari me yll%s%s- Të palexuarKrejt mesazhet
@@ -872,6 +878,7 @@
BccPërNga
+ Përgjigjuni<Marrës i Panjohur><Dërgues i Panjohur>Shtëpie
diff --git a/app/ui/legacy/src/main/res/values-sr/strings.xml b/app/ui/legacy/src/main/res/values-sr/strings.xml
index 33bb40ed928020b39e2e01df5eda71b1446f937d..460ebd73611f62abf7d335ff976018db34964220 100644
--- a/app/ui/legacy/src/main/res/values-sr/strings.xml
+++ b/app/ui/legacy/src/main/res/values-sr/strings.xml
@@ -241,10 +241,6 @@
Уклања К-9 идентификацију из заглавља порукеСакриј временску зонуКоришћење УТЦ уместо локалне зоне у заглављима
- Сакриј тему у обавештењима
- никад
- кад је уређај закључан
- увекПрикажи дугме за брисањеникаду обавештењу једне поруке
@@ -252,7 +248,6 @@
Подаци на закључаном екранубез обавештењаназив програма
- број непрочитаних порукаброј порука и пошиљаоцикао и кад је откључан екранТихи сати
@@ -265,6 +260,7 @@
Адреса е-поштеЛозинкаПрикажи лозинку
+
Ручна поставаДобављам податке о налогу\u2026
@@ -306,8 +302,6 @@
мобилнојбежичнојосталим
- Спољашње складиште (СД картица)
- Обично унутрашње складиштеУклони обрисане поруке са сервераодмахприликом провере
@@ -383,8 +377,6 @@
НаставиНапредноПоставке налога
- Подразумевани налог
- Подразумевано шаљи пошту са овог налогаОбавештења о новој поштиОбавештења за фасциклесве
@@ -404,8 +396,6 @@
Означава поруку прочитаном када се отвори за приказОзначи као прочитано по брисањуОзначи поруку прочитаном по брисању
- Поставке обавештења
- Отвори системске поставке обавештењаУвек прикажи сликенеод контаката
diff --git a/app/ui/legacy/src/main/res/values-sv/strings.xml b/app/ui/legacy/src/main/res/values-sv/strings.xml
index 5aaa5a80eb84dc263e670c6ea38191b1a4b084e9..64b4ff46402ad23638a86d14b358ce52ce88797c 100644
--- a/app/ui/legacy/src/main/res/values-sv/strings.xml
+++ b/app/ui/legacy/src/main/res/values-sv/strings.xml
@@ -25,12 +25,40 @@
Visa senaste ändringar när appen uppdateradesTa reda på vad som är nytt i denna utgåva
- Welcome to Mail
- Mail is the default mail client for /e/
+ Välkommen till K-9 Mail
+
+K-9 Mail är en kraftfull fri e-postklient för Android.
+
+Några av funktionerna som förbättrats är:
+
+
+
Push-e-post med IMAP IDLE
+
Bättre prestanda
+
Meddelandelagring
+
E-postsignaturer
+
Blindkopia-till-dig-själv
+
Mapprenumerationer
+
Synkronisera alla mappar
+
Inställning av svarsadress
+
Tangentbordsgenvägar
+
Bättre stöd för IMAP
+
Spara bilagor till minneskort
+
Tömma papperskorgen
+
Meddelandesortering
+
…och mycket annat
+
+
+Observera att K-9 inte stödjer gratiskonton på Hotmail och har, som så många andra e-postklienter, några svårigheter att prata med Microsoft Exchange.
+
+ ]]>
- -- Sent from /e/ Mail.
+ -- \nSkickat från min Android-enhet med K-9 Mail. Ursäkta min korthet.
- The account \"%s\" will be removed from Mail.
+ Kontot \"%s\" kommer att tas bort från K-9 Mail.UpphovsmänRevisionsinformation
@@ -38,17 +66,19 @@
Tillåter att denna applikation läser dina e-postmeddelanden.Ta bort e-postTillåter att denna applikation tar bort dina e-postmeddelanden.
- About Mail
+ Om K-9 MailKontonMapparAvancerat
- Skriv
+ SkrivaSvaraSvara allaVidarebefordraVidarebefordra som bilagaVälj kontoVälj mapp
+ Flytta till…
+ Kopiera till…Kontrollerar %s:%s%sHämtar rubriker %s:%s%sSkickar %s%s
@@ -77,11 +107,12 @@
FlyttaFlytta till utkastSkicka…
- Omarkivera…
+ Arkivera om…KlarKasseraSpara som utkastKontrollera e-post
+ Kontrollera e-post i alla kontonSkicka meddelandenUppdatera mapplistaHitta mapp
@@ -124,8 +155,8 @@
AnslutningsfelMeddelandet hittades inteInläsningsfel av meddelande
- Läs in ytterligare upp
- till %d
+ Läs in ytterligare
+ upp till %d%.1f GB%.1f MB%.1f kB
@@ -173,6 +204,9 @@
Logga extra diagnostisk informationLogga känslig informationKan visa lösenord i loggarna.
+ Exportera loggar
+ Exporten lyckades. Loggar kan innehålla känslig information. Var försiktig med vem du skickar dem till.
+ Exporten misslyckades.Läs in fler meddelandenTill:%sÄmne
@@ -187,7 +221,7 @@
%s skrev:%2$s skrev: (%1$s)Du måste ange minst en mottagare.
- Mottagarfältet är inte komplett!
+ Mottagarfältet innehåller ofullständig inmatning!Hittar ingen e-postadress för denna kontakt.Vissa bilagor kan inte vidarebefordras eftersom de inte har hämtats.Meddelandet kan inte vidarebefordras eftersom vissa bilagor inte har hämtats.
@@ -212,8 +246,8 @@
Det gick inte att hämta ytterligare meddelanderubriker från databas eller e-postserver.Mer från denna avsändareFrån %s
- Felsök / Rensa meddelandets brödtext
- Meddelandet kasserat
+ Felsök / Rensa meddelandets text
+ Meddelandet kasseradesMeddelandet sparat som utkastVisa stjärnorStjärnor indikerar flaggade meddelanden
@@ -223,17 +257,17 @@
Korrespondent ovanför ämnesradVisar korrespondentens namn ovanför ämnesraden istället för under denVisa kontaktnamn
- Använd mottagarnas namn från Kontakter om tillgängligt
+ Använd mottagarnas namn från kontakter om tillgängligtFärglägg kontakter
- Färglägg namn i kontaktlistan
+ Färglägg namn i din kontaktlistaTeckensnitt med fast bredd
- Använd ett teckensnitt med fast bredd när meddelanden med enbart text visas
+ Använd ett teckensnitt med fast bredd när meddelanden med enbart oformaterad text visasAnpassa automatiskt meddelandenKrymp meddelanden så att de får plats på skärmenÅtervänd till listan efter borttagningÅtervänd till meddelandelistan efter att meddelande tagits bort
- Visa nästa meddelande efter ta bort
- Visa nästa meddelande som standard efter att meddelande tagits bort
+ Visa nästa meddelande efter borttagning
+ Visa nästa meddelande som standard efter borttagning av meddelandeBekräfta åtgärderVisa en dialogruta när du genomför valda åtgärderTa bort
@@ -243,13 +277,9 @@
Markera alla meddelanden som lästaTa bort (från avisering)Dölj e-postklient
- Remove Mail User-Agent from mail headers
+ Ta bort K-9-användaragent från meddelanderubrikerDölj tidszon
- Använd UTC istället för lokal tidszon i postrubriker och svarrubriker
- Dölj ämne i aviseringar
- Aldrig
- När enheten är låst
- Alltid
+ Använd UTC istället för lokal tidszon i postrubriker och svarsrubrikVisa knappen \"Ta bort\"AldrigFör enstaka meddelandeavisering
@@ -257,19 +287,23 @@
Aviseringar på låsskärmenInga aviseringar på låsskärmenApplikationsnamn
- Antal olästa meddelanden
+ Nytt meddelandeantalMeddelandeantal och avsändareSamma som när skärmen är olåstTyst tidInaktivera ringsignaler, vibration och blinkande på nattenStäng av aviseringar
- Stäng av avisering under \"Tyst tid\"
+ Inaktivera aviseringar helt under tyst tidTyst tid börjarTyst tid slutarKonfigurera ett nytt kontoE-postadressLösenordVisa lösenord
+
+ För att se ditt lösenord här, aktivera skärmlåset på denna enhet.
+ Verifiera din identitet
+ Lås upp för att se ditt lösenordKonfigurera manuelltHämtar kontoinformation\u2026
@@ -311,21 +345,19 @@
Mobilt nätverkWi-FiAnnat
- Extern lagring (SD-kort)
- Vanlig intern lagring
- Ta bort meddelanden som tas bort på servern
+ Ta bort borttagna meddelanden från servernDirektVid e-postkontrollManuelltDetektera automatiskt namnområde för IMAPSökvägsprefix för IMAP
- Namn på utkastmapp
- Namn på skickatmapp
+ Utkastmapp
+ Mappen SkickatPapperskorgsmapp
- Namn på arkivmapp
- Namn på skräpmapp
+ Arkivmapp
+ SkräppostmappVisa endast prenumererade mappar
- Expandera automatiskt mappen
+ Expandera automatiskt mappSökväg för Outlook Web AppvalfrittSökväg för autentisering
@@ -388,8 +420,6 @@
FortsättAvanceratKontoinställningar
- Standardkonto
- Skicka e-post från detta konto som standardAviseringar vid ny e-postAviseringsmapparAlla
@@ -405,25 +435,28 @@
Visa avisering även för e-post som jag själv skickatEndast kontakterVisa aviseringar endast för meddelanden från kända kontakter
+ Ignorera chattmeddelanden
+ Visa inte aviseringar för meddelanden som tillhör en e-postchattMarkera som läst vid öppningMarkera ett meddelande som läst när det visasMarkera som läst när det tas bortMarkera ett meddelande som läst när det tas bort
- Aviseringsinställningar
- Öppna inställningar för systemaviseringar
+ Aviseringskategorier
+ Konfigurera aviseringar för nya meddelanden
+ Konfigurera fel- och statusaviseringarVisa alltid bilderNejFrån kontakterFrån allaSkickar e-post
- Citera meddelandet när du svarar
+ Citera meddelande när du svararInkludera orginalmeddelandet i ditt svar.
- Skriv svar efter citerad text
+ Skriv svar efter citerat meddelandeOriginalmeddelandet kommer att visas ovanför ditt svar.Avlägsna signaturer vid svarSignaturer kommer att tas bort från citerade meddelandenMeddelandeformat
- Endast text (bilder och formatering tas bort)
+ Oformaterad text (ta bort bilder och formatering)HTML (bilder och formatering behålls)AutomatisktVisa alltid kopia/blindkopia
@@ -433,7 +466,7 @@
Prefix (som Gmail)Rubriker (som Outlook)Skicka skickade meddelanden
- Överföra meddelanden till mappen Skickat efter sändning
+ Ladda upp meddelanden till mappen Skickat efter sändningAllmänna inställningarE-postläsningE-posthämtning
@@ -507,7 +540,7 @@
Endast 1:a klassens mappar1:a och 2:a klassens mapparAlla utom 2:a klassens mappar
- Synkronisera fjärradering
+ Synkronisera fjärrborttagningTa bort meddelanden när de tas bort från servernSaknade OpenPGP-app - har den avinstallerats?Mappinställningar
@@ -569,13 +602,13 @@
Flytta nerFlytta längst upp / gör till standardTa bort
- Beskrivning av identitet
+ Identitetsbeskrivning(valfritt)Ditt namn(valfritt)E-postadress(krävs)
- Svarsadress (reply-to)
+ Svarsadress(valfritt)Signatur(valfritt)
@@ -598,7 +631,7 @@
Lästa meddelanden överstMeddelanden med bilagor överstMeddelanden utan bilagor överst
- Sortera på…
+ Sortera efter…DatumMottagetÄmne
@@ -619,9 +652,9 @@
1:a och 2:a klassens mapparDölj 2:a klassens mapparPlacering av signatur
- Före citerad text
- Efter citerad text
- Använd appens tema
+ Före citerat meddelande
+ Efter citerat meddelande
+ Använd apptemaMörktLjustAnvänd systemstandard
@@ -663,6 +696,7 @@
I meddelandelistorI listvyerVisa samlad inkorg
+ Visa antalet stjärnmarkerade%s%s - OlästaAlla meddelanden
@@ -732,14 +766,14 @@
NejBekräfta markera alla som lästaVill du markera alla meddelanden som lästa?
- Bekräfta töm papperskorgen
+ Bekräfta tömning av papperskorgenVill du tömma papperskorgen?JaNej
- Bekräfta flytt till skräpmapp
+ Bekräfta flytt till skräppostmapp
- Vill du verkligen flytta detta meddelande till skräpmappen?
- Vill du verkligen flytta %1$d meddelanden till skräpmappen?
+ Vill du verkligen flytta detta meddelande till skräppostmappen?
+ Vill du verkligen flytta %1$d meddelanden till skräppostmappen?JaNej
@@ -777,7 +811,7 @@
Utgående serverlösenordAnvänd samma lösenord för utgående serverServernamn: %s
- Visa antal olästa för…
+ Visa antalet olästa för…KontoKontot för vilken olästa räkningen ska visasSamlad inkorg
@@ -849,7 +883,7 @@
Visa kontaktbilderVisa kontaktbilder i meddelandelistanMarkera alla som lästa
- Färglägg bilder på kontakter
+ Färglägg kontaktbilderFärglägg kontaktbilder som saknasSynliga meddelandeåtgärderVisa valda åtgärder i meddelandelistans meny
@@ -872,6 +906,7 @@
BlindkopiaTillFrån
+ Svara till<Okänd mottagare><Okänd avsändare>Hem
@@ -880,8 +915,8 @@
MobilIngen Utkast mapp konfigurerad för detta konto!Ingen nyckel konfigurerad för detta konto! Kontrollera dina inställningar.
- Crypto-leverantören använder inkompatibel version. Kontrollera dina inställningar!
- Kan inte ansluta till crypto leverantör, granska dina inställningar eller klicka på crypto ikonen för nytt försök.
+ Kryptoleverantören använder inkompatibel version. Kontrollera dina inställningar!
+ Kan inte ansluta till kryptoleverantör, granska dina inställningar eller klicka på kryptoikonen för nytt försök.Det gick inte att initiera ände-till-ände-kryptering, vänligen kontrollera dina inställningarPGP/INLINE läge stöder inte bilagor!Aktivera PGP/INLINE
@@ -905,7 +940,7 @@
Signaturer kan brytas när de skickas till e-postlistor.Signaturer kan visas som \"signature.asc\" bilagor i vissa klienter.Krypterade meddelanden inkluderar alltid en signatur.
- Oformatterad text
+ Oformaterad textände-till-ände-signatur innehöll ett felmåste hämta meddelandet fullständigt för att behandla signatureninnehåller icke-stödd ände-till-ände-signatur
@@ -922,7 +957,7 @@
Krypteradmen det fanns ett dekrypteringsfelmåste hämta meddelandet fullständigt för dekryptering
- men ingen crypto app är konfigurerad
+ men ingen kryptoapp är konfigureradKrypteradmen inte ände-till-ändeÄnde-till-ände krypterad
@@ -966,7 +1001,7 @@
Detta e-postmeddelande är krypteratDetta e-postmeddelande har krypterats med OpenPGP.\nFör att läsa det, måste du installera och konfigurera en kompatibel OpenPGP-app.Gå till inställningar
- Mail Message List
+ K-9 MeddelandelistaLäser in meddelanden…Det gick inte att hämta mapplistaFel vid hämtning av mottagarens status från OpenPGP-leverantör!
@@ -975,7 +1010,7 @@
Aktivera krypteringInaktivera krypteringKrypterande meddelanden säkerställer att de kan läsas av mottagaren, och ingen annan.
- Kryptering visas endast om den stöds av alla mottagare, och de måste ha skickat ett e-postmeddelande till dig innan.
+ Kryptering visas endast om den stöds av alla mottagare, och de måste ha skickat dig ett e-postmeddelande tidigare.Växla kryptering genom att klicka på denna ikon.UppfattatBakåt
@@ -989,7 +1024,7 @@
Allmänna inställningarIngen OpenPGP-app installeradInstallera
- Mail requires OpenKeychain for end-to-end encryption.
+ K-9 Mail kräver OpenKeychain för ände-till-ände-kryptering.Krypterat meddelandeKryptera meddelandeämnenKanske inte stöds av vissa mottagare
@@ -1027,7 +1062,7 @@ Du kan behålla detta meddelande och använda det som en säkerhetskopia för di
Sover tills nätverket är tillgängligtTryck för att lära dig mer.Push-info
- När du använder Push upprätthåller K-9 Mail en anslutning till e-postservern. Android kräver att ett pågående meddelande visas medan appen är aktiv i bakgrunden. %s
+ Vid användning av Push upprätthåller K-9 Mail en anslutning till e-postservern. Android kräver att ett pågående meddelande visas medan appen är aktiv i bakgrunden. %sMen Android låter dig också dölja aviseringen.Lär dig merAnpassa avisering
diff --git a/app/ui/legacy/src/main/res/values-tr/strings.xml b/app/ui/legacy/src/main/res/values-tr/strings.xml
index b0ba5ce152cc66a5fb964a9bc389a86f0a59af1c..31ba42e15ba0e6d07482f483b76f4cdd849da72e 100644
--- a/app/ui/legacy/src/main/res/values-tr/strings.xml
+++ b/app/ui/legacy/src/main/res/values-tr/strings.xml
@@ -82,6 +82,7 @@
ÇıkartTaslak olarak KaydetPostayı Kontrol et
+ Tüm hesaplardaki e-postaları kontrol edinİletileri GönderKlasörleri yineleKlasör bul
@@ -156,6 +157,7 @@
Posta gönderiliyor:Eşzamanla (İttir)
+ Yeni iletiler beklenirken görüntülenirİletilerİletilerle ilgili bildirimlerÇeşitli
@@ -244,10 +246,6 @@
Remove Mail User-Agent from mail headersZaman dilimini gizlePosta ve yanıt başlıklarında yerel zaman dilimi yerine UTC kullan
- Bildirimlerde konuyu gizle
- Hiçbir zaman
- Cihaz kilitlendiği zaman
- Her zaman\'Sil\' butonunu gösterHiçbir zamanTek bir mesaj bildirimi için
@@ -255,7 +253,6 @@
Kilit Ekranı BildirimleriKilit ekranı bildirimi yokUygulama adı
- Okunmamış mesaj sayısıMesaj sayısı ve gönderenlerEkran kilidi açıkken olduğu gibiSessiz Zaman
@@ -268,6 +265,10 @@
E-posta adresiParolaParolayı göster
+
+ Şifrenizi görmek için ekran kilidini etkinleştirin.
+ Kimliğinizi doğrulayın
+ Şifrenizi görmek için kilidi açınEl ile ayarHesap bilgisi alınıyor\u2026
@@ -309,8 +310,6 @@
Cep TelefonuWi-FiDiğer
- Harici depolama (SD kart)
- Düzenli dahili depolamaSunucudan silinen mesajları temizleHemenOylama zamanı
@@ -386,8 +385,6 @@
DevamGelişmişHesap ayarları
- Öntanımlı hesap
- Postayı varsayılan olarak bu hesaptan gönderYeni posta bildirimleriBildirimler klasörüHepsi
@@ -403,12 +400,14 @@
Gönderdiğim mesajlar için bir bildirim gösterSadece kişilerSadece bilinen kişilerden gelen mesajlar için bildirim göster
+ Sohbet mesajlarını yoksayAçılan iletiyi okundu olarak işaretleMesaj okunmak üzere açıldığında okundu olarak işaretleSilindiğinde okundu olarak işaretleBir ileti silindiğinde okundu olarak işaretlemek
- Bildirim ayarları
- Sistem bildirim ayarlarını aç
+ Bildirim kategorileri
+ Yeni ileti bildirimlerini ayarla
+ Hata ve durum bildirimlerini ayarlaDaima resimleri gösterHayırKişilerden
@@ -524,6 +523,7 @@
Sınıflama yok1. Sınıf2. Sınıf
+ Sorgu sınıfı ile aynıKlasör bildirim sınıfıSınıflama yok1. Sınıf
@@ -660,6 +660,7 @@
İleti görünümlerindeliste görünümlerindeBirleşik Gelen Kutusunu Göster
+ Yıldızlanan sayısını göster%s%s - OkunmadıBütün mesajlar
@@ -1019,4 +1020,11 @@ Bu iletiyi saklayabilir ve gizli anahtarınız için bir yedekleme olarak kullan
Kişilerle ilgili öneriler sunabilmek, kişi adlarını ve fotoğraflarını görüntüleyebilmek için uygulamanın kişilerinize erişmesi gerekir.Veriler yüklenirken bir hata oluştu Başlatılıyor...
+ Yeni e-postalar bekleniyor
+ Arkaplan senkronizasyonuna izin verilene kadar uyku halinde
+ Şebekeye erişene kadar uyku halinde
+ Daha fazlasını öğrenmek için dokunun.
+ Aynı zamanda Android de bildirimleri gizlemenize olanak sağlamaktadır.
+ Daha fazlasını öğren
+ Bildirimleri ayarla
diff --git a/app/ui/legacy/src/main/res/values-uk/strings.xml b/app/ui/legacy/src/main/res/values-uk/strings.xml
index 25c0cd57f070db50aebbd7a7b5e44058c2ac3738..d37ebfa4a1236ef942cbf29b5e44d4f7633f0c5f 100644
--- a/app/ui/legacy/src/main/res/values-uk/strings.xml
+++ b/app/ui/legacy/src/main/res/values-uk/strings.xml
@@ -128,923 +128,916 @@
Помилка завантаження повідомленняЗавантажити
ще %d листів
- %.1f ГБ
- %.1f МБ
- %.1f кБ
- %d Б
- Розмір облікового запису \"%s\" зменшився з %s до %s
- Стиснення облікового запису \"%s\"
- Нова пошта
-
- %d нове повідомлення
- %d нових повідомлень
- %d нових повідомлень
- %d нових повідомлень
-
- %d непрочитане(-их) (%s)
- ще %1$d у %2$s
- Відповісти
- Позначити прочитаним
- Позначити всі прочитаними
- Видалити
- Видалити всі
- Архівувати
- Архівувати всі
- Спам
- Помилка сертифікату для %s
- Перевірте налаштування вашого серверу
- Помилка автентифікації
- Помилка автентифікації для %s. Змініть налаштування сервера.
- Перевірка пошти: %s:%s
- Перевірка пошти
- Надсилання пошти: %s
- Надсилання пошти
- :
- Синхронізувати (пуш)
- Відображається під час очікування нових повідомлень
- Повідомлення
- Сповіщення, пов\'язані з повідомленнями
- Різне
- Різні сповіщення (про помилки тощо)
- Вхідні
- Вихідні
- Чернетки
- Кошик
- Надіслані
- Не вдалося надіслати деякі повідомлення
- Версія
- Увімкнути ведення журналу налагодження
- Записувати додаткову діагностичну інформацію
- Записувати конфіденційну інформацію
- Може відображати паролі в журналах.
- Завантажити більше повідомлень
- До:%s
- Тема
- Текст повідомлення
- Підпис
- -------- Вихідне повідомлення --------
- Тема:
- Надіслано:
- Від:
- Кому:
- Копія:
- %s написав(-ла):
- %1$s, %2$s написав(-ла):
- Додайте принаймні одного адресата.
- Поле адресата містить неповні дані!
- У цього контакту не знайдено жодної адреси електронної пошти.
- Деякі вкладення не можуть бути переслані, бо вони не завантажилися.
- Повідомлення не може бути переслане, тому що деякі вкладення не завантажені.
- Включити цитоване повідомлення
- Видалити цитований текст
- Редагувати цитований текст
- Видалити вкладення
- Від: %s <%s>
- Кому:
- Копія:
- Прихована копія:
- Відкрити
- Зберегти
- Не вдалося зберегти вкладення.
- Показати зображення
- Не знайдено додаток для перегляду %s.
- Завантажити усе повідомлення
- Не можу відобразити повідомлення
- за допомогою %1$s
-
- Всі заголовки завантажено, немає додаткових заголовків для відображення.
- Не вдалося завантажити додаткові заголовки з бази даних або поштового сервера.
- Більше від цього відправника
- Від %s
- Налагодження / Очистити тіло повідомлення
- Повідомлення скасовано
- Повідомлення збережено як чернетку
- Показувати зірочки
- Зірочки показують відмічені повідомлення
- Рядки попереднього перегляду
- Показувати імена відправників
- Показувати імена відправників замість їх електронних адрес
- Відправник вище теми
- Показувати імена відправників над темою, а не під нею
- Показувати імена контактів
- Використовувати імена одержувачів із Контактів, якщо це можливо
- Позначати контакти кольором
- Позначати кольором імена з вашого списку контактів
- Моноширинні шрифти
- Використовувати моноширинний шрифт для відображення звичайних текстових повідомлень
- Припасовувати текст повідомлень до ширини екрану
- Стискати повідомлення до ширини екрану
- Повернутися до списку після видалення
- Повернутися до списку повідомлень після видалення поточного повідомлення
- Показувати наступне повідомлення після видалення
- Показувати наступне повідомлення після видалення поточного повідомлення
- Підтвердження дій
- Показати діалогове вікно щоразу, коли ви виконуєте вибрані дії
- Видалити
- Видалити позначене зірочкою (при перегляді повідомлення)
- Спам
- Скасувати повідомлення
- Позначити всі повідомлення як прочитані
- Видалити (зі сповіщення)
- Приховати поштовий клієнт
- Remove Mail User-Agent from mail headers
- Приховати часову зону
- Використовувати UTC замість місцевого часу в заголовках листів та відповідей
- Приховувати тему в сповіщеннях
- Ніколи
- Коли пристрій заблоковано
- Завжди
- Показувати кнопку \"Видалити\"
- Ніколи
- У сповіщенні з одним повідомленням
- Завжди
- Сповіщення на заблокованому екрані
- Без сповіщень на заблокованому екрані
- Ім\'я додатку
- Кількість непрочитаних повідомлень
- Кількість повідомлень і відправники
- Так само, як і при розблокованому екрані
- Тиха Година
- Вимкнути звук, вібрацію та блимання у нічний час
- Вимкнути сповіщення
- Повністю вимкнути сповіщення під час Тихої Години
- Початок Тихої Години
- Кінець Тихої Години
- Налаштувати новий обліковий запис
- Адреса електронної пошти
- Пароль
- Показати пароль
- Ручне налаштування
-
- Отримання інформації про обліковий запис\u2026
- Перевірка налаштувань вхідного сервера\u2026
- Перевірка налаштувань вихідного сервера\u2026
- Автентифікація\u2026
- Отримання налаштувань облікового запису\u2026
- Скасування\u2026
- Майже готово!
- Дайте ім’я цьому обліковому запису (необов’язково):
- Введіть ваше ім’я (відображається у вихідних повідомленнях):
- Тип облікового запису
- Виберіть тип поштової скриньки
- POP3
- IMAP
- Звичайний пароль
- Пароль, що передається незахищено
- Зашифрований пароль
- Сертифікат клієнта
- Налаштування сервера вхідних повідомлень
- Ім’я користувача
- Пароль
- Сертифікат клієнта
- Сервер POP3
- Сервер IMAP
- Сервер Exchange
- Порт
- Тип системи захисту
- Метод автентифікації
- Немає
- SSL/TLS
- STARTTLS
- \"%1$s = %2$s\" недійсне з \"%3$s = %4$s\"
- Коли я видаляю повідомлення
- Не видаляти на сервері
- Видаляти на сервері
- Позначити як прочитане на сервері
- Використовувати стискання даних у мережі:
- Мобільний інтернет
- WI-FI
- Інше
- Зовнішня пам’ять (SD-карта)
- Постійна внутрішня пам’ять
- Стирати видалені повідомлення на сервері
- Негайно
- При опитуванні сервера
- Вручну
- Автовизначення області імен IMAP
- Префікс шляху IMAP
- Назва теки Чернеток
- Назва теки Надісланих
- Назва теки Кошику
- Назва теки Архіву
- Назва теки Спам
- Показувати лише теки, на які здійснено підписку
- Автоматично відкривати теку
- Шлях Outlook Web Access
- Необов’язкове
- Шлях для автентифікації
- Необов’язкове
- Псевдонім поштової скриньки
- Необов’язкове
- Налаштування сервера вихідної пошти
- Сервер SMTP
- Порт
- Тип системи захисту
- Завжди вимагати входу в систему.
- Ім’я користувача
- Пароль
- Метод автентифікації
- \"%1$s = %2$s\" недійсне з \"%3$s = %4$s\"
- Неправильне налаштування: %s
- Параметри облікового запису
- Стиснути обліковий запис
- Частота опитування тек
- Ніколи
- Кожні 15 хвилин
- Кожні 30 хвилин
- Кожної години
- Кожні 2 години
- Кожні 3 години
- Кожні 6 годин
- Кожні 12 годин
- Кожні 24 години
- Використовувати push для цього облікового запису
- Якщо ваш сервер підтримує таку можливість, то нові повідомлення з\'являтимуться моментально. Цей параметр може істотно покращити або погіршити швидкодію.
- Оновлювати з’єднання IMAP IDLE
- Кожні 2 хвилини
- Кожні 3 хвилини
- Кожні 6 хвилин
- Кожні 12 хвилин
- Кожні 24 хвилини
- Кожні 36 хвилин
- Кожні 48 хвилин
- Кожні 60 хвилин
- Сповіщати мене про отримання нової пошти
- Сповіщати мене, коли триває перевірка пошти
- Кількість відображуваних повідомлень
- 10 повідомлень
- 25 повідомлень
- 50 повідомлень
- 100 повідомлень
- 250 повідомлень
- 500 повідомлень
- 1000 повідомлень
- 2500 повідомлень
- 5000 повідомлень
- 10000 повідомлень
- усі повідомлення
- Не можна копіювати чи переміщувати повідомлення, не синхронізоване з сервером
- Не вдалося завершити налаштування
- Ім\'я користувача або пароль невірні.\n(%s)
- Сервер надав недійсний сертифікат SSL. Це може бути зумовлено неналежним налаштуванням сервера або тим, що хтось намагається атакувати вас чи ваш поштовий сервер. Якщо ви не впевнені в тому, що відбувається, натисність "Відхилити" та зв’яжіться з адміністраторами вашого поштового серверу.\n\n(%s)
- Не можу з\'єднатися з сервером.\n(%s)
- Редагувати деталі
- Продовжити
- Додатково
- Параметри облікового запису
- Типовий обліковий запис
- Типово надсилати пошту з цього облікового запису
- Сповіщення про нову пошту
- Теки, щодо яких показуються сповіщення
- Усі
- Лише теки 1-го класу
- Теки 1-го та 2-го класів
- Усі, крім тек 2-го класу
- Жодної
- Сповіщення про синхронізацію
- Адреса вашої електронної пошти
- Сповіщати у рядку стану про нові листи
- Сповіщати у рядку стану про перевірку пошти
- Включити вихідні повідомлення
- Показати сповіщення про надіслані мною повідомлення
- Лише контактам
- Показувати сповіщення лише для повідомлень від вже відомих контактів
- Позначати повідомлення прочитаним після відкриття
- Позначати повідомлення прочитаним після відкриття для перегляду
- Позначити прочитаним після видалення
- Позначити повідомлення прочитаним після видалення
- Налаштування сповіщень
- Відкрити системні налаштування сповіщень
- Завжди показувати зображення
- Ні
- Від контактів
- Від усіх
- Надсилання повідомлення
- Цитувати повідомлення при відповіді на нього
- Включати оригінальне повідомлення у відповідь.
- Текст відповіді після цитованого тексту
- Оригінальне повідомлення відобразиться над вашою відповіддю.
- Видаляти підписи з цитованого повідомлення при відповіді
- Підписи цитованого повідомлення будуть видалені при відповіді
- Формат повідомлення
- Звичайний текст (видалити зображення та форматування)
- HTML (зберігати зображення та форматування)
- Автоматичний (звичайний текст, якщо тільки не створюється відповідь на повідомлення HTML-формату)
- Завжди показувати поля \"Копія\" / \"Прихована копія\"
- Звіт про прочитання
- Завжди запитувати звіт про прочитання
- Стиль цитування при відповіді
- Префікс (наприклад, Gmail)
- Заголовок (наприклад, Outlook)
- Вивантажити надіслані повідомлення
- Вивантажити повідомлення в теку \"Надіслані\" після надсилання
- Загальні налаштування
- Читання повідомлення
- Отримання пошти
- Теки
- Префікс цитованого тексту
- Наскрізне шифрування
- Увімкнути підтримку OpenPGP
- Обрати додаток OpenPGP
- Налаштувати ключ наскрізного шифрування
- Не налаштовано жодного OpenPGP-додатку
- Підключено до %s
- Налаштування...
- Зберігати усі чернетки зашифрованими
- Усі чернетки будуть зберігатися зашифрованими
- Шифрувати чернетки тільки якщо шифрування увімкнено
- Частота опитування тек
- Колір облікового запису
- Виберіть колір облікового запису для тек та списку облікових записів
- Без кольору
- Колір LED-індикатору сповіщення
- Колір блимання LED-індикатору вашого телефону для цього облікового запису
- Розмір локальної теки
- Отримувати повідомлення розміром до
- 1 КБ
- 2 КБ
- 4 КБ
- 8 КБ
- 16 КБ
- 32 КБ
- 64 КБ
- 128 КБ
- 256 КБ
- 512 КБ
- 1 МБ
- 2 МБ
- 5 МБ
- 10 МБ
- будь-якого розміру (без обмежень)
- Синхронізувати повідомлення за
- увесь час (без обмежень)
- сьогодні
- останні 2 дні
- останні 3 дні
- останній тиждень
- останні 2 тижні
- останні 3 тижні
- останній місяць
- останні 2 місяці
- останні 3 місяці
- останні 6 місяців
- останній рік
- Теки для відображення
- Усі
- Тільки теки 1-го класу
- Теки 1-го та 2-го класу
- Усі, крім тек 2-го класу
- Теки для опитування
- Усі
- Тільки теки 1-го класу
- Теки 1-го та 2-го класу
- Усі, крім тек 2-го класу
- Нічого
- Теки для надсилання
- Усі
- Тільки теки 1-го класу
- Теки 1-го та 2-го класу
- Усі, крім тек 2-го класу
- Нічого
- Теки призначення при переміщенні / копіюванні
- Усі
- Тільки теки 1-го класу
- Теки 1-го та 2-го класу
- Усі, крім тек 2-го класу
- Синхронізація видалень на сервері
- Видаляти повідомлення синхронно з видаленням на сервері
- Немає OpenPGP-додатка - він був видалений?
- Налаштування тек
- Показувати у верхній групі
- Показувати у верхній частині списку тек
- Клас відображення теки
- Без класу
- 1-ий клас
- 2-ий клас
- Клас опитування теки
- Немає
- 1-ий клас
- 2-ий клас
- Такий самий, як і клас відображення
- Клас надсилання теки
- Без класу
- 1-ий клас
- 2-ий клас
- Такий як і клас розкладу (poll)
- Клас сповіщення теки
- Без класу
- 1-й клас
- 2-й клас
- Такий самий, як і клас надсилання
- Видалити локальні повідомлення
- Сервер вхідної пошти
- Налаштувати сервер вхідної пошти
- Сервер вихідної пошти
- Налаштувати сервер вихідної пошти (SMTP)
- Ім’я облікового запису
- Ваше ім’я
- Сповіщення
- Вібрація
- Вібрація при отрманні нової пошти
- Шаблони вібрації
- типовий
- шаблон 1
- шаблон 2
- шаблон 3
- шаблон 4
- шаблон 5
- Повторити вібрацію
- Звук сповіщення про новий лист
- Блимання LED-індикатором
- Блимання LED-індикатором при отриманні нового листа
- Параметри створення повідомлень
- Типові налаштування написання листів
- Встановити типові значення полів \"Від\", \"Прихована копія\" і підпис
- Управління особами
- Встановити альтернативні адреси \"Від\" та підписи
- Управління особами
- Управління особою
- Редагувати особу
- Зберегти
- Нова особа
- Прихована копія усіх повідомлень до
- Редагувати
- Пересунути вище
- Пересунути нижче
- Пересунути на початок / зробити типовою
- Видалити
- Опис особи
- (Необов’язково)
- Ваше ім’я
- (Необов’язково)
- Адреса електронної пошти
- (Обов’язково)
- Відповідати на адресу
- (Необов’язково)
- Підпис
- (Обов’язково)
- Використовувати підпис
- Підпис
- Початкова особа
- Вибрати особу
- Надіслати як
- Не можна видалити останню особу
- Не можна використовувати особу без адреси електронної пошти
- Спершу старі повідомлення
- Спершу нові повідомлення
- Тема за алфавітом
- Тема за алфавітом у зворотньому порядку
- Відправники за алфавітом
- Відправники за алфавітом в зворотньому порядку
- Спершу повідомлення із зірочками
- Спершу повідомлення без зірочок
- Спершу непрочитані повідомлення
- Спершу прочитані повідомлення
- Спершу повідомлення з вкладеннями
- Спершу повідомлення без вкладень
- Упорядкувати за…
- датою
- часом отримання
- темою
- відправником
- наявністю зірочки
- статусом прочитання
- наявністю вкладень
- Видалити обліковий запис
- Нерозпізнаний сертифікат
- Прийняти ключ
- Відхилити ключ
- Del (або D) - Видалити\nR - Відповісти\nA - Відповісти всім\nC - Написати лист\nF - Переслати\nM - Перемістити\nV - Архівувати\nY - Копіювати\nZ - Позначити (не)прочитаним\nG - Позначити зірочкою\nO - Тип сортування\nI - Порядок сортування\nQ - Повернутися до тек\nS - Вибрати / Зняти вибір\nJ або P - Попереднє повідомлення\nK або N - Наступне повідомлення
- Del (або D) - Видалити\nC - Написати лист\nM - Перемістити\nV - Архівувати\nY - Копіювати\nZ - Позначити (не)прочитаним\nG - Позначити зірочкою\nO - Тип сортування\nI - Порядок сортування\nQ - Поввернутися до тек\nS - Вибрати / Зняти вибір
- Назва теки містить
- Показати теки…
- Відображати усі теки
- Відображати тільки теки 1-го класу
- Відображати теки 1-го і 2-го класу
- Відображати усі, крім тек 2-го класу
- Розташування підпису
- перед цитованим повідомленням
- після цитованого повідомлення
- Використовувати тему додатку
- Темна
- Світла
- Типова системна
- Екран
- Глобальні
- Відлагодження
- Конфіденційність
- Мережа
- Взаємодія
- Список облікових записів
- Списки повідомлень
- Повідомлення
- Тема
- Тема екрану перегляду повідомлення
- Тема екрану створення повідомлення
- Мова
- Налаштування не знайдені
- Фіксована тема повідомлення
- Виберіть тему екрану перегляду повідомлення під час перегляду повідомлення
- Використовувати фіксовану тему перегляду повідомлення
- Системна (System default)
- Фонова синхронізація
- Ніколи
- Завжди
- Коли \"Автосинхронізація\" увімкнена
- Вибрати усе
- Найбільша кількість тек для перевірки при надсиланні
- 5 тек
- 10 тек
- 25 тек
- 50 тек
- 100 тек
- 250 тек
- 500 тек
- 1000 тек
- Анімація
- Використовувати яскраві візуальні ефекти
- Навігація кнопками зміни гучності
- при перегляді повідомлень
- у списках
- %s%s
- - Непрочитані
- Всі повідомлення
- Всі повідомлення у теках для пошуку
- Об\'єднані Вхідні
- Усі повідомлення в об\'єднаних теках
- Об’єднати
- Усі повідомлення показуються у теці \"Об\'єднані Вхідні\"
- Теки для пошуку
- Всі
- Видимі
- Жодна
- Жодної
- Автоматично (%s)
- Розмір шрифту
- Налаштувати розмір шрифту
- Список облікових записів
- Ім’я облікового запису
- Опис облікового запису
- Списки тек
- Назва теки
- Статус теки
- Списки повідомлень
- Тема
- Відправник
- Дата
- Попередній перегляд
- Повідомлення
- Відправник
- Кому
- Копія
- Прихована копія
- Додаткові заголовки
- Тема
- Час і дата
- Тіло повідомлення
- %d%%
- %1$s: %2$s
- Створення повідомлення
- Поля для вводу тексту
- Типовий
- Найдрібніший
- Дрібний
- Менший
- Малий
- Середній
- Великий
- Більший
- Для цієї дії не знайдено відповідного додатку.
- Помилка відправки: %s
- Зберегти чернетку повідомлення?
- Зберегти чи Скасувати зміни?
- Зберегти чи Скасувати це повідомлення?
- Скасувати повідомлення?
- Ви дійсно хочете скасувати це повідомлення?
- Виберіть текст для копіювання.
- Очистити локальні повідомлення?
- Це видалить всі локальні повідомлення з теки. Жодне повідомлення не буде видалене з сервера.
- Очистити повідомлення
- Підтвердіть видалення
- Ви хочете видалити це повідомлення?
-
- Ви дійсно хочете видалити це повідомлення?
- Ви дійсно хочете видалити %1$d повідомлень?
- Ви дійсно хочете видалити %1$d повідомлень?
- Ви дійсно хочете видалити %1$d повідомлень?
-
- Так
- Ні
- Підтвердіть позначення усіх повідомлень прочитаними
- Хочете позначити усі повідомлення прочитаними?
- Підтвердіть очищення кошика
- Ви хочете очистити теку \"Кошик\"?
- Так
- Ні
- Підтвердіть переміщення в теку \"Спам\"
-
- Ви дійсно хочете перемістити це повідомлення в спам?
- Ви дійсно хочете перемістити %1$d повідомлень у спам?
- Ви дійсно хочете перемістити %1$d повідомлень у спам?
- Ви дійсно хочете перемістити %1$d повідомлень у теку \"Спам\"?
-
- Так
- Ні
- Завантаження вкладення
- »
- ›
- Резервне копіювання
- Різне
- Експорт налаштувань
- Експорт
- Поділитися
- Експортуються налаштування…
- Налаштування успішно експортовані
- Не вдалося експортувати налаштування
- Імпортувати налаштування
- Вибрати файл
- Імпорт
- Налаштування успішно імпортовано
- Введіть паролі
- Не вдалося імпортувати налаштування
- Не вдалося прочитати файл з налаштуваннями
- Не вдалося імпортувати деякі налаштування
- Успішно імпортовано
- Потрібен пароль
- Не імпортовано
- Збій імпортування
- Пізніше
- Імпортувати налаштування
- Імпортуються налаштування…
-
- Щоб користуватися обліковим записом %s, потрібно надати пароль сервера.
- Щоб користуватися обліковим записом %s, потрібно надати паролі сервера.
- Щоб користуватися обліковим записом %s, потрібно надати паролі сервера.
- Щоб користуватися обліковим записом %s, потрібно надати паролі сервера.
-
- Пароль сервера вхідної пошти
- Пароль сервера вихідної пошти
- Використовувати той же пароль для сервера вихідної пошти
- Ім\'я сервера: %s
- Показати кількість непрочитаних для…
- Обліковий запис
- Обліковий запис, для якого має відображатися кількість непрочитаних листів
- Об\'єднані Вхідні
- Показувати Об\'єднані Вхідні
- Кількість тек
- Показати кількість непрочитаних листів тільки однієї теки
- Тека
- Тека, для якої має відображатися кількість непрочитаних листів
- Готово
- %1$s - %2$s
- Не вибрано жодного облікового запису
- Не вибрано жодної теки
- Нема тексту
- Відкрити посилання
- Надіслати посилання
- Скопіювати текст посилання у буфер обміну
- Текст посилання
- Посилання
- Зображення
- Переглянути зображеня
- Зберегти зображення
- Завантажити зображення
- Копіювати посилання на зображення до буфера обміну
- Посилання на зображення
- Подзвонити за номером
- Зберегти до Контактів
- Копіювати телефонний номер до буфера обміну
- Телефонний номер
- Надіслати листа
- Зберегти до Контактів
- Копіювати електронну адресу до буфера обміну
- Електронна адреса
- Всі
- 10
- 25
- 50
- 100
- 250
- 500
- 1000
- Обмеження пошуку на сервері
- Надсилання запиту до сервера
-
- Отримання %dрезультату
- Отримання %dрезультатів
- Отримання %d результатів
- Отримання %d результатів
-
-
- Отримання %1$d з %2$d результату
- Отримання %1$d з %2$d результатів
- Отримання %1$d з %2$d результатів
- Отримання %1$d з %2$d результатів
-
- Віддалений пошук не вдався
- Пошук
- Увімкнути пошук на сервері
- Шукати повідомлення на сервері на додаток до тих, що є на вашому пристрої
- Шукати повідомлення на сервері
- Для пошуку на сервері необхідне з\'єднання з мережею.
- Змінювати колір при прочитанні
- Інший колір фону буде означати, що повідомлення прочитане
- Групування повідомлень
- Групувати повідомлення у діалоги
- Оновлення баз даних
- Оновлення баз даних…
- Оновлення баз даних облікового запису \"%s\"
- Перегляд на розділеному екрані
- Завжди
- Ніколи
- Коли в альбомній орієнтації
- Будь ласка, виберіть повідомлення зліва
- Показувати зображення контактів
- Показувати зображення контактів в списку повідомлень
- Позначити усе прочитаним
- Позначати кольором зображення контактів
- Позначати кольором зображення відсутніх контактів
- Видимі дії над повідомленням
- Показувати вибрані дії в меню перегляду повідомлень
- Завантаження вкладення…
- Надсилання повідомлення
- Збереження чернетки
- Отримання вкладення…
- Автентифікація неможлива. Сервер не декларує здатність працювати з SASL EXTERNAL. Це може бути спричинено проблемою з сертифікатом клієнта (сплив строк дії, невідомий центр сертифікації) або іншою проблемою налаштувань.
-
- Використовувати сертифікат клієнта
- Сертифікат клієнта відсутній
- Прибрати вибір сертифіката клієнта
- Не вдалося отримати сертифікат клієнта для \"%s\"
- Розширені налаштування
- Сертифікат клієнта \"%1$s\" втратив чинність або ще не набрав чинності (%2$s)
-
- *Зашифровано*
- Додати з Контактів
- Копія
- Прихована копія
- До
- Від
-
- <Невідомий Адресат>
- <Невідомий Відправник>
- Домашній
- Робочий
- Інший
- Мобільний
- Теку \"Чернетки\" не налаштовано для цього облікового запису!
- Ключ не налаштовано для цього облікового запису! Перевірте налаштування.
- Криптопровайдер використовує несумісну версію. Перевірте свої налаштування.
- Не можу з\'єднатися з провайдером шифрування; перевірте ваші налаштування або натисніть значок шифрування, щоб спробувати знову!
- Не вдалося ініціалізувати наскрізне шифрування. Перевірте свої налаштування.
- Режим PGP/INLINE не підтримує вкладення!
- Увімкнути PGP/INLINE
- Вимкнути PGP/INLINE
- Увімкнути PGP Sign-Only
- Вимкнути PGP Sign-Only
- Режим PGP/INLINE
- Електронний лист буде відправлено в форматі PGP/INLINE.\nВикоритовуйте лише з метою забезпечення сумісності:
- Деякі клієнти підтримують лише цей формат
- Підписи можуть ламатися під час передачі
- Вкладення не підтримуються
- Зрозуміло!
- Вимкнути
- Залишити увімкненим
- Зрозуміло!
- Вимкнути
- Залишити увімкненим
- Режим PGP Sign-Only
- У цьому режимі ваш PGP-ключ буде використаний для створення криптографічного підпису незашифрованого електронного листа.
- Це не шифрує електронний лист, але засвідчує, що він був надісланий від вашого ключа.
- Підписи можуть бути пошкоджені при надсиланні листа у списки розсилки.
- Деякі клієнти можуть відображати підписи як вкладення \'signature.asc\'.
- Зашифровані листи завжди містять підпис.
- Простий текст
- підпис наскрізного шифрування містив помилку
- необхідно повністю завантажити повідомлення для обробки підпису
- містить непідтримуваний підпис наскрізного шифрування
- Повідомлення зашифроване, але цей формат не підтримується.
- Повідомлення зашифроване, але розшифровування було скасоване.
- Звичайний текст, підписаний наскрізним шифруванням
- від перевіреного підписувача
- Підписаний звичайний текст
- але ключ наскрізного шифрування не співпав з ключем відправника
- але термін дійсності ключа наскрізного шифрування минув
- але ключ наскрізного шифрування відкликано
- але ключ наскрізного шифрування не вважається безпечним
- від невідомого ключа наскрізного шифрування
- Зашифровано
- але виникла помилка розшифрування
- необхідно повністю завантажити повідомлення для розшифровки
- але не налаштовано жодного криптографічного додатку
- Зашифровано
- але не наскрізне
- Зашифровано наскрізним шифруванням
- від перевіреного відправника
- Зашифровано
- від невідомого ключа наскрізного шифрування
- але ключ наскрізного шифрування не співпав з ключем відправника
- але термін дійсності ключа наскрізного шифрування минув
- але ключ наскрізного шифрування відкликано
- але ключ наскрізного шифрування не вважається безпечним
- але зашифрована наскрізним шифруванням інформація містить помилки
- але шифрування не вважається безпечним
- Гаразд
- Пошук ключа
- Переглянути підписувача
- Переглянути відправника
- Деталі
- Розблокувати
- Ця частина не була зашифрована і може бути небезпечною.
- Незахищене вкладення
- Завантаження…
- Розшифровування скасовано.
- Спробувати знову
- Для розшифровування зашифроване повідомлення необхідно завантажити.
- Помилка під час розшифровування електронного листа
- Спеціальні символи наразі не підтримуються!
- Помилка розбору адреси!
- Приховати незашифровані підписи
- Тільки зашифровані підписи будуть відображені
- Усі підписи будуть відображені
- Шифрування недоступне у режимі PGP Sign-Only
- Непідписаний Текст
- Попередження про застарілість APG
- APG більше не підтримується!
- Через це підтримку APG було видалено з K-9 Mail.
- Розробка зупинена на початку 2014
- Містить невиправлені проблеми з безпекою
- Ви можете перейти сюди, щоб дізнатися більше.
- Зрозуміло!
- APG
- Цей електронний лист зашифровано
- Цей електронний лист було зашифровано за допомогою OpenPGP.\nЩоб його прочитати, необхідно встановити та налаштувати сумісний OpenPGP-додаток.
- Перейти до Налаштувань
- Mail Message List
- Завантаження листів…
- Не вдалося отримати список тек
- Не вдалося отримати статус адресата від провайдера OpenPGP.
- Шифрування неможливе
- Деякі з вибраних адресатів не підтримують цю функцію.
- Увімкнути шифрування
- Вимкнути шифрування
- Шифрування повідомлень гарантує, що вони можуть бути прочитані адресатом, і ніким іншим.
- Можливість шифрування відображатиметься лише в тому випадку, якщо його підтримують усі адресати і якщо вони раніше надсилали вам електронного листа.
- Перемкніть шифрування цією піктограмою.
- Зрозуміло
- Назад
- Вимкнути шифрування
- Шифрування OpenPGP
- Автоматичне шифрування у режимі взаємності
- Автоматичне шифрування у режимі взаємності
- Повідомлення будуть шифруватися за вашим вибором або при відповіді на шифроване повідомлення.
- Якщо і відправник, і адресат увімкнуть режим взаємності, шифрування типово буде увімкнене.
- Ви можете перейти сюди, щоб дізнатися більше.
- Загальні налаштування
- Не встановлено додатка OpenPGP
- Встановити
- Mail requires OpenKeychain for end-to-end encryption.
- Зашифроване повідомлення
- Шифрувати теми повідомлень
- Може не підтримуватися деякими адресатами
- Внутрішня помилка: Недійсний обліковий запис!
- Помилка підключення до %s!
- Надіслати Повідомлення з Налаштуваннями Автоматичного Шифрування
- Безпечно поділитися налаштуваннями наскрізного шифрування з іншими пристроями
- Повідомлення з Налаштуваннями Автоматичного Шифрування
- Повідомлення з Налаштуваннями Автоматичного Шифрування безпечно надсилає ваші налаштування наскрізного шифрування на інші пристрої.
- Надіслати Повідомлення з Налаштуваннями
- Повідомлення буде надіслано на вашу адресу:
- Створення повідомлення з налаштуваннями...
- Надсилання повідомлення до:
- Для завершення налаштування відкрийте повідомлення на іншому своєму пристрої та введіть Код Налаштування.
- Показати Код Налаштування
- Повідомлення з Налаштуваннями Автоматичного Шифрування
- Це повідомлення містить усю інформацію для безпечного надсилання налаштувань автоматичного шифрування разом з секретним ключем з вашого пристрою.
+ %.1f ГБ
+ %.1f МБ
+ %.1f кБ
+ %d Б
+ Розмір облікового запису \"%s\" зменшився з %s до %s
+ Стиснення облікового запису \"%s\"
+ Нова пошта
+
+ %d нове повідомлення
+ %d нових повідомлень
+ %d нових повідомлень
+ %d нових повідомлень
+
+ %d непрочитане(-их) (%s)
+ ще %1$d у %2$s
+ Відповісти
+ Позначити прочитаним
+ Позначити всі прочитаними
+ Видалити
+ Видалити всі
+ Архівувати
+ Архівувати всі
+ Спам
+ Помилка сертифікату для %s
+ Перевірте налаштування вашого серверу
+ Помилка автентифікації
+ Помилка автентифікації для %s. Змініть налаштування сервера.
+ Перевірка пошти: %s:%s
+ Перевірка пошти
+ Надсилання пошти: %s
+ Надсилання пошти
+ :
+ Синхронізувати (пуш)
+ Відображається під час очікування нових повідомлень
+ Повідомлення
+ Сповіщення, пов\'язані з повідомленнями
+ Різне
+ Різні сповіщення (про помилки тощо)
+ Вхідні
+ Вихідні
+ Чернетки
+ Кошик
+ Надіслані
+ Не вдалося надіслати деякі повідомлення
+ Версія
+ Увімкнути ведення журналу налагодження
+ Записувати додаткову діагностичну інформацію
+ Записувати конфіденційну інформацію
+ Може відображати паролі в журналах.
+ Завантажити більше повідомлень
+ До:%s
+ Тема
+ Текст повідомлення
+ Підпис
+ -------- Вихідне повідомлення --------
+ Тема:
+ Надіслано:
+ Від:
+ Кому:
+ Копія:
+ %s написав(-ла):
+ %1$s, %2$s написав(-ла):
+ Додайте принаймні одного адресата.
+ Поле адресата містить неповні дані!
+ У цього контакту не знайдено жодної адреси електронної пошти.
+ Деякі вкладення не можуть бути переслані, бо вони не завантажилися.
+ Повідомлення не може бути переслане, тому що деякі вкладення не завантажені.
+ Включити цитоване повідомлення
+ Видалити цитований текст
+ Редагувати цитований текст
+ Видалити вкладення
+ Від: %s <%s>
+ Кому:
+ Копія:
+ Прихована копія:
+ Відкрити
+ Зберегти
+ Не вдалося зберегти вкладення.
+ Показати зображення
+ Не знайдено додаток для перегляду %s.
+ Завантажити усе повідомлення
+ Не можу відобразити повідомлення
+ за допомогою %1$s
+
+ Всі заголовки завантажено, немає додаткових заголовків для відображення.
+ Не вдалося завантажити додаткові заголовки з бази даних або поштового сервера.
+ Більше від цього відправника
+ Від %s
+ Налагодження / Очистити тіло повідомлення
+ Повідомлення скасовано
+ Повідомлення збережено як чернетку
+ Показувати зірочки
+ Зірочки показують відмічені повідомлення
+ Рядки попереднього перегляду
+ Показувати імена відправників
+ Показувати імена відправників замість їх електронних адрес
+ Відправник вище теми
+ Показувати імена відправників над темою, а не під нею
+ Показувати імена контактів
+ Використовувати імена одержувачів із Контактів, якщо це можливо
+ Позначати контакти кольором
+ Позначати кольором імена з вашого списку контактів
+ Моноширинні шрифти
+ Використовувати моноширинний шрифт для відображення звичайних текстових повідомлень
+ Припасовувати текст повідомлень до ширини екрану
+ Стискати повідомлення до ширини екрану
+ Повернутися до списку після видалення
+ Повернутися до списку повідомлень після видалення поточного повідомлення
+ Показувати наступне повідомлення після видалення
+ Показувати наступне повідомлення після видалення поточного повідомлення
+ Підтвердження дій
+ Показати діалогове вікно щоразу, коли ви виконуєте вибрані дії
+ Видалити
+ Видалити позначене зірочкою (при перегляді повідомлення)
+ Спам
+ Скасувати повідомлення
+ Позначити всі повідомлення як прочитані
+ Видалити (зі сповіщення)
+ Приховати поштовий клієнт
+ Прибрати K-9 User-Agent з поштових заголовків
+ Приховати часову зону
+ Використовувати UTC замість місцевого часу в заголовках листів та відповідей
+ Показувати кнопку \"Видалити\"
+ Ніколи
+ У сповіщенні з одним повідомленням
+ Завжди
+ Сповіщення на заблокованому екрані
+ Без сповіщень на заблокованому екрані
+ Ім\'я додатку
+ Кількість повідомлень і відправники
+ Так само, як і при розблокованому екрані
+ Тиха Година
+ Вимкнути звук, вібрацію та блимання у нічний час
+ Вимкнути сповіщення
+ Повністю вимкнути сповіщення під час Тихої Години
+ Початок Тихої Години
+ Кінець Тихої Години
+ Налаштувати новий обліковий запис
+ Адреса електронної пошти
+ Пароль
+ Показати пароль
+
+ Ручне налаштування
+
+ Отримання інформації про обліковий запис\u2026
+ Перевірка налаштувань вхідного сервера\u2026
+ Перевірка налаштувань вихідного сервера\u2026
+ Автентифікація\u2026
+ Отримання налаштувань облікового запису\u2026
+ Скасування\u2026
+ Майже готово!
+ Дайте ім’я цьому обліковому запису (необов’язково):
+ Введіть ваше ім’я (відображається у вихідних повідомленнях):
+ Тип облікового запису
+ Виберіть тип поштової скриньки
+ POP3
+ IMAP
+ Звичайний пароль
+ Пароль, що передається незахищено
+ Зашифрований пароль
+ Сертифікат клієнта
+ Налаштування сервера вхідних повідомлень
+ Ім’я користувача
+ Пароль
+ Сертифікат клієнта
+ Сервер POP3
+ Сервер IMAP
+ Сервер Exchange
+ Порт
+ Тип системи захисту
+ Метод автентифікації
+ Немає
+ SSL/TLS
+ STARTTLS
+ \"%1$s = %2$s\" недійсне з \"%3$s = %4$s\"
+ Коли я видаляю повідомлення
+ Не видаляти на сервері
+ Видаляти на сервері
+ Позначити як прочитане на сервері
+ Використовувати стискання даних у мережі:
+ Мобільний інтернет
+ WI-FI
+ Інше
+ Стирати видалені повідомлення на сервері
+ Негайно
+ При опитуванні сервера
+ Вручну
+ Автовизначення області імен IMAP
+ Префікс шляху IMAP
+ Назва теки Чернеток
+ Назва теки Надісланих
+ Назва теки Кошику
+ Назва теки Архіву
+ Назва теки Спам
+ Показувати лише теки, на які здійснено підписку
+ Автоматично відкривати теку
+ Шлях Outlook Web Access
+ Необов’язкове
+ Шлях для автентифікації
+ Необов’язкове
+ Псевдонім поштової скриньки
+ Необов’язкове
+ Налаштування сервера вихідної пошти
+ Сервер SMTP
+ Порт
+ Тип системи захисту
+ Завжди вимагати входу в систему.
+ Ім’я користувача
+ Пароль
+ Метод автентифікації
+ \"%1$s = %2$s\" недійсне з \"%3$s = %4$s\"
+ Неправильне налаштування: %s
+ Параметри облікового запису
+ Стиснути обліковий запис
+ Частота опитування тек
+ Ніколи
+ Кожні 15 хвилин
+ Кожні 30 хвилин
+ Кожної години
+ Кожні 2 години
+ Кожні 3 години
+ Кожні 6 годин
+ Кожні 12 годин
+ Кожні 24 години
+ Використовувати push для цього облікового запису
+ Якщо ваш сервер підтримує таку можливість, то нові повідомлення з\'являтимуться моментально. Цей параметр може істотно покращити або погіршити швидкодію.
+ Оновлювати з’єднання IMAP IDLE
+ Кожні 2 хвилини
+ Кожні 3 хвилини
+ Кожні 6 хвилин
+ Кожні 12 хвилин
+ Кожні 24 хвилини
+ Кожні 36 хвилин
+ Кожні 48 хвилин
+ Кожні 60 хвилин
+ Сповіщати мене про отримання нової пошти
+ Сповіщати мене, коли триває перевірка пошти
+ Кількість відображуваних повідомлень
+ 10 повідомлень
+ 25 повідомлень
+ 50 повідомлень
+ 100 повідомлень
+ 250 повідомлень
+ 500 повідомлень
+ 1000 повідомлень
+ 2500 повідомлень
+ 5000 повідомлень
+ 10000 повідомлень
+ усі повідомлення
+ Не можна копіювати чи переміщувати повідомлення, не синхронізоване з сервером
+ Не вдалося завершити налаштування
+ Ім\'я користувача або пароль невірні.\n(%s)
+ Сервер надав недійсний сертифікат SSL. Це може бути зумовлено неналежним налаштуванням сервера або тим, що хтось намагається атакувати вас чи ваш поштовий сервер. Якщо ви не впевнені в тому, що відбувається, натисність "Відхилити" та зв’яжіться з адміністраторами вашого поштового серверу.\n\n(%s)
+ Не можу з\'єднатися з сервером.\n(%s)
+ Редагувати деталі
+ Продовжити
+ Додатково
+ Параметри облікового запису
+ Сповіщення про нову пошту
+ Теки, щодо яких показуються сповіщення
+ Усі
+ Лише теки 1-го класу
+ Теки 1-го та 2-го класів
+ Усі, крім тек 2-го класу
+ Жодної
+ Сповіщення про синхронізацію
+ Адреса вашої електронної пошти
+ Сповіщати у рядку стану про нові листи
+ Сповіщати у рядку стану про перевірку пошти
+ Включити вихідні повідомлення
+ Показати сповіщення про надіслані мною повідомлення
+ Лише контактам
+ Показувати сповіщення лише для повідомлень від вже відомих контактів
+ Позначати повідомлення прочитаним після відкриття
+ Позначати повідомлення прочитаним після відкриття для перегляду
+ Позначити прочитаним після видалення
+ Позначити повідомлення прочитаним після видалення
+ Категорії сповіщень
+ Налаштуйте сповіщення для нових повідомлень
+ Налаштуйте сповіщення про помилки та статуси
+ Завжди показувати зображення
+ Ні
+ Від контактів
+ Від усіх
+ Надсилання повідомлення
+ Цитувати повідомлення при відповіді на нього
+ Включати оригінальне повідомлення у відповідь.
+ Текст відповіді після цитованого тексту
+ Оригінальне повідомлення відобразиться над вашою відповіддю.
+ Видаляти підписи з цитованого повідомлення при відповіді
+ Підписи цитованого повідомлення будуть видалені при відповіді
+ Формат повідомлення
+ Звичайний текст (видалити зображення та форматування)
+ HTML (зберігати зображення та форматування)
+ Автоматичний (звичайний текст, якщо тільки не створюється відповідь на повідомлення HTML-формату)
+ Завжди показувати поля \"Копія\" / \"Прихована копія\"
+ Звіт про прочитання
+ Завжди запитувати звіт про прочитання
+ Стиль цитування при відповіді
+ Префікс (наприклад, Gmail)
+ Заголовок (наприклад, Outlook)
+ Вивантажити надіслані повідомлення
+ Вивантажити повідомлення в теку \"Надіслані\" після надсилання
+ Загальні налаштування
+ Читання повідомлення
+ Отримання пошти
+ Теки
+ Префікс цитованого тексту
+ Наскрізне шифрування
+ Увімкнути підтримку OpenPGP
+ Обрати додаток OpenPGP
+ Налаштувати ключ наскрізного шифрування
+ Не налаштовано жодного OpenPGP-додатку
+ Підключено до %s
+ Налаштування...
+ Зберігати усі чернетки зашифрованими
+ Усі чернетки будуть зберігатися зашифрованими
+ Шифрувати чернетки тільки якщо шифрування увімкнено
+ Частота опитування тек
+ Колір облікового запису
+ Виберіть колір облікового запису для тек та списку облікових записів
+ Без кольору
+ Колір LED-індикатору сповіщення
+ Колір блимання LED-індикатору вашого телефону для цього облікового запису
+ Розмір локальної теки
+ Отримувати повідомлення розміром до
+ 1 КБ
+ 2 КБ
+ 4 КБ
+ 8 КБ
+ 16 КБ
+ 32 КБ
+ 64 КБ
+ 128 КБ
+ 256 КБ
+ 512 КБ
+ 1 МБ
+ 2 МБ
+ 5 МБ
+ 10 МБ
+ будь-якого розміру (без обмежень)
+ Синхронізувати повідомлення за
+ увесь час (без обмежень)
+ сьогодні
+ останні 2 дні
+ останні 3 дні
+ останній тиждень
+ останні 2 тижні
+ останні 3 тижні
+ останній місяць
+ останні 2 місяці
+ останні 3 місяці
+ останні 6 місяців
+ останній рік
+ Теки для відображення
+ Усі
+ Тільки теки 1-го класу
+ Теки 1-го та 2-го класу
+ Усі, крім тек 2-го класу
+ Теки для опитування
+ Усі
+ Тільки теки 1-го класу
+ Теки 1-го та 2-го класу
+ Усі, крім тек 2-го класу
+ Нічого
+ Теки для надсилання
+ Усі
+ Тільки теки 1-го класу
+ Теки 1-го та 2-го класу
+ Усі, крім тек 2-го класу
+ Нічого
+ Теки призначення при переміщенні / копіюванні
+ Усі
+ Тільки теки 1-го класу
+ Теки 1-го та 2-го класу
+ Усі, крім тек 2-го класу
+ Синхронізація видалень на сервері
+ Видаляти повідомлення синхронно з видаленням на сервері
+ Немає OpenPGP-додатка - він був видалений?
+ Налаштування тек
+ Показувати у верхній групі
+ Показувати у верхній частині списку тек
+ Клас відображення теки
+ Без класу
+ 1-ий клас
+ 2-ий клас
+ Клас опитування теки
+ Немає
+ 1-ий клас
+ 2-ий клас
+ Такий самий, як і клас відображення
+ Клас надсилання теки
+ Без класу
+ 1-ий клас
+ 2-ий клас
+ Такий як і клас розкладу (poll)
+ Клас сповіщення теки
+ Без класу
+ 1-й клас
+ 2-й клас
+ Такий самий, як і клас надсилання
+ Видалити локальні повідомлення
+ Сервер вхідної пошти
+ Налаштувати сервер вхідної пошти
+ Сервер вихідної пошти
+ Налаштувати сервер вихідної пошти (SMTP)
+ Ім’я облікового запису
+ Ваше ім’я
+ Сповіщення
+ Вібрація
+ Вібрація при отрманні нової пошти
+ Шаблони вібрації
+ типовий
+ шаблон 1
+ шаблон 2
+ шаблон 3
+ шаблон 4
+ шаблон 5
+ Повторити вібрацію
+ Звук сповіщення про новий лист
+ Блимання LED-індикатором
+ Блимання LED-індикатором при отриманні нового листа
+ Параметри створення повідомлень
+ Типові налаштування написання листів
+ Встановити типові значення полів \"Від\", \"Прихована копія\" і підпис
+ Управління особами
+ Встановити альтернативні адреси \"Від\" та підписи
+ Управління особами
+ Управління особою
+ Редагувати особу
+ Зберегти
+ Нова особа
+ Прихована копія усіх повідомлень до
+ Редагувати
+ Пересунути вище
+ Пересунути нижче
+ Пересунути на початок / зробити типовою
+ Видалити
+ Опис особи
+ (Необов’язково)
+ Ваше ім’я
+ (Необов’язково)
+ Адреса електронної пошти
+ (Обов’язково)
+ Відповідати на адресу
+ (Необов’язково)
+ Підпис
+ (Обов’язково)
+ Використовувати підпис
+ Підпис
+ Початкова особа
+ Вибрати особу
+ Надіслати як
+ Не можна видалити останню особу
+ Не можна використовувати особу без адреси електронної пошти
+ Спершу старі повідомлення
+ Спершу нові повідомлення
+ Тема за алфавітом
+ Тема за алфавітом у зворотньому порядку
+ Відправники за алфавітом
+ Відправники за алфавітом в зворотньому порядку
+ Спершу повідомлення із зірочками
+ Спершу повідомлення без зірочок
+ Спершу непрочитані повідомлення
+ Спершу прочитані повідомлення
+ Спершу повідомлення з вкладеннями
+ Спершу повідомлення без вкладень
+ Упорядкувати за…
+ датою
+ часом отримання
+ темою
+ відправником
+ наявністю зірочки
+ статусом прочитання
+ наявністю вкладень
+ Видалити обліковий запис
+ Нерозпізнаний сертифікат
+ Прийняти ключ
+ Відхилити ключ
+ Del (або D) - Видалити\nR - Відповісти\nA - Відповісти всім\nC - Написати лист\nF - Переслати\nM - Перемістити\nV - Архівувати\nY - Копіювати\nZ - Позначити (не)прочитаним\nG - Позначити зірочкою\nO - Тип сортування\nI - Порядок сортування\nQ - Повернутися до тек\nS - Вибрати / Зняти вибір\nJ або P - Попереднє повідомлення\nK або N - Наступне повідомлення
+ Del (або D) - Видалити\nC - Написати лист\nM - Перемістити\nV - Архівувати\nY - Копіювати\nZ - Позначити (не)прочитаним\nG - Позначити зірочкою\nO - Тип сортування\nI - Порядок сортування\nQ - Поввернутися до тек\nS - Вибрати / Зняти вибір
+ Назва теки містить
+ Показати теки…
+ Відображати усі теки
+ Відображати тільки теки 1-го класу
+ Відображати теки 1-го і 2-го класу
+ Відображати усі, крім тек 2-го класу
+ Розташування підпису
+ перед цитованим повідомленням
+ після цитованого повідомлення
+ Використовувати тему додатку
+ Темна
+ Світла
+ Типова системна
+ Екран
+ Глобальні
+ Відлагодження
+ Конфіденційність
+ Мережа
+ Взаємодія
+ Список облікових записів
+ Списки повідомлень
+ Повідомлення
+ Тема
+ Тема екрану перегляду повідомлення
+ Тема екрану створення повідомлення
+ Мова
+ Налаштування не знайдені
+ Фіксована тема повідомлення
+ Виберіть тему екрану перегляду повідомлення під час перегляду повідомлення
+ Використовувати фіксовану тему перегляду повідомлення
+ Системна (System default)
+ Фонова синхронізація
+ Ніколи
+ Завжди
+ Коли \"Автосинхронізація\" увімкнена
+ Вибрати усе
+ Найбільша кількість тек для перевірки при надсиланні
+ 5 тек
+ 10 тек
+ 25 тек
+ 50 тек
+ 100 тек
+ 250 тек
+ 500 тек
+ 1000 тек
+ Анімація
+ Використовувати яскраві візуальні ефекти
+ Навігація кнопками зміни гучності
+ при перегляді повідомлень
+ у списках
+ Показувати Об\'єднані Вхідні
+ %s%s
+ - Непрочитані
+ Всі повідомлення
+ Всі повідомлення у теках для пошуку
+ Об\'єднані Вхідні
+ Усі повідомлення в об\'єднаних теках
+ Об’єднати
+ Усі повідомлення показуються у теці \"Об\'єднані Вхідні\"
+ Теки для пошуку
+ Всі
+ Видимі
+ Жодна
+ Жодної
+ Автоматично (%s)
+ Розмір шрифту
+ Налаштувати розмір шрифту
+ Список облікових записів
+ Ім’я облікового запису
+ Опис облікового запису
+ Списки тек
+ Назва теки
+ Статус теки
+ Списки повідомлень
+ Тема
+ Відправник
+ Дата
+ Попередній перегляд
+ Повідомлення
+ Відправник
+ Кому
+ Копія
+ Прихована копія
+ Додаткові заголовки
+ Тема
+ Час і дата
+ Тіло повідомлення
+ %d%%
+ %1$s: %2$s
+ Створення повідомлення
+ Поля для вводу тексту
+ Типовий
+ Найдрібніший
+ Дрібний
+ Менший
+ Малий
+ Середній
+ Великий
+ Більший
+ Для цієї дії не знайдено відповідного додатку.
+ Помилка відправки: %s
+ Зберегти чернетку повідомлення?
+ Зберегти чи Скасувати це повідомлення?
+ Зберегти чи Скасувати зміни?
+ Скасувати повідомлення?
+ Ви дійсно хочете скасувати це повідомлення?
+ Виберіть текст для копіювання.
+ Очистити локальні повідомлення?
+ Це видалить всі локальні повідомлення з теки. Жодне повідомлення не буде видалене з сервера.
+ Очистити повідомлення
+ Підтвердіть видалення
+ Ви хочете видалити це повідомлення?
+
+ Ви дійсно хочете видалити це повідомлення?
+ Ви дійсно хочете видалити %1$d повідомлень?
+ Ви дійсно хочете видалити %1$d повідомлень?
+ Ви дійсно хочете видалити %1$d повідомлень?
+
+ Так
+ Ні
+ Підтвердіть позначення усіх повідомлень прочитаними
+ Хочете позначити усі повідомлення прочитаними?
+ Підтвердіть очищення кошика
+ Ви хочете очистити теку \"Кошик\"?
+ Так
+ Ні
+ Підтвердіть переміщення в теку \"Спам\"
+
+ Ви дійсно хочете перемістити це повідомлення в спам?
+ Ви дійсно хочете перемістити %1$d повідомлень у спам?
+ Ви дійсно хочете перемістити %1$d повідомлень у спам?
+ Ви дійсно хочете перемістити %1$d повідомлень у теку \"Спам\"?
+
+ Так
+ Ні
+ Завантаження вкладення
+ »
+ ›
+ Резервне копіювання
+ Різне
+ Експорт налаштувань
+ Експорт
+ Поділитися
+ Експортуються налаштування…
+ Налаштування успішно експортовані
+ Не вдалося експортувати налаштування
+ Імпортувати налаштування
+ Вибрати файл
+ Імпорт
+ Налаштування успішно імпортовано
+ Введіть паролі
+ Не вдалося імпортувати налаштування
+ Не вдалося прочитати файл з налаштуваннями
+ Не вдалося імпортувати деякі налаштування
+ Успішно імпортовано
+ Потрібен пароль
+ Не імпортовано
+ Збій імпортування
+ Пізніше
+ Імпортувати налаштування
+ Імпортуються налаштування…
+
+ Щоб користуватися обліковим записом %s, потрібно надати пароль сервера.
+ Щоб користуватися обліковим записом %s, потрібно надати паролі сервера.
+ Щоб користуватися обліковим записом %s, потрібно надати паролі сервера.
+ Щоб користуватися обліковим записом %s, потрібно надати паролі сервера.
+
+ Пароль сервера вхідної пошти
+ Пароль сервера вихідної пошти
+ Використовувати той же пароль для сервера вихідної пошти
+ Ім\'я сервера: %s
+ Показати кількість непрочитаних для…
+ Обліковий запис
+ Обліковий запис, для якого має відображатися кількість непрочитаних листів
+ Об\'єднані Вхідні
+ Кількість тек
+ Показати кількість непрочитаних листів тільки однієї теки
+ Тека
+ Тека, для якої має відображатися кількість непрочитаних листів
+ Готово
+ %1$s - %2$s
+ Не вибрано жодного облікового запису
+ Не вибрано жодної теки
+ Нема тексту
+ Відкрити посилання
+ Надіслати посилання
+ Копіювати посилання до буфера обміну
+ Посилання
+ Скопіювати текст посилання у буфер обміну
+ Текст посилання
+ Зображення
+ Переглянути зображеня
+ Зберегти зображення
+ Завантажити зображення
+ Копіювати посилання на зображення до буфера обміну
+ Посилання на зображення
+ Подзвонити за номером
+ Зберегти до Контактів
+ Копіювати телефонний номер до буфера обміну
+ Телефонний номер
+ Надіслати листа
+ Зберегти до Контактів
+ Копіювати електронну адресу до буфера обміну
+ Електронна адреса
+ Всі
+ 10
+ 25
+ 50
+ 100
+ 250
+ 500
+ 1000
+ Обмеження пошуку на сервері
+ Надсилання запиту до сервера
+
+ Отримання %dрезультату
+ Отримання %dрезультатів
+ Отримання %d результатів
+ Отримання %d результатів
+
+
+ Отримання %1$d з %2$d результату
+ Отримання %1$d з %2$d результатів
+ Отримання %1$d з %2$d результатів
+ Отримання %1$d з %2$d результатів
+
+ Віддалений пошук не вдався
+ Пошук
+ Увімкнути пошук на сервері
+ Шукати повідомлення на сервері на додаток до тих, що є на вашому пристрої
+ Шукати повідомлення на сервері
+ Для пошуку на сервері необхідне з\'єднання з мережею.
+ Змінювати колір при прочитанні
+ Інший колір фону буде означати, що повідомлення прочитане
+ Групування повідомлень
+ Групувати повідомлення у діалоги
+ Оновлення баз даних
+ Оновлення баз даних…
+ Оновлення баз даних облікового запису \"%s\"
+ Перегляд на розділеному екрані
+ Завжди
+ Ніколи
+ Коли в альбомній орієнтації
+ Будь ласка, виберіть повідомлення зліва
+ Показувати зображення контактів
+ Показувати зображення контактів в списку повідомлень
+ Позначити усе прочитаним
+ Позначати кольором зображення контактів
+ Позначати кольором зображення відсутніх контактів
+ Видимі дії над повідомленням
+ Показувати вибрані дії в меню перегляду повідомлень
+ Завантаження вкладення…
+ Надсилання повідомлення
+ Збереження чернетки
+ Отримання вкладення…
+ Автентифікація неможлива. Сервер не декларує здатність працювати з SASL EXTERNAL. Це може бути спричинено проблемою з сертифікатом клієнта (сплив строк дії, невідомий центр сертифікації) або іншою проблемою налаштувань.
+
+ Використовувати сертифікат клієнта
+ Сертифікат клієнта відсутній
+ Прибрати вибір сертифіката клієнта
+ Не вдалося отримати сертифікат клієнта для \"%s\"
+ Розширені налаштування
+ Сертифікат клієнта \"%1$s\" втратив чинність або ще не набрав чинності (%2$s)
+
+ *Зашифровано*
+ Додати з Контактів
+ Копія
+ Прихована копія
+ До
+ Від
+ <Невідомий Адресат>
+ <Невідомий Відправник>
+ Домашній
+ Робочий
+ Інший
+ Мобільний
+ Теку \"Чернетки\" не налаштовано для цього облікового запису!
+ Ключ не налаштовано для цього облікового запису! Перевірте налаштування.
+ Криптопровайдер використовує несумісну версію. Перевірте свої налаштування.
+ Не можу з\'єднатися з провайдером шифрування; перевірте ваші налаштування або натисніть значок шифрування, щоб спробувати знову!
+ Не вдалося ініціалізувати наскрізне шифрування. Перевірте свої налаштування.
+ Режим PGP/INLINE не підтримує вкладення!
+ Увімкнути PGP/INLINE
+ Вимкнути PGP/INLINE
+ Увімкнути PGP Sign-Only
+ Вимкнути PGP Sign-Only
+ Режим PGP/INLINE
+ Електронний лист буде відправлено в форматі PGP/INLINE.\nВикоритовуйте лише з метою забезпечення сумісності:
+ Деякі клієнти підтримують лише цей формат
+ Підписи можуть ламатися під час передачі
+ Вкладення не підтримуються
+ Зрозуміло!
+ Вимкнути
+ Залишити увімкненим
+ Зрозуміло!
+ Вимкнути
+ Залишити увімкненим
+ Режим PGP Sign-Only
+ У цьому режимі ваш PGP-ключ буде використаний для створення криптографічного підпису незашифрованого електронного листа.
+ Це не шифрує електронний лист, але засвідчує, що він був надісланий від вашого ключа.
+ Підписи можуть бути пошкоджені при надсиланні листа у списки розсилки.
+ Деякі клієнти можуть відображати підписи як вкладення \'signature.asc\'.
+ Зашифровані листи завжди містять підпис.
+ Простий текст
+ підпис наскрізного шифрування містив помилку
+ необхідно повністю завантажити повідомлення для обробки підпису
+ містить непідтримуваний підпис наскрізного шифрування
+ Повідомлення зашифроване, але цей формат не підтримується.
+ Повідомлення зашифроване, але розшифровування було скасоване.
+ Звичайний текст, підписаний наскрізним шифруванням
+ від перевіреного підписувача
+ Підписаний звичайний текст
+ але ключ наскрізного шифрування не співпав з ключем відправника
+ але термін дійсності ключа наскрізного шифрування минув
+ але ключ наскрізного шифрування відкликано
+ але ключ наскрізного шифрування не вважається безпечним
+ від невідомого ключа наскрізного шифрування
+ Зашифровано
+ але виникла помилка розшифрування
+ необхідно повністю завантажити повідомлення для розшифровки
+ але не налаштовано жодного криптографічного додатку
+ Зашифровано
+ але не наскрізне
+ Зашифровано наскрізним шифруванням
+ від перевіреного відправника
+ Зашифровано
+ від невідомого ключа наскрізного шифрування
+ але ключ наскрізного шифрування не співпав з ключем відправника
+ але термін дійсності ключа наскрізного шифрування минув
+ але ключ наскрізного шифрування відкликано
+ але ключ наскрізного шифрування не вважається безпечним
+ але зашифрована наскрізним шифруванням інформація містить помилки
+ але шифрування не вважається безпечним
+ Гаразд
+ Пошук ключа
+ Переглянути підписувача
+ Переглянути відправника
+ Деталі
+ Розблокувати
+ Ця частина не була зашифрована і може бути небезпечною.
+ Незахищене вкладення
+ Завантаження…
+ Розшифровування скасовано.
+ Спробувати знову
+ Для розшифровування зашифроване повідомлення необхідно завантажити.
+ Помилка під час розшифровування електронного листа
+ Спеціальні символи наразі не підтримуються!
+ Помилка розбору адреси!
+ Приховати незашифровані підписи
+ Тільки зашифровані підписи будуть відображені
+ Усі підписи будуть відображені
+ Шифрування недоступне у режимі PGP Sign-Only
+ Непідписаний Текст
+ Попередження про застарілість APG
+ APG більше не підтримується!
+ Через це підтримку APG було видалено з K-9 Mail.
+ Розробка зупинена на початку 2014
+ Містить невиправлені проблеми з безпекою
+ Ви можете перейти сюди, щоб дізнатися більше.
+ Зрозуміло!
+ APG
+ Цей електронний лист зашифровано
+ Цей електронний лист було зашифровано за допомогою OpenPGP.\nЩоб його прочитати, необхідно встановити та налаштувати сумісний OpenPGP-додаток.
+ Перейти до Налаштувань
+ K-9 Список повідомлень
+ Завантаження листів…
+ Не вдалося отримати список тек
+ Не вдалося отримати статус адресата від провайдера OpenPGP.
+ Шифрування неможливе
+ Деякі з вибраних адресатів не підтримують цю функцію.
+ Увімкнути шифрування
+ Вимкнути шифрування
+ Шифрування повідомлень гарантує, що вони можуть бути прочитані адресатом, і ніким іншим.
+ Можливість шифрування відображатиметься лише в тому випадку, якщо його підтримують усі адресати і якщо вони раніше надсилали вам електронного листа.
+ Перемкніть шифрування цією піктограмою.
+ Зрозуміло
+ Назад
+ Вимкнути шифрування
+ Шифрування OpenPGP
+ Автоматичне шифрування у режимі взаємності
+ Автоматичне шифрування у режимі взаємності
+ Повідомлення будуть шифруватися за вашим вибором або при відповіді на шифроване повідомлення.
+ Якщо і відправник, і адресат увімкнуть режим взаємності, шифрування типово буде увімкнене.
+ Ви можете перейти сюди, щоб дізнатися більше.
+ Загальні налаштування
+ Не встановлено додатка OpenPGP
+ Встановити
+ K-9 Mail потребує OpenKeychain для наскрізного шифрування.
+ Зашифроване повідомлення
+ Шифрувати теми повідомлень
+ Може не підтримуватися деякими адресатами
+ Внутрішня помилка: Недійсний обліковий запис!
+ Помилка підключення до %s!
+ Надіслати Повідомлення з Налаштуваннями Автоматичного Шифрування
+ Безпечно поділитися налаштуваннями наскрізного шифрування з іншими пристроями
+ Повідомлення з Налаштуваннями Автоматичного Шифрування
+ Повідомлення з Налаштуваннями Автоматичного Шифрування безпечно надсилає ваші налаштування наскрізного шифрування на інші пристрої.
+ Надіслати Повідомлення з Налаштуваннями
+ Повідомлення буде надіслано на вашу адресу:
+ Створення повідомлення з налаштуваннями...
+ Надсилання повідомлення до:
+ Для завершення налаштування відкрийте повідомлення на іншому своєму пристрої та введіть Код Налаштування.
+ Показати Код Налаштування
+ Повідомлення з Налаштуваннями Автоматичного Шифрування
+ Це повідомлення містить усю інформацію для безпечного надсилання налаштувань автоматичного шифрування разом з секретним ключем з вашого пристрою.
Щоб налаштувати ваш новий пристрій для роботи з автоматичним шифруванням, дотримуйтесь інструкцій на його екрані.
Ви можете зберегти це повідомлення і використовувати його як резервну копію вашого секретного ключа. Якщо ви хочете це зробити, запишіть пароль і збережіть його у надійному місці.
- При надсиланні повідомлення сталася помилка. Перевірте підключення до мережі та налаштування вихідного сервера.
- Увімкнено
- Вимкнено
- Відкрити
- Закрити
-
- Дозволити доступ до контактів
- Цей додаток потребує доступу до ваших контактів, щоб мати можливість відображати імена і фотографії контактів та відображати пропозиції під час їх введення.
- Сталася помилка при завантаженні даних
- Ініціалізація...
- Очікування нових листів
- Очікування дозволу на фонову синхронізацію
- Очікування наявності мережі
- Натисніть, щоб дізнатися більше.
- Інформація про сповіщення
- Під час використання пуш-сповіщень, K-9 Mail використовує з\'єднання з поштовим сервером. Android\'у необхідно відображати сповіщення безперервно доки програма працює на фоні. %s
- Тим не менш, Android також дозволяє приховати сповіщення.
- Дізнатися більше
- Налаштувати сповіщення
- Якщо вам не потрібне миттєве сповіщення про нові повідомлення, вам варто вимкнути Push і використовувати Polling. Polling перевіряє пошту з регулярними інтервалами і не потребує сповіщення.
- Вимкнути пуш-сповіщення
+ При надсиланні повідомлення сталася помилка. Перевірте підключення до мережі та налаштування вихідного сервера.
+ Увімкнено
+ Вимкнено
+ Відкрити
+ Закрити
+
+ Дозволити доступ до контактів
+ Цей додаток потребує доступу до ваших контактів, щоб мати можливість відображати імена і фотографії контактів та відображати пропозиції під час їх введення.
+ Сталася помилка при завантаженні даних
+ Ініціалізація...
+ Очікування нових листів
+ Очікування дозволу на фонову синхронізацію
+ Очікування наявності мережі
+ Натисніть, щоб дізнатися більше.
+ Інформація про сповіщення
+ Під час використання пуш-сповіщень, K-9 Mail використовує з\'єднання з поштовим сервером. Android\'у необхідно відображати сповіщення безперервно доки програма працює на фоні. %s
+ Тим не менш, Android також дозволяє приховати сповіщення.
+ Дізнатися більше
+ Налаштувати сповіщення
+ Якщо вам не потрібне миттєве сповіщення про нові повідомлення, вам варто вимкнути Push і використовувати Polling. Polling перевіряє пошту з регулярними інтервалами і не потребує сповіщення.
+ Вимкнути пуш-сповіщення
diff --git a/app/ui/legacy/src/main/res/values-zh-rCN/strings.xml b/app/ui/legacy/src/main/res/values-zh-rCN/strings.xml
index 095fd4bba2c19bc4bab720fa22b85f2f4e03c32a..88badf985395a7f1047cb5a6fe4fa49c09a154f5 100644
--- a/app/ui/legacy/src/main/res/values-zh-rCN/strings.xml
+++ b/app/ui/legacy/src/main/res/values-zh-rCN/strings.xml
@@ -49,6 +49,8 @@
作为附件转发切换账户选择文件夹
+ 移动至…
+ 复制到…收取 %s:%s%s获取邮件头:%s:%s%s发送中 %s%s
@@ -82,6 +84,7 @@
丢弃保存为草稿检查新邮件
+ 检查所有账户邮件发送邮件刷新文件夹列表搜索文件夹
@@ -170,6 +173,9 @@
记录额外的调试信息记录敏感信息将会在日志中显示密码。
+ 导出日志
+ 导出成功。日志可能包含敏感信息。小心选择你要发给的人。
+ 导出失败加载更多邮件收件人: %s主题
@@ -243,10 +249,6 @@
Remove Mail User-Agent from mail headers隐藏时区在邮件头及恢复头中使用UTC时间而不是本地时间
- 在通知中隐藏主题
- 从不
- 当设备锁定时
- 总是显示“删除”按钮从不为单条消息通知
@@ -254,7 +256,7 @@
屏幕锁定通知无屏幕锁定通知应用程序名称
- 未读消息计数
+ 新消息总数消息计数及发件人与解除屏幕锁定时相同免打扰时间
@@ -267,6 +269,10 @@
电子邮件地址密码显示密码
+
+ 要查看您的密码,请在此设备上启用屏幕锁定。
+ 验证你的身份
+ 解锁查看你额密码手工设置正在获取账户信息\u2026
@@ -308,8 +314,6 @@
手机移动网络Wi-Fi其他
- 外部存储(SD 卡)
- 正常内部存储抹掉删除的邮件立刻接收邮件时
@@ -385,8 +389,6 @@
继续高级通用设置
- 默认账户
- 默认使用这个账户发送邮件新邮件通知提醒文件夹全部
@@ -402,12 +404,15 @@
发送邮件时显示通知仅联系人仅显示通讯录中已有联系人邮件
+ 忽略聊天信息
+ 不显示属于电子邮件聊天消息的通知邮件打开时标记为已读当邮件打开时标记为已读删除后标记为已读删除邮件时将其标记为已读
- 通知设置
- 打开系统通知设置
+ 通知类别
+ 配置新消息通知
+ 配置错误和状态通知显示图片从不来自您的联系人的邮件
@@ -660,6 +665,7 @@
信息视图不同的列表视图显示全局收件箱
+ 显示星标邮件数%s%s - 未读所有邮件
@@ -864,6 +870,7 @@
秘送收件人发件人
+ 回复给<未知收件人><未知发件人>住宅
diff --git a/app/ui/legacy/src/main/res/values-zh-rTW/strings.xml b/app/ui/legacy/src/main/res/values-zh-rTW/strings.xml
index ada0440879c0bbdba51cea82e10053d800a3b76b..147074959d193d92d0ba39c8ec9c6d28e05f75a4 100644
--- a/app/ui/legacy/src/main/res/values-zh-rTW/strings.xml
+++ b/app/ui/legacy/src/main/res/values-zh-rTW/strings.xml
@@ -11,15 +11,15 @@
版權所有 2008-%s The K-9 Dog Walkers. Portions Copyright 2006-%s the Android Open Source Project.原始碼Apache 授權條款, 版本 2.0
- 開源專案
+ 開放原始碼專案網站
- 用戶論壇
+ 使用者論壇FediverseTwitter函式庫授權
- 變更記錄檔
- 無法載入變更記錄檔
+ 變更記錄
+ 無法載入變更記錄第%s版最新消息顯示應用程式更新後的最新變更
@@ -28,13 +28,13 @@
Welcome to MailMail is the default mail client for /e/
- -- Sent from /e/ Mail.
+ -- \n使用 K-9 Mail 寄送。來自我的 Android 裝置。
- The account \"%s\" will be removed from Mail.
+ 帳號「%s」將從 K-9 Mail 中刪除。作者修訂資訊
- 顯示郵件
+ 讀取郵件允許該程式讀取郵件。刪除郵件允許該程式刪除郵件。
@@ -49,8 +49,10 @@
以附件形式轉寄選取帳號選取信件匣
+ 移至...
+ 複製至...正在接收%s:%s%s
- 正在接收郵件訊息%s:%s%s
+ 正在接收郵件標頭%s:%s%s正在寄送%s%s正在處理%s:%s%s\u0020%d/%d
@@ -63,7 +65,7 @@
取消寄送再次寄送
- 主題為空,確認寄送請再按一次。
+ 主題空白,確定要寄送的話請再按一次。選擇取消選擇回覆
@@ -76,12 +78,13 @@
編輯為新訊息移動移至草稿
- 郵件選項…
+ 郵件寄送選項…再次封存完成捨棄儲存為草稿檢查新郵件
+ 為所有帳號檢查新郵件寄送重整信件匣尋找信件匣
@@ -100,13 +103,13 @@
加上星號移除星號複製
- 顯示標題
+ 顯示標頭位址已複製到剪貼簿主題文字已複製到剪貼簿
- 切換為黑色主題
- 切換為白色主題
+ 切換為暗色主題
+ 切換為亮色主題標記為未讀讀取回條要求讀取回條
@@ -122,14 +125,14 @@
正在載入郵件…網路連接錯誤沒有找到郵件
- 訊息載入錯誤
+ 郵件載入錯誤再載入%d封郵件%.1fGB%.1fMB%.1fkB%dB帳號「%s」已從%s縮小到%s
- 正在壓縮帳號「%s」
+ 正在壓實帳號「%s」您有新郵件%d 條新訊息
@@ -153,18 +156,18 @@
正在寄送郵件:%s正在寄送郵件:
- 同步(推播)
+ 同步(推送)等待新郵件時顯示郵件與郵件相關的通知
- 偏好設定
- 其他通知,如错誤通知等。
+ 雜項設定
+ 其他通知,如錯誤通知等。收件匣寄件備份草稿垃圾桶寄件備份
- 部分郵件沒有成功寄送
+ 有些郵件沒有成功寄送版本啟用除錯日誌記錄額外的除錯訊息
@@ -177,7 +180,7 @@
簽名--------原始郵件--------主題:
- 收到日期:
+ 送件日期:寄件人:收件人:副本:
@@ -198,15 +201,15 @@
密件副本:開啟儲存
- 無法保存附件。
+ 無法存檔附件。顯示圖片無法開啟%s。找不到可以開啟該附件的程式。下載完整郵件無法顯示郵件透過 %1$s
- 全部郵件的訊息都已經下載,沒有其他的郵件訊息可以顯示。
- 從資料庫或郵件伺服器存取其他的郵件訊息失敗。
+ 全部郵件的標頭都已經下載,沒有其他的郵件標頭可以顯示。
+ 從資料庫或郵件伺服器存取其他的郵件標頭失敗。來自這個寄件人的更多郵件寄送自 %s調試/刪除訊息本文
@@ -223,8 +226,8 @@
用聯絡人姓名取代顯示電子郵件地址使用顏色標示特定聯絡人使用顏色標示聯絡人列表
- 定寬字體
- 使用定寬字體顯示純文字郵件
+ 固定寬度字體
+ 使用固定寬度字體顯示純文字郵件自動調整訊息調整訊息內容符合螢幕大小刪除後自動返回到列表
@@ -234,7 +237,7 @@
確認操作進行選擇操作時總是顯示一個對話框進行確認刪除
- 移除星號 (僅檢視郵件時)
+ 移除星號 (檢視郵件時)標記為垃圾郵件捨棄郵件全部標記為已讀
@@ -243,10 +246,6 @@
Remove Mail User-Agent from mail headers隱藏時區在郵件標頭及回覆標頭中使用 UTC 時間而不是本地時間
- 進行通知時隱藏主題
- 絕不
- 當裝置上鎖時
- 總是顯示「刪除」按鈕絕不針對單一訊息通知
@@ -254,7 +253,7 @@
螢幕鎖定通知無螢幕鎖定通知應用程式名稱
- 未讀訊息數
+ 新訊息總數訊息數及寄件人與解除螢幕鎖定時相同靜音時間
@@ -267,9 +266,13 @@
電子郵件地址密碼顯示密碼
+
+ 要在這查看你的密碼請為這個裝置啟用螢幕上鎖。
+ 驗證你的身份
+ 解所來查看你的密碼手動設定
- 正在獲取帳號訊息…
+ 正在汲取帳號訊息…正在檢查內送伺服器設定…正在檢查外寄伺服器設定…驗證…
@@ -285,11 +288,11 @@
普通密碼非安全傳輸的密碼已加密的密碼
- 用戶端憑證
- 郵件伺服器設定
+ 使用者客戶端憑證
+ 內送伺服器設定使用者名稱密碼
- 用戶端憑證
+ 使用者客戶端憑證POP3伺服器IMAP伺服器WebDAV (Exchange)伺服器
@@ -308,8 +311,6 @@
行動網路Wi-Fi其他
- 外部儲存 (記憶卡)
- 手機內部儲存抹除刪除的郵件立刻接收郵件時
@@ -333,7 +334,7 @@
SMTP伺服器埠號加密類型
- 要求登錄。
+ 要求登入。使用者名稱密碼身份驗證方法
@@ -351,9 +352,9 @@
6 小時一次12 小時一次24 小時一次
- 在這個帳戶上啟用推送郵件
+ 在這個帳號上啟用推送郵件如果你的郵件伺服器支援此功能,那麼新郵件將會立刻顯示在手機上。這個選項可能大幅的提升性能,也可能嚴重的影響性能。
- 重整間隔連接
+ 重整 IDLE 連線2 分鐘一次3 分鐘一次6 分鐘一次
@@ -379,14 +380,12 @@
沒有與伺服器同步的郵件無法進行複製或移動無法完成設定使用者名稱或密碼不正確。\n(%s)
- 伺服器提供了一个無效的 SSL 憑證。這是由於不正確的伺服器配置而導致的,也可能是由於有人試圖攻擊您或者您的郵件伺服器。如果您不能確定到底是什麼原因,請點擊「拒絕」,並聯絡您的郵件伺服器管理人員。\n\n(%s)
+ 伺服器提供了一個無效的 SSL 憑證。這是由於不正確的伺服器設定而導致的,也可能是由於有人試圖攻擊你或者你的郵件伺服器。如果你不能確定到底是什麼原因,請點擊「拒絕」,並聯絡你的郵件伺服器管理人員。\n\n(%s)無法連線到伺服器。\n(%s)編輯詳細訊息繼續進階帳號設定
- 預設帳號
- 預設使用這個帳號寄送郵件新郵件通知通知信件匣全部
@@ -402,12 +401,15 @@
寄送郵件時顯示通知僅限聯絡人僅限顥示通訊錄中已有聯絡人郵件
+ 忽略聊天郵件
+ 若郵件是屬於電子郵件聊天應用則不顯示通知開啟自動標記已讀開啟檢視郵件內容時自動標記為已讀刪除後標記為已讀刪除郵件時將其標記為已讀
- 通知設定
- 開啟系統通知設定
+ 通知類別
+ 設定新郵件的通知
+ 設定錯誤與狀態通知顯示圖片不要來自您的聯絡人的郵件
@@ -427,22 +429,22 @@
讀取回條永遠要求讀取回條回覆時的引用樣式
- 前綴 (如同 Gmail, Pine)
- 段落 (如同 Outlook, Yahoo!, Hotmail)
+ 行首 (如同 Gmail, Pine)
+ 分隔行 (如同 Outlook, Yahoo!, Hotmail)上傳要寄送的郵件寄送後將郵件上傳到已寄送信件匣一般設定讀取郵件接收郵件信件匣
- 引用本文前綴
+ 引用本文行首端到端加密啟用 OpenPGP 支援選擇 OpenPGP 應用程式
- 配置端到端金鑰
+ 設定端到端金鑰未設定 OpenPGP 應用程式已連接至 %s
- 正在配置...
+ 正在設定...儲存草稿時加密所有草稿將加密儲存僅在啟用加密時才加密草稿
@@ -531,11 +533,11 @@
與推送層別相同清除本地郵件內送伺服器
- 配置內送伺服器
+ 設定內送伺服器外寄伺服器
- 配置外寄(SMTP)伺服器
+ 設定外寄(SMTP)伺服器帳號名稱
- 您的名字
+ 你的名字通知震動有新郵件時震動
@@ -627,7 +629,7 @@
除錯隱私網路
- 交互
+ 互動帳號列表郵件列表郵件
@@ -636,7 +638,7 @@
新郵件主題語系未找到設定
- 固定訊息主題
+ 固定的郵件顯示設定主題讀取訊息內容時顯示訊息檢視主題使用固定訊息檢視主題系統預設值
@@ -660,6 +662,7 @@
訊息檢視不同的訊息檢視列表顯示全域收件匣
+ 顯示有標記星號的數量%s%s- 未讀所有郵件
@@ -675,7 +678,7 @@
無自動 (%s)字體大小
- 配置字體大小
+ 設定字體大小帳號列表帳號名稱帳號描述
@@ -851,12 +854,12 @@
正在接收附件...無法認證。伺服器未公告 SASL EXTERNAL 的構架 。可能是由於伺服器憑證有問題(已過期,或者未知的認證機構),或者是由於其他的配置問題。
- 使用用戶端憑證
- 無用戶端憑證
- 移除用戶端憑證選擇
- 無法取得別名「%s」的用戶端憑證
+ 使用客戶端憑證
+ 無客戶端憑證
+ 移除客戶端憑證選擇
+ 無法取得別名「%s」的客戶端憑證進階選項
- 用戶端憑證 \"%1$s\" 已經過期,或者尚未開始生效。(%2$s)
+ 客戶端憑證 \"%1$s\" 已經過期,或者尚未開始生效。(%2$s)*已加密*從聯絡人中新增
@@ -864,13 +867,14 @@
密件副本收件人寄件人:
+ 回覆給<未知收件人><未知寄件人>
- 住宅
+ 住家工作其他
- 行動網路
- 此賬號沒有設定草稿信件匣!
+ 行動電話
+ 此帳號沒有設定草稿信件匣!沒有為此帳戶設定的金鑰!請檢查裝置。加密服務提供者使用不相容版本。請檢查您的設定!無法連線到加密服務提供者,請檢查您的設定或按一下加密圖示重試!
@@ -892,7 +896,7 @@
停用保持啟用僅用 PGP 簽名模式
- 在此模式中,你的 PGP 金鑰將用於给未加密的郵件進行簽名。
+ 在此模式中,你的 PGP 金鑰將用於給未加密的郵件進行簽名。郵件不會被加密,但是可以驗證郵件是由你寄送的。寄送至郵件列表時,簽名可能會中斷。簽名在一些郵件軟體中會顯示為附件「signature.asc」。
@@ -958,7 +962,7 @@
郵件已被加密這封郵件使用 OpenPGP 進行了加密。\n請安裝並配置一個相容 OpenPGP 的應用程式来查看郵件。前往設定
- Mail Message List
+ K-9 訊息列表正在載入郵件…收取信件匣列表失敗檢索支持 OpenPGP 的收件人狀態出錯!
@@ -981,23 +985,23 @@
一般設定未安裝 OpenPGP 應用程式安裝
- Mail requires OpenKeychain for end-to-end encryption.
+ K-9 Mail 需要 OpenKeychain 提供端到端加密。已加密的訊息。加密訊息主題有些收件人可能不支援加密内部錯誤:帳號無效!無法連接到%s!
- 寄送自動加密配置訊息
- 與其他裝置安全共享端到端配置
- 自動加密配置訊息
- 透過自動加密配置訊息,能安全地與其他裝置共享你的端到端配置。
- 寄送配置訊息
+ 寄送Autocrypt設定的訊息
+ 與其他裝置安全共享端到端設定
+ Autocrypt設定的訊息
+ 透過Autocrypt設定訊息,能安全地與其他裝置共享你的端到端設定。
+ 寄送設定訊息訊息將會寄送至你的地址:
- 正在生成配置訊息…
+ 正在產生設定訊息…寄送訊息至:請在你的其他裝置上開啟訊息,並輸入設定代碼以完成設定精靈。顯示設定代碼
- 自動加密配置訊息
+ Autocrypt設定訊息這條訊息包括所有你的舊裝置上的 Autocrypt 設定與你的私鑰。
要在你的新裝置上設定自動加密,请按您的新裝置上的提示操作。
@@ -1010,19 +1014,19 @@
開啟關閉
- 允許訪問聯絡人
- 為了能夠提供聯絡人建議,並顯示聯絡人姓名和照片,應用程式需要訪問你的聯絡人。
+ 允許存取聯絡人
+ 為了能夠提供聯絡人建議,並顯示聯絡人姓名和照片,應用程式需要存取你的聯絡人。載入資料時發生錯誤初始化...正在等待新郵件等待背景同步允許等待網路可用按一下了解更多
- 推播資訊
- 使用推播時,K-9 Mail 會保持與郵件伺服器的連線。當應用程式在背景執行時,Android 需要開啟顯示持續的通知的權限。%s
- 不過,Android 也允許您隱藏通知。
+ 推送資訊
+ 使用推送時,K-9 Mail 會保持與郵件伺服器的連線。當應用程式在背景執行時,Android 需要開啟顯示持續的通知的權限。%s
+ 不過,Android 也允許你隱藏通知。了解更多
- 配置通知
- 如果您不需要新郵件的即時通知,則應停用推播並使用輪詢。輪詢會定期檢查新郵件,不需要通知權限。
- 停用推播
+ 設定通知
+ 如果你不需要新郵件的即時通知,則應停用推送並使用輪詢。輪詢會定期檢查新郵件,不需要通知權限。
+ 停用推送
diff --git a/app/ui/legacy/src/main/res/values/strings.xml b/app/ui/legacy/src/main/res/values/strings.xml
index e7622002f27e9fe5cda3fc3eb579f963f3211557..93dc3643308973690282e81ba3189e7cb8d9670f 100644
--- a/app/ui/legacy/src/main/res/values/strings.xml
+++ b/app/ui/legacy/src/main/res/values/strings.xml
@@ -67,6 +67,8 @@
Choose AccountChoose Folder
+ Move to…
+ Copy to…Poll %s:%s%sFetching headers %s:%s%s
@@ -213,6 +215,9 @@
Log extra diagnostic informationLog sensitive informationMay show passwords in logs.
+ Export logs
+ Export successful. Logs might contain sensitive information. Be careful who you send them to.
+ Export failed.Load more messagesTo:%s
@@ -704,8 +709,8 @@
(Optional)Email address(Required)
- Reply-to address(Optional)
+ Reply-to addressSignature(Optional)
diff --git a/app/ui/legacy/src/main/res/xml/account_settings.xml b/app/ui/legacy/src/main/res/xml/account_settings.xml
index eb11c55db5b90ad7ff7a37ce33ec7be6d3740b3a..b050c779a628ba12496b5702c09d7f453b67bc49 100644
--- a/app/ui/legacy/src/main/res/xml/account_settings.xml
+++ b/app/ui/legacy/src/main/res/xml/account_settings.xml
@@ -1,5 +1,7 @@
-
-
+
+
@@ -14,7 +16,6 @@
android:key="account_description"
android:title="@string/account_settings_description_label" />
-
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_show_pictures_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_mail_display_count_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_message_age_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_autodownload_message_size_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_mail_check_frequency_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_folder_sync_mode_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_folder_push_mode_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_setup_incoming_delete_policy_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_setup_expunge_policy_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_setup_push_limit_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/idle_refresh_period_label" />
@@ -169,8 +170,8 @@
android:entries="@array/message_format_entries"
android:entryValues="@array/message_format_values"
android:key="message_format"
- android:title="@string/account_settings_message_format_label"
- app:useSimpleSummaryProvider="true" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_message_format_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_quote_style_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_setup_auto_expand_folder" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_folder_display_mode_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_folder_target_mode_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_searchable_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/archive_folder_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/drafts_folder_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/sent_folder_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/spam_folder_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/trash_folder_label" />
@@ -304,8 +305,8 @@
android:entries="@array/folder_notify_new_mail_mode_entries"
android:entryValues="@array/folder_notify_new_mail_mode_values"
android:key="folder_notify_new_mail_mode"
- android:title="@string/account_settings_folder_notify_new_mail_mode_label"
- app:useSimpleSummaryProvider="true" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_folder_notify_new_mail_mode_label" />
-
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_vibrate_pattern_label" />
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_vibrate_times" />
-
+ app:useSimpleSummaryProvider="true"
+ android:title="@string/account_settings_remote_search_num_label" />
@@ -460,9 +459,10 @@
+ android:summaryOff="@string/account_settings_crypto_encrypt_all_drafts_off"
+ />
- assertThat(status.displayType).isEqualTo(CryptoStatusDisplayType.ENABLED_ERROR)
+ assertThat(status.displayType).isEqualTo(CryptoStatusDisplayType.UNAVAILABLE)
assertThat(status.isProviderStateOk()).isTrue()
assertThat(status.isOpenPgpConfigured).isTrue()
}
}
@Test
- fun getCurrentCryptoStatus_withOpportunistic__missingKeys() {
+ fun getCurrentCryptoStatus_withOpportunistic__privateMissingKeys() {
val recipientAutocryptStatus = RecipientAutocryptStatus(
RecipientAutocryptStatusType.UNAVAILABLE, null
)
setupCryptoProvider(recipientAutocryptStatus)
+ recipientPresenter.onCryptoModeChanged(CryptoMode.CHOICE_ENABLED)
+ runBackgroundTask()
assertNotNull(recipientPresenter.currentCachedCryptoStatus) { status ->
- assertThat(status.displayType).isEqualTo(CryptoStatusDisplayType.UNAVAILABLE)
+ assertThat(status.displayType).isEqualTo(CryptoStatusDisplayType.ENABLED_ERROR)
assertThat(status.isProviderStateOk()).isTrue()
assertThat(status.isOpenPgpConfigured).isTrue()
}
@@ -265,8 +266,10 @@ class RecipientPresenterTest : K9RobolectricTest() {
@Test
fun getCurrentCryptoStatus_withModeInline() {
setupCryptoProvider(noRecipientsAutocryptResult)
+
recipientPresenter.onMenuSetPgpInline(true)
runBackgroundTask()
+
assertNotNull(recipientPresenter.currentCachedCryptoStatus) { status ->
assertThat(status.displayType).isEqualTo(CryptoStatusDisplayType.UNAVAILABLE)
assertThat(status.isProviderStateOk()).isTrue()
@@ -278,7 +281,6 @@ class RecipientPresenterTest : K9RobolectricTest() {
assertThat(Robolectric.getBackgroundThreadScheduler().runOneTask()).isTrue()
}
-
private fun setupCryptoProvider(autocryptStatusResult: RecipientAutocryptStatus) {
stubbing(account) {
on { openPgpProvider } doReturn CRYPTO_PROVIDER
@@ -289,6 +291,7 @@ class RecipientPresenterTest : K9RobolectricTest() {
recipientPresenter.onSwitchAccount(account)
val openPgpApiMock = mock()
+
stubbing(autocryptStatusInteractor) {
on { retrieveCryptoProviderRecipientStatus(eq(openPgpApiMock), any()) } doReturn autocryptStatusResult
}
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/ReplyToPresenterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/ReplyToPresenterTest.kt
index 2dec377f39a0048bb208935e5d3725bff07bb8d8..ca33c808f5b55708e793d228f15b049b8fe414f8 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/ReplyToPresenterTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/activity/compose/ReplyToPresenterTest.kt
@@ -4,10 +4,8 @@ import android.os.Bundle
import com.fsck.k9.Identity
import com.fsck.k9.K9RobolectricTest
import com.fsck.k9.mail.Address
-
import com.google.common.truth.Truth.assertThat
import org.junit.Test
-
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
@@ -30,7 +28,9 @@ class ReplyToPresenterTest : K9RobolectricTest() {
val initialPresenter = ReplyToPresenter(initialView)
val state = Bundle()
initialPresenter.onSaveInstanceState(state)
+
replyToPresenter.onRestoreInstanceState(state)
+
verify(view).isVisible = true
}
@@ -40,6 +40,7 @@ class ReplyToPresenterTest : K9RobolectricTest() {
stubbing(view) {
on { getAddresses() } doReturn addresses
}
+
val result = replyToPresenter.getAddresses()
assertThat(result).isSameInstanceAs(addresses)
@@ -50,7 +51,9 @@ class ReplyToPresenterTest : K9RobolectricTest() {
stubbing(view) {
on { hasUncompletedText() } doReturn false
}
+
val result = replyToPresenter.isNotReadyForSending()
+
assertThat(result).isFalse()
}
@@ -114,24 +117,37 @@ class ReplyToPresenterTest : K9RobolectricTest() {
}
@Test
- fun testOnNonRecipientFieldFocused_noContentFieldVisible_expectHide() {
+ fun testOnNonRecipientFieldFocused_notVisible_expectNoChange() {
stubbing(view) {
on { isVisible } doReturn false
}
-
replyToPresenter.onNonRecipientFieldFocused()
verify(view, never()).isVisible = false
}
+ @Test
+ fun testOnNonRecipientFieldFocused_noContentFieldVisible_expectHide() {
+ stubbing(view) {
+ on { isVisible } doReturn true
+ on { getAddresses() } doReturn emptyArray()
+ }
+
+ replyToPresenter.onNonRecipientFieldFocused()
+
+ verify(view).isVisible = false
+ }
+
@Test
fun testOnNonRecipientFieldFocused_withContentFieldVisible_expectNoChange() {
stubbing(view) {
on { isVisible } doReturn true
on { getAddresses() } doReturn Address.parse(REPLY_TO_ADDRESS)
}
+
replyToPresenter.onNonRecipientFieldFocused()
+
verify(view, never()).isVisible = false
}
-}
\ No newline at end of file
+}
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/fragment/MessageListAdapterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/fragment/MessageListAdapterTest.kt
index cb18a576ae9e83bc51cdfad82cd6d88a7cf7b126..029b1421e2c8efc14016b0b5a1153b8ca90a63f8 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/fragment/MessageListAdapterTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/fragment/MessageListAdapterTest.kt
@@ -13,11 +13,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.fsck.k9.Account
-import com.fsck.k9.Clock
import com.fsck.k9.FontSizes
import com.fsck.k9.FontSizes.FONT_DEFAULT
import com.fsck.k9.FontSizes.LARGE
import com.fsck.k9.RobolectricTest
+import com.fsck.k9.TestClock
import com.fsck.k9.contacts.ContactPictureLoader
import com.fsck.k9.mail.Address
import com.fsck.k9.textString
@@ -464,7 +464,7 @@ class MessageListAdapterTest : RobolectricTest() {
contactsPictureLoader = contactsPictureLoader,
listItemListener = listItemListener,
appearance = appearance,
- relativeDateTimeFormatter = RelativeDateTimeFormatter(context, Clock.INSTANCE)
+ relativeDateTimeFormatter = RelativeDateTimeFormatter(context, TestClock())
)
}
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/crypto/MessageCryptoHelperTest.java b/app/ui/legacy/src/test/java/com/fsck/k9/ui/crypto/MessageCryptoHelperTest.java
index 5e22784365c0d6625eb2b7aabb15bf2f76304a51..86d08c9149592fc3153f0ca66837f20c8afb2788 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/ui/crypto/MessageCryptoHelperTest.java
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/ui/crypto/MessageCryptoHelperTest.java
@@ -41,8 +41,8 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.same;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt
index d1d5c9532401b891555ffea3f4d914fca4e88135..f0258c304a9a31e83f480f3a1dceecc1c5687dfe 100644
--- a/app/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/ui/helper/RelativeDateTimeFormatterTest.kt
@@ -1,8 +1,8 @@
package com.fsck.k9.ui.helper
import android.os.SystemClock
-import com.fsck.k9.Clock
import com.fsck.k9.RobolectricTest
+import com.fsck.k9.TestClock
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
@@ -10,8 +10,6 @@ import java.util.TimeZone
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
-import org.mockito.Mockito
-import org.mockito.kotlin.whenever
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
@@ -19,7 +17,7 @@ import org.robolectric.annotation.Config
class RelativeDateTimeFormatterTest : RobolectricTest() {
private val context = RuntimeEnvironment.application.applicationContext
- private val clock = Mockito.mock(Clock::class.java)
+ private val clock = TestClock()
private val dateTimeFormatter = RelativeDateTimeFormatter(context, clock)
private val zoneId = "Europe/Berlin"
@@ -123,7 +121,7 @@ class RelativeDateTimeFormatterTest : RobolectricTest() {
val dateTime = LocalDateTime.parse(time)
val timeInMillis = dateTime.toEpochMillis()
SystemClock.setCurrentTimeMillis(timeInMillis) // Is handled by ShadowSystemClock
- whenever(clock.time).thenReturn(timeInMillis)
+ clock.time = timeInMillis
}
private fun String.toEpochMillis() = LocalDateTime.parse(this).toEpochMillis()
diff --git a/app/ui/legacy/src/test/java/com/fsck/k9/ui/settings/general/GeneralSettingsViewModelTest.kt b/app/ui/legacy/src/test/java/com/fsck/k9/ui/settings/general/GeneralSettingsViewModelTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5037a828c172bb1410bdd89d88721da8a39a81e9
--- /dev/null
+++ b/app/ui/legacy/src/test/java/com/fsck/k9/ui/settings/general/GeneralSettingsViewModelTest.kt
@@ -0,0 +1,148 @@
+package com.fsck.k9.ui.settings.general
+
+import android.net.Uri
+import app.cash.turbine.test
+import com.fsck.k9.logging.LogFileWriter
+import com.google.common.truth.Truth.assertThat
+import java.io.IOException
+import kotlinx.coroutines.CoroutineName
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.take
+import kotlinx.coroutines.flow.toList
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.test.TestCoroutineDispatcher
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.setMain
+import kotlinx.coroutines.withTimeout
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.mockito.kotlin.mock
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class GeneralSettingsViewModelTest {
+ private val logFileWriter = TestLogFileWriter()
+ private val contentUri = mock()
+ private val viewModel = GeneralSettingsViewModel(logFileWriter)
+ private val testCoroutineDispatcher = TestCoroutineDispatcher()
+
+ @Before
+ fun setUp() {
+ Dispatchers.setMain(testCoroutineDispatcher)
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun `export logs without errors`() = runBlocking {
+ viewModel.uiState.test {
+ viewModel.exportLogs(contentUri)
+
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Exporting)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Success)
+ testCoroutineDispatcher.advanceTimeBy(GeneralSettingsViewModel.SNACKBAR_DURATION)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(cancelAndConsumeRemainingEvents()).isEmpty()
+ }
+ }
+
+ @Test
+ fun `export logs with consumer changing while LogFileWriter_writeLogTo is running`() = runBlocking {
+ withTimeout(timeMillis = 1000L) {
+ logFileWriter.shouldWait()
+
+ val mutex = Mutex(locked = true)
+
+ // The first consumer
+ val job = launch(CoroutineName("ConsumerOne")) {
+ var first = true
+ val states = viewModel.uiState.onEach {
+ if (first) {
+ first = false
+ mutex.unlock()
+ }
+ }.take(2).toList()
+
+ assertThat(states[0]).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(states[1]).isEqualTo(GeneralSettingsUiState.Exporting)
+ }
+
+ // Wait until the "ConsumerOne" coroutine has collected the initial UI state
+ mutex.lock()
+
+ viewModel.exportLogs(contentUri)
+
+ // Wait until the "ConsumerOne" coroutine has finished collecting items
+ job.join()
+
+ // The second consumer
+ viewModel.uiState.test {
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Exporting)
+ logFileWriter.resume()
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Success)
+ testCoroutineDispatcher.advanceTimeBy(GeneralSettingsViewModel.SNACKBAR_DURATION)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(cancelAndConsumeRemainingEvents()).isEmpty()
+ }
+ }
+ }
+
+ @Test
+ fun `export logs with IOException`() = runBlocking {
+ logFileWriter.exception = IOException()
+
+ viewModel.uiState.test {
+ viewModel.exportLogs(contentUri)
+
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Exporting)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Failure)
+ testCoroutineDispatcher.advanceTimeBy(GeneralSettingsViewModel.SNACKBAR_DURATION)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(cancelAndConsumeRemainingEvents()).isEmpty()
+ }
+ }
+
+ @Test
+ fun `export logs with IllegalStateException`() = runBlocking {
+ logFileWriter.exception = IllegalStateException()
+
+ viewModel.uiState.test {
+ viewModel.exportLogs(contentUri)
+
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Exporting)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Failure)
+ testCoroutineDispatcher.advanceTimeBy(GeneralSettingsViewModel.SNACKBAR_DURATION)
+ assertThat(awaitItem()).isEqualTo(GeneralSettingsUiState.Idle)
+ assertThat(cancelAndConsumeRemainingEvents()).isEmpty()
+ }
+ }
+}
+
+class TestLogFileWriter : LogFileWriter {
+ var exception: Throwable? = null
+ private var mutex: Mutex? = null
+
+ override suspend fun writeLogTo(contentUri: Uri) {
+ exception?.let { throw it }
+
+ mutex?.lock()
+ }
+
+ fun shouldWait() {
+ mutex = Mutex(locked = true)
+ }
+
+ fun resume() {
+ mutex!!.unlock()
+ }
+}
diff --git a/app/ui/setup/build.gradle b/app/ui/setup/build.gradle
index 31d37bcb441723904a4c8c7cd1bd5d3be2b133de..73b431bd9972539a50c5d46a9613a0400500675a 100644
--- a/app/ui/setup/build.gradle
+++ b/app/ui/setup/build.gradle
@@ -2,29 +2,23 @@ apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.android'
dependencies {
- api project(":app:ui:base")
implementation project(":app:core")
- implementation project(":app:autodiscovery:api")
implementation project(":mail:common")
+ implementation project(":app:autodiscovery:api")
- implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.androidxLifecycle}"
- implementation "androidx.lifecycle:lifecycle-livedata-ktx:${versions.androidxLifecycle}"
- implementation "androidx.constraintlayout:constraintlayout:${versions.androidxConstraintLayout}"
- implementation "androidx.core:core-ktx:${versions.androidxCore}"
implementation "com.jakewharton.timber:timber:${versions.timber}"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlinCoroutines}"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlinCoroutines}"
+ implementation "com.squareup.okhttp3:okhttp:${versions.okhttp}"
- testImplementation project(':mail:testing')
testImplementation project(':app:testing')
+ testImplementation project(":backend:imap")
testImplementation "org.robolectric:robolectric:${versions.robolectric}"
+ testImplementation "androidx.test:core:${versions.androidxTestCore}"
testImplementation "junit:junit:${versions.junit}"
testImplementation "com.google.truth:truth:${versions.truth}"
testImplementation "org.mockito:mockito-core:${versions.mockito}"
testImplementation "org.mockito.kotlin:mockito-kotlin:${versions.mockitoKotlin}"
testImplementation "org.koin:koin-test:${versions.koin}"
}
-
android {
compileSdkVersion buildConfig.compileSdk
buildToolsVersion buildConfig.buildTools
diff --git a/backend/demo/build.gradle b/backend/demo/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..62e0bd34fdd5f22e75a0afa7bef0447522bfde05
--- /dev/null
+++ b/backend/demo/build.gradle
@@ -0,0 +1,50 @@
+apply plugin: 'com.android.library'
+apply plugin: 'org.jetbrains.kotlin.android'
+apply plugin: 'kotlin-kapt'
+
+if (rootProject.testCoverage) {
+ apply plugin: 'jacoco'
+}
+
+dependencies {
+ api project(":backend:api")
+
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlinCoroutines}"
+ implementation "com.jakewharton.timber:timber:${versions.timber}"
+ implementation "com.squareup.moshi:moshi:${versions.moshi}"
+ kapt "com.squareup.moshi:moshi-kotlin-codegen:${versions.moshi}"
+
+ testImplementation project(":mail:testing")
+ testImplementation "junit:junit:${versions.junit}"
+ testImplementation "org.mockito:mockito-core:${versions.mockito}"
+ testImplementation "com.google.truth:truth:${versions.truth}"
+}
+
+android {
+ compileSdkVersion buildConfig.compileSdk
+ buildToolsVersion buildConfig.buildTools
+
+ defaultConfig {
+ minSdkVersion buildConfig.minSdk
+ }
+
+ buildTypes {
+ debug {
+ testCoverageEnabled rootProject.testCoverage
+ }
+ }
+
+ lintOptions {
+ abortOnError false
+ lintConfig file("$rootProject.projectDir/config/lint/lint.xml")
+ }
+
+ compileOptions {
+ sourceCompatibility javaVersion
+ targetCompatibility javaVersion
+ }
+
+ kotlinOptions {
+ jvmTarget = kotlinJvmVersion
+ }
+}
diff --git a/backend/demo/src/main/AndroidManifest.xml b/backend/demo/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d9551f0716026c19508d893cd3e8c63525b4aaec
--- /dev/null
+++ b/backend/demo/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/backend/demo/src/main/java/app/k9mail/backend/demo/DemoBackend.kt b/backend/demo/src/main/java/app/k9mail/backend/demo/DemoBackend.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cfc686e3cbc39a13092b3260349e471e269905dd
--- /dev/null
+++ b/backend/demo/src/main/java/app/k9mail/backend/demo/DemoBackend.kt
@@ -0,0 +1,211 @@
+package app.k9mail.backend.demo
+
+import com.fsck.k9.backend.api.Backend
+import com.fsck.k9.backend.api.BackendFolder.MoreMessages
+import com.fsck.k9.backend.api.BackendPusher
+import com.fsck.k9.backend.api.BackendPusherCallback
+import com.fsck.k9.backend.api.BackendStorage
+import com.fsck.k9.backend.api.FolderInfo
+import com.fsck.k9.backend.api.SyncConfig
+import com.fsck.k9.backend.api.SyncListener
+import com.fsck.k9.backend.api.updateFolders
+import com.fsck.k9.mail.BodyFactory
+import com.fsck.k9.mail.Flag
+import com.fsck.k9.mail.FolderType
+import com.fsck.k9.mail.Message
+import com.fsck.k9.mail.MessageDownloadState
+import com.fsck.k9.mail.Part
+import com.fsck.k9.mail.internet.MimeMessage
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.adapter
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.InputStream
+import java.util.UUID
+import okio.buffer
+import okio.source
+
+class DemoBackend(private val backendStorage: BackendStorage) : Backend {
+ private val messageStoreInfo by lazy { readMessageStoreInfo() }
+
+ override val supportsFlags: Boolean = true
+ override val supportsExpunge: Boolean = false
+ override val supportsMove: Boolean = true
+ override val supportsCopy: Boolean = true
+ override val supportsUpload: Boolean = true
+ override val supportsTrashFolder: Boolean = true
+ override val supportsSearchByDate: Boolean = false
+ override val isPushCapable: Boolean = false
+ override val isDeleteMoveToTrash: Boolean = true
+
+ override fun refreshFolderList() {
+ val localFolderServerIds = backendStorage.getFolderServerIds().toSet()
+
+ backendStorage.updateFolders {
+ val remoteFolderServerIds = messageStoreInfo.keys
+ val foldersServerIdsToCreate = remoteFolderServerIds - localFolderServerIds
+ val foldersToCreate = foldersServerIdsToCreate.mapNotNull { folderServerId ->
+ messageStoreInfo[folderServerId]?.let { folderData ->
+ FolderInfo(folderServerId, folderData.name, folderData.type)
+ }
+ }
+ createFolders(foldersToCreate)
+
+ val folderServerIdsToRemove = (localFolderServerIds - remoteFolderServerIds).toList()
+ deleteFolders(folderServerIdsToRemove)
+ }
+ }
+
+ override fun sync(folderServerId: String, syncConfig: SyncConfig, listener: SyncListener) {
+ listener.syncStarted(folderServerId)
+
+ val folderData = messageStoreInfo[folderServerId]
+ if (folderData == null) {
+ listener.syncFailed(folderServerId, "Folder $folderServerId doesn't exist", null)
+ return
+ }
+
+ val backendFolder = backendStorage.getFolder(folderServerId)
+
+ val localMessageServerIds = backendFolder.getMessageServerIds()
+ if (localMessageServerIds.isNotEmpty()) {
+ listener.syncFinished(folderServerId)
+ return
+ }
+
+ for (messageServerId in folderData.messageServerIds) {
+ val message = loadMessage(folderServerId, messageServerId)
+ backendFolder.saveMessage(message, MessageDownloadState.FULL)
+ listener.syncNewMessage(folderServerId, messageServerId, isOldMessage = false)
+ }
+
+ backendFolder.setMoreMessages(MoreMessages.FALSE)
+
+ listener.syncFinished(folderServerId)
+ }
+
+ override fun downloadMessage(syncConfig: SyncConfig, folderServerId: String, messageServerId: String) {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun downloadMessageStructure(folderServerId: String, messageServerId: String) {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun downloadCompleteMessage(folderServerId: String, messageServerId: String) {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun setFlag(folderServerId: String, messageServerIds: List, flag: Flag, newState: Boolean) = Unit
+
+ override fun markAllAsRead(folderServerId: String) = Unit
+
+ override fun expunge(folderServerId: String) {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun expungeMessages(folderServerId: String, messageServerIds: List) {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun deleteMessages(folderServerId: String, messageServerIds: List) = Unit
+
+ override fun deleteAllMessages(folderServerId: String) = Unit
+
+ override fun moveMessages(
+ sourceFolderServerId: String,
+ targetFolderServerId: String,
+ messageServerIds: List
+ ): Map {
+ // We do just enough to simulate a successful operation on the server.
+ return messageServerIds.associateWith { createNewServerId() }
+ }
+
+ override fun moveMessagesAndMarkAsRead(
+ sourceFolderServerId: String,
+ targetFolderServerId: String,
+ messageServerIds: List
+ ): Map {
+ // We do just enough to simulate a successful operation on the server.
+ return messageServerIds.associateWith { createNewServerId() }
+ }
+
+ override fun copyMessages(
+ sourceFolderServerId: String,
+ targetFolderServerId: String,
+ messageServerIds: List
+ ): Map {
+ // We do just enough to simulate a successful operation on the server.
+ return messageServerIds.associateWith { createNewServerId() }
+ }
+
+ override fun search(
+ folderServerId: String,
+ query: String?,
+ requiredFlags: Set?,
+ forbiddenFlags: Set?,
+ performFullTextSearch: Boolean
+ ): List {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun fetchPart(folderServerId: String, messageServerId: String, part: Part, bodyFactory: BodyFactory) {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun findByMessageId(folderServerId: String, messageId: String): String? {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ override fun uploadMessage(folderServerId: String, message: Message): String {
+ return createNewServerId()
+ }
+
+ override fun checkIncomingServerSettings() = Unit
+
+ override fun checkOutgoingServerSettings() = Unit
+
+ override fun sendMessage(message: Message) {
+ val inboxServerId = messageStoreInfo.filterValues { it.type == FolderType.INBOX }.keys.first()
+ val backendFolder = backendStorage.getFolder(inboxServerId)
+
+ val newMessage = message.copy(uid = createNewServerId())
+ backendFolder.saveMessage(newMessage, MessageDownloadState.FULL)
+ }
+
+ override fun createPusher(callback: BackendPusherCallback): BackendPusher {
+ throw UnsupportedOperationException("not implemented")
+ }
+
+ private fun createNewServerId() = UUID.randomUUID().toString()
+
+ private fun Message.copy(uid: String): MimeMessage {
+ val outputStream = ByteArrayOutputStream()
+ writeTo(outputStream)
+ val inputStream = ByteArrayInputStream(outputStream.toByteArray())
+ return MimeMessage.parseMimeMessage(inputStream, false).apply {
+ this.uid = uid
+ }
+ }
+
+ @OptIn(ExperimentalStdlibApi::class)
+ private fun readMessageStoreInfo(): MessageStoreInfo {
+ return getResourceAsStream("/contents.json").source().buffer().use { bufferedSource ->
+ val moshi = Moshi.Builder().build()
+ val adapter = moshi.adapter()
+ adapter.fromJson(bufferedSource)
+ } ?: error("Couldn't read message store info")
+ }
+
+ private fun loadMessage(folderServerId: String, messageServerId: String): Message {
+ return getResourceAsStream("/$folderServerId/$messageServerId.eml").use { inputStream ->
+ MimeMessage.parseMimeMessage(inputStream, false).apply {
+ uid = messageServerId
+ }
+ }
+ }
+
+ private fun getResourceAsStream(name: String): InputStream {
+ return DemoBackend::class.java.getResourceAsStream(name) ?: error("Resource '$name' not found")
+ }
+}
diff --git a/backend/demo/src/main/java/app/k9mail/backend/demo/MessageStoreInfo.kt b/backend/demo/src/main/java/app/k9mail/backend/demo/MessageStoreInfo.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6176d43b1ce4fe2a5a128b16d6b24a0857c297cb
--- /dev/null
+++ b/backend/demo/src/main/java/app/k9mail/backend/demo/MessageStoreInfo.kt
@@ -0,0 +1,13 @@
+package app.k9mail.backend.demo
+
+import com.fsck.k9.mail.FolderType
+import com.squareup.moshi.JsonClass
+
+typealias MessageStoreInfo = Map
+
+@JsonClass(generateAdapter = true)
+data class FolderData(
+ val name: String,
+ val type: FolderType,
+ val messageServerIds: List
+)
diff --git a/backend/demo/src/main/resources/contents.json b/backend/demo/src/main/resources/contents.json
new file mode 100644
index 0000000000000000000000000000000000000000..87879b8cc2f1de686566614b4fd2062f1eb0546c
--- /dev/null
+++ b/backend/demo/src/main/resources/contents.json
@@ -0,0 +1,53 @@
+{
+ "inbox": {
+ "name": "Inbox",
+ "type": "INBOX",
+ "messageServerIds": ["intro"]
+ },
+ "trash": {
+ "name": "Trash",
+ "type": "TRASH",
+ "messageServerIds": []
+ },
+ "drafts": {
+ "name": "Drafts",
+ "type": "DRAFTS",
+ "messageServerIds": []
+ },
+ "sent": {
+ "name": "Sent",
+ "type": "SENT",
+ "messageServerIds": []
+ },
+ "archive": {
+ "name": "Archive",
+ "type": "ARCHIVE",
+ "messageServerIds": []
+ },
+ "spam": {
+ "name": "Spam",
+ "type": "SPAM",
+ "messageServerIds": []
+ },
+ "turing": {
+ "name": "Turing Awards",
+ "type": "REGULAR",
+ "messageServerIds": [
+ "turing_award_1966",
+ "turing_award_1967",
+ "turing_award_1968",
+ "turing_award_1970",
+ "turing_award_1971",
+ "turing_award_1972",
+ "turing_award_1975",
+ "turing_award_1977",
+ "turing_award_1978",
+ "turing_award_1979",
+ "turing_award_1981",
+ "turing_award_1983",
+ "turing_award_1987",
+ "turing_award_1991",
+ "turing_award_1996"
+ ]
+ }
+}
diff --git a/backend/demo/src/main/resources/inbox/intro.eml b/backend/demo/src/main/resources/inbox/intro.eml
new file mode 100644
index 0000000000000000000000000000000000000000..8ff767f59ae832f2ce8de5237340d77bc0b21165
--- /dev/null
+++ b/backend/demo/src/main/resources/inbox/intro.eml
@@ -0,0 +1,9 @@
+MIME-Version: 1.0
+From: "cketti"
+Date: Thu, 23 Sep 2021 23:42:00 +0200
+Message-ID:
+Subject: Welcome to K-9 Mail
+To: User
+Content-Type: text/plain; charset=UTF-8
+
+Congratulations, you have managed to set up K-9 Mail's demo account. Have fun exploring the app.
diff --git a/backend/demo/src/main/resources/turing/turing_award_1966.eml b/backend/demo/src/main/resources/turing/turing_award_1966.eml
new file mode 100644
index 0000000000000000000000000000000000000000..6ad832041daf3701527e3d9cfc6d0557d954821b
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1966.eml
@@ -0,0 +1,84 @@
+MIME-Version: 1.0
+From: "Alan J. Perlis"
+Date: Sat, 01 Jan 1966 12:00:00 -0400
+Message-ID:
+Subject: The Synthesis of Algorithmic Systems
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7b450b100959e604d85a5320
+
+--047d7b450b100959e604d85a5320
+Content-Type: text/plain; charset=UTF-8
+
+Both knowledge and wisdom extend man's reach. Knowledge led to computers,
+wisdom to chopsticks. Unfortunately our association is overinvolved with
+the former. The latter will have to wait for a more sublime day.
+On what does and will the fame of Turing rest? That he proved a theorem
+showing that for a general computing device--later dubbed a "Turing
+machine"--there existed functions which it could not compute? I doubt it.
+More likely it rests on the model he invented and employed: his formal
+mechanism.
+This model has captured the imagination and mobilized the thoughts of a
+generation of scientists. It has provided a basis for arguments leading to
+theories. His model has proved so useful that its generated activity has
+been distributed not only in mathematics, but through several technologies
+as well. The arguments that have been employed are not always formal and
+the consequent creations not all abstract.
+Indeed a most fruitful consequence of the Turing machine has been with the
+creation, study and computation of functions which are computable, i.e., in
+computer programming. This is not surprising since computers can compute so
+much more than we yet know how to specify.
+I am sure that all will agree that this model has been enormously valuable.
+History will forgive me for not devoting any attention in this lecture to
+the effect which Turing had on the development of the general-purpose
+digital computer, which has further accelerated our involvement with the
+theory and practice of computation.
+Since the appearance of Turing's model there have, of course, been others
+which have concerned and benefited us in computing. I think, however, that
+only one has had an effect as great as Turing's: the formal mechanism
+called ALGOL Many will immediately disagree, pointing out that too few of
+us have understood it or used it.
+While such has, unhappily, been the case, it is not the point. The impulse
+given by ALGOL to the development of research in computer science is
+relevant while the number of adherents is not. ALGOL, too, has mobilized
+our thoughts and has provided us with a basis for our arguments.
+
+--047d7b450b100959e604d85a5320
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
Both knowledge and wisdom extend man's reach. Kno=
+wledge led to computers, wisdom to chopsticks. Unfortunately our associatio=
+n is overinvolved with the former. The latter will have to wait for a more =
+sublime day.=C2=A0
+
On what does and will the fame of Turing rest? That he proved a theore=
+m showing that for a general computing device--later dubbed a "Turing =
+machine"--there existed functions which it could not compute? I doubt =
+it. More likely it rests on the model he invented and employed: his formal =
+mechanism.=C2=A0
+
This model has captured the imagination and mobilized the thoughts of =
+a generation of scientists. It has provided a basis for arguments leading t=
+o theories. His model has proved so useful that its generated activity has =
+been distributed not only in mathematics, but through several technologies =
+as well. The arguments that have been employed are not always formal and th=
+e consequent creations not all abstract.=C2=A0
+
Indeed a most fruitful consequence of the Turing machine has been with=
+ the creation, study and computation of functions which are computable, i.e=
+., in computer programming. This is not surprising since computers can comp=
+ute so much more than we yet know how to specify.=C2=A0
+
I am sure that all will agree that this model has been enormously valu=
+able. History will forgive me for not devoting any attention in this lectur=
+e to the effect which Turing had on the development of the general-purpose =
+digital computer, which has further accelerated our involvement with the th=
+eory and practice of computation.=C2=A0
+
Since the appearance of Turing's model there have, of course, been=
+ others which have concerned and benefited us in computing. I think, howeve=
+r, that only one has had an effect as great as Turing's: the formal mec=
+hanism called ALGOL Many will immediately disagree, pointing out that too f=
+ew of us have understood it or used it.=C2=A0
+
While such has, unhappily, been the case, it is not the point. The imp=
+ulse given by ALGOL to the development of research in computer science is r=
+elevant while the number of adherents is not. ALGOL, too, has mobilized our=
+ thoughts and has provided us with a basis for our arguments.=C2=A0
+
+
+--047d7b450b100959e604d85a5320--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1967.eml b/backend/demo/src/main/resources/turing/turing_award_1967.eml
new file mode 100644
index 0000000000000000000000000000000000000000..a7e3299e195a22ab56a257d5e629214e88796218
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1967.eml
@@ -0,0 +1,35 @@
+MIME-Version: 1.0
+From: "Maurice V. Wilkes"
+Date: Wed, 30 Aug 1967 12:00:00 -0400
+Message-ID:
+Subject: Computers Then and Now
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7b5d9bdd0d571a04d85aec30
+
+--047d7b5d9bdd0d571a04d85aec30
+Content-Type: text/plain; charset=UTF-8
+
+I do not imagine that many of the Turing lecturers who will follow me will
+be people who were acquainted with Alan Turing. The work on computable
+numbers, for which he is famous, was published in 1936 before digital
+computers existed. Later he became one of the first of a distinguished
+succession of able mathematicians who have made contributions to the
+computer field. He was a colorful figure in the early days of digital
+computer development in England, and I would find it difficult to speak of
+that period without making some references to him.
+
+--047d7b5d9bdd0d571a04d85aec30
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
I do not imagine that many of the Turing lecturers wh=
+o will follow me will be people who were acquainted with Alan Turing. The w=
+ork on computable numbers, for which he is famous, was published in 1936 be=
+fore digital computers existed. Later he became one of the first of a disti=
+nguished succession of able mathematicians who have made contributions to t=
+he computer field. He was a colorful figure in the early days of digital co=
+mputer development in England, and I would find it difficult to speak of th=
+at period without making some references to him.
+
+
+--047d7b5d9bdd0d571a04d85aec30--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1968.eml b/backend/demo/src/main/resources/turing/turing_award_1968.eml
new file mode 100644
index 0000000000000000000000000000000000000000..274260c0ee707587afee28b0b5fae77335d9ffa7
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1968.eml
@@ -0,0 +1,40 @@
+MIME-Version: 1.0
+From: Richard Hamming
+Date: Tue, 27 Aug 1968 12:00:00 -0400
+Message-ID:
+Subject: One Man's View of Computer Science
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=089e01227b30f6f60004d85af2ae
+
+--089e01227b30f6f60004d85af2ae
+Content-Type: text/plain; charset=UTF-8
+
+Let me begin with a few personal words. When one is notified that he has
+been elected the ACM Turing lecturer for the year, he is at first
+surprised--especially is the nonacademic person surprised by an ACM award.
+After a little while the surprise is replaced by a feeling of pleasure.
+Still later comes a feeling of "Why me?" With all that has been done and is
+being done in computing, why single out me and my work? Well, I suppose
+that it has to happen to someone each year, and this
+time I am the lucky person. Anyway, let me thank you for the honor you have
+given to me and by inference to the Bell Telephone Laboratories where I
+work and which has made possible so much of what I have done.
+
+--089e01227b30f6f60004d85af2ae
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
Let me begin with a few personal words. When one is n=
+otified that he has been elected the ACM Turing lecturer for the year, he i=
+s at first surprised--especially is the nonacademic person surprised by an =
+ACM award. After a little while the surprise is replaced by a feeling of pl=
+easure. Still later comes a feeling of "Why me?" With all that ha=
+s been done and is being done in computing, why single out me and my work? =
+Well, I suppose that it has to happen to someone each year, and this=C2=A0<=
+/div>
+
time I am the lucky person. Anyway, let me thank you for the honor you=
+ have given to me and by inference to the Bell Telephone Laboratories where=
+ I work and which has made possible so much of what I have done.
+
+--089e01227b30f6f60004d85af2ae--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1970.eml b/backend/demo/src/main/resources/turing/turing_award_1970.eml
new file mode 100644
index 0000000000000000000000000000000000000000..811130ac1dd71b5e6a5b7487a10c388861e75dad
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1970.eml
@@ -0,0 +1,35 @@
+MIME-Version: 1.0
+From: "James H. Wilkinson"
+Date: Tue, 01 Sep 1970 12:00:00 -0400
+Message-ID:
+Subject: Some Comments from a Numerical Analyst
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7b5d9bdd9697d504d85ac65f
+
+--047d7b5d9bdd9697d504d85ac65f
+Content-Type: text/plain; charset=UTF-8
+
+When at last I recovered from the feeling of shocked elation at being
+invited to give the 1970 Turing Award Lecture, I became aware that I must
+indeed prepare an appropriate lecture. There appears to be a tradition that
+a Turing Lecturer should decide for himself what is expected from him, and
+probably for this reason previous lectures have differed considerably in
+style and content. However, it was made quite clear that I was to give an
+after-luncheon speech and that I would not have the benefit of an overhead
+projector or a blackboard.
+
+--047d7b5d9bdd9697d504d85ac65f
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
When at last I recovered from the feeling of shocked =
+elation at being invited to give the 1970 Turing Award Lecture, I became aw=
+are that I must indeed prepare an appropriate lecture. There appears to be =
+a tradition that a Turing Lecturer should decide for himself what is expect=
+ed from him, and probably for this reason previous lectures have differed c=
+onsiderably in style and content. However, it was made quite clear that I w=
+as to give an after-luncheon speech and that I would not have the benefit o=
+f an overhead projector or a blackboard.
+
+
+--047d7b5d9bdd9697d504d85ac65f--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1971.eml b/backend/demo/src/main/resources/turing/turing_award_1971.eml
new file mode 100644
index 0000000000000000000000000000000000000000..387f995770901c6ce0706a62f7f297833912e23a
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1971.eml
@@ -0,0 +1,32 @@
+MIME-Version: 1.0
+From: John McCarthy
+Date: Fri, 01 Jan 1971 12:00:00 -0400
+Message-ID:
+Subject: Generality in Artificial Intelligence
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=089e01030106b6942904d85ad870
+
+--089e01030106b6942904d85ad870
+Content-Type: text/plain; charset=UTF-8
+
+Postscript
+My 1971 Turing Award Lecture was entitled "Generality in Artificial
+Intelligence." The topic turned out to have been overambitious in that I
+discovered that I was unable to put my thoughts on the subject in a
+satisfactory written form at that time. It would have been better to have
+reviewed previous work rather than attempt something new, but such wasn't
+my custom at that time.
+
+--089e01030106b6942904d85ad870
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
Postscript
My 1971 Turing Award Lecture was=
+ entitled "Generality in Artificial Intelligence." The topic turn=
+ed out to have been overambitious in that I discovered that I was unable to=
+ put my thoughts on the subject in a satisfactory written form at that time=
+. It would have been better to have reviewed previous work rather than atte=
+mpt something new, but such wasn't my custom at that time.
+
+
+--089e01030106b6942904d85ad870--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1972.eml b/backend/demo/src/main/resources/turing/turing_award_1972.eml
new file mode 100644
index 0000000000000000000000000000000000000000..9c533bdbd980523196e57ab8c84930c4e9175472
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1972.eml
@@ -0,0 +1,27 @@
+MIME-Version: 1.0
+From: "Edsger W. Dijkstra"
+Date: Mon, 02 Aug 1972 12:00:00 -0500
+Message-ID:
+Subject: The Humble Programmer
+To: Alan Turing
+Content-Type: text/plain; charset=UTF-8; format=flowed
+
+As a result of a long sequence of coincidences I entered the programming
+profession officially on the first spring morning of 1952, and as far as
+I have been able to trace, I was the first Dutchman to do so in my
+country. In retrospect the most amazing thing is the slowness with which,
+at least in my part of the world, the programming profession emerged, a
+slowness which is now hard to believe. But I am grateful for two vivid
+recollections from that period that establish that slowness beyond any
+doubt.
+
+After having programmed for some three years, I had a discussion with
+van Wijngaarden, who was then my boss at the Mathematical Centre in
+Amsterdam - a discussion for which I shall remain grateful to him
+as long as I live. The point was that I was supposed to study theoretical
+physics at the University of Leiden simultaneously, and as I found the
+two activities harder and harder to combine, I had to make up my
+mind, either to stop programming and become a real, respectable theoretical
+physicist, or to carry my study of physics to a formal completion only,
+with a minimum of effort, and to become..., yes what? A programmer?
+But was that a respectable profession? After all, what was programming?
diff --git a/backend/demo/src/main/resources/turing/turing_award_1975.eml b/backend/demo/src/main/resources/turing/turing_award_1975.eml
new file mode 100644
index 0000000000000000000000000000000000000000..f91e9ec5c6e010e8d8dc936c3592bf10c5889dc0
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1975.eml
@@ -0,0 +1,30 @@
+MIME-Version: 1.0
+From: Allen Newell
+Cc: Herbert Simon
+Date: Mon, 20 Oct 1975 12:00:00 -0500
+Message-ID:
+Subject: Computer Science as Empirical Inquiry: Symbols and Search
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7b450b1092035304d85abf33
+
+--047d7b450b1092035304d85abf33
+Content-Type: text/plain; charset=UTF-8
+
+Computer science is the study of the phenomena surrounding computers. The
+founders of this society understood this very well when they called
+themselves the Association for Computing Machinery. The machine---not just
+the hardware, but the programmed, living machine--is the organism we study.
+
+--047d7b450b1092035304d85abf33
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
Computer science is the study of the phenomena surrounding=
+ computers. The founders of this society understood this very well when the=
+y called themselves the Association for Computing Machinery. The machine---=
+not just the hardware, but the programmed, living machine--is the organism =
+we study.
+
+
+
+--047d7b450b1092035304d85abf33--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1977.eml b/backend/demo/src/main/resources/turing/turing_award_1977.eml
new file mode 100644
index 0000000000000000000000000000000000000000..51cafd472a852965fe53552e39ef0f12775f8b8c
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1977.eml
@@ -0,0 +1,39 @@
+MIME-Version: 1.0
+From: "John W. Backus"
+Date: Mon, 17 Oct 1977 12:00:00 -0700
+Message-ID:
+Subject: Can Programming Be Liberated from the von Neumann Style? A Functional
+ Style and Its Algebra of Programs
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7b5d9bdd8a36e804d85ade47
+
+--047d7b5d9bdd8a36e804d85ade47
+Content-Type: text/plain; charset=UTF-8
+
+Conventional programming languages are growing ever more enormous, but not
+stronger. Inherent defects at the most basic level cause them to be both
+fat and weak: their primitive word-at-a-time style of programming inherited
+from their common ancestor--the von Neumann computer, their close coupling
+of semantics to state transitions, their division of programming into a
+world of expressions and a world of statements, their inability to
+effectively use powerful combining forms for building new programs from
+existing ones, and their lack of useful mathematical properties for
+reasoning about
+programs.
+
+--047d7b5d9bdd8a36e804d85ade47
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
Conventional programming languages are growing ever m=
+ore enormous, but not stronger. Inherent defects at the most basic level ca=
+use them to be both fat and weak: their primitive word-at-a-time style of p=
+rogramming inherited from their common ancestor--the von Neumann computer, =
+their close coupling of semantics to state transitions, their division of p=
+rogramming into a world of expressions and a world of statements, their ina=
+bility to effectively use powerful combining forms for building new program=
+s from existing ones, and their lack of useful mathematical properties for =
+reasoning about=C2=A0
+
programs.
+
+--047d7b5d9bdd8a36e804d85ade47--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1978.eml b/backend/demo/src/main/resources/turing/turing_award_1978.eml
new file mode 100644
index 0000000000000000000000000000000000000000..a1001324abb2da9cbbddb711443b368e3511d338
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1978.eml
@@ -0,0 +1,36 @@
+MIME-Version: 1.0
+From: Robert Floyd
+Date: Mon, 04 Dec 1978 12:00:00 -0500
+Message-ID:
+Subject: The Paradigms of Programming
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=089e0118419206e64304d85af860
+
+--089e0118419206e64304d85af860
+Content-Type: text/plain; charset=UTF-8
+
+Today I want to talk about the paradigms of programming, how they affect
+our success as designers of computer programs, how they should be taught,
+and how they should be embodied in our programming languages.
+A familiar example of a paradigm of programming is the technique of
+structured programming, which appears to be the dominant paradigm in most
+current treatments of programming methodology. Structured programming, as
+formulated by Dijkstra, Wirth, and Parnas, among others, consists of two
+phases.
+
+--089e0118419206e64304d85af860
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
Today I want to talk about the paradigms of programmi=
+ng, how they affect our success as designers of computer programs, how they=
+ should be taught, and how they should be embodied in our programming langu=
+ages.=C2=A0
+
A familiar example of a paradigm of programming is the technique of st=
+ructured programming, which appears to be the dominant paradigm in most cur=
+rent treatments of programming methodology. Structured programming, as form=
+ulated by Dijkstra, Wirth, and Parnas, among others, consists of two phases=
+.=C2=A0
+
+
+--089e0118419206e64304d85af860--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1979.eml b/backend/demo/src/main/resources/turing/turing_award_1979.eml
new file mode 100644
index 0000000000000000000000000000000000000000..9322643ae4768117af4c6bc87847e43e38c2edfb
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1979.eml
@@ -0,0 +1,33 @@
+MIME-Version: 1.0
+From: "Kenneth E. Iverson"
+Date: Mon, 29 Oct 1979 12:00:00 -0500
+Message-ID:
+Subject: Notation as a Tool of Thought
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=20cf30549cad76254e04d85ae4df
+
+--20cf30549cad76254e04d85ae4df
+Content-Type: text/plain; charset=UTF-8
+
+The importance of nomenclature, notation, and language as tools of thought
+has long been recognized. In chemistry and in botany, for example, the
+establishment of systems of nomenclature by Lavoisier and Linnaeus did much
+to stimulate and to channel later investigation. Concerning language,
+George Boole in his Laws off Thought asserted "That language is an
+instrument of human reason, and not merely a medium for the expression of
+thought, is a truth generally admitted."
+
+--20cf30549cad76254e04d85ae4df
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
The importance of nomenclature, notation, and languag=
+e as tools of thought has long been recognized. In chemistry and in botany,=
+ for example, the establishment of systems of nomenclature by Lavoisier and=
+ Linnaeus did much to stimulate and to channel later investigation. Concern=
+ing language, George Boole in his Laws off Thought asserted "That lang=
+uage is an instrument of human reason, and not merely a medium for the expr=
+ession of thought, is a truth generally admitted."
+
+
+--20cf30549cad76254e04d85ae4df--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1981.eml b/backend/demo/src/main/resources/turing/turing_award_1981.eml
new file mode 100644
index 0000000000000000000000000000000000000000..6dd8e51d42c0e122e342f8106ab5ca285b36deef
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1981.eml
@@ -0,0 +1,51 @@
+MIME-Version: 1.0
+From: "Edgar F. Codd"
+Date: Wed, 11 Nov 1981 12:00:00 -0800
+Message-ID:
+Subject: Relational Database: A Practical Foundation for Productivity
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7bfd026c782f2404d85ab4b8
+
+--047d7bfd026c782f2404d85ab4b8
+Content-Type: text/plain; charset=UTF-8
+
+It is well known that the growth in demands from end users for new
+applications is outstripping the capability of data processing departments
+to implement the corresponding application programs. There are two
+complementary approaches to attacking this problem (and both approaches are
+needed): one is to put end users into direct touch with the information
+stored in computers; the other is to increase the productivity of data
+processing professionals in the development of application programs. It is
+less well known that a single technology, relational database management,
+provides a practical foundation for both approaches. It is explained why
+this
+is so.
+While developing this productivity theme, it is noted that the time has
+come to draw a very sharp line between relational and non-relational
+database systems, so that the label "relational" will not be used in
+misleading ways.
+The key to drawing this line is something called a "relational processing
+capability."
+
+--047d7bfd026c782f2404d85ab4b8
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
It is well known that the growth in demands from end =
+users for new applications is outstripping the capability of data processin=
+g departments to implement the corresponding application programs. There ar=
+e two complementary approaches to attacking this problem (and both approach=
+es are needed): one is to put end users into direct touch with the informat=
+ion stored in computers; the other is to increase the productivity of data =
+processing professionals in the development of application programs. It is =
+less well known that a single technology, relational database management, p=
+rovides a practical foundation for both approaches. It is explained why thi=
+s=C2=A0
+
is so.=C2=A0
While developing this productivity theme, =
+it is noted that the time has come to draw a very sharp line between relati=
+onal and non-relational database systems, so that the label "relationa=
+l" will not be used in misleading ways.=C2=A0
+
The key to drawing this line is something called a "relational pr=
+ocessing capability."
+
+--047d7bfd026c782f2404d85ab4b8--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1983.eml b/backend/demo/src/main/resources/turing/turing_award_1983.eml
new file mode 100644
index 0000000000000000000000000000000000000000..798cdf521686ac780afc7e1d7ee26b596d0243d9
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1983.eml
@@ -0,0 +1,46 @@
+MIME-Version: 1.0
+From: Dennis Ritchie
+Date: Mon, 24 Oct 1983 12:00:00 -0400
+Message-ID:
+Subject: Reflections on Software Research
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=bcaec54fbb2250035a04d85aabcd
+
+--bcaec54fbb2250035a04d85aabcd
+Content-Type: text/plain; charset=UTF-8
+
+The UNIX operating system has suddenly become news, but it is not new. It
+began in 1969 when Ken Thompson discovered a little-used PDP-7 computer and
+set out to fashion a computing environment that he liked, His work soon
+attracted me; I joined in the enterprise, though most of the ideas, and
+most of the work for that matter, were his. Before long, others from our
+group in the research area of AT&T Bell Laboratories were using the system;
+Joe Ossanna, Doug Mcllroy, and
+Bob Morris were especially enthusiastic critics and contributors, tn 1971,
+we acquired a PDP-11, and by the end of that year we were supporting our
+first real users: three typists entering patent applications. In 1973, the
+system was rewritten in the C language, and in that year, too, it was first
+described publicly at the Operating Systems Principles conference; the
+resulting paper appeared in Communications of the ACM the next year.
+
+--bcaec54fbb2250035a04d85aabcd
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
The UNIX operating system has suddenly become news, b=
+ut it is not new. It began in 1969 when Ken Thompson discovered a little-us=
+ed PDP-7 computer and set out to fashion a computing environment that he li=
+ked, His work soon attracted me; I joined in the enterprise, though most of=
+ the ideas, and most of the work for that matter, were his. Before long, ot=
+hers from our group in the research area of AT&T Bell Laboratories were=
+ using the system; Joe Ossanna, Doug Mcllroy, and=C2=A0
+
Bob Morris were especially enthusiastic critics and contributors, tn 1=
+971, we acquired a PDP-11, and by the end of that year we were supporting o=
+ur first real users: three typists entering patent applications. In 1973, t=
+he system was rewritten in the C language, and in that year, too, it was fi=
+rst described publicly at the Operating Systems Principles conference; the =
+resulting paper appeared in Communications of the ACM the next year.=C2=A0<=
+/div>
+
+
+--bcaec54fbb2250035a04d85aabcd--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1987.eml b/backend/demo/src/main/resources/turing/turing_award_1987.eml
new file mode 100644
index 0000000000000000000000000000000000000000..945c454505aa7aee5d69e1ae04b802c592add223
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1987.eml
@@ -0,0 +1,42 @@
+MIME-Version: 1.0
+From: John Cocke
+Date: Mon, 16 Feb 1987 12:00:00 -0600
+Message-ID:
+Subject: The Search for Performance in Scientific Processors
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7bfd079665fb2c04d85ad0bc
+
+--047d7bfd079665fb2c04d85ad0bc
+Content-Type: text/plain; charset=UTF-8
+
+I am honored and grateful to have been selected to join the ranks of ACM
+Turing Award winners. I probably have spent too much of my life thinking
+about computers, but I do not regret it a bit. I was fortunate to enter the
+field of computing in its infancy and participate in its explosive growth.
+The rapid evolution of the underlying technologies in the past 30 years has
+not only provided an exciting environment, but has also presented a
+constant stream of intellectual challenges to those of us trying to harness
+this power and squeeze it to the last ounce. I hasten to say, especially to
+the
+younger members of the audience, there is no end in sight. As a matter of
+fact, I believe the next thirty years will be even more exciting and rich
+with challenges.
+
+--047d7bfd079665fb2c04d85ad0bc
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
I am honored and grateful to have been selected to jo=
+in the ranks of ACM Turing Award winners. I probably have spent too much of=
+ my life thinking about computers, but I do not regret it a bit. I was fort=
+unate to enter the field of computing in its infancy and participate in its=
+ explosive growth. The rapid evolution of the underlying technologies in th=
+e past 30 years has not only provided an exciting environment, but has also=
+ presented a constant stream of intellectual challenges to those of us tryi=
+ng to harness this power and squeeze it to the last ounce. I hasten to say,=
+ especially to the=C2=A0
+
younger members of the audience, there is no end in sight. As a matter=
+ of fact, I believe the next thirty years will be even more exciting and ri=
+ch with challenges.=C2=A0
+
+--047d7bfd079665fb2c04d85ad0bc--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1991.eml b/backend/demo/src/main/resources/turing/turing_award_1991.eml
new file mode 100644
index 0000000000000000000000000000000000000000..d068d60fa586b8da8b6d97ebd904ad2c4de3b844
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1991.eml
@@ -0,0 +1,44 @@
+MIME-Version: 1.0
+From: Robin Milner
+Date: Mon, 18 Nov 1991 12:00:00 -0700
+Message-ID:
+Subject: Elements of Interaction
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=047d7b86e6de64aecb04d85affff
+
+--047d7b86e6de64aecb04d85affff
+Content-Type: text/plain; charset=UTF-8
+
+I am greatly honored to receive this award, bearing the name of Alan
+Turing. Perhaps Turing would be pleased that it should go to someone
+educated at his old college, King's College at Cambridge. While there in
+1956 I wrote my first computer program; it was on the EDSAC. Of course
+EDSAC made history. But I am ashamed to say it did not lure me into
+computing, and I ignored computers for four years. In 1960 I thought that
+computers might be more peaceful to handle than schoolchildren--I was then
+a teacher--so I applied for a job at Ferranti in London, at the time of
+Pegasus. I was asked at the interview whether I would like to devote my
+life to computers. This daunting notion had never crossed my mind. Well,
+here I am still, and I have had the lucky chance to grow alongside computer
+science.
+
+--047d7b86e6de64aecb04d85affff
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
I am greatly honored to receive this award, bearing t=
+he name of Alan Turing. Perhaps Turing would be pleased that it should go t=
+o someone educated at his old college, King's College at Cambridge. Whi=
+le there in 1956 I wrote my first computer program; it was on the EDSAC. Of=
+ course EDSAC made history. But I am ashamed to say it did not lure me into=
+ computing, and I ignored computers for four years. In 1960 I thought that =
+computers might be more peaceful to handle than schoolchildren--I was then =
+a teacher--so I applied for a job at Ferranti in London, at the time of=C2=
+=A0
+
Pegasus. I was asked at the interview whether I would like to devote m=
+y life to computers. This daunting notion had never crossed my mind. Well, =
+here I am still, and I have had the lucky chance to grow alongside computer=
+ science.
+
+
+--047d7b86e6de64aecb04d85affff--
diff --git a/backend/demo/src/main/resources/turing/turing_award_1996.eml b/backend/demo/src/main/resources/turing/turing_award_1996.eml
new file mode 100644
index 0000000000000000000000000000000000000000..fb04a52d9f82a796cc5c3c3db5214f06c99a0ade
--- /dev/null
+++ b/backend/demo/src/main/resources/turing/turing_award_1996.eml
@@ -0,0 +1,28 @@
+MIME-Version: 1.0
+From: Amir Pnueli
+Date: Thu, 15 Feb 1996 12:00:00 -0500
+Message-ID:
+Subject: Verification Engineering: A Future Profession
+To: Alan Turing
+Content-Type: multipart/alternative; boundary=bcaec54fbb222acf6704d85aa523
+
+--bcaec54fbb222acf6704d85aa523
+Content-Type: text/plain; charset=UTF-8
+
+It is time that formal verification (of both software and hardware systems)
+be demoted from an art practiced by the enlightened few to an activity
+routinely and mundanely performed by a cadre of Verification Engineers (a
+new profession), as a standard part of the system development process.
+
+--bcaec54fbb222acf6704d85aa523
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+
It is time that formal verification (of both software=
+ and hardware systems) be demoted from an art practiced by the enlightened =
+few to an activity routinely and mundanely performed by a cadre of Verifica=
+tion Engineers (a new profession), as a standard part of the system develop=
+ment process.