mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 09:41:41 -05:00
Add button to download audio files.
This commit is contained in:
parent
bc2b0f8392
commit
d646de7184
16 changed files with 193 additions and 27 deletions
BIN
Telegram/Resources/icons/history_audio_cancel.png
Normal file
BIN
Telegram/Resources/icons/history_audio_cancel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 153 B |
BIN
Telegram/Resources/icons/history_audio_cancel@2x.png
Normal file
BIN
Telegram/Resources/icons/history_audio_cancel@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 251 B |
BIN
Telegram/Resources/icons/history_audio_cancel@3x.png
Normal file
BIN
Telegram/Resources/icons/history_audio_cancel@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 487 B |
BIN
Telegram/Resources/icons/history_audio_download.png
Normal file
BIN
Telegram/Resources/icons/history_audio_download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 160 B |
BIN
Telegram/Resources/icons/history_audio_download@2x.png
Normal file
BIN
Telegram/Resources/icons/history_audio_download@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 221 B |
BIN
Telegram/Resources/icons/history_audio_download@3x.png
Normal file
BIN
Telegram/Resources/icons/history_audio_download@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 453 B |
|
@ -61,8 +61,6 @@ enum {
|
|||
|
||||
MaxMessageSize = 4096,
|
||||
|
||||
SetOnlineAfterActivity = 30, // user with hidden last seen stays online for such amount of seconds in the interface
|
||||
|
||||
WebPageUserId = 701000,
|
||||
|
||||
UpdateDelayConstPart = 8 * 3600, // 8 hour min time between update check requests
|
||||
|
|
|
@ -15,6 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace {
|
||||
|
||||
// User with hidden last seen stays online in UI for such amount of seconds.
|
||||
constexpr auto kSetOnlineAfterActivity = TimeId(30);
|
||||
|
||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||
|
||||
} // namespace
|
||||
|
@ -213,10 +216,10 @@ void UserData::madeAction(TimeId when) {
|
|||
if (isBot() || isServiceUser() || when <= 0) {
|
||||
return;
|
||||
} else if (onlineTill <= 0 && -onlineTill < when) {
|
||||
onlineTill = -when - SetOnlineAfterActivity;
|
||||
onlineTill = -when - kSetOnlineAfterActivity;
|
||||
Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::UserOnlineChanged);
|
||||
} else if (onlineTill > 0 && onlineTill < when + 1) {
|
||||
onlineTill = when + SetOnlineAfterActivity;
|
||||
onlineTill = when + kSetOnlineAfterActivity;
|
||||
Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::UserOnlineChanged);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -559,3 +559,16 @@ historyVideoCancel: icon {{ "playlist_cancel", historyFileThumbIconFg }};
|
|||
historyVideoCancelSelected: icon {{ "playlist_cancel", historyFileThumbIconFgSelected }};
|
||||
historyVideoDownload: icon {{ "playlist_download", historyFileThumbIconFg }};
|
||||
historyVideoDownloadSelected: icon {{ "playlist_download", historyFileThumbIconFgSelected }};
|
||||
historyVideoRadialLine: 2px;
|
||||
|
||||
historyAudioDownloadSize: 20px;
|
||||
historyAudioRadialLine: 2px;
|
||||
historyAudioDownloadShift: 28px;
|
||||
historyAudioInCancel: icon {{ "history_audio_cancel", historyFileInIconFg }};
|
||||
historyAudioInCancelSelected: icon {{ "history_audio_cancel", historyFileInIconFgSelected }};
|
||||
historyAudioOutCancel: icon {{ "history_audio_cancel", historyFileOutIconFg }};
|
||||
historyAudioOutCancelSelected: icon {{ "history_audio_cancel", historyFileOutIconFgSelected }};
|
||||
historyAudioInDownload: icon {{ "history_audio_download", historyFileInIconFg }};
|
||||
historyAudioInDownloadSelected: icon {{ "history_audio_download", historyFileInIconFgSelected }};
|
||||
historyAudioOutDownload: icon {{ "history_audio_download", historyFileOutIconFg }};
|
||||
historyAudioOutDownloadSelected: icon {{ "history_audio_download", historyFileOutIconFgSelected }};
|
||||
|
|
|
@ -206,6 +206,8 @@ QSize HistoryDocument::countCurrentSize(int newWidth) {
|
|||
void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const {
|
||||
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||
|
||||
const auto cornerDownload = downloadInCorner();
|
||||
|
||||
_data->automaticLoad(_realParent->fullId(), _parent->data());
|
||||
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
||||
bool selected = (selection == FullSelection);
|
||||
|
@ -313,14 +315,8 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
|||
p.drawEllipse(inner);
|
||||
}
|
||||
|
||||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
auto fg = outbg ? (selected ? st::historyFileOutRadialFgSelected : st::historyFileOutRadialFg) : (selected ? st::historyFileInRadialFgSelected : st::historyFileInRadialFg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, fg);
|
||||
}
|
||||
|
||||
auto icon = [&] {
|
||||
if (_data->loading() || _data->uploading()) {
|
||||
const auto icon = [&] {
|
||||
if (!cornerDownload && (_data->loading() || _data->uploading())) {
|
||||
return &(outbg ? (selected ? st::historyFileOutCancelSelected : st::historyFileOutCancel) : (selected ? st::historyFileInCancelSelected : st::historyFileInCancel));
|
||||
} else if (showPause) {
|
||||
return &(outbg ? (selected ? st::historyFileOutPauseSelected : st::historyFileOutPause) : (selected ? st::historyFileInPauseSelected : st::historyFileInPause));
|
||||
|
@ -335,6 +331,14 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
|||
return &(outbg ? (selected ? st::historyFileOutDownloadSelected : st::historyFileOutDownload) : (selected ? st::historyFileInDownloadSelected : st::historyFileInDownload));
|
||||
}();
|
||||
icon->paintInCenter(p, inner);
|
||||
|
||||
if (radial && !cornerDownload) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
auto fg = outbg ? (selected ? st::historyFileOutRadialFgSelected : st::historyFileOutRadialFg) : (selected ? st::historyFileInRadialFgSelected : st::historyFileInRadialFg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, fg);
|
||||
}
|
||||
|
||||
drawCornerDownload(p, selected);
|
||||
}
|
||||
auto namewidth = width() - nameleft - nameright;
|
||||
auto statuswidth = namewidth;
|
||||
|
@ -449,6 +453,68 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
|||
}
|
||||
}
|
||||
|
||||
bool HistoryDocument::downloadInCorner() const {
|
||||
return _data->isAudioFile()
|
||||
&& _data->canBeStreamed()
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& IsServerMsgId(_parent->data()->id);
|
||||
}
|
||||
|
||||
void HistoryDocument::drawCornerDownload(Painter &p, bool selected) const {
|
||||
if (_data->loaded() || !downloadInCorner()) {
|
||||
return;
|
||||
}
|
||||
auto outbg = _parent->hasOutLayout();
|
||||
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
|
||||
const auto shift = st::historyAudioDownloadShift;
|
||||
const auto size = st::historyAudioDownloadSize;
|
||||
const auto inner = rtlrect(st::msgFilePadding.left() + shift, st::msgFilePadding.top() - topMinus + shift, size, size, width());
|
||||
auto pen = (selected
|
||||
? (outbg ? st::msgOutBgSelected : st::msgInBgSelected)
|
||||
: (outbg ? st::msgOutBg : st::msgInBg))->p;
|
||||
pen.setWidth(st::lineWidth);
|
||||
p.setPen(pen);
|
||||
if (selected) {
|
||||
p.setBrush(outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected);
|
||||
} else {
|
||||
p.setBrush(outbg ? st::msgFileOutBg : st::msgFileInBg);
|
||||
}
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(inner);
|
||||
}
|
||||
const auto icon = [&] {
|
||||
if (_data->loading()) {
|
||||
return &(outbg ? (selected ? st::historyAudioOutCancelSelected : st::historyAudioOutCancel) : (selected ? st::historyAudioInCancelSelected : st::historyAudioInCancel));
|
||||
}
|
||||
return &(outbg ? (selected ? st::historyAudioOutDownloadSelected : st::historyAudioOutDownload) : (selected ? st::historyAudioInDownloadSelected : st::historyAudioInDownload));
|
||||
}();
|
||||
icon->paintInCenter(p, inner);
|
||||
if (_animation && _animation->radial.animating()) {
|
||||
const auto rinner = inner.marginsRemoved(QMargins(st::historyAudioRadialLine, st::historyAudioRadialLine, st::historyAudioRadialLine, st::historyAudioRadialLine));
|
||||
auto fg = outbg ? (selected ? st::historyFileOutRadialFgSelected : st::historyFileOutRadialFg) : (selected ? st::historyFileInRadialFgSelected : st::historyFileInRadialFg);
|
||||
_animation->radial.draw(p, rinner, st::historyAudioRadialLine, fg);
|
||||
}
|
||||
}
|
||||
|
||||
TextState HistoryDocument::cornerDownloadTextState(
|
||||
QPoint point,
|
||||
StateRequest request) const {
|
||||
auto result = TextState(_parent);
|
||||
if (!downloadInCorner() || _data->loaded()) {
|
||||
return result;
|
||||
}
|
||||
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
|
||||
const auto shift = st::historyAudioDownloadShift;
|
||||
const auto size = st::historyAudioDownloadSize;
|
||||
const auto inner = rtlrect(st::msgFilePadding.left() + shift, st::msgFilePadding.top() - topMinus + shift, size, size, width());
|
||||
if (inner.contains(point)) {
|
||||
result.link = _data->loading() ? _cancell : _savel;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
||||
auto result = TextState(_parent);
|
||||
|
||||
|
@ -491,8 +557,11 @@ TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
|||
nametop = st::msgFileNameTop - topMinus;
|
||||
bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus;
|
||||
|
||||
if (const auto state = cornerDownloadTextState(point, request); state.link) {
|
||||
return state;
|
||||
}
|
||||
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width()));
|
||||
if ((_data->loading() || _data->uploading()) && inner.contains(point)) {
|
||||
if ((_data->loading() || _data->uploading()) && inner.contains(point) && !downloadInCorner()) {
|
||||
result.link = _cancell;
|
||||
return result;
|
||||
}
|
||||
|
@ -530,7 +599,7 @@ TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
|||
}
|
||||
}
|
||||
if (QRect(0, 0, width(), painth).contains(point)
|
||||
&& !_data->loading()
|
||||
&& (!_data->loading() || downloadInCorner())
|
||||
&& !_data->uploading()
|
||||
&& !_data->isNull()) {
|
||||
if (loaded || _data->canBePlayed()) {
|
||||
|
|
|
@ -76,6 +76,12 @@ private:
|
|||
void setStatusSize(int newSize, qint64 realDuration = 0) const;
|
||||
bool updateStatusText() const; // returns showPause
|
||||
|
||||
[[nodiscard]] bool downloadInCorner() const;
|
||||
void drawCornerDownload(Painter &p, bool selected) const;
|
||||
[[nodiscard]] TextState cornerDownloadTextState(
|
||||
QPoint point,
|
||||
StateRequest request) const;
|
||||
|
||||
not_null<DocumentData*> _data;
|
||||
|
||||
};
|
||||
|
|
|
@ -298,8 +298,8 @@ void HistoryVideo::drawCornerStatus(Painter &p, bool selected) const {
|
|||
icon->paintInCenter(p, inner);
|
||||
}
|
||||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, selected ? st::historyFileThumbRadialFgSelected : st::historyFileThumbRadialFg);
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::historyVideoRadialLine, st::historyVideoRadialLine, st::historyVideoRadialLine, st::historyVideoRadialLine)));
|
||||
_animation->radial.draw(p, rinner, st::historyVideoRadialLine, selected ? st::historyFileThumbRadialFgSelected : st::historyFileThumbRadialFg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,10 +79,12 @@ public:
|
|||
|
||||
UniversalMsgId minId() const {
|
||||
Expects(!empty());
|
||||
|
||||
return _items.back().first;
|
||||
}
|
||||
UniversalMsgId maxId() const {
|
||||
Expects(!empty());
|
||||
|
||||
return _items.front().first;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,10 @@ overviewSongCancel: icon {{ "playlist_cancel", historyFileInIconFg }};
|
|||
overviewSongCancelSelected: icon {{ "playlist_cancel", historyFileInIconFgSelected }};
|
||||
overviewSongDownload: icon {{ "playlist_download", historyFileInIconFg }};
|
||||
overviewSongDownloadSelected: icon {{ "playlist_download", historyFileInIconFgSelected }};
|
||||
overviewSmallCancel: icon {{ "history_audio_cancel", historyFileInIconFg }};
|
||||
overviewSmallCancelSelected: icon {{ "history_audio_cancel", historyFileInIconFgSelected }};
|
||||
overviewSmallDownload: icon {{ "history_audio_download", historyFileInIconFg }};
|
||||
overviewSmallDownloadSelected: icon {{ "history_audio_download", historyFileInIconFgSelected }};
|
||||
overviewFileLayout: OverviewFileLayout {
|
||||
maxWidth: 520px;
|
||||
songPadding: margins(17px, 7px, 10px, 6px);
|
||||
|
|
|
@ -898,6 +898,13 @@ Document::Document(
|
|||
}
|
||||
}
|
||||
|
||||
bool Document::downloadInCorner() const {
|
||||
return _data->isAudioFile()
|
||||
&& _data->canBeStreamed()
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& IsServerMsgId(parent()->id);
|
||||
}
|
||||
|
||||
void Document::initDimensions() {
|
||||
_maxw = _st.maxWidth;
|
||||
if (_data->isSong()) {
|
||||
|
@ -910,6 +917,8 @@ void Document::initDimensions() {
|
|||
void Document::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
||||
bool selected = (selection == FullSelection);
|
||||
|
||||
const auto cornerDownload = downloadInCorner();
|
||||
|
||||
_data->automaticLoad(parent()->fullId(), parent());
|
||||
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
||||
|
||||
|
@ -938,7 +947,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
|||
if (selected) {
|
||||
p.setBrush(st::msgFileInBgSelected);
|
||||
} else {
|
||||
auto over = ClickHandler::showAsActive((_data->loading() || _data->uploading()) ? _cancell : (loaded || _data->canBePlayed()) ? _openl : _savel);
|
||||
auto over = ClickHandler::showAsActive((!cornerDownload && (_data->loading() || _data->uploading())) ? _cancell : (loaded || _data->canBePlayed()) ? _openl : _savel);
|
||||
p.setBrush(anim::brush(_st.songIconBg, _st.songOverBg, _a_iconOver.current(context->ms, over ? 1. : 0.)));
|
||||
}
|
||||
|
||||
|
@ -947,14 +956,8 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
|||
p.drawEllipse(inner);
|
||||
}
|
||||
|
||||
if (radial) {
|
||||
auto rinner = inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine));
|
||||
auto &bg = selected ? st::historyFileInRadialFgSelected : st::historyFileInRadialFg;
|
||||
_radial->draw(p, rinner, st::msgFileRadialLine, bg);
|
||||
}
|
||||
|
||||
auto icon = [&] {
|
||||
if (_data->loading() || _data->uploading()) {
|
||||
const auto icon = [&] {
|
||||
if (!cornerDownload && (_data->loading() || _data->uploading())) {
|
||||
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
||||
} else if (showPause) {
|
||||
return &(selected ? _st.songPauseSelected : _st.songPause);
|
||||
|
@ -964,6 +967,14 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
|||
return &(selected ? _st.songDownloadSelected : _st.songDownload);
|
||||
}();
|
||||
icon->paintInCenter(p, inner);
|
||||
|
||||
if (radial && !cornerDownload) {
|
||||
auto rinner = inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine));
|
||||
auto &bg = selected ? st::historyFileInRadialFgSelected : st::historyFileInRadialFg;
|
||||
_radial->draw(p, rinner, st::msgFileRadialLine, bg);
|
||||
}
|
||||
|
||||
drawCornerDownload(p, selected, context);
|
||||
}
|
||||
} else {
|
||||
nameleft = _st.fileThumbSize + _st.filePadding.right();
|
||||
|
@ -1073,6 +1084,56 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
|||
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||
}
|
||||
|
||||
void Document::drawCornerDownload(Painter &p, bool selected, const PaintContext *context) const {
|
||||
if (_data->loaded() || !downloadInCorner()) {
|
||||
return;
|
||||
}
|
||||
const auto size = st::overviewSmallCheck.size;
|
||||
const auto shift = _st.songThumbSize + st::overviewCheckSkip - size;
|
||||
const auto inner = rtlrect(_st.songPadding.left() + shift, _st.songPadding.top() + shift, size, size, _width);
|
||||
auto pen = st::windowBg->p;
|
||||
pen.setWidth(st::lineWidth);
|
||||
p.setPen(pen);
|
||||
if (selected) {
|
||||
p.setBrush(st::msgFileInBgSelected);
|
||||
} else {
|
||||
p.setBrush(_st.songIconBg);
|
||||
}
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(inner);
|
||||
}
|
||||
const auto icon = [&] {
|
||||
if (_data->loading()) {
|
||||
return &(selected ? st::overviewSmallCancelSelected : st::overviewSmallCancel);
|
||||
}
|
||||
return &(selected ? st::overviewSmallDownloadSelected : st::overviewSmallDownload);
|
||||
}();
|
||||
icon->paintInCenter(p, inner);
|
||||
if (_radial && _radial->animating()) {
|
||||
const auto rinner = inner.marginsRemoved(QMargins(st::historyAudioRadialLine, st::historyAudioRadialLine, st::historyAudioRadialLine, st::historyAudioRadialLine));
|
||||
auto fg = selected ? st::historyFileThumbRadialFgSelected : st::historyFileThumbRadialFg;
|
||||
_radial->draw(p, rinner, st::historyAudioRadialLine, fg);
|
||||
}
|
||||
}
|
||||
|
||||
TextState Document::cornerDownloadTextState(
|
||||
QPoint point,
|
||||
StateRequest request) const {
|
||||
auto result = TextState(parent());
|
||||
if (!downloadInCorner() || _data->loaded()) {
|
||||
return result;
|
||||
}
|
||||
const auto size = st::overviewSmallCheck.size;
|
||||
const auto shift = _st.songThumbSize + st::overviewCheckSkip - size;
|
||||
const auto inner = rtlrect(_st.songPadding.left() + shift, _st.songPadding.top() + shift, size, size, _width);
|
||||
if (inner.contains(point)) {
|
||||
result.link = _data->loading() ? _cancell : _savel;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
TextState Document::getState(
|
||||
QPoint point,
|
||||
StateRequest request) const {
|
||||
|
@ -1088,6 +1149,10 @@ TextState Document::getState(
|
|||
const auto nametop = _st.songNameTop;
|
||||
const auto statustop = _st.songStatusTop;
|
||||
|
||||
if (const auto state = cornerDownloadTextState(point, request); state.link) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const auto inner = rtlrect(
|
||||
_st.songPadding.left(),
|
||||
_st.songPadding.top(),
|
||||
|
|
|
@ -29,9 +29,9 @@ class Checkbox;
|
|||
|
||||
class PaintContext : public PaintContextBase {
|
||||
public:
|
||||
PaintContext(crl::time ms, bool selecting) : PaintContextBase(ms, selecting), isAfterDate(false) {
|
||||
PaintContext(crl::time ms, bool selecting) : PaintContextBase(ms, selecting) {
|
||||
}
|
||||
bool isAfterDate;
|
||||
bool isAfterDate = false;
|
||||
|
||||
};
|
||||
|
||||
|
@ -310,6 +310,12 @@ protected:
|
|||
const style::RoundCheckbox &checkboxStyle() const override;
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool downloadInCorner() const;
|
||||
void drawCornerDownload(Painter &p, bool selected, const PaintContext *context) const;
|
||||
[[nodiscard]] TextState cornerDownloadTextState(
|
||||
QPoint point,
|
||||
StateRequest request) const;
|
||||
|
||||
not_null<DocumentData*> _data;
|
||||
StatusText _status;
|
||||
ClickHandlerPtr _msgl, _namel;
|
||||
|
|
Loading…
Add table
Reference in a new issue