Browse Source

Preferred usernames, banners and icons. (#1055)

* Re-organizing federation tests. #746 #1040

* Adding federation support for user bios. Fixes #992

* Adding icons, banners, and preferred usernames.

- Added optional community icons, and community banners.
- Added user banners.
- Added Site icon and banner, with custom favicon.
- Set up preferred usernames. Fixes #1017
- Added an additional post sort: Active
  - Hot rank now uses the published time.
  - Active uses the most recent comment time, and is default.
- DB Migration was required to add all these fields to the views.
- Added transfercommunity helper function.
- Removed title column from communities page.
- Abstracted an image-upload-form.tsx, and a banner-icon-header.tsx
- Fixes #899

* Some navbar fixes.

* Fixing css

* Some fixes.

- Showing correct user icon and banner after save without page reload.
- Abstracting diesel update overwrite.
- Adding some docs.

* Adding @ when a user doesn't have a preferred username.
remove_make_mod_or_admin_for_federated_users
Dessalines 10 months ago
committed by GitHub
parent
commit
464ea862b1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      docs/src/about_ranking.md
  2. 25
      docs/src/contributing_websocket_http_api.md
  3. 1
      server/lemmy_db/src/activity.rs
  4. 13
      server/lemmy_db/src/comment.rs
  5. 31
      server/lemmy_db/src/comment_view.rs
  6. 19
      server/lemmy_db/src/community.rs
  7. 21
      server/lemmy_db/src/community_view.rs
  8. 15
      server/lemmy_db/src/lib.rs
  9. 4
      server/lemmy_db/src/moderator.rs
  10. 1
      server/lemmy_db/src/password_reset_request.rs
  11. 13
      server/lemmy_db/src/post.rs
  12. 21
      server/lemmy_db/src/post_view.rs
  13. 2
      server/lemmy_db/src/private_message.rs
  14. 4
      server/lemmy_db/src/private_message_view.rs
  15. 16
      server/lemmy_db/src/schema.rs
  16. 16
      server/lemmy_db/src/site.rs
  17. 6
      server/lemmy_db/src/site_view.rs
  18. 6
      server/lemmy_db/src/user.rs
  19. 4
      server/lemmy_db/src/user_mention.rs
  20. 12
      server/lemmy_db/src/user_mention_view.rs
  21. 13
      server/lemmy_db/src/user_view.rs
  22. 704
      server/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/down.sql
  23. 748
      server/migrations/2020-08-03-000110_add_preferred_usernames_banners_and_icons/up.sql
  24. 21
      server/src/api/community.rs
  25. 29
      server/src/api/site.rs
  26. 21
      server/src/api/user.rs
  27. 30
      server/src/apub/community.rs
  28. 2
      server/src/apub/inbox/activities/delete.rs
  29. 2
      server/src/apub/inbox/activities/remove.rs
  30. 4
      server/src/apub/inbox/activities/undo.rs
  31. 36
      server/src/apub/user.rs
  32. 5
      server/src/code_migrations.rs
  33. 16
      ui/assets/css/main.css
  34. 2
      ui/src/api_tests/shared.ts
  35. 2
      ui/src/components/admin-settings.tsx
  36. 30
      ui/src/components/banner-icon-header.tsx
  37. 2
      ui/src/components/comment-node.tsx
  38. 2
      ui/src/components/communities.tsx
  39. 54
      ui/src/components/community-form.tsx
  40. 26
      ui/src/components/community-link.tsx
  41. 44
      ui/src/components/community.tsx
  42. 114
      ui/src/components/image-upload-form.tsx
  43. 29
      ui/src/components/main.tsx
  44. 123
      ui/src/components/navbar.tsx
  45. 2
      ui/src/components/post-listing.tsx
  46. 15
      ui/src/components/post.tsx
  47. 2
      ui/src/components/private-message-form.tsx
  48. 49
      ui/src/components/private-message.tsx
  49. 2
      ui/src/components/search.tsx
  50. 53
      ui/src/components/sidebar.tsx
  51. 50
      ui/src/components/site-form.tsx
  52. 5
      ui/src/components/sort-select.tsx
  53. 3
      ui/src/components/symbols.tsx
  54. 30
      ui/src/components/user-listing.tsx
  55. 384
      ui/src/components/user.tsx
  56. 26
      ui/src/interfaces.ts
  57. 29
      ui/src/utils.ts
  58. 10
      ui/translations/en.json

4
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.

25
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.
@ -482,7 +483,19 @@ These expire after 10 minutes.
theme: String, // Default 'darkly'
default_sort_type: i16, // The Sort types from above, zero indexed as a number
default_listing_type: i16, // Post listing types are `All, Subscribed, Community`
auth: String
lang: String,
avatar: Option<String>,
banner: Option<String>,
preferred_username: Option<String>,
email: Option<String>,
bio: Option<String>,
matrix_user_id: Option<String>,
new_password: Option<String>,
new_password_verify: Option<String>,
old_password: Option<String>,
show_avatars: bool,
send_notifications_to_email: bool,
auth: String,
}
}
```
@ -924,6 +937,8 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
data: {
name: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
auth: String
}
}
@ -950,6 +965,8 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
data: {
name: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
auth: String
}
}
@ -1105,6 +1122,8 @@ Search types are `All, Comments, Posts, Communities, Users, Url`
name: String,
title: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
category_id: i32 ,
auth: String
}
@ -1215,6 +1234,8 @@ Only mods can edit a community.
edit_id: i32,
title: String,
description: Option<String>,
icon: Option<String>,
banner: Option<String>,
category_id: i32,
auth: String
}

1
server/lemmy_db/src/activity.rs

@ -107,6 +107,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,

13
server/lemmy_db/src/comment.rs

@ -116,10 +116,7 @@ impl Comment {
) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set((
deleted.eq(new_deleted),
updated.eq(naive_now())
))
.set((deleted.eq(new_deleted), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
@ -130,10 +127,7 @@ impl Comment {
) -> Result<Self, Error> {
use crate::schema::comment::dsl::*;
diesel::update(comment.find(comment_id))
.set((
removed.eq(new_removed),
updated.eq(naive_now())
))
.set((removed.eq(new_removed), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
@ -261,6 +255,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -297,6 +292,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
banner: None,
icon: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();

31
server/lemmy_db/src/comment_view.rs

@ -23,17 +23,20 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -60,17 +63,20 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -100,17 +106,20 @@ pub struct CommentView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub banned: bool,
pub banned_from_community: bool,
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_published: chrono::NaiveDateTime,
pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
pub subscribed: Option<bool>,
@ -244,6 +253,9 @@ impl<'a> CommentQueryBuilder<'a> {
SortType::Hot => query
.order_by(hot_rank.desc())
.then_order_by(published.desc()),
SortType::Active => query
.order_by(hot_rank_active.desc())
.then_order_by(published.desc()),
SortType::New => query.order_by(published.desc()),
SortType::TopAll => query.order_by(score.desc()),
SortType::TopYear => query
@ -315,17 +327,20 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Varchar>,
banned -> Bool,
banned_from_community -> Bool,
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
creator_published -> Timestamp,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
subscribed -> Nullable<Bool>,
@ -356,17 +371,20 @@ pub struct ReplyView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub banned: bool,
pub banned_from_community: bool,
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub creator_published: chrono::NaiveDateTime,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
pub subscribed: Option<bool>,
@ -437,7 +455,7 @@ impl<'a> ReplyQueryBuilder<'a> {
}
query = match self.sort {
// SortType::Hot => query.order_by(hot_rank.desc()),
// SortType::Hot => query.order_by(hot_rank.desc()), // TODO why is this commented
SortType::New => query.order_by(published.desc()),
SortType::TopAll => query.order_by(score.desc()),
SortType::TopYear => query
@ -488,6 +506,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -524,6 +543,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -584,6 +605,7 @@ mod tests {
post_name: inserted_post.name.to_owned(),
community_id: inserted_community.id,
community_name: inserted_community.name.to_owned(),
community_icon: None,
parent_id: None,
removed: false,
deleted: false,
@ -593,11 +615,13 @@ mod tests {
published: inserted_comment.published,
updated: None,
creator_name: inserted_user.name.to_owned(),
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
score: 1,
downvotes: 0,
hot_rank: 0,
hot_rank_active: 0,
upvotes: 1,
user_id: None,
my_vote: None,
@ -619,6 +643,7 @@ mod tests {
post_name: inserted_post.name.to_owned(),
community_id: inserted_community.id,
community_name: inserted_community.name.to_owned(),
community_icon: None,
parent_id: None,
removed: false,
deleted: false,
@ -628,11 +653,13 @@ mod tests {
published: inserted_comment.published,
updated: None,
creator_name: inserted_user.name.to_owned(),
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
score: 1,
downvotes: 0,
hot_rank: 0,
hot_rank_active: 0,
upvotes: 1,
user_id: Some(inserted_user.id),
my_vote: Some(1),
@ -651,6 +678,7 @@ mod tests {
.list()
.unwrap();
read_comment_views_no_user[0].hot_rank = 0;
read_comment_views_no_user[0].hot_rank_active = 0;
let mut read_comment_views_with_user = CommentQueryBuilder::create(&conn)
.for_post_id(inserted_post.id)
@ -658,6 +686,7 @@ mod tests {
.list()
.unwrap();
read_comment_views_with_user[0].hot_rank = 0;
read_comment_views_with_user[0].hot_rank_active = 0;
let like_removed = CommentLike::remove(&conn, &comment_like_form).unwrap();
let num_deleted = Comment::delete(&conn, inserted_comment.id).unwrap();

19
server/lemmy_db/src/community.rs

@ -28,6 +28,8 @@ pub struct Community {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: chrono::NaiveDateTime,
pub icon: Option<String>,
pub banner: Option<String>,
}
#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize, Debug)]
@ -48,6 +50,8 @@ pub struct CommunityForm {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
pub icon: Option<Option<String>>,
pub banner: Option<Option<String>>,
}
impl Crud<CommunityForm> for Community {
@ -107,10 +111,7 @@ impl Community {
) -> Result<Self, Error> {
use crate::schema::community::dsl::*;
diesel::update(community.find(community_id))
.set((
deleted.eq(new_deleted),
updated.eq(naive_now())
))
.set((deleted.eq(new_deleted), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
@ -121,10 +122,7 @@ impl Community {
) -> Result<Self, Error> {
use crate::schema::community::dsl::*;
diesel::update(community.find(community_id))
.set((
removed.eq(new_removed),
updated.eq(naive_now())
))
.set((removed.eq(new_removed), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
@ -305,6 +303,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -341,6 +340,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -362,6 +363,8 @@ mod tests {
private_key: None,
public_key: None,
last_refreshed_at: inserted_community.published,
icon: None,
banner: None,
};
let community_follower_form = CommunityFollowerForm {

21
server/lemmy_db/src/community_view.rs

@ -8,6 +8,8 @@ table! {
id -> Int4,
name -> Varchar,
title -> Varchar,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
description -> Nullable<Text>,
category_id -> Int4,
creator_id -> Int4,
@ -22,6 +24,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
category_name -> Varchar,
number_of_subscribers -> BigInt,
@ -38,6 +41,8 @@ table! {
id -> Int4,
name -> Varchar,
title -> Varchar,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
description -> Nullable<Text>,
category_id -> Int4,
creator_id -> Int4,
@ -52,6 +57,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
category_name -> Varchar,
number_of_subscribers -> BigInt,
@ -72,10 +78,12 @@ table! {
user_actor_id -> Text,
user_local -> Bool,
user_name -> Varchar,
user_preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
}
}
@ -88,10 +96,12 @@ table! {
user_actor_id -> Text,
user_local -> Bool,
user_name -> Varchar,
user_preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
}
}
@ -104,10 +114,12 @@ table! {
user_actor_id -> Text,
user_local -> Bool,
user_name -> Varchar,
user_preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
}
}
@ -119,6 +131,8 @@ pub struct CommunityView {
pub id: i32,
pub name: String,
pub title: String,
pub icon: Option<String>,
pub banner: Option<String>,
pub description: Option<String>,
pub category_id: i32,
pub creator_id: i32,
@ -133,6 +147,7 @@ pub struct CommunityView {
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub category_name: String,
pub number_of_subscribers: i64,
@ -288,10 +303,12 @@ pub struct CommunityModeratorView {
pub user_actor_id: String,
pub user_local: bool,
pub user_name: String,
pub user_preferred_username: Option<String>,
pub avatar: Option<String>,
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
}
impl CommunityModeratorView {
@ -324,10 +341,12 @@ pub struct CommunityFollowerView {
pub user_actor_id: String,
pub user_local: bool,
pub user_name: String,
pub user_preferred_username: Option<String>,
pub avatar: Option<String>,
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
}
impl CommunityFollowerView {
@ -358,10 +377,12 @@ pub struct CommunityUserBanView {
pub user_actor_id: String,
pub user_local: bool,
pub user_name: String,
pub user_preferred_username: Option<String>,
pub avatar: Option<String>,
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
}
impl CommunityUserBanView {

15
server/lemmy_db/src/lib.rs

@ -134,6 +134,7 @@ pub fn get_database_url_from_env() -> Result<String, VarError> {
#[derive(EnumString, ToString, Debug, Serialize, Deserialize)]
pub enum SortType {
Active,
Hot,
New,
TopDay,
@ -180,6 +181,20 @@ pub fn is_email_regex(test: &str) -> bool {
EMAIL_REGEX.is_match(test)
}
pub fn diesel_option_overwrite(opt: &Option<String>) -> Option<Option<String>> {
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();

4
server/lemmy_db/src/moderator.rs

@ -460,6 +460,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -487,6 +488,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -523,6 +525,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();

1
server/lemmy_db/src/password_reset_request.rs

@ -95,6 +95,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,

13
server/lemmy_db/src/post.rs

@ -119,10 +119,7 @@ impl Post {
) -> Result<Self, Error> {
use crate::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set((
deleted.eq(new_deleted),
updated.eq(naive_now())
))
.set((deleted.eq(new_deleted), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
@ -133,10 +130,7 @@ impl Post {
) -> Result<Self, Error> {
use crate::schema::post::dsl::*;
diesel::update(post.find(post_id))
.set((
removed.eq(new_removed),
updated.eq(naive_now())
))
.set((removed.eq(new_removed), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
@ -322,6 +316,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -358,6 +353,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();

21
server/lemmy_db/src/post_view.rs

@ -28,6 +28,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
banned -> Bool,
@ -35,6 +36,7 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
community_removed -> Bool,
community_deleted -> Bool,
community_nsfw -> Bool,
@ -43,6 +45,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
newest_activity_time -> Timestamp,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
@ -76,6 +79,7 @@ table! {
creator_actor_id -> Text,
creator_local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Timestamp,
creator_avatar -> Nullable<Text>,
banned -> Bool,
@ -83,6 +87,7 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
community_removed -> Bool,
community_deleted -> Bool,
community_nsfw -> Bool,
@ -91,6 +96,7 @@ table! {
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
newest_activity_time -> Timestamp,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
@ -127,6 +133,7 @@ pub struct PostView {
pub creator_actor_id: String,
pub creator_local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_published: chrono::NaiveDateTime,
pub creator_avatar: Option<String>,
pub banned: bool,
@ -134,6 +141,7 @@ pub struct PostView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub community_removed: bool,
pub community_deleted: bool,
pub community_nsfw: bool,
@ -142,6 +150,7 @@ pub struct PostView {
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub newest_activity_time: chrono::NaiveDateTime,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
@ -289,6 +298,9 @@ impl<'a> PostQueryBuilder<'a> {
}
query = match self.sort {
SortType::Active => query
.then_order_by(hot_rank_active.desc())
.then_order_by(published.desc()),
SortType::Hot => query
.then_order_by(hot_rank.desc())
.then_order_by(published.desc()),
@ -405,6 +417,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
updated: None,
admin: false,
banned: false,
@ -441,6 +454,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();
@ -519,6 +534,7 @@ mod tests {
body: None,
creator_id: inserted_user.id,
creator_name: user_name.to_owned(),
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
banned: false,
@ -529,6 +545,7 @@ mod tests {
locked: false,
stickied: false,
community_name: community_name.to_owned(),
community_icon: None,
community_removed: false,
community_deleted: false,
community_nsfw: false,
@ -537,6 +554,7 @@ mod tests {
upvotes: 1,
downvotes: 0,
hot_rank: read_post_listing_no_user.hot_rank,
hot_rank_active: read_post_listing_no_user.hot_rank_active,
published: inserted_post.published,
newest_activity_time: inserted_post.published,
updated: None,
@ -569,12 +587,14 @@ mod tests {
stickied: false,
creator_id: inserted_user.id,
creator_name: user_name,
creator_preferred_username: None,
creator_published: inserted_user.published,
creator_avatar: None,
banned: false,
banned_from_community: false,
community_id: inserted_community.id,
community_name,
community_icon: None,
community_removed: false,
community_deleted: false,
community_nsfw: false,
@ -583,6 +603,7 @@ mod tests {
upvotes: 1,
downvotes: 0,
hot_rank: read_post_listing_with_user.hot_rank,
hot_rank_active: read_post_listing_with_user.hot_rank_active,
published: inserted_post.published,
newest_activity_time: inserted_post.published,
updated: None,

2
server/lemmy_db/src/private_message.rs

@ -147,6 +147,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -174,6 +175,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,

4
server/lemmy_db/src/private_message_view.rs

@ -16,10 +16,12 @@ table! {
ap_id -> Text,
local -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
creator_actor_id -> Text,
creator_local -> Bool,
recipient_name -> Varchar,
recipient_preferred_username -> Nullable<Varchar>,
recipient_avatar -> Nullable<Text>,
recipient_actor_id -> Text,
recipient_local -> Bool,
@ -42,10 +44,12 @@ pub struct PrivateMessageView {
pub ap_id: String,
pub local: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub creator_actor_id: String,
pub creator_local: bool,
pub recipient_name: String,
pub recipient_preferred_username: Option<String>,
pub recipient_avatar: Option<String>,
pub recipient_actor_id: String,
pub recipient_local: bool,

16
server/lemmy_db/src/schema.rs

@ -52,17 +52,20 @@ table! {
community_actor_id -> Nullable<Varchar>,
community_local -> Nullable<Bool>,
community_name -> Nullable<Varchar>,
community_icon -> Nullable<Text>,
banned -> Nullable<Bool>,
banned_from_community -> Nullable<Bool>,
creator_actor_id -> Nullable<Varchar>,
creator_local -> Nullable<Bool>,
creator_name -> Nullable<Varchar>,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Nullable<Timestamp>,
creator_avatar -> Nullable<Text>,
score -> Nullable<Int8>,
upvotes -> Nullable<Int8>,
downvotes -> Nullable<Int8>,
hot_rank -> Nullable<Int4>,
hot_rank_active -> Nullable<Int4>,
}
}
@ -104,6 +107,8 @@ table! {
private_key -> Nullable<Text>,
public_key -> Nullable<Text>,
last_refreshed_at -> Timestamp,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
}
}
@ -112,6 +117,8 @@ table! {
id -> Int4,
name -> Nullable<Varchar>,
title -> Nullable<Varchar>,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
description -> Nullable<Text>,
category_id -> Nullable<Int4>,
creator_id -> Nullable<Int4>,
@ -126,6 +133,7 @@ table! {
creator_actor_id -> Nullable<Varchar>,
creator_local -> Nullable<Bool>,
creator_name -> Nullable<Varchar>,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
category_name -> Nullable<Varchar>,
number_of_subscribers -> Nullable<Int8>,
@ -319,6 +327,7 @@ table! {
creator_actor_id -> Nullable<Varchar>,
creator_local -> Nullable<Bool>,
creator_name -> Nullable<Varchar>,
creator_preferred_username -> Nullable<Varchar>,
creator_published -> Nullable<Timestamp>,
creator_avatar -> Nullable<Text>,
banned -> Nullable<Bool>,
@ -326,6 +335,7 @@ table! {
community_actor_id -> Nullable<Varchar>,
community_local -> Nullable<Bool>,
community_name -> Nullable<Varchar>,
community_icon -> Nullable<Text>,
community_removed -> Nullable<Bool>,
community_deleted -> Nullable<Bool>,
community_nsfw -> Nullable<Bool>,
@ -334,6 +344,7 @@ table! {
upvotes -> Nullable<Int8>,
downvotes -> Nullable<Int8>,
hot_rank -> Nullable<Int4>,
hot_rank_active -> Nullable<Int4>,
newest_activity_time -> Nullable<Timestamp>,
}
}
@ -392,6 +403,8 @@ table! {
enable_downvotes -> Bool,
open_registration -> Bool,
enable_nsfw -> Bool,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
}
}
@ -421,6 +434,7 @@ table! {
private_key -> Nullable<Text>,
public_key -> Nullable<Text>,
last_refreshed_at -> Timestamp,
banner -> Nullable<Text>,
}
}
@ -437,7 +451,9 @@ table! {
id -> Int4,
actor_id -> Nullable<Varchar>,
name -> Nullable<Varchar>,
preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
banner -> Nullable<Text>,
email -> Nullable<Text>,
matrix_user_id -> Nullable<Text>,
bio -> Nullable<Text>,

16
server/lemmy_db/src/site.rs

@ -1,4 +1,4 @@
use crate::{schema::site, Crud};
use crate::{naive_now, schema::site, Crud};
use diesel::{dsl::*, result::Error, *};
use serde::{Deserialize, Serialize};
@ -14,6 +14,8 @@ pub struct Site {
pub enable_downvotes: bool,
pub open_registration: bool,
pub enable_nsfw: bool,
pub icon: Option<String>,
pub banner: Option<String>,
}
#[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize)]
@ -26,6 +28,9 @@ 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<Option<String>>,
pub banner: Option<Option<String>>,
}
impl Crud<SiteForm> for Site {
@ -51,3 +56,12 @@ impl Crud<SiteForm> for Site {
.get_result::<Self>(conn)
}
}
impl Site {
pub fn transfer(conn: &PgConnection, new_creator_id: i32) -> Result<Self, Error> {
use crate::schema::site::dsl::*;
diesel::update(site.find(1))
.set((creator_id.eq(new_creator_id), updated.eq(naive_now())))
.get_result::<Self>(conn)
}
}

6
server/lemmy_db/src/site_view.rs

@ -12,7 +12,10 @@ table! {
enable_downvotes -> Bool,
open_registration -> Bool,
enable_nsfw -> Bool,
icon -> Nullable<Text>,
banner -> Nullable<Text>,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
number_of_users -> BigInt,
number_of_posts -> BigInt,
@ -35,7 +38,10 @@ pub struct SiteView {
pub enable_downvotes: bool,
pub open_registration: bool,
pub enable_nsfw: bool,
pub icon: Option<String>,
pub banner: Option<String>,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub number_of_users: i64,
pub number_of_posts: i64,

6
server/lemmy_db/src/user.rs

@ -35,6 +35,7 @@ pub struct User_ {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: chrono::NaiveDateTime,
pub banner: Option<String>,
}
#[derive(Insertable, AsChangeset, Clone, Debug)]
@ -46,7 +47,7 @@ pub struct UserForm {
pub admin: bool,
pub banned: bool,
pub email: Option<String>,
pub avatar: Option<String>,
pub avatar: Option<Option<String>>,
pub updated: Option<chrono::NaiveDateTime>,
pub show_nsfw: bool,
pub theme: String,
@ -62,6 +63,7 @@ pub struct UserForm {
pub private_key: Option<String>,
pub public_key: Option<String>,
pub last_refreshed_at: Option<chrono::NaiveDateTime>,
pub banner: Option<Option<String>>,
}
impl Crud<UserForm> for User_ {
@ -167,6 +169,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -195,6 +198,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
published: inserted_user.published,

4
server/lemmy_db/src/user_mention.rs

@ -100,6 +100,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -127,6 +128,7 @@ mod tests {
email: None,
matrix_user_id: None,
avatar: None,
banner: None,
admin: false,
banned: false,
updated: None,
@ -163,6 +165,8 @@ mod tests {
public_key: None,
last_refreshed_at: None,
published: None,
icon: None,
banner: None,
};
let inserted_community = Community::create(&conn, &new_community).unwrap();

12
server/lemmy_db/src/user_mention_view.rs

@ -23,14 +23,17 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
saved -> Nullable<Bool>,
@ -60,14 +63,17 @@ table! {
community_actor_id -> Text,
community_local -> Bool,
community_name -> Varchar,
community_icon -> Nullable<Text>,
banned -> Bool,
banned_from_community -> Bool,
creator_name -> Varchar,
creator_preferred_username -> Nullable<Varchar>,
creator_avatar -> Nullable<Text>,
score -> BigInt,
upvotes -> BigInt,
downvotes -> BigInt,
hot_rank -> Int4,
hot_rank_active -> Int4,
user_id -> Nullable<Int4>,
my_vote -> Nullable<Int4>,
saved -> Nullable<Bool>,
@ -100,14 +106,17 @@ pub struct UserMentionView {
pub community_actor_id: String,
pub community_local: bool,
pub community_name: String,
pub community_icon: Option<String>,
pub banned: bool,
pub banned_from_community: bool,
pub creator_name: String,
pub creator_preferred_username: Option<String>,
pub creator_avatar: Option<String>,
pub score: i64,
pub upvotes: i64,
pub downvotes: i64,
pub hot_rank: i32,
pub hot_rank_active: i32,
pub user_id: Option<i32>,
pub my_vote: Option<i32>,
pub saved: Option<bool>,
@ -180,6 +189,9 @@ impl<'a> UserMentionQueryBuilder<'a> {
SortType::Hot => query
.order_by(hot_rank.desc())
.then_order_by(published.desc()),
SortType::Active => query
.order_by(hot_rank_active.desc())
.then_order_by(published.desc()),
SortType::New => query.order_by(published.desc()),
SortType::TopAll => query.order_by(score.desc()),
SortType::TopYear => query

13
server/lemmy_db/src/user_view.rs

@ -8,7 +8,9 @@ table! {
id -> Int4,
actor_id -> Text,
name -> Varchar,
preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
banner -> Nullable<Text>,
email -> Nullable<Text>,
matrix_user_id -> Nullable<Text>,
bio -> Nullable<Text>,
@ -30,7 +32,9 @@ table! {
id -> Int4,
actor_id -> Text,
name -> Varchar,
preferred_username -> Nullable<Varchar>,
avatar -> Nullable<Text>,
banner -> Nullable<Text>,
email -> Nullable<Text>,
matrix_user_id -> Nullable<Text>,
bio -> Nullable<Text>,
@ -55,7 +59,9 @@ pub struct UserView {
pub id: i32,
pub actor_id: String,
pub name: String,
pub preferred_username: Option<String>,
pub avatar: Option<String>,
pub banner: Option<String>,
pub email: Option<String>, // TODO this shouldn't be in this view
pub matrix_user_id: Option<String>,
pub bio: Option<String>,
@ -126,6 +132,9 @@ impl<'a> UserQueryBuilder<'a> {
SortType::Hot => query
.order_by(comment_score.desc())
.then_order_by(published.desc()),
SortType::Active => query
.order_by(comment_score.desc())
.then_order_by(published.desc()),
SortType::New => query.order_by(published.desc()),
SortType::TopAll => query.order_by(comment_score.desc()),
SortType::TopYear => query
@ -164,7 +173,9 @@ impl UserView {
id,
actor_id,
name,
preferred_username,
avatar,
banner,
"".into_sql::<Nullable<Text>>(),
matrix_user_id,
bio,
@ -192,7 +203,9 @@ impl UserView {
id,