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;
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<MTPChannelParticipant>::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) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<MTPMessage> &slice, const QVector<MTPM
if (peer->isChat()) {
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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