diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index e44415bf7..b2c2e7760 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -910,6 +910,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 @@ -1717,7 +1718,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) diff --git a/Telegram/Resources/langs/rewrites/en.json b/Telegram/Resources/langs/rewrites/en.json index facc7406c..e77a886b4 100644 --- a/Telegram/Resources/langs/rewrites/en.json +++ b/Telegram/Resources/langs/rewrites/en.json @@ -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": "" } diff --git a/Telegram/SourceFiles/_other/packer.cpp b/Telegram/SourceFiles/_other/packer.cpp index 0ba79c1be..d0060708d 100644 --- a/Telegram/SourceFiles/_other/packer.cpp +++ b/Telegram/SourceFiles/_other/packer.cpp @@ -13,17 +13,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-----\ "; @@ -181,10 +181,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; @@ -501,9 +503,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"; diff --git a/Telegram/SourceFiles/boxes/about_box.cpp b/Telegram/SourceFiles/boxes/about_box.cpp index d3ea42ff1..8808639db 100644 --- a/Telegram/SourceFiles/boxes/about_box.cpp +++ b/Telegram/SourceFiles/boxes/about_box.cpp @@ -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" @@ -113,6 +114,7 @@ void AboutBox::resizeEvent(QResizeEvent *e) { } void AboutBox::showVersionHistory() { + /* if (cRealAlphaVersion()) { auto url = u"https://tdesktop.com/"_q; if (Platform::IsWindows32Bit()) { @@ -136,8 +138,11 @@ void AboutBox::showVersionHistory() { "version of Telegram Desktop was copied to the clipboard."), Ui::LayerOption::CloseOther); } else { + */ File::OpenUrl(Core::App().changelogLink()); + /* } + */ } void AboutBox::keyPressEvent(QKeyEvent *e) { @@ -166,14 +171,15 @@ QString telegramFaqLink() { } QString currentVersionText() { - auto result = QString::fromLatin1(AppVersionStr); + auto result = QString::fromLatin1(AppKotatoVersionStr); if (cAlphaVersion()) { - result += u" alpha %1"_q.arg(cAlphaVersion() % 1000); - } else if (AppBetaVersion) { + result += u"-%1.%2"_q.arg(AppKotatoTestBranch).arg(AppKotatoTestVersion); + } else if (AppKotatoBetaVersion) { result += " beta"; } if (Platform::IsWindows64Bit()) { result += " x64"; } + result += qsl(" (TD %1)").arg(AppVersionStr); return result; } diff --git a/Telegram/SourceFiles/boxes/phone_banned_box.cpp b/Telegram/SourceFiles/boxes/phone_banned_box.cpp index b29388e96..68be59594 100644 --- a/Telegram/SourceFiles/boxes/phone_banned_box.cpp +++ b/Telegram/SourceFiles/boxes/phone_banned_box.cpp @@ -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; diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 5dc8b7ce7..ade9f6354 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -49,17 +49,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-----\ "; diff --git a/Telegram/SourceFiles/core/changelogs.cpp b/Telegram/SourceFiles/core/changelogs.cpp index a3eeafb31..295ce68d0 100644 --- a/Telegram/SourceFiles/core/changelogs.cpp +++ b/Telegram/SourceFiles/core/changelogs.cpp @@ -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" @@ -131,14 +135,18 @@ std::map BetaLogs() { } // namespace -Changelogs::Changelogs(not_null session, int oldVersion) +Changelogs::Changelogs(not_null 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); } @@ -146,12 +154,42 @@ std::unique_ptr Changelogs::Create( not_null 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(session, oldVersion) + return (oldVersion != 0 + && oldKotatoVersion < AppKotatoVersion) + ? std::make_unique(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(); @@ -186,7 +224,7 @@ void Changelogs::requestCloudLogs() { } void Changelogs::addLocalLogs() { - if (AppBetaVersion || cAlphaVersion()) { + if (AppKotatoBetaVersion || cAlphaVersion()) { addBetaLogs(); } if (!_addedSomeLocal) { diff --git a/Telegram/SourceFiles/core/changelogs.h b/Telegram/SourceFiles/core/changelogs.h index ba5e312ff..eee8021fb 100644 --- a/Telegram/SourceFiles/core/changelogs.h +++ b/Telegram/SourceFiles/core/changelogs.h @@ -20,12 +20,13 @@ namespace Core { class Changelogs final : public base::has_weak_ptr { public: - Changelogs(not_null session, int oldVersion); + Changelogs(not_null session, int oldVersion, int oldKotatoVersion); static std::unique_ptr Create( not_null session); private: + void addKotatoLogs(); void requestCloudLogs(); void addLocalLogs(); void addLocalLog(const QString &text); @@ -34,6 +35,7 @@ private: const not_null _session; const int _oldVersion = 0; + const int _oldKotatoVersion = 0; rpl::lifetime _chatsSubscription; bool _addedSomeLocal = false; diff --git a/Telegram/SourceFiles/core/crash_report_window.cpp b/Telegram/SourceFiles/core/crash_report_window.cpp index 8549595b4..c66f8f7db 100644 --- a/Telegram/SourceFiles/core/crash_report_window.cpp +++ b/Telegram/SourceFiles/core/crash_report_window.cpp @@ -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/sandbox.h" @@ -333,7 +334,7 @@ LastCrashedWindow::LastCrashedWindow( } if (_sendingState != SendingNoReport) { QString version = getReportField(qstr("version"), qstr("Version:")); - QString current = cAlphaVersion() ? u"-%1"_q.arg(cAlphaVersion()) : QString::number(AppVersion); + QString current = cAlphaVersion() ? u"-%1"_q.arg(cAlphaVersion()) : QString::number(AppKotatoVersion); if (version != current) { // currently don't accept crash reports from not current app version _sendingState = SendingNoReport; } @@ -502,7 +503,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(u"[^\\d]"_q), "").toLongLong()); } else { data = QString::number(data.replace(QRegularExpression(u"[^\\d]"_q), "").toLongLong()); @@ -714,7 +715,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 diff --git a/Telegram/SourceFiles/core/crash_reports.cpp b/Telegram/SourceFiles/core/crash_reports.cpp index 1ef46dddf..3ed6f84d2 100644 --- a/Telegram/SourceFiles/core/crash_reports.cpp +++ b/Telegram/SourceFiles/core/crash_reports.cpp @@ -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" @@ -318,10 +319,10 @@ void StartCatching() { ProcessAnnotations["Binary"] = cExeName().toUtf8().constData(); ProcessAnnotations["ApiId"] = QString::number(ApiId).toUtf8().constData(); ProcessAnnotations["Version"] = (cAlphaVersion() - ? u"%1 alpha"_q.arg(cAlphaVersion()) + ? u"%1 %2"_q.arg(cAlphaVersion()).arg(AppKotatoTestBranch) : (AppBetaVersion ? u"%1 beta"_q - : u"%1"_q).arg(AppVersion)).toUtf8().constData(); + : u"%1"_q).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(Core::Launcher::Instance().installationTag(), 16).toUtf8().constData(); diff --git a/Telegram/SourceFiles/core/launcher.cpp b/Telegram/SourceFiles/core/launcher.cpp index e039d62b9..3b296b14c 100644 --- a/Telegram/SourceFiles/core/launcher.cpp +++ b/Telegram/SourceFiles/core/launcher.cpp @@ -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 "base/options.h" @@ -115,7 +116,7 @@ void ComputeDebugMode() { } void ComputeExternalUpdater() { - QFile file(u"/etc/tdesktop/externalupdater"_q); + QFile file(u"/etc/kotatogram-desktop/externalupdater"_q); if (file.exists() && file.open(QIODevice::ReadOnly)) { QTextStream fileStream(&file); @@ -150,7 +151,7 @@ void ComputeInstallBetaVersions() { if (f.open(QIODevice::ReadOnly)) { cSetInstallBetaVersion(f.read(1) != "0"); } - } else if (AppBetaVersion) { + } else if (AppKotatoBetaVersion) { WriteInstallBetaVersionsSetting(); } } @@ -221,10 +222,13 @@ bool CheckPortableVersionFolder() { const auto portable = cExeDir() + u"TelegramForcePortable"_q; QFile key(portable + u"/tdata/alpha"_q); if (cAlphaVersion()) { + /* Assert(*AlphaPrivateKey != 0); + */ cForceWorkingDir(portable + '/'); QDir().mkpath(cWorkingDir() + u"tdata"_q); + /* cSetAlphaPrivateKey(QByteArray(AlphaPrivateKey)); if (!key.open(QIODevice::WriteOnly)) { LOG(("FATAL: Could not open '%1' for writing private key!" @@ -234,6 +238,7 @@ bool CheckPortableVersionFolder() { QDataStream dataStream(&key); dataStream.setVersion(QDataStream::Qt_5_3); dataStream << quint64(cRealAlphaVersion()) << cAlphaPrivateKey(); + */ return true; } if (!QDir(portable).exists()) { diff --git a/Telegram/SourceFiles/core/update_checker.cpp b/Telegram/SourceFiles/core/update_checker.cpp index 16c1b5172..58046d11c 100644 --- a/Telegram/SourceFiles/core/update_checker.cpp +++ b/Telegram/SourceFiles/core/update_checker.cpp @@ -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" @@ -308,7 +309,7 @@ bool UnpackUpdate(const QString &filepath) { RSA *pbKey = [] { const auto bio = MakeBIO( const_cast( - AppBetaVersion + AppKotatoBetaVersion ? UpdatesPublicBetaKey : UpdatesPublicKey), -1); @@ -325,7 +326,7 @@ bool UnpackUpdate(const QString &filepath) { pbKey = [] { const auto bio = MakeBIO( const_cast( - AppBetaVersion + AppKotatoBetaVersion ? UpdatesPublicKey : UpdatesPublicBetaKey), -1); @@ -426,8 +427,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; } @@ -557,7 +558,7 @@ bool ParseCommonMap( const auto types = (*it).toObject(); const auto list = [&]() -> std::vector { if (cAlphaVersion()) { - return { "alpha", "beta", "stable" }; + return { AppKotatoTestBranch }; } else if (cInstallBetaVersion()) { return { "beta", "stable" }; } @@ -580,7 +581,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(); @@ -651,10 +652,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); @@ -776,7 +775,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(); @@ -932,9 +931,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( @@ -1036,7 +1033,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; } @@ -1531,17 +1528,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; } @@ -1672,7 +1669,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(); } diff --git a/Telegram/SourceFiles/kotato/kotato_version.h b/Telegram/SourceFiles/kotato/kotato_version.h new file mode 100644 index 000000000..c418b981e --- /dev/null +++ b/Telegram/SourceFiles/kotato/kotato_version.h @@ -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 diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index 03cfe4c49..ca3f3d9d9 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -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" @@ -422,10 +423,11 @@ void start() { 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)); diff --git a/Telegram/SourceFiles/mtproto/session_private.cpp b/Telegram/SourceFiles/mtproto/session_private.cpp index 729a95ed6..0a36371c5 100644 --- a/Telegram/SourceFiles/mtproto/session_private.cpp +++ b/Telegram/SourceFiles/mtproto/session_private.cpp @@ -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" @@ -81,7 +82,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 @@ -93,7 +94,9 @@ using namespace details; ? u" Snap"_q : QString(); #endif // OS_MAC_STORE || OS_WIN_STORE - })(); + })() + (cAlphaVersion() + ? qsl("-%1.%2").arg(AppKotatoTestBranch).arg(AppKotatoTestVersion) + : QString()); } void WrapInvokeAfter( diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 4e2f6e878..aaacb31cc 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -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; diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp index f7811405f..fd75a0357 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced.cpp @@ -103,12 +103,9 @@ bool HasUpdate() { } void SetupUpdate( + not_null controller, not_null container, Fn showOther) { - if (!HasUpdate()) { - return; - } - const auto texts = Ui::CreateChild>( container.get()); const auto downloading = Ui::CreateChild>( @@ -131,7 +128,7 @@ void SetupUpdate( container, object_ptr(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::settingsButtonNoIcon).get(); @@ -154,6 +151,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>(); + 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(), @@ -168,16 +191,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, @@ -899,15 +912,16 @@ void Advanced::setupContent(not_null 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(); diff --git a/Telegram/SourceFiles/settings/settings_advanced.h b/Telegram/SourceFiles/settings/settings_advanced.h index 27afff623..6e2eb1f3b 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.h +++ b/Telegram/SourceFiles/settings/settings_advanced.h @@ -25,6 +25,7 @@ void SetupConnectionType( not_null container); bool HasUpdate(); void SetupUpdate( + not_null controller, not_null container, Fn showOther); void SetupWindowTitleContent( diff --git a/Telegram/SourceFiles/settings/settings_intro.cpp b/Telegram/SourceFiles/settings/settings_intro.cpp index feea99acd..76a656719 100644 --- a/Telegram/SourceFiles/settings/settings_intro.cpp +++ b/Telegram/SourceFiles/settings/settings_intro.cpp @@ -69,7 +69,7 @@ object_ptr CreateIntroSettings( if (HasUpdate()) { AddDivider(result); AddSkip(result); - SetupUpdate(result, nullptr); + SetupUpdate(window, result, nullptr); AddSkip(result); } { diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index c3f88807a..743f8aeda 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -7,6 +7,7 @@ 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" @@ -83,6 +84,7 @@ bool _useGlobalBackgroundKeys = false; bool _backgroundCanWrite = true; int32 _oldSettingsVersion = 0; +int32 _oldKotatoVersion = 0; bool _settingsRewriteNeeded = false; bool _settingsWriteAllowed = false; @@ -358,6 +360,9 @@ void start() { _basePath = cWorkingDir() + u"tdata/"_q; 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. @@ -536,7 +541,7 @@ const QString &AutoupdatePrefix(const QString &replaceWith = {}) { QString autoupdatePrefixFile() { Expects(!Core::UpdaterDisabled()); - return cWorkingDir() + "tdata/prefix"; + return cWorkingDir() + "tdata/kotatoprefix"; } const QString &readAutoupdatePrefixRaw() { @@ -553,7 +558,7 @@ const QString &readAutoupdatePrefixRaw() { return AutoupdatePrefix(value); } } - return AutoupdatePrefix("https://td.telegram.org"); + return AutoupdatePrefix("https://kotatogram.github.io"); } void writeAutoupdatePrefix(const QString &prefix) { @@ -802,6 +807,10 @@ int32 oldSettingsVersion() { return _oldSettingsVersion; } +int32 oldKotatoVersion() { + return _oldKotatoVersion; +} + class CountWaveformTask : public Task { public: CountWaveformTask(not_null media) @@ -1296,6 +1305,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); } diff --git a/Telegram/SourceFiles/storage/localstorage.h b/Telegram/SourceFiles/storage/localstorage.h index d79314bcb..1774982fd 100644 --- a/Telegram/SourceFiles/storage/localstorage.h +++ b/Telegram/SourceFiles/storage/localstorage.h @@ -69,6 +69,7 @@ void moveLegacyBackground( void reset(); int32 oldSettingsVersion(); +int32 oldKotatoVersion(); void countVoiceWaveform(not_null media); @@ -87,6 +88,9 @@ void saveRecentLanguages(const std::vector &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); diff --git a/Telegram/cmake/telegram_options.cmake b/Telegram/cmake/telegram_options.cmake index a5a6d9405..811a66744 100644 --- a/Telegram/cmake/telegram_options.cmake +++ b/Telegram/cmake/telegram_options.cmake @@ -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.") @@ -40,6 +41,6 @@ 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() diff --git a/kotatogram_changes.txt b/kotatogram_changes.txt new file mode 100644 index 000000000..1e651b474 --- /dev/null +++ b/kotatogram_changes.txt @@ -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.