diff --git a/README.md b/README.md
index 34d1f97c..d88717bc 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# [tooot](https://tooot.app/) app for Mastodon
+# [tooot](https://tooot.app/) app for Mastodon compatible platforms
[![GPL-3.0](https://img.shields.io/github/license/tooot-app/push)](LICENSE) ![GitHub issues](https://img.shields.io/github/issues/tooot-app/app) ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/tooot-app/app?include_prereleases) [![Crowdin](https://badges.crowdin.net/tooot/localized.svg)](https://crowdin.tooot.app/project/tooot)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 947ce178..6411e770 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,4 +1,5 @@
apply plugin: "com.android.application"
+apply plugin: 'com.google.gms.google-services'
import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os
diff --git a/android/app/google-services.json b/android/app/google-services.json
new file mode 100644
index 00000000..9d9e3d20
--- /dev/null
+++ b/android/app/google-services.json
@@ -0,0 +1,55 @@
+{
+ "project_info": {
+ "project_number": "661638997772",
+ "project_id": "xmflsct-mastodon-app",
+ "storage_bucket": "xmflsct-mastodon-app.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:661638997772:android:4fd02851f757f8fa9f8b29",
+ "android_client_info": {
+ "package_name": "com.xmflsct.app.tooot"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "661638997772-erabggnp958v10r0tvsrh3pg880qnvqn.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.xmflsct.app.tooot",
+ "certificate_hash": "53162f104230ee8b7b1372e4f378e2b9607ca16f"
+ }
+ },
+ {
+ "client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyDUw4s-mhQsHvs4hdIsldsi68ZIygM5MC4"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "661638997772-6aiqk97aema0rt280i7nfar3ha2mlgno.apps.googleusercontent.com",
+ "client_type": 3
+ },
+ {
+ "client_id": "661638997772-65g8ce369ugck3ii4ulk6jhb3ijg51kl.apps.googleusercontent.com",
+ "client_type": 2,
+ "ios_info": {
+ "bundle_id": "com.xmflsct.app.tooot",
+ "app_store_id": "1549772269"
+ }
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 545f156f..3b22e22f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -10,6 +10,7 @@
+
diff --git a/android/build.gradle b/android/build.gradle
index 02553cd8..65e07931 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -22,9 +22,10 @@ buildscript {
jcenter()
}
dependencies {
- classpath('com.android.tools.build:gradle:7.3.1')
+ classpath('com.android.tools.build:gradle:7.2.2')
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:5.0.1")
+ classpath 'com.google.gms:google-services:4.3.14'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/app.config.ts b/app.config.ts
index 0afae03f..087f6bc6 100644
--- a/app.config.ts
+++ b/app.config.ts
@@ -15,8 +15,9 @@ export default (): ExpoConfig => ({
},
android: {
package: 'com.xmflsct.app.tooot',
- permissions: ['CAMERA', 'VIBRATE'],
- blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT']
+ permissions: ['NOTIFICATIONS', 'CAMERA', 'VIBRATE'],
+ blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT'],
+ googleServicesFile: './android/app/google-services.json'
},
plugins: [
[
diff --git a/fastlane/metadata/en-US/release_notes.txt b/fastlane/metadata/en-US/release_notes.txt
index c030d165..46181811 100644
--- a/fastlane/metadata/en-US/release_notes.txt
+++ b/fastlane/metadata/en-US/release_notes.txt
@@ -5,4 +5,5 @@ Enjoy toooting! This version includes following improvements and fixes:
- Allowing adding more context of reports
- Option to disable autoplay gif
- Hide boosts from users
-- Followed hashtags are underlined
\ No newline at end of file
+- Followed hashtags are underlined
+- Support GoToSocial
\ No newline at end of file
diff --git a/fastlane/metadata/zh-Hans/release_notes.txt b/fastlane/metadata/zh-Hans/release_notes.txt
index 7079eb59..df4f1cc5 100644
--- a/fastlane/metadata/zh-Hans/release_notes.txt
+++ b/fastlane/metadata/zh-Hans/release_notes.txt
@@ -5,4 +5,5 @@ toooting愉快!此版本包括以下改进和修复:
- 可添加举报细节
- 新增暂停自动播放gif动画选项
- 隐藏用户的转嘟
-- 下划线高亮正在关注的话题标签
\ No newline at end of file
+- 下划线高亮正在关注的话题标签
+- 支持GoToSocial
\ No newline at end of file
diff --git a/package.json b/package.json
index 144490ed..077a8776 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"@react-native-community/blur": "^4.3.0",
"@react-native-community/netinfo": "9.3.7",
"@react-native-community/segmented-control": "^2.2.2",
+ "@react-native-firebase/app": "^16.5.0",
"@react-native-menu/menu": "^0.7.3",
"@react-navigation/bottom-tabs": "^6.5.2",
"@react-navigation/native": "^6.1.1",
diff --git a/src/@types/mastodon.d.ts b/src/@types/mastodon.d.ts
index d7a3b1c4..e1dcfa40 100644
--- a/src/@types/mastodon.d.ts
+++ b/src/@types/mastodon.d.ts
@@ -338,6 +338,9 @@ declare namespace Mastodon {
contact: { email: string; account: Account }
rules: Rule[]
}
+
+ // Gotosocial
+ account_domain?: string
}
type Instance_V1 = {
// Base
@@ -384,6 +387,9 @@ declare namespace Mastodon {
max_expiration: number
}
}
+
+ // Gotosocial
+ account_domain?: string
}
type Mention = {
diff --git a/src/components/Instance/index.tsx b/src/components/Instance/index.tsx
index 16b13b9d..1fbbde76 100644
--- a/src/components/Instance/index.tsx
+++ b/src/components/Instance/index.tsx
@@ -8,7 +8,6 @@ import { TabMeStackNavigationProp } from '@utils/navigation/navigators'
import { queryClient } from '@utils/queryHooks'
import { redirectUri, useAppsMutation } from '@utils/queryHooks/apps'
import { useInstanceQuery } from '@utils/queryHooks/instance'
-import { storage } from '@utils/storage'
import { StorageAccount } from '@utils/storage/account'
import {
generateAccountKey,
@@ -26,7 +25,6 @@ import React, { RefObject, useCallback, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
import { ScrollView } from 'react-native-gesture-handler'
-import { MMKV } from 'react-native-mmkv'
import parse from 'url-parse'
import CustomText from '../Text'
@@ -66,11 +64,13 @@ const ComponentInstance: React.FC = ({
}
})
- const deprecateAuthFollow = featureCheck('deprecate_auth_follow')
-
const appsMutation = useAppsMutation({
retry: false,
onSuccess: async (data, variables) => {
+ const scopes = featureCheck('deprecate_auth_follow')
+ ? ['read', 'write', 'push']
+ : ['read', 'write', 'follow', 'push']
+
const clientId = data.client_id
const clientSecret = data.client_secret
@@ -79,9 +79,7 @@ const ComponentInstance: React.FC = ({
const request = new AuthSession.AuthRequest({
clientId,
clientSecret,
- scopes: deprecateAuthFollow
- ? ['read', 'write', 'push']
- : ['read', 'write', 'follow', 'push'],
+ scopes,
redirectUri
})
await request.makeAuthUrlAsync(discovery)
@@ -93,10 +91,12 @@ const ComponentInstance: React.FC = ({
{
clientId,
clientSecret,
- scopes: ['read', 'write', 'follow', 'push'],
+ scopes,
redirectUri,
code: promptResult.params.code,
extraParams: {
+ client_id: clientId,
+ client_secret: clientSecret,
grant_type: 'authorization_code',
...(request.codeVerifier && { code_verifier: request.codeVerifier })
}
@@ -125,8 +125,13 @@ const ComponentInstance: React.FC = ({
'auth.domain': domain,
'auth.account.id': id,
'auth.account.acct': acct,
- // @ts-ignore
- 'auth.account.domain': instanceQuery.data?.domain || instanceQuery.data?.uri,
+ 'auth.account.domain':
+ (instanceQuery.data as Mastodon.Instance_V2)?.domain ||
+ instanceQuery.data?.account_domain ||
+ ((instanceQuery.data as Mastodon.Instance_V1)?.uri
+ ? parse((instanceQuery.data as Mastodon.Instance_V1).uri).hostname
+ : undefined) ||
+ (instanceQuery.data as Mastodon.Instance_V1)?.uri,
'auth.account.avatar_static': avatar_static,
version: instanceQuery.data?.version || '0',
preferences: undefined,
diff --git a/src/components/Timeline/Shared/Poll.tsx b/src/components/Timeline/Shared/Poll.tsx
index a69862bf..06557731 100644
--- a/src/components/Timeline/Shared/Poll.tsx
+++ b/src/components/Timeline/Shared/Poll.tsx
@@ -21,7 +21,8 @@ import { Pressable, View } from 'react-native'
import StatusContext from './Context'
const TimelinePoll: React.FC = () => {
- const { queryKey, status, ownAccount, spoilerHidden, disableDetails } = useContext(StatusContext)
+ const { queryKey, status, ownAccount, spoilerHidden, disableDetails, highlighted } =
+ useContext(StatusContext)
if (!queryKey || !status || !status.poll) return null
const poll = status.poll
@@ -92,7 +93,7 @@ const TimelinePoll: React.FC = () => {
/>
)
- } else {
+ } else if (highlighted) {
return (