added server and realm tabs to inventory screen
This commit is contained in:
parent
ee425e224e
commit
acab2f017d
12 changed files with 647 additions and 151 deletions
|
|
@ -640,6 +640,23 @@ pub struct InventoryResponse {
|
|||
pub items: Vec<InventoryItem>,
|
||||
}
|
||||
|
||||
/// A public prop from server or realm library.
|
||||
/// Used for the public inventory tabs (Server/Realm).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]
|
||||
pub struct PublicProp {
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
pub asset_path: String,
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
/// Response for public props list.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PublicPropsResponse {
|
||||
pub props: Vec<PublicProp>,
|
||||
}
|
||||
|
||||
/// A prop dropped in a channel, available for pickup.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "ssr", derive(sqlx::FromRow))]
|
||||
|
|
@ -680,6 +697,7 @@ pub struct ServerProp {
|
|||
pub is_transferable: bool,
|
||||
pub is_portable: bool,
|
||||
pub is_droppable: bool,
|
||||
pub is_public: bool,
|
||||
pub is_active: bool,
|
||||
pub available_from: Option<DateTime<Utc>>,
|
||||
pub available_until: Option<DateTime<Utc>>,
|
||||
|
|
@ -720,6 +738,12 @@ pub struct CreateServerPropRequest {
|
|||
/// Grid position (0-8): top row 0,1,2 / middle 3,4,5 / bottom 6,7,8
|
||||
#[serde(default)]
|
||||
pub default_position: Option<i16>,
|
||||
/// Whether prop is droppable (can be dropped in a channel).
|
||||
#[serde(default)]
|
||||
pub droppable: Option<bool>,
|
||||
/// Whether prop appears in the public Server inventory tab.
|
||||
#[serde(default)]
|
||||
pub public: Option<bool>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use sqlx::PgExecutor;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::models::InventoryItem;
|
||||
use crate::models::{InventoryItem, PublicProp};
|
||||
use chattyness_error::AppError;
|
||||
|
||||
/// List all inventory items for a user.
|
||||
|
|
@ -91,3 +91,67 @@ pub async fn drop_inventory_item<'e>(
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// List all public server props.
|
||||
///
|
||||
/// Returns props that are:
|
||||
/// - Active (`is_active = true`)
|
||||
/// - Public (`is_public = true`)
|
||||
/// - Currently available (within availability window if set)
|
||||
pub async fn list_public_server_props<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
) -> Result<Vec<PublicProp>, AppError> {
|
||||
let props = sqlx::query_as::<_, PublicProp>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
asset_path,
|
||||
description
|
||||
FROM server.props
|
||||
WHERE is_active = true
|
||||
AND is_public = true
|
||||
AND (available_from IS NULL OR available_from <= now())
|
||||
AND (available_until IS NULL OR available_until > now())
|
||||
ORDER BY name ASC
|
||||
"#,
|
||||
)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
Ok(props)
|
||||
}
|
||||
|
||||
/// List all public realm props for a specific realm.
|
||||
///
|
||||
/// Returns props that are:
|
||||
/// - In the specified realm
|
||||
/// - Active (`is_active = true`)
|
||||
/// - Public (`is_public = true`)
|
||||
/// - Currently available (within availability window if set)
|
||||
pub async fn list_public_realm_props<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
realm_id: Uuid,
|
||||
) -> Result<Vec<PublicProp>, AppError> {
|
||||
let props = sqlx::query_as::<_, PublicProp>(
|
||||
r#"
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
asset_path,
|
||||
description
|
||||
FROM realm.props
|
||||
WHERE realm_id = $1
|
||||
AND is_active = true
|
||||
AND is_public = true
|
||||
AND (available_from IS NULL OR available_from <= now())
|
||||
AND (available_until IS NULL OR available_until > now())
|
||||
ORDER BY name ASC
|
||||
"#,
|
||||
)
|
||||
.bind(realm_id)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
Ok(props)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ pub async fn get_server_prop_by_id<'e>(
|
|||
is_transferable,
|
||||
is_portable,
|
||||
is_droppable,
|
||||
is_public,
|
||||
is_active,
|
||||
available_from,
|
||||
available_until,
|
||||
|
|
@ -114,17 +115,22 @@ pub async fn create_server_prop<'e>(
|
|||
(None, None, None)
|
||||
};
|
||||
|
||||
let is_droppable = req.droppable.unwrap_or(true);
|
||||
let is_public = req.public.unwrap_or(false);
|
||||
|
||||
let prop = sqlx::query_as::<_, ServerProp>(
|
||||
r#"
|
||||
INSERT INTO server.props (
|
||||
name, slug, description, tags, asset_path,
|
||||
default_layer, default_emotion, default_position,
|
||||
is_droppable, is_public,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6::server.avatar_layer, $7::server.emotion_state, $8,
|
||||
$9
|
||||
$9, $10,
|
||||
$11
|
||||
)
|
||||
RETURNING
|
||||
id,
|
||||
|
|
@ -141,6 +147,7 @@ pub async fn create_server_prop<'e>(
|
|||
is_transferable,
|
||||
is_portable,
|
||||
is_droppable,
|
||||
is_public,
|
||||
is_active,
|
||||
available_from,
|
||||
available_until,
|
||||
|
|
@ -157,6 +164,8 @@ pub async fn create_server_prop<'e>(
|
|||
.bind(&default_layer)
|
||||
.bind(&default_emotion)
|
||||
.bind(default_position)
|
||||
.bind(is_droppable)
|
||||
.bind(is_public)
|
||||
.bind(created_by)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
|
@ -198,17 +207,22 @@ pub async fn upsert_server_prop<'e>(
|
|||
(None, None, None)
|
||||
};
|
||||
|
||||
let is_droppable = req.droppable.unwrap_or(true);
|
||||
let is_public = req.public.unwrap_or(false);
|
||||
|
||||
let prop = sqlx::query_as::<_, ServerProp>(
|
||||
r#"
|
||||
INSERT INTO server.props (
|
||||
name, slug, description, tags, asset_path,
|
||||
default_layer, default_emotion, default_position,
|
||||
is_droppable, is_public,
|
||||
created_by
|
||||
)
|
||||
VALUES (
|
||||
$1, $2, $3, $4, $5,
|
||||
$6::server.avatar_layer, $7::server.emotion_state, $8,
|
||||
$9
|
||||
$9, $10,
|
||||
$11
|
||||
)
|
||||
ON CONFLICT (slug) DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
|
|
@ -218,6 +232,8 @@ pub async fn upsert_server_prop<'e>(
|
|||
default_layer = EXCLUDED.default_layer,
|
||||
default_emotion = EXCLUDED.default_emotion,
|
||||
default_position = EXCLUDED.default_position,
|
||||
is_droppable = EXCLUDED.is_droppable,
|
||||
is_public = EXCLUDED.is_public,
|
||||
updated_at = now()
|
||||
RETURNING
|
||||
id,
|
||||
|
|
@ -234,6 +250,7 @@ pub async fn upsert_server_prop<'e>(
|
|||
is_transferable,
|
||||
is_portable,
|
||||
is_droppable,
|
||||
is_public,
|
||||
is_active,
|
||||
available_from,
|
||||
available_until,
|
||||
|
|
@ -250,6 +267,8 @@ pub async fn upsert_server_prop<'e>(
|
|||
.bind(&default_layer)
|
||||
.bind(&default_emotion)
|
||||
.bind(default_position)
|
||||
.bind(is_droppable)
|
||||
.bind(is_public)
|
||||
.bind(created_by)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue