Merge pull request #69 from tooot-app/nightly-210318

Nightly 210318
This commit is contained in:
xmflsct 2021-03-18 23:57:20 +01:00 committed by GitHub
commit 73d6703e56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 210 additions and 131 deletions

View File

@ -30,9 +30,11 @@ jobs:
expo-token: ${{ secrets.EXPO_TOKEN }} expo-token: ${{ secrets.EXPO_TOKEN }}
- name: -- Step 4 -- Install node dependencies - name: -- Step 4 -- Install node dependencies
run: yarn install run: yarn install
- name: -- Step 5 -- Install ruby dependencies - name: -- Step 5 -- Install native dependencies
run: npx pod-install
- name: -- Step 6 -- Install ruby dependencies
run: bundle install run: bundle install
- name: -- Step 6 -- Run fastlane - name: -- Step 7 -- Run fastlane
env: env:
ENVIRONMENT: ${{ steps.branch.outputs.branch }} ENVIRONMENT: ${{ steps.branch.outputs.branch }}
LC_ALL: en_US.UTF-8 LC_ALL: en_US.UTF-8

View File

@ -1,5 +1,6 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "fastlane" gem "fastlane"
gem 'cocoapods'
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
eval_gemfile(plugins_path) if File.exist?(plugins_path) eval_gemfile(plugins_path) if File.exist?(plugins_path)

View File

