},
traits::Crud,
};
-use lemmy_db_views::structs::SiteView;
+use lemmy_db_views::structs::{CustomEmojiView, SiteView};
use lemmy_db_views_actor::structs::PersonView;
use lemmy_utils::{error::LemmyError, version, ConnectionId};
let all_languages = Language::read_all(context.pool()).await?;
let discussion_languages = SiteLanguage::read_local(context.pool()).await?;
- let taglines_res = Tagline::get_all(context.pool(), site_view.local_site.id).await?;
- let taglines = taglines_res.is_empty().then_some(taglines_res);
+ let taglines = Tagline::get_all(context.pool(), site_view.local_site.id).await?;
+ let custom_emojis = CustomEmojiView::get_all(context.pool(), site_view.local_site.id).await?;
Ok(GetSiteResponse {
site_view,
all_languages,
discussion_languages,
taglines,
+ custom_emojis,
})
}
}
--- /dev/null
+use crate::sensitive::Sensitive;
+use lemmy_db_schema::newtypes::CustomEmojiId;
+use lemmy_db_views::structs::CustomEmojiView;
+use serde::{Deserialize, Serialize};
+use url::Url;
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CreateCustomEmoji {
+ pub category: String,
+ pub shortcode: String,
+ pub image_url: Url,
+ pub alt_text: String,
+ pub keywords: Vec<String>,
+ pub auth: Sensitive<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct EditCustomEmoji {
+ pub id: CustomEmojiId,
+ pub category: String,
+ pub image_url: Url,
+ pub alt_text: String,
+ pub keywords: Vec<String>,
+ pub auth: Sensitive<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone, Default)]
+pub struct DeleteCustomEmoji {
+ pub id: CustomEmojiId,
+ pub auth: Sensitive<String>,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct DeleteCustomEmojiResponse {
+ pub id: CustomEmojiId,
+ pub success: bool,
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CustomEmojiResponse {
+ pub custom_emoji: CustomEmojiView,
+}
pub mod community;
#[cfg(feature = "full")]
pub mod context;
+pub mod custom_emoji;
pub mod person;
pub mod post;
pub mod private_message;
};
use lemmy_db_views::structs::{
CommentView,
+ CustomEmojiView,
LocalUserView,
PostView,
RegistrationApplicationView,
pub federated_instances: Option<FederatedInstances>, // Federation may be disabled
pub all_languages: Vec<Language>,
pub discussion_languages: Vec<LanguageId>,
- pub taglines: Option<Vec<Tagline>>,
+ pub taglines: Vec<Tagline>,
+ pub custom_emojis: Vec<CustomEmojiView>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
GetPrivateMessages,
EditPrivateMessage,
DeletePrivateMessage,
+ //Emojis
+ CreateCustomEmoji,
+ EditCustomEmoji,
+ DeleteCustomEmoji,
}
#[derive(EnumString, Display, Debug, Clone)]
--- /dev/null
+use crate::PerformCrud;
+use actix_web::web::Data;
+use lemmy_api_common::{
+ context::LemmyContext,
+ custom_emoji::{CreateCustomEmoji, CustomEmojiResponse},
+ utils::{get_local_user_view_from_jwt, is_admin},
+};
+use lemmy_db_schema::source::{
+ custom_emoji::{CustomEmoji, CustomEmojiInsertForm},
+ custom_emoji_keyword::{CustomEmojiKeyword, CustomEmojiKeywordInsertForm},
+ local_site::LocalSite,
+};
+use lemmy_db_views::structs::CustomEmojiView;
+use lemmy_utils::{error::LemmyError, ConnectionId};
+
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for CreateCustomEmoji {
+ type Response = CustomEmojiResponse;
+
+ #[tracing::instrument(skip(self, context, _websocket_id))]
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<CustomEmojiResponse, LemmyError> {
+ let data: &CreateCustomEmoji = self;
+ let local_user_view =
+ get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+ let local_site = LocalSite::read(context.pool()).await?;
+ // Make sure user is an admin
+ is_admin(&local_user_view)?;
+
+ let emoji_form = CustomEmojiInsertForm::builder()
+ .local_site_id(local_site.id)
+ .shortcode(data.shortcode.to_lowercase().trim().to_string())
+ .alt_text(data.alt_text.to_string())
+ .category(data.category.to_string())
+ .image_url(data.clone().image_url.into())
+ .build();
+ let emoji = CustomEmoji::create(context.pool(), &emoji_form).await?;
+ let mut keywords = vec![];
+ for keyword in &data.keywords {
+ let keyword_form = CustomEmojiKeywordInsertForm::builder()
+ .custom_emoji_id(emoji.id)
+ .keyword(keyword.to_lowercase().trim().to_string())
+ .build();
+ keywords.push(keyword_form);
+ }
+ CustomEmojiKeyword::create(context.pool(), keywords).await?;
+ let view = CustomEmojiView::get(context.pool(), emoji.id).await?;
+ Ok(CustomEmojiResponse { custom_emoji: view })
+ }
+}
--- /dev/null
+use crate::PerformCrud;
+use actix_web::web::Data;
+use lemmy_api_common::{
+ context::LemmyContext,
+ custom_emoji::{DeleteCustomEmoji, DeleteCustomEmojiResponse},
+ utils::{get_local_user_view_from_jwt, is_admin},
+};
+use lemmy_db_schema::source::custom_emoji::CustomEmoji;
+use lemmy_utils::{error::LemmyError, ConnectionId};
+
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for DeleteCustomEmoji {
+ type Response = DeleteCustomEmojiResponse;
+
+ #[tracing::instrument(skip(self, context, _websocket_id))]
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<DeleteCustomEmojiResponse, LemmyError> {
+ let data: &DeleteCustomEmoji = self;
+ let local_user_view =
+ get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+ // Make sure user is an admin
+ is_admin(&local_user_view)?;
+ CustomEmoji::delete(context.pool(), data.id).await?;
+ Ok(DeleteCustomEmojiResponse {
+ id: data.id,
+ success: true,
+ })
+ }
+}
--- /dev/null
+mod create;
+mod delete;
+mod update;
--- /dev/null
+use crate::PerformCrud;
+use actix_web::web::Data;
+use lemmy_api_common::{
+ context::LemmyContext,
+ custom_emoji::{CustomEmojiResponse, EditCustomEmoji},
+ utils::{get_local_user_view_from_jwt, is_admin},
+};
+use lemmy_db_schema::source::{
+ custom_emoji::{CustomEmoji, CustomEmojiUpdateForm},
+ custom_emoji_keyword::{CustomEmojiKeyword, CustomEmojiKeywordInsertForm},
+ local_site::LocalSite,
+};
+use lemmy_db_views::structs::CustomEmojiView;
+use lemmy_utils::{error::LemmyError, ConnectionId};
+
+#[async_trait::async_trait(?Send)]
+impl PerformCrud for EditCustomEmoji {
+ type Response = CustomEmojiResponse;
+
+ #[tracing::instrument(skip(self, context, _websocket_id))]
+ async fn perform(
+ &self,
+ context: &Data<LemmyContext>,
+ _websocket_id: Option<ConnectionId>,
+ ) -> Result<CustomEmojiResponse, LemmyError> {
+ let data: &EditCustomEmoji = self;
+ let local_user_view =
+ get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
+
+ let local_site = LocalSite::read(context.pool()).await?;
+ // Make sure user is an admin
+ is_admin(&local_user_view)?;
+
+ let emoji_form = CustomEmojiUpdateForm::builder()
+ .local_site_id(local_site.id)
+ .alt_text(data.alt_text.to_string())
+ .category(data.category.to_string())
+ .image_url(data.clone().image_url.into())
+ .build();
+ let emoji = CustomEmoji::update(context.pool(), data.id, &emoji_form).await?;
+ CustomEmojiKeyword::delete(context.pool(), data.id).await?;
+ let mut keywords = vec![];
+ for keyword in &data.keywords {
+ let keyword_form = CustomEmojiKeywordInsertForm::builder()
+ .custom_emoji_id(emoji.id)
+ .keyword(keyword.to_lowercase().trim().to_string())
+ .build();
+ keywords.push(keyword_form);
+ }
+ CustomEmojiKeyword::create(context.pool(), keywords).await?;
+ let view = CustomEmojiView::get(context.pool(), emoji.id).await?;
+ Ok(CustomEmojiResponse { custom_emoji: view })
+ }
+}
mod comment;
mod community;
+mod custom_emoji;
mod post;
mod private_message;
mod site;
language::Language,
tagline::Tagline,
};
-use lemmy_db_views::structs::SiteView;
+use lemmy_db_views::structs::{CustomEmojiView, SiteView};
use lemmy_db_views_actor::structs::{
CommunityBlockView,
CommunityFollowerView,
let all_languages = Language::read_all(context.pool()).await?;
let discussion_languages = SiteLanguage::read_local(context.pool()).await?;
- let taglines_res = Tagline::get_all(context.pool(), site_view.local_site.id).await?;
- let taglines = (!taglines_res.is_empty()).then_some(taglines_res);
+ let taglines = Tagline::get_all(context.pool(), site_view.local_site.id).await?;
+ let custom_emojis = CustomEmojiView::get_all(context.pool(), site_view.local_site.id).await?;
Ok(GetSiteResponse {
site_view,
all_languages,
discussion_languages,
taglines,
+ custom_emojis,
})
}
}
ListCommunitiesResponse,
TransferCommunity,
},
+ custom_emoji::{
+ CreateCustomEmoji,
+ CustomEmojiResponse,
+ DeleteCustomEmoji,
+ DeleteCustomEmojiResponse,
+ EditCustomEmoji,
+ },
person::{
AddAdmin,
AddAdminResponse,
impl SendActivity for ResolveCommentReport {
type Response = CommentReportResponse;
}
+
+impl SendActivity for CreateCustomEmoji {
+ type Response = CustomEmojiResponse;
+}
+
+impl SendActivity for EditCustomEmoji {
+ type Response = CustomEmojiResponse;
+}
+
+impl SendActivity for DeleteCustomEmoji {
+ type Response = DeleteCustomEmojiResponse;
+}
--- /dev/null
+use crate::{
+ newtypes::CustomEmojiId,
+ schema::{
+ custom_emoji::dsl::custom_emoji,
+ custom_emoji_keyword::dsl::{custom_emoji_id, custom_emoji_keyword},
+ },
+ source::{
+ custom_emoji::{CustomEmoji, CustomEmojiInsertForm, CustomEmojiUpdateForm},
+ custom_emoji_keyword::{CustomEmojiKeyword, CustomEmojiKeywordInsertForm},
+ },
+ utils::{get_conn, DbPool},
+};
+use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
+use diesel_async::RunQueryDsl;
+
+impl CustomEmoji {
+ pub async fn create(pool: &DbPool, form: &CustomEmojiInsertForm) -> Result<Self, Error> {
+ let conn = &mut get_conn(pool).await?;
+ insert_into(custom_emoji)
+ .values(form)
+ .get_result::<Self>(conn)
+ .await
+ }
+ pub async fn update(
+ pool: &DbPool,
+ emoji_id: CustomEmojiId,
+ form: &CustomEmojiUpdateForm,
+ ) -> Result<Self, Error> {
+ let conn = &mut get_conn(pool).await?;
+ diesel::update(custom_emoji.find(emoji_id))
+ .set(form)
+ .get_result::<Self>(conn)
+ .await
+ }
+ pub async fn delete(pool: &DbPool, emoji_id: CustomEmojiId) -> Result<usize, Error> {
+ let conn = &mut get_conn(pool).await?;
+ diesel::delete(custom_emoji.find(emoji_id))
+ .execute(conn)
+ .await
+ }
+}
+
+impl CustomEmojiKeyword {
+ pub async fn create(
+ pool: &DbPool,
+ form: Vec<CustomEmojiKeywordInsertForm>,
+ ) -> Result<Vec<Self>, Error> {
+ let conn = &mut get_conn(pool).await?;
+ insert_into(custom_emoji_keyword)
+ .values(form)
+ .get_results::<Self>(conn)
+ .await
+ }
+ pub async fn delete(pool: &DbPool, emoji_id: CustomEmojiId) -> Result<usize, Error> {
+ let conn = &mut get_conn(pool).await?;
+ diesel::delete(custom_emoji_keyword.filter(custom_emoji_id.eq(emoji_id)))
+ .execute(conn)
+ .await
+ }
+}
pub mod comment_report;
pub mod community;
pub mod community_block;
+pub mod custom_emoji;
pub mod email_verification;
pub mod federation_allowlist;
pub mod federation_blocklist;
#[cfg_attr(feature = "full", derive(DieselNewType))]
pub struct LocalSiteId(i32);
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Default)]
+#[cfg_attr(feature = "full", derive(DieselNewType))]
+pub struct CustomEmojiId(i32);
+
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
#[cfg_attr(feature = "full", derive(AsExpression, FromSqlRow))]
}
}
+table! {
+ custom_emoji (id) {
+ id -> Int4,
+ local_site_id -> Int4,
+ shortcode -> Varchar,
+ image_url -> Text,
+ alt_text -> Text,
+ category -> Text,
+ published -> Timestamp,
+ updated -> Nullable<Timestamp>,
+ }
+}
+
+table! {
+ custom_emoji_keyword (id) {
+ id -> Int4,
+ custom_emoji_id -> Int4,
+ keyword -> Varchar,
+ }
+}
+
joinable!(person_block -> person (person_id));
joinable!(comment -> person (creator_id));
joinable!(local_site -> site (site_id));
joinable!(local_site_rate_limit -> local_site (local_site_id));
joinable!(tagline -> local_site (local_site_id));
+joinable!(custom_emoji -> local_site (local_site_id));
+joinable!(custom_emoji_keyword -> custom_emoji (custom_emoji_id));
allow_tables_to_appear_in_same_query!(
activity,
federation_blocklist,
local_site,
local_site_rate_limit,
- person_follower
+ person_follower,
+ custom_emoji,
+ custom_emoji_keyword,
);
--- /dev/null
+use crate::newtypes::{CustomEmojiId, DbUrl, LocalSiteId};
+#[cfg(feature = "full")]
+use crate::schema::custom_emoji;
+use serde::{Deserialize, Serialize};
+use typed_builder::TypedBuilder;
+
+#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", diesel(table_name = custom_emoji))]
+#[cfg_attr(
+ feature = "full",
+ diesel(belongs_to(crate::source::local_site::LocalSite))
+)]
+pub struct CustomEmoji {
+ pub id: CustomEmojiId,
+ pub local_site_id: LocalSiteId,
+ pub shortcode: String,
+ pub image_url: DbUrl,
+ pub alt_text: String,
+ pub category: String,
+ pub published: chrono::NaiveDateTime,
+ pub updated: Option<chrono::NaiveDateTime>,
+}
+
+#[derive(Debug, Clone, TypedBuilder)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", diesel(table_name = custom_emoji))]
+pub struct CustomEmojiInsertForm {
+ pub local_site_id: LocalSiteId,
+ pub shortcode: String,
+ pub image_url: DbUrl,
+ pub alt_text: String,
+ pub category: String,
+}
+
+#[derive(Debug, Clone, TypedBuilder)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", diesel(table_name = custom_emoji))]
+pub struct CustomEmojiUpdateForm {
+ pub local_site_id: LocalSiteId,
+ pub image_url: DbUrl,
+ pub alt_text: String,
+ pub category: String,
+}
--- /dev/null
+use crate::newtypes::CustomEmojiId;
+#[cfg(feature = "full")]
+use crate::schema::custom_emoji_keyword;
+use serde::{Deserialize, Serialize};
+use typed_builder::TypedBuilder;
+
+#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
+#[cfg_attr(feature = "full", derive(Queryable, Associations, Identifiable))]
+#[cfg_attr(feature = "full", diesel(table_name = custom_emoji_keyword))]
+#[cfg_attr(
+ feature = "full",
+ diesel(belongs_to(crate::source::custom_emoji::CustomEmoji))
+)]
+pub struct CustomEmojiKeyword {
+ pub id: i32,
+ pub custom_emoji_id: CustomEmojiId,
+ pub keyword: String,
+}
+
+#[derive(Debug, Clone, TypedBuilder)]
+#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
+#[cfg_attr(feature = "full", diesel(table_name = custom_emoji_keyword))]
+pub struct CustomEmojiKeywordInsertForm {
+ pub custom_emoji_id: CustomEmojiId,
+ pub keyword: String,
+}
pub mod comment_report;
pub mod community;
pub mod community_block;
+pub mod custom_emoji;
+pub mod custom_emoji_keyword;
pub mod email_verification;
pub mod federation_allowlist;
pub mod federation_blocklist;
--- /dev/null
+use crate::structs::CustomEmojiView;
+use diesel::{result::Error, ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl};
+use diesel_async::RunQueryDsl;
+use lemmy_db_schema::{
+ newtypes::{CustomEmojiId, LocalSiteId},
+ schema::{custom_emoji, custom_emoji_keyword},
+ source::{custom_emoji::CustomEmoji, custom_emoji_keyword::CustomEmojiKeyword},
+ utils::{get_conn, DbPool},
+};
+use std::collections::HashMap;
+
+type CustomEmojiTuple = (CustomEmoji, Option<CustomEmojiKeyword>);
+
+impl CustomEmojiView {
+ pub async fn get(pool: &DbPool, emoji_id: CustomEmojiId) -> Result<Self, Error> {
+ let conn = &mut get_conn(pool).await?;
+ let emojis = custom_emoji::table
+ .find(emoji_id)
+ .left_join(
+ custom_emoji_keyword::table.on(custom_emoji_keyword::custom_emoji_id.eq(custom_emoji::id)),
+ )
+ .select((
+ custom_emoji::all_columns,
+ custom_emoji_keyword::all_columns.nullable(), // (or all the columns if you want)
+ ))
+ .load::<CustomEmojiTuple>(conn)
+ .await?;
+ if let Some(emoji) = CustomEmojiView::from_tuple_to_vec(emojis)
+ .into_iter()
+ .next()
+ {
+ Ok(emoji)
+ } else {
+ Err(diesel::result::Error::NotFound)
+ }
+ }
+
+ pub async fn get_all(pool: &DbPool, for_local_site_id: LocalSiteId) -> Result<Vec<Self>, Error> {
+ let conn = &mut get_conn(pool).await?;
+ let emojis = custom_emoji::table
+ .filter(custom_emoji::local_site_id.eq(for_local_site_id))
+ .left_join(
+ custom_emoji_keyword::table.on(custom_emoji_keyword::custom_emoji_id.eq(custom_emoji::id)),
+ )
+ .order(custom_emoji::category)
+ .then_order_by(custom_emoji::id)
+ .select((
+ custom_emoji::all_columns,
+ custom_emoji_keyword::all_columns.nullable(), // (or all the columns if you want)
+ ))
+ .load::<CustomEmojiTuple>(conn)
+ .await?;
+
+ Ok(CustomEmojiView::from_tuple_to_vec(emojis))
+ }
+
+ fn from_tuple_to_vec(items: Vec<CustomEmojiTuple>) -> Vec<Self> {
+ let mut result = Vec::new();
+ let mut hash: HashMap<CustomEmojiId, Vec<CustomEmojiKeyword>> = HashMap::new();
+ for item in &items {
+ let emoji_id: CustomEmojiId = item.0.id;
+ if let std::collections::hash_map::Entry::Vacant(e) = hash.entry(emoji_id) {
+ e.insert(Vec::new());
+ result.push(CustomEmojiView {
+ custom_emoji: item.0.clone(),
+ keywords: Vec::new(),
+ })
+ }
+ if let Some(item_keyword) = &item.1 {
+ if let Some(keywords) = hash.get_mut(&emoji_id) {
+ keywords.push(item_keyword.clone())
+ }
+ }
+ }
+ for emoji in &mut result {
+ if let Some(keywords) = hash.get_mut(&emoji.custom_emoji.id) {
+ emoji.keywords = keywords.clone();
+ }
+ }
+ result
+ }
+}
#[cfg(feature = "full")]
pub mod comment_view;
#[cfg(feature = "full")]
+pub mod custom_emoji_view;
+#[cfg(feature = "full")]
pub mod local_user_view;
#[cfg(feature = "full")]
pub mod post_report_view;
comment::Comment,
comment_report::CommentReport,
community::Community,
+ custom_emoji::CustomEmoji,
+ custom_emoji_keyword::CustomEmojiKeyword,
local_site::LocalSite,
local_site_rate_limit::LocalSiteRateLimit,
local_user::LocalUser,
pub local_site_rate_limit: LocalSiteRateLimit,
pub counts: SiteAggregates,
}
+#[derive(Debug, Serialize, Deserialize, Clone)]
+pub struct CustomEmojiView {
+ pub custom_emoji: CustomEmoji,
+ pub keywords: Vec<CustomEmojiKeyword>,
+}
restart: always
pictrs:
- image: asonix/pictrs:0.3.1
+ image: asonix/pictrs:0.4.0-beta.19
# this needs to match the pictrs url in lemmy.hjson
hostname: pictrs
# we can set options to pictrs like this, here we set max. image size and forced format for conversion
- PICTRS__API_KEY=API_KEY
- RUST_LOG=debug
- RUST_BACKTRACE=full
+ - PICTRS__MEDIA__VIDEO_CODEC=vp9
+ - PICTRS__MEDIA__GIF__MAX_WIDTH=256
+ - PICTRS__MEDIA__GIF__MAX_HEIGHT=256
+ - PICTRS__MEDIA__GIF__MAX_AREA=65536
+ - PICTRS__MEDIA__GIF__MAX_FRAME_COUNT=400
user: 991:991
volumes:
- ./volumes/pictrs:/mnt
pictrs:
restart: always
- image: asonix/pictrs:0.3.1
+ image: asonix/pictrs:0.4.0-beta.19
user: 991:991
volumes:
- ./volumes/pictrs_alpha:/mnt
--- /dev/null
+drop table custom_emoji_keyword;
+drop table custom_emoji;
\ No newline at end of file
--- /dev/null
+create table custom_emoji (
+ id serial primary key,
+ local_site_id int references local_site on update cascade on delete cascade not null,
+ shortcode varchar(128) not null UNIQUE,
+ image_url text not null UNIQUE,
+ alt_text text not null,
+ category text not null,
+ published timestamp without time zone default now() not null,
+ updated timestamp without time zone
+);
+
+create table custom_emoji_keyword (
+ id serial primary key,
+ custom_emoji_id int references custom_emoji on update cascade on delete cascade not null,
+ keyword varchar(128) not null,
+ UNIQUE (custom_emoji_id, keyword)
+);
+
+create index idx_custom_emoji_category on custom_emoji (id,category);
TransferCommunity,
},
context::LemmyContext,
+ custom_emoji::{CreateCustomEmoji, DeleteCustomEmoji, EditCustomEmoji},
person::{
AddAdmin,
BanPerson,
.route("/community", web::post().to(route_post::<PurgeCommunity>))
.route("/post", web::post().to(route_post::<PurgePost>))
.route("/comment", web::post().to(route_post::<PurgeComment>)),
+ )
+ .service(
+ web::scope("/custom_emoji")
+ .wrap(rate_limit.message())
+ .route("", web::post().to(route_post_crud::<CreateCustomEmoji>))
+ .route("", web::put().to(route_post_crud::<EditCustomEmoji>))
+ .route(
+ "/delete",
+ web::post().to(route_post_crud::<DeleteCustomEmoji>),
+ ),
),
);
}
TransferCommunity,
},
context::LemmyContext,
+ custom_emoji::{CreateCustomEmoji, DeleteCustomEmoji, EditCustomEmoji},
person::{
AddAdmin,
BanPerson,
UserOperationCrud::GetComment => {
do_websocket_operation_crud::<GetComment>(context, id, op, data).await
}
+ // Emojis
+ UserOperationCrud::CreateCustomEmoji => {
+ do_websocket_operation_crud::<CreateCustomEmoji>(context, id, op, data).await
+ }
+ UserOperationCrud::EditCustomEmoji => {
+ do_websocket_operation_crud::<EditCustomEmoji>(context, id, op, data).await
+ }
+ UserOperationCrud::DeleteCustomEmoji => {
+ do_websocket_operation_crud::<DeleteCustomEmoji>(context, id, op, data).await
+ }
}
}