giving up on button carousel due to ipad compatibility

This commit is contained in:
Roland Osborne 2022-08-25 23:43:52 -07:00
parent a081f5f36d
commit f2f1c0b240
8 changed files with 58 additions and 134 deletions

View File

@ -4,72 +4,10 @@ import { CarouselWrapper } from './Carousel.styled';
import { RightOutlined, LeftOutlined, CloseOutlined, PictureOutlined, FireOutlined } from '@ant-design/icons'; import { RightOutlined, LeftOutlined, CloseOutlined, PictureOutlined, FireOutlined } from '@ant-design/icons';
import ReactResizeDetector from 'react-resize-detector'; import ReactResizeDetector from 'react-resize-detector';
export function Carousel({ pad, ready, error, items, itemRenderer, itemRemove }) { export function Carousel({ pad, items, itemRenderer, itemRemove }) {
const [slots, setSlots] = useState([]); const [slots, setSlots] = useState([]);
const [padClass, setPadClass] = useState('');
const [carouselRef, setCarouselRef] = useState(false);
const [itemIndex, setItemIndex] = useState(0);
const [scrollLeft, setScrollLeft] = useState('hidden');
const [scrollRight, setScrollRight] = useState('hidden');
const FUDGE = 1;
let carousel = useRef(); let carousel = useRef();
let itemWidth = useRef(new Map());
useEffect(() => {
setScroll('smooth');
setArrows();
}, [itemIndex, items]);
useEffect(() => {
setScroll('auto');
}, [carouselRef]);
const updateItemIndex = (val) => {
setItemIndex((i) => {
if (i + val < 0) {
return 0;
}
return i + val;
})
}
const onLeft = () => {
if (itemIndex > 0) {
updateItemIndex(-1);
}
}
const onRight = () => {
if(itemIndex + 1 < items.length) {
updateItemIndex(+1);
}
}
const setScroll = (behavior) => {
let pos = FUDGE;
for (let i = 0; i < itemIndex; i++) {
pos += itemWidth.current.get(i) + 32;
}
if (carousel.current) {
carousel.current.scrollTo({ top: 0, left: pos, behavior });
}
}
const setArrows = () => {
if (itemIndex == 0) {
setScrollLeft('hidden');
}
else {
setScrollLeft('unset');
}
if (itemIndex + 1 >= items.length) {
setScrollRight('hidden');
}
else {
setScrollRight('unset');
}
}
const RemoveItem = ({ index }) => { const RemoveItem = ({ index }) => {
if (itemRemove) { if (itemRemove) {
@ -80,12 +18,10 @@ export function Carousel({ pad, ready, error, items, itemRenderer, itemRemove })
useEffect(() => { useEffect(() => {
let assets = []; let assets = [];
if (ready) {
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
assets.push(( assets.push((
<ReactResizeDetector handleWidth={true} handleHeight={false}> <ReactResizeDetector handleWidth={true} handleHeight={false}>
{({ width, height }) => { {({ width, height }) => {
itemWidth.current.set(i, width);
return ( return (
<div class="item noselect"> <div class="item noselect">
<div class="asset">{ itemRenderer(items[i], i) }</div> <div class="asset">{ itemRenderer(items[i], i) }</div>
@ -97,51 +33,16 @@ export function Carousel({ pad, ready, error, items, itemRenderer, itemRemove })
)); ));
} }
if (items.length > 0) { if (items.length > 0) {
assets.push(<div class="space">&nbsp;</div>) assets.push(<div class="space"></div>)
} }
if (itemIndex >= items.length) {
if (items.length > 0) {
setItemIndex(items.length - 1);
}
else {
setItemIndex(0);
}
}
}
setSlots(assets); setSlots(assets);
setScroll(); }, [items]);
setArrows();
}, [ready, items]);
const onRefSet = (r) => {
if (r != null) {
carousel.current = r;
setCarouselRef(true);
}
}
return ( return (
<CarouselWrapper> <CarouselWrapper>
{ error && ( <div class="carousel" style={{ paddingLeft: pad + 32 }} ref={carousel}>
<div class="status">
<FireOutlined style={{ fontSize: 32, color: '#ff8888' }} />
</div>
)}
{ !ready && !error && (
<div class="status">
<PictureOutlined style={{ fontSize: 32 }} />
</div>
)}
{ ready && !error && (
<>
<div class="carousel" style={{ paddingLeft: pad + 32 }} ref={onRefSet}>
{slots} {slots}
</div> </div>
<div class="left-arrow" onClick={onRight} style={{ marginLeft: pad, visibility: scrollRight }}><LeftOutlined /></div>
<div class="right-arrow" onClick={onLeft} style={{ visibility: scrollLeft }}><RightOutlined /></div>
</>
)}
</CarouselWrapper> </CarouselWrapper>
); );
} }

View File

@ -12,7 +12,7 @@ export const CarouselWrapper = styled.div`
flex-direction: row; flex-direction: row;
padding-left: 32px; padding-left: 32px;
width: 100%; width: 100%;
overflow: hidden; overflow: auto;
/* hide scrollbar for IE, Edge and Firefox */ /* hide scrollbar for IE, Edge and Firefox */
-ms-overflow-style: none; -ms-overflow-style: none;
@ -105,7 +105,7 @@ export const CarouselWrapper = styled.div`
.space { .space {
height: 128px; height: 128px;
padding-left: 100%; padding-left: 32px;
} }
.object { .object {

View File

@ -55,7 +55,7 @@ export function AddTopic({ cardId, channelId }) {
const renderItem = (item, index) => { const renderItem = (item, index) => {
if (item.image) { if (item.image) {
return <img style={{ height: '100%', objectFit: 'contain' }} src={item.url} alt="" /> return <img style={{ height: 128, objectFit: 'contain' }} src={item.url} alt="" />
} }
if (item.audio) { if (item.audio) {
return <AudioFile onLabel={(label) => actions.setLabel(index, label)}/> return <AudioFile onLabel={(label) => actions.setLabel(index, label)}/>
@ -95,7 +95,7 @@ export function AddTopic({ cardId, channelId }) {
<input type='file' name="asset" accept="video/*" ref={attachVideo} onChange={e => onSelectVideo(e)} style={{display: 'none'}}/> <input type='file' name="asset" accept="video/*" ref={attachVideo} onChange={e => onSelectVideo(e)} style={{display: 'none'}}/>
{ state.assets.length > 0 && ( { state.assets.length > 0 && (
<div class="assets"> <div class="assets">
<Carousel pad={0} ready={true} items={state.assets} itemRenderer={renderItem} itemRemove={removeItem} /> <Carousel pad={32} items={state.assets} itemRenderer={renderItem} itemRemove={removeItem} />
</div> </div>
)} )}
<div class="message"> <div class="message">

View File

@ -15,7 +15,9 @@ export const AddTopicWrapper = styled.div`
} }
.assets { .assets {
padding-top: 8px; margin-top: 8px;
height: 128px;
overflow: auto;
} }
.buttons { .buttons {

View File

@ -47,13 +47,13 @@ export function VideoFile({ url, onPosition }) {
}} }}
</ReactResizeDetector> </ReactResizeDetector>
<div class="overlay" style={{ width: state.width, height: state.height }}> <div class="overlay" style={{ width: state.width, height: state.height }}>
<div class="arrows"> <div class="seek">
<div class="left-arrow"> <div class="left-seek">
<div class="icon" onClick={() => onSeek(-1)}> <div class="icon" onClick={() => onSeek(-1)}>
<LeftOutlined style={{ fontSize: 32, color: '#eeeeee' }} /> <LeftOutlined style={{ fontSize: 32, color: '#eeeeee' }} />
</div> </div>
</div> </div>
<div class="right-arrow"> <div class="right-seek">
<div class="icon" onClick={() => onSeek(1)}> <div class="icon" onClick={() => onSeek(1)}>
<RightOutlined style={{ fontSize: 32, color: '#eeeeee' }} /> <RightOutlined style={{ fontSize: 32, color: '#eeeeee' }} />
</div> </div>

View File

@ -11,19 +11,19 @@ export const VideoFileWrapper = styled.div`
display: flex; display: flex;
align-items: center; align-items: center;
.arrows { .seek {
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
.left-arrow { .left-seek {
width: 50%; width: 50%;
display: flex; display: flex;
justify-content: flex-begin; justify-content: flex-begin;
} }
.right-arrow { .right-seek {
width: 50%; width: 50%;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;

View File

@ -6,7 +6,7 @@ import { AudioAsset } from './audioAsset/AudioAsset';
import { ImageAsset } from './imageAsset/ImageAsset'; import { ImageAsset } from './imageAsset/ImageAsset';
import { Logo } from 'logo/Logo'; import { Logo } from 'logo/Logo';
import { Space, Skeleton, Button, Modal, Input } from 'antd'; import { Space, Skeleton, Button, Modal, Input } from 'antd';
import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons'; import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, PictureOutlined } from '@ant-design/icons';
import { Carousel } from 'carousel/Carousel'; import { Carousel } from 'carousel/Carousel';
export function TopicItem({ host, topic }) { export function TopicItem({ host, topic }) {
@ -116,9 +116,19 @@ export function TopicItem({ host, topic }) {
)} )}
{ state.confirmed && ( { state.confirmed && (
<div> <div>
{ state.assets.length > 0 && ( { state.error && (
<div class="asset-placeholder">
<FireOutlined style={{ fontSize: 32, color: '#ff8888' }} />
</div>
)}
{ !state.error && !state.ready && (
<div class="asset-placeholder">
<PictureOutlined style={{ fontSize: 32 }} />
</div>
)}
{ !state.error && state.ready && state.assets.length > 0 && (
<div class="topic-assets"> <div class="topic-assets">
<Carousel pad={40} ready={state.ready} error={state.error} items={state.assets} itemRenderer={renderAsset} /> <Carousel pad={40} items={state.assets} itemRenderer={renderAsset} />
</div> </div>
)} )}
<div class="message"> <div class="message">

View File

@ -77,6 +77,17 @@ export const TopicItemWrapper = styled.div`
} }
} }
.asset-placeholder {
width: 128px;
height: 128px;
display: flex;
align-items: center;
justify-content: center;
background-color: #eeeeee;
color: #888888;
margin-left: 72px;
}
.topic-assets { .topic-assets {
padding-top: 4px; padding-top: 4px;
} }