2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-30 14:17:45 +00:00

Merge remote-tracking branch 'tdesktop/dev' into dev

This commit is contained in:
RadRussianRus
2020-03-31 18:57:50 +03:00
13 changed files with 207 additions and 124 deletions

View File

@@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop" <Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE" ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A" Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.0.0.0" /> Version="2.0.1.0" />
<Properties> <Properties>
<DisplayName>Telegram Desktop</DisplayName> <DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName> <PublisherDisplayName>Telegram FZ-LLC</PublisherDisplayName>

View File

@@ -200,7 +200,7 @@ void SendExistingPhoto(
bool SendDice(Api::MessageToSend &message) { bool SendDice(Api::MessageToSend &message) {
static const auto kDiceString = QString::fromUtf8("\xF0\x9F\x8E\xB2"); static const auto kDiceString = QString::fromUtf8("\xF0\x9F\x8E\xB2");
if (message.textWithTags.text != kDiceString) { if (message.textWithTags.text.midRef(0).trimmed() != kDiceString) {
return false; return false;
} }
const auto history = message.action.history; const auto history = message.action.history;

View File

@@ -54,6 +54,15 @@ std::map<int, const char*> BetaLogs() {
1009022, 1009022,
"\xE2\x80\xA2 Organize chats into Chat Folders " "\xE2\x80\xA2 Organize chats into Chat Folders "
"if you have too many chats.\n" "if you have too many chats.\n"
},
{
2000001,
"\xE2\x80\xA2 Switch between folders using Ctrl+1, ..., Ctrl+8.\n"
"\xE2\x80\xA2 Fix crash when a pinned in folder chat "
"was added to archive.\n"
"\xE2\x80\xA2 Fix font issues in Linux version."
} }
}; };
}; };

View File

