feat(admin): require a resolution and fix panel layout and copy (#3335)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-09 01:40:34 +02:00
1 parent 4db13b0375
commit 6534ee4300
57 files changed
+1186 -255

No files matched your search

+1
View File
@@ -2,5 +2,6 @@
pub mod bigint;
pub mod forms;
pub mod plural;
pub mod timestamps;
pub mod user_tag;
+27
View File
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pub fn count_noun(count: u64, singular: &str, plural: &str) -> String {
if count == 1 {
format!("{count} {singular}")
} else {
format!("{count} {plural}")
}
}
pub fn noun_for(count: u64, singular: &'static str, plural: &'static str) -> &'static str {
if count == 1 { singular } else { plural }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn count_noun_picks_the_singular_only_for_one() {
assert_eq!(count_noun(0, "result", "results"), "0 results");
assert_eq!(count_noun(1, "result", "results"), "1 result");
assert_eq!(count_noun(2, "entry", "entries"), "2 entries");
assert_eq!(noun_for(1, "item", "items"), "item");
assert_eq!(noun_for(3, "item", "items"), "items");
}
}
+48 -74
View File
@@ -10,22 +10,6 @@ pub fn snowflake_to_timestamp_ms(snowflake: &str) -> Option<u64> {
Some(timestamp_ms)
}
pub fn format_unix_timestamp(unix_seconds: u64) -> String {
let offset = time::OffsetDateTime::from_unix_timestamp(unix_seconds as i64).ok();
match offset {
Some(dt) => {
let format = time::format_description::well_known::Rfc3339;
dt.format(&format)
.unwrap_or_else(|_| unix_seconds.to_string())
}
None => unix_seconds.to_string(),
}
}
pub fn format_unix_timestamp_ms(unix_ms: u64) -> String {
format_unix_timestamp(unix_ms / 1000)
}
pub fn relative_time(unix_seconds: u64) -> String {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
@@ -60,51 +44,50 @@ pub fn relative_time(unix_seconds: u64) -> String {
}
pub fn format_admin_timestamp(iso: &str) -> String {
let dt = time::OffsetDateTime::parse(iso, &time::format_description::well_known::Rfc3339)
time::OffsetDateTime::parse(iso, &time::format_description::well_known::Rfc3339)
.or_else(|_| {
time::OffsetDateTime::parse(
iso,
&time::format_description::well_known::Iso8601::DEFAULT,
)
})
.ok();
match dt {
Some(dt) => {
let dt = dt.to_offset(time::UtcOffset::UTC);
let month = match dt.month() {
time::Month::January => "Jan",
time::Month::February => "Feb",
time::Month::March => "Mar",
time::Month::April => "Apr",
time::Month::May => "May",
time::Month::June => "Jun",
time::Month::July => "Jul",
time::Month::August => "Aug",
time::Month::September => "Sep",
time::Month::October => "Oct",
time::Month::November => "Nov",
time::Month::December => "Dec",
};
let day = dt.day();
let year = dt.year();
let hour_12 = match dt.hour() {
0 => 12,
h if h > 12 => h - 12,
h => h,
};
let minute = dt.minute();
let ampm = if dt.hour() < 12 { "AM" } else { "PM" };
format!("{month} {day}, {year}, {hour_12}:{minute:02} {ampm} UTC")
}
None => iso.to_owned(),
}
.map_or_else(|_| iso.to_owned(), format_admin_datetime)
}
fn format_admin_datetime(dt: time::OffsetDateTime) -> String {
let dt = dt.to_offset(time::UtcOffset::UTC);
let month = match dt.month() {
time::Month::January => "Jan",
time::Month::February => "Feb",
time::Month::March => "Mar",
time::Month::April => "Apr",
time::Month::May => "May",
time::Month::June => "Jun",
time::Month::July => "Jul",
time::Month::August => "Aug",
time::Month::September => "Sep",
time::Month::October => "Oct",
time::Month::November => "Nov",
time::Month::December => "Dec",
};
let day = dt.day();
let year = dt.year();
let hour_12 = match dt.hour() {
0 => 12,
h if h > 12 => h - 12,
h => h,
};
let minute = dt.minute();
let ampm = if dt.hour() < 12 { "AM" } else { "PM" };
format!("{month} {day}, {year}, {hour_12}:{minute:02} {ampm} UTC")
}
pub fn snowflake_creation_date(snowflake: &str) -> String {
match snowflake_to_timestamp_ms(snowflake) {
Some(ms) => format_unix_timestamp_ms(ms),
None => "Unknown".to_owned(),
}
snowflake_to_timestamp_ms(snowflake)
.and_then(|ms| {
time::OffsetDateTime::from_unix_timestamp_nanos(i128::from(ms) * 1_000_000).ok()
})
.map_or_else(|| "Unknown".to_owned(), format_admin_datetime)
}
#[cfg(test)]
@@ -132,24 +115,6 @@ mod tests {
assert_eq!(snowflake_to_timestamp_ms("-1"), None);
}
#[test]
fn format_unix_timestamp_iso8601() {
let result = format_unix_timestamp(1_704_067_200);
assert!(
result.starts_with("2024-01-01"),
"expected ISO date starting with 2024-01-01, got: {result}"
);
}
#[test]
fn format_unix_timestamp_ms_converts() {
let result = format_unix_timestamp_ms(1_704_067_200_000);
assert!(
result.starts_with("2024-01-01"),
"expected ISO date, got: {result}"
);
}
#[test]
fn relative_time_just_now() {
let now = SystemTime::now()
@@ -196,10 +161,19 @@ mod tests {
#[test]
fn snowflake_creation_date_valid() {
let result = snowflake_creation_date("0");
assert!(
result.starts_with("2015-01-01"),
"expected 2015-01-01, got: {result}"
assert_eq!(snowflake_creation_date("0"), "Jan 1, 2015, 12:00 AM UTC");
}
#[test]
fn admin_timestamps_render_in_the_panel_format() {
assert_eq!(
format_admin_timestamp("2026-10-06T14:05:09.123Z"),
"Oct 6, 2026, 2:05 PM UTC"
);
assert_eq!(
format_admin_timestamp("2026-10-06T00:30:00+02:00"),
"Oct 5, 2026, 10:30 PM UTC"
);
assert_eq!(format_admin_timestamp("not a date"), "not a date");
}
}