Improved html message layout.

This commit is contained in:
John Preston 2018-07-04 00:09:25 +01:00
parent eeb1a6b769
commit cb8ff398a5
42 changed files with 895 additions and 366 deletions

View File

@ -2,6 +2,34 @@ body {
margin: 0;
font: 12px/18px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
}
strong {
font-weight: 700;
}
code, kbd, pre, samp {
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
}
code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
border-radius: 4px;
}
pre {
display: block;
margin: 0;
line-height: 1.42857143;
word-break: break-all;
word-wrap: break-word;
color: #333;
background-color: #f5f5f5;
border-radius: 4px;
overflow: auto;
padding: 3px;
border: 1px solid #eee;
max-height: none;
font-size: inherit;
}
.clearfix:after {
content: " ";
visibility: hidden;
@ -38,13 +66,13 @@ body {
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;
font-weight: 700;
}
.details {
color: #70777b;
@ -52,7 +80,6 @@ body {
.page_header .content .text {
padding: 24px 24px 22px 24px;
font-size: 22px;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@ -90,28 +117,47 @@ body {
text-transform: uppercase;
user-select: none;
}
.userpic1 {
.color_red,
.userpic1,
.media_call .thumb,
.media_file .thumb,
.media_live_location .thumb {
background-color: #ff5555;
}
.userpic2 {
.color_green,
.userpic2,
.media_call.success .thumb {
background-color: #64bf47;
}
.userpic3 {
.color_yellow,
.userpic3,
.media_venue .thumb {
background-color: #ffab00;
}
.userpic4 {
.color_blue,
.userpic4,
.media_audio_file .thumb,
.media_voice_message .thumb {
background-color: #4f9cd9;
}
.userpic5 {
.color_purple,
.userpic5,
.media_game .thumb {
background-color: #9884e8;
}
.userpic6 {
.color_pink,
.userpic6,
.media_invoice .thumb {
background-color: #e671a5;
}
.userpic7 {
.color_sea,
.userpic7,
.media_location .thumb {
background-color: #47bcd1;
}
.userpic8 {
.color_orange,
.userpic8,
.media_contact .thumb {
background-color: #ff8c44;
}
.personal_info {
@ -162,54 +208,6 @@ a.block_link:hover {
.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;
@ -229,7 +227,6 @@ a.block_link:hover {
}
.list_page .entry .name {
padding: 4px 0 2px;
font-weight: 700;
font-size: 14px;
}
.list_page .entry .subname {
@ -248,7 +245,7 @@ a.block_link:hover {
.service {
padding: 10px 24px;
}
.service .content {
.service .body {
text-align: center;
}
.service .userpic_wrap {
@ -260,3 +257,172 @@ a.block_link:hover {
.service .userpic .initials {
font-size: 24px;
}
.message .userpic .initials {
font-size: 16px;
}
.default {
padding: 10px 0 10px;
}
.default.joined {
padding-top: 0;
}
.default .from_name {
color: #3892db;
font-weight: 700;
padding-bottom: 5px;
}
.default .from_name .details {
font-weight: normal;
}
.default .body {
margin-left: 60px;
}
.default .text {
word-wrap: break-word;
line-height: 150%;
}
.default .reply_to,
.default .media_wrap {
padding-bottom: 5px;
}
.default .media {
margin: 0 -10px;
padding: 5px 10px;
}
.default .media .thumb {
width: 48px;
height: 48px;
border-radius: 50%;
background-repeat: no-repeat;
background-position: 12px 12px;
background-size: 24px 24px;
}
.default .media .title {
padding-top: 4px;
font-size: 14px;
}
.default .media .description {
color: #000000;
padding-top: 4px;
font-size: 13px;
}
.default .media .status {
padding-top: 4px;
font-size: 13px;
}
.section.calls {
background-image: url(../images/section_calls.png);
}
.section.chats {
background-image: url(../images/section_chats.png);
}
.section.contacts {
background-image: url(../images/section_contacts.png);
}
.section.frequent {
background-image: url(../images/section_frequent.png);
}
.section.photos {
background-image: url(../images/section_photos.png);
}
.section.sessions {
background-image: url(../images/section_sessions.png);
}
.section.web {
background-image: url(../images/section_web.png);
}
.section.leftchats {
background-image: url(../images/section_leftchats.png);
}
.section.other {
background-image: url(../images/section_other.png)
}
.page_header a.content {
background-image: url(../images/back.png);
}
.media_call .thumb {
background-image: url(../images/media_call.png)
}
.media_contact .thumb {
background-image: url(../images/media_contact.png)
}
.media_file .thumb {
background-image: url(../images/media_file.png)
}
.media_game .thumb {
background-image: url(../images/media_game.png)
}
.media_live_location .thumb,
.media_location .thumb,
.media_venue .thumb {
background-image: url(../images/media_location.png)
}
.media_audio_file .thumb {
background-image: url(../images/media_music.png)
}
.media_invoice .thumb {
background-image: url(../images/media_shop.png)
}
.media_voice_message .thumb {
background-image: url(../images/media_voice.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/section_calls@2x.png);
}
.section.chats {
background-image: url(../images/section_chats@2x.png);
}
.section.contacts {
background-image: url(../images/section_contacts@2x.png);
}
.section.frequent {
background-image: url(../images/section_frequent@2x.png);
}
.section.photos {
background-image: url(../images/section_photos@2x.png);
}
.section.sessions {
background-image: url(../images/section_sessions@2x.png);
}
.section.web {
background-image: url(../images/section_web@2x.png);
}
.section.leftchats {
background-image: url(../images/section_leftchats@2x.png);
}
.section.other {
background-image: url(../images/section_other@2x.png);
}
.page_header a.content {
background-image: url(../images/back@2x.png);
}
.media_call .thumb {
background-image: url(../images/media_call@2x.png)
}
.media_contact .thumb {
background-image: url(../images/media_contact@2x.png)
}
.media_file .thumb {
background-image: url(../images/media_file@2x.png)
}
.media_game .thumb {
background-image: url(../images/media_game@2x.png)
}
.media_live_location .thumb,
.media_location .thumb,
.media_venue .thumb {
background-image: url(../images/media_location@2x.png)
}
.media_audio_file .thumb {
background-image: url(../images/media_music@2x.png)
}
.media_invoice .thumb {
background-image: url(../images/media_shop@2x.png)
}
.media_voice_message .thumb {
background-image: url(../images/media_voice@2x.png)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

View File

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 656 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 283 B

After

Width:  |  Height:  |  Size: 283 B

View File

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 454 B

View File

Before

Width:  |  Height:  |  Size: 508 B

After

Width:  |  Height:  |  Size: 508 B

View File

Before

Width:  |  Height:  |  Size: 1023 B

After

Width:  |  Height:  |  Size: 1023 B

View File

Before

Width:  |  Height:  |  Size: 771 B

After

Width:  |  Height:  |  Size: 771 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

View File

Before

Width:  |  Height:  |  Size: 415 B

After

Width:  |  Height:  |  Size: 415 B

View File

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 750 B

View File

Before

Width:  |  Height:  |  Size: 134 B

After

Width:  |  Height:  |  Size: 134 B

View File

Before

Width:  |  Height:  |  Size: 216 B

After

Width:  |  Height:  |  Size: 216 B

View File

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 266 B

View File

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 447 B

View File

@ -3,20 +3,40 @@
<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>
<file alias="images/media_call.png">../export_html/images/media_call.png</file>
<file alias="images/media_call@2x.png">../export_html/images/media_call@2x.png</file>
<file alias="images/media_contact.png">../export_html/images/media_contact.png</file>
<file alias="images/media_contact@2x.png">../export_html/images/media_contact@2x.png</file>
<file alias="images/media_file.png">../export_html/images/media_file.png</file>
<file alias="images/media_file@2x.png">../export_html/images/media_file@2x.png</file>
<file alias="images/media_game.png">../export_html/images/media_game.png</file>
<file alias="images/media_game@2x.png">../export_html/images/media_game@2x.png</file>
<file alias="images/media_location.png">../export_html/images/media_location.png</file>
<file alias="images/media_location@2x.png">../export_html/images/media_location@2x.png</file>
<file alias="images/media_music.png">../export_html/images/media_music.png</file>
<file alias="images/media_music@2x.png">../export_html/images/media_music@2x.png</file>
<file alias="images/media_shop.png">../export_html/images/media_shop.png</file>
<file alias="images/media_shop@2x.png">../export_html/images/media_shop@2x.png</file>
<file alias="images/media_voice.png">../export_html/images/media_voice.png</file>
<file alias="images/media_voice@2x.png">../export_html/images/media_voice@2x.png</file>
<file alias="images/section_calls.png">../export_html/images/section_calls.png</file>
<file alias="images/section_calls@2x.png">../export_html/images/section_calls@2x.png</file>
<file alias="images/section_chats.png">../export_html/images/section_chats.png</file>
<file alias="images/section_chats@2x.png">../export_html/images/section_chats@2x.png</file>
<file alias="images/section_contacts.png">../export_html/images/section_contacts.png</file>
<file alias="images/section_contacts@2x.png">../export_html/images/section_contacts@2x.png</file>
<file alias="images/section_frequent.png">../export_html/images/section_frequent.png</file>
<file alias="images/section_frequent@2x.png">../export_html/images/section_frequent@2x.png</file>
<file alias="images/section_leftchats.png">../export_html/images/section_leftchats.png</file>
<file alias="images/section_leftchats@2x.png">../export_html/images/section_leftchats@2x.png</file>
<file alias="images/section_other.png">../export_html/images/section_other.png</file>
<file alias="images/section_other@2x.png">../export_html/images/section_other@2x.png</file>
<file alias="images/section_photos.png">../export_html/images/section_photos.png</file>
<file alias="images/section_photos@2x.png">../export_html/images/section_photos@2x.png</file>
<file alias="images/section_sessions.png">../export_html/images/section_sessions.png</file>
<file alias="images/section_sessions@2x.png">../export_html/images/section_sessions@2x.png</file>
<file alias="images/section_web.png">../export_html/images/section_web.png</file>
<file alias="images/section_web@2x.png">../export_html/images/section_web@2x.png</file>
</qresource>
<qresource prefix="/gui">
<file alias="fonts/OpenSans-Regular.ttf">../fonts/OpenSans-Regular.ttf</file>

View File

@ -20,6 +20,7 @@ QString formatPhone(QString phone);
} // namespace App
QString FillAmountAndCurrency(uint64 amount, const QString &currency);
QString formatSizeText(qint64 size);
QString formatDurationText(qint64 duration);
namespace Export {
namespace Data {
@ -940,19 +941,32 @@ Message ParseMessage(
const MTPMessage &data,
const QString &mediaFolder) {
auto result = Message();
data.match([&](const MTPDmessage &data) {
data.match([&](const auto &data) {
result.id = data.vid.v;
const auto peerId = ParsePeerId(data.vto_id);
if (IsChatPeerId(peerId)) {
result.chatId = BarePeerId(peerId);
if constexpr (!MTPDmessageEmpty::Is<decltype(data)>()) {
result.toId = ParsePeerId(data.vto_id);
const auto peerId = (!data.is_out()
&& data.has_from_id()
&& data.vto_id.type() == mtpc_peerUser)
? UserPeerId(data.vfrom_id.v)
: result.toId;
if (IsChatPeerId(peerId)) {
result.chatId = BarePeerId(peerId);
}
if (data.has_from_id()) {
result.fromId = data.vfrom_id.v;
}
if (data.has_reply_to_msg_id()) {
result.replyToMsgId = data.vreply_to_msg_id.v;
}
result.date = data.vdate.v;
result.out = data.is_out();
}
result.date = data.vdate.v;
});
data.match([&](const MTPDmessage &data) {
if (data.has_edit_date()) {
result.edited = data.vedit_date.v;
}
if (data.has_from_id()) {
result.fromId = data.vfrom_id.v;
}
if (data.has_fwd_from()) {
result.forwardedFromId = data.vfwd_from.match(
[](const MTPDmessageFwdHeader &data) {
@ -963,6 +977,10 @@ Message ParseMessage(
}
return PeerId(0);
});
result.forwardedDate = data.vfwd_from.match(
[](const MTPDmessageFwdHeader &data) {
return data.vdate.v;
});
result.savedFromChatId = data.vfwd_from.match(
[](const MTPDmessageFwdHeader &data) {
if (data.has_saved_from_peer()) {
@ -998,22 +1016,10 @@ Message ParseMessage(
? data.ventities.v
: QVector<MTPMessageEntity>{}));
}, [&](const MTPDmessageService &data) {
result.id = data.vid.v;
const auto peerId = ParsePeerId(data.vto_id);
if (IsChatPeerId(peerId)) {
result.chatId = BarePeerId(peerId);
}
result.date = data.vdate.v;
result.action = ParseServiceAction(
context,
data.vaction,
mediaFolder);
if (data.has_from_id()) {
result.fromId = data.vfrom_id.v;
}
if (data.has_reply_to_msg_id()) {
result.replyToMsgId = data.vreply_to_msg_id.v;
}
}, [&](const MTPDmessageEmpty &data) {
result.id = data.vid.v;
});
@ -1373,9 +1379,9 @@ Utf8String FormatDateTime(
const auto value = QDateTime::fromTime_t(date);
return (QString("%1") + dateSeparator + "%2" + dateSeparator + "%3"
+ separator + "%4" + timeSeparator + "%5" + timeSeparator + "%6"
).arg(value.date().year()
).arg(value.date().month(), 2, 10, QChar('0')
).arg(value.date().day(), 2, 10, QChar('0')
).arg(value.date().month(), 2, 10, QChar('0')
).arg(value.date().year()
).arg(value.time().hour(), 2, 10, QChar('0')
).arg(value.time().minute(), 2, 10, QChar('0')
).arg(value.time().second(), 2, 10, QChar('0')
@ -1392,5 +1398,9 @@ Utf8String FormatFileSize(int64 size) {
return formatSizeText(size).toUtf8();
}
Utf8String FormatDuration(int64 seconds) {
return formatDurationText(seconds).toUtf8();
}
} // namespace Data
} // namespace Export

View File

@ -26,6 +26,8 @@ using PeerId = uint64;
PeerId UserPeerId(int32 userId);
PeerId ChatPeerId(int32 chatId);
int32 BarePeerId(PeerId peerId);
bool IsChatPeerId(PeerId peerId);
bool IsUserPeerId(PeerId peerId);
int PeerColorIndex(int32 bareId);
int ApplicationColorIndex(int applicationId);
int DomainApplicationId(const Utf8String &data);
@ -462,7 +464,9 @@ struct Message {
TimeId date = 0;
TimeId edited = 0;
int32 fromId = 0;
PeerId toId = 0;
PeerId forwardedFromId = 0;
TimeId forwardedDate = 0;
PeerId savedFromChatId = 0;
Utf8String signature;
int32 viaBotId = 0;
@ -470,6 +474,7 @@ struct Message {
std::vector<TextPart> text;
Media media;
ServiceAction action;
bool out = false;
File &file();
const File &file() const;
@ -546,6 +551,7 @@ Utf8String FormatDateTime(
QChar separator = QChar(' '));
Utf8String FormatMoneyAmount(uint64 amount, const Utf8String &currency);
Utf8String FormatFileSize(int64 size);
Utf8String FormatDuration(int64 seconds);
} // namespace Data
} // namespace Export

View File

@ -197,7 +197,11 @@ Stats AbstractWriter::produceTestExample(
message.id = counter();
message.date = prevdate();
message.edited = date();
message.forwardedFromId = user.info.userId;
static auto count = 0;
if (++count % 3 == 0) {
message.forwardedFromId = Data::UserPeerId(user.info.userId);
message.forwardedDate = date();
}
message.fromId = user.info.userId;
message.replyToMsgId = counter();
message.viaBotId = bot.info.userId;
@ -485,6 +489,5 @@ Stats AbstractWriter::produceTestExample(
return result;
}
} // namespace Output
} // namespace Export

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,8 @@ private:
};
struct UserpicData;
struct PeersMap;
struct MediaData;
} // namespace details
@ -84,7 +86,9 @@ public:
private:
using Context = details::HtmlContext;
using UserpicData = details::UserpicData;
using MediaData = details::MediaData;
class Wrap;
struct MessageInfo;
[[nodiscard]] Result copyFile(
const QString &source,
@ -104,6 +108,7 @@ private:
[[nodiscard]] Result writeChatsStart(
const Data::DialogsInfo &data,
const QByteArray &listName,
const QByteArray &buttonClass,
const QByteArray &about,
const QString &fileName);
[[nodiscard]] Result writeChatStart(const Data::DialogInfo &data);
@ -153,7 +158,7 @@ private:
Data::DialogInfo _dialog;
int _messagesCount = 0;
TimeId _lastMessageDate = 0;
std::unique_ptr<MessageInfo> _lastMessageInfo;
int _dateMessageId = 0;
std::unique_ptr<Wrap> _chats;
std::unique_ptr<Wrap> _chat;

View File

@ -261,9 +261,9 @@ 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(); });
//Export::Output::HtmlWriter writer;
//writer.produceTestExample(psDownloadPath(), Export::View::PrepareEnvironment());
//crl::on_main([] { App::quit(); });
_ptsWaiter.setRequesting(true);
updateScrollColors();