diff --git a/src/abaddon.cpp b/src/abaddon.cpp index b568f47..653327c 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -1,5 +1,4 @@ #include "abaddon.hpp" -#include #include #include #include @@ -1154,35 +1153,15 @@ void Abaddon::on_window_hide() { } } -// clang-format off - -#ifdef __GLIBC__ - #ifndef _GNU_SOURCE - #define _GNU_SOURCE - #include - #ifndef __USE_GNU - #define __MUSL__ - #endif - #undef _GNU_SOURCE - #else - #include - #ifndef __USE_GNU - #define __MUSL__ - #endif - #endif -#endif - -// clang-format on - int main(int argc, char **argv) { -#ifdef __MUSL__ - char env[] = "LANG=C"; - putenv(env); -#endif - - if (std::getenv("ABADDON_NO_FC") == nullptr) + if (std::getenv("ABADDON_NO_FC") == nullptr) { Platform::SetupFonts(); + } + // windows doesnt have langinfo.h so some localization falls back to translation strings + // i dont like the default translation so this lets us use strftime + +#ifdef _WIN32 char *systemLocale = std::setlocale(LC_ALL, ""); try { if (systemLocale != nullptr) { @@ -1196,6 +1175,7 @@ int main(int argc, char **argv) { } } catch (...) {} } +#endif #if defined(_WIN32) && defined(_MSC_VER) TCHAR buf[2] { 0 }; diff --git a/src/components/channellist/channellisttree.cpp b/src/components/channellist/channellisttree.cpp index 9adee61..e5f31fa 100644 --- a/src/components/channellist/channellisttree.cpp +++ b/src/components/channellist/channellisttree.cpp @@ -1179,8 +1179,11 @@ bool ChannelListTree::SelectionFunc(const Glib::RefPtr &model, c } } - const auto type = (*model->get_iter(path))[m_columns.m_type]; - const auto id = static_cast((*model->get_iter(path))[m_columns.m_id]); + const auto iter = model->get_iter(path); + if (!iter) return false; + + const auto type = (*iter)[m_columns.m_type]; + const auto id = static_cast((*iter)[m_columns.m_id]); // todo maybe just keep this last check? if (type == RenderType::TextChannel || type == RenderType::DM || type == RenderType::Thread || (id == m_active_channel)) return true; return is_currently_selected; diff --git a/src/discord/snowflake.cpp b/src/discord/snowflake.cpp index 43fe91e..361bd9e 100644 --- a/src/discord/snowflake.cpp +++ b/src/discord/snowflake.cpp @@ -6,6 +6,8 @@ #include "util.hpp" +#include + constexpr static uint64_t DiscordEpochSeconds = 1420070400; const Snowflake Snowflake::Invalid = -1ULL; @@ -56,11 +58,8 @@ bool Snowflake::IsValid() const { } Glib::ustring Snowflake::GetLocalTimestamp() const { - const time_t secs_since_epoch = (m_num / SecondsInterval) + DiscordEpochSeconds; - const std::tm tm = *localtime(&secs_since_epoch); - std::array tmp {}; - std::strftime(tmp.data(), sizeof(tmp), "%X %x", &tm); - return tmp.data(); + const gint64 secs_since_epoch = (m_num / SecondsInterval) + DiscordEpochSeconds; + return FormatUnixEpoch(secs_since_epoch); } uint64_t Snowflake::GetUnixMilliseconds() const noexcept { diff --git a/src/util.cpp b/src/util.cpp index 09bb368..85d4b44 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -63,27 +63,33 @@ int GetTimezoneOffset() { return static_cast(local_secs - gmt_secs); } -std::string FormatISO8601(const std::string &in, int extra_offset, const std::string &fmt) { - int yr, mon, day, hr, min, sec, tzhr, tzmin; - float milli; - std::sscanf(in.c_str(), "%d-%d-%dT%d:%d:%d%f+%d:%d", - &yr, &mon, &day, &hr, &min, &sec, &milli, &tzhr, &tzmin); +Glib::ustring FormatUnixEpoch(gint64 time, const std::string &fmt) { + auto dt = Glib::wrap(g_date_time_new_from_unix_utc(time)); + +#ifdef _WIN32 std::tm tm {}; - tm.tm_year = yr - 1900; - tm.tm_mon = mon - 1; - tm.tm_mday = day; - tm.tm_hour = hr; - tm.tm_min = min; - tm.tm_sec = sec; + tm.tm_year = dt.get_year() - 1900; + tm.tm_mon = dt.get_month() - 1; + tm.tm_mday = dt.get_day_of_month(); + tm.tm_hour = dt.get_hour() + 1; + tm.tm_min = dt.get_minute(); + tm.tm_sec = dt.get_second(); tm.tm_wday = 0; tm.tm_yday = 0; tm.tm_isdst = -1; - int offset = GetTimezoneOffset(); - tm.tm_sec += offset + extra_offset; + tm.tm_sec += GetTimezoneOffset(); mktime(&tm); std::array tmp {}; std::strftime(tmp.data(), sizeof(tmp), fmt.c_str(), &tm); return tmp.data(); +#else + return dt.format(fmt); +#endif +} + +Glib::ustring FormatISO8601(const std::string &in, int extra_offset, const std::string &fmt) { + const auto epoch = Glib::DateTime::create_from_iso8601(in).add_seconds(extra_offset).to_unix(); + return FormatUnixEpoch(epoch); } void ScrollListBoxToSelected(Gtk::ListBox &list) { diff --git a/src/util.hpp b/src/util.hpp index fc9568b..4024e34 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,8 @@ std::string GetExtension(std::string url); bool IsURLViewableImage(const std::string &url); std::vector ReadWholeFile(const std::string &path); std::string HumanReadableBytes(uint64_t bytes); -std::string FormatISO8601(const std::string &in, int extra_offset = 0, const std::string &fmt = "%x %X"); +Glib::ustring FormatUnixEpoch(gint64 time, const std::string &fmt = "%x %X"); +Glib::ustring FormatISO8601(const std::string &in, int extra_offset = 0, const std::string &fmt = "%x %X"); void AddPointerCursor(Gtk::Widget &widget); template