Add some HTML design to export, except messages.
NB Testing the layout, the app is not in a working condition.
@ -1,3 +0,0 @@
|
||||
.page_wrap {
|
||||
background-color: #fff;
|
||||
}
|
247
Telegram/Resources/export_html/css/style.css
Normal file
@ -0,0 +1,247 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font: 12px/18px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
|
||||
}
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
}
|
||||
.pull_left {
|
||||
float: left;
|
||||
}
|
||||
.pull_right {
|
||||
float: right;
|
||||
}
|
||||
.page_wrap {
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
}
|
||||
.page_wrap a {
|
||||
color: #168acd;
|
||||
text-decoration: none;
|
||||
}
|
||||
.page_wrap a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.page_header {
|
||||
position: fixed;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #e3e6e8;
|
||||
}
|
||||
.page_header .content {
|
||||
width: 480px;
|
||||
margin: 0 auto;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.page_header a.content {
|
||||
background-image: url(../images/back.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 24px 21px;
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
.bold {
|
||||
color: #212121;
|
||||
}
|
||||
.details {
|
||||
color: #70777b;
|
||||
}
|
||||
.page_header .content .text {
|
||||
padding: 24px 24px 22px 24px;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.page_header a.content .text {
|
||||
padding: 24px 24px 22px 82px;
|
||||
}
|
||||
.page_body {
|
||||
padding-top: 64px;
|
||||
width: 480px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.page_about {
|
||||
padding: 24px 24px;
|
||||
}
|
||||
.with_divider {
|
||||
border-top: 1px solid #e3e6e8;
|
||||
}
|
||||
.userpic_link {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
.userpic_link:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.userpic {
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.userpic .initials {
|
||||
display: block;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
user-select: none;
|
||||
}
|
||||
.userpic1 {
|
||||
background-color: #ff5555;
|
||||
}
|
||||
.userpic2 {
|
||||
background-color: #64bf47;
|
||||
}
|
||||
.userpic3 {
|
||||
background-color: #ffab00;
|
||||
}
|
||||
.userpic4 {
|
||||
background-color: #4f9cd9;
|
||||
}
|
||||
.userpic5 {
|
||||
background-color: #9884e8;
|
||||
}
|
||||
.userpic6 {
|
||||
background-color: #e671a5;
|
||||
}
|
||||
.userpic7 {
|
||||
background-color: #47bcd1;
|
||||
}
|
||||
.userpic8 {
|
||||
background-color: #ff8c44;
|
||||
}
|
||||
.personal_info {
|
||||
padding: 24px;
|
||||
}
|
||||
.personal_info .userpic .initials {
|
||||
font-size: 30px;
|
||||
}
|
||||
.personal_info .rows {
|
||||
float: left;
|
||||
padding-right: 24px;
|
||||
}
|
||||
.personal_info .names {
|
||||
width: 164px;
|
||||
}
|
||||
.personal_info .info {
|
||||
width: 124px;
|
||||
}
|
||||
.personal_info .bio {
|
||||
width: 400px;
|
||||
}
|
||||
.personal_info .row {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
a.block_link {
|
||||
display: block;
|
||||
text-decoration: none !important;
|
||||
border-radius: 4px;
|
||||
}
|
||||
a.block_link:hover {
|
||||
text-decoration: none !important;
|
||||
background-color: #f5f7f8;
|
||||
}
|
||||
.sections {
|
||||
padding: 11px 0;
|
||||
}
|
||||
.section {
|
||||
height: 48px;
|
||||
background-position: 24px 12px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
.section .counter {
|
||||
float: right;
|
||||
padding: 14px 24px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
.section .label {
|
||||
padding: 15px 0 0 82px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.section.calls {
|
||||
background-image: url(../images/calls.png);
|
||||
}
|
||||
.section.chats {
|
||||
background-image: url(../images/chats.png);
|
||||
}
|
||||
.section.contacts {
|
||||
background-image: url(../images/contacts.png);
|
||||
}
|
||||
.section.frequent {
|
||||
background-image: url(../images/frequent.png);
|
||||
}
|
||||
.section.photos {
|
||||
background-image: url(../images/photos.png);
|
||||
}
|
||||
.section.sessions {
|
||||
background-image: url(../images/sessions.png);
|
||||
}
|
||||
.section.web {
|
||||
background-image: url(../images/web.png);
|
||||
}
|
||||
@media only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
|
||||
.section.calls {
|
||||
background-image: url(../images/calls@2x.png);
|
||||
}
|
||||
.section.chats {
|
||||
background-image: url(../images/chats@2x.png);
|
||||
}
|
||||
.section.contacts {
|
||||
background-image: url(../images/contacts@2x.png);
|
||||
}
|
||||
.section.frequent {
|
||||
background-image: url(../images/frequent@2x.png);
|
||||
}
|
||||
.section.photos {
|
||||
background-image: url(../images/photos@2x.png);
|
||||
}
|
||||
.section.sessions {
|
||||
background-image: url(../images/sessions@2x.png);
|
||||
}
|
||||
.section.web {
|
||||
background-image: url(../images/web@2x.png);
|
||||
}
|
||||
.page_header a.content {
|
||||
background-image: url(../images/back@2x.png);
|
||||
}
|
||||
}
|
||||
.list_page .page_about {
|
||||
padding: 16px 24px 0;
|
||||
font-size: 11px;
|
||||
}
|
||||
.list_page .entry_list {
|
||||
padding: 16px 0;
|
||||
}
|
||||
.list_page .entry {
|
||||
padding: 10px 16px;
|
||||
}
|
||||
.list_page .entry .userpic .initials {
|
||||
font-size: 18px;
|
||||
}
|
||||
.list_page .entry .body {
|
||||
margin-left: 66px;
|
||||
}
|
||||
.list_page .entry .name {
|
||||
padding: 4px 0 2px;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
.list_page .entry .subname {
|
||||
padding-top: 4px;
|
||||
}
|
||||
.list_page .entry .details_entry {
|
||||
padding-top: 4px;
|
||||
}
|
||||
.list_page .entry .info {
|
||||
font-size: 11px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.history {
|
||||
padding: 16px 0;
|
||||
}
|
BIN
Telegram/Resources/export_html/images/back.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
Telegram/Resources/export_html/images/back@2x.png
Normal file
After Width: | Height: | Size: 518 B |
BIN
Telegram/Resources/export_html/images/calls.png
Normal file
After Width: | Height: | Size: 656 B |
BIN
Telegram/Resources/export_html/images/calls@2x.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/Resources/export_html/images/chats.png
Normal file
After Width: | Height: | Size: 283 B |
BIN
Telegram/Resources/export_html/images/chats@2x.png
Normal file
After Width: | Height: | Size: 454 B |
BIN
Telegram/Resources/export_html/images/contacts.png
Normal file
After Width: | Height: | Size: 508 B |
BIN
Telegram/Resources/export_html/images/contacts@2x.png
Normal file
After Width: | Height: | Size: 1023 B |
BIN
Telegram/Resources/export_html/images/frequent.png
Normal file
After Width: | Height: | Size: 771 B |
BIN
Telegram/Resources/export_html/images/frequent@2x.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Telegram/Resources/export_html/images/photos.png
Normal file
After Width: | Height: | Size: 415 B |
BIN
Telegram/Resources/export_html/images/photos@2x.png
Normal file
After Width: | Height: | Size: 750 B |
BIN
Telegram/Resources/export_html/images/sessions.png
Normal file
After Width: | Height: | Size: 134 B |
BIN
Telegram/Resources/export_html/images/sessions@2x.png
Normal file
After Width: | Height: | Size: 216 B |
BIN
Telegram/Resources/export_html/images/web.png
Normal file
After Width: | Height: | Size: 266 B |
BIN
Telegram/Resources/export_html/images/web@2x.png
Normal file
After Width: | Height: | Size: 447 B |
@ -1,6 +1,22 @@
|
||||
<RCC>
|
||||
<qresource prefix="/export">
|
||||
<file alias="css/style.css">../css/export_style.css</file>
|
||||
<file alias="css/style.css">../export_html/css/style.css</file>
|
||||
<file alias="images/back.png">../export_html/images/back.png</file>
|
||||
<file alias="images/back@2x.png">../export_html/images/back@2x.png</file>
|
||||
<file alias="images/calls.png">../export_html/images/calls.png</file>
|
||||
<file alias="images/calls@2x.png">../export_html/images/calls@2x.png</file>
|
||||
<file alias="images/chats.png">../export_html/images/chats.png</file>
|
||||
<file alias="images/chats@2x.png">../export_html/images/chats@2x.png</file>
|
||||
<file alias="images/contacts.png">../export_html/images/contacts.png</file>
|
||||
<file alias="images/contacts@2x.png">../export_html/images/contacts@2x.png</file>
|
||||
<file alias="images/frequent.png">../export_html/images/frequent.png</file>
|
||||
<file alias="images/frequent@2x.png">../export_html/images/frequent@2x.png</file>
|
||||
<file alias="images/photos.png">../export_html/images/photos.png</file>
|
||||
<file alias="images/photos@2x.png">../export_html/images/photos@2x.png</file>
|
||||
<file alias="images/sessions.png">../export_html/images/sessions.png</file>
|
||||
<file alias="images/sessions@2x.png">../export_html/images/sessions@2x.png</file>
|
||||
<file alias="images/web.png">../export_html/images/web.png</file>
|
||||
<file alias="images/web@2x.png">../export_html/images/web@2x.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/gui">
|
||||
<file alias="fonts/OpenSans-Regular.ttf">../fonts/OpenSans-Regular.ttf</file>
|
||||
|
@ -8,15 +8,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "export/data/export_data_types.h"
|
||||
|
||||
#include "export/export_settings.h"
|
||||
#include "export/output/export_output_file.h"
|
||||
#include "core/mime_type.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtGui/QImageReader>
|
||||
|
||||
namespace App { // Hackish..
|
||||
QString formatPhone(QString phone);
|
||||
} // namespace App
|
||||
QString FillAmountAndCurrency(uint64 amount, const QString ¤cy);
|
||||
QString formatSizeText(qint64 size);
|
||||
|
||||
namespace Export {
|
||||
namespace Data {
|
||||
@ -24,6 +27,7 @@ namespace {
|
||||
|
||||
constexpr auto kUserPeerIdShift = (1ULL << 32);
|
||||
constexpr auto kChatPeerIdShift = (2ULL << 32);
|
||||
constexpr auto kMaxImageSize = 10000;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -39,6 +43,43 @@ int32 BarePeerId(PeerId peerId) {
|
||||
return int32(peerId & 0xFFFFFFFFULL);
|
||||
}
|
||||
|
||||
int PeerColorIndex(int32 bareId) {
|
||||
const auto index = std::abs(bareId) % 7;
|
||||
const int map[] = { 0, 7, 4, 1, 6, 3, 5 };
|
||||
return map[index];
|
||||
}
|
||||
|
||||
int StringBarePeerId(const Utf8String &data) {
|
||||
auto result = 0xFF;
|
||||
for (const auto ch : data) {
|
||||
result *= 239;
|
||||
result += ch;
|
||||
result &= 0xFF;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int ApplicationColorIndex(int applicationId) {
|
||||
static const auto official = std::map<int, int> {
|
||||
{ 1, 0 }, // iOS
|
||||
{ 7, 0 }, // iOS X
|
||||
{ 6, 1 }, // Android
|
||||
{ 21724, 1 }, // Android X
|
||||
{ 2834, 2 }, // macOS
|
||||
{ 2496, 3 }, // Webogram
|
||||
{ 2040, 4 }, // Desktop
|
||||
{ 1429, 5 }, // Windows Phone
|
||||
};
|
||||
if (const auto i = official.find(applicationId); i != end(official)) {
|
||||
return i->second;
|
||||
}
|
||||
return PeerColorIndex(applicationId);
|
||||
}
|
||||
|
||||
int DomainApplicationId(const Utf8String &data) {
|
||||
return 0x1000 + StringBarePeerId(data);
|
||||
}
|
||||
|
||||
bool IsChatPeerId(PeerId peerId) {
|
||||
return (peerId & kChatPeerIdShift) == kChatPeerIdShift;
|
||||
}
|
||||
@ -440,6 +481,43 @@ UserpicsSlice ParseUserpicsSlice(
|
||||
return result;
|
||||
}
|
||||
|
||||
QString WriteImageThumb(
|
||||
const QString &basePath,
|
||||
const QString &largePath,
|
||||
int width,
|
||||
int height,
|
||||
const QString &postfix) {
|
||||
if (largePath.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
const auto path = basePath + largePath;
|
||||
QImageReader reader(path);
|
||||
if (!reader.canRead()) {
|
||||
return QString();
|
||||
}
|
||||
const auto size = reader.size();
|
||||
if (size.isEmpty()
|
||||
|| size.width() >= kMaxImageSize
|
||||
|| size.height() >= kMaxImageSize) {
|
||||
return QString();
|
||||
}
|
||||
auto image = reader.read();
|
||||
if (image.isNull()) {
|
||||
return QString();
|
||||
}
|
||||
const auto format = reader.format();
|
||||
const auto lastSlash = largePath.lastIndexOf('/');
|
||||
const auto firstDot = largePath.indexOf('.', lastSlash + 1);
|
||||
const auto thumb = (firstDot >= 0)
|
||||
? largePath.mid(0, firstDot) + postfix + largePath.mid(firstDot)
|
||||
: largePath + postfix;
|
||||
const auto result = Output::File::PrepareRelativePath(basePath, thumb);
|
||||
if (!image.save(basePath + result, reader.format(), reader.quality())) {
|
||||
return QString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ContactInfo ParseContactInfo(const MTPUser &data) {
|
||||
auto result = ContactInfo();
|
||||
data.match([&](const MTPDuser &data) {
|
||||
@ -459,6 +537,13 @@ ContactInfo ParseContactInfo(const MTPUser &data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int ContactColorIndex(const ContactInfo &data) {
|
||||
if (data.userId != 0) {
|
||||
return PeerColorIndex(data.userId);
|
||||
}
|
||||
return PeerColorIndex(StringBarePeerId(data.phoneNumber));
|
||||
}
|
||||
|
||||
User ParseUser(const MTPUser &data) {
|
||||
auto result = User();
|
||||
result.info = ParseContactInfo(data);
|
||||
@ -1066,6 +1151,7 @@ bool AppendTopPeers(ContactsList &to, const MTPcontacts_TopPeers &data) {
|
||||
Session ParseSession(const MTPAuthorization &data) {
|
||||
return data.match([&](const MTPDauthorization &data) {
|
||||
auto result = Session();
|
||||
result.applicationId = data.vapi_id.v;
|
||||
result.platform = ParseString(data.vplatform);
|
||||
result.deviceModel = ParseString(data.vdevice_model);
|
||||
result.systemVersion = ParseString(data.vsystem_version);
|
||||
@ -1170,7 +1256,12 @@ DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data) {
|
||||
info.type = peer.user()
|
||||
? DialogTypeFromUser(*peer.user())
|
||||
: DialogTypeFromChat(*peer.chat());
|
||||
info.name = peer.name();
|
||||
info.name = peer.user()
|
||||
? peer.user()->info.firstName
|
||||
: peer.name();
|
||||
info.lastName = peer.user()
|
||||
? peer.user()->info.lastName
|
||||
: Utf8String();
|
||||
info.input = peer.input();
|
||||
}
|
||||
info.topMessageId = fields.vtop_message.v;
|
||||
@ -1297,5 +1388,9 @@ Utf8String FormatMoneyAmount(uint64 amount, const Utf8String ¤cy) {
|
||||
QString::fromUtf8(currency)).toUtf8();
|
||||
}
|
||||
|
||||
Utf8String FormatFileSize(int64 size) {
|
||||
return formatSizeText(size).toUtf8();
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
} // namespace Export
|
||||
|
@ -26,6 +26,9 @@ using PeerId = uint64;
|
||||
PeerId UserPeerId(int32 userId);
|
||||
PeerId ChatPeerId(int32 chatId);
|
||||
int32 BarePeerId(PeerId peerId);
|
||||
int PeerColorIndex(int32 bareId);
|
||||
int ApplicationColorIndex(int applicationId);
|
||||
int DomainApplicationId(const Utf8String &data);
|
||||
|
||||
Utf8String ParseString(const MTPstring &data);
|
||||
|
||||
@ -77,6 +80,13 @@ struct Image {
|
||||
File file;
|
||||
};
|
||||
|
||||
QString WriteImageThumb(
|
||||
const QString &basePath,
|
||||
const QString &largePath,
|
||||
int width,
|
||||
int height,
|
||||
const QString &postfix = "_thumb");
|
||||
|
||||
struct ContactInfo {
|
||||
int32 userId = 0;
|
||||
Utf8String firstName;
|
||||
@ -88,6 +98,7 @@ struct ContactInfo {
|
||||
};
|
||||
|
||||
ContactInfo ParseContactInfo(const MTPUser &data);
|
||||
int ContactColorIndex(const ContactInfo &data);
|
||||
|
||||
struct Photo {
|
||||
uint64 id = 0;
|
||||
@ -230,6 +241,7 @@ std::vector<int> SortedContactsIndices(const ContactsList &data);
|
||||
bool AppendTopPeers(ContactsList &to, const MTPcontacts_TopPeers &data);
|
||||
|
||||
struct Session {
|
||||
int applicationId = 0;
|
||||
Utf8String platform;
|
||||
Utf8String deviceModel;
|
||||
Utf8String systemVersion;
|
||||
@ -485,6 +497,7 @@ struct DialogInfo {
|
||||
};
|
||||
Type type = Type::Unknown;
|
||||
Utf8String name;
|
||||
Utf8String lastName;
|
||||
|
||||
MTPInputPeer input = MTP_inputPeerEmpty();
|
||||
int32 topMessageId = 0;
|
||||
@ -526,14 +539,13 @@ MessagesSlice ParseMessagesSlice(
|
||||
const QString &mediaFolder);
|
||||
|
||||
Utf8String FormatPhoneNumber(const Utf8String &phoneNumber);
|
||||
|
||||
Utf8String FormatDateTime(
|
||||
TimeId date,
|
||||
QChar dateSeparator = QChar('.'),
|
||||
QChar timeSeparator = QChar(':'),
|
||||
QChar separator = QChar(' '));
|
||||
|
||||
Utf8String FormatMoneyAmount(uint64 amount, const Utf8String ¤cy);
|
||||
Utf8String FormatFileSize(int64 size);
|
||||
|
||||
} // namespace Data
|
||||
} // namespace Export
|
||||
|
@ -56,19 +56,11 @@ std::unique_ptr<AbstractWriter> CreateWriter(Format format) {
|
||||
Unexpected("Format in Export::Output::CreateWriter.");
|
||||
}
|
||||
|
||||
Stats AbstractWriter::produceTestExample(const QString &path) {
|
||||
Stats AbstractWriter::produceTestExample(
|
||||
const QString &path,
|
||||
const Environment &environment) {
|
||||
auto result = Stats();
|
||||
const auto folder = QDir(path).absolutePath();
|
||||
auto environment = Environment();
|
||||
environment.internalLinksDomain = "https://t.me/";
|
||||
environment.aboutTelegram = "About Telegram";
|
||||
environment.aboutContacts = "About contacts";
|
||||
environment.aboutFrequent = "About frequent";
|
||||
environment.aboutSessions = "About sessions";
|
||||
environment.aboutWebSessions = "About web sessions";
|
||||
environment.aboutChats = "About chats";
|
||||
environment.aboutLeftChats = "About left chats";
|
||||
|
||||
auto settings = Settings();
|
||||
settings.format = format();
|
||||
settings.path = (folder.endsWith('/') ? folder : (folder + '/'))
|
||||
|
@ -90,7 +90,9 @@ public:
|
||||
|
||||
virtual ~AbstractWriter() = default;
|
||||
|
||||
Stats produceTestExample(const QString &path);
|
||||
Stats produceTestExample(
|
||||
const QString &path,
|
||||
const Environment &environment);
|
||||
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace Export {
|
||||
namespace Output {
|
||||
namespace details {
|
||||
|
||||
class HtmlContext {
|
||||
public:
|
||||
[[nodiscard]] QByteArray pushTag(
|
||||
const QByteArray &tag,
|
||||
std::map<QByteArray, QByteArray> &&attributes = {});
|
||||
[[nodiscard]] QByteArray popTag();
|
||||
[[nodiscard]] QByteArray indent() const;
|
||||
[[nodiscard]] bool empty() const;
|
||||
|
||||
private:
|
||||
struct Tag {
|
||||
QByteArray name;
|
||||
bool block = true;
|
||||
};
|
||||
std::vector<Tag> _tags;
|
||||
|
||||
};
|
||||
|
||||
struct UserpicData;
|
||||
|
||||
} // namespace details
|
||||
|
||||
class HtmlWriter : public AbstractWriter {
|
||||
public:
|
||||
@ -59,9 +82,11 @@ public:
|
||||
~HtmlWriter();
|
||||
|
||||
private:
|
||||
using Context = details::HtmlContext;
|
||||
using UserpicData = details::UserpicData;
|
||||
class Wrap;
|
||||
|
||||
Result copyFile(
|
||||
[[nodiscard]] Result copyFile(
|
||||
const QString &source,
|
||||
const QString &relativePath) const;
|
||||
|
||||
@ -70,34 +95,66 @@ private:
|
||||
std::unique_ptr<Wrap> fileWithRelativePath(const QString &path) const;
|
||||
QString messagesFile(int index) const;
|
||||
|
||||
Result writeSavedContacts(const Data::ContactsList &data);
|
||||
Result writeFrequentContacts(const Data::ContactsList &data);
|
||||
[[nodiscard]] Result writeSavedContacts(const Data::ContactsList &data);
|
||||
[[nodiscard]] Result writeFrequentContacts(const Data::ContactsList &data);
|
||||
|
||||
Result writeSessions(const Data::SessionsList &data);
|
||||
Result writeWebSessions(const Data::SessionsList &data);
|
||||
[[nodiscard]] Result writeSessions(const Data::SessionsList &data);
|
||||
[[nodiscard]] Result writeWebSessions(const Data::SessionsList &data);
|
||||
|
||||
Result writeChatsStart(
|
||||
[[nodiscard]] Result writeChatsStart(
|
||||
const Data::DialogsInfo &data,
|
||||
const QByteArray &listName,
|
||||
const QByteArray &about,
|
||||
const QString &fileName);
|
||||
Result writeChatStart(const Data::DialogInfo &data);
|
||||
Result writeChatSlice(const Data::MessagesSlice &data);
|
||||
Result writeChatEnd();
|
||||
Result writeChatsEnd();
|
||||
Result switchToNextChatFile(int index);
|
||||
[[nodiscard]] Result writeChatStart(const Data::DialogInfo &data);
|
||||
[[nodiscard]] Result writeChatSlice(const Data::MessagesSlice &data);
|
||||
[[nodiscard]] Result writeChatEnd();
|
||||
[[nodiscard]] Result writeChatsEnd();
|
||||
[[nodiscard]] Result switchToNextChatFile(int index);
|
||||
|
||||
void pushSection(
|
||||
int priority,
|
||||
const QByteArray &label,
|
||||
const QByteArray &type,
|
||||
int count,
|
||||
const QString &path);
|
||||
[[nodiscard]] Result writeSections();
|
||||
|
||||
[[nodiscard]] Result writeDefaultPersonal(
|
||||
const Data::PersonalInfo &data);
|
||||
[[nodiscard]] Result writeDelayedPersonal(const QString &userpicPath);
|
||||
[[nodiscard]] Result writePreparedPersonal(
|
||||
const Data::PersonalInfo &data,
|
||||
const QString &userpicPath);
|
||||
void pushUserpicsSection();
|
||||
|
||||
[[nodiscard]] QString writeUserpicThumb(
|
||||
const QString &largePath,
|
||||
const UserpicData &userpic,
|
||||
const QString &postfix = "_thumb");
|
||||
|
||||
[[nodiscard]] QString userpicsFilePath() const;
|
||||
|
||||
Settings _settings;
|
||||
Environment _environment;
|
||||
Stats *_stats = nullptr;
|
||||
|
||||
struct SavedSection;
|
||||
std::vector<SavedSection> _savedSections;
|
||||
|
||||
std::unique_ptr<Wrap> _summary;
|
||||
bool _summaryNeedDivider = false;
|
||||
bool _haveSections = false;
|
||||
|
||||
int _selfColorIndex = 0;
|
||||
std::unique_ptr<Data::PersonalInfo> _delayedPersonalInfo;
|
||||
|
||||
int _userpicsCount = 0;
|
||||
std::unique_ptr<Wrap> _userpics;
|
||||
|
||||
int _dialogsCount = 0;
|
||||
int _dialogIndex = 0;
|
||||
QString _dialogsRelativePath;
|
||||
Data::DialogInfo _dialog;
|
||||
|
||||
int _messagesCount = 0;
|
||||
|
@ -69,6 +69,8 @@ void SuggestBox::prepare() {
|
||||
}, content->lifetime());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Environment PrepareEnvironment() {
|
||||
auto result = Environment();
|
||||
const auto utfLang = [](LangKey key) {
|
||||
@ -85,8 +87,6 @@ Environment PrepareEnvironment() {
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QPointer<BoxContent> SuggestStart() {
|
||||
ClearSuggestStart();
|
||||
return Ui::show(Box<SuggestBox>(), LayerOption::KeepOther).data();
|
||||
|
@ -19,8 +19,12 @@ class SeparatePanel;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Export {
|
||||
|
||||
struct Environment;
|
||||
|
||||
namespace View {
|
||||
|
||||
Environment PrepareEnvironment();
|
||||
QPointer<BoxContent> SuggestStart();
|
||||
void ClearSuggestStart();
|
||||
|
||||
|
@ -90,6 +90,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "export/output/export_output_html.h"
|
||||
#include "export/output/export_output_stats.h"
|
||||
#include "export/view/export_view_panel_controller.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#else
|
||||
#error "test"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsForceLogoutNotification(const MTPDupdateServiceNotification &data) {
|
||||
@ -252,6 +261,10 @@ MainWidget::MainWidget(
|
||||
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
|
||||
Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
|
||||
|
||||
Export::Output::HtmlWriter writer;
|
||||
writer.produceTestExample(psDownloadPath(), Export::View::PrepareEnvironment());
|
||||
crl::on_main([] { App::quit(); });
|
||||
|
||||
_ptsWaiter.setRequesting(true);
|
||||
updateScrollColors();
|
||||
setupConnectingWidget();
|
||||
|
@ -109,7 +109,9 @@
|
||||
'<@(style_files)',
|
||||
'<!@(<(list_sources_command) <(qt_moc_list_sources_arg))',
|
||||
'telegram_sources.txt',
|
||||
'<(res_loc)/css/export_style.css',
|
||||
'<(res_loc)/export_html/css/style.css',
|
||||
'<(res_loc)/export_html/images/back.png',
|
||||
'<(res_loc)/export_html/images/back@2x.png',
|
||||
],
|
||||
'sources!': [
|
||||
'<!@(<(list_sources_command) <(qt_moc_list_sources_arg) --exclude_for <(build_os))',
|
||||
|