mirror of
https://github.com/tooot-app/app
synced 2025-04-13 01:42:41 +02:00
Lots of updates
This commit is contained in:
parent
4a6229514f
commit
541e2a5601
7
App.tsx
7
App.tsx
@ -43,9 +43,12 @@ const App: React.FC = () => {
|
||||
}, [])
|
||||
|
||||
const onBeforeLift = useCallback(async () => {
|
||||
const netInfoRes = await netInfo()
|
||||
let netInfoRes = undefined
|
||||
try {
|
||||
netInfoRes = await netInfo()
|
||||
} catch {}
|
||||
|
||||
if (netInfoRes.corrupted && netInfoRes.corrupted.length) {
|
||||
if (netInfoRes && netInfoRes.corrupted && netInfoRes.corrupted.length) {
|
||||
setLocalCorrupt(netInfoRes.corrupted)
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ describe('Testing component button', () => {
|
||||
it('with icon only', () => {
|
||||
const onPress = jest.fn()
|
||||
const { getByTestId, toJSON } = render(
|
||||
<Button type='icon' content='x' onPress={onPress} />
|
||||
<Button type='icon' content='X' onPress={onPress} />
|
||||
)
|
||||
fireEvent.press(getByTestId('base'))
|
||||
|
||||
|
@ -16,6 +16,7 @@ exports[`Testing component menu header with text only 1`] = `
|
||||
Object {
|
||||
"fontSize": 14,
|
||||
"fontWeight": "600",
|
||||
"lineHeight": 20,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(135, 135, 135)",
|
||||
|
@ -15,7 +15,7 @@ exports[`Testing component menu row loading state 1`] = `
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"height": 50,
|
||||
"minHeight": 50,
|
||||
}
|
||||
}
|
||||
testID="base"
|
||||
@ -34,28 +34,35 @@ exports[`Testing component menu row loading state 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexBasis": "70%",
|
||||
"flex": 2,
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"fontSize": 16,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
Object {
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
test
|
||||
</Text>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"fontSize": 16,
|
||||
"lineHeight": 22,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
test
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@ -76,7 +83,7 @@ exports[`Testing component menu row on press event 1`] = `
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"height": 50,
|
||||
"minHeight": 50,
|
||||
}
|
||||
}
|
||||
testID="base"
|
||||
@ -95,28 +102,35 @@ exports[`Testing component menu row on press event 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexBasis": "70%",
|
||||
"flex": 2,
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"fontSize": 16,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
Object {
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
test
|
||||
</Text>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"fontSize": 16,
|
||||
"lineHeight": 22,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
test
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@ -137,7 +151,7 @@ exports[`Testing component menu row with title and content 1`] = `
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"height": 50,
|
||||
"minHeight": 50,
|
||||
}
|
||||
}
|
||||
testID="base"
|
||||
@ -156,37 +170,44 @@ exports[`Testing component menu row with title and content 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexBasis": "70%",
|
||||
"flex": 2,
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"fontSize": 16,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
Object {
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
test title
|
||||
</Text>
|
||||
<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,
|
||||
"flexBasis": "30%",
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
"marginLeft": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
@ -196,6 +217,7 @@ exports[`Testing component menu row with title and content 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"fontSize": 16,
|
||||
"lineHeight": 22,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(135, 135, 135)",
|
||||
@ -226,7 +248,7 @@ exports[`Testing component menu row with title only 1`] = `
|
||||
onStartShouldSetResponder={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"height": 50,
|
||||
"minHeight": 50,
|
||||
}
|
||||
}
|
||||
testID="base"
|
||||
@ -245,28 +267,35 @@ exports[`Testing component menu row with title only 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexBasis": "70%",
|
||||
"flex": 2,
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
<View
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"flex": 1,
|
||||
"fontSize": 16,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
Object {
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
test title
|
||||
</Text>
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Array [
|
||||
Object {
|
||||
"fontSize": 16,
|
||||
"lineHeight": 22,
|
||||
},
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
test title
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
59
__tests__/components/Timelines/Timeline/Shared/Card.js
Normal file
59
__tests__/components/Timelines/Timeline/Shared/Card.js
Normal file
@ -0,0 +1,59 @@
|
||||
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()
|
||||
})
|
||||
})
|
@ -0,0 +1,155 @@
|
||||
// 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,393 +1,474 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Testing component button static button apply custom styling 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 {
|
||||
"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
|
||||
<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={
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": undefined,
|
||||
"opacity": 1,
|
||||
}
|
||||
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="text"
|
||||
testID="base"
|
||||
>
|
||||
test
|
||||
</Text>
|
||||
<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
|
||||
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
|
||||
<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={
|
||||
Object {
|
||||
"color": "rgb(135, 135, 135)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": undefined,
|
||||
"opacity": 1,
|
||||
}
|
||||
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="text"
|
||||
testID="base"
|
||||
>
|
||||
test
|
||||
</Text>
|
||||
<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
|
||||
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>
|
||||
<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 {
|
||||
"position": "absolute",
|
||||
}
|
||||
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 {
|
||||
"alignItems": "center",
|
||||
"height": 16,
|
||||
"justifyContent": "center",
|
||||
"opacity": 1,
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
],
|
||||
"width": 16,
|
||||
"position": "absolute",
|
||||
}
|
||||
}
|
||||
>
|
||||
<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",
|
||||
"alignItems": "center",
|
||||
"height": 16,
|
||||
"justifyContent": "center",
|
||||
"opacity": 1,
|
||||
"transform": Array [
|
||||
Object {
|
||||
"rotate": "0deg",
|
||||
},
|
||||
Object {
|
||||
"translateY": -6,
|
||||
},
|
||||
Object {
|
||||
"scale": 1,
|
||||
},
|
||||
],
|
||||
"width": 4,
|
||||
"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
|
||||
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 />
|
||||
<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
|
||||
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
|
||||
<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={
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": undefined,
|
||||
"opacity": 1,
|
||||
}
|
||||
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="text"
|
||||
testID="base"
|
||||
>
|
||||
Test Button
|
||||
</Text>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"color": "rgb(18, 18, 18)",
|
||||
"fontSize": 16,
|
||||
"fontWeight": undefined,
|
||||
"opacity": 1,
|
||||
}
|
||||
}
|
||||
testID="text"
|
||||
>
|
||||
Test Button
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
`;
|
||||
|
31
jest.config.js
Normal file
31
jest.config.js
Normal file
@ -0,0 +1,31 @@
|
||||
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' +
|
||||
')'
|
||||
]
|
||||
}
|
3
jest/async-storage.js
Normal file
3
jest/async-storage.js
Normal file
@ -0,0 +1,3 @@
|
||||
import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock'
|
||||
|
||||
jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage)
|
24
package.json
24
package.json
@ -6,7 +6,7 @@
|
||||
"ios": "expo start --ios",
|
||||
"web": "expo start --web",
|
||||
"eject": "expo eject",
|
||||
"test": "jest"
|
||||
"test": "jest --watchAll"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native-async-storage/async-storage": "^1.13.2",
|
||||
@ -95,27 +95,9 @@
|
||||
"chalk": "^4.1.0",
|
||||
"jest": "^26.6.3",
|
||||
"jest-expo": "^40.0.1",
|
||||
"nock": "^13.0.5",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"typescript": "~4.1.3"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "jest-expo",
|
||||
"collectCoverage": true,
|
||||
"collectCoverageFrom": [
|
||||
"src /**/*.{ts,tsx}",
|
||||
"!**/coverage /**",
|
||||
"!**/node_modules /**",
|
||||
"!**/app.config.ts",
|
||||
"!**/babel.config.js",
|
||||
"!**/jest.setup.ts"
|
||||
],
|
||||
"setupFiles": [
|
||||
"<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/.*)"
|
||||
]
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
}
|
@ -58,7 +58,7 @@ const Button: React.FC<Props> = ({
|
||||
} else {
|
||||
mounted.current = true
|
||||
}
|
||||
}, [content, loading, disabled])
|
||||
}, [content, loading, disabled, active])
|
||||
|
||||
const loadingSpinkit = useMemo(
|
||||
() => (
|
||||
|
@ -5,15 +5,19 @@ import { useNavigation } from '@react-navigation/native'
|
||||
import hookApps from '@utils/queryHooks/apps'
|
||||
import hookInstance from '@utils/queryHooks/instance'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { InstanceLocal, remoteUpdate } from '@utils/slices/instancesSlice'
|
||||
import {
|
||||
getLocalInstances,
|
||||
InstanceLocal,
|
||||
remoteUpdate
|
||||
} from '@utils/slices/instancesSlice'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { debounce } from 'lodash'
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Image, StyleSheet, Text, TextInput, View } from 'react-native'
|
||||
import { Alert, Image, StyleSheet, Text, TextInput, View } from 'react-native'
|
||||
import { useQueryClient } from 'react-query'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import InstanceAuth from './Instance/Auth'
|
||||
import InstanceInfo from './Instance/Info'
|
||||
import { toast } from './toast'
|
||||
@ -36,6 +40,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
const { theme } = useTheme()
|
||||
const [instanceDomain, setInstanceDomain] = useState<string | undefined>()
|
||||
const [appData, setApplicationData] = useState<InstanceLocal['appData']>()
|
||||
const localInstances = useSelector(getLocalInstances)
|
||||
|
||||
const instanceQuery = hookInstance({
|
||||
instanceDomain,
|
||||
@ -79,12 +84,32 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
|
||||
const processUpdate = useCallback(() => {
|
||||
if (instanceDomain) {
|
||||
haptics('Success')
|
||||
switch (type) {
|
||||
case 'local':
|
||||
applicationQuery.refetch()
|
||||
return
|
||||
if (
|
||||
localInstances &&
|
||||
localInstances.filter(instance => instance.url === instanceDomain)
|
||||
.length
|
||||
) {
|
||||
Alert.alert(
|
||||
'域名已存在',
|
||||
'可以登录同个域名的另外一个账户,现有账户🈚️用',
|
||||
[
|
||||
{ text: '取消', style: 'cancel' },
|
||||
{
|
||||
text: '继续',
|
||||
onPress: () => {
|
||||
applicationQuery.refetch()
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
} else {
|
||||
applicationQuery.refetch()
|
||||
}
|
||||
break
|
||||
case 'remote':
|
||||
haptics('Success')
|
||||
const queryKey: QueryKeyTimeline = [
|
||||
'Timeline',
|
||||
{ page: 'RemotePublic' }
|
||||
@ -92,8 +117,8 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
dispatch(remoteUpdate(instanceDomain))
|
||||
queryClient.resetQueries(queryKey)
|
||||
toast({ type: 'success', message: '重置成功' })
|
||||
navigation.navigate('Screen-Remote-Root')
|
||||
return
|
||||
navigation.navigate('Screen-Public', { screen: 'Screen-Public-Root' })
|
||||
break
|
||||
}
|
||||
}
|
||||
}, [instanceDomain])
|
||||
@ -160,7 +185,7 @@ const ComponentInstance: React.FC<Props> = ({
|
||||
content={buttonContent}
|
||||
onPress={processUpdate}
|
||||
disabled={!instanceQuery.data?.uri}
|
||||
loading={instanceQuery.isFetching || applicationQuery.isFetching}
|
||||
loading={instanceQuery.isLoading || applicationQuery.isLoading}
|
||||
/>
|
||||
</View>
|
||||
<View>
|
||||
|
@ -1,12 +1,12 @@
|
||||
import Icon from '@components/Icon'
|
||||
import openLink from '@components/openLink'
|
||||
import ParseEmojis from '@components/Parse/Emojis'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { useNavigation, useRoute } from '@react-navigation/native'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { LinearGradient } from 'expo-linear-gradient'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { Image, Pressable, Text, View } from 'react-native'
|
||||
import { Pressable, Text, View } from 'react-native'
|
||||
import HTMLView from 'react-native-htmlview'
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
@ -16,6 +16,7 @@ import Animated, {
|
||||
|
||||
// Prevent going to the same hashtag multiple times
|
||||
const renderNode = ({
|
||||
routeParams,
|
||||
theme,
|
||||
node,
|
||||
index,
|
||||
@ -26,6 +27,7 @@ const renderNode = ({
|
||||
showFullLink,
|
||||
disableDetails
|
||||
}: {
|
||||
routeParams?: any
|
||||
theme: any
|
||||
node: any
|
||||
index: number
|
||||
@ -42,6 +44,10 @@ const renderNode = ({
|
||||
const href = node.attribs.href
|
||||
if (classes) {
|
||||
if (classes.includes('hashtag')) {
|
||||
const tag = href.split(new RegExp(/\/tag\/(.*)|\/tags\/(.*)/))
|
||||
const differentTag = routeParams?.hashtag
|
||||
? routeParams.hashtag !== tag[1] && routeParams.hashtag !== tag[2]
|
||||
: true
|
||||
return (
|
||||
<Text
|
||||
key={index}
|
||||
@ -50,8 +56,8 @@ const renderNode = ({
|
||||
...StyleConstants.FontStyle[size]
|
||||
}}
|
||||
onPress={() => {
|
||||
const tag = href.split(new RegExp(/\/tag\/(.*)|\/tags\/(.*)/))
|
||||
!disableDetails &&
|
||||
differentTag &&
|
||||
navigation.push('Screen-Shared-Hashtag', {
|
||||
hashtag: tag[1] || tag[2]
|
||||
})
|
||||
@ -65,6 +71,9 @@ const renderNode = ({
|
||||
const accountIndex = mentions.findIndex(
|
||||
mention => mention.url === href
|
||||
)
|
||||
const differentAccount = routeParams?.account
|
||||
? routeParams.account.id !== mentions[accountIndex].id
|
||||
: true
|
||||
return (
|
||||
<Text
|
||||
key={index}
|
||||
@ -75,6 +84,7 @@ const renderNode = ({
|
||||
onPress={() => {
|
||||
accountIndex !== -1 &&
|
||||
!disableDetails &&
|
||||
differentAccount &&
|
||||
navigation.push('Screen-Shared-Account', {
|
||||
account: mentions[accountIndex]
|
||||
})
|
||||
@ -151,11 +161,13 @@ const ParseHTML: React.FC<Props> = ({
|
||||
disableDetails = false
|
||||
}) => {
|
||||
const navigation = useNavigation()
|
||||
const route = useRoute()
|
||||
const { theme } = useTheme()
|
||||
|
||||
const renderNodeCallback = useCallback(
|
||||
(node, index) =>
|
||||
renderNode({
|
||||
routeParams: route.params,
|
||||
theme,
|
||||
node,
|
||||
index,
|
||||
|
@ -2,6 +2,7 @@ import client from '@api/client'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import { toast } from '@components/toast'
|
||||
import { QueryKeyRelationship } from '@utils/queryHooks/relationship'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -15,7 +16,7 @@ export interface Props {
|
||||
const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const relationshipQueryKey = ['Relationship', { id }]
|
||||
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const fireMutation = useCallback(
|
||||
@ -31,7 +32,7 @@ const RelationshipIncoming: React.FC<Props> = ({ id }) => {
|
||||
const mutation = useMutation(fireMutation, {
|
||||
onSuccess: res => {
|
||||
haptics('Success')
|
||||
queryClient.setQueryData(relationshipQueryKey, res)
|
||||
queryClient.setQueryData(queryKeyRelationship, res)
|
||||
queryClient.refetchQueries(['Notifications'])
|
||||
},
|
||||
onError: (err: any, { type }) => {
|
||||
|
@ -2,7 +2,9 @@ import client from '@api/client'
|
||||
import Button from '@components/Button'
|
||||
import haptics from '@components/haptics'
|
||||
import { toast } from '@components/toast'
|
||||
import hookRelationship from '@utils/queryHooks/relationship'
|
||||
import hookRelationship, {
|
||||
QueryKeyRelationship
|
||||
} from '@utils/queryHooks/relationship'
|
||||
import React, { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useMutation, useQueryClient } from 'react-query'
|
||||
@ -14,7 +16,7 @@ export interface Props {
|
||||
const RelationshipOutgoing: React.FC<Props> = ({ id }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const relationshipQueryKey = ['Relationship', { id }]
|
||||
const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }]
|
||||
const query = hookRelationship({ id })
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
@ -31,7 +33,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }) => {
|
||||
const mutation = useMutation(fireMutation, {
|
||||
onSuccess: res => {
|
||||
haptics('Success')
|
||||
queryClient.setQueryData(relationshipQueryKey, res)
|
||||
queryClient.setQueryData(queryKeyRelationship, res)
|
||||
},
|
||||
onError: (err: any, { type }) => {
|
||||
haptics('Error')
|
||||
|
@ -16,11 +16,12 @@ const Stack = createNativeStackNavigator<
|
||||
>()
|
||||
|
||||
export interface Props {
|
||||
name: 'Screen-Local-Root' | 'Screen-Public-Root'
|
||||
content: { title: string; page: App.Pages }[]
|
||||
name: 'Local' | 'Public'
|
||||
content: { title: string; page: App.Pages; remote?: boolean }[]
|
||||
}
|
||||
|
||||
const Timelines: React.FC<Props> = ({ name, content }) => {
|
||||
const remoteUrl = useSelector(getRemoteUrl)
|
||||
const navigation = useNavigation()
|
||||
const { mode } = useTheme()
|
||||
const localActiveIndex = useSelector(getLocalActiveIndex)
|
||||
@ -71,16 +72,19 @@ const Timelines: React.FC<Props> = ({ name, content }) => {
|
||||
<Stack.Navigator screenOptions={{ headerHideShadow: true }}>
|
||||
<Stack.Screen
|
||||
// @ts-ignore
|
||||
name={name}
|
||||
name={`Screen-${name}-Root`}
|
||||
component={screenComponent}
|
||||
options={{
|
||||
headerTitle: name === 'Screen-Public-Root' ? publicDomain : '',
|
||||
headerTitle: name === 'Public' ? publicDomain : '',
|
||||
...(localActiveIndex !== null && {
|
||||
headerCenter: () => (
|
||||
<View style={styles.segmentsContainer}>
|
||||
<SegmentedControl
|
||||
appearance={mode}
|
||||
values={[content[0].title, content[1].title]}
|
||||
values={[
|
||||
content[0].title,
|
||||
content[1].remote ? remoteUrl : content[1].title
|
||||
]}
|
||||
selectedIndex={segment}
|
||||
onChange={({ nativeEvent }) =>
|
||||
setSegment(nativeEvent.selectedSegmentIndex)
|
||||
@ -102,7 +106,7 @@ const Timelines: React.FC<Props> = ({ name, content }) => {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
segmentsContainer: {
|
||||
flexBasis: '60%'
|
||||
flexBasis: '65%'
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -16,11 +16,9 @@ const TimelineHeader = React.memo(
|
||||
一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字一大堆文字{' '}
|
||||
<Text
|
||||
style={{ color: theme.blue }}
|
||||
onPress={() =>
|
||||
navigation.navigate('Screen-Me', {
|
||||
screen: 'Screen-Me-Settings-UpdateRemote'
|
||||
})
|
||||
}
|
||||
onPress={() => {
|
||||
navigation.navigate('Screen-Me')
|
||||
}}
|
||||
>
|
||||
前往设置{' '}
|
||||
<Icon
|
||||
|
@ -13,22 +13,14 @@ export interface Props {
|
||||
const TimelineCard: React.FC<Props> = ({ card }) => {
|
||||
const { theme } = useTheme()
|
||||
|
||||
let isMounted = false
|
||||
useEffect(() => {
|
||||
isMounted = true
|
||||
|
||||
return () => {
|
||||
isMounted = false
|
||||
}
|
||||
})
|
||||
const [imageLoaded, setImageLoaded] = useState(false)
|
||||
useEffect(() => {
|
||||
const preFetch = () =>
|
||||
card.image &&
|
||||
isMounted &&
|
||||
Image.getSize(card.image, () => isMounted && setImageLoaded(true))
|
||||
preFetch()
|
||||
}, [isMounted])
|
||||
const preFetch = () => Image.getSize(card.image, () => setImageLoaded(true))
|
||||
|
||||
if (card.image) {
|
||||
preFetch()
|
||||
}
|
||||
}, [])
|
||||
const cardVisual = useMemo(() => {
|
||||
if (imageLoaded) {
|
||||
return <Image source={{ uri: card.image }} style={styles.image} />
|
||||
@ -45,12 +37,18 @@ const TimelineCard: React.FC<Props> = ({ card }) => {
|
||||
<Pressable
|
||||
style={[styles.card, { borderColor: theme.border }]}
|
||||
onPress={async () => await openLink(card.url)}
|
||||
testID='base'
|
||||
>
|
||||
{card.image && <View style={styles.left}>{cardVisual}</View>}
|
||||
{card.image && (
|
||||
<View style={styles.left} testID='image'>
|
||||
{cardVisual}
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.right}>
|
||||
<Text
|
||||
numberOfLines={2}
|
||||
style={[styles.rightTitle, { color: theme.primary }]}
|
||||
testID='title'
|
||||
>
|
||||
{card.title}
|
||||
</Text>
|
||||
@ -58,6 +56,7 @@ const TimelineCard: React.FC<Props> = ({ card }) => {
|
||||
<Text
|
||||
numberOfLines={1}
|
||||
style={[styles.rightDescription, { color: theme.primary }]}
|
||||
testID='description'
|
||||
>
|
||||
{card.description}
|
||||
</Text>
|
||||
|
@ -7,7 +7,7 @@ const ScreenLocal: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Timelines
|
||||
name='Screen-Local-Root'
|
||||
name='Local'
|
||||
content={[
|
||||
{ title: t('local:heading.segments.left'), page: 'Following' },
|
||||
{ title: t('local:heading.segments.right'), page: 'Local' }
|
||||
|
@ -6,8 +6,8 @@ import ScreenMeLists from '@screens/Me/Lists'
|
||||
import ScreenMeRoot from '@screens/Me/Root'
|
||||
import ScreenMeListsList from '@screens/Me/Root/Lists/List'
|
||||
import ScreenMeSettings from '@screens/Me/Settings'
|
||||
import UpdateRemote from '@screens/Me/Settings/UpdateRemote'
|
||||
import ScreenMeSwitch from '@screens/Me/Switch'
|
||||
import UpdateRemote from '@screens/Me/UpdateRemote'
|
||||
import sharedScreens from '@screens/Shared/sharedScreens'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
@ -20,13 +20,13 @@ import { useDispatch, useSelector } from 'react-redux'
|
||||
interface Props {
|
||||
index: NonNullable<InstancesState['local']['activeIndex']>
|
||||
instance: InstanceLocal
|
||||
active?: boolean
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
const AccountButton: React.FC<Props> = ({
|
||||
index,
|
||||
instance,
|
||||
active = false
|
||||
disabled = false
|
||||
}) => {
|
||||
const queryClient = useQueryClient()
|
||||
const navigation = useNavigation()
|
||||
@ -40,7 +40,7 @@ const AccountButton: React.FC<Props> = ({
|
||||
return (
|
||||
<Button
|
||||
type='text'
|
||||
active={active}
|
||||
disabled={disabled}
|
||||
loading={isLoading}
|
||||
style={styles.button}
|
||||
content={`@${data?.acct || '...'}@${instance.url}`}
|
||||
@ -78,7 +78,7 @@ const ScreenMeSwitchRoot = () => {
|
||||
key={index}
|
||||
index={index}
|
||||
instance={instance}
|
||||
active={localActiveIndex === index}
|
||||
disabled={localActiveIndex === index}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Timelines from '@components/Timelines'
|
||||
import { getRemoteUrl } from '@utils/slices/instancesSlice'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@ -7,10 +8,14 @@ const ScreenPublic: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Timelines
|
||||
name='Screen-Public-Root'
|
||||
name='Public'
|
||||
content={[
|
||||
{ title: t('public:heading.segments.left'), page: 'LocalPublic' },
|
||||
{ title: t('public:heading.segments.right'), page: 'RemotePublic' }
|
||||
{
|
||||
title: t('public:heading.segments.right'),
|
||||
page: 'RemotePublic',
|
||||
remote: true
|
||||
}
|
||||
]}
|
||||
/>
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Chase } from 'react-native-animated-spinkit'
|
||||
import { FlatList, ScrollView } from 'react-native-gesture-handler'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
import { useMutation } from 'react-query'
|
||||
@ -199,6 +200,20 @@ const ScreenSharedAnnouncements: React.FC<SharedAnnouncementsProp> = ({
|
||||
[]
|
||||
)
|
||||
|
||||
const ListEmptyComponent = useCallback(() => {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width: Dimensions.get('screen').width,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<Chase size={StyleConstants.Font.Size.L} color={theme.secondary} />
|
||||
</View>
|
||||
)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.base, { backgroundColor: theme.background }]}>
|
||||
<View style={[styles.header, { height: bottomTabBarHeight }]}>
|
||||
@ -211,6 +226,7 @@ const ScreenSharedAnnouncements: React.FC<SharedAnnouncementsProp> = ({
|
||||
renderItem={renderItem}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
onMomentumScrollEnd={onMomentumScrollEnd}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
/>
|
||||
<View style={[styles.indicators, { height: bottomTabBarHeight }]}>
|
||||
{data && data.length > 1 ? (
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
NativeStackNavigatorProps
|
||||
} from 'react-native-screens/lib/typescript/types'
|
||||
|
||||
type BaseScreens =
|
||||
export type BaseScreens =
|
||||
| Nav.LocalStackParamList
|
||||
| Nav.RemoteStackParamList
|
||||
| Nav.NotificationsStackParamList
|
||||
|
@ -2,12 +2,15 @@ import client from '@api/client'
|
||||
import { AxiosError } from 'axios'
|
||||
import { useQuery, UseQueryOptions } from 'react-query'
|
||||
|
||||
export type QueryKey = ['Relationship', { id: Mastodon.Account['id'] }]
|
||||
export type QueryKeyRelationship = [
|
||||
'Relationship',
|
||||
{ id: Mastodon.Account['id'] }
|
||||
]
|
||||
|
||||
const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
const queryFunction = ({ queryKey }: { queryKey: QueryKeyRelationship }) => {
|
||||
const { id } = queryKey[1]
|
||||
|
||||
return client<Mastodon.Relationship>({
|
||||
return client<Mastodon.Relationship[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/relationships`,
|
||||
@ -17,14 +20,21 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookRelationship = <TData = Mastodon.Relationship>({
|
||||
const hookRelationship = ({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
options?: UseQueryOptions<Mastodon.Relationship, AxiosError, TData>
|
||||
}: QueryKeyRelationship[1] & {
|
||||
options?: UseQueryOptions<
|
||||
Mastodon.Relationship[],
|
||||
AxiosError,
|
||||
Mastodon.Relationship
|
||||
>
|
||||
}) => {
|
||||
const queryKey: QueryKey = ['Relationship', { ...queryKeyParams }]
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
const queryKey: QueryKeyRelationship = ['Relationship', { ...queryKeyParams }]
|
||||
return useQuery(queryKey, queryFunction, {
|
||||
...options,
|
||||
select: data => data[0]
|
||||
})
|
||||
}
|
||||
|
||||
export default hookRelationship
|
||||
|
@ -55,9 +55,10 @@ export const localAddInstance = createAsyncThunk(
|
||||
url: InstanceLocal['url']
|
||||
token: InstanceLocal['token']
|
||||
appData: InstanceLocal['appData']
|
||||
}): Promise<InstanceLocal> => {
|
||||
const store = require('@root/store')
|
||||
const state = store.getState().instances
|
||||
}): Promise<{ type: 'add' | 'overwrite'; data: InstanceLocal }> => {
|
||||
const { store } = require('@root/store')
|
||||
const instanceLocal: InstancesState['local'] = store.getState().instances
|
||||
.local
|
||||
|
||||
const { id } = await client<Mastodon.Account>({
|
||||
method: 'get',
|
||||
@ -67,14 +68,24 @@ export const localAddInstance = createAsyncThunk(
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
})
|
||||
|
||||
// Overwrite existing account?
|
||||
// if (
|
||||
// state.local.instances.filter(
|
||||
// instance => instance && instance.account && instance.account.id === id
|
||||
// ).length
|
||||
// ) {
|
||||
// return Promise.reject()
|
||||
// }
|
||||
let type: 'add' | 'overwrite'
|
||||
if (
|
||||
instanceLocal.instances.filter(instance => {
|
||||
if (instance) {
|
||||
if (instance.url === url && instance.account.id === id) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}).length
|
||||
) {
|
||||
type = 'overwrite'
|
||||
} else {
|
||||
type = 'add'
|
||||
}
|
||||
|
||||
const preferences = await client<Mastodon.Preferences>({
|
||||
method: 'get',
|
||||
@ -85,15 +96,18 @@ export const localAddInstance = createAsyncThunk(
|
||||
})
|
||||
|
||||
return Promise.resolve({
|
||||
appData,
|
||||
url,
|
||||
token,
|
||||
account: {
|
||||
id,
|
||||
preferences
|
||||
},
|
||||
notification: {
|
||||
unread: false
|
||||
type,
|
||||
data: {
|
||||
appData,
|
||||
url,
|
||||
token,
|
||||
account: {
|
||||
id,
|
||||
preferences
|
||||
},
|
||||
notification: {
|
||||
unread: false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -101,31 +115,37 @@ export const localAddInstance = createAsyncThunk(
|
||||
export const localRemoveInstance = createAsyncThunk(
|
||||
'instances/localRemoveInstance',
|
||||
async (index?: InstancesState['local']['activeIndex']): Promise<number> => {
|
||||
const store = require('@root/store')
|
||||
const local = store.getState().instances.local
|
||||
const { store } = require('@root/store')
|
||||
const instanceLocal: InstancesState['local'] = store.getState().instances
|
||||
.local
|
||||
|
||||
if (index) {
|
||||
return Promise.resolve(index)
|
||||
} else {
|
||||
if (local.activeIndex !== null) {
|
||||
const currentInstance = local.instances[local.activeIndex]
|
||||
if (instanceLocal.activeIndex !== null) {
|
||||
const currentInstance =
|
||||
instanceLocal.instances[instanceLocal.activeIndex]
|
||||
|
||||
let revoked = undefined
|
||||
try {
|
||||
revoked = await AuthSession.revokeAsync(
|
||||
{
|
||||
clientId: currentInstance.appData.clientId,
|
||||
clientSecret: currentInstance.appData.clientSecret,
|
||||
token: currentInstance.token,
|
||||
scopes: ['read', 'write', 'follow', 'push']
|
||||
},
|
||||
{
|
||||
revocationEndpoint: `https://${currentInstance.url}/oauth/revoke`
|
||||
}
|
||||
)
|
||||
} catch {}
|
||||
|
||||
const revoked = await AuthSession.revokeAsync(
|
||||
{
|
||||
clientId: currentInstance.appData.clientId,
|
||||
clientSecret: currentInstance.appData.clientSecret,
|
||||
token: currentInstance.token,
|
||||
scopes: ['read', 'write', 'follow', 'push']
|
||||
},
|
||||
{
|
||||
revocationEndpoint: `https://${currentInstance.url}/oauth/revoke`
|
||||
}
|
||||
)
|
||||
if (!revoked) {
|
||||
console.warn('Revoking error')
|
||||
}
|
||||
|
||||
return Promise.resolve(local.activeIndex)
|
||||
return Promise.resolve(instanceLocal.activeIndex)
|
||||
} else {
|
||||
throw new Error('Active index invalid, cannot remove instance')
|
||||
}
|
||||
@ -176,8 +196,23 @@ const instancesSlice = createSlice({
|
||||
extraReducers: builder => {
|
||||
builder
|
||||
.addCase(localAddInstance.fulfilled, (state, action) => {
|
||||
state.local.instances.push(action.payload)
|
||||
state.local.activeIndex = state.local.instances.length - 1
|
||||
switch (action.payload.type) {
|
||||
case 'add':
|
||||
state.local.instances.push(action.payload.data)
|
||||
state.local.activeIndex = state.local.instances.length - 1
|
||||
break
|
||||
case 'overwrite':
|
||||
state.local.instances = state.local.instances.map(instance => {
|
||||
if (
|
||||
instance.url === action.payload.data.url &&
|
||||
instance.account.id === action.payload.data.account.id
|
||||
) {
|
||||
return action.payload.data
|
||||
} else {
|
||||
return instance
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
analytics('login')
|
||||
})
|
||||
|
22
yarn.lock
22
yarn.lock
@ -6513,7 +6513,7 @@ json-stable-stringify@^1.0.1:
|
||||
dependencies:
|
||||
jsonify "~0.0.0"
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
@ -6715,6 +6715,11 @@ lodash.pick@^4.4.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
||||
|
||||
lodash.set@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
|
||||
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
|
||||
|
||||
lodash.sortby@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
@ -7384,6 +7389,16 @@ nocache@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f"
|
||||
integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==
|
||||
|
||||
nock@^13.0.5:
|
||||
version "13.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nock/-/nock-13.0.5.tgz#a618c6f86372cb79fac04ca9a2d1e4baccdb2414"
|
||||
integrity sha512-1ILZl0zfFm2G4TIeJFW0iHknxr2NyA+aGCMTjDVUsBY4CkMRispF1pfIYkTRdAR/3Bg+UzdEuK0B6HczMQZcCg==
|
||||
dependencies:
|
||||
debug "^4.1.0"
|
||||
json-stringify-safe "^5.0.1"
|
||||
lodash.set "^4.3.2"
|
||||
propagate "^2.0.0"
|
||||
|
||||
node-fetch@2.6.1, node-fetch@^2.0.0-alpha.8, node-fetch@^2.2.0, node-fetch@^2.6.0:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
@ -8032,6 +8047,11 @@ prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
propagate@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45"
|
||||
integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user