2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-09-01 23:15:59 +00:00

Notifications management moved to AuthSession.

Also implemented Global::WorkMode() as an base::Variable.
This commit is contained in:
John Preston
2017-03-04 22:36:59 +03:00
parent b14ba398e6
commit 81790b2271
80 changed files with 1299 additions and 1152 deletions

View File

@@ -100,17 +100,6 @@ MainWindow::MainWindow() {
iconbig32 = iconbig256.scaledToWidth(32, Qt::SmoothTransformation);
iconbig64 = iconbig256.scaledToWidth(64, Qt::SmoothTransformation);
subscribe(Global::RefNotifySettingsChanged(), [this](Notify::ChangeType type) {
if (type == Notify::ChangeType::DesktopEnabled) {
updateTrayMenu();
notifyClear();
} else if (type == Notify::ChangeType::ViewParams) {
notifyUpdateAll();
} else if (type == Notify::ChangeType::IncludeMuted) {
Notify::unreadCounterUpdated();
}
});
resize(st::windowDefaultWidth, st::windowDefaultHeight);
setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
@@ -118,8 +107,6 @@ MainWindow::MainWindow() {
_inactiveTimer.setSingleShot(true);
connect(&_inactiveTimer, SIGNAL(timeout()), this, SLOT(onInactiveTimer()));
connect(&_notifyWaitTimer, SIGNAL(timeout()), this, SLOT(notifyShowNext()));
connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock()));
subscribe(Global::RefSelfChanged(), [this]() { updateGlobalMenu(); });
@@ -156,7 +143,7 @@ void MainWindow::onStateChanged(Qt::WindowState state) {
updateIsActive((state == Qt::WindowMinimized) ? Global::OfflineBlurTimeout() : Global::OnlineFocusTimeout());
psUpdateSysMenu(state);
if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) {
if (state == Qt::WindowMinimized && Global::WorkMode().value() == dbiwmTrayOnly) {
App::wnd()->minimizeToTray();
}
savePosition(state);
@@ -200,7 +187,7 @@ void MainWindow::firstShow() {
trayIconMenu->addAction(notificationActionText, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
trayIconMenu->addAction(lang(lng_quit_from_tray), this, SLOT(quitFromTray()))->setEnabled(true);
}
psUpdateWorkmode();
workmodeUpdated(Global::WorkMode().value());
psFirstShow();
updateTrayMenu();
@@ -241,7 +228,7 @@ void MainWindow::clearPasscode() {
} else {
_main->showAnimated(bg, true);
}
notifyUpdateAll();
AuthSession::Current().notifications()->updateAll();
updateGlobalMenu();
if (_main) {
@@ -265,7 +252,9 @@ void MainWindow::setupPasscode() {
setInnerFocus();
}
_shouldLockAt = 0;
notifyUpdateAll();
if (AuthSession::Exists()) {
AuthSession::Current().notifications()->updateAll();
}
updateGlobalMenu();
}
@@ -360,6 +349,9 @@ void MainWindow::setupMain(const MTPUser *self) {
auto bg = animated ? grabInner() : QPixmap();
clearWidgets();
t_assert(AuthSession::Exists());
_main.create(bodyWidget());
_main->show();
updateControlsGeometry();
@@ -369,11 +361,7 @@ void MainWindow::setupMain(const MTPUser *self) {
} else {
_main->activate();
}
if (self) {
_main->start(*self);
} else {
MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(1, MTP_inputUserSelf())), _main->rpcDone(&MainWidget::startFull));
}
_main->start(self);
fixOrder();
@@ -573,7 +561,7 @@ bool MainWindow::doWeReadServerHistory() {
}
void MainWindow::checkHistoryActivation() {
if (_main && AuthSession::Current() && doWeReadServerHistory()) {
if (_main && doWeReadServerHistory()) {
_main->markActiveHistoryAsRead();
}
}
@@ -842,9 +830,9 @@ void MainWindow::toggleDisplayNotifyFromTray() {
}
}
Local::writeUserSettings();
Global::RefNotifySettingsChanged().notify(Notify::ChangeType::DesktopEnabled);
AuthSession::Current().notifications()->settingsChanged().notify(Window::Notifications::ChangeType::DesktopEnabled);
if (soundNotifyChanged) {
Global::RefNotifySettingsChanged().notify(Notify::ChangeType::SoundEnabled);
AuthSession::Current().notifications()->settingsChanged().notify(Window::Notifications::ChangeType::SoundEnabled);
}
}
@@ -854,7 +842,7 @@ void MainWindow::closeEvent(QCloseEvent *e) {
App::quit();
} else {
e->ignore();
if (!AuthSession::Current() || !Ui::hideWindowNoQuit()) {
if (!AuthSession::Exists() || !Ui::hideWindowNoQuit()) {
App::quit();
}
}
@@ -919,305 +907,10 @@ void MainWindow::onClearFailed(int task, void *manager) {
emit tempDirClearFailed(task);
}
void MainWindow::notifySchedule(History *history, HistoryItem *item) {
if (App::quitting() || !history->currentNotification() || !App::api()) return;
PeerData *notifyByFrom = (!history->peer->isUser() && item->mentionsMe()) ? item->from() : 0;
if (item->isSilent()) {
history->popNotification(item);
return;
}
bool haveSetting = (history->peer->notify != UnknownNotifySettings);
if (haveSetting) {
if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) {
if (notifyByFrom) {
haveSetting = (item->from()->notify != UnknownNotifySettings);
if (haveSetting) {
if (notifyByFrom->notify != EmptyNotifySettings && notifyByFrom->notify->mute > unixtime()) {
history->popNotification(item);
return;
}
} else {
App::api()->requestNotifySetting(notifyByFrom);
}
} else {
history->popNotification(item);
return;
}
}
} else {
if (notifyByFrom && notifyByFrom->notify == UnknownNotifySettings) {
App::api()->requestNotifySetting(notifyByFrom);
}
App::api()->requestNotifySetting(history->peer);
}
if (!item->notificationReady()) {
haveSetting = false;
}
int delay = item->Has<HistoryMessageForwarded>() ? 500 : 100, t = unixtime();
auto ms = getms(true);
bool isOnline = _main->lastWasOnline(), otherNotOld = ((cOtherOnline() * 1000LL) + Global::OnlineCloudTimeout() > t * 1000LL);
bool otherLaterThanMe = (cOtherOnline() * 1000LL + (ms - _main->lastSetOnline()) > t * 1000LL);
if (!isOnline && otherNotOld && otherLaterThanMe) {
delay = Global::NotifyCloudDelay();
} else if (cOtherOnline() >= t) {
delay = Global::NotifyDefaultDelay();
}
auto when = ms + delay;
_notifyWhenAlerts[history].insert(when, notifyByFrom);
if (Global::DesktopNotify() && !Platform::Notifications::SkipToast()) {
NotifyWhenMaps::iterator i = _notifyWhenMaps.find(history);
if (i == _notifyWhenMaps.end()) {
i = _notifyWhenMaps.insert(history, NotifyWhenMap());
}
if (i.value().constFind(item->id) == i.value().cend()) {
i.value().insert(item->id, when);
}
NotifyWaiters *addTo = haveSetting ? &_notifyWaiters : &_notifySettingWaiters;
NotifyWaiters::const_iterator it = addTo->constFind(history);
if (it == addTo->cend() || it->when > when) {
addTo->insert(history, NotifyWaiter(item->id, when, notifyByFrom));
}
}
if (haveSetting) {
if (!_notifyWaitTimer.isActive() || _notifyWaitTimer.remainingTime() > delay) {
_notifyWaitTimer.start(delay);
}
}
}
void MainWindow::notifyClear(History *history) {
if (!history) {
Window::Notifications::GetManager()->clearAll();
for (auto i = _notifyWhenMaps.cbegin(), e = _notifyWhenMaps.cend(); i != e; ++i) {
i.key()->clearNotifications();
}
_notifyWhenMaps.clear();
_notifyWhenAlerts.clear();
_notifyWaiters.clear();
_notifySettingWaiters.clear();
return;
}
Window::Notifications::GetManager()->clearFromHistory(history);
history->clearNotifications();
_notifyWhenMaps.remove(history);
_notifyWhenAlerts.remove(history);
_notifyWaiters.remove(history);
_notifySettingWaiters.remove(history);
_notifyWaitTimer.stop();
notifyShowNext();
}
void MainWindow::notifyClearFast() {
Window::Notifications::GetManager()->clearAllFast();
_notifyWhenMaps.clear();
_notifyWhenAlerts.clear();
_notifyWaiters.clear();
_notifySettingWaiters.clear();
}
void MainWindow::notifySettingGot() {
int32 t = unixtime();
for (NotifyWaiters::iterator i = _notifySettingWaiters.begin(); i != _notifySettingWaiters.end();) {
History *history = i.key();
bool loaded = false, muted = false;
if (history->peer->notify != UnknownNotifySettings) {
if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) {
loaded = true;
} else if (PeerData *from = i.value().notifyByFrom) {
if (from->notify != UnknownNotifySettings) {
if (from->notify == EmptyNotifySettings || from->notify->mute <= t) {
loaded = true;
} else {
loaded = muted = true;
}
}
} else {
loaded = muted = true;
}
}
if (loaded) {
if (HistoryItem *item = App::histItemById(history->channelId(), i.value().msg)) {
if (!item->notificationReady()) {
loaded = false;
}
} else {
muted = true;
}
}
if (loaded) {
if (!muted) {
_notifyWaiters.insert(i.key(), i.value());
}
i = _notifySettingWaiters.erase(i);
} else {
++i;
}
}
_notifyWaitTimer.stop();
notifyShowNext();
}
void MainWindow::notifyShowNext() {
if (App::quitting()) return;
auto ms = getms(true), nextAlert = 0LL;
bool alert = false;
int32 now = unixtime();
for (NotifyWhenAlerts::iterator i = _notifyWhenAlerts.begin(); i != _notifyWhenAlerts.end();) {
while (!i.value().isEmpty() && i.value().begin().key() <= ms) {
NotifySettingsPtr n = i.key()->peer->notify, f = i.value().begin().value() ? i.value().begin().value()->notify : UnknownNotifySettings;
while (!i.value().isEmpty() && i.value().begin().key() <= ms + 500) { // not more than one sound in 500ms from one peer - grouping
i.value().erase(i.value().begin());
}
if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= now)) {
alert = true;
} else if (f == EmptyNotifySettings || (f != UnknownNotifySettings && f->mute <= now)) { // notify by from()
alert = true;
}
}
if (i.value().isEmpty()) {
i = _notifyWhenAlerts.erase(i);
} else {
if (!nextAlert || nextAlert > i.value().begin().key()) {
nextAlert = i.value().begin().key();
}
++i;
}
}
if (alert) {
psFlash();
App::playSound();
}
if (_notifyWaiters.isEmpty() || !Global::DesktopNotify() || Platform::Notifications::SkipToast()) {
if (nextAlert) {
_notifyWaitTimer.start(nextAlert - ms);
}
return;
}
while (true) {
auto next = 0LL;
HistoryItem *notifyItem = 0;
History *notifyHistory = 0;
for (NotifyWaiters::iterator i = _notifyWaiters.begin(); i != _notifyWaiters.end();) {
History *history = i.key();
if (history->currentNotification() && history->currentNotification()->id != i.value().msg) {
NotifyWhenMaps::iterator j = _notifyWhenMaps.find(history);
if (j == _notifyWhenMaps.end()) {
history->clearNotifications();
i = _notifyWaiters.erase(i);
continue;
}
do {
NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id);
if (k != j.value().cend()) {
i.value().msg = k.key();
i.value().when = k.value();
break;
}
history->skipNotification();
} while (history->currentNotification());
}
if (!history->currentNotification()) {
_notifyWhenMaps.remove(history);
i = _notifyWaiters.erase(i);
continue;
}
auto when = i.value().when;
if (!notifyItem || next > when) {
next = when;
notifyItem = history->currentNotification();
notifyHistory = history;
}
++i;
}
if (notifyItem) {
if (next > ms) {
if (nextAlert && nextAlert < next) {
next = nextAlert;
nextAlert = 0;
}
_notifyWaitTimer.start(next - ms);
break;
} else {
HistoryItem *fwd = notifyItem->Has<HistoryMessageForwarded>() ? notifyItem : nullptr; // forwarded notify grouping
int32 fwdCount = 1;
auto ms = getms(true);
History *history = notifyItem->history();
NotifyWhenMaps::iterator j = _notifyWhenMaps.find(history);
if (j == _notifyWhenMaps.cend()) {
history->clearNotifications();
} else {
HistoryItem *nextNotify = 0;
do {
history->skipNotification();
if (!history->hasNotification()) {
break;
}
j.value().remove((fwd ? fwd : notifyItem)->id);
do {
NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id);
if (k != j.value().cend()) {
nextNotify = history->currentNotification();
_notifyWaiters.insert(notifyHistory, NotifyWaiter(k.key(), k.value(), 0));
break;
}
history->skipNotification();
} while (history->hasNotification());
if (nextNotify) {
if (fwd) {
HistoryItem *nextFwd = nextNotify->Has<HistoryMessageForwarded>() ? nextNotify : nullptr;
if (nextFwd && fwd->author() == nextFwd->author() && qAbs(int64(nextFwd->date.toTime_t()) - int64(fwd->date.toTime_t())) < 2) {
fwd = nextFwd;
++fwdCount;
} else {
nextNotify = 0;
}
} else {
nextNotify = 0;
}
}
} while (nextNotify);
}
Window::Notifications::GetManager()->showNotification(notifyItem, fwdCount);
if (!history->hasNotification()) {
_notifyWaiters.remove(history);
_notifyWhenMaps.remove(history);
continue;
}
}
} else {
break;
}
}
if (nextAlert) {
_notifyWaitTimer.start(nextAlert - ms);
}
}
void MainWindow::app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) {
handler->onClick(button);
}
void MainWindow::notifyUpdateAll() {
Window::Notifications::GetManager()->updateAll();
}
QImage MainWindow::iconLarge() const {
return iconbig256;
}
@@ -1346,7 +1039,6 @@ void MainWindow::updateIsActiveHook() {
}
MainWindow::~MainWindow() {
notifyClearFast();
if (_clearManager) {
_clearManager->stop();
_clearManager = nullptr;