mirror of https://github.com/procxx/kepka.git
Add base::optional as a wrapper of base::variant.
This commit is contained in:
parent
ae1dacb7d7
commit
bca444b92e
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/optional.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
template <typename Key, typename Type>
|
template <typename Key, typename Type>
|
||||||
|
@ -378,7 +380,6 @@ public:
|
||||||
using iterator = typename parent::iterator;
|
using iterator = typename parent::iterator;
|
||||||
using const_iterator = typename parent::const_iterator;
|
using const_iterator = typename parent::const_iterator;
|
||||||
using value_type = typename parent::value_type;
|
using value_type = typename parent::value_type;
|
||||||
using reference = typename parent::reference;
|
|
||||||
|
|
||||||
iterator insert(const value_type &value) {
|
iterator insert(const value_type &value) {
|
||||||
if (this->empty() || (value.first < this->front().first)) {
|
if (this->empty() || (value.first < this->front().first)) {
|
||||||
|
@ -424,19 +425,29 @@ public:
|
||||||
return this->findFirst(key);
|
return this->findFirst(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
reference operator[](const Key &key) {
|
Type &operator[](const Key &key) {
|
||||||
if (this->empty() || (key < this->front().first)) {
|
if (this->empty() || (key < this->front().first)) {
|
||||||
this->_impl.push_front(Type());
|
this->_impl.push_front({ key, Type() });
|
||||||
return this->front();
|
return this->front().second;
|
||||||
} else if (this->back().first < key) {
|
} else if (this->back().first < key) {
|
||||||
this->_impl.push_back(Type());
|
this->_impl.push_back({ key, Type() });
|
||||||
return this->back();
|
return this->back().second;
|
||||||
}
|
}
|
||||||
auto where = this->getLowerBound(key);
|
auto where = this->getLowerBound(key);
|
||||||
if (key < where->first) {
|
if (key < where->first) {
|
||||||
return *this->_impl.insert(where, { key, Type() });
|
return this->_impl.insert(where, { key, Type() })->second;
|
||||||
}
|
}
|
||||||
return *where;
|
return where->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<Type> take(const Key &key) {
|
||||||
|
auto it = find(key);
|
||||||
|
if (it == this->end()) {
|
||||||
|
return base::none;
|
||||||
|
}
|
||||||
|
auto result = std::move(it->second);
|
||||||
|
this->erase(it);
|
||||||
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
namespace functors {
|
||||||
|
|
||||||
|
struct abs_helper {
|
||||||
|
template <typename Type,
|
||||||
|
typename = decltype(0 < std::declval<Type>()),
|
||||||
|
typename = decltype(-std::declval<Type>())>
|
||||||
|
constexpr Type operator()(Type value) const {
|
||||||
|
return (0 < value) ? value : (-value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
constexpr auto abs = abs_helper {};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
inline auto add(Type a) {
|
||||||
|
return [a](auto b) { return a + b; };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace functors
|
||||||
|
} // namespace base
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/variant.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
struct none_type {
|
||||||
|
bool operator==(none_type other) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool operator!=(none_type other) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool operator<(none_type other) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool operator<=(none_type other) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool operator>(none_type other) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool operator>=(none_type other) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr none_type none = {};
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
class optional_variant {
|
||||||
|
public:
|
||||||
|
optional_variant() : _impl(none) {
|
||||||
|
}
|
||||||
|
optional_variant(const optional_variant &other) : _impl(other._impl) {
|
||||||
|
}
|
||||||
|
optional_variant(optional_variant &&other) : _impl(std::move(other._impl)) {
|
||||||
|
}
|
||||||
|
template <typename T, typename = std::enable_if_t<!std::is_base_of<optional_variant, std::decay_t<T>>::value>>
|
||||||
|
optional_variant(T &&value) : _impl(std::forward<T>(value)) {
|
||||||
|
}
|
||||||
|
optional_variant &operator=(const optional_variant &other) {
|
||||||
|
_impl = other._impl;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
optional_variant &operator=(optional_variant &&other) {
|
||||||
|
_impl = std::move(other._impl);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template <typename T, typename = std::enable_if_t<!std::is_base_of<optional_variant, std::decay_t<T>>::value>>
|
||||||
|
optional_variant &operator=(T &&value) {
|
||||||
|
_impl = std::forward<T>(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (get_if<none_type>(&_impl) == nullptr);
|
||||||
|
}
|
||||||
|
bool operator==(const optional_variant &other) const {
|
||||||
|
return _impl == other._impl;
|
||||||
|
}
|
||||||
|
bool operator!=(const optional_variant &other) const {
|
||||||
|
return _impl != other._impl;
|
||||||
|
}
|
||||||
|
bool operator<(const optional_variant &other) const {
|
||||||
|
return _impl < other._impl;
|
||||||
|
}
|
||||||
|
bool operator<=(const optional_variant &other) const {
|
||||||
|
return _impl <= other._impl;
|
||||||
|
}
|
||||||
|
bool operator>(const optional_variant &other) const {
|
||||||
|
return _impl > other._impl;
|
||||||
|
}
|
||||||
|
bool operator>=(const optional_variant &other) const {
|
||||||
|
return _impl >= other._impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
decltype(auto) is() const {
|
||||||
|
return _impl.template is<T>();
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
decltype(auto) get_unchecked() {
|
||||||
|
return _impl.template get_unchecked<T>();
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
decltype(auto) get_unchecked() const {
|
||||||
|
return _impl.template get_unchecked<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
variant<none_type, Types...> _impl;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
inline T *get_if(optional_variant<Types...> *v) {
|
||||||
|
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
inline const T *get_if(const optional_variant<Types...> *v) {
|
||||||
|
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class optional;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct optional_wrap_once {
|
||||||
|
using type = optional<Type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct optional_wrap_once<optional<Type>> {
|
||||||
|
using type = optional<Type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
using optional_wrap_once_t = typename optional_wrap_once<std::decay_t<Type>>::type;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct optional_chain_result {
|
||||||
|
using type = optional_wrap_once_t<Type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct optional_chain_result<void> {
|
||||||
|
using type = bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
using optional_chain_result_t = typename optional_chain_result<Type>::type;
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class optional : public optional_variant<Type> {
|
||||||
|
public:
|
||||||
|
using optional_variant<Type>::optional_variant;
|
||||||
|
|
||||||
|
Type &operator*() {
|
||||||
|
auto result = get_if<Type>(this);
|
||||||
|
Expects(result != nullptr);
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
const Type &operator*() const {
|
||||||
|
auto result = get_if<Type>(this);
|
||||||
|
Expects(result != nullptr);
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
Type *operator->() {
|
||||||
|
auto result = get_if<Type>(this);
|
||||||
|
Expects(result != nullptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const Type *operator->() const {
|
||||||
|
auto result = get_if<Type>(this);
|
||||||
|
Expects(result != nullptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
optional_wrap_once_t<Type> make_optional(Type &&value) {
|
||||||
|
return optional_wrap_once_t<Type> { std::forward<Type>(value) };
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type, typename Method>
|
||||||
|
inline auto optional_chain(
|
||||||
|
const optional<Type> &value,
|
||||||
|
Method &method,
|
||||||
|
std::false_type)
|
||||||
|
-> optional_chain_result_t<decltype(method(*value))> {
|
||||||
|
return value ? make_optional(method(*value)) : none;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type, typename Method>
|
||||||
|
inline auto optional_chain(
|
||||||
|
const optional<Type> &value,
|
||||||
|
Method &method,
|
||||||
|
std::true_type)
|
||||||
|
-> optional_chain_result_t<decltype(method(*value))> {
|
||||||
|
return value ? (method(*value), true) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type, typename Method>
|
||||||
|
inline auto operator|(const optional<Type> &value, Method method)
|
||||||
|
-> optional_chain_result_t<decltype(method(*value))> {
|
||||||
|
using is_void_return = std::is_same<decltype(method(*value)), void>;
|
||||||
|
return optional_chain(value, method, is_void_return {});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace base
|
|
@ -25,21 +25,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
// We use base::variant<> alias and base::get_if() helper while we don't have std::variant<>.
|
// We use base::variant<> alias and base::get_if() helper while we don't have std::variant<>.
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
struct null_variant_type {
|
|
||||||
};
|
|
||||||
|
|
||||||
inline constexpr null_variant_type null_variant() {
|
|
||||||
return null_variant_type {};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator<(null_variant_type a, null_variant_type b) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(null_variant_type a, null_variant_type b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
using variant = mapbox::util::variant<Types...>;
|
using variant = mapbox::util::variant<Types...>;
|
||||||
|
|
||||||
|
@ -53,36 +38,4 @@ inline const T *get_if(const variant<Types...> *v) {
|
||||||
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
|
return (v && v->template is<T>()) ? &v->template get_unchecked<T>() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Types>
|
|
||||||
using optional_variant = variant<null_variant_type, Types...>;
|
|
||||||
|
|
||||||
template <typename... Types>
|
|
||||||
inline bool is_null_variant(const optional_variant<Types...> &variant) {
|
|
||||||
return get_if<null_variant_type>(&variant) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
using optional = optional_variant<Type>;
|
|
||||||
|
|
||||||
using null_optional_type = null_variant_type;
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
inline Type *get_if(optional<Type> *v) {
|
|
||||||
return (v && v->template is<Type>()) ? &v->template get_unchecked<Type>() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type *get_if(const optional<Type> *v) {
|
|
||||||
return (v && v->template is<Type>()) ? &v->template get_unchecked<Type>() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
inline bool is_null_optional(const optional<Type> &optional) {
|
|
||||||
return is_null_variant(optional);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline constexpr null_optional_type null_optional() {
|
|
||||||
return null_optional_type {};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
|
|
@ -635,7 +635,7 @@ void StickersListWidget::paintFeaturedStickers(Painter &p, QRect clip) {
|
||||||
|
|
||||||
auto &sets = shownSets();
|
auto &sets = shownSets();
|
||||||
auto selectedSticker = base::get_if<OverSticker>(&_selected);
|
auto selectedSticker = base::get_if<OverSticker>(&_selected);
|
||||||
auto selectedButton = base::get_if<OverButton>(base::is_null_variant(_pressed) ? &_selected : &_pressed);
|
auto selectedButton = base::get_if<OverButton>(_pressed ? &_pressed : &_selected);
|
||||||
|
|
||||||
auto tilly = st::stickerPanPadding;
|
auto tilly = st::stickerPanPadding;
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
|
@ -727,7 +727,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
auto &sets = shownSets();
|
auto &sets = shownSets();
|
||||||
auto selectedSticker = base::get_if<OverSticker>(&_selected);
|
auto selectedSticker = base::get_if<OverSticker>(&_selected);
|
||||||
auto selectedButton = base::get_if<OverButton>(base::is_null_variant(_pressed) ? &_selected : &_pressed);
|
auto selectedButton = base::get_if<OverButton>(_pressed ? &_pressed : &_selected);
|
||||||
enumerateSections([this, &p, clip, fromColumn, toColumn, selectedSticker, selectedButton, ms](const SectionInfo &info) {
|
enumerateSections([this, &p, clip, fromColumn, toColumn, selectedSticker, selectedButton, ms](const SectionInfo &info) {
|
||||||
if (clip.top() >= info.rowsBottom) {
|
if (clip.top() >= info.rowsBottom) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -979,7 +979,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
_previewTimer.stop();
|
_previewTimer.stop();
|
||||||
|
|
||||||
auto pressed = _pressed;
|
auto pressed = _pressed;
|
||||||
setPressed(base::null_variant());
|
setPressed(base::none);
|
||||||
if (pressed != _selected) {
|
if (pressed != _selected) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -994,7 +994,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
auto &sets = shownSets();
|
auto &sets = shownSets();
|
||||||
if (!base::is_null_variant(pressed) && pressed == _selected) {
|
if (pressed && pressed == _selected) {
|
||||||
if (auto sticker = base::get_if<OverSticker>(&pressed)) {
|
if (auto sticker = base::get_if<OverSticker>(&pressed)) {
|
||||||
t_assert(sticker->section >= 0 && sticker->section < sets.size());
|
t_assert(sticker->section >= 0 && sticker->section < sets.size());
|
||||||
auto &set = sets[sticker->section];
|
auto &set = sets[sticker->section];
|
||||||
|
@ -1104,8 +1104,8 @@ void StickersListWidget::enterFromChildEvent(QEvent *e, QWidget *child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::clearSelection() {
|
void StickersListWidget::clearSelection() {
|
||||||
setPressed(base::null_variant());
|
setPressed(base::none);
|
||||||
setSelected(base::null_variant());
|
setSelected(base::none);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1394,11 +1394,11 @@ bool StickersListWidget::preventAutoHide() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::updateSelected() {
|
void StickersListWidget::updateSelected() {
|
||||||
if (!base::is_null_variant(_pressed) && !_previewShown) {
|
if (_pressed && !_previewShown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto newSelected = OverState { base::null_variant() };
|
auto newSelected = OverState { base::none };
|
||||||
auto p = mapFromGlobal(_lastMousePosition);
|
auto p = mapFromGlobal(_lastMousePosition);
|
||||||
if (!rect().contains(p)
|
if (!rect().contains(p)
|
||||||
|| p.y() < getVisibleTop() || p.y() >= getVisibleBottom()
|
|| p.y() < getVisibleTop() || p.y() >= getVisibleBottom()
|
||||||
|
@ -1487,7 +1487,7 @@ bool StickersListWidget::stickerHasDeleteButton(const Set &set, int index) const
|
||||||
|
|
||||||
void StickersListWidget::setSelected(OverState newSelected) {
|
void StickersListWidget::setSelected(OverState newSelected) {
|
||||||
if (_selected != newSelected) {
|
if (_selected != newSelected) {
|
||||||
setCursor(base::is_null_variant(newSelected) ? style::cur_default : style::cur_pointer);
|
setCursor(newSelected ? style::cur_pointer : style::cur_default);
|
||||||
|
|
||||||
auto &sets = shownSets();
|
auto &sets = shownSets();
|
||||||
auto updateSelected = [this, &sets]() {
|
auto updateSelected = [this, &sets]() {
|
||||||
|
|
|
@ -226,8 +226,8 @@ private:
|
||||||
|
|
||||||
Footer *_footer = nullptr;
|
Footer *_footer = nullptr;
|
||||||
|
|
||||||
OverState _selected = base::null_variant();
|
OverState _selected;
|
||||||
OverState _pressed = base::null_variant();
|
OverState _pressed;
|
||||||
QPoint _lastMousePosition;
|
QPoint _lastMousePosition;
|
||||||
|
|
||||||
Text _megagroupSetAbout;
|
Text _megagroupSetAbout;
|
||||||
|
|
|
@ -1174,11 +1174,10 @@ void History::setUnreadMentionsCount(int count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool History::addToUnreadMentions(MsgId msgId, AddToOverviewMethod method) {
|
bool History::addToUnreadMentions(MsgId msgId, AddToOverviewMethod method) {
|
||||||
auto count = base::get_if(&_unreadMentionsCount);
|
auto allLoaded = _unreadMentionsCount ? (_unreadMentions.size() >= *_unreadMentionsCount) : false;
|
||||||
auto allLoaded = count ? (_unreadMentions.size() >= *count) : false;
|
|
||||||
if (allLoaded) {
|
if (allLoaded) {
|
||||||
if (method == AddToOverviewNew) {
|
if (method == AddToOverviewNew) {
|
||||||
++*count;
|
++*_unreadMentionsCount;
|
||||||
_unreadMentions.insert(msgId);
|
_unreadMentions.insert(msgId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1191,9 +1190,9 @@ bool History::addToUnreadMentions(MsgId msgId, AddToOverviewMethod method) {
|
||||||
|
|
||||||
void History::eraseFromUnreadMentions(MsgId msgId) {
|
void History::eraseFromUnreadMentions(MsgId msgId) {
|
||||||
_unreadMentions.remove(msgId);
|
_unreadMentions.remove(msgId);
|
||||||
if (auto count = base::get_if(&_unreadMentionsCount)) {
|
if (_unreadMentionsCount) {
|
||||||
if (*count > 0) {
|
if (*_unreadMentionsCount > 0) {
|
||||||
--*count;
|
--*_unreadMentionsCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::UnreadMentionsChanged);
|
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::UnreadMentionsChanged);
|
||||||
|
|
|
@ -361,7 +361,7 @@ public:
|
||||||
return _unreadMentions.empty() ? 0 : _unreadMentions.back();
|
return _unreadMentions.empty() ? 0 : _unreadMentions.back();
|
||||||
}
|
}
|
||||||
int getUnreadMentionsCount(int notLoadedValue = -1) const {
|
int getUnreadMentionsCount(int notLoadedValue = -1) const {
|
||||||
return base::is_null_optional(_unreadMentionsCount) ? notLoadedValue : *base::get_if(&_unreadMentionsCount);
|
return _unreadMentionsCount ? *_unreadMentionsCount : notLoadedValue;
|
||||||
}
|
}
|
||||||
bool hasUnreadMentions() const {
|
bool hasUnreadMentions() const {
|
||||||
return (getUnreadMentionsCount() > 0);
|
return (getUnreadMentionsCount() > 0);
|
||||||
|
@ -559,7 +559,7 @@ private:
|
||||||
bool _mute = false;
|
bool _mute = false;
|
||||||
int _unreadCount = 0;
|
int _unreadCount = 0;
|
||||||
|
|
||||||
base::optional<int> _unreadMentionsCount = base::null_optional();
|
base::optional<int> _unreadMentionsCount;
|
||||||
base::flat_set<MsgId> _unreadMentions;
|
base::flat_set<MsgId> _unreadMentions;
|
||||||
|
|
||||||
Dialogs::RowsByLetter _chatListLinks[2];
|
Dialogs::RowsByLetter _chatListLinks[2];
|
||||||
|
|
|
@ -65,6 +65,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include <gsl/gsl>
|
#include <gsl/gsl>
|
||||||
|
|
||||||
#include "base/variant.h"
|
#include "base/variant.h"
|
||||||
|
#include "base/optional.h"
|
||||||
#include "base/algorithm.h"
|
#include "base/algorithm.h"
|
||||||
|
|
||||||
#include "core/basic_types.h"
|
#include "core/basic_types.h"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<(src_loc)/base/observer.h
|
<(src_loc)/base/observer.h
|
||||||
<(src_loc)/base/ordered_set.h
|
<(src_loc)/base/ordered_set.h
|
||||||
<(src_loc)/base/openssl_help.h
|
<(src_loc)/base/openssl_help.h
|
||||||
|
<(src_loc)/base/optional.h
|
||||||
<(src_loc)/base/parse_helper.cpp
|
<(src_loc)/base/parse_helper.cpp
|
||||||
<(src_loc)/base/parse_helper.h
|
<(src_loc)/base/parse_helper.h
|
||||||
<(src_loc)/base/qthelp_regex.h
|
<(src_loc)/base/qthelp_regex.h
|
||||||
|
|
Loading…
Reference in New Issue