1
0
mirror of https://github.com/tooot-app/app synced 2025-04-24 23:18:47 +02:00
This commit is contained in:
xmflsct 2023-02-12 18:38:06 +01:00
parent 4a340fca8e
commit 79a92b5df7
31 changed files with 180 additions and 143 deletions

View File

@ -42,7 +42,7 @@ const ComponentAccount: React.FC<PropsWithChildren & Props> = ({ account, props,
style={{ style={{
width: StyleConstants.Avatar.S, width: StyleConstants.Avatar.S,
height: StyleConstants.Avatar.S, height: StyleConstants.Avatar.S,
borderRadius: 8, borderRadius: StyleConstants.BorderRadius,
marginRight: StyleConstants.Spacing.S marginRight: StyleConstants.Spacing.S
}} }}
dim dim

View File

@ -45,7 +45,7 @@ const AccountButton: React.FC<Props> = ({ account, additionalActions }) => {
width: StyleConstants.Font.Size.L, width: StyleConstants.Font.Size.L,
height: StyleConstants.Font.Size.L height: StyleConstants.Font.Size.L
}} }}
style={{ borderRadius: StyleConstants.Font.Size.L / 2, overflow: 'hidden' }} style={{ borderRadius: 99, overflow: 'hidden' }}
/> />
<CustomText <CustomText
fontStyle='M' fontStyle='M'

View File

