Skip to content

Commit dd12915

Browse files
committed
feat(desktop): add boost Tauri commands; fix bot serde rename
1 parent 4a70a00 commit dd12915

4 files changed

Lines changed: 147 additions & 2 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//! Tauri commands for server boost / supporter tier system.
2+
//!
3+
//! Covers: listing boosters, adding/removing boost slots, reading tier info,
4+
//! and setting the server vanity URL (tier 2+).
5+
6+
use serde::{Deserialize, Serialize};
7+
use tauri::State;
8+
use uuid::Uuid;
9+
10+
use crate::state::AppState;
11+
use super::api_client;
12+
13+
// ─── Client-side types ────────────────────────────────────────────────────────
14+
15+
/// Server boost tier info — mirrors the API's `BoostTierInfo`.
16+
#[derive(Debug, Serialize, Deserialize)]
17+
#[serde(rename_all(serialize = "camelCase", deserialize = "snake_case"))]
18+
pub struct BoostTierInfo {
19+
pub tier: i16,
20+
pub booster_count: i64,
21+
pub extra_emoji_slots: i32,
22+
pub upload_limit_bytes: i64,
23+
pub vanity_url_available: bool,
24+
pub current_vanity_code: Option<String>,
25+
}
26+
27+
/// A single active boost slot — mirrors the API's `BoosterEntry`.
28+
#[derive(Debug, Serialize, Deserialize)]
29+
#[serde(rename_all(serialize = "camelCase", deserialize = "snake_case"))]
30+
pub struct BoosterEntry {
31+
pub id: String,
32+
pub user_id: String,
33+
pub server_id: String,
34+
pub slot: i16,
35+
pub started_at: String,
36+
pub expires_at: Option<String>,
37+
}
38+
39+
// ─── Commands ─────────────────────────────────────────────────────────────────
40+
41+
/// GET /api/v1/servers/{server_id}/boost-tier — current tier + perks.
42+
#[tauri::command]
43+
pub async fn get_server_boost_tier(
44+
state: State<'_, AppState>,
45+
server_id: Uuid,
46+
) -> Result<BoostTierInfo, String> {
47+
let session = state.session_snapshot();
48+
let (client, base) = api_client(&session).map_err(|e| e.to_string())?;
49+
let resp = client
50+
.get(format!("{base}/api/v1/servers/{server_id}/boost-tier"))
51+
.send()
52+
.await
53+
.map_err(|e| e.to_string())?;
54+
if !resp.status().is_success() {
55+
return Err(resp.text().await.unwrap_or_default());
56+
}
57+
resp.json::<BoostTierInfo>().await.map_err(|e| e.to_string())
58+
}
59+
60+
/// GET /api/v1/servers/{server_id}/boosters — list active boosters.
61+
#[tauri::command]
62+
pub async fn list_server_boosters(
63+
state: State<'_, AppState>,
64+
server_id: Uuid,
65+
) -> Result<Vec<BoosterEntry>, String> {
66+
let session = state.session_snapshot();
67+
let (client, base) = api_client(&session).map_err(|e| e.to_string())?;
68+
let resp = client
69+
.get(format!("{base}/api/v1/servers/{server_id}/boosters"))
70+
.send()
71+
.await
72+
.map_err(|e| e.to_string())?;
73+
if !resp.status().is_success() {
74+
return Err(resp.text().await.unwrap_or_default());
75+
}
76+
resp.json::<Vec<BoosterEntry>>().await.map_err(|e| e.to_string())
77+
}
78+
79+
/// POST /api/v1/servers/{server_id}/boost — add a boost slot.
80+
#[tauri::command]
81+
pub async fn boost_server(
82+
state: State<'_, AppState>,
83+
server_id: Uuid,
84+
) -> Result<BoosterEntry, String> {
85+
let session = state.session_snapshot();
86+
let (client, base) = api_client(&session).map_err(|e| e.to_string())?;
87+
let resp = client
88+
.post(format!("{base}/api/v1/servers/{server_id}/boost"))
89+
.send()
90+
.await
91+
.map_err(|e| e.to_string())?;
92+
if !resp.status().is_success() {
93+
return Err(resp.text().await.unwrap_or_default());
94+
}
95+
resp.json::<BoosterEntry>().await.map_err(|e| e.to_string())
96+
}
97+
98+
/// DELETE /api/v1/servers/{server_id}/boost/{slot} — remove a boost slot.
99+
#[tauri::command]
100+
pub async fn remove_boost(
101+
state: State<'_, AppState>,
102+
server_id: Uuid,
103+
slot: i16,
104+
) -> Result<(), String> {
105+
let session = state.session_snapshot();
106+
let (client, base) = api_client(&session).map_err(|e| e.to_string())?;
107+
let resp = client
108+
.delete(format!("{base}/api/v1/servers/{server_id}/boost/{slot}"))
109+
.send()
110+
.await
111+
.map_err(|e| e.to_string())?;
112+
if !resp.status().is_success() {
113+
return Err(resp.text().await.unwrap_or_default());
114+
}
115+
Ok(())
116+
}
117+
118+
/// PATCH /api/v1/servers/{server_id}/vanity-url — set vanity invite code (tier 2+).
119+
#[tauri::command]
120+
pub async fn set_vanity_url(
121+
state: State<'_, AppState>,
122+
server_id: Uuid,
123+
vanity_code: String,
124+
) -> Result<(), String> {
125+
let session = state.session_snapshot();
126+
let (client, base) = api_client(&session).map_err(|e| e.to_string())?;
127+
let body = serde_json::json!({ "code": vanity_code });
128+
let resp = client
129+
.patch(format!("{base}/api/v1/servers/{server_id}/vanity-url"))
130+
.json(&body)
131+
.send()
132+
.await
133+
.map_err(|e| e.to_string())?;
134+
if !resp.status().is_success() {
135+
return Err(resp.text().await.unwrap_or_default());
136+
}
137+
Ok(())
138+
}

