Skip to content

Commit 9f754df

Browse files
committed
Save new area icons to image.db
1 parent 308709c commit 9f754df

4 files changed

Lines changed: 68 additions & 20 deletions

File tree

docs/rpc/area-methods.md

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -166,33 +166,38 @@ Removes a tag from an area.
166166

167167
### set_area_icon
168168

169-
Sets an icon for an area.
169+
Sets the square icon for an area. The `id` parameter accepts either the numeric area id or its alias.
170170

171-
**Required Admin Action**: `area_admin`
172-
173-
#### Request
171+
#### Example
174172

175173
```json
176174
{
177-
"jsonrpc": "2.0",
178-
"method": "set_area_icon",
179-
"params": {
180-
"area_id": 123,
181-
"icon_url": "https://example.com/icon.png"
182-
},
183-
"id": 1
175+
"id": 123,
176+
"icon_base64": "iVBORw0KGgoAAAANSUhEUgAA...<truncated base64 payload>...AAAElFTkSuQmCC",
177+
"icon_ext": "png"
184178
}
185179
```
186180

187-
#### Response
181+
##### Params
182+
183+
| Field | Type | Description |
184+
| --- | --- | --- |
185+
| `id` | integer \| string | Area id or alias |
186+
| `icon_base64` | string | Standard base64 encoding of the icon bytes |
187+
| `icon_ext` | string | File extension without the leading dot (e.g. `png`, `svg`) |
188+
189+
#### Result
188190

189191
```json
190192
{
191-
"jsonrpc": "2.0",
192-
"result": {
193-
"success": true
193+
"id": 123,
194+
"tags": {
195+
"icon:square": "https://static.btcmap.org/images/areas/123.png",
196+
"name": "City Center"
194197
},
195-
"id": 1
198+
"created_at": "2024-01-15T12:34:56Z",
199+
"updated_at": "2024-06-30T08:00:00Z",
200+
"deleted_at": null
196201
}
197202
```
198203

src/rpc/generate_area_icons.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub async fn run(main_pool: &Pool, image_pool: &ImagePool) -> Result<Res> {
156156
})
157157
}
158158

159-
fn decode_dimensions(bytes: &[u8]) -> Option<(u32, u32)> {
159+
pub fn decode_dimensions(bytes: &[u8]) -> Option<(u32, u32)> {
160160
if looks_like_svg(bytes) {
161161
return svg_dimensions(bytes);
162162
}

src/rpc/handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ pub async fn handle(
477477
),
478478
RpcMethod::SetAreaIcon => RpcResponse::from(
479479
req.id.clone(),
480-
super::set_area_icon::run(params(req.params)?, &main_pool).await?,
480+
super::set_area_icon::run(params(req.params)?, &main_pool, &image_pool).await?,
481481
),
482482
RpcMethod::RemoveArea => RpcResponse::from(
483483
req.id.clone(),

src/rpc/set_area_icon.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
db::{self, main::area::schema::Area},
2+
db::{self, image::ImagePool, main::area::schema::Area},
33
Result,
44
};
55
use base64::prelude::*;
@@ -41,7 +41,7 @@ impl From<Area> for Res {
4141
}
4242
}
4343

44-
pub async fn run(params: Params, pool: &Pool) -> Result<Res> {
44+
pub async fn run(params: Params, pool: &Pool, image_pool: &ImagePool) -> Result<Res> {
4545
let area = db::main::area::queries::select_by_id_or_alias(&params.id, pool).await?;
4646
let file_name = format!("{}.{}", area.id, params.icon_ext);
4747
let bytes = BASE64_STANDARD.decode(params.icon_base64)?;
@@ -54,6 +54,49 @@ pub async fn run(params: Params, pool: &Pool) -> Result<Res> {
5454
))?;
5555
file.write_all(&bytes)?;
5656
file.flush()?;
57+
58+
let dims = actix_web::web::block({
59+
let bytes = bytes.clone();
60+
move || super::generate_area_icons::decode_dimensions(&bytes)
61+
})
62+
.await?;
63+
64+
if let Some((width, height)) = dims {
65+
let bytes_len = bytes.len() as i64;
66+
let existing =
67+
db::image::area::queries::select_by_area_id_and_type(area.id, "square", image_pool)
68+
.await?;
69+
70+
if let Some(existing) = &existing {
71+
if existing.image_data == bytes {
72+
// already in sync, skip DB write
73+
} else {
74+
db::image::area::queries::delete(existing.id, image_pool).await?;
75+
db::image::area::queries::insert(
76+
area.id,
77+
"square",
78+
bytes,
79+
width as i64,
80+
height as i64,
81+
bytes_len,
82+
image_pool,
83+
)
84+
.await?;
85+
}
86+
} else {
87+
db::image::area::queries::insert(
88+
area.id,
89+
"square",
90+
bytes,
91+
width as i64,
92+
height as i64,
93+
bytes_len,
94+
image_pool,
95+
)
96+
.await?;
97+
}
98+
}
99+
57100
let url = format!("https://static.btcmap.org/images/areas/{file_name}");
58101
let patch_set = Map::from_iter([("icon:square".into(), url.into())]);
59102
let area = db::main::area::queries::patch_tags(area.id, patch_set, pool).await?;

0 commit comments

Comments
 (0)