mirror of
https://github.com/perstarkse/minne.git
synced 2026-07-03 11:31:43 +02:00
chore: improve html-router auth, caching, and analytics while centralizing search labels in common.
small fix
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
extract::{Request, State},
|
||||
http::Method,
|
||||
@@ -10,7 +12,7 @@ use common::storage::{db::ProvidesDb, types::analytics::Analytics};
|
||||
|
||||
use crate::SessionType;
|
||||
|
||||
/// Middleware to count unique visitors and page loads
|
||||
/// Middleware to count unique visitors and page loads.
|
||||
pub async fn analytics_middleware<S>(
|
||||
State(state): State<S>,
|
||||
session: SessionType,
|
||||
@@ -21,17 +23,18 @@ where
|
||||
S: ProvidesDb + Clone + Send + Sync + 'static,
|
||||
{
|
||||
let path = request.uri().path();
|
||||
// Only count visits/page loads for GET requests to non-asset, non-static paths
|
||||
if request.method() == Method::GET && !path.starts_with("/assets") && !path.contains('.') {
|
||||
if !session.get::<bool>("counted_visitor").unwrap_or(false) {
|
||||
if let Err(e) = Analytics::increment_visitors(state.db()).await {
|
||||
warn!("failed to increment visitor count: {e}");
|
||||
}
|
||||
let is_new_visitor = !session.get::<bool>("counted_visitor").unwrap_or(false);
|
||||
if is_new_visitor {
|
||||
session.set("counted_visitor", true);
|
||||
}
|
||||
if let Err(e) = Analytics::increment_page_loads(state.db()).await {
|
||||
warn!("failed to increment page load count: {e}");
|
||||
}
|
||||
|
||||
let db = Arc::clone(state.db());
|
||||
tokio::spawn(async move {
|
||||
if let Err(error) = Analytics::record_page_view(&db, is_new_visitor).await {
|
||||
warn!("failed to record page view: {error}");
|
||||
}
|
||||
});
|
||||
}
|
||||
next.run(request).await
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::AuthSessionType;
|
||||
use super::response_middleware::TemplateResponse;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
/// Authenticated user extracted from request extensions by [`require_auth`].
|
||||
pub struct RequireUser(pub User);
|
||||
|
||||
// Implement FromRequestParts for RequireUser
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
extract::{Request, State},
|
||||
@@ -36,6 +37,7 @@ pub enum TemplateKind {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
/// Handler response that the template middleware renders into HTML.
|
||||
pub struct TemplateResponse {
|
||||
template_kind: TemplateKind,
|
||||
context: Value,
|
||||
@@ -180,6 +182,7 @@ fn context_to_map(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub async fn with_template_response<S>(
|
||||
State(state): State<S>,
|
||||
HxRequest(is_htmx): HxRequest,
|
||||
@@ -221,14 +224,15 @@ where
|
||||
if let Some(cached_archive) =
|
||||
html_state.get_cached_conversation_archive(user_id).await
|
||||
{
|
||||
conversation_archive = cached_archive;
|
||||
conversation_archive = cached_archive.to_vec();
|
||||
} else if let Ok(archive) =
|
||||
Conversation::get_user_sidebar_conversations(user_id, &html_state.db).await
|
||||
{
|
||||
let cached = Arc::from(archive);
|
||||
html_state
|
||||
.set_cached_conversation_archive(user_id, archive.clone())
|
||||
.set_cached_conversation_archive(user_id, Arc::clone(&cached))
|
||||
.await;
|
||||
conversation_archive = archive;
|
||||
conversation_archive = cached.to_vec();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,8 +249,8 @@ where
|
||||
};
|
||||
|
||||
let context = ContextWrapper {
|
||||
user_theme: &user_theme,
|
||||
initial_theme: &initial_theme,
|
||||
user_theme,
|
||||
initial_theme,
|
||||
is_authenticated,
|
||||
user: current_user.as_ref(),
|
||||
conversation_archive,
|
||||
@@ -290,13 +294,13 @@ where
|
||||
.context
|
||||
.get_attr("title")
|
||||
.ok()
|
||||
.and_then(|v| v.as_str().map(|s| s.to_string()))
|
||||
.and_then(|v| v.as_str().map(str::to_string))
|
||||
.unwrap_or_else(|| "Error".to_string());
|
||||
let description = template_response
|
||||
.context
|
||||
.get_attr("description")
|
||||
.ok()
|
||||
.and_then(|v| v.as_str().map(|s| s.to_string()))
|
||||
.and_then(|v| v.as_str().map(str::to_string))
|
||||
.unwrap_or_else(|| "An error occurred.".to_string());
|
||||
|
||||
let trigger_payload = json!({"toast": {"title": title, "description": description, "type": "error"}});
|
||||
|
||||
Reference in New Issue
Block a user