@@ -117,7 +117,7 @@ public:
void fill(); void fill();
void clear(); void clear();
std::optional<Command> lookup(int shortcutId) const; [[nodiscard]] std::vector<Command> lookup(int shortcutId) const;
void toggleMedia(bool toggled); void toggleMedia(bool toggled);
void toggleSupport(bool toggled); void toggleSupport(bool toggled);
@@ -128,14 +128,14 @@ private:
void writeDefaultFile(); void writeDefaultFile();
bool readCustomFile(); bool readCustomFile();
void set(const QString &keys, Command command); void set(const QString &keys, Command command, bool replace = false);
void remove(const QString &keys); void remove(const QString &keys);
void unregister(base::unique_qptr<QShortcut> shortcut); void unregister(base::unique_qptr<QShortcut> shortcut);
QStringList _errors; QStringList _errors;
base::flat_map<QKeySequence, base::unique_qptr<QShortcut>> _shortcuts; base::flat_map<QKeySequence, base::unique_qptr<QShortcut>> _shortcuts;
base::flat_map<int, Command> _commandByShortcutId; base::flat_multi_map<int, Command> _commandByShortcutId;
base::flat_set<QShortcut*> _mediaShortcuts; base::flat_set<QShortcut*> _mediaShortcuts;
base::flat_set<QShortcut*> _supportShortcuts; base::flat_set<QShortcut*> _supportShortcuts;
@@ -210,11 +210,14 @@ const QStringList &Manager::errors() const {
return _errors; return _errors;
} }
std::optional<Command> Manager::lookup(int shortcutId) const { std::vector<Command> Manager::lookup(int shortcutId) const {
const auto i = _commandByShortcutId.find(shortcutId); auto result = std::vector<Command>();
return (i != end(_commandByShortcutId)) auto i = _commandByShortcutId.findFirst(shortcutId);
? base::make_optional(i->second) const auto end = _commandByShortcutId.end();
: std::nullopt; for (; i != end && (i->first == shortcutId); ++i) {
result.push_back(i->second);
}
return result;
} }
void Manager::toggleMedia(bool toggled) { void Manager::toggleMedia(bool toggled) {
@@ -282,7 +285,7 @@ bool Manager::readCustomFile() {
const auto name = (*command).toString(); const auto name = (*command).toString();
const auto i = CommandByName.find(name); const auto i = CommandByName.find(name);
if (i != end(CommandByName)) { if (i != end(CommandByName)) {
set((*keys).toString(), i->second); set((*keys).toString(), i->second, true);
} else { } else {
LOG(("Shortcut Warning: " LOG(("Shortcut Warning: "
"could not find shortcut command handler '%1'" "could not find shortcut command handler '%1'"
@@ -347,7 +350,7 @@ void Manager::fillDefaults() {
ranges::view::ints(1, ranges::unreachable)); ranges::view::ints(1, ranges::unreachable));
for (const auto [command, index] : folders) { for (const auto [command, index] : folders) {
set(qsl("%1+shift+%2").arg(ctrl).arg(index > 9 ? 0 : index), command); set(qsl("%1+%2").arg(ctrl).arg(index), command);
} }
set(qsl("%1+shift+down").arg(ctrl), Command::FolderNext); set(qsl("%1+shift+down").arg(ctrl), Command::FolderNext);
@@ -379,10 +382,12 @@ void Manager::writeDefaultFile() {
shortcuts.push_back(version); shortcuts.push_back(version);
for (const auto &[sequence, shortcut] : _shortcuts) { for (const auto &[sequence, shortcut] : _shortcuts) {
const auto i = _commandByShortcutId.find(shortcut->id()); const auto shortcutId = shortcut->id();
if (i != end(_commandByShortcutId)) { auto i = _commandByShortcutId.findFirst(shortcutId);
const auto end = _commandByShortcutId.end();
for (; i != end && i->first == shortcutId; ++i) {
const auto j = CommandNames.find(i->second); const auto j = CommandNames.find(i->second);
if (j != end(CommandNames)) { if (j != CommandNames.end()) {
QJsonObject entry; QJsonObject entry;
entry.insert(qsl("keys"), sequence.toString().toLower()); entry.insert(qsl("keys"), sequence.toString().toLower());
entry.insert(qsl("command"), j->second); entry.insert(qsl("command"), j->second);
@@ -396,7 +401,7 @@ void Manager::writeDefaultFile() {
file.write(document.toJson(QJsonDocument::Indented)); file.write(document.toJson(QJsonDocument::Indented));
} }
void Manager::set(const QString &keys, Command command) { void Manager::set(const QString &keys, Command command, bool replace) {
if (keys.isEmpty()) { if (keys.isEmpty()) {
return; return;
} }
@@ -421,22 +426,25 @@ void Manager::set(const QString &keys, Command command) {
if (isMediaShortcut || isSupportShortcut) { if (isMediaShortcut || isSupportShortcut) {
shortcut->setEnabled(false); shortcut->setEnabled(false);
} }
const auto id = shortcut->id(); auto id = shortcut->id();
auto i = _shortcuts.find(result);
if (i == end(_shortcuts)) {
i = _shortcuts.emplace(result, std::move(shortcut)).first;
} else if (replace) {
unregister(std::exchange(i->second, std::move(shortcut)));
} else {
shortcut = nullptr;
id = i->second->id();
}
if (!id) { if (!id) {
_errors.push_back(qsl("Could not create shortcut '%1'!").arg(keys)); _errors.push_back(qsl("Could not create shortcut '%1'!").arg(keys));
return; return;
} }
auto i = _shortcuts.find(result);
if (i == end(_shortcuts)) {
i = _shortcuts.emplace(result, std::move(shortcut)).first;
} else {
unregister(std::exchange(i->second, std::move(shortcut)));
}
_commandByShortcutId.emplace(id, command); _commandByShortcutId.emplace(id, command);
if (isMediaShortcut) { if (shortcut && isMediaShortcut) {
_mediaShortcuts.emplace(i->second.get()); _mediaShortcuts.emplace(i->second.get());
} }
if (isSupportShortcut) { if (shortcut && isSupportShortcut) {
_supportShortcuts.emplace(i->second.get()); _supportShortcuts.emplace(i->second.get());
} }
} }
@@ -471,11 +479,13 @@ Manager Data;
} // namespace } // namespace
Request::Request(Command command) : _command(command) { Request::Request(std::vector<Command> commands)
: _commands(std::move(commands)) {
} }
bool Request::check(Command command, int priority) { bool Request::check(Command command, int priority) {
if (_command == command && priority > _handlerPriority) { if (ranges::contains(_commands, command)
&& priority > _handlerPriority) {
_handlerPriority = priority; _handlerPriority = priority;
return true; return true;
} }
@@ -487,12 +497,16 @@ bool Request::handle(FnMut<bool()> handler) {
return true; return true;
} }
FnMut<bool()> RequestHandler(Command command) { FnMut<bool()> RequestHandler(std::vector<Command> commands) {
auto request = Request(command); auto request = Request(std::move(commands));
RequestsStream.fire(&request); RequestsStream.fire(&request);
return std::move(request._handler); return std::move(request._handler);
} }
FnMut<bool()> RequestHandler(Command command) {
return RequestHandler(std::vector<Command>{ command });
}
bool Launch(Command command) { bool Launch(Command command) {
if (auto handler = RequestHandler(command)) { if (auto handler = RequestHandler(command)) {
return handler(); return handler();
@@ -500,6 +514,13 @@ bool Launch(Command command) {
return false; return false;
} }
bool Launch(std::vector<Command> commands) {
if (auto handler = RequestHandler(std::move(commands))) {
return handler();
}
return false;
}
rpl::producer<not_null<Request*>> Requests() { rpl::producer<not_null<Request*>> Requests() {
return RequestsStream.events(); return RequestsStream.events();
} }
@@ -515,10 +536,7 @@ const QStringList &Errors() {
} }
bool HandleEvent(not_null<QShortcutEvent*> event) { bool HandleEvent(not_null<QShortcutEvent*> event) {
if (const auto command = Data.lookup(event->shortcutId())) { return Launch(Data.lookup(event->shortcutId()));
return Launch(*command);
}
return false;
} }
void ToggleMediaShortcuts(bool toggled) { void ToggleMediaShortcuts(bool toggled) {

View File

@@ -35,16 +35,14 @@ enum class Command {
ChatPinned4, ChatPinned4,
ChatPinned5, ChatPinned5,
ShowAllChats,
ShowFolder1, ShowFolder1,
ShowFolder2, ShowFolder2,
ShowFolder3, ShowFolder3,
ShowFolder4, ShowFolder4,
ShowFolder5, ShowFolder5,
ShowFolder6, ShowFolder6,
ShowFolder7, ShowFolderLast,
ShowFolder8,
ShowFolder9,
ShowFolder10,
FolderNext, FolderNext,
FolderPrevious, FolderPrevious,
@@ -65,16 +63,14 @@ enum class Command {
}; };
constexpr auto kShowFolder = { constexpr auto kShowFolder = {
Command::ShowAllChats,
Command::ShowFolder1, Command::ShowFolder1,
Command::ShowFolder2, Command::ShowFolder2,
Command::ShowFolder3, Command::ShowFolder3,
Command::ShowFolder4, Command::ShowFolder4,
Command::ShowFolder5, Command::ShowFolder5,
Command::ShowFolder6, Command::ShowFolder6,
Command::ShowFolder7, Command::ShowFolderLast,
Command::ShowFolder8,
Command::ShowFolder9,
Command::ShowFolder10,
}; };
[[nodiscard]] FnMut<bool()> RequestHandler(Command command); [[nodiscard]] FnMut<bool()> RequestHandler(Command command);
@@ -85,13 +81,13 @@ public:
bool handle(FnMut<bool()> handler); bool handle(FnMut<bool()> handler);
private: private:
explicit Request(Command command); explicit Request(std::vector<Command> commands);
Command _command; std::vector<Command> _commands;
int _handlerPriority = -1; int _handlerPriority = -1;
FnMut<bool()> _handler; FnMut<bool()> _handler;
friend FnMut<bool()> RequestHandler(Command command); friend FnMut<bool()> RequestHandler(std::vector<Command> commands);
}; };

View File

@@ -22,8 +22,8 @@ constexpr auto AppId = "{C4A4AE8F-B9F7-4CC7-8A6C-BF7EEE87ACA5}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs; constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Kotatogram Desktop"_cs; constexpr auto AppName = "Kotatogram Desktop"_cs;
constexpr auto AppFile = "Kotatogram"_cs; constexpr auto AppFile = "Kotatogram"_cs;
constexpr auto AppVersion = 2000000; constexpr auto AppVersion = 2000001;
constexpr auto AppVersionStr = "2.0"; constexpr auto AppVersionStr = "2.0.1";
constexpr auto AppBetaVersion = false; constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
constexpr auto AppKotatoVersion = 1002001; constexpr auto AppKotatoVersion = 1002001;

View File

@@ -87,6 +87,14 @@ dialogsTextPaletteArchiveActive: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgActive; linkFg: dialogsTextFgActive;
} }
dialogsEmptyHeight: 160px;
dialogsEmptySkip: 2px;
dialogsEmptyLabel: FlatLabel(defaultFlatLabel) {
minWidth: 32px;
align: align(top);
textFg: windowSubTextFg;
}
dialogsMenuToggle: IconButton { dialogsMenuToggle: IconButton {
width: 40px; width: 40px;
height: 40px; height: 40px;

View File

@@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/shortcuts.h" #include "core/shortcuts.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "ui/text/text_utilities.h"
#include "ui/text_options.h" #include "ui/text_options.h"
#include "ui/ui_utility.h" #include "ui/ui_utility.h"
#include "data/data_drafts.h" #include "data/data_drafts.h"
@@ -123,8 +124,6 @@ InnerWidget::InnerWidget(
, _pinnedShiftAnimation([=](crl::time now) { , _pinnedShiftAnimation([=](crl::time now) {
return pinnedShiftAnimationCallback(now); return pinnedShiftAnimationCallback(now);
}) })
, _addContactLnk(this, tr::lng_add_contact_button(tr::now))
, _editFilterLnk(this, tr::lng_filters_context_edit(tr::now))
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer) , _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) { , _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
@@ -132,8 +131,6 @@ InnerWidget::InnerWidget(
setAttribute(Qt::WA_OpaquePaintEvent, true); setAttribute(Qt::WA_OpaquePaintEvent, true);
#endif // OS_MAC_OLD #endif // OS_MAC_OLD
_addContactLnk->addClickHandler([] { App::wnd()->onShowAddContact(); });
_editFilterLnk->addClickHandler([=] { editOpenedFilter(); });
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); }); _cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
_cancelSearchInChat->hide(); _cancelSearchInChat->hide();
_cancelSearchFromUser->setClickedCallback([=] { _cancelSearchFromUser->setClickedCallback([=] {
@@ -154,6 +151,7 @@ InnerWidget::InnerWidget(
session().data().contactsLoaded().changes( session().data().contactsLoaded().changes(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
refresh(); refresh();
refreshEmptyLabel();
}, lifetime()); }, lifetime());
session().data().itemRemoved( session().data().itemRemoved(
@@ -196,7 +194,9 @@ InnerWidget::InnerWidget(
setupOnlineStatusCheck(); setupOnlineStatusCheck();
session().data().chatsListChanges( rpl::merge(
session().data().chatsListChanges(),
session().data().chatsListLoadedEvents()
) | rpl::filter([=](Data::Folder *folder) { ) | rpl::filter([=](Data::Folder *folder) {
return (folder == _openedFolder); return (folder == _openedFolder);
}) | rpl::start_with_next([=] { }) | rpl::start_with_next([=] {
@@ -511,19 +511,6 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
} }
if (!otherStart) { if (!otherStart) {
p.fillRect(dialogsClip, st::dialogsBg); p.fillRect(dialogsClip, st::dialogsBg);
p.setFont(st::noContactsFont);
p.setPen(st::noContactsColor);
const auto phrase = _filterId
? (session().data().chatsList()->loaded()
? tr::lng_no_chats_filter(tr::now)
: tr::lng_contacts_loading(tr::now))
: session().data().contactsLoaded().current()
? tr::lng_no_chats(tr::now)
: tr::lng_contacts_loading(tr::now);
p.drawText(
QRect(0, 0, fullWidth, st::noContactsHeight - (session().data().contactsLoaded().current() ? st::noContactsFont->height : 0)),
phrase,
style::al_center);
} }
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
if (!_hashtagResults.empty()) { if (!_hashtagResults.empty()) {
@@ -1441,8 +1428,7 @@ void InnerWidget::setSearchedPressed(int pressed) {
} }
void InnerWidget::resizeEvent(QResizeEvent *e) { void InnerWidget::resizeEvent(QResizeEvent *e) {
_addContactLnk->move((width() - _addContactLnk->width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); resizeEmptyLabel();
_editFilterLnk->move((width() - _editFilterLnk->width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
const auto widthForCancelButton = qMax(width(), st::columnMinimalWidthLeft); const auto widthForCancelButton = qMax(width(), st::columnMinimalWidthLeft);
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width(); const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width();
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2; const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
@@ -2231,19 +2217,12 @@ void InnerWidget::refresh(bool toTop) {
if (needCollapsedRowsRefresh()) { if (needCollapsedRowsRefresh()) {
return refreshWithCollapsedRows(toTop); return refreshWithCollapsedRows(toTop);
} }
refreshEmptyLabel();
const auto list = shownDialogs(); const auto list = shownDialogs();
_addContactLnk->setVisible(!_filterId
&& (_state == WidgetState::Default)
&& list->empty()
&& session().data().contactsLoaded().current());
_editFilterLnk->setVisible((_filterId > 0)
&& (_state == WidgetState::Default)
&& list->empty()
&& session().data().chatsList()->loaded());
auto h = 0; auto h = 0;
if (_state == WidgetState::Default) { if (_state == WidgetState::Default) {
if (list->empty()) { if (list->empty()) {
h = st::noContactsHeight; h = st::dialogsEmptyHeight;
} else { } else {
h = dialogsOffset() + list->size() * DialogsRowHeight(); h = dialogsOffset() + list->size() * DialogsRowHeight();
} }
@@ -2266,6 +2245,69 @@ void InnerWidget::refresh(bool toTop) {
update(); update();
} }
void InnerWidget::refreshEmptyLabel() {
const auto data = &session().data();
const auto state = !shownDialogs()->empty()
? EmptyState::None
: (!_filterId && data->contactsLoaded().current())
? EmptyState::NoContacts
: (_filterId > 0) && data->chatsList()->loaded()
? EmptyState::EmptyFolder
: EmptyState::Loading;
if (state == EmptyState::None) {
_emptyState = state;
_empty.destroy();
return;
} else if (_emptyState == state) {
_empty->setVisible(_state == WidgetState::Default);
return;
}
_emptyState = state;
auto phrase = (state == EmptyState::NoContacts)
? tr::lng_no_chats()
: (state == EmptyState::EmptyFolder)
? tr::lng_no_chats_filter()
: tr::lng_contacts_loading();
auto link = (state == EmptyState::NoContacts)
? tr::lng_add_contact_button()
: (state == EmptyState::EmptyFolder)
? tr::lng_filters_context_edit()
: rpl::single(QString());
auto full = rpl::combine(
std::move(phrase),
std::move(link)
) | rpl::map([](const QString &phrase, const QString &link) {
auto result = Ui::Text::WithEntities(phrase);
if (!link.isEmpty()) {
result.append("\n\n").append(Ui::Text::Link(link));
}
return result;
});
_empty.create(this, std::move(full), st::dialogsEmptyLabel);
resizeEmptyLabel();
_empty->setClickHandlerFilter([=](const auto &...) {
if (_emptyState == EmptyState::NoContacts) {
App::wnd()->onShowAddContact();
} else if (_emptyState == EmptyState::EmptyFolder) {
editOpenedFilter();
}
return false;
});
_empty->setVisible(_state == WidgetState::Default);
}
void InnerWidget::resizeEmptyLabel() {
if (!_empty) {
return;
}
const auto useWidth = std::min(
_empty->naturalWidth(),
width() - 2 * st::dialogsEmptySkip);
const auto left = (width() - useWidth) / 2;
_empty->resizeToWidth(useWidth);
_empty->move(left, (st::dialogsEmptyHeight - _empty->height()) / 2);
}
void InnerWidget::clearMouseSelection(bool clearSelection) { void InnerWidget::clearMouseSelection(bool clearSelection) {
_mouseSelection = false; _mouseSelection = false;
_lastMousePosition = std::nullopt; _lastMousePosition = std::nullopt;
@@ -2611,6 +2653,7 @@ void InnerWidget::switchToFilter(FilterId filterId) {
_filterId = filterId; _filterId = filterId;
refreshWithCollapsedRows(true); refreshWithCollapsedRows(true);
} }
refreshEmptyLabel();
} }
bool InnerWidget::chooseHashtag() { bool InnerWidget::chooseHashtag() {
@@ -3048,6 +3091,27 @@ void InnerWidget::setupShortcuts() {
return false; return false;
}); });
const auto filters = &session().data().chatsFilters().list();
if (const auto filtersCount = int(filters->size())) {
auto &&folders = ranges::view::zip(
Shortcuts::kShowFolder,
ranges::view::ints(0, ranges::unreachable));
for (const auto [command, index] : folders) {
const auto select = (command == Command::ShowFolderLast)
? filtersCount
: std::clamp(index, 0, filtersCount);
request->check(command) && request->handle([=] {
if (select <= filtersCount) {
_controller->setActiveChatsFilter((select > 0)
? (*filters)[select - 1].id()
: 0);
}
return true;
});
}
}
static const auto kPinned = { static const auto kPinned = {
Command::ChatPinned1, Command::ChatPinned1,
Command::ChatPinned2, Command::ChatPinned2,
@@ -3076,42 +3140,23 @@ void InnerWidget::setupShortcuts() {
}); });
} }
auto &&folders = ranges::view::zip(
Shortcuts::kShowFolder,
ranges::view::ints(0, ranges::unreachable));
for (const auto [command, index] : folders) {
request->check(command) && request->handle([=, index = index] {
const auto list = &session().data().chatsFilters().list();
if (index >= list->size()) {
return false;
}
const auto filterId = list->at(index).id();
_controller->setActiveChatsFilter((filterId == _filterId)
? 0
: filterId);
return true;
});
}
const auto nearFolder = [=](bool isNext) { const auto nearFolder = [=](bool isNext) {
const auto id = _controller->activeChatsFilterCurrent(); const auto id = _controller->activeChatsFilterCurrent();
const auto list = &session().data().chatsFilters().list(); const auto list = &session().data().chatsFilters().list();
const auto it = (id == 0) const auto index = (id != 0)
? begin(*list) - 1 ? int(ranges::find(*list, id, &Data::ChatFilter::id)
: ranges::find(*list, id, &Data::ChatFilter::id); - begin(*list))
if (it == end(*list) && id != 0) { : -1;
if (index == list->size() && id != 0) {
return false; return false;
} }
const auto i = isNext ? 1 : -1; const auto changed = index + (isNext ? 1 : -1);
const auto index = it - begin(*list) + i; if (changed >= int(list->size()) || changed < -1) {
if (index >= (int)list->size() || index < -1) {
return false; return false;
} }
const auto filterId = (index == -1) _controller->setActiveChatsFilter((changed >= 0)
? 0 ? (*list)[changed].id()
: list->at(index).id(); : 0);
_controller->setActiveChatsFilter(filterId);
return true; return true;
}; };

View File

@@ -22,7 +22,7 @@ class Session;
namespace Ui { namespace Ui {
class IconButton; class IconButton;
class PopupMenu; class PopupMenu;
class LinkButton; class FlatLabel;
} // namespace Ui } // namespace Ui
namespace Window { namespace Window {
@@ -97,6 +97,8 @@ public:
void clearFilter(); void clearFilter();
void refresh(bool toTop = false); void refresh(bool toTop = false);
void refreshEmptyLabel();
void resizeEmptyLabel();
bool chooseRow(); bool chooseRow();
@@ -168,6 +170,13 @@ private:
NextOrOriginal, NextOrOriginal,
}; };
enum class EmptyState : uchar {
None,
Loading,
NoContacts,
EmptyFolder,
};
Main::Session &session() const; Main::Session &session() const;
void dialogRowReplaced(Row *oldRow, Row *newRow); void dialogRowReplaced(Row *oldRow, Row *newRow);
@@ -357,6 +366,7 @@ private:
int _filteredPressed = -1; int _filteredPressed = -1;
bool _waitingForSearch = false; bool _waitingForSearch = false;
EmptyState _emptyState = EmptyState::None;
QString _peerSearchQuery; QString _peerSearchQuery;
std::vector<std::unique_ptr<PeerSearchResult>> _peerSearchResults; std::vector<std::unique_ptr<PeerSearchResult>> _peerSearchResults;
@@ -376,8 +386,7 @@ private:
WidgetState _state = WidgetState::Default; WidgetState _state = WidgetState::Default;
object_ptr<Ui::LinkButton> _addContactLnk; object_ptr<Ui::FlatLabel> _empty = { nullptr };
object_ptr<Ui::LinkButton> _editFilterLnk;
object_ptr<Ui::IconButton> _cancelSearchInChat; object_ptr<Ui::IconButton> _cancelSearchInChat;
object_ptr<Ui::IconButton> _cancelSearchFromUser; object_ptr<Ui::IconButton> _cancelSearchFromUser;

View File

@@ -1948,12 +1948,6 @@ void History::setFolderPointer(Data::Folder *folder) {
const auto wasInList = inChatList(); const auto wasInList = inChatList();
if (wasInList) { if (wasInList) {
removeFromChatList(0, owner().chatsList(this->folder())); removeFromChatList(0, owner().chatsList(this->folder()));
for (const auto &filter : filters.list()) {
const auto id = filter.id();
if (inChatList(id)) {
removeFromChatList(id, filters.chatsList(id));
}
}
} }
const auto was = _folder.value_or(nullptr); const auto was = _folder.value_or(nullptr);
_folder = folder; _folder = folder;
@@ -1962,12 +1956,10 @@ void History::setFolderPointer(Data::Folder *folder) {
} }
if (wasInList) { if (wasInList) {
addToChatList(0, owner().chatsList(folder)); addToChatList(0, owner().chatsList(folder));
for (const auto &filter : filters.list()) {
if (filter.contains(this)) { owner().chatsFilters().refreshHistory(this);
const auto id = filter.id(); updateChatListEntry();
addToChatList(id, filters.chatsList(id));
}
}
owner().chatsListChanged(was); owner().chatsListChanged(was);
owner().chatsListChanged(folder); owner().chatsListChanged(folder);
} else if (!wasKnown) { } else if (!wasKnown) {

View File

@@ -1,7 +1,7 @@
AppVersion 2000000 AppVersion 2000001
AppVersionStrMajor 2.0 AppVersionStrMajor 2.0
AppVersionStrSmall 2.0 AppVersionStrSmall 2.0.1
AppVersionStr 2.0.0 AppVersionStr 2.0.1
BetaChannel 0 BetaChannel 0
AlphaVersion 0 AlphaVersion 0
AppVersionOriginal 2.0 AppVersionOriginal 2.0.1

View File

@@ -1,3 +1,9 @@
2.0.1 (31.03.20)
- Switch between folders using Ctrl+1, ..., Ctrl+8.
- Fix crash when a pinned in folder chat was added to archive.
- Fix font issues in Linux version.
2.0 (30.03.20) 2.0 (30.03.20)
- Organize chats into Chat Folders if you have too many chats. - Organize chats into Chat Folders if you have too many chats.