mirror of
https://github.com/tooot-app/app
synced 2025-04-24 07:07:24 +02:00
Merge branch 'main' into l10n_main
This commit is contained in:
commit
a728871ac6
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@ -19,17 +19,22 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16
|
||||||
- name: -- Step 3 -- Use Expo action
|
- name: -- Step 3 -- Setup Java
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'zulu'
|
||||||
|
java-version: '11'
|
||||||
|
- name: -- Step 4 -- Use Expo action
|
||||||
uses: expo/expo-github-action@v6
|
uses: expo/expo-github-action@v6
|
||||||
with:
|
with:
|
||||||
expo-version: 5.x
|
expo-version: 5.x
|
||||||
username: ${{ secrets.EXPO_USERNAME }}
|
username: ${{ secrets.EXPO_USERNAME }}
|
||||||
token: ${{ secrets.EXPO_TOKEN }}
|
token: ${{ secrets.EXPO_TOKEN }}
|
||||||
- name: -- Step 4 -- Install node dependencies
|
- name: -- Step 5 -- Install node dependencies
|
||||||
run: yarn install
|
run: yarn install
|
||||||
- name: -- Step 5 -- Install ruby dependencies
|
- name: -- Step 6 -- Install ruby dependencies
|
||||||
run: bundle install
|
run: bundle install
|
||||||
- name: -- Step 6 -- Run fastlane
|
- name: -- Step 7 -- Run fastlane
|
||||||
env:
|
env:
|
||||||
DEVELOPER_DIR: /Applications/Xcode_13.3.1.app/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_13.3.1.app/Contents/Developer
|
||||||
ENVIRONMENT: ${{ steps.branch.outputs.branch }}
|
ENVIRONMENT: ${{ steps.branch.outputs.branch }}
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
toBeDisabled,
|
|
||||||
toHaveStyle,
|
|
||||||
toHaveTextContent
|
|
||||||
} from '@testing-library/jest-native'
|
|
||||||
import { cleanup, fireEvent, render } from '@testing-library/react-native/pure'
|
|
||||||
|
|
||||||
import Button from '@components/Button'
|
|
||||||
|
|
||||||
expect.extend({ toBeDisabled, toHaveStyle, toHaveTextContent })
|
|
||||||
|
|
||||||
describe('Testing component button', () => {
|
|
||||||
afterEach(cleanup)
|
|
||||||
|
|
||||||
describe('static button', () => {
|
|
||||||
it('with text only', () => {
|
|
||||||
const onPress = jest.fn()
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<Button type='text' content='Test Button' onPress={onPress} />
|
|
||||||
)
|
|
||||||
fireEvent.press(getByTestId('base'))
|
|
||||||
|
|
||||||
expect(onPress).toHaveBeenCalled()
|
|
||||||
expect(onPress).toHaveBeenCalledTimes(1)
|
|
||||||
expect(getByTestId('text')).toHaveTextContent('Test Button')
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('with icon only', () => {
|
|
||||||
const onPress = jest.fn()
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<Button type='icon' content='X' onPress={onPress} />
|
|
||||||
)
|
|
||||||
fireEvent.press(getByTestId('base'))
|
|
||||||
|
|
||||||
expect(onPress).toHaveBeenCalled()
|
|
||||||
expect(onPress).toHaveBeenCalledTimes(1)
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('loading state', () => {
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<Button type='text' content='test' onPress={jest.fn()} loading />
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(getByTestId('base')).toBeDisabled()
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('disabled state', () => {
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<Button type='text' content='test' onPress={jest.fn()} disabled />
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(getByTestId('base')).toBeDisabled()
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('apply custom styling', () => {
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<Button
|
|
||||||
type='text'
|
|
||||||
content='test'
|
|
||||||
onPress={jest.fn()}
|
|
||||||
style={{ backgroundColor: 'black' }}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(getByTestId('base')).toHaveStyle({ backgroundColor: 'black' })
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('dynamic button', () => {
|
|
||||||
it('from default to loading', () => {
|
|
||||||
const onPress = jest.fn()
|
|
||||||
const { getByTestId, rerender } = render(
|
|
||||||
<Button type='text' content='test' onPress={onPress} />
|
|
||||||
)
|
|
||||||
rerender(<Button type='text' content='test' onPress={onPress} loading />)
|
|
||||||
|
|
||||||
expect(getByTestId('base')).toBeDisabled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('from default to disabled', () => {
|
|
||||||
const onPress = jest.fn()
|
|
||||||
const { getByTestId, rerender } = render(
|
|
||||||
<Button type='text' content='test' onPress={onPress} />
|
|
||||||
)
|
|
||||||
rerender(<Button type='text' content='test' onPress={onPress} disabled />)
|
|
||||||
|
|
||||||
expect(getByTestId('base')).toBeDisabled()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,15 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { cleanup, render } from '@testing-library/react-native/pure'
|
|
||||||
|
|
||||||
import MenuHeader from '@components/Menu/Header'
|
|
||||||
|
|
||||||
describe('Testing component menu header', () => {
|
|
||||||
afterEach(cleanup)
|
|
||||||
|
|
||||||
it('with text only', () => {
|
|
||||||
const { getByText, toJSON } = render(<MenuHeader heading='test' />)
|
|
||||||
|
|
||||||
getByText('test')
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,50 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { toBeDisabled } from '@testing-library/jest-native'
|
|
||||||
import { cleanup, fireEvent, render } from '@testing-library/react-native'
|
|
||||||
|
|
||||||
import MenuRow from '@components/Menu/Row'
|
|
||||||
|
|
||||||
expect.extend({ toBeDisabled })
|
|
||||||
|
|
||||||
describe('Testing component menu row', () => {
|
|
||||||
afterEach(cleanup)
|
|
||||||
|
|
||||||
it('with title only', () => {
|
|
||||||
const { getByText, toJSON } = render(<MenuRow title='test title' />)
|
|
||||||
getByText('test title')
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('with title and content', () => {
|
|
||||||
const { getByText, toJSON } = render(
|
|
||||||
<MenuRow title='test title' content='test content' />
|
|
||||||
)
|
|
||||||
getByText('test title')
|
|
||||||
getByText('test content')
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('on press event', () => {
|
|
||||||
const onPress = jest.fn()
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<MenuRow title='test' onPress={onPress} />
|
|
||||||
)
|
|
||||||
fireEvent.press(getByTestId('base'))
|
|
||||||
|
|
||||||
expect(onPress).toHaveBeenCalled()
|
|
||||||
expect(onPress).toHaveBeenCalledTimes(1)
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('loading state', () => {
|
|
||||||
const onPress = jest.fn()
|
|
||||||
const { getByTestId, toJSON } = render(
|
|
||||||
<MenuRow title='test' loading onPress={onPress} />
|
|
||||||
)
|
|
||||||
fireEvent.press(getByTestId('base'))
|
|
||||||
|
|
||||||
expect(onPress).toHaveBeenCalledTimes(0)
|
|
||||||
expect(getByTestId('base')).toBeDisabled()
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,30 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Testing component menu header with text only 1`] = `
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"paddingBottom": 8,
|
|
||||||
"paddingLeft": 16,
|
|
||||||
"paddingRight": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontSize": 14,
|
|
||||||
"fontWeight": "600",
|
|
||||||
"lineHeight": 20,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(135, 135, 135)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
`;
|
|
@ -1,302 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Testing component menu row loading state 1`] = `
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"minHeight": 50,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"paddingLeft": 16,
|
|
||||||
"paddingRight": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"flex": 2,
|
|
||||||
"flexDirection": "row",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontSize": 16,
|
|
||||||
"lineHeight": 22,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component menu row on press event 1`] = `
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"minHeight": 50,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"paddingLeft": 16,
|
|
||||||
"paddingRight": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"flex": 2,
|
|
||||||
"flexDirection": "row",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontSize": 16,
|
|
||||||
"lineHeight": 22,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component menu row with title and content 1`] = `
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"minHeight": 50,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"paddingLeft": 16,
|
|
||||||
"paddingRight": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"flex": 2,
|
|
||||||
"flexDirection": "row",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontSize": 16,
|
|
||||||
"lineHeight": 22,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test title
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "flex-end",
|
|
||||||
"marginLeft": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontSize": 16,
|
|
||||||
"lineHeight": 22,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(135, 135, 135)",
|
|
||||||
"opacity": 1,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test content
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component menu row with title only 1`] = `
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"minHeight": 50,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"paddingLeft": 16,
|
|
||||||
"paddingRight": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"flex": 2,
|
|
||||||
"flexDirection": "row",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontSize": 16,
|
|
||||||
"lineHeight": 22,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test title
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
@ -1,59 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import {
|
|
||||||
toBeDisabled,
|
|
||||||
toContainElement,
|
|
||||||
toHaveStyle,
|
|
||||||
toHaveTextContent
|
|
||||||
} from '@testing-library/jest-native'
|
|
||||||
import { cleanup, render } from '@testing-library/react-native/pure'
|
|
||||||
|
|
||||||
import Card from '@components/Timelines/Timeline/Shared/Card'
|
|
||||||
|
|
||||||
expect.extend({
|
|
||||||
toBeDisabled,
|
|
||||||
toContainElement,
|
|
||||||
toHaveStyle,
|
|
||||||
toHaveTextContent
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Testing component timeline card', () => {
|
|
||||||
afterEach(cleanup)
|
|
||||||
|
|
||||||
it('with text only', () => {
|
|
||||||
const { getByTestId, queryByTestId, toJSON } = render(
|
|
||||||
<Card
|
|
||||||
card={{
|
|
||||||
url: 'http://example.com',
|
|
||||||
title: 'Title'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(queryByTestId('image')).toBeNull()
|
|
||||||
expect(getByTestId('base')).toContainElement(getByTestId('title'))
|
|
||||||
expect(queryByTestId('description')).toBeNull()
|
|
||||||
|
|
||||||
expect(getByTestId('title')).toHaveTextContent('Title')
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('with text and description', () => {
|
|
||||||
const { getByTestId, queryByTestId, toJSON } = render(
|
|
||||||
<Card
|
|
||||||
card={{
|
|
||||||
url: 'http://example.com',
|
|
||||||
title: 'Title',
|
|
||||||
description: 'Description'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(queryByTestId('image')).toBeNull()
|
|
||||||
expect(getByTestId('base')).toContainElement(getByTestId('title'))
|
|
||||||
expect(getByTestId('base')).toContainElement(getByTestId('description'))
|
|
||||||
|
|
||||||
expect(getByTestId('title')).toHaveTextContent('Title')
|
|
||||||
expect(getByTestId('description')).toHaveTextContent('Description')
|
|
||||||
expect(toJSON()).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,155 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Testing component timeline card with text and description 1`] = `
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"borderRadius": 6,
|
|
||||||
"borderWidth": 0.5,
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"height": 104,
|
|
||||||
"marginTop": 16,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"borderColor": "rgba(18, 18, 18, 0.3)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"padding": 8,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={2}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontWeight": "600",
|
|
||||||
"marginBottom": 4,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="title"
|
|
||||||
>
|
|
||||||
Title
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"marginBottom": 4,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="description"
|
|
||||||
>
|
|
||||||
Description
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "rgb(135, 135, 135)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
http://example.com
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component timeline card with text only 1`] = `
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"borderRadius": 6,
|
|
||||||
"borderWidth": 0.5,
|
|
||||||
"flex": 1,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"height": 104,
|
|
||||||
"marginTop": 16,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"borderColor": "rgba(18, 18, 18, 0.3)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"padding": 8,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
numberOfLines={2}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"fontWeight": "600",
|
|
||||||
"marginBottom": 4,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="title"
|
|
||||||
>
|
|
||||||
Title
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "rgb(135, 135, 135)",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
http://example.com
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
@ -1,474 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Testing component button static button apply custom styling 1`] = `
|
|
||||||
<View>
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"borderRadius": 100,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "center",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(250, 250, 250)",
|
|
||||||
"borderColor": "rgb(18, 18, 18)",
|
|
||||||
"borderWidth": 1,
|
|
||||||
"paddingHorizontal": 16,
|
|
||||||
"paddingVertical": 8,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "black",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
"fontSize": 16,
|
|
||||||
"fontWeight": undefined,
|
|
||||||
"opacity": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="text"
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component button static button disabled state 1`] = `
|
|
||||||
<View>
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"borderRadius": 100,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "center",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(250, 250, 250)",
|
|
||||||
"borderColor": "rgb(135, 135, 135)",
|
|
||||||
"borderWidth": 1,
|
|
||||||
"paddingHorizontal": 16,
|
|
||||||
"paddingVertical": 8,
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "rgb(135, 135, 135)",
|
|
||||||
"fontSize": 16,
|
|
||||||
"fontWeight": undefined,
|
|
||||||
"opacity": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="text"
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component button static button loading state 1`] = `
|
|
||||||
<View>
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"borderRadius": 100,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "center",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(250, 250, 250)",
|
|
||||||
"borderColor": "rgb(135, 135, 135)",
|
|
||||||
"borderWidth": 1,
|
|
||||||
"paddingHorizontal": 16,
|
|
||||||
"paddingVertical": 8,
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
"fontSize": 16,
|
|
||||||
"fontWeight": undefined,
|
|
||||||
"opacity": 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="text"
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Text>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"position": "absolute",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"height": 16,
|
|
||||||
"justifyContent": "center",
|
|
||||||
"opacity": 1,
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "0deg",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(135, 135, 135)",
|
|
||||||
"borderRadius": 2,
|
|
||||||
"height": 4,
|
|
||||||
"position": "absolute",
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "73.27536734311887deg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"translateY": -6,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"scale": 0.7,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(135, 135, 135)",
|
|
||||||
"borderRadius": 2,
|
|
||||||
"height": 4,
|
|
||||||
"position": "absolute",
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "46.49829517703514deg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"translateY": -6,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"scale": 0.8008696779414123,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(135, 135, 135)",
|
|
||||||
"borderRadius": 2,
|
|
||||||
"height": 4,
|
|
||||||
"position": "absolute",
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "25.743213498935145deg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"translateY": -6,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"scale": 0.8875624559768125,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(135, 135, 135)",
|
|
||||||
"borderRadius": 2,
|
|
||||||
"height": 4,
|
|
||||||
"position": "absolute",
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "11.201058030774364deg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"translateY": -6,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"scale": 0.9510040862404615,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(135, 135, 135)",
|
|
||||||
"borderRadius": 2,
|
|
||||||
"height": 4,
|
|
||||||
"position": "absolute",
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "2.731234791722257deg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"translateY": -6,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"scale": 0.9881665278710133,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(135, 135, 135)",
|
|
||||||
"borderRadius": 2,
|
|
||||||
"height": 4,
|
|
||||||
"position": "absolute",
|
|
||||||
"transform": Array [
|
|
||||||
Object {
|
|
||||||
"rotate": "0deg",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"translateY": -6,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"scale": 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"width": 4,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component button static button with icon only 1`] = `
|
|
||||||
<View>
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"borderRadius": 100,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "center",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(250, 250, 250)",
|
|
||||||
"borderColor": "rgb(18, 18, 18)",
|
|
||||||
"borderWidth": 1,
|
|
||||||
"paddingHorizontal": 16,
|
|
||||||
"paddingVertical": 8,
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"opacity": 1,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"height": 16,
|
|
||||||
"justifyContent": "center",
|
|
||||||
"width": 16,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<RNSVGSvgView
|
|
||||||
align="xMidYMid"
|
|
||||||
bbHeight={16}
|
|
||||||
bbWidth={16}
|
|
||||||
className=""
|
|
||||||
color={4279374354}
|
|
||||||
focusable={false}
|
|
||||||
height={16}
|
|
||||||
meetOrSlice={0}
|
|
||||||
minX={0}
|
|
||||||
minY={0}
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth={2}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "transparent",
|
|
||||||
"borderWidth": 0,
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"flex": 0,
|
|
||||||
"height": 16,
|
|
||||||
"width": 16,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
tintColor={4279374354}
|
|
||||||
vbHeight={24}
|
|
||||||
vbWidth={24}
|
|
||||||
width={16}
|
|
||||||
>
|
|
||||||
<RNSVGGroup
|
|
||||||
propList={
|
|
||||||
Array [
|
|
||||||
"stroke",
|
|
||||||
"strokeWidth",
|
|
||||||
"strokeLinecap",
|
|
||||||
"strokeLinejoin",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
stroke={
|
|
||||||
Array [
|
|
||||||
2,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
strokeLinecap={1}
|
|
||||||
strokeLinejoin={1}
|
|
||||||
strokeWidth={2}
|
|
||||||
>
|
|
||||||
<RNSVGPath
|
|
||||||
d="M18 6L6 18M6 6l12 12"
|
|
||||||
/>
|
|
||||||
</RNSVGGroup>
|
|
||||||
</RNSVGSvgView>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Testing component button static button with text only 1`] = `
|
|
||||||
<View>
|
|
||||||
<View
|
|
||||||
accessible={true}
|
|
||||||
focusable={true}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onResponderGrant={[Function]}
|
|
||||||
onResponderMove={[Function]}
|
|
||||||
onResponderRelease={[Function]}
|
|
||||||
onResponderTerminate={[Function]}
|
|
||||||
onResponderTerminationRequest={[Function]}
|
|
||||||
onStartShouldSetResponder={[Function]}
|
|
||||||
style={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"alignItems": "center",
|
|
||||||
"borderRadius": 100,
|
|
||||||
"flexDirection": "row",
|
|
||||||
"justifyContent": "center",
|
|
||||||
},
|
|
||||||
Object {
|
|
||||||
"backgroundColor": "rgb(250, 250, 250)",
|
|
||||||
"borderColor": "rgb(18, 18, 18)",
|
|
||||||
"borderWidth": 1,
|
|
||||||
"paddingHorizontal": 16,
|
|
||||||
"paddingVertical": 8,
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
testID="base"
|
|
||||||
>
|
|
||||||
<Text
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "rgb(18, 18, 18)",
|
|
||||||
"fontSize": 16,
|
|
||||||
"fontWeight": undefined,
|
|
||||||
"opacity": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testID="text"
|
|
||||||
>
|
|
||||||
Test Button
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
`;
|
|
@ -1,6 +1,7 @@
|
|||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
|
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||||
@ -79,7 +80,6 @@ import com.android.build.OutputFile
|
|||||||
|
|
||||||
project.ext.react = [
|
project.ext.react = [
|
||||||
enableHermes: (findProperty('expo.jsEngine') ?: "jsc") == "hermes",
|
enableHermes: (findProperty('expo.jsEngine') ?: "jsc") == "hermes",
|
||||||
cliPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute().text.trim(), "../cli.js")
|
|
||||||
]
|
]
|
||||||
|
|
||||||
apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute().text.trim(), "../react.gradle")
|
apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute().text.trim(), "../react.gradle")
|
||||||
@ -121,6 +121,14 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
|||||||
*/
|
*/
|
||||||
def enableHermes = project.ext.react.get("enableHermes", true);
|
def enableHermes = project.ext.react.get("enableHermes", true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architectures to build native code for.
|
||||||
|
*/
|
||||||
|
def reactNativeArchitectures() {
|
||||||
|
def value = project.getProperties().get("reactNativeArchitectures")
|
||||||
|
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
ndkVersion rootProject.ext.ndkVersion
|
ndkVersion rootProject.ext.ndkVersion
|
||||||
|
|
||||||
@ -137,17 +145,86 @@ android {
|
|||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 50
|
versionCode 50
|
||||||
versionName "0.2"
|
versionName "0.2"
|
||||||
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||||
|
if (isNewArchitectureEnabled()) {
|
||||||
|
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_PLATFORM=android-21",
|
||||||
|
"APP_STL=c++_shared",
|
||||||
|
"NDK_TOOLCHAIN_VERSION=clang",
|
||||||
|
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||||
|
"PROJECT_BUILD_DIR=$buildDir",
|
||||||
|
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||||
|
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
|
||||||
|
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||||
|
cppFlags "-std=c++17"
|
||||||
|
// Make sure this target name is the same you specify inside the
|
||||||
|
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||||
|
targets "tooot_appmodules"
|
||||||
|
// Fix for windows limit on number of character in file paths and in command lines
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
arguments "NDK_OUT=${rootProject.projectDir.getParent()}\\.cxx",
|
||||||
|
"NDK_APP_SHORT_COMMANDS=true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!enableSeparateBuildPerCPUArchitecture) {
|
||||||
|
ndk {
|
||||||
|
abiFilters (*reactNativeArchitectures())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
expoSDK: project.hasProperty('expoSDK') ? project.property('expoSDK') : "",
|
expoSDK: project.hasProperty('expoSDK') ? project.property('expoSDK') : "",
|
||||||
releaseChannel: project.hasProperty('releaseChannel') ? project.property('releaseChannel') : "default"
|
releaseChannel: project.hasProperty('releaseChannel') ? project.property('releaseChannel') : "default"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
if (isNewArchitectureEnabled()) {
|
||||||
|
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
path "$projectDir/src/main/jni/Android.mk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
|
||||||
|
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
|
||||||
|
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
|
||||||
|
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||||
|
into("$buildDir/react-ndk/exported")
|
||||||
|
}
|
||||||
|
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
|
||||||
|
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
|
||||||
|
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||||
|
into("$buildDir/react-ndk/exported")
|
||||||
|
}
|
||||||
|
afterEvaluate {
|
||||||
|
// If you wish to add a custom TurboModule or component locally,
|
||||||
|
// you should uncomment this line.
|
||||||
|
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
||||||
|
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||||
|
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||||
|
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||||
|
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||||
|
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||||
|
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||||
|
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||||
|
reactNativeArchitectures().each { architecture ->
|
||||||
|
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
|
||||||
|
dependsOn("preDebugBuild")
|
||||||
|
}
|
||||||
|
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
|
||||||
|
dependsOn("preReleaseBuild")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
splits {
|
splits {
|
||||||
abi {
|
abi {
|
||||||
reset()
|
reset()
|
||||||
enable enableSeparateBuildPerCPUArchitecture
|
enable enableSeparateBuildPerCPUArchitecture
|
||||||
universalApk false // If true, also generate a universal APK
|
universalApk false // If true, also generate a universal APK
|
||||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
include (*reactNativeArchitectures())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
@ -241,14 +318,34 @@ dependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isNewArchitectureEnabled()) {
|
||||||
|
// If new architecture is enabled, we let you build RN from source
|
||||||
|
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
|
||||||
|
// This will be applied to all the imported transtitive dependency.
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy.dependencySubstitution {
|
||||||
|
substitute(module("com.facebook.react:react-native"))
|
||||||
|
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run this once to be able to run the application with BUCK
|
// Run this once to be able to run the application with BUCK
|
||||||
// puts all compile dependencies into folder libs for BUCK to use
|
// puts all compile dependencies into folder libs for BUCK to use
|
||||||
task copyDownloadableDepsToLibs(type: Copy) {
|
task copyDownloadableDepsToLibs(type: Copy) {
|
||||||
from configurations.compile
|
from configurations.implementation
|
||||||
into 'libs'
|
into 'libs'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute().text.trim(), "../native_modules.gradle");
|
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute().text.trim(), "../native_modules.gradle");
|
||||||
applyNativeModulesAppBuildGradle(project)
|
applyNativeModulesAppBuildGradle(project)
|
||||||
|
|
||||||
|
def isNewArchitectureEnabled() {
|
||||||
|
// To opt-in for the New Architecture, you can either:
|
||||||
|
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
||||||
|
// - Invoke gradle with `-newArchEnabled=true`
|
||||||
|
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||||
|
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||||
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
@ -7,6 +7,6 @@
|
|||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
tools:targetApi="28"
|
tools:targetApi="28"
|
||||||
tools:ignore="GoogleAppIndexingWarning">
|
tools:ignore="GoogleAppIndexingWarning">
|
||||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -19,6 +19,7 @@ import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
|||||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||||
|
import com.facebook.react.ReactInstanceEventListener;
|
||||||
import com.facebook.react.ReactInstanceManager;
|
import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.bridge.ReactContext;
|
import com.facebook.react.bridge.ReactContext;
|
||||||
import com.facebook.react.modules.network.NetworkingModule;
|
import com.facebook.react.modules.network.NetworkingModule;
|
||||||
@ -48,7 +49,7 @@ public class ReactNativeFlipper {
|
|||||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||||
if (reactContext == null) {
|
if (reactContext == null) {
|
||||||
reactInstanceManager.addReactInstanceEventListener(
|
reactInstanceManager.addReactInstanceEventListener(
|
||||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
new ReactInstanceEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onReactContextInitialized(ReactContext reactContext) {
|
public void onReactContextInitialized(ReactContext reactContext) {
|
||||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
|
<meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
|
||||||
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
<meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
|
||||||
<activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:screenOrientation="portrait" android:documentLaunchMode="never">
|
<activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:exported="true" android:theme="@style/Theme.App.SplashScreen" android:screenOrientation="portrait" android:documentLaunchMode="never">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
@ -13,12 +13,33 @@ public class MainActivity extends ReactActivity {
|
|||||||
super.onCreate(null);
|
super.onCreate(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the main component registered from JavaScript.
|
* Returns the name of the main component registered from JavaScript.
|
||||||
* This is used to schedule rendering of the component.
|
* This is used to schedule rendering of the component.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getMainComponentName() {
|
protected String getMainComponentName() {
|
||||||
return "main";
|
return "main";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
|
||||||
|
* you can specify the rendered you wish to use (Fabric or the older renderer).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||||
|
return new ReactActivityDelegateWrapper(this, new MainActivityDelegate(this, getMainComponentName()));
|
||||||
|
}
|
||||||
|
public static class MainActivityDelegate extends ReactActivityDelegate {
|
||||||
|
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
|
||||||
|
super(activity, mainComponentName);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected ReactRootView createRootView() {
|
||||||
|
ReactRootView reactRootView = new ReactRootView(getContext());
|
||||||
|
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||||
|
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
|
||||||
|
return reactRootView;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import com.facebook.react.ReactApplication;
|
|||||||
import com.facebook.react.ReactInstanceManager;
|
import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.config.ReactFeatureFlags;
|
||||||
import com.facebook.react.shell.MainReactPackage;
|
import com.facebook.react.shell.MainReactPackage;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
|
|
||||||
@ -54,12 +55,19 @@ public class MainApplication extends Application implements ReactApplication {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReactNativeHost getReactNativeHost() {
|
public ReactNativeHost getReactNativeHost() {
|
||||||
|
// if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||||
|
// return mNewArchitectureNativeHost;
|
||||||
|
// } else {
|
||||||
|
// return mReactNativeHost;
|
||||||
|
// }
|
||||||
return mReactNativeHost;
|
return mReactNativeHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||||
|
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||||
SoLoader.init(this, /* native exopackage */ false);
|
SoLoader.init(this, /* native exopackage */ false);
|
||||||
|
|
||||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
|
@ -1,13 +1,24 @@
|
|||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
buildToolsVersion = "30.0.2"
|
buildToolsVersion = "31.0.0"
|
||||||
minSdkVersion = 21
|
minSdkVersion = 21
|
||||||
compileSdkVersion = 30
|
compileSdkVersion = 31
|
||||||
targetSdkVersion = 30
|
targetSdkVersion = 31
|
||||||
ndkVersion = "21.4.7075529"
|
if (System.properties['os.arch'] == "aarch64") {
|
||||||
kotlinVersion = '1.5.32'
|
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||||
|
ndkVersion = "24.0.8215888"
|
||||||
|
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
// For Android Users, we need to use NDK 23, otherwise the build will
|
||||||
|
// fail due to paths longer than the OS limit
|
||||||
|
ndkVersion = "23.1.7779620"
|
||||||
|
} else {
|
||||||
|
// Otherwise we default to the side-by-side NDK version from AGP.
|
||||||
|
ndkVersion = "21.4.7075529"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
@ -16,7 +27,9 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.google.gms:google-services:4.3.3'
|
classpath 'com.google.gms:google-services:4.3.3'
|
||||||
classpath("com.android.tools.build:gradle:4.2.0")
|
classpath("com.android.tools.build:gradle:7.0.4")
|
||||||
|
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||||
|
classpath("de.undercouch:gradle-download-task:4.1.2")
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
@ -26,7 +26,18 @@ android.useAndroidX=true
|
|||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
# Version of flipper SDK to use with React Native
|
# Version of flipper SDK to use with React Native
|
||||||
FLIPPER_VERSION=0.75.1
|
FLIPPER_VERSION=0.125.0
|
||||||
|
|
||||||
|
# Use this property to specify which architecture you want to build.
|
||||||
|
# You can also override it from the CLI using
|
||||||
|
# ./gradlew <task> -PreactNativeArchitectures=x86_64
|
||||||
|
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
|
||||||
|
# Use this property to enable support to the new architecture.
|
||||||
|
# This will allow you to use TurboModules and the Fabric render in
|
||||||
|
# your application. You should enable this flag either if you want
|
||||||
|
# to write custom TurboModules/Fabric components OR use libraries that
|
||||||
|
# are providing them.
|
||||||
|
newArchEnabled=false
|
||||||
|
|
||||||
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=4096m -XX:+HeapDumpOnOutOfMemoryError
|
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=4096m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
|
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
213
android/gradlew
vendored
213
android/gradlew
vendored
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright 2015 the original author or authors.
|
||||||
@ -24,60 +24,51 @@
|
|||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
# Need this for daisy-chained symlinks.
|
||||||
while [ -h "$PRG" ] ; do
|
while
|
||||||
ls=`ls -ld "$PRG"`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
[ -h "$app_path" ]
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
do
|
||||||
PRG="$link"
|
ls=$( ls -ld "$app_path" )
|
||||||
else
|
link=${ls#*' -> '}
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
case $link in #(
|
||||||
fi
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
@ -86,9 +77,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@ -97,7 +88,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@ -105,79 +96,91 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
warn "Could not query maximum file descriptor limit"
|
||||||
fi
|
esac
|
||||||
ulimit -n $MAX_FD
|
case $MAX_FD in #(
|
||||||
if [ $? -ne 0 ] ; then
|
'' | soft) :;; #(
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
*)
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
else
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
@ -7,3 +7,9 @@ apply from: new File(["node", "--print", "require.resolve('@react-native-communi
|
|||||||
applyNativeModulesSettingsGradle(settings)
|
applyNativeModulesSettingsGradle(settings)
|
||||||
|
|
||||||
include ':app'
|
include ':app'
|
||||||
|
|
||||||
|
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||||
|
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
|
||||||
|
include(":ReactAndroid")
|
||||||
|
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ export default (): ExpoConfig => ({
|
|||||||
android: {
|
android: {
|
||||||
package: 'com.xmflsct.app.tooot',
|
package: 'com.xmflsct.app.tooot',
|
||||||
googleServicesFile: './configs/google-services.json',
|
googleServicesFile: './configs/google-services.json',
|
||||||
permissions: ['CAMERA', 'VIBRATE']
|
permissions: ['CAMERA', 'VIBRATE'],
|
||||||
|
blockedPermissions: ['USE_BIOMETRIC', 'USE_FINGERPRINT']
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -123,7 +123,7 @@ private_lane :build_ios do
|
|||||||
end
|
end
|
||||||
|
|
||||||
desc "Build and deploy Android app"
|
desc "Build and deploy Android app"
|
||||||
lane :build_android do
|
private_lane :build_android do
|
||||||
sh("echo #{ENV["ANDROID_KEYSTORE"]} | base64 -d | tee #{File.expand_path('..', Dir.pwd)}/android/tooot.jks >/dev/null", log: false)
|
sh("echo #{ENV["ANDROID_KEYSTORE"]} | base64 -d | tee #{File.expand_path('..', Dir.pwd)}/android/tooot.jks >/dev/null", log: false)
|
||||||
|
|
||||||
case ENVIRONMENT
|
case ENVIRONMENT
|
||||||
|
17
ios/Podfile
17
ios/Podfile
@ -3,17 +3,32 @@ require File.join(File.dirname(`node --print "require.resolve('react-native/pack
|
|||||||
require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules")
|
require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules")
|
||||||
|
|
||||||
platform :ios, '12.0'
|
platform :ios, '12.0'
|
||||||
|
install! 'cocoapods', :deterministic_uuids => false
|
||||||
|
|
||||||
require 'json'
|
require 'json'
|
||||||
podfile_properties = JSON.parse(File.read('./Podfile.properties.json')) rescue {}
|
podfile_properties = JSON.parse(File.read('./Podfile.properties.json')) rescue {}
|
||||||
|
|
||||||
target 'tooot' do
|
target 'tooot' do
|
||||||
use_expo_modules!
|
use_expo_modules!
|
||||||
|
post_integrate do |installer|
|
||||||
|
begin
|
||||||
|
expo_patch_react_imports!(installer)
|
||||||
|
rescue => e
|
||||||
|
Pod::UI.warn e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
config = use_native_modules!
|
config = use_native_modules!
|
||||||
|
|
||||||
|
# Flags change depending on the env values.
|
||||||
|
flags = get_default_flags()
|
||||||
|
|
||||||
use_react_native!(
|
use_react_native!(
|
||||||
:path => config[:reactNativePath],
|
:path => config[:reactNativePath],
|
||||||
:hermes_enabled => podfile_properties['expo.jsEngine'] == 'hermes'
|
:hermes_enabled => podfile_properties['expo.jsEngine'] == 'hermes',
|
||||||
|
:fabric_enabled => flags[:fabric_enabled],
|
||||||
|
# An absolute path to your application root.
|
||||||
|
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||||
)
|
)
|
||||||
|
|
||||||
# Enables Flipper.
|
# Enables Flipper.
|
||||||
|
817
ios/Podfile.lock
817
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,6 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
|
||||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
@ -20,6 +19,7 @@
|
|||||||
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
|
||||||
DA8B5B7F0DED488CAC0FF169 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */; };
|
DA8B5B7F0DED488CAC0FF169 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */; };
|
||||||
E3BC22F5F8ABE515E14CF199 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D878F932AF7A9974E06E461 /* ExpoModulesProvider.swift */; };
|
E3BC22F5F8ABE515E14CF199 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D878F932AF7A9974E06E461 /* ExpoModulesProvider.swift */; };
|
||||||
|
E613A80B28282A01003C97D6 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E613A80A28282A01003C97D6 /* AppDelegate.mm */; };
|
||||||
E633A42B281EAEAB000E540F /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E633A420281EAEAB000E540F /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
E633A42B281EAEAB000E540F /* ShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E633A420281EAEAB000E540F /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
E633A430281EAF38000E540F /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E633A42F281EAF38000E540F /* ShareViewController.swift */; };
|
E633A430281EAF38000E540F /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E633A42F281EAF38000E540F /* ShareViewController.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
@ -52,7 +52,6 @@
|
|||||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||||
13B07F961A680F5B00A75B9A /* tooot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = tooot.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
13B07F961A680F5B00A75B9A /* tooot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = tooot.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = tooot/AppDelegate.h; sourceTree = "<group>"; };
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = tooot/AppDelegate.h; sourceTree = "<group>"; };
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = tooot/AppDelegate.m; sourceTree = "<group>"; };
|
|
||||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = tooot/Images.xcassets; sourceTree = "<group>"; };
|
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = tooot/Images.xcassets; sourceTree = "<group>"; };
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = tooot/Info.plist; sourceTree = "<group>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = tooot/Info.plist; sourceTree = "<group>"; };
|
||||||
@ -72,6 +71,7 @@
|
|||||||
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = tooot/SplashScreen.storyboard; sourceTree = "<group>"; };
|
AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = tooot/SplashScreen.storyboard; sourceTree = "<group>"; };
|
||||||
B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "tooot/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
B96B72E5384D44A7B240B27E /* GoogleService-Info.plist */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "tooot/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
|
BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
|
||||||
|
E613A80A28282A01003C97D6 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = tooot/AppDelegate.mm; sourceTree = "<group>"; };
|
||||||
E633A420281EAEAB000E540F /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
E633A420281EAEAB000E540F /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
E633A427281EAEAB000E540F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
E633A427281EAEAB000E540F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
E633A42F281EAF38000E540F /* ShareViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShareViewController.swift; path = "../../node_modules/react-native-share-menu/ios/ShareViewController.swift"; sourceTree = "<group>"; };
|
E633A42F281EAF38000E540F /* ShareViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShareViewController.swift; path = "../../node_modules/react-native-share-menu/ios/ShareViewController.swift"; sourceTree = "<group>"; };
|
||||||
@ -103,10 +103,10 @@
|
|||||||
13B07FAE1A68108700A75B9A /* tooot */ = {
|
13B07FAE1A68108700A75B9A /* tooot */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E613A80A28282A01003C97D6 /* AppDelegate.mm */,
|
||||||
BB2F792B24A3F905000567C9 /* Supporting */,
|
BB2F792B24A3F905000567C9 /* Supporting */,
|
||||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||||
@ -465,9 +465,9 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
|
||||||
5EE44DD62600124E00A9BCED /* File.swift in Sources */,
|
5EE44DD62600124E00A9BCED /* File.swift in Sources */,
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||||
|
E613A80B28282A01003C97D6 /* AppDelegate.mm in Sources */,
|
||||||
E3BC22F5F8ABE515E14CF199 /* ExpoModulesProvider.swift in Sources */,
|
E3BC22F5F8ABE515E14CF199 /* ExpoModulesProvider.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -539,6 +539,7 @@
|
|||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot;
|
||||||
PRODUCT_NAME = tooot;
|
PRODUCT_NAME = tooot;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.xmflsct.app.tooot";
|
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.xmflsct.app.tooot";
|
||||||
@ -574,6 +575,7 @@
|
|||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot;
|
||||||
PRODUCT_NAME = tooot;
|
PRODUCT_NAME = tooot;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.xmflsct.app.tooot";
|
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.xmflsct.app.tooot";
|
||||||
@ -734,6 +736,7 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.xmflsct.app.tooot.ShareExtension";
|
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc com.xmflsct.app.tooot.ShareExtension";
|
||||||
@ -777,6 +780,7 @@
|
|||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = com.xmflsct.app.tooot.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.xmflsct.app.tooot.ShareExtension";
|
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.xmflsct.app.tooot.ShareExtension";
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
#import "AppDelegate.h"
|
|
||||||
|
|
||||||
#import <React/RCTBridge.h>
|
|
||||||
#import <React/RCTBundleURLProvider.h>
|
|
||||||
#import <React/RCTRootView.h>
|
|
||||||
#import <React/RCTLinkingManager.h>
|
|
||||||
#import <React/RCTConvert.h>
|
|
||||||
|
|
||||||
#import <RNShareMenu/ShareMenuManager.h>
|
|
||||||
|
|
||||||
#if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
|
|
||||||
#import <FlipperKit/FlipperClient.h>
|
|
||||||
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
|
|
||||||
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
|
|
||||||
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
|
|
||||||
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
|
|
||||||
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
|
|
||||||
|
|
||||||
// iOS 9.x or newer
|
|
||||||
- (BOOL)application:(UIApplication *)application
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
|
||||||
{
|
|
||||||
return [RCTLinkingManager application:application openURL:url options:options];
|
|
||||||
}
|
|
||||||
|
|
||||||
// iOS 8.x or older
|
|
||||||
- (BOOL)application:(UIApplication *)application
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
sourceApplication:(NSString *)sourceApplication
|
|
||||||
annotation:(id)annotation
|
|
||||||
{
|
|
||||||
return [RCTLinkingManager application:application openURL:url
|
|
||||||
sourceApplication:sourceApplication annotation:annotation];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void InitializeFlipper(UIApplication *application) {
|
|
||||||
FlipperClient *client = [FlipperClient sharedClient];
|
|
||||||
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
|
|
||||||
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
|
|
||||||
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
|
|
||||||
[client addPlugin:[FlipperKitReactPlugin new]];
|
|
||||||
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
|
|
||||||
[client start];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@implementation AppDelegate
|
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
||||||
{
|
|
||||||
#if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
|
|
||||||
InitializeFlipper(application);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
|
||||||
RCTRootView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
|
|
||||||
rootView.backgroundColor = [UIColor colorNamed:@"SplashScreenBackgroundColor"];
|
|
||||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
||||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
|
||||||
rootViewController.view = rootView;
|
|
||||||
self.window.rootViewController = rootViewController;
|
|
||||||
[self.window makeKeyAndVisible];
|
|
||||||
|
|
||||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
|
||||||
{
|
|
||||||
// If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
|
|
||||||
return @[];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
|
|
||||||
#ifdef DEBUG
|
|
||||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
|
||||||
#else
|
|
||||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linking API
|
|
||||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
|
||||||
NSString *urlString = url.absoluteString;
|
|
||||||
|
|
||||||
if ([urlString hasPrefix:@"tooot-share://"]) {
|
|
||||||
NSLog(@"Entered with the following string: %@s", urlString);
|
|
||||||
return [ShareMenuManager application:application openURL:url options:options];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [RCTLinkingManager application:application openURL:url options:options];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Universal Links
|
|
||||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
|
||||||
return [RCTLinkingManager application:application
|
|
||||||
continueUserActivity:userActivity
|
|
||||||
restorationHandler:restorationHandler];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
126
ios/tooot/AppDelegate.mm
Normal file
126
ios/tooot/AppDelegate.mm
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
#import <React/RCTBridge.h>
|
||||||
|
#import <React/RCTBundleURLProvider.h>
|
||||||
|
#import <React/RCTRootView.h>
|
||||||
|
|
||||||
|
#import <React/RCTAppSetupUtils.h>
|
||||||
|
|
||||||
|
#import <React/RCTLinkingManager.h>
|
||||||
|
#import <RNShareMenu/ShareMenuManager.h>
|
||||||
|
|
||||||
|
#if RCT_NEW_ARCH_ENABLED
|
||||||
|
#import <React/CoreModulesPlugins.h>
|
||||||
|
#import <React/RCTCxxBridgeDelegate.h>
|
||||||
|
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||||
|
#import <React/RCTSurfacePresenter.h>
|
||||||
|
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||||
|
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||||
|
|
||||||
|
#import <react/config/ReactNativeConfig.h>
|
||||||
|
|
||||||
|
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||||
|
RCTTurboModuleManager *_turboModuleManager;
|
||||||
|
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||||
|
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||||
|
facebook::react::ContextContainer::Shared _contextContainer;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
|
{
|
||||||
|
RCTAppSetupPrepareApp(application);
|
||||||
|
|
||||||
|
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||||
|
|
||||||
|
#if RCT_NEW_ARCH_ENABLED
|
||||||
|
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||||
|
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||||
|
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||||
|
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||||
|
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"main", nil);
|
||||||
|
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
rootView.backgroundColor = [UIColor colorNamed:@"SplashScreenBackgroundColor"];
|
||||||
|
} else {
|
||||||
|
rootView.backgroundColor = [UIColor whiteColor];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||||
|
rootViewController.view = rootView;
|
||||||
|
self.window.rootViewController = rootViewController;
|
||||||
|
[self.window makeKeyAndVisible];
|
||||||
|
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||||
|
#else
|
||||||
|
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RCT_NEW_ARCH_ENABLED
|
||||||
|
|
||||||
|
#pragma mark - RCTCxxBridgeDelegate
|
||||||
|
|
||||||
|
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||||
|
{
|
||||||
|
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self jsInvoker:bridge.jsCallInvoker];
|
||||||
|
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark RCTTurboModuleManagerDelegate
|
||||||
|
|
||||||
|
- (Class)getModuleClassFromName:(const char *)name
|
||||||
|
{
|
||||||
|
return RCTCoreModulesClassProvider(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name initParams: (const facebook::react::ObjCTurboModule::InitParams &)params
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||||
|
{
|
||||||
|
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Linking API
|
||||||
|
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||||
|
NSString *urlString = url.absoluteString;
|
||||||
|
|
||||||
|
if ([urlString hasPrefix:@"tooot-share://"]) {
|
||||||
|
NSLog(@"Entered with the following string: %@s", urlString);
|
||||||
|
return [ShareMenuManager application:application openURL:url options:options];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [RCTLinkingManager application:application openURL:url options:options];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Universal Links
|
||||||
|
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||||
|
return [RCTLinkingManager application:application
|
||||||
|
continueUserActivity:userActivity
|
||||||
|
restorationHandler:restorationHandler];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#import "AppDelegate.h"
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
preset: 'jest-expo',
|
|
||||||
collectCoverage: true,
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'src /**/*.{ts,tsx}',
|
|
||||||
'!**/coverage /**',
|
|
||||||
'!**/node_modules /**',
|
|
||||||
'!**/app.config.ts',
|
|
||||||
'!**/babel.config.js',
|
|
||||||
'!**/jest.setup.ts'
|
|
||||||
],
|
|
||||||
setupFiles: [
|
|
||||||
'<rootDir>/jest/async-storage.js',
|
|
||||||
'<rootDir>/jest/react-native.js',
|
|
||||||
'<rootDir>/jest/react-navigation.js'
|
|
||||||
],
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
'node_modules/(?!(jest-)?react-native' +
|
|
||||||
'|react-clone-referenced-element' +
|
|
||||||
'|@react-native-community' +
|
|
||||||
'|expo(nent)?' +
|
|
||||||
'|@expo(nent)?/.*' +
|
|
||||||
'|react-navigation' +
|
|
||||||
'|@react-navigation/.*|@unimodules/.*|unimodules' +
|
|
||||||
'|sentry-expo' +
|
|
||||||
'|native-base' +
|
|
||||||
'|@sentry/.*' +
|
|
||||||
'|redux-persist-expo-securestore' +
|
|
||||||
')'
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock'
|
|
||||||
|
|
||||||
jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage)
|
|
6
jest/react-native.js
vendored
6
jest/react-native.js
vendored
@ -1,6 +0,0 @@
|
|||||||
jest.mock('react-native/Libraries/LayoutAnimation/LayoutAnimation', () => ({
|
|
||||||
...require.requireActual(
|
|
||||||
'react-native/Libraries/LayoutAnimation/LayoutAnimation'
|
|
||||||
),
|
|
||||||
configureNext: jest.fn()
|
|
||||||
}))
|
|
14
jest/react-navigation.js
vendored
14
jest/react-navigation.js
vendored
@ -1,14 +0,0 @@
|
|||||||
import 'react-native-gesture-handler/jestSetup'
|
|
||||||
|
|
||||||
jest.mock('react-native-reanimated', () => {
|
|
||||||
const Reanimated = require('react-native-reanimated/mock')
|
|
||||||
|
|
||||||
// The mock for `call` immediately calls the callback which is incorrect
|
|
||||||
// So we override it with a no-op
|
|
||||||
Reanimated.default.call = () => {}
|
|
||||||
|
|
||||||
return Reanimated
|
|
||||||
})
|
|
||||||
|
|
||||||
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
|
|
||||||
jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper')
|
|
81
package.json
81
package.json
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "tooot",
|
"name": "tooot",
|
||||||
"versions": {
|
"versions": {
|
||||||
"native": "220428",
|
"native": "220508",
|
||||||
"major": 4,
|
"major": 4,
|
||||||
"minor": 0,
|
"minor": 0,
|
||||||
"patch": 0,
|
"patch": 0,
|
||||||
"expo": "44.0.0"
|
"expo": "45.0.0"
|
||||||
},
|
},
|
||||||
"description": "tooot app for Mastodon",
|
"description": "tooot app for Mastodon",
|
||||||
"author": "xmflsct <me@xmflsct.com>",
|
"author": "xmflsct <me@xmflsct.com>",
|
||||||
@ -19,13 +19,19 @@
|
|||||||
"android": "react-native run-android",
|
"android": "react-native run-android",
|
||||||
"iphone": "react-native run-ios",
|
"iphone": "react-native run-ios",
|
||||||
"ipad": "react-native run-ios --simulator 'iPad mini (6th generation)'",
|
"ipad": "react-native run-ios --simulator 'iPad mini (6th generation)'",
|
||||||
"app:build": "bundle exec fastlane build_android",
|
"app:build": "bundle exec fastlane build",
|
||||||
"release": "scripts/release.sh",
|
"release": "scripts/release.sh",
|
||||||
"clean": "react-native-clean-project",
|
"clean": "react-native-clean-project",
|
||||||
"postinstall": "patch-package"
|
"postinstall": "patch-package"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/react-native-action-sheet": "3.13.0",
|
"@expo/react-native-action-sheet": "3.13.0",
|
||||||
|
"@formatjs/intl-datetimeformat": "^5.0.2",
|
||||||
|
"@formatjs/intl-getcanonicallocales": "^1.9.2",
|
||||||
|
"@formatjs/intl-locale": "^2.4.47",
|
||||||
|
"@formatjs/intl-numberformat": "^7.4.3",
|
||||||
|
"@formatjs/intl-pluralrules": "^4.3.3",
|
||||||
|
"@formatjs/intl-relativetimeformat": "^10.0.1",
|
||||||
"@neverdull-agency/expo-unlimited-secure-store": "1.0.10",
|
"@neverdull-agency/expo-unlimited-secure-store": "1.0.10",
|
||||||
"@react-native-async-storage/async-storage": "1.17.3",
|
"@react-native-async-storage/async-storage": "1.17.3",
|
||||||
"@react-native-community/blur": "3.6.0",
|
"@react-native-community/blur": "3.6.0",
|
||||||
@ -37,46 +43,48 @@
|
|||||||
"@react-navigation/native-stack": "6.6.2",
|
"@react-navigation/native-stack": "6.6.2",
|
||||||
"@react-navigation/stack": "6.2.1",
|
"@react-navigation/stack": "6.2.1",
|
||||||
"@reduxjs/toolkit": "1.8.1",
|
"@reduxjs/toolkit": "1.8.1",
|
||||||
"@sentry/react-native": "3.4.1",
|
"@sentry/react-native": "3.4.2",
|
||||||
"@sharcoux/slider": "6.0.2",
|
"@sharcoux/slider": "6.0.3",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"expo": "44.0.6",
|
"expo": "45.0.1",
|
||||||
"expo-auth-session": "3.5.0",
|
"expo-auth-session": "3.6.0",
|
||||||
"expo-av": "10.2.1",
|
"expo-av": "11.2.3",
|
||||||
"expo-constants": "^13.0.2",
|
"expo-constants": "^13.1.1",
|
||||||
"expo-crypto": "10.1.2",
|
"expo-crypto": "10.2.0",
|
||||||
"expo-device": "4.1.1",
|
"expo-device": "4.2.0",
|
||||||
"expo-file-system": "13.2.0",
|
"expo-file-system": "14.0.0",
|
||||||
"expo-firebase-analytics": "6.0.1",
|
"expo-firebase-analytics": "7.0.0",
|
||||||
"expo-haptics": "11.1.1",
|
"expo-haptics": "11.2.0",
|
||||||
"expo-image-manipulator": "10.2.1",
|
"expo-image-manipulator": "10.3.1",
|
||||||
"expo-image-picker": "12.0.2",
|
"expo-image-picker": "13.1.1",
|
||||||
"expo-linking": "3.0.0",
|
"expo-linking": "3.1.0",
|
||||||
"expo-localization": "12.0.1",
|
"expo-localization": "13.0.0",
|
||||||
"expo-notifications": "0.14.1",
|
"expo-notifications": "0.15.2",
|
||||||
"expo-random": "12.1.2",
|
"expo-random": "12.2.0",
|
||||||
"expo-screen-capture": "4.1.1",
|
"expo-screen-capture": "4.2.0",
|
||||||
"expo-secure-store": "11.1.1",
|
"expo-secure-store": "11.2.0",
|
||||||
"expo-splash-screen": "0.14.2",
|
"expo-splash-screen": "0.15.1",
|
||||||
"expo-store-review": "5.1.1",
|
"expo-store-review": "5.2.0",
|
||||||
"expo-updates": "0.11.6",
|
"expo-updates": "0.13.1",
|
||||||
"expo-video-thumbnails": "6.2.0",
|
"expo-video-thumbnails": "6.3.0",
|
||||||
"expo-web-browser": "10.1.1",
|
"expo-web-browser": "10.2.0",
|
||||||
"i18next": "21.6.16",
|
"i18next": "21.8.0",
|
||||||
"li": "1.3.0",
|
"li": "1.3.0",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-i18next": "11.16.7",
|
"react-i18next": "11.16.9",
|
||||||
"react-native": "0.67.4",
|
"react-intl": "^5.25.1",
|
||||||
|
"react-native": "0.68.1",
|
||||||
"react-native-animated-spinkit": "1.5.2",
|
"react-native-animated-spinkit": "1.5.2",
|
||||||
"react-native-base64": "^0.2.1",
|
"react-native-base64": "^0.2.1",
|
||||||
"react-native-blurhash": "1.1.10",
|
"react-native-blurhash": "1.1.10",
|
||||||
"react-native-fast-image": "8.5.11",
|
"react-native-fast-image": "8.5.11",
|
||||||
"react-native-feather": "1.1.2",
|
"react-native-feather": "1.1.2",
|
||||||
"react-native-flash-message": "0.2.1",
|
"react-native-flash-message": "0.2.1",
|
||||||
"react-native-gesture-handler": "2.4.1",
|
"react-native-gesture-handler": "2.4.2",
|
||||||
"react-native-htmlview": "0.16.0",
|
"react-native-htmlview": "0.16.0",
|
||||||
|
"react-native-image-keyboard": "^2.2.0",
|
||||||
"react-native-pager-view": "5.4.11",
|
"react-native-pager-view": "5.4.11",
|
||||||
"react-native-reanimated": "2.8.0",
|
"react-native-reanimated": "2.8.0",
|
||||||
"react-native-safe-area-context": "4.2.5",
|
"react-native-safe-area-context": "4.2.5",
|
||||||
@ -85,9 +93,8 @@
|
|||||||
"react-native-svg": "12.3.0",
|
"react-native-svg": "12.3.0",
|
||||||
"react-native-swipe-list-view": "3.2.9",
|
"react-native-swipe-list-view": "3.2.9",
|
||||||
"react-native-tab-view": "3.1.1",
|
"react-native-tab-view": "3.1.1",
|
||||||
"react-query": "3.38.0",
|
"react-query": "3.39.0",
|
||||||
"react-redux": "8.0.1",
|
"react-redux": "8.0.1",
|
||||||
"react-timeago": "6.2.1",
|
|
||||||
"redux-persist": "6.0.0",
|
"redux-persist": "6.0.0",
|
||||||
"rn-placeholder": "3.0.3",
|
"rn-placeholder": "3.0.3",
|
||||||
"sentry-expo": "4.1.1",
|
"sentry-expo": "4.1.1",
|
||||||
@ -95,7 +102,7 @@
|
|||||||
"valid-url": "1.0.9"
|
"valid-url": "1.0.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.17.9",
|
"@babel/core": "7.17.10",
|
||||||
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
"@babel/plugin-proposal-optional-chaining": "7.16.7",
|
||||||
"@babel/preset-typescript": "7.16.7",
|
"@babel/preset-typescript": "7.16.7",
|
||||||
"@expo/config": "6.0.23",
|
"@expo/config": "6.0.23",
|
||||||
@ -115,7 +122,11 @@
|
|||||||
"patch-package": "6.4.7",
|
"patch-package": "6.4.7",
|
||||||
"postinstall-postinstall": "2.1.0",
|
"postinstall-postinstall": "2.1.0",
|
||||||
"react-native-clean-project": "4.0.1",
|
"react-native-clean-project": "4.0.1",
|
||||||
"typescript": "4.6.3"
|
"typescript": "4.6.4"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"@types/react": "17.0.43",
|
||||||
|
"@types/react-dom": "17.0.14"
|
||||||
},
|
},
|
||||||
"expo": {
|
"expo": {
|
||||||
"autolinking": {
|
"autolinking": {
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
diff --git a/node_modules/expo-av/ios/EXAV/EXAV.m b/node_modules/expo-av/ios/EXAV/EXAV.m
|
|
||||||
index d255852..edf934f 100644
|
|
||||||
--- a/node_modules/expo-av/ios/EXAV/EXAV.m
|
|
||||||
+++ b/node_modules/expo-av/ios/EXAV/EXAV.m
|
|
||||||
@@ -63,7 +63,7 @@ NSString *const EXDidUpdateMetadataEventName = @"didUpdateMetadata";
|
|
||||||
@property (nonatomic, assign) BOOL audioRecorderShouldBeginRecording;
|
|
||||||
@property (nonatomic, assign) int audioRecorderDurationMillis;
|
|
||||||
|
|
||||||
-@property (nonatomic, weak) EXModuleRegistry *moduleRegistry;
|
|
||||||
+@property (nonatomic, weak) EXModuleRegistry *expoModuleRegistry;
|
|
||||||
@property (nonatomic, weak) id<EXPermissionsInterface> permissionsManager;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -106,7 +106,7 @@ EX_EXPORT_MODULE(ExponentAV);
|
|
||||||
|
|
||||||
- (void)installJsiBindings
|
|
||||||
{
|
|
||||||
- id<EXJavaScriptContextProvider> jsContextProvider = [_moduleRegistry getModuleImplementingProtocol:@protocol(EXJavaScriptContextProvider)];
|
|
||||||
+ id<EXJavaScriptContextProvider> jsContextProvider = [_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXJavaScriptContextProvider)];
|
|
||||||
void *jsRuntimePtr = [jsContextProvider javaScriptRuntimePointer];
|
|
||||||
if (jsRuntimePtr) {
|
|
||||||
[self installJSIBindingsForRuntime:jsRuntimePtr withSoundDictionary:_soundDictionary];
|
|
||||||
@@ -131,16 +131,16 @@ EX_EXPORT_MODULE(ExponentAV);
|
|
||||||
|
|
||||||
#pragma mark - Expo experience lifecycle
|
|
||||||
|
|
||||||
-- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
|
|
||||||
+- (void)setModuleRegistry:(EXModuleRegistry *)expoModuleRegistry
|
|
||||||
{
|
|
||||||
- [[_moduleRegistry getModuleImplementingProtocol:@protocol(EXAppLifecycleService)] unregisterAppLifecycleListener:self];
|
|
||||||
- _moduleRegistry = moduleRegistry;
|
|
||||||
- _kernelAudioSessionManagerDelegate = [_moduleRegistry getSingletonModuleForName:@"AudioSessionManager"];
|
|
||||||
+ [[_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXAppLifecycleService)] unregisterAppLifecycleListener:self];
|
|
||||||
+ _expoModuleRegistry = expoModuleRegistry;
|
|
||||||
+ _kernelAudioSessionManagerDelegate = [_expoModuleRegistry getSingletonModuleForName:@"AudioSessionManager"];
|
|
||||||
if (!_isBackgrounded) {
|
|
||||||
[_kernelAudioSessionManagerDelegate moduleDidForeground:self];
|
|
||||||
}
|
|
||||||
- [[_moduleRegistry getModuleImplementingProtocol:@protocol(EXAppLifecycleService)] registerAppLifecycleListener:self];
|
|
||||||
- _permissionsManager = [_moduleRegistry getModuleImplementingProtocol:@protocol(EXPermissionsInterface)];
|
|
||||||
+ [[_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXAppLifecycleService)] registerAppLifecycleListener:self];
|
|
||||||
+ _permissionsManager = [_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXPermissionsInterface)];
|
|
||||||
[EXPermissionsMethodsDelegate registerRequesters:@[[EXAudioRecordingPermissionRequester new]] withPermissionsManager:_permissionsManager];
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -478,7 +478,7 @@ withEXVideoViewForTag:(nonnull NSNumber *)reactTag
|
|
||||||
{
|
|
||||||
// TODO check that the bridge is still valid after the dispatch
|
|
||||||
// TODO check if the queues are ok
|
|
||||||
- [[_moduleRegistry getModuleImplementingProtocol:@protocol(EXUIManager)] executeUIBlock:^(id view) {
|
|
||||||
+ [[_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXUIManager)] executeUIBlock:^(id view) {
|
|
||||||
if ([view isKindOfClass:[EXVideoView class]]) {
|
|
||||||
block(view);
|
|
||||||
} else {
|
|
||||||
@@ -566,7 +566,7 @@ withEXVideoViewForTag:(nonnull NSNumber *)reactTag
|
|
||||||
return EXErrorWithMessage(@"Recorder is already prepared.");
|
|
||||||
}
|
|
||||||
|
|
||||||
- id<EXFileSystemInterface> fileSystem = [_moduleRegistry getModuleImplementingProtocol:@protocol(EXFileSystemInterface)];
|
|
||||||
+ id<EXFileSystemInterface> fileSystem = [_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXFileSystemInterface)];
|
|
||||||
|
|
||||||
if (!fileSystem) {
|
|
||||||
return EXErrorWithMessage(@"No FileSystem module.");
|
|
||||||
@@ -726,7 +726,7 @@ EX_EXPORT_METHOD_AS(loadForSound,
|
|
||||||
|
|
||||||
- (void)sendEventWithName:(NSString *)eventName body:(NSDictionary *)body
|
|
||||||
{
|
|
||||||
- [[_moduleRegistry getModuleImplementingProtocol:@protocol(EXEventEmitterService)] sendEventWithName:eventName body:body];
|
|
||||||
+ [[_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXEventEmitterService)] sendEventWithName:eventName body:body];
|
|
||||||
}
|
|
||||||
|
|
||||||
EX_EXPORT_METHOD_AS(unloadForSound,
|
|
||||||
@@ -984,7 +984,7 @@ EX_EXPORT_METHOD_AS(unloadAudioRecorder,
|
|
||||||
- (void)dealloc
|
|
||||||
{
|
|
||||||
[_kernelAudioSessionManagerDelegate moduleWillDeallocate:self];
|
|
||||||
- [[_moduleRegistry getModuleImplementingProtocol:@protocol(EXAppLifecycleService)] unregisterAppLifecycleListener:self];
|
|
||||||
+ [[_expoModuleRegistry getModuleImplementingProtocol:@protocol(EXAppLifecycleService)] unregisterAppLifecycleListener:self];
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
||||||
|
|
||||||
// This will clear all @properties and deactivate the audio session:
|
|
@ -1,166 +0,0 @@
|
|||||||
diff --git a/node_modules/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt b/node_modules/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt
|
|
||||||
index 53bf40f..0ba5d89 100644
|
|
||||||
--- a/node_modules/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt
|
|
||||||
+++ b/node_modules/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.kt
|
|
||||||
@@ -56,6 +56,7 @@ import okhttp3.Callback
|
|
||||||
import okhttp3.Headers
|
|
||||||
import okhttp3.JavaNetCookieJar
|
|
||||||
import okhttp3.MediaType
|
|
||||||
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
|
||||||
import okhttp3.MultipartBody
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
@@ -63,11 +64,7 @@ import okhttp3.RequestBody
|
|
||||||
import okhttp3.Response
|
|
||||||
import okhttp3.ResponseBody
|
|
||||||
|
|
||||||
-import okio.Buffer
|
|
||||||
-import okio.BufferedSource
|
|
||||||
-import okio.ForwardingSource
|
|
||||||
-import okio.Okio
|
|
||||||
-import okio.Source
|
|
||||||
+import okio.*
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Hex
|
|
||||||
import org.apache.commons.codec.digest.DigestUtils
|
|
||||||
@@ -766,7 +763,7 @@ open class FileSystemModule(
|
|
||||||
}
|
|
||||||
|
|
||||||
val body = createRequestBody(options, decorator, fileUri.toFile())
|
|
||||||
- return requestBuilder.method(method, body).build()
|
|
||||||
+ return method?.let { requestBuilder.method(it, body).build() }
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.message?.let { Log.e(TAG, it) }
|
|
||||||
promise.reject(e)
|
|
||||||
@@ -791,7 +788,7 @@ open class FileSystemModule(
|
|
||||||
} ?: URLConnection.guessContentTypeFromName(file.name)
|
|
||||||
|
|
||||||
val fieldName = options["fieldName"]?.let { it as String } ?: file.name
|
|
||||||
- bodyBuilder.addFormDataPart(fieldName, file.name, decorator.decorate(RequestBody.create(MediaType.parse(mimeType), file)))
|
|
||||||
+ bodyBuilder.addFormDataPart(fieldName, file.name, decorator.decorate(RequestBody.create(mimeType.toMediaTypeOrNull(), file)))
|
|
||||||
bodyBuilder.build()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
@@ -816,9 +813,9 @@ open class FileSystemModule(
|
|
||||||
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val result = Bundle().apply {
|
|
||||||
- putString("body", response.body()?.string())
|
|
||||||
- putInt("status", response.code())
|
|
||||||
- putBundle("headers", translateHeaders(response.headers()))
|
|
||||||
+ putString("body", response.body?.string())
|
|
||||||
+ putInt("status", response.code)
|
|
||||||
+ putBundle("headers", translateHeaders(response.headers))
|
|
||||||
}
|
|
||||||
response.close()
|
|
||||||
promise.resolve(result)
|
|
||||||
@@ -866,7 +863,7 @@ open class FileSystemModule(
|
|
||||||
taskHandlers[uuid] = TaskHandler(call)
|
|
||||||
call.enqueue(object : Callback {
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
|
||||||
- if (call.isCanceled) {
|
|
||||||
+ if (call.isCanceled()) {
|
|
||||||
promise.resolve(null)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -876,11 +873,11 @@ open class FileSystemModule(
|
|
||||||
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val result = Bundle()
|
|
||||||
- val body = response.body()
|
|
||||||
+ val body = response.body
|
|
||||||
result.apply {
|
|
||||||
putString("body", body?.string())
|
|
||||||
- putInt("status", response.code())
|
|
||||||
- putBundle("headers", translateHeaders(response.headers()))
|
|
||||||
+ putInt("status", response.code)
|
|
||||||
+ putBundle("headers", translateHeaders(response.headers))
|
|
||||||
}
|
|
||||||
response.close()
|
|
||||||
promise.resolve(result)
|
|
||||||
@@ -900,10 +897,10 @@ open class FileSystemModule(
|
|
||||||
val resources = context.resources
|
|
||||||
val packageName = context.packageName
|
|
||||||
val resourceId = resources.getIdentifier(url, "raw", packageName)
|
|
||||||
- val bufferedSource = Okio.buffer(Okio.source(context.resources.openRawResource(resourceId)))
|
|
||||||
+ val bufferedSource = context.resources.openRawResource(resourceId).source().buffer()
|
|
||||||
val file = uri.toFile()
|
|
||||||
file.delete()
|
|
||||||
- val sink = Okio.buffer(Okio.sink(file))
|
|
||||||
+ val sink = file.sink().buffer()
|
|
||||||
sink.writeAll(bufferedSource)
|
|
||||||
sink.close()
|
|
||||||
val result = Bundle()
|
|
||||||
@@ -934,13 +931,13 @@ open class FileSystemModule(
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val file = uri.toFile()
|
|
||||||
file.delete()
|
|
||||||
- val sink = Okio.buffer(Okio.sink(file))
|
|
||||||
- sink.writeAll(response.body()!!.source())
|
|
||||||
+ val sink = file.sink().buffer()
|
|
||||||
+ sink.writeAll(response.body!!.source())
|
|
||||||
sink.close()
|
|
||||||
val result = Bundle().apply {
|
|
||||||
putString("uri", Uri.fromFile(file).toString())
|
|
||||||
- putInt("status", response.code())
|
|
||||||
- putBundle("headers", translateHeaders(response.headers()))
|
|
||||||
+ putInt("status", response.code)
|
|
||||||
+ putBundle("headers", translateHeaders(response.headers))
|
|
||||||
if (options?.get("md5") == true) {
|
|
||||||
putString("md5", md5(file))
|
|
||||||
}
|
|
||||||
@@ -1003,7 +1000,7 @@ open class FileSystemModule(
|
|
||||||
?.addNetworkInterceptor { chain ->
|
|
||||||
val originalResponse = chain.proceed(chain.request())
|
|
||||||
originalResponse.newBuilder()
|
|
||||||
- .body(ProgressResponseBody(originalResponse.body(), progressListener))
|
|
||||||
+ .body(ProgressResponseBody(originalResponse.body, progressListener))
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
?.build()
|
|
||||||
@@ -1098,7 +1095,7 @@ open class FileSystemModule(
|
|
||||||
val options = params[0]?.options
|
|
||||||
return try {
|
|
||||||
val response = call!!.execute()
|
|
||||||
- val responseBody = response.body()
|
|
||||||
+ val responseBody = response.body
|
|
||||||
val input = BufferedInputStream(responseBody!!.byteStream())
|
|
||||||
val output = FileOutputStream(file, isResume == true)
|
|
||||||
val data = ByteArray(1024)
|
|
||||||
@@ -1108,15 +1105,15 @@ open class FileSystemModule(
|
|
||||||
}
|
|
||||||
val result = Bundle().apply {
|
|
||||||
putString("uri", Uri.fromFile(file).toString())
|
|
||||||
- putInt("status", response.code())
|
|
||||||
- putBundle("headers", translateHeaders(response.headers()))
|
|
||||||
+ putInt("status", response.code)
|
|
||||||
+ putBundle("headers", translateHeaders(response.headers))
|
|
||||||
options?.get("md5").takeIf { it == true }?.let { putString("md5", file?.let { md5(it) }) }
|
|
||||||
}
|
|
||||||
response.close()
|
|
||||||
promise?.resolve(result)
|
|
||||||
null
|
|
||||||
} catch (e: Exception) {
|
|
||||||
- if (call?.isCanceled == true) {
|
|
||||||
+ if (call?.isCanceled() == true) {
|
|
||||||
promise?.resolve(null)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
@@ -1139,7 +1136,7 @@ open class FileSystemModule(
|
|
||||||
override fun contentLength(): Long = responseBody?.contentLength() ?: -1
|
|
||||||
|
|
||||||
override fun source(): BufferedSource =
|
|
||||||
- bufferedSource ?: Okio.buffer(source(responseBody!!.source()))
|
|
||||||
+ bufferedSource ?: source(responseBody!!.source()).buffer()
|
|
||||||
|
|
||||||
private fun source(source: Source): Source {
|
|
||||||
return object : ForwardingSource(source) {
|
|
||||||
@@ -1304,7 +1301,7 @@ open class FileSystemModule(
|
|
||||||
// Copied out of React Native's `NetworkingModule.java`
|
|
||||||
private fun translateHeaders(headers: Headers): Bundle {
|
|
||||||
val responseHeaders = Bundle()
|
|
||||||
- for (i in 0 until headers.size()) {
|
|
||||||
+ for (i in 0 until headers.size) {
|
|
||||||
val headerName = headers.name(i)
|
|
||||||
// multiple values for the same header
|
|
||||||
if (responseHeaders[headerName] != null) {
|
|
42
src/App.tsx
42
src/App.tsx
@ -1,4 +1,31 @@
|
|||||||
import { ActionSheetProvider } from '@expo/react-native-action-sheet'
|
import { ActionSheetProvider } from '@expo/react-native-action-sheet'
|
||||||
|
import '@formatjs/intl-getcanonicallocales/polyfill'
|
||||||
|
import '@formatjs/intl-locale/polyfill'
|
||||||
|
import '@formatjs/intl-pluralrules/polyfill'
|
||||||
|
import '@formatjs/intl-pluralrules/locale-data/de'
|
||||||
|
import '@formatjs/intl-pluralrules/locale-data/en'
|
||||||
|
import '@formatjs/intl-pluralrules/locale-data/ko'
|
||||||
|
import '@formatjs/intl-pluralrules/locale-data/vi'
|
||||||
|
import '@formatjs/intl-pluralrules/locale-data/zh'
|
||||||
|
import '@formatjs/intl-numberformat/polyfill'
|
||||||
|
import '@formatjs/intl-numberformat/locale-data/de'
|
||||||
|
import '@formatjs/intl-numberformat/locale-data/en'
|
||||||
|
import '@formatjs/intl-numberformat/locale-data/ko'
|
||||||
|
import '@formatjs/intl-numberformat/locale-data/vi'
|
||||||
|
import '@formatjs/intl-numberformat/locale-data/zh'
|
||||||
|
import '@formatjs/intl-datetimeformat/polyfill'
|
||||||
|
import '@formatjs/intl-datetimeformat/locale-data/de'
|
||||||
|
import '@formatjs/intl-datetimeformat/locale-data/en'
|
||||||
|
import '@formatjs/intl-datetimeformat/locale-data/ko'
|
||||||
|
import '@formatjs/intl-datetimeformat/locale-data/vi'
|
||||||
|
import '@formatjs/intl-datetimeformat/locale-data/zh'
|
||||||
|
import '@formatjs/intl-datetimeformat/add-all-tz'
|
||||||
|
import '@formatjs/intl-relativetimeformat/polyfill'
|
||||||
|
import '@formatjs/intl-relativetimeformat/locale-data/de'
|
||||||
|
import '@formatjs/intl-relativetimeformat/locale-data/en'
|
||||||
|
import '@formatjs/intl-relativetimeformat/locale-data/ko'
|
||||||
|
import '@formatjs/intl-relativetimeformat/locale-data/vi'
|
||||||
|
import '@formatjs/intl-relativetimeformat/locale-data/zh'
|
||||||
import queryClient from '@helpers/queryClient'
|
import queryClient from '@helpers/queryClient'
|
||||||
import i18n from '@root/i18n/i18n'
|
import i18n from '@root/i18n/i18n'
|
||||||
import Screens from '@root/Screens'
|
import Screens from '@root/Screens'
|
||||||
@ -6,7 +33,9 @@ import audio from '@root/startup/audio'
|
|||||||
import dev from '@root/startup/dev'
|
import dev from '@root/startup/dev'
|
||||||
import log from '@root/startup/log'
|
import log from '@root/startup/log'
|
||||||
import netInfo from '@root/startup/netInfo'
|
import netInfo from '@root/startup/netInfo'
|
||||||
|
import push from '@root/startup/push'
|
||||||
import sentry from '@root/startup/sentry'
|
import sentry from '@root/startup/sentry'
|
||||||
|
import timezone from '@root/startup/timezone'
|
||||||
import { persistor, store } from '@root/store'
|
import { persistor, store } from '@root/store'
|
||||||
import AccessibilityManager from '@utils/accessibility/AccessibilityManager'
|
import AccessibilityManager from '@utils/accessibility/AccessibilityManager'
|
||||||
import {
|
import {
|
||||||
@ -19,11 +48,12 @@ import * as SplashScreen from 'expo-splash-screen'
|
|||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
import { AppState, LogBox, Platform } from 'react-native'
|
import { AppState, LogBox, Platform } from 'react-native'
|
||||||
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
||||||
|
import 'react-native-image-keyboard'
|
||||||
import { enableFreeze } from 'react-native-screens'
|
import { enableFreeze } from 'react-native-screens'
|
||||||
import { QueryClientProvider } from 'react-query'
|
import { QueryClientProvider } from 'react-query'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import { PersistGate } from 'redux-persist/integration/react'
|
import { PersistGate } from 'redux-persist/integration/react'
|
||||||
import push from './startup/push'
|
import { IntlProvider } from 'react-intl'
|
||||||
|
|
||||||
Platform.select({
|
Platform.select({
|
||||||
android: LogBox.ignoreLogs(['Setting a timer for a long period of time'])
|
android: LogBox.ignoreLogs(['Setting a timer for a long period of time'])
|
||||||
@ -33,6 +63,7 @@ dev()
|
|||||||
sentry()
|
sentry()
|
||||||
audio()
|
audio()
|
||||||
push()
|
push()
|
||||||
|
timezone()
|
||||||
enableFreeze(true)
|
enableFreeze(true)
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
@ -91,13 +122,18 @@ const App: React.FC = () => {
|
|||||||
const language = getSettingsLanguage(store.getState())
|
const language = getSettingsLanguage(store.getState())
|
||||||
if (!language) {
|
if (!language) {
|
||||||
store.dispatch(changeLanguage('en'))
|
store.dispatch(changeLanguage('en'))
|
||||||
|
i18n.changeLanguage('en')
|
||||||
|
} else {
|
||||||
|
i18n.changeLanguage(language)
|
||||||
}
|
}
|
||||||
i18n.changeLanguage(language)
|
|
||||||
return (
|
return (
|
||||||
<ActionSheetProvider>
|
<ActionSheetProvider>
|
||||||
<AccessibilityManager>
|
<AccessibilityManager>
|
||||||
<ThemeManager>
|
<ThemeManager>
|
||||||
<Screens localCorrupt={localCorrupt} />
|
<IntlProvider locale={language}>
|
||||||
|
<Screens localCorrupt={localCorrupt} />
|
||||||
|
</IntlProvider>
|
||||||
</ThemeManager>
|
</ThemeManager>
|
||||||
</AccessibilityManager>
|
</AccessibilityManager>
|
||||||
</ActionSheetProvider>
|
</ActionSheetProvider>
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import { Text } from 'react-native'
|
|
||||||
import TimeAgo from 'react-timeago'
|
|
||||||
// @ts-ignore
|
|
||||||
import buildFormatter from 'react-timeago/lib/formatters/buildFormatter'
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
date: string | number
|
|
||||||
}
|
|
||||||
|
|
||||||
const RelativeTime: React.FC<Props> = ({ date }) => {
|
|
||||||
const { t } = useTranslation('componentRelativeTime')
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TimeAgo
|
|
||||||
date={date}
|
|
||||||
component={Text}
|
|
||||||
formatter={buildFormatter(t('strings', { returnObjects: true }))}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RelativeTime
|
|
@ -102,6 +102,7 @@ const TimelineDefault = React.memo(
|
|||||||
queryKey={disableOnPress ? undefined : queryKey}
|
queryKey={disableOnPress ? undefined : queryKey}
|
||||||
rootQueryKey={disableOnPress ? undefined : rootQueryKey}
|
rootQueryKey={disableOnPress ? undefined : rootQueryKey}
|
||||||
status={actualStatus}
|
status={actualStatus}
|
||||||
|
highlighted={highlighted}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { Video } from 'expo-av'
|
import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av'
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
AppState,
|
AppState,
|
||||||
@ -110,15 +110,14 @@ const AttachmentVideo: React.FC<Props> = ({
|
|||||||
source: { uri: video.url }
|
source: { uri: video.url }
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
resizeMode: 'cover',
|
resizeMode: ResizeMode.COVER,
|
||||||
posterSource: { uri: video.preview_url },
|
posterSource: { uri: video.preview_url },
|
||||||
posterStyle: { resizeMode: 'cover' }
|
posterStyle: { resizeMode: ResizeMode.COVER }
|
||||||
})}
|
})}
|
||||||
useNativeControls={false}
|
useNativeControls={false}
|
||||||
onFullscreenUpdate={async event => {
|
onFullscreenUpdate={async event => {
|
||||||
if (
|
if (
|
||||||
event.fullscreenUpdate ===
|
event.fullscreenUpdate === VideoFullscreenUpdate.PLAYER_DID_DISMISS
|
||||||
Video.FULLSCREEN_UPDATE_PLAYER_DID_DISMISS
|
|
||||||
) {
|
) {
|
||||||
if (gifv) {
|
if (gifv) {
|
||||||
await videoPlayer.current?.pauseAsync()
|
await videoPlayer.current?.pauseAsync()
|
||||||
|
@ -5,10 +5,10 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
status: Pick<
|
status: Pick<Mastodon.Status, 'content' | 'spoiler_text' | 'emojis'> & {
|
||||||
Mastodon.Status,
|
mentions?: Mastodon.Status['mentions']
|
||||||
'content' | 'spoiler_text' | 'emojis' | 'mentions' | 'tags'
|
tags?: Mastodon.Status['tags']
|
||||||
>
|
}
|
||||||
numberOfLines?: number
|
numberOfLines?: number
|
||||||
highlighted?: boolean
|
highlighted?: boolean
|
||||||
disableDetails?: boolean
|
disableDetails?: boolean
|
||||||
|
@ -18,9 +18,15 @@ export interface Props {
|
|||||||
queryKey?: QueryKeyTimeline
|
queryKey?: QueryKeyTimeline
|
||||||
rootQueryKey?: QueryKeyTimeline
|
rootQueryKey?: QueryKeyTimeline
|
||||||
status: Mastodon.Status
|
status: Mastodon.Status
|
||||||
|
highlighted: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimelineHeaderDefault = ({ queryKey, rootQueryKey, status }: Props) => {
|
const TimelineHeaderDefault = ({
|
||||||
|
queryKey,
|
||||||
|
rootQueryKey,
|
||||||
|
status,
|
||||||
|
highlighted
|
||||||
|
}: Props) => {
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>()
|
const navigation = useNavigation<StackNavigationProp<RootStackParamList>>()
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
@ -40,6 +46,7 @@ const TimelineHeaderDefault = ({ queryKey, rootQueryKey, status }: Props) => {
|
|||||||
<HeaderSharedCreated
|
<HeaderSharedCreated
|
||||||
created_at={status.created_at}
|
created_at={status.created_at}
|
||||||
edited_at={status.edited_at}
|
edited_at={status.edited_at}
|
||||||
|
highlighted={highlighted}
|
||||||
/>
|
/>
|
||||||
<HeaderSharedVisibility visibility={status.visibility} />
|
<HeaderSharedVisibility visibility={status.visibility} />
|
||||||
<HeaderSharedMuted muted={status.muted} />
|
<HeaderSharedMuted muted={status.muted} />
|
||||||
|
@ -1,25 +1,43 @@
|
|||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import RelativeTime from '@components/RelativeTime'
|
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
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 from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { FormattedDate, FormattedRelativeTime, FormattedTime } from 'react-intl'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
created_at: Mastodon.Status['created_at'] | number
|
created_at: Mastodon.Status['created_at'] | number
|
||||||
edited_at?: Mastodon.Status['edited_at']
|
edited_at?: Mastodon.Status['edited_at']
|
||||||
|
highlighted?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const HeaderSharedCreated = React.memo(
|
const HeaderSharedCreated = React.memo(
|
||||||
({ created_at, edited_at }: Props) => {
|
({ created_at, edited_at, highlighted = false }: Props) => {
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
|
|
||||||
|
const actualTime = edited_at || created_at
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||||
<RelativeTime date={edited_at || created_at} />
|
{highlighted ? (
|
||||||
|
<>
|
||||||
|
<FormattedDate
|
||||||
|
value={new Date(actualTime)}
|
||||||
|
dateStyle='medium'
|
||||||
|
timeStyle='short'
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<FormattedRelativeTime
|
||||||
|
value={
|
||||||
|
-(new Date().getTime() - new Date(actualTime).getTime()) / 1000
|
||||||
|
}
|
||||||
|
updateIntervalInSeconds={1}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
{edited_at ? (
|
{edited_at ? (
|
||||||
<Icon
|
<Icon
|
||||||
|
@ -15,6 +15,30 @@ const HeaderSharedVisibility = React.memo(
|
|||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
|
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
|
case 'public':
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
accessibilityLabel={t(
|
||||||
|
'shared.header.shared.visibility.private.accessibilityLabel'
|
||||||
|
)}
|
||||||
|
name='Globe'
|
||||||
|
size={StyleConstants.Font.Size.S}
|
||||||
|
color={colors.secondary}
|
||||||
|
style={styles.visibility}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 'unlisted':
|
||||||
|
return (
|
||||||
|
<Icon
|
||||||
|
accessibilityLabel={t(
|
||||||
|
'shared.header.shared.visibility.private.accessibilityLabel'
|
||||||
|
)}
|
||||||
|
name='Unlock'
|
||||||
|
size={StyleConstants.Font.Size.S}
|
||||||
|
color={colors.secondary}
|
||||||
|
style={styles.visibility}
|
||||||
|
/>
|
||||||
|
)
|
||||||
case 'private':
|
case 'private':
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
|
@ -4,7 +4,6 @@ import haptics from '@components/haptics'
|
|||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import { ParseEmojis } from '@components/Parse'
|
import { ParseEmojis } from '@components/Parse'
|
||||||
import RelativeTime from '@components/RelativeTime'
|
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import {
|
import {
|
||||||
MutationVarsTimelineUpdateStatusProperty,
|
MutationVarsTimelineUpdateStatusProperty,
|
||||||
@ -17,6 +16,7 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
|||||||
import { maxBy } from 'lodash'
|
import { maxBy } from 'lodash'
|
||||||
import React, { useCallback, useMemo, useState } from 'react'
|
import React, { useCallback, useMemo, useState } from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
import { FormattedRelativeTime } from 'react-intl'
|
||||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||||
import { useQueryClient } from 'react-query'
|
import { useQueryClient } from 'react-query'
|
||||||
|
|
||||||
@ -158,7 +158,16 @@ const TimelinePoll: React.FC<Props> = ({
|
|||||||
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
<CustomText fontStyle='S' style={{ color: colors.secondary }}>
|
||||||
<Trans
|
<Trans
|
||||||
i18nKey='componentTimeline:shared.poll.meta.expiration.until'
|
i18nKey='componentTimeline:shared.poll.meta.expiration.until'
|
||||||
components={[<RelativeTime date={poll.expires_at} />]}
|
components={[
|
||||||
|
<FormattedRelativeTime
|
||||||
|
value={
|
||||||
|
(new Date(poll.expires_at).getTime() -
|
||||||
|
new Date().getTime()) /
|
||||||
|
1000
|
||||||
|
}
|
||||||
|
updateIntervalInSeconds={1}
|
||||||
|
/>
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</CustomText>
|
</CustomText>
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,10 @@ import analytics from '@components/analytics'
|
|||||||
import { ActionSheetOptions } from '@expo/react-native-action-sheet'
|
import { ActionSheetOptions } from '@expo/react-native-action-sheet'
|
||||||
import * as ImageManipulator from 'expo-image-manipulator'
|
import * as ImageManipulator from 'expo-image-manipulator'
|
||||||
import * as ImagePicker from 'expo-image-picker'
|
import * as ImagePicker from 'expo-image-picker'
|
||||||
import { ImageInfo } from 'expo-image-picker/build/ImagePicker.types'
|
import {
|
||||||
|
ImageInfo,
|
||||||
|
UIImagePickerPresentationStyle
|
||||||
|
} from 'expo-image-picker/build/ImagePicker.types'
|
||||||
import i18next from 'i18next'
|
import i18next from 'i18next'
|
||||||
import { Alert, Linking, Platform } from 'react-native'
|
import { Alert, Linking, Platform } from 'react-native'
|
||||||
|
|
||||||
@ -39,7 +42,7 @@ const mediaSelector = async ({
|
|||||||
{ resize }
|
{ resize }
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
resolve(newResult)
|
resolve({ ...newResult, cancelled: false })
|
||||||
} else {
|
} else {
|
||||||
resolve(result)
|
resolve(result)
|
||||||
}
|
}
|
||||||
@ -94,8 +97,8 @@ const mediaSelector = async ({
|
|||||||
exif: false,
|
exif: false,
|
||||||
presentationStyle:
|
presentationStyle:
|
||||||
Platform.OS === 'ios' && parseInt(Platform.Version) < 13
|
Platform.OS === 'ios' && parseInt(Platform.Version) < 13
|
||||||
? 0
|
? UIImagePickerPresentationStyle.FULL_SCREEN
|
||||||
: -2
|
: UIImagePickerPresentationStyle.AUTOMATIC
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!result.cancelled) {
|
if (!result.cancelled) {
|
||||||
|
@ -34,6 +34,7 @@ const openLink = async (url: string, navigation?: any) => {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
navigation.push(page, options)
|
navigation.push(page, options)
|
||||||
} else {
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
navigationRef.navigate(page, options)
|
navigationRef.navigate(page, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"strings": {
|
|
||||||
"prefixAgo": "",
|
|
||||||
"prefixFromNow": "",
|
|
||||||
"suffixAgo": "her",
|
|
||||||
"suffixFromNow": "",
|
|
||||||
"seconds": "%d Sekunden",
|
|
||||||
"minute": "etwa eine Minute",
|
|
||||||
"minutes": "%d Minuten",
|
|
||||||
"hour": "etwa eine Stunde",
|
|
||||||
"hours": "etwa %d Stunden",
|
|
||||||
"day": "1 Tag",
|
|
||||||
"days": "%d Tage",
|
|
||||||
"month": "etwa 1 Monat",
|
|
||||||
"months": "%d Monate",
|
|
||||||
"year": "etwa 1 Jahr",
|
|
||||||
"years": "%d Jahre",
|
|
||||||
"wordSeparator": ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,8 +62,8 @@
|
|||||||
"history": {
|
"history": {
|
||||||
"accessibilityLabel": "Dieser Tröt wurde {{count}} mal bearbeitet",
|
"accessibilityLabel": "Dieser Tröt wurde {{count}} mal bearbeitet",
|
||||||
"accessibilityHint": "Für den vollständigen Verlauf auswählen",
|
"accessibilityHint": "Für den vollständigen Verlauf auswählen",
|
||||||
"text": "{{count}} bearbeitet",
|
"text_one": "{{count}} bearbeitet",
|
||||||
"text_plural": "{{count}} mal bearbeitet"
|
"text_other": "{{count}} mal bearbeitet"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attachment": {
|
"attachment": {
|
||||||
@ -219,10 +219,10 @@
|
|||||||
"refresh": "Aktualisieren"
|
"refresh": "Aktualisieren"
|
||||||
},
|
},
|
||||||
"count": {
|
"count": {
|
||||||
"voters": "{{count}} Benutzer haben abgestimmt",
|
"voters_one": "{{count}} Benutzer haben abgestimmt",
|
||||||
"voters_plural": "{{count}} Benutzer haben abgestimmt",
|
"voters_other": "{{count}} Benutzer haben abgestimmt",
|
||||||
"votes": "{{count}} Stimmen",
|
"votes_one": "{{count}} Stimmen",
|
||||||
"votes_plural": "{{count}} Stimmen"
|
"votes_other": "{{count}} Stimmen"
|
||||||
},
|
},
|
||||||
"expiration": {
|
"expiration": {
|
||||||
"expired": "Abstimmung abgelaufen",
|
"expired": "Abstimmung abgelaufen",
|
||||||
|
@ -13,6 +13,5 @@ export default {
|
|||||||
componentMediaSelector: require('./components/mediaSelector'),
|
componentMediaSelector: require('./components/mediaSelector'),
|
||||||
componentParse: require('./components/parse'),
|
componentParse: require('./components/parse'),
|
||||||
componentRelationship: require('./components/relationship'),
|
componentRelationship: require('./components/relationship'),
|
||||||
componentRelativeTime: require('./components/relativeTime'),
|
|
||||||
componentTimeline: require('./components/timeline')
|
componentTimeline: require('./components/timeline')
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
"OK": "OK",
|
||||||
"apply": "Apply",
|
"apply": "Apply",
|
||||||
"cancel": "Cancel"
|
"cancel": "Cancel"
|
||||||
},
|
},
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"strings": {
|
|
||||||
"prefixAgo": "",
|
|
||||||
"prefixFromNow": "",
|
|
||||||
"suffixAgo": "ago",
|
|
||||||
"suffixFromNow": "",
|
|
||||||
"seconds": "%d seconds",
|
|
||||||
"minute": "about a minute",
|
|
||||||
"minutes": "%d minutes",
|
|
||||||
"hour": "about an hour",
|
|
||||||
"hours": "about %d hours",
|
|
||||||
"day": "a day",
|
|
||||||
"days": "%d days",
|
|
||||||
"month": "about a month",
|
|
||||||
"months": "%d months",
|
|
||||||
"year": "about a year",
|
|
||||||
"years": "%d years",
|
|
||||||
"wordSeparator": " "
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,8 +62,8 @@
|
|||||||
"history": {
|
"history": {
|
||||||
"accessibilityLabel": "This toot has been edited {{count}} times",
|
"accessibilityLabel": "This toot has been edited {{count}} times",
|
||||||
"accessibilityHint": "Tap to view the full edit history",
|
"accessibilityHint": "Tap to view the full edit history",
|
||||||
"text": "{{count}} edit",
|
"text_one": "{{count}} edit",
|
||||||
"text_plural": "{{count}} edits"
|
"text_other": "{{count}} edits"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attachment": {
|
"attachment": {
|
||||||
@ -219,10 +219,10 @@
|
|||||||
"refresh": "Refresh"
|
"refresh": "Refresh"
|
||||||
},
|
},
|
||||||
"count": {
|
"count": {
|
||||||
"voters": "{{count}} user voted",
|
"voters_one": "{{count}} user voted",
|
||||||
"voters_plural": "{{count}} users voted",
|
"voters_other": "{{count}} users voted",
|
||||||
"votes": "{{count}} vote",
|
"votes_one": "{{count}} vote",
|
||||||
"votes_plural": "{{count}} votes"
|
"votes_other": "{{count}} votes"
|
||||||
},
|
},
|
||||||
"expiration": {
|
"expiration": {
|
||||||
"expired": "Vote expired",
|
"expired": "Vote expired",
|
||||||
|
@ -42,7 +42,13 @@
|
|||||||
"placeholder": "Spoiler warning message"
|
"placeholder": "Spoiler warning message"
|
||||||
},
|
},
|
||||||
"textInput": {
|
"textInput": {
|
||||||
"placeholder": "What's on your mind"
|
"placeholder": "What's on your mind",
|
||||||
|
"keyboardImage": {
|
||||||
|
"exceedMaximum": {
|
||||||
|
"title": "Maximum attachments amount reached",
|
||||||
|
"OK": "$t(common:buttons.OK)"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
@ -136,8 +142,8 @@
|
|||||||
"accessibilityHint": "Open emoji selection panel, swipe horizontally to change page"
|
"accessibilityHint": "Open emoji selection panel, swipe horizontally to change page"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"drafts": "Draft ({{count}})",
|
"drafts_one": "Draft ({{count}})",
|
||||||
"drafts_plural": "Drafts ({{count}})"
|
"drafts_other": "Drafts ({{count}})"
|
||||||
},
|
},
|
||||||
"editAttachment": {
|
"editAttachment": {
|
||||||
"header": {
|
"header": {
|
||||||
|
@ -116,8 +116,8 @@
|
|||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"title": "Metadata",
|
"title": "Metadata",
|
||||||
"total": "{{count}} field",
|
"total_one": "{{count}} field",
|
||||||
"total_plural": "{{count}} fields"
|
"total_other": "{{count}} fields"
|
||||||
},
|
},
|
||||||
"visibility": {
|
"visibility": {
|
||||||
"title": "Posting Visibility",
|
"title": "Posting Visibility",
|
||||||
@ -281,6 +281,7 @@
|
|||||||
"accessibilityLabel": "Actions for user {{user}}",
|
"accessibilityLabel": "Actions for user {{user}}",
|
||||||
"accessibilityHint": "You can mute, block, report or share this user"
|
"accessibilityHint": "You can mute, block, report or share this user"
|
||||||
},
|
},
|
||||||
|
"followed_by": " is following you",
|
||||||
"moved": "User moved",
|
"moved": "User moved",
|
||||||
"created_at": "Registered on: {{date}}",
|
"created_at": "Registered on: {{date}}",
|
||||||
"summary": {
|
"summary": {
|
||||||
|
@ -13,6 +13,5 @@ export default {
|
|||||||
componentMediaSelector: require('./components/mediaSelector'),
|
componentMediaSelector: require('./components/mediaSelector'),
|
||||||
componentParse: require('./components/parse'),
|
componentParse: require('./components/parse'),
|
||||||
componentRelationship: require('./components/relationship'),
|
componentRelationship: require('./components/relationship'),
|
||||||
componentRelativeTime: require('./components/relativeTime'),
|
|
||||||
componentTimeline: require('./components/timeline')
|
componentTimeline: require('./components/timeline')
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"strings": {
|
|
||||||
"prefixAgo": "",
|
|
||||||
"prefixFromNow": "",
|
|
||||||
"suffixAgo": "전",
|
|
||||||
"suffixFromNow": "",
|
|
||||||
"seconds": "%d초",
|
|
||||||
"minute": "약 1분",
|
|
||||||
"minutes": "%d분",
|
|
||||||
"hour": "약 1시간",
|
|
||||||
"hours": "약 %d시간",
|
|
||||||
"day": "하루",
|
|
||||||
"days": "%d일",
|
|
||||||
"month": "약 1달",
|
|
||||||
"months": "%d달",
|
|
||||||
"year": "약 1년",
|
|
||||||
"years": "%d년",
|
|
||||||
"wordSeparator": ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -196,10 +196,10 @@
|
|||||||
"refresh": "새로고침"
|
"refresh": "새로고침"
|
||||||
},
|
},
|
||||||
"count": {
|
"count": {
|
||||||
"voters": "{{count}}명의 사용자가 투표",
|
"voters_one": "{{count}}명의 사용자가 투표",
|
||||||
"voters_plural": "{{count}}명의 사용자가 투표",
|
"voters_other": "{{count}}명의 사용자가 투표",
|
||||||
"votes": "{{count}} 투표",
|
"votes_one": "{{count}} 투표",
|
||||||
"votes_plural": "{{count}} 투표"
|
"votes_other": "{{count}} 투표"
|
||||||
},
|
},
|
||||||
"expiration": {
|
"expiration": {
|
||||||
"expired": "투표 종료됨",
|
"expired": "투표 종료됨",
|
||||||
|
@ -134,8 +134,8 @@
|
|||||||
"accessibilityHint": "이모지 선택 패널 열기, 가로로 스와이프해서 페이지를 바꿀 수 있어요"
|
"accessibilityHint": "이모지 선택 패널 열기, 가로로 스와이프해서 페이지를 바꿀 수 있어요"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"drafts": "초안 ({{count}})",
|
"drafts_one": "초안 ({{count}})",
|
||||||
"drafts_plural": "초안 ({{count}})"
|
"drafts_other": "초안 ({{count}})"
|
||||||
},
|
},
|
||||||
"editAttachment": {
|
"editAttachment": {
|
||||||
"header": {
|
"header": {
|
||||||
|
@ -113,8 +113,8 @@
|
|||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"title": "메타데이터",
|
"title": "메타데이터",
|
||||||
"total": "{{count}}개 필드",
|
"total_one": "{{count}}개 필드",
|
||||||
"total_plural": "{{count}}개 필드"
|
"total_other": "{{count}}개 필드"
|
||||||
},
|
},
|
||||||
"visibility": {
|
"visibility": {
|
||||||
"title": "공개 범위",
|
"title": "공개 범위",
|
||||||
|
@ -13,6 +13,5 @@ export default {
|
|||||||
componentMediaSelector: require('./components/mediaSelector'),
|
componentMediaSelector: require('./components/mediaSelector'),
|
||||||
componentParse: require('./components/parse'),
|
componentParse: require('./components/parse'),
|
||||||
componentRelationship: require('./components/relationship'),
|
componentRelationship: require('./components/relationship'),
|
||||||
componentRelativeTime: require('./components/relativeTime'),
|
|
||||||
componentTimeline: require('./components/timeline')
|
componentTimeline: require('./components/timeline')
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"strings": {
|
|
||||||
"prefixAgo": "",
|
|
||||||
"prefixFromNow": "",
|
|
||||||
"suffixAgo": " trước",
|
|
||||||
"suffixFromNow": "",
|
|
||||||
"seconds": "%d giây",
|
|
||||||
"minute": "một phút",
|
|
||||||
"minutes": "%d phút",
|
|
||||||
"hour": "một giờ",
|
|
||||||
"hours": "khoảng %d giờ",
|
|
||||||
"day": "một ngày",
|
|
||||||
"days": "%d ngày",
|
|
||||||
"month": "khoảng một tháng",
|
|
||||||
"months": "%d tháng",
|
|
||||||
"year": "khoảng một năm",
|
|
||||||
"years": "%d năm",
|
|
||||||
"wordSeparator": ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,6 +13,5 @@ export default {
|
|||||||
componentMediaSelector: require('./components/mediaSelector'),
|
componentMediaSelector: require('./components/mediaSelector'),
|
||||||
componentParse: require('./components/parse'),
|
componentParse: require('./components/parse'),
|
||||||
componentRelationship: require('./components/relationship'),
|
componentRelationship: require('./components/relationship'),
|
||||||
componentRelativeTime: require('./components/relativeTime'),
|
|
||||||
componentTimeline: require('./components/timeline')
|
componentTimeline: require('./components/timeline')
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"strings": {
|
|
||||||
"prefixAgo": "",
|
|
||||||
"prefixFromNow": "",
|
|
||||||
"suffixAgo": "前",
|
|
||||||
"suffixFromNow": "",
|
|
||||||
"seconds": "%d秒",
|
|
||||||
"minute": "1分钟",
|
|
||||||
"minutes": "%d分钟",
|
|
||||||
"hour": "1小时",
|
|
||||||
"hours": "%d小时",
|
|
||||||
"day": "1天",
|
|
||||||
"days": "%d天",
|
|
||||||
"month": "1个月",
|
|
||||||
"months": "%d月",
|
|
||||||
"year": "大约1年",
|
|
||||||
"years": "%d年",
|
|
||||||
"wordSeparator": ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"strings": {
|
|
||||||
"prefixAgo": "",
|
|
||||||
"prefixFromNow": "",
|
|
||||||
"suffixAgo": "前",
|
|
||||||
"suffixFromNow": "",
|
|
||||||
"seconds": "%d 秒",
|
|
||||||
"minute": "約 1 分",
|
|
||||||
"minutes": "%d 分",
|
|
||||||
"hour": "約 1 小時",
|
|
||||||
"hours": "約 %d 小時",
|
|
||||||
"day": "1 天",
|
|
||||||
"days": "%d 天",
|
|
||||||
"month": "約 1 個月",
|
|
||||||
"months": "%d 個月",
|
|
||||||
"year": "約 1 年",
|
|
||||||
"years": "%d 年",
|
|
||||||
"wordSeparator": ""
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@ import analytics from '@components/analytics'
|
|||||||
import Button from '@components/Button'
|
import Button from '@components/Button'
|
||||||
import haptics from '@components/haptics'
|
import haptics from '@components/haptics'
|
||||||
import { ParseHTML } from '@components/Parse'
|
import { ParseHTML } from '@components/Parse'
|
||||||
import RelativeTime from '@components/RelativeTime'
|
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { BlurView } from '@react-native-community/blur'
|
import { BlurView } from '@react-native-community/blur'
|
||||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||||
@ -15,6 +14,7 @@ import { StyleConstants } from '@utils/styles/constants'
|
|||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
import { FormattedRelativeTime } from 'react-intl'
|
||||||
import { Dimensions, Platform, Pressable, StyleSheet, View } from 'react-native'
|
import { Dimensions, Platform, Pressable, StyleSheet, View } from 'react-native'
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
import { Circle } from 'react-native-animated-spinkit'
|
||||||
import FastImage from 'react-native-fast-image'
|
import FastImage from 'react-native-fast-image'
|
||||||
@ -91,7 +91,17 @@ const ScreenAnnouncements: React.FC<
|
|||||||
>
|
>
|
||||||
<Trans
|
<Trans
|
||||||
i18nKey='screenAnnouncements:content.published'
|
i18nKey='screenAnnouncements:content.published'
|
||||||
components={[<RelativeTime date={item.published_at} />]}
|
components={[
|
||||||
|
<FormattedRelativeTime
|
||||||
|
value={
|
||||||
|
-(
|
||||||
|
new Date().getTime() -
|
||||||
|
new Date(item.published_at).getTime()
|
||||||
|
) / 1000
|
||||||
|
}
|
||||||
|
updateIntervalInSeconds={1}
|
||||||
|
/>
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</CustomText>
|
</CustomText>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import apiInstance from '@api/instance'
|
|
||||||
import analytics from '@components/analytics'
|
import analytics from '@components/analytics'
|
||||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||||
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
||||||
|
@ -5,6 +5,7 @@ import Icon from '@components/Icon'
|
|||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
import { useActionSheet } from '@expo/react-native-action-sheet'
|
import { useActionSheet } from '@expo/react-native-action-sheet'
|
||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
|
import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import layoutAnimation from '@utils/styles/layoutAnimation'
|
import layoutAnimation from '@utils/styles/layoutAnimation'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
@ -17,8 +18,10 @@ import React, {
|
|||||||
useRef
|
useRef
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { FlatList, Image, Pressable, StyleSheet, View } from 'react-native'
|
import { FlatList, Pressable, StyleSheet, View } from 'react-native'
|
||||||
import { Circle } from 'react-native-animated-spinkit'
|
import { Circle } from 'react-native-animated-spinkit'
|
||||||
|
import FastImage from 'react-native-fast-image'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
import ComposeContext from '../../utils/createContext'
|
import ComposeContext from '../../utils/createContext'
|
||||||
import { ExtendedAttachment } from '../../utils/types'
|
import { ExtendedAttachment } from '../../utils/types'
|
||||||
import chooseAndUploadAttachment from './addAttachment'
|
import chooseAndUploadAttachment from './addAttachment'
|
||||||
@ -33,9 +36,14 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
|||||||
const { showActionSheetWithOptions } = useActionSheet()
|
const { showActionSheetWithOptions } = useActionSheet()
|
||||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||||
const { t } = useTranslation('screenCompose')
|
const { t } = useTranslation('screenCompose')
|
||||||
const { colors, mode } = useTheme()
|
const { colors } = useTheme()
|
||||||
const navigation = useNavigation<any>()
|
const navigation = useNavigation<any>()
|
||||||
|
|
||||||
|
const maxAttachments = useSelector(
|
||||||
|
getInstanceConfigurationStatusMaxAttachments,
|
||||||
|
() => true
|
||||||
|
)
|
||||||
|
|
||||||
const flatListRef = useRef<FlatList>(null)
|
const flatListRef = useRef<FlatList>(null)
|
||||||
|
|
||||||
const sensitiveOnPress = useCallback(() => {
|
const sensitiveOnPress = useCallback(() => {
|
||||||
@ -124,7 +132,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
|||||||
width: calculateWidth(item)
|
width: calculateWidth(item)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Image
|
<FastImage
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
source={{
|
source={{
|
||||||
uri: item.local?.local_thumbnail || item.remote?.preview_url
|
uri: item.local?.local_thumbnail || item.remote?.preview_url
|
||||||
@ -320,7 +328,9 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
|||||||
item.local?.uri || item.remote?.url || Math.random().toString()
|
item.local?.uri || item.remote?.url || Math.random().toString()
|
||||||
}
|
}
|
||||||
ListFooterComponent={
|
ListFooterComponent={
|
||||||
composeState.attachments.uploads.length < 4 ? listFooter : null
|
composeState.attachments.uploads.length < maxAttachments
|
||||||
|
? listFooter
|
||||||
|
: null
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
@ -1,17 +1,25 @@
|
|||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
import { getInstanceConfigurationStatusMaxAttachments } 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, { useContext } from 'react'
|
import React, { useContext } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { TextInput } from 'react-native'
|
import { Alert, TextInput } from 'react-native'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
import formatText from '../../formatText'
|
import formatText from '../../formatText'
|
||||||
import ComposeContext from '../../utils/createContext'
|
import ComposeContext from '../../utils/createContext'
|
||||||
|
import { uploadAttachment } from '../Footer/addAttachment'
|
||||||
|
|
||||||
const ComposeTextInput: React.FC = () => {
|
const ComposeTextInput: React.FC = () => {
|
||||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||||
const { t } = useTranslation('screenCompose')
|
const { t } = useTranslation('screenCompose')
|
||||||
const { colors, mode } = useTheme()
|
const { colors, mode } = useTheme()
|
||||||
|
|
||||||
|
const maxAttachments = useSelector(
|
||||||
|
getInstanceConfigurationStatusMaxAttachments,
|
||||||
|
() => true
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextInput
|
<TextInput
|
||||||
keyboardAppearance={mode}
|
keyboardAppearance={mode}
|
||||||
@ -54,6 +62,36 @@ const ComposeTextInput: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
ref={composeState.textInputFocus.refs.text}
|
ref={composeState.textInputFocus.refs.text}
|
||||||
scrollEnabled={false}
|
scrollEnabled={false}
|
||||||
|
onImageChange={({ nativeEvent }) => {
|
||||||
|
if (composeState.attachments.uploads.length >= maxAttachments) {
|
||||||
|
Alert.alert(
|
||||||
|
t(
|
||||||
|
'content.root.header.textInput.keyboardImage.exceedMaximum.title'
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: t(
|
||||||
|
'content.root.header.textInput.keyboardImage.exceedMaximum.OK'
|
||||||
|
),
|
||||||
|
style: 'default'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (nativeEvent.linkUri) {
|
||||||
|
uploadAttachment({
|
||||||
|
composeDispatch,
|
||||||
|
imageInfo: {
|
||||||
|
uri: nativeEvent.linkUri,
|
||||||
|
type: 'image',
|
||||||
|
width: 100,
|
||||||
|
height: 100
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<CustomText>{composeState.text.formatted}</CustomText>
|
<CustomText>{composeState.text.formatted}</CustomText>
|
||||||
</TextInput>
|
</TextInput>
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
|
import { RootStackParamList } from '@utils/navigation/navigators'
|
||||||
import React, { useState, useCallback } from 'react'
|
import React, { useState, useCallback } from 'react'
|
||||||
import { Animated, Dimensions, StyleSheet } from 'react-native'
|
import { Animated, Dimensions, StyleSheet } from 'react-native'
|
||||||
import usePanResponder from '../hooks/usePanResponder'
|
import usePanResponder from '../hooks/usePanResponder'
|
||||||
@ -17,11 +18,11 @@ const SCREEN_WIDTH = SCREEN.width
|
|||||||
const SCREEN_HEIGHT = SCREEN.height
|
const SCREEN_HEIGHT = SCREEN.height
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
imageSrc: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
imageSrc: RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
||||||
onRequestClose: () => void
|
onRequestClose: () => void
|
||||||
onZoom: (isZoomed: boolean) => void
|
onZoom: (isZoomed: boolean) => void
|
||||||
onLongPress: (
|
onLongPress: (
|
||||||
image: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
image: RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
||||||
) => void
|
) => void
|
||||||
delayLongPress: number
|
delayLongPress: number
|
||||||
swipeToCloseEnabled?: boolean
|
swipeToCloseEnabled?: boolean
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import GracefullyImage from '@components/GracefullyImage'
|
import GracefullyImage from '@components/GracefullyImage'
|
||||||
|
import { RootStackParamList } from '@utils/navigation/navigators'
|
||||||
import React, { createRef, useCallback, useRef, useState } from 'react'
|
import React, { createRef, useCallback, useRef, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
Animated,
|
Animated,
|
||||||
@ -31,11 +32,11 @@ const SCREEN_WIDTH = SCREEN.width
|
|||||||
const SCREEN_HEIGHT = SCREEN.height
|
const SCREEN_HEIGHT = SCREEN.height
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
imageSrc: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
imageSrc: RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
||||||
onRequestClose: () => void
|
onRequestClose: () => void
|
||||||
onZoom: (scaled: boolean) => void
|
onZoom: (scaled: boolean) => void
|
||||||
onLongPress: (
|
onLongPress: (
|
||||||
image: Nav.RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
image: RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
|
||||||
) => void
|
) => void
|
||||||
swipeToCloseEnabled?: boolean
|
swipeToCloseEnabled?: boolean
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import CustomText from '@components/Text'
|
import CustomText from '@components/Text'
|
||||||
|
import { useRelationshipQuery } from '@utils/queryHooks/relationship'
|
||||||
import {
|
import {
|
||||||
getInstanceAccount,
|
getInstanceAccount,
|
||||||
getInstanceUri
|
getInstanceUri
|
||||||
@ -7,6 +8,7 @@ import {
|
|||||||
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, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
import { View } from 'react-native'
|
import { View } from 'react-native'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { PlaceholderLine } from 'rn-placeholder'
|
import { PlaceholderLine } from 'rn-placeholder'
|
||||||
@ -20,6 +22,7 @@ const AccountInformationAccount: React.FC<Props> = ({
|
|||||||
account,
|
account,
|
||||||
localInstance
|
localInstance
|
||||||
}) => {
|
}) => {
|
||||||
|
const { t } = useTranslation('screenTabs')
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
const instanceAccount = useSelector(
|
const instanceAccount = useSelector(
|
||||||
getInstanceAccount,
|
getInstanceAccount,
|
||||||
@ -27,6 +30,11 @@ const AccountInformationAccount: React.FC<Props> = ({
|
|||||||
)
|
)
|
||||||
const instanceUri = useSelector(getInstanceUri)
|
const instanceUri = useSelector(getInstanceUri)
|
||||||
|
|
||||||
|
const { data: relationship } = useRelationshipQuery({
|
||||||
|
id: account?.id || '',
|
||||||
|
options: { enabled: account !== undefined }
|
||||||
|
})
|
||||||
|
|
||||||
const movedContent = useMemo(() => {
|
const movedContent = useMemo(() => {
|
||||||
if (account?.moved) {
|
if (account?.moved) {
|
||||||
return (
|
return (
|
||||||
@ -65,6 +73,11 @@ const AccountInformationAccount: React.FC<Props> = ({
|
|||||||
@{localInstance ? instanceAccount?.acct : account?.acct}
|
@{localInstance ? instanceAccount?.acct : account?.acct}
|
||||||
{localInstance ? `@${instanceUri}` : null}
|
{localInstance ? `@${instanceUri}` : null}
|
||||||
</CustomText>
|
</CustomText>
|
||||||
|
{relationship?.followed_by ? (
|
||||||
|
<CustomText fontStyle='M' style={{ color: colors.secondary }}>
|
||||||
|
{t('shared.account.followed_by')}
|
||||||
|
</CustomText>
|
||||||
|
) : null}
|
||||||
{movedContent}
|
{movedContent}
|
||||||
{account?.locked ? (
|
{account?.locked ? (
|
||||||
<Icon
|
<Icon
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Audio } from 'expo-av'
|
import { Audio, InterruptionModeAndroid, InterruptionModeIOS } from 'expo-av'
|
||||||
import log from './log'
|
import log from './log'
|
||||||
|
|
||||||
const audio = () => {
|
const audio = () => {
|
||||||
log('log', 'audio', 'setting audio playback default options')
|
log('log', 'audio', 'setting audio playback default options')
|
||||||
Audio.setAudioModeAsync({
|
Audio.setAudioModeAsync({
|
||||||
playsInSilentModeIOS: true,
|
playsInSilentModeIOS: true,
|
||||||
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DUCK_OTHERS,
|
interruptionModeIOS: InterruptionModeIOS.DuckOthers,
|
||||||
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DUCK_OTHERS
|
interruptionModeAndroid: InterruptionModeAndroid.DuckOthers
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/startup/timezone.ts
Normal file
12
src/startup/timezone.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import * as Localization from 'expo-localization'
|
||||||
|
import log from './log'
|
||||||
|
|
||||||
|
const timezone = () => {
|
||||||
|
log('log', 'Timezone', Localization.timezone)
|
||||||
|
if ('__setDefaultTimeZone' in Intl.DateTimeFormat) {
|
||||||
|
// @ts-ignore
|
||||||
|
Intl.DateTimeFormat.__setDefaultTimeZone(Localization.timezone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default timezone
|
Loading…
x
Reference in New Issue
Block a user