diff --git a/CHANGELOG.md b/CHANGELOG.md index f9e9d087c..98f7cb83d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### Version 2.6.0 +* Introduce expert setting to perform channel discovery on local server instead of [search.jabber.network](https://search.jabber.network) +* Enable delivery check marks by default and remove setting +* Enable ‘Send button indicates status’ by default and remove setting +* Move Backup and Foreground Service settings to main screen + ### Version 2.5.12 * Jingle file transfer fixes * Fixed OMEMO self healing (after backup restore) on servers w/o MAM diff --git a/README.md b/README.md index 7a25b3fe1..93d95b1ac 100644 --- a/README.md +++ b/README.md @@ -93,11 +93,13 @@ build your apk file. XMPP, like email, is a federated protocol, which means that there is not one company you can create an *official XMPP account* with. Instead there are hundreds, or even thousands, of providers out there. One of those providers is our very own [chat.sum7.eu](https://chat.sum7.eu). If you don’t like to use *chat.sum7.eu* use a web search engine of your choice to find another provider. Or maybe your university has one. Or you can run your own. Or ask a friend to run one. Once you've found one, you can use Conversations to create an account. Just select *register new account* on server within the create account dialog. ##### Running your own -If you already have a server somewhere and are willing and able to put the necessary work in, one alternative-in the spirit of federation-is to run your own. We recommend either [Prosody](https://prosody.im/) or [ejabberd](https://www.ejabberd.im/). Both of which have their own strengths. Ejabberd is slightly more mature nowadays but Prosody is arguably easier to set up. +If you already have a server somewhere and are willing and able to put the necessary work in you can run your own XMPP server. -For Prosody you need a couple of so called [community modules](https://modules.prosody.im/) most of which are maintained by the same people that develop Prosody. +As of 2019 we recommend you use [ejabberd](https://ejabberd.im). The default configuration file already enables everything you need to pass the [Conversations Compliance Suite](https://compliance.conversations.im). Make sure your Linux distribution ships a fairly recent version. -If you pick ejabberd make sure you use the latest version. Linux Distributions might bundle some very old versions of it. +With a little bit of effort [Prosody](https://prosody.im) can be configured to support all necessary extensions as well. However you will have to rely on so called [Community Modules](https://modules.prosody.im/) of varying quality. Prosody can be interesting to people who like to modify their server and create / prototype own modules. + +Performance wise - for small deployments - both ejabberd and Prosody should be fine. #### Where can I set up a custom hostname / port Conversations will automatically look up the SRV records for your domain name diff --git a/build.gradle b/build.gradle index da8d493bb..a004d3966 100644 --- a/build.gradle +++ b/build.gradle @@ -68,7 +68,7 @@ dependencies { implementation "com.leinardi.android:speed-dial:2.0.1" implementation 'com.squareup.retrofit2:retrofit:2.6.1' implementation 'com.squareup.retrofit2:converter-gson:2.6.1' - implementation 'com.squareup.okhttp3:okhttp:3.12.5' + implementation 'com.squareup.okhttp3:okhttp:3.12.6' implementation 'com.google.guava:guava:27.1-android' quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.10.16' } @@ -84,8 +84,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 25 - versionCode 346 - versionName "2.5.12" + versionCode 349 + versionName "2.6.0" archivesBaseName += "-$versionName" applicationId "eu.sum7.conversations" resValue "string", "applicationId", applicationId diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 36cd26425..b7af9659b 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -90,7 +90,7 @@ public final class Config { public static final int REFRESH_UI_INTERVAL = 500; public static final int MAX_DISPLAY_MESSAGE_CHARS = 4096; - public static final int MAX_STORAGE_MESSAGE_CHARS = 1024 * 1024 * 1024; + public static final int MAX_STORAGE_MESSAGE_CHARS = 1024 * 1024; //1MB public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java index 2989f356a..29d286a71 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpDecryptionService.java @@ -201,6 +201,9 @@ public class PgpDecryptionService { if (fixedFile.getParentFile().mkdirs()) { Log.d(Config.LOGTAG,"created parent directories for "+fixedFile.getAbsolutePath()); } + synchronized (mXmppConnectionService.FILENAMES_TO_IGNORE_DELETION) { + mXmppConnectionService.FILENAMES_TO_IGNORE_DELETION.add(outputFile.getAbsolutePath()); + } if (outputFile.renameTo(fixedFile)) { Log.d(Config.LOGTAG, "renamed " + outputFile.getAbsolutePath() + " to " + fixedFile.getAbsolutePath()); message.setRelativeFilePath(path); diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 1267ec415..2187617e3 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -307,9 +307,13 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl synchronized (this.messages) { for (int i = this.messages.size() - 1; i >= 0; --i) { final Message message = messages.get(i); + final Jid mcp = message.getCounterpart(); + if (mcp == null) { + continue; + } final boolean counterpartMatch = mode == MODE_SINGLE ? - counterpart.asBareJid().equals(message.getCounterpart().asBareJid()) : - counterpart.equals(message.getCounterpart()); + counterpart.asBareJid().equals(mcp.asBareJid()) : + counterpart.equals(mcp); if (counterpartMatch && ((message.getStatus() == Message.STATUS_RECEIVED) == received) && (carbon == message.isCarbon() || received)) { final boolean idMatch = id.equals(message.getRemoteMsgId()) || message.remoteMsgIdMatchInEdit(id); diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 81463d9e9..116906fef 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -335,7 +335,7 @@ public class MucOptions { } public boolean isContactInRoom(Contact contact) { - return findUserByRealJid(contact.getJid().asBareJid()) != null; + return contact != null && findUserByRealJid(contact.getJid().asBareJid()) != null; } public boolean isUserInRoom(Jid jid) { diff --git a/src/main/java/eu/siacs/conversations/entities/Room.java b/src/main/java/eu/siacs/conversations/entities/Room.java new file mode 100644 index 000000000..74ce07c91 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/entities/Room.java @@ -0,0 +1,90 @@ +package eu.siacs.conversations.entities; + +import com.google.common.base.Objects; +import com.google.common.base.Strings; +import com.google.common.collect.ComparisonChain; + +import java.util.Comparator; + +import eu.siacs.conversations.services.AvatarService; +import eu.siacs.conversations.utils.LanguageUtils; +import eu.siacs.conversations.utils.UIHelper; +import rocks.xmpp.addr.Jid; + +public class Room implements AvatarService.Avatarable, Comparable { + + public String address; + public String name; + public String description; + public String language; + public int nusers; + + public Room(String address, String name, String description, String language, int nusers) { + this.address = address; + this.name = name; + this.description = description; + this.language = language; + this.nusers = nusers; + } + + public Room() { + + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public Jid getRoom() { + try { + return Jid.of(address); + } catch (IllegalArgumentException e) { + return null; + } + } + + public String getLanguage() { + return LanguageUtils.convert(language); + } + + @Override + public int getAvatarBackgroundColor() { + Jid room = getRoom(); + return UIHelper.getColorForName(room != null ? room.asBareJid().toEscapedString() : name); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Room room = (Room) o; + return Objects.equal(address, room.address) && + Objects.equal(name, room.name) && + Objects.equal(description, room.description); + } + + @Override + public int hashCode() { + return Objects.hashCode(address, name, description); + } + + + public boolean contains(String needle) { + return Strings.nullToEmpty(name).contains(needle) + || Strings.nullToEmpty(description).contains(needle) + || Strings.nullToEmpty(address).contains(needle); + } + + @Override + public int compareTo(Room o) { + return ComparisonChain.start() + .compare(o.nusers, nusers) + .compare(Strings.nullToEmpty(name), Strings.nullToEmpty(o.name)) + .compare(Strings.nullToEmpty(address), Strings.nullToEmpty(o.address)) + .result(); + } +} \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 7c7456776..1f9de7e6c 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -565,4 +565,18 @@ public class IqGenerator extends AbstractGenerator { } return packet; } + + public IqPacket queryDiscoItems(Jid jid) { + IqPacket packet = new IqPacket(IqPacket.TYPE.GET); + packet.setTo(jid); + packet.addChild("query",Namespace.DISCO_ITEMS); + return packet; + } + + public IqPacket queryDiscoInfo(Jid jid) { + IqPacket packet = new IqPacket(IqPacket.TYPE.GET); + packet.setTo(jid); + packet.addChild("query",Namespace.DISCO_INFO); + return packet; + } } diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index dbf8e7cb2..56445e0d6 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -37,16 +37,14 @@ public class MessageGenerator extends AbstractGenerator { if (conversation.getMode() == Conversation.MODE_SINGLE) { packet.setTo(message.getCounterpart()); packet.setType(MessagePacket.TYPE_CHAT); - if (this.mXmppConnectionService.indicateReceived() && !isWithSelf) { + if (!isWithSelf) { packet.addChild("request", "urn:xmpp:receipts"); } } else if (message.isPrivateMessage()) { packet.setTo(message.getCounterpart()); packet.setType(MessagePacket.TYPE_CHAT); packet.addChild("x", "http://jabber.org/protocol/muc#user"); - if (this.mXmppConnectionService.indicateReceived()) { - packet.addChild("request", "urn:xmpp:receipts"); - } + packet.addChild("request", "urn:xmpp:receipts"); } else { packet.setTo(message.getCounterpart().asBareJid()); packet.setType(MessagePacket.TYPE_GROUPCHAT); diff --git a/src/main/java/eu/siacs/conversations/http/services/MuclumbusService.java b/src/main/java/eu/siacs/conversations/http/services/MuclumbusService.java index 89a8e0ec4..9fae92319 100644 --- a/src/main/java/eu/siacs/conversations/http/services/MuclumbusService.java +++ b/src/main/java/eu/siacs/conversations/http/services/MuclumbusService.java @@ -1,20 +1,15 @@ package eu.siacs.conversations.http.services; -import com.google.common.base.Objects; - import java.util.Collections; import java.util.List; import java.util.Set; -import eu.siacs.conversations.services.AvatarService; -import eu.siacs.conversations.utils.LanguageUtils; -import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.entities.Room; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Query; -import rocks.xmpp.addr.Jid; public interface MuclumbusService { @@ -31,55 +26,6 @@ public interface MuclumbusService { public List items; } - class Room implements AvatarService.Avatarable { - - public String address; - public String name; - public String description; - public String language; - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public Jid getRoom() { - try { - return Jid.of(address); - } catch (IllegalArgumentException e) { - return null; - } - } - - public String getLanguage() { - return LanguageUtils.convert(language); - } - - @Override - public int getAvatarBackgroundColor() { - Jid room = getRoom(); - return UIHelper.getColorForName(room != null ? room.asBareJid().toEscapedString() : name); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Room room = (Room) o; - return Objects.equal(address, room.address) && - Objects.equal(name, room.name) && - Objects.equal(description, room.description); - } - - @Override - public int hashCode() { - return Objects.hashCode(address, name, description); - } - } - class SearchRequest { public final Set keywords; diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 3042e510f..e5ef662bb 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.parser; import android.support.annotation.NonNull; +import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.util.Pair; @@ -27,12 +28,15 @@ import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Room; +import eu.siacs.conversations.services.ChannelDiscoveryService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.InvalidJid; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; +import eu.siacs.conversations.xmpp.forms.Data; import eu.siacs.conversations.xmpp.stanzas.IqPacket; import rocks.xmpp.addr.Jid; @@ -417,4 +421,55 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } } + + public static List items(IqPacket packet) { + ArrayList items = new ArrayList<>(); + final Element query = packet.findChild("query", Namespace.DISCO_ITEMS); + if (query == null) { + return items; + } + for(Element child : query.getChildren()) { + if ("item".equals(child.getName())) { + Jid jid = child.getAttributeAsJid("jid"); + if (jid != null) { + items.add(jid); + } + } + } + return items; + } + + public static Room parseRoom(IqPacket packet) { + final Element query = packet.findChild("query", Namespace.DISCO_INFO); + if(query == null) { + return null; + } + final Element x = query.findChild("x"); + if (x == null) { + return null; + } + final Element identity = query.findChild("identity"); + Data data = Data.parse(x); + String address = packet.getFrom().toEscapedString(); + String name = identity == null ? null : identity.getAttribute("name"); + String roomName = data.getValue("muc#roomconfig_roomname");; + String description = data.getValue("muc#roominfo_description"); + String language = data.getValue("muc#roominfo_lang"); + String occupants = data.getValue("muc#roominfo_occupants"); + int nusers; + try { + nusers = occupants == null ? 0 : Integer.parseInt(occupants); + } catch (NumberFormatException e) { + nusers = 0; + } + + return new Room( + address, + TextUtils.isEmpty(roomName) ? name : roomName, + description, + language, + nusers + ); + } + } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index b9bedec1a..84bee6408 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -827,6 +827,9 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece final Jid sender = InvalidJid.getNullForInvalid(displayed.getAttributeAsJid("sender")); if (packet.fromAccount(account) && !selfAddressed) { dismissNotification(account, counterpart, query); + if (query == null) { + activateGracePeriod(account); + } } else if (isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, counterpart.asBareJid()); if (conversation != null && id != null && sender != null) { diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 37168016a..3c049bf48 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -356,7 +356,8 @@ public class FileBackend { if (stream != null) { try { stream.close(); - } catch (IOException e) { + } catch (Exception e) { + Log.d(Config.LOGTAG, "unable to close stream", e); } } } @@ -366,6 +367,7 @@ public class FileBackend { try { socket.close(); } catch (IOException e) { + Log.d(Config.LOGTAG, "unable to close socket", e); } } } @@ -375,6 +377,7 @@ public class FileBackend { try { socket.close(); } catch (IOException e) { + Log.d(Config.LOGTAG, "unable to close server socket", e); } } } diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 0e349e508..ca2d534b2 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -38,6 +38,7 @@ import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.RawBlockable; +import eu.siacs.conversations.entities.Room; import eu.siacs.conversations.http.services.MuclumbusService; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded; @@ -81,14 +82,14 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { return get((ListItem) avatarable, size, cachedOnly); } else if (avatarable instanceof MucOptions.User) { return get((MucOptions.User) avatarable, size, cachedOnly); - } else if (avatarable instanceof MuclumbusService.Room) { - return get((MuclumbusService.Room) avatarable, size, cachedOnly); + } else if (avatarable instanceof Room) { + return get((Room) avatarable, size, cachedOnly); } throw new AssertionError("AvatarService does not know how to generate avatar from "+avatarable.getClass().getName()); } - private Bitmap get(final MuclumbusService.Room result, final int size, boolean cacheOnly) { + private Bitmap get(final Room result, final int size, boolean cacheOnly) { final Jid room = result.getRoom(); Conversation conversation = room != null ? mXmppConnectionService.findFirstMuc(room) : null; if (conversation != null) { diff --git a/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java b/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java index f5dd08485..f01bd72cc 100644 --- a/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java +++ b/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java @@ -7,14 +7,27 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import eu.siacs.conversations.Config; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Room; import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.http.services.MuclumbusService; +import eu.siacs.conversations.parser.IqParser; +import eu.siacs.conversations.utils.LanguageUtils; +import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xmpp.OnIqPacketReceived; +import eu.siacs.conversations.xmpp.XmppConnection; +import eu.siacs.conversations.xmpp.stanzas.IqPacket; import okhttp3.OkHttpClient; import okhttp3.ResponseBody; import retrofit2.Call; @@ -22,6 +35,7 @@ import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; +import rocks.xmpp.addr.Jid; public class ChannelDiscoveryService { @@ -30,7 +44,7 @@ public class ChannelDiscoveryService { private MuclumbusService muclumbusService; - private final Cache> cache; + private final Cache> cache; ChannelDiscoveryService(XmppConnectionService service) { this.service = service; @@ -56,21 +70,28 @@ public class ChannelDiscoveryService { this.muclumbusService = retrofit.create(MuclumbusService.class); } - void discover(String query, OnChannelSearchResultsFound onChannelSearchResultsFound) { - final boolean all = query == null || query.trim().isEmpty(); - List result = cache.getIfPresent(all ? "" : query); + void cleanCache() { + cache.invalidateAll(); + } + + void discover(@NonNull final String query, Method method, OnChannelSearchResultsFound onChannelSearchResultsFound) { + List result = cache.getIfPresent(key(method, query)); if (result != null) { onChannelSearchResultsFound.onChannelSearchResultsFound(result); return; } - if (all) { - discoverChannels(onChannelSearchResultsFound); + if (method == Method.LOCAL_SERVER) { + discoverChannelsLocalServers(query, onChannelSearchResultsFound); } else { - discoverChannels(query, onChannelSearchResultsFound); + if (query.isEmpty()) { + discoverChannelsJabberNetwork(onChannelSearchResultsFound); + } else { + discoverChannelsJabberNetwork(query, onChannelSearchResultsFound); + } } } - private void discoverChannels(OnChannelSearchResultsFound listener) { + private void discoverChannelsJabberNetwork(OnChannelSearchResultsFound listener) { Call call = muclumbusService.getRooms(1); try { call.enqueue(new Callback() { @@ -82,7 +103,7 @@ public class ChannelDiscoveryService { logError(response); return; } - cache.put("", body.items); + cache.put(key(Method.JABBER_NETWORK, ""), body.items); listener.onChannelSearchResultsFound(body.items); } @@ -97,7 +118,7 @@ public class ChannelDiscoveryService { } } - private void discoverChannels(final String query, OnChannelSearchResultsFound listener) { + private void discoverChannelsJabberNetwork(final String query, OnChannelSearchResultsFound listener) { MuclumbusService.SearchRequest searchRequest = new MuclumbusService.SearchRequest(query); Call searchResultCall = muclumbusService.search(searchRequest); @@ -110,7 +131,7 @@ public class ChannelDiscoveryService { logError(response); return; } - cache.put(query, body.result.items); + cache.put(key(Method.JABBER_NETWORK, query), body.result.items); listener.onChannelSearchResultsFound(body.result.items); } @@ -122,6 +143,102 @@ public class ChannelDiscoveryService { }); } + private void discoverChannelsLocalServers(final String query, final OnChannelSearchResultsFound listener) { + final Map localMucService = getLocalMucServices(); + Log.d(Config.LOGTAG, "checking with " + localMucService.size() + " muc services"); + if (localMucService.size() == 0) { + listener.onChannelSearchResultsFound(Collections.emptyList()); + return; + } + if (!query.isEmpty()) { + final List cached = cache.getIfPresent(key(Method.LOCAL_SERVER, "")); + if (cached != null) { + final List results = copyMatching(cached, query); + cache.put(key(Method.LOCAL_SERVER, query), results); + listener.onChannelSearchResultsFound(results); + } + } + final AtomicInteger queriesInFlight = new AtomicInteger(); + final List rooms = new ArrayList<>(); + for (Map.Entry entry : localMucService.entrySet()) { + IqPacket itemsRequest = service.getIqGenerator().queryDiscoItems(entry.getKey()); + queriesInFlight.incrementAndGet(); + service.sendIqPacket(entry.getValue(), itemsRequest, (account, itemsResponse) -> { + if (itemsResponse.getType() == IqPacket.TYPE.RESULT) { + final List items = IqParser.items(itemsResponse); + for (Jid item : items) { + IqPacket infoRequest = service.getIqGenerator().queryDiscoInfo(item); + queriesInFlight.incrementAndGet(); + service.sendIqPacket(account, infoRequest, new OnIqPacketReceived() { + @Override + public void onIqPacketReceived(Account account, IqPacket infoResponse) { + if (infoResponse.getType() == IqPacket.TYPE.RESULT) { + final Room room = IqParser.parseRoom(infoResponse); + if (room != null) { + rooms.add(room); + } + if (queriesInFlight.decrementAndGet() <= 0) { + finishDiscoSearch(rooms, query, listener); + } + } else { + queriesInFlight.decrementAndGet(); + } + } + }); + } + } + if (queriesInFlight.decrementAndGet() <= 0) { + finishDiscoSearch(rooms, query, listener); + } + }); + } + } + + private void finishDiscoSearch(List rooms, String query, OnChannelSearchResultsFound listener) { + Collections.sort(rooms); + cache.put(key(Method.LOCAL_SERVER, ""), rooms); + if (query.isEmpty()) { + listener.onChannelSearchResultsFound(rooms); + } else { + List results = copyMatching(rooms, query); + cache.put(key(Method.LOCAL_SERVER, query), results); + listener.onChannelSearchResultsFound(rooms); + } + } + + private static List copyMatching(List haystack, String needle) { + ArrayList result = new ArrayList<>(); + for (Room room : haystack) { + if (room.contains(needle)) { + result.add(room); + } + } + return result; + } + + private Map getLocalMucServices() { + final HashMap localMucServices = new HashMap<>(); + for (Account account : service.getAccounts()) { + if (account.isEnabled()) { + final XmppConnection xmppConnection = account.getXmppConnection(); + if (xmppConnection == null) { + continue; + } + for (final String mucService : xmppConnection.getMucServers()) { + Jid jid = Jid.of(mucService); + if (!localMucServices.containsKey(jid)) { + localMucServices.put(jid, account); + } + } + } + } + return localMucServices; + } + + private static String key(Method method, String query) { + return String.format("%s\00%s", method, query); + } + private static void logError(final Response response) { final ResponseBody errorBody = response.errorBody(); Log.d(Config.LOGTAG, "code from muclumbus=" + response.code()); @@ -129,13 +246,18 @@ public class ChannelDiscoveryService { return; } try { - Log.d(Config.LOGTAG,"error body="+errorBody.string()); + Log.d(Config.LOGTAG, "error body=" + errorBody.string()); } catch (IOException e) { //ignored } } public interface OnChannelSearchResultsFound { - void onChannelSearchResultsFound(List results); + void onChannelSearchResultsFound(List results); + } + + public enum Method { + JABBER_NETWORK, + LOCAL_SERVER } } diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index f35c83f24..a5ed8c67b 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -442,6 +442,8 @@ public class NotificationService { } catch (SecurityException e) { Log.d(Config.LOGTAG, "unable to use custom notification sound " + uri.toString()); } + } else { + mBuilder.setLocalOnly(true); } if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mBuilder.setCategory(Notification.CATEGORY_MESSAGE); @@ -563,14 +565,16 @@ public class NotificationService { if (addedActionsCount < 3) { final Message firstLocationMessage = getFirstLocationMessage(messages); if (firstLocationMessage != null) { - String label = mXmppConnectionService.getResources().getString(R.string.show_location); - PendingIntent pendingShowLocationIntent = createShowLocationIntent(firstLocationMessage); - NotificationCompat.Action locationAction = new NotificationCompat.Action.Builder( - R.drawable.ic_room_white_24dp, - label, - pendingShowLocationIntent).build(); - mBuilder.addAction(locationAction); - ++addedActionsCount; + final PendingIntent pendingShowLocationIntent = createShowLocationIntent(firstLocationMessage); + if (pendingShowLocationIntent != null) { + final String label = mXmppConnectionService.getResources().getString(R.string.show_location); + NotificationCompat.Action locationAction = new NotificationCompat.Action.Builder( + R.drawable.ic_room_white_24dp, + label, + pendingShowLocationIntent).build(); + mBuilder.addAction(locationAction); + ++addedActionsCount; + } } } if (addedActionsCount < 3) { @@ -766,7 +770,7 @@ public class NotificationService { return PendingIntent.getActivity(mXmppConnectionService, generateRequestCode(message.getConversation(), 18), intent, PendingIntent.FLAG_UPDATE_CURRENT); } } - return createOpenConversationsIntent(); + return null; } private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { @@ -906,7 +910,10 @@ public class NotificationService { } } mBuilder.setContentText(mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled)); - mBuilder.setContentIntent(createOpenConversationsIntent()); + final PendingIntent openIntent = createOpenConversationsIntent(); + if (openIntent != null) { + mBuilder.setContentIntent(openIntent); + } mBuilder.setWhen(0); mBuilder.setPriority(Notification.PRIORITY_MIN); mBuilder.setSmallIcon(connected > 0 ? R.drawable.ic_link_white_24dp : R.drawable.ic_link_off_white_24dp); @@ -920,7 +927,11 @@ public class NotificationService { } private PendingIntent createOpenConversationsIntent() { - return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService, ConversationsActivity.class), 0); + try { + return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService, ConversationsActivity.class), 0); + } catch (RuntimeException e) { + return null; + } } void updateErrorNotification() { diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 5eef556e2..df2aaec19 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -34,6 +34,7 @@ import android.provider.ContactsContract; import android.security.KeyChain; import android.support.annotation.BoolRes; import android.support.annotation.IntegerRes; +import android.support.annotation.NonNull; import android.support.v4.app.RemoteInput; import android.support.v4.content.ContextCompat; import android.text.TextUtils; @@ -42,6 +43,8 @@ import android.util.Log; import android.util.LruCache; import android.util.Pair; +import com.google.common.base.Strings; + import org.conscrypt.Conscrypt; import org.openintents.openpgp.IOpenPgpService2; import org.openintents.openpgp.util.OpenPgpApi; @@ -277,6 +280,9 @@ public class XmppConnectionService extends Service { private final Object LISTENER_LOCK = new Object(); + public final Set FILENAMES_TO_IGNORE_DELETION = new HashSet<>(); + + private final OnBindListener mOnBindListener = new OnBindListener() { @Override @@ -854,8 +860,8 @@ public class XmppConnectionService extends Service { mChannelDiscoveryService.initializeMuclumbusService(); } - public void discoverChannels(String query, ChannelDiscoveryService.OnChannelSearchResultsFound onChannelSearchResultsFound) { - mChannelDiscoveryService.discover(query, onChannelSearchResultsFound); + public void discoverChannels(String query, ChannelDiscoveryService.Method method, ChannelDiscoveryService.OnChannelSearchResultsFound onChannelSearchResultsFound) { + mChannelDiscoveryService.discover(Strings.nullToEmpty(query).trim(), method, onChannelSearchResultsFound); } public boolean isDataSaverDisabled() { @@ -1831,6 +1837,12 @@ public class XmppConnectionService extends Service { } private void markFileDeleted(final String path) { + synchronized (FILENAMES_TO_IGNORE_DELETION) { + if (FILENAMES_TO_IGNORE_DELETION.remove(path)) { + Log.d(Config.LOGTAG,"ignored deletion of "+path); + return; + } + } final File file = new File(path); final boolean isInternalFile = fileBackend.isInternalFile(file); final List uuids = databaseBackend.markFileAsDeleted(file, isInternalFile); @@ -1951,9 +1963,13 @@ public class XmppConnectionService extends Service { * This will find all conferences with the contact as member and also the conference that is the contact (that 'fake' contact is used to store the avatar) */ public List findAllConferencesWith(Contact contact) { - ArrayList results = new ArrayList<>(); + final ArrayList results = new ArrayList<>(); for (final Conversation c : conversations) { - if (c.getMode() == Conversation.MODE_MULTI && (c.getJid().asBareJid().equals(contact.getJid().asBareJid()) || c.getMucOptions().isContactInRoom(contact))) { + if (c.getMode() != Conversation.MODE_MULTI) { + continue; + } + final MucOptions mucOptions = c.getMucOptions(); + if (c.getJid().asBareJid().equals(contact.getJid().asBareJid()) || (mucOptions != null && mucOptions.isContactInRoom(contact))) { results.add(c); } } @@ -2231,6 +2247,7 @@ public class XmppConnectionService extends Service { getNotificationService().updateErrorNotification(); toggleForegroundService(); syncEnabledAccountSetting(); + mChannelDiscoveryService.cleanCache(); return true; } else { return false; @@ -3073,9 +3090,7 @@ public class XmppConnectionService extends Service { } public void fetchConferenceConfiguration(final Conversation conversation, final OnConferenceConfigurationFetched callback) { - IqPacket request = new IqPacket(IqPacket.TYPE.GET); - request.setTo(conversation.getJid().asBareJid()); - request.query("http://jabber.org/protocol/disco#info"); + IqPacket request = mIqGenerator.queryDiscoInfo(conversation.getJid().asBareJid()); sendIqPacket(conversation.getAccount(), request, new OnIqPacketReceived() { @Override public void onIqPacketReceived(Account account, IqPacket packet) { @@ -3891,10 +3906,6 @@ public class XmppConnectionService extends Service { return getBooleanPreference("autojoin", R.bool.autojoin); } - public boolean indicateReceived() { - return getBooleanPreference("indicate_received", R.bool.indicate_received); - } - public boolean useTorToConnect() { return QuickConversationsService.isConversations() && getBooleanPreference("use_tor", R.bool.use_tor); } @@ -4424,7 +4435,7 @@ public class XmppConnectionService extends Service { request.setTo(jid); final String node = presence.getNode(); final String ver = presence.getVer(); - final Element query = request.query("http://jabber.org/protocol/disco#info"); + final Element query = request.query(Namespace.DISCO_INFO); if (node != null && ver != null) { query.setAttribute("node", node + "#" + ver); } diff --git a/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java b/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java index b1684473d..567a2f3d6 100644 --- a/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java @@ -7,8 +7,10 @@ import android.content.SharedPreferences; import android.databinding.DataBindingUtil; import android.net.Uri; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v7.widget.Toolbar; import android.text.Html; +import android.text.method.LinkMovementMethod; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -27,11 +29,13 @@ import eu.siacs.conversations.databinding.ActivityChannelDiscoveryBinding; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.http.services.MuclumbusService; +import eu.siacs.conversations.entities.Room; import eu.siacs.conversations.services.ChannelDiscoveryService; +import eu.siacs.conversations.services.QuickConversationsService; import eu.siacs.conversations.ui.adapter.ChannelSearchResultAdapter; import eu.siacs.conversations.ui.util.PendingItem; import eu.siacs.conversations.ui.util.SoftKeyboardUtils; +import eu.siacs.conversations.ui.util.StyledAttributes; import eu.siacs.conversations.utils.AccountUtils; import rocks.xmpp.addr.Jid; @@ -45,6 +49,8 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O private MenuItem mMenuSearchView; private EditText mSearchEditText; + private ChannelDiscoveryService.Method method = ChannelDiscoveryService.Method.LOCAL_SERVER; + private boolean optedIn = false; @Override @@ -54,14 +60,15 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O @Override void onBackendConnected() { - if (optedIn) { - String query; + if (optedIn || method == ChannelDiscoveryService.Method.LOCAL_SERVER) { + final String query; if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) { query = mSearchEditText.getText().toString(); } else { query = mInitialSearchValue.peek(); } - xmppConnectionService.discoverChannels(query, this); + toggleLoadingScreen(); + xmppConnectionService.discoverChannels(query, this.method, this); } } @@ -73,29 +80,42 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O configureActionBar(getSupportActionBar(), true); binding.list.setAdapter(this.adapter); this.adapter.setOnChannelSearchResultSelectedListener(this); - optedIn = getPreferences().getBoolean(CHANNEL_DISCOVERY_OPT_IN, false); + this.optedIn = getPreferences().getBoolean(CHANNEL_DISCOVERY_OPT_IN, false); final String search = savedInstanceState == null ? null : savedInstanceState.getString("search"); if (search != null) { mInitialSearchValue.push(search); } + } + private static ChannelDiscoveryService.Method getMethod(final Context c) { + if (QuickConversationsService.isQuicksy()) { + return ChannelDiscoveryService.Method.JABBER_NETWORK; + } + final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(c); + final String m = p.getString("channel_discovery_method", c.getString(R.string.default_channel_discovery)); + try { + return ChannelDiscoveryService.Method.valueOf(m); + } catch (IllegalArgumentException e) { + return ChannelDiscoveryService.Method.JABBER_NETWORK; + } } @Override public boolean onCreateOptionsMenu(final Menu menu) { - getMenuInflater().inflate(R.menu.muc_users_activity, menu); + getMenuInflater().inflate(R.menu.channel_discovery_activity, menu); + AccountUtils.showHideMenuItems(menu); mMenuSearchView = menu.findItem(R.id.action_search); final View mSearchView = mMenuSearchView.getActionView(); mSearchEditText = mSearchView.findViewById(R.id.search_field); mSearchEditText.setHint(R.string.search_channels); - String initialSearchValue = mInitialSearchValue.pop(); + final String initialSearchValue = mInitialSearchValue.pop(); if (initialSearchValue != null) { mMenuSearchView.expandActionView(); mSearchEditText.append(initialSearchValue); mSearchEditText.requestFocus(); - if (optedIn && xmppConnectionService != null) { - xmppConnectionService.discoverChannels(initialSearchValue, this); + if ((optedIn || method == ChannelDiscoveryService.Method.LOCAL_SERVER) && xmppConnectionService != null) { + xmppConnectionService.discoverChannels(initialSearchValue, this.method, this); } } mSearchEditText.setOnEditorActionListener(this); @@ -119,8 +139,8 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O imm.hideSoftInputFromWindow(mSearchEditText.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); mSearchEditText.setText(""); toggleLoadingScreen(); - if (optedIn) { - xmppConnectionService.discoverChannels(null, this); + if (optedIn || method == ChannelDiscoveryService.Method.LOCAL_SERVER) { + xmppConnectionService.discoverChannels(null, this.method, this); } return true; } @@ -128,12 +148,14 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O private void toggleLoadingScreen() { adapter.submitList(Collections.emptyList()); binding.progressBar.setVisibility(View.VISIBLE); + binding.list.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_primary)); } @Override public void onStart() { super.onStart(); - if (!optedIn) { + this.method = getMethod(this); + if (!optedIn && method == ChannelDiscoveryService.Method.JABBER_NETWORK) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.channel_discovery_opt_in_title); builder.setMessage(Html.fromHtml(getString(R.string.channel_discover_opt_in_message))); @@ -141,11 +163,25 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O builder.setPositiveButton(R.string.confirm, (dialog, which) -> optIn()); builder.setOnCancelListener(dialog -> finish()); final AlertDialog dialog = builder.create(); + dialog.setOnShowListener(d -> { + final TextView textView = dialog.findViewById(android.R.id.message); + if (textView == null) { + return; + } + textView.setMovementMethod(LinkMovementMethod.getInstance()); + }); dialog.setCanceledOnTouchOutside(false); dialog.show(); + holdLoading(); } } + private void holdLoading() { + adapter.submitList(Collections.emptyList()); + binding.progressBar.setVisibility(View.GONE); + binding.list.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_primary)); + } + @Override public void onSaveInstanceState(Bundle savedInstanceState) { if (mMenuSearchView != null && mMenuSearchView.isActionViewExpanded()) { @@ -158,31 +194,36 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O SharedPreferences preferences = getPreferences(); preferences.edit().putBoolean(CHANNEL_DISCOVERY_OPT_IN, true).apply(); optedIn = true; - xmppConnectionService.discoverChannels(null, this); + toggleLoadingScreen(); + xmppConnectionService.discoverChannels(null, this.method, this); } @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (optedIn) { - xmppConnectionService.discoverChannels(v.getText().toString(), this); + if (optedIn || method == ChannelDiscoveryService.Method.LOCAL_SERVER) { + toggleLoadingScreen(); + SoftKeyboardUtils.hideSoftKeyboard(this); + xmppConnectionService.discoverChannels(v.getText().toString(), this.method, this); } - toggleLoadingScreen(); - SoftKeyboardUtils.hideSoftKeyboard(this); return true; } @Override - public void onChannelSearchResultsFound(List results) { + public void onChannelSearchResultsFound(final List results) { runOnUiThread(() -> { adapter.submitList(results); - binding.list.setVisibility(View.VISIBLE); binding.progressBar.setVisibility(View.GONE); + if (results.size() == 0) { + binding.list.setBackground(StyledAttributes.getDrawable(this, R.attr.activity_primary_background_no_results)); + } else { + binding.list.setBackgroundColor(StyledAttributes.getColor(this, R.attr.color_background_primary)); + } }); } @Override - public void onChannelSearchResult(final MuclumbusService.Room result) { + public void onChannelSearchResult(final Room result) { List accounts = AccountUtils.getEnabledAccounts(xmppConnectionService); if (accounts.size() == 1) { joinChannelSearchResult(accounts.get(0), result); @@ -200,7 +241,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O @Override public boolean onContextItemSelected(MenuItem item) { - final MuclumbusService.Room room = adapter.getCurrent(); + final Room room = adapter.getCurrent(); if (room != null) { switch (item.getItemId()) { case R.id.share_with: @@ -218,7 +259,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O return false; } - public void joinChannelSearchResult(String selectedAccount, MuclumbusService.Room result) { + public void joinChannelSearchResult(String selectedAccount, Room result) { final Jid jid = Config.DOMAIN_LOCK == null ? Jid.of(selectedAccount) : Jid.of(selectedAccount, Config.DOMAIN_LOCK, null); final boolean syncAutoJoin = getBooleanPreference("autojoin", R.bool.autojoin); final Account account = xmppConnectionService.findAccountByJid(jid); diff --git a/src/main/java/eu/siacs/conversations/ui/ChooseAccountForProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/ChooseAccountForProfilePictureActivity.java index cfb4f05fb..fca082c42 100644 --- a/src/main/java/eu/siacs/conversations/ui/ChooseAccountForProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ChooseAccountForProfilePictureActivity.java @@ -5,6 +5,7 @@ import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.widget.ListView; +import android.widget.Toast; import java.util.ArrayList; import java.util.List; @@ -78,7 +79,12 @@ public class ChooseAccountForProfilePictureActivity extends XmppActivity { intent.putExtra(EXTRA_ACCOUNT, account.getJid().asBareJid().toString()); intent.setData(uri); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(intent); + try { + startActivity(intent); + } catch (SecurityException e) { + Toast.makeText(this, R.string.sharing_application_not_grant_permission, Toast.LENGTH_SHORT).show(); + return; + } } finish(); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index c0ec6d790..1eaa1861f 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -2267,7 +2267,6 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke public void updateSendButton() { boolean hasAttachments = mediaPreviewAdapter != null && mediaPreviewAdapter.hasAttachments(); - boolean useSendButtonToIndicateStatus = activity != null && PreferenceManager.getDefaultSharedPreferences(activity).getBoolean("send_button_status", getResources().getBoolean(R.bool.send_button_status)); final Conversation c = this.conversation; final Presence.Status status; final String text = this.binding.textinput == null ? "" : this.binding.textinput.getText().toString(); @@ -2277,7 +2276,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } else { action = SendButtonTool.getAction(getActivity(), c, text); } - if (useSendButtonToIndicateStatus && c.getAccount().getStatus() == Account.State.ONLINE) { + if (c.getAccount().getStatus() == Account.State.ONLINE) { if (activity != null && activity.xmppConnectionService != null && activity.xmppConnectionService.getMessageArchiveService().isCatchingUp(c)) { status = Presence.Status.OFFLINE; } else if (c.getMode() == Conversation.MODE_SINGLE) { diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index d8c208dd4..1a24077ad 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -228,20 +228,22 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat removeErrorsOnAllBut(binding.hostnameLayout); return; } - try { - numericPort = Integer.parseInt(port); - if (numericPort < 0 || numericPort > 65535) { + if (!hostname.isEmpty()) { + try { + numericPort = Integer.parseInt(port); + if (numericPort < 0 || numericPort > 65535) { + binding.portLayout.setError(getString(R.string.not_a_valid_port)); + removeErrorsOnAllBut(binding.portLayout); + binding.port.requestFocus(); + return; + } + + } catch (NumberFormatException e) { binding.portLayout.setError(getString(R.string.not_a_valid_port)); removeErrorsOnAllBut(binding.portLayout); binding.port.requestFocus(); return; } - - } catch (NumberFormatException e) { - binding.portLayout.setError(getString(R.string.not_a_valid_port)); - removeErrorsOnAllBut(binding.portLayout); - binding.port.requestFocus(); - return; } } @@ -477,8 +479,13 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat } private void updatePortLayout() { - String hostname = this.binding.hostname.getText().toString(); - this.binding.portLayout.setEnabled(!TextUtils.isEmpty(hostname)); + final String hostname = this.binding.hostname.getText().toString(); + if (TextUtils.isEmpty(hostname)) { + this.binding.portLayout.setEnabled(false); + this.binding.portLayout.setError(null); + } else { + this.binding.portLayout.setEnabled(true); + } } protected void updateSaveButton() { @@ -613,7 +620,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat } private void refreshAvatar() { - AvatarWorkerTask.loadAvatar(mAccount,binding.avater,R.dimen.avatar_on_details_screen_size); + AvatarWorkerTask.loadAvatar(mAccount, binding.avater, R.dimen.avatar_on_details_screen_size); } @Override @@ -683,9 +690,9 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat } boolean init = intent.getBooleanExtra("init", false); boolean openedFromNotification = intent.getBooleanExtra(EXTRA_OPENED_FROM_NOTIFICATION, false); - Log.d(Config.LOGTAG,"extras "+intent.getExtras()); - this.mForceRegister = intent.hasExtra(EXTRA_FORCE_REGISTER) ? intent.getBooleanExtra(EXTRA_FORCE_REGISTER,false) : null; - Log.d(Config.LOGTAG,"force register="+mForceRegister); + Log.d(Config.LOGTAG, "extras " + intent.getExtras()); + this.mForceRegister = intent.hasExtra(EXTRA_FORCE_REGISTER) ? intent.getBooleanExtra(EXTRA_FORCE_REGISTER, false) : null; + Log.d(Config.LOGTAG, "force register=" + mForceRegister); this.mInitMode = init || this.jidToEdit == null; this.messageFingerprint = intent.getStringExtra("fingerprint"); if (!mInitMode) { @@ -975,7 +982,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat if (!mInitMode) { this.binding.avater.setVisibility(View.VISIBLE); - AvatarWorkerTask.loadAvatar(mAccount,binding.avater,R.dimen.avatar_on_details_screen_size); + AvatarWorkerTask.loadAvatar(mAccount, binding.avater, R.dimen.avatar_on_details_screen_size); } else { this.binding.avater.setVisibility(View.GONE); } diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index 99560801f..3d2b63d04 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -92,11 +92,16 @@ public class SettingsActivity extends XmppActivity implements changeOmemoSettingSummary(); if (QuickConversationsService.isQuicksy()) { - PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options"); + final PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options"); + final PreferenceCategory groupChats = (PreferenceCategory) mSettingsFragment.findPreference("group_chats"); + final Preference channelDiscoveryMethod = mSettingsFragment.findPreference("channel_discovery_method"); PreferenceScreen expert = (PreferenceScreen) mSettingsFragment.findPreference("expert"); if (connectionOptions != null) { expert.removePreference(connectionOptions); } + if (groupChats != null && channelDiscoveryMethod != null) { + groupChats.removePreference(channelDiscoveryMethod); + } } PreferenceScreen mainPreferenceScreen = (PreferenceScreen) mSettingsFragment.findPreference("main_screen"); diff --git a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java index 0ec7abd9a..dd4ea40a2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareWithActivity.java @@ -200,7 +200,12 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer intent.putExtra(Intent.EXTRA_TEXT, share.text); intent.putExtra(ConversationsActivity.EXTRA_AS_QUOTE, share.asQuote); } - startActivity(intent); + try { + startActivity(intent); + } catch (SecurityException e) { + Toast.makeText(this, R.string.sharing_application_not_grant_permission, Toast.LENGTH_SHORT).show(); + return; + } finish(); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ChannelSearchResultAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ChannelSearchResultAdapter.java index 5ba28c446..0f452e0b1 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ChannelSearchResultAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ChannelSearchResultAdapter.java @@ -16,26 +16,26 @@ import java.util.Locale; import eu.siacs.conversations.R; import eu.siacs.conversations.databinding.SearchResultItemBinding; -import eu.siacs.conversations.http.services.MuclumbusService; +import eu.siacs.conversations.entities.Room; import eu.siacs.conversations.ui.XmppActivity; import eu.siacs.conversations.ui.util.AvatarWorkerTask; import rocks.xmpp.addr.Jid; -public class ChannelSearchResultAdapter extends ListAdapter implements View.OnCreateContextMenuListener { +public class ChannelSearchResultAdapter extends ListAdapter implements View.OnCreateContextMenuListener { - private static final DiffUtil.ItemCallback DIFF = new DiffUtil.ItemCallback() { + private static final DiffUtil.ItemCallback DIFF = new DiffUtil.ItemCallback() { @Override - public boolean areItemsTheSame(@NonNull MuclumbusService.Room a, @NonNull MuclumbusService.Room b) { + public boolean areItemsTheSame(@NonNull Room a, @NonNull Room b) { return a.address != null && a.address.equals(b.address); } @Override - public boolean areContentsTheSame(@NonNull MuclumbusService.Room a, @NonNull MuclumbusService.Room b) { + public boolean areContentsTheSame(@NonNull Room a, @NonNull Room b) { return a.equals(b); } }; private OnChannelSearchResultSelected listener; - private MuclumbusService.Room current; + private Room current; public ChannelSearchResultAdapter() { super(DIFF); @@ -49,7 +49,7 @@ public class ChannelSearchResultAdapter extends ListAdapter implements CopyTextVie private DisplayMetrics metrics; private OnContactPictureClicked mOnContactPictureClickedListener; private OnContactPictureLongClicked mOnContactPictureLongClickedListener; - private boolean mIndicateReceived = false; private OnQuoteListener onQuoteListener; public MessageAdapter(XmppActivity activity, List messages) { super(activity, 0, messages); @@ -207,9 +206,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie break; case Message.STATUS_SEND_RECEIVED: case Message.STATUS_SEND_DISPLAYED: - if (mIndicateReceived) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } + viewHolder.indicatorReceived.setVisibility(View.VISIBLE); break; case Message.STATUS_SEND_FAILED: final String errorMessage = message.getErrorMessage(); @@ -903,7 +900,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie public void updatePreferences() { SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(activity); - this.mIndicateReceived = p.getBoolean("indicate_received", activity.getResources().getBoolean(R.bool.indicate_received)); } diff --git a/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java b/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java index 5c1b876a8..64c180c38 100644 --- a/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java +++ b/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java @@ -346,8 +346,12 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti return false; } final ViewHolder viewHolder = ViewHolder.get(audioPlayer); - viewHolder.progress.setProgress(current * 100 / duration); - viewHolder.runtime.setText(formatTime(current) + " / " + formatTime(duration)); + if (duration <= 0) { + viewHolder.progress.setProgress(100); + } else { + viewHolder.progress.setProgress(current * 100 / duration); + } + viewHolder.runtime.setText(String.format("%s / %s", formatTime(current), formatTime(duration))); return true; } diff --git a/src/main/java/eu/siacs/conversations/ui/text/FixedURLSpan.java b/src/main/java/eu/siacs/conversations/ui/text/FixedURLSpan.java index 0843c214f..eb45feebe 100644 --- a/src/main/java/eu/siacs/conversations/ui/text/FixedURLSpan.java +++ b/src/main/java/eu/siacs/conversations/ui/text/FixedURLSpan.java @@ -70,8 +70,8 @@ public class FixedURLSpan extends URLSpan { public void onClick(View widget) { final Uri uri = Uri.parse(getURL()); final Context context = widget.getContext(); - final boolean candidateToProcessDirecty = "xmpp".equals(uri.getScheme()) || ("https".equals(uri.getScheme()) && "conversations.im".equals(uri.getHost()) && uri.getPathSegments().size() > 1 && Arrays.asList("j","i").contains(uri.getPathSegments().get(0))); - if (candidateToProcessDirecty && context instanceof ConversationsActivity) { + final boolean candidateToProcessDirectly = "xmpp".equals(uri.getScheme()) || ("https".equals(uri.getScheme()) && "conversations.im".equals(uri.getHost()) && uri.getPathSegments().size() > 1 && Arrays.asList("j","i").contains(uri.getPathSegments().get(0))); + if (candidateToProcessDirectly && context instanceof ConversationsActivity) { if (((ConversationsActivity) context).onXmppUriClicked(uri)) { widget.playSoundEffect(0); return; diff --git a/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java b/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java index c3e874310..04efcc0c5 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java +++ b/src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java @@ -13,6 +13,7 @@ import android.view.View; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.MucOptions; @@ -71,8 +72,8 @@ public final class MucDetailsContextMenuHelper { startConversation.setVisible(true); final Contact contact = user.getContact(); final User self = conversation.getMucOptions().getSelf(); - if (contact != null && contact.showInRoster()) { - showContactDetails.setVisible(!contact.isSelf()); + if ((contact != null && contact.showInRoster()) || mucOptions.isPrivateAndNonAnonymous()) { + showContactDetails.setVisible(contact == null || !contact.isSelf()); } if ((activity instanceof ConferenceDetailsActivity || activity instanceof MucUsersActivity) && user.getRole() == MucOptions.Role.NONE) { invite.setVisible(true); @@ -135,7 +136,9 @@ public final class MucDetailsContextMenuHelper { Jid jid = user.getRealJid(); switch (item.getItemId()) { case R.id.action_contact_details: - Contact contact = user.getContact(); + final Jid realJid = user.getRealJid(); + final Account account = conversation.getAccount(); + final Contact contact = realJid == null ? null : account.getRoster().getContact(realJid); if (contact != null) { activity.switchToContactDetails(contact, fingerprint); } diff --git a/src/main/java/eu/siacs/conversations/utils/AccountUtils.java b/src/main/java/eu/siacs/conversations/utils/AccountUtils.java index e475c6718..475682bec 100644 --- a/src/main/java/eu/siacs/conversations/utils/AccountUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/AccountUtils.java @@ -102,7 +102,11 @@ public class AccountUtils { public static void showHideMenuItems(final Menu menu) { final MenuItem manageAccounts = menu.findItem(R.id.action_accounts); final MenuItem manageAccount = menu.findItem(R.id.action_account); - manageAccount.setVisible(MANAGE_ACCOUNT_ACTIVITY == null); - manageAccounts.setVisible(MANAGE_ACCOUNT_ACTIVITY != null); + if (manageAccount != null) { + manageAccount.setVisible(MANAGE_ACCOUNT_ACTIVITY == null); + } + if (manageAccounts != null) { + manageAccounts.setVisible(MANAGE_ACCOUNT_ACTIVITY != null); + } } } diff --git a/src/main/java/eu/siacs/conversations/utils/Compatibility.java b/src/main/java/eu/siacs/conversations/utils/Compatibility.java index 9e63ee3c3..4a2a14111 100644 --- a/src/main/java/eu/siacs/conversations/utils/Compatibility.java +++ b/src/main/java/eu/siacs/conversations/utils/Compatibility.java @@ -93,7 +93,7 @@ public class Compatibility { public static void removeUnusedPreferences(SettingsFragment settingsFragment) { List categories = Arrays.asList( (PreferenceCategory) settingsFragment.findPreference("notification_category"), - (PreferenceCategory) settingsFragment.findPreference("other_expert_category")); + (PreferenceCategory) settingsFragment.findPreference("advanced")); for (String key : (runsTwentySix() ? UNUSED_SETTINGS_POST_TWENTYSIX : UNUESD_SETTINGS_PRE_TWENTYSIX)) { Preference preference = settingsFragment.findPreference(key); if (preference != null) { diff --git a/src/main/java/eu/siacs/conversations/xml/Namespace.java b/src/main/java/eu/siacs/conversations/xml/Namespace.java index 4be004b97..189492fbf 100644 --- a/src/main/java/eu/siacs/conversations/xml/Namespace.java +++ b/src/main/java/eu/siacs/conversations/xml/Namespace.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.xml; public final class Namespace { + public static final String DISCO_ITEMS = "http://jabber.org/protocol/disco#items"; + public static final String DISCO_INFO = "http://jabber.org/protocol/disco#info"; public static final String BLOCKING = "urn:xmpp:blocking"; public static final String ROSTER = "jabber:iq:roster"; public static final String REGISTER = "jabber:iq:register"; diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index ac88b52f0..8851dc590 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -71,6 +71,8 @@ public class JingleConnection implements Transferable { private Element fileOffer; private DownloadableFile file = null; + private boolean proxyActivationFailed = false; + private String contentName; private String contentCreator; private Transport initialTransport; @@ -175,6 +177,7 @@ public class JingleConnection implements Transferable { @Override public void failed() { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": proxy activation failed"); + proxyActivationFailed = true; if (initiating()) { sendFallbackToIbb(); } @@ -504,10 +507,11 @@ public class JingleConnection implements Transferable { respondToIq(packet, true); - if (mJingleConnectionManager.hasStoragePermission() + if (account.getRoster().getContact(from).showInContactList() + && mJingleConnectionManager.hasStoragePermission() && size < this.mJingleConnectionManager.getAutoAcceptFileSize() && mXmppConnectionService.isDataSaverDisabled()) { - Log.d(Config.LOGTAG, "auto accepting file from " + packet.getFrom()); + Log.d(Config.LOGTAG, "auto accepting file from " + from); this.acceptedAutomatically = true; this.sendAccept(); } else { @@ -700,6 +704,11 @@ public class JingleConnection implements Transferable { } private void receiveAccept(JinglePacket packet) { + if (responding()) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order session-accept (we were responding)"); + respondToIqWithOutOfOrder(packet); + return; + } if (this.mJingleStatus != JINGLE_STATUS_INITIATED) { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order session-accept"); respondToIqWithOutOfOrder(packet); @@ -909,6 +918,18 @@ public class JingleConnection implements Transferable { private void receiveFallbackToIbb(JinglePacket packet) { + if (initiating()) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order transport-replace (we were initiating)"); + respondToIqWithOutOfOrder(packet); + return; + } + final boolean validState = mJingleStatus == JINGLE_STATUS_ACCEPTED || (proxyActivationFailed && mJingleStatus == JINGLE_STATUS_TRANSMITTING); + if (!validState) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order transport-replace"); + respondToIqWithOutOfOrder(packet); + return; + } + this.proxyActivationFailed = false; //fallback received; now we no longer need to accept another one; Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": receiving fallback to ibb"); final String receivedBlockSize = packet.getJingleContent().ibbTransport().getAttribute("block-size"); if (receivedBlockSize != null) { @@ -947,6 +968,18 @@ public class JingleConnection implements Transferable { } private void receiveTransportAccept(JinglePacket packet) { + if (responding()) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order transport-accept (we were responding)"); + respondToIqWithOutOfOrder(packet); + return; + } + final boolean validState = mJingleStatus == JINGLE_STATUS_ACCEPTED || (proxyActivationFailed && mJingleStatus == JINGLE_STATUS_TRANSMITTING); + if (!validState) { + Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received out of order transport-accept"); + respondToIqWithOutOfOrder(packet); + return; + } + this.proxyActivationFailed = false; //fallback accepted; now we no longer need to accept another one; if (packet.getJingleContent().hasIbbTransport()) { final Element ibbTransport = packet.getJingleContent().ibbTransport(); final String receivedBlockSize = ibbTransport.getAttribute("block-size"); @@ -970,8 +1003,6 @@ public class JingleConnection implements Transferable { //might be receive instead if we are not initiating if (initiating()) { this.transport.connect(onIbbTransportConnected); - } else { - this.transport.receive(file, onFileTransmissionStatusChanged); } } else { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": received invalid transport-accept"); diff --git a/src/main/res/drawable/no_results_primary_background_dark.xml b/src/main/res/drawable/no_results_primary_background_dark.xml new file mode 100644 index 000000000..48597d05c --- /dev/null +++ b/src/main/res/drawable/no_results_primary_background_dark.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/src/main/res/drawable/no_results_primary_background_light.xml b/src/main/res/drawable/no_results_primary_background_light.xml new file mode 100644 index 000000000..efe31413a --- /dev/null +++ b/src/main/res/drawable/no_results_primary_background_light.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + diff --git a/src/main/res/layout/activity_channel_discovery.xml b/src/main/res/layout/activity_channel_discovery.xml index 055b9aff2..34b680622 100644 --- a/src/main/res/layout/activity_channel_discovery.xml +++ b/src/main/res/layout/activity_channel_discovery.xml @@ -34,7 +34,6 @@ android:background="?attr/color_background_primary" android:orientation="vertical" android:scrollbars="vertical" - android:visibility="gone" app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> diff --git a/src/main/res/menu/channel_discovery_activity.xml b/src/main/res/menu/channel_discovery_activity.xml index 209bb27e0..8df3c2d8c 100644 --- a/src/main/res/menu/channel_discovery_activity.xml +++ b/src/main/res/menu/channel_discovery_activity.xml @@ -1,11 +1,21 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> + android:title="@string/search" + app:actionLayout="@layout/actionview_search" + app:showAsAction="collapseActionView|always" /> + + diff --git a/src/main/res/values-ar/strings.xml b/src/main/res/values-ar/strings.xml index a6f32014f..415672246 100644 --- a/src/main/res/values-ar/strings.xml +++ b/src/main/res/values-ar/strings.xml @@ -260,7 +260,6 @@ وقت النهاية تفعيل ساعات السكون سوف تكتم التنبيهات إبان ساعات السكون - طلب تقارير تسليم الرسائل أخرى زامِن مع الفواصل المرجعية تم نسخ بصمة OMEMO إلى الحافظة ! @@ -279,6 +278,7 @@ أنسخ الرابط الأصلي أعد الإرسال رابط الملف + تم نسخ الرابط إلى الحافظة تم نسخ عنوان الـ XMPP إلى الحافظة تم نسخ رسالة الخطأ إلى الحافظة عنوان الويب @@ -341,6 +341,7 @@ أزله مِن القناة لا يمكن تغيير انتساب %s الحظر من دخول مجموعة المحادثة + اطرده مِن القناة حظر الآن لا يمكن تغيير دول %s إعدادات القناة العمومية @@ -447,9 +448,7 @@ تعطيل الإخطارات الإشعارات موقفة ضغط الصورة - تغيير حجم الصور وضغطها دائماً - آليا وضع تحسين أداء البطارية مفعّل تعطيل المساحة المحددة كبيرة جدا @@ -653,6 +652,7 @@ رسائل رسائل إعدادات الإشعار + الأهمية ، الصوت ، الإهتزاز ضغط الفيديو اعرض الوسائط اعرض المشارِكين diff --git a/src/main/res/values-bg/strings.xml b/src/main/res/values-bg/strings.xml index 6106d4dfa..3676db05d 100644 --- a/src/main/res/values-bg/strings.xml +++ b/src/main/res/values-bg/strings.xml @@ -115,7 +115,6 @@ Тон на звънене Изпълнение на звук при получаване на ново съобщение Период на пренебрегване - Времето, през което Conversations няма да прави нищо, след като забележи дейност на друго устройство Разширени Никога да не се изпращат доклади за сривове Изпращайки проследявания на стека, Вие помагате за непрекъснатото развитие на Conversations @@ -268,10 +267,6 @@ Край Включване на тихите часове Известията ще бъдат заглушени по време на тихите часове - Бутонът за изпращане показва състоянието - Изискване на отчет за съобщенията - Получените съобщения ще бъдат отбелязани със зелена отметка, ако това се поддържа - Оцветяване на бутона за изпращане в зависимост от състоянието на контакта Други Синхронизиране с отметките Присъединяване и напускане на групови разговори според флага за автоматично присъединяване в отметките. @@ -474,9 +469,7 @@ Известията са изключени Известията са спрени временно Компресия на изображенията - Преоразмеряване и компресиране на изображенията Винаги - Автоматично Оптимизациите за използв. на батерията са вкл. Устройството Ви прилага сериозни оптимизации за използването на батерията върху Conversations, а те може да доведат до забавени известия и дори пропуснати съобщения.\nПрепоръчително е до ги изключите. Устройството Ви прилага сериозни оптимизации за използването на батерията върху Conversations, а те може да доведат до забавени известия и дори пропуснати съобщения.\n\nСега ще Ви бъде предложено да ги изключите. diff --git a/src/main/res/values-ca/strings.xml b/src/main/res/values-ca/strings.xml index 4996652ee..2889d54d2 100644 --- a/src/main/res/values-ca/strings.xml +++ b/src/main/res/values-ca/strings.xml @@ -115,7 +115,6 @@ So d\'avís Reprodueix un so quan arribi un missatge nou Període de gràcia - El temps que el Conversations guarda silenci després de veure activitat en un altre dispositiu Avançat Mai enviïs informes d\'errors Amb l\'enviament de traces d\'execució ajudeu al desenvolupament futur del Conversations @@ -268,10 +267,6 @@ Hora de finalització Habilitar hores de silenci Les notificacions seràn silenciades a les hores de silenci - Botó d\'indicació de l\'estatus enviar - Rebuts de sol.licituds dels missatges - Els missatges rebuts seràn marcats amb uns ticks verds si ho admet - Pintar el botó d\'enviament per indicar l\'estatus del contacte Altres S\'ha copiat l\'empremta digital d\'OMEMO al porta-retalls. Estàs prohibit en aquest xat de grup @@ -479,9 +474,7 @@ mentrestant. S\'han desactivat les notificacions S\'han pausat les notificacions Compressió d\'imatge - Redimensionar i comprimir imatges Sempre - Automàticament Optimitzacions de la bateria habilitades El vostre dispositiu fa algunes optimitzacions pesades de la bateria i Conversations pot provocar notificacions retardades o fins i tot pèrdua de diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml index 6e2c444e6..d8d186302 100644 --- a/src/main/res/values-cs/strings.xml +++ b/src/main/res/values-cs/strings.xml @@ -98,7 +98,6 @@ Tón upozornění Přehrát zvuk při přijetí nové zprávy Časová lhůta - Časová lhůta po kterou bude Conversations v tichém režimu při zaznamenání aktivity na jiném přístroji Rozšířené Neodesílat detaily o pádu aplikace Zasláním detailů o důvodu selhání pomůžete dalšímu vývoji aplikace Konverzace @@ -230,10 +229,6 @@ Dokdy Povolit tichý režim Upozornění budou během tichého režimu ztlumena - Tlačítko pro odeslání zobrazuje stav - Požadovat oznámení o přijetí - Přijaté zprávy budou označeny zeleně, pokud je funkce podporována - Obarvit tlačítko odesílání barvou indikující stavu kontaktu Další OMEMO otisk zkopírován do schránky! za použití účtu %s @@ -396,7 +391,6 @@ Upozornění vypnuta Upozornění pozastavena Vždy - Automaticky Povolena optimalizace využití baterie Tento přístroj provádí agresivní optimalizace využití baterie pro aplikaci Conversations. Ty mohou způsobit zpoždění upozornění nebo ztrátu zpráv.\nJe doporučeno tyto vypnout. Tento přístroj provádí agresivní optimalizace využití baterie pro aplikaci Conversations. Ty mohou způsobit zpoždění upozornění nebo ztrátu zpráv.\nnyní budete vyzváni k jejich vypnutí. diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 7abde5760..1496a276c 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -73,7 +73,7 @@ Es gibt Probleme beim Verbindungsaufbau mit einem Konto Es gibt Probleme beim Verbindungsaufbau mit mehreren Konten Hier antippen, um deine Konten zu verwalten - Datei hinzufügen + Datei auswählen Der Kontakt ist nicht in deiner Kontaktliste. Möchtest du ihn hinzufügen? Kontakt hinzufügen Zustellung fehlgeschlagen @@ -119,7 +119,7 @@ Benachrichtigungston Benachrichtigungston wiedergeben Schonfrist - Zeitspanne, in der Conversations still bleibt, nachdem es Aktivitäten auf einem anderen Gerät erkannt hat. + Die Zeitspanne, in der Benachrichtigungen nach der Erkennung von Aktivitäten auf einem deiner anderen Geräte unterdrückt werden. Erweitert Niemals Absturzberichte senden Wenn du Absturzberichte einschickst, hilfst du Conversations stetig zu verbessern @@ -281,10 +281,6 @@ Ende Ruhige Stunden aktivieren Benachrichtigungen sind während der ruhigen Stunden stumm. - \"Senden\"-Schaltfläche zeigt Online-Status an - Empfangsbestätigungen anfragen - Empfangene Nachrichten werden mit einem grünen Häkchen markiert. Bitte beachte, dass dies nicht in allen Fällen funktioniert. - \"Senden\"-Schaltfläche einfärben, um den Online-Status des Kontakts anzuzeigen Sonstiges Mit Lesezeichen synchronisieren Tritt Gruppenchats bei und verlasse sie entsprechend der Auto-Join-Funktion in deinen Lesezeichen. @@ -512,9 +508,9 @@ Benachrichtigungen deaktiviert Benachrichtigungen pausiert Bilder komprimieren - Bildgröße ändern und komprimieren + Tipp: Nutze ‘Datei auswählen’ statt ‘Bild auswählen’ um ein einzelnes Bild, unabhängig von dieser Einstellung, unkomprimiert zu übertragen. Immer - Automatisch + Nur große Bilder Akkuoptimierung aktiv Dein Telefon verwendet Akkuoptimierungen bei Conversations, welche verspätete Benachrichtigungen oder Nachrichtenverlust verursachen können.\nEs wird empfohlen, diese zu deaktivieren. Dein Telefon verwendet Akkuoptimierungen bei Conversations, welche verspätete Benachrichtigungen oder Nachrichtenverlust verursachen können.\n\nDu wirst nun gefragt, diese zu deaktivieren. @@ -858,7 +854,7 @@ Channels entdecken Channels suchen Mögliche Datenschutzverletzung! - search.jabber.network.

