mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Extracted comment member name and initial helper functions
no issue - extracted functions for easier re-use and testing - removed duplicate definition of comment member initials function
This commit is contained in:
parent
bfdf2dd8bf
commit
f982bbe9fa
6 changed files with 80 additions and 20 deletions
|
@ -21,7 +21,7 @@ export type Comment = {
|
|||
replies: number,
|
||||
likes: number,
|
||||
},
|
||||
member: Member,
|
||||
member: Member | null,
|
||||
edited_at: string,
|
||||
created_at: string,
|
||||
html: string
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {ReactComponent as AvatarIcon} from '../../images/icons/avatar.svg';
|
||||
import {Comment, useAppContext} from '../../AppContext';
|
||||
import {getInitials} from '../../utils/helpers';
|
||||
import {getMemberInitialsFromComment} from '../../utils/helpers';
|
||||
|
||||
function getDimensionClasses() {
|
||||
return 'w-8 h-8';
|
||||
|
@ -64,19 +64,7 @@ export const Avatar: React.FC<AvatarProps> = ({comment}) => {
|
|||
return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
||||
};
|
||||
|
||||
const commentGetInitials = () => {
|
||||
if (comment && !comment.member) {
|
||||
return getInitials(t('Deleted member'));
|
||||
}
|
||||
|
||||
const commentMember = (comment ? comment.member : member);
|
||||
|
||||
if (!commentMember || !commentMember.name) {
|
||||
return getInitials(t('Anonymous'));
|
||||
}
|
||||
return getInitials(commentMember.name);
|
||||
};
|
||||
|
||||
const memberInitials = (comment && getMemberInitialsFromComment(comment, t)) || '';
|
||||
const commentMember = (comment ? comment.member : member);
|
||||
|
||||
const bgColor = HSLtoString(generateHSL());
|
||||
|
@ -88,7 +76,7 @@ export const Avatar: React.FC<AvatarProps> = ({comment}) => {
|
|||
<>
|
||||
{memberName ?
|
||||
(<div className={`flex items-center justify-center rounded-full ${dimensionClasses}`} data-testid="avatar-background" style={avatarStyle}>
|
||||
<p className="font-sans text-base font-semibold text-white">{ commentGetInitials() }</p>
|
||||
<p className="font-sans text-base font-semibold text-white">{memberInitials}</p>
|
||||
</div>) :
|
||||
(<div className={`flex items-center justify-center rounded-full bg-neutral-900 dark:bg-[rgba(255,255,255,0.7)] ${dimensionClasses}`} data-testid="avatar-background" >
|
||||
<AvatarIcon className="stroke-white dark:stroke-[rgba(0,0,0,0.6)]" />
|
||||
|
|
|
@ -7,7 +7,7 @@ import ReplyForm from './forms/ReplyForm';
|
|||
import {Avatar, BlankAvatar} from './Avatar';
|
||||
import {Comment, useAppContext, useLabs} from '../../AppContext';
|
||||
import {Transition} from '@headlessui/react';
|
||||
import {formatExplicitTime, isCommentPublished} from '../../utils/helpers';
|
||||
import {formatExplicitTime, getMemberNameFromComment, isCommentPublished} from '../../utils/helpers';
|
||||
import {useRelativeTime} from '../../utils/hooks';
|
||||
import {useState} from 'react';
|
||||
|
||||
|
@ -196,10 +196,9 @@ const ReplyFormBox: React.FC<ReplyFormBoxProps> = ({comment, isInReplyMode, clos
|
|||
// -- Published comment components --
|
||||
//
|
||||
|
||||
// TODO: move name detection to helper
|
||||
const AuthorName: React.FC<{comment: Comment}> = ({comment}) => {
|
||||
const {t} = useAppContext();
|
||||
const name = !comment.member ? t('Deleted member') : (comment.member.name ? comment.member.name : t('Anonymous'));
|
||||
const name = getMemberNameFromComment(comment, t);
|
||||
return (
|
||||
<h4 className="text-[rgb(23,23,23] font-sans text-base font-bold leading-snug sm:text-sm dark:text-[rgba(255,255,255,0.85)]">
|
||||
{name}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as helpers from './helpers';
|
||||
import {buildAnonymousMember, buildComment, buildDeletedMember} from '../../test/utils/fixtures';
|
||||
|
||||
describe('formatNumber', function () {
|
||||
it('adds commas to large numbers', function () {
|
||||
|
@ -17,3 +18,47 @@ describe('formatNumber', function () {
|
|||
expect((helpers.formatNumber as any)(null)).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMemberNameFromComment', function () {
|
||||
function testName(member: any | null, expected: string) {
|
||||
const t = (str: string) => str;
|
||||
const comment = buildComment();
|
||||
comment.member = member;
|
||||
const name = helpers.getMemberNameFromComment(comment, t);
|
||||
expect(name).to.equal(expected);
|
||||
}
|
||||
|
||||
it('handles deleted member', function () {
|
||||
testName(buildDeletedMember(), 'Deleted member');
|
||||
});
|
||||
|
||||
it('handles anonymous comment', function () {
|
||||
testName(buildAnonymousMember(), 'Anonymous');
|
||||
});
|
||||
|
||||
it('handles a member with a name', function () {
|
||||
testName({name: 'Test member'}, 'Test member');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMemberInitialsFromComment', function () {
|
||||
function testInitials(member: any | null, expected: string) {
|
||||
const t = (str: string) => str;
|
||||
const comment = buildComment();
|
||||
comment.member = member;
|
||||
const initials = helpers.getMemberInitialsFromComment(comment, t);
|
||||
expect(initials).to.equal(expected);
|
||||
}
|
||||
|
||||
it('handles deleted member', function () {
|
||||
testInitials(buildDeletedMember(), 'DM');
|
||||
});
|
||||
|
||||
it('handles anonymous comment', function () {
|
||||
testInitials(buildAnonymousMember(), 'A');
|
||||
});
|
||||
|
||||
it('handles a member with a name', function () {
|
||||
testInitials({name: 'Test member'}, 'TM');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Comment, TranslationFunction} from '../AppContext';
|
||||
import {Comment, Member, TranslationFunction} from '../AppContext';
|
||||
|
||||
export function formatNumber(number: number): string {
|
||||
if (number !== 0 && !number) {
|
||||
|
@ -116,6 +116,26 @@ export function getInitials(name: string): string {
|
|||
return parts[0].substring(0, 1).toLocaleUpperCase() + parts[parts.length - 1].substring(0, 1).toLocaleUpperCase();
|
||||
}
|
||||
|
||||
export function getMemberName(member: Member | null, t: TranslationFunction) {
|
||||
if (!member) {
|
||||
return t('Deleted member');
|
||||
}
|
||||
|
||||
if (!member.name) {
|
||||
return t('Anonymous');
|
||||
}
|
||||
|
||||
return member.name;
|
||||
}
|
||||
|
||||
export function getMemberNameFromComment(comment: Comment, t: TranslationFunction) {
|
||||
return getMemberName(comment.member, t);
|
||||
}
|
||||
|
||||
export function getMemberInitialsFromComment(comment: Comment, t: TranslationFunction) {
|
||||
return getInitials(getMemberName(comment.member, t));
|
||||
}
|
||||
|
||||
// Rudimentary check for screen width
|
||||
// Note, this should be the same as breakpoint defined in Tailwind config
|
||||
export function isMobile() {
|
||||
|
|
|
@ -16,6 +16,14 @@ export function buildMember(override: any = {}) {
|
|||
};
|
||||
}
|
||||
|
||||
export function buildDeletedMember() {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function buildAnonymousMember(override: any = {}) {
|
||||
return buildMember({...override, name: ''});
|
||||
}
|
||||
|
||||
export function buildSettings(override: any = {}) {
|
||||
return {
|
||||
meta: {},
|
||||
|
|
Loading…
Add table
Reference in a new issue