mirror of https://github.com/tooot-app/app
Merge branch 'main' into release
This commit is contained in:
commit
6a8315e1e0
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "tooot",
|
"name": "tooot",
|
||||||
"version": "4.8.1",
|
"version": "4.8.2",
|
||||||
"description": "tooot for Mastodon",
|
"description": "tooot for Mastodon",
|
||||||
"author": "xmflsct <me@xmflsct.com>",
|
"author": "xmflsct <me@xmflsct.com>",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
|
|
|
@ -4,7 +4,8 @@ import ParseEmojis from '@components/Parse/Emojis'
|
||||||
import StatusContext from '@components/Timeline/Shared/Context'
|
import StatusContext from '@components/Timeline/Shared/Context'
|
||||||
import { useNavigation, useRoute } from '@react-navigation/native'
|
import { useNavigation, useRoute } from '@react-navigation/native'
|
||||||
import { StackNavigationProp } from '@react-navigation/stack'
|
import { StackNavigationProp } from '@react-navigation/stack'
|
||||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
import { urlMatcher } from '@utils/helpers/urlMatcher'
|
||||||
|
import { TabLocalStackParamList, TabSharedStackParamList } from '@utils/navigation/navigators'
|
||||||
import { useAccountStorage, useGlobalStorage } from '@utils/storage/actions'
|
import { useAccountStorage, useGlobalStorage } from '@utils/storage/actions'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import layoutAnimation from '@utils/styles/layoutAnimation'
|
import layoutAnimation from '@utils/styles/layoutAnimation'
|
||||||
|
@ -152,22 +153,34 @@ const ParseHTML: React.FC<Props> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (classes.includes('mention') && (status?.mentions?.length || mentions?.length)) {
|
if (classes.includes('mention') && (status?.mentions?.length || mentions?.length)) {
|
||||||
const matchedMention = (status?.mentions || mentions || []).find(
|
let matchedMention:
|
||||||
|
| TabSharedStackParamList['Tab-Shared-Account']['account']
|
||||||
|
| undefined = (status?.mentions || mentions || []).find(
|
||||||
mention => mention.url === href
|
mention => mention.url === href
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
matchedMention &&
|
matchedMention &&
|
||||||
excludeMentions?.current.find(eM => eM.id === matchedMention.id)
|
excludeMentions?.current.find(eM => eM.id === matchedMention?.id)
|
||||||
) {
|
) {
|
||||||
prevMentionRemoved.current = true
|
prevMentionRemoved.current = true
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!matchedMention) {
|
||||||
|
const match = urlMatcher(href)
|
||||||
|
if (match?.account?.acct) {
|
||||||
|
// @ts-ignore
|
||||||
|
matchedMention = { ...match.account, url: href }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const paramsAccount = (params as { account: Mastodon.Account } | undefined)?.account
|
const paramsAccount = (params as { account: Mastodon.Account } | undefined)?.account
|
||||||
const sameAccount = paramsAccount?.id === matchedMention?.id
|
const sameAccount = paramsAccount ? paramsAccount.id === matchedMention?.id : false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
key={index}
|
key={index}
|
||||||
style={{ color: matchedMention ? colors.blue : undefined }}
|
style={{ color: matchedMention ? colors.blue : colors.primaryDefault }}
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
matchedMention &&
|
matchedMention &&
|
||||||
!disableDetails &&
|
!disableDetails &&
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useContext, useEffect, useState } from 'react'
|
import React, { useContext, useEffect, useState } from 'react'
|
||||||
import { Pressable, View } from 'react-native'
|
import { Pressable, View } from 'react-native'
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
|
||||||
import TimelineDefault from '../Default'
|
import TimelineDefault from '../Default'
|
||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
|
|
||||||
|
@ -62,21 +61,14 @@ const TimelineCard: React.FC = () => {
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if ((!status.card?.image || !status.card.title) && !status.card?.description) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const cardContent = () => {
|
const cardContent = () => {
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
paddingVertical: StyleConstants.Spacing.M
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (match?.status && foundStatus) {
|
if (match?.status && foundStatus) {
|
||||||
return <TimelineDefault item={foundStatus} disableDetails disableOnPress />
|
return <TimelineDefault item={foundStatus} disableDetails disableOnPress />
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,28 +68,16 @@ const TimelineHeaderAndroid: React.FC = () => {
|
||||||
)
|
)
|
||||||
case 'sub':
|
case 'sub':
|
||||||
return (
|
return (
|
||||||
// @ts-ignore
|
<Fragment key={item.key}>
|
||||||
<DropdownMenu.Sub key={item.key}>
|
{item.items.map(sub => (
|
||||||
<DropdownMenu.SubTrigger
|
<DropdownMenu.Item key={sub.key} {...sub.props}>
|
||||||
key={item.trigger.key}
|
<DropdownMenu.ItemTitle children={sub.title} />
|
||||||
{...item.trigger.props}
|
{sub.icon ? (
|
||||||
>
|
<DropdownMenu.ItemIcon ios={{ name: sub.icon }} />
|
||||||
<DropdownMenu.ItemTitle children={item.trigger.title} />
|
) : null}
|
||||||
{item.trigger.icon ? (
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.ItemIcon ios={{ name: item.trigger.icon }} />
|
))}
|
||||||
) : null}
|
</Fragment>
|
||||||
</DropdownMenu.SubTrigger>
|
|
||||||
<DropdownMenu.SubContent>
|
|
||||||
{item.items.map(sub => (
|
|
||||||
<DropdownMenu.Item key={sub.key} {...sub.props}>
|
|
||||||
<DropdownMenu.ItemTitle children={sub.title} />
|
|
||||||
{sub.icon ? (
|
|
||||||
<DropdownMenu.ItemIcon ios={{ name: sub.icon }} />
|
|
||||||
) : null}
|
|
||||||
</DropdownMenu.Item>
|
|
||||||
))}
|
|
||||||
</DropdownMenu.SubContent>
|
|
||||||
</DropdownMenu.Sub>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -56,7 +56,7 @@ const HeaderConversation = ({ conversation }: Props) => {
|
||||||
<CustomText>{t('componentTimeline:shared.header.conversation.withAccounts')}</CustomText>
|
<CustomText>{t('componentTimeline:shared.header.conversation.withAccounts')}</CustomText>
|
||||||
{conversation.accounts.map((account, index) => (
|
{conversation.accounts.map((account, index) => (
|
||||||
<CustomText key={account.id} numberOfLines={1}>
|
<CustomText key={account.id} numberOfLines={1}>
|
||||||
{index !== 0 ? t('common:separator') : undefined}
|
{index !== 0 ? t('common:separator') : ' '}
|
||||||
<ParseEmojis
|
<ParseEmojis
|
||||||
content={account.display_name || account.username}
|
content={account.display_name || account.username}
|
||||||
emojis={account.emojis}
|
emojis={account.emojis}
|
||||||
|
|
|
@ -30,6 +30,8 @@ const ComposeTextInput: React.FC = () => {
|
||||||
paddingBottom: StyleConstants.Spacing.M,
|
paddingBottom: StyleConstants.Spacing.M,
|
||||||
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
marginHorizontal: StyleConstants.Spacing.Global.PagePadding,
|
||||||
color: colors.primaryDefault,
|
color: colors.primaryDefault,
|
||||||
|
borderBottomWidth: 0.5,
|
||||||
|
borderBottomColor: colors.backgroundDefaultTransparent,
|
||||||
fontSize: adaptedFontsize,
|
fontSize: adaptedFontsize,
|
||||||
lineHeight: adaptedLineheight
|
lineHeight: adaptedLineheight
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -20,7 +20,7 @@ const assignVisibility = (
|
||||||
return { visibility: 'unlisted', visibilityLock: false }
|
return { visibility: 'unlisted', visibilityLock: false }
|
||||||
}
|
}
|
||||||
case 'public':
|
case 'public':
|
||||||
switch (preferences) {
|
switch (preferences?.['posting:default:visibility']) {
|
||||||
case 'private':
|
case 'private':
|
||||||
return { visibility: 'private', visibilityLock: false }
|
return { visibility: 'private', visibilityLock: false }
|
||||||
case 'unlisted':
|
case 'unlisted':
|
||||||
|
|
|
@ -38,7 +38,7 @@ const Root: React.FC<NativeStackScreenProps<TabPublicStackParamList, 'Tab-Public
|
||||||
const previousSegment = getGlobalStorage.string('app.prev_public_segment')
|
const previousSegment = getGlobalStorage.string('app.prev_public_segment')
|
||||||
const segments: StorageGlobal['app.prev_public_segment'][] = ['Local', 'LocalPublic', 'Trending']
|
const segments: StorageGlobal['app.prev_public_segment'][] = ['Local', 'LocalPublic', 'Trending']
|
||||||
const [segment, setSegment] = useState<number>(
|
const [segment, setSegment] = useState<number>(
|
||||||
Math.min(
|
Math.max(
|
||||||
0,
|
0,
|
||||||
segments.findIndex(segment => segment === previousSegment)
|
segments.findIndex(segment => segment === previousSegment)
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { Fragment, useEffect, useMemo, useState } from 'react'
|
import React, { Fragment, useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Text, View } from 'react-native'
|
import { Platform, Text, View } from 'react-native'
|
||||||
import { useSharedValue } from 'react-native-reanimated'
|
import { useSharedValue } from 'react-native-reanimated'
|
||||||
import * as DropdownMenu from 'zeego/dropdown-menu'
|
import * as DropdownMenu from 'zeego/dropdown-menu'
|
||||||
import AccountAttachments from './Attachments'
|
import AccountAttachments from './Attachments'
|
||||||
|
@ -110,19 +110,34 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
)
|
)
|
||||||
case 'sub':
|
case 'sub':
|
||||||
return (
|
if (Platform.OS === 'ios') {
|
||||||
// @ts-ignore
|
return (
|
||||||
<DropdownMenu.Sub key={item.key}>
|
// @ts-ignore
|
||||||
<DropdownMenu.SubTrigger
|
<DropdownMenu.Sub key={item.key}>
|
||||||
key={item.trigger.key}
|
<DropdownMenu.SubTrigger
|
||||||
{...item.trigger.props}
|
key={item.trigger.key}
|
||||||
>
|
{...item.trigger.props}
|
||||||
<DropdownMenu.ItemTitle children={item.trigger.title} />
|
>
|
||||||
{item.trigger.icon ? (
|
<DropdownMenu.ItemTitle children={item.trigger.title} />
|
||||||
<DropdownMenu.ItemIcon ios={{ name: item.trigger.icon }} />
|
{item.trigger.icon ? (
|
||||||
) : null}
|
<DropdownMenu.ItemIcon ios={{ name: item.trigger.icon }} />
|
||||||
</DropdownMenu.SubTrigger>
|
) : null}
|
||||||
<DropdownMenu.SubContent>
|
</DropdownMenu.SubTrigger>
|
||||||
|
<DropdownMenu.SubContent>
|
||||||
|
{item.items.map(sub => (
|
||||||
|
<DropdownMenu.Item key={sub.key} {...sub.props}>
|
||||||
|
<DropdownMenu.ItemTitle children={sub.title} />
|
||||||
|
{sub.icon ? (
|
||||||
|
<DropdownMenu.ItemIcon ios={{ name: sub.icon }} />
|
||||||
|
) : null}
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
))}
|
||||||
|
</DropdownMenu.SubContent>
|
||||||
|
</DropdownMenu.Sub>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Fragment key={item.key}>
|
||||||
{item.items.map(sub => (
|
{item.items.map(sub => (
|
||||||
<DropdownMenu.Item key={sub.key} {...sub.props}>
|
<DropdownMenu.Item key={sub.key} {...sub.props}>
|
||||||
<DropdownMenu.ItemTitle children={sub.title} />
|
<DropdownMenu.ItemTitle children={sub.title} />
|
||||||
|
@ -131,9 +146,9 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
|
||||||
) : null}
|
) : null}
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
))}
|
))}
|
||||||
</DropdownMenu.SubContent>
|
</Fragment>
|
||||||
</DropdownMenu.Sub>
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</DropdownMenu.Group>
|
</DropdownMenu.Group>
|
||||||
|
|
|
@ -161,13 +161,15 @@ const TabSharedHistory: React.FC<TabSharedStackScreenProps<'Tab-Shared-History'>
|
||||||
<FlatList
|
<FlatList
|
||||||
style={{ flex: 1, minHeight: '100%' }}
|
style={{ flex: 1, minHeight: '100%' }}
|
||||||
data={dataReversed}
|
data={dataReversed}
|
||||||
renderItem={({ item, index }) => (
|
renderItem={({ item, index }) =>
|
||||||
<ContentView
|
index === dataReversed.length - 1 ? null : (
|
||||||
withoutBoundary={withoutBoundary}
|
<ContentView
|
||||||
item={item}
|
withoutBoundary={withoutBoundary}
|
||||||
prevItem={dataReversed[index + 1]}
|
item={item}
|
||||||
/>
|
prevItem={dataReversed[index + 1]}
|
||||||
)}
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
ItemSeparatorComponent={ComponentSeparator}
|
ItemSeparatorComponent={ComponentSeparator}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue