1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Switch to shared hooks

This commit is contained in:
Zhiyuan Zheng
2021-01-11 21:36:57 +01:00
parent fdce172c57
commit 284d6e46e0
47 changed files with 1053 additions and 727 deletions

View File

@ -14,7 +14,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
})
}
const hookAccount = <TData = Mastodon.Account>({
const useAccountQuery = <TData = Mastodon.Account>({
options,
...queryKeyParams
}: QueryKey[1] & {
@ -24,4 +24,4 @@ const hookAccount = <TData = Mastodon.Account>({
return useQuery(queryKey, queryFunction, options)
}
export default hookAccount
export { useAccountQuery }

View File

@ -22,7 +22,7 @@ const queryFunction = async ({ queryKey }: { queryKey: QueryKey }) => {
})
}
const hookAccountCheck = <TData = Mastodon.Account>({
const useAccountCheckQuery = <TData = Mastodon.Account>({
options,
...queryKeyParams
}: QueryKey[1] & {
@ -32,4 +32,4 @@ const hookAccountCheck = <TData = Mastodon.Account>({
return useQuery(queryKey, queryFunction, options)
}
export default hookAccountCheck
export { useAccountCheckQuery }

View File

@ -1,10 +1,15 @@
import client from '@api/client'
import { AxiosError } from 'axios'
import { useQuery, UseQueryOptions } from 'react-query'
import {
useMutation,
UseMutationOptions,
useQuery,
UseQueryOptions
} from 'react-query'
type QueryKey = ['Announcements', { showAll?: boolean }]
type QueryKeyAnnouncement = ['Announcements', { showAll?: boolean }]
const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
const queryFunction = ({ queryKey }: { queryKey: QueryKeyAnnouncement }) => {
const { showAll } = queryKey[1]
return client<Mastodon.Announcement[]>({
@ -19,14 +24,52 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
})
}
const hookAnnouncement = <TData = Mastodon.Announcement[]>({
const useAnnouncementQuery = <TData = Mastodon.Announcement[]>({
options,
...queryKeyParams
}: QueryKey[1] & {
}: QueryKeyAnnouncement[1] & {
options?: UseQueryOptions<Mastodon.Announcement[], AxiosError, TData>
}) => {
const queryKey: QueryKey = ['Announcements', { ...queryKeyParams }]
const queryKey: QueryKeyAnnouncement = [
'Announcements',
{ ...queryKeyParams }
]
return useQuery(queryKey, queryFunction, options)
}
export default hookAnnouncement
type MutationVarsAnnouncement = {
id: Mastodon.Announcement['id']
type: 'reaction' | 'dismiss'
name?: Mastodon.AnnouncementReaction['name']
me?: boolean
}
const mutationFunction = async ({
id,
type,
name,
me
}: MutationVarsAnnouncement) => {
switch (type) {
case 'reaction':
return client<{}>({
method: me ? 'delete' : 'put',
instance: 'local',
url: `announcements/${id}/reactions/${name}`
})
case 'dismiss':
return client<{}>({
method: 'post',
instance: 'local',
url: `announcements/${id}/dismiss`
})
}
}
const useAnnouncementMutation = (
options: UseMutationOptions<{}, AxiosError, MutationVarsAnnouncement>
) => {
return useMutation(mutationFunction, options)
}
export { useAnnouncementQuery, useAnnouncementMutation }

View File

@ -21,7 +21,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
})
}
const hookApps = <TData = Mastodon.Apps>({
const useAppsQuery = <TData = Mastodon.Apps>({
options,
...queryKeyParams
}: QueryKey[1] & {
@ -31,4 +31,4 @@ const hookApps = <TData = Mastodon.Apps>({
return useQuery(queryKey, queryFunction, options)
}
export default hookApps
export { useAppsQuery }

View File

@ -12,7 +12,7 @@ const queryFunction = () => {
})
}
const hookEmojis = <TData = Mastodon.Emoji[]>({
const useEmojisQuery = <TData = Mastodon.Emoji[]>({
options
}: {
options?: UseQueryOptions<Mastodon.Emoji[], AxiosError, TData>
@ -21,4 +21,4 @@ const hookEmojis = <TData = Mastodon.Emoji[]>({
return useQuery(queryKey, queryFunction, options)
}
export default hookEmojis
export { useEmojisQuery }

View File

@ -15,7 +15,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
})
}
const hookInstance = <TData = Mastodon.Instance>({
const useInstanceQuery = <TData = Mastodon.Instance>({
options,
...queryKeyParams
}: QueryKey[1] & {
@ -25,4 +25,4 @@ const hookInstance = <TData = Mastodon.Instance>({
return useQuery(queryKey, queryFunction, options)
}
export default hookInstance
export { useInstanceQuery }

View File

@ -12,7 +12,7 @@ const queryFunction = () => {
})
}
const hookLists = <TData = Mastodon.List[]>({
const useListsQuery = <TData = Mastodon.List[]>({
options
}: {
options?: UseQueryOptions<Mastodon.List[], AxiosError, TData>
@ -21,4 +21,4 @@ const hookLists = <TData = Mastodon.List[]>({
return useQuery(queryKey, queryFunction, options)
}
export default hookLists
export { useListsQuery }

View File

@ -1,6 +1,11 @@
import client from '@api/client'
import { AxiosError } from 'axios'
import { useQuery, UseQueryOptions } from 'react-query'
import {
useMutation,
UseMutationOptions,
useQuery,
UseQueryOptions
} from 'react-query'
export type QueryKeyRelationship = [
'Relationship',
@ -20,7 +25,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKeyRelationship }) => {
})
}
const hookRelationship = ({
const useRelationshipQuery = ({
options,
...queryKeyParams
}: QueryKeyRelationship[1] & {
@ -37,4 +42,45 @@ const hookRelationship = ({
})
}
export default hookRelationship
type MutationVarsRelationship =
| {
id: Mastodon.Account['id']
type: 'incoming'
payload: { action: 'authorize' | 'reject' }
}
| {
id: Mastodon.Account['id']
type: 'outgoing'
payload: { action: 'follow' | 'block'; state: boolean }
}
const mutationFunction = async (params: MutationVarsRelationship) => {
switch (params.type) {
case 'incoming':
return client<Mastodon.Relationship>({
method: 'post',
instance: 'local',
url: `follow_requests/${params.id}/${params.payload.action}`
})
case 'outgoing':
return client<Mastodon.Relationship>({
method: 'post',
instance: 'local',
url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${
params.payload.action
}`
})
}
}
const useRelationshipMutation = (
options: UseMutationOptions<
Mastodon.Relationship,
AxiosError,
MutationVarsRelationship
>
) => {
return useMutation(mutationFunction, options)
}
export { useRelationshipQuery, useRelationshipMutation }

View File

@ -33,7 +33,7 @@ const queryFunction = ({
})
}
const hookRelationships = <TData = Mastodon.Account[]>({
const useRelationshipsQuery = <TData = Mastodon.Account[]>({
options,
...queryKeyParams
}: QueryKey[1] & {
@ -43,4 +43,4 @@ const hookRelationships = <TData = Mastodon.Account[]>({
return useInfiniteQuery(queryKey, queryFunction, options)
}
export default hookRelationships
export { useRelationshipsQuery }

View File

@ -28,7 +28,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
})
}
const hookSearch = <TData = SearchResult>({
const useSearchQuery = <TData = SearchResult>({
options,
...queryKeyParams
}: QueryKey[1] & {
@ -38,4 +38,4 @@ const hookSearch = <TData = SearchResult>({
return useQuery(queryKey, queryFunction, options)
}
export default hookSearch
export { useSearchQuery }

View File

@ -1,7 +1,16 @@
import client from '@api/client'
import haptics from '@components/haptics'
import { AxiosError } from 'axios'
import { uniqBy } from 'lodash'
import { useInfiniteQuery, UseInfiniteQueryOptions } from 'react-query'
import {
MutationOptions,
QueryClient,
useInfiniteQuery,
UseInfiniteQueryOptions,
useMutation
} from 'react-query'
import deleteItem from './timeline/deleteItem'
import updateStatusProperty from './timeline/updateStatusProperty'
export type QueryKeyTimeline = [
'Timeline',
@ -14,7 +23,7 @@ export type QueryKeyTimeline = [
}
]
const queryFunction = async ({
const queryFunction = ({
queryKey,
pageParam
}: {
@ -22,7 +31,6 @@ const queryFunction = async ({
pageParam?: { direction: 'prev' | 'next'; id: Mastodon.Status['id'] }
}) => {
const { page, account, hashtag, list, toot } = queryKey[1]
let res
let params: { [key: string]: string } = {}
if (pageParam) {
@ -46,74 +54,51 @@ const queryFunction = async ({
switch (page) {
case 'Following':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: 'timelines/home',
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Local':
params.local = 'true'
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: 'timelines/public',
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
params: {
...params,
local: 'true'
}
})
case 'LocalPublic':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: 'timelines/public',
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'RemotePublic':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'remote',
url: 'timelines/public',
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Notifications':
res = await client<Mastodon.Notification[]>({
return client<Mastodon.Notification[]>({
method: 'get',
instance: 'local',
url: 'notifications',
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Account_Default':
if (pageParam && pageParam.direction === 'next') {
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `accounts/${account}/statuses`,
@ -122,53 +107,41 @@ const queryFunction = async ({
...params
}
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
} else {
res = await client<Mastodon.Status[]>({
return client<(Mastodon.Status & { isPinned: boolean })[]>({
method: 'get',
instance: 'local',
url: `accounts/${account}/statuses`,
params: {
pinned: 'true'
}
})
const pinnedLength = res.length
let toots = res
res = await client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `accounts/${account}/statuses`,
params: {
exclude_replies: 'true'
}
})
toots = uniqBy([...toots, ...res], 'id')
return Promise.resolve({
toots: toots,
pointer: undefined,
pinnedLength
}).then(async res1 => {
let toots = res1.map(status => {
status.isPinned = true
return status
})
const res2 = await client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `accounts/${account}/statuses`,
params: {
exclude_replies: 'true'
}
})
return uniqBy([...toots, ...res2], 'id')
})
}
case 'Account_All':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `accounts/${account}/statuses`,
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Account_Media':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `accounts/${account}/statuses`,
@ -177,100 +150,62 @@ const queryFunction = async ({
...params
}
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Hashtag':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `timelines/tag/${hashtag}`,
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Conversations':
res = await client<Mastodon.Conversation[]>({
return client<Mastodon.Conversation[]>({
method: 'get',
instance: 'local',
url: `conversations`,
params
})
if (pageParam) {
// Bug in pull to refresh in conversations
res = res.filter(b => b.id !== pageParam.id)
}
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Bookmarks':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `bookmarks`,
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Favourites':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `favourites`,
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'List':
res = await client<Mastodon.Status[]>({
return client<Mastodon.Status[]>({
method: 'get',
instance: 'local',
url: `timelines/list/${list}`,
params
})
return Promise.resolve({
toots: res,
pointer: undefined,
pinnedLength: undefined
})
case 'Toot':
res = await client<Mastodon.Status>({
return client<Mastodon.Status>({
method: 'get',
instance: 'local',
url: `statuses/${toot}`
})
const theToot = res
res = await client<{
ancestors: Mastodon.Status[]
descendants: Mastodon.Status[]
}>({
method: 'get',
instance: 'local',
url: `statuses/${toot}/context`
})
return Promise.resolve({
toots: [...res.ancestors, theToot, ...res.descendants],
pointer: res.ancestors.length,
pinnedLength: undefined
}).then(async res1 => {
const res2 = await client<{
ancestors: Mastodon.Status[]
descendants: Mastodon.Status[]
}>({
method: 'get',
instance: 'local',
url: `statuses/${toot}/context`
})
return [...res2.ancestors, res1, ...res2.descendants]
})
default:
return Promise.reject()
@ -278,7 +213,8 @@ const queryFunction = async ({
}
type Unpromise<T extends Promise<any>> = T extends Promise<infer U> ? U : never
const hookTimeline = <TData = Unpromise<ReturnType<typeof queryFunction>>>({
export type TimelineData = Unpromise<ReturnType<typeof queryFunction>>
const useTimelineQuery = <TData = TimelineData>({
options,
...queryKeyParams
}: QueryKeyTimeline[1] & {
@ -288,4 +224,199 @@ const hookTimeline = <TData = Unpromise<ReturnType<typeof queryFunction>>>({
return useInfiniteQuery(queryKey, queryFunction, options)
}
export default hookTimeline
// --- Separator ---
enum MapPropertyToUrl {
bookmarked = 'bookmark',
favourited = 'favourite',
muted = 'mute',
pinned = 'pin',
reblogged = 'reblog'
}
export type MutationVarsTimelineUpdateStatusProperty = {
// This is status in general, including "status" inside conversation and notification
type: 'updateStatusProperty'
queryKey: QueryKeyTimeline
id: Mastodon.Status['id'] | Mastodon.Poll['id']
reblog?: boolean
payload:
| {
property: 'bookmarked' | 'favourited' | 'muted' | 'pinned' | 'reblogged'
currentValue: boolean
}
| {
property: 'poll'
id: Mastodon.Poll['id']
type: 'vote' | 'refresh'
options?: boolean[]
data?: Mastodon.Poll
}
}
export type MutationVarsTimelineUpdateAccountProperty = {
// This is status in general, including "status" inside conversation and notification
type: 'updateAccountProperty'
queryKey?: QueryKeyTimeline
id: Mastodon.Account['id']
payload: {
property: 'mute' | 'block' | 'reports'
}
}
export type MutationVarsTimelineDeleteItem = {
// This is for deleting status and conversation
type: 'deleteItem'
source: 'statuses' | 'conversations'
queryKey: QueryKeyTimeline
id: Mastodon.Conversation['id']
}
export type MutationVarsTimelineDomainBlock = {
// This is for deleting status and conversation
type: 'domainBlock'
queryKey: QueryKeyTimeline
domain: string
}
export type MutationVarsTimeline =
| MutationVarsTimelineUpdateStatusProperty
| MutationVarsTimelineUpdateAccountProperty
| MutationVarsTimelineDeleteItem
| MutationVarsTimelineDomainBlock
const mutationFunction = async (params: MutationVarsTimeline) => {
switch (params.type) {
case 'updateStatusProperty':
switch (params.payload.property) {
case 'poll':
const formData = new FormData()
params.payload.type === 'vote' &&
params.payload.options!.forEach((option, index) => {
if (option) {
formData.append('choices[]', index.toString())
}
})
return client<Mastodon.Poll>({
method: params.payload.type === 'vote' ? 'post' : 'get',
instance: 'local',
url:
params.payload.type === 'vote'
? `polls/${params.payload.id}/votes`
: `polls/${params.payload.id}`,
...(params.payload.type === 'vote' && { body: formData })
})
default:
return client<Mastodon.Status>({
method: 'post',
instance: 'local',
url: `statuses/${params.id}/${
params.payload.currentValue ? 'un' : ''
}${MapPropertyToUrl[params.payload.property]}`
})
}
case 'updateAccountProperty':
switch (params.payload.property) {
case 'block':
case 'mute':
return client<Mastodon.Account>({
method: 'post',
instance: 'local',
url: `accounts/${params.id}/${params.payload.property}`
})
case 'reports':
return client<Mastodon.Account>({
method: 'post',
instance: 'local',
url: `reports`,
params: {
account_id: params.id
}
})
}
case 'deleteItem':
return client<Mastodon.Conversation>({
method: 'delete',
instance: 'local',
url: `${params.source}/${params.id}`
})
case 'domainBlock':
return client<any>({
method: 'post',
instance: 'local',
url: `domain_blocks`,
params: {
domain: params.domain
}
})
}
}
type MutationOptionsTimeline = MutationOptions<
Mastodon.Conversation | Mastodon.Notification | Mastodon.Status,
AxiosError,
MutationVarsTimeline
>
const useTimelineMutation = ({
queryClient,
onError,
onMutate,
onSettled,
onSuccess
}: {
queryClient: QueryClient
onError?: MutationOptionsTimeline['onError']
onMutate?: boolean
onSettled?: MutationOptionsTimeline['onSettled']
onSuccess?: MutationOptionsTimeline['onSuccess'] | boolean
}) => {
return useMutation<
Mastodon.Conversation | Mastodon.Notification | Mastodon.Status,
AxiosError,
MutationVarsTimeline
>(mutationFunction, {
onError,
onSettled,
...(typeof onSuccess === 'function'
? { onSuccess }
: {
onSuccess: (data, params) => {
queryClient.cancelQueries(params.queryKey)
haptics('Success')
switch (params.type) {
case 'updateStatusProperty':
switch (params.payload.property) {
case 'poll':
params.payload.data = (data as unknown) as Mastodon.Poll
updateStatusProperty({ queryClient, ...params })
break
}
break
}
}
}),
...(onMutate && {
onMutate: params => {
queryClient.cancelQueries(params.queryKey)
let oldData
params.queryKey && (oldData = queryClient.getQueryData(params.queryKey))
haptics('Success')
switch (params.type) {
case 'updateStatusProperty':
updateStatusProperty({ queryClient, ...params })
break
case 'deleteItem':
deleteItem({ queryClient, ...params })
break
}
return oldData
}
})
})
}
export { useTimelineQuery, useTimelineMutation }

View File

@ -0,0 +1,25 @@
import { InfiniteData, QueryClient } from 'react-query'
import { QueryKeyTimeline } from '../timeline'
const deleteItem = ({
queryClient,
queryKey,
id
}: {
queryClient: QueryClient
queryKey: QueryKeyTimeline
id: Mastodon.Status['id']
}) => {
queryClient.setQueryData<InfiniteData<Mastodon.Conversation[]> | undefined>(
queryKey,
old => {
if (old) {
old.pages = old.pages.map(page => page.filter(item => item.id !== id))
}
return old
}
)
}
export default deleteItem

View File

@ -0,0 +1,27 @@
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
const updateConversation = ({
item,
payload
}: {
item: Mastodon.Conversation
payload: MutationVarsTimelineUpdateStatusProperty['payload']
}) => {
switch (payload.property) {
case 'poll':
if (item.last_status) {
item.last_status[payload.property] = payload.data
}
return item
default:
if (item.last_status) {
item.last_status[payload.property] =
typeof payload.currentValue === 'boolean'
? !payload.currentValue
: true
}
return item
}
}
export default updateConversation

View File

@ -0,0 +1,24 @@
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
const updateNotification = ({
item,
payload
}: {
item: Mastodon.Notification
payload: MutationVarsTimelineUpdateStatusProperty['payload']
}) => {
switch (payload.property) {
case 'poll':
return item
default:
if (item.status) {
item.status[payload.property] =
typeof payload.currentValue === 'boolean'
? !payload.currentValue
: true
}
return item
}
}
export default updateNotification

View File

@ -0,0 +1,37 @@
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
const updateStatus = ({
item,
reblog,
payload
}: {
item: Mastodon.Status
reblog?: boolean
payload: MutationVarsTimelineUpdateStatusProperty['payload']
}) => {
switch (payload.property) {
case 'poll':
console.log(payload.data)
if (reblog) {
item.reblog!.poll = payload.data
} else {
item.poll = payload.data
}
break
default:
if (reblog) {
item.reblog![payload.property] =
typeof payload.currentValue === 'boolean'
? !payload.currentValue
: true
} else {
item[payload.property] =
typeof payload.currentValue === 'boolean'
? !payload.currentValue
: true
}
return item
}
}
export default updateStatus

View File

@ -0,0 +1,76 @@
import { findIndex } from 'lodash'
import { InfiniteData, QueryClient } from 'react-query'
import {
MutationVarsTimelineUpdateStatusProperty,
TimelineData
} from '../timeline'
import updateConversation from './update/conversation'
import updateNotification from './update/notification'
import updateStatus from './update/status'
const updateStatusProperty = ({
queryClient,
queryKey,
id,
reblog,
payload
}: {
queryClient: QueryClient
queryKey: MutationVarsTimelineUpdateStatusProperty['queryKey']
id: MutationVarsTimelineUpdateStatusProperty['id']
reblog?: MutationVarsTimelineUpdateStatusProperty['reblog']
payload: MutationVarsTimelineUpdateStatusProperty['payload']
}) => {
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
queryKey,
old => {
if (old) {
let foundToot = false
old.pages = old.pages.map(page => {
// Skip rest of the pages if any toot is found
if (foundToot) {
return page
} else {
if (
typeof (page as Mastodon.Conversation[])[0].unread === 'boolean'
) {
const items = page as Mastodon.Conversation[]
const tootIndex = findIndex(items, ['last_status.id', id])
if (tootIndex >= 0) {
foundToot = true
updateConversation({ item: items[tootIndex], payload })
}
return page
} else if (
typeof (page as Mastodon.Notification[])[0].type === 'string'
) {
const items = page as Mastodon.Notification[]
const tootIndex = findIndex(items, ['status.id', id])
if (tootIndex >= 0) {
foundToot = true
updateNotification({ item: items[tootIndex], payload })
}
} else {
const items = page as Mastodon.Status[]
const tootIndex = findIndex(items, [
reblog ? 'reblog.id' : 'id',
id
])
// if favouriets page and notifications page, remove the item instead
if (tootIndex >= 0) {
foundToot = true
updateStatus({ item: items[tootIndex], reblog, payload })
}
}
return page
}
})
}
return old
}
)
}
export default updateStatusProperty