Closed beta 10019013: Groups in common now are opened in a section.

This commit is contained in:
John Preston 2016-12-08 17:08:54 +03:00
parent 47977009b8
commit 4692fdeb5f
38 changed files with 954 additions and 537 deletions

View File

@ -309,12 +309,6 @@ simpleCloseIcon: icon {{ "simple_close", #c7c7c7 }};
simpleCloseIconOver: icon {{ "simple_close", #a3a3a3 }}; simpleCloseIconOver: icon {{ "simple_close", #a3a3a3 }};
dialogsForwardCancelIcon: icon {{ "simple_close", dialogsForwardFg }}; dialogsForwardCancelIcon: icon {{ "simple_close", dialogsForwardFg }};
profileMaxWidth: 410px;
profilePadding: margins(28px, 30px, 28px, 0px);
profileOnlineFg: statusFgActive;
profileOfflineFg: statusFg;
membersPadding: margins(0px, 10px, 0px, 10px); membersPadding: margins(0px, 10px, 0px, 10px);
forwardMargins: margins(30px, 10px, 30px, 10px); forwardMargins: margins(30px, 10px, 30px, 10px);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,19,12 FILEVERSION 0,10,19,13
PRODUCTVERSION 0,10,19,12 PRODUCTVERSION 0,10,19,13
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "CompanyName", "Telegram Messenger LLP" VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.10.19.12" VALUE "FileVersion", "0.10.19.13"
VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.19.12" VALUE "ProductVersion", "0.10.19.13"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,19,12 FILEVERSION 0,10,19,13
PRODUCTVERSION 0,10,19,12 PRODUCTVERSION 0,10,19,13
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,10 +43,10 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Telegram Messenger LLP" VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileDescription", "Telegram Updater" VALUE "FileDescription", "Telegram Updater"
VALUE "FileVersion", "0.10.19.12" VALUE "FileVersion", "0.10.19.13"
VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.19.12" VALUE "ProductVersion", "0.10.19.13"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -2511,26 +2511,26 @@ namespace {
if (!fmt.isEmpty()) *format = fmt; if (!fmt.isEmpty()) *format = fmt;
} }
buffer.seek(0); buffer.seek(0);
QString fmt = QString::fromUtf8(*format).toLower(); auto fmt = QString::fromUtf8(*format).toLower();
if (fmt == "jpg" || fmt == "jpeg") { if (fmt == "jpg" || fmt == "jpeg") {
#ifdef OS_MAC_OLD #ifdef OS_MAC_OLD
ExifData *exifData = exif_data_new_from_data((const uchar*)(data.constData()), data.size()); if (auto exifData = exif_data_new_from_data((const uchar*)(data.constData()), data.size())) {
if (exifData) { auto byteOrder = exif_data_get_byte_order(exifData);
ExifByteOrder byteOrder = exif_data_get_byte_order(exifData); if (auto exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION)) {
ExifEntry *exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION); auto orientationFix = [exifEntry, byteOrder] {
if (exifEntry) { auto orientation = exif_get_short(exifEntry->data, byteOrder);
QTransform orientationFix; switch (orientation) {
int orientation = exif_get_short(exifEntry->data, byteOrder); case 2: return QTransform(-1, 0, 0, 1, 0, 0);
switch (orientation) { case 3: return QTransform(-1, 0, 0, -1, 0, 0);
case 2: orientationFix = QTransform(-1, 0, 0, 1, 0, 0); break; case 4: return QTransform(1, 0, 0, -1, 0, 0);
case 3: orientationFix = QTransform(-1, 0, 0, -1, 0, 0); break; case 5: return QTransform(0, -1, -1, 0, 0, 0);
case 4: orientationFix = QTransform(1, 0, 0, -1, 0, 0); break; case 6: return QTransform(0, 1, -1, 0, 0, 0);
case 5: orientationFix = QTransform(0, -1, -1, 0, 0, 0); break; case 7: return QTransform(0, 1, 1, 0, 0, 0);
case 6: orientationFix = QTransform(0, 1, -1, 0, 0, 0); break; case 8: return QTransform(0, -1, 1, 0, 0, 0);
case 7: orientationFix = QTransform(0, 1, 1, 0, 0, 0); break; }
case 8: orientationFix = QTransform(0, -1, 1, 0, 0, 0); break; return QTransform();
} };
result = result.transformed(orientationFix); result = result.transformed(orientationFix());
} }
exif_data_free(exifData); exif_data_free(exifData);
} }
@ -2547,9 +2547,11 @@ namespace {
if (animated) *animated = false; if (animated) *animated = false;
return QImage(); return QImage();
} }
QByteArray img = f.readAll(); auto imageBytes = f.readAll();
QImage result = readImage(img, format, opaque, animated); auto result = readImage(imageBytes, format, opaque, animated);
if (content && !result.isNull()) *content = img; if (content && !result.isNull()) {
*content = imageBytes;
}
return result; return result;
} }

View File

@ -391,23 +391,24 @@ inline const QRegularExpression &cRussianLetters() {
return regexp; return regexp;
} }
inline QStringList cImgExtensions() { inline const QStringList &cImgExtensions() {
static QStringList imgExtensions; static QStringList result;
if (imgExtensions.isEmpty()) { if (result.isEmpty()) {
imgExtensions.reserve(4); result.reserve(4);
imgExtensions.push_back(qsl(".jpg")); result.push_back(qsl(".jpg"));
imgExtensions.push_back(qsl(".jpeg")); result.push_back(qsl(".jpeg"));
imgExtensions.push_back(qsl(".png")); result.push_back(qsl(".png"));
imgExtensions.push_back(qsl(".gif")); result.push_back(qsl(".gif"));
} }
return imgExtensions; return result;
} }
inline QStringList cPhotoExtensions() { inline const QStringList &cExtensionsForCompress() {
static QStringList photoExtensions; static QStringList result;
if (photoExtensions.isEmpty()) { if (result.isEmpty()) {
photoExtensions.push_back(qsl(".jpg")); result.push_back(qsl(".jpg"));
photoExtensions.push_back(qsl(".jpeg")); result.push_back(qsl(".jpeg"));
result.push_back(qsl(".png"));
} }
return photoExtensions; return result;
} }

View File

@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "core/utils.h" #include "core/utils.h"
#define BETA_VERSION_MACRO (10019012ULL) #define BETA_VERSION_MACRO (10019013ULL)
constexpr int AppVersion = 10020; constexpr int AppVersion = 10020;
constexpr str_const AppVersionStr = "0.10.20"; constexpr str_const AppVersionStr = "0.10.20";

View File

