From 253ddee319e5587fc8c264b7452c68fc5c207482 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Sat, 30 Jan 2021 02:03:39 +0100 Subject: [PATCH] Android build success --- .gitignore | 1 + .../app/tooot/generated/BasePackageList.java | 37 ++++ android/gradle.properties | 7 +- app.config.ts | 22 --- src/components/Timelines/Timeline.tsx | 3 - .../Timeline/Shared/HeaderActions/Account.tsx | 130 ------------- .../Timeline/Shared/HeaderActions/Domain.tsx | 87 --------- .../Timeline/Shared/HeaderActions/Root.tsx | 110 ----------- .../Timeline/Shared/HeaderActions/Share.tsx | 49 ----- .../Timeline/Shared/HeaderActions/Status.tsx | 180 ------------------ .../Timeline/Shared/HeaderNotification.tsx | 50 ++++- src/screens/Actions.tsx | 2 +- 12 files changed, 86 insertions(+), 592 deletions(-) create mode 100644 android/app/src/main/java/com/xmflsct/app/tooot/generated/BasePackageList.java delete mode 100644 src/components/Timelines/Timeline/Shared/HeaderActions/Account.tsx delete mode 100644 src/components/Timelines/Timeline/Shared/HeaderActions/Domain.tsx delete mode 100644 src/components/Timelines/Timeline/Shared/HeaderActions/Root.tsx delete mode 100644 src/components/Timelines/Timeline/Shared/HeaderActions/Share.tsx delete mode 100644 src/components/Timelines/Timeline/Shared/HeaderActions/Status.tsx diff --git a/.gitignore b/.gitignore index 3c7af134..fb87d9ef 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ build/ .gradle local.properties *.iml +*.hprof # node.js # diff --git a/android/app/src/main/java/com/xmflsct/app/tooot/generated/BasePackageList.java b/android/app/src/main/java/com/xmflsct/app/tooot/generated/BasePackageList.java new file mode 100644 index 00000000..07f590fa --- /dev/null +++ b/android/app/src/main/java/com/xmflsct/app/tooot/generated/BasePackageList.java @@ -0,0 +1,37 @@ +package com.xmflsct.app.tooot.generated; + +import java.util.Arrays; +import java.util.List; +import org.unimodules.core.interfaces.Package; + +public class BasePackageList { + public List getPackageList() { + return Arrays.asList( + new expo.modules.application.ApplicationPackage(), + new expo.modules.av.AVPackage(), + new expo.modules.constants.ConstantsPackage(), + new expo.modules.crypto.CryptoPackage(), + new expo.modules.device.DevicePackage(), + new expo.modules.errorrecovery.ErrorRecoveryPackage(), + new expo.modules.filesystem.FileSystemPackage(), + new expo.modules.firebase.analytics.FirebaseAnalyticsPackage(), + new expo.modules.firebase.core.FirebaseCorePackage(), + new expo.modules.font.FontLoaderPackage(), + new expo.modules.haptics.HapticsPackage(), + new expo.modules.imageloader.ImageLoaderPackage(), + new expo.modules.imagepicker.ImagePickerPackage(), + new expo.modules.keepawake.KeepAwakePackage(), + new expo.modules.lineargradient.LinearGradientPackage(), + new expo.modules.localization.LocalizationPackage(), + new expo.modules.location.LocationPackage(), + new expo.modules.permissions.PermissionsPackage(), + new expo.modules.securestore.SecureStorePackage(), + new expo.modules.splashscreen.SplashScreenPackage(), + new expo.modules.sqlite.SQLitePackage(), + new expo.modules.storereview.StoreReviewPackage(), + new expo.modules.updates.UpdatesPackage(), + new expo.modules.videothumbnails.VideoThumbnailsPackage(), + new expo.modules.webbrowser.WebBrowserPackage() + ); + } +} diff --git a/android/gradle.properties b/android/gradle.properties index e75e6d33..ef77174e 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -26,4 +26,9 @@ android.useAndroidX=true android.enableJetifier=true # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.54.0 \ No newline at end of file +FLIPPER_VERSION=0.54.0 + +org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=4096m -XX:+HeapDumpOnOutOfMemoryError +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.configureondemand=true \ No newline at end of file diff --git a/app.config.ts b/app.config.ts index 4880dc5e..795d0306 100644 --- a/app.config.ts +++ b/app.config.ts @@ -36,15 +36,6 @@ export default (): ExpoConfig => ({ } ] }, - ios: { - buildNumber: '4', - config: { usesNonExemptEncryption: false }, - bundleIdentifier: 'com.xmflsct.app.tooot', - googleServicesFile: './configs/GoogleService-Info.plist', - infoPlist: { - CFBundleAllowMixedLocalizations: true - } - }, locales: { en: './src/i18n/en/system.json', zh: './src/i18n/zh-Hans/system.json' @@ -54,18 +45,5 @@ export default (): ExpoConfig => ({ package: 'com.xmflsct.app.tooot', googleServicesFile: './configs/google-services.json', permissions: ['CAMERA', 'VIBRATE'] - }, - web: { - config: { - firebase: { - apiKey: 'AIzaSyAnvo0jyD1WB0tv2FLenz-CSDS-RgaWWR4', - authDomain: 'xmflsct-mastodon-app.firebaseapp.com', - projectId: 'xmflsct-mastodon-app', - storageBucket: 'xmflsct-mastodon-app.appspot.com', - messagingSenderId: '661638997772', - appId: '1:661638997772:web:1e7aab28be7dc06d9f8b29', - measurementId: 'G-3J0FS8WV5J' - } - } } }) diff --git a/src/components/Timelines/Timeline.tsx b/src/components/Timelines/Timeline.tsx index acdd3f11..de194049 100644 --- a/src/components/Timelines/Timeline.tsx +++ b/src/components/Timelines/Timeline.tsx @@ -212,9 +212,6 @@ const Timeline: React.FC = ({ ListEmptyComponent={flItemEmptyComponent} {...(!disableRefresh && { refreshControl })} ItemSeparatorComponent={ItemSeparatorComponent} - {...(queryKey && - queryKey[1].page === 'RemotePublic' && - !publicRemoteNotice && { ListHeaderComponent })} {...(toot && isSuccess && { onScrollToIndexFailed })} maintainVisibleContentPosition={{ minIndexForVisible: 0, diff --git a/src/components/Timelines/Timeline/Shared/HeaderActions/Account.tsx b/src/components/Timelines/Timeline/Shared/HeaderActions/Account.tsx deleted file mode 100644 index 4799c691..00000000 --- a/src/components/Timelines/Timeline/Shared/HeaderActions/Account.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import analytics from '@components/analytics' -import haptics from '@components/haptics' -import { MenuContainer, MenuHeader, MenuRow } from '@components/Menu' -import { toast } from '@components/toast' -import { - MutationVarsTimelineUpdateAccountProperty, - QueryKeyTimeline, - useTimelineMutation -} from '@utils/queryHooks/timeline' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { useQueryClient } from 'react-query' - -export interface Props { - queryKey?: QueryKeyTimeline - account: Mastodon.Account - setBottomSheetVisible: React.Dispatch> -} - -const HeaderActionsAccount: React.FC = ({ - queryKey, - account, - setBottomSheetVisible -}) => { - const { t } = useTranslation('componentTimeline') - - const queryClient = useQueryClient() - const mutateion = useTimelineMutation({ - queryClient, - onSuccess: (_, params) => { - const theParams = params as MutationVarsTimelineUpdateAccountProperty - haptics('Success') - toast({ - type: 'success', - message: t('common:toastMessage.success.message', { - function: t( - `shared.header.actions.account.${theParams.payload.property}.function`, - { - acct: account.acct - } - ) - }) - }) - }, - onError: (err: any, params) => { - const theParams = params as MutationVarsTimelineUpdateAccountProperty - haptics('Error') - toast({ - type: 'error', - message: t('common:toastMessage.error.message', { - function: t( - `shared.header.actions.account.${theParams.payload.property}.function` - ) - }), - ...(err.status && - typeof err.status === 'number' && - err.data && - err.data.error && - typeof err.data.error === 'string' && { - description: err.data.error - }) - }) - }, - onSettled: () => { - queryKey && queryClient.invalidateQueries(queryKey) - } - }) - - return ( - - - { - analytics('timeline_shared_headeractions_account_mute_press', { - page: queryKey && queryKey[1].page - }) - setBottomSheetVisible(false) - mutateion.mutate({ - type: 'updateAccountProperty', - queryKey, - id: account.id, - payload: { property: 'mute' } - }) - }} - iconFront='EyeOff' - title={t('shared.header.actions.account.mute.button', { - acct: account.acct - })} - /> - { - analytics('timeline_shared_headeractions_account_block_press', { - page: queryKey && queryKey[1].page - }) - setBottomSheetVisible(false) - mutateion.mutate({ - type: 'updateAccountProperty', - queryKey, - id: account.id, - payload: { property: 'block' } - }) - }} - iconFront='XCircle' - title={t('shared.header.actions.account.block.button', { - acct: account.acct - })} - /> - { - analytics('timeline_shared_headeractions_account_reports_press', { - page: queryKey && queryKey[1].page - }) - setBottomSheetVisible(false) - mutateion.mutate({ - type: 'updateAccountProperty', - queryKey, - id: account.id, - payload: { property: 'reports' } - }) - }} - iconFront='Flag' - title={t('shared.header.actions.account.reports.button', { - acct: account.acct - })} - /> - - ) -} - -export default HeaderActionsAccount diff --git a/src/components/Timelines/Timeline/Shared/HeaderActions/Domain.tsx b/src/components/Timelines/Timeline/Shared/HeaderActions/Domain.tsx deleted file mode 100644 index 075af33e..00000000 --- a/src/components/Timelines/Timeline/Shared/HeaderActions/Domain.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import analytics from '@components/analytics' -import MenuContainer from '@components/Menu/Container' -import MenuHeader from '@components/Menu/Header' -import MenuRow from '@components/Menu/Row' -import { toast } from '@components/toast' -import { - QueryKeyTimeline, - useTimelineMutation -} from '@utils/queryHooks/timeline' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { Alert } from 'react-native' -import { useQueryClient } from 'react-query' - -export interface Props { - queryKey: QueryKeyTimeline - domain: string - setBottomSheetVisible: React.Dispatch> -} - -const HeaderActionsDomain: React.FC = ({ - queryKey, - domain, - setBottomSheetVisible -}) => { - const { t } = useTranslation('componentTimeline') - const queryClient = useQueryClient() - const mutation = useTimelineMutation({ - queryClient, - onSettled: () => { - toast({ - type: 'success', - message: t('common:toastMessage.success.message', { - function: t(`shared.header.actions.domain.block.function`) - }) - }) - queryClient.invalidateQueries(queryKey) - } - }) - - return ( - - - { - analytics('timeline_shared_headeractions_domain_block_press', { - page: queryKey[1].page - }) - Alert.alert( - t('shared.header.actions.domain.alert.title', { domain }), - t('shared.header.actions.domain.alert.message'), - [ - { - text: t('shared.header.actions.domain.alert.buttons.cancel'), - style: 'cancel' - }, - { - text: t('shared.header.actions.domain.alert.buttons.confirm'), - style: 'destructive', - onPress: () => { - analytics( - 'timeline_shared_headeractions_domain_block_confirm', - { - page: queryKey && queryKey[1].page - } - ) - setBottomSheetVisible(false) - mutation.mutate({ - type: 'domainBlock', - queryKey, - domain: domain - }) - } - } - ] - ) - }} - iconFront='CloudOff' - title={t(`shared.header.actions.domain.block.button`, { - domain - })} - /> - - ) -} - -export default HeaderActionsDomain diff --git a/src/components/Timelines/Timeline/Shared/HeaderActions/Root.tsx b/src/components/Timelines/Timeline/Shared/HeaderActions/Root.tsx deleted file mode 100644 index 24da7c0c..00000000 --- a/src/components/Timelines/Timeline/Shared/HeaderActions/Root.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import analytics from '@components/analytics' -import BottomSheet from '@screens/Tabs/Shared/node_modules/@screens/Actions/BottomSheet' -import Icon from '@components/Icon' -import { QueryKeyTimeline } from '@utils/queryHooks/timeline' -import { getLocalAccount, getLocalUrl } from '@utils/slices/instancesSlice' -import { StyleConstants } from '@utils/styles/constants' -import { useTheme } from '@utils/styles/ThemeManager' -import React, { useCallback, useMemo, useState } from 'react' -import { Pressable, StyleSheet } from 'react-native' -import { useSelector } from 'react-redux' -import HeaderActionsAccount from './Account' -import HeaderActionsDomain from './Domain' -import HeaderActionsShare from './Share' -import HeaderActionsStatus from './Status' - -export interface Props { - queryKey: QueryKeyTimeline - status: Mastodon.Status - url?: string - type?: 'status' | 'account' -} - -const HeaderActions = React.memo( - ({ queryKey, status, url, type }: Props) => { - const { theme } = useTheme() - - const localAccount = useSelector(getLocalAccount) - const sameAccount = localAccount?.id === status.account.id - - const localDomain = useSelector(getLocalUrl) - const statusDomain = status.uri - ? status.uri.split(new RegExp(/\/\/(.*?)\//))[1] - : '' - const sameDomain = localDomain === statusDomain - - const [modalVisible, setBottomSheetVisible] = useState(false) - const onPress = useCallback(() => { - analytics('bottomsheet_open_press', { - page: queryKey[1].page - }) - setBottomSheetVisible(true) - }, []) - const children = useMemo( - () => ( - - ), - [] - ) - - return ( - <> - - {modalVisible && ( - setBottomSheetVisible(false)} - > - {!sameAccount && ( - - )} - - {sameAccount && ( - - )} - - {!sameDomain && ( - - )} - - {url && type ? ( - - ) : null} - - )} - - ) - }, - () => true -) - -const styles = StyleSheet.create({ - base: { - flex: 1, - flexDirection: 'row', - justifyContent: 'center', - paddingBottom: StyleConstants.Spacing.S - } -}) - -export default HeaderActions diff --git a/src/components/Timelines/Timeline/Shared/HeaderActions/Share.tsx b/src/components/Timelines/Timeline/Shared/HeaderActions/Share.tsx deleted file mode 100644 index 2ca96ec9..00000000 --- a/src/components/Timelines/Timeline/Shared/HeaderActions/Share.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import analytics from '@components/analytics' -import MenuContainer from '@components/Menu/Container' -import MenuHeader from '@components/Menu/Header' -import MenuRow from '@components/Menu/Row' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { Platform, Share } from 'react-native' - -export interface Props { - type: 'status' | 'account' - url: string - setBottomSheetVisible: React.Dispatch> -} - -const HeaderActionsShare: React.FC = ({ - type, - url, - setBottomSheetVisible -}) => { - const { t } = useTranslation('componentTimeline') - - return ( - - - { - analytics('timeline_shared_headeractions_share_press') - switch (Platform.OS) { - case 'ios': - await Share.share({ - url - }) - break - case 'android': - await Share.share({ - message: url - }) - break - } - setBottomSheetVisible(false) - }} - /> - - ) -} - -export default HeaderActionsShare diff --git a/src/components/Timelines/Timeline/Shared/HeaderActions/Status.tsx b/src/components/Timelines/Timeline/Shared/HeaderActions/Status.tsx deleted file mode 100644 index 379e7a3d..00000000 --- a/src/components/Timelines/Timeline/Shared/HeaderActions/Status.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import React from 'react' -import { useTranslation } from 'react-i18next' -import { Alert } from 'react-native' -import { useQueryClient } from 'react-query' -import { MenuContainer, MenuHeader, MenuRow } from '@components/Menu' -import { toast } from '@components/toast' -import { useNavigation } from '@react-navigation/native' -import { - MutationVarsTimelineUpdateStatusProperty, - QueryKeyTimeline, - useTimelineMutation -} from '@utils/queryHooks/timeline' -import analytics from '@components/analytics' - -export interface Props { - queryKey: QueryKeyTimeline - status: Mastodon.Status - setBottomSheetVisible: React.Dispatch> -} - -const HeaderActionsStatus: React.FC = ({ - queryKey, - status, - setBottomSheetVisible -}) => { - const navigation = useNavigation() - const { t } = useTranslation('componentTimeline') - - const queryClient = useQueryClient() - const mutation = useTimelineMutation({ - queryClient, - onMutate: true, - onError: (err: any, params, oldData) => { - const theFunction = (params as MutationVarsTimelineUpdateStatusProperty) - .payload - ? (params as MutationVarsTimelineUpdateStatusProperty).payload.property - : 'delete' - toast({ - type: 'error', - message: t('common:toastMessage.error.message', { - function: t(`shared.header.actions.status.${theFunction}.function`) - }), - ...(err.status && - typeof err.status === 'number' && - err.data && - err.data.error && - typeof err.data.error === 'string' && { - description: err.data.error - }) - }) - queryClient.setQueryData(queryKey, oldData) - } - }) - - return ( - - - { - analytics('timeline_shared_headeractions_status_delete_press', { - page: queryKey && queryKey[1].page - }) - setBottomSheetVisible(false) - mutation.mutate({ - type: 'deleteItem', - source: 'statuses', - queryKey, - id: status.id - }) - }} - iconFront='Trash' - title={t('shared.header.actions.status.delete.button')} - /> - { - analytics('timeline_shared_headeractions_status_deleteedit_press', { - page: queryKey && queryKey[1].page - }) - Alert.alert( - t('shared.header.actions.status.edit.alert.title'), - t('shared.header.actions.status.edit.alert.message'), - [ - { - text: t( - 'shared.header.actions.status.edit.alert.buttons.cancel' - ), - style: 'cancel' - }, - { - text: t( - 'shared.header.actions.status.edit.alert.buttons.confirm' - ), - style: 'destructive', - onPress: async () => { - analytics( - 'timeline_shared_headeractions_status_deleteedit_confirm', - { - page: queryKey && queryKey[1].page - } - ) - setBottomSheetVisible(false) - const res = await mutation.mutateAsync({ - type: 'deleteItem', - source: 'statuses', - queryKey, - id: status.id - }) - if (res.id) { - navigation.navigate('Screen-Compose', { - type: 'edit', - incomingStatus: res, - queryKey - }) - } - } - } - ] - ) - }} - iconFront='Edit' - title={t('shared.header.actions.status.edit.button')} - /> - { - analytics('timeline_shared_headeractions_status_mute_press', { - page: queryKey && queryKey[1].page - }) - setBottomSheetVisible(false) - mutation.mutate({ - type: 'updateStatusProperty', - queryKey, - id: status.id, - payload: { - property: 'muted', - currentValue: status.muted, - propertyCount: undefined, - countValue: undefined - } - }) - }} - iconFront='VolumeX' - title={ - status.muted - ? t('shared.header.actions.status.mute.button.negative') - : t('shared.header.actions.status.mute.button.positive') - } - /> - {/* Also note that reblogs cannot be pinned. */} - {(status.visibility === 'public' || status.visibility === 'unlisted') && ( - { - analytics('timeline_shared_headeractions_status_pin_press', { - page: queryKey && queryKey[1].page - }) - setBottomSheetVisible(false) - mutation.mutate({ - type: 'updateStatusProperty', - queryKey, - id: status.id, - payload: { - property: 'pinned', - currentValue: status.pinned, - propertyCount: undefined, - countValue: undefined - } - }) - }} - iconFront='Anchor' - title={ - status.pinned - ? t('shared.header.actions.status.pin.button.negative') - : t('shared.header.actions.status.pin.button.positive') - } - /> - )} - - ) -} - -export default HeaderActionsStatus diff --git a/src/components/Timelines/Timeline/Shared/HeaderNotification.tsx b/src/components/Timelines/Timeline/Shared/HeaderNotification.tsx index e83fc52c..338edab4 100644 --- a/src/components/Timelines/Timeline/Shared/HeaderNotification.tsx +++ b/src/components/Timelines/Timeline/Shared/HeaderNotification.tsx @@ -1,15 +1,19 @@ -import { RelationshipOutgoing } from '@components/Relationship' +import Icon from '@components/Icon' +import { + RelationshipIncoming, + RelationshipOutgoing +} from '@components/Relationship' +import { useNavigation } from '@react-navigation/native' +import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { StyleConstants } from '@utils/styles/constants' +import { useTheme } from '@utils/styles/ThemeManager' import React, { useMemo } from 'react' -import { StyleSheet, View } from 'react-native' +import { Pressable, StyleSheet, View } from 'react-native' import HeaderSharedAccount from './HeaderShared/Account' import HeaderSharedApplication from './HeaderShared/Application' import HeaderSharedCreated from './HeaderShared/Created' -import HeaderSharedVisibility from './HeaderShared/Visibility' -import RelationshipIncoming from '@root/components/Relationship/Incoming' import HeaderSharedMuted from './HeaderShared/Muted' -import { QueryKeyTimeline } from '@utils/queryHooks/timeline' -import ScreenActions from '@screens/Actions' +import HeaderSharedVisibility from './HeaderShared/Visibility' export interface Props { queryKey: QueryKeyTimeline @@ -20,6 +24,9 @@ const TimelineHeaderNotification: React.FC = ({ queryKey, notification }) => { + const navigation = useNavigation() + const { theme } = useTheme() + const actions = useMemo(() => { switch (notification.type) { case 'follow': @@ -27,11 +34,36 @@ const TimelineHeaderNotification: React.FC = ({ case 'follow_request': return default: - return notification.status ? ( - - ) : null + if (notification.status) { + return ( + + navigation.navigate('Screen-Actions', { + queryKey, + status, + url: notification.status?.url || notification.status?.uri, + type: 'status' + }) + } + children={ + + } + /> + ) + } } }, [notification.type]) + return ( )} - {sameAccount && ( + {sameAccount && status && (