1
0
mirror of https://github.com/tooot-app/app synced 2025-04-25 15:38:42 +02:00

Test development branch

This commit is contained in:
Zhiyuan Zheng 2021-02-09 01:16:12 +01:00
parent 1f4108c2d4
commit c46888acab
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
9 changed files with 158 additions and 155 deletions

27
.envrc.example Normal file
View File

@ -0,0 +1,27 @@
export TOOOT_ENVIRONMENT=""
export SENTRY_ORGANIZATION=""
export SENTRY_PROJECT=""
export SENTRY_AUTH_TOKEN=""
export SENTRY_DSN=""
# Fastlane start
export LC_ALL=""
export LANG=""
export FASTLANE_USER=""
export MATCH_PASSWORD=""
export MATCH_GIT_URL=""
export MATCH_GIT_BASIC_AUTHORIZATION=""
export APP_STORE_CONNECT_API_KEY_KEY_ID=""
export APP_STORE_CONNECT_API_KEY_ISSUER_ID=""
export APP_STORE_CONNECT_API_KEY_KEY=""
export ANDROID_KEYSTORE=""
export ANDROID_KEYSTORE_PASSWORD=""
export ANDROID_KEYSTORE_ALIAS=""
export ANDROID_KEYSTORE_KEY_PASSWORD=""
export SUPPLY_JSON_KEY_DATA=""
# Fastlane end

50
.github/workflows/development.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: Build development
on:
push:
branches:
- development
jobs:
build:
runs-on: macos-latest
steps:
- name: -- Step 1 -- Checkout code
uses: actions/checkout@v2
- name: -- Step 2 -- Setup node
uses: actions/setup-node@v2
with:
node-version: 14.x
- name: -- Step 3 -- Use Expo action
uses: expo/expo-github-action@v5
with:
expo-version: 4.x
expo-username: ${{ secrets.EXPO_USERNAME }}
expo-token: ${{ secrets.EXPO_TOKEN }}
- name: -- Step 4 -- Install node dependencies
run: yarn install
- name: -- Step 5 -- Install native dependencies
run: npx pod-install
- name: -- Step 6 -- Install ruby dependencies
run: bundle install
- name: -- Step 7 -- Run fastlane
env:
TOOOT_ENVIRONMENT: development
SENTRY_ORGANIZATION: ${{ secrets.SENTRY_ORGANIZATION }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MATCH_GIT_URL: ${{ secrets.MATCH_GIT_URL }}
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
ANDROID_KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEYSTORE_ALIAS: ${{ secrets.ANDROID_KEYSTORE_ALIAS }}
ANDROID_KEYSTORE_KEY_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_KEY_PASSWORD }}
SUPPLY_JSON_KEY_DATA: ${{ secrets.SUPPLY_JSON_KEY_DATA }}
FL_GITHUB_RELEASE_API_BEARER: ${{ secrets.GITHUB_TOKEN }}
run: yarn app:build

View File

@ -15,7 +15,7 @@ case ENVIRONMENT
when "development" when "development"
GITHUB_RELEASE= "" GITHUB_RELEASE= ""
when "staging" when "staging"
GITHUB_RELEASE = "v#{VERSION}(#{BUILD_NUMBER})" GITHUB_RELEASE = "v#{VERSION}-rc#{VERSIONS[:patch]}"
when "production" when "production"
GITHUB_RELEASE = "v#{VERSION}" GITHUB_RELEASE = "v#{VERSION}"
end end
@ -44,20 +44,14 @@ private_lane :prepare_playstore_android do
end end
desc "Create new GitHub release" desc "Create new GitHub release"
private_lane :github_release do private_lane :github_release do |options|
case ENVIRONMENT
when "staging"
is_prerelease = true
when "production"
is_prerelease = false
end
set_github_release( set_github_release(
repository_name: GITHUB_REPO, repository_name: GITHUB_REPO,
name: GITHUB_RELEASE, name: GITHUB_RELEASE,
tag_name: GITHUB_RELEASE, tag_name: GITHUB_RELEASE,
description: "No changelog provided", description: "No changelog provided",
commitish: git_branch, commitish: git_branch,
is_prerelease: is_prerelease is_prerelease: options[:prerelease]
) )
end end
@ -76,8 +70,10 @@ private_lane :build_ios do
case ENVIRONMENT case ENVIRONMENT
when "development" when "development"
match( type: "development", readonly: true ) match( type: "development", readonly: true )
build_ios_app( export_method: "development", output_directory: BUILD_DIRECTORY, output_name: "#{VERSION}-#{BUILD_NUMBER}" ) if !is_ci
build_ios_app( export_method: "development", output_directory: BUILD_DIRECTORY )
install_on_device( skip_wifi: true ) install_on_device( skip_wifi: true )
end
when "staging" when "staging"
prepare_appstore_ios prepare_appstore_ios
match( type: "appstore", readonly: true ) match( type: "appstore", readonly: true )
@ -101,6 +97,7 @@ private_lane :build_android do
case ENVIRONMENT case ENVIRONMENT
when "development" when "development"
if !is_ci
build_android_app( build_android_app(
task: 'assemble', task: 'assemble',
build_type: 'debug', build_type: 'debug',
@ -109,6 +106,7 @@ private_lane :build_android do
adb( adb(
command: "install #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}" command: "install #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}"
) )
end
when "staging" when "staging"
prepare_playstore_android prepare_playstore_android
build_android_app( build_android_app(
@ -127,7 +125,7 @@ private_lane :build_android do
} }
) )
upload_to_play_store( upload_to_play_store(
track: "alpha", track: "beta",
skip_upload_metadata: true, skip_upload_metadata: true,
skip_upload_changelogs: true, skip_upload_changelogs: true,
skip_upload_images: true, skip_upload_images: true,
@ -147,9 +145,9 @@ lane :build do
build_android build_android
case ENVIRONMENT case ENVIRONMENT
when "staging" when "staging"
github_release github_release(prerelease: true)
when "production" when "production"
github_release github_release(prerelease: false)
end end
end end
expo_release expo_release

View File

@ -112,7 +112,7 @@
"native": "210201", "native": "210201",
"major": 0, "major": 0,
"minor": 3, "minor": 3,
"patch": 0, "patch": 1,
"expo": "40.0.0" "expo": "40.0.0"
} }
} }

