mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-16 09:24:00 +00:00
Move websocket structs into lemmy_structs (ref #1115)
This commit is contained in:
parent
5c6258390c
commit
98c086abb9
44 changed files with 185 additions and 183 deletions
31
Cargo.lock
generated
31
Cargo.lock
generated
|
@ -1820,18 +1820,6 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lemmy_api_structs"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"actix-web",
|
|
||||||
"diesel",
|
|
||||||
"lemmy_db",
|
|
||||||
"lemmy_utils",
|
|
||||||
"log",
|
|
||||||
"serde 1.0.115",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_db"
|
name = "lemmy_db"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1893,9 +1881,9 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"lemmy_api_structs",
|
|
||||||
"lemmy_db",
|
"lemmy_db",
|
||||||
"lemmy_rate_limit",
|
"lemmy_rate_limit",
|
||||||
|
"lemmy_structs",
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"log",
|
"log",
|
||||||
"openssl",
|
"openssl",
|
||||||
|
@ -1907,13 +1895,28 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
"uuid 0.8.1",
|
"uuid 0.8.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lemmy_structs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"actix",
|
||||||
|
"actix-web",
|
||||||
|
"chrono",
|
||||||
|
"diesel",
|
||||||
|
"lemmy_db",
|
||||||
|
"lemmy_utils",
|
||||||
|
"log",
|
||||||
|
"serde 1.0.115",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_utils"
|
name = "lemmy_utils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -10,14 +10,14 @@ lto = true
|
||||||
members = [
|
members = [
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"lemmy_db",
|
"lemmy_db",
|
||||||
"lemmy_api_structs",
|
"lemmy_structs",
|
||||||
"lemmy_rate_limit",
|
"lemmy_rate_limit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lemmy_utils = { path = "./lemmy_utils" }
|
lemmy_utils = { path = "./lemmy_utils" }
|
||||||
lemmy_db = { path = "./lemmy_db" }
|
lemmy_db = { path = "./lemmy_db" }
|
||||||
lemmy_api_structs = { path = "./lemmy_api_structs" }
|
lemmy_structs = { path = "./lemmy_structs" }
|
||||||
lemmy_rate_limit = { path = "./lemmy_rate_limit" }
|
lemmy_rate_limit = { path = "./lemmy_rate_limit" }
|
||||||
diesel = "1.4.4"
|
diesel = "1.4.4"
|
||||||
diesel_migrations = "1.4.0"
|
diesel_migrations = "1.4.0"
|
||||||
|
@ -38,7 +38,6 @@ log = "0.4.0"
|
||||||
env_logger = "0.7.1"
|
env_logger = "0.7.1"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
strum = "0.19.2"
|
strum = "0.19.2"
|
||||||
strum_macros = "0.19.2"
|
|
||||||
jsonwebtoken = "7.0.1"
|
jsonwebtoken = "7.0.1"
|
||||||
lazy_static = "1.3.0"
|
lazy_static = "1.3.0"
|
||||||
rss = "1.9.0"
|
rss = "1.9.0"
|
||||||
|
|
|
@ -10,7 +10,7 @@ RUN cargo install --git https://github.com/romac/cargo-build-deps.git
|
||||||
WORKDIR /app/server
|
WORKDIR /app/server
|
||||||
RUN mkdir -p lemmy_db/src/ \
|
RUN mkdir -p lemmy_db/src/ \
|
||||||
lemmy_utils/src/ \
|
lemmy_utils/src/ \
|
||||||
lemmy_api_structs/src/ \
|
lemmy_structs/src/ \
|
||||||
lemmy_rate_limit/src/ \
|
lemmy_rate_limit/src/ \
|
||||||
lemmy
|
lemmy
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ RUN mkdir -p lemmy_db/src/ \
|
||||||
COPY Cargo.toml Cargo.lock ./
|
COPY Cargo.toml Cargo.lock ./
|
||||||
COPY lemmy_db/Cargo.toml ./lemmy_db/
|
COPY lemmy_db/Cargo.toml ./lemmy_db/
|
||||||
COPY lemmy_utils/Cargo.toml ./lemmy_utils/
|
COPY lemmy_utils/Cargo.toml ./lemmy_utils/
|
||||||
COPY lemmy_api_structs/Cargo.toml ./lemmy_api_structs/
|
COPY lemmy_structs/Cargo.toml ./lemmy_structs/
|
||||||
COPY lemmy_rate_limit/Cargo.toml ./lemmy_rate_limit/
|
COPY lemmy_rate_limit/Cargo.toml ./lemmy_rate_limit/
|
||||||
|
|
||||||
# Cache the deps
|
# Cache the deps
|
||||||
|
@ -28,7 +28,7 @@ RUN cargo build-deps
|
||||||
COPY src ./src/
|
COPY src ./src/
|
||||||
COPY lemmy_db/src ./lemmy_db/src/
|
COPY lemmy_db/src ./lemmy_db/src/
|
||||||
COPY lemmy_utils/src/ ./lemmy_utils/src/
|
COPY lemmy_utils/src/ ./lemmy_utils/src/
|
||||||
COPY lemmy_api_structs/src/ ./lemmy_api_structs/src/
|
COPY lemmy_structs/src/ ./lemmy_structs/src/
|
||||||
COPY lemmy_rate_limit/src/ ./lemmy_rate_limit/src/
|
COPY lemmy_rate_limit/src/ ./lemmy_rate_limit/src/
|
||||||
COPY migrations ./migrations/
|
COPY migrations ./migrations/
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ WORKDIR /app/server
|
||||||
COPY Cargo.toml Cargo.lock ./
|
COPY Cargo.toml Cargo.lock ./
|
||||||
COPY lemmy_db ./lemmy_db
|
COPY lemmy_db ./lemmy_db
|
||||||
COPY lemmy_utils ./lemmy_utils
|
COPY lemmy_utils ./lemmy_utils
|
||||||
COPY lemmy_api_structs ./lemmy_api_structs
|
COPY lemmy_structs ./lemmy_structs
|
||||||
COPY lemmy_rate_limit ./lemmy_rate_limit
|
COPY lemmy_rate_limit ./lemmy_rate_limit
|
||||||
RUN mkdir -p ./src/bin \
|
RUN mkdir -p ./src/bin \
|
||||||
&& echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
|
&& echo 'fn main() { println!("Dummy") }' > ./src/bin/main.rs
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lemmy_api_structs"
|
name = "lemmy_structs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Felix Ableitner <me@nutomic.com>"]
|
authors = ["Felix Ableitner <me@nutomic.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "lemmy_api_structs"
|
name = "lemmy_structs"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -15,3 +15,7 @@ serde = { version = "1.0.105", features = ["derive"] }
|
||||||
log = "0.4.0"
|
log = "0.4.0"
|
||||||
diesel = "1.4.4"
|
diesel = "1.4.4"
|
||||||
actix-web = { version = "3.0.0-beta.3", features = ["rustls"] }
|
actix-web = { version = "3.0.0-beta.3", features = ["rustls"] }
|
||||||
|
actix = "0.10.0"
|
||||||
|
strum = "0.19.2"
|
||||||
|
strum_macros = "0.19.2"
|
||||||
|
chrono = { version = "0.4.7", features = ["serde"] }
|
|
@ -1,13 +1,18 @@
|
||||||
|
extern crate actix;
|
||||||
extern crate actix_web;
|
extern crate actix_web;
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate strum_macros;
|
||||||
|
extern crate chrono;
|
||||||
|
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
pub mod community;
|
pub mod community;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
pub mod websocket;
|
||||||
|
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
|
@ -1,9 +1,72 @@
|
||||||
use crate::websocket::UserOperation;
|
use crate::{comment::CommentResponse, post::PostResponse};
|
||||||
use actix::{prelude::*, Recipient};
|
use actix::{prelude::*, Recipient};
|
||||||
use lemmy_api_structs::{comment::CommentResponse, post::PostResponse};
|
|
||||||
use lemmy_utils::{CommunityId, ConnectionId, IPAddr, PostId, UserId};
|
use lemmy_utils::{CommunityId, ConnectionId, IPAddr, PostId, UserId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(EnumString, ToString, Debug, Clone)]
|
||||||
|
pub enum UserOperation {
|
||||||
|
Login,
|
||||||
|
Register,
|
||||||
|
GetCaptcha,
|
||||||
|
CreateCommunity,
|
||||||
|
CreatePost,
|
||||||
|
ListCommunities,
|
||||||
|
ListCategories,
|
||||||
|
GetPost,
|
||||||
|
GetCommunity,
|
||||||
|
CreateComment,
|
||||||
|
EditComment,
|
||||||
|
DeleteComment,
|
||||||
|
RemoveComment,
|
||||||
|
MarkCommentAsRead,
|
||||||
|
SaveComment,
|
||||||
|
CreateCommentLike,
|
||||||
|
GetPosts,
|
||||||
|
CreatePostLike,
|
||||||
|
EditPost,
|
||||||
|
DeletePost,
|
||||||
|
RemovePost,
|
||||||
|
LockPost,
|
||||||
|
StickyPost,
|
||||||
|
SavePost,
|
||||||
|
EditCommunity,
|
||||||
|
DeleteCommunity,
|
||||||
|
RemoveCommunity,
|
||||||
|
FollowCommunity,
|
||||||
|
GetFollowedCommunities,
|
||||||
|
GetUserDetails,
|
||||||
|
GetReplies,
|
||||||
|
GetUserMentions,
|
||||||
|
MarkUserMentionAsRead,
|
||||||
|
GetModlog,
|
||||||
|
BanFromCommunity,
|
||||||
|
AddModToCommunity,
|
||||||
|
CreateSite,
|
||||||
|
EditSite,
|
||||||
|
GetSite,
|
||||||
|
AddAdmin,
|
||||||
|
BanUser,
|
||||||
|
Search,
|
||||||
|
MarkAllAsRead,
|
||||||
|
SaveUserSettings,
|
||||||
|
TransferCommunity,
|
||||||
|
TransferSite,
|
||||||
|
DeleteAccount,
|
||||||
|
PasswordReset,
|
||||||
|
PasswordChange,
|
||||||
|
CreatePrivateMessage,
|
||||||
|
EditPrivateMessage,
|
||||||
|
DeletePrivateMessage,
|
||||||
|
MarkPrivateMessageAsRead,
|
||||||
|
GetPrivateMessages,
|
||||||
|
UserJoin,
|
||||||
|
GetComments,
|
||||||
|
GetSiteConfig,
|
||||||
|
SaveSiteConfig,
|
||||||
|
PostJoin,
|
||||||
|
CommunityJoin,
|
||||||
|
}
|
||||||
|
|
||||||
/// Chat server sends this messages to session
|
/// Chat server sends this messages to session
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
|
@ -8,11 +8,15 @@ use crate::{
|
||||||
Perform,
|
Perform,
|
||||||
},
|
},
|
||||||
apub::{ApubLikeableType, ApubObjectType},
|
apub::{ApubLikeableType, ApubObjectType},
|
||||||
websocket::{messages::SendComment, UserOperation},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use lemmy_api_structs::{blocking, comment::*, send_local_notifs};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
comment::*,
|
||||||
|
send_local_notifs,
|
||||||
|
websocket::{SendComment, UserOperation},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::*,
|
comment::*,
|
||||||
comment_view::*,
|
comment_view::*,
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{get_user_from_jwt, get_user_from_jwt_opt, is_admin, is_mod_or_admin, Perform},
|
api::{get_user_from_jwt, get_user_from_jwt_opt, is_admin, is_mod_or_admin, Perform},
|
||||||
apub::ActorType,
|
apub::ActorType,
|
||||||
websocket::{
|
|
||||||
messages::{GetCommunityUsersOnline, JoinCommunityRoom, SendCommunityRoomMessage},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{blocking, community::*};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
community::*,
|
||||||
|
websocket::{
|
||||||
|
GetCommunityUsersOnline,
|
||||||
|
JoinCommunityRoom,
|
||||||
|
SendCommunityRoomMessage,
|
||||||
|
UserOperation,
|
||||||
|
},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::Comment,
|
comment::Comment,
|
||||||
comment_view::CommentQueryBuilder,
|
comment_view::CommentQueryBuilder,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{api::claims::Claims, DbPool, LemmyContext};
|
use crate::{api::claims::Claims, DbPool, LemmyContext};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::Community,
|
community::Community,
|
||||||
community_view::CommunityUserBanView,
|
community_view::CommunityUserBanView,
|
||||||
|
|
|
@ -2,14 +2,14 @@ use crate::{
|
||||||
api::{check_community_ban, get_user_from_jwt, get_user_from_jwt_opt, is_mod_or_admin, Perform},
|
api::{check_community_ban, get_user_from_jwt, get_user_from_jwt_opt, is_mod_or_admin, Perform},
|
||||||
apub::{ApubLikeableType, ApubObjectType},
|
apub::{ApubLikeableType, ApubObjectType},
|
||||||
fetch_iframely_and_pictrs_data,
|
fetch_iframely_and_pictrs_data,
|
||||||
websocket::{
|
|
||||||
messages::{GetPostUsersOnline, JoinPostRoom, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use lemmy_api_structs::{blocking, post::*};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
post::*,
|
||||||
|
websocket::{GetPostUsersOnline, JoinPostRoom, SendPost, UserOperation},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment_view::*,
|
comment_view::*,
|
||||||
community_view::*,
|
community_view::*,
|
||||||
|
|
|
@ -2,15 +2,16 @@ use crate::{
|
||||||
api::{get_user_from_jwt, get_user_from_jwt_opt, is_admin, Perform},
|
api::{get_user_from_jwt, get_user_from_jwt_opt, is_admin, Perform},
|
||||||
apub::fetcher::search_by_apub_id,
|
apub::fetcher::search_by_apub_id,
|
||||||
version,
|
version,
|
||||||
websocket::{
|
|
||||||
messages::{GetUsersOnline, SendAllMessage},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{blocking, site::*, user::Register};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
site::*,
|
||||||
|
user::Register,
|
||||||
|
websocket::{GetUsersOnline, SendAllMessage, UserOperation},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
category::*,
|
category::*,
|
||||||
comment_view::*,
|
comment_view::*,
|
||||||
|
|
|
@ -2,10 +2,6 @@ use crate::{
|
||||||
api::{claims::Claims, get_user_from_jwt, get_user_from_jwt_opt, is_admin, Perform},
|
api::{claims::Claims, get_user_from_jwt, get_user_from_jwt_opt, is_admin, Perform},
|
||||||
apub::ApubObjectType,
|
apub::ApubObjectType,
|
||||||
captcha_espeak_wav_base64,
|
captcha_espeak_wav_base64,
|
||||||
websocket::{
|
|
||||||
messages::{CaptchaItem, CheckCaptcha, JoinUserRoom, SendAllMessage, SendUserRoomMessage},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix_web::web::Data;
|
use actix_web::web::Data;
|
||||||
|
@ -13,7 +9,18 @@ use anyhow::Context;
|
||||||
use bcrypt::verify;
|
use bcrypt::verify;
|
||||||
use captcha::{gen, Difficulty};
|
use captcha::{gen, Difficulty};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use lemmy_api_structs::{blocking, user::*};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
user::*,
|
||||||
|
websocket::{
|
||||||
|
CaptchaItem,
|
||||||
|
CheckCaptcha,
|
||||||
|
JoinUserRoom,
|
||||||
|
SendAllMessage,
|
||||||
|
SendUserRoomMessage,
|
||||||
|
UserOperation,
|
||||||
|
},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::*,
|
comment::*,
|
||||||
comment_view::*,
|
comment_view::*,
|
||||||
|
|
|
@ -40,7 +40,7 @@ use activitystreams::{
|
||||||
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
use actix_web::{body::Body, web, web::Path, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
community::Community,
|
community::Community,
|
||||||
|
|
|
@ -38,7 +38,7 @@ use activitystreams_ext::Ext2;
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{Community, CommunityForm},
|
community::{Community, CommunityForm},
|
||||||
community_view::{CommunityFollowerView, CommunityModeratorView},
|
community_view::{CommunityFollowerView, CommunityModeratorView},
|
||||||
|
|
|
@ -15,7 +15,7 @@ use activitystreams::{base::BaseExt, collection::OrderedCollection, object::Note
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use diesel::result::Error::NotFound;
|
use diesel::result::Error::NotFound;
|
||||||
use lemmy_api_structs::{blocking, site::SearchResponse};
|
use lemmy_structs::{blocking, site::SearchResponse};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
|
|
|
@ -9,20 +9,17 @@ use crate::{
|
||||||
FromApub,
|
FromApub,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Create, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Create, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{
|
use lemmy_structs::{
|
||||||
blocking,
|
blocking,
|
||||||
comment::CommentResponse,
|
comment::CommentResponse,
|
||||||
post::PostResponse,
|
post::PostResponse,
|
||||||
send_local_notifs,
|
send_local_notifs,
|
||||||
|
websocket::{SendComment, SendPost, UserOperation},
|
||||||
};
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
|
|
@ -11,20 +11,17 @@ use crate::{
|
||||||
GroupExt,
|
GroupExt,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendCommunityRoomMessage, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Delete, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{
|
use lemmy_structs::{
|
||||||
blocking,
|
blocking,
|
||||||
comment::CommentResponse,
|
comment::CommentResponse,
|
||||||
community::CommunityResponse,
|
community::CommunityResponse,
|
||||||
post::PostResponse,
|
post::PostResponse,
|
||||||
|
websocket::{SendComment, SendCommunityRoomMessage, SendPost, UserOperation},
|
||||||
};
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
|
|
@ -9,16 +9,17 @@ use crate::{
|
||||||
FromApub,
|
FromApub,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Dislike, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Dislike, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{blocking, comment::CommentResponse, post::PostResponse};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
comment::CommentResponse,
|
||||||
|
post::PostResponse,
|
||||||
|
websocket::{SendComment, SendPost, UserOperation},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{CommentForm, CommentLike, CommentLikeForm},
|
comment::{CommentForm, CommentLike, CommentLikeForm},
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
|
|
|
@ -9,16 +9,17 @@ use crate::{
|
||||||
FromApub,
|
FromApub,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Like, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Like, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{blocking, comment::CommentResponse, post::PostResponse};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
comment::CommentResponse,
|
||||||
|
post::PostResponse,
|
||||||
|
websocket::{SendComment, SendPost, UserOperation},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{CommentForm, CommentLike, CommentLikeForm},
|
comment::{CommentForm, CommentLike, CommentLikeForm},
|
||||||
comment_view::CommentView,
|
comment_view::CommentView,
|
||||||
|
|
|
@ -12,20 +12,17 @@ use crate::{
|
||||||
GroupExt,
|
GroupExt,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendCommunityRoomMessage, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Remove, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use lemmy_api_structs::{
|
use lemmy_structs::{
|
||||||
blocking,
|
blocking,
|
||||||
comment::CommentResponse,
|
comment::CommentResponse,
|
||||||
community::CommunityResponse,
|
community::CommunityResponse,
|
||||||
post::PostResponse,
|
post::PostResponse,
|
||||||
|
websocket::{SendComment, SendCommunityRoomMessage, SendPost, UserOperation},
|
||||||
};
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
|
|
@ -11,10 +11,6 @@ use crate::{
|
||||||
GroupExt,
|
GroupExt,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendCommunityRoomMessage, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -25,11 +21,12 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use lemmy_api_structs::{
|
use lemmy_structs::{
|
||||||
blocking,
|
blocking,
|
||||||
comment::CommentResponse,
|
comment::CommentResponse,
|
||||||
community::CommunityResponse,
|
community::CommunityResponse,
|
||||||
post::PostResponse,
|
post::PostResponse,
|
||||||
|
websocket::{SendComment, SendCommunityRoomMessage, SendPost, UserOperation},
|
||||||
};
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm, CommentLike},
|
comment::{Comment, CommentForm, CommentLike},
|
||||||
|
|
|
@ -10,20 +10,17 @@ use crate::{
|
||||||
FromApub,
|
FromApub,
|
||||||
PageExt,
|
PageExt,
|
||||||
},
|
},
|
||||||
websocket::{
|
|
||||||
messages::{SendComment, SendPost},
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
|
use activitystreams::{activity::Update, base::AnyBase, object::Note, prelude::*};
|
||||||
use actix_web::HttpResponse;
|
use actix_web::HttpResponse;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{
|
use lemmy_structs::{
|
||||||
blocking,
|
blocking,
|
||||||
comment::CommentResponse,
|
comment::CommentResponse,
|
||||||
post::PostResponse,
|
post::PostResponse,
|
||||||
send_local_notifs,
|
send_local_notifs,
|
||||||
|
websocket::{SendComment, SendPost, UserOperation},
|
||||||
};
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment::{Comment, CommentForm},
|
comment::{Comment, CommentForm},
|
||||||
|
|
|
@ -15,7 +15,7 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::{
|
||||||
insert_activity,
|
insert_activity,
|
||||||
FromApub,
|
FromApub,
|
||||||
},
|
},
|
||||||
websocket::{messages::SendUserRoomMessage, UserOperation},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
|
@ -17,7 +16,11 @@ use activitystreams::{
|
||||||
};
|
};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::{blocking, user::PrivateMessageResponse};
|
use lemmy_structs::{
|
||||||
|
blocking,
|
||||||
|
user::PrivateMessageResponse,
|
||||||
|
websocket::{SendUserRoomMessage, UserOperation},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{CommunityFollower, CommunityFollowerForm},
|
community::{CommunityFollower, CommunityFollowerForm},
|
||||||
naive_now,
|
naive_now,
|
||||||
|
|
|
@ -32,7 +32,7 @@ use activitystreams_ext::{Ext1, Ext2};
|
||||||
use actix_web::{body::Body, HttpResponse};
|
use actix_web::{body::Body, HttpResponse};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{activity::do_insert_activity, user::User_};
|
use lemmy_db::{activity::do_insert_activity, user::User_};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
apub::get_apub_protocol_string,
|
apub::get_apub_protocol_string,
|
||||||
|
|
|
@ -35,7 +35,7 @@ use activitystreams::{
|
||||||
use activitystreams_ext::Ext1;
|
use activitystreams_ext::Ext1;
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::Community,
|
community::Community,
|
||||||
post::{Post, PostForm},
|
post::{Post, PostForm},
|
||||||
|
|
|
@ -27,7 +27,7 @@ use activitystreams::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
private_message::{PrivateMessage, PrivateMessageForm},
|
private_message::{PrivateMessage, PrivateMessageForm},
|
||||||
user::User_,
|
user::User_,
|
||||||
|
|
|
@ -27,7 +27,7 @@ use activitystreams::{
|
||||||
use activitystreams_ext::Ext1;
|
use activitystreams_ext::Ext1;
|
||||||
use actix_web::{body::Body, web, HttpResponse};
|
use actix_web::{body::Body, web, HttpResponse};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
naive_now,
|
naive_now,
|
||||||
user::{UserForm, User_},
|
user::{UserForm, User_},
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate strum_macros;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate actix;
|
extern crate actix;
|
||||||
extern crate actix_web;
|
extern crate actix_web;
|
||||||
|
|
|
@ -16,7 +16,7 @@ use diesel::{
|
||||||
PgConnection,
|
PgConnection,
|
||||||
};
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::get_database_url_from_env;
|
use lemmy_db::get_database_url_from_env;
|
||||||
use lemmy_rate_limit::{rate_limiter::RateLimiter, RateLimit};
|
use lemmy_rate_limit::{rate_limiter::RateLimiter, RateLimit};
|
||||||
use lemmy_server::{
|
use lemmy_server::{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{api::Perform, LemmyContext};
|
use crate::{api::Perform, LemmyContext};
|
||||||
use actix_web::{error::ErrorBadRequest, *};
|
use actix_web::{error::ErrorBadRequest, *};
|
||||||
use lemmy_api_structs::{comment::*, community::*, post::*, site::*, user::*};
|
use lemmy_structs::{comment::*, community::*, post::*, site::*, user::*};
|
||||||
use lemmy_rate_limit::RateLimit;
|
use lemmy_rate_limit::RateLimit;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use actix_web::{error::ErrorBadRequest, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
comment_view::{ReplyQueryBuilder, ReplyView},
|
comment_view::{ReplyQueryBuilder, ReplyView},
|
||||||
community::Community,
|
community::Community,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{version, LemmyContext};
|
use crate::{version, LemmyContext};
|
||||||
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
use actix_web::{body::Body, error::ErrorBadRequest, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::site_view::SiteView;
|
use lemmy_db::site_view::SiteView;
|
||||||
use lemmy_utils::{apub::get_apub_protocol_string, settings::Settings, LemmyError};
|
use lemmy_utils::{apub::get_apub_protocol_string, settings::Settings, LemmyError};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::LemmyContext;
|
use crate::LemmyContext;
|
||||||
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
use actix_web::{error::ErrorBadRequest, web::Query, *};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use lemmy_api_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_db::{community::Community, user::User_};
|
use lemmy_db::{community::Community, user::User_};
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
use crate::{
|
use crate::{websocket::chat_server::ChatServer, LemmyContext};
|
||||||
websocket::{
|
|
||||||
chat_server::ChatServer,
|
|
||||||
messages::{Connect, Disconnect, StandardMessage, WSMessage},
|
|
||||||
},
|
|
||||||
LemmyContext,
|
|
||||||
};
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use actix_web::*;
|
use actix_web::*;
|
||||||
use actix_web_actors::ws;
|
use actix_web_actors::ws;
|
||||||
|
use lemmy_structs::websocket::{Connect, Disconnect, StandardMessage, WSMessage};
|
||||||
use lemmy_utils::utils::get_ip;
|
use lemmy_utils::utils::get_ip;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
websocket::{
|
websocket::handlers::{do_user_operation, to_json_string, Args},
|
||||||
handlers::{do_user_operation, to_json_string, Args},
|
|
||||||
messages::*,
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
@ -13,7 +9,7 @@ use diesel::{
|
||||||
r2d2::{ConnectionManager, Pool},
|
r2d2::{ConnectionManager, Pool},
|
||||||
PgConnection,
|
PgConnection,
|
||||||
};
|
};
|
||||||
use lemmy_api_structs::{comment::*, community::*, post::*, site::*, user::*};
|
use lemmy_structs::{comment::*, community::*, post::*, site::*, user::*, websocket::*};
|
||||||
use lemmy_rate_limit::RateLimit;
|
use lemmy_rate_limit::RateLimit;
|
||||||
use lemmy_utils::{
|
use lemmy_utils::{
|
||||||
location_info,
|
location_info,
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
api::Perform,
|
api::Perform,
|
||||||
websocket::{
|
websocket::chat_server::{ChatServer, SessionInfo},
|
||||||
chat_server::{ChatServer, SessionInfo},
|
|
||||||
messages::*,
|
|
||||||
UserOperation,
|
|
||||||
},
|
|
||||||
LemmyContext,
|
LemmyContext,
|
||||||
};
|
};
|
||||||
use actix::{Actor, Context, Handler, ResponseFuture};
|
use actix::{Actor, Context, Handler, ResponseFuture};
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
|
use lemmy_structs::websocket::*;
|
||||||
use lemmy_db::naive_now;
|
use lemmy_db::naive_now;
|
||||||
use lemmy_rate_limit::RateLimit;
|
use lemmy_rate_limit::RateLimit;
|
||||||
use lemmy_utils::{ConnectionId, IPAddr, LemmyError};
|
use lemmy_utils::{ConnectionId, IPAddr, LemmyError};
|
||||||
|
|
|
@ -1,67 +1,2 @@
|
||||||
pub mod chat_server;
|
pub mod chat_server;
|
||||||
pub mod handlers;
|
pub mod handlers;
|
||||||
pub mod messages;
|
|
||||||
|
|
||||||
#[derive(EnumString, ToString, Debug, Clone)]
|
|
||||||
pub enum UserOperation {
|
|
||||||
Login,
|
|
||||||
Register,
|
|
||||||
GetCaptcha,
|
|
||||||
CreateCommunity,
|
|
||||||
CreatePost,
|
|
||||||
ListCommunities,
|
|
||||||
ListCategories,
|
|
||||||
GetPost,
|
|
||||||
GetCommunity,
|
|
||||||
CreateComment,
|
|
||||||
EditComment,
|
|
||||||
DeleteComment,
|
|
||||||
RemoveComment,
|
|
||||||
MarkCommentAsRead,
|
|
||||||
SaveComment,
|
|
||||||
CreateCommentLike,
|
|
||||||
GetPosts,
|
|
||||||
CreatePostLike,
|
|
||||||
EditPost,
|
|
||||||
DeletePost,
|
|
||||||
RemovePost,
|
|
||||||
LockPost,
|
|
||||||
StickyPost,
|
|
||||||
SavePost,
|
|
||||||
EditCommunity,
|
|
||||||
DeleteCommunity,
|
|
||||||
RemoveCommunity,
|
|
||||||
FollowCommunity,
|
|
||||||
GetFollowedCommunities,
|
|
||||||
GetUserDetails,
|
|
||||||
GetReplies,
|
|
||||||
GetUserMentions,
|
|
||||||
MarkUserMentionAsRead,
|
|
||||||
GetModlog,
|
|
||||||
BanFromCommunity,
|
|
||||||
AddModToCommunity,
|
|
||||||
CreateSite,
|
|
||||||
EditSite,
|
|
||||||
GetSite,
|
|
||||||
AddAdmin,
|
|
||||||
BanUser,
|
|
||||||
Search,
|
|
||||||
MarkAllAsRead,
|
|
||||||
SaveUserSettings,
|
|
||||||
TransferCommunity,
|
|
||||||
TransferSite,
|
|
||||||
DeleteAccount,
|
|
||||||
PasswordReset,
|
|
||||||
PasswordChange,
|
|
||||||
CreatePrivateMessage,
|
|
||||||
EditPrivateMessage,
|
|
||||||
DeletePrivateMessage,
|
|
||||||
MarkPrivateMessageAsRead,
|
|
||||||
GetPrivateMessages,
|
|
||||||
UserJoin,
|
|
||||||
GetComments,
|
|
||||||
GetSiteConfig,
|
|
||||||
SaveSiteConfig,
|
|
||||||
PostJoin,
|
|
||||||
CommunityJoin,
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue