Add button to download audio files.

This commit is contained in:
John Preston 2019-03-15 16:09:05 +04:00
parent bc2b0f8392
commit d646de7184
16 changed files with 193 additions and 27 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

View file

@ -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

View file

@ -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);
}
}

View file

@ -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 }};

View file

@ -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()) {

View file

@ -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;
};

View file

@ -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);
}
}
}

View file

@ -79,10 +79,12 @@ public:
UniversalMsgId minId() const {
Expects(!empty());
return _items.back().first;
}
UniversalMsgId maxId() const {
Expects(!empty());
return _items.front().first;
}

View file

@ -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);

View file

@ -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(),

View file

@ -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;