diff options
author | Dessalines <tyhou13@gmx.com> | 2020-01-31 22:53:55 -0500 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2020-01-31 22:53:55 -0500 |
commit | 895d85782508f0195be3a33e7830748dac89ee53 (patch) | |
tree | cd788ba6de4f6d2f9388ea2243eeb1e57f46aeec | |
parent | 7b4bf68486ad46b70e761b88be4819d4fc044f91 (diff) | |
parent | 8cbdba1da39c15d2a3d13919398fc4d4c8ef2c6c (diff) |
Merge branch 'dev' into nutomic-api-benchmark
27 files changed, 571 insertions, 96 deletions
@@ -159,25 +159,26 @@ Lemmy is free, open-source software, meaning no advertising, monetizing, or vent ## Translations -If you'd like to add translations, take a look a look at the [English translation file](ui/src/translations/en.ts). +If you'd like to add translations, take a look at the [English translation file](ui/src/translations/en.ts). -- Languages supported: Catalan, (`ca`), English (`en`), Chinese (`zh`), Dutch (`nl`), Esperanto (`eo`), Finnish (`fi`), French (`fr`), Spanish (`es`), Swedish (`sv`), German (`de`), Russian (`ru`), Italian (`it`). +- Languages supported: Catalan, (`ca`), Farsi (`fa`), English (`en`), Chinese (`zh`), Dutch (`nl`), Esperanto (`eo`), Finnish (`fi`), French (`fr`), Spanish (`es`), Swedish (`sv`), German (`de`), Russian (`ru`), Italian (`it`). <!-- translations --> lang | done | missing ---- | ---- | ------- -ca | 100% | -de | 88% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,docs,message_sent,messages,old_password,matrix_user_id,private_message_disclaimer,send_notifications_to_email,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -eo | 76% | number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,theme,donate_to_lemmy,donate,from,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -es | 100% | -fi | 100% | -fr | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -it | 84% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -nl | 93% | create_private_message,send_secure_message,send_message,message,message_sent,messages,matrix_user_id,private_message_disclaimer,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -ru | 72% | cross_posts,cross_post,number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,theme,donate_to_lemmy,donate,monero,by,to,from,transfer_community,transfer_site,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -sv | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message -zh | 70% | cross_posts,cross_post,users,number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,nsfw,show_nsfw,theme,donate_to_lemmy,donate,monero,by,to,from,transfer_community,transfer_site,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +ca | 100% | old +de | 87% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,old,docs,message_sent,messages,old_password,matrix_user_id,private_message_disclaimer,send_notifications_to_email,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +fa | 73% | cross_post,subscribed_to_communities,trending_communities,create_private_message,send_secure_message,send_message,message,mod,mods,moderates,remove_as_mod,appoint_as_mod,modlog,stickied,ban,ban_from_site,unban,unban_from_site,banned,number_of_subscribers,subscribers,both,saved,unsubscribe,subscribe,subscribed,old,api,docs,inbox,inbox_for,message_sent,notifications_error,messages,no_email_setup,matrix_user_id,private_message_disclaimer,url,body,copy_suggested_title,community,expand_here,subscribe_to_communities,theme,sponsor_message,general_sponsors,joined,by,to,from,landing_0,logged_in,community_moderator_already_exists,community_follower_already_exists,community_user_already_banned,no_slurs,admin_already_created,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +eo | 75% | number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,old,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,theme,donate_to_lemmy,donate,from,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +es | 100% | old +fi | 100% | old +fr | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,old,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +it | 84% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,old,docs,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +nl | 92% | create_private_message,send_secure_message,send_message,message,old,message_sent,messages,matrix_user_id,private_message_disclaimer,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +ru | 72% | cross_posts,cross_post,number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,stickied,delete_account,delete_account_confirm,banned,creator,number_online,old,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,theme,donate_to_lemmy,donate,monero,by,to,from,transfer_community,transfer_site,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +sv | 83% | create_private_message,send_secure_message,send_message,message,avatar,upload_avatar,show_avatars,archive_link,old,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,donate_to_lemmy,donate,from,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message +zh | 70% | cross_posts,cross_post,users,number_of_communities,create_private_message,send_secure_message,send_message,message,preview,upload_image,avatar,upload_avatar,show_avatars,formatting_help,view_source,sticky,unsticky,archive_link,settings,stickied,delete_account,delete_account_confirm,banned,creator,number_online,old,docs,replies,mentions,message_sent,messages,old_password,forgot_password,reset_password_mail_sent,password_change,new_password,no_email_setup,matrix_user_id,private_message_disclaimer,send_notifications_to_email,language,browser_default,downvotes_disabled,enable_downvotes,open_registration,registration_closed,enable_nsfw,recent_comments,nsfw,show_nsfw,theme,donate_to_lemmy,donate,monero,by,to,from,transfer_community,transfer_site,are_you_sure,yes,no,logged_in,email_already_exists,couldnt_create_private_message,no_private_message_edit_allowed,couldnt_update_private_message <!-- translationsstop --> If you'd like to update this report, run: diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml index 3d4cd949..646627bd 100644 --- a/docker/prod/docker-compose.yml +++ b/docker/prod/docker-compose.yml @@ -11,7 +11,7 @@ services: - lemmy_db:/var/lib/postgresql/data restart: always lemmy: - image: dessalines/lemmy:v0.6.5 + image: dessalines/lemmy:v0.6.7 ports: - "127.0.0.1:8536:8536" restart: always diff --git a/server/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql b/server/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql new file mode 100644 index 00000000..06ec5971 --- /dev/null +++ b/server/migrations/2020-01-29-011901_create_reply_materialized_view/down.sql @@ -0,0 +1,25 @@ +-- Drop the materialized / built views +drop view reply_view; +create view reply_view as +with closereply as ( + select + c2.id, + c2.creator_id as sender_id, + c.creator_id as recipient_id + from comment c + inner join comment c2 on c.id = c2.parent_id + where c2.creator_id != c.creator_id + -- Do union where post is null + union + select + c.id, + c.creator_id as sender_id, + p.creator_id as recipient_id + from comment c, post p + where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +) +select cv.*, +closereply.recipient_id +from comment_view cv, closereply +where closereply.id = cv.id +; diff --git a/server/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql b/server/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql new file mode 100644 index 00000000..ebbb1dff --- /dev/null +++ b/server/migrations/2020-01-29-011901_create_reply_materialized_view/up.sql @@ -0,0 +1,27 @@ +-- https://github.com/dessalines/lemmy/issues/197 +drop view reply_view; + +-- Do the reply_view referencing the comment_mview +create view reply_view as +with closereply as ( + select + c2.id, + c2.creator_id as sender_id, + c.creator_id as recipient_id + from comment c + inner join comment c2 on c.id = c2.parent_id + where c2.creator_id != c.creator_id + -- Do union where post is null + union + select + c.id, + c.creator_id as sender_id, + p.creator_id as recipient_id + from comment c, post p + where c.post_id = p.id and c.parent_id is null and c.creator_id != p.creator_id +) +select cv.*, +closereply.recipient_id +from comment_mview cv, closereply +where closereply.id = cv.id +; diff --git a/server/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql b/server/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql new file mode 100644 index 00000000..d93ebc2e --- /dev/null +++ b/server/migrations/2020-01-29-030825_create_user_mention_materialized_view/down.sql @@ -0,0 +1 @@ +drop view user_mention_mview; diff --git a/server/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql b/server/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql new file mode 100644 index 00000000..b0ae4e9d --- /dev/null +++ b/server/migrations/2020-01-29-030825_create_user_mention_materialized_view/up.sql @@ -0,0 +1,67 @@ +create view user_mention_mview as +with all_comment as +( + select + ca.* + from comment_aggregates_mview ca +) + +select + ac.id, + um.id as user_mention_id, + ac.creator_id, + ac.post_id, + ac.parent_id, + ac.content, + ac.removed, + um.read, + ac.published, + ac.updated, + ac.deleted, + ac.community_id, + ac.banned, + ac.banned_from_community, + ac.creator_name, + ac.creator_avatar, + ac.score, + ac.upvotes, + ac.downvotes, + u.id as user_id, + coalesce(cl.score, 0) as my_vote, + (select cs.id::bool from comment_saved cs where u.id = cs.user_id and cs.comment_id = ac.id) as saved, + um.recipient_id +from user_ u +cross join all_comment ac +left join comment_like cl on u.id = cl.user_id and ac.id = cl.comment_id +left join user_mention um on um.comment_id = ac.id + +union all + +select + ac.id, + um.id as user_mention_id, + ac.creator_id, + ac.post_id, + ac.parent_id, + ac.content, + ac.removed, + um.read, + ac.published, + ac.updated, + ac.deleted, + ac.community_id, + ac.banned, + ac.banned_from_community, + ac.creator_name, + ac.creator_avatar, + ac.score, + ac.upvotes, + ac.downvotes, + null as user_id, + null as my_vote, + null as saved, + um.recipient_id +from all_comment ac +left join user_mention um on um.comment_id = ac.id +; + diff --git a/server/query_testing/generate_explain_reports.sh b/server/query_testing/generate_explain_reports.sh index 0dc06f65..6ce7dc42 100755 --- a/server/query_testing/generate_explain_reports.sh +++ b/server/query_testing/generate_explain_reports.sh @@ -18,6 +18,15 @@ psql -qAt -U lemmy -f explain.sql > community_view.json echo "explain (analyze, format json) select * from site_view limit 1" > explain.sql psql -qAt -U lemmy -f explain.sql > site_view.json +echo "explain (analyze, format json) select * from reply_view where user_id = 34 and recipient_id = 34" > explain.sql +psql -qAt -U lemmy -f explain.sql > reply_view.json + +echo "explain (analyze, format json) select * from user_mention_view where user_id = 34 and recipient_id = 34" > explain.sql +psql -qAt -U lemmy -f explain.sql > user_mention_view.json + +echo "explain (analyze, format json) select * from user_mention_mview where user_id = 34 and recipient_id = 34" > explain.sql +psql -qAt -U lemmy -f explain.sql > user_mention_mview.json + grep "Execution Time" *.json rm explain.sql diff --git a/server/src/db/user_mention_view.rs b/server/src/db/user_mention_view.rs index 7a45d222..1cf43984 100644 --- a/server/src/db/user_mention_view.rs +++ b/server/src/db/user_mention_view.rs @@ -1,4 +1,3 @@ -use super::user_mention_view::user_mention_view::BoxedQuery; use super::*; use diesel::pg::Pg; @@ -31,6 +30,34 @@ table! { } } +table! { + user_mention_mview (id) { + id -> Int4, + user_mention_id -> Int4, + creator_id -> Int4, + post_id -> Int4, + parent_id -> Nullable<Int4>, + content -> Text, + removed -> Bool, + read -> Bool, + published -> Timestamp, + updated -> Nullable<Timestamp>, + deleted -> Bool, + community_id -> Int4, + banned -> Bool, + banned_from_community -> Bool, + creator_name -> Varchar, + creator_avatar -> Nullable<Text>, + score -> BigInt, + upvotes -> BigInt, + downvotes -> BigInt, + user_id -> Nullable<Int4>, + my_vote -> Nullable<Int4>, + saved -> Nullable<Bool>, + recipient_id -> Int4, + } +} + #[derive( Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize, QueryableByName, Clone, )] @@ -63,7 +90,7 @@ pub struct UserMentionView { pub struct UserMentionQueryBuilder<'a> { conn: &'a PgConnection, - query: BoxedQuery<'a, Pg>, + query: super::user_mention_view::user_mention_mview::BoxedQuery<'a, Pg>, for_user_id: i32, sort: &'a SortType, unread_only: bool, @@ -73,9 +100,9 @@ pub struct UserMentionQueryBuilder<'a> { impl<'a> UserMentionQueryBuilder<'a> { pub fn create(conn: &'a PgConnection, for_user_id: i32) -> Self { - use super::user_mention_view::user_mention_view::dsl::*; + use super::user_mention_view::user_mention_mview::dsl::*; - let query = user_mention_view.into_boxed(); + let query = user_mention_mview.into_boxed(); UserMentionQueryBuilder { conn, @@ -109,7 +136,7 @@ impl<'a> UserMentionQueryBuilder<'a> { } pub fn list(self) -> Result<Vec<UserMentionView>, Error> { - use super::user_mention_view::user_mention_view::dsl::*; + use super::user_mention_view::user_mention_mview::dsl::*; let mut query = self.query; diff --git a/server/src/version.rs b/server/src/version.rs index f2428229..c6b30c76 100644 --- a/server/src/version.rs +++ b/server/src/version.rs @@ -1 +1 @@ -pub const VERSION: &str = "v0.6.5"; +pub const VERSION: &str = "v0.6.7"; diff --git a/ui/package.json b/ui/package.json index d3085650..7e75052b 100644 --- a/ui/package.json +++ b/ui/package.json @@ -49,6 +49,7 @@ "fuse-box": "^3.1.3", "lint-staged": "^10.0.2", "sortpack": "^2.0.1", + "ts-node": "^8.6.2", "ts-transform-classcat": "^0.0.2", "ts-transform-inferno": "^4.0.2", "typescript": "^3.7.5" @@ -59,7 +60,7 @@ "engineStrict": true, "husky": { "hooks": { - "pre-commit": "ts-node translation_report.ts && git add ../README.md && cargo clippy --manifest-path ../server/Cargo.toml --all-targets --all-features -- -D warnings && lint-staged" + "pre-commit": "yarn run ts-node translation_report.ts && git add ../README.md && cargo clippy --manifest-path ../server/Cargo.toml --all-targets --all-features -- -D warnings && lint-staged" } }, "lint-staged": { diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx index e4543d66..7eb30f50 100644 --- a/ui/src/components/comment-form.tsx +++ b/ui/src/components/comment-form.tsx @@ -96,6 +96,7 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { className={`form-control ${this.state.previewMode && 'd-none'}`} value={this.state.commentForm.content} onInput={linkEvent(this, this.handleCommentContentChange)} + onPaste={linkEvent(this, this.handleImageUploadPaste)} required disabled={this.props.disabled} rows={2} @@ -208,9 +209,22 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> { i.props.onReplyCancel(); } + handleImageUploadPaste(i: CommentForm, event: any) { + let image = event.clipboardData.files[0]; + if (image) { + i.handleImageUpload(i, image); + } + } + handleImageUpload(i: CommentForm, event: any) { - event.preventDefault(); - let file = event.target.files[0]; + let file: any; + if (event.target) { + event.preventDefault(); + file = event.target.files[0]; + } else { + file = event; + } + const imageUploadUrl = `/pictshare/api/upload.php`; const formData = new FormData(); formData.append('file', file); diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index 221c9211..3c5f6890 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -11,6 +11,7 @@ import { SortType, Post, GetPostsForm, + GetCommunityForm, ListingType, GetPostsResponse, CreatePostLikeResponse, @@ -98,11 +99,11 @@ export class Community extends Component<any, State> { () => console.log('complete') ); - if (this.state.communityId) { - WebSocketService.Instance.getCommunity(this.state.communityId); - } else if (this.state.communityName) { - WebSocketService.Instance.getCommunityByName(this.state.communityName); - } + let form: GetCommunityForm = { + id: this.state.communityId ? this.state.communityId : null, + name: this.state.communityName ? this.state.communityName : null, + }; + WebSocketService.Instance.getCommunity(form); } componentWillUnmount() { diff --git a/ui/src/components/inbox.tsx b/ui/src/components/inbox.tsx index ba5cc6ad..41c1ce60 100644 --- a/ui/src/components/inbox.tsx +++ b/ui/src/components/inbox.tsx @@ -38,6 +38,8 @@ enum UnreadType { Messages, } +type ReplyType = Comment | PrivateMessageI; + interface InboxState { unreadOrAll: UnreadOrAll; unreadType: UnreadType; @@ -186,7 +188,7 @@ export class Inbox extends Component<any, InboxState> { } all() { - let combined: Array<Comment | PrivateMessageI> = []; + let combined: Array<ReplyType> = []; combined.push(...this.state.replies); combined.push(...this.state.mentions); diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx index 18ba98c9..1828fce9 100644 --- a/ui/src/components/navbar.tsx +++ b/ui/src/components/navbar.tsx @@ -138,7 +138,7 @@ export class Navbar extends Component<any, NavbarState> { </li> <li className="nav-item"> <Link - class="nav-link ml-2" + class="nav-link" to="/sponsors" title={i18n.t('donate_to_lemmy')} > diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx index ebc7d7b7..57d9a964 100644 --- a/ui/src/components/post-form.tsx +++ b/ui/src/components/post-form.tsx @@ -160,6 +160,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> { class="form-control" value={this.state.postForm.url} onInput={linkEvent(this, this.handlePostUrlChange)} + onPaste={linkEvent(this, this.handleImageUploadPaste)} /> {this.state.suggestedTitle && ( <div @@ -442,9 +443,22 @@ export class PostForm extends Component<PostFormProps, PostFormState> { i.setState(i.state); } + handleImageUploadPaste(i: PostForm, event: any) { + let image = event.clipboardData.files[0]; + if (image) { + i.handleImageUpload(i, image); + } + } + handleImageUpload(i: PostForm, event: any) { - event.preventDefault(); - let file = event.target.files[0]; + let file: any; + if (event.target) { + event.preventDefault(); + file = event.target.files[0]; + } else { + file = event; + } + const imageUploadUrl = `/pictshare/api/upload.php`; const formData = new FormData(); formData.append('file', file); diff --git a/ui/src/components/post.tsx b/ui/src/components/post.tsx index f57d8913..36621248 100644 --- a/ui/src/components/post.tsx +++ b/ui/src/components/post.tsx @@ -23,6 +23,7 @@ import { SearchType, SortType, SearchForm, + GetPostForm, SearchResponse, GetSiteResponse, GetCommunityResponse, @@ -84,7 +85,10 @@ export class Post extends Component<any, PostState> { () => console.log('complete') ); - WebSocketService.Instance.getPost(postId); + let form: GetPostForm = { + id: postId, + }; + WebSocketService.Instance.getPost(form); } componentWillUnmount() { @@ -231,6 +235,18 @@ export class Post extends Component<any, PostState> { onChange={linkEvent(this, this.handleCommentSortChange)} /> </label> + <label + className={`btn btn-sm btn-secondary pointer ${this.state + .commentSort === CommentSortType.Old && 'active'}`} + > + {i18n.t('old')} + <input + type="radio" + value={CommentSortType.Old} + checked={this.state.commentSort === CommentSortType.Old} + onChange={linkEvent(this, this.handleCommentSortChange)} + /> + </label> </div> ); } @@ -313,6 +329,13 @@ export class Post extends Component<any, PostState> { +a.comment.deleted - +b.comment.deleted || b.comment.published.localeCompare(a.comment.published) ); + } else if (this.state.commentSort == CommentSortType.Old) { + tree.sort( + (a, b) => + +a.comment.removed - +b.comment.removed || + +a.comment.deleted - +b.comment.deleted || + a.comment.published.localeCompare(b.comment.published) + ); } else if (this.state.commentSort == CommentSortType.Hot) { tree.sort( (a, b) => diff --git a/ui/src/i18next.ts b/ui/src/i18next.ts index 51e7e3a3..0d3ab177 100644 --- a/ui/src/i18next.ts +++ b/ui/src/i18next.ts @@ -12,6 +12,7 @@ import { nl } from './translations/nl'; import { it } from './translations/it'; import { fi } from './translations/fi'; import { ca } from './translations/ca'; +import { fa } from './translations/fa'; // https://github.com/nimbusec-oss/inferno-i18next/blob/master/tests/T.test.js#L66 const resources = { @@ -27,6 +28,7 @@ const resources = { it, fi, ca, + fa, }; function format(value: any, format: any, lng: any): any { diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index cd3961b5..f83595d7 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -47,6 +47,7 @@ export enum CommentSortType { Hot, Top, New, + Old, } export enum ListingType { @@ -248,6 +249,10 @@ export interface FollowCommunityForm { auth?: string; } +export interface GetFollowedCommunitiesForm { + auth: string; +} + export interface GetFollowedCommunitiesResponse { communities: Array<CommunityUser>; } @@ -523,6 +528,12 @@ export interface CommunityForm { auth?: string; } +export interface GetCommunityForm { + id?: number; + name?: string; + auth?: string; +} + export interface GetCommunityResponse { community: Community; moderators: Array<CommunityUser>; @@ -572,6 +583,11 @@ export interface PostFormParams { community?: string; } +export interface GetPostForm { + id: number; + auth?: string; +} + export interface GetPostResponse { post: Post; comments: Array<Comment>; @@ -759,6 +775,45 @@ export interface PrivateMessageResponse { message: PrivateMessage; } +export type MessageType = + | EditPrivateMessageForm + | LoginForm + | RegisterForm + | CommunityForm + | FollowCommunityForm + | ListCommunitiesForm + | GetFollowedCommunitiesForm + | PostForm + | GetPostForm + | GetPostsForm + | GetCommunityForm + | CommentForm + | CommentLikeForm + | SaveCommentForm + | CreatePostLikeForm + | BanFromCommunityForm + | AddAdminForm + | AddModToCommunityForm + | TransferCommunityForm + | TransferSiteForm + | SaveCommentForm + | BanUserForm + | AddAdminForm + | GetUserDetailsForm + | GetRepliesForm + | GetUserMentionsForm + | EditUserMentionForm + | GetModlogForm + | SiteForm + | SearchForm + | UserSettingsForm + | DeleteAccountForm + | PasswordResetForm + | PasswordChangeForm + | PrivateMessageForm + | EditPrivateMessageForm + | GetPrivateMessagesForm; + type ResponseType = | SiteResponse | GetFollowedCommunitiesResponse diff --git a/ui/src/services/WebSocketService.ts b/ui/src/services/WebSocketService.ts index b4042194..a7e9b7e0 100644 --- a/ui/src/services/WebSocketService.ts +++ b/ui/src/services/WebSocketService.ts @@ -9,9 +9,12 @@ import { CommentForm, SaveCommentForm, CommentLikeForm, + GetPostForm, GetPostsForm, CreatePostLikeForm, + GetCommunityForm, FollowCommunityForm, + GetFollowedCommunitiesForm, GetUserDetailsForm, ListCommunitiesForm, GetModlogForm, @@ -35,6 +38,7 @@ import { PrivateMessageForm, EditPrivateMessageForm, GetPrivateMessagesForm, + MessageType, } from '../interfaces'; import { webSocket } from 'rxjs/webSocket'; |