[Threadgate] Tweak threadgate buttons (#9173)
* tweak in-post threadgate button * tweak composer threadgate button * reduce date length slightly * pressed styles * make date length depend on breakpoint * add chevron to label btn * add tiny chevron, special-case button icon width * [Threadgate] Add hint (#9350) * get tooltip working on web * add compatibility layer for working in iOS sheets * add timeout to profile tooltip now that it appears instantly * rm debug code * Update ThreadgateBtn.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * remeasure when keyboard changes --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * fix types * [Threadgate] Refresh dialog (#9342) * wip new ui * update threadgate dialog with new designs * restore nobody option * relayout android sheet when ratio changes * fix ratio changing case in bottom sheet * timebox reached, use setTimeout * update panel styles * missing imports * extract out Panel * tweak layout animation * fix icon color * use same color mechamism for icon as text * restore the header * refreshed toggle styles (#9343) * [Threadgate] Persist settings (#9341) * add persist toggle to threadgate dialog * move state back down * sort out spacing * wire up query * @surfdude29 tweaks * use tiny chevron in WhoCanReply * wait for prefetch before opening * move Panel into the Toggle namespace * default -> pref * use medium date length * rm hover state from web selects, fix border radius * fix key issue in Selects --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {Fragment, useMemo} from 'react'
|
||||
import {Fragment, useMemo, useRef} from 'react'
|
||||
import {
|
||||
Keyboard,
|
||||
Platform,
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
type ThreadgateAllowUISetting,
|
||||
threadgateViewToAllowUISetting,
|
||||
} from '#/state/queries/threadgate'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
@@ -30,13 +30,13 @@ import {
|
||||
PostInteractionSettingsDialog,
|
||||
usePrefetchPostInteractionSettings,
|
||||
} from '#/components/dialogs/PostInteractionSettingsDialog'
|
||||
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
|
||||
import {Earth_Stroke2_Corner0_Rounded as Earth} from '#/components/icons/Globe'
|
||||
import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group'
|
||||
import {TinyChevronBottom_Stroke2_Corner0_Rounded as TinyChevronDownIcon} from '#/components/icons/Chevron'
|
||||
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSignIcon} from '#/components/icons/CircleBanSign'
|
||||
import {Earth_Stroke2_Corner0_Rounded as EarthIcon} from '#/components/icons/Globe'
|
||||
import {Group3_Stroke2_Corner0_Rounded as GroupIcon} from '#/components/icons/Group'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {Text} from '#/components/Typography'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {PencilLine_Stroke2_Corner0_Rounded as PencilLine} from './icons/Pencil'
|
||||
|
||||
interface WhoCanReplyProps {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
@@ -69,6 +69,11 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
|
||||
postUri: post.uri,
|
||||
rootPostUri: rootUri,
|
||||
})
|
||||
const prefetchPromise = useRef<Promise<void>>(Promise.resolve())
|
||||
|
||||
const prefetch = () => {
|
||||
prefetchPromise.current = prefetchPostInteractionSettings()
|
||||
}
|
||||
|
||||
const anyoneCanReply =
|
||||
settings.length === 1 && settings[0].type === 'everybody'
|
||||
@@ -84,7 +89,14 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
|
||||
Keyboard.dismiss()
|
||||
}
|
||||
if (isThreadAuthor) {
|
||||
editDialogControl.open()
|
||||
// wait on prefetch if it manages to resolve in under 200ms
|
||||
// otherwise, proceed immediately and show the spinner -sfn
|
||||
Promise.race([
|
||||
prefetchPromise.current,
|
||||
new Promise(res => setTimeout(res, 200)),
|
||||
]).finally(() => {
|
||||
editDialogControl.open()
|
||||
})
|
||||
} else {
|
||||
infoDialogControl.open()
|
||||
}
|
||||
@@ -100,18 +112,27 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
|
||||
{...(isThreadAuthor
|
||||
? Platform.select({
|
||||
web: {
|
||||
onHoverIn: prefetchPostInteractionSettings,
|
||||
onHoverIn: prefetch,
|
||||
},
|
||||
native: {
|
||||
onPressIn: prefetchPostInteractionSettings,
|
||||
onPressIn: prefetch,
|
||||
},
|
||||
})
|
||||
: {})}
|
||||
hitSlop={HITSLOP_10}>
|
||||
{({hovered}) => (
|
||||
<View style={[a.flex_row, a.align_center, a.gap_xs, style]}>
|
||||
{({hovered, focused, pressed}) => (
|
||||
<View
|
||||
style={[
|
||||
a.flex_row,
|
||||
a.align_center,
|
||||
a.gap_xs,
|
||||
(hovered || focused || pressed) && native({opacity: 0.5}),
|
||||
style,
|
||||
]}>
|
||||
<Icon
|
||||
color={t.palette.contrast_400}
|
||||
color={
|
||||
isThreadAuthor ? t.palette.primary_500 : t.palette.contrast_400
|
||||
}
|
||||
width={16}
|
||||
settings={settings}
|
||||
/>
|
||||
@@ -119,14 +140,16 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
|
||||
style={[
|
||||
a.text_sm,
|
||||
a.leading_tight,
|
||||
t.atoms.text_contrast_medium,
|
||||
hovered && a.underline,
|
||||
isThreadAuthor
|
||||
? {color: t.palette.primary_500}
|
||||
: t.atoms.text_contrast_medium,
|
||||
(hovered || focused || pressed) && web(a.underline),
|
||||
]}>
|
||||
{description}
|
||||
</Text>
|
||||
|
||||
{isThreadAuthor && (
|
||||
<PencilLine width={12} fill={t.palette.primary_500} />
|
||||
<TinyChevronDownIcon width={8} fill={t.palette.primary_500} />
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
@@ -164,7 +187,11 @@ function Icon({
|
||||
settings.length === 0 ||
|
||||
settings.every(setting => setting.type === 'everybody')
|
||||
const isNobody = !!settings.find(gate => gate.type === 'nobody')
|
||||
const IconComponent = isEverybody ? Earth : isNobody ? CircleBanSign : Group
|
||||
const IconComponent = isEverybody
|
||||
? EarthIcon
|
||||
: isNobody
|
||||
? CircleBanSignIcon
|
||||
: GroupIcon
|
||||
return <IconComponent fill={color} width={width} />
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user