Wenn du diese Funktion verwendest, werden deine IP-Adresse und deine Suchbegriffe an diesen Dienst übertragen. Weitere Informationen findest du in der Datenschutzerklärung.]]>
+ search.jabber.network.

Wenn du diese Funktion verwendest, werden deine IP-Adresse und deine Suchbegriffe an diesen Dienst übertragen. Weitere Informationen findest du in der Datenschutzerklärung.]]>
Ich habe bereits ein Konto Vorhandenes Konto hinzufügen Neues Konto erstellen @@ -874,4 +870,12 @@ Bitte gib das Passwort für dieses Konto ein Diese Aktion kann nicht ausgeführt werden Öffentlichen Channel beitreten... + Die teilende App hat keine Berechtigung für den Zugriff auf diese Datei erteilt. + + jabber.network + Lokaler Server + Die meisten Benutzer sollten hier ‘jabber.network’ auswählen um bessere Vorschläge aus dem gesamten, öffentlichen XMPP Ökosystem zu bekommen. + Channelsuchmethode + Sicherungskopie + Über diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml index 121738426..1f0a83ed9 100644 --- a/src/main/res/values-el/strings.xml +++ b/src/main/res/values-el/strings.xml @@ -118,7 +118,6 @@ Ήχος Κουδούνισμα όταν δέχεστε νέο μήνυμα Περίοδος Χάριτος - Η διάρκεια του χρόνου που το Conversations σταματάει τη λειτουργία του καθώς ανιχνεύθηκε δραστηριόητα σε άλλη συσκευή Προχωρημένος Να μην αποστέλλονται αναφορές λαθών Στέλνοντας ίχνη στοίβας βοηθάτε την συνεχόμενη ανάπτυξη του Conversations @@ -281,10 +280,6 @@ Ώρα λήξης Ενεργοποίηση ωρών ησυχίας Οι ειδοποιήσεις θα σιγαστούν κατά τις ώρες ησυχίας - Το κουμπί αποστολής υποδηλώνει την κατάσταση - Αίτηση για αποδείξεις μηνυμάτων - Τα ληφθέντα μηνύματα θα σημειώνονται με ένα πράσινο τικ, αν αυτό υποστηρίζεται - Χρωματισμός του κουμπιού αποστολής ως ένδειξη κατάστασης επαφής Άλλο Συγχρονισμός με σελιδοδείκτες Συμμετοχή και έξοδος από ομαδικές συζητήσεις σύμφωνα με την επιλογή αυτόματης συμμετοχής στους σελιδοδείκτες σας. @@ -511,9 +506,7 @@ Απενεργοποίηση ειδοποιήσεων Παύση ειδοποιήσεων Συμπίεση εικόνας - Σμίκρυνση και συμπίεση εικόνων Πάντα - Αυτόματα Ενεργοποίηση βελτιστοποίησης χρήσης μπαταρίας Η συσκευή σας χρησιμοποιεί βελτιστοποίηση στην χρήση μπαταρίας του Conversations που μπορεί να οδηγήσει σε αργοπορημένες ειδοποιήσεις ή ακόμα και σε απώλεια μηνυμάτων.\nΠροτείνεται να την απενεργοποιήσετε Η συσκευή σας χρησιμοποιεί βελτιστοποίηση στην χρήση μπαταρίας του Conversations που μπορεί να οδηγήσει σε αργοπορημένες ειδοποιήσεις ή ακόμα και σε απώλεια μηνυμάτων.\nΘα σας ζητηθεί να την απενεργοποιήσετε. diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 01f649d2b..1805aa075 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -119,7 +119,7 @@ Tono Reproduce tono con la notificación Periodo de gracia - Periodo de tiempo en el que Conversations deshabilita las notificaciones tras ver que tienes actividad en otro de tus dispositivos + El periodo de tiempo en el que las notificaciones están silenciadas tras detectar actividad en otro de tus dispositivos. Avanzado Nunca informar de errores Si envías registros de error ayudas al desarrollo de Conversations @@ -281,10 +281,6 @@ Hora de fin Habilitar horario de silencio Las notificaciones serán silenciadas durante el horario de silencio - Botón enviar indica estado - Solicitar entrega de mensaje - Cuando el contacto reciba el mensaje será indicado con una marca verde. Cuidado, esto podría no funcionar en todos los casos. - El color del botón enviar indica el estado del contacto Otros Sincronizar marcadores Unirse y salir de las conversaciones en grupo de acuerdo con la marca de unirse automáticamente de tus marcadores. @@ -337,6 +333,7 @@ %s ofrecido para descarga Cancelar transferencia falló la transferencia del archivo + transferencia del fichero cancelada El archivo ha sido eliminado No se ha encontrado ninguna aplicación para abrir el archivo No se ha encontrado aplicación para abrir el link @@ -511,9 +508,9 @@ Notificaciones deshabilitadas Notificaciones pausadas Compresión de imagen - Redimensionar y comprimir las imágenes + Pista: Usa \'Seleccionar archivo\' en lugar de \'Seleccionar imagen\' para enviar imágenes individuales sin comprimir con independencia de los ajustes. Siempre - Automáticamente + Solo imágenes de gran tamaño Optimizaciones de uso de batería habilitadas Tu dispositivo está realizando optimizaciones de uso de batería en Conversations que pueden hacer que los mensajes se retrasen o incluso hacer que se pierdan.\nEs recomendable deshabilitarlas. Tu dispositivo está realizando optimizaciones de uso de batería en Conversations que pueden hacer que los mensajes se retrasen o incluso hacer que se pierdan.\n\nEl sistema te preguntará ahora para deshabilitarlas. @@ -857,6 +854,7 @@ Descubrir canales Buscar canales ¡Posible violación de privacidad! + search.jabbercat.org.

Usando esta funcionalidad transmitirás tu dirección IP y los términos buscados a este servicio. Ver su Política de Privacidad para más información.]]>
Ya tengo una cuenta Añadir una cuenta existente Registrar una cuenta nueva @@ -872,4 +870,12 @@ Por favor ingrese la contraseña para esta cuenta No se ha podido realizar esta acción Unirse a canal público... + La aplicación \'Compartir\' no concedió permisos para acceder a este fichero. + + jabber.network + Servidor local + La mayoría de los usuarios deberían elegir \'jabber.network\' para mejores sugerencias de todo el ecosistema público XMPP. + Método para la búsqueda de Canales + Copia de respaldo + Acerca de diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index bc769c730..cb2ab23c1 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -119,7 +119,6 @@ Dei-tonua Mezu berri bat heltzerakoan dei-tonua jo Grazia epea - Beste gailu batean aktibitatea ikusi ostean Conversationsek isilik mantentzen den denbora Aurreratua Gelditze txostenik ez bidali inoiz Akats harraskak bidaliz Conversationsen garapenean laguntzen duzu @@ -281,10 +280,6 @@ Amaiera ordua Ordu lasaiak gaitu Jakinarazpenak isilaraziko dira ordu lasaiak iraun bitartean - Bidaltze botoiak egoera adierazten du - Mezuen jasotzea eskatu - Jasotako mezuak marka berde batekin markatuko dira. Baliteke kasu guztietan ez funtzionatzea. - Bidaltze botoia koloreztatu kontaktu baten egoera adierazteko Besteak Laster-markekin sinkronizatu Taldeetan sartu eta taldeak utzi zure laster-marken auto-batu markaren arabera. @@ -511,9 +506,7 @@ Jakinarazpenak ezgaituta Jakinarazpenak gelditu dira Irudiak konprimatu - Irudiak konprimatu eta neurriz aldatu Beti - Automatikoki Bateriaren optimizazioak gaituta Zure gailua jakinarazpen atzeratuak edota mezuen galera ekar lezaketen bateriaren optimizazio handiak egiten ari da Conversationsen.\nHoriek ezgaitzea gomendatzen da. Zure gailua jakinarazpen atzeratuak edota mezuen galera ekar lezaketen bateriaren optimizazio handiak egiten ari da Conversationsen.\nJarraian hauek ezgaitzea eskatuko zaizu. diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index d0cff7724..19f1caaa5 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -119,7 +119,7 @@ Sonnerie Jouer un son lors de la réception d\'un message Période sans notification - Durée d\'inactivité de Conversations après avoir repéré un changement sur un autre appareil + La durée pendant laquelle les notifications sont désactivées après la détection d\'une activité sur l\'un de vos autres appareils. Avancé Ne pas envoyer de rapports d\'erreurs En envoyant des logs vous aidez le développement de Conversations. @@ -281,10 +281,6 @@ Heure de fin Activer les heures tranquilles Les notifications seront muettes pendant les heures tranquilles. - Statut sur le bouton Envoyer - Accusés de réception - Les messages reçus seront marqués d\'une coche verte (si supporté). - Le bouton Envoyer change de couleur pour indiquer le statut du contact. Autres Synchroniser avec les signets Rejoignez et quittez les discussions de groupe en fonction de l\'indicateur de jointure automatique dans vos favoris. @@ -512,9 +508,7 @@ Notifications désactivées Notifications en pause Compression de l\'image - Redimensionner et compresser les images Toujours - Automatiquement Optimisations de batterie activées Votre appareil applique sur Conversations des optimisations de batterie très strictes qui pourraient provoquer des retards dans les notifications, voire des pertes de messages.\nNous vous recommandons de les désactiver. Votre appareil applique sur Conversations des optimisations de batterie très strictes qui pourraient provoquer des retards dans les notifications, voire des pertes de messages.\nVous allez maintenant avoir la possibilité de les désactiver. @@ -874,4 +868,5 @@ Veuillez saisir le mot de passe pour ce compte Action impossible à réaliser Rejoindre le canal public ... + L\'application de partage n\'a pas accordé la permission d\'accéder à ce fichier. diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index bf4088dfe..d2c46b24c 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -119,7 +119,7 @@ Ton de aviso Emitir son cando chegue unha nova mensaxe Período de graza - O tempo que Conversations permanece silente despois de ver actividade en outro dispositivo + O tempo no que as notificacións son silenciadas tras detectar actividade en algún dos teus outros dispositivos. Avanzado Nunca enviar informe de erros Enviando volcados de pilas axudas ao desenvolvemento de Conversations @@ -281,10 +281,6 @@ Hora de finalización Establecer horario sen notificacións As notificacións serán silenciadas durante estas horas - O botón Enviar indica o estado - Solicitar avisos de recepción - As mensaxes recibidas marcaránse cun sinal verde si este está admitido - Boton de enviar de cor para indicar o estado do contacto Outro Sincronizar cos marcadores Unirse e deixar conversas de grupo de acordo coa marca auto-unirse nos seus marcadores. @@ -337,6 +333,7 @@ Ofreceuse %s para descargar Cancelar a transmisión fallou a transmisión do ficheiro + Detívose a transmisión do ficheiro Este ficheiro eliminouse Non se atopou un aplicativo para abrir o ficheiro Non se atopou ningunha aplicación para abrir a ligazón @@ -511,9 +508,9 @@ Notificacións desactivadas Notificacións pausadas Compresión de imaxes - Escalar e comprimir imaxes + Truco: Utiliza \'Escoller ficheiro\' no lugar de \'Escoller imaxe\' para enviar imaxes individuais sen comprimir obviando este axuste. Sempre - Automáticamente + Só imaxes grandes Optimizacións de batería activadas O seu dispositivo está a realizar algunhas optimizacións de batería extremas en Conversations que poderían levar a notificacións con retraso ou incluso perda das mesmas.\nÉ recomendado desactivalas. O seu dispositivo está facendo unhas optimizacións de batería moi fortes en Conversations que poderían facer que se retrasasen algunhas mensaxes ou incluso se perdesen.\n\nAgora pediráselle que se desactive as mesmas. @@ -857,6 +854,7 @@ Descubrir canales Buscar canales Posible intrusión na intimidade! + search.jabber.network.

Ao utilizar esta función transmitirá o seu enderezo IP e termos de busca a ese servizo. Lea a súa Política de Intimidade para máis información.]]>
Xa teño unha conta Engadir conta existente Rexistrar unha nova conta @@ -872,4 +870,12 @@ Introduza o contrasinal de esta conta Non se puido completar a acción Unirse a canle pública... + A aplicación que comparte non proporciona permiso para acceder ao ficheiro. + + jabber.network + Servidor local + A maioría das usuarias debería escoller \'jabber.network\' para obter mellores suxestións desde o ecosistema público XMPP. + Método de descubrimento de canles + Respaldo + Acerca de diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index 239bb7064..c59821692 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -118,7 +118,6 @@ Csengőhang Hangeffekt lejátszása új üzenet érkezésekor Türelmi idő - A szoftver csendben marad ennyi ideig, miután aktivitást észlelt másik eszközön Fejlett funkciók Ne küldjön programhiba jelentéseket A hibák jelentésével segíted a Conversations program fejlesztését @@ -280,10 +279,6 @@ Befejezése Csöndes órák engedélyezése Értesítések el lesznek némítva a csöndes órákban - A küldés gomb jelzi az állapotot - Üzenet nyugták kérése - A megkapott üzenetek egy zöld pipával lesznek jelölve ha támogatott ez a funkció - Kiszínezi a küldés gombot, hogy jelezze a partner állapotát Egyéb Szinkronizáljon könyvjelzőkkel Csatlakozzon és hagyja ott a csoportos beszélgetéseket a könyvjelzők automatikus csatlakozásának megfelelően. @@ -510,9 +505,7 @@ Értesítések letiltva Értesítések szüneteltetve Kép tömörítés - Átméretezi és tömöríti a képeket Mindig - Automatikusan Akkumulátor optimalizációk engedélyezve A készülék erős akkumulátor optimalizálást végez a Conversations programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhet is vezethet.\nJavasolt kikapcsolni ezt. A készülék erős akkumulátor optimalizálást végez a Conversations programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhet is vezethet.\nMost meg lesz kérve az optimalizáció letiltására. diff --git a/src/main/res/values-id/strings.xml b/src/main/res/values-id/strings.xml index 7359773be..a0352c89e 100644 --- a/src/main/res/values-id/strings.xml +++ b/src/main/res/values-id/strings.xml @@ -206,10 +206,6 @@ Waktu selesai Aktifkan waktu sunyi Pemberitahuan akan disunyukan ketika jam sunyi. - Tombol kirim menunjukan statusnya - Permintaan penerimaan pesan - Pesan yang diterima akan ditambahkan centang hijau jika didukung - Warnai tombol kirim untuk mengindikasikan status kontak Lainnya menggunakan akun %s Anda tidak terhubung. Coba lagi nanti @@ -325,7 +321,6 @@ Sinkronkan dengan kontak Tampilkan notifikasi untuk semua pesan Selalu - Secara otomatis Pengoptimalan baterai diaktifkan Non-aktifkan Area yang dipilih terlalu besar diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 44a5dc410..3c7e1d2a9 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -119,7 +119,6 @@ Suono di notifica Esegui un suono quando arriva un nuovo messaggio Periodo di grazia - Il periodo di tempo in cui Conversations resta silenzioso quando vede attività su un altro dispositivo Avanzate Non inviare mai segnalazioni di errore Se scegli di inviare una segnalazione dell’errore aiuterai lo sviluppo di Conversations @@ -281,10 +280,6 @@ Orario fine Attiva ore di quiete Le notifiche verranno silenziate durante le ore di quiete - Il pulsante di invio indica lo stato - Richiedi la ricevuta di ritorno - I messaggi ricevuti verranno contrassegnati con una spunta verde se supportato - Colora il pulsante di invio per indicare lo stato del contatto Altro Sincronizza con i segnalibri Entra ed esci dalle chat di gruppo rispettando l\'opzione di entrata automatica nei tuoi segnalibri. @@ -337,6 +332,7 @@ %s offerto da scaricare Annulla trasmissione trasmissione del file fallita + trasmissione file annullata Il file è stato eliminato Nessuna applicazione trovata per aprire il file Nessuna applicazione trovata per aprire il link @@ -511,9 +507,7 @@ Notifiche disattivate Notifiche in pausa Compressione immagini - Ridimensiona e comprimi le immagini Sempre - Automaticamente Ottimizzazioni batteria attivate Il tuo dispositivo sta facendo delle ingenti ottimizzazioni della batteria per Conversations che potrebbero portare ritardi alle notifiche o anche perdita di messaggi.\nSi consiglia di disattivarle. Il tuo dispositivo sta facendo delle ingenti ottimizzazioni della batteria per Conversations che potrebbero portare ritardi alle notifiche o anche perdita di messaggi.\n\nTi verrà ora chiesto di disattivarle. @@ -857,6 +851,7 @@ Individua i canali Cerca i canali Possibile violazione della privacy! + search.jabber.network.

