diff --git a/server/migrations/2020-06-30-135809_remove_mat_views/up.sql b/server/migrations/2020-06-30-135809_remove_mat_views/up.sql index bd792a8b9..9e2fa59ce 100644 --- a/server/migrations/2020-06-30-135809_remove_mat_views/up.sql +++ b/server/migrations/2020-06-30-135809_remove_mat_views/up.sql @@ -106,6 +106,7 @@ select u.actor_id as creator_actor_id, u."local" as creator_local, u."name" as creator_name, + u.published as creator_published, u.avatar as creator_avatar, u.banned as banned, cb.id::bool as banned_from_community, @@ -490,6 +491,7 @@ select u.actor_id as creator_actor_id, u.local as creator_local, u.name as creator_name, + u.published as creator_published, u.avatar as creator_avatar, -- score details coalesce(cl.total, 0) as score, diff --git a/server/src/db/comment_view.rs b/server/src/db/comment_view.rs index d1b27a3c8..75ed4cb7c 100644 --- a/server/src/db/comment_view.rs +++ b/server/src/db/comment_view.rs @@ -28,6 +28,7 @@ table! { creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, + creator_published -> Timestamp, score -> BigInt, upvotes -> BigInt, downvotes -> BigInt, @@ -63,6 +64,7 @@ table! { creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, + creator_published -> Timestamp, score -> BigInt, upvotes -> BigInt, downvotes -> BigInt, @@ -101,6 +103,7 @@ pub struct CommentView { pub creator_local: bool, pub creator_name: String, pub creator_avatar: Option, + pub creator_published: chrono::NaiveDateTime, pub score: i64, pub upvotes: i64, pub downvotes: i64, @@ -314,6 +317,7 @@ table! { creator_local -> Bool, creator_name -> Varchar, creator_avatar -> Nullable, + creator_published -> Timestamp, score -> BigInt, upvotes -> BigInt, downvotes -> BigInt, @@ -353,6 +357,7 @@ pub struct ReplyView { pub creator_local: bool, pub creator_name: String, pub creator_avatar: Option, + pub creator_published: chrono::NaiveDateTime, pub score: i64, pub upvotes: i64, pub downvotes: i64, @@ -576,6 +581,7 @@ mod tests { published: inserted_comment.published, updated: None, creator_name: inserted_user.name.to_owned(), + creator_published: inserted_user.published, creator_avatar: None, score: 1, downvotes: 0, @@ -609,6 +615,7 @@ mod tests { published: inserted_comment.published, updated: None, creator_name: inserted_user.name.to_owned(), + creator_published: inserted_user.published, creator_avatar: None, score: 1, downvotes: 0, diff --git a/server/src/db/post_view.rs b/server/src/db/post_view.rs index 808cf28c4..cda5cecf0 100644 --- a/server/src/db/post_view.rs +++ b/server/src/db/post_view.rs @@ -28,6 +28,7 @@ table! { creator_actor_id -> Text, creator_local -> Bool, creator_name -> Varchar, + creator_published -> Timestamp, creator_avatar -> Nullable, banned -> Bool, banned_from_community -> Bool, @@ -75,6 +76,7 @@ table! { creator_actor_id -> Text, creator_local -> Bool, creator_name -> Varchar, + creator_published -> Timestamp, creator_avatar -> Nullable, banned -> Bool, banned_from_community -> Bool, @@ -125,6 +127,7 @@ pub struct PostView { pub creator_actor_id: String, pub creator_local: bool, pub creator_name: String, + pub creator_published: chrono::NaiveDateTime, pub creator_avatar: Option, pub banned: bool, pub banned_from_community: bool, @@ -499,6 +502,7 @@ mod tests { body: None, creator_id: inserted_user.id, creator_name: user_name.to_owned(), + creator_published: inserted_user.published, creator_avatar: None, banned: false, banned_from_community: false, @@ -548,6 +552,7 @@ mod tests { stickied: false, creator_id: inserted_user.id, creator_name: user_name, + creator_published: inserted_user.published, creator_avatar: None, banned: false, banned_from_community: false, diff --git a/ui/src/components/cake-day.tsx b/ui/src/components/cake-day.tsx new file mode 100644 index 000000000..67ac7f8bf --- /dev/null +++ b/ui/src/components/cake-day.tsx @@ -0,0 +1,41 @@ +import { Component } from 'inferno'; +import moment from 'moment'; +import { i18n } from '../i18next'; + +interface CakeDayProps { + creator_name: string; + creator_published: string; +} + +export class CakeDay extends Component { + render() { + const { creator_name, creator_published } = this.props; + + return ( + this.isCakeDay(creator_published) && ( +
+ + + +
+ ) + ); + } + + isCakeDay(input: string): boolean { + const userCreationDate = moment.utc(input).local(); + const currentDate = moment(new Date()); + + return ( + userCreationDate.date() === currentDate.date() && + userCreationDate.month() === currentDate.month() + ); + } + + cakeDayTippy(creator_name: string): string { + return i18n.t('cake_day_info', { creator_name }); + } +} diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx index 155efe8e0..762344aae 100644 --- a/ui/src/components/comment-node.tsx +++ b/ui/src/components/comment-node.tsx @@ -33,6 +33,7 @@ import { CommentForm } from './comment-form'; import { CommentNodes } from './comment-nodes'; import { UserListing } from './user-listing'; import { i18n } from '../i18next'; +import { CakeDay } from './cake-day'; interface CommentNodeState { showReply: boolean; @@ -124,6 +125,7 @@ export class CommentNode extends Component { render() { let node = this.props.node; + const { creator_name, creator_published } = node.comment; return (
{ }} /> + + + {this.isMod && (
{i18n.t('mod')} diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx index 3d6088427..e6b9721c8 100644 --- a/ui/src/components/post-listing.tsx +++ b/ui/src/components/post-listing.tsx @@ -35,6 +35,7 @@ import { previewLines, } from '../utils'; import { i18n } from '../i18next'; +import { CakeDay } from './cake-day'; interface PostListingState { showEdit: boolean; @@ -253,6 +254,8 @@ export class PostListing extends Component { listing() { let post = this.props.post; + const { creator_name, creator_published } = post; + return (
@@ -432,6 +435,12 @@ export class PostListing extends Component { actor_id: post.creator_actor_id, }} /> + + + {this.isMod && ( {i18n.t('mod')} diff --git a/ui/src/components/symbols.tsx b/ui/src/components/symbols.tsx index 77d7a0860..3386dbe59 100644 --- a/ui/src/components/symbols.tsx +++ b/ui/src/components/symbols.tsx @@ -168,6 +168,9 @@ export class Symbols extends Component { + + + ); diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index 69914fd39..4f680324a 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -46,6 +46,7 @@ import { ListingTypeSelect } from './listing-type-select'; import { CommentNodes } from './comment-nodes'; import { MomentTime } from './moment-time'; import { i18n } from '../i18next'; +import moment from 'moment'; enum View { Overview, @@ -412,6 +413,15 @@ export class User extends Component { )} +
+ + + + + {i18n.t('cake_day_title')}{' '} + {moment.utc(user.published).local().format('MMM DD, YYYY')} + +
{i18n.t('joined')}
diff --git a/ui/src/interfaces.ts b/ui/src/interfaces.ts index 7e29319f9..774836a27 100644 --- a/ui/src/interfaces.ts +++ b/ui/src/interfaces.ts @@ -183,6 +183,7 @@ export interface Post { creator_actor_id: string; creator_local: boolean; creator_name: string; + creator_published: string; creator_avatar?: string; community_actor_id: string; community_local: boolean; @@ -227,6 +228,7 @@ export interface Comment { creator_local: boolean; creator_name: string; creator_avatar?: string; + creator_published: string; score: number; upvotes: number; downvotes: number; diff --git a/ui/translations/en.json b/ui/translations/en.json index 62b11ce4a..3dda59480 100644 --- a/ui/translations/en.json +++ b/ui/translations/en.json @@ -265,5 +265,7 @@ "action": "Action", "emoji_picker": "Emoji Picker", "block_leaving": "Are you sure you want to leave?", - "what_is": "What is" + "what_is": "What is", + "cake_day_title": "Cake day:", + "cake_day_info": "It's {{ creator_name }}'s cake day today!" }