Merge tag 'v5.12.3' into dev

This commit is contained in:
AlexeyZavar 2025-03-13 12:55:33 +03:00
commit b0a4d15d64
27 changed files with 316 additions and 61 deletions

View file

@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="5.12.1.0" />
Version="5.12.3.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>

View file

@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 5,12,1,0
PRODUCTVERSION 5,12,1,0
FILEVERSION 5,12,3,0
PRODUCTVERSION 5,12,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop"
VALUE "FileVersion", "5.12.1.0"
VALUE "FileVersion", "5.12.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2025"
VALUE "ProductName", "AyuGram Desktop"
VALUE "ProductVersion", "5.12.1.0"
VALUE "ProductVersion", "5.12.3.0"
END
END
BLOCK "VarFileInfo"

View file

@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 5,12,1,0
PRODUCTVERSION 5,12,1,0
FILEVERSION 5,12,3,0
PRODUCTVERSION 5,12,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop Updater"
VALUE "FileVersion", "5.12.1.0"
VALUE "FileVersion", "5.12.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2025"
VALUE "ProductName", "AyuGram Desktop"
VALUE "ProductVersion", "5.12.1.0"
VALUE "ProductVersion", "5.12.3.0"
END
END
BLOCK "VarFileInfo"

View file

@ -363,15 +363,17 @@ object_ptr<Ui::RpWidget> AddReactionsSelector(
const auto customEmojiPaused = [controller = args.controller] {
return controller->isGifPausedAtLeastFor(PauseReason::Layer);
};
auto context = Core::TextContext({
auto simpleContext = Core::TextContext({
.session = session,
.repaint = [=] { raw->update(); },
});
auto context = simpleContext;
context.customEmojiFactory = [=](
QStringView data,
const Ui::Text::MarkedContext &context
) -> std::unique_ptr<Ui::Text::CustomEmoji> {
const auto id = Data::ParseCustomEmojiData(data);
auto result = Ui::Text::MakeCustomEmoji(data, context);
auto result = Ui::Text::MakeCustomEmoji(data, simpleContext);
if (state->unifiedFactoryOwner->lookupReactionId(id).custom()) {
return std::make_unique<MaybeDisabledEmoji>(
std::move(result),

View file

@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs;
constexpr auto AppNameOld = "AyuGram for Windows"_cs;
constexpr auto AppName = "AyuGram Desktop"_cs;
constexpr auto AppFile = "AyuGram"_cs;
constexpr auto AppVersion = 5012001;
constexpr auto AppVersionStr = "5.12.1";
constexpr auto AppVersion = 5012003;
constexpr auto AppVersionStr = "5.12.3";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View file

@ -322,6 +322,9 @@ QString CountriesInstance::flagEmojiByISO2(const QString &iso) const {
|| iso.back() < 'A'
|| iso.back() > 'Z') {
return QString();
} else if (iso == u"FT"_q) {
return QString::fromUtf8(
"\xF0\x9F\x8F\xB4\xE2\x80\x8D\xE2\x98\xA0\xEF\xB8\x8F");
}
auto result = QString(4, QChar(0xD83C));
result[1] = QChar(iso.front().unicode() - 'A' + 0xDDE6);

View file

@ -4905,33 +4905,14 @@ void InnerWidget::setupShortcuts() {
});
}
const auto nearFolder = [=](bool isNext) {
const auto id = _controller->activeChatsFilterCurrent();
const auto list = &session().data().chatsFilters().list();
const auto index = int(ranges::find(
*list,
id,
&Data::ChatFilter::id
) - begin(*list));
if (index == list->size() && id != 0) {
return false;
}
const auto changed = index + (isNext ? 1 : -1);
if (changed >= int(list->size()) || changed < 0) {
return false;
}
_controller->setActiveChatsFilter((changed >= 0)
? (*list)[changed].id()
: 0);
return true;
};
request->check(Command::FolderNext) && request->handle([=] {
return nearFolder(true);
using namespace Window;
return CheckAndJumpToNearChatsFilter(_controller, true, true);
});
request->check(Command::FolderPrevious) && request->handle([=] {
return nearFolder(false);
using namespace Window;
return CheckAndJumpToNearChatsFilter(_controller, false, true);
});
request->check(Command::ReadChat) && request->handle([=] {

View file

@ -1334,6 +1334,9 @@ void Widget::toggleFiltersMenu(bool enabled) {
if (_layout == Layout::Child) {
enabled = false;
}
if (const auto id = controller()->windowId(); id.forum() || id.folder()) {
enabled = false;
}
if (!enabled == !_chatFilters) {
return;
} else if (enabled) {

View file

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/layers/generic_box.h"
#include "ui/text/text_utilities.h"
#include "ui/boxes/calendar_box.h"
#include "ui/boxes/choose_time.h"
#include "platform/platform_specific.h"
#include "core/application.h"
#include "core/file_utilities.h"
@ -388,7 +389,7 @@ void SettingsWidget::addFormatAndLocationLabel(
void SettingsWidget::addLimitsLabel(
not_null<Ui::VerticalLayout*> container) {
auto fromLink = value() | rpl::map([](const Settings &data) {
auto fromDateLink = value() | rpl::map([](const Settings &data) {
return data.singlePeerFrom;
}) | rpl::distinct_until_changed(
) | rpl::map([](TimeId from) {
@ -399,7 +400,34 @@ void SettingsWidget::addLimitsLabel(
) | Ui::Text::ToLink(u"internal:edit_from"_q);
}) | rpl::flatten_latest();
auto tillLink = value() | rpl::map([](const Settings &data) {
const auto mapToTime = [](TimeId id, const QString &link) {
return rpl::single(id
? QLocale().toString(
base::unixtime::parse(id).time(),
QLocale::ShortFormat)
: QString()
) | Ui::Text::ToLink(link);
};
const auto concat = [](TextWithEntities date, TextWithEntities link) {
return link.text.isEmpty()
? date
: date.append(u", "_q).append(std::move(link));
};
auto fromTimeLink = value() | rpl::map([](const Settings &data) {
return data.singlePeerFrom;
}) | rpl::distinct_until_changed(
) | rpl::map([=](TimeId from) {
return mapToTime(from, u"internal:edit_from_time"_q);
}) | rpl::flatten_latest();
auto fromLink = rpl::combine(
std::move(fromDateLink),
std::move(fromTimeLink)
) | rpl::map(concat);
auto tillDateLink = value() | rpl::map([](const Settings &data) {
return data.singlePeerTill;
}) | rpl::distinct_until_changed(
) | rpl::map([](TimeId till) {
@ -410,6 +438,18 @@ void SettingsWidget::addLimitsLabel(
) | Ui::Text::ToLink(u"internal:edit_till"_q);
}) | rpl::flatten_latest();
auto tillTimeLink = value() | rpl::map([](const Settings &data) {
return data.singlePeerTill;
}) | rpl::distinct_until_changed(
) | rpl::map([=](TimeId till) {
return mapToTime(till, u"internal:edit_till_time"_q);
}) | rpl::flatten_latest();
auto tillLink = rpl::combine(
std::move(tillDateLink),
std::move(tillTimeLink)
) | rpl::map(concat);
auto datesText = tr::lng_export_limits(
lt_from,
std::move(fromLink),
@ -424,8 +464,47 @@ void SettingsWidget::addLimitsLabel(
object_ptr<Ui::FlatLabel>(
container,
std::move(datesText),
st::exportLocationLabel),
st::boxLabel),
st::exportLimitsPadding);
const auto removeTime = [](TimeId dateTime) {
return base::unixtime::serialize(
QDateTime(
base::unixtime::parse(dateTime).date(),
QTime()));
};
const auto editTimeLimit = [=](Fn<TimeId()> now, Fn<void(TimeId)> done) {
_showBoxCallback(Box([=](not_null<Ui::GenericBox*> box) {
auto result = Ui::ChooseTimeWidget(
box->verticalLayout(),
[&] {
const auto time = base::unixtime::parse(now()).time();
return time.hour() * 3600
+ time.minute() * 60
+ time.second();
}(),
true);
const auto widget = box->addRow(std::move(result.widget));
const auto toSave = widget->lifetime().make_state<TimeId>(0);
std::move(
result.secondsValue
) | rpl::start_with_next([=](TimeId t) {
*toSave = t;
}, box->lifetime());
box->addButton(tr::lng_settings_save(), [=] {
done(*toSave);
box->closeBox();
});
box->addButton(tr::lng_cancel(), [=] {
box->closeBox();
});
box->setTitle(tr::lng_settings_ttl_after_custom());
}));
};
constexpr auto kOffset = 600;
label->overrideLinkClickHandler([=](const QString &url) {
if (url == u"internal:edit_from"_q) {
const auto done = [=](TimeId limit) {
@ -439,10 +518,38 @@ void SettingsWidget::addLimitsLabel(
readData().singlePeerTill,
tr::lng_export_from_beginning(),
done);
} else if (url == u"internal:edit_from_time"_q) {
const auto now = [=] {
auto result = TimeId(0);
changeData([&](Settings &settings) {
result = settings.singlePeerFrom;
});
return result;
};
const auto done = [=](TimeId time) {
changeData([&](Settings &settings) {
const auto result = time
+ removeTime(settings.singlePeerFrom);
if (result >= settings.singlePeerTill
&& settings.singlePeerTill) {
settings.singlePeerFrom = settings.singlePeerTill
- kOffset;
} else {
settings.singlePeerFrom = result;
}
});
};
editTimeLimit(now, done);
} else if (url == u"internal:edit_till"_q) {
const auto done = [=](TimeId limit) {
changeData([&](Settings &settings) {
settings.singlePeerTill = limit;
if (limit <= settings.singlePeerFrom
&& settings.singlePeerFrom) {
settings.singlePeerTill = settings.singlePeerFrom
+ kOffset;
} else {
settings.singlePeerTill = limit;
}
});
};
editDateLimit(
@ -451,6 +558,28 @@ void SettingsWidget::addLimitsLabel(
0,
tr::lng_export_till_end(),
done);
} else if (url == u"internal:edit_till_time"_q) {
const auto now = [=] {
auto result = TimeId(0);
changeData([&](Settings &settings) {
result = settings.singlePeerTill;
});
return result;
};
const auto done = [=](TimeId time) {
changeData([&](Settings &settings) {
const auto result = time
+ removeTime(settings.singlePeerTill);
if (result <= settings.singlePeerFrom
&& settings.singlePeerFrom) {
settings.singlePeerTill = settings.singlePeerFrom
+ kOffset;
} else {
settings.singlePeerTill = result;
}
});
};
editTimeLimit(now, done);
} else {
Unexpected("Click handler URL in export limits edit.");
}

View file

@ -1567,7 +1567,7 @@ void VoiceRecordBar::init() {
if (value == 0. && !show) {
_lock->hide();
} else if (value == 1. && show) {
computeAndSetLockProgress(QCursor::pos());
_lock->requestPaintProgress(calcLockProgress(QCursor::pos()));
}
if (_fullRecord && !show) {
updateTTLGeometry(TTLAnimationType::RightLeft, 1.);
@ -1872,6 +1872,52 @@ void VoiceRecordBar::startRecording() {
_inField = true;
struct FloatingState {
Ui::Animations::Basic animation;
float64 animationProgress = 0;
float64 cursorProgress = 0;
bool lockCapturedByInput = false;
float64 frameCounter = 0;
rpl::lifetime lifetime;
};
const auto stateOwned
= _recordingLifetime.make_state<std::unique_ptr<FloatingState>>(
std::make_unique<FloatingState>());
const auto state = stateOwned->get();
_lock->locks() | rpl::start_with_next([=] {
stateOwned->reset();
}, state->lifetime);
constexpr auto kAnimationThreshold = 0.35;
const auto calcStateRatio = [=](float64 counter) {
return (1 - std::cos(std::fmod(counter, 2 * M_PI))) * 0.5;
};
state->animation.init([=](crl::time now) {
if (state->cursorProgress > kAnimationThreshold) {
state->lockCapturedByInput = true;
}
if (state->lockCapturedByInput) {
if (state->cursorProgress < 0.01) {
state->lockCapturedByInput = false;
state->frameCounter = 0;
} else {
_lock->requestPaintProgress(state->cursorProgress);
return;
}
}
const auto progress = anim::interpolateF(
state->cursorProgress,
kAnimationThreshold,
calcStateRatio(state->frameCounter));
state->frameCounter += 0.01;
_lock->requestPaintProgress(progress);
});
state->animation.start();
if (hasDuration()) {
stateOwned->reset();
}
_send->events(
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::MouseMove
@ -1892,7 +1938,10 @@ void VoiceRecordBar::startRecording() {
if (_showLockAnimation.animating() || !hasDuration()) {
return;
}
computeAndSetLockProgress(mouse->globalPos());
const auto inputProgress = calcLockProgress(mouse->globalPos());
if (inputProgress > state->animationProgress) {
state->cursorProgress = inputProgress;
}
} else if (type == QEvent::MouseButtonRelease) {
checkTipRequired();
stop(_inField.current());
@ -2328,10 +2377,14 @@ float64 VoiceRecordBar::showListenAnimationRatio() const {
}
void VoiceRecordBar::computeAndSetLockProgress(QPoint globalPos) {
_lock->requestPaintProgress(calcLockProgress(globalPos));
}
float64 VoiceRecordBar::calcLockProgress(QPoint globalPos) {
const auto localPos = mapFromGlobal(globalPos);
const auto lower = _lock->height();
const auto higher = 0;
_lock->requestPaintProgress(Progress(localPos.y(), higher - lower));
return Progress(localPos.y(), higher - lower);
}
bool VoiceRecordBar::peekTTLState() const {

View file

@ -156,6 +156,7 @@ private:
[[nodiscard]] float64 activeAnimationRatio() const;
void computeAndSetLockProgress(QPoint globalPos);
[[nodiscard]] float64 calcLockProgress(QPoint globalPos);
[[nodiscard]] bool peekTTLState() const;
[[nodiscard]] bool takeTTLState() const;

View file

@ -748,6 +748,7 @@ AdminLog::OwnedItem AboutView::makeNewPeerInfo(not_null<UserData*> user) {
owned.get(),
GenerateNewPeerInfo(owned.get(), _item.get(), user, _commonGroups),
HistoryView::MediaGenericDescriptor{
.maxWidth = st::newPeerWidth,
.service = true,
.hideServiceText = true,
}));

View file

@ -308,6 +308,9 @@ void ContactStatus::Bar::showState(
_emojiStatusInfo->entity()->overrideLinkClickHandler([=] {
_emojiStatusClicks.fire({});
});
_emojiStatusInfo->entity()->setAnimationsPausedCallback([] {
return Ui::FlatLabel::WhichAnimationsPaused::CustomEmoji;
});
}
_emojiStatusInfo->setVisible(has);
_add->setText((type == Type::Add)

View file

@ -304,7 +304,7 @@ QSize MediaGenericTextPart::countCurrentSize(int newWidth) {
const auto size = CountOptimalTextSize(
_text,
st::msgMinWidth,
newWidth - skip);
std::max(st::msgMinWidth, newWidth - skip));
return {
size.width() + skip,
_margins.top() + size.height() + _margins.bottom(),

View file

@ -274,7 +274,10 @@ void InnerWidget::markUnpinned(std::vector<Entry>::iterator i) {
}
++after;
}
if (after == _entries.size()) {
if (after == _entries.size() && !_allLoaded) {
// We don't know if the correct position is exactly in the end
// of the loaded part or later, so we hide it for now, let it
// be loaded later while scrolling.
_entries.erase(i);
} else if (after > index + 1) {
std::rotate(i, i + 1, begin(_entries) + after);

View file

@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/linux/base_linux_xdp_utilities.h"
#include "core/sandbox.h"
#include "core/application.h"
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
#include "core/core_settings.h"
#endif
#include "base/random.h"
#include <QtCore/QAbstractEventDispatcher>

View file

@ -423,7 +423,8 @@ void Manager::Private::init(XdgNotifications::NotificationsProxy proxy) {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
for (const auto &[key, notifications] : _notifications) {
for (const auto &[msgId, notification] : notifications) {
if (id == v::get<uint>(notification->id)) {
const auto &nid = notification->id;
if (v::is<uint>(nid) && v::get<uint>(nid) == id) {
if (actionName == "default") {
_manager->notificationActivated({ key, msgId });
} else if (actionName == "mail-mark-read") {
@ -447,7 +448,8 @@ void Manager::Private::init(XdgNotifications::NotificationsProxy proxy) {
Core::Sandbox::Instance().customEnterFromEventLoop([&] {
for (const auto &[key, notifications] : _notifications) {
for (const auto &[msgId, notification] : notifications) {
if (id == v::get<uint>(notification->id)) {
const auto &nid = notification->id;
if (v::is<uint>(nid) && v::get<uint>(nid) == id) {
_manager->notificationReplied(
{ key, msgId },
{ QString::fromStdString(text), {} });
@ -468,7 +470,8 @@ void Manager::Private::init(XdgNotifications::NotificationsProxy proxy) {
std::string token) {
for (const auto &[key, notifications] : _notifications) {
for (const auto &[msgId, notification] : notifications) {
if (id == v::get<uint>(notification->id)) {
const auto &nid = notification->id;
if (v::is<uint>(nid) && v::get<uint>(nid) == id) {
GLib::setenv("XDG_ACTIVATION_TOKEN", token, true);
return;
}
@ -501,7 +504,8 @@ void Manager::Private::init(XdgNotifications::NotificationsProxy proxy) {
* In all other cases we keep the notification reference so that we may clear the notification later from history,
* if the message for that notification is read (e.g. chat is opened or read from another device).
*/
if (id == v::get<uint>(notification->id) && reason == 2) {
const auto &nid = notification->id;
if (v::is<uint>(nid) && v::get<uint>(nid) == id && reason == 2) {
clearNotification({ key, msgId });
return;
}

View file

@ -18,7 +18,8 @@ namespace Ui {
ChooseTimeResult ChooseTimeWidget(
not_null<RpWidget*> parent,
TimeId startSeconds) {
TimeId startSeconds,
bool hiddenDaysInput) {
using TimeField = Ui::TimePartWithPlaceholder;
const auto putNext = [](not_null<TimeField*> field, QChar ch) {
field->setCursorPosition(0);
@ -79,6 +80,10 @@ ChooseTimeResult ChooseTimeWidget(
const auto hour = Ui::MakeWeak(state->hour);
const auto minute = Ui::MakeWeak(state->minute);
if (hiddenDaysInput) {
day->setVisible(false);
}
day->setPhrase(tr::lng_days);
day->setMaxValue(31);
day->setWheelStep(1);
@ -105,13 +110,16 @@ ChooseTimeResult ChooseTimeWidget(
content->sizeValue(
) | rpl::start_with_next([=](const QSize &s) {
const auto inputWidth = s.width() / 3;
const auto inputWidth = s.width() / (hiddenDaysInput ? 2 : 3);
auto rect = QRect(
0,
(s.height() - day->height()) / 2,
inputWidth,
day->height());
for (const auto &input : { day, hour, minute }) {
if (input->isHidden()) {
continue;
}
input->setGeometry(rect - st::muteBoxTimeFieldPadding);
rect.translate(inputWidth, 0);
}

View file

@ -20,6 +20,7 @@ struct ChooseTimeResult {
ChooseTimeResult ChooseTimeWidget(
not_null<RpWidget*> parent,
TimeId startSeconds);
TimeId startSeconds,
bool hiddenDaysInput = false);
} // namespace Ui

View file

@ -1244,3 +1244,4 @@ newPeerUserpics: GroupCallUserpics {
align: align(left);
}
newPeerUserpicsPadding: margins(0px, 3px, 0px, 0px);
newPeerWidth: 320px;

View file

@ -72,8 +72,8 @@ void SendButton::setState(State state) {
st::universalDuration);
setPointerCursor(_state.type != Type::Slowmode);
updateSize();
update();
}
update();
}
void SendButton::finishAnimating() {

View file

@ -49,6 +49,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat_filters.h"
#include "data/data_replies_list.h"
#include "data/data_peer_values.h"
#include "data/data_premium_limits.h"
#include "data/data_web_page.h"
#include "passport/passport_form_controller.h"
#include "chat_helpers/tabbed_selector.h"
@ -3252,4 +3253,34 @@ SessionController::~SessionController() {
resetFakeUnreadWhileOpened();
}
bool CheckAndJumpToNearChatsFilter(
not_null<SessionController*> controller,
bool isNext,
bool jump) {
const auto id = controller->activeChatsFilterCurrent();
const auto session = &controller->session();
const auto list = &session->data().chatsFilters().list();
const auto index = int(ranges::find(
*list,
id,
&Data::ChatFilter::id
) - begin(*list));
if (index == list->size() && id != 0) {
return false;
}
const auto changed = index + (isNext ? 1 : -1);
if (changed >= int(list->size()) || changed < 0) {
return false;
}
if (changed > Data::PremiumLimits(session).dialogFiltersCurrent()) {
return false;
}
if (jump) {
controller->setActiveChatsFilter((changed >= 0)
? (*list)[changed].id()
: 0);
}
return true;
}
} // namespace Window

View file

@ -757,4 +757,9 @@ void ActivateWindow(not_null<SessionController*> controller);
not_null<SessionController*> controller,
GifPauseReason level);
bool CheckAndJumpToNearChatsFilter(
not_null<SessionController*> controller,
bool isNext,
bool jump);
} // namespace Window

View file

@ -1148,10 +1148,19 @@ depends:yasm/yasm
""")
stage('liblcms2', """
mac:
git clone -b lcms2.16 https://github.com/mm2/Little-CMS.git liblcms2
cd liblcms2
win:
depends:python/Scripts/activate.bat
%THIRDPARTY_DIR%\\python\\Scripts\\activate.bat
meson setup --default-library=static --buildtype=debug -Db_vscrt=mtd out/Debug
meson compile -C out/Debug
release:
meson setup --default-library=static --buildtype=release -Db_vscrt=mt out/Release
meson compile -C out/Release
win:
deactivate
mac:
buildOneArch() {
arch=$1
folder=`pwd`/$2
@ -1689,6 +1698,7 @@ win:
SET OPENSSL_LIBS_DIR=%OPENSSL_DIR%\\out
SET ZLIB_LIBS_DIR=%LIBS_DIR%\\zlib
SET WEBP_DIR=%LIBS_DIR%\\libwebp
SET LCMS2_DIR=%LIBS_DIR%\\liblcms2
configure -prefix "%LIBS_DIR%\\Qt-%QT%" ^
%CONFIGURATIONS% ^
-force-debug-info ^
@ -1726,7 +1736,10 @@ win:
-D WebP_mux_INCLUDE_DIR="%WEBP_DIR%\\src" ^
-D WebP_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webp.lib" ^
-D WebP_demux_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webpdemux.lib" ^
-D WebP_mux_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webpmux.lib"
-D WebP_mux_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webpmux.lib" ^
-D LCMS2_FOUND=1 ^
-D LCMS2_INCLUDE_DIR="%LCMS2_DIR%\\include" ^
-D LCMS2_LIBRARIES="%LCMS2_DIR%\\out\Release\\src\\liblcms2.a"
cmake --build . --config Debug --parallel
cmake --install . --config Debug

View file

@ -1,7 +1,7 @@
AppVersion 5012001
AppVersion 5012003
AppVersionStrMajor 5.12
AppVersionStrSmall 5.12.1
AppVersionStr 5.12.1
AppVersionStrSmall 5.12.3
AppVersionStr 5.12.3
BetaChannel 0
AlphaVersion 0
AppVersionOriginal 5.12.1
AppVersionOriginal 5.12.3

View file

@ -1,3 +1,13 @@
5.12.3 (10.03.25)
- Fix a couple more crashes.
- Fix gift disappearing on unpin.
- Fix country emoji for Fragment numbers.
5.12.2 (09.03.25)
- Fix some crashes.
5.12.1 (08.03.25)
- Fix a crash in some chat switchings.

2
cmake

@ -1 +1 @@
Subproject commit 8c146a3ec6f4475e5083eee84d126960495a7e1d
Subproject commit 90e6d73100a9fd2dc4c30a270c3bbc1d35924f32