L\'uso di questa funzione trasmetterà il tuo indirizzo IP e i termini di ricerca a quel servizio. Vedi la loro Informativa sulla Privacy per saperne di più.]]>
Ho già un account Aggiungi un account pre-esistente Registra un nuovo account @@ -871,4 +866,5 @@ Questo account è già stato configurato Inserisci la password per questo account Impossibile eseguire questa azione + Entra in un canale pubblico... diff --git a/src/main/res/values-iw/strings.xml b/src/main/res/values-iw/strings.xml index 3a5ad007e..7300c187e 100644 --- a/src/main/res/values-iw/strings.xml +++ b/src/main/res/values-iw/strings.xml @@ -197,10 +197,6 @@ זמן סיום הפעל \"שעות שקטות\" ההתראות יושבתו במהלך שעות שקטות - לחצן השליחה מעיד על הסטטוס - בקש אימות הגעת הודעות - יופיע סימן \"וי\" ליד כל הודעה שהתקבלה על ידי איש הקשר, במידה והפעולה נתמכת על ידי איש הקשר. - צבעו של לחצן שליחת ההודעות יעיד על סטטוס איש הקשר. אחר טביעת אצבע של OMEMO הועתקה משתמש בחשבון: %s diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index 0751ba481..4ddd4917f 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -115,7 +115,6 @@ 着信音 新しいメッセージが届いたときにサウンドを再生します 猶予期間 - 別のデバイスで活動を見た後、Conversations を静かにする時間の長さ 詳細 クラッシュレポートを送信しない スタックトレースを送信することで、あなたは Conversations の継続的な開発を支援しています @@ -273,10 +272,6 @@ 終了時間 消音時間を有効にする 消音時間の間、通知は無音になります - 送信ボタンにステータスを示す - 要求メッセージの受信 - サポートされている場合、受信したメッセージに緑色のチェックマークが付きます - 送信ボタンに連絡先ステータスを示す色が付きます その他 ブックマークと同期 ブックマークの自動参加フラグに従って、グループチャットに参加したり退席します。 @@ -476,9 +471,7 @@ 通知は無効 通知は一時停止 画像の圧縮 - 画像のサイズ変更と圧縮 常に - 自動 バッテリー最適化が有効 お使いのデバイスは、Conversations で、通知の遅延やメッセージの損失につながる可能性のある、いくつかの重いバッテリーの最適化を行っています。\nそれらを無効にすることをお勧めします。 お使いのデバイスは、Conversations で通知の遅延やメッセージの損失につながる可能性のある、いくつかの重いバッテリーの最適化を行っています。\n\n今、それらを無効にするように求められます。 diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml index 90e516032..943a8a0e0 100644 --- a/src/main/res/values-ko/strings.xml +++ b/src/main/res/values-ko/strings.xml @@ -230,10 +230,6 @@ 마감 시간 무음 시간대 사용 무음 시간대에는 알림이 해제됩니다 - 전송 버튼이 상태를 나타냄 - 메세지 영수증 요청 - 만약 지원될 경우, 수신된 메세지는 초록색 기호로 표시됩니다. - 연락처 상태를 표시하기 위해 전송 버튼을 색칠함 기타 OMEMO 핑거프린트가 클립보드에 복사되었습니다 using account %s @@ -396,7 +392,6 @@ 알림 해제됨 알림 일시중지됨 항상 - 자동 배터리 최적화 사용됨 당신의 기기는 메세지를 받지 못하게 되거나 알림을 지연시킬 수도 있는 고강도의 배터리 최적화를 Conversations에 하고 있습니다.\n배터리 최적화를 해제하는 것을 추천합니다. 당신의 기기는 메세지를 받지 못하게 되거나 알림을 지연시킬 수도 있는 고강도의 배터리 최적화를 Conversations에 하고 있습니다.\n이것을 해제할 것인지 물어볼 것입니다. diff --git a/src/main/res/values-nb-rNO/strings.xml b/src/main/res/values-nb-rNO/strings.xml index 9991a5fdc..149313e75 100644 --- a/src/main/res/values-nb-rNO/strings.xml +++ b/src/main/res/values-nb-rNO/strings.xml @@ -105,7 +105,6 @@ Ringetone Spill en lyd når en ny melding ankommer Fristperiode - Mengden tid Conversations forholder seg rolig i, etter å ha sett aktivitet på en annen enhet Avansert Aldri send kræsjrapporter Ved å sende inn stabelsporinger hjelper du den pågående utviklingen av Conversations @@ -248,10 +247,6 @@ Avslutning Aktiver stille tidsavgrensning Varslinger blir ikke spilt under stilletid - Forsendelsesknappstatus - Forespør meldingskvitteringer - Mottatte meldinger vil bli avmerket i grønt hvis støttet - Fargelegg send-knapp for å indikere kontakt-status Annet OMEMO-fingeravtrykk kopiert til utklippstavle! Du er bannlyst fra denne gruppesludringen @@ -437,7 +432,6 @@ Varslinger deaktivert Varslinger pauset Alltid - Automatisk Batterioptimaliseringer aktivert Enheten din gjør noen tunge batterioptimaliseringer på Conversations som kan føre til forsinkede varslinger eller tap av meldinger.\nDet anbefales at du deaktiverer disse. Enheten din gjør noen tunge batterioptimaliseringer på Conversations som kan føre til forsinkede varslinger eller tap av meldinger.\n\nDu vil nå bli bedt om å deaktivere disse. diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 87be4330c..4ad1ee413 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -119,7 +119,6 @@ Meldingstoon Geluid afspelen wanneer een nieuw bericht ontvangen wordt Uitstelperiode - Hoe lang Conversations stil blijft na activiteit op een ander apparaat waar te nemen Geavanceerd Verstuur nooit crashrapportages Door crashrapportages te versturen help je de ontwikkeling van Conversations @@ -281,10 +280,6 @@ Eindtijd Stille uren inschakelen Tijdens stille uren worden meldingen onderdrukt - Verstuur-knop toont status aan - Vraag ontvangstbevestigingen - Indien ondersteund, worden ontvangen berichten met een groen vinkje aangeduid - Kleur verstuur-knop in om status van contact weer te geven Andere Synchroniseren met bladwijzers Neem deel aan en verlaat groepsgesprekken op basis van de automatische deelname-optie in je bladwijzers. @@ -512,9 +507,7 @@ Meldingen uitgeschakeld Meldingen gepauzeerd Afbeeldingscompressie - Afbeeldingen verkleinen en comprimeren Altijd - Automatisch Batterij-optimalisaties ingeschakeld Je apparaat voert sterke batterij-optimalisaties uit op Conversations, die kunnen leiden tot vertraagde meldingen of zelfs verlies van berichten.\nHet is aangeraden deze optimalisaties uit te schakelen. Je apparaat voert sterke batterij-optimalisaties uit op Conversations, die kunnen leiden tot vertraagde meldingen of zelfs verlies van berichten.\nJe zal nu gevraagd worden deze optimalisaties uit te schakelen. diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 442a4b742..b9167c26a 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -119,7 +119,7 @@ Dzwonek Odtwórz dźwięk gdy nadejdzie wiadomość Czas bez powiadomień - Czas od ostatniej aktywności na innym urządzeniu, przez który Conversations nie odzywa się + Długość czasu kiedy powiadomienia są uśpione po wykryciu aktywności na jednym z twoich innych urządzeń. Zaawansowane Nie wysyłaj raportów awarii Wysyłając ślady stosu pomagasz rozwijać Conversations @@ -281,10 +281,6 @@ Koniec Włącz godziny ciszy Powiadomienia będą wyciszone w wybranym przedziale czasu - Przycisk wysyłania wskazuje status - Raporty dostarczenia - Jeżeli to możliwe, oznaczaj dostarczone wiadomości zielonym haczykiem - Koloruj przycisk wysyłania w zależności od statusu kontaktu Inne Synchronizuj z zakładkami Dołączaj i wychodź z konferencji przy użyciu flagi automatycznego dołączania z zakładek @@ -337,6 +333,7 @@ Zaproponowano pobranie pliku %s Anuluj przesyłanie Przesyłanie pliku nie powiodło się + transmisja pliku anulowana Plik został usunięty Nie odnaleziono aplikacji skojarzonej z typem pliku Brak aplikacji do otwarcia linka @@ -515,9 +512,9 @@ Powiadomienia wyłączone Powiadomienia wstrzymane Kompresja obrazów - Zmień rozmiar i kompresuj obrazki + Podpowiedź: Użyj \'Wybierz plik\' zamiast \'Wybierz obraz\' aby wysłać poszczególne obrazki bez kompresji bez względu na to ustawienie. Zawsze - Automatycznie + Tylko duże obrazki Optymalizacje zużycia baterii włączone Twoje urządzenie wykonuje poważnie optymalizacje zużycia baterii przez Conversations, które mogą powodować opóźnienie powiadomień lub nawet utratę wiadomości.\nZaleca się ich wyłączenie. Twoje urządzenie wykonuje poważnie optymalizacje zużycia baterii przez Conversations, które mogą powodować opóźnienie powiadomień lub nawet utratę wiadomości.\nZostaniesz teraz poproszony o ich wyłączenie @@ -874,6 +871,7 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Odkryj kanały Wyszukaj kanał Możliwe naruszenie prywatności! + search.jabber.network.

