mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
giving up on button carousel due to ipad compatibility
This commit is contained in:
parent
a081f5f36d
commit
f2f1c0b240
@ -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,68 +18,31 @@ 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 }) => {
|
return (
|
||||||
itemWidth.current.set(i, width);
|
<div class="item noselect">
|
||||||
return (
|
<div class="asset">{ itemRenderer(items[i], i) }</div>
|
||||||
<div class="item noselect">
|
<RemoveItem index={i} />
|
||||||
<div class="asset">{ itemRenderer(items[i], i) }</div>
|
</div>
|
||||||
<RemoveItem index={i} />
|
);
|
||||||
</div>
|
}}
|
||||||
);
|
</ReactResizeDetector>
|
||||||
}}
|
));
|
||||||
</ReactResizeDetector>
|
}
|
||||||
));
|
if (items.length > 0) {
|
||||||
}
|
assets.push(<div class="space"></div>)
|
||||||
if (items.length > 0) {
|
|
||||||
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">
|
{slots}
|
||||||
<FireOutlined style={{ fontSize: 32, color: '#ff8888' }} />
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ !ready && !error && (
|
|
||||||
<div class="status">
|
|
||||||
<PictureOutlined style={{ fontSize: 32 }} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ ready && !error && (
|
|
||||||
<>
|
|
||||||
<div class="carousel" style={{ paddingLeft: pad + 32 }} ref={onRefSet}>
|
|
||||||
{slots}
|
|
||||||
</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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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">
|
||||||
|
@ -15,7 +15,9 @@ export const AddTopicWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
.assets {
|
.assets {
|
||||||
padding-top: 8px;
|
margin-top: 8px;
|
||||||
|
height: 128px;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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">
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user