From b688a2e5182fa62d5edd8b2087a14804a156c190 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Fri, 23 Jan 2015 12:48:21 +0300
Subject: [PATCH] improved libappindicator load, making user online for some
 time after incoming msg

---
 Telegram/SourceFiles/app.cpp             |   8 +-
 Telegram/SourceFiles/config.h            |   2 +
 Telegram/SourceFiles/history.cpp         |  23 +----
 Telegram/SourceFiles/pspecific_linux.cpp | 114 ++++++++++-------------
 4 files changed, 60 insertions(+), 87 deletions(-)

diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index bab7871c8..254857e9f 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -193,7 +193,10 @@ namespace App {
 	}
 
 	int32 onlineWillChangeIn(int32 online, int32 now) {
-		if (online <= 0) return 86400;
+        if (online <= 0) {
+            if (-online > now) return -online - now;
+            return 86400;
+        }
 		if (online > now) {
 			return online - now;
 		}
@@ -217,11 +220,12 @@ namespace App {
 		if (online <= 0) {
 			switch (online) {
 			case 0: return lang(lng_status_offline);
+            case -1: return lang(lng_status_invisible);
 			case -2: return lang(lng_status_recently);
 			case -3: return lang(lng_status_last_week);
 			case -4: return lang(lng_status_last_month);
 			}
-			return lang(lng_status_invisible);
+            return (-online > now) ? lang(lng_status_online) : lang(lng_status_recently);
 		}
 		if (online > now) {
 			return lang(lng_status_online);
diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h
index cc85ebb17..98bb77fba 100644
--- a/Telegram/SourceFiles/config.h
+++ b/Telegram/SourceFiles/config.h
@@ -113,6 +113,8 @@ enum {
 	SaveDraftTimeout = 1000, // save draft after 1 secs of not changing text
 	SaveDraftAnywayTimeout = 5000, // or save anyway each 5 secs
 
+    HiddenIsOnlineAfterMessage = 60, // user with hidden last seen stays online for such amount of seconds in the interface
+
 	ServiceUserId = 777000,
 };
 
diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp
index 6a687c261..01b08fe28 100644
--- a/Telegram/SourceFiles/history.cpp
+++ b/Telegram/SourceFiles/history.cpp
@@ -1182,26 +1182,6 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) {
 	return h.value()->addToBack(msg, msgState > 0);
 }
 
-/*
-HistoryItem *Histories::addToBack(const MTPgeoChatMessage &msg, bool newMsg) {
-	PeerId peer = 0;
-	switch (msg.type()) {
-	case mtpc_geoChatMessage:
-		peer = App::peerFromChat(msg.c_geoChatMessage().vchat_id);
-	break;
-	case mtpc_geoChatMessageService:
-		peer = App::peerFromChat(msg.c_geoChatMessageService().vchat_id);
-	break;
-	}
-	if (!peer) return 0;
-
-	iterator h = find(peer);
-	if (h == end()) {
-		h = insert(peer, new History(peer));
-	}
-	return h.value()->addToBack(msg, newMsg);
-}/**/
-
 HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, bool newMsg, bool returnExisting) {
 	HistoryItem *result = 0;
 
@@ -1423,6 +1403,9 @@ void History::newItemAdded(HistoryItem *item) {
 	App::checkImageCacheSize();
 	if (item->from()) {
 		unregTyping(item->from());
+        if (item->from()->onlineTill < 0) {
+            item->from()->onlineTill = -unixtime() - HiddenIsOnlineAfterMessage;
+        }
 	}
 	if (item->out()) {
 		if (unreadBar) unreadBar->destroy();
diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp
index b1b104a64..19dabd38b 100644
--- a/Telegram/SourceFiles/pspecific_linux.cpp
+++ b/Telegram/SourceFiles/pspecific_linux.cpp
@@ -43,7 +43,7 @@ extern "C" {
 namespace {
 	bool frameless = true;
 	bool finished = true;
-    bool useAppIndicator = false, useStatusIcon = false, trayIconChecked = false, useUnityCount = false;
+    bool useGtkBase = false, useAppIndicator = false, useStatusIcon = false, trayIconChecked = false, useUnityCount = false;
 
     AppIndicator *_trayIndicator = 0;
     GtkStatusIcon *_trayIcon = 0;
@@ -325,35 +325,25 @@ namespace {
     class _PsInitializer {
     public:
         _PsInitializer() {
-            setupGTK();
+            setupGtk();
             setupUnity();
         }
-        void setupGTK() {
-            int useversion = 3;
-            QLibrary lib_gtk(QLatin1String("gtk-3"), 0, 0), lib_indicator(QLatin1String("appindicator3"), 1, 0);
-            if (lib_gtk.load()) {
-                _initLogs.push_back(QString("Loaded 'gtk-3' version 0 library, will try appindicator3 lib"));
-            } else {
-                lib_gtk.setFileNameAndVersion(QLatin1String("gtk-3"), QString());
-                if (lib_gtk.load()) {
-                    _initLogs.push_back(QString("Loaded 'gtk-3' without version library, will try appindicator3 lib"));
-                } else {
-                    useversion = 2;
-                    lib_gtk.setFileNameAndVersion(QLatin1String("gtk-x11-2.0"), 0);
-                    if (lib_gtk.load()) {
-                        _initLogs.push_back(QString("Loaded 'gtk-x11-2.0' version 0 library, will try appindicator lib"));
-                    } else {
-                        lib_gtk.setFileNameAndVersion(QLatin1String("gtk-x11-2.0"), QString());
-                        if (lib_gtk.load()) {
-                            _initLogs.push_back(QString("Loaded 'gtk-x11-2.0' without version library, will try appindicator lib"));
-                        } else {
-                            _initLogs.push_back(QString("Init Error: Failed to load 'gtk-x11-2.0' library!"));
-                            return;
-                        }
-                    }
-                }
-            }
 
+        bool loadLibrary(QLibrary &lib, const char *name, int version) {
+            lib.setFileNameAndVersion(QLatin1String(name), version);
+            if (lib.load()) {
+                _initLogs.push_back(QString("Loaded '%1' version %2 library").arg(name).arg(version));
+                return true;
+            }
+            lib.setFileNameAndVersion(QLatin1String(name), QString());
+            if (lib.load()) {
+                _initLogs.push_back(QString("Loaded '%1' without version library").arg(name));
+                return true;
+            }
+            return false;
+        }
+
+        void setupGtkBase(QLibrary &lib_gtk) {
             if (!loadFunction(lib_gtk, "gtk_init_check", ps_gtk_init_check)) return;
             if (!loadFunction(lib_gtk, "gtk_menu_new", ps_gtk_menu_new)) return;
             if (!loadFunction(lib_gtk, "gtk_menu_get_type", ps_gtk_menu_get_type)) return;
@@ -370,31 +360,41 @@ namespace {
             if (!loadFunction(lib_gtk, "g_type_check_instance_cast", ps_g_type_check_instance_cast)) return;
             if (!loadFunction(lib_gtk, "g_signal_connect_data", ps_g_signal_connect_data)) return;
 
-            if (useversion == 3 && lib_indicator.load()) {
-                _initLogs.push_back(QString("Loaded 'appindicator3' version 1 library"));
-                setupAppIndicator(lib_indicator);
-            } else {
-                lib_indicator.setFileNameAndVersion(QLatin1String("appindicator3"), QString());
-                if (useversion == 3 && lib_indicator.load()) {
-                    _initLogs.push_back(QString("Loaded 'appindicator3' without version library"));
+            useGtkBase = true;
+        }
+
+        void setupAppIndicator(QLibrary &lib_indicator) {
+            if (!loadFunction(lib_indicator, "app_indicator_new", ps_app_indicator_new)) return;
+            if (!loadFunction(lib_indicator, "app_indicator_set_status", ps_app_indicator_set_status)) return;
+            if (!loadFunction(lib_indicator, "app_indicator_set_menu", ps_app_indicator_set_menu)) return;
+            if (!loadFunction(lib_indicator, "app_indicator_set_icon_full", ps_app_indicator_set_icon_full)) return;
+            useAppIndicator = true;
+        }
+
+        void setupGtk() {
+            QLibrary lib_gtk, lib_indicator;
+            if (loadLibrary(lib_gtk, "gtk-3", 0)) {
+                if (loadLibrary(lib_indicator, "appindicator3", 1)) {
+                    setupGtkBase(lib_gtk);
                     setupAppIndicator(lib_indicator);
-                } else {
-                    lib_indicator.setFileNameAndVersion(QLatin1String("appindicator"), 1);
-                    if (useversion == 2 && lib_indicator.load()) {
-                        _initLogs.push_back(QString("Loaded 'appindicator' version 1 library"));
+                }
+            }
+            if (!useGtkBase || !useAppIndicator) {
+                if (lib_gtk.isLoaded()) lib_gtk.unload();
+                if (lib_indicator.isLoaded()) lib_indicator.unload();
+                if (loadLibrary(lib_gtk, "gtk-x11-2.0", 0)) {
+                    if (loadLibrary(lib_indicator, "appindicator", 1)) {
+                        useGtkBase = useAppIndicator = false;
+                        setupGtkBase(lib_gtk);
                         setupAppIndicator(lib_indicator);
-                    } else {
-                        lib_indicator.setFileNameAndVersion(QLatin1String("appindicator"), QString());
-                        if (useversion == 2 && lib_indicator.load()) {
-                            _initLogs.push_back(QString("Loaded 'appindicator' without version library"));
-                            setupAppIndicator(lib_indicator);
-                        } else {
-                            _initLogs.push_back(QString("Failed to load 'appindicator' library!"));
-                            return;
-                        }
                     }
                 }
             }
+            if (!useGtkBase) {
+                useAppIndicator = false;
+                _initLogs.push_back(QString("Init Error: Failed to load 'gtk-x11-2.0' library!"));
+                return;
+            }
 
             if (!loadFunction(lib_gtk, "gdk_init_check", ps_gdk_init_check)) return;
             if (!loadFunction(lib_gtk, "gdk_pixbuf_new_from_data", ps_gdk_pixbuf_new_from_data)) return;
@@ -413,26 +413,10 @@ namespace {
             if (!loadFunction(lib_gtk, "g_idle_add", ps_g_idle_add)) return;
             useStatusIcon = true;
         }
-        void setupAppIndicator(QLibrary &lib_indicator) {
-            if (!loadFunction(lib_indicator, "app_indicator_new", ps_app_indicator_new)) return;
-            if (!loadFunction(lib_indicator, "app_indicator_set_status", ps_app_indicator_set_status)) return;
-            if (!loadFunction(lib_indicator, "app_indicator_set_menu", ps_app_indicator_set_menu)) return;
-            if (!loadFunction(lib_indicator, "app_indicator_set_icon_full", ps_app_indicator_set_icon_full)) return;
-            useAppIndicator = true;
-        }
+
         void setupUnity() {
             QLibrary lib_unity(QLatin1String("unity"), 9, 0);
-            if (lib_unity.load()) {
-                _initLogs.push_back(QString("Loaded 'unity' version 9 library"));
-            } else {
-                lib_unity.setFileNameAndVersion(QLatin1String("unity"), QString());
-                if (lib_unity.load()) {
-                    _initLogs.push_back(QString("Loaded 'unity' without version library"));
-                } else {
-                    _initLogs.push_back(QString("Init Error: Failed to load 'unity' library!"));
-                    return;
-                }
-            }
+            if (!loadLibrary(lib_unity, "unity", 9)) return;
 
             if (!loadFunction(lib_unity, "unity_launcher_entry_get_for_desktop_id", ps_unity_launcher_entry_get_for_desktop_id)) return;
             if (!loadFunction(lib_unity, "unity_launcher_entry_set_count", ps_unity_launcher_entry_set_count)) return;