Add “download image” option to web, simplify downloads (#10025)
This commit is contained in:
@@ -3,9 +3,11 @@ import {Pressable, StyleSheet, View} from 'react-native'
|
||||
import {Image} from 'expo-image'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {FocusGuards, FocusScope} from 'radix-ui/internal'
|
||||
import {RemoveScrollBar} from 'react-remove-scroll-bar'
|
||||
|
||||
import {saveImageToMediaLibrary} from '#/lib/media/manip'
|
||||
import {useA11y} from '#/state/a11y'
|
||||
import {useLightbox, useLightboxControls} from '#/state/lightbox'
|
||||
import {
|
||||
@@ -21,8 +23,12 @@ import {
|
||||
ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeftIcon,
|
||||
ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon,
|
||||
} from '#/components/icons/Chevron'
|
||||
import {DotGrid3x1_Stroke2_Corner0_Rounded as EllipsisIcon} from '#/components/icons/DotGrid'
|
||||
import {Download_Stroke2_Corner0_Rounded as DownloadIcon} from '#/components/icons/Download'
|
||||
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import * as Menu from '#/components/Menu'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type ImageSource} from './ImageViewing/@types'
|
||||
|
||||
@@ -242,6 +248,52 @@ function LightboxGallery({
|
||||
<Text>{_(msg`Image ${index + 1} of ${imgs.length}`)}</Text>
|
||||
</div>
|
||||
)}
|
||||
<Menu.Root>
|
||||
<Menu.Trigger label={_(msg`Image options`)}>
|
||||
{({props}) => (
|
||||
<Button
|
||||
{...props}
|
||||
style={[
|
||||
a.absolute,
|
||||
styles.menuBtn,
|
||||
styles.blurredBackdrop,
|
||||
a.transition_color,
|
||||
delayedFadeInAnim,
|
||||
]}
|
||||
hoverStyle={styles.blurredBackdropHover}
|
||||
color="secondary"
|
||||
label={_(msg`Image options`)}
|
||||
shape="round"
|
||||
size={gtPhone ? 'large' : 'small'}>
|
||||
<EllipsisIcon
|
||||
size={gtPhone ? 'md' : 'sm'}
|
||||
style={{color: t.palette.white}}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</Menu.Trigger>
|
||||
<Menu.Outer>
|
||||
<Menu.Group>
|
||||
<Menu.Item
|
||||
label={_(msg`Download image`)}
|
||||
onPress={() => {
|
||||
saveImageToMediaLibrary({uri: img.uri}).then(
|
||||
() => {
|
||||
Toast.show(_(msg`Image saved`))
|
||||
},
|
||||
() => {
|
||||
Toast.show(_(msg`Failed to save image`), {type: 'error'})
|
||||
},
|
||||
)
|
||||
}}>
|
||||
<Menu.ItemText>
|
||||
<Trans>Download image</Trans>
|
||||
</Menu.ItemText>
|
||||
<Menu.ItemIcon icon={DownloadIcon} position="right" />
|
||||
</Menu.Item>
|
||||
</Menu.Group>
|
||||
</Menu.Outer>
|
||||
</Menu.Root>
|
||||
<Button
|
||||
onPress={onClose}
|
||||
style={[
|
||||
@@ -369,6 +421,10 @@ const styles = StyleSheet.create({
|
||||
padding: 16,
|
||||
boxSizing: 'border-box',
|
||||
},
|
||||
menuBtn: {
|
||||
top: 20,
|
||||
left: 20,
|
||||
},
|
||||
closeBtn: {
|
||||
top: 20,
|
||||
right: 20,
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import {compressIfNeeded} from '#/lib/media/manip'
|
||||
import {openCamera, openCropper, openPicker} from '#/lib/media/picker'
|
||||
import {type PickerImage} from '#/lib/media/picker.shared'
|
||||
import {convertCdnPreset} from '#/lib/media/util'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {isCancelledError} from '#/lib/strings/errors'
|
||||
@@ -616,9 +617,7 @@ export {PreviewableUserAvatar}
|
||||
// manually string-replace to use the smaller ones
|
||||
// -prf
|
||||
function hackModifyThumbnailPath(uri: string, isEnabled: boolean): string {
|
||||
return isEnabled
|
||||
? uri.replace('/img/avatar/plain/', '/img/avatar_thumbnail/plain/')
|
||||
: uri
|
||||
return isEnabled ? convertCdnPreset(uri, 'avatar_thumbnail') : uri
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
||||
Reference in New Issue
Block a user