feat(profile): 'Active now' / 'Last active …' line from presence (#150)
One line under the handle in the user profile popover, from the presence the
SDK already receives (currently_active + last_active_ago): 'Active now',
'Active just now', 'Last active 12 min ago / 3 hours ago / yesterday / 5 days
ago / over a month ago'. Nothing is shown without presence data or for an
offline user with no timestamp (Hide Online Status users), so nothing new is
exposed; re-renders on the existing presence events, no polling. Wording
unit-tested; verified headless ('Active now' for an online member).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -19,6 +19,7 @@ import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { BreakWord, LineClamp2, LineClamp3 } from '../../styles/Text.css';
|
||||
import { ModalMobileFull } from '../../styles/Modal.css';
|
||||
import { UserPresence } from '../../hooks/useUserPresence';
|
||||
import { describeLastActive } from '../../utils/lastActive';
|
||||
import { AvatarPresence, PresenceBadge } from '../presence';
|
||||
import { AvatarDecoration } from '../avatar-decoration/AvatarDecoration';
|
||||
import { ImageViewer } from '../image-viewer';
|
||||
@@ -110,6 +111,8 @@ type UserHeroNameProps = {
|
||||
status?: string;
|
||||
pronouns?: string;
|
||||
timezone?: string;
|
||||
/** [Gitea #150] Presence for the "Active now / Last active …" line. */
|
||||
presence?: UserPresence;
|
||||
};
|
||||
export function UserHeroName({
|
||||
displayName,
|
||||
@@ -117,7 +120,9 @@ export function UserHeroName({
|
||||
status,
|
||||
pronouns,
|
||||
timezone,
|
||||
presence,
|
||||
}: UserHeroNameProps) {
|
||||
const lastActive = describeLastActive(presence);
|
||||
const username = getMxIdLocalPart(userId);
|
||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||
const localTimeInfo = useLocalTime(timezone, !hour24Clock);
|
||||
@@ -158,6 +163,13 @@ export function UserHeroName({
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
{lastActive && (
|
||||
<Box alignItems="Center" gap="100" style={{ marginTop: '1px', overflow: 'hidden' }}>
|
||||
<Text size="T200" style={{ opacity: 0.6 }}>
|
||||
{lastActive}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
{status && (
|
||||
<Box alignItems="Center" gap="100" style={{ marginTop: '2px', overflow: 'hidden' }}>
|
||||
<Text
|
||||
|
||||
@@ -371,6 +371,7 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
|
||||
displayName={displayName}
|
||||
userId={userId}
|
||||
status={presence?.status}
|
||||
presence={presence && presence.lastActiveTs !== 0 ? presence : undefined}
|
||||
pronouns={extProfile.pronouns}
|
||||
timezone={extProfile.timezone}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user