@ -2,8 +2,16 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
CFPropertyList (3.0.3) CFPropertyList (3.0.3)
activesupport (5.2.4.5)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.7.0) addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
artifactory (3.0.15) artifactory (3.0.15)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.1.1) aws-eventstream (1.1.1)
@ -24,10 +32,48 @@ GEM
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4) babosa (1.0.4)
claide (1.0.3) claide (1.0.3)
cocoapods (1.10.1)
addressable (~> 2.6)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.10.1)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.19.0, < 2.0)
cocoapods-core (1.10.1)
activesupport (> 5.0, < 6)
addressable (~> 2.6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.4.0)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-trunk (1.5.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored (1.2) colored (1.2)
colored2 (3.1.2) colored2 (3.1.2)
commander-fastlane (4.4.6) commander-fastlane (4.4.6)
highline (~> 1.7.2) highline (~> 1.7.2)
concurrent-ruby (1.1.8)
declarative (0.0.20) declarative (0.0.20)
declarative-option (0.1.0) declarative-option (0.1.0)
digest-crc (0.6.3) digest-crc (0.6.3)
@ -36,6 +82,9 @@ GEM
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6) dotenv (2.7.6)
emoji_regex (3.2.2) emoji_regex (3.2.2)
escape (0.0.4)
ethon (0.12.0)
ffi (>= 1.3.0)
excon (0.79.0) excon (0.79.0)
faraday (1.3.0) faraday (1.3.0)
faraday-net_http (~> 1.0) faraday-net_http (~> 1.0)
@ -89,6 +138,9 @@ GEM
fastlane-plugin-json (1.0.0) fastlane-plugin-json (1.0.0)
fastlane-plugin-versioning_android (0.1.0) fastlane-plugin-versioning_android (0.1.0)
fastlane-plugin-yarn (1.2) fastlane-plugin-yarn (1.2)
ffi (1.15.0)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3) gh_inspector (1.1.3)
google-api-client (0.38.0) google-api-client (0.38.0)
addressable (~> 2.5, >= 2.5.1) addressable (~> 2.5, >= 2.5.1)
@ -137,16 +189,22 @@ GEM
http-cookie (1.0.3) http-cookie (1.0.3)
domain_name (~> 0.5) domain_name (~> 0.5)
httpclient (2.8.3) httpclient (2.8.3)
i18n (1.8.9)
concurrent-ruby (~> 1.0)
jmespath (1.4.0) jmespath (1.4.0)
json (2.5.1) json (2.5.1)
jwt (2.2.2) jwt (2.2.2)
memoist (0.16.2) memoist (0.16.2)
mini_magick (4.11.0) mini_magick (4.11.0)
mini_mime (1.0.2) mini_mime (1.0.2)
minitest (5.14.4)
molinillo (0.6.6)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.0.0) multipart-post (2.0.0)
nanaimo (0.3.0) nanaimo (0.3.0)
nap (1.1.0)
naturally (2.2.1) naturally (2.2.1)
netrc (0.11.0)
os (1.1.1) os (1.1.1)
plist (3.6.0) plist (3.6.0)
public_suffix (4.0.6) public_suffix (4.0.6)
@ -158,6 +216,7 @@ GEM
retriable (3.1.2) retriable (3.1.2)
rexml (3.2.4) rexml (3.2.4)
rouge (2.0.7) rouge (2.0.7)
ruby-macho (1.4.0)
ruby2_keywords (0.0.4) ruby2_keywords (0.0.4)
rubyzip (2.3.0) rubyzip (2.3.0)
security (0.1.3) security (0.1.3)
@ -173,10 +232,15 @@ GEM
terminal-notifier (2.0.0) terminal-notifier (2.0.0)
terminal-table (1.8.0) terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1) unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-cursor (0.7.1) tty-cursor (0.7.1)
tty-screen (0.8.1) tty-screen (0.8.1)
tty-spinner (0.9.3) tty-spinner (0.9.3)
tty-cursor (~> 0.7) tty-cursor (~> 0.7)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
uber (0.1.0) uber (0.1.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
@ -199,6 +263,7 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
cocoapods
fastlane fastlane
fastlane-plugin-json fastlane-plugin-json
fastlane-plugin-versioning_android fastlane-plugin-versioning_android

View File

@ -9,7 +9,7 @@ VERSIONS = read_json( json_path: "./package.json" )[:versions]
ENVIRONMENT = ENV["ENVIRONMENT"] ENVIRONMENT = ENV["ENVIRONMENT"]
VERSION = "#{VERSIONS[:major]}.#{VERSIONS[:minor]}" VERSION = "#{VERSIONS[:major]}.#{VERSIONS[:minor]}"
RELEASE_CHANNEL = "#{VERSIONS[:major]}-#{ENVIRONMENT}" RELEASE_CHANNEL = "#{VERSIONS[:major]}-#{ENVIRONMENT}"
BUILD_NUMBER = ENV["GITHUB_RUN_NUMBER"] BUILD_NUMBER = "#{Time.now.strftime("%y%m%d")}#{ENV["GITHUB_RUN_NUMBER"]}"
GITHUB_REPO = "tooot-app/app" GITHUB_REPO = "tooot-app/app"
case ENVIRONMENT case ENVIRONMENT
when "candidate" when "candidate"
@ -32,7 +32,7 @@ private_lane :prepare_appstore_ios do
key: "NSAppTransportSecurity", key: "NSAppTransportSecurity",
value: {} value: {}
) )
increment_build_number( xcodeproj: XCODEPROJ, build_number: BUILD_NUMBER, skip_info_plist: true ) increment_build_number( xcodeproj: XCODEPROJ, build_number: BUILD_NUMBER )
app_store_connect_api_key app_store_connect_api_key
end end
@ -42,11 +42,6 @@ private_lane :update_expo_ios do
set_info_plist_value( path: EXPO_PLIST, key: "EXUpdatesReleaseChannel", value: RELEASE_CHANNEL ) set_info_plist_value( path: EXPO_PLIST, key: "EXUpdatesReleaseChannel", value: RELEASE_CHANNEL )
end end
desc 'IOS: Install pods'
private_lane :install_pods_ios do
cocoapods(podfile: "./ios/", deployment: true)
end
desc "ANDROID: Prepare play store" desc "ANDROID: Prepare play store"
private_lane :prepare_playstore_android do private_lane :prepare_playstore_android do
android_set_version_name( version_name: VERSION, gradle_file: "./android/app/build.gradle" ) android_set_version_name( version_name: VERSION, gradle_file: "./android/app/build.gradle" )
@ -79,7 +74,6 @@ private_lane :build_ios do
case ENVIRONMENT case ENVIRONMENT
when "candidate" when "candidate"
install_pods_ios
prepare_appstore_ios prepare_appstore_ios
match( type: "appstore", readonly: true ) match( type: "appstore", readonly: true )
build_ios_app( export_method: "app-store", include_symbols: true, include_bitcode: true, silent: true ) build_ios_app( export_method: "app-store", include_symbols: true, include_bitcode: true, silent: true )
@ -90,7 +84,6 @@ private_lane :build_ios do
changelog: "Ready for testing" changelog: "Ready for testing"
) )
when "release" when "release"
install_pods_ios
prepare_appstore_ios prepare_appstore_ios
match( type: "appstore", readonly: true ) match( type: "appstore", readonly: true )
build_ios_app( export_method: "app-store", include_bitcode: true, silent: true ) build_ios_app( export_method: "app-store", include_bitcode: true, silent: true )

View File

