data_lastseen_status.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. namespace Data {
  9. inline constexpr auto kLifeStartDate = 1375315200; // Let it be 01.08.2013.
  10. class LastseenStatus final {
  11. public:
  12. LastseenStatus() = default;
  13. [[nodiscard]] static LastseenStatus Recently(bool byMe = false) {
  14. return LastseenStatus(kRecentlyValue, false, byMe);
  15. }
  16. [[nodiscard]] static LastseenStatus WithinWeek(bool byMe = false) {
  17. return LastseenStatus(kWithinWeekValue, false, byMe);
  18. }
  19. [[nodiscard]] static LastseenStatus WithinMonth(bool byMe = false) {
  20. return LastseenStatus(kWithinMonthValue, false, byMe);
  21. }
  22. [[nodiscard]] static LastseenStatus LongAgo(bool byMe = false) {
  23. return LastseenStatus(kLongAgoValue, false, byMe);
  24. }
  25. [[nodiscard]] static LastseenStatus OnlineTill(
  26. TimeId till,
  27. bool local = false,
  28. bool hiddenByMe = false) {
  29. return (till >= kLifeStartDate + kSpecialValueSkip)
  30. ? LastseenStatus(till - kLifeStartDate, !local, hiddenByMe)
  31. : LongAgo(hiddenByMe);
  32. }
  33. [[nodiscard]] bool isHidden() const {
  34. return !_available;
  35. }
  36. [[nodiscard]] bool isRecently() const {
  37. return !_available && (_value == kRecentlyValue);
  38. }
  39. [[nodiscard]] bool isWithinWeek() const {
  40. return !_available && (_value == kWithinWeekValue);
  41. }
  42. [[nodiscard]] bool isWithinMonth() const {
  43. return !_available && (_value == kWithinMonthValue);
  44. }
  45. [[nodiscard]] bool isLongAgo() const {
  46. return !_available && (_value == kLongAgoValue);
  47. }
  48. [[nodiscard]] bool isHiddenByMe() const {
  49. return _hiddenByMe;
  50. }
  51. [[nodiscard]] bool isOnline(TimeId now) const {
  52. return (_value >= kSpecialValueSkip)
  53. && (kLifeStartDate + _value > now);
  54. }
  55. [[nodiscard]] bool isLocalOnlineValue() const {
  56. return !_available && (_value >= kSpecialValueSkip);
  57. }
  58. [[nodiscard]] TimeId onlineTill() const {
  59. return (_value >= kSpecialValueSkip)
  60. ? (kLifeStartDate + _value)
  61. : 0;
  62. }
  63. [[nodiscard]] uint32 serialize() const {
  64. return (_value & 0x3FFFFFFF)
  65. | (_available << 30)
  66. | (_hiddenByMe << 31);
  67. }
  68. [[nodiscard]] static LastseenStatus FromSerialized(uint32 value) {
  69. auto result = LastseenStatus();
  70. result._value = value & 0x3FFFFFFF;
  71. result._available = (value >> 30) & 1;
  72. result._hiddenByMe = (value >> 31) & 1;
  73. return result.valid() ? result : LastseenStatus();
  74. }
  75. [[nodiscard]] static LastseenStatus FromLegacy(int32 value) {
  76. if (value == -2) {
  77. return LastseenStatus::Recently();
  78. } else if (value == -3) {
  79. return LastseenStatus::WithinWeek();
  80. } else if (value == -4) {
  81. return LastseenStatus::WithinMonth();
  82. } else if (value < -30) {
  83. return LastseenStatus::OnlineTill(-value, true);
  84. } else if (value > 0) {
  85. return LastseenStatus::OnlineTill(value);
  86. }
  87. return LastseenStatus();
  88. }
  89. friend inline constexpr auto operator<=>(
  90. LastseenStatus,
  91. LastseenStatus) = default;
  92. friend inline constexpr bool operator==(
  93. LastseenStatus a,
  94. LastseenStatus b) = default;
  95. private:
  96. static constexpr auto kLongAgoValue = uint32(0);
  97. static constexpr auto kRecentlyValue = uint32(1);
  98. static constexpr auto kWithinWeekValue = uint32(2);
  99. static constexpr auto kWithinMonthValue = uint32(3);
  100. static constexpr auto kSpecialValueSkip = uint32(4);
  101. static constexpr auto kValidAfter = kLifeStartDate + kSpecialValueSkip;
  102. [[nodiscard]] bool valid() const {
  103. constexpr auto kMaxSum = uint32(std::numeric_limits<TimeId>::max());
  104. return (kMaxSum - _value > uint32(kLifeStartDate))
  105. && (!_available || (_value >= kSpecialValueSkip));
  106. }
  107. LastseenStatus(uint32 value, bool available, bool hiddenByMe)
  108. : _value(value)
  109. , _available(available ? 1 : 0)
  110. , _hiddenByMe(hiddenByMe ? 1 : 0) {
  111. }
  112. uint32 _value : 30 = 0;
  113. uint32 _available : 1 = 0;
  114. uint32 _hiddenByMe : 1 = 0;
  115. };
  116. } // namespace Data