mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-27 13:21:32 +00:00
Add cake day display in user page & posts/comments #682
This commit is contained in:
parent
8fda7d00d5
commit
68e9755e59
10 changed files with 90 additions and 1 deletions
|
@ -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,
|
||||
|
|
|
@ -28,6 +28,7 @@ table! {
|
|||
creator_local -> Bool,
|
||||
creator_name -> Varchar,
|
||||
creator_avatar -> Nullable<Text>,
|
||||
creator_published -> Timestamp,
|
||||
score -> BigInt,
|
||||
upvotes -> BigInt,
|
||||
downvotes -> BigInt,
|
||||
|
@ -63,6 +64,7 @@ table! {
|
|||
creator_local -> Bool,
|
||||
creator_name -> Varchar,
|
||||
creator_avatar -> Nullable<Text>,
|
||||
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<String>,
|
||||
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<Text>,
|
||||
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<String>,
|
||||
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,
|
||||
|
|
|
@ -28,6 +28,7 @@ table! {
|
|||
creator_actor_id -> Text,
|
||||
creator_local -> Bool,
|
||||
creator_name -> Varchar,
|
||||
creator_published -> Timestamp,
|
||||
creator_avatar -> Nullable<Text>,
|
||||
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<Text>,
|
||||
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<String>,
|
||||
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,
|
||||
|
|
41
ui/src/components/cake-day.tsx
vendored
Normal file
41
ui/src/components/cake-day.tsx
vendored
Normal file
|
@ -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<CakeDayProps, any> {
|
||||
render() {
|
||||
const { creator_name, creator_published } = this.props;
|
||||
|
||||
return (
|
||||
this.isCakeDay(creator_published) && (
|
||||
<div
|
||||
className="mr-lg-2 d-inline-block unselectable pointer mx-2"
|
||||
data-tippy-content={this.cakeDayTippy(creator_name)}
|
||||
>
|
||||
<svg class="icon icon-inline">
|
||||
<use xlinkHref="#icon-cake"></use>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
8
ui/src/components/comment-node.tsx
vendored
8
ui/src/components/comment-node.tsx
vendored
|
@ -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<CommentNodeProps, CommentNodeState> {
|
|||
|
||||
render() {
|
||||
let node = this.props.node;
|
||||
const { creator_name, creator_published } = node.comment;
|
||||
return (
|
||||
<div
|
||||
className={`comment ${
|
||||
|
@ -160,6 +162,12 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
|||
}}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<CakeDay
|
||||
creator_name={creator_name}
|
||||
creator_published={creator_published}
|
||||
/>
|
||||
|
||||
{this.isMod && (
|
||||
<div className="badge badge-light d-none d-sm-inline mr-2">
|
||||
{i18n.t('mod')}
|
||||
|
|
9
ui/src/components/post-listing.tsx
vendored
9
ui/src/components/post-listing.tsx
vendored
|
@ -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<PostListingProps, PostListingState> {
|
|||
|
||||
listing() {
|
||||
let post = this.props.post;
|
||||
const { creator_name, creator_published } = post;
|
||||
|
||||
return (
|
||||
<div class="row">
|
||||
<div className={`vote-bar col-1 pr-0 small text-center`}>
|
||||
|
@ -432,6 +435,12 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
|||
actor_id: post.creator_actor_id,
|
||||
}}
|
||||
/>
|
||||
|
||||
<CakeDay
|
||||
creator_name={creator_name}
|
||||
creator_published={creator_published}
|
||||
/>
|
||||
|
||||
{this.isMod && (
|
||||
<span className="mx-1 badge badge-light">
|
||||
{i18n.t('mod')}
|
||||
|
|
3
ui/src/components/symbols.tsx
vendored
3
ui/src/components/symbols.tsx
vendored
File diff suppressed because one or more lines are too long
10
ui/src/components/user.tsx
vendored
10
ui/src/components/user.tsx
vendored
|
@ -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<any, UserState> {
|
|||
)}
|
||||
</ul>
|
||||
</h5>
|
||||
<div className="d-flex align-items-center mb-2">
|
||||
<svg class="icon">
|
||||
<use xlinkHref="#icon-cake"></use>
|
||||
</svg>
|
||||
<span className="ml-2">
|
||||
{i18n.t('cake_day_title')}{' '}
|
||||
{moment.utc(user.published).local().format('MMM DD, YYYY')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
{i18n.t('joined')} <MomentTime data={user} showAgo />
|
||||
</div>
|
||||
|
|
2
ui/src/interfaces.ts
vendored
2
ui/src/interfaces.ts
vendored
|
@ -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;
|
||||
|
|
4
ui/translations/en.json
vendored
4
ui/translations/en.json
vendored
|
@ -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!"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue