mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
feat(admin): require a resolution and fix panel layout and copy (#3335)
This commit is contained in:
1 parent
4db13b0375
commit
6534ee4300
57 files changed
+1186
-255
No files matched your search
@@ -2,5 +2,6 @@
|
||||
|
||||
pub mod bigint;
|
||||
pub mod forms;
|
||||
pub mod plural;
|
||||
pub mod timestamps;
|
||||
pub mod user_tag;
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user