diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/auth/create/CreateAccount.tsx | 3 | ||||
-rw-r--r-- | src/view/com/auth/login/Login.tsx | 3 | ||||
-rw-r--r-- | src/view/com/composer/Composer.tsx | 41 | ||||
-rw-r--r-- | src/view/com/composer/photos/Gallery.tsx | 244 | ||||
-rw-r--r-- | src/view/com/modals/AltImage.tsx | 167 | ||||
-rw-r--r-- | src/view/com/modals/Confirm.tsx | 16 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThread.tsx | 6 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 2 | ||||
-rw-r--r-- | src/view/com/post/Post.tsx | 6 | ||||
-rw-r--r-- | src/view/com/posts/FeedSlice.tsx | 2 | ||||
-rw-r--r-- | src/view/com/util/images/Gallery.tsx | 19 | ||||
-rw-r--r-- | src/view/com/util/post-embeds/index.tsx | 19 | ||||
-rw-r--r-- | src/view/screens/CustomFeed.tsx | 5 | ||||
-rw-r--r-- | src/view/screens/Profile.tsx | 2 |
14 files changed, 316 insertions, 219 deletions
diff --git a/src/view/com/auth/create/CreateAccount.tsx b/src/view/com/auth/create/CreateAccount.tsx index 97200709b..d6cb1a0a7 100644 --- a/src/view/com/auth/create/CreateAccount.tsx +++ b/src/view/com/auth/create/CreateAccount.tsx @@ -56,9 +56,10 @@ export const CreateAccount = observer( } else { try { await model.submit() - track('Create Account') } catch { // dont need to handle here + } finally { + track('Try Create Account') } } }, [model, track]) diff --git a/src/view/com/auth/login/Login.tsx b/src/view/com/auth/login/Login.tsx index af4f01874..c76c33938 100644 --- a/src/view/com/auth/login/Login.tsx +++ b/src/view/com/auth/login/Login.tsx @@ -327,7 +327,6 @@ const LoginForm = ({ identifier: fullIdent, password, }) - track('Sign In', {resumedSession: false}) } catch (e: any) { const errMsg = e.toString() store.log.warn('Failed to login', e) @@ -341,6 +340,8 @@ const LoginForm = ({ } else { setError(cleanError(errMsg)) } + } finally { + track('Sign In', {resumedSession: false}) } } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 52b90b6c7..fc324d3e5 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -92,18 +92,24 @@ export const ComposePost = observer(function ComposePost({ const onPressCancel = useCallback(() => { if (graphemeLength > 0 || !gallery.isEmpty) { + if (store.shell.activeModals.some(modal => modal.name === 'confirm')) { + store.shell.closeModal() + } store.shell.openModal({ name: 'confirm', - title: 'Cancel draft', - onPressConfirm: onClose, + title: 'Discard draft', + onPressConfirm: hackfixOnClose, onPressCancel: () => { store.shell.closeModal() }, - message: "Are you sure you'd like to cancel this draft?", + message: "Are you sure you'd like to discard this draft?", + confirmBtnText: 'Discard', + confirmBtnStyle: {backgroundColor: colors.red4}, }) + } else { + hackfixOnClose() } - hackfixOnClose() - }, [store, hackfixOnClose, graphemeLength, gallery, onClose]) + }, [store, hackfixOnClose, graphemeLength, gallery]) // initial setup useEffect(() => { @@ -114,14 +120,10 @@ export const ComposePost = observer(function ComposePost({ const onEscape = useCallback( (e: KeyboardEvent) => { if (e.key === 'Escape') { - if (store.shell.activeModals.some(modal => modal.name === 'confirm')) { - store.shell.closeModal() - } - onPressCancel() } }, - [store, onPressCancel], + [onPressCancel], ) useEffect(() => { if (isDesktopWeb) { @@ -172,9 +174,6 @@ export const ComposePost = observer(function ComposePost({ knownHandles: autocompleteView.knownHandles, langs: store.preferences.postLanguages, }) - track('Create Post', { - imageCount: gallery.size, - }) } catch (e: any) { if (extLink) { setExtLink({ @@ -186,6 +185,11 @@ export const ComposePost = observer(function ComposePost({ setError(cleanError(e.message)) setIsProcessing(false) return + } finally { + track('Create Post', { + imageCount: gallery.size, + }) + if (replyTo && replyTo.uri) track('Post:Reply') } if (!replyTo) { await store.me.mainFeed.addPostToTop(createdPost.uri) @@ -227,13 +231,13 @@ export const ComposePost = observer(function ComposePost({ <View style={[s.flex1, viewStyles]} aria-modal accessibilityViewIsModal> <View style={styles.topbar}> <TouchableOpacity - testID="composerCancelButton" + testID="composerDiscardButton" onPress={onPressCancel} onAccessibilityEscape={onPressCancel} accessibilityRole="button" - accessibilityLabel="Cancel" - accessibilityHint="Closes post composer"> - <Text style={[pal.link, s.f18]}>Cancel</Text> + accessibilityLabel="Discard" + accessibilityHint="Closes post composer and discards post draft"> + <Text style={[pal.link, s.f18, styles.discard]}>Discard</Text> </TouchableOpacity> <View style={s.flex1} /> {isProcessing ? ( @@ -386,6 +390,9 @@ const styles = StyleSheet.create({ paddingHorizontal: 20, height: 55, }, + discard: { + color: colors.red3, + }, postBtn: { borderRadius: 20, paddingHorizontal: 20, diff --git a/src/view/com/composer/photos/Gallery.tsx b/src/view/com/composer/photos/Gallery.tsx index f46c05333..c226d25cc 100644 --- a/src/view/com/composer/photos/Gallery.tsx +++ b/src/view/com/composer/photos/Gallery.tsx @@ -1,16 +1,16 @@ -import React, {useCallback} from 'react' +import React from 'react' import {ImageStyle, Keyboard} from 'react-native' import {GalleryModel} from 'state/models/media/gallery' import {observer} from 'mobx-react-lite' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {colors} from 'lib/styles' +import {s, colors} from 'lib/styles' import {StyleSheet, TouchableOpacity, View} from 'react-native' -import {ImageModel} from 'state/models/media/image' import {Image} from 'expo-image' import {Text} from 'view/com/util/text/Text' import {isDesktopWeb} from 'platform/detection' import {openAltTextModal} from 'lib/media/alt-text' import {useStores} from 'state/index' +import {usePalette} from 'lib/hooks/usePalette' interface Props { gallery: GalleryModel @@ -18,67 +18,39 @@ interface Props { export const Gallery = observer(function ({gallery}: Props) { const store = useStores() - const getImageStyle = useCallback(() => { - let side: number + const pal = usePalette('default') - if (gallery.size === 1) { - side = 250 - } else { - side = (isDesktopWeb ? 560 : 350) / gallery.size - } + let side: number - return { - height: side, - width: side, - } - }, [gallery]) - - const imageStyle = getImageStyle() - const handleAddImageAltText = useCallback( - (image: ImageModel) => { - Keyboard.dismiss() - openAltTextModal(store, image) - }, - [store], - ) - const handleRemovePhoto = useCallback( - (image: ImageModel) => { - gallery.remove(image) - }, - [gallery], - ) + if (gallery.size === 1) { + side = 250 + } else { + side = (isDesktopWeb ? 560 : 350) / gallery.size + } - const handleEditPhoto = useCallback( - (image: ImageModel) => { - gallery.edit(image) - }, - [gallery], - ) + const imageStyle = { + height: side, + width: side, + } const isOverflow = !isDesktopWeb && gallery.size > 2 - const imageControlLabelStyle = { - borderRadius: 5, - paddingHorizontal: 10, - position: 'absolute' as const, - zIndex: 1, - ...(isOverflow - ? { - left: 4, - bottom: 4, - } - : isDesktopWeb && gallery.size < 3 - ? { - left: 8, - top: 8, - } - : { - left: 4, - top: 4, - }), - } + const altTextControlStyle = isOverflow + ? { + left: 4, + bottom: 4, + } + : isDesktopWeb && gallery.size < 3 + ? { + left: 8, + top: 8, + } + : { + left: 4, + top: 4, + } - const imageControlsSubgroupStyle = { + const imageControlsStyle = { display: 'flex' as const, flexDirection: 'row' as const, position: 'absolute' as const, @@ -103,63 +75,90 @@ export const Gallery = observer(function ({gallery}: Props) { } return !gallery.isEmpty ? ( - <View testID="selectedPhotosView" style={styles.gallery}> - {gallery.images.map(image => ( - <View key={`selected-image-${image.path}`} style={[imageStyle]}> - <TouchableOpacity - testID="altTextButton" - accessibilityRole="button" - accessibilityLabel="Add alt text" - accessibilityHint="" - onPress={() => { - handleAddImageAltText(image) - }} - style={imageControlLabelStyle}> - <Text style={styles.imageControlTextContent}>ALT</Text> - </TouchableOpacity> - <View style={imageControlsSubgroupStyle}> + <> + <View testID="selectedPhotosView" style={styles.gallery}> + {gallery.images.map(image => ( + <View key={`selected-image-${image.path}`} style={[imageStyle]}> <TouchableOpacity - testID="editPhotoButton" + testID="altTextButton" accessibilityRole="button" - accessibilityLabel="Edit image" + accessibilityLabel="Add alt text" accessibilityHint="" onPress={() => { - handleEditPhoto(image) + Keyboard.dismiss() + openAltTextModal(store, image) }} - style={styles.imageControl}> - <FontAwesomeIcon - icon="pen" - size={12} - style={{color: colors.white}} - /> + style={[styles.altTextControl, altTextControlStyle]}> + <Text style={styles.altTextControlLabel}>ALT</Text> + {image.altText.length > 0 ? ( + <FontAwesomeIcon + icon="check" + size={10} + style={{color: colors.green3}} + /> + ) : undefined} </TouchableOpacity> + <View style={imageControlsStyle}> + <TouchableOpacity + testID="editPhotoButton" + accessibilityRole="button" + accessibilityLabel="Edit image" + accessibilityHint="" + onPress={() => gallery.edit(image)} + style={styles.imageControl}> + <FontAwesomeIcon + icon="pen" + size={12} + style={{color: colors.white}} + /> + </TouchableOpacity> + <TouchableOpacity + testID="removePhotoButton" + accessibilityRole="button" + accessibilityLabel="Remove image" + accessibilityHint="" + onPress={() => gallery.remove(image)} + style={styles.imageControl}> + <FontAwesomeIcon + icon="xmark" + size={16} + style={{color: colors.white}} + /> + </TouchableOpacity> + </View> <TouchableOpacity - testID="removePhotoButton" accessibilityRole="button" - accessibilityLabel="Remove image" + accessibilityLabel="Add alt text" accessibilityHint="" - onPress={() => handleRemovePhoto(image)} - style={styles.imageControl}> - <FontAwesomeIcon - icon="xmark" - size={16} - style={{color: colors.white}} - /> - </TouchableOpacity> - </View> + onPress={() => { + Keyboard.dismiss() + openAltTextModal(store, image) + }} + style={styles.altTextHiddenRegion} + /> - <Image - testID="selectedPhotoImage" - style={[styles.image, imageStyle] as ImageStyle} - source={{ - uri: image.cropped?.path ?? image.path, - }} - accessible={true} - accessibilityIgnoresInvertColors - /> + <Image + testID="selectedPhotoImage" + style={[styles.image, imageStyle] as ImageStyle} + source={{ + uri: image.cropped?.path ?? image.path, + }} + accessible={true} + accessibilityIgnoresInvertColors + /> + </View> + ))} + </View> + <View style={[styles.reminder]}> + <View style={[styles.infoIcon, pal.viewLight]}> + <FontAwesomeIcon icon="info" size={12} color={pal.colors.text} /> </View> - ))} - </View> + <Text type="sm" style={[pal.textLight, s.flex1]}> + Alt text describes images for blind and low-vision users, and helps + give context to everyone. + </Text> + </View> + </> ) : null }) @@ -179,19 +178,46 @@ const styles = StyleSheet.create({ height: 24, borderRadius: 12, backgroundColor: 'rgba(0, 0, 0, 0.75)', - borderWidth: 0.5, alignItems: 'center', justifyContent: 'center', }, - imageControlTextContent: { + altTextControl: { + position: 'absolute', + zIndex: 1, borderRadius: 6, + backgroundColor: 'rgba(0, 0, 0, 0.75)', + paddingHorizontal: 8, + paddingVertical: 3, + flexDirection: 'row', + alignItems: 'center', + }, + altTextControlLabel: { color: 'white', fontSize: 12, fontWeight: 'bold', letterSpacing: 1, - backgroundColor: 'rgba(0, 0, 0, 0.75)', - borderWidth: 0.5, - paddingHorizontal: 10, - paddingVertical: 3, + }, + altTextHiddenRegion: { + position: 'absolute', + left: 4, + right: 4, + bottom: 4, + top: 30, + zIndex: 1, + }, + + reminder: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + borderRadius: 8, + paddingVertical: 14, + }, + infoIcon: { + width: 22, + height: 22, + borderRadius: 12, + alignItems: 'center', + justifyContent: 'center', }, }) diff --git a/src/view/com/modals/AltImage.tsx b/src/view/com/modals/AltImage.tsx index 07270d557..e1145a0fe 100644 --- a/src/view/com/modals/AltImage.tsx +++ b/src/view/com/modals/AltImage.tsx @@ -1,5 +1,15 @@ -import React, {useCallback, useState} from 'react' -import {StyleSheet, TextInput, TouchableOpacity, View} from 'react-native' +import React, {useMemo, useCallback, useState} from 'react' +import { + ImageStyle, + KeyboardAvoidingView, + ScrollView, + StyleSheet, + TextInput, + TouchableOpacity, + View, + useWindowDimensions, +} from 'react-native' +import {Image} from 'expo-image' import {usePalette} from 'lib/hooks/usePalette' import {gradients, s} from 'lib/styles' import {enforceLen} from 'lib/strings/helpers' @@ -8,7 +18,7 @@ import {useTheme} from 'lib/ThemeContext' import {Text} from '../util/text/Text' import LinearGradient from 'react-native-linear-gradient' import {useStores} from 'state/index' -import {isDesktopWeb} from 'platform/detection' +import {isDesktopWeb, isAndroid} from 'platform/detection' import {ImageModel} from 'state/models/media/image' export const snapPoints = ['fullscreen'] @@ -22,6 +32,24 @@ export function Component({image}: Props) { const store = useStores() const theme = useTheme() const [altText, setAltText] = useState(image.altText) + const windim = useWindowDimensions() + + const imageStyles = useMemo<ImageStyle>(() => { + const maxWidth = isDesktopWeb ? 450 : windim.width + if (image.height > image.width) { + return { + resizeMode: 'contain', + width: '100%', + aspectRatio: 1, + borderRadius: 8, + } + } + return { + width: '100%', + height: (maxWidth / image.width) * image.height, + borderRadius: 8, + } + }, [image, windim]) const onPressSave = useCallback(() => { image.setAltText(altText) @@ -33,69 +61,94 @@ export function Component({image}: Props) { } return ( - <View - testID="altTextImageModal" - style={[pal.view, styles.container, s.flex1]} - nativeID="imageAltText"> - <Text style={[styles.title, pal.text]}>Add alt text</Text> - <TextInput - testID="altTextImageInput" - style={[styles.textArea, pal.border, pal.text]} - keyboardAppearance={theme.colorScheme} - multiline - value={altText} - onChangeText={text => setAltText(enforceLen(text, MAX_ALT_TEXT))} - accessibilityLabel="Image alt text" - accessibilityHint="Sets image alt text for screenreaders" - accessibilityLabelledBy="imageAltText" - /> - <View style={styles.buttonControls}> - <TouchableOpacity - testID="altTextImageSaveBtn" - onPress={onPressSave} - accessibilityLabel="Save alt text" - accessibilityHint={`Saves alt text, which reads: ${altText}`} - accessibilityRole="button"> - <LinearGradient - colors={[gradients.blueLight.start, gradients.blueLight.end]} - start={{x: 0, y: 0}} - end={{x: 1, y: 1}} - style={[styles.button]}> - <Text type="button-lg" style={[s.white, s.bold]}> - Save - </Text> - </LinearGradient> - </TouchableOpacity> - <TouchableOpacity - testID="altTextImageCancelBtn" - onPress={onPressCancel} - accessibilityRole="button" - accessibilityLabel="Cancel add image alt text" - accessibilityHint="Exits adding alt text to image" - onAccessibilityEscape={onPressCancel}> - <View style={[styles.button]}> - <Text type="button-lg" style={[pal.textLight]}> - Cancel - </Text> + <KeyboardAvoidingView + behavior={isAndroid ? 'height' : 'padding'} + style={[pal.view, styles.container]}> + <ScrollView + testID="altTextImageModal" + style={styles.scrollContainer} + keyboardShouldPersistTaps="always" + nativeID="imageAltText"> + <View style={styles.scrollInner}> + <View style={[pal.viewLight, styles.imageContainer]}> + <Image + testID="selectedPhotoImage" + style={imageStyles} + source={{ + uri: image.cropped?.path ?? image.path, + }} + accessible={true} + accessibilityIgnoresInvertColors + /> + </View> + <TextInput + testID="altTextImageInput" + style={[styles.textArea, pal.border, pal.text]} + keyboardAppearance={theme.colorScheme} + multiline + placeholder="Add alt text" + placeholderTextColor={pal.colors.textLight} + value={altText} + onChangeText={text => setAltText(enforceLen(text, MAX_ALT_TEXT))} + accessibilityLabel="Image alt text" + accessibilityHint="" + accessibilityLabelledBy="imageAltText" + autoFocus + /> + <View style={styles.buttonControls}> + <TouchableOpacity + testID="altTextImageSaveBtn" + onPress={onPressSave} + accessibilityLabel="Save alt text" + accessibilityHint={`Saves alt text, which reads: ${altText}`} + accessibilityRole="button"> + <LinearGradient + colors={[gradients.blueLight.start, gradients.blueLight.end]} + start={{x: 0, y: 0}} + end={{x: 1, y: 1}} + style={[styles.button]}> + <Text type="button-lg" style={[s.white, s.bold]}> + Save + </Text> + </LinearGradient> + </TouchableOpacity> + <TouchableOpacity + testID="altTextImageCancelBtn" + onPress={onPressCancel} + accessibilityRole="button" + accessibilityLabel="Cancel add image alt text" + accessibilityHint="" + onAccessibilityEscape={onPressCancel}> + <View style={[styles.button]}> + <Text type="button-lg" style={[pal.textLight]}> + Cancel + </Text> + </View> + </TouchableOpacity> </View> - </TouchableOpacity> - </View> - </View> + </View> + </ScrollView> + </KeyboardAvoidingView> ) } const styles = StyleSheet.create({ container: { - gap: 18, - paddingVertical: isDesktopWeb ? 0 : 18, - paddingHorizontal: isDesktopWeb ? 0 : 12, + flex: 1, height: '100%', width: '100%', + paddingVertical: isDesktopWeb ? 0 : 18, + }, + scrollContainer: { + flex: 1, + height: '100%', + paddingHorizontal: isDesktopWeb ? 0 : 12, + }, + scrollInner: { + gap: 12, }, - title: { - textAlign: 'center', - fontWeight: 'bold', - fontSize: 24, + imageContainer: { + borderRadius: 8, }, textArea: { borderWidth: 1, diff --git a/src/view/com/modals/Confirm.tsx b/src/view/com/modals/Confirm.tsx index 11e1a6334..f9bc0de14 100644 --- a/src/view/com/modals/Confirm.tsx +++ b/src/view/com/modals/Confirm.tsx @@ -12,6 +12,7 @@ import {ErrorMessage} from '../util/error/ErrorMessage' import {cleanError} from 'lib/strings/errors' import {usePalette} from 'lib/hooks/usePalette' import {isDesktopWeb} from 'platform/detection' +import type {ConfirmModal} from 'state/models/ui/shell' export const snapPoints = ['50%'] @@ -20,12 +21,9 @@ export function Component({ message, onPressConfirm, onPressCancel, -}: { - title: string - message: string | (() => JSX.Element) - onPressConfirm: () => void | Promise<void> - onPressCancel?: () => void | Promise<void> -}) { + confirmBtnText, + confirmBtnStyle, +}: ConfirmModal) { const pal = usePalette('default') const store = useStores() const [isProcessing, setIsProcessing] = useState<boolean>(false) @@ -68,11 +66,13 @@ export function Component({ <TouchableOpacity testID="confirmBtn" onPress={onPress} - style={[styles.btn]} + style={[styles.btn, confirmBtnStyle]} accessibilityRole="button" accessibilityLabel="Confirm" accessibilityHint=""> - <Text style={[s.white, s.bold, s.f18]}>Confirm</Text> + <Text style={[s.white, s.bold, s.f18]}> + {confirmBtnText ?? 'Confirm'} + </Text> </TouchableOpacity> )} {onPressCancel === undefined ? null : ( diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 610b96507..51f63dbb3 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -9,10 +9,8 @@ import { } from 'react-native' import {AppBskyFeedDefs} from '@atproto/api' import {CenteredView, FlatList} from '../util/Views' -import { - PostThreadModel, - PostThreadItemModel, -} from 'state/models/content/post-thread' +import {PostThreadModel} from 'state/models/content/post-thread' +import {PostThreadItemModel} from 'state/models/content/post-thread-item' import { FontAwesomeIcon, FontAwesomeIconStyle, diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 647468401..002795d77 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -7,7 +7,7 @@ import { FontAwesomeIcon, FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {PostThreadItemModel} from 'state/models/content/post-thread' +import {PostThreadItemModel} from 'state/models/content/post-thread-item' import {Link} from '../util/Link' import {RichText} from '../util/text/RichText' import {Text} from '../util/text/Text' diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index b9d146dee..3eac7ee7b 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -13,10 +13,8 @@ import {observer} from 'mobx-react-lite' import Clipboard from '@react-native-clipboard/clipboard' import {AtUri} from '@atproto/api' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import { - PostThreadModel, - PostThreadItemModel, -} from 'state/models/content/post-thread' +import {PostThreadModel} from 'state/models/content/post-thread' +import {PostThreadItemModel} from 'state/models/content/post-thread-item' import {Link} from '../util/Link' import {UserInfoText} from '../util/UserInfoText' import {PostMeta} from '../util/PostMeta' diff --git a/src/view/com/posts/FeedSlice.tsx b/src/view/com/posts/FeedSlice.tsx index 888466200..d75ff1385 100644 --- a/src/view/com/posts/FeedSlice.tsx +++ b/src/view/com/posts/FeedSlice.tsx @@ -1,6 +1,6 @@ import React from 'react' import {StyleSheet, View} from 'react-native' -import {PostsFeedSliceModel} from 'state/models/feeds/post' +import {PostsFeedSliceModel} from 'state/models/feeds/posts-slice' import {AtUri} from '@atproto/api' import {Link} from '../util/Link' import {Text} from '../util/text/Text' diff --git a/src/view/com/util/images/Gallery.tsx b/src/view/com/util/images/Gallery.tsx index 723db289c..a7a64b171 100644 --- a/src/view/com/util/images/Gallery.tsx +++ b/src/view/com/util/images/Gallery.tsx @@ -45,23 +45,28 @@ export const GalleryItem: FC<GalleryItemProps> = ({ accessibilityIgnoresInvertColors /> </TouchableOpacity> - {image.alt === '' ? null : <Text style={styles.alt}>ALT</Text>} + {image.alt === '' ? null : ( + <View style={styles.altContainer}> + <Text style={styles.alt}>ALT</Text> + </View> + )} </View> ) } const styles = StyleSheet.create({ - alt: { + altContainer: { backgroundColor: 'rgba(0, 0, 0, 0.75)', borderRadius: 6, - color: 'white', - fontSize: 12, - fontWeight: 'bold', - letterSpacing: 1, - paddingHorizontal: 10, + paddingHorizontal: 6, paddingVertical: 3, position: 'absolute', left: 6, bottom: 6, }, + alt: { + color: 'white', + fontSize: 10, + fontWeight: 'bold', + }, }) diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx index 53ef17318..7f2244b7b 100644 --- a/src/view/com/util/post-embeds/index.tsx +++ b/src/view/com/util/post-embeds/index.tsx @@ -126,7 +126,11 @@ export function PostEmbeds({ onPress={() => openLightbox(0)} onPressIn={() => onPressIn(0)} style={styles.singleImage}> - {alt === '' ? null : <Text style={styles.alt}>ALT</Text>} + {alt === '' ? null : ( + <View style={styles.altContainer}> + <Text style={styles.alt}>ALT</Text> + </View> + )} </AutoSizedImage> </View> ) @@ -201,17 +205,18 @@ const styles = StyleSheet.create({ borderRadius: 8, marginTop: 4, }, - alt: { + altContainer: { backgroundColor: 'rgba(0, 0, 0, 0.75)', borderRadius: 6, - color: 'white', - fontSize: 12, - fontWeight: 'bold', - letterSpacing: 1, - paddingHorizontal: 10, + paddingHorizontal: 6, paddingVertical: 3, position: 'absolute', left: 6, bottom: 6, }, + alt: { + color: 'white', + fontSize: 10, + fontWeight: 'bold', + }, }) diff --git a/src/view/screens/CustomFeed.tsx b/src/view/screens/CustomFeed.tsx index 4149cd49d..c0dcd7980 100644 --- a/src/view/screens/CustomFeed.tsx +++ b/src/view/screens/CustomFeed.tsx @@ -31,12 +31,14 @@ import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn' import {DropdownButton, DropdownItem} from 'view/com/util/forms/DropdownButton' import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' import {EmptyState} from 'view/com/util/EmptyState' +import {useAnalytics} from 'lib/analytics/analytics' type Props = NativeStackScreenProps<CommonNavigatorParams, 'CustomFeed'> export const CustomFeedScreen = withAuthRequired( observer(({route}: Props) => { const store = useStores() const pal = usePalette('default') + const {track} = useAnalytics() const {rkey, name} = route.params const uri = useMemo( () => makeRecordUri(name, 'app.bsky.feed.generator', rkey), @@ -99,7 +101,8 @@ export const CustomFeedScreen = withAuthRequired( const onPressShare = React.useCallback(() => { const url = toShareUrl(`/profile/${name}/feed/${rkey}`) shareUrl(url) - }, [name, rkey]) + track('CustomFeed:Share') + }, [name, rkey, track]) const onScrollToTop = React.useCallback(() => { scrollElRef.current?.scrollToOffset({offset: 0, animated: true}) diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx index f51bda825..390266440 100644 --- a/src/view/screens/Profile.tsx +++ b/src/view/screens/Profile.tsx @@ -9,7 +9,7 @@ import {CenteredView} from '../com/util/Views' import {ScreenHider} from 'view/com/util/moderation/ScreenHider' import {ProfileUiModel, Sections} from 'state/models/ui/profile' import {useStores} from 'state/index' -import {PostsFeedSliceModel} from 'state/models/feeds/post' +import {PostsFeedSliceModel} from 'state/models/feeds/posts-slice' import {ProfileHeader} from '../com/profile/ProfileHeader' import {FeedSlice} from '../com/posts/FeedSlice' import {ListCard} from 'view/com/lists/ListCard' |