[Core] Versioning and updater
This commit is contained in:
		
							parent
							
								
									e978824912
								
							
						
					
					
						commit
						5e04b5c995
					
				
					 23 changed files with 558 additions and 86 deletions
				
			
		| 
						 | 
				
			
			@ -775,6 +775,7 @@ PRIVATE
 | 
			
		|||
    intro/intro_widget.h
 | 
			
		||||
    kotato/kotato_lang.cpp
 | 
			
		||||
    kotato/kotato_lang.h
 | 
			
		||||
    kotato/kotato_version.h
 | 
			
		||||
    lang/lang_cloud_manager.cpp
 | 
			
		||||
    lang/lang_cloud_manager.h
 | 
			
		||||
    lang/lang_instance.cpp
 | 
			
		||||
| 
						 | 
				
			
			@ -1516,7 +1517,7 @@ if ((NOT DESKTOP_APP_DISABLE_AUTOUPDATE OR APPLE) AND NOT build_macstore AND NOT
 | 
			
		|||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    if (DESKTOP_APP_SPECIAL_TARGET)
 | 
			
		||||
    if (DESKTOP_APP_SPECIAL_TARGET OR KTGDESKTOP_ENABLE_PACKER)
 | 
			
		||||
        add_executable(Packer)
 | 
			
		||||
        init_target(Packer)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
	"ktg_about_text1_tdesktop": "Telegram Desktop",
 | 
			
		||||
	"ktg_about_text3": "Visit {channel_link} or {faq_link} for more info.",
 | 
			
		||||
	"ktg_about_text3_channel": "Kotatogram channel",
 | 
			
		||||
	"ktg_new_version": "Kotatogram Desktop has been updated to {version} (TD {td_version})\n\nFull version history is available here:\n{link}",
 | 
			
		||||
	"ktg_open_from_tray": "Open Kotatogram",
 | 
			
		||||
	"ktg_quit_from_tray": "Quit Kotatogram",
 | 
			
		||||
	"ktg_tray_icon_text": "Kotatogram is still running here,\nyou can change this from settings page.\nIf this icon disappears from tray menu,\nyou can drag it here from hidden icons.",
 | 
			
		||||
| 
						 | 
				
			
			@ -25,5 +26,6 @@
 | 
			
		|||
	"ktg_outdated_soon": "Otherwise, Kotatogram Desktop will stop updating on {date}.",
 | 
			
		||||
	"ktg_outdated_now": "So that Kotatogram Desktop can update to newer versions.",
 | 
			
		||||
	"ktg_mac_menu_show": "Show Kotatogram",
 | 
			
		||||
	"ktg_in_app_update_disabled": "In-app updater is disabled.",
 | 
			
		||||
	"dummy_last_string": ""
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,17 +19,17 @@ bool OnlyAlphaKey = false;
 | 
			
		|||
 | 
			
		||||
const char *PublicKey = "\
 | 
			
		||||
-----BEGIN RSA PUBLIC KEY-----\n\
 | 
			
		||||
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
 | 
			
		||||
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
 | 
			
		||||
+9PKKlb8mmr3BB9A45ZNwLT6G9AK3+qkZLHojeSA+m84/a6GP4svAgMBAAE=\n\
 | 
			
		||||
MIGJAoGBALUEi8NQfcq/GToD5CdgdNhgj2at2nusoWsHuUdIOGEOehpt2PiQlzt+\n\
 | 
			
		||||
qziKJDO8+tPnQV0Nzq6UqZXA0eCT4CvP2jZyLq/xnNzlinQXT+wPu2wqBabRTfoC\n\
 | 
			
		||||
TIiLseFjv2zEsXCCkhiaUfAtU3w09yw0/D8vl1/5+N/4mpAic+0VAgMBAAE=\n\
 | 
			
		||||
-----END RSA PUBLIC KEY-----\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
const char *PublicBetaKey = "\
 | 
			
		||||
-----BEGIN RSA PUBLIC KEY-----\n\
 | 
			
		||||
MIGJAoGBALWu9GGs0HED7KG7BM73CFZ6o0xufKBRQsdnq3lwA8nFQEvmdu+g/I1j\n\
 | 
			
		||||
0LQ+0IQO7GW4jAgzF/4+soPDb6uHQeNFrlVx1JS9DZGhhjZ5rf65yg11nTCIHZCG\n\
 | 
			
		||||
w/CVnbwQOw0g5GBwwFV3r0uTTvy44xx8XXxk+Qknu4eBCsmrAFNnAgMBAAE=\n\
 | 
			
		||||
MIGJAoGBAPgjMkWHsxk1d4NcPC5jyPlEddvOdl3yH+s8xpm8MxCVwhWu5dazkC0Z\n\
 | 
			
		||||
v1/0UnkegO4jNkSY3ycDqn+T3NjxNxnL0EsKh7MjinyMUe3ZISzaIyrdq/8v4bvB\n\
 | 
			
		||||
/Z1X5Ruw2HacoWo/EVsXY9zCTrY53IRrKy4HQbCOloK2+TBimyX5AgMBAAE=\n\
 | 
			
		||||
-----END RSA PUBLIC KEY-----\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -187,10 +187,12 @@ int main(int argc, char *argv[])
 | 
			
		|||
			AlphaVersion = QString(argv[i + 1]).toULongLong();
 | 
			
		||||
			if (AlphaVersion > version * 1000ULL && AlphaVersion < (version + 1) * 1000ULL) {
 | 
			
		||||
				BetaChannel = false;
 | 
			
		||||
				/*
 | 
			
		||||
				AlphaSignature = countAlphaVersionSignature(AlphaVersion);
 | 
			
		||||
				if (AlphaSignature.isEmpty()) {
 | 
			
		||||
					return -1;
 | 
			
		||||
				}
 | 
			
		||||
				*/
 | 
			
		||||
			} else {
 | 
			
		||||
				cout << "Bad -alpha param value passed, should be for the same version: " << version << ", alpha: " << AlphaVersion << "\n";
 | 
			
		||||
				return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -507,9 +509,11 @@ int main(int argc, char *argv[])
 | 
			
		|||
#else
 | 
			
		||||
#error Unknown platform!
 | 
			
		||||
#endif
 | 
			
		||||
	/*
 | 
			
		||||
	if (AlphaVersion) {
 | 
			
		||||
		outName += "_" + AlphaSignature;
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
	QFile out(outName);
 | 
			
		||||
	if (!out.open(QIODevice::WriteOnly)) {
 | 
			
		||||
		cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "boxes/about_box.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "kotato/kotato_lang.h"
 | 
			
		||||
#include "lang/lang_keys.h"
 | 
			
		||||
#include "lang/lang_instance.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +113,7 @@ void AboutBox::resizeEvent(QResizeEvent *e) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void AboutBox::showVersionHistory() {
 | 
			
		||||
	/*
 | 
			
		||||
	if (cRealAlphaVersion()) {
 | 
			
		||||
		auto url = qsl("https://tdesktop.com/");
 | 
			
		||||
		if (Platform::IsWindows32Bit()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -132,8 +134,11 @@ void AboutBox::showVersionHistory() {
 | 
			
		|||
		Ui::show(Box<Ui::InformBox>("The link to the current private alpha "
 | 
			
		||||
			"version of Telegram Desktop was copied to the clipboard."));
 | 
			
		||||
	} else {
 | 
			
		||||
	*/
 | 
			
		||||
		UrlClickHandler::Open(Core::App().changelogLink());
 | 
			
		||||
	/*
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AboutBox::keyPressEvent(QKeyEvent *e) {
 | 
			
		||||
| 
						 | 
				
			
			@ -162,14 +167,15 @@ QString telegramFaqLink() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
QString currentVersionText() {
 | 
			
		||||
	auto result = QString::fromLatin1(AppVersionStr);
 | 
			
		||||
	auto result = QString::fromLatin1(AppKotatoVersionStr);
 | 
			
		||||
	if (cAlphaVersion()) {
 | 
			
		||||
		result += qsl(" alpha %1").arg(cAlphaVersion() % 1000);
 | 
			
		||||
	} else if (AppBetaVersion) {
 | 
			
		||||
		result += qsl("-%1.%2").arg(AppKotatoTestBranch).arg(AppKotatoTestVersion);
 | 
			
		||||
	} else if (AppKotatoBetaVersion) {
 | 
			
		||||
		result += " beta";
 | 
			
		||||
	}
 | 
			
		||||
	if (Platform::IsWindows64Bit()) {
 | 
			
		||||
		result += " x64";
 | 
			
		||||
	}
 | 
			
		||||
	result += qsl(" (TD %1)").arg(AppVersionStr);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "boxes/phone_banned_box.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "ui/boxes/confirm_box.h"
 | 
			
		||||
#include "core/click_handler_types.h" // UrlClickHandler
 | 
			
		||||
#include "base/qthelp_url.h" // qthelp::url_encode
 | 
			
		||||
| 
						 | 
				
			
			@ -19,10 +20,10 @@ namespace Ui {
 | 
			
		|||
namespace {
 | 
			
		||||
 | 
			
		||||
void SendToBannedHelp(const QString &phone) {
 | 
			
		||||
	const auto version = QString::fromLatin1(AppVersionStr)
 | 
			
		||||
	const auto version = QString::fromLatin1(AppKotatoVersionStr)
 | 
			
		||||
		+ (cAlphaVersion()
 | 
			
		||||
			? qsl(" alpha %1").arg(cAlphaVersion())
 | 
			
		||||
			: (AppBetaVersion ? " beta" : ""));
 | 
			
		||||
			? qsl("-%1.%2").arg(AppKotatoTestBranch).arg(AppKotatoTestVersion)
 | 
			
		||||
			: (AppKotatoBetaVersion ? " beta" : ""));
 | 
			
		||||
 | 
			
		||||
	const auto subject = qsl("Banned phone number: ") + phone;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,17 +54,17 @@ inline const char *cGUIDStr() {
 | 
			
		|||
 | 
			
		||||
static const char *UpdatesPublicKey = "\
 | 
			
		||||
-----BEGIN RSA PUBLIC KEY-----\n\
 | 
			
		||||
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
 | 
			
		||||
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
 | 
			
		||||
+9PKKlb8mmr3BB9A45ZNwLT6G9AK3+qkZLHojeSA+m84/a6GP4svAgMBAAE=\n\
 | 
			
		||||
MIGJAoGBALUEi8NQfcq/GToD5CdgdNhgj2at2nusoWsHuUdIOGEOehpt2PiQlzt+\n\
 | 
			
		||||
qziKJDO8+tPnQV0Nzq6UqZXA0eCT4CvP2jZyLq/xnNzlinQXT+wPu2wqBabRTfoC\n\
 | 
			
		||||
TIiLseFjv2zEsXCCkhiaUfAtU3w09yw0/D8vl1/5+N/4mpAic+0VAgMBAAE=\n\
 | 
			
		||||
-----END RSA PUBLIC KEY-----\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
static const char *UpdatesPublicBetaKey = "\
 | 
			
		||||
-----BEGIN RSA PUBLIC KEY-----\n\
 | 
			
		||||
MIGJAoGBALWu9GGs0HED7KG7BM73CFZ6o0xufKBRQsdnq3lwA8nFQEvmdu+g/I1j\n\
 | 
			
		||||
0LQ+0IQO7GW4jAgzF/4+soPDb6uHQeNFrlVx1JS9DZGhhjZ5rf65yg11nTCIHZCG\n\
 | 
			
		||||
w/CVnbwQOw0g5GBwwFV3r0uTTvy44xx8XXxk+Qknu4eBCsmrAFNnAgMBAAE=\n\
 | 
			
		||||
MIGJAoGBAPgjMkWHsxk1d4NcPC5jyPlEddvOdl3yH+s8xpm8MxCVwhWu5dazkC0Z\n\
 | 
			
		||||
v1/0UnkegO4jNkSY3ycDqn+T3NjxNxnL0EsKh7MjinyMUe3ZISzaIyrdq/8v4bvB\n\
 | 
			
		||||
/Z1X5Ruw2HacoWo/EVsXY9zCTrY53IRrKy4HQbCOloK2+TBimyX5AgMBAAE=\n\
 | 
			
		||||
-----END RSA PUBLIC KEY-----\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "core/changelogs.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_lang.h"
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "storage/localstorage.h"
 | 
			
		||||
#include "lang/lang_keys.h"
 | 
			
		||||
#include "lang/lang_instance.h"
 | 
			
		||||
#include "core/application.h"
 | 
			
		||||
#include "main/main_domain.h"
 | 
			
		||||
#include "main/main_session.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -84,14 +88,18 @@ std::map<int, const char*> BetaLogs() {
 | 
			
		|||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
Changelogs::Changelogs(not_null<Main::Session*> session, int oldVersion)
 | 
			
		||||
Changelogs::Changelogs(not_null<Main::Session*> session, int oldVersion, int oldKotatoVersion)
 | 
			
		||||
: _session(session)
 | 
			
		||||
, _oldVersion(oldVersion) {
 | 
			
		||||
, _oldVersion(oldVersion)
 | 
			
		||||
, _oldKotatoVersion(oldKotatoVersion) {
 | 
			
		||||
 | 
			
		||||
	LOG(("Previous Kotatogram version: %1").arg(_oldKotatoVersion));
 | 
			
		||||
 | 
			
		||||
	_session->data().chatsListChanges(
 | 
			
		||||
	) | rpl::filter([](Data::Folder *folder) {
 | 
			
		||||
		return !folder;
 | 
			
		||||
	}) | rpl::start_with_next([=] {
 | 
			
		||||
		requestCloudLogs();
 | 
			
		||||
		addKotatoLogs();
 | 
			
		||||
	}, _chatsSubscription);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -99,12 +107,42 @@ std::unique_ptr<Changelogs> Changelogs::Create(
 | 
			
		|||
		not_null<Main::Session*> session) {
 | 
			
		||||
	auto &local = Core::App().domain().local();
 | 
			
		||||
	const auto oldVersion = local.oldVersion();
 | 
			
		||||
	const auto oldKotatoVersion = Local::oldKotatoVersion();
 | 
			
		||||
	local.clearOldVersion();
 | 
			
		||||
	return (oldVersion > 0 && oldVersion < AppVersion)
 | 
			
		||||
		? std::make_unique<Changelogs>(session, oldVersion)
 | 
			
		||||
	return (oldVersion != 0
 | 
			
		||||
		&& oldKotatoVersion < AppKotatoVersion)
 | 
			
		||||
		? std::make_unique<Changelogs>(session, oldVersion, oldKotatoVersion)
 | 
			
		||||
		: nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Changelogs::addKotatoLogs() {
 | 
			
		||||
	_chatsSubscription.destroy();
 | 
			
		||||
	
 | 
			
		||||
	if (_addedSomeLocal) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	auto baseLang = Lang::GetInstance().baseId();
 | 
			
		||||
	auto currentLang = Lang::Id();
 | 
			
		||||
	QString channelLink;
 | 
			
		||||
 | 
			
		||||
	for (const auto language : { "ru", "uk", "be" }) {
 | 
			
		||||
		if (baseLang.startsWith(QLatin1String(language)) || currentLang == QString(language)) {
 | 
			
		||||
			channelLink = "https://t.me/kotatogram_ru";
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (channelLink.isEmpty()) {
 | 
			
		||||
		channelLink = "https://t.me/kotatogram";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto text = ktr("ktg_new_version",
 | 
			
		||||
		{ "version", QString::fromLatin1(AppKotatoVersionStr) },
 | 
			
		||||
		{ "td_version", QString::fromLatin1(AppVersionStr) },
 | 
			
		||||
		{ "link", channelLink });
 | 
			
		||||
	addLocalLog(text.trimmed());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Changelogs::requestCloudLogs() {
 | 
			
		||||
	_chatsSubscription.destroy();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +177,7 @@ void Changelogs::requestCloudLogs() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void Changelogs::addLocalLogs() {
 | 
			
		||||
	if (AppBetaVersion || cAlphaVersion()) {
 | 
			
		||||
	if (AppKotatoBetaVersion || cAlphaVersion()) {
 | 
			
		||||
		addBetaLogs();
 | 
			
		||||
	}
 | 
			
		||||
	if (!_addedSomeLocal) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,12 +20,13 @@ namespace Core {
 | 
			
		|||
 | 
			
		||||
class Changelogs final : public base::has_weak_ptr {
 | 
			
		||||
public:
 | 
			
		||||
	Changelogs(not_null<Main::Session*> session, int oldVersion);
 | 
			
		||||
	Changelogs(not_null<Main::Session*> session, int oldVersion, int oldKotatoVersion);
 | 
			
		||||
 | 
			
		||||
	static std::unique_ptr<Changelogs> Create(
 | 
			
		||||
		not_null<Main::Session*> session);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void addKotatoLogs();
 | 
			
		||||
	void requestCloudLogs();
 | 
			
		||||
	void addLocalLogs();
 | 
			
		||||
	void addLocalLog(const QString &text);
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +35,7 @@ private:
 | 
			
		|||
 | 
			
		||||
	const not_null<Main::Session*> _session;
 | 
			
		||||
	const int _oldVersion = 0;
 | 
			
		||||
	const int _oldKotatoVersion = 0;
 | 
			
		||||
	rpl::lifetime _chatsSubscription;
 | 
			
		||||
	bool _addedSomeLocal = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "core/crash_report_window.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "core/crash_reports.h"
 | 
			
		||||
#include "core/application.h"
 | 
			
		||||
#include "core/launcher.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +310,7 @@ LastCrashedWindow::LastCrashedWindow(
 | 
			
		|||
	}
 | 
			
		||||
	if (_sendingState != SendingNoReport) {
 | 
			
		||||
		QString version = getReportField(qstr("version"), qstr("Version:"));
 | 
			
		||||
		QString current = cAlphaVersion() ? qsl("-%1").arg(cAlphaVersion()) : QString::number(AppVersion);
 | 
			
		||||
		QString current = cAlphaVersion() ? qsl("-%1").arg(cAlphaVersion()) : QString::number(AppKotatoVersion);
 | 
			
		||||
		if (version != current) { // currently don't accept crash reports from not current app version
 | 
			
		||||
			_sendingState = SendingNoReport;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -478,7 +479,7 @@ QString LastCrashedWindow::getReportField(const QLatin1String &name, const QLati
 | 
			
		|||
			QString data = lines.at(i).trimmed().mid(prefix.size()).trimmed();
 | 
			
		||||
 | 
			
		||||
			if (name == qstr("version")) {
 | 
			
		||||
				if (data.endsWith(qstr(" alpha"))) {
 | 
			
		||||
				if (data.endsWith(qstr(" %1").arg(AppKotatoTestBranch))) {
 | 
			
		||||
					data = QString::number(-data.replace(QRegularExpression(qsl("[^\\d]")), "").toLongLong());
 | 
			
		||||
				} else {
 | 
			
		||||
					data = QString::number(data.replace(QRegularExpression(qsl("[^\\d]")), "").toLongLong());
 | 
			
		||||
| 
						 | 
				
			
			@ -690,7 +691,7 @@ void LastCrashedWindow::updateControls() {
 | 
			
		|||
					if (_sendingState == SendingTooOld || _sendingState == SendingUnofficial) {
 | 
			
		||||
						QString verStr = getReportField(qstr("version"), qstr("Version:"));
 | 
			
		||||
						qint64 ver = verStr.isEmpty() ? 0 : verStr.toLongLong();
 | 
			
		||||
						if (!ver || (ver == AppVersion) || (ver < 0 && (-ver / 1000) == AppVersion)) {
 | 
			
		||||
						if (!ver || (ver == AppKotatoVersion) || (ver < 0 && (-ver / 1000) == AppKotatoVersion)) {
 | 
			
		||||
							h += _getApp.height() + padding;
 | 
			
		||||
							_getApp.show();
 | 
			
		||||
							h -= _yourReportName.height() + padding; // hide report name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "core/crash_reports.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "platform/platform_specific.h"
 | 
			
		||||
#include "base/platform/base_platform_info.h"
 | 
			
		||||
#include "core/launcher.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +310,7 @@ void StartCatching(not_null<Core::Launcher*> launcher) {
 | 
			
		|||
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
 | 
			
		||||
	ProcessAnnotations["Binary"] = cExeName().toUtf8().constData();
 | 
			
		||||
	ProcessAnnotations["ApiId"] = QString::number(ApiId).toUtf8().constData();
 | 
			
		||||
	ProcessAnnotations["Version"] = (cAlphaVersion() ? qsl("%1 alpha").arg(cAlphaVersion()) : (AppBetaVersion ? qsl("%1 beta") : qsl("%1")).arg(AppVersion)).toUtf8().constData();
 | 
			
		||||
	ProcessAnnotations["Version"] = (cAlphaVersion() ? qsl("%1 %2").arg(cAlphaVersion()).arg(AppKotatoTestBranch) : (AppBetaVersion ? qsl("%1 beta") : qsl("%1")).arg(AppKotatoVersion)).toUtf8().constData();
 | 
			
		||||
	ProcessAnnotations["Launched"] = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss").toUtf8().constData();
 | 
			
		||||
	ProcessAnnotations["Platform"] = PlatformString().toUtf8().constData();
 | 
			
		||||
	ProcessAnnotations["UserTag"] = QString::number(launcher->installationTag(), 16).toUtf8().constData();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "core/launcher.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "platform/platform_launcher.h"
 | 
			
		||||
#include "platform/platform_specific.h"
 | 
			
		||||
#include "platform/linux/linux_desktop_environment.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +113,7 @@ void ComputeDebugMode() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void ComputeExternalUpdater() {
 | 
			
		||||
	QFile file(qsl("/etc/tdesktop/externalupdater"));
 | 
			
		||||
	QFile file(qsl("/etc/kotatogram-desktop/externalupdater"));
 | 
			
		||||
 | 
			
		||||
	if (file.exists() && file.open(QIODevice::ReadOnly)) {
 | 
			
		||||
		QTextStream fileStream(&file);
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +154,7 @@ void ComputeInstallBetaVersions() {
 | 
			
		|||
		if (f.open(QIODevice::ReadOnly)) {
 | 
			
		||||
			cSetInstallBetaVersion(f.read(1) != "0");
 | 
			
		||||
		}
 | 
			
		||||
	} else if (AppBetaVersion) {
 | 
			
		||||
	} else if (AppKotatoBetaVersion) {
 | 
			
		||||
		WriteInstallBetaVersionsSetting();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -224,10 +225,13 @@ bool CheckPortableVersionFolder() {
 | 
			
		|||
	const auto portable = cExeDir() + qsl("TelegramForcePortable");
 | 
			
		||||
	QFile key(portable + qsl("/tdata/alpha"));
 | 
			
		||||
	if (cAlphaVersion()) {
 | 
			
		||||
		/*
 | 
			
		||||
		Assert(*AlphaPrivateKey != 0);
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		cForceWorkingDir(portable + '/');
 | 
			
		||||
		QDir().mkpath(cWorkingDir() + qstr("tdata"));
 | 
			
		||||
		/*
 | 
			
		||||
		cSetAlphaPrivateKey(QByteArray(AlphaPrivateKey));
 | 
			
		||||
		if (!key.open(QIODevice::WriteOnly)) {
 | 
			
		||||
			LOG(("FATAL: Could not open '%1' for writing private key!"
 | 
			
		||||
| 
						 | 
				
			
			@ -237,6 +241,7 @@ bool CheckPortableVersionFolder() {
 | 
			
		|||
		QDataStream dataStream(&key);
 | 
			
		||||
		dataStream.setVersion(QDataStream::Qt_5_3);
 | 
			
		||||
		dataStream << quint64(cRealAlphaVersion()) << cAlphaPrivateKey();
 | 
			
		||||
		*/
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	if (!QDir(portable).exists()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "core/update_checker.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "platform/platform_specific.h"
 | 
			
		||||
#include "base/platform/base_platform_info.h"
 | 
			
		||||
#include "base/platform/base_platform_file_utilities.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +306,7 @@ bool UnpackUpdate(const QString &filepath) {
 | 
			
		|||
	RSA *pbKey = [] {
 | 
			
		||||
		const auto bio = MakeBIO(
 | 
			
		||||
			const_cast<char*>(
 | 
			
		||||
				AppBetaVersion
 | 
			
		||||
				AppKotatoBetaVersion
 | 
			
		||||
					? UpdatesPublicBetaKey
 | 
			
		||||
					: UpdatesPublicKey),
 | 
			
		||||
			-1);
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +323,7 @@ bool UnpackUpdate(const QString &filepath) {
 | 
			
		|||
		pbKey = [] {
 | 
			
		||||
			const auto bio = MakeBIO(
 | 
			
		||||
				const_cast<char*>(
 | 
			
		||||
					AppBetaVersion
 | 
			
		||||
					AppKotatoBetaVersion
 | 
			
		||||
						? UpdatesPublicKey
 | 
			
		||||
						: UpdatesPublicBetaKey),
 | 
			
		||||
				-1);
 | 
			
		||||
| 
						 | 
				
			
			@ -423,8 +424,8 @@ bool UnpackUpdate(const QString &filepath) {
 | 
			
		|||
				LOG(("Update Error: downloaded alpha version %1 is not greater, than mine %2").arg(alphaVersion).arg(cAlphaVersion()));
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (int32(version) <= AppVersion) {
 | 
			
		||||
			LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
 | 
			
		||||
		} else if (int32(version) <= AppKotatoVersion) {
 | 
			
		||||
			LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppKotatoVersion));
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +555,7 @@ bool ParseCommonMap(
 | 
			
		|||
	const auto types = (*it).toObject();
 | 
			
		||||
	const auto list = [&]() -> std::vector<QString> {
 | 
			
		||||
		if (cAlphaVersion()) {
 | 
			
		||||
			return { "alpha", "beta", "stable" };
 | 
			
		||||
			return { AppKotatoTestBranch };
 | 
			
		||||
		} else if (cInstallBetaVersion()) {
 | 
			
		||||
			return { "beta", "stable" };
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -577,7 +578,7 @@ bool ParseCommonMap(
 | 
			
		|||
		if (version == map.constEnd()) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		const auto isAvailableAlpha = (type == "alpha");
 | 
			
		||||
		const auto isAvailableAlpha = (type == AppKotatoTestBranch);
 | 
			
		||||
		const auto availableVersion = [&] {
 | 
			
		||||
			if ((*version).isString()) {
 | 
			
		||||
				const auto string = (*version).toString();
 | 
			
		||||
| 
						 | 
				
			
			@ -648,10 +649,8 @@ HttpChecker::HttpChecker(bool testing) : Checker(testing) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void HttpChecker::start() {
 | 
			
		||||
	const auto updaterVersion = Platform::AutoUpdateVersion();
 | 
			
		||||
	const auto path = Local::readAutoupdatePrefix()
 | 
			
		||||
		+ qstr("/current")
 | 
			
		||||
		+ (updaterVersion > 1 ? QString::number(updaterVersion) : QString());
 | 
			
		||||
		+ qstr("/current");
 | 
			
		||||
	auto url = QUrl(path);
 | 
			
		||||
	DEBUG_LOG(("Update Info: requesting update state"));
 | 
			
		||||
	const auto request = QNetworkRequest(url);
 | 
			
		||||
| 
						 | 
				
			
			@ -773,7 +772,7 @@ QString HttpChecker::validateLatestUrl(
 | 
			
		|||
		QString url) const {
 | 
			
		||||
	const auto myVersion = isAvailableAlpha
 | 
			
		||||
		? cAlphaVersion()
 | 
			
		||||
		: uint64(AppVersion);
 | 
			
		||||
		: uint64(AppKotatoVersion);
 | 
			
		||||
	const auto validVersion = (cAlphaVersion() || !isAvailableAlpha);
 | 
			
		||||
	if (!validVersion || availableVersion <= myVersion) {
 | 
			
		||||
		return QString();
 | 
			
		||||
| 
						 | 
				
			
			@ -929,9 +928,7 @@ void MtpChecker::start() {
 | 
			
		|||
		crl::on_main(this, [=] { fail(); });
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	const auto updaterVersion = Platform::AutoUpdateVersion();
 | 
			
		||||
	const auto feed = "tdhbcfeed"
 | 
			
		||||
		+ (updaterVersion > 1 ? QString::number(updaterVersion) : QString());
 | 
			
		||||
	const auto feed = "ktghbcfeed";
 | 
			
		||||
	MTP::ResolveChannel(&_mtp, feed, [=](
 | 
			
		||||
			const MTPInputChannel &channel) {
 | 
			
		||||
		_mtp.send(
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,7 +1030,7 @@ auto MtpChecker::parseText(const QByteArray &text) const
 | 
			
		|||
auto MtpChecker::validateLatestLocation(
 | 
			
		||||
		uint64 availableVersion,
 | 
			
		||||
		const FileLocation &location) const -> FileLocation {
 | 
			
		||||
	const auto myVersion = uint64(AppVersion);
 | 
			
		||||
	const auto myVersion = uint64(AppKotatoVersion);
 | 
			
		||||
	return (availableVersion <= myVersion) ? FileLocation() : location;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1528,17 +1525,17 @@ bool checkReadyUpdate() {
 | 
			
		|||
		if (versionNum == 0x7FFFFFFF) { // alpha version
 | 
			
		||||
			quint64 alphaVersion = 0;
 | 
			
		||||
			if (fVersion.read((char*)&alphaVersion, sizeof(quint64)) != sizeof(quint64)) {
 | 
			
		||||
				LOG(("Update Error: cant read alpha version from file '%1'").arg(versionPath));
 | 
			
		||||
				LOG(("Update Error: cant read test version from file '%1'").arg(versionPath));
 | 
			
		||||
				ClearAll();
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			if (!cAlphaVersion() || alphaVersion <= cAlphaVersion()) {
 | 
			
		||||
				LOG(("Update Error: cant install alpha version %1 having alpha version %2").arg(alphaVersion).arg(cAlphaVersion()));
 | 
			
		||||
				LOG(("Update Error: cant install test version %1 having %2 version %3").arg(alphaVersion).arg(AppKotatoTestBranch).arg(cAlphaVersion()));
 | 
			
		||||
				ClearAll();
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (versionNum <= AppVersion) {
 | 
			
		||||
			LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
 | 
			
		||||
		} else if (versionNum <= AppKotatoVersion) {
 | 
			
		||||
			LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppKotatoVersion));
 | 
			
		||||
			ClearAll();
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1668,7 +1665,7 @@ void UpdateApplication() {
 | 
			
		|||
 | 
			
		||||
QString countAlphaVersionSignature(uint64 version) { // duplicated in packer.cpp
 | 
			
		||||
	if (cAlphaPrivateKey().isEmpty()) {
 | 
			
		||||
		LOG(("Error: Trying to count alpha version signature without alpha private key!"));
 | 
			
		||||
		//LOG(("Error: Trying to count alpha version signature without alpha private key!"));
 | 
			
		||||
		return QString();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								Telegram/SourceFiles/kotato/kotato_version.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Telegram/SourceFiles/kotato/kotato_version.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
This file is part of Kotatogram Desktop,
 | 
			
		||||
the unofficial app based on Telegram Desktop.
 | 
			
		||||
 | 
			
		||||
For license and copyright information please follow this link:
 | 
			
		||||
https://github.com/kotatogram/kotatogram-desktop/blob/dev/LEGAL
 | 
			
		||||
*/
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
constexpr auto AppKotatoVersion = 1004009;
 | 
			
		||||
constexpr auto AppKotatoVersionStr = "1.4.9";
 | 
			
		||||
constexpr auto AppKotatoBetaVersion = true;
 | 
			
		||||
 | 
			
		||||
//#define KTGDESKTOP_IS_TEST_VERSION
 | 
			
		||||
constexpr auto AppKotatoTestBranch = "dev";
 | 
			
		||||
constexpr auto AppKotatoTestVersion = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef KTGDESKTOP_IS_TEST_VERSION
 | 
			
		||||
constexpr auto AppKotatoTestVersionFull = (1000ULL * AppKotatoVersion + AppKotatoTestVersion);
 | 
			
		||||
#else // KTGDESKTOP_IS_TEST_VERSION
 | 
			
		||||
constexpr auto AppKotatoTestVersionFull = (0ULL);
 | 
			
		||||
#endif // KTGDESKTOP_IS_TEST_VERSION
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "logs.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "platform/platform_specific.h"
 | 
			
		||||
#include "core/crash_reports.h"
 | 
			
		||||
#include "core/launcher.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -425,10 +426,11 @@ void start(not_null<Core::Launcher*> launcher) {
 | 
			
		|||
		LogsData = nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOG(("Launched version: %1, install beta: %2, alpha: %3, debug mode: %4"
 | 
			
		||||
	LOG(("Launched version: %1, install beta: %2, %3: %4, debug mode: %5"
 | 
			
		||||
		).arg(AppVersion
 | 
			
		||||
		).arg(Logs::b(cInstallBetaVersion())
 | 
			
		||||
		).arg(cAlphaVersion()
 | 
			
		||||
		).arg(AppKotatoTestBranch
 | 
			
		||||
		).arg(AppKotatoTestVersion
 | 
			
		||||
		).arg(Logs::b(DebugEnabled())));
 | 
			
		||||
	LOG(("Executable dir: %1, name: %2").arg(cExeDir(), cExeName()));
 | 
			
		||||
	LOG(("Initial working dir: %1").arg(initialWorkingDir));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "mtproto/session_private.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "mtproto/details/mtproto_bound_key_creator.h"
 | 
			
		||||
#include "mtproto/details/mtproto_dcenter.h"
 | 
			
		||||
#include "mtproto/details/mtproto_dump_to_text.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +81,7 @@ using namespace details;
 | 
			
		|||
#else
 | 
			
		||||
	const auto arch = ' ' + QSysInfo::buildCpuArchitecture();
 | 
			
		||||
#endif
 | 
			
		||||
	return QString::fromLatin1(AppVersionStr) + arch + ([] {
 | 
			
		||||
	return QString::fromLatin1(AppKotatoVersionStr) + arch + ([] {
 | 
			
		||||
#if defined OS_MAC_STORE
 | 
			
		||||
		return u" Mac App Store"_q;
 | 
			
		||||
#elif defined OS_WIN_STORE // OS_MAC_STORE
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +95,9 @@ using namespace details;
 | 
			
		|||
#else // OS_MAC_STORE || OS_WIN_STORE || (defined Q_OS_UNIX && !defined Q_OS_MAC)
 | 
			
		||||
		return QString();
 | 
			
		||||
#endif // OS_MAC_STORE || OS_WIN_STORE || (defined Q_OS_UNIX && !defined Q_OS_MAC)
 | 
			
		||||
	})();
 | 
			
		||||
	})() + (cAlphaVersion()
 | 
			
		||||
				? qsl("-%1.%2").arg(AppKotatoTestBranch).arg(AppKotatoTestVersion)
 | 
			
		||||
				: QString());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WrapInvokeAfter(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,13 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "settings.h"
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "ui/emoji_config.h"
 | 
			
		||||
 | 
			
		||||
Qt::LayoutDirection gLangDir = Qt::LeftToRight;
 | 
			
		||||
 | 
			
		||||
bool gInstallBetaVersion = AppBetaVersion;
 | 
			
		||||
uint64 gAlphaVersion = AppAlphaVersion;
 | 
			
		||||
uint64 gRealAlphaVersion = AppAlphaVersion;
 | 
			
		||||
bool gInstallBetaVersion = AppKotatoBetaVersion;
 | 
			
		||||
uint64 gAlphaVersion = AppKotatoTestVersionFull;
 | 
			
		||||
uint64 gRealAlphaVersion = AppKotatoTestVersionFull;
 | 
			
		||||
QByteArray gAlphaPrivateKey;
 | 
			
		||||
 | 
			
		||||
bool gManyInstance = false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,12 +86,9 @@ bool HasUpdate() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void SetupUpdate(
 | 
			
		||||
		not_null<Window::Controller*> controller,
 | 
			
		||||
		not_null<Ui::VerticalLayout*> container,
 | 
			
		||||
		Fn<void(Type)> showOther) {
 | 
			
		||||
	if (!HasUpdate()) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto texts = Ui::CreateChild<rpl::event_stream<QString>>(
 | 
			
		||||
		container.get());
 | 
			
		||||
	const auto downloading = Ui::CreateChild<rpl::event_stream<bool>>(
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +111,7 @@ void SetupUpdate(
 | 
			
		|||
			container,
 | 
			
		||||
			object_ptr<Ui::VerticalLayout>(container)));
 | 
			
		||||
	const auto inner = options->entity();
 | 
			
		||||
	const auto install = cAlphaVersion() ? nullptr : AddButton(
 | 
			
		||||
	const auto install = (cAlphaVersion() || !HasUpdate()) ? nullptr : AddButton(
 | 
			
		||||
		inner,
 | 
			
		||||
		tr::lng_settings_install_beta(),
 | 
			
		||||
		st::settingsButton).get();
 | 
			
		||||
| 
						 | 
				
			
			@ -137,6 +134,32 @@ void SetupUpdate(
 | 
			
		|||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rpl::combine(
 | 
			
		||||
		toggle->widthValue(),
 | 
			
		||||
		label->widthValue()
 | 
			
		||||
	) | rpl::start_with_next([=] {
 | 
			
		||||
		label->moveToLeft(
 | 
			
		||||
			st::settingsUpdateStatePosition.x(),
 | 
			
		||||
			st::settingsUpdateStatePosition.y());
 | 
			
		||||
	}, label->lifetime());
 | 
			
		||||
	label->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
			
		||||
 | 
			
		||||
	if (!HasUpdate()) {
 | 
			
		||||
		texts->fire_copy(version);
 | 
			
		||||
		auto &lifetime = container->lifetime();
 | 
			
		||||
		const auto toggles = lifetime.make_state<rpl::event_stream<bool>>();
 | 
			
		||||
		toggle->toggleOn(toggles->events_starting_with(false));
 | 
			
		||||
		toggle->toggledChanges(
 | 
			
		||||
		) | rpl::start_with_next([=](bool value) {
 | 
			
		||||
			if (value) {
 | 
			
		||||
				toggles->fire_copy(false);
 | 
			
		||||
				controller->showToast(ktr("ktg_in_app_update_disabled"));
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}, container->lifetime());
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const auto check = AddButton(
 | 
			
		||||
		inner,
 | 
			
		||||
		tr::lng_settings_check_now(),
 | 
			
		||||
| 
						 | 
				
			
			@ -151,16 +174,6 @@ void SetupUpdate(
 | 
			
		|||
		update->moveToLeft(0, 0);
 | 
			
		||||
	}, update->lifetime());
 | 
			
		||||
 | 
			
		||||
	rpl::combine(
 | 
			
		||||
		toggle->widthValue(),
 | 
			
		||||
		label->widthValue()
 | 
			
		||||
	) | rpl::start_with_next([=] {
 | 
			
		||||
		label->moveToLeft(
 | 
			
		||||
			st::settingsUpdateStatePosition.x(),
 | 
			
		||||
			st::settingsUpdateStatePosition.y());
 | 
			
		||||
	}, label->lifetime());
 | 
			
		||||
	label->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
			
		||||
 | 
			
		||||
	const auto showDownloadProgress = [=](int64 ready, int64 total) {
 | 
			
		||||
		texts->fire(tr::lng_settings_downloading_update(
 | 
			
		||||
			tr::now,
 | 
			
		||||
| 
						 | 
				
			
			@ -742,15 +755,16 @@ void Advanced::setupContent(not_null<Window::SessionController*> controller) {
 | 
			
		|||
		}
 | 
			
		||||
	};
 | 
			
		||||
	const auto addUpdate = [&] {
 | 
			
		||||
		if (HasUpdate()) {
 | 
			
		||||
			addDivider();
 | 
			
		||||
			AddSkip(content);
 | 
			
		||||
			AddSubsectionTitle(content, tr::lng_settings_version_info());
 | 
			
		||||
			SetupUpdate(content, [=](Type type) {
 | 
			
		||||
		addDivider();
 | 
			
		||||
		AddSkip(content);
 | 
			
		||||
		AddSubsectionTitle(content, tr::lng_settings_version_info());
 | 
			
		||||
		SetupUpdate(
 | 
			
		||||
			&controller->window(),
 | 
			
		||||
			content,
 | 
			
		||||
			[=](Type type) {
 | 
			
		||||
				_showOther.fire_copy(type);
 | 
			
		||||
			});
 | 
			
		||||
			AddSkip(content);
 | 
			
		||||
		}
 | 
			
		||||
		AddSkip(content);
 | 
			
		||||
	};
 | 
			
		||||
	if (!cAutoUpdate()) {
 | 
			
		||||
		addUpdate();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ void SetupConnectionType(
 | 
			
		|||
	not_null<Ui::VerticalLayout*> container);
 | 
			
		||||
bool HasUpdate();
 | 
			
		||||
void SetupUpdate(
 | 
			
		||||
	not_null<Window::Controller*> controller,
 | 
			
		||||
	not_null<Ui::VerticalLayout*> container,
 | 
			
		||||
	Fn<void(Type)> showOther);
 | 
			
		||||
void SetupSystemIntegrationContent(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ object_ptr<Ui::RpWidget> CreateIntroSettings(
 | 
			
		|||
	if (HasUpdate()) {
 | 
			
		||||
		AddDivider(result);
 | 
			
		||||
		AddSkip(result);
 | 
			
		||||
		SetupUpdate(result, nullptr);
 | 
			
		||||
		SetupUpdate(window, result, nullptr);
 | 
			
		||||
		AddSkip(result);
 | 
			
		||||
	}
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
*/
 | 
			
		||||
#include "storage/localstorage.h"
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "kotato/kotato_version.h"
 | 
			
		||||
#include "storage/serialize_common.h"
 | 
			
		||||
#include "storage/storage_account.h"
 | 
			
		||||
#include "storage/details/storage_file_utilities.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +84,7 @@ bool _useGlobalBackgroundKeys = false;
 | 
			
		|||
bool _backgroundCanWrite = true;
 | 
			
		||||
 | 
			
		||||
int32 _oldSettingsVersion = 0;
 | 
			
		||||
int32 _oldKotatoVersion = 0;
 | 
			
		||||
bool _settingsRewriteNeeded = false;
 | 
			
		||||
bool _settingsWriteAllowed = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -357,6 +360,9 @@ void start() {
 | 
			
		|||
	_basePath = cWorkingDir() + qsl("tdata/");
 | 
			
		||||
	if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
 | 
			
		||||
 | 
			
		||||
	_oldKotatoVersion = readKotatoVersion();
 | 
			
		||||
	writeKotatoVersion(AppKotatoVersion);
 | 
			
		||||
 | 
			
		||||
	ReadSettingsContext context;
 | 
			
		||||
	FileReadDescriptor settingsData;
 | 
			
		||||
	// We dropped old test authorizations when migrated to multi auth.
 | 
			
		||||
| 
						 | 
				
			
			@ -533,7 +539,7 @@ const QString &AutoupdatePrefix(const QString &replaceWith = {}) {
 | 
			
		|||
QString autoupdatePrefixFile() {
 | 
			
		||||
	Expects(!Core::UpdaterDisabled());
 | 
			
		||||
 | 
			
		||||
	return cWorkingDir() + "tdata/prefix";
 | 
			
		||||
	return cWorkingDir() + "tdata/kotatoprefix";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const QString &readAutoupdatePrefixRaw() {
 | 
			
		||||
| 
						 | 
				
			
			@ -550,7 +556,7 @@ const QString &readAutoupdatePrefixRaw() {
 | 
			
		|||
			return AutoupdatePrefix(value);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return AutoupdatePrefix("https://td.telegram.org");
 | 
			
		||||
	return AutoupdatePrefix("https://kotatogram.github.io");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void writeAutoupdatePrefix(const QString &prefix) {
 | 
			
		||||
| 
						 | 
				
			
			@ -799,6 +805,10 @@ int32 oldSettingsVersion() {
 | 
			
		|||
	return _oldSettingsVersion;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32 oldKotatoVersion() {
 | 
			
		||||
	return _oldKotatoVersion;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CountWaveformTask : public Task {
 | 
			
		||||
public:
 | 
			
		||||
	CountWaveformTask(not_null<Data::DocumentMedia*> media)
 | 
			
		||||
| 
						 | 
				
			
			@ -1293,6 +1303,32 @@ void incrementRecentHashtag(RecentHashtagPack &recent, const QString &tag) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qint32 readKotatoVersion() {
 | 
			
		||||
	qint32 version = 0;
 | 
			
		||||
	QFile f(_basePath + qsl("ktg_version"));
 | 
			
		||||
	if (f.open(QIODevice::ReadOnly)) {
 | 
			
		||||
		QDataStream stream(&f);
 | 
			
		||||
		stream.setVersion(QDataStream::Qt_5_1);
 | 
			
		||||
		while (!stream.atEnd()) {
 | 
			
		||||
			stream >> version;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		f.close();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return version;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void writeKotatoVersion(int version) {
 | 
			
		||||
	qint32 writtenVersion = version;
 | 
			
		||||
	QFile f(_basePath + qsl("ktg_version"));
 | 
			
		||||
	if (f.open(QIODevice::WriteOnly)) {
 | 
			
		||||
		QDataStream stream(&f);
 | 
			
		||||
		stream << writtenVersion;
 | 
			
		||||
		f.close();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool readOldMtpData(bool remove, ReadSettingsContext &context) {
 | 
			
		||||
	return _readOldMtpData(remove, context);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,6 +69,7 @@ void moveLegacyBackground(
 | 
			
		|||
void reset();
 | 
			
		||||
 | 
			
		||||
int32 oldSettingsVersion();
 | 
			
		||||
int32 oldKotatoVersion();
 | 
			
		||||
 | 
			
		||||
void countVoiceWaveform(not_null<Data::DocumentMedia*> media);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +88,9 @@ void saveRecentLanguages(const std::vector<Lang::Language> &list);
 | 
			
		|||
void removeRecentLanguage(const QString &id);
 | 
			
		||||
void incrementRecentHashtag(RecentHashtagPack &recent, const QString &tag);
 | 
			
		||||
 | 
			
		||||
qint32 readKotatoVersion();
 | 
			
		||||
void writeKotatoVersion(int version);
 | 
			
		||||
 | 
			
		||||
bool readOldMtpData(
 | 
			
		||||
	bool remove,
 | 
			
		||||
	Storage::details::ReadSettingsContext &context);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		||||
 | 
			
		||||
option(TDESKTOP_API_TEST "Use test API credentials." OFF)
 | 
			
		||||
option(KTGDESKTOP_ENABLE_PACKER "Enable building update packer on non-special targets." OFF)
 | 
			
		||||
set(TDESKTOP_API_ID "0" CACHE STRING "Provide 'api_id' for the Telegram API access.")
 | 
			
		||||
set(TDESKTOP_API_HASH "" CACHE STRING "Provide 'api_hash' for the Telegram API access.")
 | 
			
		||||
set(TDESKTOP_LAUNCHER_BASENAME "" CACHE STRING "Desktop file base name (Linux only).")
 | 
			
		||||
| 
						 | 
				
			
			@ -47,9 +48,9 @@ if (DESKTOP_APP_DISABLE_AUTOUPDATE)
 | 
			
		|||
    target_compile_definitions(Telegram PRIVATE TDESKTOP_DISABLE_AUTOUPDATE)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (DESKTOP_APP_SPECIAL_TARGET)
 | 
			
		||||
    target_compile_definitions(Telegram PRIVATE TDESKTOP_ALLOW_CLOSED_ALPHA)
 | 
			
		||||
endif()
 | 
			
		||||
# if (DESKTOP_APP_SPECIAL_TARGET)
 | 
			
		||||
#     target_compile_definitions(Telegram PRIVATE TDESKTOP_ALLOW_CLOSED_ALPHA)
 | 
			
		||||
# endif()
 | 
			
		||||
 | 
			
		||||
if (NOT TDESKTOP_LAUNCHER_BASENAME)
 | 
			
		||||
    set(TDESKTOP_LAUNCHER_BASENAME "kotatogramdesktop")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										330
									
								
								kotatogram_changes.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										330
									
								
								kotatogram_changes.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,330 @@
 | 
			
		|||
1.4.9 (08.03.2022)
 | 
			
		||||
- Updated TDesktop sources to 3.5.2.
 | 
			
		||||
- Internal rework of Kotatogram Settings.
 | 
			
		||||
- Allow select time when jumping to date in chat.
 | 
			
		||||
- Always show TDesktop's experimental settings and allow their translation.
 | 
			
		||||
- Make message icon color same as name color.
 | 
			
		||||
- Fix avatar cropping in Windows system notifications.
 | 
			
		||||
- Warn when trying to unquoted forward a quiz (by blank-x).
 | 
			
		||||
- Show "Copy callback data" only for callback buttons (by blank-x).
 | 
			
		||||
- Go to chat on Shift+Enter in Forward box (by blank-x).
 | 
			
		||||
- Fix name icons (by blank-x).
 | 
			
		||||
- Fix tg://user?id links for 64-bit IDs (by blank-x).
 | 
			
		||||
- Fix showing "Mention user" for channels (by blank-x).
 | 
			
		||||
- Fix profile pictures rounding (by blank-x).
 | 
			
		||||
- Fix chat status filters by admin rights (by blank-x).
 | 
			
		||||
- New Kotatogram macOS icon (by gershik).
 | 
			
		||||
 | 
			
		||||
1.4.8 (31.12.2021)
 | 
			
		||||
- Better font settings.
 | 
			
		||||
- Fixed severe crash in Saved Messages.
 | 
			
		||||
- Fixed non-clickable part of message author name if there an icon near it.
 | 
			
		||||
 | 
			
		||||
1.4.7 (30.12.2021)
 | 
			
		||||
- Ability to switch accounts by hotkeys.
 | 
			
		||||
- Added icon near the author name in message.
 | 
			
		||||
- Fixed ranks in admin list.
 | 
			
		||||
 | 
			
		||||
1.4.6 (18.12.2021)
 | 
			
		||||
- Updated TDesktop sources to 3.3.
 | 
			
		||||
- Ability to disable remembering image compression when sending.
 | 
			
		||||
- Custom auto-replaces now work without emoji replacement enabled.
 | 
			
		||||
- Removed window size restiction.
 | 
			
		||||
- Fixed tg:// link protocol in system.
 | 
			
		||||
- Fixed "External video player" option.
 | 
			
		||||
 | 
			
		||||
1.4.5 (04.12.2021)
 | 
			
		||||
- Updated TDesktop sources to 3.1.1.
 | 
			
		||||
- Fixed caption sending modes in unquoted forward.
 | 
			
		||||
- Fixed "Qt scaling" option.
 | 
			
		||||
- Removed duplicate of GIF button in shared media.
 | 
			
		||||
- Fixed animated emoji size.
 | 
			
		||||
- Fix custom font size scale.
 | 
			
		||||
 | 
			
		||||
1.4.4 (22.09.2021)
 | 
			
		||||
- Updated TDesktop sources to 3.1.
 | 
			
		||||
- Added option to remember forward mode.
 | 
			
		||||
- Added ability to set default forward mode.
 | 
			
		||||
- Replaced unquoted forward method with option to restore the old one.
 | 
			
		||||
- Added option to disable per-chat themes.
 | 
			
		||||
- Removed GTK integration option, since it's not needed anymore.
 | 
			
		||||
- Fixed missing sending inline bot response preview option.
 | 
			
		||||
- Fixed missing sending inline bot response preview in comments and scheduled messages.
 | 
			
		||||
- Fixed option "Disable edit by Up key" in comments and scheduled messages.
 | 
			
		||||
- GIF section in shared media and forwarded sticker info are now same as in TDesktop.
 | 
			
		||||
 | 
			
		||||
1.4.3 (26.08.2021)
 | 
			
		||||
- Reworked sending without "via @bot" tag.
 | 
			
		||||
- Optional hotkeys to restart application and to reload Kotatogram translation.
 | 
			
		||||
- Fixed blocking user in "Recent Actions".
 | 
			
		||||
- Updated translations, including phrases from previous version.
 | 
			
		||||
- Fixed errors and crashes in AppImage related to gdk-pixbuf.
 | 
			
		||||
 | 
			
		||||
1.4.2 (21.08.2021)
 | 
			
		||||
- Updated TDesktop sources to 2.8.11.
 | 
			
		||||
- Manually choose notification mute time.
 | 
			
		||||
- Auto-login option for Telegram sites.
 | 
			
		||||
- Multi-threaded video decoding option.
 | 
			
		||||
- External video player.
 | 
			
		||||
- Sending without "via @bot" mark.
 | 
			
		||||
- Font size JSON option.
 | 
			
		||||
- Backported message self-destruct 1 month option.
 | 
			
		||||
- Localized self-destruct messages button to Russian.
 | 
			
		||||
- Fixed missing "Copy Share Link" in forward window when a single album is selected.
 | 
			
		||||
- Fixed applying of some bundled Kotatogram translations.
 | 
			
		||||
 | 
			
		||||
1.4.1 (29.04.2021)
 | 
			
		||||
- Updated TDesktop sources to 2.7.4.
 | 
			
		||||
- Separate Kotatogram's MPRIS and TDesktop's MPRIS.
 | 
			
		||||
- Fix crash on right clicking emoji button.
 | 
			
		||||
- Attempt to fix repeating changelogs.
 | 
			
		||||
- Smaller font for options with radio buttons.
 | 
			
		||||
- Don't show top notification switch in own profile.
 | 
			
		||||
- Remove unnecessary separator in own profile.
 | 
			
		||||
- Fix dependent separated "Send stickers and GIFs" restriction.
 | 
			
		||||
- Updated translations.
 | 
			
		||||
 | 
			
		||||
1.4 (13.04.2021)
 | 
			
		||||
- Updated TDesktop sources to 2.7.1.
 | 
			
		||||
- Ability to forward messages without author.
 | 
			
		||||
- Local folders.
 | 
			
		||||
- Ability to set API ID and hash by start parameter or environment variable.
 | 
			
		||||
- Use checkboxes in polls with multiple answers.
 | 
			
		||||
- Reworked admins info.
 | 
			
		||||
- Show group type in chat lists.
 | 
			
		||||
- Show star icon for groups where you're an admin.
 | 
			
		||||
- Do not notify when pinning by default.
 | 
			
		||||
- Ability to mention user from context menu in members list.
 | 
			
		||||
- Improved theme keys search.
 | 
			
		||||
- Experimental top bar customization.
 | 
			
		||||
- Reworked changning time when scheduling messages.
 | 
			
		||||
- Improved keyboard navigation for calendar.
 | 
			
		||||
- Ability to jump to date in chat (Ctrl+H by default).
 | 
			
		||||
- Use ghost icon from Android app.
 | 
			
		||||
- Hide Edit and All Chats from context menu.
 | 
			
		||||
- Show button to remove recent sticker.
 | 
			
		||||
- Option to retain selection after forward.
 | 
			
		||||
- Hide account name in notification if it's the current one.
 | 
			
		||||
- Possible fix for crash on Permissions click in profile.
 | 
			
		||||
- Fix for crash on profile double open in blocked users list.
 | 
			
		||||
- Option to disable monospace bubbles expansion (user-contributed).
 | 
			
		||||
- Click-to-copy for ID, phone and username in profile.
 | 
			
		||||
- Revoke messages by default.
 | 
			
		||||
- Additional info for chats in folders.
 | 
			
		||||
- Manage buttons in profile.
 | 
			
		||||
- Forward to multiple chats.
 | 
			
		||||
- Allow add up to 10 accounts in 32-bit build and up to 100 in 64 bit builds.
 | 
			
		||||
- Do not share phone number by default (from 64Gram).
 | 
			
		||||
- GIFs shared media section (from 64Gram).
 | 
			
		||||
- Uwrapped "Stickers and GIFs" permission (from 64Gram).
 | 
			
		||||
- Option to disable emoji panel on hover.
 | 
			
		||||
- Option to use native window frame on Windows and macOS.
 | 
			
		||||
- Option to disable tray counter.
 | 
			
		||||
- Option to use Telegram tray icon on Linux panels.
 | 
			
		||||
- Set media clear limit down to 1 day.
 | 
			
		||||
- Many translations from Crowdin page.
 | 
			
		||||
 | 
			
		||||
1.3.9 (9.09.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.3.2.
 | 
			
		||||
- Ability to forward messages without author.
 | 
			
		||||
- Local folders.
 | 
			
		||||
- Ability to set API ID and hash by start parameter or environment variable.
 | 
			
		||||
- Use checkboxes in polls with multiple answers.
 | 
			
		||||
- Reworked admins info.
 | 
			
		||||
- Show group type in chat lists.
 | 
			
		||||
- Show star icon for groups where you're an admin.
 | 
			
		||||
- Do not notify when pinning by default.
 | 
			
		||||
- Ability to mention user from context menu in members list.
 | 
			
		||||
- Open pop-up emoji panel on RMB when disabled by hover.
 | 
			
		||||
- Improved theme keys search.
 | 
			
		||||
- Experimental top bar customization.
 | 
			
		||||
- Reworked changning time when scheduling messages.
 | 
			
		||||
- Improved keyboard navigation for calendar.
 | 
			
		||||
- Italian translation (by alsoGAMER and CrisMystik).
 | 
			
		||||
- Ability to jump to date in chat (Ctrl+J by default).
 | 
			
		||||
- Use ghost icon from Android app.
 | 
			
		||||
- Hide Edit and All Chats from context menu.
 | 
			
		||||
- Show button to remove recent sticker.
 | 
			
		||||
- Portuguese (Brasil) translation (by lipetst).
 | 
			
		||||
 | 
			
		||||
1.3.8 (10.07.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.18.
 | 
			
		||||
- Restored one-click forward to Saved Messages.
 | 
			
		||||
- Ability to go to chat from forward when selecting one.
 | 
			
		||||
- Make retaining selection after forward optional.
 | 
			
		||||
- Option to open chat on click in forward window.
 | 
			
		||||
- Hide account name in notification if it's the current one.
 | 
			
		||||
- Possible fix for crash on Permissions click in profile.
 | 
			
		||||
- Turkish translation (by disk3).
 | 
			
		||||
- Polish translation (by Sebek).
 | 
			
		||||
 | 
			
		||||
1.3.7 (3.07.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.17.
 | 
			
		||||
- Option to disable monospace bubbles expansion (user-contributed).
 | 
			
		||||
- Click-to-copy for ID, phone and username in profile.
 | 
			
		||||
- Revoke messages by default.
 | 
			
		||||
- Additional info for chats in folders.
 | 
			
		||||
- Manage buttons in profile.
 | 
			
		||||
- Forward to multiple chats.
 | 
			
		||||
- Allow add up to 10 accounts.
 | 
			
		||||
- Do not share phone number by default (from TDesktop-x64).
 | 
			
		||||
- GIFs shared media section (from TDesktop-x64).
 | 
			
		||||
- Uwrapped "Stickers and GIFs" permission (from TDesktop-x64).
 | 
			
		||||
- Ukranian translation (by winqooq).
 | 
			
		||||
 | 
			
		||||
1.3.6 (22.05.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.6.
 | 
			
		||||
- Option to disable emoji panel on hover.
 | 
			
		||||
- Option to use native window frame on Windows and macOS.
 | 
			
		||||
- Option to disable tray counter.
 | 
			
		||||
- Option to use Telegram tray icon on Linux panels.
 | 
			
		||||
- Set media clear limit down to 1 day.
 | 
			
		||||
 | 
			
		||||
1.3.5 (10.05.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.4.
 | 
			
		||||
 | 
			
		||||
1.3.4 (6.05.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.2.
 | 
			
		||||
- Optional Bot API chat ID format.
 | 
			
		||||
- Message ID in date tooltip.
 | 
			
		||||
- Option to scale sticker width along with height.
 | 
			
		||||
- Show time of service message.
 | 
			
		||||
 | 
			
		||||
1.3.3 (3.05.2020)
 | 
			
		||||
- Fixed crash from 1.3.2.
 | 
			
		||||
 | 
			
		||||
1.3.2 (2.05.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.1.
 | 
			
		||||
 | 
			
		||||
1.3.1 (27.04.2020)
 | 
			
		||||
- Some post-refactor bugfixes.
 | 
			
		||||
 | 
			
		||||
1.3 (25.04.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.1.
 | 
			
		||||
- Search messages from user from context menu.
 | 
			
		||||
- "query" parameter for tg://resolve and t.me links to set search query.
 | 
			
		||||
- Select and copy text in link open box and bot button click.
 | 
			
		||||
- Select and copy text of poll explanation, showing it in box.
 | 
			
		||||
- Added two existed options to menu: tray icon and profile picture rounding.
 | 
			
		||||
- Suggest to hide pinned message when unpinning.
 | 
			
		||||
- Show Discuss button even if you haven't subscribed to channel.
 | 
			
		||||
 | 
			
		||||
1.2.2 (2.04.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.0.1.
 | 
			
		||||
- Option to hide All chats folder.
 | 
			
		||||
 | 
			
		||||
1.2.1 (31.03.2020)
 | 
			
		||||
- Updated TDesktop sources to 2.0.
 | 
			
		||||
- Option to set default folder. Also added context menu to All chats filter.
 | 
			
		||||
- Option to show only unmuted chats in folder counter.
 | 
			
		||||
- Option to hide Edit button in folder sidebar.
 | 
			
		||||
- Compact folder sidebar option.
 | 
			
		||||
- Restored unreleased notification toggle as option.
 | 
			
		||||
- tg://settings/kotato link to open Kotatogram Settings. Also added three-dots menu there.
 | 
			
		||||
 | 
			
		||||
1.2 (19.03.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.21.
 | 
			
		||||
- New logo and option to choose alternative icons.
 | 
			
		||||
 | 
			
		||||
1.1.9 (15.03.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.20 beta.
 | 
			
		||||
- Support for taskbar flashing alert on Linux.
 | 
			
		||||
- Bot privacy status in members list.
 | 
			
		||||
- Custom tray and taskbar icon.
 | 
			
		||||
- Show working dir in tray icon tooltip.
 | 
			
		||||
- Option to change rounding of profile pictures.
 | 
			
		||||
- Option to always show profile picture in top bar.
 | 
			
		||||
- Ban members option in Recent Actions.
 | 
			
		||||
 | 
			
		||||
1.1.8 (27.02.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.19 beta.
 | 
			
		||||
- Option to disable taskbar icon flashing.
 | 
			
		||||
- Control notification sound from tray menu.
 | 
			
		||||
- Option to change recent stickers show limit (up to 200 or disable at all).
 | 
			
		||||
- Show video playback controls for GIFs.
 | 
			
		||||
 | 
			
		||||
1.1.7 (8.02.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.10 beta.
 | 
			
		||||
- Allow up to 64px as minimal sticker size.
 | 
			
		||||
- Optional confirmation before calling.
 | 
			
		||||
- "Disable Up to edit" now in options menu.
 | 
			
		||||
- Option to use original font height.
 | 
			
		||||
 | 
			
		||||
1.1.6 (31.01.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.9.
 | 
			
		||||
- Custom text replaces.
 | 
			
		||||
- Ability to use system font (user-contributed).
 | 
			
		||||
 | 
			
		||||
1.1.5 (25.01.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.8.
 | 
			
		||||
 | 
			
		||||
1.1.4 (24.01.2020)
 | 
			
		||||
- Updated TDesktop sources to 1.9.7.
 | 
			
		||||
 | 
			
		||||
1.1.3 (19.12.2019)
 | 
			
		||||
- Updated TDesktop sources to 1.9.4.
 | 
			
		||||
- Option to disable Up shortcut to edit previous message.
 | 
			
		||||
- Speed boost now affects only upload since original download manager was rebuilt.
 | 
			
		||||
 | 
			
		||||
1.1.2 beta (21.12.2019)
 | 
			
		||||
- Adaptive message width option (user-contributed).
 | 
			
		||||
- Compact chat list mode.
 | 
			
		||||
- Forwarded info for stickers.
 | 
			
		||||
 | 
			
		||||
1.1.1 beta (11.10.2019)
 | 
			
		||||
- Updated TDesktop sources to 1.9.1 beta.
 | 
			
		||||
 | 
			
		||||
1.1 (21.10.2019)
 | 
			
		||||
- Options menu with almost all JSON options (except for scales).
 | 
			
		||||
- Font start options are now removed in favor of JSON and settings menu.
 | 
			
		||||
- Highlight for specific media in album.
 | 
			
		||||
 | 
			
		||||
1.0.10 (15.10.2019)
 | 
			
		||||
- Change fonts in Kotatogram Settings.
 | 
			
		||||
 | 
			
		||||
1.0.9 (11.10.2019)
 | 
			
		||||
- Options menu: sticker height, emoji outline, scheduled messages button visibility.
 | 
			
		||||
 | 
			
		||||
1.0.8 (8.10.2019)
 | 
			
		||||
- Option to hide phone number in drawer.
 | 
			
		||||
- Option to set custom interface scales.
 | 
			
		||||
- Keyboard shortcut to save draft to cloud (Ctrl+S by default).
 | 
			
		||||
 | 
			
		||||
1.0.7 beta (7.10.2019)
 | 
			
		||||
- JSON locale rewrites.
 | 
			
		||||
- Russian language support for fork strings.
 | 
			
		||||
- Show custom settings and restart app from settings' three-dots menu.
 | 
			
		||||
- Show custom admin titles in member list.
 | 
			
		||||
- Option to enable network speed boost. Warning: can work bad with low connection speeds.
 | 
			
		||||
- Fixed "Channel is unaccessible" when clicking on linked channel from message.
 | 
			
		||||
 | 
			
		||||
1.0.6 (5.10.2019)
 | 
			
		||||
- JSON configuration.
 | 
			
		||||
 | 
			
		||||
1.0.5 (4.10.2019)
 | 
			
		||||
- Minor fixes and improvements.
 | 
			
		||||
 | 
			
		||||
1.0.4 (3.10.2019)
 | 
			
		||||
- Minor fixes and improvements.
 | 
			
		||||
 | 
			
		||||
1.0.3 (2.10.2019)
 | 
			
		||||
- Always show edit timer.
 | 
			
		||||
- Disabled big emoji outline.
 | 
			
		||||
- Show restriction date to user.
 | 
			
		||||
 | 
			
		||||
1.0.2 (1.10.2019)
 | 
			
		||||
- Hide pinned message from chat menu.
 | 
			
		||||
- Always show scheduled messages button.
 | 
			
		||||
- View discussion group and discussed channel in profile.
 | 
			
		||||
 | 
			
		||||
1.0.1 (30.09.2019)
 | 
			
		||||
- Show previously hidden pinned message in chat.
 | 
			
		||||
- Show ID in chat profile.
 | 
			
		||||
- Copy bot button callback data from its context menu.
 | 
			
		||||
 | 
			
		||||
1.0 (22.09.2019)
 | 
			
		||||
 | 
			
		||||
- Mention user by name instead of username by right clicking mention suggestion.
 | 
			
		||||
- Clickable links and usernames in profile bios.
 | 
			
		||||
- Custom font selection by start options.
 | 
			
		||||
- Adjusted caption, photo, and sticker sizes.
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue