Files
telegram-tui/src/utils.rs
Mikhail Kilin 4deb0fbe00 commit
2026-01-30 15:07:13 +03:00

161 lines
5.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use std::ffi::CString;
use std::os::raw::c_char;
#[link(name = "tdjson")]
extern "C" {
fn td_execute(request: *const c_char) -> *const c_char;
}
/// Отключаем логи TDLib синхронно, до создания клиента
pub fn disable_tdlib_logs() {
let request = r#"{"@type":"setLogVerbosityLevel","new_verbosity_level":0}"#;
let c_request = CString::new(request).unwrap();
unsafe {
let _ = td_execute(c_request.as_ptr());
}
// Также перенаправляем логи в никуда
let request2 = r#"{"@type":"setLogStream","log_stream":{"@type":"logStreamEmpty"}}"#;
let c_request2 = CString::new(request2).unwrap();
unsafe {
let _ = td_execute(c_request2.as_ptr());
}
}
/// Форматирование timestamp в время HH:MM с учётом timezone offset
/// timezone_str: строка формата "+03:00" или "-05:00"
pub fn format_timestamp_with_tz(timestamp: i32, timezone_str: &str) -> String {
let secs = timestamp as i64;
// Парсим timezone offset (например "+03:00" -> 3 часа)
let offset_hours = parse_timezone_offset(timezone_str);
let hours = ((secs % 86400) / 3600) as i32;
let minutes = ((secs % 3600) / 60) as u32;
// Применяем timezone offset
let local_hours = ((hours + offset_hours) % 24 + 24) % 24;
format!("{:02}:{:02}", local_hours, minutes)
}
/// Парсит timezone строку типа "+03:00" в количество часов
fn parse_timezone_offset(tz: &str) -> i32 {
// Простой парсинг "+03:00" или "-05:00"
if tz.len() >= 3 {
let sign = if tz.starts_with('-') { -1 } else { 1 };
let hours_str = &tz[1..3];
if let Ok(hours) = hours_str.parse::<i32>() {
return sign * hours;
}
}
3 // fallback к MSK
}
/// Устаревшая функция для обратной совместимости (используется дефолтный +03:00)
#[allow(dead_code)]
pub fn format_timestamp(timestamp: i32) -> String {
format_timestamp_with_tz(timestamp, "+03:00")
}
/// Форматирование timestamp в дату для разделителя
pub fn format_date(timestamp: i32) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
let msg_day = timestamp as i64 / 86400;
let today = now / 86400;
if msg_day == today {
"Сегодня".to_string()
} else if msg_day == today - 1 {
"Вчера".to_string()
} else {
// Простое форматирование даты
let days_since_epoch = timestamp as i64 / 86400;
// Приблизительный расчёт даты (без учёта високосных годов)
let year = 1970 + (days_since_epoch / 365) as i32;
let day_of_year = days_since_epoch % 365;
let months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let mut month = 0;
let mut day = day_of_year as i32;
for (i, &m) in months.iter().enumerate() {
if day < m {
month = i + 1;
break;
}
day -= m;
}
format!("{:02}.{:02}.{}", day + 1, month, year)
}
}
/// Получить день из timestamp для группировки
pub fn get_day(timestamp: i32) -> i64 {
timestamp as i64 / 86400
}
/// Форматирование timestamp в полную дату и время (DD.MM.YYYY HH:MM)
pub fn format_datetime(timestamp: i32) -> String {
let secs = timestamp as i64;
// Время
let hours = ((secs % 86400) / 3600) as u32;
let minutes = ((secs % 3600) / 60) as u32;
let local_hours = (hours + 3) % 24; // MSK
// Дата
let days_since_epoch = secs / 86400;
let year = 1970 + (days_since_epoch / 365) as i32;
let day_of_year = days_since_epoch % 365;
let months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let mut month = 1;
let mut day = day_of_year as i32;
for (i, &m) in months.iter().enumerate() {
if day < m {
month = i + 1;
break;
}
day -= m;
}
format!("{:02}.{:02}.{} {:02}:{:02}", day + 1, month, year, local_hours, minutes)
}
/// Форматирование "был(а) онлайн" из timestamp
pub fn format_was_online(timestamp: i32) -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i32;
let diff = now - timestamp;
if diff < 60 {
"был(а) только что".to_string()
} else if diff < 3600 {
let mins = diff / 60;
format!("был(а) {} мин. назад", mins)
} else if diff < 86400 {
let hours = diff / 3600;
format!("был(а) {} ч. назад", hours)
} else {
// Показываем дату
let datetime = chrono::DateTime::from_timestamp(timestamp as i64, 0)
.map(|dt| dt.format("%d.%m %H:%M").to_string())
.unwrap_or_else(|| "давно".to_string());
format!("был(а) {}", datetime)
}
}