130 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
This file is part of Telegram Desktop,
 | 
						|
the official desktop application for the Telegram messaging service.
 | 
						|
 | 
						|
For license and copyright information please follow this link:
 | 
						|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
						|
*/
 | 
						|
#pragma once
 | 
						|
 | 
						|
namespace Data {
 | 
						|
 | 
						|
inline constexpr auto kLifeStartDate = 1375315200; // Let it be 01.08.2013.
 | 
						|
 | 
						|
class LastseenStatus final {
 | 
						|
public:
 | 
						|
	LastseenStatus() = default;
 | 
						|
 | 
						|
	[[nodiscard]] static LastseenStatus Recently(bool byMe = false) {
 | 
						|
		return LastseenStatus(kRecentlyValue, false, byMe);
 | 
						|
	}
 | 
						|
	[[nodiscard]] static LastseenStatus WithinWeek(bool byMe = false) {
 | 
						|
		return LastseenStatus(kWithinWeekValue, false, byMe);
 | 
						|
	}
 | 
						|
	[[nodiscard]] static LastseenStatus WithinMonth(bool byMe = false) {
 | 
						|
		return LastseenStatus(kWithinMonthValue, false, byMe);
 | 
						|
	}
 | 
						|
	[[nodiscard]] static LastseenStatus LongAgo(bool byMe = false) {
 | 
						|
		return LastseenStatus(kLongAgoValue, false, byMe);
 | 
						|
	}
 | 
						|
	[[nodiscard]] static LastseenStatus OnlineTill(
 | 
						|
			TimeId till,
 | 
						|
			bool local = false,
 | 
						|
			bool hiddenByMe = false) {
 | 
						|
		return (till >= kLifeStartDate + kSpecialValueSkip)
 | 
						|
			? LastseenStatus(till - kLifeStartDate, !local, hiddenByMe)
 | 
						|
			: LongAgo(hiddenByMe);
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] bool isHidden() const {
 | 
						|
		return !_available;
 | 
						|
	}
 | 
						|
	[[nodiscard]] bool isRecently() const {
 | 
						|
		return !_available && (_value == kRecentlyValue);
 | 
						|
	}
 | 
						|
	[[nodiscard]] bool isWithinWeek() const {
 | 
						|
		return !_available && (_value == kWithinWeekValue);
 | 
						|
	}
 | 
						|
	[[nodiscard]] bool isWithinMonth() const {
 | 
						|
		return !_available && (_value == kWithinMonthValue);
 | 
						|
	}
 | 
						|
	[[nodiscard]] bool isLongAgo() const {
 | 
						|
		return !_available && (_value == kLongAgoValue);
 | 
						|
	}
 | 
						|
	[[nodiscard]] bool isHiddenByMe() const {
 | 
						|
		return _hiddenByMe;
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] bool isOnline(TimeId now) const {
 | 
						|
		return (_value >= kSpecialValueSkip)
 | 
						|
			&& (kLifeStartDate + _value > now);
 | 
						|
	}
 | 
						|
	[[nodiscard]] bool isLocalOnlineValue() const {
 | 
						|
		return !_available && (_value >= kSpecialValueSkip);
 | 
						|
	}
 | 
						|
	[[nodiscard]] TimeId onlineTill() const {
 | 
						|
		return (_value >= kSpecialValueSkip)
 | 
						|
			? (kLifeStartDate + _value)
 | 
						|
			: 0;
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] uint32 serialize() const {
 | 
						|
		return (_value & 0x3FFFFFFF)
 | 
						|
			| (_available << 30)
 | 
						|
			| (_hiddenByMe << 31);
 | 
						|
	}
 | 
						|
	[[nodiscard]] static LastseenStatus FromSerialized(uint32 value) {
 | 
						|
		auto result = LastseenStatus();
 | 
						|
		result._value = value & 0x3FFFFFFF;
 | 
						|
		result._available = (value >> 30) & 1;
 | 
						|
		result._hiddenByMe = (value >> 31) & 1;
 | 
						|
		return result.valid() ? result : LastseenStatus();
 | 
						|
	}
 | 
						|
 | 
						|
	[[nodiscard]] static LastseenStatus FromLegacy(int32 value) {
 | 
						|
		if (value == -2) {
 | 
						|
			return LastseenStatus::Recently();
 | 
						|
		} else if (value == -3) {
 | 
						|
			return LastseenStatus::WithinWeek();
 | 
						|
		} else if (value == -4) {
 | 
						|
			return LastseenStatus::WithinMonth();
 | 
						|
		} else if (value < -30) {
 | 
						|
			return LastseenStatus::OnlineTill(-value, true);
 | 
						|
		} else if (value > 0) {
 | 
						|
			return LastseenStatus::OnlineTill(value);
 | 
						|
		}
 | 
						|
		return LastseenStatus();
 | 
						|
	}
 | 
						|
 | 
						|
	friend inline constexpr auto operator<=>(
 | 
						|
		LastseenStatus,
 | 
						|
		LastseenStatus) = default;
 | 
						|
	friend inline constexpr bool operator==(
 | 
						|
		LastseenStatus a,
 | 
						|
		LastseenStatus b) = default;
 | 
						|
 | 
						|
private:
 | 
						|
	static constexpr auto kLongAgoValue = uint32(0);
 | 
						|
	static constexpr auto kRecentlyValue = uint32(1);
 | 
						|
	static constexpr auto kWithinWeekValue = uint32(2);
 | 
						|
	static constexpr auto kWithinMonthValue = uint32(3);
 | 
						|
	static constexpr auto kSpecialValueSkip = uint32(4);
 | 
						|
	static constexpr auto kValidAfter = kLifeStartDate + kSpecialValueSkip;
 | 
						|
 | 
						|
	[[nodiscard]] bool valid() const {
 | 
						|
		return !_available || (_value >= kSpecialValueSkip);
 | 
						|
	}
 | 
						|
 | 
						|
	LastseenStatus(uint32 value, bool available, bool hiddenByMe)
 | 
						|
	: _value(value)
 | 
						|
	, _available(available ? 1 : 0)
 | 
						|
	, _hiddenByMe(hiddenByMe ? 1 : 0) {
 | 
						|
	}
 | 
						|
 | 
						|
	uint32 _value : 30 = 0;
 | 
						|
	uint32 _available : 1 = 0;
 | 
						|
	uint32 _hiddenByMe : 1 = 0;
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
} // namespace Data
 |