Allow scheduling voice chats for up to 7 days.

This commit is contained in:
John Preston 2021-04-09 17:59:43 +04:00
parent 71c4cc9623
commit 4ecd1049b2
5 changed files with 78 additions and 46 deletions

View file

@ -134,13 +134,32 @@ void ScheduleGroupCallBox(
: tr::lng_group_call_schedule_notified_group)( : tr::lng_group_call_schedule_notified_group)(
lt_duration, lt_duration,
duration->value()); duration->value());
auto descriptor = Ui::ChooseDateTimeBox(
box, const auto now = QDateTime::currentDateTime();
tr::lng_group_call_schedule_title(), const auto min = [] {
tr::lng_schedule_button(), return base::unixtime::serialize(
send, QDateTime::currentDateTime().addSecs(12));
base::unixtime::now() + kDefaultScheduleDuration, };
std::move(description)); const auto max = [] {
return base::unixtime::serialize(
QDateTime(QDate::currentDate().addDays(8))) - 1;
};
// At least half an hour later, at zero minutes/seconds.
const auto schedule = QDateTime(
now.date(),
QTime(now.time().hour(), 0)
).addSecs(60 * 60 * (now.time().minute() < 30 ? 1 : 2));
auto descriptor = Ui::ChooseDateTimeBox(box, {
.title = tr::lng_group_call_schedule_title(),
.submit = tr::lng_schedule_button(),
.done = send,
.min = min,
.time = base::unixtime::serialize(schedule),
.max = max,
.description = std::move(description),
});
using namespace rpl::mappers; using namespace rpl::mappers;
*duration = rpl::combine( *duration = rpl::combine(

View file

@ -76,14 +76,14 @@ void ScheduleBox(
box->closeBox(); box->closeBox();
copy(result); copy(result);
}; };
auto descriptor = Ui::ChooseDateTimeBox( auto descriptor = Ui::ChooseDateTimeBox(box, {
box, .title = (type == SendMenu::Type::Reminder
(type == SendMenu::Type::Reminder
? tr::lng_remind_title() ? tr::lng_remind_title()
: tr::lng_schedule_title()), : tr::lng_schedule_title()),
tr::lng_schedule_button(), .submit = tr::lng_schedule_button(),
[=](TimeId result) { save(false, result); }, .done = [=](TimeId result) { save(false, result); },
time); .time = time,
});
SendMenu::SetupMenuAndShortcuts( SendMenu::SetupMenuAndShortcuts(
descriptor.submit.data(), descriptor.submit.data(),

View file

@ -50,11 +50,10 @@ QString DayString(const QDate &date) {
QString::number(date.day())); QString::number(date.day()));
} }
QString TimeString(TimeId time) { QString TimeString(QTime time) {
const auto parsed = base::unixtime::parse(time).time();
return QString("%1:%2" return QString("%1:%2"
).arg(parsed.hour() ).arg(time.hour()
).arg(parsed.minute(), 2, 10, QLatin1Char('0')); ).arg(time.minute(), 2, 10, QLatin1Char('0'));
} }
int ProcessWheelEvent(not_null<QWheelEvent*> e) { int ProcessWheelEvent(not_null<QWheelEvent*> e) {
@ -569,36 +568,33 @@ void TimeInput::startBorderAnimation() {
ChooseDateTimeBoxDescriptor ChooseDateTimeBox( ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
not_null<GenericBox*> box, not_null<GenericBox*> box,
rpl::producer<QString> title, ChooseDateTimeBoxArgs &&args) {
rpl::producer<QString> submit,
Fn<void(TimeId)> done,
TimeId time,
rpl::producer<QString> description) {
struct State { struct State {
rpl::variable<QDate> date; rpl::variable<QDate> date;
not_null<InputField*> day; not_null<InputField*> day;
not_null<TimeInput*> time; not_null<TimeInput*> time;
not_null<FlatLabel*> at; not_null<FlatLabel*> at;
}; };
box->setTitle(std::move(title)); box->setTitle(std::move(args.title));
box->setWidth(st::boxWideWidth); box->setWidth(st::boxWideWidth);
const auto content = box->addRow( const auto content = box->addRow(
object_ptr<FixedHeightWidget>(box, st::scheduleHeight)); object_ptr<FixedHeightWidget>(box, st::scheduleHeight));
if (description) { if (args.description) {
box->addRow(object_ptr<FlatLabel>( box->addRow(object_ptr<FlatLabel>(
box, box,
std::move(description), std::move(args.description),
st::boxLabel)); st::boxLabel));
} }
const auto parsed = base::unixtime::parse(args.time);
const auto state = box->lifetime().make_state<State>(State{ const auto state = box->lifetime().make_state<State>(State{
.date = base::unixtime::parse(time).date(), .date = parsed.date(),
.day = CreateChild<InputField>( .day = CreateChild<InputField>(
content, content,
st::scheduleDateField), st::scheduleDateField),
.time = CreateChild<TimeInput>( .time = CreateChild<TimeInput>(
content, content,
TimeString(time)), TimeString(parsed.time())),
.at = CreateChild<FlatLabel>( .at = CreateChild<FlatLabel>(
content, content,
tr::lng_schedule_at(), tr::lng_schedule_at(),
@ -611,8 +607,19 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
state->time->setFocusFast(); state->time->setFocusFast();
}, state->day->lifetime()); }, state->day->lifetime());
const auto minDate = QDate::currentDate(); const auto min = args.min ? args.min : [] {
const auto maxDate = minDate.addYears(1).addDays(-1); return base::unixtime::now() + kMinimalSchedule;
};
const auto max = args.max ? args.max : [] {
return base::unixtime::serialize(
QDateTime::currentDateTime().addYears(1)) - 1;
};
const auto minDate = [=] {
return base::unixtime::parse(min()).date();
};
const auto maxDate = [=] {
return base::unixtime::parse(max()).date();
};
const auto &dayViewport = state->day->rawTextEdit()->viewport(); const auto &dayViewport = state->day->rawTextEdit()->viewport();
base::install_event_filter(dayViewport, [=](not_null<QEvent*> event) { base::install_event_filter(dayViewport, [=](not_null<QEvent*> event) {
@ -623,7 +630,7 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
return base::EventFilterResult::Continue; return base::EventFilterResult::Continue;
} }
const auto d = state->date.current().addDays(direction); const auto d = state->date.current().addDays(direction);
state->date = std::clamp(d, minDate, maxDate); state->date = std::clamp(d, minDate(), maxDate());
return base::EventFilterResult::Cancel; return base::EventFilterResult::Cancel;
} }
return base::EventFilterResult::Continue; return base::EventFilterResult::Continue;
@ -661,8 +668,8 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
(*calendar)->closeBox(); (*calendar)->closeBox();
}; };
const auto finalize = [=](not_null<CalendarBox*> box) { const auto finalize = [=](not_null<CalendarBox*> box) {
box->setMinDate(minDate); box->setMinDate(minDate());
box->setMaxDate(maxDate); box->setMaxDate(maxDate());
}; };
*calendar = box->getDelegate()->show(Box<CalendarBox>( *calendar = box->getDelegate()->show(Box<CalendarBox>(
state->date.current(), state->date.current(),
@ -686,12 +693,12 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
} }
const auto result = base::unixtime::serialize( const auto result = base::unixtime::serialize(
QDateTime(state->date.current(), time)); QDateTime(state->date.current(), time));
if (result <= base::unixtime::now() + kMinimalSchedule) { if (result < min() || result > max()) {
return 0; return 0;
} }
return result; return result;
}; };
const auto save = [=] { const auto save = [=, done = args.done] {
if (const auto result = collect()) { if (const auto result = collect()) {
done(result); done(result);
} else { } else {
@ -703,7 +710,7 @@ ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
auto result = ChooseDateTimeBoxDescriptor(); auto result = ChooseDateTimeBoxDescriptor();
box->setFocusCallback([=] { state->time->setFocusFast(); }); box->setFocusCallback([=] { state->time->setFocusFast(); });
result.submit = box->addButton(std::move(submit), save); result.submit = box->addButton(std::move(args.submit), save);
result.collect = [=] { result.collect = [=] {
if (const auto result = collect()) { if (const auto result = collect()) {
return result; return result;

View file

@ -19,12 +19,18 @@ struct ChooseDateTimeBoxDescriptor {
rpl::producer<TimeId> values; rpl::producer<TimeId> values;
}; };
struct ChooseDateTimeBoxArgs {
rpl::producer<QString> title;
rpl::producer<QString> submit;
Fn<void(TimeId)> done;
Fn<TimeId()> min;
TimeId time = 0;
Fn<TimeId()> max;
rpl::producer<QString> description;
};
ChooseDateTimeBoxDescriptor ChooseDateTimeBox( ChooseDateTimeBoxDescriptor ChooseDateTimeBox(
not_null<GenericBox*> box, not_null<GenericBox*> box,
rpl::producer<QString> title, ChooseDateTimeBoxArgs &&args);
rpl::producer<QString> submit,
Fn<void(TimeId)> done,
TimeId time,
rpl::producer<QString> description = nullptr);
} // namespace Ui } // namespace Ui

View file

@ -201,12 +201,12 @@ void EditInviteLinkBox(
: (state->expireValue < 0) : (state->expireValue < 0)
? (now - state->expireValue) ? (now - state->expireValue)
: (now + kDay); : (now + kDay);
ChooseDateTimeBox( ChooseDateTimeBox(box, {
box, .title = tr::lng_group_invite_expire_after(),
tr::lng_group_invite_expire_after(), .submit = tr::lng_settings_save(),
tr::lng_settings_save(), .done = save,
save, .time = time,
time); });
})); }));
}); });
usageGroup->setChangedCallback([=](int value) { usageGroup->setChangedCallback([=](int value) {