[Improvement] Jump to date and time
This commit is contained in:
parent
34dddff858
commit
72bbf3ea58
15 changed files with 190 additions and 57 deletions
BIN
Telegram/Resources/icons/menu/to_beginning.png
Normal file
BIN
Telegram/Resources/icons/menu/to_beginning.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 195 B |
BIN
Telegram/Resources/icons/menu/to_beginning@2x.png
Normal file
BIN
Telegram/Resources/icons/menu/to_beginning@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 313 B |
BIN
Telegram/Resources/icons/menu/to_beginning@3x.png
Normal file
BIN
Telegram/Resources/icons/menu/to_beginning@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 418 B |
|
|
@ -177,6 +177,10 @@
|
||||||
"ktg_settings_compress_images_default": "Compress images by default",
|
"ktg_settings_compress_images_default": "Compress images by default",
|
||||||
"ktg_pip_not_supported": "Sorry, Picture-in-Picture mode is not supported here.",
|
"ktg_pip_not_supported": "Sorry, Picture-in-Picture mode is not supported here.",
|
||||||
"ktg_forward_quiz_unquoted": "Sorry, quizzes that are currently open and unvoted on cannot be forwarded unquoted.",
|
"ktg_forward_quiz_unquoted": "Sorry, quizzes that are currently open and unvoted on cannot be forwarded unquoted.",
|
||||||
|
"ktg_jump_to_date_title": "Jump to...",
|
||||||
|
"ktg_jump_to_date_button": "Jump",
|
||||||
|
"ktg_jump_to_beginning": "Jump to beginning",
|
||||||
|
"ktg_show_calendar": "Show calendar",
|
||||||
"ktg_in_app_update_disabled": "In-app updater is disabled.",
|
"ktg_in_app_update_disabled": "In-app updater is disabled.",
|
||||||
"ktg_settings_view_profile_on_top": "Show \"View Profile\" first",
|
"ktg_settings_view_profile_on_top": "Show \"View Profile\" first",
|
||||||
"ktg_settings_view_profile_on_top_about": "This option also enables \"Add \"View Profile\"\" from TDesktop's experimental settings.",
|
"ktg_settings_view_profile_on_top_about": "This option also enables \"Add \"View Profile\"\" from TDesktop's experimental settings.",
|
||||||
|
|
|
||||||
|
|
@ -2958,7 +2958,7 @@ void ApiWrap::readFeaturedSets() {
|
||||||
|
|
||||||
void ApiWrap::resolveJumpToDate(
|
void ApiWrap::resolveJumpToDate(
|
||||||
Dialogs::Key chat,
|
Dialogs::Key chat,
|
||||||
const QDate &date,
|
const QDateTime &date,
|
||||||
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
||||||
if (const auto peer = chat.peer()) {
|
if (const auto peer = chat.peer()) {
|
||||||
const auto topic = chat.topic();
|
const auto topic = chat.topic();
|
||||||
|
|
@ -2971,13 +2971,13 @@ template <typename Callback>
|
||||||
void ApiWrap::requestMessageAfterDate(
|
void ApiWrap::requestMessageAfterDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
const QDate &date,
|
const QDateTime &date,
|
||||||
Callback &&callback) {
|
Callback &&callback) {
|
||||||
// API returns a message with date <= offset_date.
|
// API returns a message with date <= offset_date.
|
||||||
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
|
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
|
||||||
// This should give us the first message with date >= desired_date.
|
// This should give us the first message with date >= desired_date.
|
||||||
const auto offsetId = 0;
|
const auto offsetId = 0;
|
||||||
const auto offsetDate = static_cast<int>(date.startOfDay().toSecsSinceEpoch()) - 1;
|
const auto offsetDate = static_cast<int>(date.toSecsSinceEpoch()) - 1;
|
||||||
const auto addOffset = -1;
|
const auto addOffset = -1;
|
||||||
const auto limit = 1;
|
const auto limit = 1;
|
||||||
const auto maxId = 0;
|
const auto maxId = 0;
|
||||||
|
|
@ -3054,7 +3054,7 @@ void ApiWrap::requestMessageAfterDate(
|
||||||
void ApiWrap::resolveJumpToHistoryDate(
|
void ApiWrap::resolveJumpToHistoryDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
const QDate &date,
|
const QDateTime &date,
|
||||||
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
Fn<void(not_null<PeerData*>, MsgId)> callback) {
|
||||||
if (const auto channel = peer->migrateTo()) {
|
if (const auto channel = peer->migrateTo()) {
|
||||||
return resolveJumpToHistoryDate(
|
return resolveJumpToHistoryDate(
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ public:
|
||||||
|
|
||||||
void resolveJumpToDate(
|
void resolveJumpToDate(
|
||||||
Dialogs::Key chat,
|
Dialogs::Key chat,
|
||||||
const QDate &date,
|
const QDateTime &date,
|
||||||
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
||||||
|
|
||||||
using SliceType = Data::LoadDirection;
|
using SliceType = Data::LoadDirection;
|
||||||
|
|
@ -495,13 +495,13 @@ private:
|
||||||
void resolveJumpToHistoryDate(
|
void resolveJumpToHistoryDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
const QDate &date,
|
const QDateTime &date,
|
||||||
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void requestMessageAfterDate(
|
void requestMessageAfterDate(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId topicRootId,
|
MsgId topicRootId,
|
||||||
const QDate &date,
|
const QDateTime &date,
|
||||||
Callback &&callback);
|
Callback &&callback);
|
||||||
|
|
||||||
void sharedMediaDone(
|
void sharedMediaDone(
|
||||||
|
|
|
||||||
|
|
@ -2937,7 +2937,7 @@ void Widget::clearSearchCache() {
|
||||||
|
|
||||||
void Widget::showCalendar() {
|
void Widget::showCalendar() {
|
||||||
if (_searchInChat) {
|
if (_searchInChat) {
|
||||||
controller()->showCalendar(_searchInChat, QDate());
|
controller()->showCalendar(_searchInChat, QDateTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3788,9 +3788,9 @@ void HistoryInner::mouseActionUpdate() {
|
||||||
|
|
||||||
if (point.x() >= dateLeft && point.x() < dateLeft + dateWidth) {
|
if (point.x() >= dateLeft && point.x() < dateLeft + dateWidth) {
|
||||||
if (!_scrollDateLink) {
|
if (!_scrollDateLink) {
|
||||||
_scrollDateLink = std::make_shared<Window::DateClickHandler>(item->history(), view->dateTime().date());
|
_scrollDateLink = std::make_shared<Window::DateClickHandler>(item->history(), view->dateTime());
|
||||||
} else {
|
} else {
|
||||||
static_cast<Window::DateClickHandler*>(_scrollDateLink.get())->setDate(view->dateTime().date());
|
static_cast<Window::DateClickHandler*>(_scrollDateLink.get())->setDate(view->dateTime());
|
||||||
}
|
}
|
||||||
dragState = TextState(
|
dragState = TextState(
|
||||||
nullptr,
|
nullptr,
|
||||||
|
|
|
||||||
|
|
@ -990,7 +990,7 @@ ComposeSearch::Inner::Inner(
|
||||||
_bottomBar->showCalendarRequests(
|
_bottomBar->showCalendarRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
hideList();
|
hideList();
|
||||||
_window->showCalendar({ _history }, QDate());
|
_window->showCalendar({ _history }, QDateTime());
|
||||||
}, _bottomBar->lifetime());
|
}, _bottomBar->lifetime());
|
||||||
|
|
||||||
_bottomBar->showBoxFromRequests(
|
_bottomBar->showBoxFromRequests(
|
||||||
|
|
|
||||||
|
|
@ -2541,7 +2541,7 @@ void RepliesWidget::listUpdateDateLink(
|
||||||
link = nullptr;
|
link = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto date = view->dateTime().date();
|
const auto date = view->dateTime();
|
||||||
if (!link) {
|
if (!link) {
|
||||||
link = std::make_shared<Window::DateClickHandler>(_topic, date);
|
link = std::make_shared<Window::DateClickHandler>(_topic, date);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ public:
|
||||||
|
|
||||||
void skipMonth(int skip);
|
void skipMonth(int skip);
|
||||||
void showMonth(QDate month);
|
void showMonth(QDate month);
|
||||||
|
void skipDays(int skip);
|
||||||
[[nodiscard]] bool showsMonthOf(QDate date) const;
|
[[nodiscard]] bool showsMonthOf(QDate date) const;
|
||||||
|
|
||||||
[[nodiscard]] int highlightedIndex() const {
|
[[nodiscard]] int highlightedIndex() const {
|
||||||
|
|
@ -68,6 +69,9 @@ public:
|
||||||
[[nodiscard]] bool isEnabled(int index) const {
|
[[nodiscard]] bool isEnabled(int index) const {
|
||||||
return (index >= _minDayIndex) && (index <= _maxDayIndex);
|
return (index >= _minDayIndex) && (index <= _maxDayIndex);
|
||||||
}
|
}
|
||||||
|
QDate highlighted() const {
|
||||||
|
return _highlighted;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] QDate month() const {
|
[[nodiscard]] QDate month() const {
|
||||||
return _month.current();
|
return _month.current();
|
||||||
|
|
@ -99,6 +103,7 @@ private:
|
||||||
|
|
||||||
static int DaysShiftForMonth(QDate month, QDate min);
|
static int DaysShiftForMonth(QDate month, QDate min);
|
||||||
static int RowsCountForMonth(QDate month, QDate min, QDate max);
|
static int RowsCountForMonth(QDate month, QDate min, QDate max);
|
||||||
|
void setHighlightedDate(QDate highlighted);
|
||||||
|
|
||||||
bool _allowsSelection = false;
|
bool _allowsSelection = false;
|
||||||
|
|
||||||
|
|
@ -197,6 +202,36 @@ void CalendarBox::Context::skipMonth(int skip) {
|
||||||
showMonth(QDate(year, month, 1));
|
showMonth(QDate(year, month, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CalendarBox::Context::skipDays(int skip) {
|
||||||
|
auto date = _highlighted;
|
||||||
|
|
||||||
|
if (_month.current().month() == _highlighted.month()
|
||||||
|
&& _month.current().year() == _highlighted.year()) {
|
||||||
|
date = date.addDays(skip);
|
||||||
|
} else if (skip < 0) {
|
||||||
|
date = QDate(
|
||||||
|
_month.current().year(),
|
||||||
|
_month.current().month(),
|
||||||
|
_month.current().daysInMonth());
|
||||||
|
} else {
|
||||||
|
date = QDate(
|
||||||
|
_month.current().year(),
|
||||||
|
_month.current().month(),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date.isValid() && date >= _min && date <= _max) {
|
||||||
|
auto needMonthChange = (date.month() != _highlighted.month()
|
||||||
|
|| date.year() != _highlighted.year());
|
||||||
|
|
||||||
|
setHighlightedDate(date);
|
||||||
|
|
||||||
|
if (needMonthChange) {
|
||||||
|
showMonth(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int CalendarBox::Context::DaysShiftForMonth(QDate month, QDate min) {
|
int CalendarBox::Context::DaysShiftForMonth(QDate month, QDate min) {
|
||||||
Expects(!month.isNull());
|
Expects(!month.isNull());
|
||||||
|
|
||||||
|
|
@ -245,6 +280,12 @@ int CalendarBox::Context::RowsCountForMonth(
|
||||||
return cellsFull / kDaysInWeek;
|
return cellsFull / kDaysInWeek;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CalendarBox::Context::setHighlightedDate(QDate highlighted) {
|
||||||
|
_highlighted = highlighted;
|
||||||
|
_highlightedIndex = _month.current().daysTo(_highlighted);
|
||||||
|
applyMonth(_month.current(), true);
|
||||||
|
}
|
||||||
|
|
||||||
QDate CalendarBox::Context::dateFromIndex(int index) const {
|
QDate CalendarBox::Context::dateFromIndex(int index) const {
|
||||||
constexpr auto kMonthsCount = 12;
|
constexpr auto kMonthsCount = 12;
|
||||||
auto month = _month.current().month();
|
auto month = _month.current().month();
|
||||||
|
|
@ -350,6 +391,9 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] int countMaxHeight() const;
|
[[nodiscard]] int countMaxHeight() const;
|
||||||
void setDateChosenCallback(Fn<void(QDate)> callback);
|
void setDateChosenCallback(Fn<void(QDate)> callback);
|
||||||
|
void selectBeginning();
|
||||||
|
void selectEnd();
|
||||||
|
void selectHighlighted();
|
||||||
|
|
||||||
~Inner();
|
~Inner();
|
||||||
|
|
||||||
|
|
@ -728,6 +772,18 @@ void CalendarBox::Inner::setDateChosenCallback(Fn<void(QDate)> callback) {
|
||||||
_dateChosenCallback = std::move(callback);
|
_dateChosenCallback = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CalendarBox::Inner::selectBeginning() {
|
||||||
|
_dateChosenCallback(_context->dateFromIndex(_context->minDayIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalendarBox::Inner::selectEnd() {
|
||||||
|
_dateChosenCallback(_context->dateFromIndex(_context->maxDayIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalendarBox::Inner::selectHighlighted() {
|
||||||
|
_dateChosenCallback(_context->highlighted());
|
||||||
|
}
|
||||||
|
|
||||||
CalendarBox::Inner::~Inner() = default;
|
CalendarBox::Inner::~Inner() = default;
|
||||||
|
|
||||||
class CalendarBox::Title final : public RpWidget {
|
class CalendarBox::Title final : public RpWidget {
|
||||||
|
|
@ -1135,14 +1191,20 @@ void CalendarBox::keyPressEvent(QKeyEvent *e) {
|
||||||
jump(_previous.data());
|
jump(_previous.data());
|
||||||
} else if (e->key() == Qt::Key_End) {
|
} else if (e->key() == Qt::Key_End) {
|
||||||
jump(_next.data());
|
jump(_next.data());
|
||||||
} else if (e->key() == Qt::Key_Left
|
} else if (e->key() == Qt::Key_PageUp) {
|
||||||
|| e->key() == Qt::Key_Up
|
|
||||||
|| e->key() == Qt::Key_PageUp) {
|
|
||||||
goPreviousMonth();
|
goPreviousMonth();
|
||||||
} else if (e->key() == Qt::Key_Right
|
} else if (e->key() == Qt::Key_PageDown) {
|
||||||
|| e->key() == Qt::Key_Down
|
|
||||||
|| e->key() == Qt::Key_PageDown) {
|
|
||||||
goNextMonth();
|
goNextMonth();
|
||||||
|
} else if (e->key() == Qt::Key_Left) {
|
||||||
|
_context->skipDays(-1);
|
||||||
|
} else if (e->key() == Qt::Key_Right) {
|
||||||
|
_context->skipDays(1);
|
||||||
|
} else if (e->key() == Qt::Key_Up) {
|
||||||
|
_context->skipDays(-7);
|
||||||
|
} else if (e->key() == Qt::Key_Down) {
|
||||||
|
_context->skipDays(7);
|
||||||
|
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
|
||||||
|
_inner->selectHighlighted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,7 @@ namespace {
|
||||||
constexpr auto kMinimalSchedule = TimeId(10);
|
constexpr auto kMinimalSchedule = TimeId(10);
|
||||||
|
|
||||||
QString DayString(const QDate &date) {
|
QString DayString(const QDate &date) {
|
||||||
return tr::lng_month_day(
|
return langDayOfMonthFull(date);
|
||||||
tr::now,
|
|
||||||
lt_month,
|
|
||||||
Lang::MonthDay(date.month())(tr::now),
|
|
||||||
lt_day,
|
|
||||||
QString::number(date.day()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TimeString(QTime time) {
|
QString TimeString(QTime time) {
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ menuIconPorn: icon {{ "menu/porn", menuIconColor }};
|
||||||
menuIconViolence: icon {{ "menu/violence", menuIconColor }};
|
menuIconViolence: icon {{ "menu/violence", menuIconColor }};
|
||||||
menuIconHide: icon {{ "menu/hide", menuIconColor }};
|
menuIconHide: icon {{ "menu/hide", menuIconColor }};
|
||||||
menuIconMention: icon {{ "menu/mention", menuSubmenuArrowFg }};
|
menuIconMention: icon {{ "menu/mention", menuSubmenuArrowFg }};
|
||||||
|
menuIconToBeginning: icon {{ "menu/to_beginning", menuSubmenuArrowFg }};
|
||||||
menuIconMuteFor: icon {{ "menu/mute_for", menuIconColor }};
|
menuIconMuteFor: icon {{ "menu/mute_for", menuIconColor }};
|
||||||
menuIconSilent: icon {{ "menu/silent", menuIconColor }};
|
menuIconSilent: icon {{ "menu/silent", menuIconColor }};
|
||||||
menuIconCustomize: icon {{ "menu/customize", menuIconColor }};
|
menuIconCustomize: icon {{ "menu/customize", menuIconColor }};
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
|
||||||
|
#include "kotato/kotato_settings.h"
|
||||||
|
#include "kotato/kotato_lang.h"
|
||||||
#include "api/api_text_entities.h"
|
#include "api/api_text_entities.h"
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
#include "boxes/peers/add_bot_to_chat_box.h"
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
|
|
@ -64,9 +66,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "calls/calls_instance.h" // Core::App().calls().inCall().
|
#include "calls/calls_instance.h" // Core::App().calls().inCall().
|
||||||
#include "calls/group/calls_group_call.h"
|
#include "calls/group/calls_group_call.h"
|
||||||
|
#include "ui/boxes/choose_date_time.h"
|
||||||
#include "ui/boxes/calendar_box.h"
|
#include "ui/boxes/calendar_box.h"
|
||||||
#include "ui/boxes/collectible_info_box.h"
|
#include "ui/boxes/collectible_info_box.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/dynamic_thumbnails.h"
|
#include "ui/dynamic_thumbnails.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "main/main_app_config.h"
|
#include "main/main_app_config.h"
|
||||||
|
|
@ -92,6 +96,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
#include "styles/style_layers.h" // st::boxLabel
|
#include "styles/style_layers.h" // st::boxLabel
|
||||||
|
#include "styles/style_info.h"
|
||||||
|
#include "styles/style_menu_icons.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -303,6 +309,53 @@ void MainWindowShow::processChosenSticker(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChooseJumpDateTimeBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
QDateTime minDate,
|
||||||
|
QDateTime maxDate,
|
||||||
|
QDateTime highlighted,
|
||||||
|
Fn<void(TimeId)> onDone,
|
||||||
|
Fn<void()> onBegnning,
|
||||||
|
Fn<void()> onCalendar,
|
||||||
|
bool hasCalendar) {
|
||||||
|
|
||||||
|
auto descriptor = Ui::ChooseDateTimeBox(box,
|
||||||
|
Ui::ChooseDateTimeBoxArgs{
|
||||||
|
.title = rktr("ktg_jump_to_date_title"),
|
||||||
|
.submit = rktr("ktg_jump_to_date_button"),
|
||||||
|
.done = std::move(onDone),
|
||||||
|
.min = [=] { return base::unixtime::serialize(minDate); },
|
||||||
|
.time = base::unixtime::serialize(highlighted),
|
||||||
|
.max = [=] { return base::unixtime::serialize(maxDate); },
|
||||||
|
});
|
||||||
|
const auto topMenuButton = box->addTopButton(st::infoTopBarMenu);
|
||||||
|
const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
|
||||||
|
topMenuButton.data()->setClickedCallback([=] {
|
||||||
|
*menu = base::make_unique_q<Ui::PopupMenu>(
|
||||||
|
topMenuButton.data(),
|
||||||
|
st::popupMenuWithIcons);
|
||||||
|
(*menu)->addAction(
|
||||||
|
ktr("ktg_jump_to_beginning"),
|
||||||
|
std::move(onBegnning),
|
||||||
|
&st::menuIconToBeginning);
|
||||||
|
if (hasCalendar) {
|
||||||
|
(*menu)->addAction(
|
||||||
|
ktr("ktg_show_calendar"),
|
||||||
|
std::move(onCalendar),
|
||||||
|
&st::menuIconSchedule);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*menu)->setForcedOrigin(Ui::PanelAnimation::Origin::TopRight);
|
||||||
|
const auto buttonTopLeft = topMenuButton.data()->mapToGlobal(QPoint());
|
||||||
|
const auto buttonRect = QRect(buttonTopLeft, topMenuButton.data()->size());
|
||||||
|
const auto pos = QPoint(
|
||||||
|
buttonRect.x() + buttonRect.width(),
|
||||||
|
buttonRect.y() + buttonRect.height());
|
||||||
|
(*menu)->popup(pos);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void ActivateWindow(not_null<SessionController*> controller) {
|
void ActivateWindow(not_null<SessionController*> controller) {
|
||||||
|
|
@ -329,13 +382,13 @@ bool operator!=(const PeerThemeOverride &a, const PeerThemeOverride &b) {
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateClickHandler::DateClickHandler(Dialogs::Key chat, QDate date)
|
DateClickHandler::DateClickHandler(Dialogs::Key chat, QDateTime date)
|
||||||
: _chat(chat)
|
: _chat(chat)
|
||||||
, _weak(chat.topic())
|
, _weak(chat.topic())
|
||||||
, _date(date) {
|
, _date(date) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DateClickHandler::setDate(QDate date) {
|
void DateClickHandler::setDate(QDateTime date) {
|
||||||
_date = date;
|
_date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2158,7 +2211,7 @@ void SessionController::startOrJoinGroupCall(
|
||||||
Core::App().calls().startOrJoinGroupCall(uiShow(), peer, args);
|
Core::App().calls().startOrJoinGroupCall(uiShow(), peer, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
void SessionController::showCalendar(Dialogs::Key chat, QDateTime requestedDate) {
|
||||||
const auto topic = chat.topic();
|
const auto topic = chat.topic();
|
||||||
const auto history = chat.owningHistory();
|
const auto history = chat.owningHistory();
|
||||||
if (!history) {
|
if (!history) {
|
||||||
|
|
@ -2167,11 +2220,11 @@ void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||||
const auto currentPeerDate = [&] {
|
const auto currentPeerDate = [&] {
|
||||||
if (topic) {
|
if (topic) {
|
||||||
if (const auto item = topic->lastMessage()) {
|
if (const auto item = topic->lastMessage()) {
|
||||||
return base::unixtime::parse(item->date()).date();
|
return base::unixtime::parse(item->date());
|
||||||
}
|
}
|
||||||
return QDate();
|
return QDateTime();
|
||||||
} else if (history->scrollTopItem) {
|
} else if (history->scrollTopItem) {
|
||||||
return history->scrollTopItem->dateTime().date();
|
return history->scrollTopItem->dateTime();
|
||||||
} else if (history->loadedAtTop()
|
} else if (history->loadedAtTop()
|
||||||
&& !history->isEmpty()
|
&& !history->isEmpty()
|
||||||
&& history->peer->migrateFrom()) {
|
&& history->peer->migrateFrom()) {
|
||||||
|
|
@ -2179,41 +2232,41 @@ void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||||
if (migrated->scrollTopItem) {
|
if (migrated->scrollTopItem) {
|
||||||
// We're up in the migrated history.
|
// We're up in the migrated history.
|
||||||
// So current date is the date of first message here.
|
// So current date is the date of first message here.
|
||||||
return history->blocks.front()->messages.front()->dateTime().date();
|
return history->blocks.front()->messages.front()->dateTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (const auto item = history->lastMessage()) {
|
} else if (const auto item = history->lastMessage()) {
|
||||||
return base::unixtime::parse(item->date()).date();
|
return base::unixtime::parse(item->date());
|
||||||
}
|
}
|
||||||
return QDate();
|
return QDateTime();
|
||||||
}();
|
}();
|
||||||
const auto maxPeerDate = [&] {
|
const auto maxPeerDate = [&] {
|
||||||
if (topic) {
|
if (topic) {
|
||||||
if (const auto item = topic->lastMessage()) {
|
if (const auto item = topic->lastMessage()) {
|
||||||
return base::unixtime::parse(item->date()).date();
|
return base::unixtime::parse(item->date());
|
||||||
}
|
}
|
||||||
return QDate();
|
return QDateTime();
|
||||||
}
|
}
|
||||||
const auto check = history->peer->migrateTo()
|
const auto check = history->peer->migrateTo()
|
||||||
? history->owner().historyLoaded(history->peer->migrateTo())
|
? history->owner().historyLoaded(history->peer->migrateTo())
|
||||||
: history;
|
: history;
|
||||||
if (const auto item = check ? check->lastMessage() : nullptr) {
|
if (const auto item = check ? check->lastMessage() : nullptr) {
|
||||||
return base::unixtime::parse(item->date()).date();
|
return base::unixtime::parse(item->date());
|
||||||
}
|
}
|
||||||
return QDate();
|
return QDateTime();
|
||||||
}();
|
}();
|
||||||
const auto minPeerDate = [&] {
|
const auto minPeerDate = [&] {
|
||||||
const auto startDate = [&] {
|
const auto startDate = [&] {
|
||||||
// Telegram was launched in August 2013 :)
|
// Telegram was launched in August 2013 :)
|
||||||
return QDate(2013, 8, 1);
|
return QDate(2013, 8, 1).startOfDay();
|
||||||
};
|
};
|
||||||
if (topic) {
|
if (topic) {
|
||||||
return base::unixtime::parse(topic->creationDate()).date();
|
return base::unixtime::parse(topic->creationDate());
|
||||||
} else if (const auto chat = history->peer->migrateFrom()) {
|
} else if (const auto chat = history->peer->migrateFrom()) {
|
||||||
if (const auto history = chat->owner().historyLoaded(chat)) {
|
if (const auto history = chat->owner().historyLoaded(chat)) {
|
||||||
if (history->loadedAtTop()) {
|
if (history->loadedAtTop()) {
|
||||||
if (!history->isEmpty()) {
|
if (!history->isEmpty()) {
|
||||||
return history->blocks.front()->messages.front()->dateTime().date();
|
return history->blocks.front()->messages.front()->dateTime();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return startDate();
|
return startDate();
|
||||||
|
|
@ -2222,9 +2275,9 @@ void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||||
}
|
}
|
||||||
if (history->loadedAtTop()) {
|
if (history->loadedAtTop()) {
|
||||||
if (!history->isEmpty()) {
|
if (!history->isEmpty()) {
|
||||||
return history->blocks.front()->messages.front()->dateTime().date();
|
return history->blocks.front()->messages.front()->dateTime();
|
||||||
}
|
}
|
||||||
return QDate::currentDate();
|
return QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
return startDate();
|
return startDate();
|
||||||
}();
|
}();
|
||||||
|
|
@ -2232,7 +2285,8 @@ void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||||
? requestedDate
|
? requestedDate
|
||||||
: !currentPeerDate.isNull()
|
: !currentPeerDate.isNull()
|
||||||
? currentPeerDate
|
? currentPeerDate
|
||||||
: QDate::currentDate();
|
: QDateTime::currentDateTime();
|
||||||
|
|
||||||
struct ButtonState {
|
struct ButtonState {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
None,
|
None,
|
||||||
|
|
@ -2291,9 +2345,10 @@ void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||||
button->setPointerCursor(false);
|
button->setPointerCursor(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto weak = base::make_weak(this);
|
const auto weak = base::make_weak(this);
|
||||||
const auto weakTopic = base::make_weak(topic);
|
const auto weakTopic = base::make_weak(topic);
|
||||||
const auto jump = [=](const QDate &date) {
|
const auto jump = [=](const QDateTime &date) {
|
||||||
const auto open = [=](not_null<PeerData*> peer, MsgId id) {
|
const auto open = [=](not_null<PeerData*> peer, MsgId id) {
|
||||||
if (const auto strong = weak.get()) {
|
if (const auto strong = weak.get()) {
|
||||||
if (!topic) {
|
if (!topic) {
|
||||||
|
|
@ -2314,15 +2369,31 @@ void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||||
session().api().resolveJumpToDate(chat, date, open);
|
session().api().resolveJumpToDate(chat, date, open);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
show(Box<Ui::CalendarBox>(Ui::CalendarBoxArgs{
|
const auto showCalendarCallback = [=] {
|
||||||
.month = highlighted,
|
show(Box<Ui::CalendarBox>(Ui::CalendarBoxArgs{
|
||||||
.highlighted = highlighted,
|
.month = highlighted.date(),
|
||||||
.callback = [=](const QDate &date) { jump(date); },
|
.highlighted = highlighted.date(),
|
||||||
.minDate = minPeerDate,
|
.callback = [=](const QDate &date) { jump(date.startOfDay()); },
|
||||||
.maxDate = maxPeerDate,
|
.minDate = minPeerDate.date(),
|
||||||
.allowsSelection = history->peer->isUser(),
|
.maxDate = maxPeerDate.date(),
|
||||||
.selectionChanged = selectionChanged,
|
.allowsSelection = history->peer->isUser(),
|
||||||
}));
|
.selectionChanged = selectionChanged,
|
||||||
|
}), Ui::LayerOption::CloseOther);
|
||||||
|
};
|
||||||
|
|
||||||
|
show(Box(ChooseJumpDateTimeBox,
|
||||||
|
minPeerDate,
|
||||||
|
maxPeerDate,
|
||||||
|
highlighted,
|
||||||
|
[=](TimeId result) {
|
||||||
|
jump(base::unixtime::parse(result));
|
||||||
|
},
|
||||||
|
[=] {
|
||||||
|
jump(minPeerDate);
|
||||||
|
},
|
||||||
|
std::move(showCalendarCallback),
|
||||||
|
history->peer->isUser()),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionController::showPassportForm(const Passport::FormRequest &request) {
|
void SessionController::showPassportForm(const Passport::FormRequest &request) {
|
||||||
|
|
|
||||||
|
|
@ -101,15 +101,15 @@ bool operator!=(const PeerThemeOverride &a, const PeerThemeOverride &b);
|
||||||
|
|
||||||
class DateClickHandler : public ClickHandler {
|
class DateClickHandler : public ClickHandler {
|
||||||
public:
|
public:
|
||||||
DateClickHandler(Dialogs::Key chat, QDate date);
|
DateClickHandler(Dialogs::Key chat, QDateTime date);
|
||||||
|
|
||||||
void setDate(QDate date);
|
void setDate(QDateTime date);
|
||||||
void onClick(ClickContext context) const override;
|
void onClick(ClickContext context) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Dialogs::Key _chat;
|
Dialogs::Key _chat;
|
||||||
base::weak_ptr<Data::ForumTopic> _weak;
|
base::weak_ptr<Data::ForumTopic> _weak;
|
||||||
QDate _date;
|
QDateTime _date;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -473,7 +473,7 @@ public:
|
||||||
|
|
||||||
void showCalendar(
|
void showCalendar(
|
||||||
Dialogs::Key chat,
|
Dialogs::Key chat,
|
||||||
QDate requestedDate);
|
QDateTime requestedDateTime);
|
||||||
|
|
||||||
void showAddContact();
|
void showAddContact();
|
||||||
void showNewGroup();
|
void showNewGroup();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue