Support selecting messages range.

This commit is contained in:
John Preston 2021-11-16 09:52:13 +04:00
parent 4414369fc8
commit b7c95e9636
3 changed files with 314 additions and 39 deletions

View file

@ -28,9 +28,9 @@ class CalendarBox::Context {
public: public:
Context(QDate month, QDate highlighted); Context(QDate month, QDate highlighted);
void setHasSelection(bool has); void setAllowsSelection(bool allowsSelection);
[[nodiscard]] bool hasSelection() const { [[nodiscard]] bool allowsSelection() const {
return _hasSelection; return _allowsSelection;
} }
void setMinDate(QDate date); void setMinDate(QDate date);
@ -66,20 +66,38 @@ public:
return (index >= _minDayIndex) && (index <= _maxDayIndex); return (index >= _minDayIndex) && (index <= _maxDayIndex);
} }
[[nodiscard]] QDate month() const {
return _month.current();
}
[[nodiscard]] rpl::producer<QDate> monthValue() const { [[nodiscard]] rpl::producer<QDate> monthValue() const {
return _month.value(); return _month.value();
} }
QDate dateFromIndex(int index) const; [[nodiscard]] QDate dateFromIndex(int index) const;
QString labelFromIndex(int index) const; [[nodiscard]] QString labelFromIndex(int index) const;
void toggleSelectionMode(bool enabled);
[[nodiscard]] bool selectionMode() const;
[[nodiscard]] rpl::producer<> selectionUpdates() const;
[[nodiscard]] std::optional<int> selectedMin() const;
[[nodiscard]] std::optional<int> selectedMax() const;
void startSelection(int index);
void updateSelection(int index);
private: private:
struct Selection {
QDate min;
QDate max;
int minIndex = 0;
int maxIndex = 0;
};
void applyMonth(const QDate &month, bool forced = false); void applyMonth(const QDate &month, bool forced = false);
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);
bool _hasSelection = false; bool _allowsSelection = false;
rpl::variable<QDate> _month; rpl::variable<QDate> _month;
QDate _min, _max; QDate _min, _max;
@ -94,6 +112,12 @@ private:
int _daysShift = 0; int _daysShift = 0;
int _rowsCount = 0; int _rowsCount = 0;
Selection _selection;
QDate _selectionStart;
int _selectionStartIndex = 0;
rpl::event_stream<> _selectionUpdates;
bool _selectionMode = false;
}; };
CalendarBox::Context::Context(QDate month, QDate highlighted) CalendarBox::Context::Context(QDate month, QDate highlighted)
@ -101,8 +125,8 @@ CalendarBox::Context::Context(QDate month, QDate highlighted)
showMonth(month); showMonth(month);
} }
void CalendarBox::Context::setHasSelection(bool has) { void CalendarBox::Context::setAllowsSelection(bool allows) {
_hasSelection = has; _allowsSelection = allows;
} }
void CalendarBox::Context::setMinDate(QDate date) { void CalendarBox::Context::setMinDate(QDate date) {
@ -128,17 +152,31 @@ bool CalendarBox::Context::showsMonthOf(QDate date) const {
} }
void CalendarBox::Context::applyMonth(const QDate &month, bool forced) { void CalendarBox::Context::applyMonth(const QDate &month, bool forced) {
const auto was = _month.current();
_daysCount = month.daysInMonth(); _daysCount = month.daysInMonth();
_daysShift = DaysShiftForMonth(month, _min); _daysShift = DaysShiftForMonth(month, _min);
_rowsCount = RowsCountForMonth(month, _min, _max); _rowsCount = RowsCountForMonth(month, _min, _max);
_highlightedIndex = month.daysTo(_highlighted); _highlightedIndex = month.daysTo(_highlighted);
_minDayIndex = _min.isNull() ? INT_MIN : month.daysTo(_min); _minDayIndex = _min.isNull() ? INT_MIN : month.daysTo(_min);
_maxDayIndex = _max.isNull() ? INT_MAX : month.daysTo(_max); _maxDayIndex = _max.isNull() ? INT_MAX : month.daysTo(_max);
const auto shift = was.isNull() ? 0 : month.daysTo(was);
auto updated = false;
const auto update = [&](const QDate &date, int &index) {
if (shift && !date.isNull()) {
index += shift;
}
};
update(_selection.min, _selection.minIndex);
update(_selection.max, _selection.maxIndex);
update(_selectionStart, _selectionStartIndex);
if (forced) { if (forced) {
_month.force_assign(month); _month.force_assign(month);
} else { } else {
_month = month; _month = month;
} }
if (updated) {
_selectionUpdates.fire({});
}
} }
void CalendarBox::Context::skipMonth(int skip) { void CalendarBox::Context::skipMonth(int skip) {
@ -235,6 +273,70 @@ QString CalendarBox::Context::labelFromIndex(int index) const {
return QString::number(day()); return QString::number(day());
} }
void CalendarBox::Context::toggleSelectionMode(bool enabled) {
if (_selectionMode == enabled) {
return;
}
_selectionMode = enabled;
_selectionStart = {};
_selection = {};
_selectionUpdates.fire({});
}
bool CalendarBox::Context::selectionMode() const {
return _selectionMode;
}
rpl::producer<> CalendarBox::Context::selectionUpdates() const {
return _selectionUpdates.events();
}
std::optional<int> CalendarBox::Context::selectedMin() const {
return _selection.min.isNull()
? std::optional<int>()
: _selection.minIndex;
}
std::optional<int> CalendarBox::Context::selectedMax() const {
return _selection.max.isNull()
? std::optional<int>()
: _selection.maxIndex;
}
void CalendarBox::Context::startSelection(int index) {
Expects(_selectionMode);
if (!_selectionStart.isNull() && _selectionStartIndex == index) {
return;
}
_selectionStartIndex = index;
_selectionStart = dateFromIndex(index);
updateSelection(index);
}
void CalendarBox::Context::updateSelection(int index) {
Expects(_selectionMode);
Expects(!_selectionStart.isNull());
index = std::clamp(index, minDayIndex(), maxDayIndex());
const auto start = _selectionStartIndex;
const auto min = std::min(index, start);
const auto max = std::max(index, start);
if (!_selection.min.isNull()
&& _selection.minIndex == min
&& !_selection.max.isNull()
&& _selection.maxIndex == max) {
return;
}
_selection = Selection{
.min = dateFromIndex(min),
.max = dateFromIndex(max),
.minIndex = min,
.maxIndex = max,
};
_selectionUpdates.fire({});
}
class CalendarBox::Inner final : public RpWidget { class CalendarBox::Inner final : public RpWidget {
public: public:
Inner( Inner(
@ -294,6 +396,11 @@ CalendarBox::Inner::Inner(
) | rpl::start_with_next([=](QDate month) { ) | rpl::start_with_next([=](QDate month) {
monthChanged(month); monthChanged(month);
}, lifetime()); }, lifetime());
context->selectionUpdates(
) | rpl::start_with_next([=] {
update();
}, lifetime());
} }
void CalendarBox::Inner::monthChanged(QDate month) { void CalendarBox::Inner::monthChanged(QDate month) {
@ -329,7 +436,13 @@ void CalendarBox::Inner::paintRows(Painter &p, QRect clip) {
p.setFont(st::calendarDaysFont); p.setFont(st::calendarDaysFont);
auto y = rowsTop(); auto y = rowsTop();
auto index = -_context->daysShift(); auto index = -_context->daysShift();
auto highlightedIndex = _context->highlightedIndex(); const auto selectionMode = _context->selectionMode();
const auto impossible = index - 45;
const auto selectedMin = _context->selectedMin().value_or(impossible);
const auto selectedMax = _context->selectedMax().value_or(impossible);
const auto highlightedIndex = selectionMode
? impossible
: _context->highlightedIndex();
const auto daysCount = _context->daysCount(); const auto daysCount = _context->daysCount();
const auto rowsCount = _context->rowsCount(); const auto rowsCount = _context->rowsCount();
const auto rowHeight = _st.cellSize.height(); const auto rowHeight = _st.cellSize.height();
@ -339,31 +452,59 @@ void CalendarBox::Inner::paintRows(Painter &p, QRect clip) {
rowsCount); rowsCount);
y += fromRow * rowHeight; y += fromRow * rowHeight;
index += fromRow * kDaysInWeek; index += fromRow * kDaysInWeek;
const auto innerSkipLeft = (_st.cellSize.width() - _st.cellInner) / 2;
const auto innerSkipTop = (_st.cellSize.height() - _st.cellInner) / 2;
for (auto row = fromRow; row != tillRow; ++row, y += rowHeight) { for (auto row = fromRow; row != tillRow; ++row, y += rowHeight) {
auto x = rowsLeft(); auto x = rowsLeft();
const auto fromIndex = index;
const auto tillIndex = (index + kDaysInWeek);
const auto selectedFrom = std::max(fromIndex, selectedMin);
const auto selectedTill = std::min(tillIndex, selectedMax + 1);
const auto selectedInRow = (selectedTill - selectedFrom);
if (selectedInRow > 0) {
auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen);
p.setBrush(st::lightButtonBgOver);
p.drawRoundedRect(
(x
+ (selectedFrom - index) * _st.cellSize.width()
+ innerSkipLeft
- st::lineWidth),
y + innerSkipTop - st::lineWidth,
((selectedInRow - 1) * _st.cellSize.width()
+ 2 * st::lineWidth
+ _st.cellInner),
_st.cellInner + 2 * st::lineWidth,
(_st.cellInner / 2.) + st::lineWidth,
(_st.cellInner / 2.) + st::lineWidth);
p.setBrush(Qt::NoBrush);
}
for (auto col = 0; col != kDaysInWeek; ++col, ++index, x += _st.cellSize.width()) { for (auto col = 0; col != kDaysInWeek; ++col, ++index, x += _st.cellSize.width()) {
auto rect = myrtlrect(x, y, _st.cellSize.width(), _st.cellSize.height()); const auto rect = myrtlrect(x, y, _st.cellSize.width(), _st.cellSize.height());
auto grayedOut = (index < 0 || index >= daysCount || !rect.intersects(clip)); const auto selected = (index >= selectedMin) && (index <= selectedMax);
auto highlighted = (index == highlightedIndex); const auto grayedOut = !selected && (index < 0 || index >= daysCount);
auto enabled = _context->isEnabled(index); const auto highlighted = (index == highlightedIndex);
auto innerLeft = x + (_st.cellSize.width() - _st.cellInner) / 2; const auto enabled = _context->isEnabled(index);
auto innerTop = y + (_st.cellSize.height() - _st.cellInner) / 2; const auto innerLeft = x + innerSkipLeft;
const auto innerTop = y + innerSkipTop;
if (highlighted) { if (highlighted) {
PainterHighQualityEnabler hq(p); auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(grayedOut ? st::windowBgOver : st::dialogsBgActive); p.setBrush(grayedOut ? st::windowBgOver : st::dialogsBgActive);
p.drawEllipse(myrtlrect(innerLeft, innerTop, _st.cellInner, _st.cellInner)); p.drawEllipse(myrtlrect(innerLeft, innerTop, _st.cellInner, _st.cellInner));
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
} }
auto it = _ripples.find(index); const auto it = _ripples.find(index);
if (it != _ripples.cend()) { if (it != _ripples.cend()) {
auto colorOverride = [highlighted, grayedOut] { const auto colorOverride = [&] {
if (highlighted) { if (selectionMode) {
return st::lightButtonBgOver;
} else if (highlighted) {
return grayedOut ? st::windowBgRipple : st::dialogsRippleBgActive; return grayedOut ? st::windowBgRipple : st::dialogsRippleBgActive;
} }
return st::windowBgOver; return st::windowBgOver;
}; }()->c;
it->second->paint(p, innerLeft, innerTop, width(), &(colorOverride()->c)); it->second->paint(p, innerLeft, innerTop, width(), &colorOverride);
if (it->second->empty()) { if (it->second->empty()) {
_ripples.erase(it); _ripples.erase(it);
} }
@ -400,6 +541,20 @@ void CalendarBox::Inner::mouseMoveEvent(QMouseEvent *e) {
} else { } else {
setSelected(kEmptySelection); setSelected(kEmptySelection);
} }
if (_pressed != kEmptySelection && _context->selectionMode()) {
const auto row = (point.y() >= rowsTop())
? (point.y() - rowsTop()) / size.height()
: -1;
const auto col = (point.y() < rowsTop())
? 0
: (point.x() >= rowsLeft())
? std::min(
(point.x() - rowsLeft()) / size.width(),
kDaysInWeek - 1)
: 0;
const auto index = row * kDaysInWeek + col - _context->daysShift();
_context->updateSelection(index);
}
} }
void CalendarBox::Inner::setSelected(int selected) { void CalendarBox::Inner::setSelected(int selected) {
@ -440,13 +595,24 @@ void CalendarBox::Inner::mousePressEvent(QMouseEvent *e) {
} }
auto ripplePosition = QPoint(cell.x() + (_st.cellSize.width() - _st.cellInner) / 2, cell.y() + (_st.cellSize.height() - _st.cellInner) / 2); auto ripplePosition = QPoint(cell.x() + (_st.cellSize.width() - _st.cellInner) / 2, cell.y() + (_st.cellSize.height() - _st.cellInner) / 2);
it->second->add(e->pos() - ripplePosition); it->second->add(e->pos() - ripplePosition);
if (_context->selectionMode()) {
if (_context->selectedMin().has_value()
&& (e->modifiers() & Qt::ShiftModifier)) {
_context->updateSelection(_selected);
} else {
_context->startSelection(_selected);
}
}
} }
} }
void CalendarBox::Inner::mouseReleaseEvent(QMouseEvent *e) { void CalendarBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
auto pressed = _pressed; auto pressed = _pressed;
setPressed(kEmptySelection); setPressed(kEmptySelection);
if (pressed != kEmptySelection && pressed == _selected) { if (pressed != kEmptySelection
&& pressed == _selected
&& !_context->selectionMode()) {
crl::on_main(this, [=] { crl::on_main(this, [=] {
const auto onstack = _dateChosenCallback; const auto onstack = _dateChosenCallback;
onstack(_context->dateFromIndex(pressed)); onstack(_context->dateFromIndex(pressed));
@ -490,7 +656,8 @@ protected:
void paintEvent(QPaintEvent *e); void paintEvent(QPaintEvent *e);
private: private:
void monthChanged(QDate month); void setTextFromMonth(QDate month);
void setText(QString text);
void paintDayNames(Painter &p, QRect clip); void paintDayNames(Painter &p, QRect clip);
const style::CalendarSizes &_st; const style::CalendarSizes &_st;
@ -513,13 +680,30 @@ CalendarBox::Title::Title(
_textLeft = _st.padding.left() + (_st.cellSize.width() - dayWidth) / 2; _textLeft = _st.padding.left() + (_st.cellSize.width() - dayWidth) / 2;
_context->monthValue( _context->monthValue(
) | rpl::start_with_next([=](QDate date) { ) | rpl::filter([=] {
monthChanged(date); return !_context->selectionMode();
}) | rpl::start_with_next([=](QDate date) {
setTextFromMonth(date);
}, lifetime());
_context->selectionUpdates(
) | rpl::start_with_next([=] {
if (!_context->selectionMode()) {
setTextFromMonth(_context->month());
} else if (!_context->selectedMin()) {
setText(tr::lng_calendar_select_days(tr::now));
} else {
setText(QString::number(1 + *_context->selectedMax() - *_context->selectedMin())); // #TODO calendar
}
}, lifetime()); }, lifetime());
} }
void CalendarBox::Title::monthChanged(QDate month) { void CalendarBox::Title::setTextFromMonth(QDate month) {
_text = langMonthOfYearFull(month.month(), month.year()); setText(langMonthOfYearFull(month.month(), month.year()));
}
void CalendarBox::Title::setText(QString text) {
_text = std::move(text);
_textWidth = st::calendarTitleFont->width(_text); _textWidth = st::calendarTitleFont->width(_text);
update(); update();
} }
@ -570,9 +754,10 @@ CalendarBox::CalendarBox(QWidget*, CalendarBoxArgs &&args)
, _next(this, st::calendarNext) , _next(this, st::calendarNext)
, _callback(std::move(args.callback.value())) , _callback(std::move(args.callback.value()))
, _finalize(std::move(args.finalize)) , _finalize(std::move(args.finalize))
, _jumpTimer([=] { jump(_jumpButton); }) { , _jumpTimer([=] { jump(_jumpButton); })
, _selectionChanged(std::move(args.selectionChanged)) {
_title->setAttribute(Qt::WA_TransparentForMouseEvents); _title->setAttribute(Qt::WA_TransparentForMouseEvents);
_context->setHasSelection(args.allowsSelection); _context->setAllowsSelection(args.allowsSelection);
_context->setMinDate(args.minDate); _context->setMinDate(args.minDate);
_context->setMaxDate(args.maxDate); _context->setMaxDate(args.maxDate);
@ -612,6 +797,12 @@ CalendarBox::CalendarBox(QWidget*, CalendarBoxArgs &&args)
setupJumps(_next.data(), &_nextEnabled); setupJumps(_next.data(), &_nextEnabled);
} }
CalendarBox::~CalendarBox() = default;
void CalendarBox::toggleSelectionMode(bool enabled) {
_context->toggleSelectionMode(enabled);
}
void CalendarBox::showJumpTooltip(not_null<IconButton*> button) { void CalendarBox::showJumpTooltip(not_null<IconButton*> button) {
_tooltipButton = button; _tooltipButton = button;
Ui::Tooltip::Show(kTooltipDelay, this); Ui::Tooltip::Show(kTooltipDelay, this);
@ -644,21 +835,33 @@ void CalendarBox::prepare() {
_inner->setDateChosenCallback(std::move(_callback)); _inner->setDateChosenCallback(std::move(_callback));
addButton(tr::lng_close(), [=] { closeBox(); });
_context->monthValue( _context->monthValue(
) | rpl::start_with_next([=](QDate month) { ) | rpl::start_with_next([=](QDate month) {
monthChanged(month); monthChanged(month);
}, lifetime()); }, lifetime());
setExactScroll(); setExactScroll();
_context->selectionUpdates(
) | rpl::start_with_next([=] {
_selectionMode = _context->selectionMode();
if (_selectionChanged) {
const auto count = !_selectionMode
? std::optional<int>()
: !_context->selectedMin()
? 0
: (1 + *_context->selectedMax() - *_context->selectedMin());
_selectionChanged(this, count);
}
if (!_selectionMode) {
clearButtons();
createButtons();
}
}, lifetime());
createButtons();
if (_finalize) { if (_finalize) {
_finalize(this); _finalize(this);
} }
if (_context->hasSelection()) {
addLeftButton(tr::lng_calendar_select_days(), [=] {
});
}
} }
bool CalendarBox::isPreviousEnabled() const { bool CalendarBox::isPreviousEnabled() const {
@ -714,6 +917,21 @@ void CalendarBox::processScroll() {
_watchScroll = true; _watchScroll = true;
} }
void CalendarBox::createButtons() {
if (!_context->allowsSelection()) {
addButton(tr::lng_close(), [=] { closeBox(); });
} else if (!_context->selectionMode()) {
addButton(tr::lng_close(), [=] { closeBox(); });
addLeftButton(tr::lng_calendar_select_days(), [=] {
_context->toggleSelectionMode(true);
});
} else {
addButton(tr::lng_cancel(), [=] {
_context->toggleSelectionMode(false);
});
}
}
QString CalendarBox::tooltipText() const { QString CalendarBox::tooltipText() const {
if (_tooltipButton == _previous.data()) { if (_tooltipButton == _previous.data()) {
return tr::lng_calendar_start_tip(tr::now); return tr::lng_calendar_start_tip(tr::now);
@ -737,14 +955,14 @@ void CalendarBox::monthChanged(QDate month) {
_previousEnabled = isPreviousEnabled(); _previousEnabled = isPreviousEnabled();
_previous->setIconOverride(_previousEnabled ? nullptr : &st::calendarPreviousDisabled); _previous->setIconOverride(_previousEnabled ? nullptr : &st::calendarPreviousDisabled);
_previous->setRippleColorOverride(_previousEnabled ? nullptr : &st::boxBg); _previous->setRippleColorOverride(_previousEnabled ? nullptr : &st::boxBg);
_previous->setCursor(_previousEnabled ? style::cur_pointer : style::cur_default); _previous->setPointerCursor(_previousEnabled);
if (!_previousEnabled) { if (!_previousEnabled) {
_previous->clearState(); _previous->clearState();
} }
_nextEnabled = isNextEnabled(); _nextEnabled = isNextEnabled();
_next->setIconOverride(_nextEnabled ? nullptr : &st::calendarNextDisabled); _next->setIconOverride(_nextEnabled ? nullptr : &st::calendarNextDisabled);
_next->setRippleColorOverride(_nextEnabled ? nullptr : &st::boxBg); _next->setRippleColorOverride(_nextEnabled ? nullptr : &st::boxBg);
_next->setCursor(_nextEnabled ? style::cur_pointer : style::cur_default); _next->setPointerCursor(_nextEnabled);
if (!_nextEnabled) { if (!_nextEnabled) {
_next->clearState(); _next->clearState();
} }
@ -782,6 +1000,4 @@ void CalendarBox::keyPressEvent(QKeyEvent *e) {
} }
} }
CalendarBox::~CalendarBox() = default;
} // namespace Ui } // namespace Ui

View file

@ -38,6 +38,9 @@ struct CalendarBoxArgs {
QDate minDate; QDate minDate;
QDate maxDate; QDate maxDate;
bool allowsSelection = false; bool allowsSelection = false;
Fn<void(
not_null<Ui::CalendarBox*>,
std::optional<int>)> selectionChanged;
}; };
class CalendarBox final : public BoxContent, private AbstractTooltipShower { class CalendarBox final : public BoxContent, private AbstractTooltipShower {
@ -45,6 +48,8 @@ public:
CalendarBox(QWidget*, CalendarBoxArgs &&args); CalendarBox(QWidget*, CalendarBoxArgs &&args);
~CalendarBox(); ~CalendarBox();
void toggleSelectionMode(bool enabled);
protected: protected:
void prepare() override; void prepare() override;
@ -61,6 +66,7 @@ private:
void goNextMonth(); void goNextMonth();
void setExactScroll(); void setExactScroll();
void processScroll(); void processScroll();
void createButtons();
void showJumpTooltip(not_null<IconButton*> button); void showJumpTooltip(not_null<IconButton*> button);
void jumpAfterDelay(not_null<IconButton*> button); void jumpAfterDelay(not_null<IconButton*> button);
@ -95,6 +101,11 @@ private:
QPointer<IconButton> _jumpButton; QPointer<IconButton> _jumpButton;
base::Timer _jumpTimer; base::Timer _jumpTimer;
bool _selectionMode = false;
Fn<void(
not_null<Ui::CalendarBox*>,
std::optional<int>)> _selectionChanged;
}; };
} // namespace Ui } // namespace Ui

View file

@ -1207,6 +1207,53 @@ void SessionController::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
: !currentPeerDate.isNull() : !currentPeerDate.isNull()
? currentPeerDate ? currentPeerDate
: QDate::currentDate(); : QDate::currentDate();
struct ButtonState {
enum class Type {
None,
Disabled,
Active,
};
Type type = Type::None;
style::complex_color disabledFg = style::complex_color([] {
auto result = st::attentionBoxButton.textFg->c;
result.setAlpha(result.alpha() / 2);
return result;
});
style::RoundButton disabled = st::attentionBoxButton;
};
const auto buttonState = std::make_shared<ButtonState>();
buttonState->disabled.textFg
= buttonState->disabled.textFgOver
= buttonState->disabledFg.color();
buttonState->disabled.ripple.color
= buttonState->disabled.textBgOver
= buttonState->disabled.textBg;
const auto selectionChanged = [=](
not_null<Ui::CalendarBox*> box,
std::optional<int> selected) {
if (!selected.has_value()) {
buttonState->type = ButtonState::Type::None;
return;
}
const auto type = (*selected > 0)
? ButtonState::Type::Active
: ButtonState::Type::Disabled;
if (buttonState->type == type) {
return;
}
buttonState->type = type;
box->clearButtons();
box->addButton(tr::lng_cancel(), [=] {
box->toggleSelectionMode(false);
});
auto text = tr::lng_profile_clear_history();
const auto button = box->addLeftButton(std::move(text), [=] {
}, (*selected > 0) ? st::attentionBoxButton : buttonState->disabled);
if (!*selected) {
button->setPointerCursor(false);
}
};
show(Box<Ui::CalendarBox>(Ui::CalendarBoxArgs{ show(Box<Ui::CalendarBox>(Ui::CalendarBoxArgs{
.month = highlighted, .month = highlighted,
.highlighted = highlighted, .highlighted = highlighted,
@ -1216,6 +1263,7 @@ void SessionController::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
.minDate = minPeerDate, .minDate = minPeerDate,
.maxDate = maxPeerDate, .maxDate = maxPeerDate,
.allowsSelection = history->peer->isUser(), .allowsSelection = history->peer->isUser(),
.selectionChanged = selectionChanged,
})); }));
} }