add: economy api
This commit is contained in:
parent
0a3ce3e9fe
commit
3c4ce1fae5
6 changed files with 51 additions and 16 deletions
|
@ -250,7 +250,8 @@ svg.icon {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg.icon.filled {
|
svg.icon.filled,
|
||||||
|
.filled svg.icon {
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
("class" "avatar shadow")
|
("class" "avatar shadow")
|
||||||
("loading" "lazy")
|
("loading" "lazy")
|
||||||
("style" "--size: {{ size }}"))
|
("style" "--size: {{ size }}"))
|
||||||
|
|
||||||
(text "{%- endmacro %} {% macro community_avatar(id, community=false, size=\"24px\") -%} {% if community -%}")
|
(text "{%- endmacro %} {% macro community_avatar(id, community=false, size=\"24px\") -%} {% if community -%}")
|
||||||
(img
|
(img
|
||||||
("src" "/api/v1/communities/{{ id }}/avatar")
|
("src" "/api/v1/communities/{{ id }}/avatar")
|
||||||
|
@ -14,7 +13,6 @@
|
||||||
("class" "avatar shadow")
|
("class" "avatar shadow")
|
||||||
("loading" "lazy")
|
("loading" "lazy")
|
||||||
("style" "--size: {{ size }}"))
|
("style" "--size: {{ size }}"))
|
||||||
|
|
||||||
(text "{% else %}")
|
(text "{% else %}")
|
||||||
(img
|
(img
|
||||||
("src" "/api/v1/communities/{{ id }}/avatar")
|
("src" "/api/v1/communities/{{ id }}/avatar")
|
||||||
|
@ -22,7 +20,6 @@
|
||||||
("class" "avatar shadow")
|
("class" "avatar shadow")
|
||||||
("loading" "lazy")
|
("loading" "lazy")
|
||||||
("style" "--size: {{ size }}"))
|
("style" "--size: {{ size }}"))
|
||||||
|
|
||||||
(text "{%- endif %} {%- endmacro %} {% macro banner(username, border_radius=\"var(--radius)\") -%}")
|
(text "{%- endif %} {%- endmacro %} {% macro banner(username, border_radius=\"var(--radius)\") -%}")
|
||||||
(img
|
(img
|
||||||
("title" "{{ username }}'s banner")
|
("title" "{{ username }}'s banner")
|
||||||
|
@ -31,21 +28,18 @@
|
||||||
("class" "banner shadow w_full")
|
("class" "banner shadow w_full")
|
||||||
("loading" "lazy")
|
("loading" "lazy")
|
||||||
("style" "border-radius: {{ border_radius }};"))
|
("style" "border-radius: {{ border_radius }};"))
|
||||||
|
|
||||||
(text "{%- endmacro %} {% macro community_banner(id, community=false) -%} {% if community %}")
|
(text "{%- endmacro %} {% macro community_banner(id, community=false) -%} {% if community %}")
|
||||||
(img
|
(img
|
||||||
("src" "/api/v1/communities/{{ id }}/banner")
|
("src" "/api/v1/communities/{{ id }}/banner")
|
||||||
("alt" "{{ community.title }}'s banner")
|
("alt" "{{ community.title }}'s banner")
|
||||||
("class" "banner shadow")
|
("class" "banner shadow")
|
||||||
("loading" "lazy"))
|
("loading" "lazy"))
|
||||||
|
|
||||||
(text "{% else %}")
|
(text "{% else %}")
|
||||||
(img
|
(img
|
||||||
("src" "/api/v1/communities/{{ id }}/banner")
|
("src" "/api/v1/communities/{{ id }}/banner")
|
||||||
("alt" "{{ id }}'s banner")
|
("alt" "{{ id }}'s banner")
|
||||||
("class" "banner shadow")
|
("class" "banner shadow")
|
||||||
("loading" "lazy"))
|
("loading" "lazy"))
|
||||||
|
|
||||||
(text "{%- endif %} {%- endmacro %} {% macro community_listing_card(community) -%}")
|
(text "{%- endif %} {%- endmacro %} {% macro community_listing_card(community) -%}")
|
||||||
(a
|
(a
|
||||||
("class" "card secondary w_full flex items_center gap_4")
|
("class" "card secondary w_full flex items_center gap_4")
|
||||||
|
@ -69,12 +63,10 @@
|
||||||
(b
|
(b
|
||||||
(text "{{ community.member_count }} "))
|
(text "{{ community.member_count }} "))
|
||||||
(text "members"))))
|
(text "members"))))
|
||||||
|
|
||||||
(text "{%- endmacro %} {% macro username(user) -%}")
|
(text "{%- endmacro %} {% macro username(user) -%}")
|
||||||
(div
|
(div
|
||||||
("style" "display: contents")
|
("style" "display: contents")
|
||||||
(text "{% if user.settings.display_name -%} {{ user.settings.display_name }} {% else %} {{ user.username }} {%- endif %}"))
|
(text "{% if user.settings.display_name -%} {{ user.settings.display_name }} {% else %} {{ user.username }} {%- endif %}"))
|
||||||
|
|
||||||
(text "{%- endmacro %} {% macro likes(id, asset_type, likes=0, dislikes=0, secondary=false, disable_dislikes=false) -%}")
|
(text "{%- endmacro %} {% macro likes(id, asset_type, likes=0, dislikes=0, secondary=false, disable_dislikes=false) -%}")
|
||||||
(button
|
(button
|
||||||
("title" "Like")
|
("title" "Like")
|
||||||
|
@ -85,7 +77,6 @@
|
||||||
(span
|
(span
|
||||||
(text "{{ likes }}"))
|
(text "{{ likes }}"))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
|
|
||||||
(text "{% if not user or not user.settings.hide_dislikes and not disable_dislikes -%}")
|
(text "{% if not user or not user.settings.hide_dislikes and not disable_dislikes -%}")
|
||||||
(button
|
(button
|
||||||
("title" "Dislike")
|
("title" "Dislike")
|
||||||
|
@ -96,15 +87,21 @@
|
||||||
(span
|
(span
|
||||||
(text "{{ dislikes }}"))
|
(text "{{ dislikes }}"))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
|
|
||||||
(text "{%- endif %} {%- endmacro %} {% macro full_username(user) -%} {% if user and user.username -%}")
|
(text "{%- endif %} {%- endmacro %} {% macro full_username(user) -%} {% if user and user.username -%}")
|
||||||
(div
|
(div
|
||||||
("class" "flex items_center")
|
("class" "flex items_center")
|
||||||
(a
|
(a
|
||||||
("href" "/@{{ user.username }}")
|
("href" "/@{{ user.username }}")
|
||||||
("class" "flush")
|
("class" "flush flex gap_1")
|
||||||
("style" "font-weight: 600")
|
("style" "font-weight: 600")
|
||||||
("target" "_top")
|
("target" "_top")
|
||||||
|
(text "{% if user.settings.private_profile -%}")
|
||||||
|
(span
|
||||||
|
("title" "Private")
|
||||||
|
("class" "flex items_center")
|
||||||
|
(icon (text "lock")))
|
||||||
|
(text "{%- endif %}")
|
||||||
|
|
||||||
(text "{% if user.permissions|has_banned -%}")
|
(text "{% if user.permissions|has_banned -%}")
|
||||||
(del ("class" "fade") (text "{{ self::username(user=user) }}"))
|
(del ("class" "fade") (text "{{ self::username(user=user) }}"))
|
||||||
(text "{% else %}")
|
(text "{% else %}")
|
||||||
|
@ -134,7 +131,6 @@
|
||||||
("style" "display: contents")
|
("style" "display: contents")
|
||||||
(text "{{ self::post(post=post, owner=owner, secondary=secondary, community=community, show_community=show_community, can_manage_post=can_manage_post, repost=repost, expect_repost=true) }}"))
|
(text "{{ self::post(post=post, owner=owner, secondary=secondary, community=community, show_community=show_community, can_manage_post=can_manage_post, repost=repost, expect_repost=true) }}"))
|
||||||
(text "{%- endmacro %}")
|
(text "{%- endmacro %}")
|
||||||
|
|
||||||
(text "{% macro post_info(post, community) -%}")
|
(text "{% macro post_info(post, community) -%}")
|
||||||
; info about the post: edited, date, etc.
|
; info about the post: edited, date, etc.
|
||||||
(text "{% if post.context.edited != 0 -%}")
|
(text "{% if post.context.edited != 0 -%}")
|
||||||
|
@ -200,7 +196,6 @@
|
||||||
(text "{{ icon \"trash-2\" }}"))
|
(text "{{ icon \"trash-2\" }}"))
|
||||||
(text "{%- endif %}")
|
(text "{%- endif %}")
|
||||||
(text "{%- endmacro %}")
|
(text "{%- endmacro %}")
|
||||||
|
|
||||||
(text "{% macro post_buttons_box(post, community, owner, can_manage_post, show_comments=true) -%}")
|
(text "{% macro post_buttons_box(post, community, owner, can_manage_post, show_comments=true) -%}")
|
||||||
(div
|
(div
|
||||||
("class" "flex justify_between items_center gap_2 w_full")
|
("class" "flex justify_between items_center gap_2 w_full")
|
||||||
|
|
28
crates/app/src/routes/api/v1/economy.rs
Normal file
28
crates/app/src/routes/api/v1/economy.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use crate::{get_user_from_token, State, cookie::CookieJar};
|
||||||
|
use axum::{response::IntoResponse, Extension, Json};
|
||||||
|
use tetratto_core::model::{economy::CoinTransfer, oauth, ApiReturn, Error};
|
||||||
|
use super::CreateCoinTransfer;
|
||||||
|
|
||||||
|
pub async fn create_request(
|
||||||
|
jar: CookieJar,
|
||||||
|
Extension(data): Extension<State>,
|
||||||
|
Json(req): Json<CreateCoinTransfer>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let data = &(data.read().await).0;
|
||||||
|
let user = match get_user_from_token!(jar, data, oauth::AppScope::UserSendCoins) {
|
||||||
|
Some(ua) => ua,
|
||||||
|
None => return Json(Error::NotAllowed.into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
match data
|
||||||
|
.create_transfer(CoinTransfer::new(user.id, req.receiver, req.amount))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(s) => Json(ApiReturn {
|
||||||
|
ok: true,
|
||||||
|
message: "Stack created".to_string(),
|
||||||
|
payload: s.id.to_string(),
|
||||||
|
}),
|
||||||
|
Err(e) => Json(e.into()),
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ pub mod auth;
|
||||||
pub mod channels;
|
pub mod channels;
|
||||||
pub mod communities;
|
pub mod communities;
|
||||||
pub mod domains;
|
pub mod domains;
|
||||||
|
pub mod economy;
|
||||||
pub mod journals;
|
pub mod journals;
|
||||||
pub mod letters;
|
pub mod letters;
|
||||||
pub mod notes;
|
pub mod notes;
|
||||||
|
@ -705,6 +706,8 @@ pub fn routes() -> Router {
|
||||||
.route("/letters/{id}/read", post(letters::add_read_request))
|
.route("/letters/{id}/read", post(letters::add_read_request))
|
||||||
.route("/letters/sent", get(letters::list_sent_request))
|
.route("/letters/sent", get(letters::list_sent_request))
|
||||||
.route("/letters/received", get(letters::list_received_request))
|
.route("/letters/received", get(letters::list_received_request))
|
||||||
|
// economy
|
||||||
|
.route("/transfers", post(economy::create_request))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lw_routes() -> Router {
|
pub fn lw_routes() -> Router {
|
||||||
|
@ -1212,3 +1215,9 @@ pub struct CreateLetter {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub replying_to: String,
|
pub replying_to: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CreateCoinTransfer {
|
||||||
|
pub receiver: usize,
|
||||||
|
pub amount: i32,
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{auto_method, DataManager};
|
||||||
use oiseau::{cache::Cache, execute, get, params, query_rows, PostgresRow};
|
use oiseau::{cache::Cache, execute, get, params, query_rows, PostgresRow};
|
||||||
|
|
||||||
impl DataManager {
|
impl DataManager {
|
||||||
/// Get a [`Letter`] from an SQL row.
|
/// Get a [`CoinTransfer`] from an SQL row.
|
||||||
pub(crate) fn get_transfer_from_row(x: &PostgresRow) -> CoinTransfer {
|
pub(crate) fn get_transfer_from_row(x: &PostgresRow) -> CoinTransfer {
|
||||||
CoinTransfer {
|
CoinTransfer {
|
||||||
id: get!(x->0(i64)) as usize,
|
id: get!(x->0(i64)) as usize,
|
||||||
|
@ -51,7 +51,7 @@ impl DataManager {
|
||||||
/// Create a new transfer in the database.
|
/// Create a new transfer in the database.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// * `data` - a mock [`Letter`] object to insert
|
/// * `data` - a mock [`CoinTransfer`] object to insert
|
||||||
pub async fn create_transfer(&self, data: CoinTransfer) -> Result<CoinTransfer> {
|
pub async fn create_transfer(&self, data: CoinTransfer) -> Result<CoinTransfer> {
|
||||||
// check values
|
// check values
|
||||||
let mut sender = self.get_user_by_id(data.sender).await?;
|
let mut sender = self.get_user_by_id(data.sender).await?;
|
||||||
|
|
|
@ -106,6 +106,8 @@ pub enum AppScope {
|
||||||
UserCreateProducts,
|
UserCreateProducts,
|
||||||
/// Create letters on behalf of the user.
|
/// Create letters on behalf of the user.
|
||||||
UserCreateLetters,
|
UserCreateLetters,
|
||||||
|
/// Send coins on behalf of the user.
|
||||||
|
UserSendCoins,
|
||||||
/// Delete posts owned by the user.
|
/// Delete posts owned by the user.
|
||||||
UserDeletePosts,
|
UserDeletePosts,
|
||||||
/// Delete messages owned by the user.
|
/// Delete messages owned by the user.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue