Skip to content

Commit 6be570f

Browse files
committed
add screen size handling to the backend
1 parent 2cd317e commit 6be570f

File tree

6 files changed

+61
-3
lines changed

6 files changed

+61
-3
lines changed

src/app/core/reports.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::collections::BTreeMap;
22
use std::fmt::{Debug, Display};
33

44
use crate::app::DuckDBConn;
5-
use crate::utils::duckdb::{repeat_vars, ParamVec};
6-
use anyhow::{bail, Result};
5+
use crate::utils::duckdb::{ParamVec, repeat_vars};
6+
use anyhow::{Result, bail};
77
use chrono::{DateTime, Utc};
88
use duckdb::params_from_iter;
99
use schemars::JsonSchema;
@@ -66,6 +66,7 @@ pub enum Dimension {
6666
UtmCampaign,
6767
UtmContent,
6868
UtmTerm,
69+
ScreenSize,
6970
}
7071

7172
#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, Copy, Hash, Eq, PartialEq, PartialOrd, Ord)]
@@ -191,6 +192,7 @@ fn filter_sql(filters: &[DimensionFilter]) -> Result<(String, ParamVec<'_>)> {
191192
Dimension::UtmCampaign => format!("utm_campaign {filter_value}"),
192193
Dimension::UtmContent => format!("utm_content {filter_value}"),
193194
Dimension::UtmTerm => format!("utm_term {filter_value}"),
195+
Dimension::ScreenSize => format!("screen_size {filter_value}"),
194196
})
195197
})
196198
.collect::<Result<Vec<String>>>()?;
@@ -481,6 +483,7 @@ pub fn dimension_report(
481483
Dimension::UtmCampaign => ("utm_campaign", "utm_campaign", None),
482484
Dimension::UtmContent => ("utm_content", "utm_content", None),
483485
Dimension::UtmTerm => ("utm_term", "utm_term", None),
486+
Dimension::ScreenSize => ("screen_size", "screen_size", None),
484487
};
485488
let filters_sql = match (filters_sql.is_empty(), dimension_scope_sql) {
486489
(true, Some(scope)) => format!("and ({scope})"),

src/app/models.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub struct Event {
2323
pub utm_campaign: Option<String>,
2424
pub utm_content: Option<String>,
2525
pub utm_term: Option<String>,
26+
pub screen_size: Option<String>,
2627
}
2728

2829
#[derive(Debug, Clone)]
@@ -100,6 +101,7 @@ macro_rules! event_params {
100101
$event.utm_term,
101102
None::<std::time::Duration>,
102103
None::<std::time::Duration>,
104+
$event.screen_size,
103105
]
104106
};
105107
}

src/utils/seed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ pub fn random_events(
125125
utm_medium: Some(random_el(UTM_MEDIUMS, 0.6).to_string()),
126126
utm_source: Some(random_el(UTM_SOURCES, 0.6).to_string()),
127127
utm_term: Some(random_el(UTM_TERMS, 0.6).to_string()),
128+
screen_size: None,
128129
})
129130
})
130131
}

src/web/routes/dashboard.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ async fn project_detailed_handler(
227227
let city = city.filter(|city| !city.is_empty());
228228
data.push(DimensionTableRow { dimension_value: key, value, display_name: city, icon: country });
229229
}
230+
Dimension::ScreenSize => {
231+
let display_name =
232+
key.chars().next().map(|c| c.to_uppercase().collect::<String>() + &key[c.len_utf8()..]);
233+
data.push(DimensionTableRow { dimension_value: key, value, display_name, icon: None });
234+
}
230235
_ => {
231236
data.push(DimensionTableRow { dimension_value: key, value, display_name: None, icon: None });
232237
}

src/web/routes/event.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct EventRequest {
3131
url: String,
3232
referrer: Option<String>,
3333
utm: Option<Utm>,
34+
screen_width: Option<u32>,
3435
}
3536

3637
#[derive(serde::Deserialize, JsonSchema)]
@@ -42,6 +43,15 @@ struct Utm {
4243
term: Option<String>,
4344
}
4445

46+
fn screen_size_bucket(width: u32) -> &'static str {
47+
match width {
48+
0..=767 => "mobile",
49+
768..=1023 => "tablet",
50+
1024..=2559 => "desktop",
51+
_ => "ultrawide",
52+
}
53+
}
54+
4555
static EXISTING_ENTITIES: LazyLock<quick_cache::sync::Cache<String, ()>> =
4656
LazyLock::new(|| quick_cache::sync::Cache::new(512));
4757

@@ -131,8 +141,45 @@ fn process_event(
131141
utm_medium: event.utm.as_ref().and_then(|u| u.medium.clone()),
132142
utm_source: event.utm.as_ref().and_then(|u| u.source.clone()),
133143
utm_term: event.utm.as_ref().and_then(|u| u.term.clone()),
144+
screen_size: event.screen_width.map(|w| screen_size_bucket(w).to_string()),
134145
};
135146

136147
events.send(event)?;
137148
Ok(())
138149
}
150+
151+
#[cfg(test)]
152+
mod tests {
153+
use super::screen_size_bucket;
154+
155+
#[test]
156+
fn test_screen_size_bucket_mobile() {
157+
assert_eq!(screen_size_bucket(0), "mobile");
158+
assert_eq!(screen_size_bucket(375), "mobile");
159+
assert_eq!(screen_size_bucket(430), "mobile");
160+
assert_eq!(screen_size_bucket(767), "mobile");
161+
}
162+
163+
#[test]
164+
fn test_screen_size_bucket_tablet() {
165+
assert_eq!(screen_size_bucket(768), "tablet");
166+
assert_eq!(screen_size_bucket(810), "tablet");
167+
assert_eq!(screen_size_bucket(1023), "tablet");
168+
}
169+
170+
#[test]
171+
fn test_screen_size_bucket_desktop() {
172+
assert_eq!(screen_size_bucket(1024), "desktop");
173+
assert_eq!(screen_size_bucket(1280), "desktop");
174+
assert_eq!(screen_size_bucket(1920), "desktop");
175+
assert_eq!(screen_size_bucket(2559), "desktop");
176+
}
177+
178+
#[test]
179+
fn test_screen_size_bucket_ultrawide() {
180+
assert_eq!(screen_size_bucket(2560), "ultrawide");
181+
assert_eq!(screen_size_bucket(3440), "ultrawide");
182+
assert_eq!(screen_size_bucket(3840), "ultrawide");
183+
assert_eq!(screen_size_bucket(7680), "ultrawide");
184+
}
185+
}

0 commit comments

Comments
 (0)