1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00
This commit is contained in:
xmflsct
2022-08-07 01:18:10 +02:00
parent 99b38f421c
commit e2ba4660df
40 changed files with 462 additions and 752 deletions

View File

@@ -47,10 +47,6 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
const [checkingAttachments, setCheckingAttachments] = useState(false)
const removeDraft = useCallback(ts => {
dispatch(removeInstanceDraft(ts))
}, [])
const renderItem = useCallback(
({ item }: { item: ComposeStateDraft }) => {
return (
@@ -144,7 +140,7 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
}}
source={{
uri:
attachment.local?.local_thumbnail ||
attachment.local?.thumbnail ||
attachment.remote?.preview_url
}}
/>
@@ -157,38 +153,6 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
},
[theme]
)
const renderHiddenItem = useCallback(
({ item }) => (
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
backgroundColor: colors.red
}}
children={
<Pressable
style={{
flexBasis:
StyleConstants.Font.Size.L +
StyleConstants.Spacing.Global.PagePadding * 4,
justifyContent: 'center',
alignItems: 'center'
}}
onPress={() => removeDraft(item.timestamp)}
children={
<Icon
name='Trash'
size={StyleConstants.Font.Size.L}
color={colors.primaryOverlay}
/>
}
/>
}
/>
),
[theme]
)
return (
<>
@@ -220,7 +184,35 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
<SwipeListView
data={instanceDrafts}
renderItem={renderItem}
renderHiddenItem={renderHiddenItem}
renderHiddenItem={({ item }) => (
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
backgroundColor: colors.red
}}
children={
<Pressable
style={{
flexBasis:
StyleConstants.Font.Size.L +
StyleConstants.Spacing.Global.PagePadding * 4,
justifyContent: 'center',
alignItems: 'center'
}}
onPress={() => dispatch(removeInstanceDraft(item.timestamp))}
children={
<Icon
name='Trash'
size={StyleConstants.Font.Size.L}
color={colors.primaryOverlay}
/>
}
/>
}
/>
)}
disableRightSwipe={true}
rightOpenValue={-actionWidth}
// previewRowKey={

View File

@@ -35,7 +35,7 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
video.local
? ({
url: video.local.uri,
preview_url: video.local.local_thumbnail,
preview_url: video.local.thumbnail,
blurhash: video.remote?.blurhash
} as Mastodon.AttachmentVideo)
: (video.remote as Mastodon.AttachmentVideo)

View File

