1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #include "passport/passport_panel_form.h"
9
10 #include "passport/passport_panel_controller.h"
11 #include "passport/ui/passport_form_row.h"
12 #include "lang/lang_keys.h"
13 #include "boxes/abstract_box.h"
14 #include "core/click_handler_types.h"
15 #include "data/data_user.h"
16 #include "ui/effects/animations.h"
17 #include "ui/widgets/shadow.h"
18 #include "ui/widgets/buttons.h"
19 #include "ui/widgets/scroll_area.h"
20 #include "ui/widgets/labels.h"
21 #include "ui/widgets/box_content_divider.h"
22 #include "ui/wrap/vertical_layout.h"
23 #include "ui/wrap/fade_wrap.h"
24 #include "ui/wrap/padding_wrap.h"
25 #include "ui/text/text_utilities.h"
26 #include "ui/text/text_options.h"
27 #include "ui/special_buttons.h"
28 #include "styles/style_passport.h"
29 #include "styles/style_layers.h"
30 #include "styles/style_boxes.h"
31
32 namespace Passport {
33
PanelForm(QWidget * parent,not_null<PanelController * > controller)34 PanelForm::PanelForm(
35 QWidget *parent,
36 not_null<PanelController*> controller)
37 : RpWidget(parent)
38 , _controller(controller)
39 , _scroll(this, st::passportPanelScroll)
40 , _topShadow(this)
41 , _bottomShadow(this)
42 , _submit(
43 this,
44 tr::lng_passport_authorize(),
45 st::passportPanelAuthorize) {
46 setupControls();
47 }
48
setupControls()49 void PanelForm::setupControls() {
50 const auto inner = setupContent();
51
52 _submit->addClickHandler([=] {
53 _controller->submitForm();
54 });
55
56 using namespace rpl::mappers;
57
58 _topShadow->toggleOn(
59 _scroll->scrollTopValue() | rpl::map(_1 > 0));
60 _bottomShadow->toggleOn(rpl::combine(
61 _scroll->scrollTopValue(),
62 _scroll->heightValue(),
63 inner->heightValue(),
64 _1 + _2 < _3));
65 }
66
setupContent()67 not_null<Ui::RpWidget*> PanelForm::setupContent() {
68 const auto bot = _controller->bot();
69
70 const auto inner = _scroll->setOwnedWidget(
71 object_ptr<Ui::VerticalLayout>(this));
72 _scroll->widthValue(
73 ) | rpl::start_with_next([=](int width) {
74 inner->resizeToWidth(width);
75 }, inner->lifetime());
76
77 const auto userpicWrap = inner->add(
78 object_ptr<Ui::FixedHeightWidget>(
79 inner,
80 st::passportFormUserpic.size.height()),
81 st::passportFormUserpicPadding);
82 _userpic = Ui::AttachParentChild(
83 userpicWrap,
84 object_ptr<Ui::UserpicButton>(
85 userpicWrap,
86 bot,
87 Ui::UserpicButton::Role::Custom,
88 st::passportFormUserpic));
89 userpicWrap->widthValue(
90 ) | rpl::start_with_next([=](int width) {
91 _userpic->move((width - _userpic->width()) / 2, _userpic->y());
92 }, _userpic->lifetime());
93
94 _about1 = inner->add(
95 object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
96 inner,
97 object_ptr<Ui::FlatLabel>(
98 inner,
99 tr::lng_passport_request1(tr::now, lt_bot, bot->name),
100 st::passportPasswordLabelBold)),
101 st::passportFormAbout1Padding)->entity();
102
103 _about2 = inner->add(
104 object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
105 inner,
106 object_ptr<Ui::FlatLabel>(
107 inner,
108 tr::lng_passport_request2(tr::now),
109 st::passportPasswordLabel)),
110 st::passportFormAbout2Padding)->entity();
111
112 inner->add(object_ptr<Ui::BoxContentDivider>(
113 inner,
114 st::passportFormDividerHeight));
115 inner->add(
116 object_ptr<Ui::FlatLabel>(
117 inner,
118 tr::lng_passport_header(tr::now),
119 st::passportFormHeader),
120 st::passportFormHeaderPadding);
121
122 auto index = 0;
123 _controller->fillRows([&](
124 QString title,
125 QString description,
126 bool ready,
127 bool error) {
128 _rows.push_back(inner->add(object_ptr<Row>(this)));
129 _rows.back()->addClickHandler([=] {
130 _controller->editScope(index);
131 });
132 _rows.back()->updateContent(
133 title,
134 description,
135 ready,
136 error,
137 anim::type::instant);
138 ++index;
139 });
140 _controller->refillRows(
141 ) | rpl::start_with_next([=] {
142 auto index = 0;
143 _controller->fillRows([&](
144 QString title,
145 QString description,
146 bool ready,
147 bool error) {
148 Expects(index < _rows.size());
149
150 _rows[index++]->updateContent(
151 title,
152 description,
153 ready,
154 error,
155 anim::type::normal);
156 });
157 }, lifetime());
158 const auto policyUrl = _controller->privacyPolicyUrl();
159 auto text = policyUrl.isEmpty()
160 ? tr::lng_passport_allow(
161 lt_bot,
162 rpl::single('@' + bot->username)
163 ) | Ui::Text::ToWithEntities()
164 : tr::lng_passport_accept_allow(
165 lt_policy,
166 tr::lng_passport_policy(
167 lt_bot,
168 rpl::single(bot->name)
169 ) | Ui::Text::ToLink(policyUrl),
170 lt_bot,
171 rpl::single('@' + bot->username) | Ui::Text::ToWithEntities(),
172 Ui::Text::WithEntities);
173 const auto policy = inner->add(
174 object_ptr<Ui::FlatLabel>(
175 inner,
176 std::move(text),
177 st::passportFormPolicy),
178 st::passportFormPolicyPadding);
179 policy->setLinksTrusted();
180
181 return inner;
182 }
183
resizeEvent(QResizeEvent * e)184 void PanelForm::resizeEvent(QResizeEvent *e) {
185 updateControlsGeometry();
186 }
187
updateControlsGeometry()188 void PanelForm::updateControlsGeometry() {
189 const auto submitTop = height() - _submit->height();
190 _scroll->setGeometry(0, 0, width(), submitTop);
191 _topShadow->resizeToWidth(width());
192 _topShadow->moveToLeft(0, 0);
193 _bottomShadow->resizeToWidth(width());
194 _bottomShadow->moveToLeft(0, submitTop - st::lineWidth);
195 _submit->setFullWidth(width());
196 _submit->moveToLeft(0, submitTop);
197
198 _scroll->updateBars();
199 }
200
201 } // namespace Passport
202