Update design for clicking on badges
Co-authored-by: Evan Hahn <69474926+EvanHahn-Signal@users.noreply.github.com>
This commit is contained in:
parent
0e1b41cc62
commit
4c30e272f3
|
@ -112,12 +112,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__badge {
|
&__badge {
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
// Positioning should be overridden by JavaScript. These are set defensively.
|
// Positioning should be overridden by JavaScript. These are set defensively.
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
||||||
|
&--static {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--button {
|
||||||
|
background-color: transparent;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: contain;
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
@include keyboard-mode {
|
||||||
|
&:focus {
|
||||||
|
outline: 2px solid $color-ultramarine;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
||||||
name: text('name', overrideProps.name || ''),
|
name: text('name', overrideProps.name || ''),
|
||||||
noteToSelf: boolean('noteToSelf', overrideProps.noteToSelf || false),
|
noteToSelf: boolean('noteToSelf', overrideProps.noteToSelf || false),
|
||||||
onClick: action('onClick'),
|
onClick: action('onClick'),
|
||||||
|
onClickBadge: action('onClickBadge'),
|
||||||
phoneNumber: text('phoneNumber', overrideProps.phoneNumber || ''),
|
phoneNumber: text('phoneNumber', overrideProps.phoneNumber || ''),
|
||||||
searchResult: boolean(
|
searchResult: boolean(
|
||||||
'searchResult',
|
'searchResult',
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
CSSProperties,
|
||||||
FunctionComponent,
|
FunctionComponent,
|
||||||
MouseEvent,
|
MouseEvent,
|
||||||
ReactChild,
|
ReactChild,
|
||||||
|
@ -68,6 +69,7 @@ export type Props = {
|
||||||
searchResult?: boolean;
|
searchResult?: boolean;
|
||||||
|
|
||||||
onClick?: (event: MouseEvent<HTMLButtonElement>) => unknown;
|
onClick?: (event: MouseEvent<HTMLButtonElement>) => unknown;
|
||||||
|
onClickBadge?: (event: MouseEvent<HTMLButtonElement>) => unknown;
|
||||||
|
|
||||||
// Matches Popper's RefHandler type
|
// Matches Popper's RefHandler type
|
||||||
innerRef?: React.Ref<HTMLDivElement>;
|
innerRef?: React.Ref<HTMLDivElement>;
|
||||||
|
@ -104,6 +106,7 @@ export const Avatar: FunctionComponent<Props> = ({
|
||||||
loading,
|
loading,
|
||||||
noteToSelf,
|
noteToSelf,
|
||||||
onClick,
|
onClick,
|
||||||
|
onClickBadge,
|
||||||
sharedGroupNames,
|
sharedGroupNames,
|
||||||
size,
|
size,
|
||||||
theme,
|
theme,
|
||||||
|
@ -254,19 +257,35 @@ export const Avatar: FunctionComponent<Props> = ({
|
||||||
badgeTheme
|
badgeTheme
|
||||||
);
|
);
|
||||||
if (badgeImagePath) {
|
if (badgeImagePath) {
|
||||||
badgeNode = (
|
const positionStyles: CSSProperties = {
|
||||||
<img
|
width: badgePlacement.size,
|
||||||
alt={badge.name}
|
height: badgePlacement.size,
|
||||||
className="module-Avatar__badge"
|
bottom: badgePlacement.bottom,
|
||||||
src={badgeImagePath}
|
right: badgePlacement.right,
|
||||||
style={{
|
};
|
||||||
width: badgePlacement.size,
|
if (onClickBadge) {
|
||||||
height: badgePlacement.size,
|
badgeNode = (
|
||||||
bottom: badgePlacement.bottom,
|
<button
|
||||||
right: badgePlacement.right,
|
aria-label={badge.name}
|
||||||
}}
|
className="module-Avatar__badge module-Avatar__badge--button"
|
||||||
/>
|
onClick={onClickBadge}
|
||||||
);
|
style={{
|
||||||
|
backgroundImage: `url('${encodeURI(badgeImagePath)}')`,
|
||||||
|
...positionStyles,
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
badgeNode = (
|
||||||
|
<img
|
||||||
|
alt={badge.name}
|
||||||
|
className="module-Avatar__badge module-Avatar__badge--static"
|
||||||
|
src={badgeImagePath}
|
||||||
|
style={positionStyles}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (badge && !theme) {
|
} else if (badge && !theme) {
|
||||||
log.error('<Avatar> requires a theme if a badge is provided');
|
log.error('<Avatar> requires a theme if a badge is provided');
|
||||||
|
|
|
@ -14,7 +14,6 @@ import { BadgeDialog } from '../BadgeDialog';
|
||||||
import type { BadgeType } from '../../badges/types';
|
import type { BadgeType } from '../../badges/types';
|
||||||
import { SharedGroupNames } from '../SharedGroupNames';
|
import { SharedGroupNames } from '../SharedGroupNames';
|
||||||
import { ConfirmationDialog } from '../ConfirmationDialog';
|
import { ConfirmationDialog } from '../ConfirmationDialog';
|
||||||
import { shouldShowBadges } from '../../badges/shouldShowBadges';
|
|
||||||
|
|
||||||
export type PropsDataType = {
|
export type PropsDataType = {
|
||||||
areWeAdmin: boolean;
|
areWeAdmin: boolean;
|
||||||
|
@ -107,13 +106,8 @@ export const ContactModal = ({
|
||||||
theme={theme}
|
theme={theme}
|
||||||
title={contact.title}
|
title={contact.title}
|
||||||
unblurredAvatarPath={contact.unblurredAvatarPath}
|
unblurredAvatarPath={contact.unblurredAvatarPath}
|
||||||
onClick={() => {
|
onClick={() => setView(ContactModalView.ShowingAvatar)}
|
||||||
setView(
|
onClickBadge={() => setView(ContactModalView.ShowingBadges)}
|
||||||
preferredBadge && shouldShowBadges()
|
|
||||||
? ContactModalView.ShowingBadges
|
|
||||||
: ContactModalView.ShowingAvatar
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<div className="ContactModal__name">{contact.title}</div>
|
<div className="ContactModal__name">{contact.title}</div>
|
||||||
<div className="module-about__container">
|
<div className="module-about__container">
|
||||||
|
|
|
@ -15,7 +15,6 @@ import type { LocalizerType, ThemeType } from '../../../types/Util';
|
||||||
import { bemGenerator } from './util';
|
import { bemGenerator } from './util';
|
||||||
import { BadgeDialog } from '../../BadgeDialog';
|
import { BadgeDialog } from '../../BadgeDialog';
|
||||||
import type { BadgeType } from '../../../badges/types';
|
import type { BadgeType } from '../../../badges/types';
|
||||||
import { shouldShowBadges } from '../../../badges/shouldShowBadges';
|
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
badges?: ReadonlyArray<BadgeType>;
|
badges?: ReadonlyArray<BadgeType>;
|
||||||
|
@ -92,11 +91,10 @@ export const ConversationDetailsHeader: React.ComponentType<Props> = ({
|
||||||
{...conversation}
|
{...conversation}
|
||||||
noteToSelf={isMe}
|
noteToSelf={isMe}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActiveModal(
|
setActiveModal(ConversationDetailsHeaderActiveModal.ShowingAvatar);
|
||||||
preferredBadge && shouldShowBadges()
|
}}
|
||||||
? ConversationDetailsHeaderActiveModal.ShowingBadges
|
onClickBadge={() => {
|
||||||
: ConversationDetailsHeaderActiveModal.ShowingAvatar
|
setActiveModal(ConversationDetailsHeaderActiveModal.ShowingBadges);
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
sharedGroupNames={[]}
|
sharedGroupNames={[]}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
|
Loading…
Reference in New Issue