lotus(#6): render avatar decorations on in-call tiles
Adds io.lotus.decorations (toWidget): the host pushes a userId->image-URL map and EC overlays the profile decoration on each tile avatar (TileAvatar), keyed by userId, with a useSyncExternalStore-backed store. Makes A6 first-class in-call instead of absent. URLs are validated https/blob. Additive: no-op unless the host sends decorations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7d792c33bf
commit
70358d442b
@@ -18,3 +18,20 @@ Please see LICENSE in the repository root for full details.
|
||||
/* TODO: make this --cpd-color-fg-primary when available. */
|
||||
color: var(--cpd-color-text-primary);
|
||||
}
|
||||
|
||||
/* [lotus #6] Wrap so the decoration can overlay the avatar precisely. */
|
||||
.container {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
/* [lotus #6] APNG/PNG profile decoration drawn over the in-call tile avatar.
|
||||
The decoration art shares the avatar's box (transparent padding, ring at the
|
||||
edges), matching how the host renders it elsewhere. */
|
||||
.lotusDecoration {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
pointer-events: none;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
+14
-1
@@ -10,6 +10,7 @@ import { InlineSpinner } from "@vector-im/compound-web";
|
||||
|
||||
import styles from "./TileAvatar.module.css";
|
||||
import { Avatar, type Props as AvatarProps } from "../Avatar";
|
||||
import { useLotusDecoration } from "../lotus/lotusDecorations";
|
||||
|
||||
interface Props extends AvatarProps {
|
||||
size: number;
|
||||
@@ -17,14 +18,26 @@ interface Props extends AvatarProps {
|
||||
}
|
||||
|
||||
export const TileAvatar: FC<Props> = ({ size, loading, ...props }) => {
|
||||
// [lotus #6] Profile decoration overlay for this participant, pushed by the
|
||||
// host via io.lotus.decorations. undefined unless the host opted in.
|
||||
const decoration = useLotusDecoration(props.id);
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.container}>
|
||||
{loading && (
|
||||
<div className={styles.loading}>
|
||||
<InlineSpinner size={size / 3} />
|
||||
</div>
|
||||
)}
|
||||
<Avatar size={size} {...props} />
|
||||
{decoration && (
|
||||
<img
|
||||
className={styles.lotusDecoration}
|
||||
src={decoration}
|
||||
alt=""
|
||||
aria-hidden
|
||||
style={{ width: size, height: size }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user