mirror of https://github.com/procxx/kepka.git
voice messages moved to documents with waveforms
This commit is contained in:
parent
ffa588bf5d
commit
189d0e8de3
|
@ -1286,6 +1286,15 @@ msgFileRadialLine: 3px;
|
||||||
|
|
||||||
msgVideoSize: size(320px, 240px);
|
msgVideoSize: size(320px, 240px);
|
||||||
|
|
||||||
|
msgWaveformBar: 2px;
|
||||||
|
msgWaveformSkip: 1px;
|
||||||
|
msgWaveformMin: 2px;
|
||||||
|
msgWaveformMax: 20px;
|
||||||
|
msgWaveformInActive: #59b6eb;
|
||||||
|
msgWaveformInInactive: #deeaf1;
|
||||||
|
msgWaveformOutActive: #78c67f;
|
||||||
|
msgWaveformOutInactive: #c4e8c5;
|
||||||
|
|
||||||
sendPadding: 9px;
|
sendPadding: 9px;
|
||||||
btnSend: flatButton(btnDefFlat) {
|
btnSend: flatButton(btnDefFlat) {
|
||||||
color: btnYesColor;
|
color: btnYesColor;
|
||||||
|
@ -1386,7 +1395,7 @@ btnRecordAudio: sprite(379px, 390px, 16px, 24px);
|
||||||
btnRecordAudioActive: sprite(379px, 366px, 16px, 24px);
|
btnRecordAudioActive: sprite(379px, 366px, 16px, 24px);
|
||||||
recordSignalColor: #f17077;
|
recordSignalColor: #f17077;
|
||||||
recordSignalMin: 5px;
|
recordSignalMin: 5px;
|
||||||
recordSignalMax: 10px;
|
recordSignalMax: 12px;
|
||||||
recordCancel: #aaa;
|
recordCancel: #aaa;
|
||||||
recordCancelActive: #ec6466;
|
recordCancelActive: #ec6466;
|
||||||
recordFont: font(13px);
|
recordFont: font(13px);
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace {
|
||||||
|
|
||||||
PhotosData photosData;
|
PhotosData photosData;
|
||||||
VideosData videosData;
|
VideosData videosData;
|
||||||
AudiosData audiosData;
|
|
||||||
DocumentsData documentsData;
|
DocumentsData documentsData;
|
||||||
|
|
||||||
typedef QHash<QString, ImageLinkData*> ImageLinksData;
|
typedef QHash<QString, ImageLinkData*> ImageLinksData;
|
||||||
|
@ -65,7 +64,6 @@ namespace {
|
||||||
|
|
||||||
PhotoItems photoItems;
|
PhotoItems photoItems;
|
||||||
VideoItems videoItems;
|
VideoItems videoItems;
|
||||||
AudioItems audioItems;
|
|
||||||
DocumentItems documentItems;
|
DocumentItems documentItems;
|
||||||
WebPageItems webPageItems;
|
WebPageItems webPageItems;
|
||||||
SharedContactItems sharedContactItems;
|
SharedContactItems sharedContactItems;
|
||||||
|
@ -1293,22 +1291,6 @@ namespace App {
|
||||||
return App::videoSet(video.vid.v, convert, video.vaccess_hash.v, video.vdate.v, video.vduration.v, video.vw.v, video.vh.v, App::image(video.vthumb), video.vdc_id.v, video.vsize.v);
|
return App::videoSet(video.vid.v, convert, video.vaccess_hash.v, video.vdate.v, video.vduration.v, video.vw.v, video.vh.v, App::image(video.vthumb), video.vdc_id.v, video.vsize.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioData *feedAudio(const MTPaudio &audio, AudioData *convert) {
|
|
||||||
switch (audio.type()) {
|
|
||||||
case mtpc_audio: {
|
|
||||||
return feedAudio(audio.c_audio(), convert);
|
|
||||||
} break;
|
|
||||||
case mtpc_audioEmpty: {
|
|
||||||
return App::audioSet(audio.c_audioEmpty().vid.v, convert, 0, 0, QString(), 0, 0, 0);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
return App::audio(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioData *feedAudio(const MTPDaudio &audio, AudioData *convert) {
|
|
||||||
return App::audioSet(audio.vid.v, convert, audio.vaccess_hash.v, audio.vdate.v, qs(audio.vmime_type), audio.vduration.v, audio.vdc_id.v, audio.vsize.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) {
|
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) {
|
||||||
switch (document.type()) {
|
switch (document.type()) {
|
||||||
case mtpc_document: {
|
case mtpc_document: {
|
||||||
|
@ -1568,56 +1550,6 @@ namespace App {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioData *audio(const AudioId &audio) {
|
|
||||||
AudiosData::const_iterator i = ::audiosData.constFind(audio);
|
|
||||||
if (i == ::audiosData.cend()) {
|
|
||||||
i = ::audiosData.insert(audio, new AudioData(audio));
|
|
||||||
}
|
|
||||||
return i.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioData *audioSet(const AudioId &audio, AudioData *convert, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) {
|
|
||||||
if (convert) {
|
|
||||||
if (convert->id != audio) {
|
|
||||||
AudiosData::iterator i = ::audiosData.find(convert->id);
|
|
||||||
if (i != ::audiosData.cend() && i.value() == convert) {
|
|
||||||
::audiosData.erase(i);
|
|
||||||
}
|
|
||||||
convert->id = audio;
|
|
||||||
convert->status = FileReady;
|
|
||||||
}
|
|
||||||
if (date) {
|
|
||||||
convert->access = access;
|
|
||||||
convert->date = date;
|
|
||||||
convert->mime = mime;
|
|
||||||
convert->duration = duration;
|
|
||||||
convert->dc = dc;
|
|
||||||
convert->size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AudiosData::const_iterator i = ::audiosData.constFind(audio);
|
|
||||||
AudioData *result;
|
|
||||||
if (i == ::audiosData.cend()) {
|
|
||||||
if (convert) {
|
|
||||||
result = convert;
|
|
||||||
} else {
|
|
||||||
result = new AudioData(audio, access, date, mime, duration, dc, size);
|
|
||||||
}
|
|
||||||
::audiosData.insert(audio, result);
|
|
||||||
} else {
|
|
||||||
result = i.value();
|
|
||||||
if (result != convert && date) {
|
|
||||||
result->access = access;
|
|
||||||
result->date = date;
|
|
||||||
result->mime = mime;
|
|
||||||
result->duration = duration;
|
|
||||||
result->dc = dc;
|
|
||||||
result->size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentData *document(const DocumentId &document) {
|
DocumentData *document(const DocumentId &document) {
|
||||||
DocumentsData::const_iterator i = ::documentsData.constFind(document);
|
DocumentsData::const_iterator i = ::documentsData.constFind(document);
|
||||||
if (i == ::documentsData.cend()) {
|
if (i == ::documentsData.cend()) {
|
||||||
|
@ -1795,9 +1727,6 @@ namespace App {
|
||||||
for (VideosData::const_iterator i = ::videosData.cbegin(), e = ::videosData.cend(); i != e; ++i) {
|
for (VideosData::const_iterator i = ::videosData.cbegin(), e = ::videosData.cend(); i != e; ++i) {
|
||||||
i.value()->forget();
|
i.value()->forget();
|
||||||
}
|
}
|
||||||
for (AudiosData::const_iterator i = ::audiosData.cbegin(), e = ::audiosData.cend(); i != e; ++i) {
|
|
||||||
i.value()->forget();
|
|
||||||
}
|
|
||||||
for (DocumentsData::const_iterator i = ::documentsData.cbegin(), e = ::documentsData.cend(); i != e; ++i) {
|
for (DocumentsData::const_iterator i = ::documentsData.cbegin(), e = ::documentsData.cend(); i != e; ++i) {
|
||||||
i.value()->forget();
|
i.value()->forget();
|
||||||
}
|
}
|
||||||
|
@ -1955,10 +1884,6 @@ namespace App {
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
::videosData.clear();
|
::videosData.clear();
|
||||||
for (AudiosData::const_iterator i = ::audiosData.cbegin(), e = ::audiosData.cend(); i != e; ++i) {
|
|
||||||
delete *i;
|
|
||||||
}
|
|
||||||
::audiosData.clear();
|
|
||||||
for (DocumentsData::const_iterator i = ::documentsData.cbegin(), e = ::documentsData.cend(); i != e; ++i) {
|
for (DocumentsData::const_iterator i = ::documentsData.cbegin(), e = ::documentsData.cend(); i != e; ++i) {
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
@ -1977,7 +1902,6 @@ namespace App {
|
||||||
cSetReportSpamStatuses(ReportSpamStatuses());
|
cSetReportSpamStatuses(ReportSpamStatuses());
|
||||||
::photoItems.clear();
|
::photoItems.clear();
|
||||||
::videoItems.clear();
|
::videoItems.clear();
|
||||||
::audioItems.clear();
|
|
||||||
::documentItems.clear();
|
::documentItems.clear();
|
||||||
::webPageItems.clear();
|
::webPageItems.clear();
|
||||||
::sharedContactItems.clear();
|
::sharedContactItems.clear();
|
||||||
|
@ -2392,22 +2316,6 @@ namespace App {
|
||||||
return ::videosData;
|
return ::videosData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void regAudioItem(AudioData *data, HistoryItem *item) {
|
|
||||||
::audioItems[data].insert(item, NullType());
|
|
||||||
}
|
|
||||||
|
|
||||||
void unregAudioItem(AudioData*data, HistoryItem *item) {
|
|
||||||
::audioItems[data].remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
const AudioItems &audioItems() {
|
|
||||||
return ::audioItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
const AudiosData &audiosData() {
|
|
||||||
return ::audiosData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void regDocumentItem(DocumentData *data, HistoryItem *item) {
|
void regDocumentItem(DocumentData *data, HistoryItem *item) {
|
||||||
::documentItems[data].insert(item, NullType());
|
::documentItems[data].insert(item, NullType());
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ class FileUploader;
|
||||||
typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
|
typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
|
||||||
typedef QHash<PhotoData*, HistoryItemsMap> PhotoItems;
|
typedef QHash<PhotoData*, HistoryItemsMap> PhotoItems;
|
||||||
typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
|
typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
|
||||||
typedef QHash<AudioData*, HistoryItemsMap> AudioItems;
|
|
||||||
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
|
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
|
||||||
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
|
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
|
||||||
typedef QHash<int32, HistoryItemsMap> SharedContactItems;
|
typedef QHash<int32, HistoryItemsMap> SharedContactItems;
|
||||||
|
@ -45,7 +44,6 @@ typedef QHash<ClipReader*, HistoryItem*> GifItems;
|
||||||
|
|
||||||
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
typedef QHash<PhotoId, PhotoData*> PhotosData;
|
||||||
typedef QHash<VideoId, VideoData*> VideosData;
|
typedef QHash<VideoId, VideoData*> VideosData;
|
||||||
typedef QHash<AudioId, AudioData*> AudiosData;
|
|
||||||
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
||||||
|
|
||||||
struct ReplyMarkup {
|
struct ReplyMarkup {
|
||||||
|
@ -107,8 +105,6 @@ namespace App {
|
||||||
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = 0);
|
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = 0);
|
||||||
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = 0);
|
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = 0);
|
||||||
VideoData *feedVideo(const MTPDvideo &video, VideoData *convert = 0);
|
VideoData *feedVideo(const MTPDvideo &video, VideoData *convert = 0);
|
||||||
AudioData *feedAudio(const MTPaudio &audio, AudioData *convert = 0);
|
|
||||||
AudioData *feedAudio(const MTPDaudio &audio, AudioData *convert = 0);
|
|
||||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
||||||
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = 0);
|
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = 0);
|
||||||
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = 0);
|
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = 0);
|
||||||
|
@ -138,8 +134,6 @@ namespace App {
|
||||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
||||||
VideoData *video(const VideoId &video);
|
VideoData *video(const VideoId &video);
|
||||||
VideoData *videoSet(const VideoId &video, VideoData *convert, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size);
|
VideoData *videoSet(const VideoId &video, VideoData *convert, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size);
|
||||||
AudioData *audio(const AudioId &audio);
|
|
||||||
AudioData *audioSet(const AudioId &audio, AudioData *convert, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size);
|
|
||||||
DocumentData *document(const DocumentId &document);
|
DocumentData *document(const DocumentId &document);
|
||||||
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
||||||
WebPageData *webPage(const WebPageId &webPage);
|
WebPageData *webPage(const WebPageId &webPage);
|
||||||
|
@ -219,11 +213,6 @@ namespace App {
|
||||||
const VideoItems &videoItems();
|
const VideoItems &videoItems();
|
||||||
const VideosData &videosData();
|
const VideosData &videosData();
|
||||||
|
|
||||||
void regAudioItem(AudioData *data, HistoryItem *item);
|
|
||||||
void unregAudioItem(AudioData*data, HistoryItem *item);
|
|
||||||
const AudioItems &audioItems();
|
|
||||||
const AudiosData &audiosData();
|
|
||||||
|
|
||||||
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
||||||
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
||||||
const DocumentItems &documentItems();
|
const DocumentItems &documentItems();
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ void AppClass::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId) {
|
||||||
int32 filesize = 0;
|
int32 filesize = 0;
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
|
||||||
ReadyLocalMedia ready(PreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, MTP_audioEmpty(MTP_long(0)), photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, false, 0);
|
ReadyLocalMedia ready(PreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, false, 0);
|
||||||
|
|
||||||
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), App::app(), SLOT(photoUpdated(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), App::app(), SLOT(photoUpdated(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -56,7 +56,7 @@ public:
|
||||||
void play(const AudioMsgId &audio, int64 position = 0);
|
void play(const AudioMsgId &audio, int64 position = 0);
|
||||||
void play(const SongMsgId &song, int64 position = 0);
|
void play(const SongMsgId &song, int64 position = 0);
|
||||||
void pauseresume(MediaOverviewType type, bool fast = false);
|
void pauseresume(MediaOverviewType type, bool fast = false);
|
||||||
void seek(int64 position); // type == OverviewDocuments
|
void seek(int64 position); // type == OverviewFiles
|
||||||
void stop(MediaOverviewType type);
|
void stop(MediaOverviewType type);
|
||||||
|
|
||||||
void stopAndClear();
|
void stopAndClear();
|
||||||
|
@ -201,8 +201,8 @@ signals:
|
||||||
void captureOnStart();
|
void captureOnStart();
|
||||||
void captureOnStop(bool needResult);
|
void captureOnStop(bool needResult);
|
||||||
|
|
||||||
void onDone(QByteArray data, qint32 samples);
|
void onDone(QByteArray data, VoiceWaveform waveform, qint32 samples);
|
||||||
void onUpdate(qint16 level, qint32 samples);
|
void onUpdate(quint16 level, qint32 samples);
|
||||||
void onError();
|
void onError();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -338,8 +338,8 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void error();
|
void error();
|
||||||
void update(qint16 level, qint32 samples);
|
void update(quint16 level, qint32 samples);
|
||||||
void done(QByteArray data, qint32 samples);
|
void done(QByteArray data, VoiceWaveform waveform, qint32 samples);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -360,3 +360,4 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat);
|
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat);
|
||||||
|
VoiceWaveform audioCountWaveform(const FileLocation &file, const QByteArray &data);
|
||||||
|
|
|
@ -313,11 +313,13 @@ void AutoDownloadBox::onSave() {
|
||||||
bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups));
|
bool enabledGroups = ((cAutoDownloadAudio() & dbiadNoGroups) && !(autoDownloadAudio & dbiadNoGroups));
|
||||||
cSetAutoDownloadAudio(autoDownloadAudio);
|
cSetAutoDownloadAudio(autoDownloadAudio);
|
||||||
if (enabledPrivate || enabledGroups) {
|
if (enabledPrivate || enabledGroups) {
|
||||||
const AudiosData &data(App::audiosData());
|
const DocumentsData &data(App::documentsData());
|
||||||
for (AudiosData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||||
|
if (i.value()->voice()) {
|
||||||
i.value()->automaticLoadSettingsChanged();
|
i.value()->automaticLoadSettingsChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
int32 autoDownloadGif = (_gifPrivate.checked() ? 0 : dbiadNoPrivate) | (_gifGroups.checked() ? 0 : dbiadNoGroups);
|
int32 autoDownloadGif = (_gifPrivate.checked() ? 0 : dbiadNoPrivate) | (_gifGroups.checked() ? 0 : dbiadNoGroups);
|
||||||
|
@ -328,8 +330,10 @@ void AutoDownloadBox::onSave() {
|
||||||
if (enabledPrivate || enabledGroups) {
|
if (enabledPrivate || enabledGroups) {
|
||||||
const DocumentsData &data(App::documentsData());
|
const DocumentsData &data(App::documentsData());
|
||||||
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||||
|
if (i.value()->isAnimation()) {
|
||||||
i.value()->automaticLoadSettingsChanged();
|
i.value()->automaticLoadSettingsChanged();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Notify::automaticLoadSettingsChangedGif();
|
Notify::automaticLoadSettingsChangedGif();
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
|
@ -118,6 +118,8 @@ enum {
|
||||||
AudioVoiceMsgInMemory = 2 * 1024 * 1024, // 2 Mb audio is hold in memory and auto loaded
|
AudioVoiceMsgInMemory = 2 * 1024 * 1024, // 2 Mb audio is hold in memory and auto loaded
|
||||||
AudioPauseDeviceTimeout = 3000, // pause in 3 secs after playing is over
|
AudioPauseDeviceTimeout = 3000, // pause in 3 secs after playing is over
|
||||||
|
|
||||||
|
WaveformSamplesCount = 100,
|
||||||
|
|
||||||
StickerInMemory = 2 * 1024 * 1024, // 2 Mb stickers hold in memory, auto loaded and displayed inline
|
StickerInMemory = 2 * 1024 * 1024, // 2 Mb stickers hold in memory, auto loaded and displayed inline
|
||||||
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
StickerMaxSize = 2048, // 2048x2048 is a max image size for sticker
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ FileUploader::FileUploader() : sentSize(0) {
|
||||||
void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &media) {
|
void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &media) {
|
||||||
if (media.type == PreparePhoto) {
|
if (media.type == PreparePhoto) {
|
||||||
App::feedPhoto(media.photo, media.photoThumbs);
|
App::feedPhoto(media.photo, media.photoThumbs);
|
||||||
} else if (media.type == PrepareDocument) {
|
} else if (media.type == PrepareDocument || media.type == PrepareAudio) {
|
||||||
DocumentData *document;
|
DocumentData *document;
|
||||||
if (media.photoThumbs.isEmpty()) {
|
if (media.photoThumbs.isEmpty()) {
|
||||||
document = App::feedDocument(media.document);
|
document = App::feedDocument(media.document);
|
||||||
|
@ -40,13 +40,12 @@ void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &me
|
||||||
document = App::feedDocument(media.document, media.photoThumbs.begin().value());
|
document = App::feedDocument(media.document, media.photoThumbs.begin().value());
|
||||||
}
|
}
|
||||||
document->status = FileUploading;
|
document->status = FileUploading;
|
||||||
|
if (!media.data.isEmpty()) {
|
||||||
|
document->setData(media.data);
|
||||||
|
}
|
||||||
if (!media.file.isEmpty()) {
|
if (!media.file.isEmpty()) {
|
||||||
document->setLocation(FileLocation(StorageFilePartial, media.file));
|
document->setLocation(FileLocation(StorageFilePartial, media.file));
|
||||||
}
|
}
|
||||||
} else if (media.type == PrepareAudio) {
|
|
||||||
AudioData *audio = App::feedAudio(media.audio);
|
|
||||||
audio->status = FileUploading;
|
|
||||||
audio->setData(media.data);
|
|
||||||
}
|
}
|
||||||
queue.insert(msgId, File(media));
|
queue.insert(msgId, File(media));
|
||||||
sendNext();
|
sendNext();
|
||||||
|
@ -56,7 +55,7 @@ void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file)
|
||||||
if (file->type == PreparePhoto) {
|
if (file->type == PreparePhoto) {
|
||||||
PhotoData *photo = App::feedPhoto(file->photo, file->photoThumbs);
|
PhotoData *photo = App::feedPhoto(file->photo, file->photoThumbs);
|
||||||
photo->uploadingData = new PhotoData::UploadingData(file->partssize);
|
photo->uploadingData = new PhotoData::UploadingData(file->partssize);
|
||||||
} else if (file->type == PrepareDocument) {
|
} else if (file->type == PrepareDocument || file->type == PrepareAudio) {
|
||||||
DocumentData *document;
|
DocumentData *document;
|
||||||
if (file->thumb.isNull()) {
|
if (file->thumb.isNull()) {
|
||||||
document = App::feedDocument(file->document);
|
document = App::feedDocument(file->document);
|
||||||
|
@ -64,13 +63,12 @@ void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file)
|
||||||
document = App::feedDocument(file->document, file->thumb);
|
document = App::feedDocument(file->document, file->thumb);
|
||||||
}
|
}
|
||||||
document->status = FileUploading;
|
document->status = FileUploading;
|
||||||
|
if (!file->content.isEmpty()) {
|
||||||
|
document->setData(file->content);
|
||||||
|
}
|
||||||
if (!file->filepath.isEmpty()) {
|
if (!file->filepath.isEmpty()) {
|
||||||
document->setLocation(FileLocation(StorageFilePartial, file->filepath));
|
document->setLocation(FileLocation(StorageFilePartial, file->filepath));
|
||||||
}
|
}
|
||||||
} else if (file->type == PrepareAudio) {
|
|
||||||
AudioData *audio = App::feedAudio(file->audio);
|
|
||||||
audio->status = FileUploading;
|
|
||||||
audio->setData(file->content);
|
|
||||||
}
|
}
|
||||||
queue.insert(msgId, File(file));
|
queue.insert(msgId, File(file));
|
||||||
sendNext();
|
sendNext();
|
||||||
|
@ -87,12 +85,6 @@ void FileUploader::currentFailed() {
|
||||||
doc->status = FileUploadFailed;
|
doc->status = FileUploadFailed;
|
||||||
}
|
}
|
||||||
emit documentFailed(j.key());
|
emit documentFailed(j.key());
|
||||||
} else if (j->type() == PrepareAudio) {
|
|
||||||
AudioData *audio = App::audio(j->id());
|
|
||||||
if (audio->status == FileUploading) {
|
|
||||||
audio->status = FileUploadFailed;
|
|
||||||
}
|
|
||||||
emit audioFailed(j.key());
|
|
||||||
}
|
}
|
||||||
queue.erase(j);
|
queue.erase(j);
|
||||||
}
|
}
|
||||||
|
@ -150,7 +142,7 @@ void FileUploader::sendNext() {
|
||||||
if (requestsSent.isEmpty() && docRequestsSent.isEmpty()) {
|
if (requestsSent.isEmpty() && docRequestsSent.isEmpty()) {
|
||||||
if (i->type() == PreparePhoto) {
|
if (i->type() == PreparePhoto) {
|
||||||
emit photoReady(uploading, MTP_inputFile(MTP_long(i->id()), MTP_int(i->partsCount), MTP_string(i->filename()), MTP_string(i->file ? i->file->filemd5 : i->media.jpeg_md5)));
|
emit photoReady(uploading, MTP_inputFile(MTP_long(i->id()), MTP_int(i->partsCount), MTP_string(i->filename()), MTP_string(i->file ? i->file->filemd5 : i->media.jpeg_md5)));
|
||||||
} else if (i->type() == PrepareDocument) {
|
} else if (i->type() == PrepareDocument || i->type() == PrepareAudio) {
|
||||||
QByteArray docMd5(32, Qt::Uninitialized);
|
QByteArray docMd5(32, Qt::Uninitialized);
|
||||||
hashMd5Hex(i->md5Hash.result(), docMd5.data());
|
hashMd5Hex(i->md5Hash.result(), docMd5.data());
|
||||||
|
|
||||||
|
@ -160,12 +152,6 @@ void FileUploader::sendNext() {
|
||||||
} else {
|
} else {
|
||||||
emit documentReady(uploading, doc);
|
emit documentReady(uploading, doc);
|
||||||
}
|
}
|
||||||
} else if (i->type() == PrepareAudio) {
|
|
||||||
QByteArray audioMd5(32, Qt::Uninitialized);
|
|
||||||
hashMd5Hex(i->md5Hash.result(), audioMd5.data());
|
|
||||||
|
|
||||||
MTPInputFile audio = (i->docSize > UseBigFilesFrom) ? MTP_inputFileBig(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename())) : MTP_inputFile(MTP_long(i->id()), MTP_int(i->docPartsCount), MTP_string(i->filename()), MTP_string(audioMd5));
|
|
||||||
emit audioReady(uploading, audio);
|
|
||||||
}
|
}
|
||||||
queue.remove(uploading);
|
queue.remove(uploading);
|
||||||
uploading = FullMsgId();
|
uploading = FullMsgId();
|
||||||
|
@ -303,7 +289,7 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||||
photo->uploadingData->offset = k->fileSentSize;
|
photo->uploadingData->offset = k->fileSentSize;
|
||||||
}
|
}
|
||||||
emit photoProgress(k.key());
|
emit photoProgress(k.key());
|
||||||
} else if (k->type() == PrepareDocument) {
|
} else if (k->type() == PrepareDocument || k->type() == PrepareAudio) {
|
||||||
DocumentData *doc = App::document(k->id());
|
DocumentData *doc = App::document(k->id());
|
||||||
if (doc->uploading()) {
|
if (doc->uploading()) {
|
||||||
doc->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize;
|
doc->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize;
|
||||||
|
@ -312,15 +298,6 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit documentProgress(k.key());
|
emit documentProgress(k.key());
|
||||||
} else if (k->type() == PrepareAudio) {
|
|
||||||
AudioData *audio = App::audio(k->id());
|
|
||||||
if (audio->uploading()) {
|
|
||||||
audio->uploadOffset = (k->docSentParts - docRequestsSent.size()) * k->docPartSize;
|
|
||||||
if (audio->uploadOffset > audio->size) {
|
|
||||||
audio->uploadOffset = audio->size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit audioProgress(k.key());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,15 +51,12 @@ signals:
|
||||||
void photoReady(const FullMsgId &msgId, const MTPInputFile &file);
|
void photoReady(const FullMsgId &msgId, const MTPInputFile &file);
|
||||||
void documentReady(const FullMsgId &msgId, const MTPInputFile &file);
|
void documentReady(const FullMsgId &msgId, const MTPInputFile &file);
|
||||||
void thumbDocumentReady(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
|
void thumbDocumentReady(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
|
||||||
void audioReady(const FullMsgId &msgId, const MTPInputFile &file);
|
|
||||||
|
|
||||||
void photoProgress(const FullMsgId &msgId);
|
void photoProgress(const FullMsgId &msgId);
|
||||||
void documentProgress(const FullMsgId &msgId);
|
void documentProgress(const FullMsgId &msgId);
|
||||||
void audioProgress(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
void photoFailed(const FullMsgId &msgId);
|
void photoFailed(const FullMsgId &msgId);
|
||||||
void documentFailed(const FullMsgId &msgId);
|
void documentFailed(const FullMsgId &msgId);
|
||||||
void audioFailed(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -352,8 +352,8 @@ bool History::updateTyping(uint64 ms, bool force) {
|
||||||
switch (sendActions.begin().value().type) {
|
switch (sendActions.begin().value().type) {
|
||||||
case SendActionRecordVideo: newTypingStr = peer->isUser() ? lang(lng_send_action_record_video) : lng_user_action_record_video(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionRecordVideo: newTypingStr = peer->isUser() ? lang(lng_send_action_record_video) : lng_user_action_record_video(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
case SendActionUploadVideo: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_video) : lng_user_action_upload_video(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionUploadVideo: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_video) : lng_user_action_upload_video(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
case SendActionRecordAudio: newTypingStr = peer->isUser() ? lang(lng_send_action_record_audio) : lng_user_action_record_audio(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionRecordVoice: newTypingStr = peer->isUser() ? lang(lng_send_action_record_audio) : lng_user_action_record_audio(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
case SendActionUploadAudio: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_audio) : lng_user_action_upload_audio(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionUploadVoice: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_audio) : lng_user_action_upload_audio(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
case SendActionUploadPhoto: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_photo) : lng_user_action_upload_photo(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionUploadPhoto: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_photo) : lng_user_action_upload_photo(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
case SendActionUploadFile: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_file) : lng_user_action_upload_file(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionUploadFile: newTypingStr = peer->isUser() ? lang(lng_send_action_upload_file) : lng_user_action_upload_file(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
case SendActionChooseLocation: newTypingStr = peer->isUser() ? lang(lng_send_action_geo_location) : lng_user_action_geo_location(lt_user, sendActions.begin().key()->firstName); break;
|
case SendActionChooseLocation: newTypingStr = peer->isUser() ? lang(lng_send_action_geo_location) : lng_user_action_geo_location(lt_user, sendActions.begin().key()->firstName); break;
|
||||||
|
@ -1249,8 +1249,8 @@ void Histories::regSendAction(History *history, UserData *user, const MTPSendMes
|
||||||
case mtpc_sendMessageTypingAction: history->typing[user] = ms + 6000; break;
|
case mtpc_sendMessageTypingAction: history->typing[user] = ms + 6000; break;
|
||||||
case mtpc_sendMessageRecordVideoAction: history->sendActions.insert(user, SendAction(SendActionRecordVideo, ms + 6000)); break;
|
case mtpc_sendMessageRecordVideoAction: history->sendActions.insert(user, SendAction(SendActionRecordVideo, ms + 6000)); break;
|
||||||
case mtpc_sendMessageUploadVideoAction: history->sendActions.insert(user, SendAction(SendActionUploadVideo, ms + 6000, action.c_sendMessageUploadVideoAction().vprogress.v)); break;
|
case mtpc_sendMessageUploadVideoAction: history->sendActions.insert(user, SendAction(SendActionUploadVideo, ms + 6000, action.c_sendMessageUploadVideoAction().vprogress.v)); break;
|
||||||
case mtpc_sendMessageRecordAudioAction: history->sendActions.insert(user, SendAction(SendActionRecordAudio, ms + 6000)); break;
|
case mtpc_sendMessageRecordAudioAction: history->sendActions.insert(user, SendAction(SendActionRecordVoice, ms + 6000)); break;
|
||||||
case mtpc_sendMessageUploadAudioAction: history->sendActions.insert(user, SendAction(SendActionUploadAudio, ms + 6000, action.c_sendMessageUploadAudioAction().vprogress.v)); break;
|
case mtpc_sendMessageUploadAudioAction: history->sendActions.insert(user, SendAction(SendActionUploadVoice, ms + 6000, action.c_sendMessageUploadAudioAction().vprogress.v)); break;
|
||||||
case mtpc_sendMessageUploadPhotoAction: history->sendActions.insert(user, SendAction(SendActionUploadPhoto, ms + 6000, action.c_sendMessageUploadPhotoAction().vprogress.v)); break;
|
case mtpc_sendMessageUploadPhotoAction: history->sendActions.insert(user, SendAction(SendActionUploadPhoto, ms + 6000, action.c_sendMessageUploadPhotoAction().vprogress.v)); break;
|
||||||
case mtpc_sendMessageUploadDocumentAction: history->sendActions.insert(user, SendAction(SendActionUploadFile, ms + 6000, action.c_sendMessageUploadDocumentAction().vprogress.v)); break;
|
case mtpc_sendMessageUploadDocumentAction: history->sendActions.insert(user, SendAction(SendActionUploadFile, ms + 6000, action.c_sendMessageUploadDocumentAction().vprogress.v)); break;
|
||||||
case mtpc_sendMessageGeoLocationAction: history->sendActions.insert(user, SendAction(SendActionChooseLocation, ms + 6000)); break;
|
case mtpc_sendMessageGeoLocationAction: history->sendActions.insert(user, SendAction(SendActionChooseLocation, ms + 6000)); break;
|
||||||
|
@ -1369,13 +1369,6 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
default: badMedia = 1; break;
|
default: badMedia = 1; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mtpc_messageMediaAudio:
|
|
||||||
switch (m.vmedia.c_messageMediaAudio().vaudio.type()) {
|
|
||||||
case mtpc_audio: break;
|
|
||||||
case mtpc_audioEmpty: badMedia = 2; break;
|
|
||||||
default: badMedia = 1; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case mtpc_messageMediaDocument:
|
case mtpc_messageMediaDocument:
|
||||||
switch (m.vmedia.c_messageMediaDocument().vdocument.type()) {
|
switch (m.vmedia.c_messageMediaDocument().vdocument.type()) {
|
||||||
case mtpc_document: break;
|
case mtpc_document: break;
|
||||||
|
@ -3060,18 +3053,14 @@ namespace {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 audioMaxStatusWidth(AudioData *audio) {
|
|
||||||
int32 result = st::normalFont->width(formatDownloadText(audio->size, audio->size));
|
|
||||||
result = qMax(result, st::normalFont->width(formatPlayedText(audio->duration, audio->duration)));
|
|
||||||
result = qMax(result, st::normalFont->width(formatDurationAndSizeText(audio->duration, audio->size)));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 documentMaxStatusWidth(DocumentData *document) {
|
int32 documentMaxStatusWidth(DocumentData *document) {
|
||||||
int32 result = st::normalFont->width(formatDownloadText(document->size, document->size));
|
int32 result = st::normalFont->width(formatDownloadText(document->size, document->size));
|
||||||
if (SongData *song = document->song()) {
|
if (SongData *song = document->song()) {
|
||||||
result = qMax(result, st::normalFont->width(formatPlayedText(song->duration, song->duration)));
|
result = qMax(result, st::normalFont->width(formatPlayedText(song->duration, song->duration)));
|
||||||
result = qMax(result, st::normalFont->width(formatDurationAndSizeText(song->duration, document->size)));
|
result = qMax(result, st::normalFont->width(formatDurationAndSizeText(song->duration, document->size)));
|
||||||
|
} else if (VoiceData *voice = document->voice()) {
|
||||||
|
result = qMax(result, st::normalFont->width(formatPlayedText(voice->duration, voice->duration)));
|
||||||
|
result = qMax(result, st::normalFont->width(formatDurationAndSizeText(voice->duration, document->size)));
|
||||||
} else {
|
} else {
|
||||||
result = qMax(result, st::normalFont->width(formatSizeText(document->size)));
|
result = qMax(result, st::normalFont->width(formatSizeText(document->size)));
|
||||||
}
|
}
|
||||||
|
@ -3785,291 +3774,151 @@ ImagePtr HistoryVideo::replyPreview() {
|
||||||
return _data->replyPreview;
|
return _data->replyPreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryAudio::HistoryAudio(const MTPDaudio &audio) : HistoryFileMedia()
|
HistoryDocumentVoicePlayback::HistoryDocumentVoicePlayback(const HistoryDocument *that)
|
||||||
, _data(App::feedAudio(audio)) {
|
: _position(0)
|
||||||
setLinks(new AudioOpenLink(_data), new AudioOpenLink(_data), new AudioCancelLink(_data));
|
, a_progress(0., 0.)
|
||||||
|
, _a_progress(animation(const_cast<HistoryDocument*>(that), &HistoryDocument::step_voiceProgress)) {
|
||||||
setStatusSize(FileStatusSizeReady);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryAudio::HistoryAudio(const HistoryAudio &other) : HistoryFileMedia()
|
void HistoryDocumentVoice::ensurePlayback(const HistoryDocument *that) const {
|
||||||
, _data(other._data) {
|
if (!_playback) {
|
||||||
setLinks(new AudioOpenLink(_data), new AudioOpenLink(_data), new AudioCancelLink(_data));
|
_playback = new HistoryDocumentVoicePlayback(that);
|
||||||
|
|
||||||
setStatusSize(other._statusSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::initDimensions(const HistoryItem *parent) {
|
|
||||||
_maxw = st::msgFileMinWidth;
|
|
||||||
|
|
||||||
int32 tleft = 0, tright = 0;
|
|
||||||
|
|
||||||
tleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
|
||||||
tright = st::msgFileThumbPadding.left();
|
|
||||||
_maxw = qMax(_maxw, tleft + audioMaxStatusWidth(_data) + int(st::mediaUnreadSkip + st::mediaUnreadSize) + parent->skipBlockWidth() + st::msgPadding.right());
|
|
||||||
|
|
||||||
_maxw = qMax(tleft + st::semiboldFont->width(lang(lng_media_audio)) + tright, _maxw);
|
|
||||||
_maxw = qMin(_maxw, int(st::msgMaxWidth));
|
|
||||||
|
|
||||||
_height = _minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const {
|
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
|
||||||
|
|
||||||
_data->automaticLoad(parent);
|
|
||||||
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
|
||||||
|
|
||||||
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
|
|
||||||
|
|
||||||
if (displayLoading) {
|
|
||||||
ensureAnimation(parent);
|
|
||||||
if (!_animation->radial.animating()) {
|
|
||||||
_animation->radial.start(_data->progress());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool showPause = updateStatusText(parent);
|
|
||||||
bool radial = isRadialAnimation(ms);
|
|
||||||
|
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
|
||||||
|
|
||||||
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
|
||||||
nametop = st::msgFileNameTop;
|
|
||||||
nameright = st::msgFilePadding.left();
|
|
||||||
statustop = st::msgFileStatusTop;
|
|
||||||
|
|
||||||
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
if (selected) {
|
|
||||||
p.setBrush(outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected);
|
|
||||||
} else if (isThumbAnimation(ms)) {
|
|
||||||
float64 over = _animation->a_thumbOver.current();
|
|
||||||
p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over));
|
|
||||||
} else {
|
|
||||||
bool over = textlnkDrawOver(_data->loading() ? _cancell : _savel);
|
|
||||||
p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg));
|
|
||||||
}
|
|
||||||
|
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
|
||||||
p.drawEllipse(inner);
|
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
|
||||||
|
|
||||||
if (radial) {
|
|
||||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
|
||||||
style::color bg(outbg ? (selected ? st::msgOutBgSelected : st::msgOutBg) : (selected ? st::msgInBgSelected : st::msgInBg));
|
|
||||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
style::sprite icon;
|
|
||||||
if (showPause) {
|
|
||||||
icon = outbg ? (selected ? st::msgFileOutPauseSelected : st::msgFileOutPause) : (selected ? st::msgFileInPauseSelected : st::msgFileInPause);
|
|
||||||
} else if (radial || _data->loading()) {
|
|
||||||
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
|
||||||
} else if (loaded) {
|
|
||||||
icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
|
|
||||||
} else {
|
|
||||||
icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
|
|
||||||
}
|
|
||||||
p.drawSpriteCenter(inner, icon);
|
|
||||||
|
|
||||||
int32 namewidth = _width - nameleft - nameright;
|
|
||||||
|
|
||||||
p.setFont(st::semiboldFont);
|
|
||||||
p.setPen(st::black);
|
|
||||||
p.drawTextLeft(nameleft, nametop, _width, lang(lng_media_audio));
|
|
||||||
|
|
||||||
style::color status(outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg));
|
|
||||||
p.setFont(st::normalFont);
|
|
||||||
p.setPen(status);
|
|
||||||
p.drawTextLeft(nameleft, statustop, _width, _statusText);
|
|
||||||
|
|
||||||
if (parent->isMediaUnread()) {
|
|
||||||
int32 w = st::normalFont->width(_statusText);
|
|
||||||
if (w + st::mediaUnreadSkip + st::mediaUnreadSize <= namewidth) {
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
p.setBrush(outbg ? (selected ? st::msgFileOutBgSelected : st::msgFileOutBg) : (selected ? st::msgFileInBgSelected : st::msgFileInBg));
|
|
||||||
|
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
|
||||||
p.drawEllipse(rtlrect(nameleft + w + st::mediaUnreadSkip, statustop + st::mediaUnreadTop, st::mediaUnreadSize, st::mediaUnreadSize, _width));
|
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const {
|
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
|
||||||
|
|
||||||
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
|
|
||||||
bool loaded = _data->loaded();
|
|
||||||
|
|
||||||
bool showPause = updateStatusText(parent);
|
|
||||||
|
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
|
||||||
|
|
||||||
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
|
|
||||||
if ((_data->loading() || _data->status == FileUploading || !loaded) && inner.contains(x, y)) {
|
|
||||||
lnk = (_data->loading() || _data->status == FileUploading) ? _cancell : _savel;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x >= 0 && y >= 0 && x < _width && y < _height && _data->access && !_data->loading()) {
|
|
||||||
lnk = _openl;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString HistoryAudio::inDialogsText() const {
|
void HistoryDocumentVoice::checkPlaybackFinished() const {
|
||||||
return lang(lng_in_dlg_audio);
|
if (_playback && !_playback->_a_progress.animating()) {
|
||||||
|
delete _playback;
|
||||||
|
_playback = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString HistoryAudio::inHistoryText() const {
|
|
||||||
return qsl("[ ") + lang(lng_in_dlg_audio) + qsl(" ]");
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::regItem(HistoryItem *item) {
|
|
||||||
App::regAudioItem(_data, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::unregItem(HistoryItem *item) {
|
|
||||||
App::unregAudioItem(_data, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::updateFrom(const MTPMessageMedia &media, HistoryItem *parent) {
|
|
||||||
if (media.type() == mtpc_messageMediaAudio) {
|
|
||||||
App::feedAudio(media.c_messageMediaAudio().vaudio, _data);
|
|
||||||
if (!_data->data().isEmpty()) {
|
|
||||||
Local::writeAudio(mediaKey(AudioFileLocation, _data->dc, _data->id), _data->data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryAudio::setStatusSize(int32 newSize, qint64 realDuration) const {
|
|
||||||
HistoryFileMedia::setStatusSize(newSize, _data->size, _data->duration, realDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HistoryAudio::updateStatusText(const HistoryItem *parent) const {
|
|
||||||
bool showPause = false;
|
|
||||||
int32 statusSize = 0, realDuration = 0;
|
|
||||||
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
|
|
||||||
statusSize = FileStatusSizeFailed;
|
|
||||||
} else if (_data->status == FileUploading) {
|
|
||||||
statusSize = _data->uploadOffset;
|
|
||||||
} else if (_data->loading()) {
|
|
||||||
statusSize = _data->loadOffset();
|
|
||||||
} else if (_data->loaded()) {
|
|
||||||
AudioMsgId playing;
|
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
|
||||||
int64 playingPosition = 0, playingDuration = 0;
|
|
||||||
int32 playingFrequency = 0;
|
|
||||||
if (audioPlayer()) {
|
|
||||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
|
||||||
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
|
|
||||||
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
|
|
||||||
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
|
|
||||||
} else {
|
|
||||||
statusSize = FileStatusSizeLoaded;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
statusSize = FileStatusSizeReady;
|
|
||||||
}
|
|
||||||
if (statusSize != _statusSize) {
|
|
||||||
setStatusSize(statusSize, realDuration);
|
|
||||||
}
|
|
||||||
return showPause;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryDocument::HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
HistoryDocument::HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
||||||
, _data(document)
|
, _parent(0)
|
||||||
, _linksavel(new DocumentSaveLink(_data))
|
, _data(document) {
|
||||||
, _linkcancell(new DocumentCancelLink(_data))
|
create(!caption.isEmpty());
|
||||||
, _name(documentName(_data))
|
if (HistoryDocumentNamed *named = Get<HistoryDocumentNamed>()) {
|
||||||
, _namew(st::semiboldFont->width(_name))
|
named->_name = documentName(_data);
|
||||||
, _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
named->_namew = st::semiboldFont->width(named->_name);
|
||||||
setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data));
|
}
|
||||||
|
|
||||||
|
setLinks(new DocumentOpenLink(_data), _data->voice() ? (ITextLink*)(new VoiceSaveLink(_data)) : new DocumentSaveLink(_data), new DocumentCancelLink(_data));
|
||||||
|
|
||||||
setStatusSize(FileStatusSizeReady);
|
setStatusSize(FileStatusSizeReady);
|
||||||
|
|
||||||
if (!caption.isEmpty()) {
|
if (HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
_caption.setText(st::msgFont, caption + parent->skipBlock(), itemTextNoMonoOptions(parent));
|
captioned->_caption.setText(st::msgFont, caption + parent->skipBlock(), itemTextNoMonoOptions(parent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedia()
|
HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedia()
|
||||||
, _data(other._data)
|
, _parent(0)
|
||||||
, _linksavel(new DocumentSaveLink(_data))
|
, _data(other._data) {
|
||||||
, _linkcancell(new DocumentCancelLink(_data))
|
const HistoryDocumentCaptioned *captioned = other.Get<HistoryDocumentCaptioned>();
|
||||||
, _name(other._name)
|
create(captioned != 0);
|
||||||
, _namew(other._namew)
|
if (HistoryDocumentNamed *named = Get<HistoryDocumentNamed>()) {
|
||||||
, _thumbw(other._thumbw)
|
if (const HistoryDocumentNamed *oin = other.Get<HistoryDocumentNamed>()) {
|
||||||
, _caption(other._caption) {
|
named->_name = oin->_name;
|
||||||
setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data));
|
named->_namew = oin->_namew;
|
||||||
|
} else {
|
||||||
|
named->_name = documentName(_data);
|
||||||
|
named->_namew = st::semiboldFont->width(named->_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLinks(new DocumentOpenLink(_data), _data->voice() ? (ITextLink*)(new VoiceSaveLink(_data)) : new DocumentSaveLink(_data), new DocumentCancelLink(_data));
|
||||||
|
|
||||||
setStatusSize(other._statusSize);
|
setStatusSize(other._statusSize);
|
||||||
|
|
||||||
|
if (captioned) {
|
||||||
|
Get<HistoryDocumentCaptioned>()->_caption = captioned->_caption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryDocument::create(bool caption) {
|
||||||
|
uint64 mask;
|
||||||
|
if (_data->voice()) {
|
||||||
|
mask = HistoryDocumentVoice::Bit();
|
||||||
|
} else {
|
||||||
|
mask = HistoryDocumentNamed::Bit();
|
||||||
|
if (caption) {
|
||||||
|
mask |= HistoryDocumentCaptioned::Bit();
|
||||||
|
}
|
||||||
|
if (!_data->song() && !_data->thumb->isNull() && _data->thumb->width() && _data->thumb->height()) {
|
||||||
|
mask |= HistoryDocumentThumbed::Bit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateInterfaces(mask);
|
||||||
|
if (HistoryDocumentThumbed *thumbed = Get<HistoryDocumentThumbed>()) {
|
||||||
|
thumbed->_linksavel.reset(new DocumentSaveLink(_data));
|
||||||
|
thumbed->_linkcancell.reset(new DocumentCancelLink(_data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocument::initDimensions(const HistoryItem *parent) {
|
void HistoryDocument::initDimensions(const HistoryItem *parent) {
|
||||||
if (_caption.hasSkipBlock()) {
|
_parent = parent;
|
||||||
_caption.setSkipBlock(parent->skipBlockWidth(), parent->skipBlockHeight());
|
|
||||||
|
HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>();
|
||||||
|
if (captioned && captioned->_caption.hasSkipBlock()) {
|
||||||
|
captioned->_caption.setSkipBlock(parent->skipBlockWidth(), parent->skipBlockHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withThumb()) {
|
HistoryDocumentThumbed *thumbed = Get<HistoryDocumentThumbed>();
|
||||||
|
if (thumbed) {
|
||||||
_data->thumb->load();
|
_data->thumb->load();
|
||||||
int32 tw = _data->thumb->width(), th = _data->thumb->height();
|
int32 tw = _data->thumb->width(), th = _data->thumb->height();
|
||||||
if (tw > th) {
|
if (tw > th) {
|
||||||
_thumbw = (tw * st::msgFileThumbSize) / th;
|
thumbed->_thumbw = (tw * st::msgFileThumbSize) / th;
|
||||||
} else {
|
} else {
|
||||||
_thumbw = st::msgFileThumbSize;
|
thumbed->_thumbw = st::msgFileThumbSize;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
_thumbw = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_maxw = st::msgFileMinWidth;
|
_maxw = st::msgFileMinWidth;
|
||||||
|
|
||||||
int32 tleft = 0, tright = 0;
|
int32 tleft = 0, tright = 0;
|
||||||
bool wthumb = withThumb();
|
if (thumbed) {
|
||||||
if (wthumb) {
|
|
||||||
tleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
tleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
||||||
tright = st::msgFileThumbPadding.left();
|
tright = st::msgFileThumbPadding.left();
|
||||||
_maxw = qMax(_maxw, tleft + documentMaxStatusWidth(_data) + tright);
|
_maxw = qMax(_maxw, tleft + documentMaxStatusWidth(_data) + tright);
|
||||||
} else {
|
} else {
|
||||||
tleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
tleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
||||||
tright = st::msgFileThumbPadding.left();
|
tright = st::msgFileThumbPadding.left();
|
||||||
_maxw = qMax(_maxw, tleft + documentMaxStatusWidth(_data) + parent->skipBlockWidth() + st::msgPadding.right());
|
int32 unread = _data->voice() ? (st::mediaUnreadSkip + st::mediaUnreadSize) : 0;
|
||||||
|
_maxw = qMax(_maxw, tleft + documentMaxStatusWidth(_data) + unread + parent->skipBlockWidth() + st::msgPadding.right());
|
||||||
}
|
}
|
||||||
|
|
||||||
_maxw = qMax(tleft + _namew + tright, _maxw);
|
if (HistoryDocumentNamed *named = Get<HistoryDocumentNamed>()) {
|
||||||
|
_maxw = qMax(tleft + named->_namew + tright, _maxw);
|
||||||
_maxw = qMin(_maxw, int(st::msgMaxWidth));
|
_maxw = qMin(_maxw, int(st::msgMaxWidth));
|
||||||
|
}
|
||||||
|
|
||||||
if (wthumb) {
|
if (thumbed) {
|
||||||
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
||||||
} else {
|
} else {
|
||||||
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_caption.isEmpty()) {
|
if (captioned) {
|
||||||
_height = _minh;
|
_minh += captioned->_caption.countHeight(_maxw - st::msgPadding.left() - st::msgPadding.right()) + st::msgPadding.bottom();
|
||||||
} else {
|
} else {
|
||||||
_minh += _caption.countHeight(_maxw - st::msgPadding.left() - st::msgPadding.right()) + st::msgPadding.bottom();
|
_height = _minh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 HistoryDocument::resize(int32 width, const HistoryItem *parent) {
|
int32 HistoryDocument::resize(int32 width, const HistoryItem *parent) {
|
||||||
if (_caption.isEmpty()) {
|
HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>();
|
||||||
|
if (!captioned) {
|
||||||
return HistoryFileMedia::resize(width, parent);
|
return HistoryFileMedia::resize(width, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
_width = qMin(width, _maxw);
|
_width = qMin(width, _maxw);
|
||||||
bool wthumb = withThumb();
|
if (Get<HistoryDocumentThumbed>()) {
|
||||||
if (wthumb) {
|
|
||||||
_height = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
_height = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
||||||
} else {
|
} else {
|
||||||
_height = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
_height = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
||||||
}
|
}
|
||||||
_height += _caption.countHeight(_width - st::msgPadding.left() - st::msgPadding.right()) + st::msgPadding.bottom();
|
_height += captioned->_caption.countHeight(_width - st::msgPadding.left() - st::msgPadding.right()) + st::msgPadding.bottom();
|
||||||
|
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
@ -4094,8 +3943,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
||||||
bool radial = isRadialAnimation(ms);
|
bool radial = isRadialAnimation(ms);
|
||||||
|
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
|
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
|
||||||
bool wthumb = withThumb();
|
if (const HistoryDocumentThumbed *thumbed = Get<HistoryDocumentThumbed>()) {
|
||||||
if (wthumb) {
|
|
||||||
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
||||||
nametop = st::msgFileThumbNameTop;
|
nametop = st::msgFileThumbNameTop;
|
||||||
nameright = st::msgFileThumbPadding.left();
|
nameright = st::msgFileThumbPadding.left();
|
||||||
|
@ -4104,7 +3952,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
||||||
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
||||||
|
|
||||||
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
|
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
|
||||||
QPixmap thumb = loaded ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
|
QPixmap thumb = loaded ? _data->thumb->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
|
||||||
p.drawPixmap(rthumb.topLeft(), thumb);
|
p.drawPixmap(rthumb.topLeft(), thumb);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
|
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
|
||||||
|
@ -4148,11 +3996,11 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data->status != FileUploadFailed) {
|
if (_data->status != FileUploadFailed) {
|
||||||
const TextLinkPtr &lnk((_data->loading() || _data->status == FileUploading) ? _linkcancell : _linksavel);
|
const TextLinkPtr &lnk((_data->loading() || _data->status == FileUploading) ? thumbed->_linkcancell : thumbed->_linksavel);
|
||||||
bool over = textlnkDrawOver(lnk);
|
bool over = textlnkDrawOver(lnk);
|
||||||
p.setFont(over ? st::semiboldFont->underline() : st::semiboldFont);
|
p.setFont(over ? st::semiboldFont->underline() : st::semiboldFont);
|
||||||
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
|
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
|
||||||
p.drawTextLeft(nameleft, linktop, _width, _link, _linkw);
|
p.drawTextLeft(nameleft, linktop, _width, thumbed->_link, thumbed->_linkw);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
||||||
|
@ -4189,7 +4037,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
||||||
} else if (radial || _data->loading()) {
|
} else if (radial || _data->loading()) {
|
||||||
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
||||||
} else if (loaded) {
|
} else if (loaded) {
|
||||||
if (_data->song()) {
|
if (_data->song() || _data->voice()) {
|
||||||
icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
|
icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
|
||||||
} else if (_data->isImage()) {
|
} else if (_data->isImage()) {
|
||||||
icon = outbg ? (selected ? st::msgFileOutImageSelected : st::msgFileOutImage) : (selected ? st::msgFileInImageSelected : st::msgFileInImage);
|
icon = outbg ? (selected ? st::msgFileOutImageSelected : st::msgFileOutImage) : (selected ? st::msgFileInImageSelected : st::msgFileInImage);
|
||||||
|
@ -4203,12 +4051,70 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
||||||
}
|
}
|
||||||
int32 namewidth = _width - nameleft - nameright;
|
int32 namewidth = _width - nameleft - nameright;
|
||||||
|
|
||||||
|
if (const HistoryDocumentVoice *voice = Get<HistoryDocumentVoice>()) {
|
||||||
|
const VoiceWaveform *wf = 0;
|
||||||
|
uchar norm_value = 0;
|
||||||
|
if (_data->voice()) {
|
||||||
|
wf = &_data->voice()->waveform;
|
||||||
|
if (wf->isEmpty()) {
|
||||||
|
wf = 0;
|
||||||
|
if (loaded) {
|
||||||
|
Local::countVoiceWaveform(_data);
|
||||||
|
}
|
||||||
|
} else if (wf->at(0) < 0) {
|
||||||
|
wf = 0;
|
||||||
|
} else {
|
||||||
|
norm_value = _data->voice()->wavemax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float64 prg = voice->_playback ? voice->_playback->a_progress.current() : 0;
|
||||||
|
|
||||||
|
// rescale waveform by going in waveform.size * bar_count 1D grid
|
||||||
|
style::color active(outbg ? st::msgWaveformOutActive : st::msgWaveformInActive);
|
||||||
|
style::color inactive(outbg ? st::msgWaveformOutInactive : st::msgWaveformInInactive);
|
||||||
|
int32 wf_size = wf ? wf->size() : WaveformSamplesCount, availw = int32(namewidth + st::msgWaveformSkip), activew = qRound(availw * prg);
|
||||||
|
int32 bar_count = qMin(availw / int32(st::msgWaveformBar + st::msgWaveformSkip), wf_size);
|
||||||
|
uchar max_value = 0;
|
||||||
|
int32 max_delta = st::msgWaveformMax - st::msgWaveformMin, bottom = st::msgFilePadding.top() + st::msgWaveformMax;
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
for (uint32 i = 0, bar_x = 0, sum_i = 0; i < wf_size; ++i) {
|
||||||
|
uchar value = wf ? wf->at(i) : 0;
|
||||||
|
if (sum_i + bar_count >= wf_size) { // draw bar
|
||||||
|
sum_i = sum_i + bar_count - wf_size;
|
||||||
|
if (sum_i < (bar_count + 1) / 2) {
|
||||||
|
if (max_value < value) max_value = value;
|
||||||
|
}
|
||||||
|
int32 bar_value = ((max_value * max_delta) + ((norm_value + 1) / 2)) / (norm_value + 1);
|
||||||
|
|
||||||
|
if (bar_x >= activew) {
|
||||||
|
p.fillRect(nameleft + bar_x, bottom - bar_value, st::msgWaveformBar, st::msgWaveformMin + bar_value, inactive);
|
||||||
|
} else if (bar_x + st::msgWaveformBar <= activew) {
|
||||||
|
p.fillRect(nameleft + bar_x, bottom - bar_value, st::msgWaveformBar, st::msgWaveformMin + bar_value, active);
|
||||||
|
} else {
|
||||||
|
p.fillRect(nameleft + bar_x, bottom - bar_value, activew - bar_x, st::msgWaveformMin + bar_value, active);
|
||||||
|
p.fillRect(nameleft + activew, bottom - bar_value, st::msgWaveformBar - (activew - bar_x), st::msgWaveformMin + bar_value, inactive);
|
||||||
|
}
|
||||||
|
bar_x += st::msgWaveformBar + st::msgWaveformSkip;
|
||||||
|
|
||||||
|
if (sum_i < (bar_count + 1) / 2) {
|
||||||
|
max_value = 0;
|
||||||
|
} else {
|
||||||
|
max_value = value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (max_value < value) max_value = value;
|
||||||
|
|
||||||
|
sum_i += bar_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (const HistoryDocumentNamed *named = Get<HistoryDocumentNamed>()) {
|
||||||
p.setFont(st::semiboldFont);
|
p.setFont(st::semiboldFont);
|
||||||
p.setPen(st::black);
|
p.setPen(st::black);
|
||||||
if (namewidth < _namew) {
|
if (namewidth < named->_namew) {
|
||||||
p.drawTextLeft(nameleft, nametop, _width, st::semiboldFont->elided(_name, namewidth));
|
p.drawTextLeft(nameleft, nametop, _width, st::semiboldFont->elided(named->_name, namewidth));
|
||||||
} else {
|
} else {
|
||||||
p.drawTextLeft(nameleft, nametop, _width, _name, _namew);
|
p.drawTextLeft(nameleft, nametop, _width, named->_name, named->_namew);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
style::color status(outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg));
|
style::color status(outbg ? (selected ? st::mediaOutFgSelected : st::mediaOutFg) : (selected ? st::mediaInFgSelected : st::mediaInFg));
|
||||||
|
@ -4216,9 +4122,21 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
||||||
p.setPen(status);
|
p.setPen(status);
|
||||||
p.drawTextLeft(nameleft, statustop, _width, _statusText);
|
p.drawTextLeft(nameleft, statustop, _width, _statusText);
|
||||||
|
|
||||||
if (!_caption.isEmpty()) {
|
if (parent->isMediaUnread()) {
|
||||||
|
int32 w = st::normalFont->width(_statusText);
|
||||||
|
if (w + st::mediaUnreadSkip + st::mediaUnreadSize <= namewidth) {
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(outbg ? (selected ? st::msgFileOutBgSelected : st::msgFileOutBg) : (selected ? st::msgFileInBgSelected : st::msgFileInBg));
|
||||||
|
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||||
|
p.drawEllipse(rtlrect(nameleft + w + st::mediaUnreadSkip, statustop + st::mediaUnreadTop, st::mediaUnreadSize, st::mediaUnreadSize, _width));
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
p.setPen(st::black);
|
p.setPen(st::black);
|
||||||
_caption.draw(p, st::msgPadding.left(), bottom, captionw);
|
captioned->_caption.draw(p, st::msgPadding.left(), bottom, captionw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4231,8 +4149,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
|
||||||
bool showPause = updateStatusText(parent);
|
bool showPause = updateStatusText(parent);
|
||||||
|
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
|
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
|
||||||
bool wthumb = withThumb();
|
if (const HistoryDocumentThumbed *thumbed = Get<HistoryDocumentThumbed>()) {
|
||||||
if (wthumb) {
|
|
||||||
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
||||||
linktop = st::msgFileThumbLinkTop;
|
linktop = st::msgFileThumbLinkTop;
|
||||||
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
||||||
|
@ -4245,8 +4162,8 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_data->status != FileUploadFailed) {
|
if (_data->status != FileUploadFailed) {
|
||||||
if (rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, _width).contains(x, y)) {
|
if (rtlrect(nameleft, linktop, thumbed->_linkw, st::semiboldFont->height, _width).contains(x, y)) {
|
||||||
lnk = (_data->loading() || _data->uploading()) ? _linkcancell : _linksavel;
|
lnk = (_data->loading() || _data->uploading()) ? thumbed->_linkcancell : thumbed->_linksavel;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4261,14 +4178,14 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 height = _height;
|
int32 height = _height;
|
||||||
if (!_caption.isEmpty()) {
|
if (const HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
if (y >= bottom) {
|
if (y >= bottom) {
|
||||||
bool inText = false;
|
bool inText = false;
|
||||||
_caption.getState(lnk, inText, x - st::msgPadding.left(), y - bottom, _width - st::msgPadding.left() - st::msgPadding.right());
|
captioned->_caption.getState(lnk, inText, x - st::msgPadding.left(), y - bottom, _width - st::msgPadding.left() - st::msgPadding.right());
|
||||||
state = inText ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
state = inText ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
height -= _caption.countHeight(_width - st::msgPadding.left() - st::msgPadding.right()) + st::msgPadding.bottom();
|
height -= captioned->_caption.countHeight(_width - st::msgPadding.left() - st::msgPadding.right()) + st::msgPadding.bottom();
|
||||||
}
|
}
|
||||||
if (x >= 0 && y >= 0 && x < _width && y < height && !_data->loading() && !_data->uploading() && _data->access) {
|
if (x >= 0 && y >= 0 && x < _width && y < height && !_data->loading() && !_data->uploading() && _data->access) {
|
||||||
lnk = _openl;
|
lnk = _openl;
|
||||||
|
@ -4277,28 +4194,53 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString HistoryDocument::inDialogsText() const {
|
const QString HistoryDocument::inDialogsText() const {
|
||||||
return (_name.isEmpty() ? lang(lng_in_dlg_file) : _name) + (_caption.isEmpty() ? QString() : (' ' + _caption.original(0, 0xFFFF, Text::ExpandLinksNone)));
|
QString result;
|
||||||
|
if (Get<HistoryDocumentVoice>()) {
|
||||||
|
result = lang(lng_in_dlg_audio);
|
||||||
|
} else {
|
||||||
|
const HistoryDocumentNamed *named = Get<HistoryDocumentNamed>();
|
||||||
|
result = (!named || named->_name.isEmpty()) ? lang(lng_in_dlg_file) : named->_name;
|
||||||
|
}
|
||||||
|
if (const HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
|
if (!captioned->_caption.isEmpty()) {
|
||||||
|
result.append(' ').append(captioned->_caption.original(0, 0xFFFF, Text::ExpandLinksNone));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString HistoryDocument::inHistoryText() const {
|
const QString HistoryDocument::inHistoryText() const {
|
||||||
return qsl("[ ") + lang(lng_in_dlg_file) + (_name.isEmpty() ? QString() : (qsl(" : ") + _name)) + (_caption.isEmpty() ? QString() : (qsl(", ") + _caption.original(0, 0xFFFF, Text::ExpandLinksAll))) + qsl(" ]");
|
QString result = qsl("[ ") + lang(Get<HistoryDocumentVoice>() ? lng_in_dlg_audio : lng_in_dlg_file);
|
||||||
|
if (const HistoryDocumentNamed *named = Get<HistoryDocumentNamed>()) {
|
||||||
|
if (!named->_name.isEmpty()) {
|
||||||
|
result.append(qsl(" : ")).append(named->_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (const HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
|
if (!captioned->_caption.isEmpty()) {
|
||||||
|
result.append(qsl(", ")).append(captioned->_caption.original(0, 0xFFFF, Text::ExpandLinksAll));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.append(qsl(" ]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryDocument::setStatusSize(int32 newSize, qint64 realDuration) const {
|
void HistoryDocument::setStatusSize(int32 newSize, qint64 realDuration) const {
|
||||||
HistoryFileMedia::setStatusSize(newSize, _data->size, _data->song() ? _data->song()->duration : -1, realDuration);
|
int32 duration = _data->song() ? _data->song()->duration : (_data->voice() ? _data->voice()->duration : -1);
|
||||||
|
HistoryFileMedia::setStatusSize(newSize, _data->size, duration, realDuration);
|
||||||
|
if (const HistoryDocumentThumbed *thumbed = Get<HistoryDocumentThumbed>()) {
|
||||||
if (_statusSize == FileStatusSizeReady) {
|
if (_statusSize == FileStatusSizeReady) {
|
||||||
_link = lang(lng_media_download).toUpper();
|
thumbed->_link = lang(lng_media_download).toUpper();
|
||||||
} else if (_statusSize == FileStatusSizeLoaded) {
|
} else if (_statusSize == FileStatusSizeLoaded) {
|
||||||
_link = lang(lng_media_open_with).toUpper();
|
thumbed->_link = lang(lng_media_open_with).toUpper();
|
||||||
} else if (_statusSize == FileStatusSizeFailed) {
|
} else if (_statusSize == FileStatusSizeFailed) {
|
||||||
_link = lang(lng_media_download).toUpper();
|
thumbed->_link = lang(lng_media_download).toUpper();
|
||||||
} else if (_statusSize >= 0) {
|
} else if (_statusSize >= 0) {
|
||||||
_link = lang(lng_media_cancel).toUpper();
|
thumbed->_link = lang(lng_media_cancel).toUpper();
|
||||||
} else {
|
} else {
|
||||||
_link = lang(lng_media_open_with).toUpper();
|
thumbed->_link = lang(lng_media_open_with).toUpper();
|
||||||
|
}
|
||||||
|
thumbed->_linkw = st::semiboldFont->width(thumbed->_link);
|
||||||
}
|
}
|
||||||
_linkw = st::semiboldFont->width(_link);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryDocument::updateStatusText(const HistoryItem *parent) const {
|
bool HistoryDocument::updateStatusText(const HistoryItem *parent) const {
|
||||||
|
@ -4311,7 +4253,41 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const {
|
||||||
} else if (_data->loading()) {
|
} else if (_data->loading()) {
|
||||||
statusSize = _data->loadOffset();
|
statusSize = _data->loadOffset();
|
||||||
} else if (_data->loaded()) {
|
} else if (_data->loaded()) {
|
||||||
if (_data->song()) {
|
if (_data->voice()) {
|
||||||
|
AudioMsgId playing;
|
||||||
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
|
int64 playingPosition = 0, playingDuration = 0;
|
||||||
|
int32 playingFrequency = 0;
|
||||||
|
if (audioPlayer()) {
|
||||||
|
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
|
if (const HistoryDocumentVoice *voice = Get<HistoryDocumentVoice>()) {
|
||||||
|
bool was = voice->_playback;
|
||||||
|
voice->ensurePlayback(this);
|
||||||
|
if (!was || playingPosition != voice->_playback->_position) {
|
||||||
|
float64 prg = playingDuration ? snap(float64(playingPosition) / playingDuration, 0., 1.) : 0.;
|
||||||
|
if (voice->_playback->_position < playingPosition) {
|
||||||
|
voice->_playback->a_progress.start(prg);
|
||||||
|
} else {
|
||||||
|
voice->_playback->a_progress = anim::fvalue(0., prg);
|
||||||
|
}
|
||||||
|
voice->_playback->_position = playingPosition;
|
||||||
|
voice->_playback->_a_progress.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
|
||||||
|
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
|
||||||
|
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
|
||||||
|
} else {
|
||||||
|
statusSize = FileStatusSizeLoaded;
|
||||||
|
if (const HistoryDocumentVoice *voice = Get<HistoryDocumentVoice>()) {
|
||||||
|
voice->checkPlaybackFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_data->song()) {
|
||||||
SongMsgId playing;
|
SongMsgId playing;
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
int64 playingPosition = 0, playingDuration = 0;
|
int64 playingPosition = 0, playingDuration = 0;
|
||||||
|
@ -4342,6 +4318,21 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const {
|
||||||
return showPause;
|
return showPause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryDocument::step_voiceProgress(float64 ms, bool timer) {
|
||||||
|
if (HistoryDocumentVoice *voice = Get<HistoryDocumentVoice>()) {
|
||||||
|
if (voice->_playback) {
|
||||||
|
float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
|
||||||
|
if (dt >= 1) {
|
||||||
|
voice->_playback->_a_progress.stop();
|
||||||
|
voice->_playback->a_progress.finish();
|
||||||
|
} else {
|
||||||
|
voice->_playback->a_progress.update(qMin(dt, 1.), anim::linear);
|
||||||
|
}
|
||||||
|
if (timer) Ui::repaintHistoryItem(_parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryDocument::regItem(HistoryItem *item) {
|
void HistoryDocument::regItem(HistoryItem *item) {
|
||||||
App::regDocumentItem(_data, item);
|
App::regDocumentItem(_data, item);
|
||||||
}
|
}
|
||||||
|
@ -4353,6 +4344,13 @@ void HistoryDocument::unregItem(HistoryItem *item) {
|
||||||
void HistoryDocument::updateFrom(const MTPMessageMedia &media, HistoryItem *parent) {
|
void HistoryDocument::updateFrom(const MTPMessageMedia &media, HistoryItem *parent) {
|
||||||
if (media.type() == mtpc_messageMediaDocument) {
|
if (media.type() == mtpc_messageMediaDocument) {
|
||||||
App::feedDocument(media.c_messageMediaDocument().vdocument, _data);
|
App::feedDocument(media.c_messageMediaDocument().vdocument, _data);
|
||||||
|
if (!_data->data().isEmpty()) {
|
||||||
|
if (_data->voice()) {
|
||||||
|
Local::writeAudio(mediaKey(AudioFileLocation, _data->dc, _data->id), _data->data());
|
||||||
|
} else {
|
||||||
|
Local::writeStickerImage(mediaKey(DocumentFileLocation, _data->dc, _data->id), _data->data());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4361,6 +4359,7 @@ ImagePtr HistoryDocument::replyPreview() {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryGif::HistoryGif(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
HistoryGif::HistoryGif(DocumentData *document, const QString &caption, const HistoryItem *parent) : HistoryFileMedia()
|
||||||
|
, _parent(0)
|
||||||
, _data(document)
|
, _data(document)
|
||||||
, _thumbw(1)
|
, _thumbw(1)
|
||||||
, _thumbh(1)
|
, _thumbh(1)
|
||||||
|
@ -5126,7 +5125,6 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||||
_maxw = _minh = _height = 0;
|
_maxw = _minh = _height = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_lineHeight) _lineHeight = qMax(st::webPageTitleFont->height, st::webPageDescriptionFont->height);
|
if (!_lineHeight) _lineHeight = qMax(st::webPageTitleFont->height, st::webPageDescriptionFont->height);
|
||||||
|
|
||||||
if (!_openl && !_data->url.isEmpty()) _openl = TextLinkPtr(new TextLink(_data->url));
|
if (!_openl && !_data->url.isEmpty()) _openl = TextLinkPtr(new TextLink(_data->url));
|
||||||
|
@ -5144,7 +5142,7 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||||
} else {
|
} else {
|
||||||
_asArticle = true;
|
_asArticle = true;
|
||||||
}
|
}
|
||||||
if (_asArticle && (_data->description.isEmpty() || (title.isEmpty() && _data->siteName.isEmpty()))) {
|
if (_asArticle && _data->description.isEmpty() && title.isEmpty() && _data->siteName.isEmpty()) {
|
||||||
_asArticle = false;
|
_asArticle = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6121,12 +6119,6 @@ void HistoryMessage::initMedia(const MTPMessageMedia *media, QString ¤tTex
|
||||||
_media = new HistoryVideo(video.vvideo.c_video(), qs(video.vcaption), this);
|
_media = new HistoryVideo(video.vvideo.c_video(), qs(video.vcaption), this);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case mtpc_messageMediaAudio: {
|
|
||||||
const MTPAudio &audio(media->c_messageMediaAudio().vaudio);
|
|
||||||
if (audio.type() == mtpc_audio) {
|
|
||||||
_media = new HistoryAudio(audio.c_audio());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case mtpc_messageMediaDocument: {
|
case mtpc_messageMediaDocument: {
|
||||||
const MTPDocument &document(media->c_messageMediaDocument().vdocument);
|
const MTPDocument &document(media->c_messageMediaDocument().vdocument);
|
||||||
if (document.type() == mtpc_document) {
|
if (document.type() == mtpc_document) {
|
||||||
|
@ -6225,8 +6217,8 @@ void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const {
|
||||||
left += (!fromChannel() && out() && !Adaptive::Wide()) ? st::msgMargin.right() : st::msgMargin.left();
|
left += (!fromChannel() && out() && !Adaptive::Wide()) ? st::msgMargin.right() : st::msgMargin.left();
|
||||||
if (displayFromPhoto()) {
|
if (displayFromPhoto()) {
|
||||||
left += st::msgPhotoSkip;
|
left += st::msgPhotoSkip;
|
||||||
} else if (!Adaptive::Wide() && !out() && !fromChannel() && st::msgPhotoSkip - (hmaxwidth - hwidth) > 0) {
|
// } else if (!Adaptive::Wide() && !out() && !fromChannel() && st::msgPhotoSkip - (hmaxwidth - hwidth) > 0) {
|
||||||
left += st::msgPhotoSkip - (hmaxwidth - hwidth);
|
// left += st::msgPhotoSkip - (hmaxwidth - hwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
width = hwidth - st::msgMargin.left() - st::msgMargin.right();
|
width = hwidth - st::msgMargin.left() - st::msgMargin.right();
|
||||||
|
|
|
@ -95,23 +95,24 @@ enum HistoryMediaType {
|
||||||
MediaTypeVideo,
|
MediaTypeVideo,
|
||||||
MediaTypeGeo,
|
MediaTypeGeo,
|
||||||
MediaTypeContact,
|
MediaTypeContact,
|
||||||
MediaTypeAudio,
|
MediaTypeFile,
|
||||||
MediaTypeDocument,
|
|
||||||
MediaTypeGif,
|
MediaTypeGif,
|
||||||
MediaTypeSticker,
|
MediaTypeSticker,
|
||||||
MediaTypeImageLink,
|
MediaTypeImageLink,
|
||||||
MediaTypeWebPage,
|
MediaTypeWebPage,
|
||||||
|
MediaTypeMusicFile,
|
||||||
|
MediaTypeVoiceFile,
|
||||||
|
|
||||||
MediaTypeCount
|
MediaTypeCount
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MediaOverviewType {
|
enum MediaOverviewType {
|
||||||
OverviewPhotos,
|
OverviewPhotos = 0,
|
||||||
OverviewVideos,
|
OverviewVideos = 1,
|
||||||
OverviewAudioDocuments,
|
OverviewMusicFiles = 2,
|
||||||
OverviewDocuments,
|
OverviewFiles = 3,
|
||||||
OverviewAudios,
|
OverviewVoiceFiles = 4,
|
||||||
OverviewLinks,
|
OverviewLinks = 5,
|
||||||
|
|
||||||
OverviewCount
|
OverviewCount
|
||||||
};
|
};
|
||||||
|
@ -120,9 +121,9 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OverviewPhotos: return MTP_inputMessagesFilterPhotos();
|
case OverviewPhotos: return MTP_inputMessagesFilterPhotos();
|
||||||
case OverviewVideos: return MTP_inputMessagesFilterVideo();
|
case OverviewVideos: return MTP_inputMessagesFilterVideo();
|
||||||
case OverviewAudioDocuments: return MTP_inputMessagesFilterAudioDocuments();
|
case OverviewMusicFiles: return MTP_inputMessagesFilterMusic();
|
||||||
case OverviewDocuments: return MTP_inputMessagesFilterDocument();
|
case OverviewFiles: return MTP_inputMessagesFilterDocument();
|
||||||
case OverviewAudios: return MTP_inputMessagesFilterAudio();
|
case OverviewVoiceFiles: return MTP_inputMessagesFilterVoice();
|
||||||
case OverviewLinks: return MTP_inputMessagesFilterUrl();
|
case OverviewLinks: return MTP_inputMessagesFilterUrl();
|
||||||
default: type = OverviewCount; break;
|
default: type = OverviewCount; break;
|
||||||
}
|
}
|
||||||
|
@ -133,8 +134,8 @@ enum SendActionType {
|
||||||
SendActionTyping,
|
SendActionTyping,
|
||||||
SendActionRecordVideo,
|
SendActionRecordVideo,
|
||||||
SendActionUploadVideo,
|
SendActionUploadVideo,
|
||||||
SendActionRecordAudio,
|
SendActionRecordVoice,
|
||||||
SendActionUploadAudio,
|
SendActionUploadVoice,
|
||||||
SendActionUploadPhoto,
|
SendActionUploadPhoto,
|
||||||
SendActionUploadFile,
|
SendActionUploadFile,
|
||||||
SendActionChooseLocation,
|
SendActionChooseLocation,
|
||||||
|
@ -1205,10 +1206,11 @@ inline MediaOverviewType mediaToOverviewType(HistoryMedia *media) {
|
||||||
switch (media->type()) {
|
switch (media->type()) {
|
||||||
case MediaTypePhoto: return OverviewPhotos;
|
case MediaTypePhoto: return OverviewPhotos;
|
||||||
case MediaTypeVideo: return OverviewVideos;
|
case MediaTypeVideo: return OverviewVideos;
|
||||||
case MediaTypeDocument: return media->getDocument()->song() ? OverviewAudioDocuments : OverviewDocuments;
|
case MediaTypeFile: return OverviewFiles;
|
||||||
case MediaTypeGif: return media->getDocument()->isGifv() ? OverviewCount : OverviewDocuments;
|
case MediaTypeMusicFile: return media->getDocument()->isMusic() ? OverviewMusicFiles : OverviewFiles;
|
||||||
// case MediaTypeSticker: return OverviewDocuments;
|
case MediaTypeVoiceFile: return OverviewVoiceFiles;
|
||||||
case MediaTypeAudio: return OverviewAudios;
|
case MediaTypeGif: return media->getDocument()->isGifv() ? OverviewCount : OverviewFiles;
|
||||||
|
// case MediaTypeSticker: return OverviewFiles;
|
||||||
}
|
}
|
||||||
return OverviewCount;
|
return OverviewCount;
|
||||||
}
|
}
|
||||||
|
@ -1418,76 +1420,52 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistoryAudio : public HistoryFileMedia {
|
struct HistoryDocumentThumbed : public BasicInterface<HistoryDocumentThumbed> {
|
||||||
public:
|
HistoryDocumentThumbed(Interfaces *interfaces) : _thumbw(0), _linkw(0) {
|
||||||
|
|
||||||
HistoryAudio(const MTPDaudio &audio);
|
|
||||||
HistoryAudio(const HistoryAudio &other);
|
|
||||||
HistoryMediaType type() const {
|
|
||||||
return MediaTypeAudio;
|
|
||||||
}
|
}
|
||||||
HistoryMedia *clone() const {
|
TextLinkPtr _linksavel, _linkcancell;
|
||||||
return new HistoryAudio(*this);
|
int32 _thumbw;
|
||||||
|
|
||||||
|
mutable int32 _linkw;
|
||||||
|
mutable QString _link;
|
||||||
|
};
|
||||||
|
struct HistoryDocumentCaptioned : public BasicInterface<HistoryDocumentCaptioned> {
|
||||||
|
HistoryDocumentCaptioned(Interfaces *interfaces) : _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
|
||||||
}
|
}
|
||||||
|
Text _caption;
|
||||||
void initDimensions(const HistoryItem *parent);
|
};
|
||||||
|
struct HistoryDocumentNamed : public BasicInterface<HistoryDocumentNamed> {
|
||||||
void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const;
|
HistoryDocumentNamed(Interfaces *interfaces) : _namew(0) {
|
||||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const;
|
|
||||||
|
|
||||||
const QString inDialogsText() const;
|
|
||||||
const QString inHistoryText() const;
|
|
||||||
|
|
||||||
bool uploading() const {
|
|
||||||
return _data->uploading();
|
|
||||||
}
|
}
|
||||||
|
QString _name;
|
||||||
|
int32 _namew;
|
||||||
|
};
|
||||||
|
class HistoryDocument;
|
||||||
|
struct HistoryDocumentVoicePlayback {
|
||||||
|
HistoryDocumentVoicePlayback(const HistoryDocument *that);
|
||||||
|
|
||||||
AudioData *audio() {
|
int32 _position;
|
||||||
return _data;
|
anim::fvalue a_progress;
|
||||||
|
Animation _a_progress;
|
||||||
|
};
|
||||||
|
struct HistoryDocumentVoice : public BasicInterface<HistoryDocumentVoice> {
|
||||||
|
HistoryDocumentVoice(Interfaces *that) : _playback(0) {
|
||||||
}
|
}
|
||||||
|
~HistoryDocumentVoice() {
|
||||||
void regItem(HistoryItem *item);
|
deleteAndMark(_playback);
|
||||||
void unregItem(HistoryItem *item);
|
|
||||||
|
|
||||||
void updateFrom(const MTPMessageMedia &media, HistoryItem *parent);
|
|
||||||
|
|
||||||
bool needsBubble(const HistoryItem *parent) const {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
bool customInfoLayout() const {
|
void ensurePlayback(const HistoryDocument *interfaces) const;
|
||||||
return false;
|
void checkPlaybackFinished() const;
|
||||||
}
|
mutable HistoryDocumentVoicePlayback *_playback;
|
||||||
QMargins bubbleMargins() const {
|
|
||||||
return st::msgPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
float64 dataProgress() const {
|
|
||||||
return _data->progress();
|
|
||||||
}
|
|
||||||
bool dataFinished() const {
|
|
||||||
return !_data->loading() && !_data->uploading();
|
|
||||||
}
|
|
||||||
bool dataLoaded() const {
|
|
||||||
return _data->loaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AudioData *_data;
|
|
||||||
|
|
||||||
void setStatusSize(int32 newSize, qint64 realDuration = 0) const;
|
|
||||||
bool updateStatusText(const HistoryItem *parent) const; // returns showPause
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class HistoryDocument : public HistoryFileMedia {
|
class HistoryDocument : public HistoryFileMedia, public Interfaces {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent);
|
HistoryDocument(DocumentData *document, const QString &caption, const HistoryItem *parent);
|
||||||
HistoryDocument(const HistoryDocument &other);
|
HistoryDocument(const HistoryDocument &other);
|
||||||
HistoryMediaType type() const {
|
HistoryMediaType type() const {
|
||||||
return MediaTypeDocument;
|
return _data->voice() ? MediaTypeVoiceFile : (_data->song() ? MediaTypeMusicFile : MediaTypeFile);
|
||||||
}
|
}
|
||||||
HistoryMedia *clone() const {
|
HistoryMedia *clone() const {
|
||||||
return new HistoryDocument(*this);
|
return new HistoryDocument(*this);
|
||||||
|
@ -1506,10 +1484,6 @@ public:
|
||||||
return _data->uploading();
|
return _data->uploading();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool withThumb() const {
|
|
||||||
return !_data->song() && !_data->thumb->isNull() && _data->thumb->width() && _data->thumb->height();
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentData *getDocument() {
|
DocumentData *getDocument() {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
@ -1525,7 +1499,10 @@ public:
|
||||||
ImagePtr replyPreview();
|
ImagePtr replyPreview();
|
||||||
|
|
||||||
QString getCaption() const {
|
QString getCaption() const {
|
||||||
return _caption.original();
|
if (const HistoryDocumentCaptioned *captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
|
return captioned->_caption.original();
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
bool needsBubble(const HistoryItem *parent) const {
|
bool needsBubble(const HistoryItem *parent) const {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1534,12 +1511,14 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QMargins bubbleMargins() const {
|
QMargins bubbleMargins() const {
|
||||||
return withThumb() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding;
|
return Get<HistoryDocumentThumbed>() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding;
|
||||||
}
|
}
|
||||||
bool hideForwardedFrom() const {
|
bool hideForwardedFrom() const {
|
||||||
return _data->song();
|
return _data->song();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void step_voiceProgress(float64 ms, bool timer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
float64 dataProgress() const {
|
float64 dataProgress() const {
|
||||||
|
@ -1554,17 +1533,9 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void create(bool caption);
|
||||||
|
const HistoryItem *_parent;
|
||||||
DocumentData *_data;
|
DocumentData *_data;
|
||||||
TextLinkPtr _linksavel, _linkcancell;
|
|
||||||
|
|
||||||
QString _name;
|
|
||||||
int32 _namew;
|
|
||||||
int32 _thumbw;
|
|
||||||
|
|
||||||
mutable int32 _linkw;
|
|
||||||
mutable QString _link;
|
|
||||||
|
|
||||||
Text _caption;
|
|
||||||
|
|
||||||
void setStatusSize(int32 newSize, qint64 realDuration = 0) const;
|
void setStatusSize(int32 newSize, qint64 realDuration = 0) const;
|
||||||
bool updateStatusText(const HistoryItem *parent) const; // returns showPause
|
bool updateStatusText(const HistoryItem *parent) const; // returns showPause
|
||||||
|
@ -2237,7 +2208,20 @@ inline int32 newMessageFlags(PeerData *p) {
|
||||||
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out);
|
return p->isSelf() ? 0 : (((p->isChat() || (p->isUser() && !p->asUser()->botInfo)) ? MTPDmessage::flag_unread : 0) | MTPDmessage::flag_out);
|
||||||
}
|
}
|
||||||
inline int32 newForwardedFlags(PeerData *p, int32 from, HistoryMessage *msg) {
|
inline int32 newForwardedFlags(PeerData *p, int32 from, HistoryMessage *msg) {
|
||||||
return newMessageFlags(p) | (from ? MTPDmessage::flag_from_id : 0) | (msg->via() ? MTPDmessage::flag_via_bot_id : 0) | (!p->isChannel() && msg->getMedia() && (msg->getMedia()->type() == MediaTypeAudio/* || msg->getMedia()->type() == MediaTypeVideo*/) ? MTPDmessage::flag_media_unread : 0);
|
int32 result = newMessageFlags(p) | (from ? MTPDmessage::flag_from_id : 0);
|
||||||
|
if (msg->via()) {
|
||||||
|
result |= MTPDmessage::flag_via_bot_id;
|
||||||
|
}
|
||||||
|
if (!p->isChannel()) {
|
||||||
|
if (HistoryMedia *media = msg->getMedia()) {
|
||||||
|
if (media->type() == MediaTypeVoiceFile) {
|
||||||
|
result |= MTPDmessage::flag_media_unread;
|
||||||
|
// } else if (media->type() == MediaTypeVideo) {
|
||||||
|
// result |= MTPDmessage::flag_media_unread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HistoryServiceMsg : public HistoryItem {
|
class HistoryServiceMsg : public HistoryItem {
|
||||||
|
|
|
@ -865,9 +865,9 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
|
HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
|
||||||
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument) {
|
bool lnkIsAudio = lnkDocument ? lnkDocument->document()->voice() : false;
|
||||||
|
if (lnkPhoto || lnkVideo || lnkDocument) {
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -879,17 +879,17 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if ((lnkVideo && lnkVideo->video()->loading()) || (lnkAudio && lnkAudio->audio()->loading()) || (lnkDocument && lnkDocument->document()->loading())) {
|
if ((lnkVideo && lnkVideo->video()->loading()) || (lnkDocument && lnkDocument->document()->loading())) {
|
||||||
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if (lnkDocument && lnkDocument->document()->loaded() && lnkDocument->document()->isGifv()) {
|
if (lnkDocument && lnkDocument->document()->loaded() && lnkDocument->document()->isGifv()) {
|
||||||
_menu->addAction(lang(lng_context_save_gif), this, SLOT(saveContextGif()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_save_gif), this, SLOT(saveContextGif()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
||||||
_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkIsAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isUponSelected > 1) {
|
if (isUponSelected > 1) {
|
||||||
|
@ -1071,8 +1071,6 @@ void HistoryInner::copyContextImage() {
|
||||||
void HistoryInner::cancelContextDownload() {
|
void HistoryInner::cancelContextDownload() {
|
||||||
if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
|
if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
|
||||||
lnkVideo->video()->cancel();
|
lnkVideo->video()->cancel();
|
||||||
} else if (AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data())) {
|
|
||||||
lnkAudio->audio()->cancel();
|
|
||||||
} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
|
} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
|
||||||
lnkDocument->document()->cancel();
|
lnkDocument->document()->cancel();
|
||||||
} else if (HistoryItem *item = App::contextItem()) {
|
} else if (HistoryItem *item = App::contextItem()) {
|
||||||
|
@ -1088,8 +1086,6 @@ void HistoryInner::showContextInFolder() {
|
||||||
QString already;
|
QString already;
|
||||||
if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
|
if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
|
||||||
already = lnkVideo->video()->already(true);
|
already = lnkVideo->video()->already(true);
|
||||||
} else if (AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data())) {
|
|
||||||
already = lnkAudio->audio()->already(true);
|
|
||||||
} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
|
} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
|
||||||
already = lnkDocument->document()->already(true);
|
already = lnkDocument->document()->already(true);
|
||||||
} else if (HistoryItem *item = App::contextItem()) {
|
} else if (HistoryItem *item = App::contextItem()) {
|
||||||
|
@ -1106,10 +1102,8 @@ void HistoryInner::openContextFile() {
|
||||||
HistoryItem *was = App::hoveredLinkItem();
|
HistoryItem *was = App::hoveredLinkItem();
|
||||||
App::hoveredLinkItem(App::contextItem());
|
App::hoveredLinkItem(App::contextItem());
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
|
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
|
||||||
if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton);
|
|
||||||
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
|
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
|
||||||
App::hoveredLinkItem(was);
|
App::hoveredLinkItem(was);
|
||||||
}
|
}
|
||||||
|
@ -1117,8 +1111,6 @@ void HistoryInner::openContextFile() {
|
||||||
void HistoryInner::saveContextFile() {
|
void HistoryInner::saveContextFile() {
|
||||||
if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
|
if (VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data())) {
|
||||||
VideoSaveLink::doSave(lnkVideo->video(), true);
|
VideoSaveLink::doSave(lnkVideo->video(), true);
|
||||||
} else if (AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data())) {
|
|
||||||
AudioSaveLink::doSave(lnkAudio->audio(), true);
|
|
||||||
} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
|
} else if (DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data())) {
|
||||||
DocumentSaveLink::doSave(lnkDocument->document(), true);
|
DocumentSaveLink::doSave(lnkDocument->document(), true);
|
||||||
} else if (HistoryItem *item = App::contextItem()) {
|
} else if (HistoryItem *item = App::contextItem()) {
|
||||||
|
@ -2720,8 +2712,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout()));
|
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout()));
|
||||||
if (audioCapture()) {
|
if (audioCapture()) {
|
||||||
connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError()));
|
connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError()));
|
||||||
connect(audioCapture(), SIGNAL(onUpdate(qint16,qint32)), this, SLOT(onRecordUpdate(qint16,qint32)));
|
connect(audioCapture(), SIGNAL(onUpdate(quint16,qint32)), this, SLOT(onRecordUpdate(quint16,qint32)));
|
||||||
connect(audioCapture(), SIGNAL(onDone(QByteArray,qint32)), this, SLOT(onRecordDone(QByteArray,qint32)));
|
connect(audioCapture(), SIGNAL(onDone(QByteArray,VoiceWaveform,qint32)), this, SLOT(onRecordDone(QByteArray,VoiceWaveform,qint32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateHistoryItems.setSingleShot(true);
|
_updateHistoryItems.setSingleShot(true);
|
||||||
|
@ -3005,8 +2997,8 @@ void HistoryWidget::updateSendAction(History *history, SendActionType type, int3
|
||||||
case SendActionTyping: action = MTP_sendMessageTypingAction(); break;
|
case SendActionTyping: action = MTP_sendMessageTypingAction(); break;
|
||||||
case SendActionRecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
case SendActionRecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
||||||
case SendActionUploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
case SendActionUploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
||||||
case SendActionRecordAudio: action = MTP_sendMessageRecordAudioAction(); break;
|
case SendActionRecordVoice: action = MTP_sendMessageRecordAudioAction(); break;
|
||||||
case SendActionUploadAudio: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
case SendActionUploadVoice: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
||||||
case SendActionUploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
case SendActionUploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
||||||
case SendActionUploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
case SendActionUploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
||||||
case SendActionChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
case SendActionChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
||||||
|
@ -3055,16 +3047,16 @@ void HistoryWidget::onRecordError() {
|
||||||
stopRecording(false);
|
stopRecording(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onRecordDone(QByteArray result, qint32 samples) {
|
void HistoryWidget::onRecordDone(QByteArray result, VoiceWaveform waveform, qint32 samples) {
|
||||||
if (!_peer) return;
|
if (!_peer) return;
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
int32 duration = samples / AudioVoiceMsgFrequency;
|
int32 duration = samples / AudioVoiceMsgFrequency;
|
||||||
_fileLoader.addTask(new FileLoadTask(result, duration, FileLoadTo(_peer->id, _broadcast.checked(), replyToId())));
|
_fileLoader.addTask(new FileLoadTask(result, duration, waveform, FileLoadTo(_peer->id, _broadcast.checked(), replyToId())));
|
||||||
cancelReply(lastForceReplyReplied());
|
cancelReply(lastForceReplyReplied());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onRecordUpdate(qint16 level, qint32 samples) {
|
void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
|
||||||
if (!_recording) {
|
if (!_recording) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3077,7 +3069,7 @@ void HistoryWidget::onRecordUpdate(qint16 level, qint32 samples) {
|
||||||
}
|
}
|
||||||
updateField();
|
updateField();
|
||||||
if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
|
if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
|
||||||
updateSendAction(_history, SendActionRecordAudio);
|
updateSendAction(_history, SendActionRecordVoice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4241,9 +4233,9 @@ void HistoryWidget::firstLoadMessages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadImportant) {
|
if (loadImportant) {
|
||||||
_firstLoadRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
_firstLoadRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
} else {
|
} else {
|
||||||
_firstLoadRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
_firstLoadRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(offset), MTP_int(0), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4265,9 +4257,9 @@ void HistoryWidget::loadMessages() {
|
||||||
int32 offset = 0, loadCount = offset_id ? MessagesPerPage : MessagesFirstLoad;
|
int32 offset = 0, loadCount = offset_id ? MessagesPerPage : MessagesFirstLoad;
|
||||||
|
|
||||||
if (loadImportant) {
|
if (loadImportant) {
|
||||||
_preloadRequest = MTP::send(MTPchannels_GetImportantHistory(from->peer->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
_preloadRequest = MTP::send(MTPchannels_GetImportantHistory(from->peer->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
} else {
|
} else {
|
||||||
_preloadRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
_preloadRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4295,9 +4287,9 @@ void HistoryWidget::loadMessagesDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadImportant) {
|
if (loadImportant) {
|
||||||
_preloadDownRequest = MTP::send(MTPchannels_GetImportantHistory(from->peer->asChannel()->inputChannel, MTP_int(offset_id + 1), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
_preloadDownRequest = MTP::send(MTPchannels_GetImportantHistory(from->peer->asChannel()->inputChannel, MTP_int(offset_id + 1), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
} else {
|
} else {
|
||||||
_preloadDownRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id + 1), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
_preloadDownRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id + 1), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4355,9 +4347,9 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadImportant) {
|
if (loadImportant) {
|
||||||
_delayedShowAtRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
_delayedShowAtRequest = MTP::send(MTPchannels_GetImportantHistory(from->asChannel()->inputChannel, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
} else {
|
} else {
|
||||||
_delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
_delayedShowAtRequest = MTP::send(MTPmessages_GetHistory(from->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4807,7 +4799,7 @@ void HistoryWidget::onDocumentSelect() {
|
||||||
void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) {
|
void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
if (!_history) return;
|
if (!_history) return;
|
||||||
|
|
||||||
if (_peer && (_peer->isChannel() && !_peer->asChannel()->canPublish())) return;
|
if (_peer && !_canSendMessages) return;
|
||||||
|
|
||||||
_attachDrag = getDragState(e->mimeData());
|
_attachDrag = getDragState(e->mimeData());
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
|
@ -4887,7 +4879,7 @@ void HistoryWidget::stopRecording(bool send) {
|
||||||
_recording = false;
|
_recording = false;
|
||||||
_recordingSamples = 0;
|
_recordingSamples = 0;
|
||||||
if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
|
if (_peer && (!_peer->isChannel() || _peer->isMegagroup() || !_peer->asChannel()->canPublish() || (!_peer->asChannel()->isBroadcast() && !_broadcast.checked()))) {
|
||||||
updateSendAction(_history, SendActionRecordAudio, -1);
|
updateSendAction(_history, SendActionRecordVoice, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -5151,7 +5143,7 @@ void HistoryWidget::onPhotoDrop(const QMimeData *data) {
|
||||||
void HistoryWidget::onDocumentDrop(const QMimeData *data) {
|
void HistoryWidget::onDocumentDrop(const QMimeData *data) {
|
||||||
if (!_history) return;
|
if (!_history) return;
|
||||||
|
|
||||||
if (_peer && (_peer->isChannel() && !_peer->asChannel()->canPublish())) return;
|
if (_peer && !_canSendMessages) return;
|
||||||
|
|
||||||
QStringList files = getMediasFromMime(data);
|
QStringList files = getMediasFromMime(data);
|
||||||
if (files.isEmpty()) return;
|
if (files.isEmpty()) return;
|
||||||
|
@ -5161,7 +5153,7 @@ void HistoryWidget::onDocumentDrop(const QMimeData *data) {
|
||||||
|
|
||||||
void HistoryWidget::onFilesDrop(const QMimeData *data) {
|
void HistoryWidget::onFilesDrop(const QMimeData *data) {
|
||||||
|
|
||||||
if (_peer && (_peer->isChannel() && !_peer->asChannel()->canPublish())) return;
|
if (_peer && !_canSendMessages) return;
|
||||||
|
|
||||||
QStringList files = getMediasFromMime(data);
|
QStringList files = getMediasFromMime(data);
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
|
@ -5522,13 +5514,10 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
|
||||||
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onPhotoUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onPhotoUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(documentReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onDocumentUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(documentReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onDocumentUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(thumbDocumentReady(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), this, SLOT(onThumbDocumentUploaded(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(thumbDocumentReady(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), this, SLOT(onThumbDocumentUploaded(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(audioReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onAudioUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
|
|
||||||
connect(App::uploader(), SIGNAL(photoProgress(const FullMsgId&)), this, SLOT(onPhotoProgress(const FullMsgId&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(photoProgress(const FullMsgId&)), this, SLOT(onPhotoProgress(const FullMsgId&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(documentProgress(const FullMsgId&)), this, SLOT(onDocumentProgress(const FullMsgId&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(documentProgress(const FullMsgId&)), this, SLOT(onDocumentProgress(const FullMsgId&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(audioProgress(const FullMsgId&)), this, SLOT(onAudioProgress(const FullMsgId&)), Qt::UniqueConnection);
|
|
||||||
connect(App::uploader(), SIGNAL(photoFailed(const FullMsgId&)), this, SLOT(onPhotoFailed(const FullMsgId&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(photoFailed(const FullMsgId&)), this, SLOT(onPhotoFailed(const FullMsgId&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(documentFailed(const FullMsgId&)), this, SLOT(onDocumentFailed(const FullMsgId&)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(documentFailed(const FullMsgId&)), this, SLOT(onDocumentFailed(const FullMsgId&)), Qt::UniqueConnection);
|
||||||
connect(App::uploader(), SIGNAL(audioFailed(const FullMsgId&)), this, SLOT(onAudioFailed(const FullMsgId&)), Qt::UniqueConnection);
|
|
||||||
|
|
||||||
App::uploader()->upload(newId, file);
|
App::uploader()->upload(newId, file);
|
||||||
|
|
||||||
|
@ -5552,7 +5541,7 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
|
||||||
if (!h->peer->isChannel()) {
|
if (!h->peer->isChannel()) {
|
||||||
flags |= MTPDmessage::flag_media_unread;
|
flags |= MTPDmessage::flag_media_unread;
|
||||||
}
|
}
|
||||||
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(file->audio), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
|
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(file->to.peer), MTPPeer(), MTPint(), MTPint(), MTP_int(file->to.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(file->document, MTP_string(file->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_peer && file->to.peer == _peer->id) {
|
if (_peer && file->to.peer == _peer->id) {
|
||||||
|
@ -5628,7 +5617,9 @@ namespace {
|
||||||
} else if (document->type == StickerDocument && document->sticker()) {
|
} else if (document->type == StickerDocument && document->sticker()) {
|
||||||
attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->sticker()->alt), document->sticker()->set));
|
attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->sticker()->alt), document->sticker()->set));
|
||||||
} else if (document->type == SongDocument && document->song()) {
|
} else if (document->type == SongDocument && document->song()) {
|
||||||
attributes.push_back(MTP_documentAttributeAudio(MTP_int(document->song()->duration), MTP_string(document->song()->title), MTP_string(document->song()->performer)));
|
attributes.push_back(MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_title | MTPDdocumentAttributeAudio::flag_performer), MTP_int(document->song()->duration), MTP_string(document->song()->title), MTP_string(document->song()->performer), MTPstring()));
|
||||||
|
} else if (document->type == VoiceDocument && document->voice()) {
|
||||||
|
attributes.push_back(MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_voice | MTPDdocumentAttributeAudio::flag_waveform), MTP_int(document->voice()->duration), MTPstring(), MTPstring(), MTP_string(documentWaveformEncode5bit(document->voice()->waveform))));
|
||||||
}
|
}
|
||||||
return MTP_vector<MTPDocumentAttribute>(attributes);
|
return MTP_vector<MTPDocumentAttribute>(attributes);
|
||||||
}
|
}
|
||||||
|
@ -5684,33 +5675,6 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, const MTPInp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onAudioUploaded(const FullMsgId &newId, const MTPInputFile &file) {
|
|
||||||
if (!MTP::authedId()) return;
|
|
||||||
HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::histItemById(newId));
|
|
||||||
if (item) {
|
|
||||||
AudioData *audio = 0;
|
|
||||||
if (HistoryAudio *media = dynamic_cast<HistoryAudio*>(item->getMedia())) {
|
|
||||||
audio = media->audio();
|
|
||||||
}
|
|
||||||
if (audio) {
|
|
||||||
uint64 randomId = MTP::nonce<uint64>();
|
|
||||||
App::historyRegRandom(randomId, newId);
|
|
||||||
History *hist = item->history();
|
|
||||||
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
|
|
||||||
int32 sendFlags = 0;
|
|
||||||
if (replyTo) {
|
|
||||||
sendFlags |= MTPmessages_SendMedia::flag_reply_to_msg_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fromChannelName = hist->peer->isChannel() && !hist->peer->isMegagroup() && hist->peer->asChannel()->canPublish() && item->fromChannel();
|
|
||||||
if (fromChannelName) {
|
|
||||||
sendFlags |= MTPmessages_SendMedia::flag_broadcast;
|
|
||||||
}
|
|
||||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedAudio(file, MTP_int(audio->duration), MTP_string(audio->mime)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::onPhotoProgress(const FullMsgId &newId) {
|
void HistoryWidget::onPhotoProgress(const FullMsgId &newId) {
|
||||||
if (!MTP::authedId()) return;
|
if (!MTP::authedId()) return;
|
||||||
if (HistoryItem *item = App::histItemById(newId)) {
|
if (HistoryItem *item = App::histItemById(newId)) {
|
||||||
|
@ -5728,18 +5692,7 @@ void HistoryWidget::onDocumentProgress(const FullMsgId &newId) {
|
||||||
HistoryMedia *media = item->getMedia();
|
HistoryMedia *media = item->getMedia();
|
||||||
DocumentData *doc = media ? media->getDocument() : 0;
|
DocumentData *doc = media ? media->getDocument() : 0;
|
||||||
if (!item->fromChannel()) {
|
if (!item->fromChannel()) {
|
||||||
updateSendAction(item->history(), SendActionUploadFile, doc ? doc->uploadOffset : 0);
|
updateSendAction(item->history(), (doc && doc->voice()) ? SendActionUploadVoice : SendActionUploadFile, doc ? doc->uploadOffset : 0);
|
||||||
}
|
|
||||||
Ui::repaintHistoryItem(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::onAudioProgress(const FullMsgId &newId) {
|
|
||||||
if (!MTP::authedId()) return;
|
|
||||||
if (HistoryItem *item = App::histItemById(newId)) {
|
|
||||||
AudioData *audio = (item->getMedia() && item->getMedia()->type() == MediaTypeAudio) ? static_cast<HistoryAudio*>(item->getMedia())->audio() : 0;
|
|
||||||
if (!item->fromChannel()) {
|
|
||||||
updateSendAction(item->history(), SendActionUploadAudio, audio ? audio->uploadOffset : 0);
|
|
||||||
}
|
}
|
||||||
Ui::repaintHistoryItem(item);
|
Ui::repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -5760,19 +5713,10 @@ void HistoryWidget::onDocumentFailed(const FullMsgId &newId) {
|
||||||
if (!MTP::authedId()) return;
|
if (!MTP::authedId()) return;
|
||||||
HistoryItem *item = App::histItemById(newId);
|
HistoryItem *item = App::histItemById(newId);
|
||||||
if (item) {
|
if (item) {
|
||||||
|
HistoryMedia *media = item->getMedia();
|
||||||
|
DocumentData *doc = media ? media->getDocument() : 0;
|
||||||
if (!item->fromChannel()) {
|
if (!item->fromChannel()) {
|
||||||
updateSendAction(item->history(), SendActionUploadFile, -1);
|
updateSendAction(item->history(), (doc && doc->voice()) ? SendActionUploadVoice : SendActionUploadFile, -1);
|
||||||
}
|
|
||||||
Ui::repaintHistoryItem(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::onAudioFailed(const FullMsgId &newId) {
|
|
||||||
if (!MTP::authedId()) return;
|
|
||||||
HistoryItem *item = App::histItemById(newId);
|
|
||||||
if (item) {
|
|
||||||
if (!item->fromChannel()) {
|
|
||||||
updateSendAction(item->history(), SendActionUploadAudio, -1);
|
|
||||||
}
|
}
|
||||||
Ui::repaintHistoryItem(item);
|
Ui::repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
@ -7194,7 +7138,7 @@ void HistoryWidget::drawRecording(Painter &p) {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::recordSignalColor->b);
|
p.setBrush(st::recordSignalColor->b);
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
float64 delta = qMin(float64(a_recordingLevel.current()) * 3 * M_PI / 0x7fff, 1.);
|
float64 delta = qMin(float64(a_recordingLevel.current()) / 0x4000, 1.);
|
||||||
int32 d = 2 * qRound(st::recordSignalMin + (delta * (st::recordSignalMax - st::recordSignalMin)));
|
int32 d = 2 * qRound(st::recordSignalMin + (delta * (st::recordSignalMax - st::recordSignalMin)));
|
||||||
p.drawEllipse(_attachPhoto.x() + (_attachEmoji.width() - d) / 2, _attachPhoto.y() + (_attachPhoto.height() - d) / 2, d, d);
|
p.drawEllipse(_attachPhoto.x() + (_attachEmoji.width() - d) / 2, _attachPhoto.y() + (_attachPhoto.height() - d) / 2, d, d);
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
|
|
|
@ -610,15 +610,12 @@ public slots:
|
||||||
void onPhotoUploaded(const FullMsgId &msgId, const MTPInputFile &file);
|
void onPhotoUploaded(const FullMsgId &msgId, const MTPInputFile &file);
|
||||||
void onDocumentUploaded(const FullMsgId &msgId, const MTPInputFile &file);
|
void onDocumentUploaded(const FullMsgId &msgId, const MTPInputFile &file);
|
||||||
void onThumbDocumentUploaded(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
|
void onThumbDocumentUploaded(const FullMsgId &msgId, const MTPInputFile &file, const MTPInputFile &thumb);
|
||||||
void onAudioUploaded(const FullMsgId &msgId, const MTPInputFile &file);
|
|
||||||
|
|
||||||
void onPhotoProgress(const FullMsgId &msgId);
|
void onPhotoProgress(const FullMsgId &msgId);
|
||||||
void onDocumentProgress(const FullMsgId &msgId);
|
void onDocumentProgress(const FullMsgId &msgId);
|
||||||
void onAudioProgress(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
void onPhotoFailed(const FullMsgId &msgId);
|
void onPhotoFailed(const FullMsgId &msgId);
|
||||||
void onDocumentFailed(const FullMsgId &msgId);
|
void onDocumentFailed(const FullMsgId &msgId);
|
||||||
void onAudioFailed(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
void onReportSpamClicked();
|
void onReportSpamClicked();
|
||||||
void onReportSpamSure();
|
void onReportSpamSure();
|
||||||
|
@ -683,8 +680,8 @@ public slots:
|
||||||
void updateField();
|
void updateField();
|
||||||
|
|
||||||
void onRecordError();
|
void onRecordError();
|
||||||
void onRecordDone(QByteArray result, qint32 samples);
|
void onRecordDone(QByteArray result, VoiceWaveform waveform, qint32 samples);
|
||||||
void onRecordUpdate(qint16 level, qint32 samples);
|
void onRecordUpdate(quint16 level, qint32 samples);
|
||||||
|
|
||||||
void onUpdateHistoryItems();
|
void onUpdateHistoryItems();
|
||||||
|
|
||||||
|
|
|
@ -550,23 +550,25 @@ void LayoutOverviewVideo::updateStatusText() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutOverviewAudio::LayoutOverviewAudio(AudioData *audio, HistoryItem *parent) : LayoutAbstractFileItem(OverviewItemInfo::Bit(), parent)
|
LayoutOverviewVoice::LayoutOverviewVoice(DocumentData *voice, HistoryItem *parent) : LayoutAbstractFileItem(OverviewItemInfo::Bit(), parent)
|
||||||
, _data(audio)
|
, _data(voice)
|
||||||
, _namel(new AudioOpenLink(_data)) {
|
, _namel(new DocumentOpenLink(_data)) {
|
||||||
setLinks(new AudioOpenLink(_data), new AudioOpenLink(_data), new AudioCancelLink(_data));
|
t_assert(_data->voice() != 0);
|
||||||
|
|
||||||
|
setLinks(new DocumentOpenLink(_data), new DocumentOpenLink(_data), new DocumentCancelLink(_data));
|
||||||
updateName();
|
updateName();
|
||||||
QString d = textcmdLink(1, textRichPrepare(langDateTime(date(_data->date))));
|
QString d = textcmdLink(1, textRichPrepare(langDateTime(date(_data->date))));
|
||||||
TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto };
|
TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto };
|
||||||
_details.setText(st::normalFont, lng_date_and_duration(lt_date, d, lt_duration, formatDurationText(_data->duration)), opts);
|
_details.setText(st::normalFont, lng_date_and_duration(lt_date, d, lt_duration, formatDurationText(_data->voice()->duration)), opts);
|
||||||
_details.setLink(1, TextLinkPtr(new MessageLink(parent)));
|
_details.setLink(1, TextLinkPtr(new MessageLink(parent)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewAudio::initDimensions() {
|
void LayoutOverviewVoice::initDimensions() {
|
||||||
_maxw = st::profileMaxWidth;
|
_maxw = st::profileMaxWidth;
|
||||||
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() + st::lineWidth;
|
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() + st::lineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
void LayoutOverviewVoice::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||||
bool selected = (selection == FullSelection);
|
bool selected = (selection == FullSelection);
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(_parent);
|
||||||
|
@ -666,7 +668,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
void LayoutOverviewVoice::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||||
bool loaded = _data->loaded();
|
bool loaded = _data->loaded();
|
||||||
|
|
||||||
bool showPause = updateStatusText();
|
bool showPause = updateStatusText();
|
||||||
|
@ -696,7 +698,7 @@ void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewAudio::updateName() const {
|
void LayoutOverviewVoice::updateName() const {
|
||||||
int32 version = 0;
|
int32 version = 0;
|
||||||
if (HistoryForwarded *fwd = _parent->toHistoryForwarded()) {
|
if (HistoryForwarded *fwd = _parent->toHistoryForwarded()) {
|
||||||
_name.setText(st::semiboldFont, lang(lng_forwarded_from) + ' ' + App::peerName(fwd->fromForwarded()), _textNameOptions);
|
_name.setText(st::semiboldFont, lang(lng_forwarded_from) + ' ' + App::peerName(fwd->fromForwarded()), _textNameOptions);
|
||||||
|
@ -708,7 +710,7 @@ void LayoutOverviewAudio::updateName() const {
|
||||||
_nameVersion = version;
|
_nameVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayoutOverviewAudio::updateStatusText() const {
|
bool LayoutOverviewVoice::updateStatusText() const {
|
||||||
bool showPause = false;
|
bool showPause = false;
|
||||||
int32 statusSize = 0, realDuration = 0;
|
int32 statusSize = 0, realDuration = 0;
|
||||||
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
|
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
|
||||||
|
@ -733,7 +735,7 @@ bool LayoutOverviewAudio::updateStatusText() const {
|
||||||
statusSize = FileStatusSizeReady;
|
statusSize = FileStatusSizeReady;
|
||||||
}
|
}
|
||||||
if (statusSize != _statusSize) {
|
if (statusSize != _statusSize) {
|
||||||
setStatusSize(statusSize, _data->size, _data->duration, realDuration);
|
setStatusSize(statusSize, _data->size, _data->voice()->duration, realDuration);
|
||||||
}
|
}
|
||||||
return showPause;
|
return showPause;
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,9 +349,9 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LayoutOverviewAudio : public LayoutAbstractFileItem {
|
class LayoutOverviewVoice : public LayoutAbstractFileItem {
|
||||||
public:
|
public:
|
||||||
LayoutOverviewAudio(AudioData *audio, HistoryItem *parent);
|
LayoutOverviewVoice(DocumentData *voice, HistoryItem *parent);
|
||||||
|
|
||||||
virtual void initDimensions();
|
virtual void initDimensions();
|
||||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||||
|
@ -372,7 +372,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioData *_data;
|
DocumentData *_data;
|
||||||
TextLinkPtr _namel;
|
TextLinkPtr _namel;
|
||||||
|
|
||||||
mutable Text _name, _details;
|
mutable Text _name, _details;
|
||||||
|
|
|
@ -198,10 +198,11 @@ FileLoadTask::FileLoadTask(const QImage &image, PrepareMediaType type, const Fil
|
||||||
, _result(0) {
|
, _result(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileLoadTask::FileLoadTask(const QByteArray &audio, int32 duration, const FileLoadTo &to) : _id(MTP::nonce<uint64>())
|
FileLoadTask::FileLoadTask(const QByteArray &voice, int32 duration, const VoiceWaveform &waveform, const FileLoadTo &to) : _id(MTP::nonce<uint64>())
|
||||||
, _to(to)
|
, _to(to)
|
||||||
, _content(audio)
|
, _content(voice)
|
||||||
, _duration(duration)
|
, _duration(duration)
|
||||||
|
, _waveform(waveform)
|
||||||
, _type(PrepareAudio)
|
, _type(PrepareAudio)
|
||||||
, _confirm(FileLoadNoForceConfirm)
|
, _confirm(FileLoadNoForceConfirm)
|
||||||
, _result(0) {
|
, _result(0) {
|
||||||
|
@ -220,7 +221,7 @@ void FileLoadTask::process() {
|
||||||
QString thumbname = "thumb.jpg";
|
QString thumbname = "thumb.jpg";
|
||||||
QByteArray thumbdata;
|
QByteArray thumbdata;
|
||||||
|
|
||||||
bool animated = false;
|
bool animated = false, song = false, gif = false, voice = (_type == PrepareAudio);
|
||||||
QImage fullimage = _image;
|
QImage fullimage = _image;
|
||||||
|
|
||||||
if (!_filepath.isEmpty()) {
|
if (!_filepath.isEmpty()) {
|
||||||
|
@ -232,23 +233,24 @@ void FileLoadTask::process() {
|
||||||
filesize = info.size();
|
filesize = info.size();
|
||||||
filemime = mimeTypeForFile(info).name();
|
filemime = mimeTypeForFile(info).name();
|
||||||
filename = info.fileName();
|
filename = info.fileName();
|
||||||
if (filesize <= MaxUploadPhotoSize && _type != PrepareAudio) {
|
if (filesize <= MaxUploadPhotoSize && !voice) {
|
||||||
bool opaque = (filemime != stickerMime);
|
bool opaque = (filemime != stickerMime);
|
||||||
fullimage = App::readImage(_filepath, 0, opaque, &animated);
|
fullimage = App::readImage(_filepath, 0, opaque, &animated);
|
||||||
}
|
}
|
||||||
} else if (!_content.isEmpty()) {
|
} else if (!_content.isEmpty()) {
|
||||||
filesize = _content.size();
|
filesize = _content.size();
|
||||||
|
if (voice) {
|
||||||
|
filename = filedialogDefaultName(qsl("audio"), qsl(".ogg"), QString(), true);
|
||||||
|
filemime = "audio/ogg";
|
||||||
|
} else {
|
||||||
MimeType mimeType = mimeTypeForData(_content);
|
MimeType mimeType = mimeTypeForData(_content);
|
||||||
filemime = mimeType.name();
|
filemime = mimeType.name();
|
||||||
if (filesize <= MaxUploadPhotoSize && _type != PrepareAudio) {
|
if (filesize <= MaxUploadPhotoSize && !voice) {
|
||||||
bool opaque = (filemime != stickerMime);
|
bool opaque = (filemime != stickerMime);
|
||||||
fullimage = App::readImage(_content, 0, opaque, &animated);
|
fullimage = App::readImage(_content, 0, opaque, &animated);
|
||||||
}
|
}
|
||||||
if (filemime == "image/jpeg") {
|
if (filemime == "image/jpeg") {
|
||||||
filename = filedialogDefaultName(qsl("image"), qsl(".jpg"), QString(), true);
|
filename = filedialogDefaultName(qsl("image"), qsl(".jpg"), QString(), true);
|
||||||
} else if (_type == PrepareAudio) {
|
|
||||||
filename = filedialogDefaultName(qsl("audio"), qsl(".ogg"), QString(), true);
|
|
||||||
filemime = "audio/ogg";
|
|
||||||
} else {
|
} else {
|
||||||
QString ext;
|
QString ext;
|
||||||
QStringList patterns = mimeType.globPatterns();
|
QStringList patterns = mimeType.globPatterns();
|
||||||
|
@ -257,6 +259,7 @@ void FileLoadTask::process() {
|
||||||
}
|
}
|
||||||
filename = filedialogDefaultName(qsl("file"), ext, QString(), true);
|
filename = filedialogDefaultName(qsl("file"), ext, QString(), true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (!_image.isNull()) {
|
} else if (!_image.isNull()) {
|
||||||
_image = QImage();
|
_image = QImage();
|
||||||
|
|
||||||
|
@ -292,10 +295,8 @@ void FileLoadTask::process() {
|
||||||
MTPPhotoSize thumbSize(MTP_photoSizeEmpty(MTP_string("")));
|
MTPPhotoSize thumbSize(MTP_photoSizeEmpty(MTP_string("")));
|
||||||
MTPPhoto photo(MTP_photoEmpty(MTP_long(0)));
|
MTPPhoto photo(MTP_photoEmpty(MTP_long(0)));
|
||||||
MTPDocument document(MTP_documentEmpty(MTP_long(0)));
|
MTPDocument document(MTP_documentEmpty(MTP_long(0)));
|
||||||
MTPAudio audio(MTP_audioEmpty(MTP_long(0)));
|
|
||||||
|
|
||||||
bool song = false, gif = false;
|
if (!voice) {
|
||||||
if (_type != PrepareAudio) {
|
|
||||||
if (filemime == qstr("audio/mp3") || filemime == qstr("audio/m4a") || filemime == qstr("audio/aac") || filemime == qstr("audio/ogg") || filemime == qstr("audio/flac") ||
|
if (filemime == qstr("audio/mp3") || filemime == qstr("audio/m4a") || filemime == qstr("audio/aac") || filemime == qstr("audio/ogg") || filemime == qstr("audio/flac") ||
|
||||||
filename.endsWith(qstr(".mp3"), Qt::CaseInsensitive) || filename.endsWith(qstr(".m4a"), Qt::CaseInsensitive) ||
|
filename.endsWith(qstr(".mp3"), Qt::CaseInsensitive) || filename.endsWith(qstr(".m4a"), Qt::CaseInsensitive) ||
|
||||||
filename.endsWith(qstr(".aac"), Qt::CaseInsensitive) || filename.endsWith(qstr(".ogg"), Qt::CaseInsensitive) ||
|
filename.endsWith(qstr(".aac"), Qt::CaseInsensitive) || filename.endsWith(qstr(".ogg"), Qt::CaseInsensitive) ||
|
||||||
|
@ -358,7 +359,7 @@ void FileLoadTask::process() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fullimage.isNull() && fullimage.width() > 0 && !song && !gif) {
|
if (!fullimage.isNull() && fullimage.width() > 0 && !song && !gif && !voice) {
|
||||||
int32 w = fullimage.width(), h = fullimage.height();
|
int32 w = fullimage.width(), h = fullimage.height();
|
||||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
|
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
|
||||||
|
|
||||||
|
@ -408,8 +409,10 @@ void FileLoadTask::process() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_type == PrepareAudio) {
|
if (voice) {
|
||||||
audio = MTP_audio(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_int(_duration), MTP_string(filemime), MTP_int(filesize), MTP_int(MTP::maindc()));
|
attributes[0] = MTP_documentAttributeAudio(MTP_int(MTPDdocumentAttributeAudio::flag_voice | MTPDdocumentAttributeAudio::flag_waveform), MTP_int(_duration), MTPstring(), MTPstring(), MTP_string(documentWaveformEncode5bit(_waveform)));
|
||||||
|
attributes.resize(1);
|
||||||
|
document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
|
||||||
} else {
|
} else {
|
||||||
document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
|
document = MTP_document(MTP_long(_id), MTP_long(0), MTP_int(unixtime()), MTP_string(filemime), MTP_int(filesize), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
|
||||||
if (photo.type() == mtpc_photoEmpty) {
|
if (photo.type() == mtpc_photoEmpty) {
|
||||||
|
@ -431,7 +434,6 @@ void FileLoadTask::process() {
|
||||||
_result->thumb = thumb;
|
_result->thumb = thumb;
|
||||||
|
|
||||||
_result->photo = photo;
|
_result->photo = photo;
|
||||||
_result->audio = audio;
|
|
||||||
_result->document = document;
|
_result->document = document;
|
||||||
_result->photoThumbs = photoThumbs;
|
_result->photoThumbs = photoThumbs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ typedef QList<ToPrepareMedia> ToPrepareMedias;
|
||||||
|
|
||||||
typedef QMap<int32, QByteArray> UploadFileParts;
|
typedef QMap<int32, QByteArray> UploadFileParts;
|
||||||
struct ReadyLocalMedia {
|
struct ReadyLocalMedia {
|
||||||
ReadyLocalMedia(PrepareMediaType type, const QString &file, const QString &filename, int32 filesize, const QByteArray &data, const uint64 &id, const uint64 &thumbId, const QString &thumbExt, const PeerId &peer, const MTPPhoto &photo, const MTPAudio &audio, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, const QByteArray &jpeg, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) :
|
ReadyLocalMedia(PrepareMediaType type, const QString &file, const QString &filename, int32 filesize, const QByteArray &data, const uint64 &id, const uint64 &thumbId, const QString &thumbExt, const PeerId &peer, const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, const QByteArray &jpeg, bool broadcast, bool ctrlShiftEnter, MsgId replyTo) :
|
||||||
replyTo(replyTo), type(type), file(file), filename(filename), filesize(filesize), data(data), thumbExt(thumbExt), id(id), thumbId(thumbId), peer(peer), photo(photo), document(document), audio(audio), photoThumbs(photoThumbs), broadcast(broadcast), ctrlShiftEnter(ctrlShiftEnter) {
|
replyTo(replyTo), type(type), file(file), filename(filename), filesize(filesize), data(data), thumbExt(thumbExt), id(id), thumbId(thumbId), peer(peer), photo(photo), document(document), photoThumbs(photoThumbs), broadcast(broadcast), ctrlShiftEnter(ctrlShiftEnter) {
|
||||||
if (!jpeg.isEmpty()) {
|
if (!jpeg.isEmpty()) {
|
||||||
int32 size = jpeg.size();
|
int32 size = jpeg.size();
|
||||||
for (int32 i = 0, part = 0; i < size; i += UploadPartSize, ++part) {
|
for (int32 i = 0, part = 0; i < size; i += UploadPartSize, ++part) {
|
||||||
|
@ -74,7 +74,6 @@ struct ReadyLocalMedia {
|
||||||
|
|
||||||
MTPPhoto photo;
|
MTPPhoto photo;
|
||||||
MTPDocument document;
|
MTPDocument document;
|
||||||
MTPAudio audio;
|
|
||||||
PreparedPhotoThumbs photoThumbs;
|
PreparedPhotoThumbs photoThumbs;
|
||||||
UploadFileParts parts;
|
UploadFileParts parts;
|
||||||
QByteArray jpeg_md5;
|
QByteArray jpeg_md5;
|
||||||
|
@ -203,7 +202,6 @@ struct FileLoadResult {
|
||||||
QPixmap thumb;
|
QPixmap thumb;
|
||||||
|
|
||||||
MTPPhoto photo;
|
MTPPhoto photo;
|
||||||
MTPAudio audio;
|
|
||||||
MTPDocument document;
|
MTPDocument document;
|
||||||
|
|
||||||
PreparedPhotoThumbs photoThumbs;
|
PreparedPhotoThumbs photoThumbs;
|
||||||
|
@ -248,7 +246,7 @@ public:
|
||||||
FileLoadTask(const QString &filepath, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm);
|
FileLoadTask(const QString &filepath, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm);
|
||||||
FileLoadTask(const QByteArray &content, PrepareMediaType type, const FileLoadTo &to);
|
FileLoadTask(const QByteArray &content, PrepareMediaType type, const FileLoadTo &to);
|
||||||
FileLoadTask(const QImage &image, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &originalText = QString());
|
FileLoadTask(const QImage &image, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &originalText = QString());
|
||||||
FileLoadTask(const QByteArray &audio, int32 duration, const FileLoadTo &to);
|
FileLoadTask(const QByteArray &voice, int32 duration, const VoiceWaveform &waveform, const FileLoadTo &to);
|
||||||
|
|
||||||
uint64 fileid() const {
|
uint64 fileid() const {
|
||||||
return _id;
|
return _id;
|
||||||
|
@ -265,6 +263,7 @@ protected:
|
||||||
QImage _image;
|
QImage _image;
|
||||||
QByteArray _content;
|
QByteArray _content;
|
||||||
int32 _duration;
|
int32 _duration;
|
||||||
|
VoiceWaveform _waveform;
|
||||||
PrepareMediaType _type;
|
PrepareMediaType _type;
|
||||||
FileLoadForceConfirmType _confirm;
|
FileLoadForceConfirmType _confirm;
|
||||||
QString _originalText;
|
QString _originalText;
|
||||||
|
|
|
@ -2785,6 +2785,77 @@ namespace Local {
|
||||||
return _storageWebFilesSize;
|
return _storageWebFilesSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CountWaveformTask : public Task {
|
||||||
|
public:
|
||||||
|
CountWaveformTask(DocumentData *doc)
|
||||||
|
: _doc(doc)
|
||||||
|
, _loc(doc->location(true))
|
||||||
|
, _data(doc->data())
|
||||||
|
, _wavemax(0) {
|
||||||
|
if (_data.isEmpty() && !_loc.accessEnable()) {
|
||||||
|
_doc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void process() {
|
||||||
|
if (!_doc) return;
|
||||||
|
|
||||||
|
_waveform = audioCountWaveform(_loc, _data);
|
||||||
|
uchar wavemax = 0;
|
||||||
|
for (int32 i = 0, l = _waveform.size(); i < l; ++i) {
|
||||||
|
uchar waveat = _waveform.at(i);
|
||||||
|
if (wavemax < waveat) wavemax = waveat;
|
||||||
|
}
|
||||||
|
_wavemax = wavemax;
|
||||||
|
}
|
||||||
|
void finish() {
|
||||||
|
if (VoiceData *voice = _doc ? _doc->voice() : 0) {
|
||||||
|
if (!_waveform.isEmpty()) {
|
||||||
|
voice->waveform = _waveform;
|
||||||
|
voice->wavemax = _wavemax;
|
||||||
|
}
|
||||||
|
if (voice->waveform.isEmpty()) {
|
||||||
|
voice->waveform.resize(1);
|
||||||
|
voice->waveform[0] = -2;
|
||||||
|
voice->wavemax = 0;
|
||||||
|
} else if (voice->waveform[0] < 0) {
|
||||||
|
voice->waveform[0] = -2;
|
||||||
|
voice->wavemax = 0;
|
||||||
|
}
|
||||||
|
const DocumentItems &items(App::documentItems());
|
||||||
|
DocumentItems::const_iterator i = items.constFind(_doc);
|
||||||
|
if (i != items.cend()) {
|
||||||
|
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
|
||||||
|
Ui::repaintHistoryItem(j.key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual ~CountWaveformTask() {
|
||||||
|
if (_data.isEmpty() && _doc) {
|
||||||
|
_loc.accessDisable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DocumentData *_doc;
|
||||||
|
FileLocation _loc;
|
||||||
|
QByteArray _data;
|
||||||
|
VoiceWaveform _waveform;
|
||||||
|
char _wavemax;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void countVoiceWaveform(DocumentData *document) {
|
||||||
|
if (VoiceData *voice = document->voice()) {
|
||||||
|
if (_localLoader) {
|
||||||
|
voice->waveform.resize(1 + sizeof(TaskId));
|
||||||
|
voice->waveform[0] = -1; // counting
|
||||||
|
TaskId taskId = _localLoader->addTask(new CountWaveformTask(document));
|
||||||
|
memcpy(voice->waveform.data() + 1, &taskId, sizeof(taskId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cancelTask(TaskId id) {
|
void cancelTask(TaskId id) {
|
||||||
if (_localLoader) {
|
if (_localLoader) {
|
||||||
_localLoader->cancelTask(id);
|
_localLoader->cancelTask(id);
|
||||||
|
|
|
@ -144,6 +144,8 @@ namespace Local {
|
||||||
int32 hasWebFiles();
|
int32 hasWebFiles();
|
||||||
qint64 storageWebFilesSize();
|
qint64 storageWebFilesSize();
|
||||||
|
|
||||||
|
void countVoiceWaveform(DocumentData *document);
|
||||||
|
|
||||||
void cancelTask(TaskId id);
|
void cancelTask(TaskId id);
|
||||||
|
|
||||||
void writeStickers();
|
void writeStickers();
|
||||||
|
|
|
@ -1124,9 +1124,9 @@ bool MainWidget::kickParticipantFail(ChatData *chat, const RPCError &error) {
|
||||||
|
|
||||||
void MainWidget::checkPeerHistory(PeerData *peer) {
|
void MainWidget::checkPeerHistory(PeerData *peer) {
|
||||||
if (peer->isChannel() && !peer->isMegagroup()) {
|
if (peer->isChannel() && !peer->isMegagroup()) {
|
||||||
MTP::send(MTPchannels_GetImportantHistory(peer->asChannel()->inputChannel, MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
|
MTP::send(MTPchannels_GetImportantHistory(peer->asChannel()->inputChannel, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
|
||||||
} else {
|
} else {
|
||||||
MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
|
MTP::send(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::checkedHistory, peer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1479,9 +1479,9 @@ void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case OverviewPhotos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaPhotos, lang(lng_media_type_photos))), SIGNAL(clicked()), this, SLOT(onPhotosSelect())); break;
|
case OverviewPhotos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaPhotos, lang(lng_media_type_photos))), SIGNAL(clicked()), this, SLOT(onPhotosSelect())); break;
|
||||||
case OverviewVideos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaVideos, lang(lng_media_type_videos))), SIGNAL(clicked()), this, SLOT(onVideosSelect())); break;
|
case OverviewVideos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaVideos, lang(lng_media_type_videos))), SIGNAL(clicked()), this, SLOT(onVideosSelect())); break;
|
||||||
case OverviewAudioDocuments: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaSongs, lang(lng_media_type_songs))), SIGNAL(clicked()), this, SLOT(onSongsSelect())); break;
|
case OverviewMusicFiles: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaSongs, lang(lng_media_type_songs))), SIGNAL(clicked()), this, SLOT(onSongsSelect())); break;
|
||||||
case OverviewDocuments: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaDocuments, lang(lng_media_type_files))), SIGNAL(clicked()), this, SLOT(onDocumentsSelect())); break;
|
case OverviewFiles: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaDocuments, lang(lng_media_type_files))), SIGNAL(clicked()), this, SLOT(onDocumentsSelect())); break;
|
||||||
case OverviewAudios: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaAudios, lang(lng_media_type_audios))), SIGNAL(clicked()), this, SLOT(onAudiosSelect())); break;
|
case OverviewVoiceFiles: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaAudios, lang(lng_media_type_audios))), SIGNAL(clicked()), this, SLOT(onAudiosSelect())); break;
|
||||||
case OverviewLinks: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaLinks, lang(lng_media_type_links))), SIGNAL(clicked()), this, SLOT(onLinksSelect())); break;
|
case OverviewLinks: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaLinks, lang(lng_media_type_links))), SIGNAL(clicked()), this, SLOT(onLinksSelect())); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1709,24 +1709,6 @@ void MainWidget::videoLoadRetry() {
|
||||||
if (video) video->save(failedFileName);
|
if (video) video->save(failedFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::audioLoadProgress(FileLoader *loader) {
|
|
||||||
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
|
|
||||||
if (!l) return;
|
|
||||||
|
|
||||||
AudioData *audio = App::audio(l->objId());
|
|
||||||
if (audio->loaded()) {
|
|
||||||
audio->performActionOnLoad();
|
|
||||||
}
|
|
||||||
|
|
||||||
const AudioItems &items(App::audioItems());
|
|
||||||
AudioItems::const_iterator i = items.constFind(audio);
|
|
||||||
if (i != items.cend()) {
|
|
||||||
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
|
|
||||||
Ui::repaintHistoryItem(j.key());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
||||||
AudioMsgId playing;
|
AudioMsgId playing;
|
||||||
AudioPlayerState state = AudioPlayerStopped;
|
AudioPlayerState state = AudioPlayerStopped;
|
||||||
|
@ -1734,7 +1716,7 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
||||||
if (playing == audioId && state == AudioPlayerStoppedAtStart) {
|
if (playing == audioId && state == AudioPlayerStoppedAtStart) {
|
||||||
audioPlayer()->clearStoppedAtStart(audioId);
|
audioPlayer()->clearStoppedAtStart(audioId);
|
||||||
|
|
||||||
AudioData *audio = audioId.audio;
|
DocumentData *audio = audioId.audio;
|
||||||
QString already = audio->already(true);
|
QString already = audio->already(true);
|
||||||
if (already.isEmpty() && !audio->data().isEmpty()) {
|
if (already.isEmpty() && !audio->data().isEmpty()) {
|
||||||
bool mp3 = (audio->mime == qstr("audio/mp3"));
|
bool mp3 = (audio->mime == qstr("audio/mp3"));
|
||||||
|
@ -1746,7 +1728,7 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
||||||
f.close();
|
f.close();
|
||||||
already = filename;
|
already = filename;
|
||||||
audio->setLocation(FileLocation(StorageFilePartial, filename));
|
audio->setLocation(FileLocation(StorageFilePartial, filename));
|
||||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputAudioFileLocation), audio->dc, audio->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
Local::writeFileLocation(mediaKey(AudioFileLocation, audio->dc, audio->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1794,7 +1776,7 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
|
||||||
f.close();
|
f.close();
|
||||||
already = filename;
|
already = filename;
|
||||||
document->setLocation(FileLocation(StorageFilePartial, filename));
|
document->setLocation(FileLocation(StorageFilePartial, filename));
|
||||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputDocumentFileLocation), document->dc, document->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
Local::writeFileLocation(mediaKey(DocumentFileLocation, document->dc, document->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1831,24 +1813,6 @@ void MainWidget::hidePlayer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::audioLoadFailed(FileLoader *loader, bool started) {
|
|
||||||
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
|
|
||||||
if (!l) return;
|
|
||||||
|
|
||||||
loadFailed(l, started, SLOT(audioLoadRetry()));
|
|
||||||
AudioData *audio = App::audio(l->objId());
|
|
||||||
if (audio) {
|
|
||||||
if (audio->loading()) audio->cancel();
|
|
||||||
audio->status = FileDownloadFailed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::audioLoadRetry() {
|
|
||||||
Ui::hideLayer();
|
|
||||||
AudioData *audio = App::audio(failedObjId);
|
|
||||||
if (audio) audio->save(failedFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::documentLoadProgress(FileLoader *loader) {
|
void MainWidget::documentLoadProgress(FileLoader *loader) {
|
||||||
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
|
mtpFileLoader *l = loader ? loader->mtpLoader() : 0;
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
|
@ -1915,9 +1879,9 @@ void MainWidget::inlineResultLoadFailed(FileLoader *loader, bool started) {
|
||||||
//Ui::repaintInlineItem();
|
//Ui::repaintInlineItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::audioMarkRead(AudioData *data) {
|
void MainWidget::audioMarkRead(DocumentData *data) {
|
||||||
const AudioItems &items(App::audioItems());
|
const DocumentItems &items(App::documentItems());
|
||||||
AudioItems::const_iterator i = items.constFind(data);
|
DocumentItems::const_iterator i = items.constFind(data);
|
||||||
if (i != items.cend()) {
|
if (i != items.cend()) {
|
||||||
mediaMarkRead(i.value());
|
mediaMarkRead(i.value());
|
||||||
}
|
}
|
||||||
|
@ -2428,7 +2392,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||||
if (overview && overview->peer() == peer) {
|
if (overview && overview->peer() == peer) {
|
||||||
if (overview->type() != type) {
|
if (overview->type() != type) {
|
||||||
overview->switchType(type);
|
overview->switchType(type);
|
||||||
} else if (type == OverviewAudioDocuments) { // hack for player
|
} else if (type == OverviewMusicFiles) { // hack for player
|
||||||
showBackFromStack();
|
showBackFromStack();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2872,17 +2836,17 @@ void MainWidget::onVideosSelect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::onSongsSelect() {
|
void MainWidget::onSongsSelect() {
|
||||||
if (overview) overview->switchType(OverviewAudioDocuments);
|
if (overview) overview->switchType(OverviewMusicFiles);
|
||||||
_mediaType.hideStart();
|
_mediaType.hideStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::onDocumentsSelect() {
|
void MainWidget::onDocumentsSelect() {
|
||||||
if (overview) overview->switchType(OverviewDocuments);
|
if (overview) overview->switchType(OverviewFiles);
|
||||||
_mediaType.hideStart();
|
_mediaType.hideStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::onAudiosSelect() {
|
void MainWidget::onAudiosSelect() {
|
||||||
if (overview) overview->switchType(OverviewAudios);
|
if (overview) overview->switchType(OverviewVoiceFiles);
|
||||||
_mediaType.hideStart();
|
_mediaType.hideStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -375,7 +375,7 @@ public:
|
||||||
void cancelForwarding();
|
void cancelForwarding();
|
||||||
void finishForwarding(History *hist, bool broadcast); // send them
|
void finishForwarding(History *hist, bool broadcast); // send them
|
||||||
|
|
||||||
void audioMarkRead(AudioData *data);
|
void audioMarkRead(DocumentData *data);
|
||||||
void videoMarkRead(VideoData *data);
|
void videoMarkRead(VideoData *data);
|
||||||
void mediaMarkRead(const HistoryItemsMap &items);
|
void mediaMarkRead(const HistoryItemsMap &items);
|
||||||
|
|
||||||
|
@ -448,9 +448,6 @@ public slots:
|
||||||
void videoLoadProgress(FileLoader *loader);
|
void videoLoadProgress(FileLoader *loader);
|
||||||
void videoLoadFailed(FileLoader *loader, bool started);
|
void videoLoadFailed(FileLoader *loader, bool started);
|
||||||
void videoLoadRetry();
|
void videoLoadRetry();
|
||||||
void audioLoadProgress(FileLoader *loader);
|
|
||||||
void audioLoadFailed(FileLoader *loader, bool started);
|
|
||||||
void audioLoadRetry();
|
|
||||||
void audioPlayProgress(const AudioMsgId &audioId);
|
void audioPlayProgress(const AudioMsgId &audioId);
|
||||||
void documentLoadProgress(FileLoader *loader);
|
void documentLoadProgress(FileLoader *loader);
|
||||||
void documentLoadFailed(FileLoader *loader, bool started);
|
void documentLoadFailed(FileLoader *loader, bool started);
|
||||||
|
|
|
@ -363,7 +363,7 @@ void MediaView::updateControls() {
|
||||||
_dateNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height);
|
_dateNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height);
|
||||||
}
|
}
|
||||||
updateHeader();
|
updateHeader();
|
||||||
if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewDocuments))) {
|
if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewFiles))) {
|
||||||
_leftNavVisible = (_index > 0) || (_index == 0 && (
|
_leftNavVisible = (_index > 0) || (_index == 0 && (
|
||||||
(!_msgmigrated && _history && _history->overview[_overview].size() < _history->overviewCount(_overview)) ||
|
(!_msgmigrated && _history && _history->overview[_overview].size() < _history->overviewCount(_overview)) ||
|
||||||
(_msgmigrated && _migrated && _migrated->overview[_overview].size() < _migrated->overviewCount(_overview)) ||
|
(_msgmigrated && _migrated && _migrated->overview[_overview].size() < _migrated->overviewCount(_overview)) ||
|
||||||
|
@ -865,7 +865,7 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
|
||||||
_canForward = _msgid > 0;
|
_canForward = _msgid > 0;
|
||||||
_canDelete = context ? context->canDelete() : false;
|
_canDelete = context ? context->canDelete() : false;
|
||||||
if (_history) {
|
if (_history) {
|
||||||
_overview = OverviewDocuments;
|
_overview = OverviewFiles;
|
||||||
findCurrent();
|
findCurrent();
|
||||||
}
|
}
|
||||||
displayDocument(doc, context);
|
displayDocument(doc, context);
|
||||||
|
@ -1486,7 +1486,7 @@ void MediaView::keyPressEvent(QKeyEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaView::moveToNext(int32 delta) {
|
void MediaView::moveToNext(int32 delta) {
|
||||||
if (_index < 0 || (_history && _overview != OverviewPhotos && _overview != OverviewDocuments) || (_overview == OverviewCount && !_user)) {
|
if (_index < 0 || (_history && _overview != OverviewPhotos && _overview != OverviewFiles) || (_overview == OverviewCount && !_user)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_msgmigrated && !_history->overviewLoaded(_overview)) {
|
if (_msgmigrated && !_history->overviewLoaded(_overview)) {
|
||||||
|
@ -1515,7 +1515,7 @@ void MediaView::moveToNext(int32 delta) {
|
||||||
if (HistoryMedia *media = item->getMedia()) {
|
if (HistoryMedia *media = item->getMedia()) {
|
||||||
switch (media->type()) {
|
switch (media->type()) {
|
||||||
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
|
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
|
||||||
case MediaTypeDocument:
|
case MediaTypeFile:
|
||||||
case MediaTypeGif:
|
case MediaTypeGif:
|
||||||
case MediaTypeSticker: displayDocument(media->getDocument(), item); preloadData(delta); break;
|
case MediaTypeSticker: displayDocument(media->getDocument(), item); preloadData(delta); break;
|
||||||
}
|
}
|
||||||
|
@ -1562,7 +1562,7 @@ void MediaView::preloadData(int32 delta) {
|
||||||
if (HistoryMedia *media = item->getMedia()) {
|
if (HistoryMedia *media = item->getMedia()) {
|
||||||
switch (media->type()) {
|
switch (media->type()) {
|
||||||
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break;
|
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break;
|
||||||
case MediaTypeDocument:
|
case MediaTypeFile:
|
||||||
case MediaTypeGif:
|
case MediaTypeGif:
|
||||||
case MediaTypeSticker: media->getDocument()->forget(); break;
|
case MediaTypeSticker: media->getDocument()->forget(); break;
|
||||||
}
|
}
|
||||||
|
@ -1587,7 +1587,7 @@ void MediaView::preloadData(int32 delta) {
|
||||||
if (HistoryMedia *media = item->getMedia()) {
|
if (HistoryMedia *media = item->getMedia()) {
|
||||||
switch (media->type()) {
|
switch (media->type()) {
|
||||||
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->download(); break;
|
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->download(); break;
|
||||||
case MediaTypeDocument:
|
case MediaTypeFile:
|
||||||
case MediaTypeGif: {
|
case MediaTypeGif: {
|
||||||
DocumentData *doc = media->getDocument();
|
DocumentData *doc = media->getDocument();
|
||||||
doc->thumb->load();
|
doc->thumb->load();
|
||||||
|
|
|
@ -368,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||||
mtpTypeId(mtpc_invokeWithLayer18),
|
mtpTypeId(mtpc_invokeWithLayer18),
|
||||||
};
|
};
|
||||||
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
static const uint32 mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||||
static const mtpPrime mtpCurrentLayer = 45;
|
static const mtpPrime mtpCurrentLayer = 46;
|
||||||
|
|
||||||
template <typename bareT>
|
template <typename bareT>
|
||||||
class MTPBoxed : public bareT {
|
class MTPBoxed : public bareT {
|
||||||
|
|
|
@ -388,7 +388,7 @@ bool mtpFileLoader::loadPart() {
|
||||||
} else {
|
} else {
|
||||||
switch (_locationType) {
|
switch (_locationType) {
|
||||||
case VideoFileLocation: loc = MTP_inputVideoFileLocation(MTP_long(_id), MTP_long(_access)); break;
|
case VideoFileLocation: loc = MTP_inputVideoFileLocation(MTP_long(_id), MTP_long(_access)); break;
|
||||||
case AudioFileLocation: loc = MTP_inputAudioFileLocation(MTP_long(_id), MTP_long(_access)); break;
|
case AudioFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(_id), MTP_long(_access)); break;
|
||||||
case DocumentFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(_id), MTP_long(_access)); break;
|
case DocumentFileLocation: loc = MTP_inputDocumentFileLocation(MTP_long(_id), MTP_long(_access)); break;
|
||||||
default: cancel(true); return false; break;
|
default: cancel(true); return false; break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,23 +30,6 @@ enum LocationType {
|
||||||
AudioFileLocation = 0x74dc404d, // mtpc_inputAudioFileLocation
|
AudioFileLocation = 0x74dc404d, // mtpc_inputAudioFileLocation
|
||||||
VideoFileLocation = 0x3d0364ec, // mtpc_inputVideoFileLocation
|
VideoFileLocation = 0x3d0364ec, // mtpc_inputVideoFileLocation
|
||||||
};
|
};
|
||||||
inline LocationType mtpToLocationType(mtpTypeId type) {
|
|
||||||
switch (type) {
|
|
||||||
case mtpc_inputDocumentFileLocation: return DocumentFileLocation;
|
|
||||||
case mtpc_inputAudioFileLocation: return AudioFileLocation;
|
|
||||||
case mtpc_inputVideoFileLocation: return VideoFileLocation;
|
|
||||||
default: return UnknownFileLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inline mtpTypeId mtpFromLocationType(LocationType type) {
|
|
||||||
switch (type) {
|
|
||||||
case DocumentFileLocation: return mtpc_inputDocumentFileLocation;
|
|
||||||
case AudioFileLocation: return mtpc_inputAudioFileLocation;
|
|
||||||
case VideoFileLocation: return mtpc_inputVideoFileLocation;
|
|
||||||
case UnknownFileLocation:
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum StorageFileType {
|
enum StorageFileType {
|
||||||
StorageFileUnknown = 0xaa963b05, // mtpc_storage_fileUnknown
|
StorageFileUnknown = 0xaa963b05, // mtpc_storage_fileUnknown
|
||||||
|
|
|
@ -693,34 +693,6 @@ void _serialize_inputMediaVideo(MTPStringLogger &to, int32 stage, int32 lev, Typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_inputMediaUploadedAudio(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ inputMediaUploadedAudio");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" file: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 1: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 2: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputMediaAudio(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ inputMediaAudio");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputMediaUploadedDocument(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_inputMediaUploadedDocument(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -928,20 +900,6 @@ void _serialize_inputEncryptedFileLocation(MTPStringLogger &to, int32 stage, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_inputAudioFileLocation(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ inputAudioFileLocation");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputDocumentFileLocation(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_inputDocumentFileLocation(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -1279,14 +1237,15 @@ void _serialize_channel(MTPStringLogger &to, int32 stage, int32 lev, Types &type
|
||||||
case 7: to.add(" verified: "); ++stages.back(); if (flag & MTPDchannel::flag_verified) { to.add("YES [ BY BIT 7 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
case 7: to.add(" verified: "); ++stages.back(); if (flag & MTPDchannel::flag_verified) { to.add("YES [ BY BIT 7 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||||
case 8: to.add(" megagroup: "); ++stages.back(); if (flag & MTPDchannel::flag_megagroup) { to.add("YES [ BY BIT 8 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
case 8: to.add(" megagroup: "); ++stages.back(); if (flag & MTPDchannel::flag_megagroup) { to.add("YES [ BY BIT 8 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
||||||
case 9: to.add(" restricted: "); ++stages.back(); if (flag & MTPDchannel::flag_restricted) { to.add("YES [ BY BIT 9 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
case 9: to.add(" restricted: "); ++stages.back(); if (flag & MTPDchannel::flag_restricted) { to.add("YES [ BY BIT 9 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||||
case 10: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 10: to.add(" invites_enabled: "); ++stages.back(); if (flag & MTPDchannel::flag_invites_enabled) { to.add("YES [ BY BIT 10 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break;
|
||||||
case 11: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 11: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 12: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 12: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 13: to.add(" username: "); ++stages.back(); if (flag & MTPDchannel::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
case 13: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 14: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 14: to.add(" username: "); ++stages.back(); if (flag & MTPDchannel::flag_username) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||||
case 15: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 15: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 16: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 16: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 17: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDchannel::flag_restriction_reason) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
case 17: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 18: to.add(" restriction_reason: "); ++stages.back(); if (flag & MTPDchannel::flag_restriction_reason) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1587,19 +1546,6 @@ void _serialize_messageMediaDocument(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_messageMediaAudio(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ messageMediaAudio");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" audio: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_messageMediaWebPage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_messageMediaWebPage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -2189,20 +2135,6 @@ void _serialize_contactBlocked(MTPStringLogger &to, int32 stage, int32 lev, Type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_contactSuggested(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ contactSuggested");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 1: to.add(" mutual_contacts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_contactStatus(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_contactStatus(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -2294,20 +2226,6 @@ void _serialize_contacts_blockedSlice(MTPStringLogger &to, int32 stage, int32 le
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_contacts_suggested(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ contacts_suggested");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 1: to.add(" users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_messages_dialogs(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_messages_dialogs(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -2458,14 +2376,6 @@ void _serialize_inputMessagesFilterDocument(MTPStringLogger &to, int32 stage, in
|
||||||
to.add("{ inputMessagesFilterDocument }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ inputMessagesFilterDocument }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_inputMessagesFilterAudio(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
to.add("{ inputMessagesFilterAudio }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputMessagesFilterAudioDocuments(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
to.add("{ inputMessagesFilterAudioDocuments }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputMessagesFilterUrl(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_inputMessagesFilterUrl(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
to.add("{ inputMessagesFilterUrl }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ inputMessagesFilterUrl }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -2474,6 +2384,14 @@ void _serialize_inputMessagesFilterGif(MTPStringLogger &to, int32 stage, int32 l
|
||||||
to.add("{ inputMessagesFilterGif }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ inputMessagesFilterGif }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_inputMessagesFilterVoice(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ inputMessagesFilterVoice }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _serialize_inputMessagesFilterMusic(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ inputMessagesFilterMusic }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_updateNewMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_updateNewMessage(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -3067,6 +2985,21 @@ void _serialize_updateBotInlineQuery(MTPStringLogger &to, int32 stage, int32 lev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_updateBotInlineSend(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ updateBotInlineSend");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" user_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" query: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 2: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_updates_state(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -3673,24 +3606,6 @@ void _serialize_messages_sentEncryptedFile(MTPStringLogger &to, int32 stage, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_inputAudioEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
to.add("{ inputAudioEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputAudio(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ inputAudio");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_inputDocumentEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_inputDocumentEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
to.add("{ inputDocumentEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ inputDocumentEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -3709,38 +3624,6 @@ void _serialize_inputDocument(MTPStringLogger &to, int32 stage, int32 lev, Types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_audioEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ audioEmpty");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_audio(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ audio");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 2: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 3: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 4: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 5: to.add(" size: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
case 6: to.add(" dc_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_documentEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_documentEmpty(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -3908,10 +3791,18 @@ void _serialize_inputPrivacyKeyStatusTimestamp(MTPStringLogger &to, int32 stage,
|
||||||
to.add("{ inputPrivacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ inputPrivacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_inputPrivacyKeyChatInvite(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ inputPrivacyKeyChatInvite }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_privacyKeyStatusTimestamp(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_privacyKeyStatusTimestamp(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
to.add("{ privacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ privacyKeyStatusTimestamp }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_privacyKeyChatInvite(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
to.add("{ privacyKeyChatInvite }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_inputPrivacyValueAllowContacts(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_inputPrivacyValueAllowContacts(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
to.add("{ inputPrivacyValueAllowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
to.add("{ inputPrivacyValueAllowContacts }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -4092,9 +3983,12 @@ void _serialize_documentAttributeAudio(MTPStringLogger &to, int32 stage, int32 l
|
||||||
to.add("\n").addSpaces(lev);
|
to.add("\n").addSpaces(lev);
|
||||||
}
|
}
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" voice: "); ++stages.back(); if (flag & MTPDdocumentAttributeAudio::flag_voice) { to.add("YES [ BY BIT 10 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 10 IN FIELD flags ]"); } break;
|
||||||
case 2: to.add(" performer: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 2: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 3: to.add(" title: "); ++stages.back(); if (flag & MTPDdocumentAttributeAudio::flag_title) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
|
||||||
|
case 4: to.add(" performer: "); ++stages.back(); if (flag & MTPDdocumentAttributeAudio::flag_performer) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 1 IN FIELD flags ]"); } break;
|
||||||
|
case 5: to.add(" waveform: "); ++stages.back(); if (flag & MTPDdocumentAttributeAudio::flag_waveform) { types.push_back(mtpc_bytes); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6373,19 +6267,6 @@ void _serialize_contacts_importContacts(MTPStringLogger &to, int32 stage, int32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _serialize_contacts_getSuggested(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
|
||||||
if (stage) {
|
|
||||||
to.add(",\n").addSpaces(lev);
|
|
||||||
} else {
|
|
||||||
to.add("{ contacts_getSuggested");
|
|
||||||
to.add("\n").addSpaces(lev);
|
|
||||||
}
|
|
||||||
switch (stage) {
|
|
||||||
case 0: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _serialize_contacts_deleteContact(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_contacts_deleteContact(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -6482,10 +6363,11 @@ void _serialize_messages_getHistory(MTPStringLogger &to, int32 stage, int32 lev,
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 2: to.add(" add_offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 2: to.add(" offset_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 3: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 3: to.add(" add_offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 4: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 4: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 5: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 5: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 6: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6539,10 +6421,11 @@ void _serialize_channels_getImportantHistory(MTPStringLogger &to, int32 stage, i
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 1: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 1: to.add(" offset_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 2: to.add(" add_offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 2: to.add(" offset_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 3: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 3: to.add(" add_offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 4: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 4: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
case 5: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
case 5: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 6: to.add(" min_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7063,6 +6946,20 @@ void _serialize_channels_deleteChannel(MTPStringLogger &to, int32 stage, int32 l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _serialize_channels_toggleInvites(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
|
if (stage) {
|
||||||
|
to.add(",\n").addSpaces(lev);
|
||||||
|
} else {
|
||||||
|
to.add("{ channels_toggleInvites");
|
||||||
|
to.add("\n").addSpaces(lev);
|
||||||
|
}
|
||||||
|
switch (stage) {
|
||||||
|
case 0: to.add(" channel: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
case 1: to.add(" enabled: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||||
|
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _serialize_messages_getChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
void _serialize_messages_getChats(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, int32 flag) {
|
||||||
if (stage) {
|
if (stage) {
|
||||||
to.add(",\n").addSpaces(lev);
|
to.add(",\n").addSpaces(lev);
|
||||||
|
@ -7678,8 +7575,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_inputMediaUploadedVideo, _serialize_inputMediaUploadedVideo);
|
_serializers.insert(mtpc_inputMediaUploadedVideo, _serialize_inputMediaUploadedVideo);
|
||||||
_serializers.insert(mtpc_inputMediaUploadedThumbVideo, _serialize_inputMediaUploadedThumbVideo);
|
_serializers.insert(mtpc_inputMediaUploadedThumbVideo, _serialize_inputMediaUploadedThumbVideo);
|
||||||
_serializers.insert(mtpc_inputMediaVideo, _serialize_inputMediaVideo);
|
_serializers.insert(mtpc_inputMediaVideo, _serialize_inputMediaVideo);
|
||||||
_serializers.insert(mtpc_inputMediaUploadedAudio, _serialize_inputMediaUploadedAudio);
|
|
||||||
_serializers.insert(mtpc_inputMediaAudio, _serialize_inputMediaAudio);
|
|
||||||
_serializers.insert(mtpc_inputMediaUploadedDocument, _serialize_inputMediaUploadedDocument);
|
_serializers.insert(mtpc_inputMediaUploadedDocument, _serialize_inputMediaUploadedDocument);
|
||||||
_serializers.insert(mtpc_inputMediaUploadedThumbDocument, _serialize_inputMediaUploadedThumbDocument);
|
_serializers.insert(mtpc_inputMediaUploadedThumbDocument, _serialize_inputMediaUploadedThumbDocument);
|
||||||
_serializers.insert(mtpc_inputMediaDocument, _serialize_inputMediaDocument);
|
_serializers.insert(mtpc_inputMediaDocument, _serialize_inputMediaDocument);
|
||||||
|
@ -7697,7 +7592,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_inputFileLocation, _serialize_inputFileLocation);
|
_serializers.insert(mtpc_inputFileLocation, _serialize_inputFileLocation);
|
||||||
_serializers.insert(mtpc_inputVideoFileLocation, _serialize_inputVideoFileLocation);
|
_serializers.insert(mtpc_inputVideoFileLocation, _serialize_inputVideoFileLocation);
|
||||||
_serializers.insert(mtpc_inputEncryptedFileLocation, _serialize_inputEncryptedFileLocation);
|
_serializers.insert(mtpc_inputEncryptedFileLocation, _serialize_inputEncryptedFileLocation);
|
||||||
_serializers.insert(mtpc_inputAudioFileLocation, _serialize_inputAudioFileLocation);
|
|
||||||
_serializers.insert(mtpc_inputDocumentFileLocation, _serialize_inputDocumentFileLocation);
|
_serializers.insert(mtpc_inputDocumentFileLocation, _serialize_inputDocumentFileLocation);
|
||||||
_serializers.insert(mtpc_inputPhotoCropAuto, _serialize_inputPhotoCropAuto);
|
_serializers.insert(mtpc_inputPhotoCropAuto, _serialize_inputPhotoCropAuto);
|
||||||
_serializers.insert(mtpc_inputPhotoCrop, _serialize_inputPhotoCrop);
|
_serializers.insert(mtpc_inputPhotoCrop, _serialize_inputPhotoCrop);
|
||||||
|
@ -7751,7 +7645,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_messageMediaContact, _serialize_messageMediaContact);
|
_serializers.insert(mtpc_messageMediaContact, _serialize_messageMediaContact);
|
||||||
_serializers.insert(mtpc_messageMediaUnsupported, _serialize_messageMediaUnsupported);
|
_serializers.insert(mtpc_messageMediaUnsupported, _serialize_messageMediaUnsupported);
|
||||||
_serializers.insert(mtpc_messageMediaDocument, _serialize_messageMediaDocument);
|
_serializers.insert(mtpc_messageMediaDocument, _serialize_messageMediaDocument);
|
||||||
_serializers.insert(mtpc_messageMediaAudio, _serialize_messageMediaAudio);
|
|
||||||
_serializers.insert(mtpc_messageMediaWebPage, _serialize_messageMediaWebPage);
|
_serializers.insert(mtpc_messageMediaWebPage, _serialize_messageMediaWebPage);
|
||||||
_serializers.insert(mtpc_messageMediaVenue, _serialize_messageMediaVenue);
|
_serializers.insert(mtpc_messageMediaVenue, _serialize_messageMediaVenue);
|
||||||
_serializers.insert(mtpc_messageActionEmpty, _serialize_messageActionEmpty);
|
_serializers.insert(mtpc_messageActionEmpty, _serialize_messageActionEmpty);
|
||||||
|
@ -7802,7 +7695,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_contact, _serialize_contact);
|
_serializers.insert(mtpc_contact, _serialize_contact);
|
||||||
_serializers.insert(mtpc_importedContact, _serialize_importedContact);
|
_serializers.insert(mtpc_importedContact, _serialize_importedContact);
|
||||||
_serializers.insert(mtpc_contactBlocked, _serialize_contactBlocked);
|
_serializers.insert(mtpc_contactBlocked, _serialize_contactBlocked);
|
||||||
_serializers.insert(mtpc_contactSuggested, _serialize_contactSuggested);
|
|
||||||
_serializers.insert(mtpc_contactStatus, _serialize_contactStatus);
|
_serializers.insert(mtpc_contactStatus, _serialize_contactStatus);
|
||||||
_serializers.insert(mtpc_contacts_link, _serialize_contacts_link);
|
_serializers.insert(mtpc_contacts_link, _serialize_contacts_link);
|
||||||
_serializers.insert(mtpc_contacts_contactsNotModified, _serialize_contacts_contactsNotModified);
|
_serializers.insert(mtpc_contacts_contactsNotModified, _serialize_contacts_contactsNotModified);
|
||||||
|
@ -7810,7 +7702,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_contacts_importedContacts, _serialize_contacts_importedContacts);
|
_serializers.insert(mtpc_contacts_importedContacts, _serialize_contacts_importedContacts);
|
||||||
_serializers.insert(mtpc_contacts_blocked, _serialize_contacts_blocked);
|
_serializers.insert(mtpc_contacts_blocked, _serialize_contacts_blocked);
|
||||||
_serializers.insert(mtpc_contacts_blockedSlice, _serialize_contacts_blockedSlice);
|
_serializers.insert(mtpc_contacts_blockedSlice, _serialize_contacts_blockedSlice);
|
||||||
_serializers.insert(mtpc_contacts_suggested, _serialize_contacts_suggested);
|
|
||||||
_serializers.insert(mtpc_messages_dialogs, _serialize_messages_dialogs);
|
_serializers.insert(mtpc_messages_dialogs, _serialize_messages_dialogs);
|
||||||
_serializers.insert(mtpc_messages_dialogsSlice, _serialize_messages_dialogsSlice);
|
_serializers.insert(mtpc_messages_dialogsSlice, _serialize_messages_dialogsSlice);
|
||||||
_serializers.insert(mtpc_messages_messages, _serialize_messages_messages);
|
_serializers.insert(mtpc_messages_messages, _serialize_messages_messages);
|
||||||
|
@ -7825,10 +7716,10 @@ namespace {
|
||||||
_serializers.insert(mtpc_inputMessagesFilterPhotoVideo, _serialize_inputMessagesFilterPhotoVideo);
|
_serializers.insert(mtpc_inputMessagesFilterPhotoVideo, _serialize_inputMessagesFilterPhotoVideo);
|
||||||
_serializers.insert(mtpc_inputMessagesFilterPhotoVideoDocuments, _serialize_inputMessagesFilterPhotoVideoDocuments);
|
_serializers.insert(mtpc_inputMessagesFilterPhotoVideoDocuments, _serialize_inputMessagesFilterPhotoVideoDocuments);
|
||||||
_serializers.insert(mtpc_inputMessagesFilterDocument, _serialize_inputMessagesFilterDocument);
|
_serializers.insert(mtpc_inputMessagesFilterDocument, _serialize_inputMessagesFilterDocument);
|
||||||
_serializers.insert(mtpc_inputMessagesFilterAudio, _serialize_inputMessagesFilterAudio);
|
|
||||||
_serializers.insert(mtpc_inputMessagesFilterAudioDocuments, _serialize_inputMessagesFilterAudioDocuments);
|
|
||||||
_serializers.insert(mtpc_inputMessagesFilterUrl, _serialize_inputMessagesFilterUrl);
|
_serializers.insert(mtpc_inputMessagesFilterUrl, _serialize_inputMessagesFilterUrl);
|
||||||
_serializers.insert(mtpc_inputMessagesFilterGif, _serialize_inputMessagesFilterGif);
|
_serializers.insert(mtpc_inputMessagesFilterGif, _serialize_inputMessagesFilterGif);
|
||||||
|
_serializers.insert(mtpc_inputMessagesFilterVoice, _serialize_inputMessagesFilterVoice);
|
||||||
|
_serializers.insert(mtpc_inputMessagesFilterMusic, _serialize_inputMessagesFilterMusic);
|
||||||
_serializers.insert(mtpc_updateNewMessage, _serialize_updateNewMessage);
|
_serializers.insert(mtpc_updateNewMessage, _serialize_updateNewMessage);
|
||||||
_serializers.insert(mtpc_updateMessageID, _serialize_updateMessageID);
|
_serializers.insert(mtpc_updateMessageID, _serialize_updateMessageID);
|
||||||
_serializers.insert(mtpc_updateDeleteMessages, _serialize_updateDeleteMessages);
|
_serializers.insert(mtpc_updateDeleteMessages, _serialize_updateDeleteMessages);
|
||||||
|
@ -7871,6 +7762,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_updateStickerSets, _serialize_updateStickerSets);
|
_serializers.insert(mtpc_updateStickerSets, _serialize_updateStickerSets);
|
||||||
_serializers.insert(mtpc_updateSavedGifs, _serialize_updateSavedGifs);
|
_serializers.insert(mtpc_updateSavedGifs, _serialize_updateSavedGifs);
|
||||||
_serializers.insert(mtpc_updateBotInlineQuery, _serialize_updateBotInlineQuery);
|
_serializers.insert(mtpc_updateBotInlineQuery, _serialize_updateBotInlineQuery);
|
||||||
|
_serializers.insert(mtpc_updateBotInlineSend, _serialize_updateBotInlineSend);
|
||||||
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
_serializers.insert(mtpc_updates_state, _serialize_updates_state);
|
||||||
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
_serializers.insert(mtpc_updates_differenceEmpty, _serialize_updates_differenceEmpty);
|
||||||
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
_serializers.insert(mtpc_updates_difference, _serialize_updates_difference);
|
||||||
|
@ -7910,12 +7802,8 @@ namespace {
|
||||||
_serializers.insert(mtpc_messages_dhConfig, _serialize_messages_dhConfig);
|
_serializers.insert(mtpc_messages_dhConfig, _serialize_messages_dhConfig);
|
||||||
_serializers.insert(mtpc_messages_sentEncryptedMessage, _serialize_messages_sentEncryptedMessage);
|
_serializers.insert(mtpc_messages_sentEncryptedMessage, _serialize_messages_sentEncryptedMessage);
|
||||||
_serializers.insert(mtpc_messages_sentEncryptedFile, _serialize_messages_sentEncryptedFile);
|
_serializers.insert(mtpc_messages_sentEncryptedFile, _serialize_messages_sentEncryptedFile);
|
||||||
_serializers.insert(mtpc_inputAudioEmpty, _serialize_inputAudioEmpty);
|
|
||||||
_serializers.insert(mtpc_inputAudio, _serialize_inputAudio);
|
|
||||||
_serializers.insert(mtpc_inputDocumentEmpty, _serialize_inputDocumentEmpty);
|
_serializers.insert(mtpc_inputDocumentEmpty, _serialize_inputDocumentEmpty);
|
||||||
_serializers.insert(mtpc_inputDocument, _serialize_inputDocument);
|
_serializers.insert(mtpc_inputDocument, _serialize_inputDocument);
|
||||||
_serializers.insert(mtpc_audioEmpty, _serialize_audioEmpty);
|
|
||||||
_serializers.insert(mtpc_audio, _serialize_audio);
|
|
||||||
_serializers.insert(mtpc_documentEmpty, _serialize_documentEmpty);
|
_serializers.insert(mtpc_documentEmpty, _serialize_documentEmpty);
|
||||||
_serializers.insert(mtpc_document, _serialize_document);
|
_serializers.insert(mtpc_document, _serialize_document);
|
||||||
_serializers.insert(mtpc_help_support, _serialize_help_support);
|
_serializers.insert(mtpc_help_support, _serialize_help_support);
|
||||||
|
@ -7935,7 +7823,9 @@ namespace {
|
||||||
_serializers.insert(mtpc_sendMessageChooseContactAction, _serialize_sendMessageChooseContactAction);
|
_serializers.insert(mtpc_sendMessageChooseContactAction, _serialize_sendMessageChooseContactAction);
|
||||||
_serializers.insert(mtpc_contacts_found, _serialize_contacts_found);
|
_serializers.insert(mtpc_contacts_found, _serialize_contacts_found);
|
||||||
_serializers.insert(mtpc_inputPrivacyKeyStatusTimestamp, _serialize_inputPrivacyKeyStatusTimestamp);
|
_serializers.insert(mtpc_inputPrivacyKeyStatusTimestamp, _serialize_inputPrivacyKeyStatusTimestamp);
|
||||||
|
_serializers.insert(mtpc_inputPrivacyKeyChatInvite, _serialize_inputPrivacyKeyChatInvite);
|
||||||
_serializers.insert(mtpc_privacyKeyStatusTimestamp, _serialize_privacyKeyStatusTimestamp);
|
_serializers.insert(mtpc_privacyKeyStatusTimestamp, _serialize_privacyKeyStatusTimestamp);
|
||||||
|
_serializers.insert(mtpc_privacyKeyChatInvite, _serialize_privacyKeyChatInvite);
|
||||||
_serializers.insert(mtpc_inputPrivacyValueAllowContacts, _serialize_inputPrivacyValueAllowContacts);
|
_serializers.insert(mtpc_inputPrivacyValueAllowContacts, _serialize_inputPrivacyValueAllowContacts);
|
||||||
_serializers.insert(mtpc_inputPrivacyValueAllowAll, _serialize_inputPrivacyValueAllowAll);
|
_serializers.insert(mtpc_inputPrivacyValueAllowAll, _serialize_inputPrivacyValueAllowAll);
|
||||||
_serializers.insert(mtpc_inputPrivacyValueAllowUsers, _serialize_inputPrivacyValueAllowUsers);
|
_serializers.insert(mtpc_inputPrivacyValueAllowUsers, _serialize_inputPrivacyValueAllowUsers);
|
||||||
|
@ -8133,7 +8023,6 @@ namespace {
|
||||||
_serializers.insert(mtpc_contacts_getStatuses, _serialize_contacts_getStatuses);
|
_serializers.insert(mtpc_contacts_getStatuses, _serialize_contacts_getStatuses);
|
||||||
_serializers.insert(mtpc_contacts_getContacts, _serialize_contacts_getContacts);
|
_serializers.insert(mtpc_contacts_getContacts, _serialize_contacts_getContacts);
|
||||||
_serializers.insert(mtpc_contacts_importContacts, _serialize_contacts_importContacts);
|
_serializers.insert(mtpc_contacts_importContacts, _serialize_contacts_importContacts);
|
||||||
_serializers.insert(mtpc_contacts_getSuggested, _serialize_contacts_getSuggested);
|
|
||||||
_serializers.insert(mtpc_contacts_deleteContact, _serialize_contacts_deleteContact);
|
_serializers.insert(mtpc_contacts_deleteContact, _serialize_contacts_deleteContact);
|
||||||
_serializers.insert(mtpc_contacts_getBlocked, _serialize_contacts_getBlocked);
|
_serializers.insert(mtpc_contacts_getBlocked, _serialize_contacts_getBlocked);
|
||||||
_serializers.insert(mtpc_contacts_exportCard, _serialize_contacts_exportCard);
|
_serializers.insert(mtpc_contacts_exportCard, _serialize_contacts_exportCard);
|
||||||
|
@ -8180,6 +8069,7 @@ namespace {
|
||||||
_serializers.insert(mtpc_channels_inviteToChannel, _serialize_channels_inviteToChannel);
|
_serializers.insert(mtpc_channels_inviteToChannel, _serialize_channels_inviteToChannel);
|
||||||
_serializers.insert(mtpc_channels_kickFromChannel, _serialize_channels_kickFromChannel);
|
_serializers.insert(mtpc_channels_kickFromChannel, _serialize_channels_kickFromChannel);
|
||||||
_serializers.insert(mtpc_channels_deleteChannel, _serialize_channels_deleteChannel);
|
_serializers.insert(mtpc_channels_deleteChannel, _serialize_channels_deleteChannel);
|
||||||
|
_serializers.insert(mtpc_channels_toggleInvites, _serialize_channels_toggleInvites);
|
||||||
_serializers.insert(mtpc_messages_getChats, _serialize_messages_getChats);
|
_serializers.insert(mtpc_messages_getChats, _serialize_messages_getChats);
|
||||||
_serializers.insert(mtpc_channels_getChannels, _serialize_channels_getChannels);
|
_serializers.insert(mtpc_channels_getChannels, _serialize_channels_getChannels);
|
||||||
_serializers.insert(mtpc_messages_getFullChat, _serialize_messages_getFullChat);
|
_serializers.insert(mtpc_messages_getFullChat, _serialize_messages_getFullChat);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -153,8 +153,6 @@ inputMediaContact#a6e45987 phone_number:string first_name:string last_name:strin
|
||||||
inputMediaUploadedVideo#82713fdf file:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
|
inputMediaUploadedVideo#82713fdf file:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
|
||||||
inputMediaUploadedThumbVideo#7780ddf9 file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
|
inputMediaUploadedThumbVideo#7780ddf9 file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
|
||||||
inputMediaVideo#936a4ebd id:InputVideo caption:string = InputMedia;
|
inputMediaVideo#936a4ebd id:InputVideo caption:string = InputMedia;
|
||||||
inputMediaUploadedAudio#4e498cab file:InputFile duration:int mime_type:string = InputMedia;
|
|
||||||
inputMediaAudio#89938781 id:InputAudio = InputMedia;
|
|
||||||
inputMediaUploadedDocument#1d89306d file:InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string = InputMedia;
|
inputMediaUploadedDocument#1d89306d file:InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string = InputMedia;
|
||||||
inputMediaUploadedThumbDocument#ad613491 file:InputFile thumb:InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string = InputMedia;
|
inputMediaUploadedThumbDocument#ad613491 file:InputFile thumb:InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string = InputMedia;
|
||||||
inputMediaDocument#1a77f29c id:InputDocument caption:string = InputMedia;
|
inputMediaDocument#1a77f29c id:InputDocument caption:string = InputMedia;
|
||||||
|
@ -177,7 +175,6 @@ inputVideo#ee579652 id:long access_hash:long = InputVideo;
|
||||||
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
|
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
|
||||||
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
|
inputVideoFileLocation#3d0364ec id:long access_hash:long = InputFileLocation;
|
||||||
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
|
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
|
||||||
inputAudioFileLocation#74dc404d id:long access_hash:long = InputFileLocation;
|
|
||||||
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
|
inputDocumentFileLocation#4e45abe9 id:long access_hash:long = InputFileLocation;
|
||||||
|
|
||||||
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
|
inputPhotoCropAuto#ade6b004 = InputPhotoCrop;
|
||||||
|
@ -219,7 +216,7 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
||||||
chatEmpty#9ba2d800 id:int = Chat;
|
chatEmpty#9ba2d800 id:int = Chat;
|
||||||
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
||||||
chatForbidden#7328bdb id:int title:string = Chat;
|
chatForbidden#7328bdb id:int title:string = Chat;
|
||||||
channel#4b1b7506 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true id:int access_hash:long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat;
|
channel#4b1b7506 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true editor:flags.3?true moderator:flags.4?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true invites_enabled:flags.10?true id:int access_hash:long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string = Chat;
|
||||||
channelForbidden#2d85832c id:int access_hash:long title:string = Chat;
|
channelForbidden#2d85832c id:int access_hash:long title:string = Chat;
|
||||||
|
|
||||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||||
|
@ -246,7 +243,6 @@ messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||||
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
|
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
|
||||||
messageMediaUnsupported#9f84f49e = MessageMedia;
|
messageMediaUnsupported#9f84f49e = MessageMedia;
|
||||||
messageMediaDocument#f3e02ea8 document:Document caption:string = MessageMedia;
|
messageMediaDocument#f3e02ea8 document:Document caption:string = MessageMedia;
|
||||||
messageMediaAudio#c6b68300 audio:Audio = MessageMedia;
|
|
||||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||||
messageMediaVenue#7912b71f geo:GeoPoint title:string address:string provider:string venue_id:string = MessageMedia;
|
messageMediaVenue#7912b71f geo:GeoPoint title:string address:string provider:string venue_id:string = MessageMedia;
|
||||||
|
|
||||||
|
@ -319,8 +315,6 @@ importedContact#d0028438 user_id:int client_id:long = ImportedContact;
|
||||||
|
|
||||||
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
|
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
|
||||||
|
|
||||||
contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
|
|
||||||
|
|
||||||
contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
|
contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
|
||||||
|
|
||||||
contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
|
contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
|
||||||
|
@ -333,8 +327,6 @@ contacts.importedContacts#ad524315 imported:Vector<ImportedContact> retry_contac
|
||||||
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
|
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
|
||||||
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
|
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
|
||||||
|
|
||||||
contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested;
|
|
||||||
|
|
||||||
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
|
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
|
||||||
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
|
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
|
||||||
|
|
||||||
|
@ -354,10 +346,10 @@ inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
|
||||||
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
|
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
|
||||||
inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
|
inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
|
||||||
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
||||||
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
|
|
||||||
inputMessagesFilterAudioDocuments#5afbf764 = MessagesFilter;
|
|
||||||
inputMessagesFilterUrl#7ef0dd87 = MessagesFilter;
|
inputMessagesFilterUrl#7ef0dd87 = MessagesFilter;
|
||||||
inputMessagesFilterGif#ffc86587 = MessagesFilter;
|
inputMessagesFilterGif#ffc86587 = MessagesFilter;
|
||||||
|
inputMessagesFilterVoice#50f5c392 = MessagesFilter;
|
||||||
|
inputMessagesFilterMusic#3751b49e = MessagesFilter;
|
||||||
|
|
||||||
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||||
|
@ -401,6 +393,7 @@ updateStickerSetsOrder#f0dfb451 order:Vector<long> = Update;
|
||||||
updateStickerSets#43ae3dec = Update;
|
updateStickerSets#43ae3dec = Update;
|
||||||
updateSavedGifs#9375341e = Update;
|
updateSavedGifs#9375341e = Update;
|
||||||
updateBotInlineQuery#c01eea08 query_id:long user_id:int query:string offset:string = Update;
|
updateBotInlineQuery#c01eea08 query_id:long user_id:int query:string offset:string = Update;
|
||||||
|
updateBotInlineSend#f69e113 user_id:int query:string id:string = Update;
|
||||||
|
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
|
|
||||||
|
@ -459,15 +452,9 @@ messages.dhConfig#2c221edd g:int p:bytes version:int random:bytes = messages.DhC
|
||||||
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
|
messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
|
||||||
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
|
messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
|
||||||
|
|
||||||
inputAudioEmpty#d95adc84 = InputAudio;
|
|
||||||
inputAudio#77d440ff id:long access_hash:long = InputAudio;
|
|
||||||
|
|
||||||
inputDocumentEmpty#72f0eaae = InputDocument;
|
inputDocumentEmpty#72f0eaae = InputDocument;
|
||||||
inputDocument#18798952 id:long access_hash:long = InputDocument;
|
inputDocument#18798952 id:long access_hash:long = InputDocument;
|
||||||
|
|
||||||
audioEmpty#586988d8 id:long = Audio;
|
|
||||||
audio#f9e35055 id:long access_hash:long date:int duration:int mime_type:string size:int dc_id:int = Audio;
|
|
||||||
|
|
||||||
documentEmpty#36f8c871 id:long = Document;
|
documentEmpty#36f8c871 id:long = Document;
|
||||||
document#f9a39f4f id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
|
document#f9a39f4f id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
|
||||||
|
|
||||||
|
@ -492,8 +479,10 @@ sendMessageChooseContactAction#628cbc6f = SendMessageAction;
|
||||||
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||||
|
|
||||||
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
|
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
|
||||||
|
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
|
||||||
|
|
||||||
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
||||||
|
privacyKeyChatInvite#500e6dfa = PrivacyKey;
|
||||||
|
|
||||||
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
|
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
|
||||||
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
|
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
|
||||||
|
@ -519,7 +508,7 @@ documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||||
documentAttributeSticker#3a556302 alt:string stickerset:InputStickerSet = DocumentAttribute;
|
documentAttributeSticker#3a556302 alt:string stickerset:InputStickerSet = DocumentAttribute;
|
||||||
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||||
documentAttributeAudio#ded218e0 duration:int title:string performer:string = DocumentAttribute;
|
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
|
||||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||||
|
|
||||||
messages.stickersNotModified#f1749a22 = messages.Stickers;
|
messages.stickersNotModified#f1749a22 = messages.Stickers;
|
||||||
|
@ -552,7 +541,7 @@ account.password#7c18141c current_salt:bytes new_salt:bytes hint:string has_reco
|
||||||
|
|
||||||
account.passwordSettings#b7b72ab3 email:string = account.PasswordSettings;
|
account.passwordSettings#b7b72ab3 email:string = account.PasswordSettings;
|
||||||
|
|
||||||
account.passwordInputSettings#bcfc532c flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string = account.PasswordInputSettings;
|
account.passwordInputSettings#86916deb flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string = account.PasswordInputSettings;
|
||||||
|
|
||||||
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
|
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
|
||||||
|
|
||||||
|
@ -717,7 +706,6 @@ users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||||
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
|
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
|
||||||
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
|
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
|
||||||
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
|
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
|
||||||
contacts.getSuggested#cd773428 limit:int = contacts.Suggested;
|
|
||||||
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
|
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
|
||||||
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
|
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
|
||||||
contacts.block#332b49fc id:InputUser = Bool;
|
contacts.block#332b49fc id:InputUser = Bool;
|
||||||
|
@ -730,7 +718,7 @@ contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
||||||
|
|
||||||
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
|
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
|
||||||
messages.getDialogs#6b47f94d offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
|
messages.getDialogs#6b47f94d offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
|
||||||
messages.getHistory#8a8ec2da peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
messages.getHistory#afa92846 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
messages.search#d4569248 flags:# important_only:flags.0?true peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
|
messages.search#d4569248 flags:# important_only:flags.0?true peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
|
||||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||||
messages.deleteHistory#b7c13bd9 peer:InputPeer max_id:int = messages.AffectedHistory;
|
messages.deleteHistory#b7c13bd9 peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||||
|
@ -808,7 +796,7 @@ help.getAppChangelog#5bab7fb2 device_model:string system_version:string app_vers
|
||||||
help.getTermsOfService#37d78f83 lang_code:string = help.TermsOfService;
|
help.getTermsOfService#37d78f83 lang_code:string = help.TermsOfService;
|
||||||
|
|
||||||
channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
|
channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
|
||||||
channels.getImportantHistory#ddb929cb channel:InputChannel offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
channels.getImportantHistory#8f494bb2 channel:InputChannel offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||||
channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
|
channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
|
||||||
|
@ -832,3 +820,4 @@ channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> =
|
||||||
channels.kickFromChannel#a672de14 channel:InputChannel user_id:InputUser kicked:Bool = Updates;
|
channels.kickFromChannel#a672de14 channel:InputChannel user_id:InputUser kicked:Bool = Updates;
|
||||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
||||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||||
|
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
||||||
|
|
|
@ -39,7 +39,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
|
||||||
, _resizeSkip(0)
|
, _resizeSkip(0)
|
||||||
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
|
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
|
||||||
, _type(type)
|
, _type(type)
|
||||||
, _reversed(_type != OverviewDocuments && _type != OverviewLinks)
|
, _reversed(_type != OverviewFiles && _type != OverviewLinks)
|
||||||
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
|
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
|
||||||
, _history(App::history(_peer->id))
|
, _history(App::history(_peer->id))
|
||||||
, _channel(peerToChannel(_peer->id))
|
, _channel(peerToChannel(_peer->id))
|
||||||
|
@ -108,7 +108,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
|
||||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||||
|
|
||||||
_cancelSearch.hide();
|
_cancelSearch.hide();
|
||||||
if (_type == OverviewLinks || _type == OverviewDocuments) {
|
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||||
_search.show();
|
_search.show();
|
||||||
} else {
|
} else {
|
||||||
_search.hide();
|
_search.hide();
|
||||||
|
@ -735,7 +735,7 @@ QPoint OverviewInner::mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewInner::activate() {
|
void OverviewInner::activate() {
|
||||||
if (_type == OverviewLinks || _type == OverviewDocuments) {
|
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||||
_search.setFocus();
|
_search.setFocus();
|
||||||
} else {
|
} else {
|
||||||
setFocus();
|
setFocus();
|
||||||
|
@ -759,7 +759,7 @@ void OverviewInner::clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
|
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
|
||||||
if (_type == OverviewAudioDocuments) {
|
if (_type == OverviewMusicFiles) {
|
||||||
int32 itemIndex = -1;
|
int32 itemIndex = -1;
|
||||||
fixItemIndex(itemIndex, (msgId.channel == _channel) ? msgId.msg : ((_migrated && msgId.channel == _migrated->channelId()) ? -msgId.msg : 0));
|
fixItemIndex(itemIndex, (msgId.channel == _channel) ? msgId.msg : ((_migrated && msgId.channel == _migrated->channelId()) ? -msgId.msg : 0));
|
||||||
if (itemIndex >= 0) {
|
if (itemIndex >= 0) {
|
||||||
|
@ -1261,9 +1261,9 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
_contextMenuLnk = textlnkOver();
|
_contextMenuLnk = textlnkOver();
|
||||||
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument) {
|
bool lnkIsAudio = lnkDocument ? lnkDocument->document()->voice() : false;
|
||||||
|
if (lnkPhoto || lnkVideo || lnkDocument) {
|
||||||
_menu = new PopupMenu();
|
_menu = new PopupMenu();
|
||||||
if (App::hoveredLinkItem()) {
|
if (App::hoveredLinkItem()) {
|
||||||
_menu->addAction(lang(lng_context_to_msg), this, SLOT(goToMessage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_to_msg), this, SLOT(goToMessage()))->setEnabled(true);
|
||||||
|
@ -1271,14 +1271,14 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (lnkPhoto) {
|
if (lnkPhoto) {
|
||||||
_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if ((lnkVideo && lnkVideo->video()->loading()) || (lnkAudio && lnkAudio->audio()->loading()) || (lnkDocument && lnkDocument->document()->loading())) {
|
if ((lnkVideo && lnkVideo->video()->loading()) || (lnkDocument && lnkDocument->document()->loading())) {
|
||||||
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
|
||||||
_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
_menu->addAction(lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_context_show_in_finder : lng_context_show_in_folder), this, SLOT(showContextInFolder()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_open_video : (lnkIsAudio ? lng_context_open_audio : lng_context_open_file)), this, SLOT(openContextFile()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
_menu->addAction(lang(lnkVideo ? lng_context_save_video : (lnkIsAudio ? lng_context_save_audio : lng_context_save_file)), this, SLOT(saveContextFile()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isUponSelected > 1) {
|
if (isUponSelected > 1) {
|
||||||
|
@ -1420,8 +1420,8 @@ void OverviewInner::switchType(MediaOverviewType type) {
|
||||||
if (_type != type) {
|
if (_type != type) {
|
||||||
clear();
|
clear();
|
||||||
_type = type;
|
_type = type;
|
||||||
_reversed = (_type != OverviewLinks && _type != OverviewDocuments);
|
_reversed = (_type != OverviewLinks && _type != OverviewFiles);
|
||||||
if (_type == OverviewLinks || _type == OverviewDocuments) {
|
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||||
_search.show();
|
_search.show();
|
||||||
} else {
|
} else {
|
||||||
_search.hide();
|
_search.hide();
|
||||||
|
@ -1502,12 +1502,9 @@ void OverviewInner::selectMessage() {
|
||||||
|
|
||||||
void OverviewInner::cancelContextDownload() {
|
void OverviewInner::cancelContextDownload() {
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkVideo) {
|
if (lnkVideo) {
|
||||||
lnkVideo->video()->cancel();
|
lnkVideo->video()->cancel();
|
||||||
} else if (lnkAudio) {
|
|
||||||
lnkAudio->audio()->cancel();
|
|
||||||
} else if (lnkDocument) {
|
} else if (lnkDocument) {
|
||||||
lnkDocument->document()->cancel();
|
lnkDocument->document()->cancel();
|
||||||
}
|
}
|
||||||
|
@ -1515,18 +1512,15 @@ void OverviewInner::cancelContextDownload() {
|
||||||
|
|
||||||
void OverviewInner::showContextInFolder() {
|
void OverviewInner::showContextInFolder() {
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
QString already = lnkVideo ? lnkVideo->video()->already(true) : (lnkAudio ? lnkAudio->audio()->already(true) : (lnkDocument ? lnkDocument->document()->already(true) : QString()));
|
QString already = lnkVideo ? lnkVideo->video()->already(true) : (lnkDocument ? lnkDocument->document()->already(true) : QString());
|
||||||
if (!already.isEmpty()) psShowInFolder(already);
|
if (!already.isEmpty()) psShowInFolder(already);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewInner::saveContextFile() {
|
void OverviewInner::saveContextFile() {
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkVideo) VideoSaveLink::doSave(lnkVideo->video(), true);
|
if (lnkVideo) VideoSaveLink::doSave(lnkVideo->video(), true);
|
||||||
if (lnkAudio) AudioSaveLink::doSave(lnkAudio->audio(), true);
|
|
||||||
if (lnkDocument) DocumentSaveLink::doSave(lnkDocument->document(), true);
|
if (lnkDocument) DocumentSaveLink::doSave(lnkDocument->document(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1534,10 +1528,8 @@ void OverviewInner::openContextFile() {
|
||||||
HistoryItem *was = App::hoveredLinkItem();
|
HistoryItem *was = App::hoveredLinkItem();
|
||||||
App::hoveredLinkItem(App::contextItem());
|
App::hoveredLinkItem(App::contextItem());
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
|
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
|
||||||
if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton);
|
|
||||||
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
|
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
|
||||||
App::hoveredLinkItem(was);
|
App::hoveredLinkItem(was);
|
||||||
}
|
}
|
||||||
|
@ -1581,7 +1573,7 @@ void OverviewInner::onNeedSearchMessages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewInner::onSearchUpdate() {
|
void OverviewInner::onSearchUpdate() {
|
||||||
QString filterText = (_type == OverviewLinks || _type == OverviewDocuments) ? _search.text().trimmed() : QString();
|
QString filterText = (_type == OverviewLinks || _type == OverviewFiles) ? _search.text().trimmed() : QString();
|
||||||
bool inSearch = !filterText.isEmpty(), changed = (inSearch != _inSearch);
|
bool inSearch = !filterText.isEmpty(), changed = (inSearch != _inSearch);
|
||||||
_inSearch = inSearch;
|
_inSearch = inSearch;
|
||||||
|
|
||||||
|
@ -1729,7 +1721,7 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||||
|
|
||||||
_height = countHeight();
|
_height = countHeight();
|
||||||
} else {
|
} else {
|
||||||
bool dateEveryMonth = (_type == OverviewDocuments), dateEveryDay = (_type == OverviewLinks);
|
bool dateEveryMonth = (_type == OverviewFiles), dateEveryDay = (_type == OverviewLinks);
|
||||||
bool withDates = (dateEveryMonth || dateEveryDay);
|
bool withDates = (dateEveryMonth || dateEveryDay);
|
||||||
|
|
||||||
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
||||||
|
@ -1793,7 +1785,7 @@ void OverviewInner::mediaOverviewUpdated() {
|
||||||
int32 newHeight = _marginTop + _height + _marginBottom, deltaHeight = newHeight - height();
|
int32 newHeight = _marginTop + _height + _marginBottom, deltaHeight = newHeight - height();
|
||||||
if (deltaHeight) {
|
if (deltaHeight) {
|
||||||
resize(_width, newHeight);
|
resize(_width, newHeight);
|
||||||
if (_type != OverviewLinks && _type != OverviewDocuments) {
|
if (_type != OverviewLinks && _type != OverviewFiles) {
|
||||||
_overview->scrollBy(deltaHeight);
|
_overview->scrollBy(deltaHeight);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1909,10 +1901,10 @@ void OverviewInner::recountMargins() {
|
||||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||||
_marginBottom = 0;
|
_marginBottom = 0;
|
||||||
_marginTop = qMax(_minHeight - _height - _marginBottom, 0);
|
_marginTop = qMax(_minHeight - _height - _marginBottom, 0);
|
||||||
} else if (_type == OverviewAudioDocuments) {
|
} else if (_type == OverviewMusicFiles) {
|
||||||
_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 == OverviewDocuments) {
|
} else if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||||
_marginTop = st::linksSearchMargin.top() + _search.height() + st::linksSearchMargin.bottom();
|
_marginTop = st::linksSearchMargin.top() + _search.height() + st::linksSearchMargin.bottom();
|
||||||
_marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding));
|
_marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1940,15 +1932,15 @@ LayoutMediaItem *OverviewInner::layoutPrepare(HistoryItem *item) {
|
||||||
i.value()->initDimensions();
|
i.value()->initDimensions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_type == OverviewAudios) {
|
} else if (_type == OverviewVoiceFiles) {
|
||||||
if (media && media->type() == MediaTypeAudio) {
|
if (media && (media->type() == MediaTypeVoiceFile)) {
|
||||||
if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) {
|
if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) {
|
||||||
i = _layoutItems.insert(item, new LayoutOverviewAudio(static_cast<HistoryAudio*>(media)->audio(), item));
|
i = _layoutItems.insert(item, new LayoutOverviewVoice(media->getDocument(), item));
|
||||||
i.value()->initDimensions();
|
i.value()->initDimensions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_type == OverviewDocuments || _type == OverviewAudioDocuments) {
|
} else if (_type == OverviewFiles || _type == OverviewMusicFiles) {
|
||||||
if (media && (media->type() == MediaTypeDocument || media->type() == MediaTypeGif)) {
|
if (media && (media->type() == MediaTypeFile || media->type() == MediaTypeMusicFile || media->type() == MediaTypeGif)) {
|
||||||
if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) {
|
if ((i = _layoutItems.constFind(item)) == _layoutItems.cend()) {
|
||||||
i = _layoutItems.insert(item, new LayoutOverviewDocument(media->getDocument(), item));
|
i = _layoutItems.insert(item, new LayoutOverviewDocument(media->getDocument(), item));
|
||||||
i.value()->initDimensions();
|
i.value()->initDimensions();
|
||||||
|
@ -2032,7 +2024,7 @@ void OverviewWidget::onScroll() {
|
||||||
int32 preloadThreshold = _scroll.height() * 5;
|
int32 preloadThreshold = _scroll.height() * 5;
|
||||||
bool needToPreload = false;
|
bool needToPreload = false;
|
||||||
do {
|
do {
|
||||||
needToPreload = (type() == OverviewLinks || type() == OverviewDocuments) ? (_scroll.scrollTop() + preloadThreshold > _scroll.scrollTopMax()) : (_scroll.scrollTop() < preloadThreshold);
|
needToPreload = (type() == OverviewLinks || type() == OverviewFiles) ? (_scroll.scrollTop() + preloadThreshold > _scroll.scrollTopMax()) : (_scroll.scrollTop() < preloadThreshold);
|
||||||
if (!needToPreload || !_inner.preloadLocal()) {
|
if (!needToPreload || !_inner.preloadLocal()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2097,7 +2089,7 @@ void OverviewWidget::scrollBy(int32 add) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::scrollReset() {
|
void OverviewWidget::scrollReset() {
|
||||||
_scroll.scrollToY((type() == OverviewLinks || type() == OverviewDocuments) ? 0 : _scroll.scrollTopMax());
|
_scroll.scrollToY((type() == OverviewLinks || type() == OverviewFiles) ? 0 : _scroll.scrollTopMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
|
void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
|
||||||
|
@ -2142,9 +2134,9 @@ void OverviewWidget::switchType(MediaOverviewType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OverviewPhotos: _header = lang(lng_profile_photos_header); break;
|
case OverviewPhotos: _header = lang(lng_profile_photos_header); break;
|
||||||
case OverviewVideos: _header = lang(lng_profile_videos_header); break;
|
case OverviewVideos: _header = lang(lng_profile_videos_header); break;
|
||||||
case OverviewAudioDocuments: _header = lang(lng_profile_songs_header); break;
|
case OverviewMusicFiles: _header = lang(lng_profile_songs_header); break;
|
||||||
case OverviewDocuments: _header = lang(lng_profile_files_header); break;
|
case OverviewFiles: _header = lang(lng_profile_files_header); break;
|
||||||
case OverviewAudios: _header = lang(lng_profile_audios_header); break;
|
case OverviewVoiceFiles: _header = lang(lng_profile_audios_header); break;
|
||||||
case OverviewLinks: _header = lang(lng_profile_shared_links_header); break;
|
case OverviewLinks: _header = lang(lng_profile_shared_links_header); break;
|
||||||
}
|
}
|
||||||
noSelectingScroll();
|
noSelectingScroll();
|
||||||
|
@ -2183,7 +2175,7 @@ int32 OverviewWidget::lastScrollTop() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 OverviewWidget::countBestScroll() const {
|
int32 OverviewWidget::countBestScroll() const {
|
||||||
if (type() == OverviewAudioDocuments && audioPlayer()) {
|
if (type() == OverviewMusicFiles && audioPlayer()) {
|
||||||
SongMsgId playing;
|
SongMsgId playing;
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
|
@ -2193,7 +2185,7 @@ int32 OverviewWidget::countBestScroll() const {
|
||||||
return snap(top - int(_scroll.height() - (st::msgPadding.top() + st::mediaThumbSize + st::msgPadding.bottom())) / 2, 0, _scroll.scrollTopMax());
|
return snap(top - int(_scroll.height() - (st::msgPadding.top() + st::mediaThumbSize + st::msgPadding.bottom())) / 2, 0, _scroll.scrollTopMax());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type() == OverviewLinks || type() == OverviewDocuments) {
|
} else if (type() == OverviewLinks || type() == OverviewFiles) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return _scroll.scrollTopMax();
|
return _scroll.scrollTopMax();
|
||||||
|
@ -2350,7 +2342,7 @@ void OverviewWidget::onScrollTimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::onPlayerSongChanged(const FullMsgId &msgId) {
|
void OverviewWidget::onPlayerSongChanged(const FullMsgId &msgId) {
|
||||||
if (type() == OverviewAudioDocuments) {
|
if (type() == OverviewMusicFiles) {
|
||||||
// int32 top = _inner.itemTop(msgId);
|
// int32 top = _inner.itemTop(msgId);
|
||||||
// if (top > 0) {
|
// if (top > 0) {
|
||||||
// _scroll.scrollToY(snap(top - int(_scroll.height() - (st::msgPadding.top() + st::mediaThumbSize + st::msgPadding.bottom())) / 2, 0, _scroll.scrollTopMax()));
|
// _scroll.scrollToY(snap(top - int(_scroll.height() - (st::msgPadding.top() + st::mediaThumbSize + st::msgPadding.bottom())) / 2, 0, _scroll.scrollTopMax()));
|
||||||
|
|
|
@ -198,7 +198,7 @@ void PlayerWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||||
if (playing == _song && playingDuration) {
|
if (playing == _song && playingDuration) {
|
||||||
if (playingState == AudioPlayerPlaying || playingState == AudioPlayerStarting || playingState == AudioPlayerResuming) {
|
if (playingState == AudioPlayerPlaying || playingState == AudioPlayerStarting || playingState == AudioPlayerResuming) {
|
||||||
audioPlayer()->pauseresume(OverviewDocuments);
|
audioPlayer()->pauseresume(OverviewFiles);
|
||||||
}
|
}
|
||||||
_down = OverPlayback;
|
_down = OverPlayback;
|
||||||
_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
|
_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
|
||||||
|
@ -210,7 +210,7 @@ void PlayerWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
} else if (_over == OverFull && _song) {
|
} else if (_over == OverFull && _song) {
|
||||||
if (HistoryItem *item = App::histItemById(_song.msgId)) {
|
if (HistoryItem *item = App::histItemById(_song.msgId)) {
|
||||||
App::main()->showMediaOverview(item->history()->peer, OverviewAudioDocuments);
|
App::main()->showMediaOverview(item->history()->peer, OverviewMusicFiles);
|
||||||
}
|
}
|
||||||
} else if (_over == OverRepeat) {
|
} else if (_over == OverRepeat) {
|
||||||
_repeat = !_repeat;
|
_repeat = !_repeat;
|
||||||
|
@ -269,23 +269,23 @@ void PlayerWidget::updateControls() {
|
||||||
_fullAvailable = (_index >= 0);
|
_fullAvailable = (_index >= 0);
|
||||||
|
|
||||||
History *history = _msgmigrated ? _migrated : _history;
|
History *history = _msgmigrated ? _migrated : _history;
|
||||||
_prevAvailable = _fullAvailable && ((_index > 0) || (_index == 0 && _migrated && !_msgmigrated && !_migrated->overview[OverviewAudioDocuments].isEmpty()));
|
_prevAvailable = _fullAvailable && ((_index > 0) || (_index == 0 && _migrated && !_msgmigrated && !_migrated->overview[OverviewMusicFiles].isEmpty()));
|
||||||
_nextAvailable = _fullAvailable && ((_index < history->overview[OverviewAudioDocuments].size() - 1) || (_msgmigrated && _index == _migrated->overview[OverviewAudioDocuments].size() - 1 && _history->overviewLoaded(OverviewAudioDocuments) && _history->overviewCount(OverviewAudioDocuments) > 0));
|
_nextAvailable = _fullAvailable && ((_index < history->overview[OverviewMusicFiles].size() - 1) || (_msgmigrated && _index == _migrated->overview[OverviewMusicFiles].size() - 1 && _history->overviewLoaded(OverviewMusicFiles) && _history->overviewCount(OverviewMusicFiles) > 0));
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
update();
|
update();
|
||||||
if (_index >= 0 && _index < MediaOverviewStartPerPage) {
|
if (_index >= 0 && _index < MediaOverviewStartPerPage) {
|
||||||
if (!_history->overviewLoaded(OverviewAudioDocuments) || (_migrated && !_migrated->overviewLoaded(OverviewAudioDocuments))) {
|
if (!_history->overviewLoaded(OverviewMusicFiles) || (_migrated && !_migrated->overviewLoaded(OverviewMusicFiles))) {
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
if (_msgmigrated || (_migrated && _index == 0 && _history->overviewLoaded(OverviewAudioDocuments))) {
|
if (_msgmigrated || (_migrated && _index == 0 && _history->overviewLoaded(OverviewMusicFiles))) {
|
||||||
App::main()->loadMediaBack(_migrated->peer, OverviewAudioDocuments);
|
App::main()->loadMediaBack(_migrated->peer, OverviewMusicFiles);
|
||||||
} else {
|
} else {
|
||||||
App::main()->loadMediaBack(_history->peer, OverviewAudioDocuments);
|
App::main()->loadMediaBack(_history->peer, OverviewMusicFiles);
|
||||||
if (_migrated && _index == 0 && _migrated->overview[OverviewAudioDocuments].isEmpty() && !_migrated->overviewLoaded(OverviewAudioDocuments)) {
|
if (_migrated && _index == 0 && _migrated->overview[OverviewMusicFiles].isEmpty() && !_migrated->overviewLoaded(OverviewMusicFiles)) {
|
||||||
App::main()->loadMediaBack(_migrated->peer, OverviewAudioDocuments);
|
App::main()->loadMediaBack(_migrated->peer, OverviewMusicFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_msgmigrated && !_history->overviewCountLoaded(OverviewAudioDocuments)) {
|
if (_msgmigrated && !_history->overviewCountLoaded(OverviewMusicFiles)) {
|
||||||
App::main()->preloadOverview(_history->peer, OverviewAudioDocuments);
|
App::main()->preloadOverview(_history->peer, OverviewMusicFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ void PlayerWidget::findCurrent() {
|
||||||
_index = -1;
|
_index = -1;
|
||||||
if (!_history) return;
|
if (!_history) return;
|
||||||
|
|
||||||
const History::MediaOverview *o = &(_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments];
|
const History::MediaOverview *o = &(_msgmigrated ? _migrated : _history)->overview[OverviewMusicFiles];
|
||||||
if ((_msgmigrated ? _migrated : _history)->channelId() == _song.msgId.channel) {
|
if ((_msgmigrated ? _migrated : _history)->channelId() == _song.msgId.channel) {
|
||||||
for (int i = 0, l = o->size(); i < l; ++i) {
|
for (int i = 0, l = o->size(); i < l; ++i) {
|
||||||
if (o->at(i) == _song.msgId.msg) {
|
if (o->at(i) == _song.msgId.msg) {
|
||||||
|
@ -312,14 +312,14 @@ void PlayerWidget::preloadNext() {
|
||||||
if (_index < 0) return;
|
if (_index < 0) return;
|
||||||
|
|
||||||
History *history = _msgmigrated ? _migrated : _history;
|
History *history = _msgmigrated ? _migrated : _history;
|
||||||
const History::MediaOverview *o = &history->overview[OverviewAudioDocuments];
|
const History::MediaOverview *o = &history->overview[OverviewMusicFiles];
|
||||||
HistoryItem *next = 0;
|
HistoryItem *next = 0;
|
||||||
if (_index < o->size() - 1) {
|
if (_index < o->size() - 1) {
|
||||||
next = App::histItemById(history->channelId(), o->at(_index + 1));
|
next = App::histItemById(history->channelId(), o->at(_index + 1));
|
||||||
} else if (_msgmigrated && _index == o->size() - 1 && _history->overviewLoaded(OverviewAudioDocuments) && _history->overviewCount(OverviewAudioDocuments) > 0) {
|
} else if (_msgmigrated && _index == o->size() - 1 && _history->overviewLoaded(OverviewMusicFiles) && _history->overviewCount(OverviewMusicFiles) > 0) {
|
||||||
next = App::histItemById(_history->channelId(), _history->overview[OverviewAudioDocuments].at(0));
|
next = App::histItemById(_history->channelId(), _history->overview[OverviewMusicFiles].at(0));
|
||||||
} else if (_msgmigrated && _index == o->size() - 1 && !_history->overviewCountLoaded(OverviewAudioDocuments)) {
|
} else if (_msgmigrated && _index == o->size() - 1 && !_history->overviewCountLoaded(OverviewMusicFiles)) {
|
||||||
if (App::main()) App::main()->preloadOverview(_history->peer, OverviewAudioDocuments);
|
if (App::main()) App::main()->preloadOverview(_history->peer, OverviewMusicFiles);
|
||||||
}
|
}
|
||||||
if (next) {
|
if (next) {
|
||||||
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
|
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
|
||||||
|
@ -348,12 +348,12 @@ void PlayerWidget::clearSelection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||||
if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == OverviewAudioDocuments) {
|
if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == OverviewMusicFiles) {
|
||||||
_index = -1;
|
_index = -1;
|
||||||
History *history = _msgmigrated ? _migrated : _history;
|
History *history = _msgmigrated ? _migrated : _history;
|
||||||
if (history->channelId() == _song.msgId.channel) {
|
if (history->channelId() == _song.msgId.channel) {
|
||||||
for (int i = 0, l = history->overview[OverviewAudioDocuments].size(); i < l; ++i) {
|
for (int i = 0, l = history->overview[OverviewMusicFiles].size(); i < l; ++i) {
|
||||||
if (history->overview[OverviewAudioDocuments].at(i) == _song.msgId.msg) {
|
if (history->overview[OverviewMusicFiles].at(i) == _song.msgId.msg) {
|
||||||
_index = i;
|
_index = i;
|
||||||
preloadNext();
|
preloadNext();
|
||||||
break;
|
break;
|
||||||
|
@ -476,7 +476,7 @@ void PlayerWidget::playPressed() {
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
||||||
if (playingState == AudioPlayerPausing || playingState == AudioPlayerPaused || playingState == AudioPlayerPausedAtEnd) {
|
if (playingState == AudioPlayerPausing || playingState == AudioPlayerPaused || playingState == AudioPlayerPausedAtEnd) {
|
||||||
audioPlayer()->pauseresume(OverviewDocuments);
|
audioPlayer()->pauseresume(OverviewFiles);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
audioPlayer()->play(_song);
|
audioPlayer()->play(_song);
|
||||||
|
@ -492,7 +492,7 @@ void PlayerWidget::pausePressed() {
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
||||||
if (playingState == AudioPlayerStarting || playingState == AudioPlayerResuming || playingState == AudioPlayerPlaying || playingState == AudioPlayerFinishing) {
|
if (playingState == AudioPlayerStarting || playingState == AudioPlayerResuming || playingState == AudioPlayerPlaying || playingState == AudioPlayerFinishing) {
|
||||||
audioPlayer()->pauseresume(OverviewDocuments);
|
audioPlayer()->pauseresume(OverviewFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -504,7 +504,7 @@ void PlayerWidget::playPausePressed() {
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
|
||||||
audioPlayer()->pauseresume(OverviewDocuments);
|
audioPlayer()->pauseresume(OverviewFiles);
|
||||||
} else {
|
} else {
|
||||||
audioPlayer()->play(_song);
|
audioPlayer()->play(_song);
|
||||||
if (App::main()) App::main()->documentPlayProgress(_song);
|
if (App::main()) App::main()->documentPlayProgress(_song);
|
||||||
|
@ -515,11 +515,11 @@ void PlayerWidget::prevPressed() {
|
||||||
if (isHidden()) return;
|
if (isHidden()) return;
|
||||||
|
|
||||||
History *history = _msgmigrated ? _migrated : _history;
|
History *history = _msgmigrated ? _migrated : _history;
|
||||||
const History::MediaOverview *o = history ? &history->overview[OverviewAudioDocuments] : 0;
|
const History::MediaOverview *o = history ? &history->overview[OverviewMusicFiles] : 0;
|
||||||
if (audioPlayer() && o && _index > 0 && _index <= o->size() && !o->isEmpty()) {
|
if (audioPlayer() && o && _index > 0 && _index <= o->size() && !o->isEmpty()) {
|
||||||
startPlay(FullMsgId(history->channelId(), o->at(_index - 1)));
|
startPlay(FullMsgId(history->channelId(), o->at(_index - 1)));
|
||||||
} else if (!_index && _history && _migrated && !_msgmigrated) {
|
} else if (!_index && _history && _migrated && !_msgmigrated) {
|
||||||
o = &_migrated->overview[OverviewAudioDocuments];
|
o = &_migrated->overview[OverviewMusicFiles];
|
||||||
if (!o->isEmpty()) {
|
if (!o->isEmpty()) {
|
||||||
startPlay(FullMsgId(_migrated->channelId(), o->at(o->size() - 1)));
|
startPlay(FullMsgId(_migrated->channelId(), o->at(o->size() - 1)));
|
||||||
}
|
}
|
||||||
|
@ -530,11 +530,11 @@ void PlayerWidget::nextPressed() {
|
||||||
if (isHidden()) return;
|
if (isHidden()) return;
|
||||||
|
|
||||||
History *history = _msgmigrated ? _migrated : _history;
|
History *history = _msgmigrated ? _migrated : _history;
|
||||||
const History::MediaOverview *o = history ? &history->overview[OverviewAudioDocuments] : 0;
|
const History::MediaOverview *o = history ? &history->overview[OverviewMusicFiles] : 0;
|
||||||
if (audioPlayer() && o && _index >= 0 && _index < o->size() - 1) {
|
if (audioPlayer() && o && _index >= 0 && _index < o->size() - 1) {
|
||||||
startPlay(FullMsgId(history->channelId(), o->at(_index + 1)));
|
startPlay(FullMsgId(history->channelId(), o->at(_index + 1)));
|
||||||
} else if (o && (_index == o->size() - 1) && _msgmigrated && _history->overviewLoaded(OverviewAudioDocuments)) {
|
} else if (o && (_index == o->size() - 1) && _msgmigrated && _history->overviewLoaded(OverviewMusicFiles)) {
|
||||||
o = &_history->overview[OverviewAudioDocuments];
|
o = &_history->overview[OverviewMusicFiles];
|
||||||
if (!o->isEmpty()) {
|
if (!o->isEmpty()) {
|
||||||
startPlay(FullMsgId(_history->channelId(), o->at(0)));
|
startPlay(FullMsgId(_history->channelId(), o->at(0)));
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ void PlayerWidget::nextPressed() {
|
||||||
void PlayerWidget::stopPressed() {
|
void PlayerWidget::stopPressed() {
|
||||||
if (!_song || isHidden()) return;
|
if (!_song || isHidden()) return;
|
||||||
|
|
||||||
audioPlayer()->stop(OverviewDocuments);
|
audioPlayer()->stop(OverviewFiles);
|
||||||
if (App::main()) App::main()->hidePlayer();
|
if (App::main()) App::main()->hidePlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState,
|
||||||
display = _song.song->song()->duration;
|
display = _song.song->song()->duration;
|
||||||
}
|
}
|
||||||
bool showPause = false, stopped = ((playingState & AudioPlayerStoppedMask) || playingState == AudioPlayerFinishing);
|
bool showPause = false, stopped = ((playingState & AudioPlayerStoppedMask) || playingState == AudioPlayerFinishing);
|
||||||
bool wasPlaying = !!_duration;
|
bool wasPlaying = (_duration != 0);
|
||||||
if (!stopped) {
|
if (!stopped) {
|
||||||
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
|
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,9 +209,9 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
|
||||||
// shared media
|
// shared media
|
||||||
connect((_mediaButtons[OverviewPhotos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaPhotos()));
|
connect((_mediaButtons[OverviewPhotos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaPhotos()));
|
||||||
connect((_mediaButtons[OverviewVideos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaVideos()));
|
connect((_mediaButtons[OverviewVideos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaVideos()));
|
||||||
connect((_mediaButtons[OverviewAudioDocuments] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaSongs()));
|
connect((_mediaButtons[OverviewMusicFiles] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaSongs()));
|
||||||
connect((_mediaButtons[OverviewDocuments] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaDocuments()));
|
connect((_mediaButtons[OverviewFiles] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaDocuments()));
|
||||||
connect((_mediaButtons[OverviewAudios] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaAudios()));
|
connect((_mediaButtons[OverviewVoiceFiles] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaAudios()));
|
||||||
connect((_mediaButtons[OverviewLinks] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaLinks()));
|
connect((_mediaButtons[OverviewLinks] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaLinks()));
|
||||||
updateMediaLinks();
|
updateMediaLinks();
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ void ProfileInner::loadProfilePhotos(int32 yFrom) {
|
||||||
int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5;
|
int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5;
|
||||||
MTP::clearLoaderPriorities();
|
MTP::clearLoaderPriorities();
|
||||||
|
|
||||||
int32 partfrom = _mediaButtons[OverviewAudios]->y() + _mediaButtons[OverviewAudios]->height() + st::profileHeaderSkip;
|
int32 partfrom = _mediaButtons[OverviewVoiceFiles]->y() + _mediaButtons[OverviewVoiceFiles]->height() + st::profileHeaderSkip;
|
||||||
yFrom -= partfrom;
|
yFrom -= partfrom;
|
||||||
yTo -= partfrom;
|
yTo -= partfrom;
|
||||||
|
|
||||||
|
@ -440,15 +440,15 @@ void ProfileInner::onMediaVideos() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::onMediaSongs() {
|
void ProfileInner::onMediaSongs() {
|
||||||
App::main()->showMediaOverview(_peer, OverviewAudioDocuments);
|
App::main()->showMediaOverview(_peer, OverviewMusicFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::onMediaDocuments() {
|
void ProfileInner::onMediaDocuments() {
|
||||||
App::main()->showMediaOverview(_peer, OverviewDocuments);
|
App::main()->showMediaOverview(_peer, OverviewFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::onMediaAudios() {
|
void ProfileInner::onMediaAudios() {
|
||||||
App::main()->showMediaOverview(_peer, OverviewAudios);
|
App::main()->showMediaOverview(_peer, OverviewVoiceFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileInner::onMediaLinks() {
|
void ProfileInner::onMediaLinks() {
|
||||||
|
@ -1711,9 +1711,9 @@ QString ProfileInner::overviewLinkText(int32 type, int32 count) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OverviewPhotos: return lng_profile_photos(lt_count, count);
|
case OverviewPhotos: return lng_profile_photos(lt_count, count);
|
||||||
case OverviewVideos: return lng_profile_videos(lt_count, count);
|
case OverviewVideos: return lng_profile_videos(lt_count, count);
|
||||||
case OverviewAudioDocuments: return lng_profile_songs(lt_count, count);
|
case OverviewMusicFiles: return lng_profile_songs(lt_count, count);
|
||||||
case OverviewDocuments: return lng_profile_files(lt_count, count);
|
case OverviewFiles: return lng_profile_files(lt_count, count);
|
||||||
case OverviewAudios: return lng_profile_audios(lt_count, count);
|
case OverviewVoiceFiles: return lng_profile_audios(lt_count, count);
|
||||||
case OverviewLinks: return lng_profile_shared_links(lt_count, count);
|
case OverviewLinks: return lng_profile_shared_links(lt_count, count);
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
|
|
|
@ -1013,97 +1013,6 @@ void VideoData::setLocation(const FileLocation &loc) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
|
||||||
if (button != Qt::LeftButton) return;
|
|
||||||
AudioData *data = audio();
|
|
||||||
|
|
||||||
if (!data->date) return;
|
|
||||||
|
|
||||||
HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0);
|
|
||||||
|
|
||||||
bool play = audioPlayer() && item;
|
|
||||||
const FileLocation &location(data->location(true));
|
|
||||||
if (!location.isEmpty() || (!data->data().isEmpty() && play)) {
|
|
||||||
if (play) {
|
|
||||||
AudioMsgId playing;
|
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
|
||||||
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
|
||||||
audioPlayer()->pauseresume(OverviewAudios);
|
|
||||||
} else {
|
|
||||||
AudioMsgId audio(data, item->fullId());
|
|
||||||
audioPlayer()->play(audio);
|
|
||||||
if (App::main()) {
|
|
||||||
App::main()->audioPlayProgress(audio);
|
|
||||||
App::main()->audioMarkRead(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
psOpenFile(location.name());
|
|
||||||
if (App::main()) App::main()->audioMarkRead(data);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data->status != FileReady) return;
|
|
||||||
|
|
||||||
QString filename;
|
|
||||||
if (!data->saveToCache()) {
|
|
||||||
bool mp3 = (data->mime == qstr("audio/mp3"));
|
|
||||||
filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
|
|
||||||
|
|
||||||
if (filename.isEmpty()) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->save(filename, ActionOnLoadOpen, item ? item->fullId() : FullMsgId());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioSaveLink::doSave(AudioData *data, bool forceSavingAs) {
|
|
||||||
if (!data->date) return;
|
|
||||||
|
|
||||||
QString already = data->already(true);
|
|
||||||
bool openWith = !already.isEmpty();
|
|
||||||
if (openWith && !forceSavingAs) {
|
|
||||||
QPoint pos(QCursor::pos());
|
|
||||||
if (!psShowOpenWithMenu(pos.x(), pos.y(), already)) {
|
|
||||||
psOpenFile(already, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QFileInfo alreadyInfo(already);
|
|
||||||
QDir alreadyDir(already.isEmpty() ? QDir() : alreadyInfo.dir());
|
|
||||||
bool mp3 = (data->mime == qstr("audio/mp3"));
|
|
||||||
QString name = already.isEmpty() ? (mp3 ? qsl(".mp3") : qsl(".ogg")) : alreadyInfo.fileName();
|
|
||||||
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), name, forceSavingAs, alreadyDir);
|
|
||||||
if (!filename.isEmpty()) {
|
|
||||||
ActionOnLoad action = already.isEmpty() ? ActionOnLoadNone : ActionOnLoadOpenWith;
|
|
||||||
FullMsgId actionMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
|
|
||||||
data->save(filename, action, actionMsgId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioSaveLink::onClick(Qt::MouseButton button) const {
|
|
||||||
if (button != Qt::LeftButton) return;
|
|
||||||
doSave(audio());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioCancelLink::onClick(Qt::MouseButton button) const {
|
|
||||||
AudioData *data = audio();
|
|
||||||
if (!data->date || button != Qt::LeftButton) return;
|
|
||||||
|
|
||||||
if (data->uploading()) {
|
|
||||||
HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0);
|
|
||||||
if (HistoryMessage *msg = item->toHistoryMessage()) {
|
|
||||||
if (msg->getMedia() && msg->getMedia()->type() == MediaTypeAudio && static_cast<HistoryAudio*>(msg->getMedia())->audio() == data) {
|
|
||||||
App::contextItem(item);
|
|
||||||
App::main()->deleteLayer(-2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data->cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StickerData::setInstalled() const {
|
bool StickerData::setInstalled() const {
|
||||||
switch (set.type()) {
|
switch (set.type()) {
|
||||||
case mtpc_inputStickerSetID: {
|
case mtpc_inputStickerSetID: {
|
||||||
|
@ -1122,239 +1031,44 @@ bool StickerData::setInstalled() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size)
|
|
||||||
: id(id)
|
|
||||||
, access(access)
|
|
||||||
, date(date)
|
|
||||||
, mime(mime)
|
|
||||||
, duration(duration)
|
|
||||||
, dc(dc)
|
|
||||||
, size(size)
|
|
||||||
, status(FileReady)
|
|
||||||
, uploadOffset(0)
|
|
||||||
, _actionOnLoad(ActionOnLoadNone)
|
|
||||||
, _loader(0) {
|
|
||||||
_location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioData::saveToCache() const {
|
|
||||||
return size < AudioVoiceMsgInMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::forget() {
|
|
||||||
_data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::automaticLoad(const HistoryItem *item) {
|
|
||||||
if (loaded() || status != FileReady) return;
|
|
||||||
|
|
||||||
if (saveToCache() && _loader != CancelledMtpFileLoader) {
|
|
||||||
if (item) {
|
|
||||||
bool loadFromCloud = false;
|
|
||||||
if (item->history()->peer->isUser()) {
|
|
||||||
loadFromCloud = !(cAutoDownloadAudio() & dbiadNoPrivate);
|
|
||||||
} else {
|
|
||||||
loadFromCloud = !(cAutoDownloadAudio() & dbiadNoGroups);
|
|
||||||
}
|
|
||||||
save(QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::automaticLoadSettingsChanged() {
|
|
||||||
if (loaded() || status != FileReady || !saveToCache() || _loader != CancelledMtpFileLoader) return;
|
|
||||||
_loader = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::performActionOnLoad() {
|
|
||||||
if (_actionOnLoad == ActionOnLoadNone) return;
|
|
||||||
|
|
||||||
const FileLocation &loc(location(true));
|
|
||||||
QString already = loc.name();
|
|
||||||
bool play = _actionOnLoadMsgId.msg && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && audioPlayer();
|
|
||||||
|
|
||||||
if (play) {
|
|
||||||
if (loaded()) {
|
|
||||||
AudioMsgId playing;
|
|
||||||
AudioPlayerState state = AudioPlayerStopped;
|
|
||||||
audioPlayer()->currentState(&playing, &state);
|
|
||||||
if (playing.msgId == _actionOnLoadMsgId && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) {
|
|
||||||
audioPlayer()->pauseresume(OverviewAudios);
|
|
||||||
} else {
|
|
||||||
audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId));
|
|
||||||
if (App::main()) App::main()->audioMarkRead(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (already.isEmpty()) return;
|
|
||||||
if (_actionOnLoad == ActionOnLoadOpenWith) {
|
|
||||||
if (already.isEmpty()) return;
|
|
||||||
|
|
||||||
QPoint pos(QCursor::pos());
|
|
||||||
if (!psShowOpenWithMenu(pos.x(), pos.y(), already)) {
|
|
||||||
psOpenFile(already, true);
|
|
||||||
}
|
|
||||||
if (App::main()) App::main()->audioMarkRead(this);
|
|
||||||
} else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) {
|
|
||||||
psOpenFile(already);
|
|
||||||
if (App::main()) App::main()->audioMarkRead(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_actionOnLoad = ActionOnLoadNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioData::loaded(bool check) const {
|
|
||||||
if (loading() && _loader->done()) {
|
|
||||||
if (_loader->fileType() == mtpc_storage_fileUnknown) {
|
|
||||||
_loader->deleteLater();
|
|
||||||
_loader->rpcInvalidate();
|
|
||||||
_loader = CancelledMtpFileLoader;
|
|
||||||
} else {
|
|
||||||
AudioData *that = const_cast<AudioData*>(this);
|
|
||||||
that->_location = FileLocation(mtpToStorageType(_loader->fileType()), _loader->fileName());
|
|
||||||
that->_data = _loader->bytes();
|
|
||||||
|
|
||||||
_loader->deleteLater();
|
|
||||||
_loader->rpcInvalidate();
|
|
||||||
_loader = 0;
|
|
||||||
}
|
|
||||||
notifyLayoutChanged();
|
|
||||||
}
|
|
||||||
return !_data.isEmpty() || !already(check).isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioData::loading() const {
|
|
||||||
return _loader && _loader != CancelledMtpFileLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioData::displayLoading() const {
|
|
||||||
return loading() ? (!_loader->loadingLocal() || !_loader->autoLoading()) : uploading();
|
|
||||||
}
|
|
||||||
|
|
||||||
float64 AudioData::progress() const {
|
|
||||||
if (uploading()) {
|
|
||||||
if (size > 0) {
|
|
||||||
return float64(uploadOffset) / size;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return loading() ? _loader->currentProgress() : (loaded() ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 AudioData::loadOffset() const {
|
|
||||||
return loading() ? _loader->currentOffset() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioData::uploading() const {
|
|
||||||
return status == FileUploading;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::save(const QString &toFile, ActionOnLoad action, const FullMsgId &actionMsgId, LoadFromCloudSetting fromCloud, bool autoLoading) {
|
|
||||||
if (loaded(true)) {
|
|
||||||
const FileLocation &l(location(true));
|
|
||||||
if (!toFile.isEmpty()) {
|
|
||||||
if (!_data.isEmpty()) {
|
|
||||||
QFile f(toFile);
|
|
||||||
f.open(QIODevice::WriteOnly);
|
|
||||||
f.write(_data);
|
|
||||||
} else if (l.accessEnable()) {
|
|
||||||
QFile(l.name()).copy(toFile);
|
|
||||||
l.accessDisable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_loader == CancelledMtpFileLoader) _loader = 0;
|
|
||||||
if (_loader) {
|
|
||||||
if (!_loader->setFileName(toFile)) {
|
|
||||||
cancel();
|
|
||||||
_loader = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_actionOnLoad = action;
|
|
||||||
_actionOnLoadMsgId = actionMsgId;
|
|
||||||
|
|
||||||
if (_loader) {
|
|
||||||
if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
|
|
||||||
} else {
|
|
||||||
status = FileReady;
|
|
||||||
_loader = new mtpFileLoader(dc, id, access, AudioFileLocation, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
|
|
||||||
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(audioLoadProgress(FileLoader*)));
|
|
||||||
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(audioLoadFailed(FileLoader*,bool)));
|
|
||||||
_loader->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyLayoutChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::cancel() {
|
|
||||||
if (!loading()) return;
|
|
||||||
|
|
||||||
mtpFileLoader *l = _loader;
|
|
||||||
_loader = CancelledMtpFileLoader;
|
|
||||||
if (l) {
|
|
||||||
l->cancel();
|
|
||||||
l->deleteLater();
|
|
||||||
l->rpcInvalidate();
|
|
||||||
|
|
||||||
notifyLayoutChanged();
|
|
||||||
}
|
|
||||||
_actionOnLoad = ActionOnLoadNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::notifyLayoutChanged() const {
|
|
||||||
const AudioItems &items(App::audioItems());
|
|
||||||
AudioItems::const_iterator i = items.constFind(const_cast<AudioData*>(this));
|
|
||||||
if (i != items.cend()) {
|
|
||||||
for (HistoryItemsMap::const_iterator j = i->cbegin(), e = i->cend(); j != e; ++j) {
|
|
||||||
Notify::historyItemLayoutChanged(j.key());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AudioData::already(bool check) const {
|
|
||||||
return location(check).name();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray AudioData::data() const {
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FileLocation &AudioData::location(bool check) const {
|
|
||||||
if (check && !_location.check()) {
|
|
||||||
const_cast<AudioData*>(this)->_location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
|
||||||
}
|
|
||||||
return _location;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioData::setLocation(const FileLocation &loc) {
|
|
||||||
if (loc.check()) {
|
|
||||||
_location = loc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
|
void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
|
||||||
if (!data->date) return;
|
if (!data->date) return;
|
||||||
|
|
||||||
HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0);
|
HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0);
|
||||||
|
|
||||||
|
bool playVoice = data->voice() && audioPlayer() && item;
|
||||||
bool playMusic = data->song() && audioPlayer() && item;
|
bool playMusic = data->song() && audioPlayer() && item;
|
||||||
bool playAnimation = data->isAnimation() && item && item->getMedia();
|
bool playAnimation = data->isAnimation() && item && item->getMedia();
|
||||||
const FileLocation &location(data->location(true));
|
const FileLocation &location(data->location(true));
|
||||||
if (!location.isEmpty() || (!data->data().isEmpty() && (playMusic || playAnimation))) {
|
if (!location.isEmpty() || (!data->data().isEmpty() && (playVoice || playMusic || playAnimation))) {
|
||||||
if (playMusic) {
|
if (playVoice) {
|
||||||
|
AudioMsgId playing;
|
||||||
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
|
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
|
audioPlayer()->pauseresume(OverviewVoiceFiles);
|
||||||
|
} else {
|
||||||
|
AudioMsgId audio(data, item->fullId());
|
||||||
|
audioPlayer()->play(audio);
|
||||||
|
if (App::main()) {
|
||||||
|
App::main()->audioPlayProgress(audio);
|
||||||
|
App::main()->audioMarkRead(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (playMusic) {
|
||||||
SongMsgId playing;
|
SongMsgId playing;
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
audioPlayer()->pauseresume(OverviewDocuments);
|
audioPlayer()->pauseresume(OverviewFiles);
|
||||||
} else {
|
} else {
|
||||||
SongMsgId song(data, item->fullId());
|
SongMsgId song(data, item->fullId());
|
||||||
audioPlayer()->play(song);
|
audioPlayer()->play(song);
|
||||||
if (App::main()) App::main()->documentPlayProgress(song);
|
if (App::main()) App::main()->documentPlayProgress(song);
|
||||||
}
|
}
|
||||||
|
} else if (data->voice()) {
|
||||||
|
psOpenFile(location.name());
|
||||||
|
if (App::main()) App::main()->audioMarkRead(data);
|
||||||
} else if (data->size < MediaViewImageSizeLimit) {
|
} else if (data->size < MediaViewImageSizeLimit) {
|
||||||
if (!data->data().isEmpty() && playAnimation) {
|
if (!data->data().isEmpty() && playAnimation) {
|
||||||
if (action == ActionOnLoadPlayInline) {
|
if (action == ActionOnLoadPlayInline) {
|
||||||
|
@ -1386,21 +1100,32 @@ void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
|
||||||
|
|
||||||
QString filename;
|
QString filename;
|
||||||
if (!data->saveToCache()) {
|
if (!data->saveToCache()) {
|
||||||
QString name = data->name, filter;
|
QString name, filter, caption, prefix;
|
||||||
MimeType mimeType = mimeTypeForName(data->mime);
|
MimeType mimeType = mimeTypeForName(data->mime);
|
||||||
QStringList p = mimeType.globPatterns();
|
QStringList p = mimeType.globPatterns();
|
||||||
QString pattern = p.isEmpty() ? QString() : p.front();
|
QString pattern = p.isEmpty() ? QString() : p.front();
|
||||||
if (name.isEmpty()) {
|
if (data->voice()) {
|
||||||
|
bool mp3 = (data->mime == qstr("audio/mp3"));
|
||||||
|
name = mp3 ? qsl(".mp3") : qsl(".ogg");
|
||||||
|
filter = mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)");
|
||||||
|
caption = lang(lng_save_audio);
|
||||||
|
prefix = qsl("audio");
|
||||||
|
} else {
|
||||||
|
if (data->name.isEmpty()) {
|
||||||
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
||||||
|
} else {
|
||||||
|
name = data->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pattern.isEmpty()) {
|
if (pattern.isEmpty()) {
|
||||||
filter = QString();
|
filter = QString();
|
||||||
} else {
|
} else {
|
||||||
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
||||||
}
|
}
|
||||||
|
caption = lang(lng_save_file);
|
||||||
|
prefix = qsl("doc");
|
||||||
|
}
|
||||||
|
|
||||||
filename = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, false);
|
filename = saveFileName(caption, filter, prefix, name, false);
|
||||||
|
|
||||||
if (filename.isEmpty()) return;
|
if (filename.isEmpty()) return;
|
||||||
}
|
}
|
||||||
|
@ -1410,16 +1135,17 @@ void DocumentOpenLink::doOpen(DocumentData *data, ActionOnLoad action) {
|
||||||
|
|
||||||
void DocumentOpenLink::onClick(Qt::MouseButton button) const {
|
void DocumentOpenLink::onClick(Qt::MouseButton button) const {
|
||||||
if (button != Qt::LeftButton) return;
|
if (button != Qt::LeftButton) return;
|
||||||
doOpen(document());
|
doOpen(document(), document()->voice() ? ActionOnLoadNone : ActionOnLoadOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GifOpenLink::doOpen(DocumentData *data) {
|
void VoiceSaveLink::onClick(Qt::MouseButton button) const {
|
||||||
return DocumentOpenLink::doOpen(data, ActionOnLoadPlayInline);
|
if (button != Qt::LeftButton) return;
|
||||||
|
doOpen(document(), ActionOnLoadNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GifOpenLink::onClick(Qt::MouseButton button) const {
|
void GifOpenLink::onClick(Qt::MouseButton button) const {
|
||||||
if (button != Qt::LeftButton) return;
|
if (button != Qt::LeftButton) return;
|
||||||
doOpen(document());
|
doOpen(document(), ActionOnLoadPlayInline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) {
|
void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) {
|
||||||
|
@ -1433,23 +1159,34 @@ void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) {
|
||||||
psOpenFile(already, true);
|
psOpenFile(already, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
QFileInfo alreadyInfo(already);
|
QFileInfo alreadyInfo(already);
|
||||||
QDir alreadyDir(already.isEmpty() ? QDir() : alreadyInfo.dir());
|
QDir alreadyDir(already.isEmpty() ? QDir() : alreadyInfo.dir());
|
||||||
QString name = already.isEmpty() ? data->name : alreadyInfo.fileName(), filter;
|
QString caption, filter, prefix, name;
|
||||||
MimeType mimeType = mimeTypeForName(data->mime);
|
MimeType mimeType = mimeTypeForName(data->mime);
|
||||||
QStringList p = mimeType.globPatterns();
|
QStringList p = mimeType.globPatterns();
|
||||||
QString pattern = p.isEmpty() ? QString() : p.front();
|
QString pattern = p.isEmpty() ? QString() : p.front();
|
||||||
if (name.isEmpty()) {
|
if (data->voice()) {
|
||||||
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
bool mp3 = (data->mime == qstr("audio/mp3"));
|
||||||
}
|
caption = lang(lng_save_audio);
|
||||||
|
filter = mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)");
|
||||||
|
prefix = qsl("audio");
|
||||||
|
name = already.isEmpty() ? (mp3 ? qsl(".mp3") : qsl(".ogg")) : alreadyInfo.fileName();
|
||||||
|
} else {
|
||||||
|
caption = lang(lng_save_file);
|
||||||
if (pattern.isEmpty()) {
|
if (pattern.isEmpty()) {
|
||||||
filter = QString();
|
filter = QString();
|
||||||
} else {
|
} else {
|
||||||
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
||||||
}
|
}
|
||||||
|
prefix = qsl("doc");
|
||||||
|
name = already.isEmpty() ? data->name : alreadyInfo.fileName();
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString filename = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, forceSavingAs, alreadyDir);
|
QString filename = saveFileName(caption, filter, prefix, name, forceSavingAs, alreadyDir);
|
||||||
if (!filename.isEmpty()) {
|
if (!filename.isEmpty()) {
|
||||||
ActionOnLoad action = already.isEmpty() ? ActionOnLoadNone : ActionOnLoadOpenWith;
|
ActionOnLoad action = already.isEmpty() ? ActionOnLoadNone : ActionOnLoadOpenWith;
|
||||||
FullMsgId actionMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
|
FullMsgId actionMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
|
||||||
|
@ -1482,6 +1219,14 @@ void DocumentCancelLink::onClick(Qt::MouseButton button) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VoiceData::~VoiceData() {
|
||||||
|
if (!waveform.isEmpty() && waveform.at(0) == -1 && waveform.size() > sizeof(TaskId)) {
|
||||||
|
TaskId taskId = 0;
|
||||||
|
memcpy(&taskId, waveform.constData() + 1, sizeof(taskId));
|
||||||
|
Local::cancelTask(taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) : id(id)
|
DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) : id(id)
|
||||||
, type(FileDocument)
|
, type(FileDocument)
|
||||||
, access(access)
|
, access(access)
|
||||||
|
@ -1496,8 +1241,8 @@ DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 dat
|
||||||
, _duration(-1)
|
, _duration(-1)
|
||||||
, _actionOnLoad(ActionOnLoadNone)
|
, _actionOnLoad(ActionOnLoadNone)
|
||||||
, _loader(0) {
|
, _loader(0) {
|
||||||
_location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
|
||||||
setattributes(attributes);
|
setattributes(attributes);
|
||||||
|
_location = Local::readFileLocation(mediaKey(voice() ? AudioFileLocation : DocumentFileLocation, dc, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes) {
|
void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes) {
|
||||||
|
@ -1535,11 +1280,27 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||||
case mtpc_documentAttributeAudio: {
|
case mtpc_documentAttributeAudio: {
|
||||||
const MTPDdocumentAttributeAudio &d(attributes[i].c_documentAttributeAudio());
|
const MTPDdocumentAttributeAudio &d(attributes[i].c_documentAttributeAudio());
|
||||||
if (type == FileDocument) {
|
if (type == FileDocument) {
|
||||||
|
if (d.is_voice()) {
|
||||||
|
type = VoiceDocument;
|
||||||
|
VoiceData *voice = new VoiceData();
|
||||||
|
_additional = voice;
|
||||||
|
} else {
|
||||||
type = SongDocument;
|
type = SongDocument;
|
||||||
SongData *song = new SongData();
|
SongData *song = new SongData();
|
||||||
_additional = song;
|
_additional = song;
|
||||||
}
|
}
|
||||||
if (song()) {
|
}
|
||||||
|
if (voice()) {
|
||||||
|
voice()->duration = d.vduration.v;
|
||||||
|
VoiceWaveform waveform = documentWaveformDecode(qba(d.vwaveform));
|
||||||
|
uchar wavemax = 0;
|
||||||
|
for (int32 i = 0, l = waveform.size(); i < l; ++i) {
|
||||||
|
uchar waveat = waveform.at(i);
|
||||||
|
if (wavemax < waveat) wavemax = waveat;
|
||||||
|
}
|
||||||
|
voice()->waveform = waveform;
|
||||||
|
voice()->wavemax = wavemax;
|
||||||
|
} else if (song()) {
|
||||||
song()->duration = d.vduration.v;
|
song()->duration = d.vduration.v;
|
||||||
song()->title = qs(d.vtitle);
|
song()->title = qs(d.vtitle);
|
||||||
song()->performer = qs(d.vperformer);
|
song()->performer = qs(d.vperformer);
|
||||||
|
@ -1558,7 +1319,7 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentData::saveToCache() const {
|
bool DocumentData::saveToCache() const {
|
||||||
return (type == StickerDocument) || (isAnimation() && size < AnimationInMemory);
|
return (type == StickerDocument) || (isAnimation() && size < AnimationInMemory) || (voice() && size < AudioVoiceMsgInMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::forget() {
|
void DocumentData::forget() {
|
||||||
|
@ -1586,12 +1347,22 @@ void DocumentData::automaticLoad(const HistoryItem *item) {
|
||||||
loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate) || !(cAutoDownloadGif() & dbiadNoGroups);
|
loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate) || !(cAutoDownloadGif() & dbiadNoGroups);
|
||||||
}
|
}
|
||||||
save(QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
|
save(QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
|
||||||
|
} else if (voice()) {
|
||||||
|
if (item) {
|
||||||
|
bool loadFromCloud = false;
|
||||||
|
if (item->history()->peer->isUser()) {
|
||||||
|
loadFromCloud = !(cAutoDownloadAudio() & dbiadNoPrivate);
|
||||||
|
} else {
|
||||||
|
loadFromCloud = !(cAutoDownloadAudio() & dbiadNoGroups);
|
||||||
|
}
|
||||||
|
save(QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::automaticLoadSettingsChanged() {
|
void DocumentData::automaticLoadSettingsChanged() {
|
||||||
if (loaded() || status != FileReady || !isAnimation() || !saveToCache() || _loader != CancelledMtpFileLoader) return;
|
if (loaded() || status != FileReady || (!isAnimation() && !voice()) || !saveToCache() || _loader != CancelledMtpFileLoader) return;
|
||||||
_loader = 0;
|
_loader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,15 +1373,28 @@ void DocumentData::performActionOnLoad() {
|
||||||
QString already = loc.name();
|
QString already = loc.name();
|
||||||
HistoryItem *item = _actionOnLoadMsgId.msg ? App::histItemById(_actionOnLoadMsgId) : 0;
|
HistoryItem *item = _actionOnLoadMsgId.msg ? App::histItemById(_actionOnLoadMsgId) : 0;
|
||||||
bool showImage = item && (size < MediaViewImageSizeLimit);
|
bool showImage = item && (size < MediaViewImageSizeLimit);
|
||||||
|
bool playVoice = voice() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item;
|
||||||
bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item;
|
bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item;
|
||||||
bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item->getMedia();
|
bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item->getMedia();
|
||||||
if (playMusic) {
|
if (playVoice) {
|
||||||
|
if (loaded()) {
|
||||||
|
AudioMsgId playing;
|
||||||
|
AudioPlayerState state = AudioPlayerStopped;
|
||||||
|
audioPlayer()->currentState(&playing, &state);
|
||||||
|
if (playing.msgId == _actionOnLoadMsgId && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) {
|
||||||
|
audioPlayer()->pauseresume(OverviewVoiceFiles);
|
||||||
|
} else {
|
||||||
|
audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId));
|
||||||
|
if (App::main()) App::main()->audioMarkRead(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (playMusic) {
|
||||||
if (loaded()) {
|
if (loaded()) {
|
||||||
SongMsgId playing;
|
SongMsgId playing;
|
||||||
AudioPlayerState playingState = AudioPlayerStopped;
|
AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
audioPlayer()->currentState(&playing, &playingState);
|
audioPlayer()->currentState(&playing, &playingState);
|
||||||
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
audioPlayer()->pauseresume(OverviewDocuments);
|
audioPlayer()->pauseresume(OverviewFiles);
|
||||||
} else {
|
} else {
|
||||||
SongMsgId song(this, item->fullId());
|
SongMsgId song(this, item->fullId());
|
||||||
audioPlayer()->play(song);
|
audioPlayer()->play(song);
|
||||||
|
@ -1636,7 +1420,10 @@ void DocumentData::performActionOnLoad() {
|
||||||
psOpenFile(already, true);
|
psOpenFile(already, true);
|
||||||
}
|
}
|
||||||
} else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) {
|
} else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) {
|
||||||
if (loc.accessEnable()) {
|
if (voice()) {
|
||||||
|
psOpenFile(already);
|
||||||
|
if (App::main()) App::main()->audioMarkRead(this);
|
||||||
|
} else if (loc.accessEnable()) {
|
||||||
if (showImage && QImageReader(loc.name()).canRead()) {
|
if (showImage && QImageReader(loc.name()).canRead()) {
|
||||||
if (_actionOnLoad == ActionOnLoadPlayInline) {
|
if (_actionOnLoad == ActionOnLoadPlayInline) {
|
||||||
item->getMedia()->playInline(item);
|
item->getMedia()->playInline(item);
|
||||||
|
@ -1735,7 +1522,8 @@ void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMs
|
||||||
if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
|
if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
|
||||||
} else {
|
} else {
|
||||||
status = FileReady;
|
status = FileReady;
|
||||||
_loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
|
LocationType type = voice() ? AudioFileLocation : DocumentFileLocation;
|
||||||
|
_loader = new mtpFileLoader(dc, id, access, type, toFile, size, (saveToCache() ? LoadToCacheAsWell : LoadToFileOnly), fromCloud, autoLoading);
|
||||||
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(documentLoadProgress(FileLoader*)));
|
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(documentLoadProgress(FileLoader*)));
|
||||||
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(documentLoadFailed(FileLoader*,bool)));
|
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(documentLoadFailed(FileLoader*,bool)));
|
||||||
_loader->start();
|
_loader->start();
|
||||||
|
@ -1769,6 +1557,24 @@ void DocumentData::notifyLayoutChanged() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit) {
|
||||||
|
VoiceWaveform result((encoded5bit.size() * 8) / 5, 0);
|
||||||
|
for (int32 i = 0, l = result.size(); i < l; ++i) { // read each 5 bit of encoded5bit as 0-31 unsigned char
|
||||||
|
int32 byte = (i * 5) / 8, shift = (i * 5) % 8;
|
||||||
|
result[i] = (((*(uint16*)(encoded5bit.constData() + byte)) >> shift) & 0x1F);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray documentWaveformEncode5bit(const VoiceWaveform &waveform) {
|
||||||
|
QByteArray result((waveform.size() * 5 + 7) / 8, 0);
|
||||||
|
for (int32 i = 0, l = waveform.size(); i < l; ++i) { // write each 0-31 unsigned char as 5 bit to result
|
||||||
|
int32 byte = (i * 5) / 8, shift = (i * 5) % 8;
|
||||||
|
(*(uint16*)(result.data() + byte)) |= (uint16(waveform.at(i) & 0x1F) << shift);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QString DocumentData::already(bool check) const {
|
QString DocumentData::already(bool check) const {
|
||||||
if (check && _location.name().isEmpty()) return QString();
|
if (check && _location.name().isEmpty()) return QString();
|
||||||
return location(check).name();
|
return location(check).name();
|
||||||
|
@ -1780,7 +1586,8 @@ QByteArray DocumentData::data() const {
|
||||||
|
|
||||||
const FileLocation &DocumentData::location(bool check) const {
|
const FileLocation &DocumentData::location(bool check) const {
|
||||||
if (check && !_location.check()) {
|
if (check && !_location.check()) {
|
||||||
const_cast<DocumentData*>(this)->_location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
LocationType type = voice() ? AudioFileLocation : DocumentFileLocation;
|
||||||
|
const_cast<DocumentData*>(this)->_location = Local::readFileLocation(mediaKey(type, dc, id));
|
||||||
}
|
}
|
||||||
return _location;
|
return _location;
|
||||||
}
|
}
|
||||||
|
|
|
@ -914,138 +914,13 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioData {
|
|
||||||
public:
|
|
||||||
AudioData(const AudioId &id, const uint64 &access = 0, int32 date = 0, const QString &mime = QString(), int32 duration = 0, int32 dc = 0, int32 size = 0);
|
|
||||||
|
|
||||||
void automaticLoad(const HistoryItem *item); // auto load voice message
|
|
||||||
void automaticLoadSettingsChanged();
|
|
||||||
|
|
||||||
bool loaded(bool check = false) const;
|
|
||||||
bool loading() const;
|
|
||||||
bool displayLoading() const;
|
|
||||||
void save(const QString &toFile, ActionOnLoad action = ActionOnLoadNone, const FullMsgId &actionMsgId = FullMsgId(), LoadFromCloudSetting fromCloud = LoadFromCloudOrLocal, bool autoLoading = false);
|
|
||||||
void cancel();
|
|
||||||
float64 progress() const;
|
|
||||||
int32 loadOffset() const;
|
|
||||||
bool uploading() const;
|
|
||||||
|
|
||||||
QString already(bool check = false) const;
|
|
||||||
QByteArray data() const;
|
|
||||||
const FileLocation &location(bool check = false) const;
|
|
||||||
void setLocation(const FileLocation &loc);
|
|
||||||
|
|
||||||
bool saveToCache() const;
|
|
||||||
|
|
||||||
void performActionOnLoad();
|
|
||||||
|
|
||||||
void forget();
|
|
||||||
void setData(const QByteArray &data) {
|
|
||||||
_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioId id;
|
|
||||||
uint64 access;
|
|
||||||
int32 date;
|
|
||||||
QString mime;
|
|
||||||
int32 duration;
|
|
||||||
int32 dc;
|
|
||||||
int32 size;
|
|
||||||
|
|
||||||
FileStatus status;
|
|
||||||
int32 uploadOffset;
|
|
||||||
|
|
||||||
int32 md5[8];
|
|
||||||
|
|
||||||
private:
|
|
||||||
FileLocation _location;
|
|
||||||
QByteArray _data;
|
|
||||||
|
|
||||||
ActionOnLoad _actionOnLoad;
|
|
||||||
FullMsgId _actionOnLoadMsgId;
|
|
||||||
mutable mtpFileLoader *_loader;
|
|
||||||
|
|
||||||
void notifyLayoutChanged() const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AudioMsgId {
|
|
||||||
AudioMsgId() : audio(0) {
|
|
||||||
}
|
|
||||||
AudioMsgId(AudioData *audio, const FullMsgId &msgId) : audio(audio), msgId(msgId) {
|
|
||||||
}
|
|
||||||
AudioMsgId(AudioData *audio, ChannelId channelId, MsgId msgId) : audio(audio), msgId(channelId, msgId) {
|
|
||||||
}
|
|
||||||
operator bool() const {
|
|
||||||
return audio;
|
|
||||||
}
|
|
||||||
AudioData *audio;
|
|
||||||
FullMsgId msgId;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator<(const AudioMsgId &a, const AudioMsgId &b) {
|
|
||||||
return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.msgId < b.msgId);
|
|
||||||
}
|
|
||||||
inline bool operator==(const AudioMsgId &a, const AudioMsgId &b) {
|
|
||||||
return a.audio == b.audio && a.msgId == b.msgId;
|
|
||||||
}
|
|
||||||
inline bool operator!=(const AudioMsgId &a, const AudioMsgId &b) {
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AudioLink : public ITextLink {
|
|
||||||
TEXT_LINK_CLASS(AudioLink)
|
|
||||||
|
|
||||||
public:
|
|
||||||
AudioLink(AudioData *audio) : _audio(audio) {
|
|
||||||
}
|
|
||||||
AudioData *audio() const {
|
|
||||||
return _audio;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
AudioData *_audio;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioSaveLink : public AudioLink {
|
|
||||||
TEXT_LINK_CLASS(AudioSaveLink)
|
|
||||||
|
|
||||||
public:
|
|
||||||
AudioSaveLink(AudioData *audio) : AudioLink(audio) {
|
|
||||||
}
|
|
||||||
static void doSave(AudioData *audio, bool forceSavingAs = false);
|
|
||||||
void onClick(Qt::MouseButton button) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioOpenLink : public AudioLink {
|
|
||||||
TEXT_LINK_CLASS(AudioOpenLink)
|
|
||||||
|
|
||||||
public:
|
|
||||||
AudioOpenLink(AudioData *audio) : AudioLink(audio) {
|
|
||||||
}
|
|
||||||
void onClick(Qt::MouseButton button) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioCancelLink : public AudioLink {
|
|
||||||
TEXT_LINK_CLASS(AudioCancelLink)
|
|
||||||
|
|
||||||
public:
|
|
||||||
AudioCancelLink(AudioData *audio) : AudioLink(audio) {
|
|
||||||
}
|
|
||||||
void onClick(Qt::MouseButton button) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DocumentType {
|
enum DocumentType {
|
||||||
FileDocument = 0,
|
FileDocument = 0,
|
||||||
VideoDocument = 1,
|
VideoDocument = 1,
|
||||||
SongDocument = 2,
|
SongDocument = 2,
|
||||||
StickerDocument = 3,
|
StickerDocument = 3,
|
||||||
AnimatedDocument = 4,
|
AnimatedDocument = 4,
|
||||||
|
VoiceDocument = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DocumentAdditionalData {
|
struct DocumentAdditionalData {
|
||||||
|
@ -1072,6 +947,16 @@ struct SongData : public DocumentAdditionalData {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QVector<char> VoiceWaveform; // [0] == -1 -- counting, [0] == -2 -- could not count
|
||||||
|
struct VoiceData : public DocumentAdditionalData {
|
||||||
|
VoiceData() : duration(0), wavemax(0) {
|
||||||
|
}
|
||||||
|
~VoiceData();
|
||||||
|
int32 duration;
|
||||||
|
VoiceWaveform waveform;
|
||||||
|
char wavemax;
|
||||||
|
};
|
||||||
|
|
||||||
bool fileIsImage(const QString &name, const QString &mime);
|
bool fileIsImage(const QString &name, const QString &mime);
|
||||||
|
|
||||||
class DocumentData {
|
class DocumentData {
|
||||||
|
@ -1126,12 +1011,21 @@ public:
|
||||||
SongData *song() {
|
SongData *song() {
|
||||||
return (type == SongDocument) ? static_cast<SongData*>(_additional) : 0;
|
return (type == SongDocument) ? static_cast<SongData*>(_additional) : 0;
|
||||||
}
|
}
|
||||||
|
VoiceData *voice() {
|
||||||
|
return (type == VoiceDocument) ? static_cast<VoiceData*>(_additional) : 0;
|
||||||
|
}
|
||||||
|
const VoiceData *voice() const {
|
||||||
|
return (type == VoiceDocument) ? static_cast<VoiceData*>(_additional) : 0;
|
||||||
|
}
|
||||||
bool isAnimation() const {
|
bool isAnimation() const {
|
||||||
return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive);
|
return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
bool isGifv() const {
|
bool isGifv() const {
|
||||||
return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive);
|
return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
bool isMusic() const {
|
||||||
|
return (type == SongDocument) ? !static_cast<SongData*>(_additional)->title.isEmpty() : false;
|
||||||
|
}
|
||||||
int32 duration() const {
|
int32 duration() const {
|
||||||
return (isAnimation() || type == VideoDocument) ? _duration : -1;
|
return (isAnimation() || type == VideoDocument) ? _duration : -1;
|
||||||
}
|
}
|
||||||
|
@ -1139,6 +1033,9 @@ public:
|
||||||
return !isAnimation() && (type != VideoDocument) && (_duration > 0);
|
return !isAnimation() && (type != VideoDocument) && (_duration > 0);
|
||||||
}
|
}
|
||||||
void recountIsImage();
|
void recountIsImage();
|
||||||
|
void setData(const QByteArray &data) {
|
||||||
|
_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
~DocumentData();
|
~DocumentData();
|
||||||
|
|
||||||
|
@ -1172,6 +1069,9 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit);
|
||||||
|
QByteArray documentWaveformEncode5bit(const VoiceWaveform &waveform);
|
||||||
|
|
||||||
struct SongMsgId {
|
struct SongMsgId {
|
||||||
SongMsgId() : song(0) {
|
SongMsgId() : song(0) {
|
||||||
}
|
}
|
||||||
|
@ -1196,6 +1096,31 @@ inline bool operator!=(const SongMsgId &a, const SongMsgId &b) {
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AudioMsgId {
|
||||||
|
AudioMsgId() : audio(0) {
|
||||||
|
}
|
||||||
|
AudioMsgId(DocumentData *audio, const FullMsgId &msgId) : audio(audio), msgId(msgId) {
|
||||||
|
}
|
||||||
|
AudioMsgId(DocumentData *audio, ChannelId channelId, MsgId msgId) : audio(audio), msgId(channelId, msgId) {
|
||||||
|
}
|
||||||
|
operator bool() const {
|
||||||
|
return audio;
|
||||||
|
}
|
||||||
|
DocumentData *audio;
|
||||||
|
FullMsgId msgId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator<(const AudioMsgId &a, const AudioMsgId &b) {
|
||||||
|
return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.msgId < b.msgId);
|
||||||
|
}
|
||||||
|
inline bool operator==(const AudioMsgId &a, const AudioMsgId &b) {
|
||||||
|
return a.audio == b.audio && a.msgId == b.msgId;
|
||||||
|
}
|
||||||
|
inline bool operator!=(const AudioMsgId &a, const AudioMsgId &b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
class DocumentLink : public ITextLink {
|
class DocumentLink : public ITextLink {
|
||||||
TEXT_LINK_CLASS(DocumentLink)
|
TEXT_LINK_CLASS(DocumentLink)
|
||||||
|
|
||||||
|
@ -1233,13 +1158,22 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VoiceSaveLink : public DocumentOpenLink {
|
||||||
|
TEXT_LINK_CLASS(VoiceSaveLink)
|
||||||
|
|
||||||
|
public:
|
||||||
|
VoiceSaveLink(DocumentData *document) : DocumentOpenLink(document) {
|
||||||
|
}
|
||||||
|
void onClick(Qt::MouseButton button) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class GifOpenLink : public DocumentOpenLink {
|
class GifOpenLink : public DocumentOpenLink {
|
||||||
TEXT_LINK_CLASS(GifOpenLink)
|
TEXT_LINK_CLASS(GifOpenLink)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GifOpenLink(DocumentData *document) : DocumentOpenLink(document) {
|
GifOpenLink(DocumentData *document) : DocumentOpenLink(document) {
|
||||||
}
|
}
|
||||||
static void doOpen(DocumentData *document);
|
|
||||||
void onClick(Qt::MouseButton button) const;
|
void onClick(Qt::MouseButton button) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -532,18 +532,21 @@ inline void destroyImplementation(I *&ptr) {
|
||||||
class Interfaces;
|
class Interfaces;
|
||||||
typedef void(*InterfaceConstruct)(void *location, Interfaces *interfaces);
|
typedef void(*InterfaceConstruct)(void *location, Interfaces *interfaces);
|
||||||
typedef void(*InterfaceDestruct)(void *location);
|
typedef void(*InterfaceDestruct)(void *location);
|
||||||
|
typedef void(*InterfaceAssign)(void *location, void *waslocation);
|
||||||
|
|
||||||
struct InterfaceWrapStruct {
|
struct InterfaceWrapStruct {
|
||||||
InterfaceWrapStruct() : Size(0), Construct(0), Destruct(0) {
|
InterfaceWrapStruct() : Size(0), Construct(0), Destruct(0) {
|
||||||
}
|
}
|
||||||
InterfaceWrapStruct(int size, InterfaceConstruct construct, InterfaceDestruct destruct)
|
InterfaceWrapStruct(int size, InterfaceConstruct construct, InterfaceDestruct destruct, InterfaceAssign assign)
|
||||||
: Size(size)
|
: Size(size)
|
||||||
, Construct(construct)
|
, Construct(construct)
|
||||||
, Destruct(destruct) {
|
, Destruct(destruct)
|
||||||
|
, Assign(assign) {
|
||||||
}
|
}
|
||||||
int Size;
|
int Size;
|
||||||
InterfaceConstruct Construct;
|
InterfaceConstruct Construct;
|
||||||
InterfaceDestruct Destruct;
|
InterfaceDestruct Destruct;
|
||||||
|
InterfaceAssign Assign;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <int Value, int Denominator>
|
template <int Value, int Denominator>
|
||||||
|
@ -560,6 +563,9 @@ struct InterfaceWrapTemplate {
|
||||||
static void Destruct(void *location) {
|
static void Destruct(void *location) {
|
||||||
((Type*)location)->~Type();
|
((Type*)location)->~Type();
|
||||||
}
|
}
|
||||||
|
static void Assign(void *location, void *waslocation) {
|
||||||
|
*((Type*)location) = *((Type*)waslocation);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern InterfaceWrapStruct InterfaceWraps[64];
|
extern InterfaceWrapStruct InterfaceWraps[64];
|
||||||
|
@ -578,7 +584,7 @@ public:
|
||||||
if (InterfaceIndexLast.testAndSetOrdered(last, last + 1)) {
|
if (InterfaceIndexLast.testAndSetOrdered(last, last + 1)) {
|
||||||
t_assert(last < 64);
|
t_assert(last < 64);
|
||||||
if (_index.testAndSetOrdered(0, last + 1)) {
|
if (_index.testAndSetOrdered(0, last + 1)) {
|
||||||
InterfaceWraps[last] = InterfaceWrapStruct(InterfaceWrapTemplate<Type>::Size, InterfaceWrapTemplate<Type>::Construct, InterfaceWrapTemplate<Type>::Destruct);
|
InterfaceWraps[last] = InterfaceWrapStruct(InterfaceWrapTemplate<Type>::Size, InterfaceWrapTemplate<Type>::Construct, InterfaceWrapTemplate<Type>::Destruct, InterfaceWrapTemplate<Type>::Assign);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -627,6 +633,10 @@ public:
|
||||||
int size, last;
|
int size, last;
|
||||||
int offsets[64];
|
int offsets[64];
|
||||||
|
|
||||||
|
bool equals(const uint64 &mask) const {
|
||||||
|
return _mask == mask;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64 _mask;
|
uint64 _mask;
|
||||||
|
|
||||||
|
@ -637,22 +647,25 @@ const InterfacesMetadata *GetInterfacesMetadata(uint64 mask);
|
||||||
class Interfaces {
|
class Interfaces {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Interfaces(uint64 mask = 0) : _meta(GetInterfacesMetadata(mask)), _data(0) {
|
Interfaces(uint64 mask = 0) : _data(0) {
|
||||||
if (_meta->size) {
|
if (mask) {
|
||||||
_data = malloc(_meta->size);
|
const InterfacesMetadata *meta = GetInterfacesMetadata(mask);
|
||||||
|
int32 size = sizeof(const InterfacesMetadata *) + meta->size;
|
||||||
|
_data = malloc(size);
|
||||||
if (!_data) { // terminate if we can't allocate memory
|
if (!_data) { // terminate if we can't allocate memory
|
||||||
throw "Can't allocate memory!";
|
throw "Can't allocate memory!";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _meta->last; ++i) {
|
_meta() = meta;
|
||||||
int offset = _meta->offsets[i];
|
for (int i = 0; i < meta->last; ++i) {
|
||||||
|
int offset = meta->offsets[i];
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
try {
|
try {
|
||||||
InterfaceWraps[i].Construct(_dataptrunsafe(offset), this);
|
InterfaceWraps[i].Construct(_dataptrunsafe(offset), this);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
--i;
|
--i;
|
||||||
offset = _meta->offsets[--i];
|
offset = meta->offsets[--i];
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
InterfaceWraps[i].Destruct(_dataptrunsafe(offset));
|
InterfaceWraps[i].Destruct(_dataptrunsafe(offset));
|
||||||
}
|
}
|
||||||
|
@ -663,10 +676,28 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void UpdateInterfaces(uint64 mask = 0) {
|
||||||
|
if (!_data && !mask) return;
|
||||||
|
if (!_data || !_meta()->equals(mask)) {
|
||||||
|
Interfaces tmp(mask);
|
||||||
|
tmp.swap(*this);
|
||||||
|
|
||||||
|
if (_data && tmp._data) {
|
||||||
|
const InterfacesMetadata *meta = _meta(), *wasmeta = tmp._meta();
|
||||||
|
for (int i = 0; i < meta->last; ++i) {
|
||||||
|
int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
|
||||||
|
if (offset >= 0 && wasoffset >= 0) {
|
||||||
|
InterfaceWraps[i].Assign(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
~Interfaces() {
|
~Interfaces() {
|
||||||
if (_data) {
|
if (_data) {
|
||||||
for (int i = 0; i < _meta->last; ++i) {
|
const InterfacesMetadata *meta = _meta();
|
||||||
int offset = _meta->offsets[i];
|
for (int i = 0; i < meta->last; ++i) {
|
||||||
|
int offset = meta->offsets[i];
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
InterfaceWraps[i].Destruct(_dataptrunsafe(offset));
|
InterfaceWraps[i].Destruct(_dataptrunsafe(offset));
|
||||||
}
|
}
|
||||||
|
@ -677,24 +708,33 @@ public:
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type *Get() {
|
Type *Get() {
|
||||||
return (Type*)_dataptr(_meta->offsets[Type::Index()]);
|
return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
|
||||||
}
|
}
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
const Type *Get() const {
|
const Type *Get() const {
|
||||||
return (const Type*)_dataptr(_meta->offsets[Type::Index()]);
|
return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void *_dataptrunsafe(int skip) const {
|
void *_dataptrunsafe(int skip) const {
|
||||||
return (char*)_data + skip;
|
return (char*)_data + sizeof(const InterfacesMetadata*) + skip;
|
||||||
}
|
}
|
||||||
void *_dataptr(int skip) const {
|
void *_dataptr(int skip) const {
|
||||||
return (skip >= 0) ? _dataptrunsafe(skip) : 0;
|
return (skip >= 0) ? _dataptrunsafe(skip) : 0;
|
||||||
}
|
}
|
||||||
const InterfacesMetadata *_meta;
|
const InterfacesMetadata *&_meta() const {
|
||||||
|
return *static_cast<const InterfacesMetadata**>(_data);
|
||||||
|
}
|
||||||
void *_data;
|
void *_data;
|
||||||
|
|
||||||
|
Interfaces(const Interfaces &other);
|
||||||
|
Interfaces &operator=(const Interfaces &other);
|
||||||
|
|
||||||
|
void swap(Interfaces &other) {
|
||||||
|
std::swap(_data, other._data);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
|
|
|
@ -645,7 +645,7 @@ void Window::sendServiceHistoryRequest() {
|
||||||
int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status | MTPDuser::flag_verified;
|
int32 userFlags = MTPDuser::flag_first_name | MTPDuser::flag_phone | MTPDuser::flag_status | MTPDuser::flag_verified;
|
||||||
user = App::feedUsers(MTP_vector<MTPUser>(1, MTP_user(MTP_int(userFlags), MTP_int(ServiceUserId), MTPlong(), MTP_string("Telegram"), MTPstring(), MTPstring(), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently(), MTPint(), MTPstring(), MTPstring())));
|
user = App::feedUsers(MTP_vector<MTPUser>(1, MTP_user(MTP_int(userFlags), MTP_int(ServiceUserId), MTPlong(), MTP_string("Telegram"), MTPstring(), MTPstring(), MTP_string("42777"), MTP_userProfilePhotoEmpty(), MTP_userStatusRecently(), MTPint(), MTPstring(), MTPstring())));
|
||||||
}
|
}
|
||||||
_serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail));
|
_serviceHistoryRequest = MTP::send(MTPmessages_GetHistory(user->input, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(1), MTP_int(0), MTP_int(0)), main->rpcDone(&MainWidget::serviceHistoryDone), main->rpcFail(&MainWidget::serviceHistoryFail));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupMain(bool anim, const MTPUser *self) {
|
void Window::setupMain(bool anim, const MTPUser *self) {
|
||||||
|
|
Loading…
Reference in New Issue