mirror of
https://github.com/celisej567/abaddon.git
synced 2026-09-04 11:33:27 +03:00
mark more channels as unread properly
This commit is contained in:
@@ -2253,6 +2253,7 @@ void DiscordClient::StoreMessageData(Message &msg) {
|
||||
|
||||
// some notes for myself
|
||||
// a read channel is determined by checking if the channel object's last message id is equal to the read state's last message id
|
||||
// channels without entries are also unread
|
||||
// here the absence of an entry in m_unread indicates a read channel and the value is only the mention count since the message doesnt matter
|
||||
// no entry.id cannot be a guild even though sometimes it looks like it
|
||||
void DiscordClient::HandleReadyReadState(const ReadyEventData &data) {
|
||||
@@ -2270,6 +2271,26 @@ void DiscordClient::HandleReadyReadState(const ReadyEventData &data) {
|
||||
if (it->second > entry.LastMessageID)
|
||||
m_unread[entry.ID] = entry.MentionCount;
|
||||
}
|
||||
|
||||
// channels that arent in the read state are considered unread
|
||||
for (const auto &guild : data.Guilds) {
|
||||
if (!guild.JoinedAt.has_value()) continue; // doubt this can happen but whatever
|
||||
const auto joined_at = Snowflake::FromISO8601(*guild.JoinedAt);
|
||||
for (const auto &channel : *guild.Channels) {
|
||||
if (channel.LastMessageID.has_value()) {
|
||||
// unread messages from before you joined dont count as unread
|
||||
if (*channel.LastMessageID < joined_at) continue;
|
||||
if (std::find_if(data.ReadState.Entries.begin(), data.ReadState.Entries.end(), [id = channel.ID](const ReadStateEntry &e) {
|
||||
return e.ID == id;
|
||||
}) == data.ReadState.Entries.end()) {
|
||||
// cant be unread if u cant even see the channel
|
||||
// better to check here since HasChannelPermission hits the store
|
||||
if (HasChannelPermission(GetUserData().ID, channel.ID, Permission::VIEW_CHANNEL))
|
||||
m_unread[channel.ID] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiscordClient::HandleReadyGuildSettings(const ReadyEventData &data) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "snowflake.hpp"
|
||||
#include "util.hpp"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <chrono>
|
||||
|
||||
constexpr static uint64_t DiscordEpochSeconds = 1420070400;
|
||||
|
||||
@@ -14,13 +15,13 @@ Snowflake::Snowflake(uint64_t n)
|
||||
: m_num(n) {}
|
||||
|
||||
Snowflake::Snowflake(const std::string &str) {
|
||||
if (str.size())
|
||||
if (!str.empty())
|
||||
m_num = std::stoull(str);
|
||||
else
|
||||
m_num = Invalid;
|
||||
}
|
||||
Snowflake::Snowflake(const Glib::ustring &str) {
|
||||
if (str.size())
|
||||
if (!str.empty())
|
||||
m_num = std::strtoull(str.c_str(), nullptr, 10);
|
||||
else
|
||||
m_num = Invalid;
|
||||
@@ -38,6 +39,14 @@ Snowflake Snowflake::FromNow() {
|
||||
return snowflake;
|
||||
}
|
||||
|
||||
Snowflake Snowflake::FromISO8601(std::string_view ts) {
|
||||
int yr, mon, day, hr, min, sec, tzhr, tzmin;
|
||||
float milli;
|
||||
std::sscanf(ts.data(), "%d-%d-%dT%d:%d:%d%f+%d:%d",
|
||||
&yr, &mon, &day, &hr, &min, &sec, &milli, &tzhr, &tzmin);
|
||||
return SecondsInterval * (util::TimeToEpoch(yr, mon, day, hr, min, sec) - DiscordEpochSeconds) + static_cast<uint64_t>(milli * static_cast<float>(SecondsInterval));
|
||||
}
|
||||
|
||||
bool Snowflake::IsValid() const {
|
||||
return m_num != Invalid;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct Snowflake {
|
||||
Snowflake(const Glib::ustring &str);
|
||||
|
||||
static Snowflake FromNow(); // not thread safe
|
||||
static Snowflake FromISO8601(std::string_view ts);
|
||||
|
||||
bool IsValid() const;
|
||||
std::string GetLocalTimestamp() const;
|
||||
@@ -26,7 +27,7 @@ struct Snowflake {
|
||||
return m_num;
|
||||
}
|
||||
|
||||
const static Snowflake Invalid; // makes sense to me
|
||||
const static Snowflake Invalid; // makes sense to me
|
||||
const static uint64_t SecondsInterval = 4194304000ULL; // the "difference" between two snowflakes one second apart
|
||||
|
||||
friend void from_json(const nlohmann::json &j, Snowflake &s);
|
||||
|
||||
29
src/util.cpp
29
src/util.cpp
@@ -1,4 +1,5 @@
|
||||
#include "util.hpp"
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
|
||||
Semaphore::Semaphore(int count)
|
||||
@@ -215,3 +216,31 @@ bool util::IsFile(std::string_view path) {
|
||||
if (ec) return false;
|
||||
return status.type() == std::filesystem::file_type::regular;
|
||||
}
|
||||
|
||||
constexpr bool IsLeapYear(int year) {
|
||||
if (year % 4 != 0) return false;
|
||||
if (year % 100 != 0) return true;
|
||||
return (year % 400) == 0;
|
||||
}
|
||||
|
||||
constexpr static int SecsPerMinute = 60;
|
||||
constexpr static int SecsPerHour = 3600;
|
||||
constexpr static int SecsPerDay = 86400;
|
||||
constexpr static std::array<int, 12> DaysOfMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
// may god smite whoever is responsible for the absolutely abominable api that is C time functions
|
||||
// i shouldnt have to write this. mktime ALMOST works but it adds the current timezone offset. WHY???
|
||||
uint64_t util::TimeToEpoch(int year, int month, int day, int hour, int minute, int seconds) {
|
||||
uint64_t secs = 0;
|
||||
for (int y = 1970; y < year; ++y)
|
||||
secs += (IsLeapYear(y) ? 366 : 365) * SecsPerDay;
|
||||
for (int m = 1; m < month; ++m) {
|
||||
secs += DaysOfMonth[m - 1] * SecsPerDay;
|
||||
if (m == 2 && IsLeapYear(year)) secs += SecsPerDay;
|
||||
}
|
||||
secs += (day - 1) * SecsPerDay;
|
||||
secs += hour * SecsPerHour;
|
||||
secs += minute * SecsPerMinute;
|
||||
secs += seconds;
|
||||
return secs;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ struct is_optional<::std::optional<T>> : ::std::true_type {};
|
||||
bool IsFolder(std::string_view path);
|
||||
|
||||
bool IsFile(std::string_view path);
|
||||
|
||||
uint64_t TimeToEpoch(int year, int month, int day, int hour, int minute, int seconds);
|
||||
} // namespace util
|
||||
|
||||
class Semaphore {
|
||||
|
||||
Reference in New Issue
Block a user