@@ -4,13 +4,7 @@ import { useSearchQuery } from '@utils/queryHooks/search'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import { chunk, forEach, groupBy, sortBy } from 'lodash'
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useRef
} from 'react'
import React, { useContext, useEffect, useMemo, useRef } from 'react'
import {
AccessibilityInfo,
findNodeHandle,
@@ -147,35 +141,25 @@ const ComposeRoot = React.memo(
}
}, [isFetching])
const listItem = useCallback(
({ item }) => (
<ComposeRootSuggestion
item={item}
composeState={composeState}
composeDispatch={composeDispatch}
/>
),
[composeState]
)
const ListFooter = useCallback(
() => (
<ComposeRootFooter
accessibleRefAttachments={accessibleRefAttachments}
accessibleRefEmojis={accessibleRefEmojis}
/>
),
[]
)
return (
<View style={styles.base}>
<FlatList
renderItem={listItem}
renderItem={({ item }) => (
<ComposeRootSuggestion
item={item}
composeState={composeState}
composeDispatch={composeDispatch}
/>
)}
ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='always'
ListHeaderComponent={ComposeRootHeader}
ListFooterComponent={ListFooter}
ListFooterComponent={() => (
<ComposeRootFooter
accessibleRefAttachments={accessibleRefAttachments}
accessibleRefEmojis={accessibleRefEmojis}
/>
)}
ItemSeparatorComponent={ComponentSeparator}
// @ts-ignore
data={data ? data[composeState.tag?.type] : undefined}

View File

@@ -56,9 +56,12 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
})
}, [composeState.attachments.sensitive])
const calculateWidth = useCallback(item => {
const calculateWidth = useCallback((item: ExtendedAttachment) => {
if (item.local) {
return (item.local.width / item.local.height) * DEFAULT_HEIGHT
return (
((item.local.width || 100) / (item.local.height || 100)) *
DEFAULT_HEIGHT
)
} else {
if (item.remote) {
if (item.remote.meta.original.aspect) {
@@ -135,7 +138,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
<FastImage
style={{ width: '100%', height: '100%' }}
source={{
uri: item.local?.local_thumbnail || item.remote?.preview_url
uri: item.local?.thumbnail || item.remote?.preview_url
}}
/>
{item.remote?.meta?.original?.duration ? (

View File

@@ -42,22 +42,6 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
}
}, [composeState.emoji.active])
const listHeader = useCallback(
({ section: { title } }) => (
<CustomText
fontStyle='S'
style={{
position: 'absolute',
left: StyleConstants.Spacing.L,
color: colors.secondary
}}
>
{title}
</CustomText>
),
[]
)
const listItem = useCallback(
({ index, item }: { item: Mastodon.Emoji[]; index: number }) => {
return (
@@ -155,7 +139,18 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
keyboardShouldPersistTaps='always'
sections={composeState.emoji.emojis || []}
keyExtractor={item => item[0].shortcode}
renderSectionHeader={listHeader}
renderSectionHeader={({ section: { title } }) => (
<CustomText
fontStyle='S'
style={{
position: 'absolute',
left: StyleConstants.Spacing.L,
color: colors.secondary
}}
>
{title}
</CustomText>
)}
renderItem={listItem}
windowSize={2}
/>

View File

@@ -7,7 +7,7 @@ import { ActionSheetOptions } from '@expo/react-native-action-sheet'
import i18next from 'i18next'
import apiInstance from '@api/instance'
import mediaSelector from '@components/mediaSelector'
import { ImageOrVideo } from 'react-native-image-crop-picker'
import { Asset } from 'react-native-image-picker'
export interface Props {
composeDispatch: Dispatch<ComposeAction>
@@ -22,46 +22,40 @@ export const uploadAttachment = async ({
media
}: {
composeDispatch: Dispatch<ComposeAction>
media: { uri: string } & Pick<ImageOrVideo, 'mime' | 'width' | 'height'>
media: Required<Pick<Asset, 'uri' | 'type' | 'fileName'>>
}) => {
const hash = await Crypto.digestStringAsync(
Crypto.CryptoDigestAlgorithm.SHA256,
media.uri + Math.random()
)
switch (media.mime.split('/')[0]) {
switch (media.type.split('/')[0]) {
case 'image':
composeDispatch({
type: 'attachment/upload/start',
payload: {
local: { ...media, type: 'image', local_thumbnail: media.uri, hash },
local: { ...media, thumbnail: media.uri, hash },
uploading: true
}
})
break
case 'video':
VideoThumbnails.getThumbnailAsync(media.uri)
.then(({ uri, width, height }) =>
.then(({ uri, width, height }) => {
console.log('new', uri, width, height)
composeDispatch({
type: 'attachment/upload/start',
payload: {
local: {
...media,
type: 'video',
local_thumbnail: uri,
hash,
width,
height
},
local: { ...media, thumbnail: uri, hash, width, height },
uploading: true
}
})
)
})
.catch(() =>
composeDispatch({
type: 'attachment/upload/start',
payload: {
local: { ...media, type: 'video', hash },
local: { ...media, hash },
uploading: true
}
})
@@ -71,7 +65,7 @@ export const uploadAttachment = async ({
composeDispatch({
type: 'attachment/upload/start',
payload: {
local: { ...media, type: 'unknown', hash },
local: { ...media, hash },
uploading: true
}
})
@@ -102,8 +96,8 @@ export const uploadAttachment = async ({
const formData = new FormData()
formData.append('file', {
uri: media.uri,
name: media.uri.match(new RegExp(/.*\/(.*)/))?.[1] || 'file.jpg',
type: media.mime
name: media.fileName,
type: media.type
} as any)
return apiInstance<Mastodon.Attachment>({
@@ -140,7 +134,8 @@ const chooseAndUploadAttachment = async ({
showActionSheetWithOptions
})
for (const media of result) {
uploadAttachment({ composeDispatch, media })
const requiredMedia = media as Required<Asset>
uploadAttachment({ composeDispatch, media: requiredMedia })
await new Promise(res => setTimeout(res, 500))
}
}

View File

@@ -101,15 +101,7 @@ const ComposeTextInput: React.FC = () => {
}
for (const file of files) {
uploadAttachment({
composeDispatch,
media: {
uri: file.uri,
mime: file.type,
width: 100,
height: 100
}
})
uploadAttachment({ composeDispatch, media: file })
}
}}
>

View File

@@ -1,12 +1,8 @@
import { ImageOrVideo } from 'react-native-image-crop-picker'
import { Asset } from 'react-native-image-picker'
export type ExtendedAttachment = {
remote?: Mastodon.Attachment
local?: { uri: string } & Pick<ImageOrVideo, 'width' | 'height' | 'mime'> & {
type: 'image' | 'video' | 'unknown'
local_thumbnail?: string
hash?: string
}
local?: Asset & { thumbnail?: string; hash: string }
uploading?: boolean
}
@@ -121,10 +117,7 @@ export type ComposeAction =
}
| {
type: 'attachment/upload/end'
payload: {
remote: Mastodon.Attachment
local: { uri: string } & Pick<ImageOrVideo, 'width' | 'height' | 'mime'>
}
payload: { remote: Mastodon.Attachment; local: Asset }
}
| {
type: 'attachment/upload/fail'