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
 | 
			
		||||
 | 
			
		||||
#include "base/optional.h"
 | 
			
		||||
 | 
			
		||||
namespace base {
 | 
			
		||||
 | 
			
		||||
template <typename Key, typename Type>
 | 
			
		||||
| 
						 | 
				
			
			@ -378,7 +380,6 @@ public:
 | 
			
		|||
	using iterator = typename parent::iterator;
 | 
			
		||||
	using const_iterator = typename parent::const_iterator;
 | 
			
		||||
	using value_type = typename parent::value_type;
 | 
			
		||||
	using reference = typename parent::reference;
 | 
			
		||||
 | 
			
		||||
	iterator insert(const value_type &value) {
 | 
			
		||||
		if (this->empty() || (value.first < this->front().first)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -424,19 +425,29 @@ public:
 | 
			
		|||
		return this->findFirst(key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reference operator[](const Key &key) {
 | 
			
		||||
	Type &operator[](const Key &key) {
 | 
			
		||||
		if (this->empty() || (key < this->front().first)) {
 | 
			
		||||
			this->_impl.push_front(Type());
 | 
			
		||||
			return this->front();
 | 
			
		||||
			this->_impl.push_front({ key, Type() });
 | 
			
		||||
			return this->front().second;
 | 
			
		||||
		} else if (this->back().first < key) {
 | 
			
		||||
			this->_impl.push_back(Type());
 | 
			
		||||
			return this->back();
 | 
			
		||||
			this->_impl.push_back({ key, Type() });
 | 
			
		||||
			return this->back().second;
 | 
			
		||||
		}
 | 
			
		||||
		auto where = this->getLowerBound(key);
 | 
			
		||||
		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<>.
 | 
			
		||||
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>
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -635,7 +635,7 @@ void StickersListWidget::paintFeaturedStickers(Painter &p, QRect clip) {
 | 
			
		|||
 | 
			
		||||
	auto &sets = shownSets();
 | 
			
		||||
	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 ms = getms();
 | 
			
		||||
| 
						 | 
				
			
			@ -727,7 +727,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
 | 
			
		|||
	auto ms = getms();
 | 
			
		||||
	auto &sets = shownSets();
 | 
			
		||||
	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) {
 | 
			
		||||
		if (clip.top() >= info.rowsBottom) {
 | 
			
		||||
			return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -979,7 +979,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
 | 
			
		|||
	_previewTimer.stop();
 | 
			
		||||
 | 
			
		||||
	auto pressed = _pressed;
 | 
			
		||||
	setPressed(base::null_variant());
 | 
			
		||||
	setPressed(base::none);
 | 
			
		||||
	if (pressed != _selected) {
 | 
			
		||||
		update();
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -994,7 +994,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
 | 
			
		|||
	updateSelected();
 | 
			
		||||
 | 
			
		||||
	auto &sets = shownSets();
 | 
			
		||||
	if (!base::is_null_variant(pressed) && pressed == _selected) {
 | 
			
		||||
	if (pressed && pressed == _selected) {
 | 
			
		||||
		if (auto sticker = base::get_if<OverSticker>(&pressed)) {
 | 
			
		||||
			t_assert(sticker->section >= 0 && sticker->section < sets.size());
 | 
			
		||||
			auto &set = sets[sticker->section];
 | 
			
		||||
| 
						 | 
				
			
			@ -1104,8 +1104,8 @@ void StickersListWidget::enterFromChildEvent(QEvent *e, QWidget *child) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void StickersListWidget::clearSelection() {
 | 
			
		||||
	setPressed(base::null_variant());
 | 
			
		||||
	setSelected(base::null_variant());
 | 
			
		||||
	setPressed(base::none);
 | 
			
		||||
	setSelected(base::none);
 | 
			
		||||
	update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1394,11 +1394,11 @@ bool StickersListWidget::preventAutoHide() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void StickersListWidget::updateSelected() {
 | 
			
		||||
	if (!base::is_null_variant(_pressed) && !_previewShown) {
 | 
			
		||||
	if (_pressed && !_previewShown) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto newSelected = OverState { base::null_variant() };
 | 
			
		||||
	auto newSelected = OverState { base::none };
 | 
			
		||||
	auto p = mapFromGlobal(_lastMousePosition);
 | 
			
		||||
	if (!rect().contains(p)
 | 
			
		||||
		|| p.y() < getVisibleTop() || p.y() >= getVisibleBottom()
 | 
			
		||||
| 
						 | 
				
			
			@ -1487,7 +1487,7 @@ bool StickersListWidget::stickerHasDeleteButton(const Set &set, int index) const
 | 
			
		|||
 | 
			
		||||
void StickersListWidget::setSelected(OverState 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 updateSelected = [this, &sets]() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -226,8 +226,8 @@ private:
 | 
			
		|||
 | 
			
		||||
	Footer *_footer = nullptr;
 | 
			
		||||
 | 
			
		||||
	OverState _selected = base::null_variant();
 | 
			
		||||
	OverState _pressed = base::null_variant();
 | 
			
		||||
	OverState _selected;
 | 
			
		||||
	OverState _pressed;
 | 
			
		||||
	QPoint _lastMousePosition;
 | 
			
		||||
 | 
			
		||||
	Text _megagroupSetAbout;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1174,11 +1174,10 @@ void History::setUnreadMentionsCount(int count) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
bool History::addToUnreadMentions(MsgId msgId, AddToOverviewMethod method) {
 | 
			
		||||
	auto count = base::get_if(&_unreadMentionsCount);
 | 
			
		||||
	auto allLoaded = count ? (_unreadMentions.size() >= *count) : false;
 | 
			
		||||
	auto allLoaded = _unreadMentionsCount ? (_unreadMentions.size() >= *_unreadMentionsCount) : false;
 | 
			
		||||
	if (allLoaded) {
 | 
			
		||||
		if (method == AddToOverviewNew) {
 | 
			
		||||
			++*count;
 | 
			
		||||
			++*_unreadMentionsCount;
 | 
			
		||||
			_unreadMentions.insert(msgId);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1191,9 +1190,9 @@ bool History::addToUnreadMentions(MsgId msgId, AddToOverviewMethod method) {
 | 
			
		|||
 | 
			
		||||
void History::eraseFromUnreadMentions(MsgId msgId) {
 | 
			
		||||
	_unreadMentions.remove(msgId);
 | 
			
		||||
	if (auto count = base::get_if(&_unreadMentionsCount)) {
 | 
			
		||||
		if (*count > 0) {
 | 
			
		||||
			--*count;
 | 
			
		||||
	if (_unreadMentionsCount) {
 | 
			
		||||
		if (*_unreadMentionsCount > 0) {
 | 
			
		||||
			--*_unreadMentionsCount;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::UnreadMentionsChanged);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -361,7 +361,7 @@ public:
 | 
			
		|||
		return _unreadMentions.empty() ? 0 : _unreadMentions.back();
 | 
			
		||||
	}
 | 
			
		||||
	int getUnreadMentionsCount(int notLoadedValue = -1) const {
 | 
			
		||||
		return base::is_null_optional(_unreadMentionsCount) ? notLoadedValue : *base::get_if(&_unreadMentionsCount);
 | 
			
		||||
		return _unreadMentionsCount ? *_unreadMentionsCount : notLoadedValue;
 | 
			
		||||
	}
 | 
			
		||||
	bool hasUnreadMentions() const {
 | 
			
		||||
		return (getUnreadMentionsCount() > 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -559,7 +559,7 @@ private:
 | 
			
		|||
	bool _mute = false;
 | 
			
		||||
	int _unreadCount = 0;
 | 
			
		||||
 | 
			
		||||
	base::optional<int> _unreadMentionsCount = base::null_optional();
 | 
			
		||||
	base::optional<int> _unreadMentionsCount;
 | 
			
		||||
	base::flat_set<MsgId> _unreadMentions;
 | 
			
		||||
 | 
			
		||||
	Dialogs::RowsByLetter _chatListLinks[2];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,6 +65,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
			
		|||
#include <gsl/gsl>
 | 
			
		||||
 | 
			
		||||
#include "base/variant.h"
 | 
			
		||||
#include "base/optional.h"
 | 
			
		||||
#include "base/algorithm.h"
 | 
			
		||||
 | 
			
		||||
#include "core/basic_types.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
<(src_loc)/base/observer.h
 | 
			
		||||
<(src_loc)/base/ordered_set.h
 | 
			
		||||
<(src_loc)/base/openssl_help.h
 | 
			
		||||
<(src_loc)/base/optional.h
 | 
			
		||||
<(src_loc)/base/parse_helper.cpp
 | 
			
		||||
<(src_loc)/base/parse_helper.h
 | 
			
		||||
<(src_loc)/base/qthelp_regex.h
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue