diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/WhoCanReply.tsx (renamed from src/view/com/threadgate/WhoCanReply.tsx) | 95 | ||||
-rw-r--r-- | src/view/com/post-thread/PostThreadItem.tsx | 305 |
2 files changed, 164 insertions, 236 deletions
diff --git a/src/view/com/threadgate/WhoCanReply.tsx b/src/components/WhoCanReply.tsx index 3f9970f5f..cd171a0a4 100644 --- a/src/view/com/threadgate/WhoCanReply.tsx +++ b/src/components/WhoCanReply.tsx @@ -33,7 +33,8 @@ import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/componen import {Earth_Stroke2_Corner0_Rounded as Earth} from '#/components/icons/Globe' import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' import {Text} from '#/components/Typography' -import {TextLink} from '../util/Link' +import {TextLink} from '../view/com/util/Link' +import {PencilLine_Stroke2_Corner0_Rounded as PencilLine} from './icons/Pencil' interface WhoCanReplyProps { post: AppBskyFeedDefs.PostView @@ -41,11 +42,7 @@ interface WhoCanReplyProps { style?: StyleProp<ViewStyle> } -export function WhoCanReplyInline({ - post, - isThreadAuthor, - style, -}: WhoCanReplyProps) { +export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) { const {_} = useLingui() const t = useTheme() const infoDialogControl = useDialogControl() @@ -90,73 +87,13 @@ export function WhoCanReplyInline({ ]}> {description} </Text> + {isThreadAuthor && ( + <PencilLine width={12} fill={t.palette.primary_500} /> + )} </View> )} </Button> - <InfoDialog control={infoDialogControl} post={post} settings={settings} /> - </> - ) -} - -export function WhoCanReplyBlock({ - post, - isThreadAuthor, - style, -}: WhoCanReplyProps) { - const {_} = useLingui() - const t = useTheme() - const infoDialogControl = useDialogControl() - const {settings, isRootPost, onPressEdit} = useWhoCanReply(post) - - if (!isRootPost) { - return null - } - if (!settings.length && !isThreadAuthor) { - return null - } - - const isEverybody = settings.length === 0 - const isNobody = !!settings.find(gate => gate.type === 'nobody') - const description = isEverybody - ? _(msg`Everybody can reply`) - : isNobody - ? _(msg`Replies on this thread are disabled`) - : _(msg`Some people can reply`) - - return ( - <> - <Button - label={ - isThreadAuthor ? _(msg`Edit who can reply`) : _(msg`Who can reply`) - } - onPress={isThreadAuthor ? onPressEdit : infoDialogControl.open} - hitSlop={HITSLOP_10}> - {({hovered}) => ( - <View - style={[ - a.flex_1, - a.flex_row, - a.align_center, - a.py_sm, - a.pr_lg, - style, - ]}> - <View style={[{paddingLeft: 25, paddingRight: 18}]}> - <Icon color={t.palette.contrast_300} settings={settings} /> - </View> - <Text - style={[ - a.text_sm, - a.leading_tight, - t.atoms.text_contrast_medium, - hovered && a.underline, - ]}> - {description} - </Text> - </View> - )} - </Button> - <InfoDialog control={infoDialogControl} post={post} settings={settings} /> + <WhoCanReplyDialog control={infoDialogControl} post={post} /> </> ) } @@ -176,31 +113,24 @@ function Icon({ return <IconComponent fill={color} width={width} /> } -function InfoDialog({ +export function WhoCanReplyDialog({ control, post, - settings, }: { control: Dialog.DialogControlProps post: AppBskyFeedDefs.PostView - settings: ThreadgateSetting[] }) { return ( <Dialog.Outer control={control}> <Dialog.Handle /> - <InfoDialogInner post={post} settings={settings} /> + <WhoCanReplyDialogInner post={post} /> </Dialog.Outer> ) } -function InfoDialogInner({ - post, - settings, -}: { - post: AppBskyFeedDefs.PostView - settings: ThreadgateSetting[] -}) { +function WhoCanReplyDialogInner({post}: {post: AppBskyFeedDefs.PostView}) { const {_} = useLingui() + const {settings} = useWhoCanReply(post) return ( <Dialog.ScrollableInner label={_(msg`Who can reply dialog`)} @@ -334,6 +264,9 @@ function useWhoCanReply(post: AppBskyFeedDefs.PostView) { name: 'threadgate', settings, async onConfirm(newSettings: ThreadgateSetting[]) { + if (JSON.stringify(settings) === JSON.stringify(newSettings)) { + return + } try { if (newSettings.length) { await createThreadgate(agent, post.uri, newSettings) diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx index 92b529db7..46c6c958e 100644 --- a/src/view/com/post-thread/PostThreadItem.tsx +++ b/src/view/com/post-thread/PostThreadItem.tsx @@ -34,8 +34,8 @@ import {ContentHider} from '../../../components/moderation/ContentHider' import {LabelsOnMyPost} from '../../../components/moderation/LabelsOnMe' import {PostAlerts} from '../../../components/moderation/PostAlerts' import {PostHider} from '../../../components/moderation/PostHider' +import {WhoCanReply} from '../../../components/WhoCanReply' import {getTranslatorLink, isPostInLanguage} from '../../../locale/helpers' -import {WhoCanReplyBlock, WhoCanReplyInline} from '../threadgate/WhoCanReply' import {ErrorMessage} from '../util/error/ErrorMessage' import {Link, TextLink} from '../util/Link' import {formatCount} from '../util/numeric/format' @@ -406,177 +406,172 @@ let PostThreadItemLoaded = ({ const isThreadedChildAdjacentBot = isThreadedChild && nextPost?.ctx.depth === depth return ( - <> - <PostOuterWrapper - post={post} - depth={depth} - showParentReplyLine={!!showParentReplyLine} - treeView={treeView} - hasPrecedingItem={hasPrecedingItem} - hideTopBorder={hideTopBorder}> - <PostHider - testID={`postThreadItem-by-${post.author.handle}`} - href={postHref} - disabled={overrideBlur} - style={[pal.view]} - modui={moderation.ui('contentList')} - iconSize={isThreadedChild ? 26 : 38} - iconStyles={ - isThreadedChild - ? {marginRight: 4} - : {marginLeft: 2, marginRight: 2} - } - profile={post.author} - interpretFilterAsBlur> - <View - style={{ - flexDirection: 'row', - gap: 10, - paddingLeft: 8, - height: isThreadedChildAdjacentTop ? 8 : 16, - }}> - <View style={{width: 38}}> - {!isThreadedChild && showParentReplyLine && ( + <PostOuterWrapper + post={post} + depth={depth} + showParentReplyLine={!!showParentReplyLine} + treeView={treeView} + hasPrecedingItem={hasPrecedingItem} + hideTopBorder={hideTopBorder}> + <PostHider + testID={`postThreadItem-by-${post.author.handle}`} + href={postHref} + disabled={overrideBlur} + style={[pal.view]} + modui={moderation.ui('contentList')} + iconSize={isThreadedChild ? 26 : 38} + iconStyles={ + isThreadedChild ? {marginRight: 4} : {marginLeft: 2, marginRight: 2} + } + profile={post.author} + interpretFilterAsBlur> + <View + style={{ + flexDirection: 'row', + gap: 10, + paddingLeft: 8, + height: isThreadedChildAdjacentTop ? 8 : 16, + }}> + <View style={{width: 38}}> + {!isThreadedChild && showParentReplyLine && ( + <View + style={[ + styles.replyLine, + { + flexGrow: 1, + backgroundColor: pal.colors.replyLine, + marginBottom: 4, + }, + ]} + /> + )} + </View> + </View> + + <View + style={[ + styles.layout, + { + paddingBottom: + showChildReplyLine && !isThreadedChild + ? 0 + : isThreadedChildAdjacentBot + ? 4 + : 8, + }, + ]}> + {/* If we are in threaded mode, the avatar is rendered in PostMeta */} + {!isThreadedChild && ( + <View style={styles.layoutAvi}> + <PreviewableUserAvatar + size={38} + profile={post.author} + moderation={moderation.ui('avatar')} + type={post.author.associated?.labeler ? 'labeler' : 'user'} + /> + + {showChildReplyLine && ( <View style={[ styles.replyLine, { flexGrow: 1, backgroundColor: pal.colors.replyLine, - marginBottom: 4, + marginTop: 4, }, ]} /> )} </View> - </View> + )} <View - style={[ - styles.layout, - { - paddingBottom: - showChildReplyLine && !isThreadedChild - ? 0 - : isThreadedChildAdjacentBot - ? 4 - : 8, - }, - ]}> - {/* If we are in threaded mode, the avatar is rendered in PostMeta */} - {!isThreadedChild && ( - <View style={styles.layoutAvi}> - <PreviewableUserAvatar - size={38} - profile={post.author} - moderation={moderation.ui('avatar')} - type={post.author.associated?.labeler ? 'labeler' : 'user'} - /> - - {showChildReplyLine && ( - <View - style={[ - styles.replyLine, - { - flexGrow: 1, - backgroundColor: pal.colors.replyLine, - marginTop: 4, - }, - ]} - /> - )} - </View> - )} - - <View + style={ + isThreadedChild + ? styles.layoutContentThreaded + : styles.layoutContent + }> + <PostMeta + author={post.author} + moderation={moderation} + authorHasWarning={!!post.author.labels?.length} + timestamp={post.indexedAt} + postHref={postHref} + showAvatar={isThreadedChild} + avatarModeration={moderation.ui('avatar')} + avatarSize={28} + displayNameType="md-bold" + displayNameStyle={isThreadedChild && s.ml2} style={ - isThreadedChild - ? styles.layoutContentThreaded - : styles.layoutContent - }> - <PostMeta - author={post.author} - moderation={moderation} - authorHasWarning={!!post.author.labels?.length} - timestamp={post.indexedAt} - postHref={postHref} - showAvatar={isThreadedChild} - avatarModeration={moderation.ui('avatar')} - avatarSize={28} - displayNameType="md-bold" - displayNameStyle={isThreadedChild && s.ml2} - style={ - isThreadedChild && { - alignItems: 'center', - paddingBottom: isWeb ? 5 : 2, - } + isThreadedChild && { + alignItems: 'center', + paddingBottom: isWeb ? 5 : 2, } - /> - <LabelsOnMyPost post={post} /> - <PostAlerts - modui={moderation.ui('contentList')} - style={[a.pt_2xs, a.pb_2xs]} - /> - {richText?.text ? ( - <View style={styles.postTextContainer}> - <RichText - enableTags - value={richText} - style={[a.flex_1, a.text_md]} - numberOfLines={limitLines ? MAX_POST_LINES : undefined} - authorHandle={post.author.handle} - /> - </View> - ) : undefined} - {limitLines ? ( - <TextLink - text={_(msg`Show More`)} - style={pal.link} - onPress={onPressShowMore} - href="#" + } + /> + <LabelsOnMyPost post={post} /> + <PostAlerts + modui={moderation.ui('contentList')} + style={[a.pt_2xs, a.pb_2xs]} + /> + {richText?.text ? ( + <View style={styles.postTextContainer}> + <RichText + enableTags + value={richText} + style={[a.flex_1, a.text_md]} + numberOfLines={limitLines ? MAX_POST_LINES : undefined} + authorHandle={post.author.handle} /> - ) : undefined} - {post.embed && ( - <View style={[a.pb_xs]}> - <PostEmbeds embed={post.embed} moderation={moderation} /> - </View> - )} - <PostCtrls - post={post} - record={record} - richText={richText} - onPressReply={onPressReply} - logContext="PostThreadItem" + </View> + ) : undefined} + {limitLines ? ( + <TextLink + text={_(msg`Show More`)} + style={pal.link} + onPress={onPressShowMore} + href="#" /> - </View> + ) : undefined} + {post.embed && ( + <View style={[a.pb_xs]}> + <PostEmbeds embed={post.embed} moderation={moderation} /> + </View> + )} + <PostCtrls + post={post} + record={record} + richText={richText} + onPressReply={onPressReply} + logContext="PostThreadItem" + /> </View> - {hasMore ? ( - <Link - style={[ - styles.loadMore, - { - paddingLeft: treeView ? 8 : 70, - paddingTop: 0, - paddingBottom: treeView ? 4 : 12, - }, - ]} - href={postHref} - title={itemTitle} - noFeedback> - <Text type="sm-medium" style={pal.textLight}> - <Trans>More</Trans> - </Text> - <FontAwesomeIcon - icon="angle-right" - color={pal.colors.textLight} - size={14} - /> - </Link> - ) : undefined} - </PostHider> - </PostOuterWrapper> - <WhoCanReplyBlock post={post} isThreadAuthor={isThreadAuthor} /> - </> + </View> + {hasMore ? ( + <Link + style={[ + styles.loadMore, + { + paddingLeft: treeView ? 8 : 70, + paddingTop: 0, + paddingBottom: treeView ? 4 : 12, + }, + ]} + href={postHref} + title={itemTitle} + noFeedback> + <Text type="sm-medium" style={pal.textLight}> + <Trans>More</Trans> + </Text> + <FontAwesomeIcon + icon="angle-right" + color={pal.colors.textLight} + size={14} + /> + </Link> + ) : undefined} + </PostHider> + </PostOuterWrapper> ) } } @@ -671,7 +666,7 @@ function ExpandedPostDetails({ s.mb10, ]}> <Text style={[a.text_sm, pal.textLight]}>{niceDate(post.indexedAt)}</Text> - <WhoCanReplyInline post={post} isThreadAuthor={isThreadAuthor} /> + <WhoCanReply post={post} isThreadAuthor={isThreadAuthor} /> {needsTranslation && ( <> <Text style={[a.text_sm, pal.textLight]}>·</Text> |