Story viewing improvements

This commit is contained in:
Josh Perez 2022-05-03 19:50:44 -04:00 committed by GitHub
parent d4e0f6a38d
commit 7d8464757b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 149 additions and 2 deletions

View File

@ -40,6 +40,7 @@ $color-black-alpha-05: rgba($color-black, 0.05);
$color-black-alpha-06: rgba($color-black, 0.06);
$color-black-alpha-08: rgba($color-black, 0.08);
$color-black-alpha-12: rgba($color-black, 0.12);
$color-black-alpha-16: rgba($color-black, 0.16);
$color-black-alpha-20: rgba($color-black, 0.2);
$color-black-alpha-30: rgba($color-black, 0.3);
$color-black-alpha-40: rgba($color-black, 0.4);
@ -49,6 +50,8 @@ $color-black-alpha-70: rgba($color-black, 0.7);
$color-black-alpha-80: rgba($color-black, 0.8);
$color-black-alpha-90: rgba($color-black, 0.9);
$color-transparent: rgba(0, 0, 0, 0);
$color-ultramarine-dark: #1851b4;
$color-ultramarine-icon: #3a76f0;
$color-ultramarine-light: #6191f3;

View File

@ -72,7 +72,8 @@
padding: 0 16px;
position: absolute;
transform: translateX(-50%);
width: 284px;
min-width: 284px;
width: 56.25vh;
z-index: $z-index-above-base;
&--group-avatar {
@ -93,7 +94,7 @@
}
&__caption {
@include font-body-1-bold;
@include font-body-1;
color: $color-gray-05;
padding: 4px 0;
margin-bottom: 24px;
@ -146,4 +147,69 @@
height: 100%;
}
}
&__arrow {
align-items: center;
display: flex;
height: 100vh;
position: absolute;
width: 25%;
button {
@include button-reset;
height: 24px;
opacity: 0;
width: 24px;
transition: opacity 200ms ease-in-out;
}
&--left {
justify-content: flex-start;
left: 0;
button {
margin-left: 24px;
@include color-svg(
'../images/icons/v2/chevron-left-24.svg',
$color-white
);
}
}
&--right {
justify-content: flex-end;
right: 0;
button {
margin-right: 24px;
@include color-svg(
'../images/icons/v2/chevron-right-24.svg',
$color-white
);
}
}
&--visible button {
opacity: 1;
visibility: visible;
}
}
&__protection {
position: absolute;
width: 100%;
z-index: $z-index-above-base;
&--top {
background: linear-gradient($color-black-alpha-16, $color-transparent);
top: 0;
height: 80px;
}
&--bottom {
background: linear-gradient($color-transparent, $color-black-alpha-40);
bottom: 0;
height: 180px;
}
}
}

View File

@ -42,6 +42,7 @@ function getDefaultProps(): PropsType {
stories: [
{
attachment: fakeAttachment({
path: 'snow.jpg',
url: '/fixtures/snow.jpg',
}),
messageId: '123',
@ -60,6 +61,7 @@ story.add('Wide story', () => (
stories={[
{
attachment: fakeAttachment({
path: 'file.jpg',
url: '/fixtures/nathan-anderson-316188-unsplash.jpg',
}),
messageId: '123',
@ -89,6 +91,7 @@ story.add('Multi story', () => {
stories={[
{
attachment: fakeAttachment({
path: 'snow.jpg',
url: '/fixtures/snow.jpg',
}),
messageId: '123',
@ -97,6 +100,7 @@ story.add('Multi story', () => {
},
{
attachment: fakeAttachment({
path: 'file.jpg',
url: '/fixtures/nathan-anderson-316188-unsplash.jpg',
}),
messageId: '456',
@ -115,6 +119,7 @@ story.add('Caption', () => (
{
attachment: fakeAttachment({
caption: 'This place looks lovely',
path: 'file.jpg',
url: '/fixtures/nathan-anderson-316188-unsplash.jpg',
}),
messageId: '123',
@ -133,6 +138,7 @@ story.add('Long Caption', () => (
attachment: fakeAttachment({
caption:
'Snowycle, snowycle, snowycle\nI want to ride my snowycle, snowycle, snowycle\nI want to ride my snowycle\nI want to ride my snow\nI want to ride my snowycle\nI want to ride it where I like\nSnowycle, snowycle, snowycle\nI want to ride my snowycle, snowycle, snowycle\nI want to ride my snowycle\nI want to ride my snow\nI want to ride my snowycle\nI want to ride it where I like\nSnowycle, snowycle, snowycle\nI want to ride my snowycle, snowycle, snowycle\nI want to ride my snowycle\nI want to ride my snow\nI want to ride my snowycle\nI want to ride it where I like',
path: 'file.jpg',
url: '/fixtures/snow.jpg',
}),
messageId: '123',

View File

@ -9,6 +9,7 @@ import React, {
useRef,
useState,
} from 'react';
import classNames from 'classnames';
import { useSpring, animated, to } from '@react-spring/web';
import type { BodyRangeType, LocalizerType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations';
@ -76,6 +77,13 @@ export type PropsType = {
const CAPTION_BUFFER = 20;
const CAPTION_INITIAL_LENGTH = 200;
const CAPTION_MAX_LENGTH = 700;
const MOUSE_IDLE_TIME = 3000;
enum Arrow {
None,
Left,
Right,
}
export const StoryViewer = ({
conversationId,
@ -313,6 +321,38 @@ export const StoryViewer = ({
loadStoryReplies(conversationId, messageId);
}, [conversationId, isGroupStory, loadStoryReplies, messageId]);
const [arrowToShow, setArrowToShow] = useState<Arrow>(Arrow.None);
useEffect(() => {
if (arrowToShow === Arrow.None) {
return;
}
let lastMouseMove: number | undefined;
function updateLastMouseMove() {
lastMouseMove = Date.now();
}
function checkMouseIdle() {
requestAnimationFrame(() => {
if (lastMouseMove && Date.now() - lastMouseMove > MOUSE_IDLE_TIME) {
setArrowToShow(Arrow.None);
} else {
checkMouseIdle();
}
});
}
checkMouseIdle();
document.addEventListener('mousemove', updateLastMouseMove);
return () => {
lastMouseMove = undefined;
document.removeEventListener('mousemove', updateLastMouseMove);
};
}, [arrowToShow]);
const replies =
replyState && replyState.messageId === messageId ? replyState.replies : [];
@ -327,6 +367,22 @@ export const StoryViewer = ({
style={{ background: getStoryBackground(attachment) }}
/>
<div className="StoryViewer__content">
<div
className={classNames(
'StoryViewer__arrow StoryViewer__arrow--left',
{
'StoryViewer__arrow--visible': arrowToShow === Arrow.Left,
}
)}
onMouseMove={() => setArrowToShow(Arrow.Left)}
>
<button
aria-label={i18n('back')}
onClick={showPrevStory}
type="button"
/>
</div>
<div className="StoryViewer__protection StoryViewer__protection--top" />
<div className="StoryViewer__container">
<StoryImage
attachment={attachment}
@ -481,6 +537,22 @@ export const StoryViewer = ({
</div>
</div>
</div>
<div
className={classNames(
'StoryViewer__arrow StoryViewer__arrow--right',
{
'StoryViewer__arrow--visible': arrowToShow === Arrow.Right,
}
)}
onMouseMove={() => setArrowToShow(Arrow.Right)}
>
<button
aria-label={i18n('forward')}
onClick={showNextStory}
type="button"
/>
</div>
<div className="StoryViewer__protection StoryViewer__protection--bottom" />
<button
aria-label={i18n('MyStories__more')}
className="StoryViewer__more"