mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Fixed #497
This commit is contained in:
@ -6,29 +6,19 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback } from 'react'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import analytics from './analytics'
|
||||
import GracefullyImage from './GracefullyImage'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
account: Mastodon.Account
|
||||
onPress?: () => void
|
||||
origin?: string
|
||||
}
|
||||
|
||||
const ComponentAccount: React.FC<Props> = ({
|
||||
account,
|
||||
onPress: customOnPress,
|
||||
origin
|
||||
}) => {
|
||||
const ComponentAccount: React.FC<Props> = ({ account, onPress: customOnPress }) => {
|
||||
const { colors } = useTheme()
|
||||
const navigation =
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
|
||||
const onPress = useCallback(() => {
|
||||
analytics('search_account_press', { page: origin })
|
||||
navigation.push('Tab-Shared-Account', { account })
|
||||
}, [])
|
||||
const onPress = useCallback(() => navigation.push('Tab-Shared-Account', { account }), [])
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { useRelationshipQuery } from '@utils/queryHooks/relationship'
|
||||
import {
|
||||
@ -135,9 +134,6 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
|
||||
return // For Android
|
||||
}
|
||||
if (actions[index].id === 'account-mute') {
|
||||
analytics('timeline_shared_headeractions_account_mute_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateAccountProperty',
|
||||
queryKey,
|
||||
@ -149,9 +145,6 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
|
||||
actions[index].id === 'account-block' ||
|
||||
(actions[index].id === 'account' && actions[index].actions?.[0].id === 'account-block')
|
||||
) {
|
||||
analytics('timeline_shared_headeractions_account_block_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateAccountProperty',
|
||||
queryKey,
|
||||
@ -163,9 +156,6 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
|
||||
actions[index].id === 'account-reports' ||
|
||||
(actions[index].id === 'account' && actions[index].actions?.[0].id === 'account-reports')
|
||||
) {
|
||||
analytics('timeline_shared_headeractions_account_reports_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateAccountProperty',
|
||||
queryKey,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||
import { getInstanceUrl } from '@utils/slices/instancesSlice'
|
||||
@ -71,9 +70,6 @@ const contextMenuInstance = ({ actions, status, queryKey, rootQueryKey }: Props)
|
||||
actions[index].id === 'instance-block' ||
|
||||
(actions[index].id === 'instance' && actions[index].actions?.[0].id === 'instance-block')
|
||||
) {
|
||||
analytics('timeline_shared_headeractions_domain_block_press', {
|
||||
page: queryKey[1].page
|
||||
})
|
||||
Alert.alert(
|
||||
t('instance.block.alert.title', { instance }),
|
||||
t('instance.block.alert.message'),
|
||||
@ -82,9 +78,6 @@ const contextMenuInstance = ({ actions, status, queryKey, rootQueryKey }: Props)
|
||||
text: t('instance.block.alert.buttons.confirm'),
|
||||
style: 'destructive',
|
||||
onPress: () => {
|
||||
analytics('timeline_shared_headeractions_domain_block_confirm', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'domainBlock',
|
||||
queryKey,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import Clipboard from '@react-native-clipboard/clipboard'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
@ -39,7 +38,6 @@ const contextMenuShare = ({ copiableContent, actions, type, url }: Props) => {
|
||||
return // For Android
|
||||
}
|
||||
if (actions[index].id === 'copy') {
|
||||
analytics('timeline_shared_headeractions_copy_press')
|
||||
Clipboard.setString(copiableContent?.current.content || '')
|
||||
displayMessage({
|
||||
theme,
|
||||
@ -48,7 +46,6 @@ const contextMenuShare = ({ copiableContent, actions, type, url }: Props) => {
|
||||
})
|
||||
}
|
||||
if (actions[index].id === 'share') {
|
||||
analytics('timeline_shared_headeractions_share_press')
|
||||
switch (Platform.OS) {
|
||||
case 'ios':
|
||||
Share.share({ url })
|
||||
|
@ -1,5 +1,4 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import analytics from '@components/analytics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
@ -107,17 +106,11 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||
return // For Android
|
||||
}
|
||||
if (actions[index].id === 'status-delete') {
|
||||
analytics('timeline_shared_headeractions_status_delete_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
|
||||
{
|
||||
text: t('status.delete.alert.buttons.confirm'),
|
||||
style: 'destructive',
|
||||
onPress: async () => {
|
||||
analytics('timeline_shared_headeractions_status_delete_confirm', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'deleteItem',
|
||||
source: 'statuses',
|
||||
@ -133,17 +126,11 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||
])
|
||||
}
|
||||
if (actions[index].id === 'status-delete-edit') {
|
||||
analytics('timeline_shared_headeractions_status_deleteedit_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
|
||||
{
|
||||
text: t('status.deleteEdit.alert.buttons.confirm'),
|
||||
style: 'destructive',
|
||||
onPress: async () => {
|
||||
analytics('timeline_shared_headeractions_status_deleteedit_confirm', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||
if (status.in_reply_to_id) {
|
||||
replyToStatus = await apiInstance<Mastodon.Status>({
|
||||
@ -174,9 +161,6 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||
])
|
||||
}
|
||||
if (actions[index].id === 'status-mute') {
|
||||
analytics('timeline_shared_headeractions_status_mute_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -191,9 +175,6 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||
})
|
||||
}
|
||||
if (actions[index].id === 'status-edit') {
|
||||
analytics('timeline_shared_headeractions_status_edit_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
let replyToStatus: Mastodon.Status | undefined = undefined
|
||||
if (status.in_reply_to_id) {
|
||||
replyToStatus = await apiInstance<Mastodon.Status>({
|
||||
@ -224,9 +205,6 @@ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) =
|
||||
}
|
||||
if (actions[index].id === 'status-pin') {
|
||||
// Also note that reblogs cannot be pinned.
|
||||
analytics('timeline_shared_headeractions_status_pin_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
|
@ -5,7 +5,6 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback } from 'react'
|
||||
import { Pressable } from 'react-native'
|
||||
import analytics from './analytics'
|
||||
import CustomText from './Text'
|
||||
|
||||
export interface Props {
|
||||
@ -24,7 +23,6 @@ const ComponentHashtag: React.FC<Props> = ({
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
|
||||
const onPress = useCallback(() => {
|
||||
analytics('search_account_press', { page: origin })
|
||||
navigation.push('Tab-Shared-Hashtag', { hashtag: hashtag.name })
|
||||
}, [])
|
||||
|
||||
|
@ -9,18 +9,10 @@ import * as WebBrowser from 'expo-web-browser'
|
||||
import { debounce } from 'lodash'
|
||||
import React, { RefObject, useCallback, useMemo, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import {
|
||||
Alert,
|
||||
Image,
|
||||
KeyboardAvoidingView,
|
||||
Platform,
|
||||
TextInput,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
|
||||
import { ScrollView } from 'react-native-gesture-handler'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { Placeholder } from 'rn-placeholder'
|
||||
import analytics from './analytics'
|
||||
import InstanceAuth from './Instance/Auth'
|
||||
import InstanceInfo from './Instance/Info'
|
||||
import CustomText from './Text'
|
||||
@ -65,11 +57,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
|
||||
const processUpdate = useCallback(() => {
|
||||
if (domain) {
|
||||
analytics('instance_login')
|
||||
if (
|
||||
instances &&
|
||||
instances.filter(instance => instance.url === domain).length
|
||||
) {
|
||||
if (instances && instances.filter(instance => instance.url === domain).length) {
|
||||
Alert.alert(t('update.alert.title'), t('update.alert.message'), [
|
||||
{
|
||||
text: t('update.alert.buttons.cancel'),
|
||||
@ -142,9 +130,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
borderBottomWidth: 1,
|
||||
...StyleConstants.FontStyle.M,
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: instanceQuery.isError
|
||||
? colors.red
|
||||
: colors.border
|
||||
borderBottomColor: instanceQuery.isError ? colors.red : colors.border
|
||||
}}
|
||||
editable={false}
|
||||
defaultValue='https://'
|
||||
@ -156,9 +142,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
...StyleConstants.FontStyle.M,
|
||||
marginRight: StyleConstants.Spacing.M,
|
||||
color: colors.primaryDefault,
|
||||
borderBottomColor: instanceQuery.isError
|
||||
? colors.red
|
||||
: colors.border
|
||||
borderBottomColor: instanceQuery.isError ? colors.red : colors.border
|
||||
}}
|
||||
onChangeText={onChangeText}
|
||||
autoCapitalize='none'
|
||||
@ -166,7 +150,6 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
keyboardType='url'
|
||||
textContentType='URL'
|
||||
onSubmitEditing={({ nativeEvent: { text } }) => {
|
||||
analytics('instance_textinput_submit', { match: text === domain })
|
||||
if (
|
||||
text === domain &&
|
||||
instanceQuery.isSuccess &&
|
||||
@ -182,11 +165,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
keyboardAppearance={mode}
|
||||
{...(scrollViewRef && {
|
||||
onFocus: () =>
|
||||
setTimeout(
|
||||
() =>
|
||||
scrollViewRef.current?.scrollTo({ y: 0, animated: true }),
|
||||
150
|
||||
)
|
||||
setTimeout(() => scrollViewRef.current?.scrollTo({ y: 0, animated: true }), 150)
|
||||
})}
|
||||
autoCorrect={false}
|
||||
spellCheck={false}
|
||||
@ -211,27 +190,19 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
<InstanceInfo
|
||||
style={{ alignItems: 'flex-start' }}
|
||||
header={t('server.information.accounts')}
|
||||
content={
|
||||
instanceQuery.data?.stats?.user_count?.toString() || undefined
|
||||
}
|
||||
content={instanceQuery.data?.stats?.user_count?.toString() || undefined}
|
||||
potentialWidth={4}
|
||||
/>
|
||||
<InstanceInfo
|
||||
style={{ alignItems: 'center' }}
|
||||
header={t('server.information.statuses')}
|
||||
content={
|
||||
instanceQuery.data?.stats?.status_count?.toString() ||
|
||||
undefined
|
||||
}
|
||||
content={instanceQuery.data?.stats?.status_count?.toString() || undefined}
|
||||
potentialWidth={4}
|
||||
/>
|
||||
<InstanceInfo
|
||||
style={{ alignItems: 'flex-end' }}
|
||||
header={t('server.information.domains')}
|
||||
content={
|
||||
instanceQuery.data?.stats?.domain_count?.toString() ||
|
||||
undefined
|
||||
}
|
||||
content={instanceQuery.data?.stats?.domain_count?.toString() || undefined}
|
||||
potentialWidth={4}
|
||||
/>
|
||||
</View>
|
||||
@ -248,17 +219,11 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.S}
|
||||
color={colors.secondary}
|
||||
style={{
|
||||
marginTop:
|
||||
(StyleConstants.Font.LineHeight.S -
|
||||
StyleConstants.Font.Size.S) /
|
||||
2,
|
||||
marginTop: (StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
}}
|
||||
/>
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ flex: 1, color: colors.secondary }}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ flex: 1, color: colors.secondary }}>
|
||||
{t('server.disclaimer.base')}
|
||||
</CustomText>
|
||||
</View>
|
||||
@ -274,10 +239,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
size={StyleConstants.Font.Size.S}
|
||||
color={colors.secondary}
|
||||
style={{
|
||||
marginTop:
|
||||
(StyleConstants.Font.LineHeight.S -
|
||||
StyleConstants.Font.Size.S) /
|
||||
2,
|
||||
marginTop: (StyleConstants.Font.LineHeight.S - StyleConstants.Font.Size.S) / 2,
|
||||
marginRight: StyleConstants.Spacing.XS
|
||||
}}
|
||||
/>
|
||||
@ -292,22 +254,14 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
<CustomText
|
||||
accessible
|
||||
style={{ color: colors.blue }}
|
||||
onPress={() => {
|
||||
analytics('view_privacy')
|
||||
WebBrowser.openBrowserAsync(
|
||||
'https://tooot.app/privacy-policy'
|
||||
)
|
||||
}}
|
||||
onPress={() => WebBrowser.openBrowserAsync('https://tooot.app/privacy-policy')}
|
||||
/>,
|
||||
<CustomText
|
||||
accessible
|
||||
style={{ color: colors.blue }}
|
||||
onPress={() => {
|
||||
analytics('view_tos')
|
||||
WebBrowser.openBrowserAsync(
|
||||
'https://tooot.app/terms-of-service'
|
||||
)
|
||||
}}
|
||||
onPress={() =>
|
||||
WebBrowser.openBrowserAsync('https://tooot.app/terms-of-service')
|
||||
}
|
||||
/>
|
||||
]}
|
||||
/>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import openLink from '@components/openLink'
|
||||
import ParseEmojis from '@components/Parse/Emojis'
|
||||
@ -63,7 +62,6 @@ const renderNode = ({
|
||||
lineHeight: adaptedLineheight
|
||||
}}
|
||||
onPress={() => {
|
||||
analytics('status_hashtag_press')
|
||||
!disableDetails &&
|
||||
differentTag &&
|
||||
navigation.push('Tab-Shared-Hashtag', {
|
||||
@ -89,7 +87,6 @@ const renderNode = ({
|
||||
lineHeight: adaptedLineheight
|
||||
}}
|
||||
onPress={() => {
|
||||
analytics('status_mention_press')
|
||||
accountIndex !== -1 &&
|
||||
!disableDetails &&
|
||||
differentAccount &&
|
||||
@ -118,7 +115,6 @@ const renderNode = ({
|
||||
lineHeight: adaptedLineheight
|
||||
}}
|
||||
onPress={async () => {
|
||||
analytics('status_link_press')
|
||||
if (!disableDetails) {
|
||||
if (shouldBeTag) {
|
||||
navigation.push('Tab-Shared-Hashtag', {
|
||||
@ -255,7 +251,6 @@ const ParseHTML = React.memo(
|
||||
<Pressable
|
||||
accessibilityLabel={t('HTML.accessibilityHint')}
|
||||
onPress={() => {
|
||||
analytics('status_readmore', { totalLines, expanded })
|
||||
layoutAnimation()
|
||||
setExpanded(!expanded)
|
||||
}}
|
||||
|
@ -1,11 +1,7 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import {
|
||||
QueryKeyRelationship,
|
||||
useRelationshipMutation
|
||||
} from '@utils/queryHooks/relationship'
|
||||
import { QueryKeyRelationship, useRelationshipMutation } from '@utils/queryHooks/relationship'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
@ -23,17 +19,12 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
||||
const queryKeyNotification: QueryKeyTimeline = [
|
||||
'Timeline',
|
||||
{ page: 'Notifications' }
|
||||
]
|
||||
const queryKeyNotification: QueryKeyTimeline = ['Timeline', { page: 'Notifications' }]
|
||||
const queryClient = useQueryClient()
|
||||
const mutation = useRelationshipMutation({
|
||||
onSuccess: res => {
|
||||
haptics('Success')
|
||||
queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [
|
||||
res
|
||||
])
|
||||
queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [res])
|
||||
queryClient.refetchQueries(queryKeyNotification)
|
||||
},
|
||||
onError: (err: any, { type }) => {
|
||||
@ -62,28 +53,26 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
||||
type='icon'
|
||||
content='X'
|
||||
loading={mutation.isLoading}
|
||||
onPress={() => {
|
||||
analytics('relationship_incoming_press_reject')
|
||||
onPress={() =>
|
||||
mutation.mutate({
|
||||
id,
|
||||
type: 'incoming',
|
||||
payload: { action: 'reject' }
|
||||
})
|
||||
}}
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
round
|
||||
type='icon'
|
||||
content='Check'
|
||||
loading={mutation.isLoading}
|
||||
onPress={() => {
|
||||
analytics('relationship_incoming_press_authorize')
|
||||
onPress={() =>
|
||||
mutation.mutate({
|
||||
id,
|
||||
type: 'incoming',
|
||||
payload: { action: 'authorize' }
|
||||
})
|
||||
}}
|
||||
}
|
||||
style={styles.approve}
|
||||
/>
|
||||
</View>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
@ -29,10 +28,7 @@ const RelationshipOutgoing = React.memo(
|
||||
const mutation = useRelationshipMutation({
|
||||
onSuccess: (res, { payload: { action } }) => {
|
||||
haptics('Success')
|
||||
queryClient.setQueryData<Mastodon.Relationship[]>(
|
||||
queryKeyRelationship,
|
||||
[res]
|
||||
)
|
||||
queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [res])
|
||||
if (action === 'block') {
|
||||
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Following' }]
|
||||
queryClient.invalidateQueries(queryKey)
|
||||
@ -64,17 +60,12 @@ const RelationshipOutgoing = React.memo(
|
||||
onPress = () => {}
|
||||
} else {
|
||||
if (query.data?.blocked_by) {
|
||||
analytics('relationship_outgoing_blocked_by')
|
||||
content = t('button.blocked_by')
|
||||
onPress = () => {
|
||||
analytics('relationship_outgoing_blocked_by_press')
|
||||
}
|
||||
onPress = () => {}
|
||||
} else {
|
||||
if (query.data?.blocking) {
|
||||
analytics('relationship_outgoing_blocking')
|
||||
content = t('button.blocking')
|
||||
onPress = () => {
|
||||
analytics('relationship_outgoing_blocking_press')
|
||||
mutation.mutate({
|
||||
id,
|
||||
type: 'outgoing',
|
||||
@ -86,10 +77,8 @@ const RelationshipOutgoing = React.memo(
|
||||
}
|
||||
} else {
|
||||
if (query.data?.following) {
|
||||
analytics('relationship_outgoing_following')
|
||||
content = t('button.following')
|
||||
onPress = () => {
|
||||
analytics('relationship_outgoing_following_press')
|
||||
mutation.mutate({
|
||||
id,
|
||||
type: 'outgoing',
|
||||
@ -101,10 +90,8 @@ const RelationshipOutgoing = React.memo(
|
||||
}
|
||||
} else {
|
||||
if (query.data?.requested) {
|
||||
analytics('relationship_outgoing_requested')
|
||||
content = t('button.requested')
|
||||
onPress = () => {
|
||||
analytics('relationship_outgoing_requested_press')
|
||||
mutation.mutate({
|
||||
id,
|
||||
type: 'outgoing',
|
||||
@ -115,10 +102,8 @@ const RelationshipOutgoing = React.memo(
|
||||
})
|
||||
}
|
||||
} else {
|
||||
analytics('relationship_outgoing_default')
|
||||
content = t('button.default')
|
||||
onPress = () => {
|
||||
analytics('relationship_outgoing_default_press')
|
||||
mutation.mutate({
|
||||
id,
|
||||
type: 'outgoing',
|
||||
|
@ -1,5 +1,4 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
@ -79,7 +78,6 @@ const TimelineConversation = React.memo(
|
||||
const navigation =
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
const onPress = useCallback(() => {
|
||||
analytics('timeline_conversation_press')
|
||||
if (conversation.last_status) {
|
||||
conversation.unread && mutate()
|
||||
navigation.push('Tab-Shared-Toot', {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import TimelineActioned from '@components/Timeline/Shared/Actioned'
|
||||
import TimelineActions from '@components/Timeline/Shared/Actions'
|
||||
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
||||
@ -17,7 +16,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { uniqBy } from 'lodash'
|
||||
import React, { useRef } from 'react'
|
||||
import { Platform, Pressable, StyleProp, View, ViewStyle } from 'react-native'
|
||||
import { Pressable, StyleProp, View, ViewStyle } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
import TimelineContextMenu from './Shared/ContextMenu'
|
||||
import TimelineFeedback from './Shared/Feedback'
|
||||
@ -29,7 +28,6 @@ export interface Props {
|
||||
item: Mastodon.Status & { _pinned?: boolean } // For account page, internal property
|
||||
queryKey?: QueryKeyTimeline
|
||||
rootQueryKey?: QueryKeyTimeline
|
||||
origin?: string
|
||||
highlighted?: boolean
|
||||
disableDetails?: boolean
|
||||
disableOnPress?: boolean
|
||||
@ -40,7 +38,6 @@ const TimelineDefault: React.FC<Props> = ({
|
||||
item,
|
||||
queryKey,
|
||||
rootQueryKey,
|
||||
origin,
|
||||
highlighted = false,
|
||||
disableDetails = false,
|
||||
disableOnPress = false
|
||||
@ -65,9 +62,6 @@ const TimelineDefault: React.FC<Props> = ({
|
||||
|
||||
const onPress = () => {
|
||||
if (highlighted) return
|
||||
analytics('timeline_default_press', {
|
||||
page: queryKey ? queryKey[1].page : origin
|
||||
})
|
||||
navigation.push('Tab-Shared-Toot', {
|
||||
toot: actualStatus,
|
||||
rootQueryKey: queryKey
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import Icon from '@components/Icon'
|
||||
import CustomText from '@components/Text'
|
||||
@ -27,20 +26,11 @@ const TimelineEmpty = React.memo(
|
||||
const children = () => {
|
||||
switch (status) {
|
||||
case 'loading':
|
||||
return (
|
||||
<Circle
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.secondary}
|
||||
/>
|
||||
)
|
||||
return <Circle size={StyleConstants.Font.Size.L} color={colors.secondary} />
|
||||
case 'error':
|
||||
return (
|
||||
<>
|
||||
<Icon
|
||||
name='Frown'
|
||||
size={StyleConstants.Font.Size.L}
|
||||
color={colors.primaryDefault}
|
||||
/>
|
||||
<Icon name='Frown' size={StyleConstants.Font.Size.L} color={colors.primaryDefault} />
|
||||
<CustomText
|
||||
fontStyle='M'
|
||||
style={{
|
||||
@ -51,14 +41,7 @@ const TimelineEmpty = React.memo(
|
||||
>
|
||||
{t('empty.error.message')}
|
||||
</CustomText>
|
||||
<Button
|
||||
type='text'
|
||||
content={t('empty.error.button')}
|
||||
onPress={() => {
|
||||
analytics('timeline_error_press_refetch')
|
||||
refetch()
|
||||
}}
|
||||
/>
|
||||
<Button type='text' content={t('empty.error.button')} onPress={() => refetch()} />
|
||||
</>
|
||||
)
|
||||
case 'success':
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import TimelineActioned from '@components/Timeline/Shared/Actioned'
|
||||
import TimelineActions from '@components/Timeline/Shared/Actions'
|
||||
import TimelineAttachment from '@components/Timeline/Shared/Attachment'
|
||||
@ -15,7 +14,7 @@ import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { getInstanceAccount } from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { isEqual, uniqBy } from 'lodash'
|
||||
import { uniqBy } from 'lodash'
|
||||
import React, { useCallback, useRef } from 'react'
|
||||
import { Platform, Pressable, View } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
@ -57,7 +56,6 @@ const TimelineNotifications: React.FC<Props> = ({
|
||||
const actualAccount = notification.status ? notification.status.account : notification.account
|
||||
|
||||
const onPress = useCallback(() => {
|
||||
analytics('timeline_notification_press')
|
||||
notification.status &&
|
||||
navigation.push('Tab-Shared-Toot', {
|
||||
toot: notification.status,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
@ -6,7 +5,7 @@ import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, StyleSheet, View } from 'react-native'
|
||||
|
||||
@ -20,8 +19,7 @@ const TimelineActioned = React.memo(
|
||||
({ account, action, notification = false }: Props) => {
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { colors } = useTheme()
|
||||
const navigation =
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
const name = account?.display_name || account?.username
|
||||
const iconColor = colors.primaryDefault
|
||||
|
||||
@ -29,10 +27,7 @@ const TimelineActioned = React.memo(
|
||||
<ParseEmojis content={content} emojis={account.emojis} size='S' />
|
||||
)
|
||||
|
||||
const onPress = useCallback(() => {
|
||||
analytics('timeline_shared_actioned_press', { action })
|
||||
navigation.push('Tab-Shared-Account', { account })
|
||||
}, [])
|
||||
const onPress = () => navigation.push('Tab-Shared-Account', { account })
|
||||
|
||||
const children = () => {
|
||||
switch (action) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import CustomText from '@components/Text'
|
||||
@ -84,18 +83,16 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}
|
||||
})
|
||||
|
||||
const onPressReply = useCallback(() => {
|
||||
analytics('timeline_shared_actions_reply_press', {
|
||||
page: queryKey[1].page,
|
||||
count: status.replies_count
|
||||
})
|
||||
navigation.navigate('Screen-Compose', {
|
||||
type: 'reply',
|
||||
incomingStatus: status,
|
||||
accts,
|
||||
queryKey
|
||||
})
|
||||
}, [status.replies_count])
|
||||
const onPressReply = useCallback(
|
||||
() =>
|
||||
navigation.navigate('Screen-Compose', {
|
||||
type: 'reply',
|
||||
incomingStatus: status,
|
||||
accts,
|
||||
queryKey
|
||||
}),
|
||||
[status.replies_count]
|
||||
)
|
||||
const { showActionSheetWithOptions } = useActionSheet()
|
||||
const onPressReblog = useCallback(() => {
|
||||
if (!status.reblogged) {
|
||||
@ -112,11 +109,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
(selectedIndex: number) => {
|
||||
switch (selectedIndex) {
|
||||
case 0:
|
||||
analytics('timeline_shared_actions_reblog_public_press', {
|
||||
page: queryKey[1].page,
|
||||
count: status.reblogs_count,
|
||||
current: status.reblogged
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -133,11 +125,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
})
|
||||
break
|
||||
case 1:
|
||||
analytics('timeline_shared_actions_reblog_unlisted_press', {
|
||||
page: queryKey[1].page,
|
||||
count: status.reblogs_count,
|
||||
current: status.reblogged
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -157,11 +144,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}
|
||||
)
|
||||
} else {
|
||||
analytics('timeline_shared_actions_reblog_press', {
|
||||
page: queryKey[1].page,
|
||||
count: status.reblogs_count,
|
||||
current: status.reblogged
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -179,11 +161,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
}
|
||||
}, [status.reblogged, status.reblogs_count])
|
||||
const onPressFavourite = useCallback(() => {
|
||||
analytics('timeline_shared_actions_favourite_press', {
|
||||
page: queryKey[1].page,
|
||||
count: status.favourites_count,
|
||||
current: status.favourited
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -199,10 +176,6 @@ const TimelineActions: React.FC<Props> = ({
|
||||
})
|
||||
}, [status.favourited, status.favourites_count])
|
||||
const onPressBookmark = useCallback(() => {
|
||||
analytics('timeline_shared_actions_bookmark_press', {
|
||||
page: queryKey[1].page,
|
||||
current: status.bookmarked
|
||||
})
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import AttachmentAudio from '@components/Timeline/Shared/Attachment/Audio'
|
||||
@ -195,7 +194,6 @@ const TimelineAttachment = React.memo(
|
||||
content={t('shared.attachment.sensitive.button')}
|
||||
overlay
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_attachment_blurview_press_show')
|
||||
layoutAnimation()
|
||||
setSensitiveShown(false)
|
||||
haptics('Light')
|
||||
@ -209,7 +207,6 @@ const TimelineAttachment = React.memo(
|
||||
round
|
||||
overlay
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_attachment_blurview_press_hide')
|
||||
setSensitiveShown(true)
|
||||
haptics('Light')
|
||||
}}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import { Slider } from '@sharcoux/slider'
|
||||
@ -25,7 +24,6 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
|
||||
const [audioPlaying, setAudioPlaying] = useState(false)
|
||||
const [audioPosition, setAudioPosition] = useState(0)
|
||||
const playAudio = useCallback(async () => {
|
||||
analytics('timeline_shared_attachment_audio_play_press', { id: audio.id })
|
||||
if (!audioPlayer) {
|
||||
const { sound } = await Audio.Sound.createAsync(
|
||||
{ uri: audio.url },
|
||||
@ -41,7 +39,6 @@ const AttachmentAudio: React.FC<Props> = ({ total, index, sensitiveShown, audio
|
||||
}
|
||||
}, [audioPlayer, audioPosition])
|
||||
const pauseAudio = useCallback(async () => {
|
||||
analytics('timeline_shared_attachment_audio_pause_press', { id: audio.id })
|
||||
audioPlayer!.pauseAsync()
|
||||
setAudioPlaying(false)
|
||||
}, [audioPlayer])
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import React from 'react'
|
||||
@ -34,27 +33,17 @@ const AttachmentImage = ({
|
||||
hidden={sensitiveShown}
|
||||
uri={{ original: image.preview_url, remote: image.remote_url }}
|
||||
blurhash={image.blurhash}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_attachment_image_press', {
|
||||
id: image.id
|
||||
})
|
||||
navigateToImagesViewer(image.id)
|
||||
}}
|
||||
onPress={() => navigateToImagesViewer(image.id)}
|
||||
style={{
|
||||
aspectRatio:
|
||||
total > 1 ||
|
||||
!image.meta?.original?.width ||
|
||||
!image.meta?.original?.height
|
||||
total > 1 || !image.meta?.original?.width || !image.meta?.original?.height
|
||||
? attachmentAspectRatio({ total, index })
|
||||
: image.meta.original.height / image.meta.original.width > 1
|
||||
? 1
|
||||
: image.meta.original.width / image.meta.original.height
|
||||
}}
|
||||
/>
|
||||
<AttachmentAltText
|
||||
sensitiveShown={sensitiveShown}
|
||||
text={image.description}
|
||||
/>
|
||||
<AttachmentAltText sensitiveShown={sensitiveShown} text={image.description} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
@ -18,12 +17,7 @@ export interface Props {
|
||||
attachment: Mastodon.AttachmentUnknown
|
||||
}
|
||||
|
||||
const AttachmentUnsupported: React.FC<Props> = ({
|
||||
total,
|
||||
index,
|
||||
sensitiveShown,
|
||||
attachment
|
||||
}) => {
|
||||
const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown, attachment }) => {
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { colors } = useTheme()
|
||||
|
||||
@ -55,9 +49,7 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
color: attachment.blurhash
|
||||
? colors.backgroundDefault
|
||||
: colors.primaryDefault
|
||||
color: attachment.blurhash ? colors.backgroundDefault : colors.primaryDefault
|
||||
}}
|
||||
>
|
||||
{t('shared.attachment.unsupported.text')}
|
||||
@ -69,17 +61,13 @@ const AttachmentUnsupported: React.FC<Props> = ({
|
||||
size='S'
|
||||
overlay
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_attachment_unsupported_press')
|
||||
attachment.remote_url && openLink(attachment.remote_url)
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
<AttachmentAltText
|
||||
sensitiveShown={sensitiveShown}
|
||||
text={attachment.description}
|
||||
/>
|
||||
<AttachmentAltText sensitiveShown={sensitiveShown} text={attachment.description} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { AppState, AppStateStatus, Pressable, View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import attachmentAspectRatio from './aspectRatio'
|
||||
import analytics from '@components/analytics'
|
||||
import AttachmentAltText from './AltText'
|
||||
import { Platform } from 'expo-modules-core'
|
||||
|
||||
@ -30,13 +29,6 @@ const AttachmentVideo: React.FC<Props> = ({
|
||||
const [videoPosition, setVideoPosition] = useState<number>(0)
|
||||
const [videoResizeMode, setVideoResizeMode] = useState<ResizeMode>(ResizeMode.COVER)
|
||||
const playOnPress = useCallback(async () => {
|
||||
analytics('timeline_shared_attachment_video_length', {
|
||||
length: video.meta?.length
|
||||
})
|
||||
analytics('timeline_shared_attachment_vide_play_press', {
|
||||
id: video.id,
|
||||
timestamp: Date.now()
|
||||
})
|
||||
setVideoLoading(true)
|
||||
if (!videoLoaded) {
|
||||
await videoPlayer.current?.loadAsync({ uri: video.url })
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
@ -14,43 +13,37 @@ export interface Props {
|
||||
highlighted: boolean
|
||||
}
|
||||
|
||||
const TimelineAvatar = React.memo(
|
||||
({ queryKey, account, highlighted }: Props) => {
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const navigation =
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
// Need to fix go back root
|
||||
const onPress = useCallback(() => {
|
||||
analytics('timeline_shared_avatar_press', {
|
||||
page: queryKey && queryKey[1].page
|
||||
})
|
||||
queryKey && navigation.push('Tab-Shared-Account', { account })
|
||||
}, [])
|
||||
const TimelineAvatar = React.memo(({ queryKey, account, highlighted }: Props) => {
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
// Need to fix go back root
|
||||
const onPress = useCallback(() => {
|
||||
queryKey && navigation.push('Tab-Shared-Account', { account })
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<GracefullyImage
|
||||
{...(highlighted && {
|
||||
accessibilityLabel: t('shared.avatar.accessibilityLabel', {
|
||||
name: account.display_name
|
||||
}),
|
||||
accessibilityHint: t('shared.avatar.accessibilityHint', {
|
||||
name: account.display_name
|
||||
})
|
||||
})}
|
||||
onPress={onPress}
|
||||
uri={{ original: account?.avatar, static: account?.avatar_static }}
|
||||
dimension={{
|
||||
width: StyleConstants.Avatar.M,
|
||||
height: StyleConstants.Avatar.M
|
||||
}}
|
||||
style={{
|
||||
borderRadius: StyleConstants.Avatar.M,
|
||||
overflow: 'hidden',
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
)
|
||||
return (
|
||||
<GracefullyImage
|
||||
{...(highlighted && {
|
||||
accessibilityLabel: t('shared.avatar.accessibilityLabel', {
|
||||
name: account.display_name
|
||||
}),
|
||||
accessibilityHint: t('shared.avatar.accessibilityHint', {
|
||||
name: account.display_name
|
||||
})
|
||||
})}
|
||||
onPress={onPress}
|
||||
uri={{ original: account?.avatar, static: account?.avatar_static }}
|
||||
dimension={{
|
||||
width: StyleConstants.Avatar.M,
|
||||
height: StyleConstants.Avatar.M
|
||||
}}
|
||||
style={{
|
||||
borderRadius: StyleConstants.Avatar.M,
|
||||
overflow: 'hidden',
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
export default TimelineAvatar
|
||||
|
@ -1,5 +1,4 @@
|
||||
import ComponentAccount from '@components/Account'
|
||||
import analytics from '@components/analytics'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
@ -130,10 +129,10 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||
)
|
||||
}
|
||||
if (isStatus && foundStatus) {
|
||||
return <TimelineDefault item={foundStatus} disableDetails disableOnPress origin='card' />
|
||||
return <TimelineDefault item={foundStatus} disableDetails disableOnPress />
|
||||
}
|
||||
if (isAccount && foundAccount) {
|
||||
return <ComponentAccount account={foundAccount} origin='card' />
|
||||
return <ComponentAccount account={foundAccount} />
|
||||
}
|
||||
return (
|
||||
<>
|
||||
@ -193,10 +192,7 @@ const TimelineCard = React.memo(({ card }: Props) => {
|
||||
overflow: 'hidden',
|
||||
borderColor: colors.border
|
||||
}}
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_card_press')
|
||||
await openLink(card.url, navigation)
|
||||
}}
|
||||
onPress={async () => await openLink(card.url, navigation)}
|
||||
children={cardContent}
|
||||
/>
|
||||
)
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import CustomText from '@components/Text'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
@ -11,10 +10,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { StyleSheet, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
status: Pick<
|
||||
Mastodon.Status,
|
||||
'id' | 'edited_at' | 'reblogs_count' | 'favourites_count'
|
||||
>
|
||||
status: Pick<Mastodon.Status, 'id' | 'edited_at' | 'reblogs_count' | 'favourites_count'>
|
||||
highlighted: boolean
|
||||
}
|
||||
|
||||
@ -26,8 +22,7 @@ const TimelineFeedback = React.memo(
|
||||
|
||||
const { t } = useTranslation('componentTimeline')
|
||||
const { colors } = useTheme()
|
||||
const navigation =
|
||||
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
|
||||
const { data } = useStatusHistory({
|
||||
id: status.id,
|
||||
@ -39,28 +34,20 @@ const TimelineFeedback = React.memo(
|
||||
<View style={{ flexDirection: 'row' }}>
|
||||
{status.reblogs_count > 0 ? (
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.reblogged_by.accessibilityLabel',
|
||||
{
|
||||
count: status.reblogs_count
|
||||
}
|
||||
)}
|
||||
accessibilityHint={t(
|
||||
'shared.actionsUsers.reblogged_by.accessibilityHint'
|
||||
)}
|
||||
accessibilityLabel={t('shared.actionsUsers.reblogged_by.accessibilityLabel', {
|
||||
count: status.reblogs_count
|
||||
})}
|
||||
accessibilityHint={t('shared.actionsUsers.reblogged_by.accessibilityHint')}
|
||||
accessibilityRole='button'
|
||||
style={[styles.text, { color: colors.blue }]}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_feedback_press_reblog', {
|
||||
count: status.reblogs_count
|
||||
})
|
||||
onPress={() =>
|
||||
navigation.push('Tab-Shared-Users', {
|
||||
reference: 'statuses',
|
||||
id: status.id,
|
||||
type: 'reblogged_by',
|
||||
count: status.reblogs_count
|
||||
})
|
||||
}}
|
||||
}
|
||||
>
|
||||
{t('shared.actionsUsers.reblogged_by.text', {
|
||||
count: status.reblogs_count
|
||||
@ -69,28 +56,20 @@ const TimelineFeedback = React.memo(
|
||||
) : null}
|
||||
{status.favourites_count > 0 ? (
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.favourited_by.accessibilityLabel',
|
||||
{
|
||||
count: status.reblogs_count
|
||||
}
|
||||
)}
|
||||
accessibilityHint={t(
|
||||
'shared.actionsUsers.favourited_by.accessibilityHint'
|
||||
)}
|
||||
accessibilityLabel={t('shared.actionsUsers.favourited_by.accessibilityLabel', {
|
||||
count: status.reblogs_count
|
||||
})}
|
||||
accessibilityHint={t('shared.actionsUsers.favourited_by.accessibilityHint')}
|
||||
accessibilityRole='button'
|
||||
style={[styles.text, { color: colors.blue }]}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_feedback_press_favourite', {
|
||||
count: status.favourites_count
|
||||
})
|
||||
onPress={() =>
|
||||
navigation.push('Tab-Shared-Users', {
|
||||
reference: 'statuses',
|
||||
id: status.id,
|
||||
type: 'favourited_by',
|
||||
count: status.favourites_count
|
||||
})
|
||||
}}
|
||||
}
|
||||
>
|
||||
{t('shared.actionsUsers.favourited_by.text', {
|
||||
count: status.favourites_count
|
||||
@ -101,23 +80,13 @@ const TimelineFeedback = React.memo(
|
||||
<View>
|
||||
{data && data.length > 1 ? (
|
||||
<CustomText
|
||||
accessibilityLabel={t(
|
||||
'shared.actionsUsers.history.accessibilityLabel',
|
||||
{
|
||||
count: data.length - 1
|
||||
}
|
||||
)}
|
||||
accessibilityHint={t(
|
||||
'shared.actionsUsers.history.accessibilityHint'
|
||||
)}
|
||||
accessibilityLabel={t('shared.actionsUsers.history.accessibilityLabel', {
|
||||
count: data.length - 1
|
||||
})}
|
||||
accessibilityHint={t('shared.actionsUsers.history.accessibilityHint')}
|
||||
accessibilityRole='button'
|
||||
style={[styles.text, { marginRight: 0, color: colors.blue }]}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_feedback_press_history', {
|
||||
count: data.length - 1
|
||||
})
|
||||
navigation.push('Tab-Shared-History', { id: status.id })
|
||||
}}
|
||||
onPress={() => navigation.push('Tab-Shared-History', { id: status.id })}
|
||||
>
|
||||
{t('shared.actionsUsers.history.text', {
|
||||
count: data.length - 1
|
||||
|
@ -1,15 +1,11 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Icon from '@components/Icon'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { ParseEmojis } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import {
|
||||
QueryKeyTimeline,
|
||||
useTimelineMutation
|
||||
} from '@utils/queryHooks/timeline'
|
||||
import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import { useQueryClient } from 'react-query'
|
||||
@ -71,27 +67,6 @@ const HeaderConversation = ({ queryKey, conversation }: Props) => {
|
||||
}
|
||||
})
|
||||
|
||||
const actionOnPress = useCallback(() => {
|
||||
analytics('timeline_conversation_delete_press')
|
||||
mutation.mutate({
|
||||
type: 'deleteItem',
|
||||
source: 'conversations',
|
||||
queryKey,
|
||||
id: conversation.id
|
||||
})
|
||||
}, [])
|
||||
|
||||
const actionChildren = useMemo(
|
||||
() => (
|
||||
<Icon
|
||||
name='Trash'
|
||||
color={colors.secondary}
|
||||
size={StyleConstants.Font.Size.L}
|
||||
/>
|
||||
),
|
||||
[]
|
||||
)
|
||||
|
||||
return (
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<View style={{ flex: 3 }}>
|
||||
@ -116,8 +91,15 @@ const HeaderConversation = ({ queryKey, conversation }: Props) => {
|
||||
|
||||
<Pressable
|
||||
style={{ flex: 1, flexDirection: 'row', justifyContent: 'center' }}
|
||||
onPress={actionOnPress}
|
||||
children={actionChildren}
|
||||
onPress={() =>
|
||||
mutation.mutate({
|
||||
type: 'deleteItem',
|
||||
source: 'conversations',
|
||||
queryKey,
|
||||
id: conversation.id
|
||||
})
|
||||
}
|
||||
children={<Icon name='Trash' color={colors.secondary} size={StyleConstants.Font.Size.L} />}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -20,9 +19,6 @@ const HeaderSharedApplication = React.memo(
|
||||
fontStyle='S'
|
||||
accessibilityRole='link'
|
||||
onPress={async () => {
|
||||
analytics('timeline_shared_header_application_press', {
|
||||
application
|
||||
})
|
||||
application.website && (await openLink(application.website))
|
||||
}}
|
||||
style={{
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import Icon from '@components/Icon'
|
||||
@ -40,9 +39,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
const { colors, theme } = useTheme()
|
||||
const { t, i18n } = useTranslation('componentTimeline')
|
||||
|
||||
const [allOptions, setAllOptions] = useState(
|
||||
new Array(poll.options.length).fill(false)
|
||||
)
|
||||
const [allOptions, setAllOptions] = useState(new Array(poll.options.length).fill(false))
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const mutation = useTimelineMutation({
|
||||
@ -86,8 +83,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
return (
|
||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_vote_press')
|
||||
onPress={() =>
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -101,7 +97,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
options: allOptions
|
||||
}
|
||||
})
|
||||
}}
|
||||
}
|
||||
type='text'
|
||||
content={t('shared.poll.meta.button.vote')}
|
||||
loading={mutation.isLoading}
|
||||
@ -113,8 +109,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
return (
|
||||
<View style={{ marginRight: StyleConstants.Spacing.S }}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_refresh_press')
|
||||
onPress={() =>
|
||||
mutation.mutate({
|
||||
type: 'updateStatusProperty',
|
||||
queryKey,
|
||||
@ -127,7 +122,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
type: 'refresh'
|
||||
}
|
||||
})
|
||||
}}
|
||||
}
|
||||
type='text'
|
||||
content={t('shared.poll.meta.button.refresh')}
|
||||
loading={mutation.isLoading}
|
||||
@ -136,14 +131,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [
|
||||
theme,
|
||||
i18n.language,
|
||||
poll.expired,
|
||||
poll.voted,
|
||||
allOptions,
|
||||
mutation.isLoading
|
||||
])
|
||||
}, [theme, i18n.language, poll.expired, poll.voted, allOptions, mutation.isLoading])
|
||||
|
||||
const isSelected = useCallback(
|
||||
(index: number): string =>
|
||||
@ -154,20 +142,13 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
)
|
||||
|
||||
const pollBodyDisallow = useMemo(() => {
|
||||
const maxValue = maxBy(
|
||||
poll.options,
|
||||
option => option.votes_count
|
||||
)?.votes_count
|
||||
const maxValue = maxBy(poll.options, option => option.votes_count)?.votes_count
|
||||
return poll.options.map((option, index) => (
|
||||
<View
|
||||
key={index}
|
||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||
>
|
||||
<View key={index} style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Icon
|
||||
style={{
|
||||
paddingTop:
|
||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={
|
||||
@ -176,9 +157,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
}` as any
|
||||
}
|
||||
size={StyleConstants.Font.Size.M}
|
||||
color={
|
||||
poll.own_votes?.includes(index) ? colors.blue : colors.disabled
|
||||
}
|
||||
color={poll.own_votes?.includes(index) ? colors.blue : colors.disabled}
|
||||
/>
|
||||
<CustomText style={{ flex: 1 }}>
|
||||
<ParseEmojis content={option.title} emojis={poll.emojis} />
|
||||
@ -194,11 +173,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{poll.votes_count
|
||||
? Math.round(
|
||||
(option.votes_count /
|
||||
(poll.voters_count || poll.votes_count)) *
|
||||
100
|
||||
)
|
||||
? Math.round((option.votes_count / (poll.voters_count || poll.votes_count)) * 100)
|
||||
: 0}
|
||||
%
|
||||
</CustomText>
|
||||
@ -213,11 +188,9 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
marginTop: StyleConstants.Spacing.XS,
|
||||
marginBottom: StyleConstants.Spacing.S,
|
||||
width: `${Math.round(
|
||||
(option.votes_count / (poll.voters_count || poll.votes_count)) *
|
||||
100
|
||||
(option.votes_count / (poll.voters_count || poll.votes_count)) * 100
|
||||
)}%`,
|
||||
backgroundColor:
|
||||
option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||
backgroundColor: option.votes_count === maxValue ? colors.blue : colors.disabled
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
@ -229,21 +202,15 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
key={index}
|
||||
style={{ flex: 1, paddingVertical: StyleConstants.Spacing.S }}
|
||||
onPress={() => {
|
||||
analytics('timeline_shared_vote_option_press')
|
||||
!allOptions[index] && haptics('Light')
|
||||
if (poll.multiple) {
|
||||
setAllOptions(allOptions.map((o, i) => (i === index ? !o : o)))
|
||||
} else {
|
||||
{
|
||||
const otherOptions =
|
||||
allOptions[index] === false ? false : undefined
|
||||
const otherOptions = allOptions[index] === false ? false : undefined
|
||||
setAllOptions(
|
||||
allOptions.map((o, i) =>
|
||||
i === index
|
||||
? !o
|
||||
: otherOptions !== undefined
|
||||
? otherOptions
|
||||
: o
|
||||
i === index ? !o : otherOptions !== undefined ? otherOptions : o
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -253,8 +220,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Icon
|
||||
style={{
|
||||
paddingTop:
|
||||
StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
paddingTop: StyleConstants.Font.LineHeight.M - StyleConstants.Font.Size.M,
|
||||
marginRight: StyleConstants.Spacing.S
|
||||
}}
|
||||
name={isSelected(index)}
|
||||
@ -271,13 +237,9 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
|
||||
const pollVoteCounts = () => {
|
||||
if (poll.voters_count !== null) {
|
||||
return (
|
||||
t('shared.poll.meta.count.voters', { count: poll.voters_count }) + ' • '
|
||||
)
|
||||
return t('shared.poll.meta.count.voters', { count: poll.voters_count }) + ' • '
|
||||
} else if (poll.votes_count !== null) {
|
||||
return (
|
||||
t('shared.poll.meta.count.votes', { count: poll.votes_count }) + ' • '
|
||||
)
|
||||
return t('shared.poll.meta.count.votes', { count: poll.votes_count }) + ' • '
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,10 +270,7 @@ const TimelinePoll: React.FC<Props> = ({
|
||||
}}
|
||||
>
|
||||
{pollButton}
|
||||
<CustomText
|
||||
fontStyle='S'
|
||||
style={{ flexShrink: 1, color: colors.secondary }}
|
||||
>
|
||||
<CustomText fontStyle='S' style={{ flexShrink: 1, color: colors.secondary }}>
|
||||
{pollVoteCounts()}
|
||||
{pollExpiration()}
|
||||
</CustomText>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import analytics from '@components/analytics'
|
||||
import { ParseHTML } from '@components/Parse'
|
||||
import CustomText from '@components/Text'
|
||||
import getLanguage from '@helpers/getLanguage'
|
||||
@ -85,15 +84,9 @@ const TimelineTranslate = React.memo(
|
||||
onPress={() => {
|
||||
if (enabled) {
|
||||
if (!isSuccess) {
|
||||
analytics('timeline_shared_translate_retry', {
|
||||
language: detectedLanguage
|
||||
})
|
||||
refetch()
|
||||
}
|
||||
} else {
|
||||
analytics('timeline_shared_translate', {
|
||||
language: detectedLanguage
|
||||
})
|
||||
setEnabled(true)
|
||||
}
|
||||
}}
|
||||
|
@ -1,7 +0,0 @@
|
||||
import * as Analytics from 'expo-firebase-analytics'
|
||||
|
||||
const analytics = (event: string, params?: { [key: string]: any }) => {
|
||||
Analytics.logEvent(event, params).catch(() => {})
|
||||
}
|
||||
|
||||
export default analytics
|
Reference in New Issue
Block a user