Merge branch 'main' into activity-sender

This commit is contained in:
Felix Ableitner 2020-08-24 15:11:51 +02:00
commit ba1135184b
72 changed files with 1006 additions and 2116 deletions

1
README.md vendored
View file

@ -112,6 +112,7 @@ Each Lemmy server can set its own moderation policy; appointing site-wide admins
### Libraries ### Libraries
- [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client)
- [Kotlin API ( under development )](https://github.com/eiknat/lemmy-client) - [Kotlin API ( under development )](https://github.com/eiknat/lemmy-client)
## Support / Donate ## Support / Donate

View file

@ -13,8 +13,8 @@ pushd ../../ui
yarn yarn
popd popd
mkdir -p volumes/pictrs_{alpha,beta,gamma} mkdir -p volumes/pictrs_{alpha,beta,gamma,delta,epsilon}
sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma} sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma,delta,epsilon}
sudo docker build ../../ --file ../federation/Dockerfile --tag lemmy-federation:latest sudo docker build ../../ --file ../federation/Dockerfile --tag lemmy-federation:latest
@ -28,6 +28,8 @@ echo "Waiting for Lemmy to start..."
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8570/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8580/api/v1/site')" != "200" ]]; do sleep 1; done
yarn api-test || true yarn api-test || true
popd popd

View file

@ -12,8 +12,8 @@ pushd ../../ui
yarn yarn
popd popd
mkdir -p volumes/pictrs_{alpha,beta,gamma} mkdir -p volumes/pictrs_{alpha,beta,gamma,delta,epsilon}
sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma} sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma,delta,epsilon}
sudo docker build ../../ --file ../federation/Dockerfile --tag lemmy-federation:latest sudo docker build ../../ --file ../federation/Dockerfile --tag lemmy-federation:latest

View file

@ -6,5 +6,7 @@ echo "Waiting for Lemmy to start..."
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8570/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8580/api/v1/site')" != "200" ]]; do sleep 1; done
yarn api-test || true yarn api-test || true
popd popd

View file

@ -7,16 +7,20 @@ services:
- "8540:8540" - "8540:8540"
- "8550:8550" - "8550:8550"
- "8560:8560" - "8560:8560"
- "8570:8570"
- "8580:8580"
volumes: volumes:
# Hack to make this work from both docker/federation/ and docker/federation-test/ # Hack to make this work from both docker/federation/ and docker/federation-test/
- ../federation/nginx.conf:/etc/nginx/nginx.conf - ../federation/nginx.conf:/etc/nginx/nginx.conf
restart: on-failure restart: on-failure
depends_on: depends_on:
- lemmy-alpha
- pictrs - pictrs
- iframely
- lemmy-alpha
- lemmy-beta - lemmy-beta
- lemmy-gamma - lemmy-gamma
- iframely - lemmy-delta
- lemmy-epsilon
pictrs: pictrs:
restart: always restart: always
@ -34,7 +38,7 @@ services:
- LEMMY_FRONT_END_DIR=/app/dist - LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8540 - LEMMY_PORT=8540
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha - LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@ -64,7 +68,7 @@ services:
- LEMMY_FRONT_END_DIR=/app/dist - LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8550 - LEMMY_PORT=8550
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta - LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@ -94,7 +98,7 @@ services:
- LEMMY_FRONT_END_DIR=/app/dist - LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8560 - LEMMY_PORT=8560
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma - LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@ -115,6 +119,68 @@ services:
volumes: volumes:
- ./volumes/postgres_gamma:/var/lib/postgresql/data - ./volumes/postgres_gamma:/var/lib/postgresql/data
# An instance with only an allowlist for beta
lemmy-delta:
image: lemmy-federation:latest
environment:
- LEMMY_HOSTNAME=lemmy-delta:8570
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta
- LEMMY_PORT=8570
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-delta
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_delta
postgres_delta:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_delta:/var/lib/postgresql/data
# An instance who has a blocklist, with lemmy-alpha blocked
lemmy-epsilon:
image: lemmy-federation:latest
environment:
- LEMMY_HOSTNAME=lemmy-epsilon:8580
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha
- LEMMY_PORT=8580
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-epsilon
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_epsilon
postgres_epsilon:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_epsilon:/var/lib/postgresql/data
iframely: iframely:
image: dogbin/iframely:latest image: dogbin/iframely:latest
volumes: volumes:

View file

