[🐴] Mod disabled (#4089)

* Handle send failures

* Add chat disabled state
zio/stable
Eric Bailey 2024-05-17 18:05:21 -05:00 committed by GitHub
parent 8b3bfb3cf7
commit 49314e2d1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 109 additions and 10 deletions

View File

@ -0,0 +1,26 @@
import React from 'react'
import {View} from 'react-native'
import {Trans} from '@lingui/macro'
import {atoms as a, useTheme} from '#/alf'
import {Text} from '#/components/Typography'
export function ChatDisabled() {
const t = useTheme()
return (
<View style={[a.p_md]}>
<View style={[a.p_xl, a.rounded_md, t.atoms.bg_contrast_25]}>
<Text
style={[a.text_md, a.font_bold, a.pb_sm, t.atoms.text_contrast_high]}>
<Trans>Your chats have been disabled</Trans>
</Text>
<Text style={[a.text_sm, a.leading_snug, t.atoms.text_contrast_medium]}>
<Trans>
Our moderators have reviewed reports and decided to disable your
access to chats on Bluesky.
</Trans>
</Text>
</View>
</View>
)
}

View File

@ -16,11 +16,12 @@ import {AppBskyRichtextFacet, RichText} from '@atproto/api'
import {shortenLinks} from '#/lib/strings/rich-text-manip' import {shortenLinks} from '#/lib/strings/rich-text-manip'
import {isIOS, isNative} from '#/platform/detection' import {isIOS, isNative} from '#/platform/detection'
import {useConvoActive} from '#/state/messages/convo' import {useConvoActive} from '#/state/messages/convo'
import {ConvoItem} from '#/state/messages/convo/types' import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {ScrollProvider} from 'lib/ScrollContext' import {ScrollProvider} from 'lib/ScrollContext'
import {isWeb} from 'platform/detection' import {isWeb} from 'platform/detection'
import {List} from 'view/com/util/List' import {List} from 'view/com/util/List'
import {ChatDisabled} from '#/screens/Messages/Conversation/ChatDisabled'
import {MessageInput} from '#/screens/Messages/Conversation/MessageInput' import {MessageInput} from '#/screens/Messages/Conversation/MessageInput'
import {MessageListError} from '#/screens/Messages/Conversation/MessageListError' import {MessageListError} from '#/screens/Messages/Conversation/MessageListError'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
@ -296,10 +297,16 @@ export function MessagesList({
/> />
</ScrollProvider> </ScrollProvider>
{!blocked ? ( {!blocked ? (
<MessageInput <>
onSendMessage={onSendMessage} {convoState.status === ConvoStatus.Disabled ? (
scrollToEnd={scrollToEndNow} <ChatDisabled />
/> ) : (
<MessageInput
onSendMessage={onSendMessage}
scrollToEnd={scrollToEndNow}
/>
)}
</>
) : ( ) : (
footer footer
)} )}

View File

@ -152,6 +152,7 @@ export class Convo {
fetchMessageHistory: undefined, fetchMessageHistory: undefined,
} }
} }
case ConvoStatus.Disabled:
case ConvoStatus.Suspended: case ConvoStatus.Suspended:
case ConvoStatus.Backgrounded: case ConvoStatus.Backgrounded:
case ConvoStatus.Ready: { case ConvoStatus.Ready: {
@ -241,6 +242,13 @@ export class Convo {
this.withdrawRequestedPollInterval() this.withdrawRequestedPollInterval()
break break
} }
case ConvoDispatchEvent.Disable: {
this.status = ConvoStatus.Disabled
this.fetchMessageHistory() // finish init
this.cleanupFirehoseConnection?.()
this.withdrawRequestedPollInterval()
break
}
} }
break break
} }
@ -269,6 +277,12 @@ export class Convo {
this.withdrawRequestedPollInterval() this.withdrawRequestedPollInterval()
break break
} }
case ConvoDispatchEvent.Disable: {
this.status = ConvoStatus.Disabled
this.cleanupFirehoseConnection?.()
this.withdrawRequestedPollInterval()
break
}
} }
break break
} }
@ -303,6 +317,12 @@ export class Convo {
this.withdrawRequestedPollInterval() this.withdrawRequestedPollInterval()
break break
} }
case ConvoDispatchEvent.Disable: {
this.status = ConvoStatus.Disabled
this.cleanupFirehoseConnection?.()
this.withdrawRequestedPollInterval()
break
}
} }
break break
} }
@ -321,6 +341,10 @@ export class Convo {
this.error = action.payload this.error = action.payload
break break
} }
case ConvoDispatchEvent.Disable: {
this.status = ConvoStatus.Disabled
break
}
} }
break break
} }
@ -343,9 +367,17 @@ export class Convo {
this.error = action.payload this.error = action.payload
break break
} }
case ConvoDispatchEvent.Disable: {
this.status = ConvoStatus.Disabled
break
}
} }
break break
} }
case ConvoStatus.Disabled: {
// can't do anything
break
}
default: default:
break break
} }
@ -424,9 +456,13 @@ export class Convo {
throw new Error('Convo: could not find recipients in convo') throw new Error('Convo: could not find recipients in convo')
} }
// await new Promise(y => setTimeout(y, 2000)) const userIsDisabled = this.sender.chatDisabled as boolean
// throw new Error('UNCOMMENT TO TEST INIT FAILURE')
this.dispatch({event: ConvoDispatchEvent.Ready}) if (userIsDisabled) {
this.dispatch({event: ConvoDispatchEvent.Disable})
} else {
this.dispatch({event: ConvoDispatchEvent.Ready})
}
} catch (e: any) { } catch (e: any) {
logger.error(e, {context: 'Convo: setup failed'}) logger.error(e, {context: 'Convo: setup failed'})
@ -829,6 +865,10 @@ export class Convo {
], ],
}) })
break break
case 'Account is disabled':
this.pendingMessageFailure = 'unrecoverable'
this.dispatch({event: ConvoDispatchEvent.Disable})
break
default: default:
logger.warn( logger.warn(
`Convo handleSendMessageFailure could not handle error`, `Convo handleSendMessageFailure could not handle error`,

View File

@ -8,6 +8,7 @@ import {
ConvoParams, ConvoParams,
ConvoState, ConvoState,
ConvoStateBackgrounded, ConvoStateBackgrounded,
ConvoStateDisabled,
ConvoStateReady, ConvoStateReady,
ConvoStateSuspended, ConvoStateSuspended,
} from '#/state/messages/convo/types' } from '#/state/messages/convo/types'
@ -40,6 +41,7 @@ export function useConvoActive() {
| ConvoStateReady | ConvoStateReady
| ConvoStateBackgrounded | ConvoStateBackgrounded
| ConvoStateSuspended | ConvoStateSuspended
| ConvoStateDisabled
if (!ctx) { if (!ctx) {
throw new Error('useConvo must be used within a ConvoProvider') throw new Error('useConvo must be used within a ConvoProvider')
} }

View File

@ -20,6 +20,7 @@ export enum ConvoStatus {
Error = 'error', Error = 'error',
Backgrounded = 'backgrounded', Backgrounded = 'backgrounded',
Suspended = 'suspended', Suspended = 'suspended',
Disabled = 'disabled',
} }
export enum ConvoItemError { export enum ConvoItemError {
@ -50,6 +51,7 @@ export enum ConvoDispatchEvent {
Background = 'background', Background = 'background',
Suspend = 'suspend', Suspend = 'suspend',
Error = 'error', Error = 'error',
Disable = 'disable',
} }
export type ConvoDispatch = export type ConvoDispatch =
@ -72,6 +74,9 @@ export type ConvoDispatch =
event: ConvoDispatchEvent.Error event: ConvoDispatchEvent.Error
payload: ConvoError payload: ConvoError
} }
| {
event: ConvoDispatchEvent.Disable
}
export type ConvoItem = export type ConvoItem =
| { | {
@ -194,6 +199,18 @@ export type ConvoStateError = {
sendMessage: undefined sendMessage: undefined
fetchMessageHistory: undefined fetchMessageHistory: undefined
} }
export type ConvoStateDisabled = {
status: ConvoStatus.Disabled
items: ConvoItem[]
convo: ChatBskyConvoDefs.ConvoView
error: undefined
sender: AppBskyActorDefs.ProfileViewBasic
recipients: AppBskyActorDefs.ProfileViewBasic[]
isFetchingHistory: boolean
deleteMessage: DeleteMessage
sendMessage: SendMessage
fetchMessageHistory: FetchMessageHistory
}
export type ConvoState = export type ConvoState =
| ConvoStateUninitialized | ConvoStateUninitialized
| ConvoStateInitializing | ConvoStateInitializing
@ -201,6 +218,7 @@ export type ConvoState =
| ConvoStateBackgrounded | ConvoStateBackgrounded
| ConvoStateSuspended | ConvoStateSuspended
| ConvoStateError | ConvoStateError
| ConvoStateDisabled
export type ConvoEvent = { export type ConvoEvent = {
type: 'invalidate-block-state' type: 'invalidate-block-state'

View File

@ -1,6 +1,7 @@
import { import {
ConvoState, ConvoState,
ConvoStateBackgrounded, ConvoStateBackgrounded,
ConvoStateDisabled,
ConvoStateReady, ConvoStateReady,
ConvoStateSuspended, ConvoStateSuspended,
ConvoStatus, ConvoStatus,
@ -13,10 +14,15 @@ import {
*/ */
export function isConvoActive( export function isConvoActive(
convo: ConvoState, convo: ConvoState,
): convo is ConvoStateReady | ConvoStateBackgrounded | ConvoStateSuspended { ): convo is
| ConvoStateReady
| ConvoStateBackgrounded
| ConvoStateSuspended
| ConvoStateDisabled {
return ( return (
convo.status === ConvoStatus.Ready || convo.status === ConvoStatus.Ready ||
convo.status === ConvoStatus.Backgrounded || convo.status === ConvoStatus.Backgrounded ||
convo.status === ConvoStatus.Suspended convo.status === ConvoStatus.Suspended ||
convo.status === ConvoStatus.Disabled
) )
} }