@ -116,7 +116,7 @@ const Button: React.FC<Props> = ({
}} }}
style={[ style={[
{ {
borderRadius: 100, borderRadius: 99,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
borderWidth: overlay ? 0 : selected ? 1.5 : 1, borderWidth: overlay ? 0 : selected ? 1.5 : 1,

View File

@ -35,7 +35,7 @@ const EmojisButton: React.FC = () => {
borderWidth: 2, borderWidth: 2,
borderColor: colors.primaryDefault, borderColor: colors.primaryDefault,
padding: StyleConstants.Spacing.Global.PagePadding / 2, padding: StyleConstants.Spacing.Global.PagePadding / 2,
borderRadius: 100 borderRadius: 99
}} }}
> >
<Icon <Icon

View File

@ -51,7 +51,7 @@ const HeaderLeft: React.FC<Props> = ({
minWidth: 44, minWidth: 44,
marginLeft: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S, marginLeft: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S,
...(type === undefined && { ...(type === undefined && {
borderRadius: 100 borderRadius: 99
}), }),
...(type === 'text' && { ...(type === 'text' && {
paddingHorizontal: StyleConstants.Spacing.S paddingHorizontal: StyleConstants.Spacing.S

View File

@ -98,9 +98,7 @@ const HeaderRight: React.FC<Props> = ({
minHeight: 44, minHeight: 44,
minWidth: 44, minWidth: 44,
marginRight: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S, marginRight: native ? -StyleConstants.Spacing.S : StyleConstants.Spacing.S,
...(type === undefined && { ...(type === undefined && { borderRadius: 99 }),
borderRadius: 100
}),
...(type === 'text' && { ...(type === 'text' && {
paddingHorizontal: StyleConstants.Spacing.S paddingHorizontal: StyleConstants.Spacing.S
}) })

View File

@ -89,7 +89,7 @@ const MenuRow: React.FC<Props> = ({
width: 8, width: 8,
height: 8, height: 8,
backgroundColor: colors.red, backgroundColor: colors.red,
borderRadius: 8, borderRadius: StyleConstants.BorderRadius,
marginRight: StyleConstants.Spacing.S marginRight: StyleConstants.Spacing.S
}} }}
/> />

View File

@ -31,9 +31,11 @@ export const SwipeToActions = <T extends unknown>({
haptics(action.haptic || 'Light') haptics(action.haptic || 'Light')
action.onPress({ item }) action.onPress({ item })
}} }}
style={{ backgroundColor: 'rgba(0, 255, 0, 0.2)' }}
> >
<View <View
style={{ style={{
flex: 1,
paddingHorizontal: StyleConstants.Spacing.L, paddingHorizontal: StyleConstants.Spacing.L,
flexBasis: perActionWidth, flexBasis: perActionWidth,
backgroundColor: action.color, backgroundColor: action.color,

View File

@ -67,7 +67,7 @@ const TimelineConversation: React.FC<Props> = ({ conversation, queryKey, highlig
<View style={{ flex: 1, width: '100%', flexDirection: 'row' }}> <View style={{ flex: 1, width: '100%', flexDirection: 'row' }}>
<View <View
style={{ style={{
borderRadius: 4, borderRadius: StyleConstants.BorderRadius,
overflow: 'hidden', overflow: 'hidden',
marginRight: StyleConstants.Spacing.S, marginRight: StyleConstants.Spacing.S,
width: StyleConstants.Avatar.M, width: StyleConstants.Avatar.M,

View File

@ -118,7 +118,7 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
width: '100%', width: '100%',
height: StyleConstants.Spacing.M + StyleConstants.Spacing.S * 2, height: StyleConstants.Spacing.M + StyleConstants.Spacing.S * 2,
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding, paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
borderRadius: 100, borderRadius: 99,
opacity: sensitiveShown ? 0.35 : undefined opacity: sensitiveShown ? 0.35 : undefined
}} }}
> >

View File

@ -49,7 +49,7 @@ const TimelineAvatar: React.FC<Props> = ({ account }) => {
} }
} }
style={{ style={{
borderRadius: StyleConstants.Avatar.M, borderRadius: 99,
overflow: 'hidden', overflow: 'hidden',
marginRight: StyleConstants.Spacing.S marginRight: StyleConstants.Spacing.S
}} }}

View File

@ -137,7 +137,7 @@ const TimelineCard: React.FC = () => {
flexDirection: 'row', flexDirection: 'row',
marginTop: StyleConstants.Spacing.M, marginTop: StyleConstants.Spacing.M,
borderWidth: 1, borderWidth: 1,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
overflow: 'hidden', overflow: 'hidden',
borderColor: colors.border borderColor: colors.border
}} }}

View File

@ -0,0 +1,26 @@
import i18n from '@i18n/index'
import { Alert } from 'react-native'
export const discardConfirmation = ({
condition,
action
}: {
condition: boolean
action: () => void
}) => {
if (condition) {
Alert.alert(i18n.t('common:discard.title'), i18n.t('common:discard.message'), [
{
text: i18n.t('common:buttons.discard'),
style: 'destructive',
onPress: () => action()
},
{
text: i18n.t('common:buttons.cancel'),
style: 'default'
}
])
} else {
action()
}
}

View File

@ -5,7 +5,7 @@ import i18next from 'i18next'
import { Asset, launchImageLibrary } from 'react-native-image-picker' import { Asset, launchImageLibrary } from 'react-native-image-picker'
const queryKeyInstance: QueryKeyInstance = ['Instance'] const queryKeyInstance: QueryKeyInstance = ['Instance']
export const MAX_MEDIA_ATTACHMENTS: number = export const MAX_MEDIA_ATTACHMENTS = (): number =>
queryClient.getQueryData<Mastodon.Instance<any>>(queryKeyInstance)?.configuration?.statuses queryClient.getQueryData<Mastodon.Instance<any>>(queryKeyInstance)?.configuration?.statuses
.max_media_attachments || 4 .max_media_attachments || 4
@ -27,7 +27,7 @@ const mediaSelector = async ({
indicateMaximum = false, indicateMaximum = false,
showActionSheetWithOptions showActionSheetWithOptions
}: Props): Promise<Asset[]> => { }: Props): Promise<Asset[]> => {
const _maximum = maximum || MAX_MEDIA_ATTACHMENTS const _maximum = maximum || MAX_MEDIA_ATTACHMENTS()
const options = () => { const options = () => {
switch (mediaType) { switch (mediaType) {

View File

@ -52,7 +52,7 @@ const Share = ({
padding: StyleConstants.Spacing.M, padding: StyleConstants.Spacing.M,
borderWidth: 1, borderWidth: 1,
borderColor: colors.shimmerHighlight, borderColor: colors.shimmerHighlight,
borderRadius: 8 borderRadius: StyleConstants.BorderRadius
}} }}
children={text} children={text}
/> />
@ -65,7 +65,7 @@ const Share = ({
padding: StyleConstants.Spacing.M, padding: StyleConstants.Spacing.M,
borderWidth: 1, borderWidth: 1,
borderColor: colors.shimmerHighlight, borderColor: colors.shimmerHighlight,
borderRadius: 8 borderRadius: StyleConstants.BorderRadius
}} }}
> >
<FlatList <FlatList

View File

@ -73,7 +73,7 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
padding: StyleConstants.Spacing.Global.PagePadding, padding: StyleConstants.Spacing.Global.PagePadding,
marginTop: StyleConstants.Spacing.Global.PagePadding, marginTop: StyleConstants.Spacing.Global.PagePadding,
borderWidth: 1, borderWidth: 1,
borderRadius: 6, borderRadius: StyleConstants.BorderRadius,
borderColor: colors.primaryDefault, borderColor: colors.primaryDefault,
backgroundColor: colors.backgroundDefault backgroundColor: colors.backgroundDefault
}} }}
@ -123,7 +123,7 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
marginTop: StyleConstants.Spacing.Global.PagePadding / 2, marginTop: StyleConstants.Spacing.Global.PagePadding / 2,
marginBottom: StyleConstants.Spacing.Global.PagePadding / 2, marginBottom: StyleConstants.Spacing.Global.PagePadding / 2,
marginRight: StyleConstants.Spacing.M, marginRight: StyleConstants.Spacing.M,
borderRadius: 6, borderRadius: StyleConstants.BorderRadius,
flexDirection: 'row', flexDirection: 'row',
borderColor: reaction.me ? colors.disabled : colors.primaryDefault, borderColor: reaction.me ? colors.disabled : colors.primaryDefault,
backgroundColor: reaction.me ? colors.disabled : colors.backgroundDefault backgroundColor: reaction.me ? colors.disabled : colors.backgroundDefault
@ -231,7 +231,7 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
style={{ style={{
width: StyleConstants.Spacing.S, width: StyleConstants.Spacing.S,
height: StyleConstants.Spacing.S, height: StyleConstants.Spacing.S,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
borderWidth: 1, borderWidth: 1,
borderColor: colors.primaryDefault, borderColor: colors.primaryDefault,
backgroundColor: i === index ? colors.primaryDefault : undefined, backgroundColor: i === index ? colors.primaryDefault : undefined,
@ -271,7 +271,7 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
style={{ style={{
width: StyleConstants.Spacing.S, width: StyleConstants.Spacing.S,
height: StyleConstants.Spacing.S, height: StyleConstants.Spacing.S,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
borderWidth: 1, borderWidth: 1,
borderColor: colors.primaryDefault, borderColor: colors.primaryDefault,
backgroundColor: i === index ? colors.primaryDefault : undefined, backgroundColor: i === index ? colors.primaryDefault : undefined,

View File

@ -56,7 +56,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
padding: StyleConstants.Spacing.S, padding: StyleConstants.Spacing.S,
borderColor: colors.border, borderColor: colors.border,
borderWidth: 1, borderWidth: 1,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
marginBottom: StyleConstants.Spacing.S marginBottom: StyleConstants.Spacing.S
}} }}
> >

View File

@ -1,3 +1,4 @@
import { discardConfirmation } from '@components/discardConfirmation'
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { HeaderLeft, HeaderRight } from '@components/Header' import { HeaderLeft, HeaderRight } from '@components/Header'
import { ModalScrollView } from '@components/ModalScrollView' import { ModalScrollView } from '@components/ModalScrollView'
@ -6,9 +7,11 @@ import apiInstance from '@utils/api/instance'
import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators' import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import { Image } from 'expo-image'
import React, { useContext, useEffect, useState } from 'react' import React, { useContext, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Alert, TextInput } from 'react-native' import { Alert, TextInput, View } from 'react-native'
import { DEFAULT_WIDTH } from './Root/Footer/Attachments'
import ComposeContext from './utils/createContext' import ComposeContext from './utils/createContext'
const ComposeEditAttachment: React.FC< const ComposeEditAttachment: React.FC<
@ -20,7 +23,7 @@ const ComposeEditAttachment: React.FC<
} }
}) => { }) => {
const { colors } = useTheme() const { colors } = useTheme()
const { t } = useTranslation('screenCompose') const { t } = useTranslation(['common', 'screenCompose'])
const { composeState, composeDispatch } = useContext(ComposeContext) const { composeState, composeDispatch } = useContext(ComposeContext)
const [isSubmitting, setIsSubmitting] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false)
@ -31,55 +34,88 @@ const ComposeEditAttachment: React.FC<
return null return null
} }
const [altText, setAltText] = useState<string | undefined>(theAttachment.description)
useEffect(() => { useEffect(() => {
navigation.setOptions({ navigation.setOptions({
title: t('content.editAttachment.header.title'), title: t('screenCompose:content.editAttachment.header.title'),
headerLeft: () => <HeaderLeft content='chevron-down' onPress={() => navigation.goBack()} />, headerLeft: () => (
<HeaderLeft
content='chevron-down'
onPress={() => {
discardConfirmation({
condition: theAttachment.description != altText,
action: () => navigation.goBack()
})
}}
/>
),
headerRight: () => ( headerRight: () => (
<HeaderRight <HeaderRight
accessibilityLabel={t('content.editAttachment.header.right.accessibilityLabel')} accessibilityLabel={t(
'screenCompose:content.editAttachment.header.right.accessibilityLabel'
)}
content='save' content='save'
loading={isSubmitting} loading={isSubmitting}
onPress={() => { onPress={() => {
if (composeState.type === 'edit') { if (composeState.type === 'edit') {
composeDispatch({ type: 'attachment/edit', payload: { ...theAttachment } }) composeDispatch({
type: 'attachment/edit',
payload: { ...theAttachment, description: altText }
})
navigation.goBack() navigation.goBack()
return return
} }
setIsSubmitting(true)
const body = { description: theAttachment.description }
theAttachment?.id && theAttachment?.id &&
apiInstance<Mastodon.Attachment>({ apiInstance<Mastodon.Attachment>({
method: 'put', method: 'put',
url: `media/${theAttachment.id}`, url: `media/${theAttachment.id}`,
body body: { description: altText }
}) })
.then(() => { .then(res => {
setIsSubmitting(false)
haptics('Success') haptics('Success')
composeDispatch({
type: 'attachment/edit',
payload: res.body
})
navigation.goBack() navigation.goBack()
}) })
.catch(() => { .catch(() => {
setIsSubmitting(false) setIsSubmitting(false)
haptics('Error') haptics('Error')
Alert.alert(t('content.editAttachment.header.right.failed.title'), undefined, [ Alert.alert(
t('screenCompose:content.editAttachment.header.right.failed.title'),
undefined,
[
{ {
text: t('content.editAttachment.header.right.failed.button'), text: t('screenCompose:content.editAttachment.header.right.failed.button'),
style: 'cancel' style: 'cancel'
} }
]) ]
)
}) })
}} }}
/> />
) )
}) })
}, [theAttachment]) }, [theAttachment, altText])
return ( return (
<ModalScrollView> <ModalScrollView>
<View style={{ alignItems: 'center', marginBottom: StyleConstants.Spacing.M }}>
<Image
style={{
width: DEFAULT_WIDTH,
height: DEFAULT_WIDTH,
borderRadius: StyleConstants.BorderRadius
}}
source={theAttachment.preview_url}
/>
</View>
<CustomText fontStyle='M' style={{ color: colors.primaryDefault }} fontWeight='Bold'> <CustomText fontStyle='M' style={{ color: colors.primaryDefault }} fontWeight='Bold'>
{t('content.editAttachment.content.altText.heading')} {t('screenCompose:content.editAttachment.content.altText.heading')}
</CustomText> </CustomText>
<TextInput <TextInput
style={{ style={{
@ -94,18 +130,10 @@ const ComposeEditAttachment: React.FC<
}} }}
maxLength={1500} maxLength={1500}
multiline multiline
onChangeText={e => value={altText}
composeDispatch({ onChangeText={e => setAltText(e)}
type: 'attachment/edit', placeholder={t('screenCompose:content.editAttachment.content.altText.placeholder')}
payload: {
...theAttachment,
description: e
}
})
}
placeholder={t('content.editAttachment.content.altText.placeholder')}
placeholderTextColor={colors.secondary} placeholderTextColor={colors.secondary}
value={theAttachment.description}
/> />
<CustomText <CustomText
fontStyle='S' fontStyle='S'

View File

@ -30,7 +30,7 @@ const ComposeActions: React.FC = () => {
const attachmentOnPress = () => { const attachmentOnPress = () => {
if (composeState.poll.active) return if (composeState.poll.active) return
if (composeState.attachments.uploads.length < MAX_MEDIA_ATTACHMENTS) { if (composeState.attachments.uploads.length < MAX_MEDIA_ATTACHMENTS()) {
return chooseAndUploadAttachment({ composeDispatch, showActionSheetWithOptions }) return chooseAndUploadAttachment({ composeDispatch, showActionSheetWithOptions })
} }
} }

View File

@ -12,19 +12,19 @@ import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation' import layoutAnimation from '@utils/styles/layoutAnimation'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import { Image } from 'expo-image' import { Image } from 'expo-image'
import React, { RefObject, useContext, useEffect, useRef } from 'react' import React, { RefObject, useContext, useRef } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { FlatList, Pressable, StyleSheet, View } from 'react-native' import { FlatList, Pressable, StyleSheet, View } from 'react-native'
import ComposeContext from '../../utils/createContext' import ComposeContext from '../../utils/createContext'
import { ExtendedAttachment } from '../../utils/types' import { ExtendedAttachment } from '../../utils/types'
import chooseAndUploadAttachment from './addAttachment' import chooseAndUploadAttachment from './addAttachment'
export const DEFAULT_WIDTH = 150
export interface Props { export interface Props {
accessibleRefAttachments: RefObject<View> accessibleRefAttachments: RefObject<View>
} }
const DEFAULT_HEIGHT = 200
const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => { const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
const { showActionSheetWithOptions } = useActionSheet() const { showActionSheetWithOptions } = useActionSheet()
const { composeState, composeDispatch } = useContext(ComposeContext) const { composeState, composeDispatch } = useContext(ComposeContext)
@ -40,72 +40,22 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
payload: { sensitive: !composeState.attachments.sensitive } payload: { sensitive: !composeState.attachments.sensitive }
}) })
const calculateWidth = (item: ExtendedAttachment) => {
if (item.local) {
return ((item.local.width || 100) / (item.local.height || 100)) * DEFAULT_HEIGHT
} else {
if (item.remote) {
if (item.remote.meta.original.aspect) {
return item.remote.meta.original.aspect * DEFAULT_HEIGHT
} else if (item.remote.meta.original.width && item.remote.meta.original.height) {
return (
(item.remote.meta.original.width / item.remote.meta.original.height) * DEFAULT_HEIGHT
)
} else {
return DEFAULT_HEIGHT
}
} else {
return DEFAULT_HEIGHT
}
}
}
const snapToOffsets = () => {
const attachmentsOffsets = composeState.attachments.uploads.map((_, index) => {
let currentOffset = 0
Array.from(Array(index).keys()).map(
i =>
(currentOffset =
currentOffset +
calculateWidth(composeState.attachments.uploads[i]) +
StyleConstants.Spacing.Global.PagePadding)
)
return currentOffset
})
return attachmentsOffsets.length < 4
? [
...attachmentsOffsets,
attachmentsOffsets.reduce((a, b) => a + b, 0) +
DEFAULT_HEIGHT +
StyleConstants.Spacing.Global.PagePadding
]
: attachmentsOffsets
}
let prevOffsets = useRef<number[]>()
useEffect(() => {
const snap = snapToOffsets()
if (snap.length > (prevOffsets.current ? prevOffsets.current.length : 0)) {
flatListRef.current?.scrollToOffset({
offset: snap[snapToOffsets.length - 2] + snap[snapToOffsets.length - 1]
})
}
prevOffsets.current = snap
}, [snapToOffsets, prevOffsets.current])
const renderAttachment = ({ item, index }: { item: ExtendedAttachment; index: number }) => { const renderAttachment = ({ item, index }: { item: ExtendedAttachment; index: number }) => {
return ( return (
<View <View
key={index} key={index}
style={{ style={{
height: DEFAULT_HEIGHT,
marginLeft: StyleConstants.Spacing.Global.PagePadding, marginLeft: StyleConstants.Spacing.Global.PagePadding,
marginTop: StyleConstants.Spacing.Global.PagePadding, marginTop: StyleConstants.Spacing.Global.PagePadding,
marginBottom: StyleConstants.Spacing.Global.PagePadding, marginBottom: StyleConstants.Spacing.Global.PagePadding
width: calculateWidth(item)
}} }}
> >
<Image <Image
style={{ width: '100%', height: '100%' }} style={{
width: DEFAULT_WIDTH,
height: DEFAULT_WIDTH,
borderRadius: StyleConstants.BorderRadius
}}
source={ source={
item.local?.thumbnail item.local?.thumbnail
? { uri: item.local?.thumbnail } ? { uri: item.local?.thumbnail }
@ -123,7 +73,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
paddingRight: StyleConstants.Spacing.S, paddingRight: StyleConstants.Spacing.S,
paddingTop: StyleConstants.Spacing.XS, paddingTop: StyleConstants.Spacing.XS,
paddingBottom: StyleConstants.Spacing.XS, paddingBottom: StyleConstants.Spacing.XS,
color: colors.backgroundDefault, color: colors.primaryOverlay,
backgroundColor: colors.backgroundOverlayInvert backgroundColor: colors.backgroundOverlayInvert
}} }}
> >
@ -157,7 +107,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
})} })}
type='icon' type='icon'
content='x' content='x'
spacing='M' size='L'
round round
overlay overlay
onPress={() => { onPress={() => {
@ -175,11 +125,11 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
accessibilityLabel={t('content.root.footer.attachments.edit.accessibilityLabel', { accessibilityLabel={t('content.root.footer.attachments.edit.accessibilityLabel', {
attachment: index + 1 attachment: index + 1
})} })}
type='icon'
content='edit'
spacing='M'
round
overlay overlay
size='S'
type='text'
content={!!item.remote?.description?.length ? 'ALT ✓' : '+ ALT'}
fontBold
onPress={() => navigation.navigate('Screen-Compose-EditAttachment', { index })} onPress={() => navigation.navigate('Screen-Compose-EditAttachment', { index })}
/> />
) : null} ) : null}
@ -230,23 +180,23 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
pagingEnabled={false} pagingEnabled={false}
snapToAlignment='center' snapToAlignment='center'
renderItem={renderAttachment} renderItem={renderAttachment}
snapToOffsets={snapToOffsets()} snapToOffsets={new Array(composeState.attachments.uploads.length).fill(DEFAULT_WIDTH)}
keyboardShouldPersistTaps='always' keyboardShouldPersistTaps='always'
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
data={composeState.attachments.uploads} data={composeState.attachments.uploads}
keyExtractor={item => item.local?.uri || item.remote?.url || Math.random().toString()} keyExtractor={item => item.local?.uri || item.remote?.url || Math.random().toString()}
ListFooterComponent={ ListFooterComponent={
composeState.attachments.uploads.length < MAX_MEDIA_ATTACHMENTS ? ( composeState.attachments.uploads.length < MAX_MEDIA_ATTACHMENTS() ? (
<Pressable <Pressable
accessible accessible
accessibilityLabel={t('content.root.footer.attachments.upload.accessibilityLabel')} accessibilityLabel={t('content.root.footer.attachments.upload.accessibilityLabel')}
style={{ style={{
height: DEFAULT_HEIGHT, width: DEFAULT_WIDTH,
height: DEFAULT_WIDTH,
marginLeft: StyleConstants.Spacing.Global.PagePadding, marginLeft: StyleConstants.Spacing.Global.PagePadding,
marginTop: StyleConstants.Spacing.Global.PagePadding, marginTop: StyleConstants.Spacing.Global.PagePadding,
marginBottom: StyleConstants.Spacing.Global.PagePadding, marginBottom: StyleConstants.Spacing.Global.PagePadding,
width: DEFAULT_HEIGHT, backgroundColor: colors.disabled
backgroundColor: colors.backgroundOverlayInvert
}} }}
onPress={async () => { onPress={async () => {
await chooseAndUploadAttachment({ await chooseAndUploadAttachment({
@ -258,9 +208,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
<Button <Button
type='icon' type='icon'
content='upload-cloud' content='upload-cloud'
spacing='M' size='L'
round
overlay
onPress={async () => { onPress={async () => {
await chooseAndUploadAttachment({ await chooseAndUploadAttachment({
composeDispatch, composeDispatch,
@ -270,10 +218,11 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
style={{ style={{
position: 'absolute', position: 'absolute',
top: top:
(DEFAULT_HEIGHT - StyleConstants.Spacing.M * 2 - StyleConstants.Font.Size.M) / (DEFAULT_WIDTH - StyleConstants.Spacing.M * 2 - StyleConstants.Font.Size.M) / 2,
2,
left: left:
(DEFAULT_HEIGHT - StyleConstants.Spacing.M * 2 - StyleConstants.Font.Size.M) / 2 (DEFAULT_WIDTH - StyleConstants.Spacing.M * 2 - StyleConstants.Font.Size.M) / 2,
borderWidth: 0,
backgroundColor: ''
}} }}
/> />
</Pressable> </Pressable>

View File

@ -38,8 +38,8 @@ const ComposePoll: React.FC = () => {
<View <View
style={{ style={{
flex: 1, flex: 1,
borderWidth: StyleSheet.hairlineWidth, borderWidth: 1,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
margin: StyleConstants.Spacing.Global.PagePadding, margin: StyleConstants.Spacing.Global.PagePadding,
borderColor: colors.border borderColor: colors.border
}} }}
@ -70,7 +70,7 @@ const ComposePoll: React.FC = () => {
flex: 1, flex: 1,
padding: StyleConstants.Spacing.S, padding: StyleConstants.Spacing.S,
borderWidth: StyleSheet.hairlineWidth, borderWidth: StyleSheet.hairlineWidth,
borderRadius: 6, borderRadius: StyleConstants.BorderRadius,
...StyleConstants.FontStyle.M, ...StyleConstants.FontStyle.M,
marginLeft: StyleConstants.Spacing.S, marginLeft: StyleConstants.Spacing.S,
borderColor: colors.border, borderColor: colors.border,

View File

@ -17,7 +17,7 @@ const ComposeReply: React.FC = () => {
flex: 1, flex: 1,
flexDirection: 'row', flexDirection: 'row',
borderWidth: 1, borderWidth: 1,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
overflow: 'hidden', overflow: 'hidden',
borderColor: colors.border, borderColor: colors.border,
marginHorizontal: StyleConstants.Spacing.Global.PagePadding, marginHorizontal: StyleConstants.Spacing.Global.PagePadding,

View File

@ -71,7 +71,7 @@ const ComposeTextInput: React.FC = () => {
scrollEnabled={false} scrollEnabled={false}
disableCopyPaste={false} disableCopyPaste={false}
onPaste={(error: string | null | undefined, files: PastedFile[]) => { onPaste={(error: string | null | undefined, files: PastedFile[]) => {
if (composeState.attachments.uploads.length + files.length > MAX_MEDIA_ATTACHMENTS) { if (composeState.attachments.uploads.length + files.length > MAX_MEDIA_ATTACHMENTS()) {
Alert.alert( Alert.alert(
t('screenCompose:content.root.header.textInput.keyboardImage.exceedMaximum.title'), t('screenCompose:content.root.header.textInput.keyboardImage.exceedMaximum.title'),
undefined, undefined,

View File

@ -28,7 +28,39 @@ const composeInitialState: Omit<ComposeState, 'timestamp'> = {
}, },
attachments: { attachments: {
sensitive: false, sensitive: false,
uploads: [] uploads: [
// Test images
// {
// remote: {
// id: '01',
// type: 'image',
// url: 'https://images.unsplash.com/photo-1669311540088-8d44f4ab2cd7',
// preview_url: 'https://images.unsplash.com/photo-1669311540088-8d44f4ab2cd7'
// },
// local: undefined,
// uploading: false
// },
// {
// remote: {
// id: '02',
// type: 'image',
// url: 'https://images.unsplash.com/photo-1669311605888-07172f42cb35',
// preview_url: 'https://images.unsplash.com/photo-1669311605888-07172f42cb35'
// },
// local: undefined,
// uploading: false
// },
// {
// remote: {
// id: '03',
// type: 'image',
// url: 'https://images.unsplash.com/photo-1669311576866-d77abb31f4ce',
// preview_url: 'https://images.unsplash.com/photo-1669311576866-d77abb31f4ce'
// },
// local: undefined,
// uploading: false
// }
]
}, },
visibility: 'public', visibility: 'public',
visibilityLock: false, visibilityLock: false,

View File

@ -134,7 +134,7 @@ const Explore = ({ route: { key: page } }: { route: { key: 'Explore' } }) => {
paddingHorizontal: StyleConstants.Spacing.Global.PagePadding, paddingHorizontal: StyleConstants.Spacing.Global.PagePadding,
marginTop: StyleConstants.Spacing.S, marginTop: StyleConstants.Spacing.S,
borderWidth: 1, borderWidth: 1,
borderRadius: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
marginHorizontal: StyleConstants.Spacing.Global.PagePadding, marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
borderColor: colors.border borderColor: colors.border
}} }}

View File

@ -14,7 +14,7 @@ const AccountInformationAvatar: React.FC = () => {
return ( return (
<GracefullyImage <GracefullyImage
style={{ borderRadius: 8, overflow: 'hidden' }} style={{ borderRadius: StyleConstants.BorderRadius, overflow: 'hidden' }}
dimension={{ width: StyleConstants.Avatar.L, height: StyleConstants.Avatar.L }} dimension={{ width: StyleConstants.Avatar.L, height: StyleConstants.Avatar.L }}
sources={{ sources={{
default: { uri: account?.avatar }, default: { uri: account?.avatar },

View File

@ -110,7 +110,7 @@ const TabSharedReport: React.FC<TabSharedStackScreenProps<'Tab-Shared-Report'>>
margin: StyleConstants.Spacing.Global.PagePadding, margin: StyleConstants.Spacing.Global.PagePadding,
borderWidth: 1, borderWidth: 1,
borderColor: colors.red, borderColor: colors.red,
borderRadius: 8 borderRadius: StyleConstants.BorderRadius
}} }}
> >
<ComponentAccount account={account} props={{}} /> <ComponentAccount account={account} props={{}} />

View File

@ -79,7 +79,7 @@ const TabSharedUsers: React.FC<TabSharedStackScreenProps<'Tab-Shared-Users'>> =
padding: StyleConstants.Spacing.S, padding: StyleConstants.Spacing.S,
borderColor: colors.border, borderColor: colors.border,
borderWidth: 1, borderWidth: 1,
borderRadius: StyleConstants.Spacing.S borderRadius: StyleConstants.BorderRadius
}} }}
> >
<Icon <Icon

View File

@ -55,7 +55,7 @@ const ScreenTabs = () => {
sources={{ default: { uri: avatarStatic } }} sources={{ default: { uri: avatarStatic } }}
dimension={{ width: size, height: size }} dimension={{ width: size, height: size }}
style={{ style={{
borderRadius: size, borderRadius: 99,
overflow: 'hidden', overflow: 'hidden',
borderWidth: focused ? 2 : 0, borderWidth: focused ? 2 : 0,
borderColor: focused ? colors.primaryDefault : color borderColor: focused ? colors.primaryDefault : color

View File

@ -21,5 +21,7 @@ export const StyleConstants = {
Global: { PagePadding: Base * 4 } Global: { PagePadding: Base * 4 }
}, },
BorderRadius: Base * 2,
Avatar: { XS: 32, S: 40, M: 48, L: 96 } Avatar: { XS: 32, S: 40, M: 48, L: 96 }
} }

View File

@ -83,9 +83,9 @@ const themeColors: {
dark_darker: 'rgba(18, 18, 18, 0.5)' dark_darker: 'rgba(18, 18, 18, 0.5)'
}, },
backgroundOverlayInvert: { backgroundOverlayInvert: {
light: 'rgba(25, 25, 25, 0.5)', light: 'rgba(25, 25, 25, 0.75)',
dark_lighter: 'rgba(0, 0, 0, 0.5)', dark_lighter: 'rgba(0, 0, 0, 0.75)',
dark_darker: 'rgba(0, 0, 0, 0.5)' dark_darker: 'rgba(0, 0, 0, 0.75)'
}, },
border: { border: {