opt-in to send last userinteraction in presence
This commit is contained in:
parent
6639d0f23b
commit
71e9117176
|
@ -19,6 +19,7 @@
|
|||
* XEP-0280: Message Carbons
|
||||
* XEP-0308: Last Message Correction
|
||||
* XEP-0313: Message Archive Management
|
||||
* XEP-0319: Last User Interaction in Presence
|
||||
* XEP-0333: Chat Markers
|
||||
* XEP-0352: Client State Indication
|
||||
* XEP-0357: Push Notifications
|
||||
|
|
|
@ -34,7 +34,6 @@ public class Contact implements ListItem, Blockable {
|
|||
public static final String LAST_PRESENCE = "last_presence";
|
||||
public static final String LAST_TIME = "last_time";
|
||||
public static final String GROUPS = "groups";
|
||||
public Lastseen lastseen = new Lastseen();
|
||||
protected String accountUuid;
|
||||
protected String systemName;
|
||||
protected String serverName;
|
||||
|
@ -50,9 +49,14 @@ public class Contact implements ListItem, Blockable {
|
|||
protected Account account;
|
||||
protected Avatar avatar;
|
||||
|
||||
private boolean mActive = false;
|
||||
private long mLastseen = 0;
|
||||
private String mLastPresence = null;
|
||||
|
||||
public Contact(final String account, final String systemName, final String serverName,
|
||||
final Jid jid, final int subscription, final String photoUri,
|
||||
final String systemAccount, final String keys, final String avatar, final Lastseen lastseen, final String groups) {
|
||||
final String systemAccount, final String keys, final String avatar, final long lastseen,
|
||||
final String presence, final String groups) {
|
||||
this.accountUuid = account;
|
||||
this.systemName = systemName;
|
||||
this.serverName = serverName;
|
||||
|
@ -75,7 +79,8 @@ public class Contact implements ListItem, Blockable {
|
|||
} catch (JSONException e) {
|
||||
this.groups = new JSONArray();
|
||||
}
|
||||
this.lastseen = lastseen;
|
||||
this.mLastseen = lastseen;
|
||||
this.mLastPresence = presence;
|
||||
}
|
||||
|
||||
public Contact(final Jid jid) {
|
||||
|
@ -83,9 +88,6 @@ public class Contact implements ListItem, Blockable {
|
|||
}
|
||||
|
||||
public static Contact fromCursor(final Cursor cursor) {
|
||||
final Lastseen lastseen = new Lastseen(
|
||||
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
|
||||
cursor.getLong(cursor.getColumnIndex(LAST_TIME)));
|
||||
final Jid jid;
|
||||
try {
|
||||
jid = Jid.fromString(cursor.getString(cursor.getColumnIndex(JID)), true);
|
||||
|
@ -102,7 +104,8 @@ public class Contact implements ListItem, Blockable {
|
|||
cursor.getString(cursor.getColumnIndex(SYSTEMACCOUNT)),
|
||||
cursor.getString(cursor.getColumnIndex(KEYS)),
|
||||
cursor.getString(cursor.getColumnIndex(AVATAR)),
|
||||
lastseen,
|
||||
cursor.getLong(cursor.getColumnIndex(LAST_TIME)),
|
||||
cursor.getString(cursor.getColumnIndex(LAST_PRESENCE)),
|
||||
cursor.getString(cursor.getColumnIndex(GROUPS)));
|
||||
}
|
||||
|
||||
|
@ -197,8 +200,8 @@ public class Contact implements ListItem, Blockable {
|
|||
values.put(PHOTOURI, photoUri);
|
||||
values.put(KEYS, keys.toString());
|
||||
values.put(AVATAR, avatar == null ? null : avatar.getFilename());
|
||||
values.put(LAST_PRESENCE, lastseen.presence);
|
||||
values.put(LAST_TIME, lastseen.time);
|
||||
values.put(LAST_PRESENCE, mLastPresence);
|
||||
values.put(LAST_TIME, mLastseen);
|
||||
values.put(GROUPS, groups.toString());
|
||||
return values;
|
||||
}
|
||||
|
@ -517,18 +520,32 @@ public class Contact implements ListItem, Blockable {
|
|||
this.commonName = cn;
|
||||
}
|
||||
|
||||
public static class Lastseen {
|
||||
public long time;
|
||||
public String presence;
|
||||
|
||||
public Lastseen() {
|
||||
this(null, 0);
|
||||
public void flagActive() {
|
||||
this.mActive = true;
|
||||
}
|
||||
|
||||
public Lastseen(final String presence, final long time) {
|
||||
this.presence = presence;
|
||||
this.time = time;
|
||||
public void flagInactive() {
|
||||
this.mActive = false;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.mActive;
|
||||
}
|
||||
|
||||
public void setLastseen(long timestamp) {
|
||||
this.mLastseen = Math.max(timestamp, mLastseen);
|
||||
}
|
||||
|
||||
public long getLastseen() {
|
||||
return this.mLastseen;
|
||||
}
|
||||
|
||||
public void setLastPresence(String presence) {
|
||||
this.mLastPresence = presence;
|
||||
}
|
||||
|
||||
public String getLastPresence() {
|
||||
return this.mLastPresence;
|
||||
}
|
||||
|
||||
public final class Options {
|
||||
|
|
|
@ -16,8 +16,6 @@ import eu.siacs.conversations.Config;
|
|||
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
|
||||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.utils.PhoneHelper;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||
|
||||
public abstract class AbstractGenerator {
|
||||
private final String[] FEATURES = {
|
||||
|
@ -33,7 +31,8 @@ public abstract class AbstractGenerator {
|
|||
"http://jabber.org/protocol/nick+notify",
|
||||
"urn:xmpp:ping",
|
||||
"jabber:iq:version",
|
||||
"http://jabber.org/protocol/chatstates"};
|
||||
"http://jabber.org/protocol/chatstates"
|
||||
};
|
||||
private final String[] MESSAGE_CONFIRMATION_FEATURES = {
|
||||
"urn:xmpp:chat-markers:0",
|
||||
"urn:xmpp:receipts"
|
||||
|
@ -45,7 +44,7 @@ public abstract class AbstractGenerator {
|
|||
protected final String IDENTITY_NAME = "Conversations";
|
||||
protected final String IDENTITY_TYPE = "phone";
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
||||
|
||||
protected XmppConnectionService mXmppConnectionService;
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package eu.siacs.conversations.parser;
|
||||
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
|
@ -14,7 +12,6 @@ import eu.siacs.conversations.services.XmppConnectionService;
|
|||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
import eu.siacs.conversations.xmpp.stanzas.AbstractStanza;
|
||||
|
||||
public abstract class AbstractParser {
|
||||
|
||||
|
@ -24,42 +21,48 @@ public abstract class AbstractParser {
|
|||
this.mXmppConnectionService = service;
|
||||
}
|
||||
|
||||
public static Long getTimestamp(Element element, Long defaultValue) {
|
||||
public static Long parseTimestamp(Element element, Long d) {
|
||||
Element delay = element.findChild("delay","urn:xmpp:delay");
|
||||
if (delay != null) {
|
||||
String stamp = delay.getAttribute("stamp");
|
||||
if (stamp != null) {
|
||||
try {
|
||||
return AbstractParser.parseTimestamp(delay.getAttribute("stamp")).getTime();
|
||||
return AbstractParser.parseTimestamp(delay.getAttribute("stamp"));
|
||||
} catch (ParseException e) {
|
||||
return defaultValue;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
return d;
|
||||
}
|
||||
|
||||
protected long getTimestamp(Element packet) {
|
||||
return getTimestamp(packet,System.currentTimeMillis());
|
||||
public static long parseTimestamp(Element element) {
|
||||
return parseTimestamp(element, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static Date parseTimestamp(String timestamp) throws ParseException {
|
||||
public static long parseTimestamp(String timestamp) throws ParseException {
|
||||
timestamp = timestamp.replace("Z", "+0000");
|
||||
SimpleDateFormat dateFormat;
|
||||
long ms;
|
||||
if (timestamp.charAt(19) == '.' && timestamp.length() >= 25) {
|
||||
String millis = timestamp.substring(19,timestamp.length() - 5);
|
||||
try {
|
||||
double fractions = Double.parseDouble("0" + millis);
|
||||
ms = Math.round(1000 * fractions);
|
||||
} catch (NumberFormatException e) {
|
||||
ms = 0;
|
||||
}
|
||||
} else {
|
||||
ms = 0;
|
||||
}
|
||||
timestamp = timestamp.substring(0,19)+timestamp.substring(timestamp.length() -5,timestamp.length());
|
||||
dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",Locale.US);
|
||||
return dateFormat.parse(timestamp);
|
||||
return Math.min(dateFormat.parse(timestamp).getTime()+ms, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
protected void updateLastseen(long timestamp, final Account account, final Jid from) {
|
||||
final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart();
|
||||
protected void updateLastseen(final Account account, final Jid from) {
|
||||
final Contact contact = account.getRoster().getContact(from);
|
||||
if (timestamp >= contact.lastseen.time) {
|
||||
contact.lastseen.time = timestamp;
|
||||
if (!presence.isEmpty()) {
|
||||
contact.lastseen.presence = presence;
|
||||
}
|
||||
}
|
||||
contact.setLastPresence(from.isBareJid() ? "" : from.getResourcepart());
|
||||
}
|
||||
|
||||
protected String avatarData(Element items) {
|
||||
|
|
|
@ -7,12 +7,12 @@ import android.util.Pair;
|
|||
import net.java.otr4j.session.Session;
|
||||
import net.java.otr4j.session.SessionStatus;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -32,6 +32,7 @@ import eu.siacs.conversations.http.HttpConnectionManager;
|
|||
import eu.siacs.conversations.services.MessageArchiveService;
|
||||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.Xmlns;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xmpp.OnMessagePacketReceived;
|
||||
import eu.siacs.conversations.xmpp.chatstate.ChatState;
|
||||
|
@ -328,7 +329,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
|||
}
|
||||
|
||||
if (timestamp == null) {
|
||||
timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis());
|
||||
timestamp = AbstractParser.parseTimestamp(packet);
|
||||
}
|
||||
final String body = packet.getBody();
|
||||
final Element mucUserElement = packet.findChild("x", "http://jabber.org/protocol/muc#user");
|
||||
|
@ -439,7 +440,7 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
|||
message.setType(Message.TYPE_PRIVATE);
|
||||
}
|
||||
} else {
|
||||
updateLastseen(timestamp, account, from);
|
||||
updateLastseen(account, from);
|
||||
}
|
||||
|
||||
if (replacementId != null && mXmppConnectionService.allowMessageCorrection()) {
|
||||
|
@ -601,7 +602,6 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
|
|||
mXmppConnectionService.markRead(conversation);
|
||||
}
|
||||
} else {
|
||||
updateLastseen(timestamp, account, from);
|
||||
final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED);
|
||||
Message message = displayedMessage == null ? null : displayedMessage.prev();
|
||||
while (message != null
|
||||
|
|
|
@ -2,6 +2,7 @@ package eu.siacs.conversations.parser;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -206,6 +207,20 @@ public class PresenceParser extends AbstractParser implements
|
|||
mXmppConnectionService.fetchCaps(account, from, presence);
|
||||
}
|
||||
|
||||
final Element idle = packet.findChild("idle","urn:xmpp:idle:1");
|
||||
if (idle != null) {
|
||||
contact.flagInactive();
|
||||
String since = idle.getAttribute("since");
|
||||
try {
|
||||
contact.setLastseen(AbstractParser.parseTimestamp(since));
|
||||
} catch (NullPointerException | ParseException e) {
|
||||
contact.setLastseen(System.currentTimeMillis());
|
||||
}
|
||||
} else {
|
||||
contact.flagActive();
|
||||
contact.setLastseen(AbstractParser.parseTimestamp(packet));
|
||||
}
|
||||
|
||||
PgpEngine pgp = mXmppConnectionService.getPgpEngine();
|
||||
Element x = packet.findChild("x", "jabber:x:signed");
|
||||
if (pgp != null && x != null) {
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.os.FileObserver;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.SystemClock;
|
||||
|
@ -80,6 +79,7 @@ import eu.siacs.conversations.entities.Roster;
|
|||
import eu.siacs.conversations.entities.ServiceDiscoveryResult;
|
||||
import eu.siacs.conversations.entities.Transferable;
|
||||
import eu.siacs.conversations.entities.TransferablePlaceholder;
|
||||
import eu.siacs.conversations.generator.AbstractGenerator;
|
||||
import eu.siacs.conversations.generator.IqGenerator;
|
||||
import eu.siacs.conversations.generator.MessageGenerator;
|
||||
import eu.siacs.conversations.generator.PresenceGenerator;
|
||||
|
@ -141,6 +141,9 @@ public class XmppConnectionService extends Service {
|
|||
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
|
||||
private final IqGenerator mIqGenerator = new IqGenerator(this);
|
||||
private final List<String> mInProgressAvatarFetches = new ArrayList<>();
|
||||
|
||||
private long mLastActivity = 0;
|
||||
|
||||
public DatabaseBackend databaseBackend;
|
||||
private ContentObserver contactObserver = new ContentObserver(null) {
|
||||
@Override
|
||||
|
@ -1584,6 +1587,7 @@ public class XmppConnectionService extends Service {
|
|||
|
||||
public void setOnConversationListChangedListener(OnConversationUpdate listener) {
|
||||
synchronized (this) {
|
||||
this.mLastActivity = System.currentTimeMillis();
|
||||
if (checkListeners()) {
|
||||
switchToForeground();
|
||||
}
|
||||
|
@ -1796,22 +1800,29 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
|
||||
private void switchToForeground() {
|
||||
final boolean broadcastLastActivity = broadcastLastActivity();
|
||||
for (Conversation conversation : getConversations()) {
|
||||
conversation.setIncomingChatState(ChatState.ACTIVE);
|
||||
}
|
||||
for (Account account : getAccounts()) {
|
||||
if (account.getStatus() == Account.State.ONLINE) {
|
||||
account.deactivateGracePeriod();
|
||||
XmppConnection connection = account.getXmppConnection();
|
||||
if (connection != null && connection.getFeatures().csi()) {
|
||||
final XmppConnection connection = account.getXmppConnection();
|
||||
if (connection != null ) {
|
||||
if (connection.getFeatures().csi()) {
|
||||
connection.sendActive();
|
||||
}
|
||||
if (broadcastLastActivity) {
|
||||
sendPresence(account, false); //send new presence but don't include idle because we are not
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(Config.LOGTAG, "app switched into foreground");
|
||||
}
|
||||
|
||||
private void switchToBackground() {
|
||||
final boolean broadcastLastActivity = broadcastLastActivity();
|
||||
for (Account account : getAccounts()) {
|
||||
if (account.getStatus() == Account.State.ONLINE) {
|
||||
XmppConnection connection = account.getXmppConnection();
|
||||
|
@ -1819,6 +1830,9 @@ public class XmppConnectionService extends Service {
|
|||
if (connection.getFeatures().csi()) {
|
||||
connection.sendInactive();
|
||||
}
|
||||
if (broadcastLastActivity) {
|
||||
sendPresence(account, broadcastLastActivity);
|
||||
}
|
||||
if (Config.CLOSE_TCP_WHEN_SWITCHING_TO_BACKGROUND && mPushManagementService.available(account)) {
|
||||
connection.waitForPush();
|
||||
cancelWakeUpCall(account.getUuid().hashCode());
|
||||
|
@ -2253,6 +2267,7 @@ public class XmppConnectionService extends Service {
|
|||
private void disconnect(Account account, boolean force) {
|
||||
if ((account.getStatus() == Account.State.ONLINE)
|
||||
|| (account.getStatus() == Account.State.DISABLED)) {
|
||||
final XmppConnection connection = account.getXmppConnection();
|
||||
if (!force) {
|
||||
List<Conversation> conversations = getConversations();
|
||||
for (Conversation conversation : conversations) {
|
||||
|
@ -2270,7 +2285,7 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
sendOfflinePresence(account);
|
||||
}
|
||||
account.getXmppConnection().disconnect(force);
|
||||
connection.disconnect(force);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2814,6 +2829,10 @@ public class XmppConnectionService extends Service {
|
|||
return getPreferences().getBoolean("show_connection_options", false);
|
||||
}
|
||||
|
||||
public boolean broadcastLastActivity() {
|
||||
return getPreferences().getBoolean("last_activity", false);
|
||||
}
|
||||
|
||||
public int unreadCount() {
|
||||
int count = 0;
|
||||
for (Conversation conversation : getConversations()) {
|
||||
|
@ -3052,6 +3071,10 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
|
||||
public void sendPresence(final Account account) {
|
||||
sendPresence(account, checkListeners() && broadcastLastActivity());
|
||||
}
|
||||
|
||||
private void sendPresence(final Account account, final boolean includeIdleTimestamp) {
|
||||
PresencePacket packet;
|
||||
if (manuallyChangePresence()) {
|
||||
packet = mPresenceGenerator.selfPresence(account, account.getPresenceStatus());
|
||||
|
@ -3062,6 +3085,10 @@ public class XmppConnectionService extends Service {
|
|||
} else {
|
||||
packet = mPresenceGenerator.selfPresence(account, getTargetPresence());
|
||||
}
|
||||
if (mLastActivity > 0 && includeIdleTimestamp) {
|
||||
long since = Math.min(mLastActivity, System.currentTimeMillis()); //don't send future dates
|
||||
packet.addChild("idle","urn:xmpp:idle:1").setAttribute("since", AbstractGenerator.getTimestamp(since));
|
||||
}
|
||||
sendPresencePacket(account, packet);
|
||||
}
|
||||
|
||||
|
@ -3072,9 +3099,10 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
|
||||
public void refreshAllPresences() {
|
||||
boolean includeIdleTimestamp = checkListeners() && broadcastLastActivity();
|
||||
for (Account account : getAccounts()) {
|
||||
if (!account.isOptionSet(Account.OPTION_DISABLED)) {
|
||||
sendPresence(account);
|
||||
sendPresence(account, includeIdleTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
|||
}
|
||||
};
|
||||
private Jid accountJid;
|
||||
private TextView lastseen;
|
||||
private Jid contactJid;
|
||||
private TextView contactJidTv;
|
||||
private TextView accountJidTv;
|
||||
|
@ -114,7 +115,8 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
|||
private QuickContactBadge badge;
|
||||
private LinearLayout keys;
|
||||
private LinearLayout tags;
|
||||
private boolean showDynamicTags;
|
||||
private boolean showDynamicTags = false;
|
||||
private boolean showLastSeen = false;
|
||||
private String messageFingerprint;
|
||||
|
||||
private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() {
|
||||
|
@ -203,6 +205,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
|||
|
||||
contactJidTv = (TextView) findViewById(R.id.details_contactjid);
|
||||
accountJidTv = (TextView) findViewById(R.id.details_account);
|
||||
lastseen = (TextView) findViewById(R.id.details_lastseen);
|
||||
statusMessage = (TextView) findViewById(R.id.status_message);
|
||||
send = (CheckBox) findViewById(R.id.details_send_presence);
|
||||
receive = (CheckBox) findViewById(R.id.details_receive_presence);
|
||||
|
@ -220,9 +223,14 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
|||
getActionBar().setHomeButtonEnabled(true);
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.showDynamicTags = preferences.getBoolean("show_dynamic_tags",false);
|
||||
this.showLastSeen = preferences.getBoolean("last_activity", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -371,6 +379,18 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd
|
|||
statusMessage.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (contact.isBlocked() && !this.showDynamicTags) {
|
||||
lastseen.setVisibility(View.VISIBLE);
|
||||
lastseen.setText(R.string.contact_blocked);
|
||||
} else {
|
||||
if (showLastSeen && contact.getLastseen() > 0) {
|
||||
lastseen.setVisibility(View.VISIBLE);
|
||||
lastseen.setText(UIHelper.lastseen(getApplicationContext(), contact.isActive(), contact.getLastseen()));
|
||||
} else {
|
||||
lastseen.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (contact.getPresences().size() > 1) {
|
||||
contactJidTv.setText(contact.getDisplayJid() + " ("
|
||||
+ contact.getPresences().size() + ")");
|
||||
|
|
|
@ -162,7 +162,8 @@ public class SettingsActivity extends XmppActivity implements
|
|||
"away_when_screen_off",
|
||||
"allow_message_correction",
|
||||
"treat_vibrate_as_silent",
|
||||
"manually_change_presence");
|
||||
"manually_change_presence",
|
||||
"last_activity");
|
||||
if (name.equals("resource")) {
|
||||
String resource = preferences.getString("resource", "mobile")
|
||||
.toLowerCase(Locale.US);
|
||||
|
|
|
@ -912,7 +912,7 @@ public abstract class XmppActivity extends Activity {
|
|||
final String[] presencesArray = presences.asStringArray();
|
||||
int preselectedPresence = 0;
|
||||
for (int i = 0; i < presencesArray.length; ++i) {
|
||||
if (presencesArray[i].equals(contact.lastseen.presence)) {
|
||||
if (presencesArray[i].equals(contact.getLastPresence())) {
|
||||
preselectedPresence = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -107,12 +107,10 @@ public class UIHelper {
|
|||
.get(Calendar.DAY_OF_YEAR);
|
||||
}
|
||||
|
||||
public static String lastseen(Context context, long time) {
|
||||
if (time == 0) {
|
||||
return context.getString(R.string.never_seen);
|
||||
}
|
||||
public static String lastseen(Context context, boolean active, long time) {
|
||||
long difference = (System.currentTimeMillis() - time) / 1000;
|
||||
if (difference < 60) {
|
||||
active = active && difference <= 300;
|
||||
if (active || difference < 60) {
|
||||
return context.getString(R.string.last_seen_now);
|
||||
} else if (difference < 60 * 2) {
|
||||
return context.getString(R.string.last_seen_min);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
|
||||
public final class Xmlns {
|
||||
public static final String BLOCKING = "urn:xmpp:blocking";
|
||||
public static final String ROSTER = "jabber:iq:roster";
|
||||
|
|
|
@ -83,7 +83,7 @@ public class MessagePacket extends AbstractAcknowledgeableStanza {
|
|||
if (packet == null) {
|
||||
return null;
|
||||
}
|
||||
Long timestamp = AbstractParser.getTimestamp(forwarded,null);
|
||||
Long timestamp = AbstractParser.parseTimestamp(forwarded, null);
|
||||
return new Pair(packet,timestamp);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,12 +53,20 @@
|
|||
android:orientation="horizontal">
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/details_lastseen"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black54"
|
||||
android:textSize="?attr/TextSizeBody" />
|
||||
|
||||
<TextView
|
||||
android:layout_marginTop="8dp"
|
||||
android:id="@+id/status_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/black54"
|
||||
android:textColor="@color/black87"
|
||||
android:textStyle="italic"
|
||||
android:textSize="?attr/TextSizeBody" />
|
||||
|
||||
|
|
|
@ -653,4 +653,7 @@
|
|||
<string name="gp_short">Short</string>
|
||||
<string name="gp_medium">Medium</string>
|
||||
<string name="gp_long">Long</string>
|
||||
<string name="pref_broadcast_last_activity">Broadcast last activity</string>
|
||||
<string name="pref_broadcast_last_activity_summary">Let all your contacts know when use Conversations</string>
|
||||
<string name="pref_privacy">Privacy</string>
|
||||
</resources>
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
android:key="resource"
|
||||
android:summary="@string/pref_xmpp_resource_summary"
|
||||
android:title="@string/pref_xmpp_resource"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/pref_privacy">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="confirm_messages"
|
||||
|
@ -26,11 +28,13 @@
|
|||
android:key="chat_states"
|
||||
android:summary="@string/pref_chat_states_summary"
|
||||
android:title="@string/pref_chat_states"/>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="last_activity"
|
||||
android:title="@string/pref_broadcast_last_activity"
|
||||
android:summary="@string/pref_broadcast_last_activity_summary"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="notifications"
|
||||
android:title="@string/pref_notification_settings">
|
||||
<PreferenceCategory android:title="@string/pref_notification_settings">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="show_notification"
|
||||
|
@ -88,8 +92,7 @@
|
|||
android:entryValues="@array/grace_periods_values"
|
||||
/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:title="@string/pref_attachments">
|
||||
<PreferenceCategory android:title="@string/pref_attachments">
|
||||
<ListPreference
|
||||
android:defaultValue="524288"
|
||||
android:entries="@array/filesizes"
|
||||
|
|
Loading…
Reference in New Issue