mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Improve session details box design.
This commit is contained in:
parent
92e398e0b7
commit
1d1fa5f98b
5 changed files with 298 additions and 116 deletions
|
@ -74,6 +74,7 @@
|
|||
<file alias="settings/devices/device_desktop_mac.lottie">../../icons/settings/devices/device_desktop_mac.lottie</file>
|
||||
<file alias="settings/devices/device_desktop_win.lottie">../../icons/settings/devices/device_desktop_win.lottie</file>
|
||||
<file alias="settings/devices/device_linux.lottie">../../icons/settings/devices/device_linux.lottie</file>
|
||||
<file alias="settings/devices/device_linux_ubuntu.lottie">../../icons/settings/devices/device_linux_ubuntu.lottie</file>
|
||||
<file alias="settings/devices/device_phone_android.lottie">../../icons/settings/devices/device_phone_android.lottie</file>
|
||||
<file alias="settings/devices/device_phone_ios.lottie">../../icons/settings/devices/device_phone_ios.lottie</file>
|
||||
<file alias="settings/devices/device_tablet_ios.lottie">../../icons/settings/devices/device_tablet_ios.lottie</file>
|
||||
|
|
|
@ -279,71 +279,6 @@ membersAbout: FlatLabel(defaultFlatLabel) {
|
|||
style: boxLabelStyle;
|
||||
}
|
||||
|
||||
sessionsScroll: boxScroll;
|
||||
sessionsHeight: 350px;
|
||||
sessionsTerminateAll: SettingsButton(defaultSettingsButton) {
|
||||
textFg: attentionButtonFg;
|
||||
textFgOver: attentionButtonFgOver;
|
||||
font: font(boxFontSize semibold);
|
||||
height: 20px;
|
||||
padding: margins(77px, 12px, 22px, 10px);
|
||||
}
|
||||
sessionsTerminateAllIcon: icon {{ "settings/devices/terminate_all", attentionButtonFg }};
|
||||
sessionsTerminateAllIconLeft: 30px;
|
||||
sessionHeight: 84px;
|
||||
sessionInfoTop: 21px;
|
||||
sessionLocationTop: 43px;
|
||||
sessionCurrentSkip: 8px;
|
||||
sessionSubtitleSkip: 14px;
|
||||
sessionPadding: margins(77px, 11px, 22px, 0px);
|
||||
sessionNameFont: msgNameFont;
|
||||
sessionNameFg: boxTextFg;
|
||||
sessionWhenFont: msgDateFont;
|
||||
sessionWhenFg: windowSubTextFg;
|
||||
sessionInfoFont: msgFont;
|
||||
sessionInfoFg: windowSubTextFg;
|
||||
sessionTerminateTop: 9px;
|
||||
sessionTerminateSkip: 22px;
|
||||
sessionUserpicSize: 42px;
|
||||
sessionUserpicPosition: point(21px, 10px);
|
||||
sessionNamePadding: margins(0px, 0px, 5px, 0px);
|
||||
sessionTerminate: IconButton {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
icon: smallCloseIcon;
|
||||
iconOver: smallCloseIconOver;
|
||||
iconPosition: point(5px, 5px);
|
||||
|
||||
rippleAreaPosition: point(0px, 0px);
|
||||
rippleAreaSize: 20px;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
sessionNameStyle: TextStyle(defaultTextStyle) {
|
||||
font: sessionNameFont;
|
||||
}
|
||||
sessionWhenStyle: TextStyle(defaultTextStyle) {
|
||||
font: sessionWhenFont;
|
||||
}
|
||||
sessionInfoStyle: TextStyle(defaultTextStyle) {
|
||||
font: sessionInfoFont;
|
||||
}
|
||||
sessionIconWindows: icon{{ "settings/devices/device_desktop_win", historyPeerUserpicFg }};
|
||||
sessionIconMac: icon{{ "settings/devices/device_desktop_mac", historyPeerUserpicFg }};
|
||||
sessionIconUbuntu: icon{{ "settings/devices/device_linux_ubuntu", historyPeerUserpicFg }};
|
||||
sessionIconLinux: icon{{ "settings/devices/device_linux", historyPeerUserpicFg }};
|
||||
sessionIconiPhone: icon{{ "settings/devices/device_phone_ios", historyPeerUserpicFg }};
|
||||
sessionIconiPad: icon{{ "settings/devices/device_tablet_ios", historyPeerUserpicFg }};
|
||||
sessionIconAndroid: icon{{ "settings/devices/device_phone_android", historyPeerUserpicFg }};
|
||||
sessionIconWeb: icon{{ "settings/devices/device_web_other", historyPeerUserpicFg }};
|
||||
sessionIconChrome: icon{{ "settings/devices/device_web_chrome", historyPeerUserpicFg }};
|
||||
sessionIconEdge: icon{{ "settings/devices/device_web_edge", historyPeerUserpicFg }};
|
||||
sessionIconFirefox: icon{{ "settings/devices/device_web_firefox", historyPeerUserpicFg }};
|
||||
sessionIconSafari: icon{{ "settings/devices/device_web_safari", historyPeerUserpicFg }};
|
||||
sessionIconOther: icon{{ "settings/devices/device_other", historyPeerUserpicFg }};
|
||||
|
||||
passcodeHeaderFont: font(19px);
|
||||
passcodeHeaderHeight: 80px;
|
||||
passcodeInput: InputField(introPhone) {
|
||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "lottie/lottie_icon.h"
|
||||
|
@ -93,56 +94,6 @@ void RenameBox(not_null<Ui::GenericBox*> box) {
|
|||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
void SessionInfoBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const EntryData &data,
|
||||
Fn<void(uint64)> terminate) {
|
||||
box->setTitle(rpl::single(data.name));
|
||||
box->setWidth(st::boxWidth);
|
||||
|
||||
const auto skips = style::margins(0, 0, 0, st::settingsSectionSkip);
|
||||
const auto date = base::unixtime::parse(data.activeTime);
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
rpl::single(langDateTimeFull(date)),
|
||||
st::boxDividerLabel),
|
||||
st::boxRowPadding + skips);
|
||||
|
||||
const auto add = [&](rpl::producer<QString> label, QString value) {
|
||||
if (value.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Settings::AddSubsectionTitle(
|
||||
box->verticalLayout(),
|
||||
std::move(label));
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
rpl::single(value),
|
||||
st::boxDividerLabel),
|
||||
st::boxRowPadding + skips);
|
||||
};
|
||||
add(tr::lng_sessions_application(), data.info);
|
||||
add(tr::lng_sessions_system(), data.system);
|
||||
add(tr::lng_sessions_ip(), data.ip);
|
||||
add(tr::lng_sessions_location(), data.location);
|
||||
if (!data.location.isEmpty()) {
|
||||
Settings::AddDividerText(
|
||||
box->verticalLayout(),
|
||||
tr::lng_sessions_location_about());
|
||||
}
|
||||
|
||||
box->addButton(tr::lng_about_done(), [=] { box->closeBox(); });
|
||||
box->addLeftButton(tr::lng_sessions_terminate(), [=, hash = data.hash] {
|
||||
const auto weak = Ui::MakeWeak(box.get());
|
||||
terminate(hash);
|
||||
if (weak) {
|
||||
box->closeBox();
|
||||
}
|
||||
}, st::attentionBoxButton);
|
||||
}
|
||||
|
||||
[[nodiscard]] QString LocationAndDate(const EntryData &entry) {
|
||||
return (entry.location.isEmpty() ? entry.ip : entry.location)
|
||||
+ (entry.hash
|
||||
|
@ -265,6 +216,44 @@ void SessionInfoBox(
|
|||
Unexpected("Type in IconForType.");
|
||||
}
|
||||
|
||||
[[nodiscard]] const style::icon *IconBigForType(Type type) {
|
||||
switch (type) {
|
||||
case Type::Web: return &st::sessionBigIconWeb;
|
||||
case Type::Other: return &st::sessionBigIconOther;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Lottie::Icon> LottieForType(Type type) {
|
||||
if (IconBigForType(type)) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto path = [&] {
|
||||
switch (type) {
|
||||
case Type::Windows: return "device_desktop_win";
|
||||
case Type::Mac: return "device_desktop_mac";
|
||||
case Type::Ubuntu: return "device_linux_ubuntu";
|
||||
case Type::Linux: return "device_linux";
|
||||
case Type::iPhone: return "device_phone_ios";
|
||||
case Type::iPad: return "device_tablet_ios";
|
||||
case Type::Android: return "device_phone_android";
|
||||
case Type::Chrome: return "device_web_chrome";
|
||||
case Type::Edge: return "device_web_edge";
|
||||
case Type::Firefox: return "device_web_firefox";
|
||||
case Type::Safari: return "device_web_safari";
|
||||
}
|
||||
Unexpected("Type in LottieForType.");
|
||||
}();
|
||||
const auto size = st::sessionBigLottieSize;
|
||||
static const auto kWhite = style::owned_color(Qt::white);
|
||||
return std::make_unique<Lottie::Icon>(Lottie::IconDescriptor{
|
||||
.path = u":/icons/settings/devices/"_q + path + u".lottie"_q,
|
||||
.color = kWhite.color(),
|
||||
.sizeOverride = QSize(size, size),
|
||||
.frame = 1,
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage GenerateUserpic(Type type) {
|
||||
const auto size = st::sessionUserpicSize;
|
||||
const auto full = size * style::DevicePixelRatio();
|
||||
|
@ -285,6 +274,172 @@ void SessionInfoBox(
|
|||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> GenerateUserpicBig(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
rpl::producer<> shown,
|
||||
Type type) {
|
||||
const auto size = st::sessionBigUserpicSize;
|
||||
const auto full = size * style::DevicePixelRatio();
|
||||
const auto rect = QRect(0, 0, size, size);
|
||||
|
||||
const auto result = Ui::CreateChild<Ui::RpWidget>(parent.get());
|
||||
result->resize(rect.size());
|
||||
struct State {
|
||||
QImage background;
|
||||
std::unique_ptr<Lottie::Icon> lottie;
|
||||
QImage lottieFrame;
|
||||
QImage colorizedFrame;
|
||||
};
|
||||
const auto state = result->lifetime().make_state<State>();
|
||||
state->background = QImage(
|
||||
full,
|
||||
full,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
state->background.fill(Qt::transparent);
|
||||
state->background.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
state->colorizedFrame = state->lottieFrame = state->background;
|
||||
|
||||
auto p = QPainter(&state->background);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setBrush(ColorForType(type));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(rect);
|
||||
if (const auto icon = IconBigForType(type)) {
|
||||
icon->paintInCenter(p, rect);
|
||||
}
|
||||
p.end();
|
||||
|
||||
if ((state->lottie = LottieForType(type))) {
|
||||
std::move(
|
||||
shown
|
||||
) | rpl::start_with_next([=] {
|
||||
state->lottie->animate(
|
||||
[=] { result->update(); },
|
||||
0,
|
||||
state->lottie->framesCount());
|
||||
}, result->lifetime());
|
||||
}
|
||||
|
||||
result->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
auto p = QPainter(result);
|
||||
p.drawImage(QPoint(0, 0), state->background);
|
||||
if (state->lottie) {
|
||||
state->lottieFrame.fill(Qt::black);
|
||||
auto q = QPainter(&state->lottieFrame);
|
||||
state->lottie->paintInCenter(q, result->rect());
|
||||
q.end();
|
||||
style::colorizeImage(
|
||||
state->lottieFrame,
|
||||
st::historyPeerUserpicFg->c,
|
||||
&state->colorizedFrame);
|
||||
p.drawImage(QPoint(0, 0), state->colorizedFrame);
|
||||
|
||||
}
|
||||
}, result->lifetime());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SessionInfoBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const EntryData &data,
|
||||
Fn<void(uint64)> terminate) {
|
||||
box->setWidth(st::boxWideWidth);
|
||||
|
||||
const auto shown = box->lifetime().make_state<rpl::event_stream<>>();
|
||||
box->setShowFinishedCallback([=] {
|
||||
shown->fire({});
|
||||
});
|
||||
|
||||
const auto userpicWrap = box->addRow(
|
||||
object_ptr<Ui::FixedHeightWidget>(box, st::sessionBigUserpicSize),
|
||||
st::sessionBigCoverPadding);
|
||||
const auto big = GenerateUserpicBig(
|
||||
userpicWrap,
|
||||
shown->events(),
|
||||
TypeFromEntry(data));
|
||||
userpicWrap->sizeValue(
|
||||
) | rpl::start_with_next([=](QSize size) {
|
||||
big->move((size.width() - big->width()) / 2, 0);
|
||||
}, userpicWrap->lifetime());
|
||||
|
||||
const auto nameWrap = box->addRow(
|
||||
object_ptr<Ui::FixedHeightWidget>(
|
||||
box,
|
||||
st::sessionBigName.maxHeight));
|
||||
const auto name = Ui::CreateChild<Ui::FlatLabel>(
|
||||
nameWrap,
|
||||
rpl::single(data.name),
|
||||
st::sessionBigName);
|
||||
nameWrap->widthValue(
|
||||
) | rpl::start_with_next([=](int width) {
|
||||
name->resizeToWidth(width);
|
||||
name->move((width - name->width()) / 2, 0);
|
||||
}, name->lifetime());
|
||||
|
||||
const auto dateWrap = box->addRow(
|
||||
object_ptr<Ui::FixedHeightWidget>(
|
||||
box,
|
||||
st::sessionDateLabel.style.font->height),
|
||||
style::margins(0, 0, 0, st::sessionDateSkip));
|
||||
const auto date = Ui::CreateChild<Ui::FlatLabel>(
|
||||
dateWrap,
|
||||
rpl::single(
|
||||
langDateTimeFull(base::unixtime::parse(data.activeTime))),
|
||||
st::sessionDateLabel);
|
||||
rpl::combine(
|
||||
dateWrap->widthValue(),
|
||||
date->widthValue()
|
||||
) | rpl::start_with_next([=](int outer, int inner) {
|
||||
date->move((outer - inner) / 2, 0);
|
||||
}, date->lifetime());
|
||||
|
||||
using namespace Settings;
|
||||
const auto container = box->verticalLayout();
|
||||
AddDivider(container);
|
||||
AddSkip(container, st::sessionSubtitleSkip);
|
||||
AddSubsectionTitle(container, tr::lng_sessions_info());
|
||||
|
||||
const auto add = [&](rpl::producer<QString> label, QString value) {
|
||||
if (value.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
container->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
rpl::single(value),
|
||||
st::boxLabel),
|
||||
st::boxRowPadding + st::sessionValuePadding);
|
||||
container->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
std::move(label),
|
||||
st::sessionValueLabel),
|
||||
(st::boxRowPadding
|
||||
+ style::margins{ 0, 0, 0, st::sessionValueSkip }));
|
||||
};
|
||||
add(tr::lng_sessions_application(), data.info);
|
||||
add(tr::lng_sessions_system(), data.system);
|
||||
add(tr::lng_sessions_ip(), data.ip);
|
||||
add(tr::lng_sessions_location(), data.location);
|
||||
AddSkip(container, st::sessionValueSkip);
|
||||
if (!data.location.isEmpty()) {
|
||||
AddDividerText(container, tr::lng_sessions_location_about());
|
||||
}
|
||||
|
||||
box->addButton(tr::lng_about_done(), [=] { box->closeBox(); });
|
||||
if (const auto hash = data.hash) {
|
||||
box->addLeftButton(tr::lng_sessions_terminate(), [=] {
|
||||
const auto weak = Ui::MakeWeak(box.get());
|
||||
terminate(hash);
|
||||
if (weak) {
|
||||
box->closeBox();
|
||||
}
|
||||
}, st::attentionBoxButton);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class SessionsContent : public Ui::RpWidget {
|
||||
|
@ -737,6 +892,7 @@ rpl::producer<uint64> SessionsContent::Inner::terminateOne() const {
|
|||
|
||||
rpl::producer<EntryData> SessionsContent::Inner::showRequests() const {
|
||||
return rpl::merge(
|
||||
_current->showRequests(),
|
||||
_incomplete->showRequests(),
|
||||
_list->showRequests());
|
||||
}
|
||||
|
|
|
@ -237,3 +237,93 @@ settingsDeviceName: InputField(defaultInputField) {
|
|||
dictionariesSectionButton: SettingsButton(settingsUpdateToggle) {
|
||||
font: font(14px semibold);
|
||||
}
|
||||
|
||||
sessionsScroll: boxScroll;
|
||||
sessionsHeight: 350px;
|
||||
sessionsTerminateAll: SettingsButton(defaultSettingsButton) {
|
||||
textFg: attentionButtonFg;
|
||||
textFgOver: attentionButtonFgOver;
|
||||
font: font(boxFontSize semibold);
|
||||
height: 20px;
|
||||
padding: margins(77px, 12px, 22px, 10px);
|
||||
}
|
||||
sessionsTerminateAllIcon: icon {{ "settings/devices/terminate_all", attentionButtonFg }};
|
||||
sessionsTerminateAllIconLeft: 30px;
|
||||
sessionHeight: 84px;
|
||||
sessionInfoTop: 21px;
|
||||
sessionLocationTop: 43px;
|
||||
sessionCurrentSkip: 8px;
|
||||
sessionSubtitleSkip: 14px;
|
||||
sessionPadding: margins(77px, 11px, 22px, 0px);
|
||||
sessionNameFont: msgNameFont;
|
||||
sessionNameFg: boxTextFg;
|
||||
sessionWhenFont: msgDateFont;
|
||||
sessionWhenFg: windowSubTextFg;
|
||||
sessionInfoFont: msgFont;
|
||||
sessionInfoFg: windowSubTextFg;
|
||||
sessionTerminateTop: 9px;
|
||||
sessionTerminateSkip: 22px;
|
||||
sessionUserpicSize: 42px;
|
||||
sessionUserpicPosition: point(21px, 10px);
|
||||
sessionNamePadding: margins(0px, 0px, 5px, 0px);
|
||||
sessionTerminate: IconButton {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
icon: smallCloseIcon;
|
||||
iconOver: smallCloseIconOver;
|
||||
iconPosition: point(5px, 5px);
|
||||
|
||||
rippleAreaPosition: point(0px, 0px);
|
||||
rippleAreaSize: 20px;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
sessionNameStyle: TextStyle(defaultTextStyle) {
|
||||
font: sessionNameFont;
|
||||
}
|
||||
sessionWhenStyle: TextStyle(defaultTextStyle) {
|
||||
font: sessionWhenFont;
|
||||
}
|
||||
sessionInfoStyle: TextStyle(defaultTextStyle) {
|
||||
font: sessionInfoFont;
|
||||
}
|
||||
sessionIconWindows: icon{{ "settings/devices/device_desktop_win", historyPeerUserpicFg }};
|
||||
sessionIconMac: icon{{ "settings/devices/device_desktop_mac", historyPeerUserpicFg }};
|
||||
sessionIconUbuntu: icon{{ "settings/devices/device_linux_ubuntu", historyPeerUserpicFg }};
|
||||
sessionIconLinux: icon{{ "settings/devices/device_linux", historyPeerUserpicFg }};
|
||||
sessionIconiPhone: icon{{ "settings/devices/device_phone_ios", historyPeerUserpicFg }};
|
||||
sessionIconiPad: icon{{ "settings/devices/device_tablet_ios", historyPeerUserpicFg }};
|
||||
sessionIconAndroid: icon{{ "settings/devices/device_phone_android", historyPeerUserpicFg }};
|
||||
sessionIconWeb: icon{{ "settings/devices/device_web_other", historyPeerUserpicFg }};
|
||||
sessionIconChrome: icon{{ "settings/devices/device_web_chrome", historyPeerUserpicFg }};
|
||||
sessionIconEdge: icon{{ "settings/devices/device_web_edge", historyPeerUserpicFg }};
|
||||
sessionIconFirefox: icon{{ "settings/devices/device_web_firefox", historyPeerUserpicFg }};
|
||||
sessionIconSafari: icon{{ "settings/devices/device_web_safari", historyPeerUserpicFg }};
|
||||
sessionIconOther: icon{{ "settings/devices/device_other", historyPeerUserpicFg }};
|
||||
sessionBigUserpicSize: 70px;
|
||||
sessionBigLottieSize: 52px;
|
||||
sessionBigIconOther: icon{{ "settings/devices/device_other_large", historyPeerUserpicFg }};
|
||||
sessionBigIconWeb: icon{{ "settings/devices/device_web_other_large", historyPeerUserpicFg }};
|
||||
sessionBigCoverPadding: margins(0px, 18px, 0px, 7px);
|
||||
sessionBigName: FlatLabel(defaultFlatLabel) {
|
||||
textFg: boxTitleFg;
|
||||
maxHeight: 29px;
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(20px semibold);
|
||||
linkFont: font(20px semibold);
|
||||
linkFontOver: font(20px semibold underline);
|
||||
}
|
||||
align: align(top);
|
||||
}
|
||||
sessionDateLabel: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowSubTextFg;
|
||||
align: align(top);
|
||||
}
|
||||
sessionDateSkip: 19px;
|
||||
sessionValuePadding: margins(0px, 5px, 0px, 2px);
|
||||
sessionValueLabel: FlatLabel(defaultFlatLabel) {
|
||||
textFg: windowSubTextFg;
|
||||
}
|
||||
sessionValueSkip: 8px;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit fd4d8576adb611780d1dc7dcce4fe0115eabc9c0
|
||||
Subproject commit ad7fce76f3b403471a296c928bae67cd36b8b2cf
|
Loading…
Add table
Reference in a new issue