bobashare_web/views/
upload.rs

1use askama::Template;
2use axum::{extract::State, response::IntoResponse};
3use chrono::TimeDelta;
4use tracing::{event, instrument, Level};
5
6use super::{filters, render_template, CurrentNavigation, ErrorResponse, TemplateState};
7use crate::AppState;
8
9#[derive(Debug, Clone)]
10pub struct ExpiryUnit {
11    pub name: &'static str,
12    pub value: &'static str,
13    pub default: bool,
14    pub duration: TimeDelta,
15}
16pub fn iter_expiry_units() -> impl Iterator<Item = ExpiryUnit> {
17    [
18        ExpiryUnit {
19            name: "seconds",
20            value: "s",
21            default: false,
22            duration: TimeDelta::try_seconds(1).unwrap(),
23        },
24        ExpiryUnit {
25            name: "minutes",
26            value: "m",
27            default: false,
28            duration: TimeDelta::try_minutes(1).unwrap(),
29        },
30        ExpiryUnit {
31            name: "hours",
32            value: "h",
33            default: false,
34            duration: TimeDelta::try_hours(1).unwrap(),
35        },
36        ExpiryUnit {
37            name: "days",
38            value: "d",
39            default: true,
40            duration: TimeDelta::try_days(1).unwrap(),
41        },
42        ExpiryUnit {
43            name: "weeks",
44            value: "w",
45            default: false,
46            duration: TimeDelta::try_days(7).unwrap(),
47        },
48        ExpiryUnit {
49            name: "months",
50            value: "mon",
51            default: false,
52            duration: TimeDelta::try_days(30).unwrap(),
53        },
54        ExpiryUnit {
55            name: "years",
56            value: "y",
57            default: false,
58            duration: TimeDelta::try_days(365).unwrap(),
59        },
60    ]
61    .into_iter()
62}
63
64#[derive(Template)]
65#[template(path = "upload.html.jinja")]
66pub struct UploadTemplate<'s> {
67    pub state: TemplateState<'s>,
68    // TODO: make this iterator and not vec
69    pub expiry_units: Vec<ExpiryUnit>,
70    pub never_expiry_allowed: bool,
71}
72
73#[instrument(skip(state))]
74pub async fn upload(
75    State(state): State<&'static AppState>,
76) -> Result<impl IntoResponse, ErrorResponse> {
77    let mut state = TemplateState::from(state);
78    state.current_navigation = Some(CurrentNavigation::Upload);
79    event!(Level::DEBUG, "returning upload template");
80    render_template(UploadTemplate {
81        expiry_units: iter_expiry_units()
82            .take_while(|e| {
83                if let Some(max) = state.max_expiry {
84                    max >= e.duration
85                } else {
86                    true
87                }
88            })
89            .collect(),
90        never_expiry_allowed: state.max_expiry.is_none(),
91        state,
92    })
93}
94
95#[derive(Template)]
96#[template(path = "paste.html.jinja")]
97pub struct PasteTemplate<'s> {
98    pub state: TemplateState<'s>,
99    pub expiry_units: Vec<ExpiryUnit>,
100    pub never_expiry_allowed: bool,
101}
102
103#[instrument(skip(state))]
104pub async fn paste(
105    State(state): State<&'static AppState>,
106) -> Result<impl IntoResponse, ErrorResponse> {
107    let mut state = TemplateState::from(state);
108    state.current_navigation = Some(CurrentNavigation::Paste);
109    event!(Level::DEBUG, "returning paste template");
110    render_template(PasteTemplate {
111        expiry_units: iter_expiry_units()
112            .take_while(|e| {
113                if let Some(max) = state.max_expiry {
114                    max >= e.duration
115                } else {
116                    true
117                }
118            })
119            .collect(),
120        never_expiry_allowed: state.max_expiry.is_none(),
121        state,
122    })
123}