chore: optimize resource usage (#162)
* avoid string allocation * cache image * . * . * . * fix
This commit is contained in:
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
use anyhow::{anyhow, Error};
|
||||
use chrono::{Local, TimeZone};
|
||||
use global::constants::IMAGE_RESIZE_SERVICE;
|
||||
use gpui::{Image, ImageFormat};
|
||||
use gpui::{Image, ImageFormat, SharedString, SharedUri};
|
||||
use nostr_sdk::prelude::*;
|
||||
use qrcode::render::svg;
|
||||
use qrcode::QrCode;
|
||||
@@ -15,87 +15,92 @@ const HOURS_IN_DAY: i64 = 24;
|
||||
const DAYS_IN_MONTH: i64 = 30;
|
||||
const FALLBACK_IMG: &str = "https://image.nostr.build/c30703b48f511c293a9003be8100cdad37b8798b77a1dc3ec6eb8a20443d5dea.png";
|
||||
|
||||
pub trait ReadableProfile {
|
||||
fn avatar_url(&self, proxy: bool) -> String;
|
||||
fn display_name(&self) -> String;
|
||||
pub trait RenderedProfile {
|
||||
fn avatar(&self, proxy: bool) -> SharedUri;
|
||||
fn display_name(&self) -> SharedString;
|
||||
}
|
||||
|
||||
impl ReadableProfile for Profile {
|
||||
fn avatar_url(&self, proxy: bool) -> String {
|
||||
impl RenderedProfile for Profile {
|
||||
fn avatar(&self, proxy: bool) -> SharedUri {
|
||||
self.metadata()
|
||||
.picture
|
||||
.as_ref()
|
||||
.filter(|picture| !picture.is_empty())
|
||||
.map(|picture| {
|
||||
if proxy {
|
||||
format!(
|
||||
let url = format!(
|
||||
"{IMAGE_RESIZE_SERVICE}/?url={picture}&w=100&h=100&fit=cover&mask=circle&default={FALLBACK_IMG}&n=-1"
|
||||
)
|
||||
);
|
||||
|
||||
SharedUri::from(url)
|
||||
} else {
|
||||
picture.into()
|
||||
SharedUri::from(picture)
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| "brand/avatar.png".into())
|
||||
.unwrap_or_else(|| SharedUri::from("brand/avatar.png"))
|
||||
}
|
||||
|
||||
fn display_name(&self) -> String {
|
||||
fn display_name(&self) -> SharedString {
|
||||
if let Some(display_name) = self.metadata().display_name.as_ref() {
|
||||
if !display_name.is_empty() {
|
||||
return display_name.into();
|
||||
return SharedString::from(display_name);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(name) = self.metadata().name.as_ref() {
|
||||
if !name.is_empty() {
|
||||
return name.into();
|
||||
return SharedString::from(name);
|
||||
}
|
||||
}
|
||||
|
||||
shorten_pubkey(self.public_key(), 4)
|
||||
SharedString::from(shorten_pubkey(self.public_key(), 4))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ReadableTimestamp {
|
||||
fn to_human_time(&self) -> String;
|
||||
fn to_ago(&self) -> String;
|
||||
pub trait RenderedTimestamp {
|
||||
fn to_human_time(&self) -> SharedString;
|
||||
fn to_ago(&self) -> SharedString;
|
||||
}
|
||||
|
||||
impl ReadableTimestamp for Timestamp {
|
||||
fn to_human_time(&self) -> String {
|
||||
impl RenderedTimestamp for Timestamp {
|
||||
fn to_human_time(&self) -> SharedString {
|
||||
let input_time = match Local.timestamp_opt(self.as_u64() as i64, 0) {
|
||||
chrono::LocalResult::Single(time) => time,
|
||||
_ => return "9999".into(),
|
||||
_ => return SharedString::from("9999"),
|
||||
};
|
||||
|
||||
let now = Local::now();
|
||||
let input_date = input_time.date_naive();
|
||||
let now_date = now.date_naive();
|
||||
let yesterday_date = (now - chrono::Duration::days(1)).date_naive();
|
||||
|
||||
let time_format = input_time.format("%H:%M %p");
|
||||
|
||||
match input_date {
|
||||
date if date == now_date => format!("Today at {time_format}"),
|
||||
date if date == yesterday_date => format!("Yesterday at {time_format}"),
|
||||
_ => format!("{}, {time_format}", input_time.format("%d/%m/%y")),
|
||||
date if date == now_date => SharedString::from(format!("Today at {time_format}")),
|
||||
date if date == yesterday_date => {
|
||||
SharedString::from(format!("Yesterday at {time_format}"))
|
||||
}
|
||||
_ => SharedString::from(format!("{}, {time_format}", input_time.format("%d/%m/%y"))),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_ago(&self) -> String {
|
||||
fn to_ago(&self) -> SharedString {
|
||||
let input_time = match Local.timestamp_opt(self.as_u64() as i64, 0) {
|
||||
chrono::LocalResult::Single(time) => time,
|
||||
_ => return "1m".into(),
|
||||
_ => return SharedString::from("1m"),
|
||||
};
|
||||
|
||||
let now = Local::now();
|
||||
let duration = now.signed_duration_since(input_time);
|
||||
|
||||
match duration {
|
||||
d if d.num_seconds() < SECONDS_IN_MINUTE => NOW.into(),
|
||||
d if d.num_minutes() < MINUTES_IN_HOUR => format!("{}m", d.num_minutes()),
|
||||
d if d.num_hours() < HOURS_IN_DAY => format!("{}h", d.num_hours()),
|
||||
d if d.num_days() < DAYS_IN_MONTH => format!("{}d", d.num_days()),
|
||||
_ => input_time.format("%b %d").to_string(),
|
||||
d if d.num_seconds() < SECONDS_IN_MINUTE => SharedString::from(NOW),
|
||||
d if d.num_minutes() < MINUTES_IN_HOUR => {
|
||||
SharedString::from(format!("{}m", d.num_minutes()))
|
||||
}
|
||||
d if d.num_hours() < HOURS_IN_DAY => SharedString::from(format!("{}h", d.num_hours())),
|
||||
d if d.num_days() < DAYS_IN_MONTH => SharedString::from(format!("{}d", d.num_days())),
|
||||
_ => SharedString::from(input_time.format("%b %d").to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
use nostr_connect::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CoopAuthUrlHandler;
|
||||
|
||||
impl AuthUrlHandler for CoopAuthUrlHandler {
|
||||
fn on_auth_url(&self, auth_url: Url) -> BoxedFuture<Result<()>> {
|
||||
Box::pin(async move {
|
||||
log::info!("Received Auth URL: {auth_url}");
|
||||
webbrowser::open(auth_url.as_str())?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
pub mod debounced_delay;
|
||||
pub mod display;
|
||||
pub mod event;
|
||||
pub mod handle_auth;
|
||||
pub mod nip05;
|
||||
pub mod nip96;
|
||||
|
||||
Reference in New Issue
Block a user