summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDessalines <tyhou13@gmx.com>2020-01-02 16:55:54 -0500
committerDessalines <tyhou13@gmx.com>2020-01-02 16:55:54 -0500
commit5b42dc3393431184293ded2f9d30a11fe5548d52 (patch)
treee906ad2afdd3d7e9f8e0f6116d6023a42ba92d03
parent576980bf64fcde5ec66e0260c81ef3225dd264bd (diff)
Adding show_avatar user setting, and option to send notifications to inbox.
- Fixes #254 - Fixes #394
-rw-r--r--.gitignore1
-rw-r--r--server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql20
-rw-r--r--server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql22
-rw-r--r--server/src/api/comment.rs79
-rw-r--r--server/src/api/user.rs10
-rw-r--r--server/src/apub/mod.rs2
-rw-r--r--server/src/db/comment.rs2
-rw-r--r--server/src/db/comment_view.rs2
-rw-r--r--server/src/db/community.rs2
-rw-r--r--server/src/db/moderator.rs4
-rw-r--r--server/src/db/password_reset_request.rs2
-rw-r--r--server/src/db/post.rs2
-rw-r--r--server/src/db/post_view.rs2
-rw-r--r--server/src/db/user.rs10
-rw-r--r--server/src/db/user_mention.rs4
-rw-r--r--server/src/db/user_view.rs4
-rw-r--r--server/src/schema.rs2
-rw-r--r--ui/src/components/comment-node.tsx3
-rw-r--r--ui/src/components/main.tsx3
-rw-r--r--ui/src/components/navbar.tsx4
-rw-r--r--ui/src/components/post-listing.tsx3
-rw-r--r--ui/src/components/search.tsx3
-rw-r--r--ui/src/components/sidebar.tsx9
-rw-r--r--ui/src/components/user.tsx56
-rw-r--r--ui/src/interfaces.ts5
-rw-r--r--ui/src/translations/en.ts2
-rw-r--r--ui/src/utils.ts7
27 files changed, 249 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
index 4cb8939f..16548f36 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
ansible/inventory
ansible/passwords/
+docker/lemmy_mine.hjson
build/
.idea/
diff --git a/server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql b/server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql
new file mode 100644
index 00000000..ec061223
--- /dev/null
+++ b/server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/down.sql
@@ -0,0 +1,20 @@
+-- Drop the columns
+drop view user_view;
+alter table user_ drop column show_avatars;
+alter table user_ drop column send_notifications_to_email;
+
+-- Rebuild the view
+create view user_view as
+select id,
+name,
+avatar,
+email,
+fedi_name,
+admin,
+banned,
+published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
diff --git a/server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql b/server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql
new file mode 100644
index 00000000..21f0aff4
--- /dev/null
+++ b/server/migrations/2020-01-02-172755_add_show_avatar_and_email_notifications_to_user/up.sql
@@ -0,0 +1,22 @@
+-- Add columns
+alter table user_ add column show_avatars boolean default true not null;
+alter table user_ add column send_notifications_to_email boolean default false not null;
+
+-- Rebuild the user_view
+drop view user_view;
+create view user_view as
+select id,
+name,
+avatar,
+email,
+fedi_name,
+admin,
+banned,
+show_avatars,
+send_notifications_to_email,
+published,
+(select count(*) from post p where p.creator_id = u.id) as number_of_posts,
+(select coalesce(sum(score), 0) from post p, post_like pl where u.id = p.creator_id and p.id = pl.post_id) as post_score,
+(select count(*) from comment c where c.creator_id = u.id) as number_of_comments,
+(select coalesce(sum(score), 0) from comment c, comment_like cl where u.id = c.creator_id and c.id = cl.comment_id) as comment_score
+from user_ u;
diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs
index ed658985..5c3417dd 100644
--- a/server/src/api/comment.rs
+++ b/server/src/api/comment.rs
@@ -1,4 +1,6 @@
use super::*;
+use crate::send_email;
+use crate::settings::Settings;
#[derive(Serialize, Deserialize)]
pub struct CreateComment {
@@ -56,6 +58,8 @@ impl Perform<CommentResponse> for Oper<CreateComment> {
let user_id = claims.id;
+ let hostname = &format!("https://{}", Settings::get().hostname);
+
// Check for a community ban
let post = Post::read(&conn, data.post_id)?;
if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() {
@@ -89,17 +93,13 @@ impl Perform<CommentResponse> for Oper<CreateComment> {
let extracted_usernames = extract_usernames(&comment_form.content);
for username_mention in &extracted_usernames {
- let mention_user = User_::read_from_name(&conn, (*username_mention).to_string());
-
- if mention_user.is_ok() {
- let mention_user_id = mention_user?.id;
-
+ if let Ok(mention_user) = User_::read_from_name(&conn, (*username_mention).to_string()) {
// You can't mention yourself
// At some point, make it so you can't tag the parent creator either
// This can cause two notifications, one for reply and the other for mention
- if mention_user_id != user_id {
+ if mention_user.id != user_id {
let user_mention_form = UserMentionForm {
- recipient_id: mention_user_id,
+ recipient_id: mention_user.id,
comment_id: inserted_comment.id,
read: None,
};
@@ -109,11 +109,76 @@ impl Perform<CommentResponse> for Oper<CreateComment> {
match UserMention::create(&conn, &user_mention_form) {
Ok(_mention) => (),
Err(_e) => eprintln!("{}", &_e),
+ };
+
+ // Send an email to those users that have notifications on
+ if mention_user.send_notifications_to_email {
+ if let Some(mention_email) = mention_user.email {
+ let subject = &format!(
+ "{} - Mentioned by {}",
+ Settings::get().hostname,
+ claims.username
+ );
+ let html = &format!(
+ "<h1>User Mention</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
+ claims.username, comment_form.content, hostname
+ );
+ match send_email(subject, &mention_email, &mention_user.name, html) {
+ Ok(_o) => _o,
+ Err(e) => eprintln!("{}", e),
+ };
+ }
}
}
}
}
+ // Send notifs to the parent commenter / poster
+ match data.parent_id {
+ Some(parent_id) => {
+ let parent_comment = Comment::read(&conn, parent_id)?;
+ let parent_user = User_::read(&conn, parent_comment.creator_id)?;
+ if parent_user.send_notifications_to_email {
+ if let Some(comment_reply_email) = parent_user.email {
+ let subject = &format!(
+ "{} - Reply from {}",
+ Settings::get().hostname,
+ claims.username
+ );
+ let html = &format!(
+ "<h1>Comment Reply</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
+ claims.username, comment_form.content, hostname
+ );
+ match send_email(subject, &comment_reply_email, &parent_user.name, html) {
+ Ok(_o) => _o,
+ Err(e) => eprintln!("{}", e),
+ };
+ }
+ }
+ }
+ // Its a post
+ None => {
+ let parent_user = User_::read(&conn, post.creator_id)?;
+ if parent_user.send_notifications_to_email {
+ if let Some(post_reply_email) = parent_user.email {
+ let subject = &format!(
+ "{} - Reply from {}",
+ Settings::get().hostname,
+ claims.username
+ );
+ let html = &format!(
+ "<h1>Post Reply</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
+ claims.username, comment_form.content, hostname
+ );
+ match send_email(subject, &post_reply_email, &parent_user.name, html) {
+ Ok(_o) => _o,
+ Err(e) => eprintln!("{}", e),
+ };
+ }
+ }
+ }
+ };
+
// You like your own comment by default
let like_form = CommentLikeForm {
comment_id: inserted_comment.id,
diff --git a/server/src/api/user.rs b/server/src/api/user.rs
index 912587da..41729eb7 100644
--- a/server/src/api/user.rs
+++ b/server/src/api/user.rs
@@ -32,6 +32,8 @@ pub struct SaveUserSettings {
new_password: Option<String>,
new_password_verify: Option<String>,
old_password: Option<String>,
+ show_avatars: bool,
+ send_notifications_to_email: bool,
auth: String,
}
@@ -231,6 +233,8 @@ impl Perform<LoginResponse> for Oper<Register> {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
// Create the user
@@ -356,6 +360,8 @@ impl Perform<LoginResponse> for Oper<SaveUserSettings> {
default_sort_type: data.default_sort_type,
default_listing_type: data.default_listing_type,
lang: data.lang.to_owned(),
+ show_avatars: data.show_avatars,
+ send_notifications_to_email: data.send_notifications_to_email,
};
let updated_user = match User_::update(&conn, user_id, &user_form) {
@@ -497,6 +503,8 @@ impl Perform<AddAdminResponse> for Oper<AddAdmin> {
default_sort_type: read_user.default_sort_type,
default_listing_type: read_user.default_listing_type,
lang: read_user.lang,
+ show_avatars: read_user.show_avatars,
+ send_notifications_to_email: read_user.send_notifications_to_email,
};
match User_::update(&conn, data.user_id, &user_form) {
@@ -560,6 +568,8 @@ impl Perform<BanUserResponse> for Oper<BanUser> {
default_sort_type: read_user.default_sort_type,
default_listing_type: read_user.default_listing_type,
lang: read_user.lang,
+ show_avatars: read_user.show_avatars,
+ send_notifications_to_email: read_user.send_notifications_to_email,
};
match User_::update(&conn, data.user_id, &user_form) {
diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs
index b1a01b6d..2d2e5ad3 100644
--- a/server/src/apub/mod.rs
+++ b/server/src/apub/mod.rs
@@ -32,6 +32,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let person = user.as_person();
diff --git a/server/src/db/comment.rs b/server/src/db/comment.rs
index 64195356..b3198052 100644
--- a/server/src/db/comment.rs
+++ b/server/src/db/comment.rs
@@ -183,6 +183,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/comment_view.rs b/server/src/db/comment_view.rs
index c56da51d..2942bbe7 100644
--- a/server/src/db/comment_view.rs
+++ b/server/src/db/comment_view.rs
@@ -381,6 +381,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/community.rs b/server/src/db/community.rs
index b5d05384..09c3ddc4 100644
--- a/server/src/db/community.rs
+++ b/server/src/db/community.rs
@@ -229,6 +229,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/moderator.rs b/server/src/db/moderator.rs
index 7f1c3499..dc018bd9 100644
--- a/server/src/db/moderator.rs
+++ b/server/src/db/moderator.rs
@@ -451,6 +451,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_mod = User_::create(&conn, &new_mod).unwrap();
@@ -470,6 +472,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/password_reset_request.rs b/server/src/db/password_reset_request.rs
index b7983f53..1664516b 100644
--- a/server/src/db/password_reset_request.rs
+++ b/server/src/db/password_reset_request.rs
@@ -101,6 +101,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/post.rs b/server/src/db/post.rs
index da669ea1..084edc9b 100644
--- a/server/src/db/post.rs
+++ b/server/src/db/post.rs
@@ -196,6 +196,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/post_view.rs b/server/src/db/post_view.rs
index 22e2eb14..f0638eb5 100644
--- a/server/src/db/post_view.rs
+++ b/server/src/db/post_view.rs
@@ -311,6 +311,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
diff --git a/server/src/db/user.rs b/server/src/db/user.rs
index 82736f8e..b0401297 100644
--- a/server/src/db/user.rs
+++ b/server/src/db/user.rs
@@ -24,6 +24,8 @@ pub struct User_ {
pub default_sort_type: i16,
pub default_listing_type: i16,
pub lang: String,
+ pub show_avatars: bool,
+ pub send_notifications_to_email: bool,
}
#[derive(Insertable, AsChangeset, Clone)]
@@ -43,6 +45,8 @@ pub struct UserForm {
pub default_sort_type: i16,
pub default_listing_type: i16,
pub lang: String,
+ pub show_avatars: bool,
+ pub send_notifications_to_email: bool,
}
impl Crud<UserForm> for User_ {
@@ -100,6 +104,7 @@ pub struct Claims {
pub default_listing_type: i16,
pub lang: String,
pub avatar: Option<String>,
+ pub show_avatars: bool,
}
impl Claims {
@@ -125,6 +130,7 @@ impl User_ {
default_listing_type: self.default_listing_type,
lang: self.lang.to_owned(),
avatar: self.avatar.to_owned(),
+ show_avatars: self.show_avatars.to_owned(),
};
encode(
&Header::default(),
@@ -187,6 +193,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
@@ -208,6 +216,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let read_user = User_::read(&conn, inserted_user.id).unwrap();
diff --git a/server/src/db/user_mention.rs b/server/src/db/user_mention.rs
index 5392c87a..67286779 100644
--- a/server/src/db/user_mention.rs
+++ b/server/src/db/user_mention.rs
@@ -77,6 +77,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_user = User_::create(&conn, &new_user).unwrap();
@@ -96,6 +98,8 @@ mod tests {
default_sort_type: SortType::Hot as i16,
default_listing_type: ListingType::Subscribed as i16,
lang: "browser".into(),
+ show_avatars: true,
+ send_notifications_to_email: false,
};
let inserted_recipient = User_::create(&conn, &recipient_form).unwrap();
diff --git a/server/src/db/user_view.rs b/server/src/db/user_view.rs
index 2d50b40c..e0de2230 100644
--- a/server/src/db/user_view.rs
+++ b/server/src/db/user_view.rs
@@ -11,6 +11,8 @@ table! {
fedi_name -> Varchar,
admin -> Bool,
banned -> Bool,
+ show_avatars -> Bool,
+ send_notifications_to_email -> Bool,
published -> Timestamp,
number_of_posts -> BigInt,
post_score -> BigInt,
@@ -31,6 +33,8 @@ pub struct UserView {
pub fedi_name: String,
pub admin: bool,
pub banned: bool,
+ pub show_avatars: bool,
+ pub send_notifications_to_email: bool,
pub published: chrono::NaiveDateTime,
pub number_of_posts: i64,
pub post_score: i64,
diff --git a/server/src/schema.rs b/server/src/schema.rs
index 86834072..61957067 100644
--- a/server/src/schema.rs
+++ b/server/src/schema.rs
@@ -270,6 +270,8 @@ table! {
default_sort_type -> Int2,
default_listing_type -> Int2,
lang -> Varchar,
+ show_avatars -> Bool,
+ send_notifications_to_email -> Bool,
}
}
diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx
index b3ca682b..64bc7134 100644
--- a/ui/src/components/comment-node.tsx
+++ b/ui/src/components/comment-node.tsx
@@ -23,6 +23,7 @@ import {
canMod,
isMod,
pictshareAvatarThumbnail,
+ showAvatars,
} from '../utils';
import * as moment from 'moment';
import { MomentTime } from './moment-time';
@@ -138,7 +139,7 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
className="text-info"
to={`/u/${node.comment.creator_name}`}
>
- {node.comment.creator_avatar && (
+ {node.comment.creator_avatar && showAvatars() && (
<img
height="32"
width="32"
diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx
index d1042f38..373889f9 100644
--- a/ui/src/components/main.tsx
+++ b/ui/src/components/main.tsx
@@ -32,6 +32,7 @@ import {
routeListingTypeToEnum,
postRefetchSeconds,
pictshareAvatarThumbnail,
+ showAvatars,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -345,7 +346,7 @@ export class Main extends Component<any, MainState> {
{this.state.site.admins.map(admin => (
<li class="list-inline-item">
<Link class="text-info" to={`/u/${admin.name}`}>
- {admin.avatar && (
+ {admin.avatar && showAvatars() && (
<img
height="32"
width="32"
diff --git a/ui/src/components/navbar.tsx b/ui/src/components/navbar.tsx
index f1a98941..f1c35b1f 100644
--- a/ui/src/components/navbar.tsx
+++ b/ui/src/components/navbar.tsx
@@ -13,7 +13,7 @@ import {
GetSiteResponse,
Comment,
} from '../interfaces';
-import { msgOp, pictshareAvatarThumbnail } from '../utils';
+import { msgOp, pictshareAvatarThumbnail, showAvatars } from '../utils';
import { version } from '../version';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -152,7 +152,7 @@ export class Navbar extends Component<any, NavbarState> {
to={`/u/${UserService.Instance.user.username}`}
>
<span>
- {UserService.Instance.user.avatar && (
+ {UserService.Instance.user.avatar && showAvatars() && (
<img
src={pictshareAvatarThumbnail(
UserService.Instance.user.avatar
diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx
index 1f3a74ac..8b4c1cb6 100644
--- a/ui/src/components/post-listing.tsx
+++ b/ui/src/components/post-listing.tsx
@@ -26,6 +26,7 @@ import {
isVideo,
getUnixTime,
pictshareAvatarThumbnail,
+ showAvatars,
} from '../utils';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -249,7 +250,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<li className="list-inline-item">
<span>{i18n.t('by')} </span>
<Link className="text-info" to={`/u/${post.creator_name}`}>
- {post.creator_avatar && (
+ {post.creator_avatar && showAvatars() && (
<img
height="32"
width="32"
diff --git a/ui/src/components/search.tsx b/ui/src/components/search.tsx
index d92c06e1..00c670d8 100644
--- a/ui/src/components/search.tsx
+++ b/ui/src/components/search.tsx
@@ -20,6 +20,7 @@ import {
routeSearchTypeToEnum,
routeSortTypeToEnum,
pictshareAvatarThumbnail,
+ showAvatars,
} from '../utils';
import { PostListing } from './post-listing';
import { SortSelect } from './sort-select';
@@ -288,7 +289,7 @@ export class Search extends Component<any, SearchState> {
className="text-info"
to={`/u/${(i.data as UserView).name}`}
>
- {(i.data as UserView).avatar && (
+ {(i.data as UserView).avatar && showAvatars() && (
<img
height="32"
width="32"
diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx
index 0e95666f..089dd558 100644
--- a/ui/src/components/sidebar.tsx
+++ b/ui/src/components/sidebar.tsx
@@ -8,7 +8,12 @@ import {
UserView,
} from '../interfaces';
import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime, pictshareAvatarThumbnail } from '../utils';
+import {
+ mdToHtml,
+ getUnixTime,
+ pictshareAvatarThumbnail,
+ showAvatars,
+} from '../utils';
import { CommunityForm } from './community-form';
import { i18n } from '../i18next';
import { T } from 'inferno-i18next';
@@ -194,7 +199,7 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
{this.props.moderators.map(mod => (
<li class="list-inline-item">
<Link class="text-info" to={`/u/${mod.user_name}`}>
- {mod.avatar && (
+ {mod.avatar && showAvatars() && (
<img
height="32"
width="32"
diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx
index 99c340c5..30ee3dcf 100644
--- a/ui/src/components/user.tsx
+++ b/ui/src/components/user.tsx
@@ -28,6 +28,7 @@ import {
themes,
setTheme,
languages,
+ showAvatars,
} from '../utils';
import { PostListing } from './post-listing';
import { SortSelect } from './sort-select';
@@ -80,6 +81,8 @@ export class User extends Component<any, UserState> {
comment_score: null,
banned: null,
avatar: null,
+ show_avatars: null,
+ send_notifications_to_email: null,
},
user_id: null,
username: null,
@@ -99,6 +102,8 @@ export class User extends Component<any, UserState> {
default_sort_type: null,
default_listing_type: null,
lang: null,
+ show_avatars: null,
+ send_notifications_to_email: null,
auth: null,
},
userSettingsLoading: null,
@@ -207,7 +212,7 @@ export class User extends Component<any, UserState> {
<div class="row">
<div class="col-12 col-md-8">
<h5>
- {this.state.user.avatar && (
+ {this.state.user.avatar && showAvatars() && (
<img
height="80"
width="80"
@@ -611,6 +616,41 @@ export class User extends Component<any, UserState> {
</div>
)}
<div class="form-group">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ checked={this.state.userSettingsForm.show_avatars}
+ onChange={linkEvent(
+ this,
+ this.handleUserSettingsShowAvatarsChange
+ )}
+ />
+ <label class="form-check-label">
+ <T i18nKey="show_avatars">#</T>
+ </label>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ disabled={!this.state.user.email}
+ checked={
+ this.state.userSettingsForm.send_notifications_to_email
+ }
+ onChange={linkEvent(
+ this,
+ this.handleUserSettingsSendNotificationsToEmailChange
+ )}
+ />
+ <label class="form-check-label">
+ <T i18nKey="send_notifications_to_email">#</T>
+ </label>
+ </div>
+ </div>
+ <div class="form-group">
<button type="submit" class="btn btn-block btn-secondary mr-4">
{this.state.userSettingsLoading ? (
<svg class="icon icon-spinner spin">
@@ -804,6 +844,17 @@ export class User extends Component<any, UserState> {
i.setState(i.state);
}
+ handleUserSettingsShowAvatarsChange(i: User, event: any) {
+ i.state.userSettingsForm.show_avatars = event.target.checked;
+ UserService.Instance.user.show_avatars = event.target.checked; // Just for instant updates
+ i.setState(i.state);
+ }
+
+ handleUserSettingsSendNotificationsToEmailChange(i: User, event: any) {
+ i.state.userSettingsForm.send_notifications_to_email = event.target.checked;
+ i.setState(i.state);
+ }
+
handleUserSettingsThemeChange(i: User, event: any) {
i.state.userSettingsForm.theme = event.target.value;
setTheme(event.target.value);
@@ -957,6 +1008,9 @@ export class User extends Component<any, UserState> {
this.state.userSettingsForm.lang = UserService.Instance.user.lang;
this.state.userSettingsForm.avatar = UserService.Instance.user.avatar;
this.state.userSettingsForm.email = this.state.user.email;
+ this.state.userSettingsForm.send_notifications_to_email = this.state.user.send_notifications_to_email;
+ this.state.userSettingsForm.show_avatars =
+ UserService.Instance.user.show_avatars;
}
document.title = `/u/${this.state.user.name} - ${WebSocketService.Instance.site.name}`;
window.scrollTo(0, 0);
diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts
index 1762bd60..7fc7a252 100644
--- a/ui/src/interfaces.ts
+++ b/ui/src/interfaces.ts
@@ -81,6 +81,7 @@ export interface User {
default_listing_type: ListingType;
lang: string;
avatar?: string;
+ show_avatars: boolean;
}
export interface UserView {
@@ -95,6 +96,8 @@ export interface UserView {
number_of_comments: number;
comment_score: number;
banned: boolean;
+ show_avatars: boolean;
+ send_notifications_to_email: boolean;
}
export interface CommunityUser {
@@ -486,6 +489,8 @@ export interface UserSettingsForm {
new_password?: string;
new_password_verify?: string;
old_password?: string;
+ show_avatars: boolean;
+ send_notifications_to_email: boolean;
auth: string;
}
diff --git a/ui/src/translations/en.ts b/ui/src/translations/en.ts
index 5e0adbaa..bd7e39cc 100644
--- a/ui/src/translations/en.ts
+++ b/ui/src/translations/en.ts
@@ -29,6 +29,7 @@ export const en = {
preview: 'Preview',
upload_image: 'upload image',
avatar: 'Avatar',
+ show_avatars: 'Show Avatars',
formatting_help: 'formatting help',
view_source: 'view source',
unlock: 'unlock',
@@ -126,6 +127,7 @@ export const en = {
new_password: 'New Password',
no_email_setup: "This server hasn't correctly set up email.",
email: 'Email',