mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Display photos and videos together in MediaView.
This commit is contained in:
parent
e07a7a4b4c
commit
54d6673d0b
5 changed files with 90 additions and 48 deletions
|
@ -36,13 +36,15 @@ MTPmessages_Search PrepareSearchRequest(
|
|||
const QString &query,
|
||||
MsgId messageId,
|
||||
SparseIdsLoadDirection direction) {
|
||||
auto filter = [&] {
|
||||
const auto filter = [&] {
|
||||
using Type = Storage::SharedMediaType;
|
||||
switch (type) {
|
||||
case Type::Photo:
|
||||
return MTP_inputMessagesFilterPhotos();
|
||||
case Type::Video:
|
||||
return MTP_inputMessagesFilterVideo();
|
||||
case Type::PhotoVideo:
|
||||
return MTP_inputMessagesFilterPhotoVideo();
|
||||
case Type::MusicFile:
|
||||
return MTP_inputMessagesFilterMusic();
|
||||
case Type::File:
|
||||
|
@ -63,10 +65,10 @@ MTPmessages_Search PrepareSearchRequest(
|
|||
return MTP_inputMessagesFilterEmpty();
|
||||
}();
|
||||
|
||||
auto minId = 0;
|
||||
auto maxId = 0;
|
||||
auto limit = messageId ? kSharedMediaLimit : 0;
|
||||
auto offsetId = [&] {
|
||||
const auto minId = 0;
|
||||
const auto maxId = 0;
|
||||
const auto limit = messageId ? kSharedMediaLimit : 0;
|
||||
const auto offsetId = [&] {
|
||||
switch (direction) {
|
||||
case SparseIdsLoadDirection::Before:
|
||||
case SparseIdsLoadDirection::Around: return messageId;
|
||||
|
@ -74,7 +76,7 @@ MTPmessages_Search PrepareSearchRequest(
|
|||
}
|
||||
Unexpected("Direction in PrepareSearchRequest");
|
||||
}();
|
||||
auto addOffset = [&] {
|
||||
const auto addOffset = [&] {
|
||||
switch (direction) {
|
||||
case SparseIdsLoadDirection::Before: return 0;
|
||||
case SparseIdsLoadDirection::Around: return -limit / 2;
|
||||
|
@ -130,7 +132,8 @@ SearchResult ParseSearchResult(
|
|||
if (auto channel = peer->asChannel()) {
|
||||
channel->ptsReceived(d.vpts.v);
|
||||
} else {
|
||||
LOG(("API Error: received messages.channelMessages when no channel was passed! (ParseSearchResult)"));
|
||||
LOG(("API Error: received messages.channelMessages when "
|
||||
"no channel was passed! (ParseSearchResult)"));
|
||||
}
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
|
@ -139,7 +142,8 @@ SearchResult ParseSearchResult(
|
|||
} break;
|
||||
|
||||
case mtpc_messages_messagesNotModified: {
|
||||
LOG(("API Error: received messages.messagesNotModified! (ParseSearchResult)"));
|
||||
LOG(("API Error: received messages.messagesNotModified! "
|
||||
"(ParseSearchResult)"));
|
||||
return (const QVector<MTPMessage>*)nullptr;
|
||||
} break;
|
||||
}
|
||||
|
|
|
@ -839,10 +839,13 @@ bool HistoryPhoto::needsBubble() const {
|
|||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryPhoto::sharedMediaTypes() const {
|
||||
using Type = Storage::SharedMediaType;
|
||||
if (_parent->toHistoryMessage()) {
|
||||
return Storage::SharedMediaType::Photo;
|
||||
return Storage::SharedMediaTypesMask{}
|
||||
.added(Type::Photo)
|
||||
.added(Type::PhotoVideo);
|
||||
}
|
||||
return Storage::SharedMediaType::ChatPhoto;
|
||||
return Type::ChatPhoto;
|
||||
}
|
||||
|
||||
ImagePtr HistoryPhoto::replyPreview() {
|
||||
|
@ -1305,7 +1308,10 @@ bool HistoryVideo::needsBubble() const {
|
|||
}
|
||||
|
||||
Storage::SharedMediaTypesMask HistoryVideo::sharedMediaTypes() const {
|
||||
return Storage::SharedMediaType::Video;
|
||||
using Type = Storage::SharedMediaType;
|
||||
return Storage::SharedMediaTypesMask{}
|
||||
.added(Type::Video)
|
||||
.added(Type::PhotoVideo);
|
||||
}
|
||||
|
||||
void HistoryVideo::updateStatusText() const {
|
||||
|
|
|
@ -211,12 +211,22 @@ bool MediaView::fileBubbleShown() const {
|
|||
bool MediaView::gifShown() const {
|
||||
if (_gif && _gif->ready()) {
|
||||
if (!_gif->started()) {
|
||||
if (_doc && (_doc->isVideoFile() || _doc->isVideoMessage()) && _autoplayVideoDocument != _doc && !_gif->videoPaused()) {
|
||||
_gif->pauseResumeVideo();
|
||||
const_cast<MediaView*>(this)->_videoPaused = _gif->videoPaused();
|
||||
const auto streamVideo = _doc
|
||||
&& (_doc->isVideoFile() || _doc->isVideoMessage());
|
||||
const auto pauseOnStart = (_autoplayVideoDocument != _doc);
|
||||
if (streamVideo && pauseOnStart && !_gif->videoPaused()) {
|
||||
const_cast<MediaView*>(this)->toggleVideoPaused();
|
||||
}
|
||||
auto rounding = (_doc && _doc->isVideoMessage()) ? ImageRoundRadius::Ellipse : ImageRoundRadius::None;
|
||||
_gif->start(_gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), _gif->width() / cIntRetinaFactor(), _gif->height() / cIntRetinaFactor(), rounding, RectPart::AllCorners);
|
||||
const auto rounding = (_doc && _doc->isVideoMessage())
|
||||
? ImageRoundRadius::Ellipse
|
||||
: ImageRoundRadius::None;
|
||||
_gif->start(
|
||||
_gif->width() / cIntRetinaFactor(),
|
||||
_gif->height() / cIntRetinaFactor(),
|
||||
_gif->width() / cIntRetinaFactor(),
|
||||
_gif->height() / cIntRetinaFactor(),
|
||||
rounding,
|
||||
RectPart::AllCorners);
|
||||
const_cast<MediaView*>(this)->_current = QPixmap();
|
||||
updateMixerVideoVolume();
|
||||
Global::RefVideoVolumeChanged().notify();
|
||||
|
@ -413,13 +423,27 @@ void MediaView::updateActions() {
|
|||
}
|
||||
_actions.push_back({ lang(lng_mediaview_save_as), SLOT(onSaveAs()) });
|
||||
|
||||
if (auto overviewType =
|
||||
sharedMediaType()
|
||||
| SharedMediaOverviewType) {
|
||||
if (const auto overviewType = computeOverviewType()) {
|
||||
_actions.push_back({ lang(_doc ? lng_mediaview_files_all : lng_mediaview_photos_all), SLOT(onOverview()) });
|
||||
}
|
||||
}
|
||||
|
||||
auto MediaView::computeOverviewType() const
|
||||
-> base::optional<SharedMediaType> {
|
||||
if (const auto mediaType = sharedMediaType()) {
|
||||
if (const auto overviewType = SharedMediaOverviewType(*mediaType)) {
|
||||
return overviewType;
|
||||
} else if (mediaType == SharedMediaType::PhotoVideo) {
|
||||
if (_photo) {
|
||||
return SharedMediaOverviewType(SharedMediaType::Photo);
|
||||
} else if (_doc) {
|
||||
return SharedMediaOverviewType(SharedMediaType::Video);
|
||||
}
|
||||
}
|
||||
}
|
||||
return base::none;
|
||||
}
|
||||
|
||||
void MediaView::step_state(TimeMs ms, bool timer) {
|
||||
bool result = false;
|
||||
for (Showing::iterator i = _animations.begin(); i != _animations.end();) {
|
||||
|
@ -512,21 +536,26 @@ void MediaView::step_radial(TimeMs ms, bool timer) {
|
|||
_radial.stop();
|
||||
return;
|
||||
}
|
||||
auto wasAnimating = _radial.animating();
|
||||
const auto wasAnimating = _radial.animating();
|
||||
_radial.update(radialProgress(), !radialLoading(), ms + radialTimeShift());
|
||||
if (timer && (wasAnimating || _radial.animating())) {
|
||||
update(radialRect());
|
||||
}
|
||||
if (_doc && _doc->loaded() && _doc->size < App::kImageSizeLimit && (!_radial.animating() || _doc->isAnimation() || _doc->isVideoFile())) {
|
||||
const auto ready = _doc && _doc->loaded();
|
||||
const auto streamVideo = _doc->isAnimation() || _doc->isVideoFile();
|
||||
const auto tryOpenImage = (_doc->size < App::kImageSizeLimit);
|
||||
if (ready && ((tryOpenImage && !_radial.animating()) || streamVideo)) {
|
||||
if (_doc->isVideoFile() || _doc->isVideoMessage()) {
|
||||
_autoplayVideoDocument = _doc;
|
||||
}
|
||||
if (!_doc->data().isEmpty() && (_doc->isAnimation() || _doc->isVideoFile())) {
|
||||
if (!_doc->data().isEmpty() && streamVideo) {
|
||||
displayDocument(_doc, App::histItemById(_msgid));
|
||||
} else {
|
||||
auto &location = _doc->location(true);
|
||||
if (location.accessEnable()) {
|
||||
if (_doc->isAnimation() || _doc->isVideoFile() || _doc->isTheme() || QImageReader(location.name()).canRead()) {
|
||||
if (streamVideo
|
||||
|| _doc->isTheme()
|
||||
|| QImageReader(location.name()).canRead()) {
|
||||
displayDocument(_doc, App::histItemById(_msgid));
|
||||
}
|
||||
location.accessDisable();
|
||||
|
@ -963,9 +992,7 @@ void MediaView::onDelete() {
|
|||
void MediaView::onOverview() {
|
||||
if (_menu) _menu->hideMenu(true);
|
||||
update();
|
||||
if (auto overviewType =
|
||||
sharedMediaType()
|
||||
| SharedMediaOverviewType) {
|
||||
if (const auto overviewType = computeOverviewType()) {
|
||||
close();
|
||||
SharedMediaShowOverview(*overviewType, _history);
|
||||
}
|
||||
|
@ -991,14 +1018,14 @@ base::optional<MediaView::SharedMediaType> MediaView::sharedMediaType() const {
|
|||
if (auto item = App::histItemById(_msgid)) {
|
||||
if (_photo) {
|
||||
if (item->toHistoryMessage()) {
|
||||
return Type::Photo;
|
||||
return Type::PhotoVideo;
|
||||
}
|
||||
return Type::ChatPhoto;
|
||||
} else if (_doc) {
|
||||
if (_doc->isGifv()) {
|
||||
return Type::GIF;
|
||||
} else if (_doc->isVideoFile()) {
|
||||
return Type::Video;
|
||||
return Type::PhotoVideo;
|
||||
}
|
||||
return Type::File;
|
||||
}
|
||||
|
@ -1254,7 +1281,7 @@ void MediaView::showDocument(not_null<DocumentData*> document, HistoryItem *cont
|
|||
void MediaView::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item) {
|
||||
stopGif();
|
||||
destroyThemePreview();
|
||||
_doc = nullptr;
|
||||
_doc = _autoplayVideoDocument = nullptr;
|
||||
_fullScreenVideo = false;
|
||||
_photo = photo;
|
||||
_radial.stop();
|
||||
|
@ -1646,11 +1673,7 @@ void MediaView::onVideoPauseResume() {
|
|||
} else if (_gif->state() == Media::Clip::State::Finished) {
|
||||
restartVideoAtSeekPosition(0);
|
||||
} else {
|
||||
_gif->pauseResumeVideo();
|
||||
_videoPaused = _gif->videoPaused();
|
||||
if (_videoIsSilent) {
|
||||
updateSilentVideoPlaybackState();
|
||||
}
|
||||
toggleVideoPaused();
|
||||
}
|
||||
} else {
|
||||
stopGif();
|
||||
|
@ -1659,6 +1682,14 @@ void MediaView::onVideoPauseResume() {
|
|||
}
|
||||
}
|
||||
|
||||
void MediaView::toggleVideoPaused() {
|
||||
_gif->pauseResumeVideo();
|
||||
_videoPaused = _gif->videoPaused();
|
||||
if (_videoIsSilent) {
|
||||
updateSilentVideoPlaybackState();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaView::restartVideoAtSeekPosition(TimeMs positionMs) {
|
||||
_autoplayVideoDocument = _doc;
|
||||
|
||||
|
@ -2857,9 +2888,7 @@ void MediaView::updateHeader() {
|
|||
_headerText = lang(lng_mediaview_single_photo);
|
||||
}
|
||||
}
|
||||
_headerHasLink = (
|
||||
sharedMediaType()
|
||||
| SharedMediaOverviewType) != base::none;
|
||||
_headerHasLink = computeOverviewType() != base::none;
|
||||
auto hwidth = st::mediaviewThickFont->width(_headerText);
|
||||
if (hwidth > width() / 3) {
|
||||
hwidth = width() / 3;
|
||||
|
|
|
@ -171,6 +171,7 @@ private:
|
|||
using SharedMediaKey = SharedMediaWithLastSlice::Key;
|
||||
base::optional<SharedMediaType> sharedMediaType() const;
|
||||
base::optional<SharedMediaKey> sharedMediaKey() const;
|
||||
base::optional<SharedMediaType> computeOverviewType() const;
|
||||
bool validSharedMedia() const;
|
||||
void validateSharedMedia();
|
||||
void handleSharedMediaUpdate(SharedMediaWithLastSlice &&update);
|
||||
|
@ -201,6 +202,7 @@ private:
|
|||
void updateVideoPlaybackState(const Media::Player::TrackState &state);
|
||||
void updateSilentVideoPlaybackState();
|
||||
void restartVideoAtSeekPosition(TimeMs positionMs);
|
||||
void toggleVideoPaused();
|
||||
|
||||
void createClipController();
|
||||
void setClipControllerGeometry();
|
||||
|
|
|
@ -28,18 +28,19 @@ namespace Storage {
|
|||
|
||||
// Allow forward declarations.
|
||||
enum class SharedMediaType : char {
|
||||
Photo = 0,
|
||||
Video = 1,
|
||||
MusicFile = 2,
|
||||
File = 3,
|
||||
VoiceFile = 4,
|
||||
Link = 5,
|
||||
ChatPhoto = 6,
|
||||
RoundVoiceFile = 7,
|
||||
GIF = 8,
|
||||
RoundFile = 9,
|
||||
Photo,
|
||||
Video,
|
||||
PhotoVideo,
|
||||
MusicFile,
|
||||
File,
|
||||
VoiceFile,
|
||||
Link,
|
||||
ChatPhoto,
|
||||
RoundVoiceFile,
|
||||
GIF,
|
||||
RoundFile,
|
||||
|
||||
kCount = 10,
|
||||
kCount,
|
||||
};
|
||||
constexpr auto kSharedMediaTypeCount = static_cast<int>(SharedMediaType::kCount);
|
||||
constexpr bool IsValidSharedMediaType(SharedMediaType type) {
|
||||
|
|
Loading…
Add table
Reference in a new issue