-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add WIP UIs for trending topics and suggested starterpacks * Disable SPs for now * Improve explore treatment a bit, add some polish to cards * Add tiny option in RightNav * Add persisted option to hide trending from sidebar * Add to settings, abstract state, not updating in tab * Fix up hide/show toggle state, WITH broadcast hacK * Clean up persisted code, add new setting * Add new interstitial to Discover * Exploration * First hack at mute words * Wire up interstitial and Explore page * Align components * Some skeleton UI * Handle service config, enablement, load states, update lex contract * Centralize mute word handling * Stale time to 30m * Cache enabled value for reloads, use real data for service config * Remove broadcast hack * Remove titleChild * Gate settings too * Update package, rm langs * Add feature gate * Only english during beta period * Hook up real data * Tweak config * Straight passthrough links * Hook up prod agent * Fix no-show logic * Up config query to 5 min * Remove old file * Remove comment * Remove stray flex_1 * Make trending setting global * Quick placeholder state * Limit # in sidebar, tweak spacing * Tweak gaps * Handle hide/show of sidebar * Simplify messages * Remove interstitial * Revert "Remove interstitial" This reverts commit 1358ad4. * Only show interstitial on mobile * Fix gap * Add explore page recommendations * [topics] add topic screen (#7149) * add topic screen * decode * fix search query * decode * add server route * Fix potential bad destructure (undefined) --------- Co-authored-by: Paul Frazee <[email protected]> Co-authored-by: Dan Abramov <[email protected]> Co-authored-by: Hailey <[email protected]>
- Loading branch information
1 parent
a07949e
commit a2019ac
Showing
29 changed files
with
1,268 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
import React from 'react' | ||
import {View} from 'react-native' | ||
import {AtUri} from '@atproto/api' | ||
import {msg} from '@lingui/macro' | ||
import {useLingui} from '@lingui/react' | ||
|
||
// import {makeProfileLink} from '#/lib/routes/links' | ||
// import {feedUriToHref} from '#/lib/strings/url-helpers' | ||
// import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' | ||
// import {CloseQuote_Filled_Stroke2_Corner0_Rounded as Quote} from '#/components/icons/Quote' | ||
// import {UserAvatar} from '#/view/com/util/UserAvatar' | ||
import type {TrendingTopic} from '#/state/queries/trending/useTrendingTopics' | ||
import {atoms as a, useTheme, ViewStyleProp} from '#/alf' | ||
import {Link as InternalLink, LinkProps} from '#/components/Link' | ||
import {Text} from '#/components/Typography' | ||
|
||
export function TrendingTopic({ | ||
topic: raw, | ||
size, | ||
style, | ||
}: {topic: TrendingTopic; size?: 'large' | 'small'} & ViewStyleProp) { | ||
const t = useTheme() | ||
const topic = useTopic(raw) | ||
|
||
const isSmall = size === 'small' | ||
// const hasAvi = topic.type === 'feed' || topic.type === 'profile' | ||
// const aviSize = isSmall ? 16 : 20 | ||
// const iconSize = isSmall ? 16 : 20 | ||
|
||
return ( | ||
<View | ||
style={[ | ||
a.flex_row, | ||
a.align_center, | ||
a.rounded_full, | ||
a.border, | ||
t.atoms.border_contrast_medium, | ||
t.atoms.bg, | ||
isSmall | ||
? [ | ||
{ | ||
paddingVertical: 5, | ||
paddingHorizontal: 10, | ||
}, | ||
] | ||
: [a.py_sm, a.px_md], | ||
style, | ||
/* | ||
{ | ||
padding: 6, | ||
gap: hasAvi ? 4 : 2, | ||
}, | ||
a.pr_md, | ||
*/ | ||
]}> | ||
{/* | ||
<View | ||
style={[ | ||
a.align_center, | ||
a.justify_center, | ||
a.rounded_full, | ||
a.overflow_hidden, | ||
{ | ||
width: aviSize, | ||
height: aviSize, | ||
}, | ||
]}> | ||
{topic.type === 'tag' ? ( | ||
<Hashtag width={iconSize} /> | ||
) : topic.type === 'topic' ? ( | ||
<Quote width={iconSize - 2} /> | ||
) : topic.type === 'feed' ? ( | ||
<UserAvatar | ||
type="user" | ||
size={aviSize} | ||
avatar="" | ||
/> | ||
) : ( | ||
<UserAvatar | ||
type="user" | ||
size={aviSize} | ||
avatar="" | ||
/> | ||
)} | ||
</View> | ||
*/} | ||
|
||
<Text | ||
style={[ | ||
a.font_bold, | ||
a.leading_tight, | ||
isSmall ? [a.text_sm] : [a.text_md, {paddingBottom: 1}], | ||
]} | ||
numberOfLines={1}> | ||
{topic.displayName} | ||
</Text> | ||
</View> | ||
) | ||
} | ||
|
||
export function TrendingTopicSkeleton({ | ||
size = 'large', | ||
index = 0, | ||
}: { | ||
size?: 'large' | 'small' | ||
index?: number | ||
}) { | ||
const t = useTheme() | ||
const isSmall = size === 'small' | ||
return ( | ||
<View | ||
style={[ | ||
a.rounded_full, | ||
a.border, | ||
t.atoms.border_contrast_medium, | ||
t.atoms.bg_contrast_25, | ||
isSmall | ||
? { | ||
width: index % 2 === 0 ? 75 : 90, | ||
height: 27, | ||
} | ||
: { | ||
width: index % 2 === 0 ? 90 : 110, | ||
height: 36, | ||
}, | ||
]} | ||
/> | ||
) | ||
} | ||
|
||
export function TrendingTopicLink({ | ||
topic: raw, | ||
children, | ||
...rest | ||
}: { | ||
topic: TrendingTopic | ||
} & Omit<LinkProps, 'to' | 'label'>) { | ||
const topic = useTopic(raw) | ||
|
||
return ( | ||
<InternalLink label={topic.label} to={topic.url} {...rest}> | ||
{children} | ||
</InternalLink> | ||
) | ||
} | ||
|
||
type ParsedTrendingTopic = | ||
| { | ||
type: 'topic' | 'tag' | 'unknown' | ||
label: string | ||
displayName: string | ||
url: string | ||
uri: undefined | ||
} | ||
| { | ||
type: 'profile' | 'feed' | ||
label: string | ||
displayName: string | ||
url: string | ||
uri: AtUri | ||
} | ||
|
||
export function useTopic(raw: TrendingTopic): ParsedTrendingTopic { | ||
const {_} = useLingui() | ||
return React.useMemo(() => { | ||
const {topic: displayName, link} = raw | ||
|
||
if (link.startsWith('/search')) { | ||
return { | ||
type: 'topic', | ||
label: _(msg`Browse posts about ${displayName}`), | ||
displayName, | ||
uri: undefined, | ||
url: link, | ||
} | ||
} else if (link.startsWith('/hashtag')) { | ||
return { | ||
type: 'tag', | ||
label: _(msg`Browse posts tagged with ${displayName}`), | ||
displayName, | ||
// displayName: displayName.replace(/^#/, ''), | ||
uri: undefined, | ||
url: link, | ||
} | ||
} | ||
|
||
/* | ||
if (!link.startsWith('at://')) { | ||
// above logic | ||
} else { | ||
const urip = new AtUri(link) | ||
switch (urip.collection) { | ||
case 'app.bsky.actor.profile': { | ||
return { | ||
type: 'profile', | ||
label: _(msg`View ${displayName}'s profile`), | ||
displayName, | ||
uri: urip, | ||
url: makeProfileLink({did: urip.host, handle: urip.host}), | ||
} | ||
} | ||
case 'app.bsky.feed.generator': { | ||
return { | ||
type: 'feed', | ||
label: _(msg`Browse the ${displayName} feed`), | ||
displayName, | ||
uri: urip, | ||
url: feedUriToHref(link), | ||
} | ||
} | ||
} | ||
} | ||
*/ | ||
|
||
return { | ||
type: 'unknown', | ||
label: _(msg`Browse topic ${displayName}`), | ||
displayName, | ||
uri: undefined, | ||
url: link, | ||
} | ||
}, [_, raw]) | ||
} |
Oops, something went wrong.