@ -67,9 +67,6 @@ historyToDownBadgeSize: 22px;
historyToDownShownAfter: 480px; historyToDownShownAfter: 480px;
historyToDownDuration: 150; historyToDownDuration: 150;
historyEmptyDog: icon {{ "history_empty_dog", #ffffff }};
historyEmptySize: 128px;
membersInnerWidth: 310px; membersInnerWidth: 310px;
membersInnerHeightMax: 360px; membersInnerHeightMax: 360px;
membersInnerDropdown: InnerDropdown(defaultInnerDropdown) { membersInnerDropdown: InnerDropdown(defaultInnerDropdown) {

View File

@ -335,14 +335,6 @@ QVector<int> ServiceMessagePainter::countLineWidths(const Text &text, const QRec
} }
void paintEmpty(Painter &p, int width, int height) { void paintEmpty(Painter &p, int width, int height) {
auto position = QPoint((width - st::historyEmptySize) / 2, ((height - st::historyEmptySize) * 4) / 9);
p.setPen(Qt::NoPen);
p.setBrush(st::msgServiceBg);
{
PainterHighQualityEnabler hq(p);
p.drawEllipse(rtlrect(position.x(), position.y(), st::historyEmptySize, st::historyEmptySize, width));
}
st::historyEmptyDog.paint(p, position.x() + (st::historyEmptySize - st::historyEmptyDog.width()) / 2, position.y() + (st::historyEmptySize - st::historyEmptyDog.height()) / 2, width);
} }
void serviceColorsUpdated() { void serviceColorsUpdated() {

View File

@ -5551,9 +5551,7 @@ void HistoryWidget::step_recording(float64 ms, bool timer) {
void HistoryWidget::chooseAttach() { void HistoryWidget::chooseAttach() {
if (!_history) return; if (!_history) return;
auto photoExtensions = cPhotoExtensions(); auto filter = filedialogAllFilesFilter() + qsl(";;Image files (*") + cImgExtensions().join(qsl(" *")) + qsl(")");
auto imageExtensions = cImgExtensions();
auto filter = filedialogAllFilesFilter() + qsl(";;Image files (*") + imageExtensions.join(qsl(" *")) + qsl(");;Photo files (*") + photoExtensions.join(qsl(" *")) + qsl(")");
_attachFilesQueryId = FileDialog::queryReadFiles(lang(lng_choose_files), filter); _attachFilesQueryId = FileDialog::queryReadFiles(lang(lng_choose_files), filter);
} }
@ -5578,7 +5576,7 @@ void HistoryWidget::notifyFileQueryUpdated(const FileDialog::QueryUpdate &update
} }
} else { } else {
auto lists = getSendingFilesLists(update.filePaths); auto lists = getSendingFilesLists(update.filePaths);
if (lists.allFilesArePhotos) { if (lists.allFilesForCompress) {
confirmSendingFiles(lists); confirmSendingFiles(lists);
} else { } else {
validateSendingFiles(lists, [this](const QStringList &files) { validateSendingFiles(lists, [this](const QStringList &files) {
@ -6525,7 +6523,7 @@ bool HistoryWidget::confirmSendingFiles(const SendingFilesLists &lists, Compress
auto insertTextOnCancel = QString(); auto insertTextOnCancel = QString();
auto prepareBox = [this, &files, &lists, compressed, &image] { auto prepareBox = [this, &files, &lists, compressed, &image] {
if (files.size() > 1) { if (files.size() > 1) {
return new SendFilesBox(files, lists.allFilesArePhotos ? compressed : CompressConfirm::None); return new SendFilesBox(files, lists.allFilesForCompress ? compressed : CompressConfirm::None);
} }
auto filepath = files.front(); auto filepath = files.front();
auto animated = false; auto animated = false;
@ -6610,8 +6608,8 @@ HistoryWidget::SendingFilesLists HistoryWidget::getSendingFilesLists(const QStri
} }
void HistoryWidget::getSendingLocalFileInfo(SendingFilesLists &result, const QString &filepath) { void HistoryWidget::getSendingLocalFileInfo(SendingFilesLists &result, const QString &filepath) {
auto hasPhotoExtension = [](const QString &filepath) { auto hasExtensionForCompress = [](const QString &filepath) {
for_const (auto extension, cPhotoExtensions()) { for_const (auto extension, cExtensionsForCompress()) {
if (filepath.right(extension.size()).compare(extension, Qt::CaseInsensitive) == 0) { if (filepath.right(extension.size()).compare(extension, Qt::CaseInsensitive) == 0) {
return true; return true;
} }
@ -6629,9 +6627,9 @@ void HistoryWidget::getSendingLocalFileInfo(SendingFilesLists &result, const QSt
result.tooLargeFiles.push_back(filepath); result.tooLargeFiles.push_back(filepath);
} else { } else {
result.filesToSend.push_back(filepath); result.filesToSend.push_back(filepath);
if (result.allFilesArePhotos) { if (result.allFilesForCompress) {
if (filesize > App::kImageSizeLimit || !hasPhotoExtension(filepath)) { if (filesize > App::kImageSizeLimit || !hasExtensionForCompress(filepath)) {
result.allFilesArePhotos = false; result.allFilesForCompress = false;
} }
} }
} }

View File

@ -858,7 +858,7 @@ private:
QStringList emptyFiles; QStringList emptyFiles;
QStringList tooLargeFiles; QStringList tooLargeFiles;
QStringList filesToSend; QStringList filesToSend;
bool allFilesArePhotos = true; bool allFilesForCompress = true;
}; };
SendingFilesLists getSendingFilesLists(const QList<QUrl> &files); SendingFilesLists getSendingFilesLists(const QList<QUrl> &files);
SendingFilesLists getSendingFilesLists(const QStringList &files); SendingFilesLists getSendingFilesLists(const QStringList &files);

View File

@ -4546,15 +4546,14 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateWebPage: { case mtpc_updateWebPage: {
auto &d = update.c_updateWebPage(); auto &d = update.c_updateWebPage();
if (!ptsUpdated(d.vpts.v, d.vpts_count.v, update)) { // update web page anyway
return;
}
// update before applying skipped
App::feedWebPage(d.vwebpage); App::feedWebPage(d.vwebpage);
_history->updatePreview(); _history->updatePreview();
webPagesOrGamesUpdate(); webPagesOrGamesUpdate();
if (!ptsUpdated(d.vpts.v, d.vpts_count.v, update)) {
return;
}
ptsApplySkippedUpdates(); ptsApplySkippedUpdates();
} break; } break;
@ -4893,8 +4892,13 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateChannelWebPage: { case mtpc_updateChannelWebPage: {
auto &d = update.c_updateChannelWebPage(); auto &d = update.c_updateChannelWebPage();
auto channel = App::channelLoaded(d.vchannel_id.v);
// update web page anyway
App::feedWebPage(d.vwebpage);
_history->updatePreview();
webPagesOrGamesUpdate();
auto channel = App::channelLoaded(d.vchannel_id.v);
if (channel && !_handlingChannelDifference) { if (channel && !_handlingChannelDifference) {
if (channel->ptsRequesting()) { // skip global updates while getting channel difference if (channel->ptsRequesting()) { // skip global updates while getting channel difference
return; return;
@ -4903,12 +4907,6 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
} }
} }
// update before applying skipped
App::feedWebPage(d.vwebpage);
_history->updatePreview();
webPagesOrGamesUpdate();
if (channel && !_handlingChannelDifference) { if (channel && !_handlingChannelDifference) {
channel->ptsApplySkippedUpdates(); channel->ptsApplySkippedUpdates();
} }

View File

@ -238,17 +238,8 @@ mediaPlayerListMarginBottom: 10px;
mediaPlayerScrollShadow: icon {{ "playlist_shadow", windowShadowFg }}; mediaPlayerScrollShadow: icon {{ "playlist_shadow", windowShadowFg }};
mediaPlayerListMarginTop: 8px; mediaPlayerListMarginTop: 8px;
mediaPlayerListIconFg: #ffffff;
mediaPlayerFileLayout: OverviewFileLayout(overviewFileLayout) { mediaPlayerFileLayout: OverviewFileLayout(overviewFileLayout) {
maxWidth: 344px; maxWidth: 344px;
songPadding: margins(17px, 7px, 10px, 6px);
songThumbSize: 36px;
songNameTop: 7px;
songStatusTop: 25px;
songIconBg: mediaPlayerActiveFg; songIconBg: mediaPlayerActiveFg;
songOverBg: mediaPlayerActiveFg; songOverBg: mediaPlayerActiveFg;
songPause: icon {{ "playlist_pause", mediaPlayerListIconFg }};
songPlay: icon {{ "playlist_play", mediaPlayerListIconFg }};
songCancel: icon {{ "playlist_cancel", mediaPlayerListIconFg }};
songDownload: icon {{ "playlist_download", mediaPlayerListIconFg }};
} }

View File

@ -2827,7 +2827,7 @@ void ConnectionPrivate::clearAuthKeyData() {
if (!_authKeyStrings->dh_prime.isEmpty()) SecureZeroMemory(_authKeyStrings->dh_prime.data(), _authKeyStrings->dh_prime.size()); if (!_authKeyStrings->dh_prime.isEmpty()) SecureZeroMemory(_authKeyStrings->dh_prime.data(), _authKeyStrings->dh_prime.size());
if (!_authKeyStrings->g_a.isEmpty()) SecureZeroMemory(_authKeyStrings->g_a.data(), _authKeyStrings->g_a.size()); if (!_authKeyStrings->g_a.isEmpty()) SecureZeroMemory(_authKeyStrings->g_a.data(), _authKeyStrings->g_a.size());
#else #else
memset(authKeyData, 0, sizeof(AuthKeyCreateData)); memset(_authKeyData.get(), 0, sizeof(AuthKeyCreateData));
if (!_authKeyStrings->dh_prime.isEmpty()) memset(_authKeyStrings->dh_prime.data(), 0, _authKeyStrings->dh_prime.size()); if (!_authKeyStrings->dh_prime.isEmpty()) memset(_authKeyStrings->dh_prime.data(), 0, _authKeyStrings->dh_prime.size());
if (!_authKeyStrings->g_a.isEmpty()) memset(_authKeyStrings->g_a.data(), 0, _authKeyStrings->g_a.size()); if (!_authKeyStrings->g_a.isEmpty()) memset(_authKeyStrings->g_a.data(), 0, _authKeyStrings->g_a.size());
#endif #endif

View File

@ -32,9 +32,13 @@ OverviewFileLayout {
songIconBg: color; songIconBg: color;
songOverBg: color; songOverBg: color;
songPause: icon; songPause: icon;
songPauseSelected: icon;
songPlay: icon; songPlay: icon;
songPlaySelected: icon;
songCancel: icon; songCancel: icon;
songCancelSelected: icon;
songDownload: icon; songDownload: icon;
songDownloadSelected: icon;
filePadding: margins; filePadding: margins;
fileThumbSize: pixels; fileThumbSize: pixels;
@ -43,6 +47,9 @@ OverviewFileLayout {
fileDateTop: pixels; fileDateTop: pixels;
} }
overviewLeftMin: 28px;
overviewLeftMax: 42px;
overviewCheckBg: #00000040; overviewCheckBg: #00000040;
overviewCheckFg: windowBg; overviewCheckFg: windowBg;
overviewCheckFgActive: windowBg; overviewCheckFgActive: windowBg;
@ -70,18 +77,30 @@ overviewFileExtTop: 24px;
overviewFileExtFg: #ffffff; overviewFileExtFg: #ffffff;
overviewFileExtFont: font(18px semibold); overviewFileExtFont: font(18px semibold);
overviewSongPause: icon {{ "playlist_pause", msgInBg }};
overviewSongPauseSelected: icon {{ "playlist_pause", msgInBgSelected }};
overviewSongPlay: icon {{ "playlist_play", msgInBg }};
overviewSongPlaySelected: icon {{ "playlist_play", msgInBgSelected }};
overviewSongCancel: icon {{ "playlist_cancel", msgInBg }};
overviewSongCancelSelected: icon {{ "playlist_cancel", msgInBgSelected }};
overviewSongDownload: icon {{ "playlist_download", msgInBg }};
overviewSongDownloadSelected: icon {{ "playlist_download", msgInBgSelected }};
overviewFileLayout: OverviewFileLayout { overviewFileLayout: OverviewFileLayout {
maxWidth: 410px; maxWidth: 520px;
songPadding: msgFilePadding; songPadding: margins(17px, 7px, 10px, 6px);
songThumbSize: msgFileSize; songThumbSize: 36px;
songNameTop: msgFileNameTop; songNameTop: 7px;
songStatusTop: msgFileStatusTop; songStatusTop: 25px;
songIconBg: msgFileInBg; songIconBg: msgFileInBg;
songOverBg: msgFileInBgOver; songOverBg: msgFileInBgOver;
songPause: historyFileInPause; songPause: overviewSongPause;
songPlay: historyFileInPlay; songPauseSelected: overviewSongPauseSelected;
songCancel: historyFileInCancel; songPlay: overviewSongPlay;
songDownload: historyFileInDownload; songPlaySelected: overviewSongPlaySelected;
songCancel: overviewSongCancel;
songCancelSelected: overviewSongCancelSelected;
songDownload: overviewSongDownload;
songDownloadSelected: overviewSongDownloadSelected;
filePadding: margins(0px, 3px, 16px, 3px); filePadding: margins(0px, 3px, 16px, 3px);
fileThumbSize: 70px; fileThumbSize: 70px;
@ -97,7 +116,7 @@ overviewLoaderSkip: 4px;
playlistHoverBg: windowBgOver; playlistHoverBg: windowBgOver;
playlistPadding: 10px; playlistPadding: 10px;
linksSearchMargin: margins(20px, 20px, 20px, 0px); linksSearchTop: 30px;
linksMaxWidth: 520px; linksMaxWidth: 520px;
linksLetterFg: #ffffff; linksLetterFg: #ffffff;
linksLetterFont: font(24px); linksLetterFont: font(24px);

View File

@ -466,9 +466,10 @@ void Video::updateStatusText() {
} }
} }
Voice::Voice(DocumentData *voice, HistoryItem *parent) : RadialProgressItem(parent) Voice::Voice(DocumentData *voice, HistoryItem *parent, const style::OverviewFileLayout &st) : RadialProgressItem(parent)
, _data(voice) , _data(voice)
, _namel(new DocumentOpenClickHandler(_data)) { , _namel(new DocumentOpenClickHandler(_data))
, _st(st) {
AddComponents(Info::Bit()); AddComponents(Info::Bit());
t_assert(_data->voice() != 0); t_assert(_data->voice() != 0);
@ -483,8 +484,8 @@ Voice::Voice(DocumentData *voice, HistoryItem *parent) : RadialProgressItem(pare
} }
void Voice::initDimensions() { void Voice::initDimensions() {
_maxw = st::overviewFileLayout.maxWidth; _maxw = _st.maxWidth;
_minh = st::overviewFileLayout.songPadding.top() + st::overviewFileLayout.songThumbSize + st::overviewFileLayout.songPadding.bottom() + st::lineWidth; _minh = _st.songPadding.top() + _st.songThumbSize + _st.songPadding.bottom() + st::lineWidth;
} }
void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
@ -508,16 +509,16 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = -1; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = -1;
nameleft = st::overviewFileLayout.songPadding.left() + st::overviewFileLayout.songThumbSize + st::overviewFileLayout.songPadding.right(); nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right();
nameright = st::overviewFileLayout.songPadding.left(); nameright = _st.songPadding.left();
nametop = st::overviewFileLayout.songNameTop; nametop = _st.songNameTop;
statustop = st::overviewFileLayout.songStatusTop; statustop = _st.songStatusTop;
if (selected) { if (selected) {
p.fillRect(clip.intersected(QRect(0, 0, _width, _height)), st::msgInBgSelected); p.fillRect(clip.intersected(QRect(0, 0, _width, _height)), st::msgInBgSelected);
} }
QRect inner(rtlrect(st::overviewFileLayout.songPadding.left(), st::overviewFileLayout.songPadding.top(), st::overviewFileLayout.songThumbSize, st::overviewFileLayout.songThumbSize, _width)); QRect inner(rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width));
if (clip.intersects(inner)) { if (clip.intersects(inner)) {
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (selected) { if (selected) {
@ -540,13 +541,13 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
auto icon = ([showPause, this, selected] { auto icon = ([showPause, this, selected] {
if (showPause) { if (showPause) {
return &(selected ? st::historyFileInPauseSelected : st::historyFileInPause); return &(selected ? _st.songPauseSelected : _st.songPause);
} else if (_status.size() < 0 || _status.size() == FileStatusSizeLoaded) { } else if (_status.size() < 0 || _status.size() == FileStatusSizeLoaded) {
return &(selected ? st::historyFileInPlaySelected : st::historyFileInPlay); return &(selected ? _st.songPlaySelected : _st.songPlay);
} else if (_data->loading()) { } else if (_data->loading()) {
return &(selected ? st::historyFileInCancelSelected : st::historyFileInCancel); return &(selected ? _st.songCancelSelected : _st.songCancel);
} }
return &(selected ? st::historyFileInDownloadSelected : st::historyFileInDownload); return &(selected ? _st.songDownloadSelected : _st.songDownload);
})(); })();
icon->paintInCenter(p, inner); icon->paintInCenter(p, inner);
} }
@ -589,12 +590,12 @@ void Voice::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, i
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
nameleft = st::overviewFileLayout.songPadding.left() + st::overviewFileLayout.songThumbSize + st::overviewFileLayout.songPadding.right(); nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right();
nameright = st::overviewFileLayout.songPadding.left(); nameright = _st.songPadding.left();
nametop = st::overviewFileLayout.songNameTop; nametop = _st.songNameTop;
statustop = st::overviewFileLayout.songStatusTop; statustop = _st.songStatusTop;
auto inner = rtlrect(st::overviewFileLayout.songPadding.left(), st::overviewFileLayout.songPadding.top(), st::overviewFileLayout.songThumbSize, st::overviewFileLayout.songThumbSize, _width); auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
if (inner.contains(x, y)) { if (inner.contains(x, y)) {
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl); link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl);
return; return;
@ -747,13 +748,13 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
auto icon = ([showPause, loaded, this, selected] { auto icon = ([showPause, loaded, this, selected] {
if (showPause) { if (showPause) {
return &(selected ? st::historyFileInPauseSelected : _st.songPause); return &(selected ? _st.songPauseSelected : _st.songPause);
} else if (loaded) { } else if (loaded) {
return &(selected ? st::historyFileInPlaySelected : _st.songPlay); return &(selected ? _st.songPlaySelected : _st.songPlay);
} else if (_data->loading()) { } else if (_data->loading()) {
return &(selected ? st::historyFileInCancelSelected : _st.songCancel); return &(selected ? _st.songCancelSelected : _st.songCancel);
} }
return &(selected ? st::historyFileInDownloadSelected : _st.songDownload); return &(selected ? _st.songDownloadSelected : _st.songDownload);
})(); })();
icon->paintInCenter(p, inner); icon->paintInCenter(p, inner);
} }

View File

@ -244,7 +244,7 @@ private:
class Voice : public RadialProgressItem { class Voice : public RadialProgressItem {
public: public:
Voice(DocumentData *voice, HistoryItem *parent); Voice(DocumentData *voice, HistoryItem *parent, const style::OverviewFileLayout &st);
void initDimensions() override; void initDimensions() override;
void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override; void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
@ -269,6 +269,8 @@ private:
StatusText _status; StatusText _status;
ClickHandlerPtr _namel; ClickHandlerPtr _namel;
const style::OverviewFileLayout &_st;
Text _name, _details; Text _name, _details;
int _nameVersion; int _nameVersion;

View File

@ -1276,14 +1276,21 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
if (_type == OverviewPhotos || _type == OverviewVideos) { if (_type == OverviewPhotos || _type == OverviewVideos) {
_photosInRow = int32(_width - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip); _photosInRow = int32(_width - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
_rowWidth = (int32(_width - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip; _rowWidth = (int32(_width - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip;
} else if (_type == OverviewLinks) { _rowsLeft = st::overviewPhotoSkip;
_rowWidth = qMin(_width - st::linksSearchMargin.left() - st::linksSearchMargin.right(), int32(st::linksMaxWidth));
} else { } else {
_rowWidth = qMin(_width - st::profilePadding.left() - st::profilePadding.right(), st::overviewFileLayout.maxWidth); auto contentLeftMin = st::overviewLeftMin;
auto contentLeftMax = st::overviewLeftMax;
if (_type == OverviewMusicFiles || _type == OverviewVoiceFiles) {
contentLeftMin -= st::overviewFileLayout.songPadding.left();
contentLeftMax -= st::overviewFileLayout.songPadding.left();
}
auto widthWithMin = st::windowMinWidth;
auto widthWithMax = st::overviewFileLayout.maxWidth + 2 * contentLeftMax;
_rowsLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - _width, 0) / float64(widthWithMax - widthWithMin));
_rowWidth = qMin(_width - 2 * _rowsLeft, st::overviewFileLayout.maxWidth);
} }
_rowsLeft = (_width - _rowWidth) / 2;
_search->setGeometry(_rowsLeft, st::linksSearchMargin.top(), _rowWidth, _search->height()); _search->setGeometry(_rowsLeft, st::linksSearchTop, _rowWidth, _search->height());
_cancelSearch->moveToLeft(_rowsLeft + _rowWidth - _cancelSearch->width(), _search->y()); _cancelSearch->moveToLeft(_rowsLeft + _rowWidth - _cancelSearch->width(), _search->y());
if (_type == OverviewPhotos || _type == OverviewVideos) { if (_type == OverviewPhotos || _type == OverviewVideos) {
@ -1797,7 +1804,7 @@ void OverviewInner::recountMargins() {
_marginTop = st::playlistPadding; _marginTop = st::playlistPadding;
_marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding)); _marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding));
} else if (_type == OverviewLinks || _type == OverviewFiles) { } else if (_type == OverviewLinks || _type == OverviewFiles) {
_marginTop = st::linksSearchMargin.top() + _search->height() + st::linksSearchMargin.bottom(); _marginTop = st::linksSearchTop + _search->height();
_marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding)); _marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding));
} else { } else {
_marginBottom = st::playlistPadding; _marginBottom = st::playlistPadding;
@ -1827,7 +1834,7 @@ Overview::Layout::ItemBase *OverviewInner::layoutPrepare(HistoryItem *item) {
} else if (_type == OverviewVoiceFiles) { } else if (_type == OverviewVoiceFiles) {
if (media && (media->type() == MediaTypeVoiceFile)) { if (media && (media->type() == MediaTypeVoiceFile)) {
if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) { if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) {
i = _layoutItems.insert(item, new Overview::Layout::Voice(media->getDocument(), item)); i = _layoutItems.insert(item, new Overview::Layout::Voice(media->getDocument(), item, st::overviewFileLayout));
i.value()->initDimensions(); i.value()->initDimensions();
} }
} }

View File

@ -144,3 +144,14 @@ profileVerifiedCheck: icon {
{ "profile_verified_star", windowBgActive, point(0px, 7px) }, { "profile_verified_star", windowBgActive, point(0px, 7px) },
{ "profile_verified_check", windowFgActive, point(4px, 11px) } { "profile_verified_check", windowFgActive, point(4px, 11px) }
}; };
profileCommonGroupsSkip: 24px;
profileCommonGroupsLeftMin: 24px;
profileCommonGroupsLeftMax: 36px;
profileCommonGroupsWidthMax: 480px;
profileCommonGroupsPadding: margins(7px, 7px, 7px, 7px);
profileCommonGroupsPhotoSize: 42px;
profileCommonGroupsNameTop: 12px;
profileCommonGroupsNameLeft: 16px;
profileCommonGroupsBgOver: windowBgOver;
profileCommonGroupsRipple: defaultRippleAnimation;

View File

@ -0,0 +1,72 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "profile/profile_back_button.h"
#include "window/top_bar_widget.h"
#include "styles/style_widgets.h"
#include "styles/style_window.h"
#include "styles/style_profile.h"
namespace Profile {
BackButton::BackButton(QWidget *parent, const QString &text) : Ui::AbstractButton(parent)
, _text(text.toUpper()) {
setCursor(style::cur_pointer);
subscribe(Adaptive::Changed(), [this] { updateAdaptiveLayout(); });
updateAdaptiveLayout();
}
int BackButton::resizeGetHeight(int newWidth) {
return st::profileTopBarHeight;
}
void BackButton::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(e->rect(), st::profileBg);
st::topBarBack.paint(p, (st::topBarArrowPadding.left() - st::topBarBack.width()) / 2, (st::topBarHeight - st::topBarBack.height()) / 2, width());
p.setFont(st::topBarButton.font);
p.setPen(st::topBarButton.textFg);
p.drawTextLeft(st::topBarArrowPadding.left(), st::topBarButton.padding.top() + st::topBarButton.textTop, width(), _text);
Window::TopBarWidget::paintUnreadCounter(p, width());
}
void BackButton::onStateChanged(State was, StateChangeSource source) {
if (isDown() && !(was & StateFlag::Down)) {
emit clicked();
}
}
void BackButton::updateAdaptiveLayout() {
if (!Adaptive::OneColumn()) {
unsubscribe(base::take(_unreadCounterSubscription));
} else if (!_unreadCounterSubscription) {
_unreadCounterSubscription = subscribe(Global::RefUnreadCounterUpdate(), [this] {
rtlupdate(0, 0, st::titleUnreadCounterRight, st::titleUnreadCounterTop);
});
}
}
} // namespace Profile

View File

@ -0,0 +1,45 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "ui/abstract_button.h"
namespace Profile {
class BackButton final : public Ui::AbstractButton, private base::Subscriber {
public:
BackButton(QWidget *parent, const QString &text);
protected:
void paintEvent(QPaintEvent *e) override;
int resizeGetHeight(int newWidth) override;
void onStateChanged(State was, StateChangeSource source) override;
private:
void updateAdaptiveLayout();
int _unreadCounterSubscription = 0;
QString _text;
};
} // namespace Profile

View File

@ -1,175 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "profile/profile_block_common_groups.h"
#include "profile/profile_section_memento.h"
#include "styles/style_widgets.h"
#include "observer_peer.h"
#include "apiwrap.h"
#include "lang.h"
namespace Profile {
namespace {
constexpr int kCommonGroupsPerPage = 20;
} // namespace
CommonGroupsWidget::CommonGroupsWidget(QWidget *parent, PeerData *peer)
: PeerListWidget(parent, peer, lang(lng_profile_common_groups_section)) {
refreshVisibility();
auto observeEvents = Notify::PeerUpdate::Flag::MembersChanged;
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
}));
setSelectedCallback([this](PeerData *selectedPeer) {
Ui::showPeerHistory(selectedPeer, ShowAtUnreadMsgId, Ui::ShowWay::Forward);
});
setPreloadMoreCallback([this] {
preloadMore();
});
}
void CommonGroupsWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
for_const (auto item, items()) {
if (item->peer == update.peer) {
updateStatusText(item);
this->update();
return;
}
}
}
int CommonGroupsWidget::resizeGetHeight(int newWidth) {
auto result = PeerListWidget::resizeGetHeight(newWidth);
return qRound(_height.current(result));
}
void CommonGroupsWidget::paintContents(Painter &p) {
_height.animating(getms());
return PeerListWidget::paintContents(p);
}
void CommonGroupsWidget::saveState(SectionMemento *memento) const {
if (auto count = itemsCount()) {
QList<PeerData*> groups;
groups.reserve(count);
for_const (auto item, items()) {
groups.push_back(item->peer);
}
memento->setCommonGroups(groups);
}
}
void CommonGroupsWidget::restoreState(const SectionMemento *memento) {
CommonGroupsEvent event;
event.groups = memento->getCommonGroups();
if (!event.groups.empty()) {
onShowCommonGroups(event);
}
}
void CommonGroupsWidget::onShowCommonGroups(const CommonGroupsEvent &event) {
for_const (auto group, event.groups) {
addItem(computeItem(group));
_preloadGroupId = group->bareId();
}
refreshVisibility();
if (event.initialHeight >= 0) {
_height.start([this] { contentSizeUpdated(); }, event.initialHeight, resizeGetHeight(width()), st::widgetSlideDuration);
}
contentSizeUpdated();
update();
}
void CommonGroupsWidget::preloadMore() {
if (_preloadRequestId || !_preloadGroupId) {
return;
}
auto user = peer()->asUser();
t_assert(user != nullptr);
auto request = MTPmessages_GetCommonChats(user->inputUser, MTP_int(_preloadGroupId), MTP_int(kCommonGroupsPerPage));
_preloadRequestId = MTP::send(request, ::rpcDone(base::lambda_guarded(this, [this](const MTPmessages_Chats &result) {
_preloadRequestId = 0;
_preloadGroupId = 0;
if (auto chats = Api::getChatsFromMessagesChats(result)) {
auto &list = chats->c_vector().v;
if (!list.empty()) {
reserveItemsForSize(itemsCount() + list.size());
for_const (auto &chatData, list) {
if (auto chat = App::feedChat(chatData)) {
addItem(computeItem(chat));
_preloadGroupId = chat->bareId();
}
}
contentSizeUpdated();
}
}
})));
}
void CommonGroupsWidget::updateStatusText(Item *item) {
auto group = item->peer;
if (auto chat = group->asChat()) {
auto count = qMax(chat->count, chat->participants.size());
item->statusText = count ? lng_chat_status_members(lt_count, count) : lang(lng_group_status);
} else if (auto megagroup = group->asMegagroup()) {
auto count = megagroup->membersCount();
item->statusText = (count > 0) ? lng_chat_status_members(lt_count, count) : lang(lng_group_status);
// Request members count.
if (!megagroup->wasFullUpdated()) App::api()->requestFullPeer(megagroup);
} else if (auto channel = group->asChannel()) {
auto count = channel->membersCount();
item->statusText = (count > 0) ? lng_chat_status_members(lt_count, count) : lang(lng_channel_status);
// Request members count.
if (!channel->wasFullUpdated()) App::api()->requestFullPeer(channel);
} else {
t_assert(!"Users should not get to CommonGroupsWidget::updateStatusText()");
}
}
CommonGroupsWidget::Item *CommonGroupsWidget::computeItem(PeerData *group) {
// Skip groups that migrated to supergroups.
if (group->migrateTo()) {
return nullptr;
}
auto it = _dataMap.constFind(group);
if (it == _dataMap.cend()) {
it = _dataMap.insert(group, new Item(group));
updateStatusText(it.value());
}
return it.value();
}
CommonGroupsWidget::~CommonGroupsWidget() {
for (auto item : base::take(_dataMap)) {
delete item;
}
}
} // namespace Profile

View File

@ -1,75 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "profile/profile_block_peer_list.h"
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Profile {
struct CommonGroupsEvent {
QList<PeerData*> groups;
// If initialHeight >= 0 the common groups widget will
// slide down starting from height() == initialHeight.
// Otherwise it will just show instantly.
int initialHeight = -1;
};
class CommonGroupsWidget : public PeerListWidget {
public:
CommonGroupsWidget(QWidget *parent, PeerData *peer);
void setShowCommonGroupsObservable(base::Observable<CommonGroupsEvent> *observable) {
subscribe(observable, [this](const CommonGroupsEvent &event) { onShowCommonGroups(event); });
}
void saveState(SectionMemento *memento) const override;
void restoreState(const SectionMemento *memento) override;
~CommonGroupsWidget();
protected:
int resizeGetHeight(int newWidth) override;
void paintContents(Painter &p) override;
private:
// Observed notifications.
void notifyPeerUpdated(const Notify::PeerUpdate &update);
void updateStatusText(Item *item);
void onShowCommonGroups(const CommonGroupsEvent &event);
void preloadMore();
Item *computeItem(PeerData *group);
QMap<PeerData*, Item*> _dataMap;
Animation _height;
int32 _preloadGroupId = 0;
mtpRequestId _preloadRequestId = 0;
};
} // namespace Profile

View File

@ -21,13 +21,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h" #include "stdafx.h"
#include "profile/profile_block_info.h" #include "profile/profile_block_info.h"
#include "profile/profile_block_common_groups.h" #include "profile/profile_common_groups_section.h"
#include "profile/profile_section_memento.h" #include "profile/profile_section_memento.h"
#include "styles/style_profile.h" #include "styles/style_profile.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/effects/widget_slide_wrap.h" #include "ui/effects/widget_slide_wrap.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "mainwidget.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "lang.h" #include "lang.h"
@ -69,12 +70,6 @@ void InfoWidget::slideCommonGroupsDown() {
contentSizeUpdated(); contentSizeUpdated();
} }
void InfoWidget::restoreState(const SectionMemento *memento) {
if (!memento->getCommonGroups().isEmpty()) {
onForceHideCommonGroups();
}
}
void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.peer != peer()) { if (update.peer != peer()) {
return; return;
@ -253,7 +248,7 @@ int InfoWidget::getCommonGroupsCount() const {
} }
void InfoWidget::refreshCommonGroups() { void InfoWidget::refreshCommonGroups() {
if (auto count = (_forceHiddenCommonGroups ? 0 : getCommonGroupsCount())) { if (auto count = getCommonGroupsCount()) {
auto text = lng_profile_common_groups(lt_count, count); auto text = lng_profile_common_groups(lt_count, count);
if (_commonGroups) { if (_commonGroups) {
_commonGroups->setText(text); _commonGroups->setText(text);
@ -270,56 +265,15 @@ void InfoWidget::refreshCommonGroups() {
} }
} }
void InfoWidget::setShowCommonGroupsObservable(base::Observable<CommonGroupsEvent> *observable) {
_showCommonGroupsObservable = observable;
subscribe(_showCommonGroupsObservable, [this](const CommonGroupsEvent &event) {
onForceHideCommonGroups();
});
}
void InfoWidget::onForceHideCommonGroups() {
if (_forceHiddenCommonGroups) {
return;
}
_forceHiddenCommonGroups = true;
_commonGroups.destroyDelayed();
refreshVisibility();
contentSizeUpdated();
}
void InfoWidget::onShowCommonGroups() { void InfoWidget::onShowCommonGroups() {
auto count = getCommonGroupsCount(); auto count = getCommonGroupsCount();
if (count <= 0) { if (count <= 0) {
refreshCommonGroups(); refreshCommonGroups();
return; return;
} }
if (_getCommonGroupsRequestId) { if (auto main = App::main()) {
return; main->showWideSection(Profile::CommonGroups::SectionMemento(peer()));
} }
auto user = peer()->asUser();
t_assert(user != nullptr);
auto request = MTPmessages_GetCommonChats(user->inputUser, MTP_int(0), MTP_int(kCommonGroupsLimit));
_getCommonGroupsRequestId = MTP::send(request, ::rpcDone(base::lambda_guarded(this, [this](const MTPmessages_Chats &result) {
_getCommonGroupsRequestId = 0;
CommonGroupsEvent event;
if (auto chats = Api::getChatsFromMessagesChats(result)) {
auto &list = chats->c_vector().v;
event.groups.reserve(list.size());
for_const (auto &chatData, list) {
if (auto chat = App::feedChat(chatData)) {
event.groups.push_back(chat);
}
}
}
auto oldHeight = height();
onForceHideCommonGroups();
if (!event.groups.empty() && _showCommonGroupsObservable) {
event.initialHeight = oldHeight - (isHidden() ? 0 : height());
_showCommonGroupsObservable->notify(event, true);
}
})));
} }
void InfoWidget::setLabeledText(ChildWidget<Ui::FlatLabel> *labelWidget, const QString &label, void InfoWidget::setLabeledText(ChildWidget<Ui::FlatLabel> *labelWidget, const QString &label,

View File

@ -36,17 +36,12 @@ class LeftOutlineButton;
namespace Profile { namespace Profile {
struct CommonGroupsEvent;
class InfoWidget : public BlockWidget, public RPCSender { class InfoWidget : public BlockWidget, public RPCSender {
public: public:
InfoWidget(QWidget *parent, PeerData *peer); InfoWidget(QWidget *parent, PeerData *peer);
void setShowCommonGroupsObservable(base::Observable<CommonGroupsEvent> *observable);
void showFinished() override; void showFinished() override;
void restoreState(const SectionMemento *memento) override;
protected: protected:
// Resizes content and counts natural widget height for the desired width. // Resizes content and counts natural widget height for the desired width.
int resizeGetHeight(int newWidth) override; int resizeGetHeight(int newWidth) override;
@ -66,7 +61,6 @@ private:
void refreshVisibility(); void refreshVisibility();
int getCommonGroupsCount() const; int getCommonGroupsCount() const;
void onForceHideCommonGroups();
void onShowCommonGroups(); void onShowCommonGroups();
void slideCommonGroupsDown(); void slideCommonGroupsDown();
@ -87,11 +81,6 @@ private:
Animation _height; Animation _height;
bool _showFinished = false; bool _showFinished = false;
bool _forceHiddenCommonGroups = false;
mtpRequestId _getCommonGroupsRequestId = 0;
base::Observable<CommonGroupsEvent> *_showCommonGroupsObservable = nullptr;
}; };
} // namespace Profile } // namespace Profile

View File

@ -0,0 +1,446 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "profile/profile_common_groups_section.h"
#include "profile/profile_section_memento.h"
#include "profile/profile_back_button.h"
#include "styles/style_widgets.h"
#include "styles/style_profile.h"
#include "styles/style_window.h"
#include "styles/style_settings.h"
#include "ui/effects/ripple_animation.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/shadow.h"
#include "mainwidget.h"
#include "observer_peer.h"
#include "apiwrap.h"
#include "lang.h"
namespace Profile {
namespace CommonGroups {
namespace {
constexpr int kCommonGroupsPerPage = 40;
} // namespace
Window::SectionWidget *SectionMemento::createWidget(QWidget *parent, const QRect &geometry) const {
auto result = new Widget(parent, _peer);
result->setInternalState(geometry, this);
return result;
}
FixedBar::FixedBar(QWidget *parent) : TWidget(parent)
, _backButton(this, lang(lng_profile_common_groups_section)) {
_backButton->moveToLeft(0, 0);
connect(_backButton, SIGNAL(clicked()), this, SLOT(onBack()));
}
void FixedBar::onBack() {
App::main()->showBackFromStack();
}
int FixedBar::resizeGetHeight(int newWidth) {
auto newHeight = 0;
auto buttonLeft = newWidth;
_backButton->resizeToWidth(newWidth);
_backButton->moveToLeft(0, 0);
newHeight += _backButton->height();
return newHeight;
}
void FixedBar::setAnimatingMode(bool enabled) {
if (_animatingMode != enabled) {
_animatingMode = enabled;
setCursor(_animatingMode ? style::cur_pointer : style::cur_default);
if (_animatingMode) {
setAttribute(Qt::WA_OpaquePaintEvent, false);
hideChildren();
} else {
setAttribute(Qt::WA_OpaquePaintEvent);
showChildren();
}
show();
}
}
void FixedBar::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
onBack();
} else {
TWidget::mousePressEvent(e);
}
}
InnerWidget::Item::Item(PeerData *peer) : peer(peer) {
}
InnerWidget::Item::~Item() = default;
InnerWidget::InnerWidget(QWidget *parent, PeerData *peer) : TWidget(parent)
, _peer(peer) {
setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent);
_rowHeight = st::profileCommonGroupsPadding.top() + st::profileCommonGroupsPhotoSize + st::profileCommonGroupsPadding.bottom();
_contentTop = st::profileCommonGroupsSkip;
}
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
_visibleTop = visibleTop;
_visibleBottom = visibleBottom;
checkPreloadMore();
}
void InnerWidget::checkPreloadMore() {
if (_visibleTop + PreloadHeightsCount * (_visibleBottom - _visibleTop) > height()) {
preloadMore();
}
}
void InnerWidget::saveState(SectionMemento *memento) const {
if (auto count = _items.size()) {
QList<PeerData*> groups;
groups.reserve(count);
for_const (auto item, _items) {
groups.push_back(item->peer);
}
memento->setCommonGroups(groups);
}
}
void InnerWidget::restoreState(const SectionMemento *memento) {
auto list = memento->getCommonGroups();
_allLoaded = false;
if (!list.empty()) {
showInitial(list);
}
}
void InnerWidget::showInitial(const QList<PeerData*> &list) {
for_const (auto group, list) {
_items.push_back(computeItem(group));
_preloadGroupId = group->bareId();
}
updateSize();
}
void InnerWidget::preloadMore() {
if (_preloadRequestId || _allLoaded) {
return;
}
auto user = peer()->asUser();
t_assert(user != nullptr);
auto request = MTPmessages_GetCommonChats(user->inputUser, MTP_int(_preloadGroupId), MTP_int(kCommonGroupsPerPage));
_preloadRequestId = MTP::send(request, ::rpcDone(base::lambda_guarded(this, [this](const MTPmessages_Chats &result) {
_preloadRequestId = 0;
_preloadGroupId = 0;
_allLoaded = true;
if (auto chats = Api::getChatsFromMessagesChats(result)) {
auto &list = chats->c_vector().v;
if (!list.empty()) {
_items.reserve(_items.size() + list.size());
for_const (auto &chatData, list) {
if (auto chat = App::feedChat(chatData)) {
auto found = false;
for_const (auto item, _items) {
if (item->peer == chat) {
found = true;
break;
}
}
if (!found) {
_items.push_back(computeItem(chat));
}
_preloadGroupId = chat->bareId();
_allLoaded = false;
}
}
updateSize();
}
}
})));
}
void InnerWidget::updateSize() {
TWidget::resizeToWidth(width());
checkPreloadMore();
}
int InnerWidget::resizeGetHeight(int newWidth) {
update();
auto contentLeftMin = st::profileCommonGroupsLeftMin;
auto contentLeftMax = st::profileCommonGroupsLeftMax;
auto widthWithMin = st::windowMinWidth;
auto widthWithMax = st::profileCommonGroupsWidthMax + 2 * contentLeftMax;
_contentLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - newWidth, 0) / float64(widthWithMax - widthWithMin));
_contentWidth = qMin(newWidth - 2 * _contentLeft, st::profileCommonGroupsWidthMax);
auto newHeight = _contentTop;
newHeight += _items.size() * _rowHeight;
newHeight += st::profileCommonGroupsSkip;
return qMax(newHeight, _minHeight);
}
void InnerWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
auto ms = getms();
auto clip = e->rect();
p.fillRect(clip, st::profileBg);
auto from = floorclamp(clip.y() - _contentTop, _rowHeight, 0, _items.size());
auto to = ceilclamp(clip.y() + clip.height() - _contentTop, _rowHeight, 0, _items.size());
for (auto i = from; i != to; ++i) {
paintRow(p, i, ms);
}
}
void InnerWidget::paintRow(Painter &p, int index, TimeMs ms) {
auto item = _items[index];
auto selected = (_pressed >= 0) ? (index == _pressed) : (index == _selected);
auto x = _contentLeft;
auto y = _contentTop + index * _rowHeight;
if (selected) {
p.fillRect(myrtlrect(x, y, _contentWidth, _rowHeight), st::profileCommonGroupsBgOver);
}
if (auto &ripple = item->ripple) {
ripple->paint(p, x, y, width(), ms);
if (ripple->empty()) {
ripple.reset();
}
}
x += st::profileCommonGroupsPadding.left();
y += st::profileCommonGroupsPadding.top();
item->peer->paintUserpic(p, st::profileCommonGroupsPhotoSize, rtl() ? (width() - x - st::profileCommonGroupsPhotoSize) : x, y);
x += st::profileCommonGroupsPhotoSize + st::profileCommonGroupsNameLeft;
y += st::profileCommonGroupsNameTop;
auto nameWidth = _contentWidth - (x - _contentLeft) - st::profileCommonGroupsPadding.right();
if (item->name.isEmpty()) {
item->name.setText(st::semiboldFont, App::peerName(item->peer), _textNameOptions);
}
_items[index]->name.drawLeftElided(p, x, y, nameWidth, width());
}
void InnerWidget::keyPressEvent(QKeyEvent *e) {
}
void InnerWidget::updateSelected(QPoint localPos) {
auto selected = -1;
auto selectedKick = false;
if (rtl()) localPos.setX(width() - localPos.x());
if (localPos.x() >= _contentLeft && localPos.x() < _contentLeft + _contentWidth && localPos.y() >= _contentTop) {
selected = (localPos.y() - _contentTop) / _rowHeight;
if (selected >= _items.size()) {
selected = -1;
}
}
if (_selected != selected) {
updateRow(_selected);
_selected = selected;
updateRow(_selected);
if (_pressed < 0) {
setCursor((_selected >= 0) ? style::cur_pointer : style::cur_default);
}
}
}
void InnerWidget::updateRow(int index) {
rtlupdate(_contentLeft, _contentTop + index * _rowHeight, _contentWidth, _rowHeight);
}
void InnerWidget::mousePressEvent(QMouseEvent *e) {
_pressed = _selected;
if (_pressed >= 0) {
auto item = _items[_pressed];
if (!item->ripple) {
auto mask = Ui::RippleAnimation::rectMask(QSize(_contentWidth, _rowHeight));
item->ripple = std_::make_unique<Ui::RippleAnimation>(st::profileCommonGroupsRipple, std_::move(mask), [this, index = _pressed] {
updateRow(index);
});
}
auto left = _contentLeft;
auto top = _contentTop + _rowHeight * _pressed;
item->ripple->add(e->pos() - QPoint(left, top));
}
}
void InnerWidget::mouseMoveEvent(QMouseEvent *e) {
updateSelected(e->pos());
}
void InnerWidget::mouseReleaseEvent(QMouseEvent *e) {
updateRow(_pressed);
auto pressed = base::take(_pressed, -1);
if (pressed >= 0 && pressed < _items.size()) {
if (auto &ripple = _items[pressed]->ripple) {
ripple->lastStop();
}
if (pressed == _selected) {
Ui::showPeerHistory(_items[pressed]->peer, ShowAtUnreadMsgId, Ui::ShowWay::Forward);
}
}
setCursor(_selected ? style::cur_pointer : style::cur_default);
updateRow(_selected);
}
InnerWidget::Item *InnerWidget::computeItem(PeerData *group) {
// Skip groups that migrated to supergroups.
if (group->migrateTo()) {
return nullptr;
}
auto it = _dataMap.constFind(group);
if (it == _dataMap.cend()) {
it = _dataMap.insert(group, new Item(group));
}
return it.value();
}
InnerWidget::~InnerWidget() {
for (auto item : base::take(_dataMap)) {
delete item;
}
}
Widget::Widget(QWidget *parent, PeerData *peer) : Window::SectionWidget(parent)
, _scroll(this, st::settingsScroll)
, _inner(this, peer)
, _fixedBar(this)
, _fixedBarShadow(this, st::shadowColor) {
_fixedBar->move(0, 0);
_fixedBar->resizeToWidth(width());
_fixedBar->show();
_fixedBarShadow->raise();
updateAdaptiveLayout();
subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); });
_scroll->setOwnedWidget(_inner);
_scroll->move(0, _fixedBar->height());
_scroll->show();
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
connect(_inner, SIGNAL(cancelled()), _fixedBar, SLOT(onBack()));
}
void Widget::updateAdaptiveLayout() {
_fixedBarShadow->moveToLeft(Adaptive::OneColumn() ? 0 : st::lineWidth, _fixedBar->height());
}
PeerData *Widget::peer() const {
return _inner->peer();
}
QPixmap Widget::grabForShowAnimation(const Window::SectionSlideParams &params) {
if (params.withTopBarShadow) _fixedBarShadow->hide();
auto result = myGrab(this);
if (params.withTopBarShadow) _fixedBarShadow->show();
return result;
}
void Widget::setInnerFocus() {
_inner->setFocus();
}
bool Widget::showInternal(const Window::SectionMemento *memento) {
if (auto profileMemento = dynamic_cast<const SectionMemento*>(memento)) {
if (profileMemento->getPeer() == peer()) {
restoreState(profileMemento);
return true;
}
}
return false;
}
void Widget::setInternalState(const QRect &geometry, const SectionMemento *memento) {
setGeometry(geometry);
myEnsureResized(this);
restoreState(memento);
}
std_::unique_ptr<Window::SectionMemento> Widget::createMemento() const {
auto result = std_::make_unique<SectionMemento>(peer());
saveState(result.get());
return std_::move(result);
}
void Widget::saveState(SectionMemento *memento) const {
memento->setScrollTop(_scroll->scrollTop());
_inner->saveState(memento);
}
void Widget::restoreState(const SectionMemento *memento) {
_inner->restoreState(memento);
auto scrollTop = memento->getScrollTop();
_scroll->scrollToY(scrollTop);
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
}
void Widget::resizeEvent(QResizeEvent *e) {
if (!width() || !height()) {
return;
}
int newScrollTop = _scroll->scrollTop() + topDelta();
_fixedBar->resizeToWidth(width());
_fixedBarShadow->resize(width(), st::lineWidth);
QSize scrollSize(width(), height() - _fixedBar->height());
if (_scroll->size() != scrollSize) {
_scroll->resize(scrollSize);
_inner->resizeToWidth(scrollSize.width(), _scroll->height());
}
if (!_scroll->isHidden()) {
if (topDelta()) {
_scroll->scrollToY(newScrollTop);
}
int scrollTop = _scroll->scrollTop();
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
}
}
void Widget::onScroll() {
int scrollTop = _scroll->scrollTop();
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
}
void Widget::showAnimatedHook() {
_fixedBar->setAnimatingMode(true);
}
void Widget::showFinishedHook() {
_fixedBar->setAnimatingMode(false);
}
} // namespace CommonGroups
} // namespace Profile

View File

@ -0,0 +1,216 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "window/section_widget.h"
#include "window/section_memento.h"
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Ui {
class ScrollArea;
class PlainShadow;
} // namespace Ui
namespace Profile {
class BackButton;
namespace CommonGroups {
class SectionMemento : public Window::SectionMemento {
public:
SectionMemento(PeerData *peer) : _peer(peer) {
}
Window::SectionWidget *createWidget(QWidget *parent, const QRect &geometry) const override;
PeerData *getPeer() const {
return _peer;
}
void setScrollTop(int scrollTop) {
_scrollTop = scrollTop;
}
int getScrollTop() const {
return _scrollTop;
}
void setCommonGroups(const QList<PeerData*> &groups) {
_commonGroups = groups;
}
const QList<PeerData*> &getCommonGroups() const {
return _commonGroups;
}
private:
PeerData *_peer;
int _scrollTop = 0;
QList<PeerData*> _commonGroups;
};
class FixedBar final : public TWidget, private base::Subscriber {
Q_OBJECT
public:
FixedBar(QWidget *parent);
// When animating mode is enabled the content is hidden and the
// whole fixed bar acts like a back button.
void setAnimatingMode(bool enabled);
protected:
void mousePressEvent(QMouseEvent *e) override;
int resizeGetHeight(int newWidth) override;
public slots:
void onBack();
private:
ChildWidget<BackButton> _backButton;
bool _animatingMode = false;
};
class InnerWidget final : public TWidget {
Q_OBJECT
public:
InnerWidget(QWidget *parent, PeerData *peer);
PeerData *peer() const {
return _peer;
}
// Updates the area that is visible inside the scroll container.
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
void resizeToWidth(int newWidth, int minHeight) {
_minHeight = minHeight;
return TWidget::resizeToWidth(newWidth);
}
void saveState(SectionMemento *memento) const;
void restoreState(const SectionMemento *memento);
~InnerWidget();
signals:
void cancelled();
protected:
void paintEvent(QPaintEvent *e) override;
void keyPressEvent(QKeyEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
// Resizes content and counts natural widget height for the desired width.
int resizeGetHeight(int newWidth) override;
private:
void updateSelected(QPoint localPos);
void updateRow(int index);
void showInitial(const QList<PeerData*> &list);
void checkPreloadMore();
void preloadMore();
void updateSize();
void paintRow(Painter &p, int index, TimeMs ms);
PeerData *_peer;
int _minHeight = 0;
int _rowHeight = 0;
int _contentLeft = 0;
int _contentTop = 0;
int _contentWidth = 0;
int _visibleTop = 0;
int _visibleBottom = 0;
struct Item {
explicit Item(PeerData *peer);
~Item();
PeerData * const peer;
Text name;
std_::unique_ptr<Ui::RippleAnimation> ripple;
};
Item *computeItem(PeerData *group);
QMap<PeerData*, Item*> _dataMap;
QList<Item*> _items;
int _selected = -1;
int _pressed = -1;
int32 _preloadGroupId = 0;
mtpRequestId _preloadRequestId = 0;
bool _allLoaded = true;
};
class Widget final : public Window::SectionWidget {
Q_OBJECT
public:
Widget(QWidget *parent, PeerData *peer);
PeerData *peer() const;
PeerData *peerForDialogs() const override {
return peer();
}
bool hasTopBarShadow() const override {
return true;
}
QPixmap grabForShowAnimation(const Window::SectionSlideParams &params) override;
void setInnerFocus() override;
bool showInternal(const Window::SectionMemento *memento) override;
std_::unique_ptr<Window::SectionMemento> createMemento() const override;
void setInternalState(const QRect &geometry, const SectionMemento *memento);
protected:
void resizeEvent(QResizeEvent *e) override;
void showAnimatedHook() override;
void showFinishedHook() override;
private slots:
void onScroll();
private:
void updateAdaptiveLayout();
void saveState(SectionMemento *memento) const;
void restoreState(const SectionMemento *memento);
ChildWidget<Ui::ScrollArea> _scroll;
ChildWidget<InnerWidget> _inner;
ChildWidget<FixedBar> _fixedBar;
ChildWidget<Ui::PlainShadow> _fixedBarShadow;
};
} // namespace CommonGroups
} // namespace Profile

View File

@ -29,59 +29,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "boxes/addcontactbox.h" #include "boxes/addcontactbox.h"
#include "boxes/confirmbox.h" #include "boxes/confirmbox.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "window/top_bar_widget.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
#include "profile/profile_back_button.h"
namespace Profile { namespace Profile {
class BackButton final : public Ui::AbstractButton, private base::Subscriber {
public:
BackButton(QWidget *parent) : Ui::AbstractButton(parent)
, _text(lang(lng_menu_back).toUpper()) {
setCursor(style::cur_pointer);
subscribe(Adaptive::Changed(), [this] { updateAdaptiveLayout(); });
updateAdaptiveLayout();
}
protected:
int resizeGetHeight(int newWidth) override {
return st::profileTopBarHeight;
}
void paintEvent(QPaintEvent *e) override {
Painter p(this);
p.fillRect(e->rect(), st::profileBg);
st::topBarBack.paint(p, (st::topBarArrowPadding.left() - st::topBarBack.width()) / 2, (st::topBarHeight - st::topBarBack.height()) / 2, width());
p.setFont(st::topBarButton.font);
p.setPen(st::topBarButton.textFg);
p.drawTextLeft(st::topBarArrowPadding.left(), st::topBarButton.padding.top() + st::topBarButton.textTop, width(), _text);
Window::TopBarWidget::paintUnreadCounter(p, width());
}
void onStateChanged(State was, StateChangeSource source) override {
if (isDown() && !(was & StateFlag::Down)) {
emit clicked();
}
}
private:
void updateAdaptiveLayout() {
if (!Adaptive::OneColumn()) {
unsubscribe(base::take(_unreadCounterSubscription));
} else if (!_unreadCounterSubscription) {
_unreadCounterSubscription = subscribe(Global::RefUnreadCounterUpdate(), [this] {
rtlupdate(0, 0, st::titleUnreadCounterRight, st::titleUnreadCounterTop);
});
}
}
int _unreadCounterSubscription = 0;
QString _text;
};
namespace { namespace {
using UpdateFlag = Notify::PeerUpdate::Flag; using UpdateFlag = Notify::PeerUpdate::Flag;
@ -98,7 +49,7 @@ FixedBar::FixedBar(QWidget *parent, PeerData *peer) : TWidget(parent)
, _peerChat(peer->asChat()) , _peerChat(peer->asChat())
, _peerChannel(peer->asChannel()) , _peerChannel(peer->asChannel())
, _peerMegagroup(peer->isMegagroup() ? _peerChannel : nullptr) , _peerMegagroup(peer->isMegagroup() ? _peerChannel : nullptr)
, _backButton(this) { , _backButton(this, lang(lng_menu_back)) {
_backButton->moveToLeft(0, 0); _backButton->moveToLeft(0, 0);
connect(_backButton, SIGNAL(clicked()), this, SLOT(onBack())); connect(_backButton, SIGNAL(clicked()), this, SLOT(onBack()));

View File

@ -24,7 +24,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "styles/style_profile.h" #include "styles/style_profile.h"
#include "styles/style_window.h" #include "styles/style_window.h"
#include "profile/profile_cover.h" #include "profile/profile_cover.h"
#include "profile/profile_block_common_groups.h"
#include "profile/profile_block_info.h" #include "profile/profile_block_info.h"
#include "profile/profile_block_settings.h" #include "profile/profile_block_settings.h"
#include "profile/profile_block_invite_link.h" #include "profile/profile_block_invite_link.h"
@ -50,16 +49,7 @@ void InnerWidget::createBlocks() {
auto channel = _peer->asChannel(); auto channel = _peer->asChannel();
auto megagroup = _peer->isMegagroup() ? channel : nullptr; auto megagroup = _peer->isMegagroup() ? channel : nullptr;
if (user || channel || megagroup) { if (user || channel || megagroup) {
auto widget = new InfoWidget(this, _peer); _blocks.push_back({ new InfoWidget(this, _peer), BlockSide::Right });
widget->setShowCommonGroupsObservable(&_showCommonGroupsObservable);
_blocks.push_back({ widget, BlockSide::Right });
}
if (user) {
_commonGroupsWidget = new CommonGroupsWidget(this, _peer);
_commonGroupsWidget->setShowCommonGroupsObservable(&_showCommonGroupsObservable);
_blocks.push_back({ _commonGroupsWidget, BlockSide::Right });
} else {
_commonGroupsWidget = nullptr;
} }
_blocks.push_back({ new SettingsWidget(this, _peer), BlockSide::Right }); _blocks.push_back({ new SettingsWidget(this, _peer), BlockSide::Right });
if (chat || channel || megagroup) { if (chat || channel || megagroup) {

View File

@ -20,13 +20,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include "profile/profile_block_common_groups.h"
namespace Profile { namespace Profile {
class CoverWidget; class CoverWidget;
class BlockWidget; class BlockWidget;
struct CommonGroupsEvent;
class SectionMemento; class SectionMemento;
class InnerWidget final : public TWidget { class InnerWidget final : public TWidget {
@ -117,12 +114,8 @@ private:
}; };
QList<Block> _blocks; QList<Block> _blocks;
// We need to save this pointer for getting common groups list for section memento.
CommonGroupsWidget *_commonGroupsWidget = nullptr;
Mode _mode = Mode::OneColumn; Mode _mode = Mode::OneColumn;
base::Observable<CommonGroupsEvent> _showCommonGroupsObservable;
}; };
} // namespace Profile } // namespace Profile

View File

@ -42,17 +42,10 @@ public:
int getScrollTop() const { int getScrollTop() const {
return _scrollTop; return _scrollTop;
} }
void setCommonGroups(const QList<PeerData*> &groups) {
_commonGroups = groups;
}
const QList<PeerData*> &getCommonGroups() const {
return _commonGroups;
}
private: private:
PeerData *_peer; PeerData *_peer;
int _scrollTop = 0; int _scrollTop = 0;
QList<PeerData*> _commonGroups;
}; };

View File

@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mainwindow.h" #include "mainwindow.h"
#include "application.h" #include "application.h"
#include "ui/widgets/scroll_area.h" #include "ui/widgets/scroll_area.h"
#include "ui/widgets/shadow.h"
namespace Profile { namespace Profile {
@ -61,6 +62,10 @@ PeerData *Widget::peer() const {
return _inner->peer(); return _inner->peer();
} }
bool Widget::hasTopBarShadow() const {
return _fixedBarShadow->isFullyShown();
}
QPixmap Widget::grabForShowAnimation(const Window::SectionSlideParams &params) { QPixmap Widget::grabForShowAnimation(const Window::SectionSlideParams &params) {
if (params.withTopBarShadow) _fixedBarShadow->hide(); if (params.withTopBarShadow) _fixedBarShadow->hide();
auto result = myGrab(this); auto result = myGrab(this);

View File

@ -21,10 +21,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#pragma once #pragma once
#include "window/section_widget.h" #include "window/section_widget.h"
#include "ui/widgets/shadow.h"
namespace Ui { namespace Ui {
class ScrollArea; class ScrollArea;
class ToggleableShadow;
} // namespace Ui } // namespace Ui
namespace Profile { namespace Profile {
@ -43,9 +43,7 @@ public:
return peer(); return peer();
} }
bool hasTopBarShadow() const override { bool hasTopBarShadow() const override;
return _fixedBarShadow->isFullyShown();
}
QPixmap grabForShowAnimation(const Window::SectionSlideParams &params) override; QPixmap grabForShowAnimation(const Window::SectionSlideParams &params) override;

View File

@ -179,7 +179,7 @@ void CreateImplementationsMap() {
Implementations.createIfNull(); Implementations.createIfNull();
Type recordTypes[] = { Type recordTypes[] = {
Type::RecordVideo, Type::RecordVideo,
Type::RecordVoice Type::RecordVoice,
}; };
for_const (auto type, recordTypes) { for_const (auto type, recordTypes) {
Implementations->insert(type, &RecordAnimation::kMeta); Implementations->insert(type, &RecordAnimation::kMeta);
@ -188,7 +188,7 @@ void CreateImplementationsMap() {
Type::UploadFile, Type::UploadFile,
Type::UploadPhoto, Type::UploadPhoto,
Type::UploadVideo, Type::UploadVideo,
Type::UploadVoice Type::UploadVoice,
}; };
for_const (auto type, uploadTypes) { for_const (auto type, uploadTypes) {
Implementations->insert(type, &UploadAnimation::kMeta); Implementations->insert(type, &UploadAnimation::kMeta);

View File

@ -882,17 +882,17 @@ historySendActionTypingLargeNumerator: 28px;
historySendActionTypingSmallNumerator: 16px; historySendActionTypingSmallNumerator: 16px;
historySendActionTypingDenominator: 12.; historySendActionTypingDenominator: 12.;
historySendActionRecordDuration: 300; historySendActionRecordDuration: 500;
historySendActionRecordPosition: point(1px, -4px); historySendActionRecordPosition: point(1px, -4px);
historySendActionRecordDelta: 3px; historySendActionRecordDelta: 4px;
historySendActionRecordStrokeNumerator: 12px; historySendActionRecordStrokeNumerator: 16px;
historySendActionRecordDenominator: 8.; historySendActionRecordDenominator: 8.;
historySendActionUploadDuration: 500; historySendActionUploadDuration: 500;
historySendActionUploadPosition: point(0px, -4px); historySendActionUploadPosition: point(0px, -4px);
historySendActionUploadDelta: 5px; historySendActionUploadDelta: 5px;
historySendActionUploadStrokeNumerator: 12px; historySendActionUploadStrokeNumerator: 16px;
historySendActionUploadSizeNumerator: 28px; historySendActionUploadSizeNumerator: 32px;
historySendActionUploadDenominator: 8.; historySendActionUploadDenominator: 8.;
MediaPlayerButton { MediaPlayerButton {

View File

@ -3,4 +3,4 @@ AppVersionStrMajor 0.10
AppVersionStrSmall 0.10.20 AppVersionStrSmall 0.10.20
AppVersionStr 0.10.20 AppVersionStr 0.10.20
AlphaChannel 0 AlphaChannel 0
BetaVersion 10019012 BetaVersion 10019013

View File

@ -390,12 +390,12 @@
'<(src_loc)/platform/platform_main_window.h', '<(src_loc)/platform/platform_main_window.h',
'<(src_loc)/platform/platform_notifications_manager.h', '<(src_loc)/platform/platform_notifications_manager.h',
'<(src_loc)/platform/platform_window_title.h', '<(src_loc)/platform/platform_window_title.h',
'<(src_loc)/profile/profile_back_button.cpp',
'<(src_loc)/profile/profile_back_button.h',
'<(src_loc)/profile/profile_block_actions.cpp', '<(src_loc)/profile/profile_block_actions.cpp',
'<(src_loc)/profile/profile_block_actions.h', '<(src_loc)/profile/profile_block_actions.h',
'<(src_loc)/profile/profile_block_channel_members.cpp', '<(src_loc)/profile/profile_block_channel_members.cpp',
'<(src_loc)/profile/profile_block_channel_members.h', '<(src_loc)/profile/profile_block_channel_members.h',
'<(src_loc)/profile/profile_block_common_groups.cpp',
'<(src_loc)/profile/profile_block_common_groups.h',
'<(src_loc)/profile/profile_block_info.cpp', '<(src_loc)/profile/profile_block_info.cpp',
'<(src_loc)/profile/profile_block_info.h', '<(src_loc)/profile/profile_block_info.h',
'<(src_loc)/profile/profile_block_invite_link.cpp', '<(src_loc)/profile/profile_block_invite_link.cpp',
@ -410,6 +410,8 @@
'<(src_loc)/profile/profile_block_shared_media.h', '<(src_loc)/profile/profile_block_shared_media.h',
'<(src_loc)/profile/profile_block_widget.cpp', '<(src_loc)/profile/profile_block_widget.cpp',
'<(src_loc)/profile/profile_block_widget.h', '<(src_loc)/profile/profile_block_widget.h',
'<(src_loc)/profile/profile_common_groups_section.cpp',
'<(src_loc)/profile/profile_common_groups_section.h',
'<(src_loc)/profile/profile_cover_drop_area.cpp', '<(src_loc)/profile/profile_cover_drop_area.cpp',
'<(src_loc)/profile/profile_cover_drop_area.h', '<(src_loc)/profile/profile_cover_drop_area.h',
'<(src_loc)/profile/profile_cover.cpp', '<(src_loc)/profile/profile_cover.cpp',