Używając tej funkcji twój adres IP oraz kryteria wyszukiwania zostaną wysłane do tej usługi. Sprawdź Politykę Prywatności aby uzyskać więcej informacji.]]>
Już mam konto Dodaj istniejące konto Zarejestruj nowe konto @@ -889,4 +887,12 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Proszę podać hasło dla tego konta Nie można wykonać tej akcji Dołącz do publicznego kanału... + Aplikacja udostępniająca nie udzieliła pozwolenia na dostęp do tego pliku. + + jabber.network + Serwer lokalny + Większość użytkowników powinna wybrać \'jabber.network\' dla lepszych sugestii z całego ekosystemu XMPP. + Metoda odkrywania kanałów + Kopia zapasowa + O aplikacji diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index 0d7b98eeb..3620e43ac 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -119,7 +119,7 @@ Toque Toca um som ao receber uma nova mensagem. Período de espera - Espaço de tempo em que o Conversations ficará sem notificações, após alguma atividade em outro dispositivo. + Espaço de tempo em que as notificações serão silenciadas, após detectar atividade em algum dos seus outros dispositivos. Avançado Nunca enviar relatórios de erros Ao enviar os stack traces você está colaborando com o desenvolvimento do Conversations. @@ -281,10 +281,6 @@ Fim Habilitar horário de sossego As notificações serão silenciadas no horário de sossego. - O botão de envio indica o status - Solicitar confirmação de recebimento - As mensagens recebidas serão marcadas com um tique verde, se suportado. - Colore o botão de envio para indicar o status do contato. Outras Sincronizar com os favoritos Entrar e sair das conversas em grupo de acordo com a sinalização de entrada automática nos seus favoritos. @@ -337,6 +333,7 @@ %s oferecido para baixar Cancelar transmissão não foi possível transferir o arquivo + transmissão do arquivo cancelada O arquivo foi excluído Não foi encontrado nenhum aplicativo para abrir o arquivo Não foi encontrado nenhum aplicativo para abrir o link @@ -511,9 +508,7 @@ Notificações desabilitadas Notificações pausadas Compressão de imagem - Redimensiona e comprime as imagens. Sempre - Automaticamente Otimizações de bateria habilitadas O seu dispositivo está aplicando uma otimização intensa de bateria no Conversations, que pode levar a atraso nas notificações ou até mesmo perda de mensagens.\nÉ recomendável desabilitar isso. O seu dispositivo está aplicando uma otimização intensa de bateria no Conversations, que pode levar a atraso nas notificações ou até mesmo perda de mensagens.\nAgora você será solicitado a desabilitá-la. @@ -856,6 +851,7 @@ Descobrir canais Pesquisar canais Provável violação de privacidade! + search.jabber.network.

