2024-04-17 22:07:47 +02:00
|
|
|
mod app;
|
|
|
|
mod auth;
|
|
|
|
mod timeline;
|
|
|
|
mod view;
|
|
|
|
mod page;
|
|
|
|
mod control;
|
2024-04-14 06:45:51 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub use app::App;
|
|
|
|
pub use timeline::Timeline;
|
|
|
|
pub use auth::{Auth, AuthToken};
|
2024-04-14 06:45:51 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub mod prelude;
|
2024-04-15 05:27:53 +02:00
|
|
|
|
2024-04-15 05:00:23 +02:00
|
|
|
pub const URL_BASE: &str = "https://feditest.alemi.dev";
|
|
|
|
pub const URL_PREFIX: &str = "/web";
|
2024-04-17 21:10:20 +02:00
|
|
|
pub const NAME: &str = "μ";
|
2024-04-14 06:45:51 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
use std::sync::Arc;
|
2024-04-14 06:45:51 +02:00
|
|
|
|
2024-04-16 06:34:50 +02:00
|
|
|
|
2024-04-15 22:03:32 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
lazy_static::lazy_static! {
|
|
|
|
pub static ref CACHE: ObjectCache = ObjectCache::default();
|
2024-04-15 22:20:33 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
#[derive(Debug, Clone, Default)]
|
|
|
|
pub struct ObjectCache(pub Arc<dashmap::DashMap<String, serde_json::Value>>);
|
2024-04-15 22:32:05 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
impl ObjectCache {
|
|
|
|
pub fn get(&self, k: &str) -> Option<serde_json::Value> {
|
|
|
|
self.0.get(k).map(|x| x.clone())
|
2024-04-14 06:45:51 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub fn put(&self, k: String, v: serde_json::Value) {
|
|
|
|
self.0.insert(k, v);
|
2024-04-16 06:42:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-14 06:45:51 +02:00
|
|
|
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub struct Http;
|
2024-04-14 06:45:51 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
impl Http {
|
|
|
|
pub async fn request<T: serde::ser::Serialize>(
|
|
|
|
method: reqwest::Method,
|
|
|
|
url: &str,
|
|
|
|
data: Option<&T>,
|
|
|
|
token: leptos::Signal<Option<String>>
|
|
|
|
) -> reqwest::Result<reqwest::Response> {
|
|
|
|
use leptos::SignalGet;
|
|
|
|
|
|
|
|
let mut req = reqwest::Client::new()
|
|
|
|
.request(method, url);
|
|
|
|
|
|
|
|
if let Some(auth) = token.get() {
|
|
|
|
req = req.header("Authorization", format!("Bearer {}", auth));
|
2024-04-15 03:38:16 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
if let Some(data) = data {
|
|
|
|
req = req.json(data);
|
2024-04-15 22:03:32 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
req.send()
|
|
|
|
.await?
|
|
|
|
.error_for_status()
|
2024-04-15 22:03:32 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub async fn fetch<T: serde::de::DeserializeOwned>(url: &str, token: leptos::Signal<Option<String>>) -> reqwest::Result<T> {
|
|
|
|
Self::request::<()>(reqwest::Method::GET, url, None, token)
|
|
|
|
.await?
|
|
|
|
.json::<T>()
|
|
|
|
.await
|
2024-04-17 07:29:56 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub async fn post<T: serde::ser::Serialize>(url: &str, data: &T, token: leptos::Signal<Option<String>>) -> reqwest::Result<()> {
|
|
|
|
Self::request(reqwest::Method::POST, url, Some(data), token)
|
|
|
|
.await?;
|
|
|
|
Ok(())
|
2024-04-14 06:45:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub struct Uri;
|
|
|
|
|
|
|
|
impl Uri {
|
|
|
|
pub fn full(kind: &str, id: &str) -> String {
|
|
|
|
if id.starts_with('+') {
|
|
|
|
id.replace('+', "https://").replace('@', "/")
|
|
|
|
} else {
|
|
|
|
format!("{URL_BASE}/{kind}/{id}")
|
|
|
|
}
|
2024-04-16 06:34:50 +02:00
|
|
|
}
|
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub fn pretty(url: &str) -> String {
|
|
|
|
if url.len() < 50 {
|
|
|
|
url.replace("https://", "")
|
|
|
|
} else {
|
|
|
|
format!("{}..", url.replace("https://", "").get(..50).unwrap_or_default())
|
|
|
|
}.replace('/', "\u{200B}/\u{200B}")
|
2024-04-17 21:10:20 +02:00
|
|
|
}
|
2024-04-15 03:03:01 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
pub fn short(url: &str) -> String {
|
|
|
|
if url.starts_with(URL_BASE) {
|
|
|
|
url.split('/').last().unwrap_or_default().to_string()
|
|
|
|
} else {
|
|
|
|
url.replace("https://", "+").replace('/', "@")
|
|
|
|
}
|
2024-04-15 03:03:01 +02:00
|
|
|
}
|
2024-04-16 08:02:03 +02:00
|
|
|
|
2024-04-17 22:07:47 +02:00
|
|
|
/// convert url id to valid frontend view id:
|
|
|
|
/// /web/users/test
|
|
|
|
/// /web/objects/+social.alemi.dev@objects@1204kasfkl
|
|
|
|
/// accepts:
|
|
|
|
/// - https://my.domain.net/users/root
|
|
|
|
/// - https://other.domain.net/unexpected/path/root
|
|
|
|
/// - +other.domain.net@users@root
|
|
|
|
/// - root
|
|
|
|
pub fn web(kind: &str, url: &str) -> String {
|
|
|
|
format!("/web/{kind}/{}", Self::short(url))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// convert url id to valid backend api id
|
|
|
|
/// https://feditest.alemi.dev/users/test
|
|
|
|
/// https://feditest.alemi.dev/users/+social.alemi.dev@users@alemi
|
|
|
|
/// accepts:
|
|
|
|
/// - https://my.domain.net/users/root
|
|
|
|
/// - https://other.domain.net/unexpected/path/root
|
|
|
|
/// - +other.domain.net@users@root
|
|
|
|
/// - root
|
2024-04-18 05:00:44 +02:00
|
|
|
pub fn api(kind: &str, url: &str, fetch: bool) -> String {
|
|
|
|
format!("{URL_BASE}/{kind}/{}{}", Self::short(url), if fetch { "?fetch=true" } else { "" })
|
2024-04-16 08:02:03 +02:00
|
|
|
}
|
|
|
|
}
|