Changeset View
Changeset View
Standalone View
Standalone View
web/modals/threads/gallery/thread-settings-media-gallery.react.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { fetchThreadMedia } from 'lib/actions/thread-actions.js'; | import { fetchThreadMedia } from 'lib/actions/thread-actions.js'; | ||||
import { useModalContext } from 'lib/components/modal-provider.react.js'; | import { useModalContext } from 'lib/components/modal-provider.react.js'; | ||||
import type { Media } from 'lib/types/media-types.js'; | import type { Media } from 'lib/types/media-types.js'; | ||||
import type { ThreadInfo } from 'lib/types/thread-types.js'; | import type { ThreadInfo } from 'lib/types/thread-types.js'; | ||||
import { useServerCall } from 'lib/utils/action-utils.js'; | import { useServerCall } from 'lib/utils/action-utils.js'; | ||||
import GalleryItem from './thread-settings-media-gallery-item.react.js'; | |||||
import css from './thread-settings-media-gallery.css'; | import css from './thread-settings-media-gallery.css'; | ||||
import Tabs from '../../../components/tabs.react.js'; | import Tabs from '../../../components/tabs.react.js'; | ||||
import MultimediaModal from '../../../media/multimedia-modal.react.js'; | import MultimediaModal from '../../../media/multimedia-modal.react.js'; | ||||
import Modal from '../../modal.react.js'; | import Modal from '../../modal.react.js'; | ||||
type MediaGalleryTab = 'All' | 'Images' | 'Videos'; | type MediaGalleryTab = 'All' | 'Images' | 'Videos'; | ||||
type ThreadSettingsMediaGalleryModalProps = { | type ThreadSettingsMediaGalleryModalProps = { | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | (media: Media) => { | ||||
} | } | ||||
pushModal(<MultimediaModal media={mediaInfo} />); | pushModal(<MultimediaModal media={mediaInfo} />); | ||||
}, | }, | ||||
[pushModal], | [pushModal], | ||||
); | ); | ||||
const filteredMediaInfos = React.useMemo(() => { | const filteredMediaInfos = React.useMemo(() => { | ||||
if (tab === 'Images') { | if (tab === 'Images') { | ||||
return mediaInfos.filter(mediaInfo => mediaInfo.type === 'photo'); | return mediaInfos.filter( | ||||
mediaInfo => | |||||
mediaInfo.type === 'photo' || mediaInfo.type === 'encrypted_photo', | |||||
); | |||||
} else if (tab === 'Videos') { | } else if (tab === 'Videos') { | ||||
return mediaInfos.filter(mediaInfo => mediaInfo.type === 'video'); | return mediaInfos.filter( | ||||
mediaInfo => | |||||
mediaInfo.type === 'video' || mediaInfo.type === 'encrypted_video', | |||||
); | |||||
} | } | ||||
return mediaInfos; | return mediaInfos; | ||||
}, [tab, mediaInfos]); | }, [tab, mediaInfos]); | ||||
const mediaCoverPhotos = React.useMemo( | const mediaCoverPhotos = React.useMemo( | ||||
() => filteredMediaInfos.map(media => media.thumbnailURI || media.uri), | () => | ||||
filteredMediaInfos.map(media => { | |||||
if (media.type === 'photo') { | |||||
return { | |||||
kind: 'plain', | |||||
uri: media.uri, | |||||
thumbHash: media.thumbHash, | |||||
}; | |||||
} else if (media.type === 'video') { | |||||
return { | |||||
kind: 'plain', | |||||
uri: media.thumbnailURI, | |||||
thumbHash: media.thumbnailThumbHash, | |||||
}; | |||||
} else if (media.type === 'encrypted_photo') { | |||||
return { | |||||
kind: 'encrypted', | |||||
holder: media.holder, | |||||
encryptionKey: media.encryptionKey, | |||||
thumbHash: media.thumbHash, | |||||
}; | |||||
} else { | |||||
return { | |||||
kind: 'encrypted', | |||||
holder: media.thumbnailHolder, | |||||
encryptionKey: media.thumbnailEncryptionKey, | |||||
thumbHash: media.thumbnailThumbHash, | |||||
}; | |||||
} | |||||
}), | |||||
[filteredMediaInfos], | [filteredMediaInfos], | ||||
); | ); | ||||
const mediaGalleryItems = React.useMemo( | const mediaGalleryItems = React.useMemo( | ||||
() => | () => | ||||
filteredMediaInfos.map((media, i) => ( | filteredMediaInfos.map((media, i) => ( | ||||
<div | <GalleryItem | ||||
key={i} | key={i} | ||||
onClick={() => onClick(media)} | onClick={() => onClick(media)} | ||||
className={css.mediaContainer} | imageSource={mediaCoverPhotos[i]} | ||||
> | imageCSSClass={css.media} | ||||
<img src={mediaCoverPhotos[i]} className={css.media} /> | imageContainerCSSClass={css.mediaContainer} | ||||
</div> | /> | ||||
)), | )), | ||||
[filteredMediaInfos, onClick, mediaCoverPhotos], | [filteredMediaInfos, onClick, mediaCoverPhotos], | ||||
); | ); | ||||
const handleScroll = React.useCallback( | const handleScroll = React.useCallback( | ||||
async event => { | async event => { | ||||
const container = event.target; | const container = event.target; | ||||
// Load more data when the user is within 1000 pixels of the end | // Load more data when the user is within 1000 pixels of the end | ||||
▲ Show 20 Lines • Show All 43 Lines • Show Last 20 Lines |