@ -1,9 +1,15 @@
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 React, { useCallback, useMemo, useRef, useState } from 'react' import React, { useCallback, useMemo, useRef, useState } from 'react'
import { Pressable, StyleProp, StyleSheet, ViewStyle } from 'react-native' import {
Image,
ImageStyle,
Pressable,
StyleProp,
StyleSheet,
ViewStyle
} from 'react-native'
import { Blurhash } from 'react-native-blurhash' import { Blurhash } from 'react-native-blurhash'
import FastImage, { ImageStyle } from 'react-native-fast-image'
// blurhas -> if blurhash, show before any loading succeed // blurhas -> if blurhash, show before any loading succeed
// original -> load original // original -> load original
@ -70,7 +76,7 @@ const GracefullyImage = React.memo(
const previewView = useMemo( const previewView = useMemo(
() => () =>
uri.preview && !imageLoaded ? ( uri.preview && !imageLoaded ? (
<FastImage <Image
source={{ uri: uri.preview }} source={{ uri: uri.preview }}
style={[{ flex: 1 }, imageStyle]} style={[{ flex: 1 }, imageStyle]}
/> />
@ -79,14 +85,14 @@ const GracefullyImage = React.memo(
) )
const originalView = useMemo( const originalView = useMemo(
() => ( () => (
<FastImage <Image
source={source} source={source}
style={[{ flex: imageLoaded ? 1 : undefined }, imageStyle]} style={[{ flex: 1 }, imageStyle]}
onLoad={onLoad} onLoad={onLoad}
onError={onError} onError={onError}
/> />
), ),
[source, imageLoaded] [source]
) )
const blurhashView = useMemo(() => { const blurhashView = useMemo(() => {
return blurhash && (hidden || !imageLoaded) ? ( return blurhash && (hidden || !imageLoaded) ? (

View File

@ -23,7 +23,7 @@ const HeaderCenter = React.memo(
/> />
) )
}, },
() => true (prev, next) => prev.content === next.content
) )
const styles = StyleSheet.create({ const styles = StyleSheet.create({

View File

@ -340,6 +340,12 @@ const ScreenCompose: React.FC<ScreenComposeProp> = ({
[totalTextCount, composeState] [totalTextCount, composeState]
) )
const headerContent = useMemo(() => {
return `${totalTextCount} / ${maxTootChars}${
__DEV__ ? ` Dirty: ${composeState.dirty.toString()}` : ''
}`
}, [totalTextCount, maxTootChars, composeState.dirty])
return ( return (
<KeyboardAvoidingView <KeyboardAvoidingView
style={styles.base} style={styles.base}
@ -358,26 +364,26 @@ const ScreenCompose: React.FC<ScreenComposeProp> = ({
name='Screen-Compose-Root' name='Screen-Compose-Root'
component={ComposeRoot} component={ComposeRoot}
options={{ options={{
...Platform.select({
ios: {
headerTitle: headerContent,
headerTitleStyle: {
fontWeight:
totalTextCount > maxTootChars
? StyleConstants.Font.Weight.Bold
: StyleConstants.Font.Weight.Normal,
fontSize: StyleConstants.Font.Size.M
},
headerTintColor:
totalTextCount > maxTootChars
? theme.red
: theme.secondary
},
android: {
headerCenter: () => <HeaderCenter content={headerContent} />
}
}),
headerLeft, headerLeft,
headerTitle: `${totalTextCount} / ${maxTootChars}${
__DEV__ ? ` Dirty: ${composeState.dirty.toString()}` : ''
}`,
headerTitleStyle: {
fontWeight:
totalTextCount > maxTootChars
? StyleConstants.Font.Weight.Bold
: StyleConstants.Font.Weight.Normal,
fontSize: StyleConstants.Font.Size.M
},
headerTintColor:
totalTextCount > maxTootChars ? theme.red : theme.secondary,
headerCenter: () => (
<HeaderCenter
content={`${totalTextCount} / ${maxTootChars}${
__DEV__ ? ` Dirty: ${composeState.dirty.toString()}` : ''
}`}
/>
),
headerRight headerRight
}} }}
/> />

View File

@ -9,7 +9,7 @@ import {
} from '@utils/slices/instancesSlice' } 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 React, { useCallback, useContext, useEffect, useState } from 'react' import React, { useCallback, useContext, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import {
Dimensions, Dimensions,
@ -42,12 +42,6 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
draft => draft.timestamp !== timestamp draft => draft.timestamp !== timestamp
) )
useEffect(() => {
if (instanceDrafts?.length === 0) {
navigation.goBack()
}
}, [instanceDrafts?.length])
const actionWidth = const actionWidth =
StyleConstants.Font.Size.L + StyleConstants.Spacing.Global.PagePadding * 4 StyleConstants.Font.Size.L + StyleConstants.Spacing.Global.PagePadding * 4

View File

@ -1,7 +1,7 @@
import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video' import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
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 React, { useContext, useMemo } from 'react' import React, { useContext, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native' import { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'
import ComposeContext from '../utils/createContext' import ComposeContext from '../utils/createContext'
@ -55,8 +55,10 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
} }
}) })
const scrollViewRef = useRef<ScrollView>(null)
return ( return (
<ScrollView> <ScrollView ref={scrollViewRef}>
{mediaDisplay} {mediaDisplay}
<View style={styles.altTextContainer}> <View style={styles.altTextContainer}>
<Text style={[styles.altTextInputHeading, { color: theme.primary }]}> <Text style={[styles.altTextInputHeading, { color: theme.primary }]}>
@ -67,6 +69,7 @@ const ComposeEditAttachmentRoot: React.FC<Props> = ({ index }) => {
styles.altTextInput, styles.altTextInput,
{ borderColor: theme.border, color: theme.primary } { borderColor: theme.border, color: theme.primary }
]} ]}
onFocus={() => scrollViewRef.current?.scrollToEnd()}
autoCapitalize='none' autoCapitalize='none'
autoCorrect={false} autoCorrect={false}
maxLength={1500} maxLength={1500}

View File

@ -4,7 +4,13 @@ import { useSearchQuery } from '@utils/queryHooks/search'
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 { forEach, groupBy, sortBy } from 'lodash' import { forEach, groupBy, sortBy } from 'lodash'
import React, { useCallback, useContext, useEffect, useMemo } from 'react' import React, {
useCallback,
useContext,
useEffect,
useMemo,
useRef
} from 'react'
import { FlatList, Image, StyleSheet, View } from 'react-native' import { FlatList, Image, StyleSheet, View } from 'react-native'
import { Circle } from 'react-native-animated-spinkit' import { Circle } from 'react-native-animated-spinkit'
import ComposeActions from './Root/Actions' import ComposeActions from './Root/Actions'
@ -30,90 +36,93 @@ const prefetchEmojis = (
}) })
} }
const ComposeRoot: React.FC = () => { const ComposeRoot = React.memo(
const { theme } = useTheme() () => {
const { theme } = useTheme()
const { composeState, composeDispatch } = useContext(ComposeContext) const { composeState, composeDispatch } = useContext(ComposeContext)
const { isFetching, data, refetch } = useSearchQuery({ const { isFetching, data, refetch } = useSearchQuery({
type: type:
composeState.tag?.type === 'accounts' || composeState.tag?.type === 'accounts' ||
composeState.tag?.type === 'hashtags' composeState.tag?.type === 'hashtags'
? composeState.tag.type ? composeState.tag.type
: undefined, : undefined,
term: composeState.tag?.text.substring(1), term: composeState.tag?.text.substring(1),
options: { enabled: false } options: { enabled: false }
}) })
useEffect(() => { useEffect(() => {
if ( if (
(composeState.tag?.type === 'accounts' || (composeState.tag?.type === 'accounts' ||
composeState.tag?.type === 'hashtags') && composeState.tag?.type === 'hashtags') &&
composeState.tag?.text composeState.tag?.text
) { ) {
refetch() refetch()
} }
}, [composeState.tag]) }, [composeState.tag])
const { data: emojisData } = useEmojisQuery({}) const { data: emojisData } = useEmojisQuery({})
useEffect(() => { useEffect(() => {
if (emojisData && emojisData.length) { if (emojisData && emojisData.length) {
let sortedEmojis: { title: string; data: Mastodon.Emoji[] }[] = [] let sortedEmojis: { title: string; data: Mastodon.Emoji[] }[] = []
forEach( forEach(
groupBy(sortBy(emojisData, ['category', 'shortcode']), 'category'), groupBy(sortBy(emojisData, ['category', 'shortcode']), 'category'),
(value, key) => sortedEmojis.push({ title: key, data: value }) (value, key) => sortedEmojis.push({ title: key, data: value })
) )
composeDispatch({ composeDispatch({
type: 'emoji', type: 'emoji',
payload: { ...composeState.emoji, emojis: sortedEmojis } payload: { ...composeState.emoji, emojis: sortedEmojis }
}) })
prefetchEmojis(sortedEmojis) prefetchEmojis(sortedEmojis)
} }
}, [emojisData]) }, [emojisData])
const listEmpty = useMemo(() => { const listEmpty = useMemo(() => {
if (isFetching) { if (isFetching) {
return ( return (
<View key='listEmpty' style={styles.loading}> <View key='listEmpty' style={styles.loading}>
<Circle <Circle
size={StyleConstants.Font.Size.M * 1.25} size={StyleConstants.Font.Size.M * 1.25}
color={theme.secondary} color={theme.secondary}
/> />
</View> </View>
) )
} }
}, [isFetching]) }, [isFetching])
const listItem = useCallback( const listItem = useCallback(
({ item }) => ( ({ item }) => (
<ComposeRootSuggestion <ComposeRootSuggestion
item={item} item={item}
composeState={composeState} composeState={composeState}
composeDispatch={composeDispatch} composeDispatch={composeDispatch}
/> />
), ),
[composeState] [composeState]
) )
return ( return (
<View style={styles.base}> <View style={styles.base}>
<FlatList <FlatList
renderItem={listItem} renderItem={listItem}
ListEmptyComponent={listEmpty} ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='handled' keyboardShouldPersistTaps='always'
ListHeaderComponent={ComposeRootHeader} ListHeaderComponent={ComposeRootHeader}
ListFooterComponent={ComposeRootFooter} ListFooterComponent={ComposeRootFooter}
ItemSeparatorComponent={ComponentSeparator} ItemSeparatorComponent={ComponentSeparator}
// @ts-ignore // @ts-ignore
data={data ? data[composeState.tag?.type] : undefined} data={data ? data[composeState.tag?.type] : undefined}
keyExtractor={() => Math.random().toString()} keyExtractor={() => Math.random().toString()}
/> />
<ComposeActions /> <ComposeActions />
<ComposeDrafts /> <ComposeDrafts />
<ComposePosting /> <ComposePosting />
</View> </View>
) )
} },
() => true
)
const styles = StyleSheet.create({ const styles = StyleSheet.create({
base: { base: {

View File

@ -246,7 +246,7 @@ const ComposeAttachments: React.FC = () => {
snapToAlignment='center' snapToAlignment='center'
renderItem={renderAttachment} renderItem={renderAttachment}
snapToOffsets={snapToOffsets} snapToOffsets={snapToOffsets}
keyboardShouldPersistTaps='handled' keyboardShouldPersistTaps='always'
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
data={composeState.attachments.uploads} data={composeState.attachments.uploads}
keyExtractor={item => keyExtractor={item =>

View File

@ -76,7 +76,7 @@ const ComposeEmojis: React.FC = () => {
<View style={styles.base}> <View style={styles.base}>
<SectionList <SectionList
horizontal horizontal
keyboardShouldPersistTaps='handled' keyboardShouldPersistTaps='always'
sections={composeState.emoji.emojis || []} sections={composeState.emoji.emojis || []}
keyExtractor={item => item.shortcode} keyExtractor={item => item.shortcode}
renderSectionHeader={listHeader} renderSectionHeader={listHeader}

View File

@ -46,7 +46,7 @@ const ComposeSpoilerInput: React.FC = () => {
}) })
}} }}
ref={composeState.textInputFocus.refs.spoiler} ref={composeState.textInputFocus.refs.spoiler}
scrollEnabled scrollEnabled={false}
onFocus={() => onFocus={() =>
composeDispatch({ composeDispatch({
type: 'textInputFocus', type: 'textInputFocus',

View File

@ -52,7 +52,7 @@ const ComposeTextInput: React.FC = () => {
}) })
}} }}
ref={composeState.textInputFocus.refs.text} ref={composeState.textInputFocus.refs.text}
scrollEnabled scrollEnabled={false}
> >
<Text>{composeState.text.formatted}</Text> <Text>{composeState.text.formatted}</Text>
</TextInput> </TextInput>

View File

@ -86,9 +86,9 @@ const HeaderComponent = React.memo(
analytics('imageviewer_more_share_press') analytics('imageviewer_more_share_press')
switch (Platform.OS) { switch (Platform.OS) {
case 'ios': case 'ios':
return Share.share({ url: imageUrls[currentIndex].url }) Share.share({ url: imageUrls[currentIndex].url })
case 'android': case 'android':
return Share.share({ message: imageUrls[currentIndex].url }) Share.share({ message: imageUrls[currentIndex].url })
} }
break break
} }

View File

@ -54,7 +54,7 @@ const ScreenMeSwitchRoot: React.FC = () => {
const instanceActive = useSelector(getInstanceActive) const instanceActive = useSelector(getInstanceActive)
return ( return (
<ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> <ScrollView style={styles.base} keyboardShouldPersistTaps='always'>
<View style={[styles.firstSection, { borderBottomColor: theme.border }]}> <View style={[styles.firstSection, { borderBottomColor: theme.border }]}>
<Text style={[styles.header, { color: theme.primary }]}> <Text style={[styles.header, { color: theme.primary }]}>
{t('content.existing')} {t('content.existing')}