Improve sessions list design.
After Width: | Height: | Size: 757 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 414 B |
After Width: | Height: | Size: 662 B |
After Width: | Height: | Size: 984 B |
After Width: | Height: | Size: 611 B |
After Width: | Height: | Size: 1011 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 821 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 699 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
|
@ -723,12 +723,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_sessions_terminate_all_about" = "Logs out all devices except for this one.";
|
"lng_sessions_terminate_all_about" = "Logs out all devices except for this one.";
|
||||||
"lng_sessions_incomplete" = "Incomplete login attempts";
|
"lng_sessions_incomplete" = "Incomplete login attempts";
|
||||||
"lng_sessions_incomplete_about" = "The devices above have no access to your messages. The code was entered correctly, but no correct password was given.";
|
"lng_sessions_incomplete_about" = "The devices above have no access to your messages. The code was entered correctly, but no correct password was given.";
|
||||||
"lng_sessions_terminate" = "Terminate";
|
"lng_sessions_info" = "Info";
|
||||||
|
"lng_sessions_terminate" = "Terminate Session";
|
||||||
"lng_sessions_application" = "Application";
|
"lng_sessions_application" = "Application";
|
||||||
"lng_sessions_system" = "System Version";
|
"lng_sessions_system" = "System version";
|
||||||
"lng_sessions_ip" = "IP Address";
|
"lng_sessions_ip" = "IP address";
|
||||||
"lng_sessions_location" = "Location";
|
"lng_sessions_location" = "Location";
|
||||||
"lng_sessions_location_about" = "This location estimate is based on the IP address and may not always be accurate.";
|
"lng_sessions_location_about" = "This location is based only on the IP address and may not always be accurate.";
|
||||||
|
"lng_sessions_about_apps" = "The official Telegram app is available for Android, iPhone, iPad, Windows, macOS and Linux.";
|
||||||
|
|
||||||
"lng_blocked_list_title" = "Blocked users";
|
"lng_blocked_list_title" = "Blocked users";
|
||||||
"lng_blocked_list_unknown_phone" = "unknown phone number";
|
"lng_blocked_list_unknown_phone" = "unknown phone number";
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Api {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto TestApiId = 17349;
|
constexpr auto TestApiId = 17349;
|
||||||
|
constexpr auto SnapApiId = 611335;
|
||||||
constexpr auto DesktopApiId = 2040;
|
constexpr auto DesktopApiId = 2040;
|
||||||
|
|
||||||
Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||||
|
@ -25,9 +26,11 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||||
result.hash = data.is_current() ? 0 : data.vhash().v;
|
result.hash = data.is_current() ? 0 : data.vhash().v;
|
||||||
result.incomplete = data.is_password_pending();
|
result.incomplete = data.is_password_pending();
|
||||||
|
|
||||||
const auto apiId = data.vapi_id().v;
|
const auto apiId = result.apiId = data.vapi_id().v;
|
||||||
const auto isTest = (apiId == TestApiId);
|
const auto isTest = (apiId == TestApiId);
|
||||||
const auto isDesktop = (apiId == DesktopApiId) || isTest;
|
const auto isDesktop = (apiId == DesktopApiId)
|
||||||
|
|| (apiId == SnapApiId)
|
||||||
|
|| isTest;
|
||||||
|
|
||||||
const auto appName = isDesktop
|
const auto appName = isDesktop
|
||||||
? QString("Telegram Desktop%1").arg(isTest ? " (GitHub)" : QString())
|
? QString("Telegram Desktop%1").arg(isTest ? " (GitHub)" : QString())
|
||||||
|
@ -59,6 +62,7 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||||
// country = QString::fromUtf8(j.value()->name);
|
// country = QString::fromUtf8(j.value()->name);
|
||||||
//}
|
//}
|
||||||
result.system = qs(data.vsystem_version());
|
result.system = qs(data.vsystem_version());
|
||||||
|
result.platform = qs(data.vplatform());
|
||||||
result.activeTime = data.vdate_active().v
|
result.activeTime = data.vdate_active().v
|
||||||
? data.vdate_active().v
|
? data.vdate_active().v
|
||||||
: data.vdate_created().v;
|
: data.vdate_created().v;
|
||||||
|
|
|
@ -21,8 +21,9 @@ public:
|
||||||
uint64 hash = 0;
|
uint64 hash = 0;
|
||||||
|
|
||||||
bool incomplete = false;
|
bool incomplete = false;
|
||||||
|
int apiId = 0;
|
||||||
TimeId activeTime = 0;
|
TimeId activeTime = 0;
|
||||||
QString name, active, info, ip, location, system;
|
QString name, active, info, ip, location, system, platform;
|
||||||
};
|
};
|
||||||
using List = std::vector<Entry>;
|
using List = std::vector<Entry>;
|
||||||
|
|
||||||
|
|
|
@ -281,10 +281,21 @@ membersAbout: FlatLabel(defaultFlatLabel) {
|
||||||
|
|
||||||
sessionsScroll: boxScroll;
|
sessionsScroll: boxScroll;
|
||||||
sessionsHeight: 350px;
|
sessionsHeight: 350px;
|
||||||
sessionHeight: 70px;
|
sessionsTerminateAll: SettingsButton(defaultSettingsButton) {
|
||||||
sessionCurrentPadding: margins(0px, 7px, 0px, 4px);
|
textFg: attentionButtonFg;
|
||||||
sessionCurrentHeight: 118px;
|
textFgOver: attentionButtonFgOver;
|
||||||
sessionPadding: margins(22px, 10px, 22px, 0px);
|
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;
|
sessionNameFont: msgNameFont;
|
||||||
sessionNameFg: boxTextFg;
|
sessionNameFg: boxTextFg;
|
||||||
sessionWhenFont: msgDateFont;
|
sessionWhenFont: msgDateFont;
|
||||||
|
@ -293,6 +304,8 @@ sessionInfoFont: msgFont;
|
||||||
sessionInfoFg: windowSubTextFg;
|
sessionInfoFg: windowSubTextFg;
|
||||||
sessionTerminateTop: 9px;
|
sessionTerminateTop: 9px;
|
||||||
sessionTerminateSkip: 22px;
|
sessionTerminateSkip: 22px;
|
||||||
|
sessionUserpicSize: 42px;
|
||||||
|
sessionUserpicPosition: point(21px, 10px);
|
||||||
sessionNamePadding: margins(0px, 0px, 5px, 0px);
|
sessionNamePadding: margins(0px, 0px, 5px, 0px);
|
||||||
sessionTerminate: IconButton {
|
sessionTerminate: IconButton {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
@ -308,10 +321,6 @@ sessionTerminate: IconButton {
|
||||||
color: windowBgOver;
|
color: windowBgOver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sessionTerminateAllButton: LinkButton(boxLinkButton) {
|
|
||||||
color: attentionButtonFg;
|
|
||||||
overColor: attentionButtonFg;
|
|
||||||
}
|
|
||||||
sessionNameStyle: TextStyle(defaultTextStyle) {
|
sessionNameStyle: TextStyle(defaultTextStyle) {
|
||||||
font: sessionNameFont;
|
font: sessionNameFont;
|
||||||
}
|
}
|
||||||
|
@ -321,6 +330,19 @@ sessionWhenStyle: TextStyle(defaultTextStyle) {
|
||||||
sessionInfoStyle: TextStyle(defaultTextStyle) {
|
sessionInfoStyle: TextStyle(defaultTextStyle) {
|
||||||
font: sessionInfoFont;
|
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);
|
passcodeHeaderFont: font(19px);
|
||||||
passcodeHeaderHeight: 80px;
|
passcodeHeaderHeight: 80px;
|
||||||
|
|
|
@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
|
#include "lottie/lottie_icon.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
@ -39,6 +40,22 @@ constexpr auto kMaxDeviceModelLength = 32;
|
||||||
|
|
||||||
using EntryData = Api::Authorizations::Entry;
|
using EntryData = Api::Authorizations::Entry;
|
||||||
|
|
||||||
|
enum class Type {
|
||||||
|
Windows,
|
||||||
|
Mac,
|
||||||
|
Ubuntu,
|
||||||
|
Linux,
|
||||||
|
iPhone,
|
||||||
|
iPad,
|
||||||
|
Android,
|
||||||
|
Web,
|
||||||
|
Chrome,
|
||||||
|
Edge,
|
||||||
|
Firefox,
|
||||||
|
Safari,
|
||||||
|
Other,
|
||||||
|
};
|
||||||
|
|
||||||
void RenameBox(not_null<Ui::GenericBox*> box) {
|
void RenameBox(not_null<Ui::GenericBox*> box) {
|
||||||
box->setTitle(tr::lng_settings_rename_device_title());
|
box->setTitle(tr::lng_settings_rename_device_title());
|
||||||
|
|
||||||
|
@ -133,6 +150,141 @@ void SessionInfoBox(
|
||||||
: QString());
|
: QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] Type TypeFromEntry(const EntryData &entry) {
|
||||||
|
using List = std::vector<int>;
|
||||||
|
const auto platform = entry.platform.toLower();
|
||||||
|
const auto device = entry.name.toLower();
|
||||||
|
const auto system = entry.system.toLower();
|
||||||
|
const auto apiId = entry.apiId;
|
||||||
|
const auto kDesktop = std::array{ 2040, 17349, 611335 };
|
||||||
|
const auto kMac = std::array{ 2834 };
|
||||||
|
const auto kAndroid
|
||||||
|
= std::array{ 5, 6, 24, 1026, 1083, 2458, 2521, 21724 };
|
||||||
|
const auto kiOS = std::array{ 1, 7, 10840, 16352 };
|
||||||
|
const auto kWeb = std::array{ 2496, 739222, 1025907 };
|
||||||
|
|
||||||
|
const auto detectBrowser = [&]() -> std::optional<Type> {
|
||||||
|
if (device.contains("edg/")
|
||||||
|
|| device.contains("edgios/")
|
||||||
|
|| device.contains("edga/")) {
|
||||||
|
return Type::Edge;
|
||||||
|
} else if (device.contains("chrome")) {
|
||||||
|
return Type::Chrome;
|
||||||
|
} else if (device.contains("safari")) {
|
||||||
|
return Type::Safari;
|
||||||
|
} else if (device.contains("firefox")) {
|
||||||
|
return Type::Firefox;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
const auto detectDesktop = [&]() -> std::optional<Type> {
|
||||||
|
if (platform.contains("windows") || system.contains("windows")) {
|
||||||
|
return Type::Windows;
|
||||||
|
} else if (platform.contains("macos") || system.contains("macos")) {
|
||||||
|
return Type::Mac;
|
||||||
|
} else if (platform.contains("ubuntu")
|
||||||
|
|| system.contains("ubuntu")
|
||||||
|
|| platform.contains("unity")
|
||||||
|
|| system.contains("unity")) {
|
||||||
|
return Type::Ubuntu;
|
||||||
|
} else if (platform.contains("linux") || system.contains("linux")) {
|
||||||
|
return Type::Linux;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ranges::contains(kAndroid, apiId)) {
|
||||||
|
return Type::Android;
|
||||||
|
} else if (ranges::contains(kDesktop, apiId)) {
|
||||||
|
return detectDesktop().value_or(Type::Linux);
|
||||||
|
} else if (ranges::contains(kMac, apiId)) {
|
||||||
|
return Type::Mac;
|
||||||
|
} else if (ranges::contains(kWeb, apiId)) {
|
||||||
|
return detectBrowser().value_or(Type::Web);
|
||||||
|
} else if (device.contains("chromebook")) {
|
||||||
|
return Type::Other;
|
||||||
|
} else if (const auto browser = detectBrowser()) {
|
||||||
|
return *browser;
|
||||||
|
} else if (device.contains("iphone")) {
|
||||||
|
return Type::iPhone;
|
||||||
|
} else if (device.contains("ipad")) {
|
||||||
|
return Type::iPad;
|
||||||
|
} else if (ranges::contains(kiOS, apiId)) {
|
||||||
|
return Type::iPhone;
|
||||||
|
} else if (const auto desktop = detectDesktop()) {
|
||||||
|
return *desktop;
|
||||||
|
} else if (platform.contains("android") || system.contains("android")) {
|
||||||
|
return Type::Android;
|
||||||
|
} else if (platform.contains("ios") || system.contains("ios")) {
|
||||||
|
return Type::iPhone;
|
||||||
|
}
|
||||||
|
return Type::Other;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] style::color ColorForType(Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case Type::Windows:
|
||||||
|
case Type::Mac:
|
||||||
|
case Type::Other:
|
||||||
|
return st::historyPeer4UserpicBg; // blue
|
||||||
|
case Type::Ubuntu:
|
||||||
|
return st::historyPeer8UserpicBg; // orange
|
||||||
|
case Type::Linux:
|
||||||
|
return st::historyPeer5UserpicBg; // purple
|
||||||
|
case Type::iPhone:
|
||||||
|
case Type::iPad:
|
||||||
|
return st::historyPeer7UserpicBg; // sea
|
||||||
|
case Type::Android:
|
||||||
|
return st::historyPeer2UserpicBg; // green
|
||||||
|
case Type::Web:
|
||||||
|
case Type::Chrome:
|
||||||
|
case Type::Edge:
|
||||||
|
case Type::Firefox:
|
||||||
|
case Type::Safari:
|
||||||
|
return st::historyPeer6UserpicBg; // pink
|
||||||
|
}
|
||||||
|
Unexpected("Type in ColorForType.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const style::icon &IconForType(Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case Type::Windows: return st::sessionIconWindows;
|
||||||
|
case Type::Mac: return st::sessionIconMac;
|
||||||
|
case Type::Ubuntu: return st::sessionIconUbuntu;
|
||||||
|
case Type::Linux: return st::sessionIconLinux;
|
||||||
|
case Type::iPhone: return st::sessionIconiPhone;
|
||||||
|
case Type::iPad: return st::sessionIconiPad;
|
||||||
|
case Type::Android: return st::sessionIconAndroid;
|
||||||
|
case Type::Web: return st::sessionIconWeb;
|
||||||
|
case Type::Chrome: return st::sessionIconChrome;
|
||||||
|
case Type::Edge: return st::sessionIconEdge;
|
||||||
|
case Type::Firefox: return st::sessionIconFirefox;
|
||||||
|
case Type::Safari: return st::sessionIconSafari;
|
||||||
|
case Type::Other: return st::sessionIconOther;
|
||||||
|
}
|
||||||
|
Unexpected("Type in IconForType.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] QImage GenerateUserpic(Type type) {
|
||||||
|
const auto size = st::sessionUserpicSize;
|
||||||
|
const auto full = size * style::DevicePixelRatio();
|
||||||
|
const auto rect = QRect(0, 0, size, size);
|
||||||
|
|
||||||
|
auto result = QImage(full, full, QImage::Format_ARGB32_Premultiplied);
|
||||||
|
result.fill(Qt::transparent);
|
||||||
|
result.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
|
|
||||||
|
auto p = QPainter(&result);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
p.setBrush(ColorForType(type));
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.drawEllipse(rect);
|
||||||
|
IconForType(type).paintInCenter(p, rect);
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class SessionsContent : public Ui::RpWidget {
|
class SessionsContent : public Ui::RpWidget {
|
||||||
|
@ -150,20 +302,15 @@ protected:
|
||||||
private:
|
private:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
Entry() = default;
|
Entry() = default;
|
||||||
Entry(const EntryData &entry)
|
explicit Entry(const EntryData &entry);
|
||||||
: data(entry)
|
|
||||||
, incomplete(entry.incomplete)
|
|
||||||
, activeTime(entry.activeTime)
|
|
||||||
, name(st::sessionNameStyle, entry.name)
|
|
||||||
, info(st::sessionInfoStyle, entry.info)
|
|
||||||
, location(st::sessionInfoStyle, LocationAndDate(entry)) {
|
|
||||||
};
|
|
||||||
|
|
||||||
EntryData data;
|
EntryData data;
|
||||||
|
|
||||||
bool incomplete = false;
|
bool incomplete = false;
|
||||||
|
Type type = Type::Other;
|
||||||
TimeId activeTime = 0;
|
TimeId activeTime = 0;
|
||||||
Ui::Text::String name, info, location;
|
Ui::Text::String name, info, location;
|
||||||
|
QImage userpic;
|
||||||
};
|
};
|
||||||
struct Full {
|
struct Full {
|
||||||
Entry current;
|
Entry current;
|
||||||
|
@ -260,6 +407,17 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SessionsContent::Entry::Entry(const EntryData &entry)
|
||||||
|
: data(entry)
|
||||||
|
, incomplete(entry.incomplete)
|
||||||
|
, type(TypeFromEntry(entry))
|
||||||
|
, activeTime(entry.activeTime)
|
||||||
|
, name(st::sessionNameStyle, entry.name)
|
||||||
|
, info(st::sessionInfoStyle, entry.info)
|
||||||
|
, location(st::sessionInfoStyle, LocationAndDate(entry))
|
||||||
|
, userpic(GenerateUserpic(type)) {
|
||||||
|
};
|
||||||
|
|
||||||
SessionsContent::SessionsContent(
|
SessionsContent::SessionsContent(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
|
@ -475,17 +633,22 @@ void SessionsContent::Inner::setupContent() {
|
||||||
Ui::show(Box(RenameBox), Ui::LayerOption::KeepOther);
|
Ui::show(Box(RenameBox), Ui::LayerOption::KeepOther);
|
||||||
});
|
});
|
||||||
|
|
||||||
_current = content->add(object_ptr<List>(content));
|
_current = content->add(
|
||||||
|
object_ptr<List>(content),
|
||||||
|
style::margins{ 0, 0, 0, st::sessionCurrentSkip });
|
||||||
const auto terminateWrap = content->add(
|
const auto terminateWrap = content->add(
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
content,
|
content,
|
||||||
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
||||||
const auto terminateInner = terminateWrap->entity();
|
const auto terminateInner = terminateWrap->entity();
|
||||||
_terminateAll = terminateInner->add(
|
_terminateAll = terminateInner->add(
|
||||||
object_ptr<Ui::SettingsButton>(
|
CreateButton(
|
||||||
terminateInner,
|
terminateInner,
|
||||||
tr::lng_sessions_terminate_all(),
|
tr::lng_sessions_terminate_all(),
|
||||||
st::terminateSessionsButton));
|
st::sessionsTerminateAll,
|
||||||
|
&st::sessionsTerminateAllIcon,
|
||||||
|
st::sessionsTerminateAllIconLeft,
|
||||||
|
&st::attentionButtonFg));
|
||||||
AddSkip(terminateInner);
|
AddSkip(terminateInner);
|
||||||
AddDividerText(terminateInner, tr::lng_sessions_terminate_all_about());
|
AddDividerText(terminateInner, tr::lng_sessions_terminate_all_about());
|
||||||
|
|
||||||
|
@ -494,7 +657,7 @@ void SessionsContent::Inner::setupContent() {
|
||||||
content,
|
content,
|
||||||
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
||||||
const auto incompleteInner = incompleteWrap->entity();
|
const auto incompleteInner = incompleteWrap->entity();
|
||||||
AddSkip(incompleteInner);
|
AddSkip(incompleteInner, st::sessionSubtitleSkip);
|
||||||
AddSubsectionTitle(incompleteInner, tr::lng_sessions_incomplete());
|
AddSubsectionTitle(incompleteInner, tr::lng_sessions_incomplete());
|
||||||
_incomplete = incompleteInner->add(object_ptr<List>(incompleteInner));
|
_incomplete = incompleteInner->add(object_ptr<List>(incompleteInner));
|
||||||
AddSkip(incompleteInner);
|
AddSkip(incompleteInner);
|
||||||
|
@ -505,19 +668,18 @@ void SessionsContent::Inner::setupContent() {
|
||||||
content,
|
content,
|
||||||
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
||||||
const auto listInner = listWrap->entity();
|
const auto listInner = listWrap->entity();
|
||||||
AddSkip(listInner);
|
AddSkip(listInner, st::sessionSubtitleSkip);
|
||||||
AddSubsectionTitle(listInner, tr::lng_sessions_other_header());
|
AddSubsectionTitle(listInner, tr::lng_sessions_other_header());
|
||||||
_list = listInner->add(object_ptr<List>(listInner));
|
_list = listInner->add(object_ptr<List>(listInner));
|
||||||
AddSkip(listInner);
|
AddSkip(listInner);
|
||||||
|
AddDividerText(listInner, tr::lng_sessions_about_apps());
|
||||||
|
|
||||||
const auto ttlWrap = content->add(
|
const auto ttlWrap = content->add(
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
content,
|
content,
|
||||||
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
object_ptr<Ui::VerticalLayout>(content)))->setDuration(0);
|
||||||
const auto ttlInner = ttlWrap->entity();
|
const auto ttlInner = ttlWrap->entity();
|
||||||
AddDivider(ttlInner);
|
AddSkip(ttlInner, st::sessionSubtitleSkip);
|
||||||
AddSkip(ttlInner);
|
|
||||||
|
|
||||||
AddSubsectionTitle(ttlInner, tr::lng_settings_terminate_title());
|
AddSubsectionTitle(ttlInner, tr::lng_settings_terminate_title());
|
||||||
|
|
||||||
AddButtonWithLabel(
|
AddButtonWithLabel(
|
||||||
|
@ -703,19 +865,24 @@ void SessionsContent::List::paintEvent(QPaintEvent *e) {
|
||||||
for (auto i = from; i != till; ++i) {
|
for (auto i = from; i != till; ++i) {
|
||||||
const auto &entry = _items[i];
|
const auto &entry = _items[i];
|
||||||
|
|
||||||
|
p.drawImage(st::sessionUserpicPosition, entry.userpic);
|
||||||
|
|
||||||
const auto nameW = _rowWidth.info;
|
const auto nameW = _rowWidth.info;
|
||||||
const auto nameH = entry.name.style()->font->height;
|
|
||||||
const auto infoW = entry.data.hash ? _rowWidth.info : available;
|
const auto infoW = entry.data.hash ? _rowWidth.info : available;
|
||||||
const auto infoH = entry.info.style()->font->height;
|
|
||||||
|
|
||||||
p.setPen(st::sessionNameFg);
|
p.setPen(st::sessionNameFg);
|
||||||
entry.name.drawLeftElided(p, x, y, nameW, w);
|
entry.name.drawLeftElided(p, x, y, nameW, w);
|
||||||
|
|
||||||
p.setPen(st::boxTextFg);
|
p.setPen(st::boxTextFg);
|
||||||
entry.info.drawLeftElided(p, x, y + nameH, infoW, w);
|
entry.info.drawLeftElided(p, x, y + st::sessionInfoTop, infoW, w);
|
||||||
|
|
||||||
p.setPen(st::sessionInfoFg);
|
p.setPen(st::sessionInfoFg);
|
||||||
entry.location.drawLeftElided(p, x, y + nameH + infoH, available, w);
|
entry.location.drawLeftElided(
|
||||||
|
p,
|
||||||
|
x,
|
||||||
|
y + st::sessionLocationTop,
|
||||||
|
available,
|
||||||
|
w);
|
||||||
|
|
||||||
p.translate(0, st::sessionHeight);
|
p.translate(0, st::sessionHeight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -632,10 +632,6 @@ manageDeleteGroupButton: SettingsCountButton(manageGroupTopButtonWithText) {
|
||||||
editPeerSkip: 7px;
|
editPeerSkip: 7px;
|
||||||
editPeerHistoryVisibilityMargins: margins(15px, 0px, 20px, 16px);
|
editPeerHistoryVisibilityMargins: margins(15px, 0px, 20px, 16px);
|
||||||
|
|
||||||
terminateSessionsButton: SettingsButton(infoBlockButton) {
|
|
||||||
padding: margins(22px, 12px, 22px, 10px);
|
|
||||||
}
|
|
||||||
|
|
||||||
infoEmptyFg: windowSubTextFg;
|
infoEmptyFg: windowSubTextFg;
|
||||||
infoEmptyPhoto: icon {{ "info_media_photo_empty", infoEmptyFg }};
|
infoEmptyPhoto: icon {{ "info_media_photo_empty", infoEmptyFg }};
|
||||||
infoEmptyVideo: icon {{ "info_media_video_empty", infoEmptyFg }};
|
infoEmptyVideo: icon {{ "info_media_video_empty", infoEmptyFg }};
|
||||||
|
@ -662,8 +658,6 @@ editPeerTopButtonsLayoutSkipCustomBottom: 11px;
|
||||||
|
|
||||||
editPeerHistoryVisibilityTopSkip: 8px;
|
editPeerHistoryVisibilityTopSkip: 8px;
|
||||||
|
|
||||||
editPeerDeleteButtonMargins: margins(25px, 11px, 22px, 16px);
|
|
||||||
editPeerDeleteButton: sessionTerminateAllButton;
|
|
||||||
editPeerPhotoMargins: margins(22px, 16px, 22px, 8px);
|
editPeerPhotoMargins: margins(22px, 16px, 22px, 8px);
|
||||||
editPeerTitle: defaultInputField;
|
editPeerTitle: defaultInputField;
|
||||||
editPeerTitleMargins: margins(27px, 21px, 22px, 8px);
|
editPeerTitleMargins: margins(27px, 21px, 22px, 8px);
|
||||||
|
|