Ao usar esse recurso, você enviará o seu endereço IP e termos de pesquisa para esse serviço. Veja sua Política de Privacidade para maiores informações.]]>
Eu já tenho uma conta. Adicionar uma conta já existente Registrar uma nova conta @@ -870,4 +866,6 @@ Esta conta já foi configurada Por favor, digite a senha para esta conta Não foi possível executar essa ação + Entrar no canal público... + O aplicativo de compartilhamento não permitiu o acesso a esse arquivo. diff --git a/src/main/res/values-pt/strings.xml b/src/main/res/values-pt/strings.xml index a5f0989ce..6bccb60fa 100644 --- a/src/main/res/values-pt/strings.xml +++ b/src/main/res/values-pt/strings.xml @@ -241,10 +241,6 @@ Hora de fim Ativar horas de tranquilidade Notificações serão silenciadas nas horas de tranquilidade - O botão de enviar indica o estado - Solicitar recibo de mensagem - Mensagens recebidas serão marcadas com um visto verde se suportado - Colorir o botão de enviar para indicar o estado do contacto Outros Impressão digital OMEMO copiada para a área de transferência! Está banido desta conversa de grupo @@ -429,7 +425,6 @@ Notificações desativadas Notificações interrompidas Sempre - Automaticamente Otimizações da bateria ativadas O seu dispositivo está a fazer otimizações de bateria bastante agressivas na aplicação Conversations que poderão levar a notificações atrasadas ou até mesmo a perda de mensagens.\nÉ recomendado que as desative. O seu dispositivo está a fazer otimizações de bateria bastantes agressivas na aplicação Conversations que poderão levar a notificações atrasadas ou até mesmo perda de mensagens.\n\nIrá-lhe agora ser pedido para desativá-las. diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 2e8104252..07fa389f9 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -119,7 +119,7 @@ Sunet de notificare Notificare sonoră atunci când este primit un mesaj nou Perioadă de grație - Durata de timp cât Conversations păstrează liniștea după ce a observat activitate pe un alt dispozitiv + Durata de timp cât notificările sunt ascunse după ce s-a observat activitate pe un alt dispozitiv al dumneavoastră. Opțiuni avansate Nu trimite rapoarte de erori Trimițând datele despre erori ajutați la continuarea dezvoltării aplicației Conversations @@ -281,10 +281,6 @@ Ora de terminare Activează orar de liniște Notificările vor fi reduse la tăcere în timpul orelor de liniște - Butonul de trimitere indică starea - Cere raport de primire - Mesajele primite vor fi marcate cu o bifa verde, dacă este suportat - Colorează butonul de trimitere pentru a indica starea contactului Altele Sincronizează cu semnele de carte Alătură-te sau părăsește discuțiile de grup în mod automat în funcție de setarea din semnele de carte. @@ -514,9 +510,9 @@ Notificări dezactivate Notificări suspendate Compresie imagini - Redimensionează și comprimă imaginile + Notă: Folosiți \'Alegeți un fișier\' în loc de \'Alegeți o imagine\' pentru a trimite imaginile necomprimate ignorând această setare. Mereu - Automat + Doar imaginile mari Optimizare baterie activată Dispozitivul dumneavoastră încearcă să optimizeze agresiv consumul bateriei pentru Conversations, asta poate duce la notificări întârziate sau chiar pierderea mesajelor.\nEste recomandat sa dezactivați aceste optimizări. Dispozitivul dumneavoastră încearcă să optimizeze agresiv consumul @@ -883,4 +879,12 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Va rugăm să introduceți parola pentru acest cont Nu se poate realiza această acțiune Alătură-te unui canal public... + Aplicația care a partajat nu a permis accesul la acest fișier. + + jabber.network + Server local + Cei mai mulți utilizatori ar trebui să aleagă \'jabber.network\' pentru a primi sugestii mai bune din întregul ecosistem XMPP. + Metoda de descoperire a canalelor + Copie de siguranță + Despre diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index edae589e7..c192ba618 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -114,7 +114,6 @@ Звук уведомления Звук при поступлении новых сообщений Грейс-период - Промежуток времени, в течение которого Conversations хранит молчание при обнаружении активности на другом устройстве Дополнительно Не отправлять отчёты об ошибках Отправляя отчёты об ошибках, вы помогаете исправить и улучшить Conversations @@ -268,10 +267,6 @@ Окончание Включить режим «тихих часов» Уведомления будут отключены во время «тихих часов» - Использовать кнопку-индикатор - Запрос в получении сообщения - Если поддерживается, поступившие сообщения будут отмечены зелёной галочкой - Раскрасить кнопку отправить, указывая текущий статус собеседника Другие OMEMO отпечаток скопирован в буфер обмена! Вы заблокированы из этой конференции @@ -482,9 +477,7 @@ Без уведомления Уведомления приостановлены Сжатие изображений - Изменять размер и сжимать изображения Всегда - Автоматически Оптимизации энергопотребления разрешены Ваше устройство использует сильные оптимизации энергопотребления, что может привести к задержке уведомлений и даже потере сообщений.\nРекомендуется их отключить. Ваше устройство использует сильные оптимизации энергопотребления, что может привести к задержке уведомлений и даже потере сообщений.\nСейчас появится предложение их отключить. diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml index 6862167ed..2c88c6796 100644 --- a/src/main/res/values-sk/strings.xml +++ b/src/main/res/values-sk/strings.xml @@ -195,10 +195,6 @@ Čas konca Povoliť tichý režim Upozornenia budú počas tichého režimu stlmené - Tlačidlo pre odoslanie zobrazuje stav - Požadovať oznámenie o prijatí - Prijaté správy budú označené zelenou kvačkou. Toto nemusí vždy plne fungovať. - Vyfarbiť tlačidlo pre odoslanie na určenie stavu kontaktu Ďalší Používa sa účet %s Overiť %s na HTTP host diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index 0c290fafc..f74530ec4 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -108,7 +108,6 @@ Звук Пуштање звука кад стигне нова порука Период одгоде - Период тишине након што Конверзација запази активност на другом уређају Напредно Никад не шаљи извештаје о паду Слањем контратрага помажете текући развој Конверзације @@ -254,10 +253,6 @@ Време завршетка Укључи тихе сате Обавештења ће бити ућуткана за време тихих сати - Дугме слања показује стање - Захтевај потврде порука - Означи примљене поруке зеленом квачицом, ако је подржано - Боја дугмета за слање показује стање контакта Остало ОМЕМО отисак копиран на клипборд! Забрањени сте на овом групном ћаскању @@ -453,7 +448,6 @@ Обавештења искључена Обавештења паузирана увек - аутоматски Оптимизација батерије је укључена Ваш уређај користи оптимизацију потрошње батерије за Конверзацију што може да доведе до застоја обавештења или чак губитка порука.\nПрепоручљиво је да то искључите. Ваш уређај користи оптимизацију потрошње батерије за Конверзацију што може да доведе до застоја обавештења или чак губитка порука.\n\nСада ћете бити упитани да то искључите. diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index c7120852d..3ef3eee0e 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -117,7 +117,6 @@ Meddelandesignal Spela ljud när meddelande tagits emot Notifieringsfrist - Hur lång tid Conversations är tyst efter aktivitet på en annan enhet Avancerat Skicka aldrig krasch-rapporter Genom att skicka in stack traces hjälper du utvecklarna av Conversations @@ -265,10 +264,6 @@ Sluttid Aktivera tysta timmar Notifieringar kommer vara tysta under tysta timmar - Skickaknappen indikerar status - Begär mottagningskvitto - Mottagna meddelanden markeras med en grön bock om det stöds - Färglägg skickaknappen för att indikera kontaktens status Annat Synkronisera med bokmärken OMEMO-fingeravtryck har kopierats till urklipp! @@ -459,9 +454,7 @@ Notifieringar deaktiverade Notifieringar pausade Bildkomprimering - Ändra storlek på och komprimera bilder Alltid - Automatiskt Batterioptimeringar aktiverade Din enhet har kraftiga batterioptimeringar som påverkar Conversations på så sätt att inkommande meddelanden kan försenas eller kan till och med gå förlorade.\nDet är rekommenderat att deaktivera batterioptimeringarna. Din enhet har kraftiga batterioptimeringar som påverkar Conversations på så sätt att inkommande meddelanden kan försenas eller kan till och med gå förlorade.\nDu kommer nu att bli ombedd att stänga av batterioptimeringarna för Conversations. diff --git a/src/main/res/values-tr-rTR/strings.xml b/src/main/res/values-tr-rTR/strings.xml index b49385a81..fab1f77d4 100644 --- a/src/main/res/values-tr-rTR/strings.xml +++ b/src/main/res/values-tr-rTR/strings.xml @@ -98,7 +98,6 @@ Zil sesi Yeni bir ileti geldiğinde sesli bildir Mühlet - Başka bir aygıt üstünde etkinlik algılandığında Conversations\'ın sessiz kalma süresi Gelişmiş Asla çöküş raporu gönderme Çöküş raporu göndermeniz Conversations’ın geliştirilmesine katkıda bulunacaktır. @@ -231,10 +230,6 @@ Bitiş zamanı Sessiz saatleri etkinleştir Bildirimler sessiz saatler boyunca sessize alınacaktır - Gönder düğmesi durum bildirsin - İleti alındısı iste - Alınan iletiler, eğer destekleniyorsa, yeşil bir tikle işaretlenecektir. - Gönder butonunu kişinin durumuna göre renklendir Diğer OMEMO parmak izi panoya kopyalandı! %s hesabını kullanarak @@ -399,7 +394,6 @@ Uyarılar devre dışı Uyarılar geçici olarak durduruldu Her zaman - Kendiliğinden Pil optimizasyonu devrede Aygıtınız Conversations üzerinde yoğun pil iyileştirmesi yaptığı için bildirimlerde gecikmeler olabilir üstelik bazı ileti kayıpları yaşanabilir.\nBu durumla karşılaşamamak için devre dışı bırakmanız önerilir. Aygıtınız Conversations üzerinde yoğun pil iyileştirmesi yaptığı için bildirimlerde gecikmeler olabilir üstelik bazı ileti kayıpları yaşanabilir.\n Şimdi bunları devre dışı bırakmanız istenecek. diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index d631e8ffe..71f5e2caf 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -116,7 +116,6 @@ Мелодія дзвінка Грати звук, коли надходить нове повідомлення Період очікування - Період часу, протягом якого програма не сповіщає, після діяльності на іншому пристрої Розширені Не надсилати звіти про збої Надсилаючи траси стеку викликів Ви допомагаєте розробці Розмов, яка продовжується @@ -279,10 +278,6 @@ Час завершення Задіяти години тиші Сповіщення не звучатимуть під час годин тиші - Кнопка відправки показує стан - Просити повідомлення про доставку - Отримані повідомлення будуть позначені зеленою галочкою, якщо ця функція підтримується - Змінювати колір кнопки відправлення на позначення статусу контакта Інше Синхронізувати з закладками Приєднуватися до груп і полишати їх відповідно до опції автоматичного приєднання, вибраної в закладках. @@ -513,9 +508,7 @@ Сповіщення вимкнено Сповіщення призупинено Стиснення зображень - Змінити розмір і стиснути зображення Завжди - Автоматично Оптимізацію батареї задіяно Ваш пристрій здійснює деяку агресивну оптимізацію Розмов для збереження заряду батареї, яка може призвести до затримки сповіщення або навіть втрати повідомлень.\nРекомендовано відключити цю оптимізацію. Ваш пристрій здійснює деяку агресивну оптимізацію Розмов для збереження заряду батареї, яка може призвести до затримки сповіщення або навіть втрати повідомлень.\nПросимо Вас зараз відключити цю оптимзацію. diff --git a/src/main/res/values-vi/strings.xml b/src/main/res/values-vi/strings.xml index 153b8d706..2335bdd05 100644 --- a/src/main/res/values-vi/strings.xml +++ b/src/main/res/values-vi/strings.xml @@ -98,7 +98,6 @@ Âm báo Chơi nhạc báo khi có tin nhắn mới Thời gian gia hạn thông báo - Khoảng thời gian Conversations giữ yên lặng sau khi xem hoạt động trên một thiết bị khác Nâng cao Không bao giờ gửi báo cáo dừng chạy Bằng việc gửi báo cáo hoạt động, bạn đang hỗ trợ nhóm phát triển của Conversations @@ -227,10 +226,6 @@ Thời gian kết thúc Bật giờ yên lặng Thông báo sẽ được tắt trong giờ yên lặng - Nút gửi biểu thị trạng thái - Yêu cầu thông báo nhận tin nhắn - Các tin nhắn đã nhận sẽ được đánh dấu kiểm màu xanh lá nếu được hỗ trợ - Tô màu nút gửi để biểu thị trạng thái của liên hệ Khác Đã chép dấu vân tay OMEMO vào clipboard! đang dùng tài khoản %s @@ -367,7 +362,6 @@ Đã tắt thông báo Đã dừng thông báo Luôn luôn - Tự động Đã bật tối ưu pin Thiết bị đang thực hiện tối ưu hoá pin trên Conversations và nó có thể gây trì hoãn thông báo hay thậm chí làm mất tin nhắn.\nBạn nên tắt chế độ đó đi. Thiết bị đang thực hiện tối ưu hoá pin trên Conversations và nó có thể gây trì hoãn thông báo hay thậm chí làm mất tin nhắn.\n\nBây giờ, bạn sẽ được yêu cầu tắt chế độ đó đi. diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 7a090cb65..a217fd4fc 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -119,7 +119,6 @@ 铃声 收到新消息时响铃 静默期限 - 发现在其它设备上的活动后,Conversations保持安静的时间 高级 从不发送崩溃报告 通过发送堆栈跟踪,您可以帮助Conversations持续发展 @@ -281,10 +280,6 @@ 结束时间 启用静默时间段 在静默时间段内通知将保持静音 - 发送按钮显示状态 - 请求消息回执 - 如果支持,收到的消息将标记为绿色对勾 - 着色发送按钮以示联系人状态 其他 同步书签 根据书签中的自动加入标记加入并离开群聊。 @@ -509,9 +504,7 @@ 禁用通知 暂停通知 图像压缩 - 调整大小并压缩图像 总是 - 自动 启用节电模式 你的设备正在为Conversations进行电池优化,这可能导致通知的延迟甚至消息的丢失。 建议不要这样做 diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml index 3d786abe5..bd3878209 100644 --- a/src/main/res/values-zh-rTW/strings.xml +++ b/src/main/res/values-zh-rTW/strings.xml @@ -99,7 +99,6 @@ 鈴聲 收到新訊息時響鈴 靜默期限 - 發現在其它設備上的活動後,Conversations保持安靜的時間 高級 總不發送崩潰報告 發送堆疊跟蹤説明 Conversations 開發人員 @@ -235,10 +234,6 @@ 結束時間 啟用靜默時間段 在靜默時間段內通知將保持靜音 - 發送按鈕顯示狀態 - 請求訊息回復 - 如果支援收到的訊息將會以綠色勾號標識 - 發送按鈕採用其他顏色以示發送狀態的區別 其他 OMEMO 指紋已拷貝到剪貼板! 用帳戶 %s @@ -401,7 +396,6 @@ 關閉通知 暫停通知 總是 - 自動 啟用節電模式 你的設備正在為Conversations進行電池優化,這可能導致通知的延遲甚至訊息的丟失。 建議不要這樣做 diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml index 54e122dad..50ca38c6e 100644 --- a/src/main/res/values/arrays.xml +++ b/src/main/res/values/arrays.xml @@ -62,7 +62,7 @@ @string/never - @string/automatically + @string/large_images_only @string/always @@ -124,4 +124,14 @@ @string/video_720p @string/video_original + + + @string/jabber_network + @string/local_server + + + + JABBER_NETWORK + LOCAL_SERVER + diff --git a/src/main/res/values/attrs.xml b/src/main/res/values/attrs.xml index 1f78b19a2..ce15d0013 100644 --- a/src/main/res/values/attrs.xml +++ b/src/main/res/values/attrs.xml @@ -22,6 +22,7 @@ + diff --git a/src/main/res/values/defaults.xml b/src/main/res/values/defaults.xml index bf543fd4e..a4a1448cd 100644 --- a/src/main/res/values/defaults.xml +++ b/src/main/res/values/defaults.xml @@ -16,7 +16,6 @@ 524288 auto light - true recent true true @@ -31,7 +30,6 @@ true true true - true true false false @@ -42,4 +40,5 @@ false false 360 + JABBER_NETWORK diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 0a9452ecd..15a4e16ea 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -119,7 +119,7 @@ Ringtone Play sound when a new message arrives Grace Period - The length of time Conversations keeps quiet after seeing activity on another device + The length of time notifications are silenced after detecting activity on one of your other devices. Advanced Never send crash reports By sending in stack traces you are helping the ongoing development of Conversations @@ -281,10 +281,6 @@ End time Enable quiet hours Notifications will be silenced during quiet hours - Send button indicates status - Request message receipts - Received messages will be marked with a green tick if supported - Colorize send button to indicate contact status Other Synchronize with bookmarks Join and leave group chats according to auto-join flag in your bookmarks. @@ -512,9 +508,9 @@ Notifications disabled Notifications paused Image Compression - Resize and compress images + Hint: Use ‘Choose file’ instead of ‘Choose picture’ to send individual images uncompressed regardless of this setting. Always - Automatically + Large images only Battery optimizations enabled Your device is doing some heavy battery optimizations on Conversations that might lead to delayed notifications or even message loss.\nIt is recommended to disable those. Your device is doing some heavy battery optimizations on Conversations that might lead to delayed notifications or even message loss.\n\nYou will now be asked to disable those. @@ -876,4 +872,12 @@ Please enter the password for this account Unable to perform this action Join public channel… + The sharing application did not grant permission to access this file. + + jabber.network + Local server + Most users should choose ‘jabber.network’ for better suggestions from the entirety of the public XMPP ecosystem. + Channel discovery method + Backup + About diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index 385458c61..72da37bf5 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -18,6 +18,7 @@ @drawable/search_background_light @drawable/no_results_background_light + @drawable/no_results_primary_background_light @drawable/list_item_background_light @color/black @@ -127,6 +128,7 @@ @color/grey700 @drawable/search_background_dark @drawable/no_results_background_dark + @drawable/no_results_primary_background_dark @drawable/list_item_background_dark @color/red_a100 diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index 90813d29a..bce0cc349 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -16,6 +16,22 @@ + + + + - - - - - - - - - - + android:key="notification_category" + android:title="@string/pref_notification_settings"> - + - - - + + + - + + + + + + + - + - + + - - - + + + + + + + + - - - @@ -207,11 +214,6 @@ android:key="btbv" android:summary="@string/pref_blind_trust_before_verification_summary" android:title="@string/pref_blind_trust_before_verification" /> - - + + + android:key="group_chats" + android:title="@string/group_chats_and_channels"> - - - + + + + - - - + + +