mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Moved widget for time choosing to td_ui.
This commit is contained in:
parent
2f7017b305
commit
ae25804d83
4 changed files with 178 additions and 105 deletions
|
@ -7,16 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "menu/menu_mute.h"
|
#include "menu/menu_mute.h"
|
||||||
|
|
||||||
#include "base/qt_signal_producer.h"
|
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "menu/menu_check_item.h"
|
#include "menu/menu_check_item.h"
|
||||||
|
#include "ui/boxes/choose_time.h"
|
||||||
#include "ui/effects/animation_value.h"
|
#include "ui/effects/animation_value.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/widgets/fields/time_part_input_with_placeholder.h"
|
|
||||||
#include "ui/widgets/menu/menu_action.h"
|
#include "ui/widgets/menu/menu_action.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -28,6 +27,8 @@ namespace MuteMenu {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kMuteDurSecondsDefault = crl::time(8) * 3600;
|
||||||
|
|
||||||
class MuteItem final : public Ui::Menu::Action {
|
class MuteItem final : public Ui::Menu::Action {
|
||||||
public:
|
public:
|
||||||
MuteItem(
|
MuteItem(
|
||||||
|
@ -139,101 +140,19 @@ void FillSoundMenu(
|
||||||
}
|
}
|
||||||
|
|
||||||
void MuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
|
void MuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
|
||||||
using TimeField = Ui::TimePartWithPlaceholder;
|
|
||||||
const auto putNext = [](not_null<TimeField*> field, QChar ch) {
|
|
||||||
field->setCursorPosition(0);
|
|
||||||
if (ch.unicode()) {
|
|
||||||
field->setText(ch + field->getLastText());
|
|
||||||
field->setCursorPosition(1);
|
|
||||||
}
|
|
||||||
field->onTextEdited();
|
|
||||||
field->setFocus();
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto erasePrevious = [](not_null<TimeField*> field) {
|
|
||||||
const auto text = field->getLastText();
|
|
||||||
if (!text.isEmpty()) {
|
|
||||||
field->setCursorPosition(text.size() - 1);
|
|
||||||
field->setText(text.mid(0, text.size() - 1));
|
|
||||||
}
|
|
||||||
field->setFocus();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
not_null<TimeField*> day;
|
|
||||||
not_null<TimeField*> hour;
|
|
||||||
not_null<TimeField*> minute;
|
|
||||||
|
|
||||||
base::unique_qptr<Ui::PopupMenu> menu;
|
base::unique_qptr<Ui::PopupMenu> menu;
|
||||||
|
|
||||||
rpl::variable<bool> noSoundChanges;
|
rpl::variable<bool> noSoundChanges;
|
||||||
int valueInSeconds = 0;
|
int lastSeconds = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto content = box->addRow(
|
auto chooseTimeResult = ChooseTimeWidget(box, kMuteDurSecondsDefault);
|
||||||
object_ptr<Ui::FixedHeightWidget>(box, st::scheduleHeight));
|
box->addRow(std::move(chooseTimeResult.widget));
|
||||||
|
|
||||||
const auto state = box->lifetime().make_state<State>(State{
|
const auto state = box->lifetime().make_state<State>(State{
|
||||||
.day = Ui::CreateChild<TimeField>(
|
|
||||||
content,
|
|
||||||
st::muteBoxTimeField,
|
|
||||||
rpl::never<QString>(),
|
|
||||||
QString::number(0)),
|
|
||||||
.hour = Ui::CreateChild<TimeField>(
|
|
||||||
content,
|
|
||||||
st::muteBoxTimeField,
|
|
||||||
rpl::never<QString>(),
|
|
||||||
QString::number(0)),
|
|
||||||
.minute = Ui::CreateChild<TimeField>(
|
|
||||||
content,
|
|
||||||
st::muteBoxTimeField,
|
|
||||||
rpl::never<QString>(),
|
|
||||||
QString::number(0)),
|
|
||||||
.noSoundChanges = false,
|
.noSoundChanges = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto day = Ui::MakeWeak(state->day);
|
|
||||||
const auto hour = Ui::MakeWeak(state->hour);
|
|
||||||
const auto minute = Ui::MakeWeak(state->minute);
|
|
||||||
|
|
||||||
day->setPhrase(tr::lng_mute_box_days);
|
|
||||||
day->setMaxValue(31);
|
|
||||||
day->setWheelStep(1);
|
|
||||||
day->putNext() | rpl::start_with_next([=](QChar ch) {
|
|
||||||
putNext(hour, ch);
|
|
||||||
}, box->lifetime());
|
|
||||||
|
|
||||||
hour->setPhrase(tr::lng_mute_box_hours);
|
|
||||||
hour->setMaxValue(23);
|
|
||||||
hour->setWheelStep(1);
|
|
||||||
hour->putNext() | rpl::start_with_next([=](QChar ch) {
|
|
||||||
putNext(minute, ch);
|
|
||||||
}, box->lifetime());
|
|
||||||
hour->erasePrevious() | rpl::start_with_next([=] {
|
|
||||||
erasePrevious(day);
|
|
||||||
}, box->lifetime());
|
|
||||||
|
|
||||||
minute->setPhrase(tr::lng_mute_box_minutes);
|
|
||||||
minute->setMaxValue(59);
|
|
||||||
minute->setWheelStep(10);
|
|
||||||
minute->erasePrevious() | rpl::start_with_next([=] {
|
|
||||||
erasePrevious(hour);
|
|
||||||
}, box->lifetime());
|
|
||||||
|
|
||||||
content->sizeValue(
|
|
||||||
) | rpl::start_with_next([=](const QSize &s) {
|
|
||||||
const auto inputWidth = s.width() / 3;
|
|
||||||
auto rect = QRect(
|
|
||||||
0,
|
|
||||||
(s.height() - day->height()) / 2,
|
|
||||||
inputWidth,
|
|
||||||
day->height());
|
|
||||||
for (const auto &input : { day, hour, minute }) {
|
|
||||||
input->setGeometry(rect - st::muteBoxTimeFieldPadding);
|
|
||||||
rect.translate(inputWidth, 0);
|
|
||||||
}
|
|
||||||
}, box->lifetime());
|
|
||||||
|
|
||||||
box->setTitle(tr::lng_mute_box_title());
|
box->setTitle(tr::lng_mute_box_title());
|
||||||
|
|
||||||
const auto topButton = box->addTopButton(st::infoTopBarMenu);
|
const auto topButton = box->addTopButton(st::infoTopBarMenu);
|
||||||
|
@ -256,31 +175,21 @@ void MuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto updateValueInSeconds = [=] {
|
auto confirmText = rpl::combine(
|
||||||
state->valueInSeconds = 0
|
std::move(chooseTimeResult.secondsValue),
|
||||||
+ day->getLastText().toUInt() * 3600 * 24
|
state->noSoundChanges.value()
|
||||||
+ hour->getLastText().toUInt() * 3600
|
) | rpl::map([=](int seconds, bool noSound) {
|
||||||
+ minute->getLastText().toUInt() * 60;
|
state->lastSeconds = seconds;
|
||||||
};
|
return !seconds
|
||||||
|
|
||||||
using Field = Ui::MaskedInputField;
|
|
||||||
auto confirmText = rpl::merge(
|
|
||||||
base::qt_signal_producer(day.data(), &Field::changed),
|
|
||||||
base::qt_signal_producer(hour.data(), &Field::changed),
|
|
||||||
base::qt_signal_producer(minute.data(), &Field::changed),
|
|
||||||
state->noSoundChanges.value() | rpl::to_empty
|
|
||||||
) | rpl::map([=] {
|
|
||||||
updateValueInSeconds();
|
|
||||||
return !state->valueInSeconds
|
|
||||||
? tr::lng_mute_menu_unmute()
|
? tr::lng_mute_menu_unmute()
|
||||||
: state->noSoundChanges.current()
|
: noSound
|
||||||
? tr::lng_mute_box_silent_notifications()
|
? tr::lng_mute_box_silent_notifications()
|
||||||
: tr::lng_mute_menu_mute();
|
: tr::lng_mute_menu_mute();
|
||||||
}) | rpl::flatten_latest();
|
}) | rpl::flatten_latest();
|
||||||
const auto confirm = box->addButton(std::move(confirmText), [=] {
|
const auto confirm = box->addButton(std::move(confirmText), [=] {
|
||||||
peer->owner().updateNotifySettings(
|
peer->owner().updateNotifySettings(
|
||||||
peer,
|
peer,
|
||||||
state->valueInSeconds,
|
state->lastSeconds,
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
state->noSoundChanges.current());
|
state->noSoundChanges.current());
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
|
|
137
Telegram/SourceFiles/ui/boxes/choose_time.cpp
Normal file
137
Telegram/SourceFiles/ui/boxes/choose_time.cpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "ui/boxes/choose_time.h"
|
||||||
|
|
||||||
|
#include "base/qt_signal_producer.h"
|
||||||
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/widgets/fields/time_part_input_with_placeholder.h"
|
||||||
|
#include "ui/wrap/padding_wrap.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
ChooseTimeResult ChooseTimeWidget(
|
||||||
|
not_null<RpWidget*> parent,
|
||||||
|
TimeId startSeconds) {
|
||||||
|
using TimeField = Ui::TimePartWithPlaceholder;
|
||||||
|
const auto putNext = [](not_null<TimeField*> field, QChar ch) {
|
||||||
|
field->setCursorPosition(0);
|
||||||
|
if (ch.unicode()) {
|
||||||
|
field->setText(ch + field->getLastText());
|
||||||
|
field->setCursorPosition(1);
|
||||||
|
}
|
||||||
|
field->onTextEdited();
|
||||||
|
field->setFocus();
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto erasePrevious = [](not_null<TimeField*> field) {
|
||||||
|
const auto text = field->getLastText();
|
||||||
|
if (!text.isEmpty()) {
|
||||||
|
field->setCursorPosition(text.size() - 1);
|
||||||
|
field->setText(text.mid(0, text.size() - 1));
|
||||||
|
}
|
||||||
|
field->setFocus();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
not_null<TimeField*> day;
|
||||||
|
not_null<TimeField*> hour;
|
||||||
|
not_null<TimeField*> minute;
|
||||||
|
|
||||||
|
rpl::variable<int> valueInSeconds = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto content = object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
parent,
|
||||||
|
st::scheduleHeight);
|
||||||
|
|
||||||
|
const auto startDays = startSeconds / 86400;
|
||||||
|
startSeconds -= startDays * 86400;
|
||||||
|
const auto startHours = startSeconds / 3600;
|
||||||
|
startSeconds -= startHours * 3600;
|
||||||
|
const auto startMinutes = startSeconds / 60;
|
||||||
|
|
||||||
|
const auto state = content->lifetime().make_state<State>(State{
|
||||||
|
.day = Ui::CreateChild<TimeField>(
|
||||||
|
content.data(),
|
||||||
|
st::muteBoxTimeField,
|
||||||
|
rpl::never<QString>(),
|
||||||
|
QString::number(startDays)),
|
||||||
|
.hour = Ui::CreateChild<TimeField>(
|
||||||
|
content.data(),
|
||||||
|
st::muteBoxTimeField,
|
||||||
|
rpl::never<QString>(),
|
||||||
|
QString::number(startHours)),
|
||||||
|
.minute = Ui::CreateChild<TimeField>(
|
||||||
|
content.data(),
|
||||||
|
st::muteBoxTimeField,
|
||||||
|
rpl::never<QString>(),
|
||||||
|
QString::number(startMinutes)),
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto day = Ui::MakeWeak(state->day);
|
||||||
|
const auto hour = Ui::MakeWeak(state->hour);
|
||||||
|
const auto minute = Ui::MakeWeak(state->minute);
|
||||||
|
|
||||||
|
day->setPhrase(tr::lng_mute_box_days);
|
||||||
|
day->setMaxValue(31);
|
||||||
|
day->setWheelStep(1);
|
||||||
|
day->putNext() | rpl::start_with_next([=](QChar ch) {
|
||||||
|
putNext(hour, ch);
|
||||||
|
}, content->lifetime());
|
||||||
|
|
||||||
|
hour->setPhrase(tr::lng_mute_box_hours);
|
||||||
|
hour->setMaxValue(23);
|
||||||
|
hour->setWheelStep(1);
|
||||||
|
hour->putNext() | rpl::start_with_next([=](QChar ch) {
|
||||||
|
putNext(minute, ch);
|
||||||
|
}, content->lifetime());
|
||||||
|
hour->erasePrevious() | rpl::start_with_next([=] {
|
||||||
|
erasePrevious(day);
|
||||||
|
}, content->lifetime());
|
||||||
|
|
||||||
|
minute->setPhrase(tr::lng_mute_box_minutes);
|
||||||
|
minute->setMaxValue(59);
|
||||||
|
minute->setWheelStep(10);
|
||||||
|
minute->erasePrevious() | rpl::start_with_next([=] {
|
||||||
|
erasePrevious(hour);
|
||||||
|
}, content->lifetime());
|
||||||
|
|
||||||
|
content->sizeValue(
|
||||||
|
) | rpl::start_with_next([=](const QSize &s) {
|
||||||
|
const auto inputWidth = s.width() / 3;
|
||||||
|
auto rect = QRect(
|
||||||
|
0,
|
||||||
|
(s.height() - day->height()) / 2,
|
||||||
|
inputWidth,
|
||||||
|
day->height());
|
||||||
|
for (const auto &input : { day, hour, minute }) {
|
||||||
|
input->setGeometry(rect - st::muteBoxTimeFieldPadding);
|
||||||
|
rect.translate(inputWidth, 0);
|
||||||
|
}
|
||||||
|
}, content->lifetime());
|
||||||
|
|
||||||
|
rpl::merge(
|
||||||
|
rpl::single(rpl::empty),
|
||||||
|
base::qt_signal_producer(day.data(), &MaskedInputField::changed),
|
||||||
|
base::qt_signal_producer(hour.data(), &MaskedInputField::changed),
|
||||||
|
base::qt_signal_producer(minute.data(), &MaskedInputField::changed)
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
state->valueInSeconds = 0
|
||||||
|
+ day->getLastText().toUInt() * 3600 * 24
|
||||||
|
+ hour->getLastText().toUInt() * 3600
|
||||||
|
+ minute->getLastText().toUInt() * 60;
|
||||||
|
}, content->lifetime());
|
||||||
|
return {
|
||||||
|
object_ptr<Ui::RpWidget>::fromRaw(content.release()),
|
||||||
|
state->valueInSeconds.value(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ui
|
25
Telegram/SourceFiles/ui/boxes/choose_time.h
Normal file
25
Telegram/SourceFiles/ui/boxes/choose_time.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/object_ptr.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
class RpWidget;
|
||||||
|
|
||||||
|
struct ChooseTimeResult {
|
||||||
|
object_ptr<RpWidget> widget;
|
||||||
|
rpl::producer<TimeId> secondsValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
ChooseTimeResult ChooseTimeWidget(
|
||||||
|
not_null<RpWidget*> parent,
|
||||||
|
TimeId startSeconds);
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -133,6 +133,8 @@ PRIVATE
|
||||||
ui/boxes/calendar_box.h
|
ui/boxes/calendar_box.h
|
||||||
ui/boxes/choose_date_time.cpp
|
ui/boxes/choose_date_time.cpp
|
||||||
ui/boxes/choose_date_time.h
|
ui/boxes/choose_date_time.h
|
||||||
|
ui/boxes/choose_time.cpp
|
||||||
|
ui/boxes/choose_time.h
|
||||||
ui/boxes/confirm_box.cpp
|
ui/boxes/confirm_box.cpp
|
||||||
ui/boxes/confirm_box.h
|
ui/boxes/confirm_box.h
|
||||||
ui/boxes/confirm_phone_box.cpp
|
ui/boxes/confirm_phone_box.cpp
|
||||||
|
|
Loading…
Add table
Reference in a new issue