stop and clear audio on logout, clearing bot keyboards in supergroups

This commit is contained in:
John Preston 2015-11-24 19:19:18 +03:00
parent c80adfc21d
commit 87b57a26ad
14 changed files with 154 additions and 28 deletions

View File

@ -522,7 +522,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
if (!peer->mgInfo || result.type() != mtpc_channels_channelParticipants) return; if (!peer->mgInfo || result.type() != mtpc_channels_channelParticipants) return;
History *h = 0;
if (bots) { if (bots) {
h = App::historyLoaded(peer->id);
peer->mgInfo->bots.clear(); peer->mgInfo->bots.clear();
peer->mgInfo->botStatus = -1; peer->mgInfo->botStatus = -1;
} else if (fromStart) { } else if (fromStart) {
@ -536,6 +538,7 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
App::feedUsers(d.vusers); App::feedUsers(d.vusers);
bool added = false, needBotsInfos = false; bool added = false, needBotsInfos = false;
int32 botStatus = peer->mgInfo->botStatus; int32 botStatus = peer->mgInfo->botStatus;
bool keyboardBotFound = !h || !h->lastKeyboardFrom;
for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
int32 userId = 0; int32 userId = 0;
bool admin = false; bool admin = false;
@ -557,6 +560,9 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
needBotsInfos = true; needBotsInfos = true;
} }
} }
if (!keyboardBotFound && u->id == h->lastKeyboardFrom) {
keyboardBotFound = true;
}
} else { } else {
if (peer->mgInfo->lastParticipants.indexOf(u) < 0) { if (peer->mgInfo->lastParticipants.indexOf(u) < 0) {
peer->mgInfo->lastParticipants.push_back(u); peer->mgInfo->lastParticipants.push_back(u);
@ -574,6 +580,10 @@ void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelP
if (needBotsInfos) { if (needBotsInfos) {
requestFullPeer(peer); requestFullPeer(peer);
} }
if (!keyboardBotFound) {
h->clearLastKeyboard();
if (App::main()) App::main()->updateBotKeyboard(h);
}
if (d.vcount.v > peer->count) { if (d.vcount.v > peer->count) {
peer->count = d.vcount.v; peer->count = d.vcount.v;
} else if (v.count() > peer->count) { } else if (v.count() > peer->count) {

View File

@ -190,6 +190,9 @@ namespace App {
if (cHasPasscode()) { if (cHasPasscode()) {
cSetHasPasscode(false); cSetHasPasscode(false);
} }
if (audioPlayer()) {
audioPlayer()->stopAndClear();
}
if (w) { if (w) {
w->tempDirDelete(Local::ClearManagerAll); w->tempDirDelete(Local::ClearManagerAll);
w->notifyClearFast(); w->notifyClearFast();
@ -696,9 +699,8 @@ namespace App {
} }
chat->botStatus = botStatus; chat->botStatus = botStatus;
if (!found) { if (!found) {
h->lastKeyboardId = 0; h->clearLastKeyboard();
h->lastKeyboardFrom = 0; if (App::main()) App::main()->updateBotKeyboard(h);
if (App::main()) App::main()->updateBotKeyboard();
} }
} }
} }
@ -794,9 +796,8 @@ namespace App {
History *h = App::historyLoaded(chat->id); History *h = App::historyLoaded(chat->id);
if (h && h->lastKeyboardFrom == user->id) { if (h && h->lastKeyboardFrom == user->id) {
h->lastKeyboardId = 0; h->clearLastKeyboard();
h->lastKeyboardFrom = 0; if (App::main()) App::main()->updateBotKeyboard(h);
if (App::main()) App::main()->updateBotKeyboard();
} }
} }
if (chat->botStatus > 0 && user->botInfo) { if (chat->botStatus > 0 && user->botInfo) {

View File

@ -269,6 +269,27 @@ void audioFinish() {
cSetHasAudioPlayer(false); 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), AudioPlayer::AudioPlayer() : _audioCurrent(0), _songCurrent(0),
_fader(new AudioPlayerFader(&_faderThread)), _fader(new AudioPlayerFader(&_faderThread)),
_loader(new AudioPlayerLoaders(&_loaderThread)) { _loader(new AudioPlayerLoaders(&_loaderThread)) {
@ -642,10 +663,64 @@ void AudioPlayer::seek(int64 position) {
} }
void AudioPlayer::stop(MediaOverviewType type) { void AudioPlayer::stop(MediaOverviewType type) {
fadedStop(type);
switch (type) { switch (type) {
case OverviewAudios: if (_audioData[_audioCurrent].audio) emit updated(_audioData[_audioCurrent].audio); break; case OverviewAudios: {
case OverviewDocuments: if (_songData[_songCurrent].song) emit updated(_songData[_songCurrent].song); break; 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();
}
} }
} }

View File

@ -59,6 +59,8 @@ public:
void seek(int64 position); // type == OverviewDocuments void seek(int64 position); // type == OverviewDocuments
void stop(MediaOverviewType type); void stop(MediaOverviewType type);
void stopAndClear();
void currentState(AudioMsgId *audio, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); 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); 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); bool checkCurrentALError(MediaOverviewType type);
struct Msg { struct Msg {
Msg() : position(0), duration(0), frequency(AudioVoiceMsgFrequency), skipStart(0), skipEnd(0), loading(0), started(0), Msg() : position(0)
state(AudioPlayerStopped), source(0), nextBuffer(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(buffers, 0, sizeof(buffers));
memset(samplesCount, 0, sizeof(samplesCount)); memset(samplesCount, 0, sizeof(samplesCount));
} }
void clearData();
QString fname; QString fname;
QByteArray data; QByteArray data;
int64 position, duration; int64 position, duration;
@ -132,11 +144,19 @@ private:
struct AudioMsg : public Msg { struct AudioMsg : public Msg {
AudioMsg() { AudioMsg() {
} }
void clear() {
audio = AudioMsgId();
Msg::clearData();
}
AudioMsgId audio; AudioMsgId audio;
}; };
struct SongMsg : public Msg { struct SongMsg : public Msg {
SongMsg() { SongMsg() {
} }
void clear() {
song = SongMsgId();
Msg::clearData();
}
SongMsgId song; SongMsgId song;
}; };

View File

@ -388,10 +388,12 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
} else { } else {
data->inchat = false; data->inchat = false;
} }
data->onlineColor = false;
data->check = _checkedContacts.contains(peer); data->check = _checkedContacts.contains(peer);
data->name.setText(st::contactsNameFont, peer->name, _textNameOptions); data->name.setText(st::contactsNameFont, peer->name, _textNameOptions);
if (peer->isUser()) { if (peer->isUser()) {
data->online = App::onlineText(peer->asUser(), _time); data->online = App::onlineText(peer->asUser(), _time);
data->onlineColor = App::onlineColorUse(peer->asUser(), _time);
} else if (peer->isChat()) { } else if (peer->isChat()) {
ChatData *chat = peer->asChat(); ChatData *chat = peer->asChat();
if (!chat->amIn()) { if (!chat->amIn()) {
@ -471,7 +473,7 @@ void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, b
} else { } else {
if (inverse) { if (inverse) {
p.setPen(st::white); 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); p.setPen(st::contactsStatusFgOnline);
} else { } else {
p.setPen(sel ? st::contactsStatusFgOver : st::contactsStatusFg); 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.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); 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(); MemberData *result = _datas[index] = new MemberData();
result->name.setText(st::contactsNameFont, _rows[index]->name, _textNameOptions); 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) { if (_filter == MembersFilterRecent) {
result->canKick = (_channel->amCreator() || _channel->amEditor() || _channel->amModerator()) ? (_roles[index] == MemberRoleNone) : false; result->canKick = (_channel->amCreator() || _channel->amEditor() || _channel->amModerator()) ? (_roles[index] == MemberRoleNone) : false;
} else if (_filter == MembersFilterAdmins) { } else if (_filter == MembersFilterAdmins) {

View File

@ -152,6 +152,7 @@ private:
struct ContactData { struct ContactData {
Text name; Text name;
QString online; QString online;
bool onlineColor;
bool inchat; bool inchat;
bool check; bool check;
}; };
@ -370,6 +371,7 @@ private:
struct MemberData { struct MemberData {
Text name; Text name;
QString online; QString online;
bool onlineColor;
bool canKick; bool canKick;
}; };

View File

@ -386,11 +386,15 @@ History::History(const PeerId &peerId) : width(0), height(0)
} }
void History::clearLastKeyboard() { void History::clearLastKeyboard() {
lastKeyboardInited = true; if (lastKeyboardId) {
lastKeyboardId = 0; if (lastKeyboardId == lastKeyboardHiddenId) {
lastKeyboardFrom = 0;
lastKeyboardHiddenId = 0; lastKeyboardHiddenId = 0;
} }
lastKeyboardId = 0;
}
lastKeyboardInited = true;
lastKeyboardFrom = 0;
}
bool History::updateTyping(uint64 ms, uint32 dots, bool force) { bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
if (!ms) ms = getms(true); if (!ms) ms = getms(true);
@ -1545,6 +1549,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
PeerId uid = peerFromUser(d.vuser_id); PeerId uid = peerFromUser(d.vuser_id);
if (lastKeyboardFrom == uid) { if (lastKeyboardFrom == uid) {
clearLastKeyboard(); clearLastKeyboard();
if (App::main()) App::main()->updateBotKeyboard(this);
} }
if (peer->isMegagroup()) { if (peer->isMegagroup()) {
if (UserData *user = App::userLoaded(uid)) { if (UserData *user = App::userLoaded(uid)) {
@ -1831,7 +1836,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
if (peer->isChat()) { if (peer->isChat()) {
botNotInChat = adding->from()->isUser() && (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser()); botNotInChat = adding->from()->isUser() && (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from()->asUser());
} else if (peer->isMegagroup()) { } 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) { if (botNotInChat) {
clearLastKeyboard(); clearLastKeyboard();
@ -2061,7 +2066,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
if (peer->isChat()) { if (peer->isChat()) {
botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser()); botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->from()->isUser() && !peer->asChat()->participants.contains(item->from()->asUser());
} else if (peer->isMegagroup()) { } 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) { if (wasKeyboardHide || botNotInChat) {
clearLastKeyboard(); clearLastKeyboard();
@ -3021,9 +3026,8 @@ void HistoryItem::destroy() {
history()->fixLastMessage(wasAtBottom); history()->fixLastMessage(wasAtBottom);
} }
if (history()->lastKeyboardId == id) { if (history()->lastKeyboardId == id) {
history()->lastKeyboardId = 0; history()->clearLastKeyboard();
history()->lastKeyboardFrom = 0; if (App::main()) App::main()->updateBotKeyboard(history());
if (App::main()) App::main()->updateBotKeyboard();
} }
HistoryMedia *m = getMedia(true); HistoryMedia *m = getMedia(true);
MediaOverviewType t = m ? mediaToOverviewType(m->type()) : OverviewCount; MediaOverviewType t = m ? mediaToOverviewType(m->type()) : OverviewCount;

View File

@ -5871,7 +5871,11 @@ void HistoryWidget::countHistoryShowFrom() {
_history->updateShowFrom(); _history->updateShowFrom();
} }
void HistoryWidget::updateBotKeyboard() { void HistoryWidget::updateBotKeyboard(History *h) {
if (h && h != _history && h != _migrated) {
return;
}
bool changed = false; bool changed = false;
bool wasVisible = _kbShown || _kbReplyTo; bool wasVisible = _kbShown || _kbReplyTo;
if ((_replyToId && !_replyTo) || !_history) { if ((_replyToId && !_replyTo) || !_history) {

View File

@ -520,7 +520,7 @@ public:
void insertBotCommand(const QString &cmd); void insertBotCommand(const QString &cmd);
bool eventFilter(QObject *obj, QEvent *e); bool eventFilter(QObject *obj, QEvent *e);
void updateBotKeyboard(); void updateBotKeyboard(History *h = 0);
DragState getDragState(const QMimeData *d); DragState getDragState(const QMimeData *d);

View File

@ -2021,14 +2021,20 @@ namespace Local {
if (_localLoader) { if (_localLoader) {
_localLoader->stop(); _localLoader->stop();
} }
_passKeySalt.clear(); // reset passcode, local key _passKeySalt.clear(); // reset passcode, local key
_draftsMap.clear(); _draftsMap.clear();
_draftsPositionsMap.clear(); _draftsPositionsMap.clear();
_fileLocations.clear();
_fileLocationPairs.clear();
_fileLocationAliases.clear();
_imagesMap.clear(); _imagesMap.clear();
_draftsNotReadMap.clear(); _draftsNotReadMap.clear();
_stickerImagesMap.clear(); _stickerImagesMap.clear();
_audiosMap.clear(); _audiosMap.clear();
_storageImagesSize = _storageStickersSize = _storageAudiosSize = 0;
_locationsKey = _reportSpamStatusesKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0; _locationsKey = _reportSpamStatusesKey = _recentStickersKeyOld = _stickersKey = _backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0;
_oldMapVersion = _oldSettingsVersion = 0;
_mapChanged = true; _mapChanged = true;
_writeMap(WriteMapNow); _writeMap(WriteMapNow);

View File

@ -2090,8 +2090,8 @@ void MainWidget::updateReplyTo() {
history.updateReplyTo(true); history.updateReplyTo(true);
} }
void MainWidget::updateBotKeyboard() { void MainWidget::updateBotKeyboard(History *h) {
history.updateBotKeyboard(); history.updateBotKeyboard(h);
} }
void MainWidget::pushReplyReturn(HistoryItem *item) { void MainWidget::pushReplyReturn(HistoryItem *item) {

View File

@ -365,7 +365,7 @@ public:
ApiWrap *api(); ApiWrap *api();
void updateReplyTo(); void updateReplyTo();
void updateBotKeyboard(); void updateBotKeyboard(History *h);
void pushReplyReturn(HistoryItem *item); void pushReplyReturn(HistoryItem *item);

View File

@ -641,7 +641,7 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState,
float64 progress = 0.; float64 progress = 0.;
int32 loaded; int32 loaded;
float64 loadProgress = 1.; float64 loadProgress = 1.;
if (duration || !_song.song->loader) { if (duration || !_song || !_song.song || !_song.song->loader) {
time = (_down == OverPlayback) ? _time : formatDurationText(display); time = (_down == OverPlayback) ? _time : formatDurationText(display);
progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.; progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.;
loaded = duration ? _song.song->size : 0; loaded = duration ? _song.song->size : 0;

View File

@ -131,7 +131,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
if (chatPhoto && chatPhoto->date) { if (chatPhoto && chatPhoto->date) {
_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); _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 (_peerChannel->isMegagroup() && (_peerChannel->mgInfo->lastParticipants.isEmpty() || (needAdmins && adminsOutdated) || _peerChannel->lastParticipantsCountOutdated())) {
if (App::api()) App::api()->requestLastParticipants(_peerChannel); if (App::api()) App::api()->requestLastParticipants(_peerChannel);
} }