From 39d75a6984c323f768f6e57c884be0e4af9e4387 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 4 Aug 2020 17:21:12 -0400 Subject: [PATCH] Some fixes. - Showing correct user icon and banner after save without page reload. - Abstracting diesel update overwrite. - Adding some docs. --- docs/src/about_ranking.md | 4 ++- docs/src/contributing_websocket_http_api.md | 3 +- server/lemmy_db/src/lib.rs | 14 +++++++++ server/lemmy_db/src/site.rs | 1 + server/src/api/community.rs | 35 +++++++-------------- server/src/api/site.rs | 26 ++------------- server/src/api/user.rs | 25 ++------------- ui/src/components/user.tsx | 2 ++ 8 files changed, 39 insertions(+), 71 deletions(-) diff --git a/docs/src/about_ranking.md b/docs/src/about_ranking.md index f1ed9b386..0f91b7e39 100644 --- a/docs/src/about_ranking.md +++ b/docs/src/about_ranking.md @@ -18,7 +18,9 @@ Score = Upvotes - Downvotes Time = time since submission (in hours) Gravity = Decay gravity, 1.8 is default ``` -- For posts, in order to bring up active posts, it uses the latest comment time (limited to a max creation age of a month ago) +- Lemmy uses the same `Rank` algorithm above, in two sorts: `Active`, and `Hot`. + - `Active` uses the post votes, and latest comment time (limited to two days). + - `Hot` uses the post votes, and the post published time. - Use Max(1, score) to make sure all comments are affected by time decay. - Add 3 to the score, so that everything that has less than 3 downvotes will seem new. Otherwise all new comments would stay at zero, near the bottom. - The sign and abs of the score are necessary for dealing with the log of negative scores. diff --git a/docs/src/contributing_websocket_http_api.md b/docs/src/contributing_websocket_http_api.md index 89c166cb2..fa241d162 100644 --- a/docs/src/contributing_websocket_http_api.md +++ b/docs/src/contributing_websocket_http_api.md @@ -330,7 +330,8 @@ curl -i -H \ These go wherever there is a `sort` field. The available sort types are: -- `Hot` - the hottest posts/communities, depending on votes, views, comments and publish date +- `Active` - the hottest posts/communities, depending on votes, and newest comment publish date. +- `Hot` - the hottest posts/communities, depending on votes and publish date. - `New` - the newest posts/communities - `TopDay` - the most upvoted posts/communities of the current day. - `TopWeek` - the most upvoted posts/communities of the current week. diff --git a/server/lemmy_db/src/lib.rs b/server/lemmy_db/src/lib.rs index 42b6f354a..edfc26468 100644 --- a/server/lemmy_db/src/lib.rs +++ b/server/lemmy_db/src/lib.rs @@ -181,6 +181,20 @@ pub fn is_email_regex(test: &str) -> bool { EMAIL_REGEX.is_match(test) } +pub fn diesel_option_overwrite(opt: &Option) -> Option> { + match opt { + // An empty string is an erase + Some(unwrapped) => { + if !unwrapped.eq("") { + Some(Some(unwrapped.to_owned())) + } else { + Some(None) + } + } + None => None, + } +} + lazy_static! { static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap(); diff --git a/server/lemmy_db/src/site.rs b/server/lemmy_db/src/site.rs index dbbde59ea..51699d657 100644 --- a/server/lemmy_db/src/site.rs +++ b/server/lemmy_db/src/site.rs @@ -28,6 +28,7 @@ pub struct SiteForm { pub enable_downvotes: bool, pub open_registration: bool, pub enable_nsfw: bool, + // when you want to null out a column, you have to send Some(None)), since sending None means you just don't want to update that column. pub icon: Option>, pub banner: Option>, } diff --git a/server/src/api/community.rs b/server/src/api/community.rs index 466ba46db..ce2851b1d 100644 --- a/server/src/api/community.rs +++ b/server/src/api/community.rs @@ -10,7 +10,15 @@ use crate::{ }, DbPool, }; -use lemmy_db::{naive_now, Bannable, Crud, Followable, Joinable, SortType}; +use lemmy_db::{ + diesel_option_overwrite, + naive_now, + Bannable, + Crud, + Followable, + Joinable, + SortType, +}; use lemmy_utils::{ generate_actor_keypair, is_valid_community_name, @@ -338,29 +346,8 @@ impl Perform for Oper { let edit_id = data.edit_id; let read_community = blocking(pool, move |conn| Community::read(conn, edit_id)).await??; - let icon = match &data.icon { - // An empty string is an erase - Some(icon) => { - if !icon.eq("") { - Some(Some(icon.to_owned())) - } else { - Some(None) - } - } - None => Some(read_community.icon), - }; - - let banner = match &data.banner { - // An empty string is an erase - Some(banner) => { - if !banner.eq("") { - Some(Some(banner.to_owned())) - } else { - Some(None) - } - } - None => Some(read_community.banner), - }; + let icon = diesel_option_overwrite(&data.icon); + let banner = diesel_option_overwrite(&data.banner); let community_form = CommunityForm { name: read_community.name, diff --git a/server/src/api/site.rs b/server/src/api/site.rs index b3219c6e4..dcbd62167 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -21,6 +21,7 @@ use lemmy_db::{ category::*, comment_view::*, community_view::*, + diesel_option_overwrite, moderator::*, moderator_views::*, naive_now, @@ -306,29 +307,8 @@ impl Perform for Oper { let found_site = blocking(pool, move |conn| Site::read(conn, 1)).await??; - let icon = match &data.icon { - // An empty string is an erase - Some(icon) => { - if !icon.eq("") { - Some(Some(icon.to_owned())) - } else { - Some(None) - } - } - None => Some(found_site.icon), - }; - - let banner = match &data.banner { - // An empty string is an erase - Some(banner) => { - if !banner.eq("") { - Some(Some(banner.to_owned())) - } else { - Some(None) - } - } - None => Some(found_site.banner), - }; + let icon = diesel_option_overwrite(&data.icon); + let banner = diesel_option_overwrite(&data.banner); let site_form = SiteForm { name: data.name.to_owned(), diff --git a/server/src/api/user.rs b/server/src/api/user.rs index 595bd2909..ffdcee9a2 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -28,6 +28,7 @@ use lemmy_db::{ comment_view::*, community::*, community_view::*, + diesel_option_overwrite, moderator::*, naive_now, password_reset_request::*, @@ -574,28 +575,8 @@ impl Perform for Oper { None => read_user.bio, }; - let avatar = match &data.avatar { - // An empty string is an erase - Some(avatar) => { - if !avatar.eq("") { - Some(Some(avatar.to_owned())) - } else { - Some(None) - } - } - None => Some(read_user.avatar), - }; - - let banner = match &data.banner { - Some(banner) => { - if !banner.eq("") { - Some(Some(banner.to_owned())) - } else { - Some(None) - } - } - None => Some(read_user.banner), - }; + let avatar = diesel_option_overwrite(&data.avatar); + let banner = diesel_option_overwrite(&data.banner); // The DB constraint should stop too many characters let preferred_username = match &data.preferred_username { diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index 9f2521af1..227c250b7 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -1082,6 +1082,8 @@ export class User extends Component { UserService.Instance.login(data); this.state.user.bio = this.state.userSettingsForm.bio; this.state.user.preferred_username = this.state.userSettingsForm.preferred_username; + this.state.user.banner = this.state.userSettingsForm.banner; + this.state.user.avatar = this.state.userSettingsForm.avatar; this.state.userSettingsLoading = false; this.setState(this.state);