From 87b57a26ad7e5a9d9cd960645ceb12f2ad875607 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 24 Nov 2015 19:19:18 +0300 Subject: [PATCH] stop and clear audio on logout, clearing bot keyboards in supergroups --- Telegram/SourceFiles/apiwrap.cpp | 10 +++ Telegram/SourceFiles/app.cpp | 13 ++-- Telegram/SourceFiles/audio.cpp | 81 +++++++++++++++++++++- Telegram/SourceFiles/audio.h | 24 ++++++- Telegram/SourceFiles/boxes/contactsbox.cpp | 10 ++- Telegram/SourceFiles/boxes/contactsbox.h | 2 + Telegram/SourceFiles/history.cpp | 18 +++-- Telegram/SourceFiles/historywidget.cpp | 6 +- Telegram/SourceFiles/historywidget.h | 2 +- Telegram/SourceFiles/localstorage.cpp | 6 ++ Telegram/SourceFiles/mainwidget.cpp | 4 +- Telegram/SourceFiles/mainwidget.h | 2 +- Telegram/SourceFiles/playerwidget.cpp | 2 +- Telegram/SourceFiles/profilewidget.cpp | 2 +- 14 files changed, 154 insertions(+), 28 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 5513083fd0..4461772be1 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -522,7 +522,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP if (!peer->mgInfo || result.type() != mtpc_channels_channelParticipants) return; + History *h = 0; if (bots) { + h = App::historyLoaded(peer->id); peer->mgInfo->bots.clear(); peer->mgInfo->botStatus = -1; } else if (fromStart) { @@ -536,6 +538,7 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP App::feedUsers(d.vusers); bool added = false, needBotsInfos = false; int32 botStatus = peer->mgInfo->botStatus; + bool keyboardBotFound = !h || !h->lastKeyboardFrom; for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { int32 userId = 0; bool admin = false; @@ -557,6 +560,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP needBotsInfos = true; } } + if (!keyboardBotFound && u->id == h->lastKeyboardFrom) { + keyboardBotFound = true; + } } else { if (peer->mgInfo->lastParticipants.indexOf(u) < 0) { peer->mgInfo->lastParticipants.push_back(u); @@ -574,6 +580,10 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP if (needBotsInfos) { requestFullPeer(peer); } + if (!keyboardBotFound) { + h->clearLastKeyboard(); + if (App::main()) App::main()->updateBotKeyboard(h); + } if (d.vcount.v > peer->count) { peer->count = d.vcount.v; } else if (v.count() > peer->count) { diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 143f00a712..0241ee9ab9 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -190,6 +190,9 @@ namespace App { if (cHasPasscode()) { cSetHasPasscode(false); } + if (audioPlayer()) { + audioPlayer()->stopAndClear(); + } if (w) { w->tempDirDelete(Local::ClearManagerAll); w->notifyClearFast(); @@ -696,9 +699,8 @@ namespace App { } chat->botStatus = botStatus; if (!found) { - h->lastKeyboardId = 0; - h->lastKeyboardFrom = 0; - if (App::main()) App::main()->updateBotKeyboard(); + h->clearLastKeyboard(); + if (App::main()) App::main()->updateBotKeyboard(h); } } } @@ -794,9 +796,8 @@ namespace App { History *h = App::historyLoaded(chat->id); if (h && h->lastKeyboardFrom == user->id) { - h->lastKeyboardId = 0; - h->lastKeyboardFrom = 0; - if (App::main()) App::main()->updateBotKeyboard(); + h->clearLastKeyboard(); + if (App::main()) App::main()->updateBotKeyboard(h); } } if (chat->botStatus > 0 && user->botInfo) { diff --git a/Telegram/SourceFiles/audio.cpp b/Telegram/SourceFiles/audio.cpp index a512c4ac98..9bcb196415 100644 --- a/Telegram/SourceFiles/audio.cpp +++ b/Telegram/SourceFiles/audio.cpp @@ -269,6 +269,27 @@ void audioFinish() { cSetHasAudioPlayer(false); } +void AudioPlayer::Msg::clearData() { + fname = QString(); + data = QByteArray(); + position = duration = 0; + frequency = AudioVoiceMsgFrequency; + skipStart = skipEnd = 0; + loading = false; + started = 0; + state = AudioPlayerStopped; + if (alIsSource(source)) { + alSourceStop(source); + } + for (int32 i = 0; i < 3; ++i) { + if (samplesCount[i]) { + alSourceUnqueueBuffers(source, 1, buffers + i); + samplesCount[i] = 0; + } + } + nextBuffer = 0; +} + AudioPlayer::AudioPlayer() : _audioCurrent(0), _songCurrent(0), _fader(new AudioPlayerFader(&_faderThread)), _loader(new AudioPlayerLoaders(&_loaderThread)) { @@ -642,10 +663,64 @@ void AudioPlayer::seek(int64 position) { } void AudioPlayer::stop(MediaOverviewType type) { - fadedStop(type); switch (type) { - case OverviewAudios: if (_audioData[_audioCurrent].audio) emit updated(_audioData[_audioCurrent].audio); break; - case OverviewDocuments: if (_songData[_songCurrent].song) emit updated(_songData[_songCurrent].song); break; + case OverviewAudios: { + AudioMsgId current; + { + QMutexLocker lock(&playerMutex); + current = _audioData[_audioCurrent].audio; + fadedStop(type); + } + if (current) emit updated(current); + } break; + + case OverviewDocuments: { + SongMsgId current; + { + QMutexLocker lock(&playerMutex); + current = _songData[_songCurrent].song; + fadedStop(type); + } + if (current) emit updated(current); + } break; + } +} + +void AudioPlayer::stopAndClear() { + AudioMsg *current_audio = 0; + { + QMutexLocker lock(&playerMutex); + current_audio = &_audioData[_audioCurrent]; + if (current_audio) { + setStoppedState(current_audio); + } + } + SongMsg *current_song = 0; + { + QMutexLocker lock(&playerMutex); + current_song = &_songData[_songCurrent]; + if (current_song) { + setStoppedState(current_song); + } + } + if (current_song) { + emit updated(current_song->song); + } + if (current_audio) { + emit updated(current_audio->audio); + } + { + QMutexLocker lock(&playerMutex); + for (int32 index = 0; index < AudioVoiceMsgSimultaneously; ++index) { + if (_audioData[index].audio) { + emit loaderOnCancel(_audioData[index].audio); + } + _audioData[index].clear(); + if (_songData[index].song) { + emit loaderOnCancel(_songData[index].song); + } + _songData[index].clear(); + } } } diff --git a/Telegram/SourceFiles/audio.h b/Telegram/SourceFiles/audio.h index 7a4da6e8f1..97fa0c342c 100644 --- a/Telegram/SourceFiles/audio.h +++ b/Telegram/SourceFiles/audio.h @@ -59,6 +59,8 @@ public: void seek(int64 position); // type == OverviewDocuments void stop(MediaOverviewType type); + void stopAndClear(); + void currentState(AudioMsgId *audio, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); void currentState(SongMsgId *song, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); @@ -109,12 +111,22 @@ private: bool checkCurrentALError(MediaOverviewType type); struct Msg { - Msg() : position(0), duration(0), frequency(AudioVoiceMsgFrequency), skipStart(0), skipEnd(0), loading(0), started(0), - state(AudioPlayerStopped), source(0), nextBuffer(0) { + Msg() : position(0) + , duration(0) + , frequency(AudioVoiceMsgFrequency) + , skipStart(0) + , skipEnd(0) + , loading(false) + , started(0) + , state(AudioPlayerStopped) + , source(0) + , nextBuffer(0) { memset(buffers, 0, sizeof(buffers)); memset(samplesCount, 0, sizeof(samplesCount)); } + void clearData(); + QString fname; QByteArray data; int64 position, duration; @@ -132,11 +144,19 @@ private: struct AudioMsg : public Msg { AudioMsg() { } + void clear() { + audio = AudioMsgId(); + Msg::clearData(); + } AudioMsgId audio; }; struct SongMsg : public Msg { SongMsg() { } + void clear() { + song = SongMsgId(); + Msg::clearData(); + } SongMsgId song; }; diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 6b974080ab..8039c47846 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -388,10 +388,12 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) { } else { data->inchat = false; } + data->onlineColor = false; data->check = _checkedContacts.contains(peer); data->name.setText(st::contactsNameFont, peer->name, _textNameOptions); if (peer->isUser()) { data->online = App::onlineText(peer->asUser(), _time); + data->onlineColor = App::onlineColorUse(peer->asUser(), _time); } else if (peer->isChat()) { ChatData *chat = peer->asChat(); if (!chat->amIn()) { @@ -471,7 +473,7 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b } else { if (inverse) { p.setPen(st::white); - } else if ((user && (uname || App::onlineColorUse(user, _time))) || (peer->isChannel() && uname)) { + } else if ((user && (uname || data->onlineColor)) || (peer->isChannel() && uname)) { p.setPen(st::contactsStatusFgOnline); } else { p.setPen(sel ? st::contactsStatusFgOver : st::contactsStatusFg); @@ -1907,7 +1909,7 @@ void MembersInner::paintDialog(Painter &p, PeerData *peer, MemberData *data, boo } p.setFont(st::contactsStatusFont->f); - p.setPen(sel ? st::contactsStatusFgOver : st::contactsStatusFg); + p.setPen(sel ? st::contactsStatusFgOver : (data->onlineColor ? st::contactsStatusFgOnline : st::contactsStatusFg)); p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), data->online); } @@ -2028,7 +2030,9 @@ MembersInner::MemberData *MembersInner::data(int32 index) { } MemberData *result = _datas[index] = new MemberData(); result->name.setText(st::contactsNameFont, _rows[index]->name, _textNameOptions); - result->online = lng_mediaview_date_time(lt_date, _dates[index].date().toString(qsl("dd.MM.yy")), lt_time, _dates[index].time().toString(cTimeFormat())); + int32 t = unixtime(); + result->online = App::onlineText(_rows[index], t);// lng_mediaview_date_time(lt_date, _dates[index].date().toString(qsl("dd.MM.yy")), lt_time, _dates[index].time().toString(cTimeFormat())); + result->onlineColor = App::onlineColorUse(_rows[index], t); if (_filter == MembersFilterRecent) { result->canKick = (_channel->amCreator() || _channel->amEditor() || _channel->amModerator()) ? (_roles[index] == MemberRoleNone) : false; } else if (_filter == MembersFilterAdmins) { diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 9dc4980023..994c547c7a 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -152,6 +152,7 @@ private: struct ContactData { Text name; QString online; + bool onlineColor; bool inchat; bool check; }; @@ -370,6 +371,7 @@ private: struct MemberData { Text name; QString online; + bool onlineColor; bool canKick; }; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index e6d151d0b6..4da45f2342 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -386,10 +386,14 @@ History::History(const PeerId &peerId) : width(0), height(0) } void History::clearLastKeyboard() { + if (lastKeyboardId) { + if (lastKeyboardId == lastKeyboardHiddenId) { + lastKeyboardHiddenId = 0; + } + lastKeyboardId = 0; + } lastKeyboardInited = true; - lastKeyboardId = 0; lastKeyboardFrom = 0; - lastKeyboardHiddenId = 0; } bool History::updateTyping(uint64 ms, uint32 dots, bool force) { @@ -1545,6 +1549,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo PeerId uid = peerFromUser(d.vuser_id); if (lastKeyboardFrom == uid) { clearLastKeyboard(); + if (App::main()) App::main()->updateBotKeyboard(this); } if (peer->isMegagroup()) { if (UserData *user = App::userLoaded(uid)) { @@ -1831,7 +1836,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a if (peer->isChat()) { botNotInChat = adding->from()->isUser() && (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser()); } else if (peer->isMegagroup()) { - botNotInChat = adding->from()->isUser() && (!peer->canWrite() || !peer->asChannel()->mgInfo->bots.isEmpty()) && !peer->asChannel()->mgInfo->bots.contains(adding->from()->asUser()); + botNotInChat = adding->from()->isUser() && (!peer->canWrite() || peer->asChannel()->mgInfo->botStatus != 0) && !peer->asChannel()->mgInfo->bots.contains(adding->from()->asUser()); } if (botNotInChat) { clearLastKeyboard(); @@ -2061,7 +2066,7 @@ void History::addOlderSlice(const QVector &slice, const QVectorisChat()) { botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser()); } else if (peer->isMegagroup()) { - botNotInChat = (!peer->canWrite() || !peer->asChannel()->mgInfo->bots.isEmpty()) && item->from()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->from()->asUser()); + botNotInChat = (!peer->canWrite() || peer->asChannel()->mgInfo->botStatus != 0) && item->from()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->from()->asUser()); } if (wasKeyboardHide || botNotInChat) { clearLastKeyboard(); @@ -3021,9 +3026,8 @@ void HistoryItem::destroy() { history()->fixLastMessage(wasAtBottom); } if (history()->lastKeyboardId == id) { - history()->lastKeyboardId = 0; - history()->lastKeyboardFrom = 0; - if (App::main()) App::main()->updateBotKeyboard(); + history()->clearLastKeyboard(); + if (App::main()) App::main()->updateBotKeyboard(history()); } HistoryMedia *m = getMedia(true); MediaOverviewType t = m ? mediaToOverviewType(m->type()) : OverviewCount; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index d63eee44c3..af513bfe56 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -5871,7 +5871,11 @@ void HistoryWidget::countHistoryShowFrom() { _history->updateShowFrom(); } -void HistoryWidget::updateBotKeyboard() { +void HistoryWidget::updateBotKeyboard(History *h) { + if (h && h != _history && h != _migrated) { + return; + } + bool changed = false; bool wasVisible = _kbShown || _kbReplyTo; if ((_replyToId && !_replyTo) || !_history) { diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 385e34acb6..78212d1eca 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -520,7 +520,7 @@ public: void insertBotCommand(const QString &cmd); bool eventFilter(QObject *obj, QEvent *e); - void updateBotKeyboard(); + void updateBotKeyboard(History *h = 0); DragState getDragState(const QMimeData *d); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 0a719aa7f3..b1dfaecdf4 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2021,14 +2021,20 @@ namespace Local { if (_localLoader) { _localLoader->stop(); } + _passKeySalt.clear(); // reset passcode, local key _draftsMap.clear(); _draftsPositionsMap.clear(); + _fileLocations.clear(); + _fileLocationPairs.clear(); + _fileLocationAliases.clear(); _imagesMap.clear(); _draftsNotReadMap.clear(); _stickerImagesMap.clear(); _audiosMap.clear(); + _storageImagesSize = _storageStickersSize = _storageAudiosSize = 0; _locationsKey = _reportSpamStatusesKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0; + _oldMapVersion = _oldSettingsVersion = 0; _mapChanged = true; _writeMap(WriteMapNow); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 4c4722231a..1d981960ff 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -2090,8 +2090,8 @@ void MainWidget::updateReplyTo() { history.updateReplyTo(true); } -void MainWidget::updateBotKeyboard() { - history.updateBotKeyboard(); +void MainWidget::updateBotKeyboard(History *h) { + history.updateBotKeyboard(h); } void MainWidget::pushReplyReturn(HistoryItem *item) { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index aa723619c3..0c64c9f9aa 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -365,7 +365,7 @@ public: ApiWrap *api(); void updateReplyTo(); - void updateBotKeyboard(); + void updateBotKeyboard(History *h); void pushReplyReturn(HistoryItem *item); diff --git a/Telegram/SourceFiles/playerwidget.cpp b/Telegram/SourceFiles/playerwidget.cpp index e14082c3e7..c5fea8de2f 100644 --- a/Telegram/SourceFiles/playerwidget.cpp +++ b/Telegram/SourceFiles/playerwidget.cpp @@ -641,7 +641,7 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, float64 progress = 0.; int32 loaded; float64 loadProgress = 1.; - if (duration || !_song.song->loader) { + if (duration || !_song || !_song.song || !_song.song->loader) { time = (_down == OverPlayback) ? _time : formatDurationText(display); progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.; loaded = duration ? _song.song->size : 0; diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 8ca8feb2f8..79022abac8 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -131,7 +131,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData if (chatPhoto && chatPhoto->date) { _photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); } - bool needAdmins = _peerChannel->amEditor(), adminsOutdated = (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated); + bool needAdmins = (_peerChannel->isMegagroup() && _peerChannel->amEditor()), adminsOutdated = (_peerChannel->isMegagroup() && (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated)); if (_peerChannel->isMegagroup() && (_peerChannel->mgInfo->lastParticipants.isEmpty() || (needAdmins && adminsOutdated) || _peerChannel->lastParticipantsCountOutdated())) { if (App::api()) App::api()->requestLastParticipants(_peerChannel); }