feat(post): add moderator and administrator role indicators

This commit is contained in:
plebeius
2025-11-28 13:29:31 +01:00
parent f01a1dcaa9
commit 5de2587cf4
40 changed files with 169 additions and 45 deletions
+13 -4
View File
@@ -57,8 +57,8 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => {
const replies = useReplies(post);
const { address, shortAddress } = author || {};
const displayName = author?.displayName?.trim();
const authorRole = roles?.[address]?.role;
const { isDescription, isRules } = post || {}; // custom properties, not from api
const authorRole = roles?.[address]?.role.replace('moderator', 'mod') || (isDescription || isRules ? 'mod' : undefined);
const stateString = useStateString(post);
const isReply = parentCid;
const { showOmittedReplies } = useShowOmittedReplies();
@@ -109,7 +109,7 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => {
/>
))}
<span className={styles.nameBlock}>
<span className={`${styles.name} ${(isDescription || isRules || authorRole) && !(deleted || removed) && styles.capcodeMod}`}>
<span className={`${styles.name} ${authorRole && !(deleted || removed) && (authorRole === 'mod' ? styles.capcodeMod : styles.capcodeAdmin)}`}>
{deleted ? (
_.capitalize(t('deleted'))
) : removed ? (
@@ -126,7 +126,16 @@ const PostInfo = ({ post, postReplyCount = 0, roles, isHidden }: PostProps) => {
) : (
_.capitalize(t('anonymous'))
)}
{!(deleted || removed) && <span className='capitalize'>{authorRole && ` ## Board ${authorRole}`} </span>}
{!(deleted || removed) && authorRole && (
<span className='capitalize'>
{' '}
## Board {authorRole}{' '}
<span
className={`${styles.capcodeIcon} ${authorRole === 'mod' ? styles.capcodeModIcon : styles.capcodeAdminIcon}`}
title={authorRole === 'mod' ? t('moderator_of_this_board') : t('administrator_of_this_board')}
/>{' '}
</span>
)}
</span>
{!(isDescription || isRules) && (
<>
@@ -422,7 +431,7 @@ const PostDesktop = ({ post, roles, showAllReplies, showReplies = true }: PostPr
isRules: true,
subplebbitAddress,
timestamp: subplebbit?.createdAt,
author: { displayName: `## ${t('board_mods')}` },
author: { displayName: _.capitalize(t('anonymous')) },
content: `${subplebbit?.rules?.map((rule: string, index: number) => `${index + 1}. ${rule}`).join('\n')}`,
replyCount: 0,
};
+16 -4
View File
@@ -57,7 +57,7 @@ const PostInfoAndMedia = ({ post, postReplyCount = 0, roles }: PostProps) => {
const { isDescription, isRules } = post || {}; // custom properties, not from api
const { address, shortAddress } = author || {};
const displayName = author?.displayName?.trim();
const authorRole = roles?.[address]?.role;
const authorRole = roles?.[address]?.role.replace('moderator', 'mod') || (isDescription || isRules ? 'mod' : undefined);
const { imageUrl: avatarImageUrl } = useAuthorAvatar({ author });
const { hideAvatars } = useAvatarVisibilityStore();
@@ -101,7 +101,7 @@ const PostInfoAndMedia = ({ post, postReplyCount = 0, roles }: PostProps) => {
<PostMenuMobile post={post} />
<span className={(hidden || ((removed || deleted) && !reason)) && parentCid ? styles.postDesktopHidden : ''}>
<span className={styles.nameBlock}>
<span className={`${styles.name} ${(isDescription || isRules || authorRole) && !(deleted || removed) && styles.capcodeMod}`}>
<span className={`${styles.name} ${authorRole && !(deleted || removed) && (authorRole === 'mod' ? styles.capcodeMod : styles.capcodeAdmin)}`}>
{removed ? (
_.capitalize(t('removed'))
) : deleted ? (
@@ -118,7 +118,19 @@ const PostInfoAndMedia = ({ post, postReplyCount = 0, roles }: PostProps) => {
) : (
_.capitalize(t('anonymous'))
)}
{!(deleted || removed) && <span className='capitalize'>{authorRole && ` ## Board ${authorRole}`} </span>}
{!(deleted || removed) && authorRole && (
<span className='capitalize'>
{' '}
## Board {authorRole}{' '}
<span className={styles.capcodeIconMobileWrapper}>
<span
className={`${styles.capcodeIconMobile} ${authorRole === 'mod' ? styles.capcodeModIcon : styles.capcodeAdminIcon}`}
title={authorRole === 'mod' ? t('moderator_of_this_board') : t('administrator_of_this_board')}
/>
</span>
&nbsp;
</span>
)}
</span>
{!(isDescription || isRules) && (
<>
@@ -318,7 +330,7 @@ const PostMobile = ({ post, roles, showAllReplies, showReplies = true }: PostPro
isRules: true,
subplebbitAddress,
timestamp: subplebbit?.createdAt,
author: { displayName: `## ${t('board_mods')}` },
author: { displayName: _.capitalize(t('anonymous')) },
content: `${subplebbit?.rules?.map((rule: string, index: number) => `${index + 1}. ${rule}`).join('\n')}`,
replyCount: 0,
};
@@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next';
import { isAllView } from '../../lib/utils/view-utils';
import { useMultisubMetadata } from '../../hooks/use-default-subplebbits';
import { useLocation } from 'react-router-dom';
import _ from 'lodash';
interface DescriptionPostProps {
avatarUrl?: string;
@@ -24,7 +25,7 @@ const SubplebbitDescription = ({ avatarUrl, createdAt, description, replyCount,
isDescription: true,
subplebbitAddress,
timestamp: isInAllView ? multisubMetadata?.createdAt : createdAt,
author: { displayName: `## ${t('board_mods')}` },
author: { displayName: _.capitalize(t('anonymous')) },
content: isInAllView ? multisubMetadata?.description : description,
link: avatarUrl,
replyCount,
@@ -15,7 +15,7 @@ const SubplebbitRules = ({ subplebbitAddress, createdAt, rules }: RulesPostProps
isRules: true,
subplebbitAddress,
timestamp: createdAt,
author: { displayName: `## ${t('board_mods')}` },
author: { displayName: _.capitalize(t('anonymous')) },
content,
replyCount: 0,
title: _.capitalize(t('rules')),
+32
View File
@@ -470,6 +470,38 @@
color: var(--post-capcode-mod-text-color) !important;
}
.capcodeAdmin {
color: #F00 !important;
}
.capcodeIcon {
width: 16px;
height: 16px;
display: inline-block;
image-rendering: pixelated;
transform: translateY(2px);
}
.capcodeIconMobileWrapper {
padding-right: 15px;
}
.capcodeIconMobile {
position: absolute;
width: 16px;
height: 16px;
image-rendering: pixelated;
transform: translateY(-1px);
}
.capcodeModIcon {
background-image: url('assets/icons/board-mod.png');
}
.capcodeAdminIcon {
background-image: url('assets/icons/board-admin.png');
}
.pendingCid {
color: red !important;
font-weight: 700 !important;