mirror of https://github.com/tooot-app/app
Use `ky` instead of `fetch`
This commit is contained in:
parent
aa53533534
commit
698b54868e
|
@ -4631,6 +4631,11 @@
|
|||
"graceful-fs": "^4.1.9"
|
||||
}
|
||||
},
|
||||
"ky": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/ky/-/ky-0.24.0.tgz",
|
||||
"integrity": "sha512-/vpuQguwV30jErrqLpoaU/YJAFALrUkqqWLILnSoBOj5/O/LKzro/pPNtxbLgY6m4w5XNM6YZ3v7/or8qLlFuw=="
|
||||
},
|
||||
"leven": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
||||
|
@ -6020,6 +6025,21 @@
|
|||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||
"requires": {
|
||||
"isarray": "0.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
}
|
||||
}
|
||||
},
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
|
@ -6717,6 +6737,14 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-3.1.4.tgz",
|
||||
"integrity": "sha512-bXx3hqz4LovFoMnJIRGIWL2oJ/PHadXviBKvgZV9yNErtURQLJSn0yfQytVtiqslhaBMZOJwH4R6HiClyofvBg=="
|
||||
},
|
||||
"react-native-safe-area-view": {
|
||||
"version": "0.14.9",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.14.9.tgz",
|
||||
"integrity": "sha512-WII/ulhpVyL/qbYb7vydq7dJAfZRBcEhg4/UWt6F6nAKpLa3gAceMOxBxI914ppwSP/TdUsandFy6lkJQE0z4A==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"react-native-screens": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-2.10.1.tgz",
|
||||
|
@ -6754,6 +6782,45 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-navigation": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-4.4.3.tgz",
|
||||
"integrity": "sha512-tNBQQzbw0PVo9FLypQUUCISMcXW0wCW8oQeHtY0spWf35KC3IZHq/WcBm4E956wFsaqrDMGCUnyaVrxZNSuUGg==",
|
||||
"requires": {
|
||||
"@react-navigation/core": "^3.7.9",
|
||||
"@react-navigation/native": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-navigation/core": {
|
||||
"version": "3.7.9",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-3.7.9.tgz",
|
||||
"integrity": "sha512-EknbzM8OI9A5alRxXtQRV5Awle68B+z1QAxNty5DxmlS3BNfmduWNGnim159ROyqxkuDffK9L/U/Tbd45mx+Jg==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"path-to-regexp": "^1.8.0",
|
||||
"query-string": "^6.13.6",
|
||||
"react-is": "^16.13.0"
|
||||
}
|
||||
},
|
||||
"@react-navigation/native": {
|
||||
"version": "3.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-3.8.3.tgz",
|
||||
"integrity": "sha512-1yLd2pi8SK3wPC58mWZ5fjW5uYr1gmMN8YwjkA2qVjyVYfzzctRkoFDu8poO5UzxEIgf/4ns6ezBtKY1Q601UQ==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"react-native-safe-area-view": "^0.14.9"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"requires": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-redux": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.2.tgz",
|
||||
|
|
12
package.json
12
package.json
|
@ -12,13 +12,18 @@
|
|||
"@react-native-async-storage/async-storage": "^1.13.0",
|
||||
"@react-native-community/masked-view": "0.1.10",
|
||||
"@react-native-community/segmented-control": "2.1.1",
|
||||
"@react-native-community/viewpager": "4.1.6",
|
||||
"@react-navigation/bottom-tabs": "^5.9.2",
|
||||
"@react-navigation/native": "^5.7.6",
|
||||
"@react-navigation/stack": "^5.9.3",
|
||||
"@reduxjs/toolkit": "^1.4.0",
|
||||
"expo": "~39.0.2",
|
||||
"expo-app-auth": "~9.2.0",
|
||||
"expo-av": "~8.6.0",
|
||||
"expo-secure-store": "~9.2.0",
|
||||
"expo-splash-screen": "~0.6.1",
|
||||
"expo-status-bar": "~1.0.2",
|
||||
"ky": "^0.24.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
|
@ -33,11 +38,8 @@
|
|||
"react-native-screens": "~2.10.1",
|
||||
"react-native-web": "~0.13.7",
|
||||
"react-native-webview": "10.7.0",
|
||||
"react-redux": "^7.2.1",
|
||||
"expo-av": "~8.6.0",
|
||||
"expo-secure-store": "~9.2.0",
|
||||
"expo-splash-screen": "~0.6.1",
|
||||
"@react-native-community/viewpager": "4.1.6"
|
||||
"react-navigation": "^4.4.3",
|
||||
"react-redux": "^7.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "~7.9.0",
|
||||
|
|
|
@ -1,43 +1,40 @@
|
|||
export async function client (url, query, { body, ...customConfig } = {}) {
|
||||
if (!url) {
|
||||
return Promise.reject('Missing URL.')
|
||||
}
|
||||
const headers = { 'Content-Type': 'application/json' }
|
||||
import store from 'src/stacks/common/store'
|
||||
import ky from 'ky'
|
||||
|
||||
const config = {
|
||||
method: body ? 'POST' : 'GET',
|
||||
...customConfig,
|
||||
headers: {
|
||||
...headers,
|
||||
...customConfig.headers
|
||||
}
|
||||
}
|
||||
export default async function client ({
|
||||
method, // * get / post
|
||||
instance, // * local / remote
|
||||
endpoint, // * if url is empty
|
||||
query, // object
|
||||
body // object
|
||||
}) {
|
||||
const state = store.getState().instanceInfo
|
||||
|
||||
const queryString = query
|
||||
? `?${query.map(({ key, value }) => `${key}=${value}`).join('&')}`
|
||||
: ''
|
||||
|
||||
if (body) {
|
||||
config.body = JSON.stringify(body)
|
||||
}
|
||||
|
||||
let data
|
||||
let response
|
||||
try {
|
||||
const response = await fetch(`${url}${queryString}`, config)
|
||||
data = await response.json()
|
||||
if (response.ok) {
|
||||
return { headers: response.headers, body: data }
|
||||
}
|
||||
throw new Error(response.statusText)
|
||||
} catch (err) {
|
||||
return Promise.reject(err.message ? err.message : data)
|
||||
response = await ky(endpoint, {
|
||||
method: method,
|
||||
prefixUrl: `https://${state[instance]}/api/v1`,
|
||||
searchParams: query,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(instance === 'local' && {
|
||||
Authorization: `Bearer ${state.localToken}`
|
||||
})
|
||||
},
|
||||
...(body && { json: body })
|
||||
})
|
||||
} catch {
|
||||
return Promise.reject('ky error')
|
||||
}
|
||||
|
||||
if (response.ok) {
|
||||
return Promise.resolve({
|
||||
headers: response.headers,
|
||||
body: await response.json()
|
||||
})
|
||||
} else {
|
||||
console.error(response.error)
|
||||
return Promise.reject({ body: response.error_message })
|
||||
}
|
||||
}
|
||||
|
||||
client.get = function (instance, endpoint, query, customConfig = {}) {
|
||||
return client(instance, endpoint, query, { ...customConfig, method: 'GET' })
|
||||
}
|
||||
|
||||
client.post = function (instance, endpoint, query, body, customConfig = {}) {
|
||||
return client(instance, endpoint, query, { ...customConfig, body })
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import store from 'src/stacks/common/store'
|
||||
|
||||
export async function client (instance, query, { body, ...customConfig } = {}) {
|
||||
const state = store.getState().instanceInfo
|
||||
|
||||
let url
|
||||
let authHeader
|
||||
switch (instance.type) {
|
||||
case 'local':
|
||||
url = `https://${state.local}/${instance.endpoint}`
|
||||
authHeader = {
|
||||
Authorization: `Bearer ${state.localToken}`
|
||||
}
|
||||
break
|
||||
case 'remote':
|
||||
url = `https://${state.remote}/${instance.endpoint}`
|
||||
authHeader = {}
|
||||
break
|
||||
default:
|
||||
return Promise.reject('Instance type is not defined.')
|
||||
}
|
||||
|
||||
const headers = { 'Content-Type': 'application/json', ...authHeader }
|
||||
|
||||
const config = {
|
||||
method: body ? 'POST' : 'GET',
|
||||
...customConfig,
|
||||
headers: {
|
||||
...headers,
|
||||
...customConfig.headers
|
||||
}
|
||||
}
|
||||
|
||||
const queryString = query
|
||||
? `?${query.map(({ key, value }) => `${key}=${value}`).join('&')}`
|
||||
: ''
|
||||
|
||||
if (body) {
|
||||
config.body = JSON.stringify(body)
|
||||
}
|
||||
|
||||
let data
|
||||
try {
|
||||
const response = await fetch(`${url}${queryString}`, config)
|
||||
data = await response.json()
|
||||
if (response.ok) {
|
||||
return { headers: response.headers, body: data }
|
||||
}
|
||||
throw new Error(response.statusText)
|
||||
} catch (err) {
|
||||
return Promise.reject(err.message ? err.message : data)
|
||||
}
|
||||
}
|
||||
|
||||
client.get = function (instance, endpoint, query, customConfig = {}) {
|
||||
return client(instance, endpoint, query, { ...customConfig, method: 'GET' })
|
||||
}
|
||||
|
||||
client.post = function (instance, endpoint, query, body, customConfig = {}) {
|
||||
return client(instance, endpoint, query, { ...customConfig, body })
|
||||
}
|
|
@ -3,7 +3,10 @@ import PropTypes from 'prop-types'
|
|||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
|
||||
import action from 'src/components/action'
|
||||
|
||||
export default function Actions ({
|
||||
id,
|
||||
replies_count,
|
||||
reblogs_count,
|
||||
reblogged,
|
||||
|
@ -20,7 +23,7 @@ export default function Actions ({
|
|||
<Feather name='repeat' />
|
||||
<Text>{reblogs_count}</Text>
|
||||
</Pressable>
|
||||
<Pressable style={styles.action}>
|
||||
<Pressable style={styles.action} onPress={() => action('favourite', id)}>
|
||||
<Feather name='heart' />
|
||||
<Text>{favourites_count}</Text>
|
||||
</Pressable>
|
||||
|
@ -34,15 +37,23 @@ export default function Actions ({
|
|||
const styles = StyleSheet.create({
|
||||
actions: {
|
||||
flex: 1,
|
||||
flexDirection: 'row'
|
||||
flexDirection: 'row',
|
||||
marginTop: 4
|
||||
},
|
||||
action: {
|
||||
width: '25%',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center'
|
||||
justifyContent: 'center',
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8
|
||||
}
|
||||
})
|
||||
|
||||
// Actions.propTypes = {
|
||||
// uri: PropTypes.string
|
||||
// }
|
||||
Actions.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
replies_count: PropTypes.number.isRequired,
|
||||
reblogs_count: PropTypes.number.isRequired,
|
||||
reblogged: PropTypes.bool.isRequired,
|
||||
favourites_count: PropTypes.number.isRequired,
|
||||
favourited: PropTypes.bool.isRequired
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ export default function TootNotification ({ toot }) {
|
|||
account={actualAccount.acct}
|
||||
created_at={toot.created_at}
|
||||
/>
|
||||
{/* Can pass toot info to next page to speed up performance */}
|
||||
<Pressable
|
||||
onPress={() => navigation.navigate('Toot', { toot: toot.id })}
|
||||
>
|
||||
|
@ -52,7 +51,7 @@ export default function TootNotification ({ toot }) {
|
|||
/>
|
||||
)}
|
||||
{toot.status.poll && <Poll poll={toot.status.poll} />}
|
||||
{toot.status.media_attachments && (
|
||||
{toot.status.media_attachments.length > 0 && (
|
||||
<Attachment
|
||||
media_attachments={toot.status.media_attachments}
|
||||
sensitive={toot.status.sensitive}
|
||||
|
@ -67,6 +66,7 @@ export default function TootNotification ({ toot }) {
|
|||
</Pressable>
|
||||
{toot.status && (
|
||||
<Actions
|
||||
id={toot.status.id}
|
||||
replies_count={toot.status.replies_count}
|
||||
reblogs_count={toot.status.reblogs_count}
|
||||
reblogged={toot.status.reblogged}
|
||||
|
@ -78,7 +78,7 @@ export default function TootNotification ({ toot }) {
|
|||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}, [toot])
|
||||
|
||||
return tootView
|
||||
}
|
||||
|
|
|
@ -50,9 +50,9 @@ export default function TootTimeline ({ toot }) {
|
|||
/>
|
||||
{/* Can pass toot info to next page to speed up performance */}
|
||||
<Pressable
|
||||
// onPress={() =>
|
||||
// navigation.navigate('Toot', { toot: actualContent.id })
|
||||
// }
|
||||
onPress={() =>
|
||||
navigation.navigate('Toot', { toot: actualContent.id })
|
||||
}
|
||||
>
|
||||
{actualContent.content ? (
|
||||
<Content
|
||||
|
@ -77,6 +77,7 @@ export default function TootTimeline ({ toot }) {
|
|||
{actualContent.card && <Card card={actualContent.card} />}
|
||||
</Pressable>
|
||||
<Actions
|
||||
id={actualContent.id}
|
||||
replies_count={actualContent.replies_count}
|
||||
reblogs_count={actualContent.reblogs_count}
|
||||
reblogged={actualContent.reblogged}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import { Alert } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
import { client } from 'src/api/client'
|
||||
|
||||
export default async function action (type, id) {
|
||||
// If header if needed for remote server
|
||||
const header = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${useSelector(
|
||||
state => state.instanceInfo.localToken
|
||||
)}`
|
||||
}
|
||||
}
|
||||
const instance = `https://${useSelector(
|
||||
state => state.instanceInfo.local
|
||||
)}/api/v1/`
|
||||
|
||||
let endpoint
|
||||
switch (type) {
|
||||
case 'favourite':
|
||||
endpoint = `${instance}statuses/${id}/favourite`
|
||||
break
|
||||
case 'unfavourite':
|
||||
endpoint = `${instance}statuses/${id}/unfavourite`
|
||||
break
|
||||
case 'reblog':
|
||||
endpoint = `${instance}statuses/${id}/reblog`
|
||||
break
|
||||
case 'unreblog':
|
||||
endpoint = `${instance}statuses/${id}/unreblog`
|
||||
break
|
||||
case 'bookmark':
|
||||
endpoint = `${instance}statuses/${id}/bookmark`
|
||||
break
|
||||
case 'unbookmark':
|
||||
endpoint = `${instance}statuses/${id}/unbookmark`
|
||||
break
|
||||
case 'mute':
|
||||
endpoint = `${instance}statuses/${id}/mute`
|
||||
break
|
||||
case 'unmute':
|
||||
endpoint = `${instance}statuses/${id}/unmute`
|
||||
break
|
||||
case 'pin':
|
||||
endpoint = `${instance}statuses/${id}/pin`
|
||||
break
|
||||
case 'unpin':
|
||||
endpoint = `${instance}statuses/${id}/unpin`
|
||||
break
|
||||
}
|
||||
|
||||
const res = await client.post(endpoint, [], header)
|
||||
console.log(res)
|
||||
|
||||
const alert = {
|
||||
title: 'This is a title',
|
||||
message: 'This is a message'
|
||||
}
|
||||
Alert.alert(alert.title, alert.message, [
|
||||
{ text: 'OK', onPress: () => console.log('OK Pressed') }
|
||||
])
|
||||
}
|
|
@ -6,7 +6,7 @@ const propTypesAttachment = PropTypes.shape({
|
|||
type: PropTypes.oneOf(['unknown', 'image', 'gifv', 'video', 'audio'])
|
||||
.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
preview_url: PropTypes.string.isRequired,
|
||||
preview_url: PropTypes.string,
|
||||
|
||||
// Others
|
||||
remote_url: PropTypes.string,
|
||||
|
|
|
@ -15,7 +15,7 @@ export default function Timeline ({
|
|||
list,
|
||||
toot,
|
||||
account,
|
||||
disableRefresh
|
||||
disableRefresh = false
|
||||
}) {
|
||||
const dispatch = useDispatch()
|
||||
const state = useSelector(state => state.timelines[page])
|
||||
|
@ -50,11 +50,25 @@ export default function Timeline ({
|
|||
{...(state.pointer && { initialScrollIndex: state.pointer })}
|
||||
{...(!disableRefresh && {
|
||||
onRefresh: () =>
|
||||
dispatch(fetch({ page, paginationDirection: 'prev' })),
|
||||
dispatch(
|
||||
fetch({
|
||||
page,
|
||||
hashtag,
|
||||
list,
|
||||
paginationDirection: 'prev'
|
||||
})
|
||||
),
|
||||
refreshing: state.status === 'loading',
|
||||
onEndReached: () => {
|
||||
if (!timelineReady) {
|
||||
dispatch(fetch({ page, paginationDirection: 'next' }))
|
||||
dispatch(
|
||||
fetch({
|
||||
page,
|
||||
hashtag,
|
||||
list,
|
||||
paginationDirection: 'next'
|
||||
})
|
||||
)
|
||||
setTimelineReady(true)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -101,7 +101,8 @@ TimelinesCombined.propTypes = {
|
|||
content: PropTypes.arrayOf(
|
||||
PropTypes.exact({
|
||||
title: PropTypes.string.isRequired,
|
||||
page: Timeline.propTypes.page
|
||||
page: Timeline.propTypes.page,
|
||||
instance: PropTypes.oneOf(['local', 'remote'])
|
||||
})
|
||||
).isRequired
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
|
||||
|
||||
import { client } from 'src/api/client'
|
||||
import client from 'src/api/client'
|
||||
|
||||
export const fetch = createAsyncThunk(
|
||||
'account/fetch',
|
||||
async ({ id }, { getState }) => {
|
||||
const instanceLocal = `https://${getState().instanceInfo.local}/api/v1/`
|
||||
const res = await client.get(`${instanceLocal}accounts/${id}`)
|
||||
const res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${id}`
|
||||
})
|
||||
return res.body
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
|
||||
|
||||
import { client } from 'src/api/client'
|
||||
import client from 'src/api/client'
|
||||
|
||||
// Naming convention
|
||||
// Following: timelines/home
|
||||
|
@ -11,170 +11,161 @@ import { client } from 'src/api/client'
|
|||
// Hashtag: hastag
|
||||
// List: list
|
||||
|
||||
function getPagination (headers, direction) {
|
||||
if (!headers) console.error('Missing pagination headers')
|
||||
const paginationLinks = headers.get('Link')
|
||||
if (paginationLinks) {
|
||||
if (direction) {
|
||||
return {
|
||||
[direction]: paginationLinks.split(
|
||||
new RegExp(`<([^>]+)>; rel="${direction}"`)
|
||||
)[1]
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
prev: paginationLinks.split(new RegExp(/<([^>]+)>; rel="prev"/))[1],
|
||||
next: paginationLinks.split(new RegExp(/<([^>]+)>; rel="next"/))[1]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
export const fetch = createAsyncThunk(
|
||||
'timeline/fetch',
|
||||
async (
|
||||
{ page, paginationDirection, query = [], account, hashtag, list, toot },
|
||||
{ page, paginationDirection, query = {}, account, hashtag, list, toot },
|
||||
{ getState }
|
||||
) => {
|
||||
const instanceLocal = `https://${getState().instanceInfo.local}/api/v1/`
|
||||
const instanceRemote = `https://${getState().instanceInfo.remote}/api/v1/`
|
||||
// If header if needed for remote server
|
||||
const header = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${getState().instanceInfo.localToken}`
|
||||
}
|
||||
}
|
||||
|
||||
let res
|
||||
// For same page, but only pagination
|
||||
|
||||
if (paginationDirection) {
|
||||
res = await client.get(
|
||||
getState().timelines[page].pagination[paginationDirection],
|
||||
query,
|
||||
header
|
||||
)
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers, paginationDirection)
|
||||
const allToots = getState().timelines[page].toots
|
||||
switch (paginationDirection) {
|
||||
case 'prev':
|
||||
query.min_id = allToots[0].id
|
||||
break
|
||||
case 'next':
|
||||
query.max_id = allToots[allToots.length - 1].id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// For each page's first query
|
||||
switch (page) {
|
||||
case 'Following':
|
||||
res = await client.get(`${instanceLocal}timelines/home`, query, header)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'timelines/home',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Local':
|
||||
query.push({ key: 'local', value: 'true' })
|
||||
res = await client.get(
|
||||
`${instanceLocal}timelines/public`,
|
||||
query,
|
||||
header
|
||||
)
|
||||
query.local = 'true'
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'timelines/public',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'LocalPublic':
|
||||
res = await client.get(
|
||||
`${instanceLocal}timelines/public`,
|
||||
query,
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'timelines/public',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'RemotePublic':
|
||||
res = await client.get(`${instanceRemote}timelines/public`, query)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'remote',
|
||||
endpoint: 'timelines/public',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Notifications':
|
||||
res = await client.get(`${instanceLocal}notifications`, query, header)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'notifications',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Account_Default':
|
||||
res = await client.get(
|
||||
`${instanceLocal}accounts/${account}/statuses`,
|
||||
[{ key: 'pinned', value: 'true' }],
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query: {
|
||||
pinned: 'true'
|
||||
}
|
||||
})
|
||||
const toots = res.body
|
||||
res = await client.get(
|
||||
`${instanceLocal}accounts/${account}/statuses`,
|
||||
[{ key: 'exclude_replies', value: 'true' }],
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query: {
|
||||
exclude_replies: 'true'
|
||||
}
|
||||
})
|
||||
toots.push(...res.body)
|
||||
return { toots: toots }
|
||||
|
||||
case 'Account_All':
|
||||
res = await client.get(
|
||||
`${instanceLocal}accounts/${account}/statuses`,
|
||||
query,
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Account_Media':
|
||||
res = await client.get(
|
||||
`${instanceLocal}accounts/${account}/statuses`,
|
||||
[{ key: 'only_media', value: 'true' }],
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query: {
|
||||
only_media: 'true'
|
||||
}
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Hashtag':
|
||||
res = await client.get(
|
||||
`${instanceLocal}timelines/tag/${hashtag}`,
|
||||
query,
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `timelines/tag/${hashtag}`,
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'List':
|
||||
res = await client.get(
|
||||
`${instanceLocal}timelines/list/${list}`,
|
||||
query,
|
||||
header
|
||||
)
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `timelines/list/${list}`,
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body,
|
||||
pagination: getPagination(res.headers)
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Toot':
|
||||
const current = await client.get(
|
||||
`${instanceLocal}statuses/${toot}`,
|
||||
[],
|
||||
header
|
||||
)
|
||||
const context = await client.get(
|
||||
`${instanceLocal}statuses/${toot}/context`,
|
||||
[],
|
||||
header
|
||||
)
|
||||
const current = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${toot}`
|
||||
})
|
||||
const context = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${toot}/context`
|
||||
})
|
||||
return {
|
||||
toots: [...context.ancestors, current, ...context.descendants],
|
||||
pointer: context.ancestors.length
|
||||
|
@ -188,7 +179,6 @@ export const fetch = createAsyncThunk(
|
|||
|
||||
const timelineInitState = {
|
||||
toots: [],
|
||||
pagination: { prev: undefined, next: undefined },
|
||||
pointer: undefined,
|
||||
status: 'idle'
|
||||
}
|
||||
|
@ -226,12 +216,6 @@ export const timelineSlice = createSlice({
|
|||
state[action.meta.arg.page].toots.push(...action.payload.toots)
|
||||
}
|
||||
|
||||
if (action.payload.pagination) {
|
||||
state[action.meta.arg.page].pagination = {
|
||||
...state[action.meta.arg.page].pagination,
|
||||
...action.payload.pagination
|
||||
}
|
||||
}
|
||||
if (action.payload.pointer) {
|
||||
state[action.meta.arg.page].pointer = action.payload.pointer
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue