From f4d71769378e6c37d84123eb486c4dfdbff3d977 Mon Sep 17 00:00:00 2001 From: NanoAim <65581271+NanoAim@users.noreply.github.com> Date: Fri, 29 Aug 2025 11:17:31 +0800 Subject: [PATCH] New user indicator --- src/components/common/user/UserShort.tsx | 55 +++++++++++++++++++++--- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/components/common/user/UserShort.tsx b/src/components/common/user/UserShort.tsx index ef2d2586..bcd0bdf2 100644 --- a/src/components/common/user/UserShort.tsx +++ b/src/components/common/user/UserShort.tsx @@ -3,6 +3,7 @@ import { observer } from "mobx-react-lite"; import { useParams } from "react-router-dom"; import { User, API } from "revolt.js"; import styled, { css } from "styled-components/macro"; +import { decodeTime } from "ulid"; import { Ref } from "preact"; import { Text } from "preact-i18n"; @@ -16,6 +17,9 @@ import { modalController } from "../../../controllers/modals/ModalController"; import Tooltip from "../Tooltip"; import UserIcon from "./UserIcon"; +// Configuration constant for easy adjustment +const NEW_MEMBER_THRESHOLD_DAYS = 14; + const BotBadge = styled.div` display: inline-block; flex-shrink: 0; @@ -23,13 +27,33 @@ const BotBadge = styled.div` padding: 0 4px; font-size: 0.6em; user-select: none; - margin-inline-start: 4px; text-transform: uppercase; color: var(--accent-contrast); background: var(--accent); border-radius: calc(var(--border-radius) / 2); `; +const NewHereBadge = styled.div` + display: inline-block; + flex-shrink: 0; + height: 1.3em; + padding: 0 5px; + font-size: 0.55em; + font-weight: 600; + user-select: none; + text-transform: uppercase; + color: white; + background: #3BA55D; + border-radius: 10px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); +`; + +const BadgeWrapper = styled.span` + display: flex; + align-items: center; + gap: 4px; +`; + type UsernameProps = Omit< JSX.HTMLAttributes, "children" | "as" @@ -73,6 +97,7 @@ export const Username = observer( user?.username; let color = masquerade?.colour; let timed_out: Date | undefined; + let isNewHere = false; if (override) { username = override; @@ -109,6 +134,14 @@ export const Username = observer( } } + // Check if user account is new + if (user) { + // Extract account creation timestamp from user ID (ULID) + const accountCreatedAt = decodeTime(user._id); + const accountAge = dayjs().diff(dayjs(accountCreatedAt), 'day'); + isNewHere = accountAge <= NEW_MEMBER_THRESHOLD_DAYS; + } + const el = ( <> @@ -139,7 +172,7 @@ export const Username = observer( if (user?.bot) { return ( - <> + {el} {masquerade ? ( @@ -148,18 +181,30 @@ export const Username = observer( )} - + ); } if (override) { return ( - <> + {el} - + + ); + } + + // Add new member badge for users with new accounts + if (isNewHere) { + return ( + + {el} + + NEW + + ); }