View File

@ -1,11 +1,8 @@
import Button from '@components/Button' import Button from '@components/Button'
import haptics from '@components/haptics'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import { useNavigation } from '@react-navigation/native'
import { useAppsQuery } from '@utils/queryHooks/apps' import { useAppsQuery } from '@utils/queryHooks/apps'
import { useInstanceQuery } from '@utils/queryHooks/instance' import { useInstanceQuery } from '@utils/queryHooks/instance'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { getLocalInstances } from '@utils/slices/instancesSlice'
import { getLocalInstances, remoteUpdate } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import * as WebBrowser from 'expo-web-browser' import * as WebBrowser from 'expo-web-browser'
@ -13,39 +10,30 @@ import { debounce } from 'lodash'
import React, { useCallback, useMemo, useState } from 'react' import React, { useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Alert, Image, StyleSheet, Text, TextInput, View } from 'react-native' import { Alert, Image, StyleSheet, Text, TextInput, View } from 'react-native'
import { useQueryClient } from 'react-query' import { useSelector } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'
import { Placeholder, Fade } from 'rn-placeholder' import { Placeholder, Fade } from 'rn-placeholder'
import analytics from './analytics' import analytics from './analytics'
import InstanceAuth from './Instance/Auth' import InstanceAuth from './Instance/Auth'
import EULA from './Instance/EULA' import EULA from './Instance/EULA'
import InstanceInfo from './Instance/Info' import InstanceInfo from './Instance/Info'
import { toast } from './toast'
export interface Props { export interface Props {
type: 'local' | 'remote'
disableHeaderImage?: boolean disableHeaderImage?: boolean
goBack?: boolean goBack?: boolean
} }
const ComponentInstance: React.FC<Props> = ({ const ComponentInstance: React.FC<Props> = ({
type,
disableHeaderImage, disableHeaderImage,
goBack = false goBack = false
}) => { }) => {
const { t, i18n } = useTranslation('componentInstance') const { t } = useTranslation('componentInstance')
const { theme } = useTheme() const { theme } = useTheme()
const navigation = useNavigation()
const localInstances = useSelector(getLocalInstances) const localInstances = useSelector(getLocalInstances)
const dispatch = useDispatch()
const queryClient = useQueryClient()
const [instanceDomain, setInstanceDomain] = useState<string>() const [instanceDomain, setInstanceDomain] = useState<string>()
const instanceQuery = useInstanceQuery({ const instanceQuery = useInstanceQuery({
instanceDomain, instanceDomain,
checkPublic: type === 'remote',
options: { enabled: false, retry: false } options: { enabled: false, retry: false }
}) })
const appsQuery = useAppsQuery({ const appsQuery = useAppsQuery({
@ -70,8 +58,6 @@ const ComponentInstance: React.FC<Props> = ({
const processUpdate = useCallback(() => { const processUpdate = useCallback(() => {
if (instanceDomain) { if (instanceDomain) {
switch (type) {
case 'local':
analytics('instance_local_login') analytics('instance_local_login')
if ( if (
localInstances && localInstances &&
@ -97,20 +83,6 @@ const ComponentInstance: React.FC<Props> = ({
} else { } else {
appsQuery.refetch() appsQuery.refetch()
} }
break
case 'remote':
analytics('instance_remote_register')
haptics('Success')
const queryKey: QueryKeyTimeline = [
'Timeline',
{ page: 'RemotePublic' }
]
dispatch(remoteUpdate(instanceDomain))
queryClient.resetQueries(queryKey)
toast({ type: 'success', message: t('update.remote.succeed') })
navigation.goBack()
break
}
} }
}, [instanceDomain]) }, [instanceDomain])
@ -129,15 +101,6 @@ const ComponentInstance: React.FC<Props> = ({
[instanceDomain, instanceQuery.isSuccess, instanceQuery.data] [instanceDomain, instanceQuery.isSuccess, instanceQuery.data]
) )
const buttonContent = useMemo(() => {
switch (type) {
case 'local':
return t('server.button.local')
case 'remote':
return t('server.button.remote')
}
}, [i18n.language])
const requestAuth = useMemo(() => { const requestAuth = useMemo(() => {
if ( if (
instanceDomain && instanceDomain &&
@ -179,10 +142,7 @@ const ComponentInstance: React.FC<Props> = ({
styles.textInput, styles.textInput,
{ {
color: theme.primary, color: theme.primary,
borderBottomColor: borderBottomColor: instanceQuery.isError
type === 'remote' &&
instanceQuery.data &&
!instanceQuery.data.publicAllow
? theme.red ? theme.red
: theme.border : theme.border
} }
@ -200,13 +160,9 @@ const ComponentInstance: React.FC<Props> = ({
/> />
<Button <Button
type='text' type='text'
content={buttonContent} content={t('server.button.local')}
onPress={processUpdate} onPress={processUpdate}
disabled={ disabled={!instanceQuery.data?.uri || !agreed}
!instanceQuery.data?.uri ||
(type === 'remote' && !instanceQuery.data.publicAllow) ||
!agreed
}
loading={instanceQuery.isFetching || appsQuery.isFetching} loading={instanceQuery.isFetching || appsQuery.isFetching}
/> />
</View> </View>
@ -262,7 +218,6 @@ const ComponentInstance: React.FC<Props> = ({
/> />
</View> </View>
</Placeholder> </Placeholder>
{type === 'local' ? (
<View style={styles.disclaimer}> <View style={styles.disclaimer}>
<Icon <Icon
name='Lock' name='Lock'
@ -285,11 +240,10 @@ const ComponentInstance: React.FC<Props> = ({
</Text> </Text>
</Text> </Text>
</View> </View>
) : null}
</View> </View>
</View> </View>
{type === 'local' ? requestAuth : null} {requestAuth}
</> </>
) )
} }

View File

@ -94,7 +94,7 @@ const AttachmentVideo: React.FC<Props> = ({
}} }}
/> />
) : null ) : null
) : gifv ? null : ( ) : (
<Button <Button
round round
overlay overlay

View File

@ -48,7 +48,7 @@ const ScreenMeRoot: React.FC = () => {
{localActiveIndex !== null ? ( {localActiveIndex !== null ? (
<MyInfo setData={setData} /> <MyInfo setData={setData} />
) : ( ) : (
<ComponentInstance type='local' /> <ComponentInstance />
)} )}
{localActiveIndex !== null ? <Collections /> : null} {localActiveIndex !== null ? <Collections /> : null}
<Settings /> <Settings />

View File

@ -102,7 +102,7 @@ const ScreenMeSwitchRoot: React.FC = () => {
<Text style={[styles.header, { color: theme.primary }]}> <Text style={[styles.header, { color: theme.primary }]}>
{t('content.new')} {t('content.new')}
</Text> </Text>
<ComponentInstance type='local' disableHeaderImage goBack /> <ComponentInstance disableHeaderImage goBack />
</View> </View>
</ScrollView> </ScrollView>
</KeyboardAvoidingView> </KeyboardAvoidingView>

View File

@ -2,43 +2,17 @@ import client from '@api/client'
import { AxiosError } from 'axios' import { AxiosError } from 'axios'
import { useQuery, UseQueryOptions } from 'react-query' import { useQuery, UseQueryOptions } from 'react-query'
export type QueryKey = [ export type QueryKey = ['Instance', { instanceDomain?: string }]
'Instance',
{ instanceDomain?: string; checkPublic: boolean }
]
const queryFunction = async ({ queryKey }: { queryKey: QueryKey }) => { const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
const { instanceDomain, checkPublic } = queryKey[1] const { instanceDomain } = queryKey[1]
let res: Mastodon.Instance & { publicAllow?: boolean } = await client< return client<Mastodon.Instance>({
Mastodon.Instance
>({
method: 'get', method: 'get',
instance: 'remote', instance: 'remote',
instanceDomain, instanceDomain,
url: `instance` url: `instance`
}) })
if (checkPublic) {
let check
try {
check = await client<Mastodon.Status[]>({
method: 'get',
instance: 'remote',
instanceDomain,
url: `timelines/public`
})
} catch {}
if (check) {
res.publicAllow = true
return res
} else {
res.publicAllow = false
return res
}
}
return res
} }
const useInstanceQuery = < const useInstanceQuery = <