crates/nexus-desktop/src-tauri/src/commands/bots.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::api_client;
1515

1616
/// Installed bot record (mirrors server `BotServerInstall`).
1717
#[derive(Debug, Serialize, Deserialize)]
18-
#[serde(rename_all = "camelCase")]
18+
#[serde(rename_all(serialize = "camelCase", deserialize = "snake_case"))]
1919
pub struct BotInstall {
2020
pub id: Uuid,
2121
pub bot_id: Uuid,
@@ -28,7 +28,7 @@ pub struct BotInstall {
2828

2929
/// Public bot info returned by the unauthenticated lookup endpoint.
3030
#[derive(Debug, Serialize, Deserialize)]
31-
#[serde(rename_all = "camelCase")]
31+
#[serde(rename_all(serialize = "camelCase", deserialize = "snake_case"))]
3232
pub struct PublicBotInfo {
3333
pub id: Uuid,
3434
pub name: String,

crates/nexus-desktop/src-tauri/src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! All HTTP calls use the `reqwest` client with the base URL from [`AppState::session`].
55
66
pub mod auth;
7+
pub mod boosters;
78
pub mod bots;
89
pub mod channels;
910
pub mod e2ee;

crates/nexus-desktop/src-tauri/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ pub fn run() {
9393
commands::bots::install_bot,
9494
commands::bots::uninstall_bot,
9595
commands::bots::get_public_bot_info,
96+
// Boost / supporter tiers
97+
commands::boosters::get_server_boost_tier,
98+
commands::boosters::list_server_boosters,
99+
commands::boosters::boost_server,
100+
commands::boosters::remove_boost,
101+
commands::boosters::set_vanity_url,
96102
commands::channels::list_channels,
97103
commands::channels::get_channel,
98104
commands::channels::create_channel,

0 commit comments

Comments
 (0)