Add a permanent add story button to MyStories

This commit is contained in:
Josh Perez 2022-08-05 19:24:49 -04:00 committed by GitHub
parent 71382b8f65
commit 7a1686b915
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 142 additions and 63 deletions

View file

@ -101,4 +101,31 @@
); );
} }
} }
&__avatar-container {
position: relative;
}
&__avatar__add-story {
@include button-reset;
@include rounded-corners;
align-items: center;
background: $color-ultramarine-dawn;
border: 2px solid $color-gray-80;
bottom: -2px;
display: flex;
height: 20px;
justify-content: center;
position: absolute;
right: -4px;
width: 20px;
z-index: $z-index-base;
&::after {
content: '';
@include color-svg('../images/icons/v2/plus-20.svg', $color-white);
height: 10px;
width: 10px;
}
}
} }

View file

@ -22,10 +22,28 @@
} }
} }
&__click-container {
align-items: center;
display: flex;
height: 100%;
width: 100%;
&:focus {
outline: none;
}
@include keyboard-mode {
&:focus {
outline: 1px solid $color-ultramarine;
}
}
}
&__info { &__info {
display: flex; display: flex;
flex: 1;
flex-direction: column; flex-direction: column;
flex: 1;
justify-content: center;
margin-left: 12px; margin-left: 12px;
margin-right: 12px; margin-right: 12px;

View file

@ -33,12 +33,9 @@ export default {
newestStory: { newestStory: {
defaultValue: getFakeStoryView(), defaultValue: getFakeStoryView(),
}, },
onClick: { onAddStory: { action: true },
action: true, onClick: { action: true },
}, queueStoryDownload: { action: true },
queueStoryDownload: {
action: true,
},
}, },
} as Meta; } as Meta;
@ -49,6 +46,10 @@ const interactionTest: PlayFunction<ReactFramework, PropsType> = async ({
canvasElement, canvasElement,
}) => { }) => {
const canvas = within(canvasElement); const canvas = within(canvasElement);
const [btnAddStory] = canvas.getAllByLabelText('Add a story');
await userEvent.click(btnAddStory);
await expect(args.onAddStory).toHaveBeenCalled();
const [btnStory] = canvas.getAllByLabelText('Story'); const [btnStory] = canvas.getAllByLabelText('Story');
await userEvent.click(btnStory); await userEvent.click(btnStory);
await expect(args.onClick).toHaveBeenCalled(); await expect(args.onClick).toHaveBeenCalled();

View file

@ -15,6 +15,7 @@ export type PropsType = {
i18n: LocalizerType; i18n: LocalizerType;
me: ConversationType; me: ConversationType;
newestStory?: StoryViewType; newestStory?: StoryViewType;
onAddStory: () => unknown;
onClick: () => unknown; onClick: () => unknown;
queueStoryDownload: (storyId: string) => unknown; queueStoryDownload: (storyId: string) => unknown;
}; };
@ -24,6 +25,7 @@ export const MyStoriesButton = ({
i18n, i18n,
me, me,
newestStory, newestStory,
onAddStory,
onClick, onClick,
queueStoryDownload, queueStoryDownload,
}: PropsType): JSX.Element => { }: PropsType): JSX.Element => {
@ -40,66 +42,96 @@ export const MyStoriesButton = ({
return ( return (
<div className="Stories__my-stories"> <div className="Stories__my-stories">
<button <div className="StoryListItem__button">
aria-label={i18n('StoryListItem__label')} <div className="MyStories__avatar-container">
className="StoryListItem__button" <Avatar
onClick={onClick} acceptedMessageRequest={acceptedMessageRequest}
tabIndex={0} avatarPath={avatarPath}
type="button" badge={undefined}
> color={getAvatarColor(color)}
<Avatar conversationType="direct"
acceptedMessageRequest={acceptedMessageRequest} i18n={i18n}
sharedGroupNames={sharedGroupNames} isMe={Boolean(isMe)}
avatarPath={avatarPath} name={name}
badge={undefined} onClick={onAddStory}
color={getAvatarColor(color)} profileName={profileName}
conversationType="direct" sharedGroupNames={sharedGroupNames}
i18n={i18n} size={AvatarSize.FORTY_EIGHT}
isMe={Boolean(isMe)} title={title}
name={name} />
profileName={profileName} <div
size={AvatarSize.FORTY_EIGHT} aria-label={i18n('Stories__add')}
title={title} className="MyStories__avatar__add-story"
/> onClick={ev => {
<div className="StoryListItem__info"> onAddStory();
<> ev.stopPropagation();
<div className="StoryListItem__info--title"> ev.preventDefault();
{i18n('Stories__mine')} }}
</div> onKeyDown={ev => {
{!newestStory && ( if (ev.key === 'Enter') {
<div className="StoryListItem__info--timestamp"> onAddStory();
{i18n('Stories__add')} ev.stopPropagation();
</div> ev.preventDefault();
)} }
</> }}
role="button"
tabIndex={0}
/>
</div> </div>
<div <div
className={classNames('StoryListItem__previews', { className="StoryListItem__click-container"
'StoryListItem__previews--multiple': hasMultiple, onClick={onClick}
})} onKeyDown={ev => {
if (ev.key === 'Enter') {
onClick();
ev.stopPropagation();
ev.preventDefault();
}
}}
role="button"
tabIndex={0}
> >
{hasMultiple && <div className="StoryListItem__previews--more" />} <div className="StoryListItem__info">
{newestStory ? ( <>
<StoryImage <div className="StoryListItem__info--title">
attachment={newestStory.attachment} {i18n('Stories__mine')}
firstName={i18n('you')} </div>
i18n={i18n} {!newestStory && (
isMe <div className="StoryListItem__info--timestamp">
isThumbnail {i18n('Stories__add')}
label="" </div>
moduleClassName="StoryListItem__previews--image" )}
queueStoryDownload={queueStoryDownload} </>
storyId={newestStory.messageId} </div>
/>
) : ( <div
<div aria-label={i18n('StoryListItem__label')}
aria-label={i18n('Stories__add')} className={classNames('StoryListItem__previews', {
className="StoryListItem__previews--add StoryListItem__previews--image" 'StoryListItem__previews--multiple': hasMultiple,
/> })}
)} >
{hasMultiple && <div className="StoryListItem__previews--more" />}
{newestStory ? (
<StoryImage
attachment={newestStory.attachment}
firstName={i18n('you')}
i18n={i18n}
isMe
isThumbnail
label=""
moduleClassName="StoryListItem__previews--image"
queueStoryDownload={queueStoryDownload}
storyId={newestStory.messageId}
/>
) : (
<div
aria-label={i18n('Stories__add')}
className="StoryListItem__previews--add StoryListItem__previews--image"
/>
)}
</div>
</div> </div>
</button> </div>
</div> </div>
); );
}; };

View file

@ -187,6 +187,7 @@ export const StoriesPane = ({
newestStory={ newestStory={
myStories.length ? getNewestMyStory(myStories[0]) : undefined myStories.length ? getNewestMyStory(myStories[0]) : undefined
} }
onAddStory={onAddStory}
onClick={onMyStoriesClicked} onClick={onMyStoriesClicked}
queueStoryDownload={queueStoryDownload} queueStoryDownload={queueStoryDownload}
/> />