From c75ecefb09e3312a7faf14bb031c44b2e448bd25 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 31 Oct 2022 21:54:24 +0100 Subject: [PATCH 1/4] Fixed #424 --- src/components/Relationship/Outgoing.tsx | 2 +- src/components/Timeline/Shared/Actions.tsx | 78 +++++----------------- src/screens/Compose.tsx | 4 +- 3 files changed, 17 insertions(+), 67 deletions(-) diff --git a/src/components/Relationship/Outgoing.tsx b/src/components/Relationship/Outgoing.tsx index 13c9b229..123ac90d 100644 --- a/src/components/Relationship/Outgoing.tsx +++ b/src/components/Relationship/Outgoing.tsx @@ -33,7 +33,7 @@ const RelationshipOutgoing = React.memo( queryKeyRelationship, [res] ) - if (action === 'follow' || action === 'block') { + if (action === 'block') { const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Following' }] queryClient.invalidateQueries(queryKey) } diff --git a/src/components/Timeline/Shared/Actions.tsx b/src/components/Timeline/Shared/Actions.tsx index 654c47ec..ddf1fdd3 100644 --- a/src/components/Timeline/Shared/Actions.tsx +++ b/src/components/Timeline/Shared/Actions.tsx @@ -48,40 +48,18 @@ const TimelineActions: React.FC = ({ const theParams = params as MutationVarsTimelineUpdateStatusProperty if ( // Un-bookmark from bookmarks page - (queryKey[1].page === 'Bookmarks' && - theParams.payload.property === 'bookmarked') || + (queryKey[1].page === 'Bookmarks' && theParams.payload.property === 'bookmarked') || // Un-favourite from favourites page - (queryKey[1].page === 'Favourites' && - theParams.payload.property === 'favourited') || - // Un-reblog from following page - (queryKey[1].page === 'Following' && - theParams.payload.property === 'reblogged' && - theParams.payload.currentValue === true) + (queryKey[1].page === 'Favourites' && theParams.payload.property === 'favourited') ) { queryClient.invalidateQueries(queryKey) - } else if ( - theParams.payload.property === 'reblogged' && - queryKey[1].page !== 'Following' - ) { - // When reblogged, update cache of following page - const tempQueryKey: QueryKeyTimeline = [ - 'Timeline', - { page: 'Following' } - ] - queryClient.invalidateQueries(tempQueryKey) } else if (theParams.payload.property === 'favourited') { // When favourited, update favourited page - const tempQueryKey: QueryKeyTimeline = [ - 'Timeline', - { page: 'Favourites' } - ] + const tempQueryKey: QueryKeyTimeline = ['Timeline', { page: 'Favourites' }] queryClient.invalidateQueries(tempQueryKey) } else if (theParams.payload.property === 'bookmarked') { // When bookmarked, update bookmark page - const tempQueryKey: QueryKeyTimeline = [ - 'Timeline', - { page: 'Bookmarks' } - ] + const tempQueryKey: QueryKeyTimeline = ['Timeline', { page: 'Bookmarks' }] queryClient.invalidateQueries(tempQueryKey) } }, @@ -91,9 +69,7 @@ const TimelineActions: React.FC = ({ theme, type: 'error', message: t('common:message.error.message', { - function: t( - `shared.actions.${correctParam.payload.property}.function` - ) + function: t(`shared.actions.${correctParam.payload.property}.function`) }), ...(err.status && typeof err.status === 'number' && @@ -182,11 +158,7 @@ const TimelineActions: React.FC = ({ const childrenReply = useMemo( () => ( <> - + {status.replies_count > 0 ? ( = ({ = ({ const color = (state: boolean) => (state ? colors.red : colors.secondary) return ( <> - + {status.favourites_count > 0 ? ( = ({ const childrenBookmark = useMemo(() => { const color = (state: boolean) => (state ? colors.yellow : colors.secondary) return ( - + ) }, [status.bookmarked]) return ( = ({ = ({ onPress={onPressReblog} children={childrenReblog} disabled={ - status.visibility === 'direct' || - (status.visibility === 'private' && !ownAccount) + status.visibility === 'direct' || (status.visibility === 'private' && !ownAccount) } /> = ({ > = ({ } else { dispatch(updateStoreReview(1)) } - const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Following' }] - queryClient.invalidateQueries(queryKey) switch (params?.type) { case 'edit': From 4f22e4bd78a3b62cfd6c9c8e2de99447fd7dca96 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 31 Oct 2022 22:15:51 +0100 Subject: [PATCH 2/4] Fixed #425 --- src/components/ContextMenu/account.ts | 57 ++++++++++++++++++++------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/components/ContextMenu/account.ts b/src/components/ContextMenu/account.ts index 02b851b5..53a9aa44 100644 --- a/src/components/ContextMenu/account.ts +++ b/src/components/ContextMenu/account.ts @@ -9,6 +9,7 @@ import { import { getInstanceAccount } from '@utils/slices/instancesSlice' import { useTheme } from '@utils/styles/ThemeManager' import { useTranslation } from 'react-i18next' +import { Platform } from 'react-native' import { ContextMenuAction } from 'react-native-context-menu-view' import { useQueryClient } from 'react-query' import { useSelector } from 'react-redux' @@ -94,22 +95,50 @@ const contextMenuAccount = ({ context: (relationship?.muting || false).toString() }), systemIcon: 'eye.slash' - }, - { - id: 'account-block', - title: t('account.block.action', { - context: (relationship?.blocking || false).toString() - }), - systemIcon: 'xmark.circle', - destructive: true - }, - { - id: 'account-reports', - title: t('account.reports.action'), - systemIcon: 'flag', - destructive: true } ) + switch (Platform.OS) { + case 'ios': + actions.push({ + id: 'account', + title: t('account.title'), + actions: [ + { + id: 'account-block', + title: t('account.block.action', { + context: (relationship?.blocking || false).toString() + }), + systemIcon: 'xmark.circle', + destructive: true + }, + { + id: 'account-reports', + title: t('account.reports.action'), + systemIcon: 'flag', + destructive: true + } + ] + }) + break + default: + actions.push( + { + id: 'account-block', + title: t('account.block.action', { + context: (relationship?.blocking || false).toString() + }), + systemIcon: 'xmark.circle', + destructive: true + }, + { + id: 'account-reports', + title: t('account.reports.action'), + systemIcon: 'flag', + destructive: true + } + ) + break + } } return (index: number) => { From fa0d28acd1e66a1a8c791cc7216c0fb84c3ac2c0 Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 31 Oct 2022 22:29:45 +0100 Subject: [PATCH 3/4] Fixed #426 --- src/components/Emojis/List.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/Emojis/List.tsx b/src/components/Emojis/List.tsx index 0ccb2c55..bf3d2281 100644 --- a/src/components/Emojis/List.tsx +++ b/src/components/Emojis/List.tsx @@ -54,9 +54,6 @@ const EmojisList = () => { const addedLength = spaceFront.length + shortcode.length + spaceRear.length setSelection({ start: selection.start + addedLength }) - ref?.current?.setNativeProps({ - selection: { start: selection.start + addedLength } - }) } const listItem = ({ index, item }: { item: Mastodon.Emoji[]; index: number }) => { From cc3d5b14e5a8092d72cf2a806f08885b34d2c04b Mon Sep 17 00:00:00 2001 From: xmflsct Date: Mon, 31 Oct 2022 23:43:42 +0100 Subject: [PATCH 4/4] Fixed #427 --- src/components/Timeline/Shared/Actions.tsx | 99 ++++++++++++++++++---- src/i18n/en/components/timeline.json | 7 +- src/utils/queryHooks/timeline.ts | 16 +++- 3 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/components/Timeline/Shared/Actions.tsx b/src/components/Timeline/Shared/Actions.tsx index ddf1fdd3..46e98e1b 100644 --- a/src/components/Timeline/Shared/Actions.tsx +++ b/src/components/Timeline/Shared/Actions.tsx @@ -2,6 +2,7 @@ import analytics from '@components/analytics' import Icon from '@components/Icon' import { displayMessage } from '@components/Message' import CustomText from '@components/Text' +import { useActionSheet } from '@expo/react-native-action-sheet' import { useNavigation } from '@react-navigation/native' import { StackNavigationProp } from '@react-navigation/stack' import { RootStackParamList } from '@utils/navigation/navigators' @@ -95,25 +96,87 @@ const TimelineActions: React.FC = ({ queryKey }) }, [status.replies_count]) + const { showActionSheetWithOptions } = useActionSheet() const onPressReblog = useCallback(() => { - analytics('timeline_shared_actions_reblog_press', { - page: queryKey[1].page, - count: status.reblogs_count, - current: status.reblogged - }) - mutation.mutate({ - type: 'updateStatusProperty', - queryKey, - rootQueryKey, - id: status.id, - reblog, - payload: { - property: 'reblogged', - currentValue: status.reblogged, - propertyCount: 'reblogs_count', - countValue: status.reblogs_count - } - }) + if (!status.reblogged) { + showActionSheetWithOptions( + { + title: t('shared.actions.reblogged.options.title'), + options: [ + t('shared.actions.reblogged.options.public'), + t('shared.actions.reblogged.options.unlisted'), + t('common:buttons.cancel') + ], + cancelButtonIndex: 2 + }, + (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, + rootQueryKey, + id: status.id, + reblog, + payload: { + property: 'reblogged', + currentValue: status.reblogged, + propertyCount: 'reblogs_count', + countValue: status.reblogs_count, + visibility: 'public' + } + }) + 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, + rootQueryKey, + id: status.id, + reblog, + payload: { + property: 'reblogged', + currentValue: status.reblogged, + propertyCount: 'reblogs_count', + countValue: status.reblogs_count, + visibility: 'unlisted' + } + }) + break + } + } + ) + } else { + analytics('timeline_shared_actions_reblog_press', { + page: queryKey[1].page, + count: status.reblogs_count, + current: status.reblogged + }) + mutation.mutate({ + type: 'updateStatusProperty', + queryKey, + rootQueryKey, + id: status.id, + reblog, + payload: { + property: 'reblogged', + currentValue: status.reblogged, + propertyCount: 'reblogs_count', + countValue: status.reblogs_count, + visibility: 'public' + } + }) + } }, [status.reblogged, status.reblogs_count]) const onPressFavourite = useCallback(() => { analytics('timeline_shared_actions_favourite_press', { diff --git a/src/i18n/en/components/timeline.json b/src/i18n/en/components/timeline.json index 066eade6..6ae14037 100644 --- a/src/i18n/en/components/timeline.json +++ b/src/i18n/en/components/timeline.json @@ -38,7 +38,12 @@ }, "reblogged": { "accessibilityLabel": "Boost this toot", - "function": "Boost toot" + "function": "Boost toot", + "options": { + "title": "Choose boost visibility", + "public": "Public boost", + "unlisted": "Unlist boost" + } }, "favourited": { "accessibilityLabel": "Add this toot to favourites", diff --git a/src/utils/queryHooks/timeline.ts b/src/utils/queryHooks/timeline.ts index d7e1b131..440969e9 100644 --- a/src/utils/queryHooks/timeline.ts +++ b/src/utils/queryHooks/timeline.ts @@ -293,11 +293,18 @@ export type MutationVarsTimelineUpdateStatusProperty = { countValue: undefined } | { - property: 'favourited' | 'reblogged' + property: 'favourited' currentValue: boolean propertyCount: 'favourites_count' | 'reblogs_count' countValue: number } + | { + property: 'reblogged' + currentValue: boolean + propertyCount: 'favourites_count' | 'reblogs_count' + countValue: number + visibility: 'public' | 'unlisted' + } | { property: 'poll' id: Mastodon.Poll['id'] @@ -371,11 +378,16 @@ const mutationFunction = async (params: MutationVarsTimeline) => { ...(params.payload.type === 'vote' && { body: formData }) }) default: + const body = new FormData() + if (params.payload.property === 'reblogged') { + body.append('visibility', params.payload.visibility) + } return apiInstance({ method: 'post', url: `statuses/${params.id}/${ params.payload.currentValue ? 'un' : '' - }${MapPropertyToUrl[params.payload.property]}` + }${MapPropertyToUrl[params.payload.property]}`, + body }) } case 'updateAccountProperty':