@ -95,4 +95,66 @@ http {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
} }
} }
server {
listen 8570;
server_name 127.0.0.1;
access_log off;
# Upload limit for pictshare
client_max_body_size 50M;
location / {
proxy_pass http://lemmy-delta:8570;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /iframely/ {
proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 8580;
server_name 127.0.0.1;
access_log off;
# Upload limit for pictshare
client_max_body_size 50M;
location / {
proxy_pass http://lemmy-epsilon:8580;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Cuts off the trailing slash on URLs to make them valid
rewrite ^(.+)/+$ $1 permanent;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /iframely/ {
proxy_pass http://iframely:80/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
} }

View file

@ -20,7 +20,7 @@ popd || exit
sudo docker build ../../ --file Dockerfile -t lemmy-federation:latest sudo docker build ../../ --file Dockerfile -t lemmy-federation:latest
for Item in alpha beta gamma ; do for Item in alpha beta gamma delta epsilon ; do
sudo mkdir -p volumes/pictrs_$Item sudo mkdir -p volumes/pictrs_$Item
sudo chown -R 991:991 volumes/pictrs_$Item sudo chown -R 991:991 volumes/pictrs_$Item
done done

View file

@ -7,16 +7,20 @@ services:
- "8540:8540" - "8540:8540"
- "8550:8550" - "8550:8550"
- "8560:8560" - "8560:8560"
- "8570:8570"
- "8580:8580"
volumes: volumes:
# Hack to make this work from both docker/federation/ and docker/federation-test/ # Hack to make this work from both docker/federation/ and docker/federation-test/
- ../federation/nginx.conf:/etc/nginx/nginx.conf - ../federation/nginx.conf:/etc/nginx/nginx.conf
restart: on-failure restart: on-failure
depends_on: depends_on:
- lemmy-alpha
- pictrs - pictrs
- iframely
- lemmy-alpha
- lemmy-beta - lemmy-beta
- lemmy-gamma - lemmy-gamma
- iframely - lemmy-delta
- lemmy-epsilon
pictrs: pictrs:
restart: always restart: always
@ -34,7 +38,7 @@ services:
- LEMMY_FRONT_END_DIR=/app/dist - LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8540 - LEMMY_PORT=8540
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha - LEMMY_SETUP__ADMIN_USERNAME=lemmy_alpha
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@ -64,7 +68,7 @@ services:
- LEMMY_FRONT_END_DIR=/app/dist - LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-gamma,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8550 - LEMMY_PORT=8550
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta - LEMMY_SETUP__ADMIN_USERNAME=lemmy_beta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@ -94,7 +98,7 @@ services:
- LEMMY_FRONT_END_DIR=/app/dist - LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true - LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false - LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta - LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-alpha,lemmy-beta,lemmy-delta,lemmy-epsilon
- LEMMY_PORT=8560 - LEMMY_PORT=8560
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma - LEMMY_SETUP__ADMIN_USERNAME=lemmy_gamma
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy - LEMMY_SETUP__ADMIN_PASSWORD=lemmy
@ -115,6 +119,68 @@ services:
volumes: volumes:
- ./volumes/postgres_gamma:/var/lib/postgresql/data - ./volumes/postgres_gamma:/var/lib/postgresql/data
# An instance with only an allowlist for beta
lemmy-delta:
image: dessalines/lemmy:travis
environment:
- LEMMY_HOSTNAME=lemmy-delta:8570
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_delta:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__ALLOWED_INSTANCES=lemmy-beta
- LEMMY_PORT=8570
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_delta
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-delta
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_delta
postgres_delta:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_delta:/var/lib/postgresql/data
# An instance who has a blocklist, with lemmy-alpha blocked
lemmy-epsilon:
image: dessalines/lemmy:travis
environment:
- LEMMY_HOSTNAME=lemmy-epsilon:8580
- LEMMY_DATABASE_URL=postgres://lemmy:password@postgres_epsilon:5432/lemmy
- LEMMY_JWT_SECRET=changeme
- LEMMY_FRONT_END_DIR=/app/dist
- LEMMY_FEDERATION__ENABLED=true
- LEMMY_FEDERATION__TLS_ENABLED=false
- LEMMY_FEDERATION__BLOCKED_INSTANCES=lemmy-alpha
- LEMMY_PORT=8580
- LEMMY_SETUP__ADMIN_USERNAME=lemmy_epsilon
- LEMMY_SETUP__ADMIN_PASSWORD=lemmy
- LEMMY_SETUP__SITE_NAME=lemmy-epsilon
- LEMMY_RATE_LIMIT__POST=99999
- LEMMY_RATE_LIMIT__REGISTER=99999
- LEMMY_CAPTCHA__ENABLED=false
- RUST_BACKTRACE=1
- RUST_LOG=debug
depends_on:
- postgres_epsilon
postgres_epsilon:
image: postgres:12-alpine
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=password
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres_epsilon:/var/lib/postgresql/data
iframely: iframely:
image: dogbin/iframely:latest image: dogbin/iframely:latest
volumes: volumes:

View file

@ -5,8 +5,8 @@ set -e
sudo docker-compose down sudo docker-compose down
sudo rm -rf volumes sudo rm -rf volumes
mkdir -p volumes/pictrs_{alpha,beta,gamma} mkdir -p volumes/pictrs_{alpha,beta,gamma,delta,epsilon}
sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma} sudo chown -R 991:991 volumes/pictrs_{alpha,beta,gamma,delta,epsilon}
sudo docker build ../../ --file ../prod/Dockerfile --tag dessalines/lemmy:travis sudo docker build ../../ --file ../prod/Dockerfile --tag dessalines/lemmy:travis
@ -17,6 +17,8 @@ echo "Waiting for Lemmy to start..."
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8540/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8550/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8560/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8570/api/v1/site')" != "200" ]]; do sleep 1; done
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'localhost:8580/api/v1/site')" != "200" ]]; do sleep 1; done
yarn yarn
yarn api-test yarn api-test
popd popd

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
api::{ api::{
check_community_ban, check_community_ban,
get_post,
get_user_from_jwt, get_user_from_jwt,
get_user_from_jwt_opt, get_user_from_jwt_opt,
is_mod_or_admin, is_mod_or_admin,
@ -12,8 +13,8 @@ use crate::{
websocket::{ websocket::{
server::{JoinCommunityRoom, SendComment}, server::{JoinCommunityRoom, SendComment},
UserOperation, UserOperation,
WebsocketInfo,
}, },
ConnectionId,
DbPool, DbPool,
LemmyContext, LemmyContext,
LemmyError, LemmyError,
@ -128,7 +129,7 @@ impl Perform for CreateComment {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &CreateComment = &self; let data: &CreateComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -151,7 +152,7 @@ impl Perform for CreateComment {
// Check for a community ban // Check for a community ban
let post_id = data.post_id; let post_id = data.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = get_post(post_id, context.pool()).await?;
check_community_ban(user.id, post.community_id, context.pool()).await?; check_community_ban(user.id, post.community_id, context.pool()).await?;
@ -225,17 +226,15 @@ impl Perform for CreateComment {
form_id: data.form_id.to_owned(), form_id: data.form_id.to_owned(),
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendComment {
ws.chatserver.do_send(SendComment { op: UserOperation::CreateComment,
op: UserOperation::CreateComment, comment: res.clone(),
comment: res.clone(), websocket_id,
my_id: ws.id, });
});
// strip out the recipient_ids, so that // strip out the recipient_ids, so that
// users don't get double notifs // users don't get double notifs
res.recipient_ids = Vec::new(); res.recipient_ids = Vec::new();
}
Ok(res) Ok(res)
} }
@ -248,7 +247,7 @@ impl Perform for EditComment {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &EditComment = &self; let data: &EditComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -283,7 +282,7 @@ impl Perform for EditComment {
// Do the mentions / recipients // Do the mentions / recipients
let post_id = orig_comment.post_id; let post_id = orig_comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = get_post(post_id, context.pool()).await?;
let updated_comment_content = updated_comment.content.to_owned(); let updated_comment_content = updated_comment.content.to_owned();
let mentions = scrape_text_for_mentions(&updated_comment_content); let mentions = scrape_text_for_mentions(&updated_comment_content);
@ -310,17 +309,15 @@ impl Perform for EditComment {
form_id: data.form_id.to_owned(), form_id: data.form_id.to_owned(),
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendComment {
ws.chatserver.do_send(SendComment { op: UserOperation::EditComment,
op: UserOperation::EditComment, comment: res.clone(),
comment: res.clone(), websocket_id,
my_id: ws.id, });
});
// strip out the recipient_ids, so that // strip out the recipient_ids, so that
// users don't get double notifs // users don't get double notifs
res.recipient_ids = Vec::new(); res.recipient_ids = Vec::new();
}
Ok(res) Ok(res)
} }
@ -333,7 +330,7 @@ impl Perform for DeleteComment {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &DeleteComment = &self; let data: &DeleteComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -379,7 +376,7 @@ impl Perform for DeleteComment {
// Build the recipients // Build the recipients
let post_id = comment_view.post_id; let post_id = comment_view.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = get_post(post_id, context.pool()).await?;
let mentions = vec![]; let mentions = vec![];
let recipient_ids = send_local_notifs( let recipient_ids = send_local_notifs(
mentions, mentions,
@ -397,17 +394,15 @@ impl Perform for DeleteComment {
form_id: None, form_id: None,
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendComment {
ws.chatserver.do_send(SendComment { op: UserOperation::DeleteComment,
op: UserOperation::DeleteComment, comment: res.clone(),
comment: res.clone(), websocket_id,
my_id: ws.id, });
});
// strip out the recipient_ids, so that // strip out the recipient_ids, so that
// users don't get double notifs // users don't get double notifs
res.recipient_ids = Vec::new(); res.recipient_ids = Vec::new();
}
Ok(res) Ok(res)
} }
@ -420,7 +415,7 @@ impl Perform for RemoveComment {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &RemoveComment = &self; let data: &RemoveComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -476,7 +471,7 @@ impl Perform for RemoveComment {
// Build the recipients // Build the recipients
let post_id = comment_view.post_id; let post_id = comment_view.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = get_post(post_id, context.pool()).await?;
let mentions = vec![]; let mentions = vec![];
let recipient_ids = send_local_notifs( let recipient_ids = send_local_notifs(
mentions, mentions,
@ -494,17 +489,15 @@ impl Perform for RemoveComment {
form_id: None, form_id: None,
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendComment {
ws.chatserver.do_send(SendComment { op: UserOperation::RemoveComment,
op: UserOperation::RemoveComment, comment: res.clone(),
comment: res.clone(), websocket_id,
my_id: ws.id, });
});
// strip out the recipient_ids, so that // strip out the recipient_ids, so that
// users don't get double notifs // users don't get double notifs
res.recipient_ids = Vec::new(); res.recipient_ids = Vec::new();
}
Ok(res) Ok(res)
} }
@ -517,7 +510,7 @@ impl Perform for MarkCommentAsRead {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &MarkCommentAsRead = &self; let data: &MarkCommentAsRead = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -589,7 +582,7 @@ impl Perform for SaveComment {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &SaveComment = &self; let data: &SaveComment = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -633,7 +626,7 @@ impl Perform for CreateCommentLike {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommentResponse, LemmyError> { ) -> Result<CommentResponse, LemmyError> {
let data: &CreateCommentLike = &self; let data: &CreateCommentLike = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -655,7 +648,7 @@ impl Perform for CreateCommentLike {
.await??; .await??;
let post_id = orig_comment.post_id; let post_id = orig_comment.post_id;
let post = blocking(context.pool(), move |conn| Post::read(conn, post_id)).await??; let post = get_post(post_id, context.pool()).await?;
check_community_ban(user.id, post.community_id, context.pool()).await?; check_community_ban(user.id, post.community_id, context.pool()).await?;
let comment_id = data.comment_id; let comment_id = data.comment_id;
@ -725,17 +718,15 @@ impl Perform for CreateCommentLike {
form_id: None, form_id: None,
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendComment {
ws.chatserver.do_send(SendComment { op: UserOperation::CreateCommentLike,
op: UserOperation::CreateCommentLike, comment: res.clone(),
comment: res.clone(), websocket_id,
my_id: ws.id, });
});
// strip out the recipient_ids, so that // strip out the recipient_ids, so that
// users don't get double notifs // users don't get double notifs
res.recipient_ids = Vec::new(); res.recipient_ids = Vec::new();
}
Ok(res) Ok(res)
} }
@ -748,7 +739,7 @@ impl Perform for GetComments {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<GetCommentsResponse, LemmyError> { ) -> Result<GetCommentsResponse, LemmyError> {
let data: &GetComments = &self; let data: &GetComments = &self;
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?; let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
@ -776,17 +767,15 @@ impl Perform for GetComments {
Err(_) => return Err(APIError::err("couldnt_get_comments").into()), Err(_) => return Err(APIError::err("couldnt_get_comments").into()),
}; };
if let Some(ws) = websocket_info { if let Some(id) = websocket_id {
// You don't need to join the specific community room, bc this is already handled by // You don't need to join the specific community room, bc this is already handled by
// GetCommunity // GetCommunity
if data.community_id.is_none() { if data.community_id.is_none() {
if let Some(id) = ws.id { // 0 is the "all" community
// 0 is the "all" community context.chat_server().do_send(JoinCommunityRoom {
ws.chatserver.do_send(JoinCommunityRoom { community_id: 0,
community_id: 0, id,
id, });
});
}
} }
} }

View file

@ -6,8 +6,8 @@ use crate::{
websocket::{ websocket::{
server::{GetCommunityUsersOnline, JoinCommunityRoom, SendCommunityRoomMessage}, server::{GetCommunityUsersOnline, JoinCommunityRoom, SendCommunityRoomMessage},
UserOperation, UserOperation,
WebsocketInfo,
}, },
ConnectionId,
}; };
use anyhow::Context; use anyhow::Context;
use lemmy_db::{ use lemmy_db::{
@ -166,7 +166,7 @@ impl Perform for GetCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<GetCommunityResponse, LemmyError> { ) -> Result<GetCommunityResponse, LemmyError> {
let data: &GetCommunity = &self; let data: &GetCommunity = &self;
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?; let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
@ -205,20 +205,17 @@ impl Perform for GetCommunity {
Err(_e) => return Err(APIError::err("couldnt_find_community").into()), Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
}; };
let online = if let Some(ws) = websocket_info { if let Some(id) = websocket_id {
if let Some(id) = ws.id { context
ws.chatserver.do_send(JoinCommunityRoom { .chat_server()
community_id: community.id, .do_send(JoinCommunityRoom { community_id, id });
id, }
});
} let online = context
ws.chatserver .chat_server()
.send(GetCommunityUsersOnline { community_id }) .send(GetCommunityUsersOnline { community_id })
.await .await
.unwrap_or(1) .unwrap_or(1);
} else {
0
};
let res = GetCommunityResponse { let res = GetCommunityResponse {
community: community_view, community: community_view,
@ -238,7 +235,7 @@ impl Perform for CreateCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<CommunityResponse, LemmyError> { ) -> Result<CommunityResponse, LemmyError> {
let data: &CreateCommunity = &self; let data: &CreateCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -333,7 +330,7 @@ impl Perform for EditCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommunityResponse, LemmyError> { ) -> Result<CommunityResponse, LemmyError> {
let data: &EditCommunity = &self; let data: &EditCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -403,7 +400,7 @@ impl Perform for EditCommunity {
community: community_view, community: community_view,
}; };
send_community_websocket(&res, websocket_info, UserOperation::EditCommunity); send_community_websocket(&res, context, websocket_id, UserOperation::EditCommunity);
Ok(res) Ok(res)
} }
@ -416,7 +413,7 @@ impl Perform for DeleteCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommunityResponse, LemmyError> { ) -> Result<CommunityResponse, LemmyError> {
let data: &DeleteCommunity = &self; let data: &DeleteCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -459,7 +456,7 @@ impl Perform for DeleteCommunity {
community: community_view, community: community_view,
}; };
send_community_websocket(&res, websocket_info, UserOperation::DeleteCommunity); send_community_websocket(&res, context, websocket_id, UserOperation::DeleteCommunity);
Ok(res) Ok(res)
} }
@ -472,7 +469,7 @@ impl Perform for RemoveCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<CommunityResponse, LemmyError> { ) -> Result<CommunityResponse, LemmyError> {
let data: &RemoveCommunity = &self; let data: &RemoveCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -527,7 +524,7 @@ impl Perform for RemoveCommunity {
community: community_view, community: community_view,
}; };
send_community_websocket(&res, websocket_info, UserOperation::RemoveCommunity); send_community_websocket(&res, context, websocket_id, UserOperation::RemoveCommunity);
Ok(res) Ok(res)
} }
@ -540,7 +537,7 @@ impl Perform for ListCommunities {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<ListCommunitiesResponse, LemmyError> { ) -> Result<ListCommunitiesResponse, LemmyError> {
let data: &ListCommunities = &self; let data: &ListCommunities = &self;
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?; let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
@ -582,7 +579,7 @@ impl Perform for FollowCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<CommunityResponse, LemmyError> { ) -> Result<CommunityResponse, LemmyError> {
let data: &FollowCommunity = &self; let data: &FollowCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -643,7 +640,7 @@ impl Perform for GetFollowedCommunities {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetFollowedCommunitiesResponse, LemmyError> { ) -> Result<GetFollowedCommunitiesResponse, LemmyError> {
let data: &GetFollowedCommunities = &self; let data: &GetFollowedCommunities = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -670,7 +667,7 @@ impl Perform for BanFromCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<BanFromCommunityResponse, LemmyError> { ) -> Result<BanFromCommunityResponse, LemmyError> {
let data: &BanFromCommunity = &self; let data: &BanFromCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -757,14 +754,12 @@ impl Perform for BanFromCommunity {
banned: data.ban, banned: data.ban,
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendCommunityRoomMessage {
ws.chatserver.do_send(SendCommunityRoomMessage { op: UserOperation::BanFromCommunity,
op: UserOperation::BanFromCommunity, response: res.clone(),
response: res.clone(), community_id,
community_id: data.community_id, websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -777,7 +772,7 @@ impl Perform for AddModToCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<AddModToCommunityResponse, LemmyError> { ) -> Result<AddModToCommunityResponse, LemmyError> {
let data: &AddModToCommunity = &self; let data: &AddModToCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -824,14 +819,12 @@ impl Perform for AddModToCommunity {
let res = AddModToCommunityResponse { moderators }; let res = AddModToCommunityResponse { moderators };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendCommunityRoomMessage {
ws.chatserver.do_send(SendCommunityRoomMessage { op: UserOperation::AddModToCommunity,
op: UserOperation::AddModToCommunity, response: res.clone(),
response: res.clone(), community_id,
community_id: data.community_id, websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -844,7 +837,7 @@ impl Perform for TransferCommunity {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetCommunityResponse, LemmyError> { ) -> Result<GetCommunityResponse, LemmyError> {
let data: &TransferCommunity = &self; let data: &TransferCommunity = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -957,20 +950,19 @@ impl Perform for TransferCommunity {
pub fn send_community_websocket( pub fn send_community_websocket(
res: &CommunityResponse, res: &CommunityResponse,
websocket_info: Option<WebsocketInfo>, context: &Data<LemmyContext>,
websocket_id: Option<ConnectionId>,
op: UserOperation, op: UserOperation,
) { ) {
if let Some(ws) = websocket_info { // Strip out the user id and subscribed when sending to others
// Strip out the user id and subscribed when sending to others let mut res_sent = res.clone();
let mut res_sent = res.clone(); res_sent.community.user_id = None;
res_sent.community.user_id = None; res_sent.community.subscribed = None;
res_sent.community.subscribed = None;
ws.chatserver.do_send(SendCommunityRoomMessage { context.chat_server().do_send(SendCommunityRoomMessage {
op, op,
response: res_sent, response: res_sent,
community_id: res.community.id, community_id: res.community.id,
my_id: ws.id, websocket_id,
}); });
}
} }

View file

@ -1,16 +1,10 @@
use crate::{ use crate::{api::claims::Claims, blocking, ConnectionId, DbPool, LemmyContext, LemmyError};
api::claims::Claims,
blocking,
websocket::WebsocketInfo,
DbPool,
LemmyContext,
LemmyError,
};
use actix_web::web::Data; use actix_web::web::Data;
use lemmy_db::{ use lemmy_db::{
community::*, community::*,
community_view::*, community_view::*,
moderator::*, moderator::*,
post::Post,
site::*, site::*,
user::*, user::*,
user_view::*, user_view::*,
@ -47,7 +41,7 @@ pub trait Perform {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<Self::Response, LemmyError>; ) -> Result<Self::Response, LemmyError>;
} }
@ -73,6 +67,13 @@ pub async fn is_admin(pool: &DbPool, user_id: i32) -> Result<(), LemmyError> {
Ok(()) Ok(())
} }
pub(in crate::api) async fn get_post(post_id: i32, pool: &DbPool) -> Result<Post, LemmyError> {
match blocking(pool, move |conn| Post::read(conn, post_id)).await? {
Ok(post) => Ok(post),
Err(_e) => Err(APIError::err("couldnt_find_post").into()),
}
}
pub(in crate::api) async fn get_user_from_jwt( pub(in crate::api) async fn get_user_from_jwt(
jwt: &str, jwt: &str,
pool: &DbPool, pool: &DbPool,

View file

@ -15,8 +15,8 @@ use crate::{
websocket::{ websocket::{
server::{GetPostUsersOnline, JoinCommunityRoom, JoinPostRoom, SendPost}, server::{GetPostUsersOnline, JoinCommunityRoom, JoinPostRoom, SendPost},
UserOperation, UserOperation,
WebsocketInfo,
}, },
ConnectionId,
LemmyContext, LemmyContext,
LemmyError, LemmyError,
}; };
@ -146,7 +146,7 @@ impl Perform for CreatePost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &CreatePost = &self; let data: &CreatePost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -247,13 +247,11 @@ impl Perform for CreatePost {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::CreatePost,
op: UserOperation::CreatePost, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -266,7 +264,7 @@ impl Perform for GetPost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<GetPostResponse, LemmyError> { ) -> Result<GetPostResponse, LemmyError> {
let data: &GetPost = &self; let data: &GetPost = &self;
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?; let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
@ -304,20 +302,18 @@ impl Perform for GetPost {
}) })
.await??; .await??;
let online = if let Some(ws) = websocket_info { if let Some(id) = websocket_id {
if let Some(id) = ws.id { context.chat_server().do_send(JoinPostRoom {
ws.chatserver.do_send(JoinPostRoom { post_id: data.id,
post_id: data.id, id,
id, });
}); }
}
ws.chatserver let online = context
.send(GetPostUsersOnline { post_id: data.id }) .chat_server()
.await .send(GetPostUsersOnline { post_id: data.id })
.unwrap_or(1) .await
} else { .unwrap_or(1);
0
};
// Return the jwt // Return the jwt
Ok(GetPostResponse { Ok(GetPostResponse {
@ -337,7 +333,7 @@ impl Perform for GetPosts {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<GetPostsResponse, LemmyError> { ) -> Result<GetPostsResponse, LemmyError> {
let data: &GetPosts = &self; let data: &GetPosts = &self;
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?; let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
@ -377,17 +373,15 @@ impl Perform for GetPosts {
Err(_e) => return Err(APIError::err("couldnt_get_posts").into()), Err(_e) => return Err(APIError::err("couldnt_get_posts").into()),
}; };
if let Some(ws) = websocket_info { if let Some(id) = websocket_id {
// You don't need to join the specific community room, bc this is already handled by // You don't need to join the specific community room, bc this is already handled by
// GetCommunity // GetCommunity
if data.community_id.is_none() { if data.community_id.is_none() {
if let Some(id) = ws.id { // 0 is the "all" community
// 0 is the "all" community context.chat_server().do_send(JoinCommunityRoom {
ws.chatserver.do_send(JoinCommunityRoom { community_id: 0,
community_id: 0, id,
id, });
});
}
} }
} }
@ -402,7 +396,7 @@ impl Perform for CreatePostLike {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &CreatePostLike = &self; let data: &CreatePostLike = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -465,13 +459,11 @@ impl Perform for CreatePostLike {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::CreatePostLike,
op: UserOperation::CreatePostLike, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -484,7 +476,7 @@ impl Perform for EditPost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &EditPost = &self; let data: &EditPost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -560,13 +552,11 @@ impl Perform for EditPost {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::EditPost,
op: UserOperation::EditPost, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -579,7 +569,7 @@ impl Perform for DeletePost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &DeletePost = &self; let data: &DeletePost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -618,13 +608,11 @@ impl Perform for DeletePost {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::DeletePost,
op: UserOperation::DeletePost, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -637,7 +625,7 @@ impl Perform for RemovePost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &RemovePost = &self; let data: &RemovePost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -687,13 +675,11 @@ impl Perform for RemovePost {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::RemovePost,
op: UserOperation::RemovePost, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -706,7 +692,7 @@ impl Perform for LockPost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &LockPost = &self; let data: &LockPost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -747,13 +733,11 @@ impl Perform for LockPost {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::LockPost,
op: UserOperation::LockPost, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -766,7 +750,7 @@ impl Perform for StickyPost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &StickyPost = &self; let data: &StickyPost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -811,13 +795,11 @@ impl Perform for StickyPost {
let res = PostResponse { post: post_view }; let res = PostResponse { post: post_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendPost {
ws.chatserver.do_send(SendPost { op: UserOperation::StickyPost,
op: UserOperation::StickyPost, post: res.clone(),
post: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -830,7 +812,7 @@ impl Perform for SavePost {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<PostResponse, LemmyError> { ) -> Result<PostResponse, LemmyError> {
let data: &SavePost = &self; let data: &SavePost = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;

View file

@ -15,8 +15,8 @@ use crate::{
websocket::{ websocket::{
server::{GetUsersOnline, SendAllMessage}, server::{GetUsersOnline, SendAllMessage},
UserOperation, UserOperation,
WebsocketInfo,
}, },
ConnectionId,
LemmyContext, LemmyContext,
LemmyError, LemmyError,
}; };
@ -167,7 +167,7 @@ impl Perform for ListCategories {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<ListCategoriesResponse, LemmyError> { ) -> Result<ListCategoriesResponse, LemmyError> {
let _data: &ListCategories = &self; let _data: &ListCategories = &self;
@ -185,7 +185,7 @@ impl Perform for GetModlog {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetModlogResponse, LemmyError> { ) -> Result<GetModlogResponse, LemmyError> {
let data: &GetModlog = &self; let data: &GetModlog = &self;
@ -259,7 +259,7 @@ impl Perform for CreateSite {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<SiteResponse, LemmyError> { ) -> Result<SiteResponse, LemmyError> {
let data: &CreateSite = &self; let data: &CreateSite = &self;
@ -300,7 +300,7 @@ impl Perform for EditSite {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<SiteResponse, LemmyError> { ) -> Result<SiteResponse, LemmyError> {
let data: &EditSite = &self; let data: &EditSite = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -337,13 +337,11 @@ impl Perform for EditSite {
let res = SiteResponse { site: site_view }; let res = SiteResponse { site: site_view };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendAllMessage {
ws.chatserver.do_send(SendAllMessage { op: UserOperation::EditSite,
op: UserOperation::EditSite, response: res.clone(),
response: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -356,7 +354,7 @@ impl Perform for GetSite {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<GetSiteResponse, LemmyError> { ) -> Result<GetSiteResponse, LemmyError> {
let data: &GetSite = &self; let data: &GetSite = &self;
@ -375,7 +373,7 @@ impl Perform for GetSite {
captcha_uuid: None, captcha_uuid: None,
captcha_answer: None, captcha_answer: None,
}; };
let login_response = register.perform(context, websocket_info.clone()).await?; let login_response = register.perform(context, websocket_id).await?;
info!("Admin {} created", setup.admin_username); info!("Admin {} created", setup.admin_username);
let create_site = CreateSite { let create_site = CreateSite {
@ -388,7 +386,7 @@ impl Perform for GetSite {
enable_nsfw: true, enable_nsfw: true,
auth: login_response.jwt, auth: login_response.jwt,
}; };
create_site.perform(context, websocket_info.clone()).await?; create_site.perform(context, websocket_id).await?;
info!("Site {} created", setup.site_name); info!("Site {} created", setup.site_name);
Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??) Some(blocking(context.pool(), move |conn| SiteView::read(conn)).await??)
} else { } else {
@ -410,11 +408,11 @@ impl Perform for GetSite {
let banned = blocking(context.pool(), move |conn| UserView::banned(conn)).await??; let banned = blocking(context.pool(), move |conn| UserView::banned(conn)).await??;
let online = if let Some(ws) = websocket_info { let online = context
ws.chatserver.send(GetUsersOnline).await.unwrap_or(1) .chat_server()
} else { .send(GetUsersOnline)
0 .await
}; .unwrap_or(1);
let my_user = get_user_from_jwt_opt(&data.auth, context.pool()) let my_user = get_user_from_jwt_opt(&data.auth, context.pool())
.await? .await?
@ -444,7 +442,7 @@ impl Perform for Search {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<SearchResponse, LemmyError> { ) -> Result<SearchResponse, LemmyError> {
let data: &Search = &self; let data: &Search = &self;
@ -608,7 +606,7 @@ impl Perform for TransferSite {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetSiteResponse, LemmyError> { ) -> Result<GetSiteResponse, LemmyError> {
let data: &TransferSite = &self; let data: &TransferSite = &self;
let mut user = get_user_from_jwt(&data.auth, context.pool()).await?; let mut user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -671,7 +669,7 @@ impl Perform for GetSiteConfig {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetSiteConfigResponse, LemmyError> { ) -> Result<GetSiteConfigResponse, LemmyError> {
let data: &GetSiteConfig = &self; let data: &GetSiteConfig = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -692,7 +690,7 @@ impl Perform for SaveSiteConfig {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetSiteConfigResponse, LemmyError> { ) -> Result<GetSiteConfigResponse, LemmyError> {
let data: &SaveSiteConfig = &self; let data: &SaveSiteConfig = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;

View file

@ -14,8 +14,8 @@ use crate::{
websocket::{ websocket::{
server::{CaptchaItem, CheckCaptcha, JoinUserRoom, SendAllMessage, SendUserRoomMessage}, server::{CaptchaItem, CheckCaptcha, JoinUserRoom, SendAllMessage, SendUserRoomMessage},
UserOperation, UserOperation,
WebsocketInfo,
}, },
ConnectionId,
LemmyContext, LemmyContext,
LemmyError, LemmyError,
}; };
@ -303,7 +303,7 @@ impl Perform for Login {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<LoginResponse, LemmyError> { ) -> Result<LoginResponse, LemmyError> {
let data: &Login = &self; let data: &Login = &self;
@ -338,7 +338,7 @@ impl Perform for Register {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<LoginResponse, LemmyError> { ) -> Result<LoginResponse, LemmyError> {
let data: &Register = &self; let data: &Register = &self;
@ -357,27 +357,22 @@ impl Perform for Register {
// If its not the admin, check the captcha // If its not the admin, check the captcha
if !data.admin && Settings::get().captcha.enabled { if !data.admin && Settings::get().captcha.enabled {
match websocket_info { let check = context
Some(ws) => { .chat_server()
let check = ws .send(CheckCaptcha {
.chatserver uuid: data
.send(CheckCaptcha { .captcha_uuid
uuid: data .to_owned()
.captcha_uuid .unwrap_or_else(|| "".to_string()),
.to_owned() answer: data
.unwrap_or_else(|| "".to_string()), .captcha_answer
answer: data .to_owned()
.captcha_answer .unwrap_or_else(|| "".to_string()),
.to_owned() })
.unwrap_or_else(|| "".to_string()), .await?;
}) if !check {
.await?; return Err(APIError::err("captcha_incorrect").into());
if !check { }
return Err(APIError::err("captcha_incorrect").into());
}
}
None => return Err(APIError::err("captcha_incorrect").into()),
};
} }
check_slurs(&data.username)?; check_slurs(&data.username)?;
@ -515,8 +510,8 @@ impl Perform for GetCaptcha {
async fn perform( async fn perform(
&self, &self,
_context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<Self::Response, LemmyError> { ) -> Result<Self::Response, LemmyError> {
let captcha_settings = Settings::get().captcha; let captcha_settings = Settings::get().captcha;
@ -547,9 +542,8 @@ impl Perform for GetCaptcha {
expires: naive_now() + Duration::minutes(10), // expires in 10 minutes expires: naive_now() + Duration::minutes(10), // expires in 10 minutes
}; };
if let Some(ws) = websocket_info { // Stores the captcha item on the queue
ws.chatserver.do_send(captcha_item); context.chat_server().do_send(captcha_item);
}
Ok(GetCaptchaResponse { Ok(GetCaptchaResponse {
ok: Some(CaptchaResponse { png, uuid, wav }), ok: Some(CaptchaResponse { png, uuid, wav }),
@ -564,7 +558,7 @@ impl Perform for SaveUserSettings {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<LoginResponse, LemmyError> { ) -> Result<LoginResponse, LemmyError> {
let data: &SaveUserSettings = &self; let data: &SaveUserSettings = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -690,7 +684,7 @@ impl Perform for GetUserDetails {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetUserDetailsResponse, LemmyError> { ) -> Result<GetUserDetailsResponse, LemmyError> {
let data: &GetUserDetails = &self; let data: &GetUserDetails = &self;
let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?; let user = get_user_from_jwt_opt(&data.auth, context.pool()).await?;
@ -788,7 +782,7 @@ impl Perform for AddAdmin {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<AddAdminResponse, LemmyError> { ) -> Result<AddAdminResponse, LemmyError> {
let data: &AddAdmin = &self; let data: &AddAdmin = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -827,13 +821,11 @@ impl Perform for AddAdmin {
let res = AddAdminResponse { admins }; let res = AddAdminResponse { admins };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendAllMessage {
ws.chatserver.do_send(SendAllMessage { op: UserOperation::AddAdmin,
op: UserOperation::AddAdmin, response: res.clone(),
response: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -846,7 +838,7 @@ impl Perform for BanUser {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<BanUserResponse, LemmyError> { ) -> Result<BanUserResponse, LemmyError> {
let data: &BanUser = &self; let data: &BanUser = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -909,13 +901,11 @@ impl Perform for BanUser {
banned: data.ban, banned: data.ban,
}; };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendAllMessage {
ws.chatserver.do_send(SendAllMessage { op: UserOperation::BanUser,
op: UserOperation::BanUser, response: res.clone(),
response: res.clone(), websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -928,7 +918,7 @@ impl Perform for GetReplies {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetRepliesResponse, LemmyError> { ) -> Result<GetRepliesResponse, LemmyError> {
let data: &GetReplies = &self; let data: &GetReplies = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -960,7 +950,7 @@ impl Perform for GetUserMentions {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetUserMentionsResponse, LemmyError> { ) -> Result<GetUserMentionsResponse, LemmyError> {
let data: &GetUserMentions = &self; let data: &GetUserMentions = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -992,7 +982,7 @@ impl Perform for MarkUserMentionAsRead {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<UserMentionResponse, LemmyError> { ) -> Result<UserMentionResponse, LemmyError> {
let data: &MarkUserMentionAsRead = &self; let data: &MarkUserMentionAsRead = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1034,7 +1024,7 @@ impl Perform for MarkAllAsRead {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<GetRepliesResponse, LemmyError> { ) -> Result<GetRepliesResponse, LemmyError> {
let data: &MarkAllAsRead = &self; let data: &MarkAllAsRead = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1086,7 +1076,7 @@ impl Perform for DeleteAccount {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<LoginResponse, LemmyError> { ) -> Result<LoginResponse, LemmyError> {
let data: &DeleteAccount = &self; let data: &DeleteAccount = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1123,7 +1113,7 @@ impl Perform for PasswordReset {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<PasswordResetResponse, LemmyError> { ) -> Result<PasswordResetResponse, LemmyError> {
let data: &PasswordReset = &self; let data: &PasswordReset = &self;
@ -1171,7 +1161,7 @@ impl Perform for PasswordChange {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<LoginResponse, LemmyError> { ) -> Result<LoginResponse, LemmyError> {
let data: &PasswordChange = &self; let data: &PasswordChange = &self;
@ -1212,7 +1202,7 @@ impl Perform for CreatePrivateMessage {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PrivateMessageResponse, LemmyError> { ) -> Result<PrivateMessageResponse, LemmyError> {
let data: &CreatePrivateMessage = &self; let data: &CreatePrivateMessage = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1290,14 +1280,12 @@ impl Perform for CreatePrivateMessage {
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendUserRoomMessage {
ws.chatserver.do_send(SendUserRoomMessage { op: UserOperation::CreatePrivateMessage,
op: UserOperation::CreatePrivateMessage, response: res.clone(),
response: res.clone(), recipient_id,
recipient_id: recipient_user.id, websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -1310,7 +1298,7 @@ impl Perform for EditPrivateMessage {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PrivateMessageResponse, LemmyError> { ) -> Result<PrivateMessageResponse, LemmyError> {
let data: &EditPrivateMessage = &self; let data: &EditPrivateMessage = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1349,14 +1337,12 @@ impl Perform for EditPrivateMessage {
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendUserRoomMessage {
ws.chatserver.do_send(SendUserRoomMessage { op: UserOperation::EditPrivateMessage,
op: UserOperation::EditPrivateMessage, response: res.clone(),
response: res.clone(), recipient_id,
recipient_id, websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -1369,7 +1355,7 @@ impl Perform for DeletePrivateMessage {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PrivateMessageResponse, LemmyError> { ) -> Result<PrivateMessageResponse, LemmyError> {
let data: &DeletePrivateMessage = &self; let data: &DeletePrivateMessage = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1414,14 +1400,12 @@ impl Perform for DeletePrivateMessage {
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendUserRoomMessage {
ws.chatserver.do_send(SendUserRoomMessage { op: UserOperation::DeletePrivateMessage,
op: UserOperation::DeletePrivateMessage, response: res.clone(),
response: res.clone(), recipient_id,
recipient_id, websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -1434,7 +1418,7 @@ impl Perform for MarkPrivateMessageAsRead {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<PrivateMessageResponse, LemmyError> { ) -> Result<PrivateMessageResponse, LemmyError> {
let data: &MarkPrivateMessageAsRead = &self; let data: &MarkPrivateMessageAsRead = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1472,14 +1456,12 @@ impl Perform for MarkPrivateMessageAsRead {
let res = PrivateMessageResponse { message }; let res = PrivateMessageResponse { message };
if let Some(ws) = websocket_info { context.chat_server().do_send(SendUserRoomMessage {
ws.chatserver.do_send(SendUserRoomMessage { op: UserOperation::MarkPrivateMessageAsRead,
op: UserOperation::MarkPrivateMessageAsRead, response: res.clone(),
response: res.clone(), recipient_id,
recipient_id, websocket_id,
my_id: ws.id, });
});
}
Ok(res) Ok(res)
} }
@ -1492,7 +1474,7 @@ impl Perform for GetPrivateMessages {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
_websocket_info: Option<WebsocketInfo>, _websocket_id: Option<ConnectionId>,
) -> Result<PrivateMessagesResponse, LemmyError> { ) -> Result<PrivateMessagesResponse, LemmyError> {
let data: &GetPrivateMessages = &self; let data: &GetPrivateMessages = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
@ -1521,18 +1503,16 @@ impl Perform for UserJoin {
async fn perform( async fn perform(
&self, &self,
context: &Data<LemmyContext>, context: &Data<LemmyContext>,
websocket_info: Option<WebsocketInfo>, websocket_id: Option<ConnectionId>,
) -> Result<UserJoinResponse, LemmyError> { ) -> Result<UserJoinResponse, LemmyError> {
let data: &UserJoin = &self; let data: &UserJoin = &self;
let user = get_user_from_jwt(&data.auth, context.pool()).await?; let user = get_user_from_jwt(&data.auth, context.pool()).await?;
if let Some(ws) = websocket_info { if let Some(ws_id) = websocket_id {
if let Some(id) = ws.id { context.chat_server().do_send(JoinUserRoom {
ws.chatserver.do_send(JoinUserRoom { user_id: user.id,
user_id: user.id, id: ws_id,
id, });
});
}
} }
Ok(UserJoinResponse { user_id: user.id }) Ok(UserJoinResponse { user_id: user.id })

View file

@ -75,7 +75,7 @@ async fn receive_create_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::CreatePost, op: UserOperation::CreatePost,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(create, &user, context).await?; announce_if_community_is_local(create, &user, context).await?;
@ -128,7 +128,7 @@ async fn receive_create_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::CreateComment, op: UserOperation::CreateComment,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(create, &user, context).await?; announce_if_community_is_local(create, &user, context).await?;

View file

@ -100,7 +100,7 @@ async fn receive_delete_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(delete, &user, context).await?; announce_if_community_is_local(delete, &user, context).await?;
@ -158,7 +158,7 @@ async fn receive_delete_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(delete, &user, context).await?; announce_if_community_is_local(delete, &user, context).await?;
@ -222,7 +222,7 @@ async fn receive_delete_community(
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
community_id, community_id,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(delete, &user, context).await?; announce_if_community_is_local(delete, &user, context).await?;

View file

@ -85,7 +85,7 @@ async fn receive_dislike_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::CreatePostLike, op: UserOperation::CreatePostLike,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(dislike, &user, context).await?; announce_if_community_is_local(dislike, &user, context).await?;
@ -142,7 +142,7 @@ async fn receive_dislike_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::CreateCommentLike, op: UserOperation::CreateCommentLike,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(dislike, &user, context).await?; announce_if_community_is_local(dislike, &user, context).await?;

View file

@ -76,7 +76,7 @@ async fn receive_like_post(like: Like, context: &LemmyContext) -> Result<HttpRes
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::CreatePostLike, op: UserOperation::CreatePostLike,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(like, &user, context).await?; announce_if_community_is_local(like, &user, context).await?;
@ -127,7 +127,7 @@ async fn receive_like_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::CreateCommentLike, op: UserOperation::CreateCommentLike,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(like, &user, context).await?; announce_if_community_is_local(like, &user, context).await?;

View file

@ -107,7 +107,7 @@ async fn receive_remove_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(remove, &mod_, context).await?; announce_if_community_is_local(remove, &mod_, context).await?;
@ -165,7 +165,7 @@ async fn receive_remove_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(remove, &mod_, context).await?; announce_if_community_is_local(remove, &mod_, context).await?;
@ -229,7 +229,7 @@ async fn receive_remove_community(
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
community_id, community_id,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(remove, &mod_, context).await?; announce_if_community_is_local(remove, &mod_, context).await?;

View file

@ -202,7 +202,7 @@ async fn receive_undo_delete_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
@ -261,7 +261,7 @@ async fn receive_undo_remove_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &mod_, context).await?; announce_if_community_is_local(undo, &mod_, context).await?;
@ -321,7 +321,7 @@ async fn receive_undo_delete_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
@ -381,7 +381,7 @@ async fn receive_undo_remove_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &mod_, context).await?; announce_if_community_is_local(undo, &mod_, context).await?;
@ -446,7 +446,7 @@ async fn receive_undo_delete_community(
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
community_id, community_id,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
@ -511,7 +511,7 @@ async fn receive_undo_remove_community(
op: UserOperation::EditCommunity, op: UserOperation::EditCommunity,
response: res, response: res,
community_id, community_id,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &mod_, context).await?; announce_if_community_is_local(undo, &mod_, context).await?;
@ -556,7 +556,7 @@ async fn receive_undo_like_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::CreateCommentLike, op: UserOperation::CreateCommentLike,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
@ -595,7 +595,7 @@ async fn receive_undo_like_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::CreatePostLike, op: UserOperation::CreatePostLike,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
@ -646,7 +646,7 @@ async fn receive_undo_dislike_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::CreateCommentLike, op: UserOperation::CreateCommentLike,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;
@ -691,7 +691,7 @@ async fn receive_undo_dislike_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::CreatePostLike, op: UserOperation::CreatePostLike,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(undo, &user, context).await?; announce_if_community_is_local(undo, &user, context).await?;

View file

@ -81,7 +81,7 @@ async fn receive_update_post(
context.chat_server().do_send(SendPost { context.chat_server().do_send(SendPost {
op: UserOperation::EditPost, op: UserOperation::EditPost,
post: res, post: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(update, &user, context).await?; announce_if_community_is_local(update, &user, context).await?;
@ -136,7 +136,7 @@ async fn receive_update_comment(
context.chat_server().do_send(SendComment { context.chat_server().do_send(SendComment {
op: UserOperation::EditComment, op: UserOperation::EditComment,
comment: res, comment: res,
my_id: None, websocket_id: None,
}); });
announce_if_community_is_local(update, &user, context).await?; announce_if_community_is_local(update, &user, context).await?;

View file

@ -152,7 +152,7 @@ async fn receive_create_private_message(
op: UserOperation::CreatePrivateMessage, op: UserOperation::CreatePrivateMessage,
response: res, response: res,
recipient_id, recipient_id,
my_id: None, websocket_id: None,
}); });
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
@ -201,7 +201,7 @@ async fn receive_update_private_message(
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
response: res, response: res,
recipient_id, recipient_id,
my_id: None, websocket_id: None,
}); });
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
@ -262,7 +262,7 @@ async fn receive_delete_private_message(
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
response: res, response: res,
recipient_id, recipient_id,
my_id: None, websocket_id: None,
}); });
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
@ -323,7 +323,7 @@ async fn receive_undo_delete_private_message(
op: UserOperation::EditPrivateMessage, op: UserOperation::EditPrivateMessage,
response: res, response: res,
recipient_id, recipient_id,
my_id: None, websocket_id: None,
}); });
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())

View file

@ -75,18 +75,14 @@ async fn main() -> Result<(), LemmyError> {
settings.bind, settings.port settings.bind, settings.port
); );
let activity_queue = create_activity_queue();
let chat_server =
ChatServer::startup(pool.clone(), rate_limiter.clone(), Client::default(), activity_queue.clone()).start();
// Create Http server with websocket support // Create Http server with websocket support
HttpServer::new(move || { HttpServer::new(move || {
let activity_queue = create_activity_queue();
let chat_server = ChatServer::startup(
pool.clone(),
rate_limiter.clone(),
Client::default(),
activity_queue.clone(),
)
.start();
let context = let context =
LemmyContext::create(pool.clone(), chat_server, Client::default(), activity_queue); LemmyContext::create(pool.clone(), chat_server.to_owned(), Client::default(), activity_queue.to_owned());
let settings = Settings::get(); let settings = Settings::get();
let rate_limiter = rate_limiter.clone(); let rate_limiter = rate_limiter.clone();
App::new() App::new()

View file

@ -1,7 +1,6 @@
use crate::{ use crate::{
api::{comment::*, community::*, post::*, site::*, user::*, Perform}, api::{comment::*, community::*, post::*, site::*, user::*, Perform},
rate_limit::RateLimit, rate_limit::RateLimit,
websocket::WebsocketInfo,
LemmyContext, LemmyContext,
}; };
use actix_web::{error::ErrorBadRequest, *}; use actix_web::{error::ErrorBadRequest, *};
@ -94,7 +93,8 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
web::post().to(route_post::<MarkCommentAsRead>), web::post().to(route_post::<MarkCommentAsRead>),
) )
.route("/like", web::post().to(route_post::<CreateCommentLike>)) .route("/like", web::post().to(route_post::<CreateCommentLike>))
.route("/save", web::put().to(route_post::<SaveComment>)), .route("/save", web::put().to(route_post::<SaveComment>))
.route("/list", web::get().to(route_get::<GetComments>)),
) )
// Private Message // Private Message
.service( .service(
@ -136,6 +136,7 @@ pub fn config(cfg: &mut web::ServiceConfig, rate_limit: &RateLimit) {
"/followed_communities", "/followed_communities",
web::get().to(route_get::<GetFollowedCommunities>), web::get().to(route_get::<GetFollowedCommunities>),
) )
.route("/join", web::post().to(route_post::<UserJoin>))
// Admin action. I don't like that it's in /user // Admin action. I don't like that it's in /user
.route("/ban", web::post().to(route_post::<BanUser>)) .route("/ban", web::post().to(route_post::<BanUser>))
// Account actions. I don't like that they're in /user maybe /accounts // Account actions. I don't like that they're in /user maybe /accounts
@ -180,13 +181,8 @@ where
Request: Perform, Request: Perform,
Request: Send + 'static, Request: Send + 'static,
{ {
let ws_info = WebsocketInfo {
chatserver: context.chat_server().to_owned(),
id: None,
};
let res = data let res = data
.perform(&context, Some(ws_info)) .perform(&context, None)
.await .await
.map(|json| HttpResponse::Ok().json(json)) .map(|json| HttpResponse::Ok().json(json))
.map_err(ErrorBadRequest)?; .map_err(ErrorBadRequest)?;

View file

@ -1,6 +1,5 @@
pub mod server; pub mod server;
use crate::ConnectionId;
use actix::prelude::*; use actix::prelude::*;
use diesel::{ use diesel::{
r2d2::{ConnectionManager, Pool}, r2d2::{ConnectionManager, Pool},
@ -10,7 +9,6 @@ use log::{error, info};
use rand::{rngs::ThreadRng, Rng}; use rand::{rngs::ThreadRng, Rng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use server::ChatServer;
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
str::FromStr, str::FromStr,
@ -77,9 +75,3 @@ pub enum UserOperation {
GetSiteConfig, GetSiteConfig,
SaveSiteConfig, SaveSiteConfig,
} }
#[derive(Clone)]
pub struct WebsocketInfo {
pub chatserver: Addr<ChatServer>,
pub id: Option<ConnectionId>,
}

View file

@ -59,7 +59,7 @@ pub struct StandardMessage {
pub struct SendAllMessage<Response> { pub struct SendAllMessage<Response> {
pub op: UserOperation, pub op: UserOperation,
pub response: Response, pub response: Response,
pub my_id: Option<ConnectionId>, pub websocket_id: Option<ConnectionId>,
} }
#[derive(Message)] #[derive(Message)]
@ -68,7 +68,7 @@ pub struct SendUserRoomMessage<Response> {
pub op: UserOperation, pub op: UserOperation,
pub response: Response, pub response: Response,
pub recipient_id: UserId, pub recipient_id: UserId,
pub my_id: Option<ConnectionId>, pub websocket_id: Option<ConnectionId>,
} }
#[derive(Message)] #[derive(Message)]
@ -77,7 +77,7 @@ pub struct SendCommunityRoomMessage<Response> {
pub op: UserOperation, pub op: UserOperation,
pub response: Response, pub response: Response,
pub community_id: CommunityId, pub community_id: CommunityId,
pub my_id: Option<ConnectionId>, pub websocket_id: Option<ConnectionId>,
} }
#[derive(Message)] #[derive(Message)]
@ -85,7 +85,7 @@ pub struct SendCommunityRoomMessage<Response> {
pub struct SendPost { pub struct SendPost {
pub op: UserOperation, pub op: UserOperation,
pub post: PostResponse, pub post: PostResponse,
pub my_id: Option<ConnectionId>, pub websocket_id: Option<ConnectionId>,
} }
#[derive(Message)] #[derive(Message)]
@ -93,7 +93,7 @@ pub struct SendPost {
pub struct SendComment { pub struct SendComment {
pub op: UserOperation, pub op: UserOperation,
pub comment: CommentResponse, pub comment: CommentResponse,
pub my_id: Option<ConnectionId>, pub websocket_id: Option<ConnectionId>,
} }
#[derive(Message)] #[derive(Message)]
@ -290,7 +290,7 @@ impl ChatServer {
op: &UserOperation, op: &UserOperation,
response: &Response, response: &Response,
post_id: PostId, post_id: PostId,
my_id: Option<ConnectionId>, websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError> ) -> Result<(), LemmyError>
where where
Response: Serialize, Response: Serialize,
@ -298,7 +298,7 @@ impl ChatServer {
let res_str = &to_json_string(op, response)?; let res_str = &to_json_string(op, response)?;
if let Some(sessions) = self.post_rooms.get(&post_id) { if let Some(sessions) = self.post_rooms.get(&post_id) {
for id in sessions { for id in sessions {
if let Some(my_id) = my_id { if let Some(my_id) = websocket_id {
if *id == my_id { if *id == my_id {
continue; continue;
} }
@ -314,7 +314,7 @@ impl ChatServer {
op: &UserOperation, op: &UserOperation,
response: &Response, response: &Response,
community_id: CommunityId, community_id: CommunityId,
my_id: Option<ConnectionId>, websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError> ) -> Result<(), LemmyError>
where where
Response: Serialize, Response: Serialize,
@ -322,7 +322,7 @@ impl ChatServer {
let res_str = &to_json_string(op, response)?; let res_str = &to_json_string(op, response)?;
if let Some(sessions) = self.community_rooms.get(&community_id) { if let Some(sessions) = self.community_rooms.get(&community_id) {
for id in sessions { for id in sessions {
if let Some(my_id) = my_id { if let Some(my_id) = websocket_id {
if *id == my_id { if *id == my_id {
continue; continue;
} }
@ -337,14 +337,14 @@ impl ChatServer {
&self, &self,
op: &UserOperation, op: &UserOperation,
response: &Response, response: &Response,
my_id: Option<ConnectionId>, websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError> ) -> Result<(), LemmyError>
where where
Response: Serialize, Response: Serialize,
{ {
let res_str = &to_json_string(op, response)?; let res_str = &to_json_string(op, response)?;
for id in self.sessions.keys() { for id in self.sessions.keys() {
if let Some(my_id) = my_id { if let Some(my_id) = websocket_id {
if *id == my_id { if *id == my_id {
continue; continue;
} }
@ -359,7 +359,7 @@ impl ChatServer {
op: &UserOperation, op: &UserOperation,
response: &Response, response: &Response,
recipient_id: UserId, recipient_id: UserId,
my_id: Option<ConnectionId>, websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError> ) -> Result<(), LemmyError>
where where
Response: Serialize, Response: Serialize,
@ -367,7 +367,7 @@ impl ChatServer {
let res_str = &to_json_string(op, response)?; let res_str = &to_json_string(op, response)?;
if let Some(sessions) = self.user_rooms.get(&recipient_id) { if let Some(sessions) = self.user_rooms.get(&recipient_id) {
for id in sessions { for id in sessions {
if let Some(my_id) = my_id { if let Some(my_id) = websocket_id {
if *id == my_id { if *id == my_id {
continue; continue;
} }
@ -382,7 +382,7 @@ impl ChatServer {
&self, &self,
user_operation: &UserOperation, user_operation: &UserOperation,
comment: &CommentResponse, comment: &CommentResponse,
my_id: Option<ConnectionId>, websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let mut comment_reply_sent = comment.clone(); let mut comment_reply_sent = comment.clone();
comment_reply_sent.comment.my_vote = None; comment_reply_sent.comment.my_vote = None;
@ -396,21 +396,26 @@ impl ChatServer {
user_operation, user_operation,
&comment_post_sent, &comment_post_sent,
comment_post_sent.comment.post_id, comment_post_sent.comment.post_id,
my_id, websocket_id,
)?; )?;
// Send it to the recipient(s) including the mentioned users // Send it to the recipient(s) including the mentioned users
for recipient_id in &comment_reply_sent.recipient_ids { for recipient_id in &comment_reply_sent.recipient_ids {
self.send_user_room_message(user_operation, &comment_reply_sent, *recipient_id, my_id)?; self.send_user_room_message(
user_operation,
&comment_reply_sent,
*recipient_id,
websocket_id,
)?;
} }
// Send it to the community too // Send it to the community too
self.send_community_room_message(user_operation, &comment_post_sent, 0, my_id)?; self.send_community_room_message(user_operation, &comment_post_sent, 0, websocket_id)?;
self.send_community_room_message( self.send_community_room_message(
user_operation, user_operation,
&comment_post_sent, &comment_post_sent,
comment.comment.community_id, comment.comment.community_id,
my_id, websocket_id,
)?; )?;
Ok(()) Ok(())
@ -420,7 +425,7 @@ impl ChatServer {
&self, &self,
user_operation: &UserOperation, user_operation: &UserOperation,
post: &PostResponse, post: &PostResponse,
my_id: Option<ConnectionId>, websocket_id: Option<ConnectionId>,
) -> Result<(), LemmyError> { ) -> Result<(), LemmyError> {
let community_id = post.post.community_id; let community_id = post.post.community_id;
@ -430,11 +435,11 @@ impl ChatServer {
post_sent.post.user_id = None; post_sent.post.user_id = None;
// Send it to /c/all and that community // Send it to /c/all and that community
self.send_community_room_message(user_operation, &post_sent, 0, my_id)?; self.send_community_room_message(user_operation, &post_sent, 0, websocket_id)?;
self.send_community_room_message(user_operation, &post_sent, community_id, my_id)?; self.send_community_room_message(user_operation, &post_sent, community_id, websocket_id)?;
// Send it to the post room // Send it to the post room
self.send_post_room_message(user_operation, &post_sent, post.post.id, my_id)?; self.send_post_room_message(user_operation, &post_sent, post.post.id, websocket_id)?;
Ok(()) Ok(())
} }
@ -478,7 +483,7 @@ impl ChatServer {
activity_queue, activity_queue,
}; };
let args = Args { let args = Args {
context: &context, context,
rate_limiter, rate_limiter,
id: msg.id, id: msg.id,
ip, ip,
@ -572,7 +577,7 @@ impl ChatServer {
} }
struct Args<'a> { struct Args<'a> {
context: &'a LemmyContext, context: LemmyContext,
rate_limiter: RateLimit, rate_limiter: RateLimit,
id: ConnectionId, id: ConnectionId,
ip: IPAddr, ip: IPAddr,
@ -594,18 +599,13 @@ where
data, data,
} = args; } = args;
let ws_info = WebsocketInfo {
chatserver: context.chat_server().to_owned(),
id: Some(id),
};
let data = data.to_string(); let data = data.to_string();
let op2 = op.clone(); let op2 = op.clone();
let fut = async move { let fut = async move {
let parsed_data: Data = serde_json::from_str(&data)?; let parsed_data: Data = serde_json::from_str(&data)?;
let res = parsed_data let res = parsed_data
.perform(&web::Data::new(context.to_owned()), Some(ws_info)) .perform(&web::Data::new(context), Some(id))
.await?; .await?;
to_json_string(&op, &res) to_json_string(&op, &res)
}; };
@ -699,7 +699,7 @@ where
fn handle(&mut self, msg: SendAllMessage<Response>, _: &mut Context<Self>) { fn handle(&mut self, msg: SendAllMessage<Response>, _: &mut Context<Self>) {
self self
.send_all_message(&msg.op, &msg.response, msg.my_id) .send_all_message(&msg.op, &msg.response, msg.websocket_id)
.ok(); .ok();
} }
} }
@ -712,7 +712,7 @@ where
fn handle(&mut self, msg: SendUserRoomMessage<Response>, _: &mut Context<Self>) { fn handle(&mut self, msg: SendUserRoomMessage<Response>, _: &mut Context<Self>) {
self self
.send_user_room_message(&msg.op, &msg.response, msg.recipient_id, msg.my_id) .send_user_room_message(&msg.op, &msg.response, msg.recipient_id, msg.websocket_id)
.ok(); .ok();
} }
} }
@ -725,7 +725,7 @@ where
fn handle(&mut self, msg: SendCommunityRoomMessage<Response>, _: &mut Context<Self>) { fn handle(&mut self, msg: SendCommunityRoomMessage<Response>, _: &mut Context<Self>) {
self self
.send_community_room_message(&msg.op, &msg.response, msg.community_id, msg.my_id) .send_community_room_message(&msg.op, &msg.response, msg.community_id, msg.websocket_id)
.ok(); .ok();
} }
} }
@ -734,7 +734,7 @@ impl Handler<SendPost> for ChatServer {
type Result = (); type Result = ();
fn handle(&mut self, msg: SendPost, _: &mut Context<Self>) { fn handle(&mut self, msg: SendPost, _: &mut Context<Self>) {
self.send_post(&msg.op, &msg.post, msg.my_id).ok(); self.send_post(&msg.op, &msg.post, msg.websocket_id).ok();
} }
} }
@ -742,7 +742,9 @@ impl Handler<SendComment> for ChatServer {
type Result = (); type Result = ();
fn handle(&mut self, msg: SendComment, _: &mut Context<Self>) { fn handle(&mut self, msg: SendComment, _: &mut Context<Self>) {
self.send_comment(&msg.op, &msg.comment, msg.my_id).ok(); self
.send_comment(&msg.op, &msg.comment, msg.websocket_id)
.ok();
} }
} }

1
ui/package.json vendored
View file

@ -37,6 +37,7 @@
"inferno-router": "^7.4.2", "inferno-router": "^7.4.2",
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",
"jwt-decode": "^2.2.0", "jwt-decode": "^2.2.0",
"lemmy-js-client": "^1.0.8",
"markdown-it": "^11.0.0", "markdown-it": "^11.0.0",
"markdown-it-container": "^3.0.0", "markdown-it-container": "^3.0.0",
"markdown-it-emoji": "^1.4.0", "markdown-it-emoji": "^1.4.0",

View file

@ -21,7 +21,7 @@ import {
API, API,
} from './shared'; } from './shared';
import { PostResponse } from '../interfaces'; import { PostResponse } from 'lemmy-js-client';
let postRes: PostResponse; let postRes: PostResponse;
@ -57,6 +57,11 @@ test('Create a comment', async () => {
expect(betaComment.score).toBe(1); expect(betaComment.score).toBe(1);
}); });
test('Create a comment in a non-existent post', async () => {
let commentRes = await createComment(alpha, -1);
expect(commentRes).toStrictEqual({ error: 'couldnt_find_post' });
});
test('Update a comment', async () => { test('Update a comment', async () => {
let commentRes = await createComment(alpha, postRes.post.id); let commentRes = await createComment(alpha, postRes.post.id);
let updateCommentRes = await updateComment(alpha, commentRes.comment.id); let updateCommentRes = await updateComment(alpha, commentRes.comment.id);
@ -131,7 +136,7 @@ test('Remove a comment from admin and community on the same instance', async ()
test('Remove a comment from admin and community on different instance', async () => { test('Remove a comment from admin and community on different instance', async () => {
let alphaUser = await registerUser(alpha); let alphaUser = await registerUser(alpha);
let newAlphaApi: API = { let newAlphaApi: API = {
url: alpha.url, client: alpha.client,
auth: alphaUser.jwt, auth: alphaUser.jwt,
}; };

View file

@ -2,6 +2,8 @@ import {
alpha, alpha,
beta, beta,
gamma, gamma,
delta,
epsilon,
setupLogins, setupLogins,
createPost, createPost,
updatePost, updatePost,
@ -22,11 +24,15 @@ beforeAll(async () => {
await setupLogins(); await setupLogins();
await followBeta(alpha); await followBeta(alpha);
await followBeta(gamma); await followBeta(gamma);
await followBeta(delta);
await followBeta(epsilon);
}); });
afterAll(async () => { afterAll(async () => {
await unfollowRemotes(alpha); await unfollowRemotes(alpha);
await unfollowRemotes(gamma); await unfollowRemotes(gamma);
await unfollowRemotes(delta);
await unfollowRemotes(epsilon);
}); });
test('Create a post', async () => { test('Create a post', async () => {
@ -45,6 +51,19 @@ test('Create a post', async () => {
expect(betaPost.community_local).toBe(true); expect(betaPost.community_local).toBe(true);
expect(betaPost.creator_local).toBe(false); expect(betaPost.creator_local).toBe(false);
expect(betaPost.score).toBe(1); expect(betaPost.score).toBe(1);
// Delta only follows beta, so it should not see an alpha ap_id
let searchDelta = await searchPost(delta, postRes.post);
expect(searchDelta.posts[0]).toBeUndefined();
// Epsilon has alpha blocked, it should not see the alpha post
let searchEpsilon = await searchPost(epsilon, postRes.post);
expect(searchEpsilon.posts[0]).toBeUndefined();
});
test('Create a post in a non-existent community', async () => {
let postRes = await createPost(alpha, -2);
expect(postRes).toStrictEqual({ error: 'couldnt_create_post' });
}); });
test('Unlike a post', async () => { test('Unlike a post', async () => {
@ -53,6 +72,10 @@ test('Unlike a post', async () => {
let unlike = await likePost(alpha, 0, postRes.post); let unlike = await likePost(alpha, 0, postRes.post);
expect(unlike.post.score).toBe(0); expect(unlike.post.score).toBe(0);
// Try to unlike it again, make sure it stays at 0
let unlike2 = await likePost(alpha, 0, postRes.post);
expect(unlike2.post.score).toBe(0);
// Make sure that post is unliked on beta // Make sure that post is unliked on beta
let searchBeta = await searchPost(beta, postRes.post); let searchBeta = await searchPost(beta, postRes.post);
let betaPost = searchBeta.posts[0]; let betaPost = searchBeta.posts[0];
@ -67,10 +90,22 @@ test('Update a post', async () => {
let search = await searchForBetaCommunity(alpha); let search = await searchForBetaCommunity(alpha);
let postRes = await createPost(alpha, search.communities[0].id); let postRes = await createPost(alpha, search.communities[0].id);
let updatedName = 'A jest test federated post, updated';
let updatedPost = await updatePost(alpha, postRes.post); let updatedPost = await updatePost(alpha, postRes.post);
expect(updatedPost.post.name).toBe('A jest test federated post, updated'); expect(updatedPost.post.name).toBe(updatedName);
expect(updatedPost.post.community_local).toBe(false); expect(updatedPost.post.community_local).toBe(false);
expect(updatedPost.post.creator_local).toBe(true); expect(updatedPost.post.creator_local).toBe(true);
// Make sure that post is updated on beta
let searchBeta = await searchPost(beta, postRes.post);
let betaPost = searchBeta.posts[0];
expect(betaPost.community_local).toBe(true);
expect(betaPost.creator_local).toBe(false);
expect(betaPost.name).toBe(updatedName);
// Make sure lemmy beta cannot update the post
let updatedPostBeta = await updatePost(beta, betaPost);
expect(updatedPostBeta).toStrictEqual({ error: 'no_post_edit_allowed' });
}); });
test('Sticky a post', async () => { test('Sticky a post', async () => {
@ -97,6 +132,15 @@ test('Sticky a post', async () => {
expect(betaPost2.community_local).toBe(true); expect(betaPost2.community_local).toBe(true);
expect(betaPost2.creator_local).toBe(false); expect(betaPost2.creator_local).toBe(false);
expect(betaPost2.stickied).toBe(false); expect(betaPost2.stickied).toBe(false);
// Make sure that gamma cannot sticky the post on beta
let searchGamma = await searchPost(gamma, postRes.post);
let gammaPost = searchGamma.posts[0];
let gammaTrySticky = await stickyPost(gamma, true, gammaPost);
let searchBeta3 = await searchPost(beta, postRes.post);
let betaPost3 = searchBeta3.posts[0];
expect(gammaTrySticky.post.stickied).toBe(true);
expect(betaPost3.stickied).toBe(false);
}); });
test('Lock a post', async () => { test('Lock a post', async () => {
@ -152,6 +196,10 @@ test('Delete a post', async () => {
// Make sure lemmy beta sees post is undeleted // Make sure lemmy beta sees post is undeleted
let betaPost2 = await getPost(beta, createFakeBetaPostToGetId); let betaPost2 = await getPost(beta, createFakeBetaPostToGetId);
expect(betaPost2.post.deleted).toBe(false); expect(betaPost2.post.deleted).toBe(false);
// Make sure lemmy beta cannot delete the post
let deletedPostBeta = await deletePost(beta, true, betaPost2.post);
expect(deletedPostBeta).toStrictEqual({ error: 'no_post_edit_allowed' });
}); });
test('Remove a post from admin and community on different instance', async () => { test('Remove a post from admin and community on different instance', async () => {

View file

@ -1,5 +1,3 @@
import fetch from 'node-fetch';
import { import {
LoginForm, LoginForm,
LoginResponse, LoginResponse,
@ -20,15 +18,21 @@ import {
CommentForm, CommentForm,
DeleteCommentForm, DeleteCommentForm,
RemoveCommentForm, RemoveCommentForm,
SearchForm,
CommentResponse, CommentResponse,
CommunityForm, CommunityForm,
DeleteCommunityForm, DeleteCommunityForm,
RemoveCommunityForm, RemoveCommunityForm,
GetUserMentionsForm,
CommentLikeForm, CommentLikeForm,
CreatePostLikeForm, CreatePostLikeForm,
PrivateMessageForm, PrivateMessageForm,
EditPrivateMessageForm, EditPrivateMessageForm,
DeletePrivateMessageForm, DeletePrivateMessageForm,
GetFollowedCommunitiesForm,
GetPrivateMessagesForm,
GetSiteForm,
GetPostForm,
PrivateMessageResponse, PrivateMessageResponse,
PrivateMessagesResponse, PrivateMessagesResponse,
GetUserMentionsResponse, GetUserMentionsResponse,
@ -36,73 +40,79 @@ import {
SortType, SortType,
ListingType, ListingType,
GetSiteResponse, GetSiteResponse,
} from '../interfaces'; SearchType,
LemmyHttp,
} from 'lemmy-js-client';
export interface API { export interface API {
url: string; client: LemmyHttp;
auth?: string; auth?: string;
} }
function apiUrl(api: API) {
return `${api.url}/api/v1`;
}
export let alpha: API = { export let alpha: API = {
url: 'http://localhost:8540', client: new LemmyHttp('http://localhost:8540/api/v1'),
}; };
export let beta: API = { export let beta: API = {
url: 'http://localhost:8550', client: new LemmyHttp('http://localhost:8550/api/v1'),
}; };
export let gamma: API = { export let gamma: API = {
url: 'http://localhost:8560', client: new LemmyHttp('http://localhost:8560/api/v1'),
};
export let delta: API = {
client: new LemmyHttp('http://localhost:8570/api/v1'),
};
export let epsilon: API = {
client: new LemmyHttp('http://localhost:8580/api/v1'),
}; };
export async function setupLogins() { export async function setupLogins() {
let form: LoginForm = { let formAlpha: LoginForm = {
username_or_email: 'lemmy_alpha', username_or_email: 'lemmy_alpha',
password: 'lemmy', password: 'lemmy',
}; };
let resAlpha = alpha.client.login(formAlpha);
let resA: Promise<LoginResponse> = fetch(`${apiUrl(alpha)}/user/login`, { let formBeta = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(form),
}).then(d => d.json());
let formB = {
username_or_email: 'lemmy_beta', username_or_email: 'lemmy_beta',
password: 'lemmy', password: 'lemmy',
}; };
let resBeta = beta.client.login(formBeta);
let resB: Promise<LoginResponse> = fetch(`${apiUrl(beta)}/user/login`, { let formGamma = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(formB),
}).then(d => d.json());
let formC = {
username_or_email: 'lemmy_gamma', username_or_email: 'lemmy_gamma',
password: 'lemmy', password: 'lemmy',
}; };
let resGamma = gamma.client.login(formGamma);
let resG: Promise<LoginResponse> = fetch(`${apiUrl(gamma)}/user/login`, { let formDelta = {
method: 'POST', username_or_email: 'lemmy_delta',
headers: { password: 'lemmy',
'Content-Type': 'application/json', };
}, let resDelta = delta.client.login(formDelta);
body: wrapper(formC),
}).then(d => d.json()); let formEpsilon = {
username_or_email: 'lemmy_epsilon',
password: 'lemmy',
};
let resEpsilon = epsilon.client.login(formEpsilon);
let res = await Promise.all([
resAlpha,
resBeta,
resGamma,
resDelta,
resEpsilon,
]);
let res = await Promise.all([resA, resB, resG]);
alpha.auth = res[0].jwt; alpha.auth = res[0].jwt;
beta.auth = res[1].jwt; beta.auth = res[1].jwt;
gamma.auth = res[2].jwt; gamma.auth = res[2].jwt;
delta.auth = res[3].jwt;
epsilon.auth = res[4].jwt;
} }
export async function createPost( export async function createPost(
@ -110,40 +120,24 @@ export async function createPost(
community_id: number community_id: number
): Promise<PostResponse> { ): Promise<PostResponse> {
let name = 'A jest test post'; let name = 'A jest test post';
let postForm: PostForm = { let form: PostForm = {
name, name,
auth: api.auth, auth: api.auth,
community_id, community_id,
nsfw: false, nsfw: false,
}; };
return api.client.createPost(form);
let createPostRes: PostResponse = await fetch(`${apiUrl(api)}/post`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(postForm),
}).then(d => d.json());
return createPostRes;
} }
export async function updatePost(api: API, post: Post): Promise<PostResponse> { export async function updatePost(api: API, post: Post): Promise<PostResponse> {
let name = 'A jest test federated post, updated'; let name = 'A jest test federated post, updated';
let postForm: PostForm = { let form: PostForm = {
name, name,
edit_id: post.id, edit_id: post.id,
auth: api.auth, auth: api.auth,
nsfw: false, nsfw: false,
}; };
return api.client.editPost(form);
let updateResponse: PostResponse = await fetch(`${apiUrl(api)}/post`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(postForm),
}).then(d => d.json());
return updateResponse;
} }
export async function deletePost( export async function deletePost(
@ -151,20 +145,12 @@ export async function deletePost(
deleted: boolean, deleted: boolean,
post: Post post: Post
): Promise<PostResponse> { ): Promise<PostResponse> {
let deletePostForm: DeletePostForm = { let form: DeletePostForm = {
edit_id: post.id, edit_id: post.id,
deleted: deleted, deleted: deleted,
auth: api.auth, auth: api.auth,
}; };
return api.client.deletePost(form);
let deletePostRes: PostResponse = await fetch(`${apiUrl(api)}/post/delete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(deletePostForm),
}).then(d => d.json());
return deletePostRes;
} }
export async function removePost( export async function removePost(
@ -172,20 +158,12 @@ export async function removePost(
removed: boolean, removed: boolean,
post: Post post: Post
): Promise<PostResponse> { ): Promise<PostResponse> {
let removePostForm: RemovePostForm = { let form: RemovePostForm = {
edit_id: post.id, edit_id: post.id,
removed, removed,
auth: api.auth, auth: api.auth,
}; };
return api.client.removePost(form);
let removePostRes: PostResponse = await fetch(`${apiUrl(api)}/post/remove`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(removePostForm),
}).then(d => d.json());
return removePostRes;
} }
export async function stickyPost( export async function stickyPost(
@ -193,21 +171,12 @@ export async function stickyPost(
stickied: boolean, stickied: boolean,
post: Post post: Post
): Promise<PostResponse> { ): Promise<PostResponse> {
let stickyPostForm: StickyPostForm = { let form: StickyPostForm = {
edit_id: post.id, edit_id: post.id,
stickied, stickied,
auth: api.auth, auth: api.auth,
}; };
return api.client.stickyPost(form);
let stickyRes: PostResponse = await fetch(`${apiUrl(api)}/post/sticky`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(stickyPostForm),
}).then(d => d.json());
return stickyRes;
} }
export async function lockPost( export async function lockPost(
@ -215,57 +184,46 @@ export async function lockPost(
locked: boolean, locked: boolean,
post: Post post: Post
): Promise<PostResponse> { ): Promise<PostResponse> {
let lockPostForm: LockPostForm = { let form: LockPostForm = {
edit_id: post.id, edit_id: post.id,
locked, locked,
auth: api.auth, auth: api.auth,
}; };
return api.client.lockPost(form);
let lockRes: PostResponse = await fetch(`${apiUrl(api)}/post/lock`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(lockPostForm),
}).then(d => d.json());
return lockRes;
} }
export async function searchPost( export async function searchPost(
api: API, api: API,
post: Post post: Post
): Promise<SearchResponse> { ): Promise<SearchResponse> {
let searchUrl = `${apiUrl(api)}/search?q=${post.ap_id}&type_=All&sort=TopAll`; let form: SearchForm = {
let searchResponse: SearchResponse = await fetch(searchUrl, { q: post.ap_id,
method: 'GET', type_: SearchType.All,
}).then(d => d.json()); sort: SortType.TopAll,
return searchResponse; };
return api.client.search(form);
} }
export async function getPost( export async function getPost(
api: API, api: API,
post_id: number post_id: number
): Promise<GetPostResponse> { ): Promise<GetPostResponse> {
let getPostUrl = `${apiUrl(api)}/post?id=${post_id}`; let form: GetPostForm = {
let getPostRes: GetPostResponse = await fetch(getPostUrl, { id: post_id,
method: 'GET', };
}).then(d => d.json()); return api.client.getPost(form);
return getPostRes;
} }
export async function searchComment( export async function searchComment(
api: API, api: API,
comment: Comment comment: Comment
): Promise<SearchResponse> { ): Promise<SearchResponse> {
let searchUrl = `${apiUrl(api)}/search?q=${ let form: SearchForm = {
comment.ap_id q: comment.ap_id,
}&type_=All&sort=TopAll`; type_: SearchType.All,
let searchResponse: SearchResponse = await fetch(searchUrl, { sort: SortType.TopAll,
method: 'GET', };
}).then(d => d.json()); return api.client.search(form);
return searchResponse;
} }
export async function searchForBetaCommunity( export async function searchForBetaCommunity(
@ -273,14 +231,12 @@ export async function searchForBetaCommunity(
): Promise<SearchResponse> { ): Promise<SearchResponse> {
// Make sure lemmy-beta/c/main is cached on lemmy_alpha // Make sure lemmy-beta/c/main is cached on lemmy_alpha
// Use short-hand search url // Use short-hand search url
let searchUrl = `${apiUrl( let form: SearchForm = {
api q: '!main@lemmy-beta:8550',
)}/search?q=!main@lemmy-beta:8550&type_=All&sort=TopAll`; type_: SearchType.All,
sort: SortType.TopAll,
let searchResponse: SearchResponse = await fetch(searchUrl, { };
method: 'GET', return api.client.search(form);
}).then(d => d.json());
return searchResponse;
} }
export async function searchForUser( export async function searchForUser(
@ -289,14 +245,12 @@ export async function searchForUser(
): Promise<SearchResponse> { ): Promise<SearchResponse> {
// Make sure lemmy-beta/c/main is cached on lemmy_alpha // Make sure lemmy-beta/c/main is cached on lemmy_alpha
// Use short-hand search url // Use short-hand search url
let searchUrl = `${apiUrl( let form: SearchForm = {
api q: apShortname,
)}/search?q=${apShortname}&type_=All&sort=TopAll`; type_: SearchType.All,
sort: SortType.TopAll,
let searchResponse: SearchResponse = await fetch(searchUrl, { };
method: 'GET', return api.client.search(form);
}).then(d => d.json());
return searchResponse;
} }
export async function followCommunity( export async function followCommunity(
@ -304,41 +258,21 @@ export async function followCommunity(
follow: boolean, follow: boolean,
community_id: number community_id: number
): Promise<CommunityResponse> { ): Promise<CommunityResponse> {
let followForm: FollowCommunityForm = { let form: FollowCommunityForm = {
community_id, community_id,
follow, follow,
auth: api.auth, auth: api.auth,
}; };
return api.client.followCommunity(form);
let followRes: CommunityResponse = await fetch(
`${apiUrl(api)}/community/follow`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(followForm),
}
)
.then(d => d.json())
.catch(_e => {});
return followRes;
} }
export async function checkFollowedCommunities( export async function checkFollowedCommunities(
api: API api: API
): Promise<GetFollowedCommunitiesResponse> { ): Promise<GetFollowedCommunitiesResponse> {
let followedCommunitiesUrl = `${apiUrl( let form: GetFollowedCommunitiesForm = {
api auth: api.auth,
)}/user/followed_communities?&auth=${api.auth}`; };
let followedCommunitiesRes: GetFollowedCommunitiesResponse = await fetch( return api.client.getFollowedCommunities(form);
followedCommunitiesUrl,
{
method: 'GET',
}
).then(d => d.json());
return followedCommunitiesRes;
} }
export async function likePost( export async function likePost(
@ -346,21 +280,13 @@ export async function likePost(
score: number, score: number,
post: Post post: Post
): Promise<PostResponse> { ): Promise<PostResponse> {
let likePostForm: CreatePostLikeForm = { let form: CreatePostLikeForm = {
post_id: post.id, post_id: post.id,
score: score, score: score,
auth: api.auth, auth: api.auth,
}; };
let likePostRes: PostResponse = await fetch(`${apiUrl(api)}/post/like`, { return api.client.likePost(form);
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(likePostForm),
}).then(d => d.json());
return likePostRes;
} }
export async function createComment( export async function createComment(
@ -369,21 +295,13 @@ export async function createComment(
parent_id?: number, parent_id?: number,
content = 'a jest test comment' content = 'a jest test comment'
): Promise<CommentResponse> { ): Promise<CommentResponse> {
let commentForm: CommentForm = { let form: CommentForm = {
content, content,
post_id, post_id,
parent_id, parent_id,
auth: api.auth, auth: api.auth,
}; };
return api.client.createComment(form);
let createResponse: CommentResponse = await fetch(`${apiUrl(api)}/comment`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(commentForm),
}).then(d => d.json());
return createResponse;
} }
export async function updateComment( export async function updateComment(
@ -391,20 +309,12 @@ export async function updateComment(
edit_id: number, edit_id: number,
content = 'A jest test federated comment update' content = 'A jest test federated comment update'
): Promise<CommentResponse> { ): Promise<CommentResponse> {
let commentForm: CommentForm = { let form: CommentForm = {
content, content,
edit_id, edit_id,
auth: api.auth, auth: api.auth,
}; };
return api.client.editComment(form);
let updateResponse: CommentResponse = await fetch(`${apiUrl(api)}/comment`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(commentForm),
}).then(d => d.json());
return updateResponse;
} }
export async function deleteComment( export async function deleteComment(
@ -412,23 +322,12 @@ export async function deleteComment(
deleted: boolean, deleted: boolean,
edit_id: number edit_id: number
): Promise<CommentResponse> { ): Promise<CommentResponse> {
let deleteCommentForm: DeleteCommentForm = { let form: DeleteCommentForm = {
edit_id, edit_id,
deleted, deleted,
auth: api.auth, auth: api.auth,
}; };
return api.client.deleteComment(form);
let deleteCommentRes: CommentResponse = await fetch(
`${apiUrl(api)}/comment/delete`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(deleteCommentForm),
}
).then(d => d.json());
return deleteCommentRes;
} }
export async function removeComment( export async function removeComment(
@ -436,33 +335,21 @@ export async function removeComment(
removed: boolean, removed: boolean,
edit_id: number edit_id: number
): Promise<CommentResponse> { ): Promise<CommentResponse> {
let removeCommentForm: RemoveCommentForm = { let form: RemoveCommentForm = {
edit_id, edit_id,
removed, removed,
auth: api.auth, auth: api.auth,
}; };
return api.client.removeComment(form);
let removeCommentRes: CommentResponse = await fetch(
`${apiUrl(api)}/comment/remove`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(removeCommentForm),
}
).then(d => d.json());
return removeCommentRes;
} }
export async function getMentions(api: API): Promise<GetUserMentionsResponse> { export async function getMentions(api: API): Promise<GetUserMentionsResponse> {
let getMentionUrl = `${apiUrl( let form: GetUserMentionsForm = {
api sort: SortType.New,
)}/user/mention?sort=New&unread_only=false&auth=${api.auth}`; unread_only: false,
let getMentionsRes: GetUserMentionsResponse = await fetch(getMentionUrl, { auth: api.auth,
method: 'GET', };
}).then(d => d.json()); return api.client.getUserMentions(form);
return getMentionsRes;
} }
export async function likeComment( export async function likeComment(
@ -470,48 +357,26 @@ export async function likeComment(
score: number, score: number,
comment: Comment comment: Comment
): Promise<CommentResponse> { ): Promise<CommentResponse> {
let likeCommentForm: CommentLikeForm = { let form: CommentLikeForm = {
comment_id: comment.id, comment_id: comment.id,
score, score,
auth: api.auth, auth: api.auth,
}; };
return api.client.likeComment(form);
let likeCommentRes: CommentResponse = await fetch(
`${apiUrl(api)}/comment/like`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(likeCommentForm),
}
).then(d => d.json());
return likeCommentRes;
} }
export async function createCommunity( export async function createCommunity(
api: API, api: API,
name_: string = randomString(5) name_: string = randomString(5)
): Promise<CommunityResponse> { ): Promise<CommunityResponse> {
let communityForm: CommunityForm = { let form: CommunityForm = {
name: name_, name: name_,
title: name_, title: name_,
category_id: 1, category_id: 1,
nsfw: false, nsfw: false,
auth: api.auth, auth: api.auth,
}; };
return api.client.createCommunity(form);
let createCommunityRes: CommunityResponse = await fetch(
`${apiUrl(api)}/community`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(communityForm),
}
).then(d => d.json());
return createCommunityRes;
} }
export async function deleteCommunity( export async function deleteCommunity(
@ -519,23 +384,12 @@ export async function deleteCommunity(
deleted: boolean, deleted: boolean,
edit_id: number edit_id: number
): Promise<CommunityResponse> { ): Promise<CommunityResponse> {
let deleteCommunityForm: DeleteCommunityForm = { let form: DeleteCommunityForm = {
edit_id, edit_id,
deleted, deleted,
auth: api.auth, auth: api.auth,
}; };
return api.client.deleteCommunity(form);
let deleteResponse: CommunityResponse = await fetch(
`${apiUrl(api)}/community/delete`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(deleteCommunityForm),
}
).then(d => d.json());
return deleteResponse;
} }
export async function removeCommunity( export async function removeCommunity(
@ -543,23 +397,12 @@ export async function removeCommunity(
removed: boolean, removed: boolean,
edit_id: number edit_id: number
): Promise<CommunityResponse> { ): Promise<CommunityResponse> {
let removeCommunityForm: RemoveCommunityForm = { let form: RemoveCommunityForm = {
edit_id, edit_id,
removed, removed,
auth: api.auth, auth: api.auth,
}; };
return api.client.removeCommunity(form);
let removeResponse: CommunityResponse = await fetch(
`${apiUrl(api)}/community/remove`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(removeCommunityForm),
}
).then(d => d.json());
return removeResponse;
} }
export async function createPrivateMessage( export async function createPrivateMessage(
@ -567,23 +410,12 @@ export async function createPrivateMessage(
recipient_id: number recipient_id: number
): Promise<PrivateMessageResponse> { ): Promise<PrivateMessageResponse> {
let content = 'A jest test federated private message'; let content = 'A jest test federated private message';
let privateMessageForm: PrivateMessageForm = { let form: PrivateMessageForm = {
content, content,
recipient_id, recipient_id,
auth: api.auth, auth: api.auth,
}; };
return api.client.createPrivateMessage(form);
let createRes: PrivateMessageResponse = await fetch(
`${apiUrl(api)}/private_message`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(privateMessageForm),
}
).then(d => d.json());
return createRes;
} }
export async function updatePrivateMessage( export async function updatePrivateMessage(
@ -591,23 +423,12 @@ export async function updatePrivateMessage(
edit_id: number edit_id: number
): Promise<PrivateMessageResponse> { ): Promise<PrivateMessageResponse> {
let updatedContent = 'A jest test federated private message edited'; let updatedContent = 'A jest test federated private message edited';
let updatePrivateMessageForm: EditPrivateMessageForm = { let form: EditPrivateMessageForm = {
content: updatedContent, content: updatedContent,
edit_id, edit_id,
auth: api.auth, auth: api.auth,
}; };
return api.client.editPrivateMessage(form);
let updateRes: PrivateMessageResponse = await fetch(
`${apiUrl(api)}/private_message`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(updatePrivateMessageForm),
}
).then(d => d.json());
return updateRes;
} }
export async function deletePrivateMessage( export async function deletePrivateMessage(
@ -615,50 +436,26 @@ export async function deletePrivateMessage(
deleted: boolean, deleted: boolean,
edit_id: number edit_id: number
): Promise<PrivateMessageResponse> { ): Promise<PrivateMessageResponse> {
let deletePrivateMessageForm: DeletePrivateMessageForm = { let form: DeletePrivateMessageForm = {
deleted, deleted,
edit_id, edit_id,
auth: api.auth, auth: api.auth,
}; };
return api.client.deletePrivateMessage(form);
let deleteRes: PrivateMessageResponse = await fetch(
`${apiUrl(api)}/private_message/delete`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(deletePrivateMessageForm),
}
).then(d => d.json());
return deleteRes;
} }
export async function registerUser( export async function registerUser(
api: API, api: API,
username: string = randomString(5) username: string = randomString(5)
): Promise<LoginResponse> { ): Promise<LoginResponse> {
let registerForm: RegisterForm = { let form: RegisterForm = {
username, username,
password: 'test', password: 'test',
password_verify: 'test', password_verify: 'test',
admin: false, admin: false,
show_nsfw: true, show_nsfw: true,
}; };
return api.client.register(form);
let registerRes: Promise<LoginResponse> = fetch(
`${apiUrl(api)}/user/register`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(registerForm),
}
).then(d => d.json());
return registerRes;
} }
export async function saveUserSettingsBio( export async function saveUserSettingsBio(
@ -668,54 +465,36 @@ export async function saveUserSettingsBio(
let form: UserSettingsForm = { let form: UserSettingsForm = {
show_nsfw: true, show_nsfw: true,
theme: 'darkly', theme: 'darkly',
default_sort_type: SortType.Active, default_sort_type: Object.keys(SortType).indexOf(SortType.Active),
default_listing_type: ListingType.All, default_listing_type: Object.keys(ListingType).indexOf(ListingType.All),
lang: 'en', lang: 'en',
show_avatars: true, show_avatars: true,
send_notifications_to_email: false, send_notifications_to_email: false,
bio: 'a changed bio', bio: 'a changed bio',
auth, auth,
}; };
return api.client.saveUserSettings(form);
let res: Promise<LoginResponse> = fetch(
`${apiUrl(api)}/user/save_user_settings`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: wrapper(form),
}
).then(d => d.json());
return res;
} }
export async function getSite( export async function getSite(
api: API, api: API,
auth: string auth: string
): Promise<GetSiteResponse> { ): Promise<GetSiteResponse> {
let siteUrl = `${apiUrl(api)}/site?auth=${auth}`; let form: GetSiteForm = {
auth,
let res: GetSiteResponse = await fetch(siteUrl, { };
method: 'GET', return api.client.getSite(form);
}).then(d => d.json());
return res;
} }
export async function listPrivateMessages( export async function listPrivateMessages(
api: API api: API
): Promise<PrivateMessagesResponse> { ): Promise<PrivateMessagesResponse> {
let getPrivateMessagesUrl = `${apiUrl(api)}/private_message/list?auth=${ let form: GetPrivateMessagesForm = {
api.auth auth: api.auth,
}&unread_only=false&limit=999`; unread_only: false,
limit: 999,
let getPrivateMessagesRes: PrivateMessagesResponse = await fetch( };
getPrivateMessagesUrl, return api.client.getPrivateMessages(form);
{
method: 'GET',
}
).then(d => d.json());
return getPrivateMessagesRes;
} }
export async function unfollowRemotes( export async function unfollowRemotes(

View file

@ -9,7 +9,7 @@ import {
SiteConfigForm, SiteConfigForm,
GetSiteConfigResponse, GetSiteConfigResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { wsJsonToRes, capitalizeFirstLetter, toast, randomStr } from '../utils'; import { wsJsonToRes, capitalizeFirstLetter, toast, randomStr } from '../utils';
import autosize from 'autosize'; import autosize from 'autosize';

View file

@ -8,7 +8,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
UserOperation, UserOperation,
CommentResponse, CommentResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { capitalizeFirstLetter, wsJsonToRes } from '../utils'; import { capitalizeFirstLetter, wsJsonToRes } from '../utils';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -16,10 +16,9 @@ import {
AddAdminForm, AddAdminForm,
TransferCommunityForm, TransferCommunityForm,
TransferSiteForm, TransferSiteForm,
BanType,
CommentSortType,
SortType, SortType,
} from '../interfaces'; } from 'lemmy-js-client';
import { CommentSortType, BanType } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
mdToHtml, mdToHtml,

View file

@ -1,11 +1,11 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { CommentSortType } from '../interfaces';
import { import {
CommentNode as CommentNodeI, CommentNode as CommentNodeI,
CommunityUser, CommunityUser,
UserView, UserView,
CommentSortType,
SortType, SortType,
} from '../interfaces'; } from 'lemmy-js-client';
import { commentSort, commentSortSortType } from '../utils'; import { commentSort, commentSortSortType } from '../utils';
import { CommentNode } from './comment-node'; import { CommentNode } from './comment-node';

View file

@ -13,7 +13,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { wsJsonToRes, toast, getPageFromProps } from '../utils'; import { wsJsonToRes, toast, getPageFromProps } from '../utils';
import { CommunityLink } from './community-link'; import { CommunityLink } from './community-link';
@ -218,7 +218,7 @@ export class Communities extends Component<any, CommunitiesState> {
refetch() { refetch() {
let listCommunitiesForm: ListCommunitiesForm = { let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
limit: communityLimit, limit: communityLimit,
page: this.state.page, page: this.state.page,
}; };

View file

@ -9,12 +9,12 @@ import {
ListCategoriesResponse, ListCategoriesResponse,
CommunityResponse, CommunityResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; Community,
} from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { wsJsonToRes, capitalizeFirstLetter, toast, randomStr } from '../utils'; import { wsJsonToRes, capitalizeFirstLetter, toast, randomStr } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { Community } from '../interfaces';
import { MarkdownTextArea } from './markdown-textarea'; import { MarkdownTextArea } from './markdown-textarea';
import { ImageUploadForm } from './image-upload-form'; import { ImageUploadForm } from './image-upload-form';

View file

@ -1,6 +1,6 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { Link } from 'inferno-router'; import { Link } from 'inferno-router';
import { Community } from '../interfaces'; import { Community } from 'lemmy-js-client';
import { hostname, pictrsAvatarThumbnail, showAvatars } from '../utils'; import { hostname, pictrsAvatarThumbnail, showAvatars } from '../utils';
interface CommunityOther { interface CommunityOther {

View file

@ -2,6 +2,7 @@ import { Component, linkEvent } from 'inferno';
import { Helmet } from 'inferno-helmet'; import { Helmet } from 'inferno-helmet';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { retryWhen, delay, take } from 'rxjs/operators'; import { retryWhen, delay, take } from 'rxjs/operators';
import { DataType } from '../interfaces';
import { import {
UserOperation, UserOperation,
Community as CommunityI, Community as CommunityI,
@ -14,7 +15,6 @@ import {
GetPostsForm, GetPostsForm,
GetCommunityForm, GetCommunityForm,
ListingType, ListingType,
DataType,
GetPostsResponse, GetPostsResponse,
PostResponse, PostResponse,
AddModToCommunityResponse, AddModToCommunityResponse,
@ -26,7 +26,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { PostListings } from './post-listings'; import { PostListings } from './post-listings';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
@ -78,7 +78,7 @@ interface CommunityProps {
interface UrlParams { interface UrlParams {
dataType?: string; dataType?: string;
sort?: string; sort?: SortType;
page?: number; page?: number;
} }
@ -287,9 +287,7 @@ export class Community extends Component<any, State> {
<SortSelect sort={this.state.sort} onChange={this.handleSortChange} /> <SortSelect sort={this.state.sort} onChange={this.handleSortChange} />
</span> </span>
<a <a
href={`/feeds/c/${this.state.communityName}.xml?sort=${ href={`/feeds/c/${this.state.communityName}.xml?sort=${this.state.sort}`}
SortType[this.state.sort]
}`}
target="_blank" target="_blank"
title="RSS" title="RSS"
rel="noopener" rel="noopener"
@ -336,20 +334,18 @@ export class Community extends Component<any, State> {
} }
handleSortChange(val: SortType) { handleSortChange(val: SortType) {
this.updateUrl({ sort: SortType[val].toLowerCase(), page: 1 }); this.updateUrl({ sort: val, page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
handleDataTypeChange(val: DataType) { handleDataTypeChange(val: DataType) {
this.updateUrl({ dataType: DataType[val].toLowerCase(), page: 1 }); this.updateUrl({ dataType: DataType[val], page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
updateUrl(paramUpdates: UrlParams) { updateUrl(paramUpdates: UrlParams) {
const dataTypeStr = const dataTypeStr = paramUpdates.dataType || DataType[this.state.dataType];
paramUpdates.dataType || DataType[this.state.dataType].toLowerCase(); const sortStr = paramUpdates.sort || this.state.sort;
const sortStr =
paramUpdates.sort || SortType[this.state.sort].toLowerCase();
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;
this.props.history.push( this.props.history.push(
`/c/${this.state.community.name}/data_type/${dataTypeStr}/sort/${sortStr}/page/${page}` `/c/${this.state.community.name}/data_type/${dataTypeStr}/sort/${sortStr}/page/${page}`
@ -361,8 +357,8 @@ export class Community extends Component<any, State> {
let getPostsForm: GetPostsForm = { let getPostsForm: GetPostsForm = {
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,
sort: SortType[this.state.sort], sort: this.state.sort,
type_: ListingType[ListingType.Community], type_: ListingType.Community,
community_id: this.state.community.id, community_id: this.state.community.id,
}; };
WebSocketService.Instance.getPosts(getPostsForm); WebSocketService.Instance.getPosts(getPostsForm);
@ -370,8 +366,8 @@ export class Community extends Component<any, State> {
let getCommentsForm: GetCommentsForm = { let getCommentsForm: GetCommentsForm = {
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,
sort: SortType[this.state.sort], sort: this.state.sort,
type_: ListingType[ListingType.Community], type_: ListingType.Community,
community_id: this.state.community.id, community_id: this.state.community.id,
}; };
WebSocketService.Instance.getComments(getCommentsForm); WebSocketService.Instance.getComments(getCommentsForm);

View file

@ -9,7 +9,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { toast, wsJsonToRes } from '../utils'; import { toast, wsJsonToRes } from '../utils';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -11,7 +11,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface CreatePostState { interface CreatePostState {

View file

@ -10,7 +10,7 @@ import {
GetSiteResponse, GetSiteResponse,
Site, Site,
PrivateMessageFormParams, PrivateMessageFormParams,
} from '../interfaces'; } from 'lemmy-js-client';
import { toast, wsJsonToRes } from '../utils'; import { toast, wsJsonToRes } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -9,7 +9,7 @@ import {
UserOperation, UserOperation,
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
} from '../interfaces'; } from 'lemmy-js-client';
interface FooterState { interface FooterState {
version: string; version: string;

View file

@ -1,5 +1,5 @@
import { Component, linkEvent } from 'inferno'; import { Component, linkEvent } from 'inferno';
import { Post } from '../interfaces'; import { Post } from 'lemmy-js-client';
import { mdToHtml } from '../utils'; import { mdToHtml } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -19,7 +19,7 @@ import {
PrivateMessageResponse, PrivateMessageResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -399,7 +399,7 @@ export class Inbox extends Component<any, InboxState> {
refetch() { refetch() {
let repliesForm: GetRepliesForm = { let repliesForm: GetRepliesForm = {
sort: SortType[this.state.sort], sort: this.state.sort,
unread_only: this.state.unreadOrAll == UnreadOrAll.Unread, unread_only: this.state.unreadOrAll == UnreadOrAll.Unread,
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,
@ -407,7 +407,7 @@ export class Inbox extends Component<any, InboxState> {
WebSocketService.Instance.getReplies(repliesForm); WebSocketService.Instance.getReplies(repliesForm);
let userMentionsForm: GetUserMentionsForm = { let userMentionsForm: GetUserMentionsForm = {
sort: SortType[this.state.sort], sort: this.state.sort,
unread_only: this.state.unreadOrAll == UnreadOrAll.Unread, unread_only: this.state.unreadOrAll == UnreadOrAll.Unread,
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,

View file

@ -6,7 +6,7 @@ import {
UserOperation, UserOperation,
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { wsJsonToRes, toast } from '../utils'; import { wsJsonToRes, toast } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -1,7 +1,7 @@
import { Component, linkEvent } from 'inferno'; import { Component, linkEvent } from 'inferno';
import { ListingType } from '../interfaces'; import { ListingType } from 'lemmy-js-client';
import { UserService } from '../services'; import { UserService } from '../services';
import { randomStr } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface ListingTypeSelectProps { interface ListingTypeSelectProps {
@ -17,6 +17,8 @@ export class ListingTypeSelect extends Component<
ListingTypeSelectProps, ListingTypeSelectProps,
ListingTypeSelectState ListingTypeSelectState
> { > {
private id = `listing-type-input-${randomStr()}`;
private emptyState: ListingTypeSelectState = { private emptyState: ListingTypeSelectState = {
type_: this.props.type_, type_: this.props.type_,
}; };
@ -42,6 +44,7 @@ export class ListingTypeSelect extends Component<
`} `}
> >
<input <input
id={`${this.id}-subscribed`}
type="radio" type="radio"
value={ListingType.Subscribed} value={ListingType.Subscribed}
checked={this.state.type_ == ListingType.Subscribed} checked={this.state.type_ == ListingType.Subscribed}
@ -56,6 +59,7 @@ export class ListingTypeSelect extends Component<
}`} }`}
> >
<input <input
id={`${this.id}-all`}
type="radio" type="radio"
value={ListingType.All} value={ListingType.All}
checked={this.state.type_ == ListingType.All} checked={this.state.type_ == ListingType.All}
@ -68,6 +72,6 @@ export class ListingTypeSelect extends Component<
} }
handleTypeChange(i: ListingTypeSelect, event: any) { handleTypeChange(i: ListingTypeSelect, event: any) {
i.props.onChange(Number(event.target.value)); i.props.onChange(event.target.value);
} }
} }

View file

@ -12,7 +12,7 @@ import {
GetCaptchaResponse, GetCaptchaResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { wsJsonToRes, validEmail, toast } from '../utils'; import { wsJsonToRes, validEmail, toast } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -13,7 +13,6 @@ import {
SortType, SortType,
GetSiteResponse, GetSiteResponse,
ListingType, ListingType,
DataType,
SiteResponse, SiteResponse,
GetPostsResponse, GetPostsResponse,
PostResponse, PostResponse,
@ -26,7 +25,8 @@ import {
AddAdminResponse, AddAdminResponse,
BanUserResponse, BanUserResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { DataType } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { PostListings } from './post-listings'; import { PostListings } from './post-listings';
import { CommentNodes } from './comment-nodes'; import { CommentNodes } from './comment-nodes';
@ -82,9 +82,9 @@ interface MainProps {
} }
interface UrlParams { interface UrlParams {
listingType?: string; listingType?: ListingType;
dataType?: string; dataType?: string;
sort?: string; sort?: SortType;
page?: number; page?: number;
} }
@ -151,7 +151,7 @@ export class Main extends Component<any, MainState> {
} }
let listCommunitiesForm: ListCommunitiesForm = { let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType[SortType.Hot], sort: SortType.Hot,
limit: 6, limit: 6,
}; };
@ -334,13 +334,9 @@ export class Main extends Component<any, MainState> {
} }
updateUrl(paramUpdates: UrlParams) { updateUrl(paramUpdates: UrlParams) {
const listingTypeStr = const listingTypeStr = paramUpdates.listingType || this.state.listingType;
paramUpdates.listingType || const dataTypeStr = paramUpdates.dataType || DataType[this.state.dataType];
ListingType[this.state.listingType].toLowerCase(); const sortStr = paramUpdates.sort || this.state.sort;
const dataTypeStr =
paramUpdates.dataType || DataType[this.state.dataType].toLowerCase();
const sortStr =
paramUpdates.sort || SortType[this.state.sort].toLowerCase();
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;
this.props.history.push( this.props.history.push(
`/home/data_type/${dataTypeStr}/listing_type/${listingTypeStr}/sort/${sortStr}/page/${page}` `/home/data_type/${dataTypeStr}/listing_type/${listingTypeStr}/sort/${sortStr}/page/${page}`
@ -549,7 +545,7 @@ export class Main extends Component<any, MainState> {
</span> </span>
{this.state.listingType == ListingType.All && ( {this.state.listingType == ListingType.All && (
<a <a
href={`/feeds/all.xml?sort=${SortType[this.state.sort]}`} href={`/feeds/all.xml?sort=${this.state.sort}`}
target="_blank" target="_blank"
rel="noopener" rel="noopener"
title="RSS" title="RSS"
@ -562,9 +558,7 @@ export class Main extends Component<any, MainState> {
{UserService.Instance.user && {UserService.Instance.user &&
this.state.listingType == ListingType.Subscribed && ( this.state.listingType == ListingType.Subscribed && (
<a <a
href={`/feeds/front/${UserService.Instance.auth}.xml?sort=${ href={`/feeds/front/${UserService.Instance.auth}.xml?sort=${this.state.sort}`}
SortType[this.state.sort]
}`}
target="_blank" target="_blank"
title="RSS" title="RSS"
rel="noopener" rel="noopener"
@ -631,17 +625,17 @@ export class Main extends Component<any, MainState> {
} }
handleSortChange(val: SortType) { handleSortChange(val: SortType) {
this.updateUrl({ sort: SortType[val].toLowerCase(), page: 1 }); this.updateUrl({ sort: val, page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
handleListingTypeChange(val: ListingType) { handleListingTypeChange(val: ListingType) {
this.updateUrl({ listingType: ListingType[val].toLowerCase(), page: 1 }); this.updateUrl({ listingType: val, page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
handleDataTypeChange(val: DataType) { handleDataTypeChange(val: DataType) {
this.updateUrl({ dataType: DataType[val].toLowerCase(), page: 1 }); this.updateUrl({ dataType: DataType[val], page: 1 });
window.scrollTo(0, 0); window.scrollTo(0, 0);
} }
@ -650,16 +644,16 @@ export class Main extends Component<any, MainState> {
let getPostsForm: GetPostsForm = { let getPostsForm: GetPostsForm = {
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,
sort: SortType[this.state.sort], sort: this.state.sort,
type_: ListingType[this.state.listingType], type_: this.state.listingType,
}; };
WebSocketService.Instance.getPosts(getPostsForm); WebSocketService.Instance.getPosts(getPostsForm);
} else { } else {
let getCommentsForm: GetCommentsForm = { let getCommentsForm: GetCommentsForm = {
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,
sort: SortType[this.state.sort], sort: this.state.sort,
type_: ListingType[this.state.listingType], type_: this.state.listingType,
}; };
WebSocketService.Instance.getComments(getCommentsForm); WebSocketService.Instance.getComments(getCommentsForm);
} }

View file

@ -19,7 +19,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { wsJsonToRes, addTypeInfo, fetchLimit, toast } from '../utils'; import { wsJsonToRes, addTypeInfo, fetchLimit, toast } from '../utils';
import { MomentTime } from './moment-time'; import { MomentTime } from './moment-time';

View file

@ -18,7 +18,7 @@ import {
PrivateMessage, PrivateMessage,
PrivateMessageResponse, PrivateMessageResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { import {
wsJsonToRes, wsJsonToRes,
pictrsAvatarThumbnail, pictrsAvatarThumbnail,
@ -137,7 +137,7 @@ export class Navbar extends Component<any, NavbarState> {
this.context.router.history.push(`/search/`); this.context.router.history.push(`/search/`);
} else { } else {
this.context.router.history.push( this.context.router.history.push(
`/search/q/${searchParam}/type/all/sort/topall/page/1` `/search/q/${searchParam}/type/All/sort/TopAll/page/1`
); );
} }
} }
@ -477,14 +477,14 @@ export class Navbar extends Component<any, NavbarState> {
fetchUnreads() { fetchUnreads() {
console.log('Fetching unreads...'); console.log('Fetching unreads...');
let repliesForm: GetRepliesForm = { let repliesForm: GetRepliesForm = {
sort: SortType[SortType.New], sort: SortType.New,
unread_only: true, unread_only: true,
page: 1, page: 1,
limit: fetchLimit, limit: fetchLimit,
}; };
let userMentionsForm: GetUserMentionsForm = { let userMentionsForm: GetUserMentionsForm = {
sort: SortType[SortType.New], sort: SortType.New,
unread_only: true, unread_only: true,
page: 1, page: 1,
limit: fetchLimit, limit: fetchLimit,

View file

@ -9,7 +9,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { wsJsonToRes, capitalizeFirstLetter, toast } from '../utils'; import { wsJsonToRes, capitalizeFirstLetter, toast } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -18,7 +18,7 @@ import {
SearchType, SearchType,
SearchResponse, SearchResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -121,7 +121,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
); );
let listCommunitiesForm: ListCommunitiesForm = { let listCommunitiesForm: ListCommunitiesForm = {
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
limit: 9999, limit: 9999,
}; };
@ -405,8 +405,8 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
if (validURL(this.state.postForm.url)) { if (validURL(this.state.postForm.url)) {
let form: SearchForm = { let form: SearchForm = {
q: this.state.postForm.url, q: this.state.postForm.url,
type_: SearchType[SearchType.Url], type_: SearchType.Url,
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
page: 1, page: 1,
limit: 6, limit: 6,
}; };
@ -433,8 +433,8 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
fetchSimilarPosts() { fetchSimilarPosts() {
let form: SearchForm = { let form: SearchForm = {
q: this.state.postForm.name, q: this.state.postForm.name,
type_: SearchType[SearchType.Posts], type_: SearchType.Posts,
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
community_id: this.state.postForm.community_id, community_id: this.state.postForm.community_id,
page: 1, page: 1,
limit: 6, limit: 6,

View file

@ -11,14 +11,14 @@ import {
SavePostForm, SavePostForm,
CommunityUser, CommunityUser,
UserView, UserView,
BanType,
BanFromCommunityForm, BanFromCommunityForm,
BanUserForm, BanUserForm,
AddModToCommunityForm, AddModToCommunityForm,
AddAdminForm, AddAdminForm,
TransferSiteForm, TransferSiteForm,
TransferCommunityForm, TransferCommunityForm,
} from '../interfaces'; } from 'lemmy-js-client';
import { BanType } from '../interfaces';
import { MomentTime } from './moment-time'; import { MomentTime } from './moment-time';
import { PostForm } from './post-form'; import { PostForm } from './post-form';
import { IFramelyCard } from './iframely-card'; import { IFramelyCard } from './iframely-card';

View file

@ -1,6 +1,6 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { Link } from 'inferno-router'; import { Link } from 'inferno-router';
import { Post, SortType } from '../interfaces'; import { Post, SortType } from 'lemmy-js-client';
import { postSort } from '../utils'; import { postSort } from '../utils';
import { PostListing } from './post-listing'; import { PostListing } from './post-listing';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -11,8 +11,6 @@ import {
Comment, Comment,
MarkCommentAsReadForm, MarkCommentAsReadForm,
CommentResponse, CommentResponse,
CommentSortType,
CommentViewType,
CommunityUser, CommunityUser,
CommunityResponse, CommunityResponse,
CommentNode as CommentNodeI, CommentNode as CommentNodeI,
@ -28,7 +26,8 @@ import {
GetSiteResponse, GetSiteResponse,
GetCommunityResponse, GetCommunityResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { CommentSortType, CommentViewType } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -439,8 +438,8 @@ export class Post extends Component<any, PostState> {
if (this.state.post.url) { if (this.state.post.url) {
let form: SearchForm = { let form: SearchForm = {
q: this.state.post.url, q: this.state.post.url,
type_: SearchType[SearchType.Url], type_: SearchType.Url,
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
page: 1, page: 1,
limit: 6, limit: 6,
}; };

View file

@ -14,7 +14,7 @@ import {
GetUserDetailsForm, GetUserDetailsForm,
SortType, SortType,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { import {
capitalizeFirstLetter, capitalizeFirstLetter,
@ -77,7 +77,7 @@ export class PrivateMessageForm extends Component<
this.state.privateMessageForm.recipient_id = this.props.params.recipient_id; this.state.privateMessageForm.recipient_id = this.props.params.recipient_id;
let form: GetUserDetailsForm = { let form: GetUserDetailsForm = {
user_id: this.state.privateMessageForm.recipient_id, user_id: this.state.privateMessageForm.recipient_id,
sort: SortType[SortType.New], sort: SortType.New,
saved_only: false, saved_only: false,
}; };
WebSocketService.Instance.getUserDetails(form); WebSocketService.Instance.getUserDetails(form);

View file

@ -4,7 +4,7 @@ import {
PrivateMessage as PrivateMessageI, PrivateMessage as PrivateMessageI,
DeletePrivateMessageForm, DeletePrivateMessageForm,
MarkPrivateMessageAsReadForm, MarkPrivateMessageAsReadForm,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { mdToHtml, pictrsAvatarThumbnail, showAvatars, toast } from '../utils'; import { mdToHtml, pictrsAvatarThumbnail, showAvatars, toast } from '../utils';
import { MomentTime } from './moment-time'; import { MomentTime } from './moment-time';

View file

@ -17,7 +17,7 @@ import {
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
Site, Site,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -57,8 +57,8 @@ interface SearchProps {
interface UrlParams { interface UrlParams {
q?: string; q?: string;
type_?: string; type_?: SearchType;
sort?: string; sort?: SortType;
page?: number; page?: number;
} }
@ -461,8 +461,8 @@ export class Search extends Component<any, SearchState> {
search() { search() {
let form: SearchForm = { let form: SearchForm = {
q: this.state.q, q: this.state.q,
type_: SearchType[this.state.type_], type_: this.state.type_,
sort: SortType[this.state.sort], sort: this.state.sort,
page: this.state.page, page: this.state.page,
limit: fetchLimit, limit: fetchLimit,
}; };
@ -473,12 +473,12 @@ export class Search extends Component<any, SearchState> {
} }
handleSortChange(val: SortType) { handleSortChange(val: SortType) {
this.updateUrl({ sort: SortType[val].toLowerCase(), page: 1 }); this.updateUrl({ sort: val, page: 1 });
} }
handleTypeChange(i: Search, event: any) { handleTypeChange(i: Search, event: any) {
i.updateUrl({ i.updateUrl({
type_: SearchType[Number(event.target.value)].toLowerCase(), type_: SearchType[event.target.value],
page: 1, page: 1,
}); });
} }
@ -487,8 +487,8 @@ export class Search extends Component<any, SearchState> {
event.preventDefault(); event.preventDefault();
i.updateUrl({ i.updateUrl({
q: i.state.searchText, q: i.state.searchText,
type_: SearchType[i.state.type_].toLowerCase(), type_: i.state.type_,
sort: SortType[i.state.sort].toLowerCase(), sort: i.state.sort,
page: i.state.page, page: i.state.page,
}); });
} }
@ -499,10 +499,8 @@ export class Search extends Component<any, SearchState> {
updateUrl(paramUpdates: UrlParams) { updateUrl(paramUpdates: UrlParams) {
const qStr = paramUpdates.q || this.state.q; const qStr = paramUpdates.q || this.state.q;
const typeStr = const typeStr = paramUpdates.type_ || this.state.type_;
paramUpdates.type_ || SearchType[this.state.type_].toLowerCase(); const sortStr = paramUpdates.sort || this.state.sort;
const sortStr =
paramUpdates.sort || SortType[this.state.sort].toLowerCase();
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;
this.props.history.push( this.props.history.push(
`/search/q/${qStr}/type/${typeStr}/sort/${sortStr}/page/${page}` `/search/q/${qStr}/type/${typeStr}/sort/${sortStr}/page/${page}`

View file

@ -7,7 +7,7 @@ import {
LoginResponse, LoginResponse,
UserOperation, UserOperation,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { wsJsonToRes, toast } from '../utils'; import { wsJsonToRes, toast } from '../utils';
import { SiteForm } from './site-form'; import { SiteForm } from './site-form';

View file

@ -8,7 +8,7 @@ import {
RemoveCommunityForm, RemoveCommunityForm,
UserView, UserView,
AddModToCommunityForm, AddModToCommunityForm,
} from '../interfaces'; } from 'lemmy-js-client';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { mdToHtml, getUnixTime } from '../utils'; import { mdToHtml, getUnixTime } from '../utils';
import { CommunityForm } from './community-form'; import { CommunityForm } from './community-form';

View file

@ -2,7 +2,7 @@ import { Component, linkEvent } from 'inferno';
import { Prompt } from 'inferno-router'; import { Prompt } from 'inferno-router';
import { MarkdownTextArea } from './markdown-textarea'; import { MarkdownTextArea } from './markdown-textarea';
import { ImageUploadForm } from './image-upload-form'; import { ImageUploadForm } from './image-upload-form';
import { Site, SiteForm as SiteFormI } from '../interfaces'; import { Site, SiteForm as SiteFormI } from 'lemmy-js-client';
import { WebSocketService } from '../services'; import { WebSocketService } from '../services';
import { capitalizeFirstLetter, randomStr } from '../utils'; import { capitalizeFirstLetter, randomStr } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';

View file

@ -1,6 +1,6 @@
import { Component, linkEvent } from 'inferno'; import { Component, linkEvent } from 'inferno';
import { SortType } from '../interfaces'; import { SortType } from 'lemmy-js-client';
import { sortingHelpUrl } from '../utils'; import { sortingHelpUrl, randomStr } from '../utils';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
interface SortSelectProps { interface SortSelectProps {
@ -14,6 +14,7 @@ interface SortSelectState {
} }
export class SortSelect extends Component<SortSelectProps, SortSelectState> { export class SortSelect extends Component<SortSelectProps, SortSelectState> {
private id = `sort-select-${randomStr()}`;
private emptyState: SortSelectState = { private emptyState: SortSelectState = {
sort: this.props.sort, sort: this.props.sort,
}; };
@ -33,6 +34,8 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
return ( return (
<> <>
<select <select
id={this.id}
name={this.id}
value={this.state.sort} value={this.state.sort}
onChange={linkEvent(this, this.handleSortChange)} onChange={linkEvent(this, this.handleSortChange)}
class="custom-select w-auto mr-2 mb-2" class="custom-select w-auto mr-2 mb-2"
@ -68,6 +71,6 @@ export class SortSelect extends Component<SortSelectProps, SortSelectState> {
} }
handleSortChange(i: SortSelect, event: any) { handleSortChange(i: SortSelect, event: any) {
i.props.onChange(Number(event.target.value)); i.props.onChange(event.target.value);
} }
} }

View file

@ -8,7 +8,7 @@ import {
Site, Site,
WebSocketJsonResponse, WebSocketJsonResponse,
UserOperation, UserOperation,
} from '../interfaces'; } from 'lemmy-js-client';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { T } from 'inferno-i18next'; import { T } from 'inferno-i18next';
import { repoUrl, wsJsonToRes, toast } from '../utils'; import { repoUrl, wsJsonToRes, toast } from '../utils';

View file

@ -12,11 +12,11 @@ import {
UserDetailsResponse, UserDetailsResponse,
UserView, UserView,
WebSocketJsonResponse, WebSocketJsonResponse,
UserDetailsView,
CommentResponse, CommentResponse,
BanUserResponse, BanUserResponse,
PostResponse, PostResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { UserDetailsView } from '../interfaces';
import { import {
wsJsonToRes, wsJsonToRes,
toast, toast,
@ -35,7 +35,7 @@ interface UserDetailsProps {
user_id?: number; user_id?: number;
page: number; page: number;
limit: number; limit: number;
sort: string; sort: SortType;
enableDownvotes: boolean; enableDownvotes: boolean;
enableNsfw: boolean; enableNsfw: boolean;
view: UserDetailsView; view: UserDetailsView;
@ -137,7 +137,7 @@ export class UserDetails extends Component<UserDetailsProps, UserDetailsState> {
]; ];
// Sort it // Sort it
if (SortType[this.props.sort] === SortType.New) { if (this.props.sort === SortType.New) {
combined.sort((a, b) => b.data.published.localeCompare(a.data.published)); combined.sort((a, b) => b.data.published.localeCompare(a.data.published));
} else { } else {
combined.sort((a, b) => b.data.score - a.data.score); combined.sort((a, b) => b.data.score - a.data.score);

View file

@ -1,6 +1,6 @@
import { Component } from 'inferno'; import { Component } from 'inferno';
import { Link } from 'inferno-router'; import { Link } from 'inferno-router';
import { UserView } from '../interfaces'; import { UserView } from 'lemmy-js-client';
import { import {
pictrsAvatarThumbnail, pictrsAvatarThumbnail,
showAvatars, showAvatars,

View file

@ -14,10 +14,10 @@ import {
DeleteAccountForm, DeleteAccountForm,
WebSocketJsonResponse, WebSocketJsonResponse,
GetSiteResponse, GetSiteResponse,
UserDetailsView,
UserDetailsResponse, UserDetailsResponse,
AddAdminResponse, AddAdminResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { UserDetailsView } from '../interfaces';
import { WebSocketService, UserService } from '../services'; import { WebSocketService, UserService } from '../services';
import { import {
wsJsonToRes, wsJsonToRes,
@ -73,7 +73,7 @@ interface UserProps {
interface UrlParams { interface UrlParams {
view?: string; view?: string;
sort?: string; sort?: SortType;
page?: number; page?: number;
} }
@ -190,17 +190,15 @@ export class User extends Component<any, UserState> {
); );
} }
static getViewFromProps(view: any): UserDetailsView { static getViewFromProps(view: string): UserDetailsView {
return view return view ? UserDetailsView[view] : UserDetailsView.Overview;
? UserDetailsView[capitalizeFirstLetter(view)]
: UserDetailsView.Overview;
} }
static getSortTypeFromProps(sort: any): SortType { static getSortTypeFromProps(sort: string): SortType {
return sort ? routeSortTypeToEnum(sort) : SortType.New; return sort ? routeSortTypeToEnum(sort) : SortType.New;
} }
static getPageFromProps(page: any): number { static getPageFromProps(page: number): number {
return page ? Number(page) : 1; return page ? Number(page) : 1;
} }
@ -272,7 +270,7 @@ export class User extends Component<any, UserState> {
<UserDetails <UserDetails
user_id={this.state.user_id} user_id={this.state.user_id}
username={this.state.username} username={this.state.username}
sort={SortType[this.state.sort]} sort={this.state.sort}
page={this.state.page} page={this.state.page}
limit={fetchLimit} limit={fetchLimit}
enableDownvotes={this.state.siteRes.site.enable_downvotes} enableDownvotes={this.state.siteRes.site.enable_downvotes}
@ -364,9 +362,7 @@ export class User extends Component<any, UserState> {
hideHot hideHot
/> />
<a <a
href={`/feeds/u/${this.state.username}.xml?sort=${ href={`/feeds/u/${this.state.username}.xml?sort=${this.state.sort}`}
SortType[this.state.sort]
}`}
target="_blank" target="_blank"
rel="noopener" rel="noopener"
title="RSS" title="RSS"
@ -538,7 +534,11 @@ export class User extends Component<any, UserState> {
<div class="mr-2">{i18n.t('sort_type')}</div> <div class="mr-2">{i18n.t('sort_type')}</div>
</label> </label>
<ListingTypeSelect <ListingTypeSelect
type_={this.state.userSettingsForm.default_listing_type} type_={
Object.values(ListingType)[
this.state.userSettingsForm.default_listing_type
]
}
onChange={this.handleUserSettingsListingTypeChange} onChange={this.handleUserSettingsListingTypeChange}
/> />
</form> </form>
@ -547,7 +547,11 @@ export class User extends Component<any, UserState> {
<div class="mr-2">{i18n.t('type')}</div> <div class="mr-2">{i18n.t('type')}</div>
</label> </label>
<SortSelect <SortSelect
sort={this.state.userSettingsForm.default_sort_type} sort={
Object.values(SortType)[
this.state.userSettingsForm.default_sort_type
]
}
onChange={this.handleUserSettingsSortTypeChange} onChange={this.handleUserSettingsSortTypeChange}
/> />
</form> </form>
@ -859,10 +863,8 @@ export class User extends Component<any, UserState> {
updateUrl(paramUpdates: UrlParams) { updateUrl(paramUpdates: UrlParams) {
const page = paramUpdates.page || this.state.page; const page = paramUpdates.page || this.state.page;
const viewStr = const viewStr = paramUpdates.view || UserDetailsView[this.state.view];
paramUpdates.view || UserDetailsView[this.state.view].toLowerCase(); const sortStr = paramUpdates.sort || this.state.sort;
const sortStr =
paramUpdates.sort || SortType[this.state.sort].toLowerCase();
this.props.history.push( this.props.history.push(
`/u/${this.state.username}/view/${viewStr}/sort/${sortStr}/page/${page}` `/u/${this.state.username}/view/${viewStr}/sort/${sortStr}/page/${page}`
); );
@ -873,12 +875,12 @@ export class User extends Component<any, UserState> {
} }
handleSortChange(val: SortType) { handleSortChange(val: SortType) {
this.updateUrl({ sort: SortType[val].toLowerCase(), page: 1 }); this.updateUrl({ sort: val, page: 1 });
} }
handleViewChange(i: User, event: any) { handleViewChange(i: User, event: any) {
i.updateUrl({ i.updateUrl({
view: UserDetailsView[Number(event.target.value)].toLowerCase(), view: UserDetailsView[Number(event.target.value)],
page: 1, page: 1,
}); });
} }
@ -912,12 +914,16 @@ export class User extends Component<any, UserState> {
} }
handleUserSettingsSortTypeChange(val: SortType) { handleUserSettingsSortTypeChange(val: SortType) {
this.state.userSettingsForm.default_sort_type = val; this.state.userSettingsForm.default_sort_type = Object.keys(
SortType
).indexOf(val);
this.setState(this.state); this.setState(this.state);
} }
handleUserSettingsListingTypeChange(val: ListingType) { handleUserSettingsListingTypeChange(val: ListingType) {
this.state.userSettingsForm.default_listing_type = val; this.state.userSettingsForm.default_listing_type = Object.keys(
ListingType
).indexOf(val);
this.setState(this.state); this.setState(this.state);
} }

1052
ui/src/interfaces.ts vendored

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,14 @@
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import { User, Claims, LoginResponse } from '../interfaces'; import { User, LoginResponse } from 'lemmy-js-client';
import { setTheme } from '../utils'; import { setTheme } from '../utils';
import jwt_decode from 'jwt-decode'; import jwt_decode from 'jwt-decode';
import { Subject, BehaviorSubject } from 'rxjs'; import { Subject, BehaviorSubject } from 'rxjs';
interface Claims {
id: number;
iss: string;
}
export class UserService { export class UserService {
private static _instance: UserService; private static _instance: UserService;
public user: User; public user: User;

View file

@ -1,8 +1,8 @@
import { wsUri } from '../env'; import { wsUri } from '../env';
import { import {
LemmyWebsocket,
LoginForm, LoginForm,
RegisterForm, RegisterForm,
UserOperation,
CommunityForm, CommunityForm,
DeleteCommunityForm, DeleteCommunityForm,
RemoveCommunityForm, RemoveCommunityForm,
@ -53,9 +53,9 @@ import {
GetSiteConfig, GetSiteConfig,
GetSiteForm, GetSiteForm,
SiteConfigForm, SiteConfigForm,
MessageType, MarkAllAsReadForm,
WebSocketJsonResponse, WebSocketJsonResponse,
} from '../interfaces'; } from 'lemmy-js-client';
import { UserService } from './'; import { UserService } from './';
import { i18n } from '../i18next'; import { i18n } from '../i18next';
import { toast } from '../utils'; import { toast } from '../utils';
@ -70,6 +70,7 @@ export class WebSocketService {
public admins: Array<UserView>; public admins: Array<UserView>;
public banned: Array<UserView>; public banned: Array<UserView>;
private client = new LemmyWebsocket();
private constructor() { private constructor() {
this.ws = new ReconnectingWebSocket(wsUri); this.ws = new ReconnectingWebSocket(wsUri);
@ -100,301 +101,287 @@ export class WebSocketService {
public userJoin() { public userJoin() {
let form: UserJoinForm = { auth: UserService.Instance.auth }; let form: UserJoinForm = { auth: UserService.Instance.auth };
this.ws.send(this.wsSendWrapper(UserOperation.UserJoin, form)); this.ws.send(this.client.userJoin(form));
} }
public login(loginForm: LoginForm) { public login(form: LoginForm) {
this.ws.send(this.wsSendWrapper(UserOperation.Login, loginForm)); this.ws.send(this.client.login(form));
} }
public register(registerForm: RegisterForm) { public register(form: RegisterForm) {
this.ws.send(this.wsSendWrapper(UserOperation.Register, registerForm)); this.ws.send(this.client.register(form));
} }
public getCaptcha() { public getCaptcha() {
this.ws.send(this.wsSendWrapper(UserOperation.GetCaptcha, {})); this.ws.send(this.client.getCaptcha());
} }
public createCommunity(form: CommunityForm) { public createCommunity(form: CommunityForm) {
this.setAuth(form); this.setAuth(form); // TODO all these setauths at some point would be good to make required
this.ws.send(this.wsSendWrapper(UserOperation.CreateCommunity, form)); this.ws.send(this.client.createCommunity(form));
} }
public editCommunity(form: CommunityForm) { public editCommunity(form: CommunityForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.EditCommunity, form)); this.ws.send(this.client.editCommunity(form));
} }
public deleteCommunity(form: DeleteCommunityForm) { public deleteCommunity(form: DeleteCommunityForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.DeleteCommunity, form)); this.ws.send(this.client.deleteCommunity(form));
} }
public removeCommunity(form: RemoveCommunityForm) { public removeCommunity(form: RemoveCommunityForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.RemoveCommunity, form)); this.ws.send(this.client.removeCommunity(form));
} }
public followCommunity(followCommunityForm: FollowCommunityForm) { public followCommunity(form: FollowCommunityForm) {
this.setAuth(followCommunityForm); this.setAuth(form);
this.ws.send( this.ws.send(this.client.followCommunity(form));
this.wsSendWrapper(UserOperation.FollowCommunity, followCommunityForm)
);
} }
public listCommunities(form: ListCommunitiesForm) { public listCommunities(form: ListCommunitiesForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.ListCommunities, form)); this.ws.send(this.client.listCommunities(form));
} }
public getFollowedCommunities() { public getFollowedCommunities() {
let form: GetFollowedCommunitiesForm = { auth: UserService.Instance.auth }; let form: GetFollowedCommunitiesForm = { auth: UserService.Instance.auth };
this.ws.send( this.ws.send(this.client.getFollowedCommunities(form));
this.wsSendWrapper(UserOperation.GetFollowedCommunities, form)
);
} }
public listCategories() { public listCategories() {
this.ws.send(this.wsSendWrapper(UserOperation.ListCategories, {})); this.ws.send(this.client.listCategories());
} }
public createPost(form: PostForm) { public createPost(form: PostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.CreatePost, form)); this.ws.send(this.client.createPost(form));
} }
public getPost(form: GetPostForm) { public getPost(form: GetPostForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.GetPost, form)); this.ws.send(this.client.getPost(form));
} }
public getCommunity(form: GetCommunityForm) { public getCommunity(form: GetCommunityForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.GetCommunity, form)); this.ws.send(this.client.getCommunity(form));
} }
public createComment(form: CommentForm) { public createComment(form: CommentForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.CreateComment, form)); this.ws.send(this.client.createComment(form));
} }
public editComment(form: CommentForm) { public editComment(form: CommentForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.EditComment, form)); this.ws.send(this.client.editComment(form));
} }
public deleteComment(form: DeleteCommentForm) { public deleteComment(form: DeleteCommentForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.DeleteComment, form)); this.ws.send(this.client.deleteComment(form));
} }
public removeComment(form: RemoveCommentForm) { public removeComment(form: RemoveCommentForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.RemoveComment, form)); this.ws.send(this.client.removeComment(form));
} }
public markCommentAsRead(form: MarkCommentAsReadForm) { public markCommentAsRead(form: MarkCommentAsReadForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.MarkCommentAsRead, form)); this.ws.send(this.client.markCommentAsRead(form));
} }
public likeComment(form: CommentLikeForm) { public likeComment(form: CommentLikeForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.CreateCommentLike, form)); this.ws.send(this.client.likeComment(form));
} }
public saveComment(form: SaveCommentForm) { public saveComment(form: SaveCommentForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.SaveComment, form)); this.ws.send(this.client.saveComment(form));
} }
public getPosts(form: GetPostsForm) { public getPosts(form: GetPostsForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.GetPosts, form)); this.ws.send(this.client.getPosts(form));
} }
public getComments(form: GetCommentsForm) { public getComments(form: GetCommentsForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.GetComments, form)); this.ws.send(this.client.getComments(form));
} }
public likePost(form: CreatePostLikeForm) { public likePost(form: CreatePostLikeForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.CreatePostLike, form)); this.ws.send(this.client.likePost(form));
} }
public editPost(form: PostForm) { public editPost(form: PostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.EditPost, form)); this.ws.send(this.client.editPost(form));
} }
public deletePost(form: DeletePostForm) { public deletePost(form: DeletePostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.DeletePost, form)); this.ws.send(this.client.deletePost(form));
} }
public removePost(form: RemovePostForm) { public removePost(form: RemovePostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.RemovePost, form)); this.ws.send(this.client.removePost(form));
} }
public lockPost(form: LockPostForm) { public lockPost(form: LockPostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.LockPost, form)); this.ws.send(this.client.lockPost(form));
} }
public stickyPost(form: StickyPostForm) { public stickyPost(form: StickyPostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.StickyPost, form)); this.ws.send(this.client.stickyPost(form));
} }
public savePost(form: SavePostForm) { public savePost(form: SavePostForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.SavePost, form)); this.ws.send(this.client.savePost(form));
} }
public banFromCommunity(form: BanFromCommunityForm) { public banFromCommunity(form: BanFromCommunityForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.BanFromCommunity, form)); this.ws.send(this.client.banFromCommunity(form));
} }
public addModToCommunity(form: AddModToCommunityForm) { public addModToCommunity(form: AddModToCommunityForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.AddModToCommunity, form)); this.ws.send(this.client.addModToCommunity(form));
} }
public transferCommunity(form: TransferCommunityForm) { public transferCommunity(form: TransferCommunityForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.TransferCommunity, form)); this.ws.send(this.client.transferCommunity(form));
} }
public transferSite(form: TransferSiteForm) { public transferSite(form: TransferSiteForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.TransferSite, form)); this.ws.send(this.client.transferSite(form));
} }
public banUser(form: BanUserForm) { public banUser(form: BanUserForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.BanUser, form)); this.ws.send(this.client.banUser(form));
} }
public addAdmin(form: AddAdminForm) { public addAdmin(form: AddAdminForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.AddAdmin, form)); this.ws.send(this.client.addAdmin(form));
} }
public getUserDetails(form: GetUserDetailsForm) { public getUserDetails(form: GetUserDetailsForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.GetUserDetails, form)); this.ws.send(this.client.getUserDetails(form));
} }
public getReplies(form: GetRepliesForm) { public getReplies(form: GetRepliesForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.GetReplies, form)); this.ws.send(this.client.getReplies(form));
} }
public getUserMentions(form: GetUserMentionsForm) { public getUserMentions(form: GetUserMentionsForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.GetUserMentions, form)); this.ws.send(this.client.getUserMentions(form));
} }
public markUserMentionAsRead(form: MarkUserMentionAsReadForm) { public markUserMentionAsRead(form: MarkUserMentionAsReadForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.MarkUserMentionAsRead, form)); this.ws.send(this.client.markUserMentionAsRead(form));
} }
public getModlog(form: GetModlogForm) { public getModlog(form: GetModlogForm) {
this.ws.send(this.wsSendWrapper(UserOperation.GetModlog, form)); this.ws.send(this.client.getModlog(form));
} }
public createSite(siteForm: SiteForm) { public createSite(form: SiteForm) {
this.setAuth(siteForm); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.CreateSite, siteForm)); this.ws.send(this.client.createSite(form));
} }
public editSite(siteForm: SiteForm) { public editSite(form: SiteForm) {
this.setAuth(siteForm); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.EditSite, siteForm)); this.ws.send(this.client.editSite(form));
} }
public getSite(form: GetSiteForm = {}) { public getSite(form: GetSiteForm = {}) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.GetSite, form)); this.ws.send(this.client.getSite(form));
} }
public getSiteConfig() { public getSiteConfig() {
let siteConfig: GetSiteConfig = {}; let form: GetSiteConfig = {};
this.setAuth(siteConfig); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.GetSiteConfig, siteConfig)); this.ws.send(this.client.getSiteConfig(form));
} }
public search(form: SearchForm) { public search(form: SearchForm) {
this.setAuth(form, false); this.setAuth(form, false);
this.ws.send(this.wsSendWrapper(UserOperation.Search, form)); this.ws.send(this.client.search(form));
} }
public markAllAsRead() { public markAllAsRead() {
let form = {}; let form: MarkAllAsReadForm;
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.MarkAllAsRead, form)); this.ws.send(this.client.markAllAsRead(form));
} }
public saveUserSettings(userSettingsForm: UserSettingsForm) { public saveUserSettings(form: UserSettingsForm) {
this.setAuth(userSettingsForm); this.setAuth(form);
this.ws.send( this.ws.send(this.client.saveUserSettings(form));
this.wsSendWrapper(UserOperation.SaveUserSettings, userSettingsForm)
);
} }
public deleteAccount(form: DeleteAccountForm) { public deleteAccount(form: DeleteAccountForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.DeleteAccount, form)); this.ws.send(this.client.deleteAccount(form));
} }
public passwordReset(form: PasswordResetForm) { public passwordReset(form: PasswordResetForm) {
this.ws.send(this.wsSendWrapper(UserOperation.PasswordReset, form)); this.ws.send(this.client.passwordReset(form));
} }
public passwordChange(form: PasswordChangeForm) { public passwordChange(form: PasswordChangeForm) {
this.ws.send(this.wsSendWrapper(UserOperation.PasswordChange, form)); this.ws.send(this.client.passwordChange(form));
} }
public createPrivateMessage(form: PrivateMessageForm) { public createPrivateMessage(form: PrivateMessageForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.CreatePrivateMessage, form)); this.ws.send(this.client.createPrivateMessage(form));
} }
public editPrivateMessage(form: EditPrivateMessageForm) { public editPrivateMessage(form: EditPrivateMessageForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.EditPrivateMessage, form)); this.ws.send(this.client.editPrivateMessage(form));
} }
public deletePrivateMessage(form: DeletePrivateMessageForm) { public deletePrivateMessage(form: DeletePrivateMessageForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.DeletePrivateMessage, form)); this.ws.send(this.client.deletePrivateMessage(form));
} }
public markPrivateMessageAsRead(form: MarkPrivateMessageAsReadForm) { public markPrivateMessageAsRead(form: MarkPrivateMessageAsReadForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send( this.ws.send(this.client.markPrivateMessageAsRead(form));
this.wsSendWrapper(UserOperation.MarkPrivateMessageAsRead, form)
);
} }
public getPrivateMessages(form: GetPrivateMessagesForm) { public getPrivateMessages(form: GetPrivateMessagesForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.GetPrivateMessages, form)); this.ws.send(this.client.getPrivateMessages(form));
} }
public saveSiteConfig(form: SiteConfigForm) { public saveSiteConfig(form: SiteConfigForm) {
this.setAuth(form); this.setAuth(form);
this.ws.send(this.wsSendWrapper(UserOperation.SaveSiteConfig, form)); this.ws.send(this.client.saveSiteConfig(form));
}
private wsSendWrapper(op: UserOperation, data: MessageType) {
let send = { op: UserOperation[op], data: data };
console.log(send);
return JSON.stringify(send);
} }
private setAuth(obj: any, throwErr: boolean = true) { private setAuth(obj: any, throwErr: boolean = true) {

38
ui/src/utils.ts vendored
View file

@ -34,9 +34,7 @@ import {
PrivateMessage, PrivateMessage,
User, User,
SortType, SortType,
CommentSortType,
ListingType, ListingType,
DataType,
SearchType, SearchType,
WebSocketResponse, WebSocketResponse,
WebSocketJsonResponse, WebSocketJsonResponse,
@ -44,7 +42,9 @@ import {
SearchResponse, SearchResponse,
CommentResponse, CommentResponse,
PostResponse, PostResponse,
} from './interfaces'; } from 'lemmy-js-client';
import { CommentSortType, DataType } from './interfaces';
import { UserService, WebSocketService } from './services'; import { UserService, WebSocketService } from './services';
import Tribute from 'tributejs/src/Tribute.js'; import Tribute from 'tributejs/src/Tribute.js';
@ -273,27 +273,11 @@ export function capitalizeFirstLetter(str: string): string {
} }
export function routeSortTypeToEnum(sort: string): SortType { export function routeSortTypeToEnum(sort: string): SortType {
if (sort == 'new') { return SortType[sort];
return SortType.New;
} else if (sort == 'hot') {
return SortType.Hot;
} else if (sort == 'active') {
return SortType.Active;
} else if (sort == 'topday') {
return SortType.TopDay;
} else if (sort == 'topweek') {
return SortType.TopWeek;
} else if (sort == 'topmonth') {
return SortType.TopMonth;
} else if (sort == 'topyear') {
return SortType.TopYear;
} else if (sort == 'topall') {
return SortType.TopAll;
}
} }
export function routeListingTypeToEnum(type: string): ListingType { export function routeListingTypeToEnum(type: string): ListingType {
return ListingType[capitalizeFirstLetter(type)]; return ListingType[type];
} }
export function routeDataTypeToEnum(type: string): DataType { export function routeDataTypeToEnum(type: string): DataType {
@ -730,8 +714,8 @@ function userSearch(text: string, cb: any) {
if (text) { if (text) {
let form: SearchForm = { let form: SearchForm = {
q: text, q: text,
type_: SearchType[SearchType.Users], type_: SearchType.Users,
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
page: 1, page: 1,
limit: mentionDropdownFetchLimit, limit: mentionDropdownFetchLimit,
}; };
@ -767,8 +751,8 @@ function communitySearch(text: string, cb: any) {
if (text) { if (text) {
let form: SearchForm = { let form: SearchForm = {
q: text, q: text,
type_: SearchType[SearchType.Communities], type_: SearchType.Communities,
sort: SortType[SortType.TopAll], sort: SortType.TopAll,
page: 1, page: 1,
limit: mentionDropdownFetchLimit, limit: mentionDropdownFetchLimit,
}; };
@ -804,7 +788,7 @@ export function getListingTypeFromProps(props: any): ListingType {
return props.match.params.listing_type return props.match.params.listing_type
? routeListingTypeToEnum(props.match.params.listing_type) ? routeListingTypeToEnum(props.match.params.listing_type)
: UserService.Instance.user : UserService.Instance.user
? UserService.Instance.user.default_listing_type ? Object.values(ListingType)[UserService.Instance.user.default_listing_type]
: ListingType.All; : ListingType.All;
} }
@ -819,7 +803,7 @@ export function getSortTypeFromProps(props: any): SortType {
return props.match.params.sort return props.match.params.sort
? routeSortTypeToEnum(props.match.params.sort) ? routeSortTypeToEnum(props.match.params.sort)
: UserService.Instance.user : UserService.Instance.user
? UserService.Instance.user.default_sort_type ? Object.values(SortType)[UserService.Instance.user.default_sort_type]
: SortType.Active; : SortType.Active;
} }

5
ui/yarn.lock vendored
View file

@ -4938,6 +4938,11 @@ lego-api@^1.0.7:
dependencies: dependencies:
chain-able "^3.0.0" chain-able "^3.0.0"
lemmy-js-client@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-1.0.8.tgz#98e34c8e3cd07427f883f60fad376dc4d6f46e7f"
integrity sha512-YZxD3+8RGz7cRKdI8EIe5iQqQIMm5WzdNz6zZ7/CdkMtXUv6YuMOEv8HLTvBoGuaWIJwlMJ+23NIarxlT26IEw==
leven@^3.1.0: leven@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"